CMake learning (1): Basic use of CMake

https://subingwen.cn/cmake/CMake-primer/

1. CMake overview

CMake is a project build tool and is cross-platform. Cmake and Makefile are actually similar, but the makefile is lower. Most IDE software integrates make, such as: nmake of VS, GNU make under linux, qmake of Qt, etc. If you write makefile yourself, you will find that makefile usually depends on the current compilation platform, and the workload of writing makefile It is relatively large and error-prone when resolving dependencies.

And CMake just can solve the above problems. It allows developers to specify the compilation process of the entire project. According to the compilation platform, the 自动生成本地化的Makefile和工程文件user only needs to make the compilation. Therefore CMake 看成一款自动生成 Makefile 的工具, the compilation process is as follows:

insert image description here

  • 蓝色虚线Indicates makefilethe process of building a project using
  • 红色实线Indicates the process of cmake building

First, you need to create a script CMakeLists.txtfile, specify some instructions in the file, and then execute cmakethe command. cmakeAfter execution, a file will be generated. MakefileAt this time, there will be some compilation instructions in the makefile file, and finally execute makethe command to execute makefilea series of instructions Generate 可执行文件( 编译过程:call the preprocessor first, then the assembler, then the linker, and finally generate the executable file).

cmake can not only generate executable files, but also generate library files, including: dynamic libraries and static libraries. After generating these library files, they can be imported into other third-party projects. Why use dynamic libraries or static libraries instead of source code for third-party projects? There are two main reasons: 1. In order to keep the source code confidential 2. For example, a library is compiled and generated from 100 source files. It is very troublesome and bloated to import 100 source files into a third-party project, and it is not easy maintain. For convenience and maintainability, these 100 source files are compiled into library files for third-party projects to call.

After introducing the function of CMake, let's summarize its functions 优点:

  • 跨平台
  • Ability to manage large projects
  • Simplify the compilation build process and compilation process
  • Extensible: You can write specific function modules for cmake to expand cmake functions

2. Use of CMake

大写、小写、混合大小写Commands supported by CMake . If the tool used when writing CMakeLists.txtthe file has a corresponding command prompt, then the upper and lower case can be used as you like, don't pay too much attention to it.

2.1 Notes

2.1.1 Comment lines

CMake uses #for line comments, which can be placed anywhere.

# 这是一个 CMakeLists.txt 文件
cmake_minimum_required(VERSION 3.0.0)

2.1.2 Comment blocks

CMake uses #[[ ]]the form for block comments.

#[[ 这是一个 CMakeLists.txt 文件。
这是一个 CMakeLists.txt 文件
这是一个 CMakeLists.txt 文件]]
cmake_minimum_required(VERSION 3.0.0)

2.2 Only source files

2.2.1 Sharing a room

(1) Preparatory work , in order to facilitate the test, I have prepared several test files on my local computer

  • add.c
#include <stdio.h>
#include "head.h"

int add(int a, int b)
{
    
    
    return a+b;
}
  • sub.c
#include <stdio.h>
#include "head.h"

// 你好
int subtract(int a, int b)
{
    
    
    return a-b;
}
  • mult.c
#include <stdio.h>
#include "head.h"

int multiply(int a, int b)
{
    
    
    return a*b;
}
  • div.c
#include <stdio.h>
#include "head.h"

double divide(int a, int b)
{
    
    
    return (double)a/b;
}
  • head.h
#ifndef _HEAD_H
#define _HEAD_H
// 加法
int add(int a, int b);
// 减法
int subtract(int a, int b);
// 乘法
int multiply(int a, int b);
// 除法
double divide(int a, int b);
#endif

  • main.c
#include <stdio.h>
#include "head.h"

int main()
{
    
    
    int a = 20;
    int b = 12;
    printf("a = %d, b = %d\n", a, b);
    printf("a + b = %d\n", add(a, b));
    printf("a - b = %d\n", subtract(a, b));
    printf("a * b = %d\n", multiply(a, b));
    printf("a / b = %f\n", divide(a, b));
    return 0;
}

(2) The directory structure of the above files is as follows:

$ tree
.
├── add.c
├── div.c
├── head.h
├── main.c
├── mult.c
└── sub.c

(3) Add CMakeLists.txt file
Add a new file in the directory where the above source file is located CMakeLists.txt, the content of the file is as follows:

