給定一個具有「app」和「lib」兄弟目錄的項目,其中「app」根據由「lib」構建的(靜態)庫構建可執行文件。我想要的是普通構建過程僅構建庫的情況,但如果構建「應用程序」,則構建「庫」和「應用程序」。鏈接建立靜態庫,而不是使用add_subdirectory?
什麼我目前做的是現在,在app
,包括我lib
與add_subdirectory
,但是由於各種原因,這是通過一種機制,我不拉在lib
的間接依賴到鏈接線的所有意識到。我想就像是讓我的應用程序只是建立libmylib.a
和libmylib.pc
,然後app
可以只從libmylib.pc
(或手動指定它)計算自己的連接線,但我不知道如何完成。
這裏有一個最低工作的例子,我已經有了設立現在:
的lib /的CMakeLists.txt
cmake_minimum_required(VERSION 3.8.0)
project(mylib CXX)
find_package(PkgConfig REQUIRED)
pkg_check_modules("mylib" "libssl")
find_package(Boost REQUIRED)
set(LIBDIR "${PROJECT_SOURCE_DIR}")
set(HEADERS "${LIBDIR}/map_printer.hpp")
set(SOURCES "${LIBDIR}/map_printer.cpp")
add_library("mylib" "${SOURCES}")
target_include_directories("mylib" PUBLIC "${LIBDIR}"
"${Boost_INCLUDE_DIR}"
"${mylib_INCLUDE_DIRS}")
target_link_libraries("mylib" "${Boost_LIBRARIES}" "${mylib_LIBRARIES}")
install(TARGETS "mylib" ARCHIVE DESTINATION "lib")
install(FILES ${HEADERS} DESTINATION "include")
應用/的CMakeLists.txt
cmake_minimum_required(VERSION 3.8.0)
project(mylib CXX)
set(APPDIR "${PROJECT_SOURCE_DIR}")
set(LIBDIR "${APPDIR}/../lib")
set(SOURCES "${APPDIR}/main.cpp")
add_subdirectory("${LIBDIR}" "build")
list(APPEND LIBS "mylib")
add_executable("myapp" "${SOURCES}")
target_include_directories("myapp" PUBLIC "${LIBDIR}")
target_link_libraries("myapp" "${LIBS}")
install(TARGETS "myapp" DESTINATION "bin")
要得到一個工作的例子,這裏是一些源文件,在libssl
拉在lib(但這個樂趣ction沒有在應用程序中使用) - 我把它們放在學家,因爲他們只是爲了保持完整性,我不想弄亂問題文本:
的問題是,當我cmake app
,然後做make VERBOSE=1
,產生鏈接器命令是:
/usr/lib/hardening-wrapper/bin/c++ CMakeFiles/myapp.dir/main.cpp.o -o myapp build/libmylib.a -lssl
但我沒有在app
的任何地方指定-lssl
。通常情況下,這樣會很好,但是在我的實際應用中,-lssl
和其他幾個不必要的符號由於間接依賴性而被包含爲.so文件。當我手動從鏈接器命令中刪除它們時,任務生成並運行得很好。理想情況下,我會使用其.pc
文件(本例中未生成)來構建.a
,並且如果必須拉入過多依賴關係,則可以手動調整鏈接行,但使用此方法時,鏈接器標記(可能其他的東西)以某種我不明白的方式從lib
範圍泄漏出來。
查看['target_link_libraries']的文檔(https://cmake.org/cmake/help/latest/command/target_link_libraries.html);如果您不希望目標的依賴關係傳播,則需要將它們指定爲「PRIVATE」或「PUBLIC」以外的值,默認情況下會按照您使用的那樣進行指定。 – legalize
@legalize Aaaaah!這非常明確,謝謝!如果你想做出答案,那麼它就像任何答案一樣好。 – Paul