CMake简介语法和外部构建

CMake简介

CMake就是一个高级的跨平台的编译配置工具,专门用于处理大型的C/C++项目,最常用的额就是使用CMake输出Makefile文件或者Project文件,分别对应Linux上编译和VS上的编译。

CMake安装

1.Centos中CMake安装

在Centos上可以直接使用yum安装,但安装的CMake版本比较老旧,现在介绍使用源码安装,但是需要先安装OpenSSL依赖项,这里以cmake-3.19.8为例说明源码安装的过程。
源码下载地址:https://cmake.org/download/,可以自行下载最新版本

#先安装openssl,需要安装nasm,否则编译出错
#直接使用yum安装
#yun install openssl
#安装cmake-3.19.8
$ tar zxf cmake-3.19.8.tar.gz
$ cd cmake-3.19.8
$ ./configure --prefix=$HOME/.local #制定安装目录
$ make -j4
$ make install

说明:

  • --prefix 用于制定安装目录,默认安装到/usr/local 目录中,安装时需要root权限。
  • make -j4 用于制定多线程编译,默认单线程编译比较耗时。

2.Ubuntu中CMake安装

$ sudo apt-get install update
$ sudo apt-get install cmake

CMake使用步骤

一般CMake的使用步骤:

  • 编写源码
  • 编写CMakeLists.txt
  • 使用cmake命令生成Makefile文件
  • 使用make命令编译
  • 运行生成的可执行文件

CMake的所有的语句都写在CMakeLists.txt文件中,且必须要是这个文件名,CMake命令会根据CMakeLists.txt中的语法构建编译规则,生成Makefile文件。可以在CMakeLists.txt中包含其他cmake文件,被包含的文件名可以自定义,一般以.cmake结尾。

CMake语法介绍

介绍一些常用的CMake语法,主要用于编译可执行程序,有关库文件的语法会在后面章节介绍。

- project关键字

可以用来指定工程名和支持的语言,默认支持所有语言,如:

# 指定工程名称,并支持所有语言(建议使用)
project(hello)
# 指定工程名,并支持C++语言
project(hello CXX)
# 指定工程名字,并支持C/C++语言
project(hello C CXX)

该定义指定了两个cmake变量

  • <projectname_BINARY_DIR> 表示生成的二进制文件的目录;
  • <projectname_SOURCE_DIR> 表示源代码目录。

可以使用message关键字输出这两个变量:

message(STATUS "binary dir ${hello_BINARY_DIR}")
message(STATUS  "source dir ${hello_SOURCE_DIR}")

一般都会是当前编译目录,但这两个变量在外部编译时会有区别,后面会介绍外部编译。但这样会有一个问题:如果改了工程名,这两个变量也会被改变。

解决方案:可以使用两个预定义的变量 PROJECT_BINARY_DIR PROJECT_SOURCE_DIR来代替上面的两个变量,这两个变量就代表当前工程的二进制目录和源码目录。

· cmake_minimum_required关键字

定义CMake最低支持的版本,低于此版本则会出错,如最低支持3.5以上版本

cmake_minimum_required(VERSION 3.5)

· set关键字

用于显示指定变量,类似于变量赋值。如 set(src_list main.cc) 表示src_list变量包含了main.cc文件。多个文件使用空格分开,如

set(src_list main.cc)
set(src_list main.cc util.cc test.cc)

还可以设置其他信息,如C++支持的版本

set(CMAKE_CXX_STANDARD 11)  # C++11
set(CMAKE_CXX_STANDARD 14)  # C++14

· message关键字

向终端用户输出自定义信息,主要包含3中信息

  1. SEND_ERROR 生产错误,生成过程被跳过;
  2. STATUS 输出前缀为 - 的信息
  3. FATAL_ERROR 立即终止所有cmake过程。

message(STATUS “binary dir ${hello_BINARY_DIR}”)
message(STATUS “source dir ${hello_SOURCE_DIR}”)
#输出内容,会有 – 前缀
– binary dir /home/cheng/tmp/cmake_test
– source dir /home/.cheng/tmp/cmake_test

· aux_source_directory关键字

查找目录中的所有源文件,并赋值给指定变量,如

# 查找当前目录下的所有源文件,将名称保存到src_list变量中,可以使用${src_list} 进行引用
aux_source_directory(. src_list)

这样便可以不用逐个添加源文件了。

· include 关键字

包含其他的cmake文件,被包含的文件一般以cmake结尾,如

include(../cmake/common.cmake)

· add_definitions关键字

添加定义信息,类似于gcc/g++中的CFLAGS和宏定义,如

add_definitions(-g -Wall -O3)

# -D开表示宏定义
if(MSVC)
	add_definitions(_D_WIN32_WINNT=0x600)
endif()

· include_directories关键字

添加头文件目录,相当于gcc/g++命令中的 -I 参数的功能,如

# 类似gcc/g++中的-I选项
include_directories(../include)

