CMake中set_property/get_property的使用
Posted fengbingchun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CMake中set_property/get_property的使用相关的知识,希望对你有一定的参考价值。
CMake中的set_property命令用于在给定作用域(scope)内设置命名属性,其格式如下:
set_property(<GLOBAL |
DIRECTORY [<dir>] |
TARGET [<target1> ...] |
SOURCE [<src1> ...]
[DIRECTORY <dirs> ...]
[TARGET_DIRECTORY <targets> ...] |
INSTALL [<file1> ...] |
TEST [<test1> ...] |
CACHE [<entry1> ...] >
[APPEND] [APPEND_STRING]
PROPERTY <name> [<value1> ...])
在作用域的零个或多个对象(objects)上设置一个属性。
第一个参数决定设置属性的作用域,它必须是以下之一:
(1).GLOBAL:作用域是唯一的,不接受name。
(2).DIRECTORY:作用域默认为当前目录,但其它目录(已由CMake处理)可以按完整或相对路径命名.相对路径被视为相对于当前源目录的路径。
<dir>可以引用二进制目录(may reference a binary directory)。
(3).TARGET:作用域(scope)可以命名零个或多个现有(existing)targets。
(4).SOURCE:作用域(scope)可以命名零个或多个源文件。默认情况下,源文件属性仅对在同一目录(CMakeLists.txt)中添加的target可见.
(5).INSTALL:作用域(scope)可以命名零个或多个已安装的文件路径。
属性key和value都可以使用生成器表达式。特定属性(specific properties)可能适用于已安装的文件和/或目录。
路径组件(path components)必须用正斜杠分割,必须规范化(normalized)并且区分大小写。
要使用相对路径引用(reference)安装前缀本身,请使用.。
(6).TEST:作用域(scope)可以命名零个或多个现有(existing)tests.
(7).CACHE:作用域(scope)必须命名零个或多个缓存现有条目(cache existing entries)。
必需的PROPERTY选项紧跟要设置的属性的名称。其余参数用于以分号分隔的列表形式组成属性值。
如果给出了APPEND选项,则该列表将追加到任何现有属性值(空值将被忽略且不追加)。如果给出了APPEND_STRING选项,则该字符串将作为字符串追加到任何现有属性值,即,它会导致更长的字符串而不是字符串列表。
注意:GENERATED源文件属性可能全局可见。
CMake中的get_property命令用于获取属性,其格式如下:
get_property(<variable>
<GLOBAL |
DIRECTORY [<dir>] |
TARGET <target> |
SOURCE <source>
[DIRECTORY <dir> | TARGET_DIRECTORY <target>] |
INSTALL <file> |
TEST <test> |
CACHE <entry> |
VARIABLE >
PROPERTY <name>
[SET | DEFINED | BRIEF_DOCS | FULL_DOCS])
从作用域中的一个对象中获取一个属性。
第一个参数指定存储结果的变量。第二个参数决定了从哪个作用域获取属性。它必须是以下之一:
(1).GLOBAL:作用域是唯一的,不接受name。
(2).DIRECTORY:作用域默认为当前目录,但另一个目录(已由CMake处理)可以按完整或相对路径<dir>命名.相对路径被视为相对于当前源目录的路径。
<dir>可以引用二进制目录(may reference a binary directory)。
(3).TARGET:作用域必须命名一个现有target。
(4).SOURCE:作用域必须命名一个源文件。默认情况下,将从当前源目录的作用域读取源文件的属性。
(5).INSTALL:作用域必须命名一个已安装的文件路径。
(6).TEST:作用域必须命名一个现有test。
(7).CACHE:作用域必须命名一个缓存条目。
(8).VARIABLE:作用域是唯一的,不接受name。
必需的PROPERTY选项紧跟要获取的属性名称。如果未设置该属性,则返回一个空值,尽管某些属性支持从父作用域继承。
如果给出了SET选项,则变量将设置为布尔值,该值指示是否已设置该属性。如果给出了DEFINED选项,则变量将设置为一个布尔值,指示是否已定义该属性。
如果给出了BRIEF_DOCS或FULL_DOCS,则变量设置为包含所请求属性的文档的字符串。如果为尚未定义的属性请求文档,则返回NOTFOUND。
注意:GENERATED源文件属性可能全局可见。
# reference: https://github.com/Kitware/CMake/blob/master/Tests/Properties/CMakeLists.txt
get_property(GLOBALRESULT GLOBAL PROPERTY GLOBALTEST DEFINED)
if(GLOBALRESULT)
message(SEND_ERROR "Error: global prop defined when it should not be, result is GLOBALRESULT=$GLOBALRESULT")
endif()
define_property(GLOBAL PROPERTY GLOBALTEST
BRIEF_DOCS "A test property"
FULL_DOCS "A long description of this test property"
)
get_property(GLOBALRESULT GLOBAL PROPERTY GLOBALTEST DEFINED)
if(NOT GLOBALRESULT)
message(SEND_ERROR "Error: global prop not defined, result is GLOBALRESULT=$GLOBALRESULT")
endif()
set_property(GLOBAL PROPERTY GLOBALTEST 1)
set_property(DIRECTORY PROPERTY DIRECTORYTEST 1)
set_property(SOURCE source/add.cpp PROPERTY SOURCETEST 1)
get_property(GLOBALRESULT GLOBAL PROPERTY GLOBALTEST)
get_property(DIRECTORYRESULT DIRECTORY PROPERTY DIRECTORYTEST)
get_property(SOURCERESULT SOURCE source/add.cpp PROPERTY SOURCETEST)
if(NOT (GLOBALRESULT AND DIRECTORYRESULT AND SOURCERESULT))
message(SEND_ERROR "Error: test results are "
"GLOBALRESULT=$GLOBALRESULT "
"DIRECTORYRESULT=$DIRECTORYRESULT "
"SOURCERESULT=$SOURCERESULT")
endif()
# test the target property
include_directories(include)
add_library(Properties source/add.cpp)
set_property(TARGET Properties PROPERTY TARGETTEST 1)
get_property(TARGETRESULT TARGET Properties PROPERTY TARGETTEST)
if(NOT TARGETRESULT)
message(SEND_ERROR "Error: target result is TARGETRESULT=$TARGETRESULT")
endif()
# test APPEND and APPEND_STRING set_property()
set_property(TARGET Properties PROPERTY FOO foo)
set_property(TARGET Properties PROPERTY BAR bar)
set_property(TARGET Properties APPEND PROPERTY FOO 123)
set_property(TARGET Properties APPEND_STRING PROPERTY BAR 456)
get_property(APPEND_RESULT TARGET Properties PROPERTY FOO)
if(NOT "$APPEND_RESULT" STREQUAL "foo;123")
message(SEND_ERROR "Error: target result is APPEND_RESULT=$APPEND_RESULT")
endif()
get_property(APPEND_STRING_RESULT TARGET Properties PROPERTY BAR)
if(NOT "$APPEND_STRING_RESULT" STREQUAL "bar456")
message(SEND_ERROR "Error: target result is APPEND_STRING_RESULT=$APPEND_STRING_RESULT")
endif()
# test get_property SET
get_property(TARGETRESULT TARGET Properties PROPERTY TARGETTEST SET)
if(NOT TARGETRESULT)
message(SEND_ERROR "Error: target prop not set, result is TARGETRESULT=$TARGETRESULT")
endif()
# test unsetting a property
set_property(TARGET Properties PROPERTY TARGETTEST)
get_property(TARGETRESULT TARGET Properties PROPERTY TARGETTEST SET)
if(TARGETRESULT)
message(SEND_ERROR "Error: target prop not unset, result is TARGETRESULT=$TARGETRESULT")
endif()
执行测试代码需要多个文件:
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 \\
target_sources add_custom_command add_custom_target \\
add_subdirectory aux_source_directory \\
set_property set_target_properties define_property)
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_set_property.cmake内容为上面的所有测试代码段:参考CMake官方测试代码
另外还包括三个目录:include,source,samples,它们都是非常简单的实现,仅用于测试,如下:
可能的执行结果如下图所示:
GitHub: https://github.com/fengbingchun/Linux_Code_Test
以上是关于CMake中set_property/get_property的使用的主要内容,如果未能解决你的问题,请参考以下文章
CMake中cmake_minimum_required的使用
Android OpenCVVisual Studio 创建支持 OpenCV 库的 CMake 工程 ② ( VS 中创建 CMake 工程 | CMake 工程中配置 OpenCV 头文件 )