CMake基础教程

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

cmake(单目录单文件)

第一个最简单的cmake构建。

demo1.cpp代码:

#include <iostream>

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 <iostream>

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 <iostream>
#include "../config/config.h"

using namespace std;

int main(int argc, char *argv[]) {
#ifdef MY_LOG
    cout << "define MY_LOG" << endl;
#else
    cout << "not define MY_LOG" << endl;
#endif
    return 0;
}

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

cmake ..

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

#define MY_LOG

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

option(MY_LOG
    "use MY_LOG"
    OFF)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值