如何使用 CMake 将子目录安装到不同位置?
How to install subdirectories to different locations with CMake?
我有几个 CMake 项目,它们定义了自己的安装逻辑。现在,我想添加一个全局 CMakeLists.txt 来添加那些使用 add_subdirectory()
的项目,以便一次构建和安装所有项目。我怎样才能从外部为他们每个人提供不同的 ${CMAKE_INSTALL_PREFIX}
?
我尝试的是在调用之间更改安装前缀以添加子目录,但它们是在实际调用 make install
时安装的,并且在那个时候,安装前缀已经设置为最后分配的值。
如果您的子项目需要相同的变量具有不同的值(在全局范围内),您不能在单个全局项目中使用 add_subdirectory
构建它们。
相反,全局项目可以通过 execute_process
或 ExternalProject_Add
使用 cmake
调用来安装它们。有时,可以使用 install(SCRIPT)
命令。
使用 execute_process
安装使子项目在 configuration
阶段立即可用。
当子项目有一些打包机制时可以使用它(见CMake tutorials about packaging),所以全局对象可以执行find_package(<subproject-name>)
和link与库,定义在子项目中,最简单的方法(使用变量,外部填充)。
# Configure subproject into <subproject-build-dir>
execute_process(COMMAND ${CMAKE_COMMAND} -D<var>=<value> <subproject-source-dir>
WORKING_DIRECTORY <subproject-build-dir>)
# Build and install subproject
execute_process(COMMAND ${CMAKE_COMMAND} --build <subproject-build-dir> --target install)
# Extract variables, related to subproject for link with it.
find_package(<subproject-name>)
# Create target in global project and link with subproject
include_directories(${<subproject-name>_INCLUDE_DIRS})
link_directories(${<subproject-name>_LIBRARY_DIRS})
add_executable(global_program main.cpp)
target_link_libraries(global_program ${<subproject-name>_LIBRARIES})
使用ExternalProject_add
安装会将目标分配给子项目,子项目将在build
阶段安装。在这种情况下也可以与子项目链接,但需要手动填充变量。
# Configure, build and install subproject
ExternalProject_Add(<subproject_target>
SOURCE_DIR <subproject-source-dir>
CMAKE_CACHE_ARGS -D<var>=<value>
BINARY_DIR <subproject-build-dir>
INSTALL_DIR <CMAKE_INSTALL_PREFIX-for-subproject>
)
# Create target in global project and link with subproject
include_directories(<subproject-include-files-location>)
link_directories(<subproject-libraries-location>)
add_executable(global_program main.cpp)
target_link_libraries(global_program <subproject-libraries-name>)
# Make sure that subproject will be built before executable.
add_dependencies(global_program <subproject_target>)
使用 install(SCRIPT)
安装会在 install
阶段执行脚本。当全局项目和子项目之间没有构建依赖关系时,可以使用这种方法。
subproject_install.cmake:
# Configure subproject into <subproject-build-dir>
execute_process(COMMAND ${CMAKE_COMMAND} -D<var>=<value> <subproject-source-dir>
WORKING_DIRECTORY <subproject-build-dir>)
# Build and install subproject
execute_process(COMMAND ${CMAKE_COMMAND} --build <subproject-build-dir> --target install)
CMakeLists.txt:
install(SCRIPT subproject_install.cmake)
我有几个 CMake 项目,它们定义了自己的安装逻辑。现在,我想添加一个全局 CMakeLists.txt 来添加那些使用 add_subdirectory()
的项目,以便一次构建和安装所有项目。我怎样才能从外部为他们每个人提供不同的 ${CMAKE_INSTALL_PREFIX}
?
我尝试的是在调用之间更改安装前缀以添加子目录,但它们是在实际调用 make install
时安装的,并且在那个时候,安装前缀已经设置为最后分配的值。
如果您的子项目需要相同的变量具有不同的值(在全局范围内),您不能在单个全局项目中使用 add_subdirectory
构建它们。
相反,全局项目可以通过 execute_process
或 ExternalProject_Add
使用 cmake
调用来安装它们。有时,可以使用 install(SCRIPT)
命令。
使用 execute_process
安装使子项目在 configuration
阶段立即可用。
当子项目有一些打包机制时可以使用它(见CMake tutorials about packaging),所以全局对象可以执行find_package(<subproject-name>)
和link与库,定义在子项目中,最简单的方法(使用变量,外部填充)。
# Configure subproject into <subproject-build-dir>
execute_process(COMMAND ${CMAKE_COMMAND} -D<var>=<value> <subproject-source-dir>
WORKING_DIRECTORY <subproject-build-dir>)
# Build and install subproject
execute_process(COMMAND ${CMAKE_COMMAND} --build <subproject-build-dir> --target install)
# Extract variables, related to subproject for link with it.
find_package(<subproject-name>)
# Create target in global project and link with subproject
include_directories(${<subproject-name>_INCLUDE_DIRS})
link_directories(${<subproject-name>_LIBRARY_DIRS})
add_executable(global_program main.cpp)
target_link_libraries(global_program ${<subproject-name>_LIBRARIES})
使用ExternalProject_add
安装会将目标分配给子项目,子项目将在build
阶段安装。在这种情况下也可以与子项目链接,但需要手动填充变量。
# Configure, build and install subproject
ExternalProject_Add(<subproject_target>
SOURCE_DIR <subproject-source-dir>
CMAKE_CACHE_ARGS -D<var>=<value>
BINARY_DIR <subproject-build-dir>
INSTALL_DIR <CMAKE_INSTALL_PREFIX-for-subproject>
)
# Create target in global project and link with subproject
include_directories(<subproject-include-files-location>)
link_directories(<subproject-libraries-location>)
add_executable(global_program main.cpp)
target_link_libraries(global_program <subproject-libraries-name>)
# Make sure that subproject will be built before executable.
add_dependencies(global_program <subproject_target>)
使用 install(SCRIPT)
安装会在 install
阶段执行脚本。当全局项目和子项目之间没有构建依赖关系时,可以使用这种方法。
subproject_install.cmake:
# Configure subproject into <subproject-build-dir>
execute_process(COMMAND ${CMAKE_COMMAND} -D<var>=<value> <subproject-source-dir>
WORKING_DIRECTORY <subproject-build-dir>)
# Build and install subproject
execute_process(COMMAND ${CMAKE_COMMAND} --build <subproject-build-dir> --target install)
CMakeLists.txt:
install(SCRIPT subproject_install.cmake)