C++ cmake:我必须按什么顺序指定目标链接库
由于必须以正确的顺序指定目标链接库中的所有库,我一次又一次地与链接器问题作斗争。但是我怎样才能确定这个顺序呢示例: 我有以下图书馆C++ cmake:我必须按什么顺序指定目标链接库,c++,boost,linker,cmake,C++,Boost,Linker,Cmake,由于必须以正确的顺序指定目标链接库中的所有库,我一次又一次地与链接器问题作斗争。但是我怎样才能确定这个顺序呢示例: 我有以下图书馆 libA depends on boost libB depends on postgresql and libA (and therefore on boost) myTarget uses libA, libB and boost directly (and through libB depends on postgresql) 由于只有在创建可执行文件时才链
libA depends on boost
libB depends on postgresql and libA (and therefore on boost)
myTarget uses libA, libB and boost directly (and through libB depends on postgresql)
由于只有在创建可执行文件时才链接所有必需的库,因此在链接myTarget(最终可执行文件)时,我必须指定所有库:
由于我正在链接boost static,我的CMakeLists.txt也包含
SET(Boost_USE_STATIC_LIBS ON)
但是,我仍然会遇到链接错误,例如“未定义对boost::re_detail::perl_matcher或boost::date_time::month_formatter的引用”
这真的很烦人,我正在改变库的顺序,一些未定义的引用消失了,但新的未定义引用出现了
如何识别正确的顺序强>
编辑: 我解决了上述问题,分别绘制了标识lib之间所有依赖关系的图,并对它们进行了适当的排序(因此添加了libboost_log.a):
因此,订购是自上而下的。Top是可执行文件,后面是直接使用的库。进一步的依赖关系随之而来,最后必须添加低级依赖关系(由boost使用)。在我的例子中,当我想要遵守链接库的顺序时,我使用cmake命令。我的意思是:
find_package(Boost COMPONENTS date_time filesystem system ...)
find_package(PostgreSQL REQUIRED)
IF(Boost_FOUND AND PostgreSQL_FOUND)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${PostgreSQL_INCLUDE_DIRS})
# ApplicationName -> your_application
# LIB_A_TARGET -> libA
# LIB_B_TARGET -> libB
SET(LIB_A_ALL_DEPS ${Boost_LIBRARIES})
SET(LIB_B_ALL_DEPS ${LIB_A_ALL_DEPS} ${PostgreSQL_LIBRARIES})
SET(EXTRA_APP_DEPS ) # here all your extra libs that they aren't in boost or postgre
SET(YOUR_APP_ALL_DEPS ${LIB_A_ALL_DEPS} ${LIB_B_ALL_DEPS} ${EXTRA_APP_DEPS})
# Here'll be all your ADD_EXECUTABLE, ADD_LIBRARY code
TARGET_LINK_LIBRARIES(${LIB_A_TARGET} ${LIB_A_ALL_DEPS})
ADD_DEPENDENCIES(${LIB_A_TARGET} ${LIB_A_ALL_DEPS})
TARGET_LINK_LIBRARIES(${LIB_B_TARGET} ${LIB_B_ALL_DEPS})
ADD_DEPENDENCIES(${LIB_B_TARGET} ${LIB_B_ALL_DEPS})
TARGET_LINK_LIBRARIES(${ApplicationName} ${YOUR_APP_ALL_DEPS})
ADD_DEPENDENCIES(${ApplicationName} ${YOUR_APP_ALL_DEPS})
ENDIF()
我还没有测试过这段代码,但我会或多或少地测试它。我知道这个示例只是可能的CMakeLists.txt的一部分,所以我需要查看您的代码才能完整地编写它
我希望它能帮助你 UNIXen有
tsort
()可以为您进行这种拓扑排序,如果您向它提供一个直接依赖项列表的话
TARGET_LINK_LIBRARIES(${ApplicationName}
libB.a
libA.a
# PostgreSQL stuff
libpq.a
libsoci_core.a
libsoci_postgresql.a
libpq.so
# Boost
libboost_program_options.a
libboost_system.a
libboost_log.a
libboost_filesystem.a
libboost_date_time.a
libboost_regex.a
# Should include all boost libraries but strangely some libs (the ones above)
# need to be specified "by hand"???
${Boost_LIBRARIES}
# Lowlevel needed by boost
${CMAKE_THREAD_LIBS_INIT} # pthreads, needed by boost
${CMAKE_DL_LIBS} # For libdl.so etc.
)
find_package(Boost COMPONENTS date_time filesystem system ...)
find_package(PostgreSQL REQUIRED)
IF(Boost_FOUND AND PostgreSQL_FOUND)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${PostgreSQL_INCLUDE_DIRS})
# ApplicationName -> your_application
# LIB_A_TARGET -> libA
# LIB_B_TARGET -> libB
SET(LIB_A_ALL_DEPS ${Boost_LIBRARIES})
SET(LIB_B_ALL_DEPS ${LIB_A_ALL_DEPS} ${PostgreSQL_LIBRARIES})
SET(EXTRA_APP_DEPS ) # here all your extra libs that they aren't in boost or postgre
SET(YOUR_APP_ALL_DEPS ${LIB_A_ALL_DEPS} ${LIB_B_ALL_DEPS} ${EXTRA_APP_DEPS})
# Here'll be all your ADD_EXECUTABLE, ADD_LIBRARY code
TARGET_LINK_LIBRARIES(${LIB_A_TARGET} ${LIB_A_ALL_DEPS})
ADD_DEPENDENCIES(${LIB_A_TARGET} ${LIB_A_ALL_DEPS})
TARGET_LINK_LIBRARIES(${LIB_B_TARGET} ${LIB_B_ALL_DEPS})
ADD_DEPENDENCIES(${LIB_B_TARGET} ${LIB_B_ALL_DEPS})
TARGET_LINK_LIBRARIES(${ApplicationName} ${YOUR_APP_ALL_DEPS})
ADD_DEPENDENCIES(${ApplicationName} ${YOUR_APP_ALL_DEPS})
ENDIF()