cmake 变量学习

0. CMAKE变量

cmake变量分为三种类型:

  • 内置变量
    内置变量也成为预留变量,由cmake内部进行创建保留
  • 自定义变量
    自定义变量是由开发人员定义编写变量,可由开发人员在cmake文件中进行修改访问。
  • 环境变量
    环境变量即为操作系统环境变量,cmake可与之交互,获取到系统相互信息,cmake中由专有命令可与之交互。

0.1 内置变量

0.2 自定义变量

自定义变量分为隐式定义与显示定义两种

0.2.1 隐式自定义变量

由project 和enable_language命令定义的变量称为隐式变量。

 project(<projectname> [languageName1 languageName2 ... ] )

该命令字段主要是定义工程名,上述命令会隐式定义一些变量,以所定义的project name开头
隐式定义变量名

<PROJECT-NAME>_BINARY_DIR
<PROJECT-NAME>_DESCRIPTION
<PROJECT-NAME>_HOMEPAGE_URL
<PROJECT-NAME>_SOURCE_DIR
<PROJECT-NAME>_VERSION
<PROJECT-NAME>_VERSION_MAJOR
<PROJECT-NAME>_VERSION_MINOR
<PROJECT-NAME>_VERSION_PATCH
<PROJECT-NAME>_VERSION_TWEAK

例如

project(helloworld) 

上述指令会自动添加如下变量定义:

helloworld_BINARY_DIR
helloworld_DESCRIPTION
helloworld_HOMEPAGE_URL
helloworld_SOURCE_DIR
helloworld_VERSION
helloworld_VERSION_MAJOR
helloworld_VERSION_MINOR
helloworld_VERSION_PATCH
helloworld_VERSION_TWEAK
enable_language(<lang> [OPTIONAL] )

该 命令打开了 CMake 对参数中指定的语言的支持,支持CXX/C/Fortran/Asm,该命令会定义如下隐藏变量:

CMAKE_<LANG>_COMPILER
CMAKE_<LANG>_CPPCHECK
CMAKE_<LANG>_CPPLINT
CMAKE_<LANG>_CREATE_SHARED_LIBRARY
CMAKE_<LANG>_CREATE_SHARED_MODULE
CMAKE_<LANG>_CREATE_STATIC_LIBRARY
CMAKE_<LANG>_FLAGS_DEBUG
CMAKE_<LANG>_FLAGS_RELEASE
CMAKE_<LANG>_COMPILER_AR

0.2.2 Normal变量定义

Nornal变量定义是采用set命令

set(<variable> <value>... [PARENT_SCOPE])

将创建变量,并将 值设置为,在被设置之前, 会被展开。value值可以跟多个,如果是多个value,则variable变量以list形式进行保存。

PARENT_SCOPE:为变量名作用域,默认状况下变量默认作用域属于当前 CMakeLists.txt或者函数 ,如果添加PARENT_SCOPE字段命令则把一个变量的值设置到父路径或者调用函数中 。

CMake会为每个CMakeList.txt文件创建各自的实例,在根目录中的CMakeList.txt称之为全局实例,而在其他目录中的称之为本地实例。其实我们可以进一步发现子目录中的CMakeList.txt创建的实例会继承相应父目录中创建的变量,并复制一份给自己使用,这样修改变量值相当于修改的是自己复制的那一份,并不影响父目录中的值。

0.2.3 CACHE变量

cache变量使用如下命令定义:

set(<variable> <value>... CACHE <type> <docstring> [FORCE])  
	<type> <docstring>为必选项
    <type> 可以被 CMake GUI 用来选择一个窗口。
    FILEPATH  = 文件选择对话框。
    PATH        = 路径选择对话框。
    STRING    = 任意的字符串。
    BOOL       = 布尔值选择复选框。
    INTERNAL = 不需要 GUI 输入端。 (适用于永久保存的变量)  
	<docstring>常用于该变量解释说明一段文字。
	[FORCE]可选项将覆盖 cache 值,常用于修改cache变量。