cmake_minimum_required(VERSION 3.0)
project(CALC)
add_executable(app add.c div.c main.c mult.c sub.c)

Next, introduce the three commands added in the CMakeLists.txt file in turn:

  • cmake_minimum_required最低: Specify the version of cmake used

    • Optional, not required, if not added there may be a warning -
  • project: Definition 工程名称, and can specify the project version, project description, web home page address, supported languages ​​(all languages ​​are supported by default), if not needed, these can be ignored, just specify the project name.

# PROJECT 指令的语法是:
project(<PROJECT-NAME> [<language-name>...])
project(<PROJECT-NAME>
       [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
       [DESCRIPTION <project-description-string>]
       [HOMEPAGE_URL <url-string>]
       [LANGUAGES <language-name>...])
  • add_executable:The definition project will generate an executable program
add_executable(可执行程序名 源文件名称)

The name of the executable program here has nothing to do with the name of the project in the project

The source file name can be one or more, if there are multiple available spaces or ; intervals

# 样式1
add_executable(app add.c div.c main.c mult.c sub.c)
# 样式2
add_executable(app add.c;div.c;main.c;mult.c;sub.c)

(4) Execute the CMake command.
Everything is ready, but the east wind is needed. After editing the CMakeLists.txt file, cmakethe command can be executed.

# cmake 命令原型
$ cmake CMakeLists.txt文件所在路径
$ tree
.
├── add.c
├── CMakeLists.txt
├── div.c
├── head.h
├── main.c
├── mult.c
└── sub.c

0 directories, 7 files
robin@OS:~/Linux/3Day/calc$ cmake .

After the command is executed cmake, the commands in CMakeLists.txt will be executed, so be careful not to make mistakes when specifying the path for the cmake command.

After executing the command, check if there are more files in the directory where the source file is located:

$ tree -L 1
.
├── add.c
├── CMakeCache.txt         # new add file
├── CMakeFiles             # new add dir
├── cmake_install.cmake    # new add file
├── CMakeLists.txt
├── div.c
├── head.h
├── main.c
├── Makefile               # new add file
├── mult.c
└── sub.c

We can see that a file makefile is generated in the corresponding directory , and then execute the command at this time to build the project to obtain the required executable program.make

$ make
Scanning dependencies of target app
[ 16%] Building C object CMakeFiles/app.dir/add.c.o
[ 33%] Building C object CMakeFiles/app.dir/div.c.o
[ 50%] Building C object CMakeFiles/app.dir/main.c.o
[ 66%] Building C object CMakeFiles/app.dir/mult.c.o
[ 83%] Building C object CMakeFiles/app.dir/sub.c.o
[100%] Linking C executable app
[100%] Built target app

# 查看可执行程序是否已经生成
$ tree -L 1
.
├── add.c
├── app					# 生成的可执行程序
├── CMakeCache.txt
├── CMakeFiles
├── cmake_install.cmake
├── CMakeLists.txt
├── div.c
├── head.h
├── main.c
├── Makefile
├── mult.c
└── sub.c

Finally, the executable program app is compiled (the name is specified in CMakeLists.txt).

2.2.2 VIP private room

From the above example, it can be seen that if the cmake command is executed in the directory where the CMakeLists.txt file is located, some directories and files (including makefile files) will be generated. If makethe command Some intermediate files and an executable file 这样会导致整个项目目录看起来很混乱are not easy to manage and maintain. At this time, we can put these generated files that have nothing to do with the project source code into a corresponding directory. For example, name this directory as build:

$ mkdir build
$ cd build
$ cmake ..
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/robin/Linux/build

Now the cmake command is buildexecuted in the directory, but CMakeLists.txt the file is 上一级in the directory of the build directory, so the path specified after the cmake command ..is the upper directory of the current directory.

makefileWhen the command is executed, a file will be generated in the build directory

$ tree build -L 1
build
├── CMakeCache.txt
├── CMakeFiles
├── cmake_install.cmake
└── Makefile

1 directory, 3 files

In this way, the make command can be executed in the build directory to compile the project, and the generated related files will naturally be stored in the build directory. 这样通过 cmake 和 make 生成的所有文件就全部和项目源文件隔离开了, Each went back to each house, each looking for each mother.

reference

Author: Su Bingyu
Link: https://subingwen.cn/cmake/CMake-primer/
Source: Dabing who loves programming

Guess you like

Origin blog.csdn.net/weixin_38346042/article/details/130816017