【发布时间】:2017-10-12 20:54:21
【问题描述】:
给定一个具有“app”和“lib”同级目录的项目,其中“app”根据“lib”构建的(静态)库构建可执行文件。我想要的是正常构建过程只构建库的情况,但如果我构建“app”,它会构建“lib”和“app”。
我现在正在做的是,在 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")
app/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")
为了获得一个工作示例,这里有一些源文件在 lib 中拉入 libssl(但此功能未在应用程序中使用) - 我将它们放在 gists 中,因为它们只是为了完整性而包含在内,我没有不想弄乱问题文本:
问题是当我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。通常这会很好,但在我的 real 应用程序中,-lssl 和其他几个不必要的符号由于间接依赖关系而被包含为 .so 文件。当我手动从链接器命令中删除它们时,任务构建并运行得很好。理想情况下,我将使用其.pc 文件(未在此示例中生成)拉入构建的.a,如果必须拉入过多的依赖项,我可以手动调整链接线,但使用这种方法,链接器标志(可能还有其他东西)以某种我不明白的方式从 lib 范围外泄漏。
【问题讨论】:
-
查看
target_link_libraries的文档;如果您不希望传播目标的依赖项,则需要将它们指定为PRIVATE或PUBLIC以外的其他内容,默认情况下假定您已使用它。 -
@legalize 啊啊啊!这使事情变得非常清楚,谢谢!如果您想做出这样的回答,它似乎是一个很好的答案。