簡體   English   中英

如何鏈接包含基於通過 CMake 定義的全局變量定義的條件類型/變量定義的庫?

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

介紹

我正在嘗試在我的 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>則找不到 header。 所以我想我應該告訴 CMake 在哪里可以找到 header,所以我最終添加了一個

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

但是,我還有另一個問題。 找到了header,但是編譯時沒有找到header中使用的很多名字。 原因是在 Toulbar2 中,一些變量/類型是通過使用 #ifdef 或 #ifndef 等預處理指令有條件地定義的,而在這些條件下使用的全局變量又是在編譯時通過 CMake 定義的。 如果您對示例感興趣,我可以提及在提到的 header 文件中使用的Cost類型。 我看到這里的拼圖中缺少一塊,但我不知道是哪一塊。 由於我預編譯了庫,當我包含 header 文件時,這些定義應該存在,因為我正確鏈接了包含這些定義的對應庫。

3)我的第三次嘗試不如我提到的其他兩次優雅,但我拼命尋找解決方案。 因此,我在項目中復制了整個 toulbar2 克隆文件夾,並嘗試將其添加為子目錄,這意味着我的主CMakeLists.txt包含以下行:

add_subdirectory(toulbar2)

它也提供了一個CMakeLists.txt ,這樣做應該沒有問題。 然后我包含了 toulbar2 的 src 目錄,里面包含了我需要的 header 文件,應該沒問題。 正確的? 錯誤的。 我遇到了與(2)之前遇到的相同問題,即當我嘗試編譯我的項目時,一些有條件定義的變量/類型實際上並未定義,即使子項目 toulbar2 已正確(無錯誤)編譯。

我只是想提一下,歡迎任何答案,但是如果你能幫我找出一個優雅的解決方案(見 1 或 2)來解決這個問題,那就更好了,因為這段代碼很快就會發布。 預先感謝您的幫助。

解決方案2)看起來不錯。 使用 toulbar2lib.hpp 編譯項目時,只需添加以下編譯標志 -DNDEBUG -DBOOST -DLONGDOUBLE_PROB -DLONGLONG_COST。 請參閱 github/toulbar2 README.md 如何在沒有 cmake 的情況下編譯這些標志(不應該在此上下文中使用的 WCSPFORMATONLY 除外)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM