CMake入门教程

博主介绍:程序喵大人

简单跟大家介绍下CMake的基本使用,掌握这几个知识点你应该可以使用CMake成功构建一个小项目。

在学习CMake之前,我们首先要掌握如何使用命令行构建程序,比如下面这个程序:

cpp 复制代码
// test.cc
#include <iostream>
int main() {
    #ifdef HELLO_WORLD
    std::cout << HELLO_WORLD << "\n";
    #endif
    std::cout << "main \n";
}

这一个简单的源文件,如何使用clang构建?

可以这样:

bash 复制代码
clang++ test.cc -std=c++14 -DHELLO_WORLD=2

如果编译链接成功,会自动在当前目录生成名为a.out的可执行文件,运行时直接./a.out即可,也可以使用-o指定生成可执行文件的名字。

那上面的命令代表什么意思?

  • clang++不用多说。
  • test.cc表示源文件的名字。
  • -std=C++14表示使用的C++标准,上面我使用的是C++14,你也可以改为使用C++11或C++17或20等。
  • -D表示定义一个宏,-DHELLO_WORLD=2表示定义了一个HELLO_WORLD的宏,它的值是2。

那如果程序复杂点呢,比如这样:

在另一个单独的头文件func.h中声明func,同时在另一个源文件中定义它的实现,这种程序怎么编译?

bash 复制代码
clang++ test.cc func.cc -std=c++14 -DHELLO_WORLD=2

直接把func.cc加进去即可。

另外,大家平时编译过程中可能会遇到找不到头文件的编译失败问题,比如找不到func.h,那怎么解决?

应该在编译时指定源文件中引用的头文件所在的目录,比如func.h在目录funch中,那怎么指定目录?可以使用-I,这里是大写的I(i),示例如下:

bash 复制代码
clang++ test.cc func.cc -std=c++14 -I funch -DHELLO_WORLD=2

还有个情况,我们经常会引用一些第三方库,比如我在程序中引用了libxxx.a,它在xxxdir目录中,那怎么链接这个库,这里有两块需要指定,一个是指定链接库所在的目录(使用-L),一个是指定链接库的名字(使用-l,小写的L),可以这样使用:

bash 复制代码
clang++ test.cc func.cc -std=c++14 -I funch  -L xxxdir -lxxx -DHELLO_WORLD=2

还有个情况,比如我还想添加一些编译参数,那可以直接在命令行后面添加:

bash 复制代码
clang++ test.cc func.cc -std=c++14 -I funch -L xxxdir -lxxx -DHELLO_WORLD=2 -Werror -Wall -fpic

通过上面的命令行构建程序,你应该明白了以下几点:

  • 如何指定参与编译的源文件
  • 如何设置C++标准
  • 如何设置并添加编译参数
  • 如何定义宏
  • 如何指定头文件目录
  • 如何指定链接库目录
  • 如何指定要链接哪个库

掌握了上面几点后,再学习CMake就简单了,其实CMake到最后也是会变成命令行来执行。

使用CMake,都需要有个CMakeLists.txt文件,可以在这个文件里添加内容,比如要构建上面的程序,可以这样写CMakeLists.txt

第1行的cmake_minimum_required表示CMake要求的最低版本号,如果你的CMake用到了高版本特有的功能,需要指定版本号要求用户升级才可以使用。

第2行的project(xxx)表示项目的名字是xxx,项目编译链接生成的程序名字就会叫xxx

第3行的add_definitions可以用于定义某个宏。

也可以使用第8行和第9行的set(CMAKE_CXX_FLAGS),无脑在后面添加参数,就像命令行一样。

include_directories用于指定头文件目录,类似于命令行中的-I

link_directories用于指定链接库目录,类似于命令行中的-L

第14行和第15行的set用于定义变量,而解析变量则使用美元符。

第17行的add_executable用于定义构建可执行程序,指定源文件列表。

第18行的target_link_libraries用于指令链接哪些库,类似于命令行中的-l

前面说过CMake到最后也会变成命令行去执行,想要看到详细信息可以打开对应的VERBOSE,就是第4行。那现在执行一下,一般使用CMake都会新建一个build目录,用做工作目录,因为会生成很多中间文件,那我们执行一下:

bash 复制代码
mkdir build
cd build
cmake ../
make

为什么有cmake ../然后make,因为make命令是通过Makefile来构建的,它只识别Makefile。而cmake ..就是识别上一级目录中的CMakeLists.txt然后在当前build目录中生成了一个Makefile,供make识别:

这是cmake后的产物:

然后再执行下make:

因为我打开了VERBOSE,所以这里可以看到详细的命令信息,你也完全可以复制上面的命令来执行,也可以生成可执行程序的。

关于cmake,就简单介绍到这里,有问题欢迎留言讨论哈。

码字不易,欢迎大家点赞,关注,评论,谢谢!

相关推荐
肆忆_16 小时前
# 用 5 个问题学懂 C++ 虚函数(入门级)
c++
不想写代码的星星20 小时前
虚函数表:C++ 多态背后的那个男人
c++
端平入洛3 天前
delete又未完全delete
c++
端平入洛4 天前
auto有时不auto
c++
郑州光合科技余经理4 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
feifeigo1234 天前
matlab画图工具
开发语言·matlab
dustcell.4 天前
haproxy七层代理
java·开发语言·前端
norlan_jame4 天前
C-PHY与D-PHY差异
c语言·开发语言
哇哈哈20215 天前
信号量和信号
linux·c++
多恩Stone5 天前
【C++入门扫盲1】C++ 与 Python:类型、编译器/解释器与 CPU 的关系
开发语言·c++·人工智能·python·算法·3d·aigc