给定一个具有“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