【发布时间】:2022-09-28 04:55:20
【问题描述】:
介绍
我正在尝试在我的 CMake 项目中使用 Toulbar2 作为 C++ 库,但是在将其链接到我的主要可执行文件时遇到了很多麻烦。
我在这里和其他类似网站上发现了很多关于这个主题的类似问题,但没有一个能帮助我解决我的具体问题。我确实尝试了所有方法,但我没有设法让它发挥作用,我希望你们中的一些人可以帮助我。
我正在运行 Ubuntu 18.04,CMake 版本 3.23,在我的项目中我使用标准 C++11。我是一名熟练的程序员,但我只是 C++ 和 CMake 的初学者/中级用户。
我已经尝试过的事情
我无法列出我所有的尝试,所以我只会提到那些我认为是我最好的尝试,以便让您了解我可能做错了什么。
1)在我的第一次尝试中,我尝试使用与导入的任何非标准库相同的方法,即在 CMakeLists.txt 中使用 find_package() 然后链接找到的 LIBRARIES 并包含找到的 INCLUDE_DIRS。然而,我很快意识到 Toulbar2 既不提供Find<package>.cmake 也不提供<name>Config.cmake 文件。所以,这种方法行不通。
2)我的第二次尝试是我认为最接近我希望的解决方案的尝试。您可以使用以下命令轻松地将 Toulbar2 编译为动态库:cmake -DLIBTB2=ON .. 在您之前创建的假设 build 目录中。使用make 编译后,您的.so 文件位于build/lib/Linux 中。安装后,您可以使用命令find_library 让CMake 自己找到这个库。所以,我的 CMakeLists.txt 最终看起来像这样:
[...]
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 正确地找到了库并运行了链接命令,但是如果我尝试 #include <toulbar2lib.hpp> 找不到标头。所以我想我应该告诉 CMake 在哪里可以找到那个标题,所以我最终添加了一个
include_directories(/path/to/header/file\'s/directory)
但是,我还有另一个问题。找到了头文件,但是在编译时找不到头文件中使用的很多名称。原因是在 Toulbar2 中,一些变量/类型是通过使用 #ifdef 或 #ifndef 等预处理指令有条件地定义的,而在这些条件下使用的全局变量是在编译时通过 CMake 定义的。如果您对示例感兴趣,我可以提及在上述头文件中使用的 Cost 类型。我看到这里的拼图中缺少一块,但我不知道是哪一块。由于我预编译了库,当我包含头文件时,这些定义应该存在,因为我正确链接了包含这些定义的对应库。
3)我的第三次尝试不如我提到的其他两次优雅,但我拼命寻找解决方案。因此,我复制了项目中的整个 toulbar2 克隆文件夹,并尝试将其添加为子目录,这意味着我的主要 CMakeLists.txt 包含以下行:
add_subdirectory(toulbar2)
它也提供了CMakeLists.txt,这样做应该没有问题。然后我包含了toulbar2的src目录,里面有我需要的头文件,应该没问题。正确的?错误的。我遇到了与 (2) 相同的问题,即当我尝试编译我的项目时,一些有条件定义的变量/类型实际上并未定义,即使子项目 toulbar2 已正确编译(没有错误)。
我只想提一下,欢迎任何答案,但是如果你能帮我找出一个优雅的解决方案(见 1 或 2)来解决这个问题,那就更好了,因为这段代码打算迟早发布。预先感谢您的帮助。
标签: c++ linker g++ linker-errors