自动化Makefile工具——CMake项目构建

平时,单个文件直接使用gcc即可完成编译操作《编译和链接!编译器做了什么?》。对于大项目就需要编写Makefile文件了,并由make工具来完成编译。徒手编写小型Makefile文件尚可,一旦复杂,就力所不及了。本文展示了,一个由多个目录,多个源文件构成的项目名为cmkCMakeLists.txt的编写格式。后续可以直接follow该文件。 如果,你只是单个文件,那么gcc足以

$ sudo apt install gcc

如果,你是小型项目,那么你可能需要make工具

$ sudo apt install make

如果,你是大项目,不能徒手完成Makefile的编写,那么自动化生成工具cmake,你值得拥有

$ sudo apt install cmake

实战吧————项目结构

如你所见,项目cmk包含了一个子目录sub,存在main.chead.c以及shead.c需要编译链接。

.
└── cmk
├── CMakeLists.txt
├── head.c
├── head.h
├── main.c
└── sub
├── CMakeLists.txt
├── shead.c
└── shead.h

cmk/sub/CMakeLists.txt

由于存在sub子目录,所以需要先将它的源文件编译称为一个静态链接库。其中, - aux_source_directoryCMake的一个指令,指将当前目录(.表示当前目录)下的所有源文件名称保存到变量DIR_LIB_SRCS中(这个变量名可以随便取)。 - add_library 该命令将$DIR_LIB_SRCS混编为静态链接库——这里命名为sub.lib

cmk/sub/CMakeLists.txt

aux_source_directory(. DIR_LIB_SRCS)
add_library (sub.lib ${DIR_LIB_SRCS})

cmk/CMakeLists.txt

主目录下的CMakeLists.txt可能要复杂一些,需要指明最低版本号,并且汇总并链接所有lib库。其中, - cmake_minimum_required 指明最低版本号。 - project 项目名,注意一个项目可能会存在好些个子项目。(比如Visual Studio,他会生成几个.sln文件。) - add_subdirectory 指定当前目录结构。 - add_executable 最终生成的目标。 - target_link_libraries 添加链接库。

cmk/CMakeLists.txt

cmake_minimum_required (VERSION 2.8)
project (cmk)
aux_source_directory (. DIR_SRCS)
add_subdirectory (sub)
add_executable (demo ${DIR_SRCS})
target_link_libraries (demo sub.lib)

cmake. & make

在上述CMakeLists.txt文件都编写完成之后,剩下的就是cmake .make了。 - cmake . 会生成Makefile文件,所有的工作,就是为了生成它。 - make 执行make命令,完成整个项目的编译,最终得到可执行文件。

$ cd cmk/
$ cmake .
-- Configuring done
-- Generating done
-- Build files have been written to: /home/vm1/Works/cmk

$ make
Scanning dependencies of target sub.lib
[ 20%] Building C object sub/CMakeFiles/sub.lib.dir/shead.c.o
[ 40%] Linking C static library libsub.lib.a
[ 40%] Built target sub.lib
Scanning dependencies of target demo
[ 60%] Linking C executable demo
[100%] Built target demo

$ ./demo

References: [1] http://www.hahack.com/codes/cmake/ [2] https://cmake.org/cmake/help/v3.12/manual/cmake-buildsystem.7.html