CMake is a meta build system that uses scripts called CMakeLists to generate build files for a specific environment (for example, makefiles on Unix machines).
CMake是一个元构建系统,通过名为CMakeLists.txt的脚本,来生成一个本地环境的的 Makefile构建文件。说白了,cmake是用来帮助我们生成Makefile的,不用自己费劲的去写了。
本人一直觉得Makefiles太难学,不好操作,构建复杂系统也不知如何入手。现在不用学了,CMake的出现解决了这个问题,让大家更方便的完成项目构建,自动化完成Makefile,而我们只需要了解CMakeLists.txt怎么写就好,书写起来会更方便,因为cmake的功能更为强大方便,提供了很多方便开发人员的功能。
所以感谢别人造好的轮子吧。
CMake是开源的,跨平台的,强大的,主流的自动化配置工具,在Ubuntu上安装很简单:
$ sudo apt-get install cmake
$ cmake --version
安装完成,我们的目的就是要开始build软件项目了。首先我们要知道我们要build的东西,也就是target是什么。
Target is an executable or a library to be built using a CMake script. You can define multiple build targets in a single script.
目标文件是一个可执行文件或库文件,使用CMake脚本来构建。在一个脚本文件中,可以定义多个目标文件。
下面使用一个简单的例子来体验一下。
1,先编写一个简单的main.c文件。比如打印“hello world”。
2,再创建一个CMakeLists.txt, 输入如下内容:
cmake_minimum_required(VERSION 3.13) # check the compatible for cmake. you may use your cmake version instead, "cmake --version"
project(cmake_test) # set the varabile of PROJECT_NAME
add_executable(cmake_test main.c) # generate the app "cmake_test" from "main.c"
3,两个文件都放在同一个目录,并cd为当前目录,然后执行cmake。
$cmake .
4,会在当前目录生成Makefile。这时再直行make。
$make
5,在当前目录下生成cmake_test的可执行文件,直行后打印输出“hello world”。
$ ./cmake_test
Hello world!
在CMakeLists.txt里,我们指定了要编译的程序名和源文件,然后Makefile就自动生成,可以make。
是不是比直接写Makefile方便多了。
如果修改了CMakeLists.txt,就要重新执行上面的操作。
cmake命令执行时,如果CMakeLists.txt里有问题,会有提示信息,根据提示信息进行修改。
===================================================================
下面我们要修改toolchain,上面例子是使用系统默认的toolchain,是Ubuntu里的gcc,现在我们要使用给iMX6芯片编一个cross platform的ARM Linux程序。
cmake_minimum_required(VERSION 3.13) # check the compatible for cmake. you may use your cmake version instead, "cmake --version"
project(cmake_test C CXX) # set the varabile of PROJECT_NAME
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(tools /home/ubuntu/Downloads/gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf)
set(CMAKE_C_COMPILER ${tools}/bin/arm-none-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${tools}/bin/arm-none-linux-gnueabihf-g++)
add_executable(cmake_test main.c) # generate the app "cmake_test" from "main.c"
然后再执行一遍cmake和make命令,就会生成ARM Linux平台的cmake_test程序。
$ file cmake_test
cmake_test: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, with debug_info, not stripped
上面CMakeListx.txt脚本,执行的是一行行的命令,形式是: command_name( argument ...)
括号里是一个或多个参数。比如:project命令。这里除了指定项目名,还加上了支持的语言类型。cmake默认支持类型就是C和CXX。
注释的形式,就是 “#” 后面的内容是注释,不可跨行,是单行注释。
set( ) 命令是给某个变量赋值,这里是给tools设置了toolchain的路径,后面使用${tools}来方便使用。
而CMake里由一些内置的变量,比如CMAKE_开头的就是,这里的CMAKE_C_COMPILER就是指定了C编译器的路径。
===================================================================
如果在编译时要引用某个路径的头文件,使用include_directories命令。
cmake_minimum_required(VERSION 3.13) # check the compatible for cmake. you may use your cmake version instead, "cmake --version"
project(cmake_test C CXX) # set the varabile of PROJECT_NAME
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(tools /home/ubuntu/Downloads/gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf)
set(CMAKE_C_COMPILER ${tools}/bin/arm-none-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${tools}/bin/arm-none-linux-gnueabihf-g++)
add_executable(cmake_test main.c) # generate the app "cmake_test" from "main.c"
include_directories(./include
./platform)
在当前文件夹下创建2个文件夹,并分别添加空的头文件在里面,然后在main.c里面包含,最后编译。
$ mkdir include; mkdir platform
$ touch include/include.h
$ touch platform/platform.h
main.c里面添加:
#include "include.h"
#include "platform.h"
然后编译:
$ cmake .
$ make
如果有多个C文件一起编译,直接添加:
cmake_minimum_required(VERSION 3.13) # check the compatible for cmake. you may use your cmake version instead, "cmake --version"
project(cmake_test C CXX) # set the varabile of PROJECT_NAME
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(tools /home/ubuntu/Downloads/gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf)
set(CMAKE_C_COMPILER ${tools}/bin/arm-none-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${tools}/bin/arm-none-linux-gnueabihf-g++)
add_executable(cmake_test
main.c
src/func.c)
include_directories(./include
./platform)
可以添加func.c文件,再编译:
$ mkdir src
创建个空的func.c文件即可。
$ touch src/func.c
$ cmake .
$ make
关于cmake详细的和高级的使用方法,要参看相关资料。
但cmake的功能太多,细节也多,初学者还是有点抓不住头绪,学习曲线个人感觉还是有点陡峭。
正常来讲,应该是官方文档是最好的参考资料,但文档一看好多内容,就很头大,理解起来费劲了。
官方文档参考:
https://cmake.org/cmake/help/latest/index.html
遇见什么不懂就查哪里把,官方文档查一下,网上搜一下,积少成多,逐个击破。