cmake起步
创建工程
从一个简单的"HelloWorld"开始。首先创建一个目录cmake,在cmake目录下新建一个hello.c文件。文件内容如下所示:
#include <stdio.h>
int main(int argc,char**argv) {
printf("Hello world\n");
return 0;
}
为了使用cmake构建这个工程,我门还需要在工程根目录下创建一个CMakeLists.txt文件,在文件中添加如下内容,具体的指令和含义在后面说明,现在先完成构建。
cmake_minimum_required(VERSION 3.10)
project(Hello)
add_executable(Hello hello.c)
此时我们的目录的内容如下:
.
├── CMakeLists.txt
└── hello.c
0 directories, 2 files
开始构建
构建的两种方式:
- 内部构建,即在工程的根目录下构建
在工程的根目录下执行cmake .
命令
➜ cmake cmake .
-- The C compiler identification is GNU 11.2.0
-- The CXX compiler identification is GNU 11.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/wjl/workspace/cmake
➜ cmake
此时目录下生成了许多文件:
.
├── CMakeCache.txt
├── CMakeFiles
│ ├── 3.18.4
...
省略...
...
├── cmake_install.cmake
├── CMakeLists.txt
├── hello.c
└── Makefile // 生成的Makefile文件
8 directories, 28 files
可以看到最后一行生成了一个Makefile文件, 可以通过make完成编译,编译完成后,在当前目录下生成一个名为Hello的可执行程序。
➜ cmake make
Scanning dependencies of target Hello
[ 50%] Building C object CMakeFiles/Hello.dir/hello.c.o
[100%] Linking C executable Hello
[100%] Built target Hello
➜ cmake ./Hello
Hello world
-
外部构建,即在工程目录下新建一个build目录,在build目录下构建
通过内部构建已经可以成功构建并编译运行了程序,但是可以看到在根目录下生成了很多文件,污染了代码目录。为了解决这个问题,可以使用外部构建,先删除之前构建生成的文件,然后在根目录下创建一个build目录。
├── build
├── CMakeLists.txt
└── hello.c
1 directory, 2 files
切换到build目录下,执行构建操作 cmake …
➜ cmake cd build
➜ build cmake .. // 注意这里cmake的参数是父目录,即CMakeLists.txt所在的目录
-- The C compiler identification is GNU 11.2.0
-- The CXX compiler identification is GNU 11.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/wjl/workspace/cmake/build
➜ build
构建完成,再查看下工程目录下的文件,此时生成的文件都在build目录下
.
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ │ ├── 3.18.4
│ │ │ ├── CMakeCCompiler.cmake
│ │ │ ├── CMakeCXXCompiler.cmake
│ │ │ ├── CMakeDetermineCompilerABI_C.bin
│ │ │ ├── CMakeDetermineCompilerABI_CXX.bin
│ │ │ ├── CMakeSystem.cmake
│ │ │ ├── CompilerIdC
│ │ │ │ ├── a.out
│ │ │ │ ├── CMakeCCompilerId.c
│ │ │ │ └── tmp
│ │ │ └── CompilerIdCXX
│ │ │ ├── a.out
│ │ │ ├── CMakeCXXCompilerId.cpp
│ │ │ └── tmp
│ │ ├── cmake.check_cache
│ │ ├── CMakeDirectoryInformation.cmake
│ │ ├── CMakeOutput.log
│ │ ├── CMakeTmp
│ │ ├── Hello.dir
│ │ │ ├── build.make
│ │ │ ├── cmake_clean.cmake
│ │ │ ├── DependInfo.cmake
│ │ │ ├── depend.make
│ │ │ ├── flags.make
│ │ │ ├── link.txt
│ │ │ └── progress.make
│ │ ├── Makefile2
│ │ ├── Makefile.cmake
│ │ ├── progress.marks
│ │ └── TargetDirectories.txt
│ ├── cmake_install.cmake
│ └── Makefile
├── CMakeLists.txt
└── hello.c
9 directories, 28 files
在build目录下执行make完成编译。生成的可执行文件Hello也保存在build目录下
➜ build make
Scanning dependencies of target Hello
[ 50%] Building C object CMakeFiles/Hello.dir/hello.c.o
[100%] Linking C executable Hello
[100%] Built target Hello
➜ build ./Hello
Hello world
➜ build
CMakeLists.txt指令
cmake_minimum_required(VERSION 3.10)
project(Hello)
add_executable(Hello hello.c)
CMakeFiles.txt是cmake的默认配置文件名,类似gnu make的Makefile文件。
当前的CMakeLists.txt中总共用到3条指令。
cmake_minimum_required(VERSION 3.10)
cmake_minimum_required
用来指定使用的cmake的最低版本。不同版本的cmake,CMakeLists.txt的指令会不同导致无法构建。
project(工程名 [VERSION] [版本号])
project
指令用来定义工程名和版本号,版本号可以省略,这个工程名会在后续的一些指令中用到,在以后的笔记中会说明
例:project(Hello VERSION 1.0)
add_executable
(可执行文件名 源代码文件列表)
add_executable
指令用来指定编译生成的执行文件,注意这里的可执行文件名不必和工程名相同。