一、参考资料
cmake详细教程(经验版)
二、CMake常用指令
add_compile_options()
功能:添加编译参数。
语法:add_compile_options(编译参数)。
# 添加编译参数 -wall -std=c++11
add_compile_options(-wall -std=c++11 -o2)
add_definitions()
功能:向C/C++编译器添加编译选项 -D。
语法:add_definitions(-DENABLE_DEBUG -DABC),参数之间用空格分隔。
#ifdef ENABLE_DEBUG
...
#endif
add_dependencies()
CMAKE之add_dependencies使用
问题引入
在项目中通常会遇见这样的情况:(例如一个项目中有:main,libhello.a, libworld.a),当项目过小的时候,编译顺序是*.a,然后是main,但是当一个项目的文件过于庞大,就会导致编译的顺序不会按照主CMAKE的 add_subdirectory 引入的先后顺序,为了解决这一问题,就需要使用 add_dependencies 进行依赖指定。
简单示例
项目结构
├── CMakeLists.txt // 下面用主CMAKE表示
├── hello
│ ├── CMakeLists.txt // 下面用HELLOCMAKE表示
│ ├── hello.c
│ └── hello.h
├── main
│ ├── CMakeLists.txt // 下面用MAINCMAKE表示
│ └── main.c
└── world
├── CMakeLists.txt // 下面用WORLDCMAKE表示
├── world.c
└── world.h
HELLOCMAKE的内容
cmake_minimum_required(VERSION 3.5.1)
set(CMAKE_C_STANDARD 99)
# 生成hello静态链接库
add_library(hello STATIC world.c hello.h)
MAINCMAKE的内容
cmake_minimum_required(VERSION 3.5.1)
project(CmakeDemo C)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY /home/lib)
set(CMAKE_C_STANDARD 99)
# 生成CmakeDemo可执行文件
add_executable(CmakeDemo main.c)
link_directories(/home/lib)
target_link_libraries(
CmakeDemo
hello
world
)
WORLDCMAKE的内容
cmake_minimum_required(VERSION 3.5.1)
set(CMAKE_C_STANDARD 99)
# 生成world静态链接库
add_library(world STATIC world.c world.h)
主CMAKE的内容
cmake_minimum_required(VERSION 3.5)
add_subdirectory(main)
add_subdirectory(hello)
add_subdirectory(world)
add_dependencies(CmakeDemo hello world)
注意
- 该示例中,只有在 主CMAKE 中使用到 add_dependencies()。
- add_dependencies() 中所填写的名称应该是其他 CMAKE 生成的名称。
- 该示例中,如果写成 add_dependencies(CmakeDemo libhello.a libworld.a) ,则会报错。
总结
当构建一个项目时,由于依赖关系的存在,所以被依赖的项目总是最先构建,这样可避免出现"找不到库的错误"。
add_executable()
功能:生成可执行文件。
语法:add_executable(exe文件名 source1 source2 .. sourceN)。
# 编译main.cpp生成可执行文件main
add_executable(main main.cpp)
add_library()
功能:生成库文件,.so动态库、.a静态库、.o中间产物。
语法:add_library(<name> [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 .. sourceN)。
参数解释
- <name>,表示库文件的名字,该库文件会根据命令里列出的源文件来创建。
- STATIC、SHARED 和 MODULE 的作用是指定生成的库文件的类型。STATIC 库是目标文件的归档文件,在链接其它目标的时候使用。
- SHARED库会被动态链接(动态链接库),在运行时会被加载。
- MODULE库是一种不会被链接到其它目标中的插件,但是可能会在运行时使用dlopen-系列的函数。
# 生成 libmindsporelite.so 动态链接库
add_library(mindsporelite SHARED main.cc)
# 生成 libmindsporelite.a 静态链接库
add_library(mindsporelite STATIC main.cc)
# 生成 libmindsporelite.o 未被链接的中间产物
# 中间文件不能作为库或者单独执行
add_library(mindsporelite OBJECT main.cc)
aux_source_directory()
功能:查找指定目录下的所有源文件,并将结果存进指定变量名。
语法:aux_source_directory(文件夹路径 变量名)。
# 遍历当前目录下的所有源代码文件,并将其添加到变量DIR_SRCS中
aux_source_directory(. DIR_SRCS)
# 编译SRC变量所代表的源代码文件,生成main可执行文件
add_executable(main ${SRC})
add_subdirectory()
功能:向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置。
语法:add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])。
顶层CMakeLists.txt 通过 add_subdirectory(dir),指明本项目包含的子目录 ,子目录下的 CMakeLists.txt 文件和源代码也会被处理,通过多层的CmakeLists,一一构建各层的库和依赖。binary_dir 指定的目录存放输出文件,如果没有指定则使用source_dir。
# 添加src子目录,src中需要有一个CMakeLists.txt
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src)
cmake_minimum_required()
功能:指定CMake的最小版本要求。
语法:cmake_minimum_required(VERSION 版本号 [FATAL_ERROR])。
# CMake最小版本要求为2.8.3
cmake_minimum_required(VERSION 2.8.3)
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变量代表包含这个工程的全路径。
find_package()
Cmake命令之find_package介绍
功能:本地导入外部库。用于查找包(通常是使用三方库),并返回关于包的细节(使用包所依赖的头文件、库文件、编译选项、链接选项等)。
语法:FIND_PACKAGE(<name> [major.minor] [QUIET] [NO_MODULE] [[REQUIRED|COMPONENTS] [componets …]])。
参数解释
- REQUIRED 表示该库是必须的,如果找不到会报错;
- COMPONENTS 用于检测该库的对应组件是否存在,如果不存在则认为找到的库不满足条件;
# find a boost install with the libraries filesystem and system
# 使用库文件系统和系统查找boost install
find_package(Boost 1.46.1 REQUIRED COMPONENTS filesystem system)
#这是第三方库,而不是自己生成的静态动态库
# check if boost was found
if(Boost_FOUND)
message ("boost found")
else()
message (FATAL_ERROR "Cannot find Boost")
endif()
# Add an executable
add_executable(third_party_include main.cpp)
# link against the boost libraries
target_link_libraries( third_party_include
PRIVATE
Boost::filesystem
)
上面的指令,使用 find_package 指令来在本地搜索对应的第三方库,Boost 代表需要查询的库名称;1.46.1 代表需要库的最低版本。
FetchContent
功能:外部导入外部库。FetchContent 是 3.11.0 版本开始提供的功能,只需要一个 URL 或者 Git 仓库即可引入一个库。
使用方法
- include(FetchContent) :表示引入 FetchContent。
- FetchContent_Declare(第三方库) :获取第三方库,可以是一个 URL 或者一个 Git 仓库。
- FetchContent_MakeAvailable(第三方库) :将这个第三方库引入项目。
- target_link_libraries(主项目 PRIVATE 子模块::子模块) :链接这个第三方库。
cmake_minimum_required(VERSION 3.14)
project(my_project)
# GoogleTest requires at least C++11
set(CMAKE_CXX_STANDARD 11)
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
FILE()
CMake 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)
include()
Load and run CMake code from a file or module.
功能:用来载入 CMakeLists.txt 文件,也用于载入预定义的cmake模块。
语法:include(<file|module> [OPTIONAL] [RESULT_VARIABLE <VAR>] [NO_POLICY_SCOPE])。
如果指定文件,则直接处理。如果指定module,则寻找 module.cmake 文件,首先在${CMAKE_MODULE_PATH} 中寻找,然后在CMake的module目录中查找。
include_directories()
功能:向工程添加多个特定的 头文件搜索路径,相当于指定g++编译器的 -I 参数。
语法:include_directories([AFTER|BEFORE][SYSTEM] dir1 dir2 ...)。
include_directories(header-dir) 是一个全局包含,向下传递。也就是说,如果某个目录的 CMakeLists.txt 中使用了该指令,其下所有的子目录默认也包含了header-dir 目录。
# 包含所有子目录
aux_source_directory()
# 包含指定目录
include_directories()
# 将/usr/include/myincludefolder 和 ./include 添加到头文件搜索路径
include_directories(/usr/include/myincludefolder ./include)
install()
项目工程结构
.
├── CMakeLists.txt
├── config.h.in
├── License.txt
├── main.cc
└── math
├── CMakeLists.txt
├── MathFunctions.cc
└── MathFunctions.h
math 目录下的 CMakeLists.txt
# 查找当前目录下的所有源文件,并将名称保存到 DIR_LIB_SRCS 变量
aux_source_directory(. DIR_LIB_SRCS)
# 指定生成 MathFunctions 链接库
add_library (MathFunctions ${
DIR_LIB_SRCS})
# 指定 MathFunctions 库的安装路径
# 将静态库 MathFunctions 安装到 `/usr/local/bin` 目录下
install(TARGETS MathFunctions DESTINATION bin)
# 将头文件 MathFunctions.h 安装到 `/usr/local/include` 目录下
install(FILES MathFunctions.h DESTINATION include)
根目录的 CMakelists.txt
# 指定安装路径
# 将可执行程序 Demo 安装到了 `/usr/local/bin` 目录下
install(TARGETS Demo DESTINATION bin)
# 将 config.h 安装到 `/usr/local/include` 目录下
install(FILES "${PROJECT_BINARY_DIR}/config.h" DESTINATION include)
[root@root]$ sudo make install
[ 50%] Built target MathFunctions
[100%] Built target Demo
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/bin/Demo
-- Installing: /usr/local/include/config.h
-- Installing: /usr/local/bin/libMathFunctions.a
-- Up-to-date: /usr/local/include/MathFunctions.h
[ehome@xman Demo5]$ ls /usr/local/bin
Demo libMathFunctions.a
[ehome@xman Demo5]$ ls /usr/local/include
config.h MathFunctions.h
/usr/local/ 是默认安装的根目录,可以通过修改 CMAKE_INSTALL_PREFIX 变量的值来指定这些文件拷贝到哪个根目录。
LIST()
cmake命令之list
link_directories()(不推荐)
功能:指定要链接的库文件的搜索路径,相当于指定g++编译器的 -L 参数。
语法:link_directories(dir1 dir2 ...)。
link_directories(/home/lib)
target_link_libraries(
CmakeDemo
hello
world
)
# 将/usr/lib/mylibfolder 和 ./lib 添加到库文件搜索路径
link_directories(/usr/lib/mylibfolder ./lib)
注意:该指令有时候不一定需要。因为 find_package 和 find_library 指令可以得到库文件的绝对路径。然而,自己写的动态库文件放在自己新建的目录下时,可以用该指令指定该目录的路径,以便工程能够找到。
link_libraries()
功能:通过 add_executable() 和 add_library() 指令生成<target>目标文件,link_libraries 将库链接到<target>目标文件中。 语法:link_libraries([item1 [item2 [...]]] [[debug|optimized|general] <item>] ...)
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
include_directories("/opt/MATLAB/R2012a/extern/include")
#directly link to the libraries.
LINK_LIBRARIES("/opt/MATLAB/R2012a/bin/glnxa64/libeng.so")
LINK_LIBRARIES("/opt/MATLAB/R2012a/bin/glnxa64/libmx.so")
#equals to below
#LINK_LIBRARIES("/opt/MATLAB/R2012a/bin/glnxa64/libeng.so" "/opt/MATLAB/R2012a/bin/glnxa64/libmx.so")
add_executable(myProject main.cpp)
cmake_minimum_required(VERSION 3.10)
project(TestSharedLib)
# C++11 编译
set(CMAKE_CXX_STANDARD 11)
# 头文件路径
set(INC_DIR /home/yoyo/MyDocuments/C++Projects/MySharedLib)
# 库文件路径
set(LIB_DIR /home/yoyo/MyDocuments/C++Projects/MySharedLib/build)
include_directories(${INC_DIR})
link_directories(${LIB_DIR})
link_libraries(MySharedLib)
add_executable(TestSharedLib main.cpp)
# 链接 MySharedLib 库
target_link_libraries(TestSharedLib MySharedLib)
MESSAGE()
功能:向终端输出用户定义的信息。
用法:MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message")。
#产生错误,生成过程被跳过。
MESSAGE(SEND_ERROR "message")
#输出前缀为--d的信息。
MESSAGE(STATUS "message")
#立即终止所有的cmake过程
MESSAGE(FATAL_ERROR "message")
# 终端执行export
export ASCEND_AICPU_PATH=/usr/local/Ascend/ascend-toolkit/latest
# CMakeLists.txt文件打印
message(STATUS "ASCEND_AICPU_PATH=${ASCEND_AICPU_PATH}")
# 终端打印输出
-- ASCEND_AICPU_PATH=/usr/local/Ascend/ascend-toolkit/latest
option()
Options that can be configured through environment variables or manually.(option通过配置环境变量或者手动设置)
对于跨平台的项目,我们往往要进行交叉编译,针对不同环境的代码和功能可能有所不同,我们往往通过option确定编译选项,不同平台编译的代码用宏进行隔离,同时编译宏也可以决定某部分代码是否编译,是否包含某个功能,对一些还不稳定的特性进行隔离。
比如,在mindsporelilte中,通过设置MSLITE_ENABLE_SHARING_MEM_WITH_OPENGL来确定是否编译OpenGL相关代码:
option(MSLITE_ENABLE_SHARING_MEM_WITH_OPENGL "enable sharing memory with OpenGL" on)
if(DEFINED ENV{MSLITE_ENABLE_SHARING_MEM_WITH_OPENGL})
set(MSLITE_ENABLE_SHARING_MEM_WITH_OPENGL $ENV{MSLITE_ENABLE_SHARING_MEM_WITH_OPENGL})
endif()
if(MSLITE_ENABLE_SHARING_MEM_WITH_OPENGL)
add_definitions(-DENABLE_OPENGL_TEXTURE)
endif()
在相关cpp文件中用宏ENABLE_OPENGL_TEXTURE隔离相关代码:
#ifdef ENABLE_OPENGL_TEXTURE
if (!lite::opencl::LoadOpenGLLibrary(&gl_handle_)) {
MS_LOG(ERROR) << "Load OpenGL symbols failed!";
return RET_ERROR;
}
#endif
project()
功能:定义工程名称,并可指定工程支持的语言。
语法:project(工程名称 [CXX] [C] [java])。
# 指定工程名及版本号
project(HELLOWORLD VERSION 1.0)
set()
功能:显式的定义变量。
语法:set(变量名 [变量值] [CACHE TYPE DOCSTRING [FORCE]])。
# 定义SRC变量,其值为main.cpp hello.cpp
set(SRC sayhello.cpp hello.cpp)
# 指定C++标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# 设置生成可执行文件的路径
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
# 设置生成链接库的路径
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
SET_TARGET_PROPERTIES()
功能:同时构建 libhello.so 和 libhello.a 两个库。
# 动态库
SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_PUTPUT 1)
# 静态库
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
# 增加动态库的版本号
# VERSION指代动态库版本,SOVERSION指代API版本。
SET_TARGET_PROPERTIES(hello PROPERTIES VERION 1.2 SOVERSION 1)
target_include_directories()
功能:为编译目标文件 <target> 指定头文件。
语法:target_include_directories(<target> [SYSTEM] [AFTER|BEFORE] <INTERFACE|PUBLIC|PRIVATE> [items1...] [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])。
<target> 必须是通过 add_executable() 或 add_library() 创建,且不能是ALIAS目标
target_link_libraries()
功能:将<target>目标文件与库文件进行链接,相当于指定g++编译器 -l 参数。
target_link_libraries(<target> ... <item>... ...)
target_link_libraries(<target>
<PRIVATE|PUBLIC|INTERFACE> <item>...
[<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
参数解释
- <target>,是指通过 add_executable() 和 add_library() 指令生成已经创建的目标文件,并且不能是 ALIAS 目标。
- [item],表示库文件没有后缀的名字。
- PUBLIC,在public后面的库会被Link到target中,并且里面的符号也会被导出,提供给第三方使用。
- PRIVATE,在private后面的库仅被link到target中,并且终结掉,第三方不能感知你调了什么库。
- INTERFACE,在interface后面引入的库不会被链接到target中,只会导出符号。
target_link_libraries() 往往和 add_subdirectory() 一起使用,在编译好一个可执行文件或库时,如果它依赖其他库,可以使用 target_link_libraries() 链接其他库。target_link_libraries 会在目标程序中生成rpath 。示例如下:
# 生成动态库
add_library(mindsporelite SHARED $<TARGET_OBJECTS:lite_src_mid>)
# 生成静态库
add_library(mindsporelite-static STATIC $<TARGET_OBJECTS:lite_src_mid>)
# 生成可执行文件
add_executable(benchmark main.cc)
# 动态链接,将 mindsporelite动态库文件链接到 benchmark可执行文件
target_link_libraries(benchmark mindsporelite)
# 静态链接,将 mindsporelite-static静态库文件链接到 benchmark可执行文件
target_link_libraries(benchmark mindsporelite-static)
link_libraries与target_link_libraries 的区别
- link_libraries用在 add_executable 之前,target_link_libraries 用在 add_executable 之后。
- link_libraries用来链接静态库,target_link_libraries用来链接导入库,即按照 header file + .lib + .dll 方式隐式调用动态库的 .lib 库。
控制指令
IF指令
总体把握一个原则,凡是出现 IF 的地方一定要有对应的ENDIF,出现 ELSEIF 的地方,ENDIF 是可选的。
IF(expression)
# THEN section.
COMMAND1(ARGS ...)COMMAND2(ARGS ...)
...
ELSE(expression)
# ELSE section.
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
ENDIF(expression)
IF(var)#如果变量不是:空,0,N, NO, OFF, FALSE, NOTFOUND 或<var>_NOTFOUND 时,表达式为真。
IF(NOT var )#与上述条件相反。
IF(var1 AND var2)#当两个变量都为真是为真。
IF(var1 OR var2)#当两个变量其中一个为真时为真。
IF(COMMAND cmd)#当给定的 cmd 确实是命令并可以调用是为真。
IF(EXISTS dir)或者 IF(EXISTS file)#当目录名或者文件名存在时为真。
IF(file1 IS_NEWER_THAN file2)#当 file1 比 file2 新,或者 file1/file2 其中有一个不存在时为真,文件名请使用完整路径。
IF(IS_DIRECTORY dirname)#当 dirname 是目录时,为真。
IF(variable MATCHES regex)
IF(string MATCHES regex)#当给定的变量或者字符串能够匹配正则表达式 regex 时为真。比如:
IF("hello" MATCHES "ell")
MESSAGE("true")
ENDIF("hello" MATCHES "ell")
# 数字比较表达式
IF(variable LESS number)
IF(string LESS number)
IF(variable GREATER number)
IF(string GREATER number)
IF(variable EQUAL number)
IF(string EQUAL number)
# 按照字母序的排列进行比较
IF(variable STRLESS string)
IF(string STRLESS string)
IF(variable STRGREATER string)
IF(string STRGREATER string)
IF(variable STREQUAL string)
IF(string STREQUAL string)
IF(DEFINED variable)#如果变量被定义,为真。
# 一个小例子,用来判断平台差异:
IF(WIN32)
MESSAGE(STATUS “This is windows.”)
# 作一些 Windows 相关的操作
ELSE(WIN32)
MESSAGE(STATUS “This is not windows”)
# 作一些非 Windows 相关的操作
ENDIF(WIN32)
上述代码用来控制在不同的平台进行不同的控制,但是,阅读起来却并不是那么舒服, ELSE(WIN32)之类的语句很容易引起歧义。可使用 CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS 开关,避免歧义。
SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
IF(WIN32)
ELSE()
ENDIF()
# 如果配合 ELSEIF 使用,可能的写法是这样:
IF(WIN32)
# do something related to WIN32
ELSEIF(UNIX)
# do something related to UNIX
ELSEIF(APPLE)
# do something related to APPLE
ENDIF(WIN32)
WHILE指令
其真假判断条件可以参考 IF 指令。
WHILE(condition)
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
ENDWHILE(condition)
FOREACH指令
FOREACH 指令的使用方法有三种形式:
列表形式
FOREACH(loop_var arg1 arg2 ...)
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
ENDFOREACH(loop_var)
AUX_SOURCE_DIRECTORY(. SRC_LIST)
FOREACH(F ${SRC_LIST})
MESSAGE(${F})
ENDFOREACH(F)
范围形式
FOREACH(loop_var RANGE total)
ENDFOREACH(loop_var)
#从 0 到 total 以1为步进举例如下:
FOREACH(VAR RANGE 10)
MESSAGE(${VAR})
ENDFOREACH(VAR)
最终得到的输出是: 0 1 2 3 4 5 6 7 8 9 10
范围和步长
# 从 start 开始到 stop 结束,以 step 为步长
FOREACH(loop_var RANGE start stop [step])
ENDFOREACH(loop_var)
FOREACH(A RANGE 5 15 3)
MESSAGE(${A})
ENDFOREACH(A)
最终得到的结果是: 5 8 11 14
三、CMake预定义变量
CMake中常用的预定义变量
BUILD_SHARED_LIBS
默认的库编译方式(shared or static),默认为static,一般在ADD_LIBRARY时直接指定编译库的类型。
CMAKE_C_FLAGS
功能:gcc编译选项。
SET(CMAKE_C_FLAGS_PUBLIC "-mcpu=cortex-a7 -mfloat-abi=softfp -mfpu=neon-vfpv4 -ffunction-sections -mno-unaligned-access -fno-aggressive-loop-optimizations -mapcs-frame -rdynamic")
SET(CMAKE_C_FLAGS_DEBUG "-Wall -ggdb3 -DNM_DEBUG ${CMAKE_C_FLAGS_PUBLIC}")
SET(CMAKE_C_FLAGS_RELEASE "-Wall -O3 ${CMAKE_C_FLAGS_PUBLIC}")
CMAKE_CXX_FLAGS
功能:g++编译选项。
# 在CMAKE_CXX_FLAGS编译选项后追加-std=c++11
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
- CMAKE_CXX_FLAGS_DEBUG: 设置编译类型为Debug时的编译选项;
- CMAKE_CXX_FLAGS_RELEASE: 设置编译类型为Release时的编译选项;
CMAKE_CXX_COMPILER
设置C++编译器。
# 设置C++编译器为g++
set(CMAKE_CXX_COMPILER "g++")
# 设置标准库版本为c++17 并开启警告
set(CMAKE_CXX_FLAGS "-std=c++17 -Wall")
# 设置Debug模式下,不开启优化,开启调试,生成更详细的gdb调试信息
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -ggdb")
# 设置Release模式下,开启最高级优化
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
CMAKE_BUILD_TYPE
功能:编译类型(Debug, Release)。
# 设定编译类型为debug,因为在调试时需要选择debug
set(CMAKE_BUILD_TYPE Debug)
# 设定编译类型为release,因为在发布时需要选择release
set(CMAKE_BUILD_TYPE release)
CMAKE_CURRENT_SOURCE_DIR
当前CMakeLists.txt文件所在目录。
CMAKE_CURRENT_BINARY_DIR
编译目录,可使用ADD_SUBDIRECTORY来修改此变量。
# 添加cmake执行子目录
ADD_SUBDIRECTORY(example)
EXECUTABLE_OUTPUT_PATH
功能:可执行文件输出的存放路径。
# 设置可执行文件的输出路径为 build/bin
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
LIBRARY_OUTPUT_PATH
功能:库文件输出的存放路径。
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
PROJECT_NAME
功能:指定项目工程的名称。
project(Demo)
PROJECT_SOURCE_DIR
功能:项目工程的根目录,例如:/PATH/TO/CMakeDemo。
PROJECT_BINARY_DIR
功能:执行cmake命令的编译路径,一般是在build目录,例如:即/PATH/TO/CMakeDemo/build。
TOP_DIR
功能:项目工程的的根目录。
include(${TOP_DIR}/cmake/utils.cmake)
系统信息变量
root@root:~$ cmake --version
cmake version 3.11.2
- CMAKE_MAJOR_VERSION: cmake的主版本号cmake version 3.11.2中的3;
- CMAKE_MINOR_VERSION: cmake的次版本号cmake version 3.11.2中的11;
- CMAKE_PATCH_VERSION: cmake的补丁等级cmake version 3.11.2中的2;
- CAMKE_SYSTEM。系统名称比如 LInux-2.6.22;
- CAMKE_SYSTEM_NAME,不包含版本的系统名,比如 linux;
- CMAKE_SYSTEM_VERSION,系统版本,比如 2.6.22;
- CMAKE_SYSTEM_PROCESSOR,处理器的名称,比如 i686;