cmake教程5-macro宏定义以及传递参数给源文件

引入在C++程序中我们经常见到如下,两个问题:
1. 输出当前程序的版本号
2. 通过cmake添加macro宏定义 出入到源文件,例如在编译opencv/caffe的时候,我们通过cmake -DUSE_CUDA=ON/OFF来确定,是否使用cuda.
问题cmake中如何实现上述两个功能的呢?

至于问题1:

我们可能想到直接在头文件中定义,这样也可以,但是如果直接在cmake中定义,然后传递给程序读取生成更加灵活。

至于问题2:

可以在cmake中通过option函数以及add_definitions函数来实现。

感兴趣也可以看 stack overflow:How to read a CMake Variable in C++ source code

cmake 传递版本号给源文件

首先定义demo11Config.h.in头文件接受CMakeLists.txt传递来的版本号参数,文件内容如下:

// the configured options and settings for demo11
#define demo11_VERSION_MAJOR @demo11_VERSION_MAJOR@
#define demo11_VERSION_MINOR @demo11_VERSION_MINOR@

demo11.cpp代码如下:


#include <stdio.h>
// demoConfig.h文件是cmake生成的
#include "demoConfig.h"

int main(int argc, char* argv[]){

    printf("%s version: %d.%d \n", argv[0], demo11_VERSION_MAJOR, demo11_VERSION_MINOR);
}

注意的是demoConfig.h是生成的在项目结构中并不存在,项目目录如下:

这里写图片描述

CMakeLists.txt如下:

cmake_minimum_required(VERSION 3.5)

project(demo11)

# The version number
set(demo11_VERSION_MAJOR 1)
set(demo11_VERSION_MINOR 0)

# configure a header file to pass some of the CMake settings to
# source code(demo11Config.h.in), the file demoConfig.h does't exists 
configure_file(
        "${PROJECT_SOURCE_DIR}/demo11Config.h.in"
        "${PROJECT_BINARY_DIR}/demoConfig.h"
)

# add the binary tree to the search path for include files
# so that we will find demoConfig.h
include_directories("${PROJECT_BINARY_DIR}")

# add the exectuable
add_executable(demo11 demo11.cpp)

cmake 编译如下:

root@xy:~/cmake_practice/cmake_build/build_demo11# cmake ../../cmake_tuorial/demo11/
-- The C compiler identification is GNU 5.4.0

可以看到生产了demoConfig.h:

drwxr-xr-x  3 root root  4096 Jun 29 08:42 ./
........
-rw-r--r--  1 root root   112 Jun 29 08:42 demoConfig.h
-rw-r--r--  1 root root  4865 Jun 29 08:42 Makefile

demoConfig.h内容如下:


// the configured options and settings for demo11
#define demo11_VERSION_MAJOR 1
#define demo11_VERSION_MINOR 0

make & run,输出如下:

root@xy:~/cmake_practice/cmake_build/build_demo11# ./demo11
./demo11 version: 1.0

添加macro到src文件中(add_definitions/option)

本实例在cmake中添加macro定义到源文件中,从而选择使用不同的lib 模块函数.

项目目录如下:demo12.cpp根据cmake定义的macro USE_SPECIFIED决定使用模块SpecifiedFun(特定的函数),还是模块CommonFun(一般的函数).

这里写图片描述

两个模块都只有一个函数showSelectedFun,主要是输出调用了哪个函数.
模块CommonFun,内容如下:

void showSelectedFun(){
    std::cout<<"Select to use common function"<<std::endl;
}

对应的cmake如下:

add_library(common_fun CommonFun.cpp)

模块SpecifiedFun,内容如下:

void showSelectedFun(){
    std::cout<<"Select to use specified function"<<std::endl;
}

对应的cmake如下:

add_library(specified_fun SpecifiedFun.cpp)

主CMakeLists.txt内容如下, 主要是通过option USE_SPECIFIED ON/OFF来决定使用添加macro add_definitions(-DUSE_SPECIFIED)

cmake_minimum_required(VERSION 3.5)

# should we use specified function
# if not set, then will use common function
option(USE_SPECIFIED "select to use specified function" ON)

