CMake中的install命令用于指定安装时要运行的规则,其格式如下:
- install(TARGETS targets... [EXPORT
] - [RUNTIME_DEPENDENCIES args...|RUNTIME_DEPENDENCY_SET
] - [[ARCHIVE|LIBRARY|RUNTIME|OBJECTS|FRAMEWORK|BUNDLE|
- PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE|FILE_SET
|CXX_MODULES_BMI] - [DESTINATION <dir>]
- [PERMISSIONS permissions...]
- [CONFIGURATIONS [Debug|Release|...]]
- [COMPONENT
] - [NAMELINK_COMPONENT
] - [OPTIONAL] [EXCLUDE_FROM_ALL]
- [NAMELINK_ONLY|NAMELINK_SKIP]
- ] [...]
- [INCLUDES DESTINATION [<dir> ...]]) # Installing Targets
-
- install(IMPORTED_RUNTIME_ARTIFACTS targets...
- [RUNTIME_DEPENDENCY_SET
] - [[LIBRARY|RUNTIME|FRAMEWORK|BUNDLE]
- [DESTINATION <dir>]
- [PERMISSIONS permissions...]
- [CONFIGURATIONS [Debug|Release|...]]
- [COMPONENT
] - [OPTIONAL] [EXCLUDE_FROM_ALL]
- ] [...]) # Installing Imported Runtime Artifacts
-
- install(
files... - TYPE <type> | DESTINATION <dir>
- [PERMISSIONS permissions...]
- [CONFIGURATIONS [Debug|Release|...]]
- [COMPONENT
] - [RENAME
] [OPTIONAL] [EXCLUDE_FROM_ALL]) # Installing Files -
- install(DIRECTORY dirs...
- TYPE <type> | DESTINATION <dir>
- [FILE_PERMISSIONS permissions...]
- [DIRECTORY_PERMISSIONS permissions...]
- [USE_SOURCE_PERMISSIONS] [OPTIONAL] [MESSAGE_NEVER]
- [CONFIGURATIONS [Debug|Release|...]]
- [COMPONENT
] [EXCLUDE_FROM_ALL] - [FILES_MATCHING]
- [[PATTERN
| REGEX ] - [EXCLUDE] [PERMISSIONS permissions...]] [...]) # Installing Directories
-
- install([[SCRIPT
] [CODE ]] - [ALL_COMPONENTS | COMPONENT
] - [EXCLUDE_FROM_ALL] [...]) # Custom Installation Logic
-
- install(EXPORT
DESTINATION <dir> - [NAMESPACE
] [FILE .cmake] - [PERMISSIONS permissions...]
- [CONFIGURATIONS [Debug|Release|...]
- [CXX_MODULES_DIRECTORY
] - [EXPORT_LINK_INTERFACE_LIBRARIES]
- [COMPONENT
] - [EXCLUDE_FROM_ALL])
- install(EXPORT_ANDROID_MK
DESTINATION <dir> [...]) # Installing Exports -
- install(RUNTIME_DEPENDENCY_SET
- [[LIBRARY|RUNTIME|FRAMEWORK]
- [DESTINATION <dir>]
- [PERMISSIONS permissions...]
- [CONFIGURATIONS [Debug|Release|...]]
- [COMPONENT
] - [NAMELINK_COMPONENT
] - [OPTIONAL] [EXCLUDE_FROM_ALL]
- ] [...]
- [PRE_INCLUDE_REGEXES regexes...]
- [PRE_EXCLUDE_REGEXES regexes...]
- [POST_INCLUDE_REGEXES regexes...]
- [POST_EXCLUDE_REGEXES regexes...]
- [POST_INCLUDE_FILES files...]
- [POST_EXCLUDE_FILES files...]
- [DIRECTORIES directories...]) # Installing Runtime Dependencies
此命令为project生成安装规则。在安装期间按顺序执行在源目录中调用install命令指定的安装规则。
环境变量CMAKE_INSTALL_MODE可以覆盖install命令的默认拷贝行为。
此命令有多个签名。其中一些定义了file和target的安装选项。此处涵盖了多个签名共有的选项,但它们仅对指定它们的签名有效。共有的选项:
(1).DESTINATION:指定要安装文件的磁盘目录。参数可以是相对或绝对路径。
如果给出了相对路径,则相对于CMAKE_INSTALL_PREFIX变量的值进行解释。可以使用CMAKE_INSTALL_PREFIX变量文档中解释的DESTDIR机制在安装时重新定位前缀。
如果给出了绝对路径(带有前导斜杠或驱动器号),则逐字使用(it is used verbatim).
由于cpack安装程序生成器不支持绝对路径,因此最好始终使用相对路径。
(2).PERMISSIONS:指定安装文件的权限。有效权限是OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ, GROUP_WRITE, GROUP_EXECUTE, WORLD_READ, WORLD_WRITE, WORLD_EXECUTE, SETUID和SETGID。在某些平台上没有意义的权限将在那些平台上会被忽略。
(3).CONFIGURATIONS:指定安装规则适用的构建配置列表(Debug, Release等)。注意:为此选项指定的值仅适用于在CONFIGURATIONS 选项之后列出的选项。
注意:CONFIGURATIONS出现在RUNTIME DESTINATION之前。
(4).COMPONENT:指定与安装规则关联的安装组件名称,例如Runtime或Development。在特定于组件的安装期间,只会执行与给定组件名称关联的安装规则。在完整安装过程中,所有组件都会安装,除非标有EXCLUDE_FROM_ALL。如果未提供COMPONENT,则会创建默认组件"Unspecified"。可以使用CMAKE_INSTALL_DEFAULT_COMPONENT_NAME变量控制默认组件名称。
(5).EXCLUDE_FROM_ALL:指定该文件从完整安装中排除,仅作为特定组件安装的一部分安装。
(6).RENAME:为安装的文件指定一个名称,该名称可能与原始文件不同。只有在命令安装单个文件时才允许重命名。
(7).OPTIONAL:指定如果要安装的文件不存在,则不报错(it is not an error).
安装文件的命令签名可能会在安装期间打印消息。使用CMAKE_INSTALL_MESSAGE变量控制打印哪些消息.
许多install命令变体隐式创建包含已安装文件的目录。如果设置了CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS,将使用指定的权限创建这些目录。否则,它们将根据类Unix平台上的uname规则创建。Windows平台不受影响。
1.Installing Targets:TARGETS形式指定从project安装target的规则。可以安装多种target输出工件(Output Artifacts):
(1).ARCHIVE:包括静态库、DLL导入库。
(2).LIBRARY:包括共享库(Shared libraries)。
(3).RUNTIME:包括可执行文件、DLL。
(4).OBJECTS:与object库关联的object文件。
(5).FRAMEWORK:标有FRAMEWORK属性的静态库和共享库。
(6).BUNDLE:标有MACOSX_BUNDLE属性的可执行文件在macOS上被视为BUNDLE targets。
(7).PUBLIC_HEADER:在非Apple平台上,与库关联的所有PUBLIC_HEADER文件都安装在PUBLIC_HEADER参数指定的目标中。对于Apple平台上的FRAMEWORK库,将忽略此参数定义的规则。
(8).PRIVATE_HEADER:类似于PUBLIC_HEADER,但用于PRIVATE_HEADER文件.
(9).RESOURCE:与PUBLIC_HEADER和PRIVATE_HEADER类似,但用于RESOURCE文件.
(10).FILE_SET
(11).CXX_MODULES_BMI:实验性的。
(12).NAMELINK_COMPONENT:在某些平台上,版本化的共享库具有符号链接。
(13).NAMELINK_ONLY:安装库target时,此选项会导致仅安装名称链接(namelink).在LIBRARY块之外使用此参数是错误的。
(14).NAMELINK_SKIP:类似于NAMELINK_ONLY,但效果相反,在安装库target时,它会导致安装名称链接以外的库文件。当NAMELINK_ONLY和NAMELINK_SKIP都没有给出时,这两个部分都会被安装。在LIBRARY块之外使用此参数是错误的。
(15).EXPORT:此选项将已安装的target文件与名为
(16).INCLUDES_DESTINATION:此选项指定目录列表,当通过install(EXPORT)命令导出时,这些目录将被添加到
(17).RUNTIME_DEPENDENCY_SET:此选项会导致将已安装的可执行文件、共享库和模块target的所有运行时依赖项添加到指定的运行时依赖项集中。然后可以使用install(RUNTIME_DEPENDENCY_SET)命令安装此集。
此关键字和RUNTIME_DEPENDENCIES关键字是互斥的。
(18).RUNTIME_DEPENDENCIES:此选项会导致已安装的可执行文件、共享库和模块target的所有运行时依赖项与target本身一起安装。
该RUNTIME_DEPENDENCIES和RUNTIME_DEPENDENCY_SET关键字是互斥的。
- message("CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") # CMAKE_INSTALL_PREFIX: /usr/local
-
- include(GNUInstallDirs)
- message("CMAKE_INSTALL_BINDIR: ${CMAKE_INSTALL_BINDIR}") # CMAKE_INSTALL_BINDIR: bin
- message("CMAKE_INSTALL_LIBDIR: ${CMAKE_INSTALL_LIBDIR}") # CMAKE_INSTALL_LIBDIR: lib
- message("CMAKE_INSTALL_INCLUDEDIR: ${CMAKE_INSTALL_INCLUDEDIR}") # CMAKE_INSTALL_INCLUDEDIR: include
-
- include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
- add_library(add STATIC ${CMAKE_CURRENT_SOURCE_DIR}/source/add.cpp)
- install(TARGETS add DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/install/${CMAKE_INSTALL_LIBDIR}) # -- Installing: /home/spring/GitHub/Linux_Code_Test/Samples_CMake/messy_usage/install/lib/libadd.a
2.Installing Imported Runtime Artifacts:该IMPORTED_RUNTIME_ARTIFACTS形式指定安装导入target的运行时工件(runtime artifacts)的规则。如果project想在安装中捆绑外部可执行文件或模块,则可以这样做。LIBRARY、RUNTIME、FRAMEWORK和BUNDLE参数具有与它们在TARGETS模式中相同的语义。
3.Installing Files:如果安装头文件,请考虑使用target_sources(FILE_SET)定义的文件集。文件集将头文件与target相关联,并将它们作为target的一部分安装。
FILES形式指定了为project安装files的规则。相对路径给出的文件名将根据当前源目录进行解释。默认情况下,如果没有给出PERMISSIONS参数,则此形式安装的文件具有OWNER_WRITE, OWNER_READ, GROUP_READ和WORLD_READ权限。
PROGRAMS形式与FILES形式相同,不同之处是安装文件的默认权限还包括OWNER_EXECUTE, GROUP_EXECUTE和WORLD_EXECUTE。此形式用于安装非target程序,例如shell脚本。
FILES或PROGRAMS的files...可以使用语法为$<...>的"生成器表达式".
必须提供TYPE或DESTINATION中的一个,但不能同时提供两个。TYPE参数指定要安装的文件的通用文件类型.然后,通过从GNUInstallDirs中获取相应的变量来自动设置目的地(destination),或者如果未定义该变量,则使用内置的默认值.
- install(FILES CMakeLists.txt DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/install) # -- Installing: /home/spring/GitHub/Linux_Code_Test/Samples_CMake/messy_usage/install/CMakeLists.txt
- install(PROGRAMS build.sh DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/install) # -- Installing: /home/spring/GitHub/Linux_Code_Test/Samples_CMake/messy_usage/install/build.sh
4.Installing Directories:要安装头(headers)的目录子树(directory sub-tree),请考虑使用target_sources(FILE_SET)定义的文件集。文件集不仅保留目录结构,它们还将头与target相关联并作为target的一部分安装。
DIRECTORY形式安装一个或多个目录的内容到给定的目的地(given destination)。目录结构被一字不差地复制到目的位置(destination)。相对路径给出的目录名是根据当前源目录进行解释的。如果未提供输入目录名,则将创建目的目录,但不会安装任何内容。FILE_PERMISSIONS和 DIRECTORY_PERMISSIONS选项指定给在目的地文件和目录的权限。
可以使用PATTERN或REGEX选项以细粒度控制目录的安装。
某些选项可能遵循string(REGEX)下所述的PATTERN或REGEX表达式,并且仅应用于与之匹配的文件或目录。EXCLUDE选项将跳过(skip)匹配的文件或目录。PERMISSIONS选项覆盖(override)匹配的文件或目录权限设置。
必须提供TYPE或DESTINATION中的一个,但不能同时提供两个。TYPE参数指定要安装的目录的通用文件类型.然后,通过从GNUInstallDirs中获取相应的变量来自动设置目的地(destination),或者如果未定义该变量,则使用内置的默认值.
- # 注意以下两条语句的差异及执行结果的不同
- install(DIRECTORY include DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/install FILES_MATCHING PATTERN "*.in") # -- Installing: /home/spring/GitHub/Linux_Code_Test/Samples_CMake/messy_usage/install/include/foo.h.in
- install(DIRECTORY include/ DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/install FILES_MATCHING PATTERN "*.in") # -- Installing: /home/spring/GitHub/Linux_Code_Test/Samples_CMake/messy_usage/install/foo.h.in
-
- # install/source下文件的权限将被修改,install/include下文件的权限保持不变
- install(DIRECTORY include source DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/install
- PATTERN "*.in" EXCLUDE
- PATTERN "source/*" PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ)
5.Custom Installation Logic:SCRIPT形式将在安装期间调用给定的CMake脚本文件。如果脚本文件名是相对路径,它将根据当前源目录进行解释。CODE形式在安装期间调用给定的CMake code。Code被指定为双引号字符串中的单个参数。
- # print a message during installation
- install(CODE "MESSAGE(WARNING \"Sample install message.\")") # CMake Warning at cmake_install.cmake:46 (MESSAGE):
- # Sample install message.
6.Installing Exports:EXPORT形式生成并安装一个CMake文件,其中包含从安装树到另一个project的导入target的代码(The EXPORT form generates and installs a CMake file containing code to import targets from the installation tree into another project)。当target名写入导入文件时,NAMESPACE选项将在target名前加上
安装的
EXPORT形式有助于外部project使用当前project构建和安装的target.
- include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
- add_library(add STATIC ${CMAKE_CURRENT_SOURCE_DIR}/source/add.cpp)
- install(TARGETS add EXPORT myproj DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/install)
- # 将会在install/myproj目录下生成myproj.cmake和myproj-noconfig.cmake
- install(EXPORT myproj NAMESPACE mp_ DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/install/myproj)
7.Installing Runtime Dependencies:安装以前由一个或多个install(TARGETS)或install(IMPORTED_RUNTIME_ARTIFACTS)命令创建的运行时依赖集。属于运行时依赖集的target的依赖项在 DLL平台上安装在RUNTIME目的地和组件(destination and component)中,在非DLL平台上的安装在LIBRARY目的地和组件中。macOS框架安装在FRAMEWORK目的地和组件中。在构建树中构建的target永远不会作为运行时依赖项安装,它们自己的依赖项也不会安装,除非target本身是使用install(TARGETS)安装的。
8.Generated Installation Script:不建议使用此功能。考虑改用cmake --install
执行测试代码需要多个文件:
build.sh内容如下:
- #! /bin/bash
-
- # supported input parameters(cmake commands)
- params=(function macro cmake_parse_arguments \
- find_library find_path find_file find_program find_package \
- cmake_policy cmake_minimum_required project include \
- string list set foreach message option if while return \
- math file configure_file \
- include_directories add_executable add_library target_link_libraries install)
-
- usage()
- {
- echo "Error: $0 needs to have an input parameter"
-
- echo "supported input parameters:"
- for param in ${params[@]}; do
- echo " $0 ${param}"
- done
-
- exit -1
- }
-
- if [ $# != 1 ]; then
- usage
- fi
-
- flag=0
- for param in ${params[@]}; do
- if [ $1 == ${param} ]; then
- flag=1
- break
- fi
- done
-
- if [ ${flag} == 0 ]; then
- echo "Error: parameter \"$1\" is not supported"
- usage
- exit -1
- fi
-
- if [[ ! -d "build" ]]; then
- mkdir build
- cd build
- else
- cd build
- fi
-
- echo "==== test $1 ===="
-
- # test_set.cmake: cmake -DTEST_CMAKE_FEATURE=$1 --log-level=verbose ..
- # test_option.cmake: cmake -DTEST_CMAKE_FEATURE=$1 -DBUILD_PYTORCH=ON ..
- cmake -DTEST_CMAKE_FEATURE=$1 ..
- # It can be executed directly on the terminal, no need to execute build.sh, for example: cmake -P test_set.cmake
- make
- make install # only used in cmake files with install command
CMakeLists.txt内容如下:
- cmake_minimum_required(VERSION 3.22)
- project(cmake_feature_usage)
-
- message("#### current cmake version: ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}")
- include(test_${TEST_CMAKE_FEATURE}.cmake)
- message("==== test finish ====")
test_install.cmake内容为上面的所有测试代码段。
另外还包括三个目录:include,source,samples,它们都是非常简单的实现,仅用于测试,如下:

可能的执行结果如下图所示: