24

我对 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 看到了外部库(它在这个项目的库依赖项中),当然找不到它。

问题是什么?

4

2 回答 2

11

我认为 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 中执行类似操作,您可能可以使用此答案中给出的命令在 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}链接起来。

您必须考虑的一些事项:

  • Maybe you have to use LOCATION_CONFIG (CMake docs, I found the get_property command in this answer )
  • link.exe has to be in your path
  • watch the scope of the BIG_LIB variable if you want to use it in an other CMakeLists.txt
于 2013-01-23T13:03:28.013 回答
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 文档中的示例:

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”链接,并为您提供更多工作机会;)

于 2013-01-22T22:28:38.653 回答