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

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值