CMake中的变量
- 变量和含义
常用变量 | 含义 |
PROJECT_NAME |
工程名变量 |
PROJECT_SOURCE_DIR |
顶层的项目目录 |
PROJECT_BINARY_DIR |
使用cmake 的路径 |
CMAKE_ROOT |
CMAKE 安装的根目录 |
CMAKE_BUILD_TYPE |
编译类型:empty ,Debug ,Release … |
CMAKE_SOURCE_DIR |
顶层的CMakeLists.txt 所在路径 |
CMAKE_BINARY_DIR |
顶层的CMakeLists.txt 的build 所在目录 |
CMAKE_<LANG>_COMPILER |
设定某个语言LANG 的编译器,比如g++ |
CMAKE_INSTALL_PREFIX |
指令install 的路径 |
CMAKE_CURRENT_SOURCE_DIR |
当前CMakeLists.txt 所在路径 |
CMAKE_CURRENT_BINARY_DIR |
当前CMakeLists.txt 的build 所在目录 |
EXECUTABLE_OUTPUT_PATH |
可执行文件输出路径 |
LIBRARY_OUTPUT_PATH |
库输出路径 |
- 个别变量解释
源码目录结构
jmudou ├── build.sh ├── CMakeLists.txt └── muduo └── base ├── Atomic.h ├── CMakeLists.txt ├── copyable.h ├── tests │ ├── Atomic_unittest.cc │ ├── CMakeLists.txt │ └── Timestamp_unittest.cc ├── Timestamp.cc ├── Timestamp.h └── Types.h
- 三个CMakeLists.txt输出
jmuduo/CMakeLists.txt: PROJECT_SOURCE_DIR= 11/jmuduo PROJECT_BINARY_DIR= 11/build/debug CMAKE_SOURCE_DIR= 11/jmuduo # 指定顶层的CMakeLists.txt的,因此所有的都相同 CMAKE_BINARY_DIR= 11/build/debug # 上面四项都是与整个项目相关,因此都是一致的。 CMAKE_CURRENT_SOURCE_DIR= 11/jmuduo # 指定当前层的CMakeLists.txt的,因此与层相关 CMAKE_CURRENT_BINARY_DIR= 11/build/debug muduo/base/test/CMakeLists.txt: PROJECT_SOURCE_DIR= 11/jmuduo PROJECT_BINARY_DIR= 11/build/debug CMAKE_SOURCE_DIR= 11/jmuduo CMAKE_BINARY_DIR= 11/build/debug CMAKE_CURRENT_SOURCE_DIR= 11/jmuduo/muduo/base/tests CMAKE_CURRENT_BINARY_DIR= 11/build/debug/muduo/base/tests muduo/base/CMakeLists.txt: PROJECT_SOURCE_DIR= 11/jmuduo PROJECT_BINARY_DIR= 11/build/debug CMAKE_SOURCE_DIR= 11/jmuduo CMAKE_BINARY_DIR= 11/build/debug CMAKE_CURRENT_SOURCE_DIR= 11/jmuduo/muduo/base CMAKE_CURRENT_BINARY_DIR= 11/build/debug/muduo/base
函数
所有的函数列表中,<>表示的参数必须要有,[]表示的参数为可选。
- set可以设置三个类型的变量值:正常变量,cache variable、环境变量。
- Normal Variable:set(<variable> <value>... [PARENT_SCOPE])
- cache:set(<variable> <value>... CACHE <type> <docstring> [FORCE])
- env:set(ENV{<variable>} [<value>])
- OPTION:提供用户可以选择的选项
- 格式:option(<variable> "description" [initial value])
- 比如:
option( USE_MYPATH "user path" ON )
- aux_source_directory
- 语法:aux_source_directory(<dir> <variable>)
- 查找目录dir下的所有源文件(即.c, .cpp, .cc等文件),并将名称保存到 variable 变量
- add_subdirectory
- add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
- 添加一个将被编译的子目录。指明CMakeLists.txt所在目录下包含了一个子目录source_dir。这样source_dir下的源文件和CMakeLists.txt等也会被处理。
- target_link_libraries
- target_link_libraries(exec libs)
- 表示可执行程序exec需要链接到一个名为libs的链接库。
- add_library
- add_library (name dir)
- 用在目录dir下的源文件生成一个名为name的静态链接库:libname.a
- configure_file
- 加入一个配置头文件,用于处理 CMake 对源码的设置
configure_file ( "${PROJECT_SOURCE_DIR}/config.h.in" # config.h.in文件目录 "${PROJECT_BINARY_DIR}/config.h" # config.h 生成的头文件目录 )
- 在配置文件config.h中,配置相关项,比如options中的USE_MYPATH:
#cmakedefine USE_MYMATH
- include
- include(file [optional]):读取CMake的相关文件。
- include(moudle [optional])
the file with name .cmake is searched in the CMAKE_MODULE_PATH。
- include_directories
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
- 添加指定目录到编译器搜索路径。
- install使用:cmake之后,sudo make install就可以执行相应的库和头文件的安装。
- TARGET格式
install(TARGETS targets... [[ARCHIVE|LIBRARY|RUNTIME] [DESTINATION <dir>] [PERMISSIONS permissions...] [CONFIGURATIONS [Debug|Release|...]] [COMPONENT <component>] [OPTIONAL] ] [...])
- targets的类型
可以安装的库有[ARCHIVE|LIBRARY|RUNTIME]三种:
1) 可执行程序视为runtime
2) 静态库视为archieve
3) Module Library视为library
4) 共享库和平台有关 - 参数
- DESTINATION:
指定一个文件将要被安装的目录。如果给的是一个全路径,那么就直接使用;如果是相对路径,默认是相对CMAKE_INSTALL_PREFIX,其值默认是/usr/local/。
1) 头文件:inclide
2) 可执行文件:bin
3) 库:lib - PERMISSIONS: 指定安装文件的权限:
1) user : OWNER_READ, OWNER_WRITE, OWNER_EXECUTE
2) group:GROUP_READ, GROUP_WRITE, GROUP_EXECUTE
3) other:WORLD_READ, WORLD_WRITE, WORLD_EXECUTE
4) uid : SETUID, and SETGID。 - CONFIGURATIONS:为安装规则建立一个配置文件列表。
- install
- FILES格式
INSTALL(FILES files... DESTINATION <dir> [PERMISSIONS permissions...] [CONFIGURATIONS [Debug|Release|...]] [COMPONENT <component>] [RENAME <name>] [OPTIONAL])
- files:即文件名
- 测试
- enanle_testing():启动测试
- add_test(testname Exename arg1 arg2 ...):
- 需要先运行测试程序enanle_testing(),这个指令才有效。
- Exename是可执行程序名,参数arg1, arg2。
- set_tests_properties(...)
- 括号内格式:(Exename [Exename2...] PROPERTIES prop1 value1 prop2 value2),其中PROPERTIES是固定的单词不能改
- 为Exename设置属性,如果没有这个属性,就报错,有如下属性:
1) WILL_FAIL:如果设置为true,那么会反转测试结果的pass/fail标志。
2) PASS_REGULAR_EXPRESSION: 匹配正则表达式,只少有一个匹配,则pass
2) FAIL_REGULAR_EXPRESSION: 匹配正则表达式,则fail
- 宏测试
macro(<name> [arg1 [arg2 [arg3 ...]]]) COMMAND1(ARGS ...) COMMAND2(ARGS ...) ... endmacro(<name>)
- 就类似于写一个函数,用宏实现,调用:name(arg1,arg2,...)。
- 设置项目的版本号
- 在顶层的CMakeLists.txt中:
# 加入版本号是 1.0 set (Project_VERSION_MAJOR 1) # 主版本号 set (Project_VERSION_MINOR 0) # 副版本号
- 在配置文件config.h.in中设置:
#define Project_VERSION_MAJOR @Project_VERSION_MAJOR@ #define Project_VERSION_MINOR @Project_VERSION_MINOR@
- main函数中就可以直接使用这两个宏,代表版本号:
printf("Version %d.%d\n", Project_VERSION_MAJOR, Project_VERSION_MINOR);
- 生成安装包需要利用CPack工具,也是CMake提供的工具。
- 先在顶层CMakeLists.txt中末尾添加:
# 构建一个 CPack 安装包 include(InstallRequiredSystemLibraries) set (CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt") set (CPACK_PACKAGE_VERSION_MAJOR "${Project_VERSION_MAJOR}") set (CPACK_PACKAGE_VERSION_MINOR "${Project_VERSION_MINOR}") include (CPack)
- 导入InstallRequiredSystemLibraries模块,以便之后导入CPack模块
- 设置一些CPack相关变量,包括版权信息和版本信息,其中版本信息用了上一节定义的版本号
- 导入CPack模块
- 生成二进制安装包:cpack -C CPackConfig.cmake
- or 生成源码安装包
- 格式:cpack -C CPackSourceConfig.cmake
在执行该命令的目录下得到:
# Demo8是项目名 $ ls -l | grep Demo8 -rwxrwxrwx 1 szz szz 8631 Dec 12 22:03 Demo8-1.0.1-Linux.sh -rw-rw-r-- 1 szz szz 3709 Dec 12 22:03 Demo8-1.0.1-Linux.tar.gz -rw-rw-r-- 1 szz szz 4982 Dec 12 22:03 Demo8-1.0.1-Linux.tar.Z
- 安装:sh Demo8-1.0.1-Linux.sh。
默认的安装路径:
By default the Demo8 will be installed in: "~/Study/SystemProgram/CMakeExe/Demo8/build/Demo8-1.0.1-Linux" Do you want to include the subdirectory Demo8-1.0.1-Linux? Saying no will install in: "~/Study/SystemProgram/CMakeExe/Demo8/build" [Yn]:
- 运行。安装后,就运行该程序
$ ./Demo8-1.0.1-Linux/bin/Demo 2 5 Now we use our own Math library. 2 ^ 5 is 32
- Demo8-1.0.1-Linux下的目录结果
Demo8-1.0.1-Linux ├── bin │ └── Demo # 可执行程序 ├── include # 头文件 │ ├── config.h │ └── MathFunctions.h └── lib # 静态库 └── libMathFunctions.a
- target_compile_definitions
- 格式
target_compile_definitions(<target> <INTERFACE|PUBLIC|PRIVATE> [items1...] [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
- 作用:编译时定义的宏
- string
- REPLACE
string(REPLACE <match_string> <replace_string> <output_variable> <input> [<input>...])
- 将所有input中出现的match_String替换为replace_string,并且将结果存在output_variable。
- message
message([<mode>] "message to display" ...)
- 显示信息给用户mode取决于信息的类型:
- STATUS:以简洁的方式显示用户感兴趣的信息。
message(STATUS "CXX_FLAGS = " ${CMAKE_CXX_FLAGS} " " ${CMAKE_CXX_FLAGS_${BUILD_TYPE}} )
- 可以理解为printf,把后面的几个信息以空格相间,然后打印出来。显示结果为(和上面对应分成三段):
CXX_FLAGS = -g -D_FILE_OFFSET_BITS=64 -Wall -Wextra -Werror -Wconversion -Wno-unused-parameter -Wold-style-cast -Woverloaded-virtual -Wpointer-arith -Wshadow -Wwrite-strings -march=native -rdynamic -O0
- find_package
find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE] [REQUIRED] [[COMPONENTS] [components...]] [OPTIONAL_COMPONENTS components...] [NO_POLICY_SCOPE])
- 主要是寻找和加载外部项目。如果PackageName找到了,PackageName-found会显出,当没有找到时,默认显示PackageName-not found。通过模式的选择,可以处理在没有找到包时的解决方案。
- QUIET:不显示有用信息,
- REQUIRED:报错
- find_path
find_path (<VAR> name0|NAMES name1 [path1 path2 ...])
- 用以寻找包含着name1文件的目录,如果找到了结果存储在VAR,没有找到结果结果是VAR-not found。成功时,变量被清除find_path再次搜索,没有成功,fin_path再次以相同的变量被调用时搜索。
- find_library同上find_path
find_library (<VAR> name0|NAMES name1 [path1 path2 ...])
- OPTIONS
- NAMES
为library指定一个或多个可能的名字。