前言:
作为一个使用C++做客户端开发的半个开发人员,自然是然不开cmake的。初识cmake还是在githup上寻找轮子的时候。大多数轮子里都会包含一个叫做CMakeLists.txt的文件,这时就需要cmake来生成编译文件了,每次都得花上很多时间在配置cmake上,现在回想那段日子,简直就是噩梦。也怪自己当初不爱文档,只爱百度。
然是这样一个东西,现在却觉得是一个十分方便的工具,遂分享一下使用心得。
CMake:
CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。只是 CMake 的组态档取名为 CMakeLists.txt。Cmake 并不直接建构出最终的软件,而是产生标准的建构档(如 Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然后再依一般的建构方式使用。这使得熟悉某个集成开发环境(IDE)的开发者可以用标准的方式建构他的软件,这种可以使用各平台的原生建构系统的能力是 CMake 和 SCons 等其他类似系统的区别之处。(抄自百度百科)
安装工具
工具下载地址:https://cmake.org/download/
选择自己需要的版本即可,然后如果window平台,那么安装的时候记得勾选创建cmake的环境变量,否则会有一丢丢问题。
第一个cmake的工程
这里主要是对官方教程的搬运,有兴趣的可以直接阅读官网的教程。
首先在源代码所在目录新建一个CMakeLists.txt文件,然后写入最简单的cmake代码
#设置cmake的最低版本 cmake_minimum_required(VERSION 3.10) # 设置工程的名称 project(hello_camke) # 将源代码添加到工程 add_executable(hello_camke main.cpp)
接着打开我们之前以安装好的cmake软件。等一下,似乎忘了什么,我们在cmake的代码中往工程里添加了一个main.cpp的文件,所以我们还得再新建一个main.cpp才行,否则cmake生成工程的时候是会报错的哦。
接着打开cmake
这里需要输入两个路径,source code是源代码路径,build the binaries生成之后的工程所在路径(这两个路径最好不要设置为同一个路径)。
然后点击configuer按钮,等待配置完成,最后点击generate,等待生成完成。到这里cmake的任务就基本完成了。
这时候就可以看到工程,目录下生成了这些文件
这个时候就可以掏出你的IDE了,当这里我选择的编译环境是msvc,所以也就只能祭出宇宙第一IDE了。
打开之后可以看到三个子工程,只需要关心hello_cmake就可以了,其他都不用管。
在main.cpp中添加代码
#include <iostream> int main() { std::cout << "hello cmake!" << std::endl; std::cin.get(); return 0; }
运行
完美!
- 这里我忽略了选择编译环境的步骤,一般会在点击configuer按钮之后弹出来,根据需求选择编译环境即可,前提是你电脑上安装了。
- cmakelists中的代码,是不区分大小写的。
再写一点点
有时候需要在软件中记录软件的版本号,但是直接定义在代码里,每次更新去代码里改又显得很low,且看怎么用cmake做得更优雅。
首先在我们需要将工程目录设置为编译时得包含目录
target_include_directories(hello_camke PUBLIC "${PROJECT_BINARY_DIR}")
新建一个myConfig.h的文件,在文件中定义一个宏。
#define VERSION @MyVersion@
这里可能有人会说,哎呀、哎呀、你这还不是把版本号写到代码里去了(就是就是)。
在cmakelist中新建一个名为 MyVersion的变量用于,然后使用configure_file函数将MyConfig.h文件中的内容复制到工程目录的新建文件。这里为了区分两个文件,新的文件名为Config.h
set(MyVersion 1.02) configure_file(myConfig.h Config.h)
最后修改main.cpp中的代码
#include "Config.h" #include <iostream> int main() { std::cout << "hello cmake!" << std::endl; std::cout << "VERSION : " << VERSION << std::endl; std::cin.get(); return 0; }
运行
VERSION : 1.02
emmmm 这样是不是就优雅多了呢 ?(好像并没有诶。。。)
这里主要使用了configure_file这个函数,这个函数的特性就是将一个文件的内容复制到另一个文件中,并且按照一定的规则将cmakelist中的变量值替换到复制的目标文件中。这里我使用了默认的替换规则,在文件中以 @变量名@ 这样的格式都会被替换为该变量在cmakelist中对应的值。
文中有提到工程目录是指build目录 源代码目录指源文件所在目录。
文章评论