Cache变量作用相当于全局变量,即同一个CMake工程中所有CMakeLists.txt 都可以访问。
所有的 Cache 变量都会出现在 CMakeCache.txt 文件中。
option、find_file命令同样可以创建cache变量。
设置Cache变量值方法:

0.3 环境变量

环境变量主要涉及到cmake如何与其交互:

  • 读取环境变量:$ENV{NAME}
  • 设置环境变量:SET(ENV{变量名} 值)

CMake变量读取

  • 获取变量值:${}
  • if 语句中直接使用变量名而不通过${}取值

1. 测试例子

1.1 CMakeLists.txt

cmake_minimum_required (VERSION 2.6)
project (veriable_test)

# The veriable to config.h.in.
set (MYTEST 1)


# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
  "${PROJECT_SOURCE_DIR}/config.h.in"
  "${PROJECT_BINARY_DIR}/config.h"
  )

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

message("PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}")
message("CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}")
message("Tutorial_SOURCE_DIR: ${Tutorial_SOURCE_DIR}")
message("PROJECT_BINARY_DIR: ${PROJECT_BINARY_DIR}")

# add the executable
add_executable(veriable_test main.c)

1.2 main.c

#include <stdio.h>

void main(void) {

#ifdef MY_TEST
    printf("mytest\n");
#endif

    printf("cmake test\n");
}

1.3 config.h.in

#define MY_TEST @MY_TEST@

1.4 编译

mkdir build
cd build
cmake ..
make

运行:

./veriable_test 

2. 常用变量

2.1 CMAKE_BINARY_DIR

表示工程的编译目录,下边三个变量有相同的值

PROJECT_BINARY_DIR: /home/xxxx/data/source/opensource/cmake/mystudy/cmake_study/day1/build
CMAKE_BINARY_DIR: /home/xxxx/data/source/opensource/cmake/mystudy/cmake_study/day1/build
veriable_test_BINARY_DIR: /home/xxxx/data/source/opensource/cmake/mystudy/cmake_study/day1/build

2.2 CMAKE_SOURCE_DIR

表示工程的源码目录,下边三个变量的值相同

PROJECT_SOURCE_DIR: /home/xxxx/data/source/opensource/cmake/mystudy/cmake_study/day1
CMAKE_SOURCE_DIR: /home/xxxx/data/source/opensource/cmake/mystudy/cmake_study/day1
veriable_test_SOURCE_DIR: /home/xxxx/data/source/opensource/cmake/mystudy/cmake_study/day1

2.3 CMAKE_CURRENT_SOURCE_DIR

指的是当前处理的 CMakeLists.txt 所在的路径

/home/xxxx/data/source/opensource/cmake/mystudy/cmake_study/day1/myfunc

2.3 CMAKE_CURRENT_LIST_FILE

输出调用这个变量的 CMakeLists.txt 的完整路径

/home/xxxx/data/source/opensource/cmake/mystudy/cmake_study/day1/myfunc/CMakeLists.txt

2.4 CMAKE_MODULE_PATH

CMake模块文件用xxxx.cmake来表示,当CMakeLists.txt包含该.cmake文件,编译运行时,该.cmake里的一些命令就会在该包含处得到执行,并且在包含以后的地方能够调用该.cmake里的一些宏和函数。
设置CMAKE_MODULE_PATH之后,由include或者find_package指令找到xxxx.cmake模块
如include(helper.cmake),路径名下需要存在helper.cmake文件;
或者find_package(helper),那么路径下需要存在Findhelper.cmake
实例:sel4代码
sel4/tools/nanopb/examples/cmake_simple/CMakeLists.txt

set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../extra)
find_package(Nanopb REQUIRED)

sel4/tools/nanopb/extra/FindNanopb.cmake

实例:sel4代码

