我想通过提供我的CMakeLists.txt
文件来增强其他解决方案,该文件在构建依赖项方面也确实有效。
滥用 CMake 的解决方案
cmake_minimum_required(VERSION 2.8)
add_library(lib1 test1.cpp)
add_library(lib2 test2.cpp)
include_directories(${CMAKE_CURRENT_DIR})
add_executable(mainexec main.cpp)
target_link_libraries(mainexec combinedLib) # Important to place before add_custom_target
set(LIBNAME "combinedLib.lib")
add_custom_command(
OUTPUT ${LIBNAME}
COMMAND lib.exe /OUT:${LIBNAME} $<TARGET_FILE:lib1> $<TARGET_FILE:lib2>
DEPENDS lib1 lib2
COMMENT "Combining libs..."
)
add_custom_target(combinedLib
DEPENDS ${LIBNAME}
)
请注意,到目前为止,此解决方案适用于 Visual Studio,但我想它可以兼容多平台。我可以想象以下版本可能适用于基于 Unix 的平台:
set(LIBNAME "libCombinedLib.a")
add_custom_command(
OUTPUT ${LIBNAME}
COMMAND ar -rcT ${LIBNAME} $<TARGET_FILE:lib1> $<TARGET_FILE:lib2>
DEPENDS lib1 lib2
COMMENT "Combining libs..."
)
请注意,这些解决方案会以某种方式滥用 CMake,因为如果您在声明target_link_libraries
之后进行调用,它会抱怨 UTILITY 类型的目标(而不是 STATIC 或 SHARED) 。add_custom_target
CMake 目标声明兼容的解决方案
为了使其符合 CMake,您可以将 `target_link_libraries' 调用替换为
target_link_libraries(mainexec ${LIBNAME})
add_dependencies(mainexec combinedLib)
就我而言,它并不完全令人满意,因为尽管它希望所有依赖项都由调用处理,但它mainexec
必须知道。combinedLib
target_link_libraries
耦合较少的替代解决方案
进一步研究导入的目标,我最终找到了解决我最后一个问题的解决方案:
cmake_minimum_required(VERSION 2.8)
add_library(lib1 test1.cpp)
add_library(lib2 test2.cpp)
include_directories(${CMAKE_CURRENT_DIR})
add_executable(mainexec main.cpp)
set(LIBNAME "combinedLib.lib")
add_custom_command(
OUTPUT ${LIBNAME}
COMMAND lib.exe /OUT:${LIBNAME} $<TARGET_FILE:lib1> $<TARGET_FILE:lib2>
DEPENDS lib1 lib2
COMMENT "Combining libs..."
)
add_custom_target(combinedLibGenerator
DEPENDS ${LIBNAME}
)
add_library(combinedLib STATIC IMPORTED)
set_property(TARGET combinedLib PROPERTY IMPORTED_LOCATION ${LIBNAME})
add_dependencies(combinedLib combinedLibGenerator)
target_link_libraries(mainexec combinedLib)
如果您打算模块化整个 add GLOBAL
afterSTATIC IMPORTED
以使导入的目标全局可见。
便携式 CMake 解决方案
在当前的 CMake 版本中,CMake 完全支持传递依赖和接口库。然后一个接口库可以“链接”到其他库,而这个接口库又可以“链接”到其他库。为什么要引号?虽然这很好用,但这实际上并没有创建一个物理的组合库,而是为“子库”集创建了一种别名。这仍然是我们最终需要的解决方案,这就是我想在这里添加它的原因。
add_library(combinedLib INTERFACE)
target_link_libraries(combinedLib INTERFACE lib1 lib2)
target_link_libraries(mainexec combinedLib)
就是这样!