也可以添加一个 CPLUS_INCLUDE_PATH 环境变量,并将目录追加到环境变量中,但CMake一般不这样用。

· link_directories关键字

添加库文件目录,相当于gcc/g++ 命令的 -L 参数的功能,如

# 类似gcc/g++ 中的-L选项
link_directories(../lib ../lib64)

也可以添加一个 LD_LIBRARY_PATH 环境变量,并将目录追加到环境变量中。Linux中一般出现找不到库文件的问题,就会追加路径到此环境变量中。

· target_link_libraries 关键字

链接库文件到程序中,相当于gcc/g++ 命令的 -l 参数的功能,如

# 类似gcc/g++ 中的 -l 选项
target_link_libraries(hello mylib)

一般都是与add_executable 配合使用,紧跟其后。

· add_executable 关键字

指定生成的可执行文件,如

set(src_list, main.cc)
add_executable(hello ${src_list})
# 生成可执行文件hello,源文件读取变量 src_list 里的内容,也就是 main.cc,也可以直接写成 add_executable(hello main.cc)
# 若要链接libmylib.so,可以添加
target_link_libraries(hello mylib)

注意:

  • 工程名hello和生成的可执行文件 hello 没有任何关系,可以相同,也可以不相同。
  • 这里只介绍了生成可执行程序用到的语法,生成和链接库文件的语法会在后面进行介绍。

CMake 语法的基本原则

  • 变量使用 ${} 方式取值,但是在 if 控制语句中是直接使用变量名;
  • 指令参数使用括号,参数之间使用空格或者分号分开,如 add_executable(hello main.cc util.cc)
  • 指令是大小写无关的,即 add_executableADD_EXECUTABLE 是一样的,但 参数和变量是大小写相关的。goole规范中全部使用小写指令和变量,可视项目情况而定,与项目保持一致就行。

语法注意事项

  • set(src_list main.cc) 可以写成 set(src_list "main.cc") ,这两种写法是一样的,但如果文件名中有空格。中文或者其他特殊字符,则必须要加双引号;
  • add_executable(hello main.cc) 后缀名可以不写,CMake会自动去找.c 和 .cpp 的源文件,但最好明确指定源文件的后缀名。

CMake 外部构建

CMake内部构建,就是在当前工程目录中进行编译,但缺点是会产生很多的临时编译文件,容易污染工程,不方便清理。而外部构建就是编译生成的文件统一放在一个目录中,不会对源代码工程有任何影响,清理也只需要删除这个编译目录。所以强烈推荐使用外部构建,外部构建的一般步骤如下:

# 1.创建并进入编译目录
#  在项目根目录中新建一个 build/release/debug 目录,cmake生成的中间文件都会放在此目录
$ mkdir build
$ cd build/

# 2. 进行cmake编译
$ cmake ..
$ cmake --build .

# 3.编译完成后安装
$ cmake --install .

# 4.更简单的是直接在cmake ..之后执行make,这与 2,3等效
$ cmake ..
$ make && make install

外部构建时有两个变量需要注意:

  • PROJECT_BINARY_DIR 编译路径,也就是当前build目录;
  • PROJECT_SOURCE_DIR 还是工程中的源码目录。
    它们在内部构建的工程中是一样,但在外部构建的工程中就不一样了。

常用 cmake 编译选项

# 指定安装路径,这是最常用的选项,类似 ./configure --prefix
-DCMAKE_INSTALL_PREFIX=$HOME/.local

# 指定第三方库的路径,一般供find_package|find_library|find_program 等命令搜索,
# 若第三方库安装在非标准目录中,则需要用此参数指定路径,也可以是一个分号分隔的路径列表,
# cmake 会在指定的路径中查找第三方库的cmake文件,一般放在lib|lib64中的cmake目录中
-DCMAKE_PREFIX_PATH=$HOME/.local/grpc
-DCMAKE_PREFIX_PATH="/tmp;/tmp/grpc"
# 指定编译类型, Debug | Release,默认编译为Release版本
-DCMAKE_BUILD_TYPE=Debug|Release

# 编译程序,等同于make命令
--build <dir>

# 安装程序, 等同于make install 命令
--install <dir>

# 指定编译平台,可以使用 cmake --help 查看本机支持的编译平台,一般在Windows上需要指定
-G "Visual Studio 14 2015 Win64|MinGW Makefiles|..."

以上已-D开头的选项也可以在CMakeLists.txt 文件中使用set或list命令添加,如下:

set(CMAKE_PREFIX_PATH "<YOUR_ADDITIONAL_SEARCH_PATH>")
list(APPEND CMAKE_PREFIX_PATH "<YOUR_ADDITIONAL_SEARCH_PATH>")

一般使用set命令就行,如下实例:

set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_PREFIX_PATH "/opt/local/grpc")
set(CMAKE_PREFIX_PATH "/opt/local/libevent")  #多个搜索路径可以写多条
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值