[注意:这几乎是Linking to a library that hasn't been built yet with CMake的副本,但在这种情况下,未构建的库来自ADD_CUSTOM_TARGET而不是ADD_LIBRARY,因此CMake无法如此有效地运行其常用的魔法。]
我的一个CMake 2.8项目目前有以下代码:
# the COMMAND was heavily simplified but you get the idea
ADD_CUSTOM_TARGET(custom_breakpad_target ALL
COMMAND cd ${CMAKE_SOURCE_DIR}/google-breakpad && make
)
# now here we are in the root "CMakeLists.txt"
LINK_DIRECTORIES(${CMAKE_SOURCE_DIR}/google-breakpad/src/client/linux)
ADD_EXECUTABLE(hello)
# ...many lines of code...
ADD_DEPENDENCIES(hello custom_breakpad_target)
TARGET_LINK_LIBRARIES(hello breakpad)
我知道LINK_DIRECTORIES因其奇怪的位置而被弃用(或至少被鄙视)(即使我们真的想把它放在TARGET_LINK_LIBRARIES旁边,它也必须在ADD_EXECUTABLE之前)。还有,这个漂亮的新命令FIND_LIBRARY。所以我想写一个根“CMakeLists.txt”更像这样:
ADD_EXECUTABLE(hello)
# ...many lines of code...
ADD_DEPENDENCIES(hello custom_breakpad_target)
FIND_LIBRARY(breakpad breakpad ${CMAKE_SOURCE_DIR}/google-breakpad/src/client/linux)
TARGET_LINK_LIBRARIES(hello breakpad)
此代码工作正常......直到我“干净”。下一次重建无法找到breakpad
,因为它已被rm'ed并且在FIND_LIBRARY运行时尚未再次创建。
我该如何使这项工作?或者让 的作品比我的作品更优雅?
到目前为止,我得到的最好的是
ADD_EXECUTABLE(hello)
# ...many lines of code...
ADD_DEPENDENCIES(hello custom_breakpad_target)
TARGET_LINK_LIBRARIES(hello ${CMAKE_SOURCE_DIR}/google-breakpad/src/client/linux/libbreakpad_client.a)
这具有审美缺点,即必须明确写出“libxxx.a”文件名,而据我理解,即使我们切换到“libxxx.1.so”,FIND_LIBRARY也会毫无疑问地继续工作。
答案 0 :(得分:1)
通过自定义命令构建外部目标很难做到。 CMake提供ExternalProject
模块来帮助解决这个问题。
使用此模块,外部库可以在CMake配置时生成 - 即第一次运行cmake
而不是在运行make
来构建实际项目时。这样做的好处是,在配置项目时,所有文件都已就位,因此使用查找脚本或CMake configure file可以轻松找到它们。
这种方法当然只有在外部库不经常更改时才有意义,因为重建库需要再次运行CMake。如果只需运行make
就需要在更改时重新编译外部库,那么使其工作的最佳方法仍然是为它编写一个完整的CMakeLists.txt并将其与add_subdirectory
一起使用。