CMake基础教程
创始人
2024-05-11 21:27:29

CMake最大优势是跨平台,可以根据不同的平台生成Makefile文件,看下CMake的基础使用。

cmake(单目录单文件)

第一个最简单的cmake构建。

demo1.cpp代码:

#include using namespace std;int main(int argc, char *argv[]) {cout << "hello, cmake" << endl;return 0;
}

编写 CMakeLists.txt 文件

CMAKE_MINIMUM_REQUIRED(VERSION 3.10)PROJECT(demo1)# 生成可执行程序
ADD_EXECUTABLE(demo1 demo1.cpp)

在当前目录下,执行cmake:

lorien@ubuntu20:/work2/cmake/demo1$ cmake ./

会生成一些中间文件和Makefile文件。
在这里插入图片描述
执行make

lorien@ubuntu20:/work2/cmake/demo1$ make

第一个cmake构建就完成了。

cmake(单目录多文件)

目录结构:
在这里插入图片描述

main.cpp:

#include "hello_cmake.h"int main(int argc, char *argv[]) {print_hello();return 0;
}

hello_cmake.cpp:

#include using namespace std;int print_hello() {cout << "hello cmake" << endl;return 0;
}

hello_cmake.h:

int print_hello();

看下CMakeLists.txt的写法

CMAKE_MINIMUM_REQUIRED(VERSION 3.10)PROJECT(demo2)# 生成可执行程序
ADD_EXECUTABLE(demo2 main.cpp hello_cmake.cpp)

通过在ADD_EXECUTABLE后面追加源文件就可以实现但目录多文件cmake构建。

如果源文件太多,在后面一直追加很是麻烦,AUX_SOURCE_DIRECTORY可以解决这个问题。

AUX_SOURCE_DIRECTORY:发现一个目录下所有源代码文件并将列表存储在一个变量中

CMAKE_MINIMUM_REQUIRED(VERSION 3.10)PROJECT(demo2)AUX_SOURCE_DIRECTORY(./ DIR_HELLO_SRCS)ADD_EXECUTABLE(demo2 ${DIR_HELLO_SRCS})

cmake(多目录多文件)

文件结构如下:

在这里插入图片描述
源文件和上面一样,不再贴了。看一下子目录和根目录下的CMakeLists.txt

mylib目录下的CMakeLists.txt

AUX_SOURCE_DIRECTORY(./ DIR_LIB_SRCS)# 生成库文件
ADD_LIBRARY(mylib STATIC ${DIR_LIB_SRCS})

ADD_LIBRARY:表示生成库文件。STATIC表示静态库。这样mylib下的所有源代码会被编译成一个.a文件

根目录下的CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 3.10)PROJECT(demo3)# 向当前工程添加存放源文件的子目录
ADD_SUBDIRECTORY(./mylib)AUX_SOURCE_DIRECTORY(./ DIR_HELLO_SRCS)ADD_EXECUTABLE(demo3 ${DIR_HELLO_SRCS})# 为target链接共享库
TARGET_LINK_LIBRARIES(demo3 mylib)

解释下两个命令:

  • ADD_SUBDIRECTORY:向当前工程添加存放源文件的子目录
  • TARGET_LINK_LIBRARIES: 为target链接共享库,target是demo3。库是mylib,这个库由上面mylib目录下的源代码编译生成。

在根目录下执行:cmake ./

我们看到在mylib目录下生成了库文件libmylib.a,在根目录下生成了可执行文件:demo3
在这里插入图片描述

cmake工程标准结构

上面的例子,源文件和cmake构建的中间产物混在一起,导致源文件被污染。合理的目录结构如下:
在这里插入图片描述

  • mylib/:存放三方库文件
  • src/:项目源文件
  • build/:cmake构建中间产物

mylib/CMakeLists.txt

AUX_SOURCE_DIRECTORY(./ DIR_LIB_SRCS)# 指定库文件存储路径
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)# 生成库文件
ADD_LIBRARY(mylib STATIC ${DIR_LIB_SRCS})

LIBRARY_OUTPUT_PATH 用于指定库文件的生成路径。

PROJECT_BINARY_DIR表示工程二进制根目录,这个目录是执行cmake命令时所处的目录,比如我们会在build下面执行cmake目录,PROJECT_BINARY_DIR就是build/

src/CMakeLists.txt

# 包含头文件搜索目录
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/mylib)# 指定可执行程序存储路径
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)AUX_SOURCE_DIRECTORY(./ DIR_SRCS)# 生成可执行文件
ADD_EXECUTABLE(demo4 ${DIR_SRCS})TARGET_LINK_LIBRARIES(demo4 mylib)

INCLUDE_DIRECTORIES:向工程添加头文件搜索路径。添加这个命令后,我们在源文件中include头文件就不用再添加目录下。src/main.cpp

// 通过INCLUDE_DIRECTORIES添加了头文件搜索路径,可以直接include文件
#include "hello_cmake.h"int main(int argc, char *argv[]) {print_hello();return 0;
}

顶层目录下的CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 3.10)PROJECT(demo4)# 向当前工程添加存放源文件的子目录
ADD_SUBDIRECTORY(./mylib)# 向当前工程添加存放源文件的子目录
ADD_SUBDIRECTORY(./src)

我们cd进入build目录,执行命令

cmake ..

看下文件结构:
在这里插入图片描述
可以看到中间文件都在build目录下面,同时生成了bin/ 和 lib/目录。避免了我们源文件被污染。接下来在build目录执行make

在这里插入图片描述
最终,可执行文件demo4在bin目录下,库文件libmylib.a在lib目录下。

cmake自定义编译选项

cmake实现自定义编译选项用来控制程序逻辑。先看下demo目录结构

在这里插入图片描述

顶层目录的CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 3.10)PROJECT(demo5)# 向当前工程添加存放源文件的子目录
ADD_SUBDIRECTORY(./src)

src/CMakeLists.txt

configure_file("${PROJECT_SOURCE_DIR}/config/config.h.in""${PROJECT_SOURCE_DIR}/config/config.h"
)option(MY_LOG"use MY_LOG"ON)SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)AUX_SOURCE_DIRECTORY(./ DIR_SRCS)ADD_EXECUTABLE(demo5 ${DIR_SRCS})

重点是configure_file和option

  • configure_file:生成配置头文件config.h,这个头文件通过config.h.in生成。
  • option:配置宏打开或者关闭

config/config.h.in

#cmakedefine MY_LOG

src/main.cpp

#include 
#include "../config/config.h"using namespace std;int main(int argc, char *argv[]) {
#ifdef MY_LOGcout << "define MY_LOG" << endl;
#elsecout << "not define MY_LOG" << endl;
#endifreturn 0;
}

接着我们进入build目录,执行cmake

cmake ..

一切正常的话,我们会在config目录下,发现cmake自动生成了头文件config.h

#define MY_LOG

如果要关掉宏定义,在src/CMakeLists.txt里面设置option为OFF

option(MY_LOG"use MY_LOG"OFF)

相关内容

热门资讯

猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...