CMake入门实践之语法(1)

前言

1. 每一个需要 cmake 操作的目录下面,都必须存在文件 CMakeLists.txt;

2. cmake 指令不区分大小写;本文为醒目,将 cmake 指令全部大写处理。

3. 变量使用 ${} 方式取值,但是在 IF 控制语句中是直接使用变量名;

4. 指令(参数1 参数2 ...),参数使用括弧括起来,参数之间使用空格或分号分开;

CMake中常用预定义变量

1. CMake 的预定义变量

PROJECT_SOURCE_DIR 工程根目录
PROJECT_BINARY_DIR 运行cmake命令的目录。建议定义为${PROJECT_SOURCE_DIR}/build下,具体因为外部编译
CMAKE_INCLUDE_PATH 环境变量,非cmake变量
CMAKE_LIBRARY_PATH 环境变量
CMAKE_CURRENT_SOURCE_DIR 当前处理的CMakeLists.txt文件所在路径
CMAKE_CURRENT_BINARY_DIR

target编译目录

--使用ADD_SURDIRECTORY指令可以更改该变量的值

--SET(EXECUTABLE_OUTPUT_PATH < dir >) 指令不会对该变量有影响,但改变了最终目标文件的存储路径;

CMAKE_CURRENT_LIST_FILE 输出调用该变量的CMakeLists.txt的完整路径
CMAKE_CURRENT_LIST_LINE 输出该变量所在的行
CMAKE_MODULE_PATH 定义自己的cmake模块所在路径
EXECUTABLE_OUTPUT_PATH 重新定义目标二进制可执行文件的存放位置
LIBRARY_OUTPUT_PATH 重新定义目标链接库文件的存放位置
PROJECT_NAME 返回由PROJECT指令定义的项目名称
CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS

用来控制IF…ELSE…语句的书写方式

2. 系统信息预定义变量

-- CMAKE_MAJOR_VERSION cmake主版本号,如2.8.6中的2
-- CMAKE_MINOR_VERSION cmake次版本号,如2.8.6中的8
-- CMAKE_PATCH_VERSION cmake补丁等级,如2.8.6中的6
-- CMAKE_SYSTEM 系统名称,例如Linux-2.6.22
-- CMAKE_SYSTEM_NAME 不包含版本的系统名,如Linux
-- CMAKE_SYSTEM_VERSION 系统版本,如2.6.22
-- CMAKE_SYSTEM_PROCESSOR 处理器名称,如i686
-- UNIX 在所有的类UNIX平台为TRUE,包括OS X和cygwin
-- WIN32 在所有的win32平台为TRUE,包括cygwin

3. 开关选项

BUILD_SHARED_LIBS

控制默认的库编译方式

--如果未进行设置,使用 ADD_LIBRARY时又没有指定库类型,默认编译生成的库都是静态库

CMAKE_C_FLAGS 设置 C 编译选项
CMAKE_CXX_FLAGS 设置 C++ 编译选项

CMake 常用语法

1. PROJECT_MINIMUM_REQUIRED

该语句一般都放置在 CMakeLists.txt 的开头,用于说明 CMake最低版本要求。

cmake_minimum_required(VERSION 2.6)

2. PROJECT

该命令一般置于CMakeLists.txt 的开头,定义了工程的名称。但项目最终编译生成的可执行文件并不是这个项目名称,而是由另一条命令(ADD_EXECUTABLE)确定的。

project(CRNode)

执行上一条指令,即定义了一个项目名称 CRNode,相应的会生成两个变量: CRNode_BINARY_DIR,CRNode_SOURCE_DIR。

camke 中预定了两个变量: PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR。在这个例子中 

PROJECT_BINARY_DIR = CRNode_BINARY_DIR       PROJECT_SOURCE_DIR = CRNode_BINARY_DIR 

实际操作中,强烈推荐直接使用 PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR,这样即使项目名称发生了变化,也不会影响 CMakeLists.txt 文件。

关于上面两个变量是否相同的问题,涉及到编译的方式是内部编译还是外部编译。如果是内部编译,则两个变量相同,如果是外部编译,则两个变量不同。

