CMake中cmake_parse_arguments的使用

Posted fengbingchun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CMake中cmake_parse_arguments的使用相关的知识,希望对你有一定的参考价值。

      CMake有一个预定义的命令cmake_parse_arguments来解析function或macro的参数,并定义一组保存相应选项值的变量。它的格式如下:

cmake_parse_arguments(<prefix> <options> <one_value_keywords>
                      <multi_value_keywords> <args>...)

cmake_parse_arguments(PARSE_ARGV <N> <prefix> <options>
                      <one_value_keywords> <multi_value_keywords>)

      第一个版本既可以在function中使用,也可以在macro中使用。参数说明:
      (1).<prefix>:前缀字符串,位于所有变量名称之前。它后跟"_"和相应关键字的名称。
      (2).<options>:包含相应macro或function的所有选项,例如,在调用macro时可以使用的关键字,后面不跟任何值。无论选项是否在参数列表中,这些关键字将始终定义为 TRUE或FALSE。如果传递将设置为TRUE,否则为FALSE。
      (3).<one_value_keywords>:包含macro或function的所有关键字,后跟一个值,例如关键字DESTINATION: DESTINATION /usr/lib
      (4).<multi_value_keywords>:包含macro或function的所有关键字,后跟多个值,例如关键字FILES: FILES test.cpp main.cpp
      所有关键字均应是唯一的:即每个关键字只能在<options>、<one_value_keywords>或<multi_value_keywords>指定一次。如果违反唯一性,将触发警告。
      所有剩余的参数都收集在变量<prefix>_UNPARSED_ARGUMENTS中,如果所有参数被识别,则该变量将未定义。可以用来检查调用的macro或function是否使用了无法识别的参数。

      function的示例代码段如下:

message("1.test function 1: ARGN")
function(test_function1)
    set(prefix FUNC1)
    set(options CSDN GITHUB)
    set(one_value_keywords DESTINATION)
    set(multi_value_keywords FILES RES)

    # ARGN:包含命名参数和可选参数的变量列表
    cmake_parse_arguments($prefix "$options" "$one_value_keywords" "$multi_value_keywords" $ARGN)

    message("FUNC1_CSDN: $FUNC1_CSDN")
    message("FUNC1_GITHUB: $FUNC1_GITHUB")
    message("FUNC1_DESTINATION: $FUNC1_DESTINATION")
    message("FUNC1_FILES: $FUNC1_FILES")
    message("FUNC1_RES: $FUNC1_RES")
    message("FUNC1_UNPARSED_ARGUMENTS: $FUNC1_UNPARSED_ARGUMENTS")

    if(NOT DEFINED FUNC1_RES)
        message("FUNC1_RES variable is not defined")
    endif()
endfunction()

test_function1(FILES test.cpp main.cpp DESTINATION /usr/lib CSDN config DEBUG)
message("------------------------------")
test_function1(RES png txt model DESTINATION /usr/lib /opt GITHUB test)

      执行结果如下图所示:

      

      macro的示例代码段如下:

message("3.test macro 1: ARGN")
macro(test_macro1)
    set(prefix MACRO1)
    set(options CSDN GITHUB)
    set(one_value_keywords DESTINATION)
    set(multi_value_keywords FILES RES)

    # ARGN:包含命名参数和可选参数的变量列表
    cmake_parse_arguments($prefix "$options" "$one_value_keywords" "$multi_value_keywords" $ARGN)

    message("MACRO1_CSDN: $MACRO1_CSDN")
    message("MACRO1_GITHUB: $MACRO1_GITHUB")
    message("MACRO1_DESTINATION: $MACRO1_DESTINATION")
    message("MACRO1_FILES: $MACRO1_FILES")
    message("MACRO1_RES: $MACRO1_RES")
    message("MACRO1_UNPARSED_ARGUMENTS: $MACRO1_UNPARSED_ARGUMENTS")

    if(NOT DEFINED MACRO1_RES)
        message("MACRO1_RES variable is not defined")
    endif()
endmacro()

test_macro1(FILES test.cpp main.cpp DESTINATION /usr/lib CSDN config DEBUG)
message("------------------------------")
test_macro1(RES png txt model DESTINATION /usr/lib /opt GITHUB test)

       执行结果如下图所示:结果与上面的function一致

       第二个版本(PARSE_ARGV)只能在function中使用,在这种情况下,解析的参数来自调用function的ARGV#变量,解析从<N>-th参数开始,其中<N>是无符号整数。

       此function的示例代码段如下:

message("2.test function 2: PARSE_ARGV")
function(test_function2 addr_csdn addr_github)
    set(prefix FUNC2)
    set(options CSDN GITHUB)
    set(one_value_keywords DESTINATION)
    set(multi_value_keywords FILES RES)

    # 命名参数(names arguments) = 2
    cmake_parse_arguments(PARSE_ARGV 2 $prefix "$options" "$one_value_keywords" "$multi_value_keywords")

    message("FUNC2_CSDN: $FUNC2_CSDN")
    message("FUNC2_GITHUB: $FUNC2_GITHUB")
    message("FUNC2_DESTINATION: $FUNC2_DESTINATION")
    message("FUNC2_FILES: $FUNC2_FILES")
    message("FUNC2_RES: $FUNC2_RES")
    message("FUNC2_UNPARSED_ARGUMENTS: $FUNC2_UNPARSED_ARGUMENTS")

    message("addr csdn: $addr_csdn")
    message("addr github: $addr_github")
endfunction()

test_function2("https://blog.csdn.net/fengbingchun" "https://github.com/fengbingchun" FILES test.cpp main.cpp DESTINATION /usr/lib CSDN config DEBUG)
message("------------------------------")
test_function2("https://blog.csdn.net/fengbingchun" "https://github.com/fengbingchun" RES png txt model DESTINATION /usr/lib /opt GITHUB test)

       执行结果如下图所示:结果与上面的function一致

        执行上述测试代码需要3个文件:./build.sh, CMakeLists.txt, test_cmake_parse_arguments.cmake

       build.sh内容如下:

#! /bin/bash

# supported input parameters
params=(function macro cmake_parse_arguments)

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 ===="
cmake -DTEST_CMAKE_FEATURE=$1 ..

      CMakeLists.txt内容如下:

CMAKE_MINIMUM_REQUIRED(VERSION 3.13)
PROJECT(cmake_feature_usage)

message("#### current cmake version: $CMAKE_MAJOR_VERSION.$CMAKE_MINOR_VERSION.$CMAKE_PATCH_VERSION")

if(TEST_CMAKE_FEATURE STREQUAL "function")
	include(test_function.cmake)
elseif(TEST_CMAKE_FEATURE STREQUAL "macro")
	include(test_macro.cmake)
elseif(TEST_CMAKE_FEATURE STREQUAL "cmake_parse_arguments")
	include(test_cmake_parse_arguments.cmake)
endif()

message("==== test finish ====")

      test_cmake_parse_arguments.cmake内容:为上面所示代码段

      GitHubhttps://github.com/fengbingchun/Linux_Code_Test

以上是关于CMake中cmake_parse_arguments的使用的主要内容,如果未能解决你的问题,请参考以下文章

CMake中cmake_policy的使用

cmake的缓存变量可以用于cpp源码中吗

CMake中cmake_minimum_required的使用

CMake (三)cmake 在工程中的用法

Android OpenCVVisual Studio 创建支持 OpenCV 库的 CMake 工程 ② ( VS 中创建 CMake 工程 | CMake 工程中配置 OpenCV 头文件 )

make如何指定cmake路径