CMake:将库链接到库

时间:2013-01-22 21:51:43

标签: cmake

我的cmake有问题。我有,比方说,CMakeLists1有一个CMakeLists2所在的子目录。

在CMakeLists2中,我的目标是一个静态库。我想将它链接到外部库。 我就这样做了:

link_directories ("path_to_library")
add_library (project2 ${sources})
target_link_libraries (project2 "name_of_external_lib")

然后,我想在project1中使用此project2中的一个类。我已经这样做了:

add_executable (project1 ${sources})
target_link_libraries (project1 project2)

但这根本不起作用。首先,project2没有链接到外部库。只是为了检查,我通过vs10项目属性添加了这个库,并且大小不同。第二件事,不知何故,project1看到外部库(它在这个项目的库依赖项中),当然找不到它。

有什么问题?

2 个答案:

答案 0 :(得分:8)

我认为CMake的默认行为是不将project2链接到外部库, 但要将两个库链接到可执行文件。 从“掌握CMake”一书中可以看出。

  

由于静态库没有链接到它们所依赖的库,所以它是   对于CMake来说,重要的是跟踪库,以便在库中指定它们   正在创建的可执行文件的链接行。

您可以尝试在CMakeLists2中使用绝对路径:

add_library (project2 ${sources})
target_link_libraries (project2 "path to ext lib"/"name of ext lib")

或者你可以添加

link_directories ("path_to_library")

到project1的CMakeLists文件。

如果您真的想要在Visual Studio中执行某些操作,则可以使用此answer中给出的命令在CMake中构建custom_command。 它可能看起来像这样(我没有测试它)。

set(EXT_LIB "path_to_library/name_of_external_lib") 
set(BIG_LIB "path_to_big_lib/name_of_big_lib")
add_library (project2 ${sources})
get_property(PROJ2_LOC TARGET project2 PROPERTY LOCATION)

add_custom_command(OUTPUT ${BIG_LIB} 
                   DEPENDS ${EXT_LIB} project2
                   COMMAND "lib.exe /OUT:${BIG_LIB} ${EXT_LIB} ${PROJ2_LOC} )

然后,您可以将您的可执行文件与 $ {BIG_LIB} 相关联。

你必须考虑的一些事情:

  • 也许您必须使用 LOCATION_CONFIG CMake docs,我在this answer中找到了get_property命令)
  • link.exe必须在您的路径中
  • 如果要在其他CMakeLists.txt
  • 中使用 BIG_LIB 变量,请观看 BIG_LIB 变量的范围

答案 1 :(得分:4)

我猜测麻烦很可能是* name_of_external_lib *不正确所以无法找到它。

我会选择:

find_library(
    LIB_I_NEED name_of_external_lib
    HINTS "path_to_library"
)

if(${LIB_I_NEED} STREQUAL "LIB_I_NEED-NOTFOUND")
    message(FATAL_ERROR "Couldn't find the 'external_lib' library)
endif()

message(STATUS "Found 'external_lib' at: ${LIB_I_NEED}")

add_library (project2 ${sources})
target_link_libraries (project2 ${LIB_I_NEED})

如果这没有帮助,请快速阅读cmake docs中的示例:

http://www.cmake.org/cmake/help/v2.8.8/cmake.html#command:target_link_libraries

它提到的一件事是:

  

虽然一次重复通常就足够了,病理对象文件   和符号安排可能需要更多。可以通过以下方式处理此类案件   手动重复最后一个target_link_libraries中的组件   调用

所以我想说另一件事可能是在project2中:

set(PROJECT_2_LIBS project2 "name_of_external_lib" PARENT_SCOPE)

然后在exe:

target_link_libraries (project1 ${PROJECT_2_LIBS})

这将在两个地方重复'external_lib'链接并为您提供更多工作机会;)