# select to use specified function, or common function
message("USE_SPECIFIED is ${USE_SPECIFIED}")

if(USE_SPECIFIED)
    add_definitions(-DUSE_SPECIFIED)
    include_directories("${PROJECT_SOURCE_DIR}/SpecifiedFun")
    add_subdirectory(SpecifiedFun)
    set(EXTRA_LIBS ${EXTRA_LIBS} specified_fun)
    message("select to use specified function, lib is: ${EXTRA_LIBS}")
else()
    include_directories("${PROJECT_SOURCE_DIR}/CommonFun")
    add_subdirectory(CommonFun)
    set(EXTRA_LIBS ${EXTRA_LIBS} common_fun)
    message("select to use common function, lib is: ${EXTRA_LIBS}")
endif(USE_SPECIFIED)

add_executable(demo12 demo12.cpp)
target_link_libraries(demo12 ${EXTRA_LIBS})

首先编译不使用USE_SPECIFIEDUSE_SPECIFIED=OFF

root@xy:~/tmp/demo12/build# cmake -DUSE_SPECIFIED=OFF ..
..........
USE_SPECIFIED is OFF
select to use common function, lib is: common_fun
-- Configuring done
-- Generating done
-- Build files have been written to: /home/xy/tmp/demo12/build

编译make:

root@xy:~/tmp/demo12/build# make 
Scanning dependencies of target common_fun
[ 25%] Building CXX object CommonFun/CMakeFiles/common_fun.dir/CommonFun.cpp.o
[ 50%] Linking CXX static library libcommon_fun.a
[ 50%] Built target common_fun
Scanning dependencies of target demo12
[ 75%] Building CXX object CMakeFiles/demo12.dir/demo12.cpp.o
[100%] Linking CXX executable demo12
[100%] Built target demo12

运行:

root@xy:~/tmp/demo12/build# ./demo12 
Select to use common function

使用macro USE_SPECIFIED直接使用cmake .. 即可
接下来的步骤一样就不重复了

参考: https://cmake.org/cmake-tutorial/
  • 10
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面为您介绍 CMake 中的 macro 和 function。 ## 1. macro macro 是一种 CMake宏定义机制,可以将一组 CMake 命令封装起来,用一个名字来调用,从而简化 CMakeLists.txt 中的代码量。 macro 的定义格式如下: ``` macro(macro_name [arg1 [arg2 [arg3 ...]]) # command1 # command2 # ... endmacro() ``` 其中,macro_name 是宏的名称,arg1、arg2、arg3...是宏的参数列表,可以有 0 至多个参数。 下面是一个简单的例子,定义了一个名为 print_info 的宏,该宏接受两个参数,分别是 name 和 age,然后输出一条信息: ``` macro(print_info name age) message("Name: ${name}, Age: ${age}") endmacro() print_info("Alice" 18) ``` 执行上述代码后,输出结果为: ``` Name: Alice, Age: 18 ``` ## 2. function function 与 macro 的作用类似,也是将一组 CMake 命令封装起来,用一个名字来调用,但 function 有明确的返回值。function 的定义格式如下: ``` function(func_name [arg1 [arg2 [arg3 ...]]) # command1 # command2 # ... return(value) endfunction() ``` 其中,func_name 是函数的名称,arg1、arg2、arg3...是函数的参数列表,可以有 0 至多个参数。value 是函数的返回值。 下面是一个简单的例子,定义了一个名为 add 的函数,该函数接受两个参数,分别是 a 和 b,然后返回它们的和: ``` function(add a b) set(result ${a}+${b}) return(${result}) endfunction() set(sum 0) math(EXPR sum "${sum} + $(add(1 2))") message("Sum: ${sum}") ``` 执行上述代码后,输出结果为: ``` Sum: 3 ``` 在 function 中,我们使用 set 命令定义了一个变量 result,然后用 return 返回了这个变量的值。在调用 add 函数时,我们使用了 $() 将函数调用结果作为表达式的一部分,然后再用 math 命令计算出 sum 的值。 以上就是 CMakemacro 和 function 的介绍,希望对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值