list(
    APPEND
        CMAKE_MODULE_PATH ${
    
    CMAKE_CURRENT_LIST_DIR}/helpers/ ${
    
    CMAKE_SOURCE_DIR}/projects/musllibc
)
include(check_arch_compiler)

./tools/seL4/cmake-tool/helpers/check_arch_compiler.cmake

2.5 CMAKE_C_COMPILER

设置编译C使用的编译工具链

set(CMAKE_C_COMPILER ${CROSS_COMPILER_PREFIX}gcc)
set(CMAKE_ASM_COMPILER ${CROSS_COMPILER_PREFIX}gcc)
set(CMAKE_CXX_COMPILER ${CROSS_COMPILER_PREFIX}g++)

2.6 @@ 引用变量

@@配合configure_file方法,将CMakeLists.txt文件中的变量传递到config文件
如CMakeLists.txt文件如下:

set (MY_TEST "hello")
configure_file (
  "${PROJECT_SOURCE_DIR}/config.h.in"
  "${PROJECT_BINARY_DIR}/config.h"
  )

config.h.in文件如下

#define MY_TEST @MY_TEST@
#cmakedefine USE_MYMATH

生成的config.h文件如下

#define MY_TEST hello
#define USE_MYMATH

3. cmake常用命令

3.1 ADD_DEFINITIONS

向C/C++编译器添加-D 定义,比如:

ADD_DEFINITIONS(-DENABLE_DEBUG -DABC)

参数之间用空格分割
如果你的代码中定义了

#ifdef ENABLE_DEBUG 
// ...
#endif

这个代码块就会生效。
如果要添加其他的编译器开关,可以通过 CMAKE_C_FLAGS 变量和CMAKE_CXX_FLAGS 变量设置。

3.2 ADD_DEPENDENCIES

定义target 依赖的其他target,确保在编译本target 之前,其他的target 已经被构建。

ADD_DEPENDENCIES(target-name depend-target1 depend-target2 ...)

3.3 AUX_SOURCE_DIRECTORY

基本语法是:

AUX_SOURCE_DIRECTORY(dir VARIABLE)

作用是发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指令临时被用来自动构建源文件列表。因为目前cmake 还不能自动发现新添加的源文件。
比如:

AUX_SOURCE_DIRECTORY(. SRC_LIST)
ADD_EXECUTABLE(main ${
    
    SRC_LIST})

3.4 FILE

FILE(WRITE filename “message to write”… )
FILE(APPEND filename “message to write”… )
FILE(READ filename variable)
FILE(GLOB variable [RELATIVE path] [globbing expressions]…)
FILE(GLOB_RECURSE variable [RELATIVE path] [globbing expressions]…)
FILE(REMOVE [directory]…)
FILE(REMOVE_RECURSE [directory]…)
FILE(MAKE_DIRECTORY [directory]…)
FILE(RELATIVE_PATH variable directory file)
FILE(TO_CMAKE_PATH path result)
FILE(TO_NATIVE_PATH path result)

3.5 INCLUDE

用来载入CMakeLists.txt 文件,也用于载入预定义的cmake 模块:

INCLUDE(file1 [OPTIONAL])
INCLUDE(module [OPTIONAL])

载入的内容将在处理到INCLUDE 语句是直接执行。

3.6 FIND_系列指令

FIND_FILE(<VAR> name1 path1 path2 ...)

VAR 变量代表找到的文件全路径,包含文件名。

FIND_LIBRARY(<VAR> name1 path1 path2 ...)

VAR 变量表示找到的库全路径,包含库文件名。

FIND_PATH(<VAR> name1 path1 path2 ...)

VAR 变量代表包含这个文件的路径。

FIND_PROGRAM(<VAR> name1 path1 path2 ...)

VAR 变量代表包含这个程序的全路径。

猜你喜欢

转载自blog.csdn.net/weixin_47139576/article/details/131642650
今日推荐