内部编译和外部编译: 假设已完成项目 CMakeLists.txt 的编写,在CMakeLists.txt 所在的目录下,有两种执行 cmake 的方法:

# 方法一 内部构建
cmake ./
make 
# 方法2   外部构建
mkdir build 
cd ./build
cmake ../
make

上述两种方法中,最大的不同在于 cmake 与 make 的工作路径不同。内部构建时,cmake 生成的中间文件和可执行文件都会放在项目目录中;外部构建方法中,中间文件与可执行文件都存放在 build 目录中。

建议使用外部构建方法,有点显而易见:最大限度的保持了代码目录的整洁,生成、编译和安装时不同于项目目录的其他目录中。在外部构建方法下,PROJECT_SOURCE_DIR 指向目录和内部构建相同,为CMakeLists.txt 所在根目录;而 PROJECT_BINARY_DIR 不同,它指向 CMakeLists.txt 所在根目录的 build 目录。

3. SET

格式:

SET(VAR [VALUE] [CACHE TYPEDOCSTRING [FORCE]])

示例:

SET(CMAKE_INSTALL_PREFIX /usr/local)

该示例中,我们显示的将 CMAKE_INSTALL_PREFIX的值定义为 /usr/local, 如此在外部构建情况下执行 make install 命令时,make 会将生成的可执行文件拷贝到  /usr/local/bin 目录下。

当然,可执行文件的安装路径 CMAKE_INSTALL_PREFIX 也可以在 执行 cmake 命令的时候指定, cmake 参数如下:

cmake -DCAMKE_INSTALL_PREFIX = /usr ..

# 如果cmake 参数和 CMakeLists.txt 文件中都不指定该值的话,则该值默认为 /usr/local.

4. ADD_SUBDIRECTORY

格式:

ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL]) 

# sourece_dir : 源文件路径
# [binary_dir] : 中间二进制与目录二进制存放路径
# [EXCLUDE_FROM_ALL] :将这个目录从编译过程中排除

这个指令用于向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置。EXCLUDE_FROM_ALL 参数的含义是将这个目录从编译过程中排除,比如,工程有时候存在 example,可能就需要构建完成后,在进入 example 目录单独进行构建。

5. INCLUDE_DIRECTORIES

格式:

INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)

# [AFTER|BEFORE]: 追加标志,指定控制追加或置前
# [SYSTEM]:笔者不知道干什么的
# dir1, ..., dir n :添加的一系列头文件搜索路径

向工程添加多个特定的头文件搜索路径,路径之间用空格分隔。类似 gcc 中的编译参数 -l ,即指定编译过程中编译器搜索头文件的路径。当项目需要的头文件不在系统默认的搜索路径时,则指定该路径。 AFTER/BEFORE 参数,控制追加或置前。默认情况下,追加当前头文件搜索路径的后面。注:如果路径包含空格,可以使用双引号将它括起来。

6. ADD_EXECUTABLE

格式:

ADD_EXECUTABLE(exename srcname)

# exename: 可执行文件名
# srcname: 生成该可执行文件的源文件

# 该命令给出源文件名称,并指出需要编译出的可执行文件名。

示例1:

ADD_EXECUTABLE(hello ${SRC_LIST})

#SRC_LIST变量中的源文件,需要编译出名为 hello 的可执行文件

示例2:

SET(SRC_LIST main.cc
        rpc/CRNode.cpp 
        rpc/Schd_types.cpp 
        task/TaskExecutor.cpp
        task/TaskMoniter.cpp
        util/Const.cpp 
        util/Globals.cc
        )

ADD_EXECUTABLE(CRNode ${SRC_LIST})

7. ADD_LIBRARY

格式:

ADD_LIBRARY(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN)

# libname: 库名称文件
# [SHARED|STATIC|MODULE]: 生成库文件类型(共享库/静态库)
# [EXCLUDE_FROM_ALL]: 表示该库不会被默认构建
# source1, ... , source N : 生成库所依赖的源文件

示例:

ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})

参考链接:https://blog.csdn.net/ajianyingxiaoqinghan/article/details/70230902 

猜你喜欢

转载自blog.csdn.net/JACK_YOUNG007/article/details/88869646