如何链接包含基于通过 CMake 定义的全局变量的条件类型/变量定义的库?

How can I link a library that contains conditional types/variables definition based on global variables defined through CMake?

提问人:Orazio Rillo 提问时间:6/6/2022 最后编辑:Orazio Rillo 更新时间:9/28/2022 访问量:85

问:

介绍

我正在尝试在我的 CMake 项目中使用 Toulbar2 作为 C++ 库,但是我在将其链接到我的主可执行文件时遇到了很多麻烦。

我在这里和其他类似网站上都发现了许多关于这个主题的类似问题,但它们都没有帮助我解决我的特定问题。我几乎尝试了所有方法,但我没有努力让它工作,我希望你们中的一些人可以帮助我。

我正在运行 Ubuntu 18.04,CMake 版本 3.23,在我的项目中,我使用的是标准 C++11。我是一个熟练的程序员,但我只是C++和CMake的初级/中级用户。

我已经尝试过做什么

我无法列出我所有的尝试,所以我只会提到那些我认为是我最好的尝试,让你了解我可能做错了什么。

1) 在我的第一次尝试中,我尝试使用与我导入的任何非标准库相同的方法,即在 CMakeLists 中使用.txt然后链接找到的 LIBRARIES 并包含找到的INCLUDE_DIRS。但是,我很快意识到 Toulbar2 既没有提供 or 文件。因此,这种方法行不通。find_package()Find<package>.cmake<name>Config.cmake

2)在我看来,我的第二次尝试使我最接近我希望的解决方案。您可以使用以下命令轻松地将 Toulbar2 编译为动态库: 在您之前创建的假设目录中。编译后,您的文件位于 .安装完成后,您可以使用命令让 CMake 自行找到此库。所以,我的CMakeLists.txt最终看起来像这样:cmake -DLIBTB2=ON ..buildmake.sobuild/lib/Linuxfind_library

[...]
find_library(TB2_LIBRARIES tb2)
if(TB2_LIBRARIES)
    set(all_depends ${all_depends} ${TB2_LIBRARIES})
else(TB2_LIBRARIES)
    add_compile_definitions("-DNO_TB2")
    message("Compiling without Toulbar2, if you want to use it, please install it first")
endif(TB2_LIBRARIES)
[...]
target_link_libraries(main ${all_depends})
[...]

此代码在某种程度上起作用,这意味着 CMake 正确找到库并运行链接命令,但是如果我尝试找不到标头。所以我想我应该告诉 CMake 在哪里可以找到该标头,所以我最终添加了一个#include <toulbar2lib.hpp>

include_directories(/path/to/header/file's/directory)

但是,我还有另一个问题。找到标头,但在编译时找不到标头中使用的许多名称。原因是在 Toulbar2 中,一些变量/类型是使用 #ifdef 或 #ifndef 等预处理指令有条件地定义的,而这些条件中使用的全局变量又是在编译时通过 CMake 定义的。如果您对示例感兴趣,我可以提及上述头文件中使用的类型。我看到这里的拼图中缺少一块,但我无法弄清楚是哪一块。由于我预编译了库,因此在包含头文件时应该存在这些定义,因为我正确地链接了包含这些定义的相应库。Cost

3)我的第三次尝试不如我提到的其他两次优雅,但我拼命地试图找到解决方案。因此,我在我的项目中复制了整个 toulbar2 克隆文件夹,并尝试将其添加为子目录,这意味着我的 main 包含以下行:CMakeLists.txt

add_subdirectory(toulbar2)

它也提供了一个,这样做应该没有问题。然后我包含 toulbar2 的 src 目录,其中包含我需要的头文件,我应该没问题。右?错。我遇到了与之前使用 (2) 相同的问题,即当我尝试编译我的项目时,即使子项目 toulbar2 被正确编译(没有错误),一些条件定义的变量/类型实际上并没有定义。CMakeLists.txt

我只是想提一下,欢迎任何答案,但是如果您能帮助我为此问题找到一个优雅的解决方案(参见 1 或 2),那就更好了,因为此代码打算很快或晚发布。提前感谢您的帮助。

C G++ 链接器错误

评论


答:

0赞 Simon de Givry 9/28/2022 #1

解决方案 2) 看起来不错。使用 toulbar2lib.hpp 编译项目时,只需添加以下编译标志 -DNDEBUG -DBOOST -DLONGDOUBLE_PROB -DLONGLONG_COST。请参阅 github/toulbar2 README.md 如何在没有 cmake 的情况下编译这些标志(WCSPFORMATONLY 除外,不应在此上下文中使用)。