古月不傲 发表于 2021-1-14 04:40

CMake教程

本帖最后由 古月不傲 于 2021-1-14 05:22 编辑

项目地址:https://github.com/ttroy50/cmake-examples

A-hello-cmake
= Hello CMake
:toc:
:toc-placement!:

toc::[]

# Introduction

Shows a very basic hello world example.
// 一个非常简单的 hello world示例
The files in this tutorial are below:
// 本教程使用到的文件如下
```
A-hello-cmake$ tree
.
├── CMakeLists.txt
├── main.cpp
```

* link:CMakeLists.txt - Contains the CMake commands you wish to run
// CMakeLists.txt:      包含你想要运行的CMake指令集
* link:main.cpp - A simple "Hello World" cpp file.
// main.cpp:                一个简单的"Hello World"文件

# Concepts

### CMakeLists.txt

CMakeLists.txt is the file which should store all your CMake commands. When
cmake is run in a folder it will look for this file and if it does not exist cmake
will exit with an error.
// CMakeLists.txt是一个存储CMake指令集的文件。
// 当在一个目录中运行CMake,它会寻找该文件,如果该文件不存在,那么CMake会报错
### Minimum CMake version

When creating a project using CMake, you can specify the minimum version
of CMake that is supported.
// 当使用CMake创建一个项目,你可以指定CMake的最低支持版本

----
cmake_minimum_required(VERSION 3.5)
----


### Projects

A CMake build can include a project name to make referencing certain
variables easier when using multiple projects.
// 使用多项目时,可以包含一个项目名,以便更容易的引用某些变量

----
project (hello_cmake)
----


### Creating an Executable

The +add_executable()+ command specifies that an executable should be
build from the specified source files, in this example main.cpp. The
first argument to the +add_executable()+ function is the name of the
executable to be built, and the second argument is the list of source files to compile.
// 给定特定的源文件编译生成一个可执行文件,本例中使用 main.cpp
// 第一个参数:要生成的可执行名,第二个参数:要编译的源文件列表

----
add_executable(hello_cmake main.cpp)
----



====
A shorthand that some people use is to have the project name and
executable name the same. This allows you to specify the CMakeLists.txt
as follows,
// 有些人使用一种简略的方法是使项目名和可执行文件名相同
// 你可以使用下面这种风格


----
cmake_minimum_required(VERSION 2.6)
project (hello_cmake)
add_executable(${PROJECT_NAME} main.cpp)
----

In this example, the +project()+ function, will create a variable
+${PROJECT_NAME}+ with the value hello_cmake. This can then be passed to
the +add_executable()+ function to output a 'hello_cmake' executable.
====
// 本例中,project()会创建一个hello_cmake的变量 ${PROJECT_NAME}
// 可以传递该变量给add_excutable()生成hello_cmake可执行文件


### Binary Directory

The root or top level folder that you run the cmake command from is known as your
CMAKE_BINARY_DIR and is the root folder for all your binary files.
CMake supports building and generating your binary files both in-place and also
out-of-source.
// CMAKE_BINARY_DIR是所有二进制文件的根目录或顶层目录
// CMake不但支持内部编译也支持外部编译,生成你的二进制文件

#### In-Place Build

In-place builds generate all temporary build files in the same directory structure
as the source code. This means that all Makefiles and object files are interspersed
with your normal code. To create an in-place build target run the cmake command
in your root directory. For example:
// 内部编译会在和源代码相同的目录下生成所有的临时文件
// 这就意味着所有的Makefiles和目标文件都和普通文件粘在一起了
// 要创建内部编译,请在根目录下运行CMake

----
A-hello-cmake$ cmake .
-- The C compiler identification is GNU 4.8.4
-- The CXX compiler identification is GNU 4.8.4
-- 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
-- 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
-- Configuring done
-- Generating done
-- Build files have been written to: /home/matrim/workspace/cmake-examples/01-basic/A-hello-cmake

A-hello-cmake$ tree
.
├── CMakeCache.txt
├── CMakeFiles
│   ├── 2.8.12.2
│   │   ├── CMakeCCompiler.cmake
│   │   ├── CMakeCXXCompiler.cmake
│   │   ├── CMakeDetermineCompilerABI_C.bin
│   │   ├── CMakeDetermineCompilerABI_CXX.bin
│   │   ├── CMakeSystem.cmake
│   │   ├── CompilerIdC
│   │   │   ├── a.out
│   │   │   └── CMakeCCompilerId.c
│   │   └── CompilerIdCXX
│   │       ├── a.out
│   │       └── CMakeCXXCompilerId.cpp
│   ├── cmake.check_cache
│   ├── CMakeDirectoryInformation.cmake
│   ├── CMakeOutput.log
│   ├── CMakeTmp
│   ├── hello_cmake.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
├── CMakeLists.txt
├── main.cpp
├── Makefile
----


#### Out-of-Source Build

Out-of-source builds allow you to create a single build folder that can be anywhere on
your file system. All temporary build and object files are located in this directory keeping
your source tree clean. To create an out-of-source build run the cmake command in
the build folder and point it to the directory with your root CMakeLists.txt file.
Using out-of-source builds if you want to recreate your cmake environment
from scratch, you only need to delete your build directory and then rerun cmake.
// 外部编译允许你去创建一个单独的bulid目录,该目录可以在你系统的任意位置创建
// 生成的所有临时文件和目标文件都会被放入该目录,这样会使你的源目录保持干净
// 要想在bulid目录中执行CMake,要将编译的目标指向CMakeLists.txt所在的目录
// 如果你想重新CMake,只需要删除build文件夹,然后重新CMake即可
For example:


----
A-hello-cmake$ mkdir build

A-hello-cmake$ cd build/

A-hello-cmake/build$ make ..
make: Nothing to be done for `..'.
matrim@freyr:~/workspace/cmake-examples/01-basic/A-hello-cmake/build$ cmake ..
-- The C compiler identification is GNU 4.8.4
-- The CXX compiler identification is GNU 4.8.4
-- 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
-- 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
-- Configuring done
-- Generating done
-- Build files have been written to: /home/matrim/workspace/cmake-examples/01-basic/A-hello-cmake/build

A-hello-cmake/build$ cd ..

A-hello-cmake$ tree
.
├── build
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   │   ├── 2.8.12.2
│   │   │   ├── CMakeCCompiler.cmake
│   │   │   ├── CMakeCXXCompiler.cmake
│   │   │   ├── CMakeDetermineCompilerABI_C.bin
│   │   │   ├── CMakeDetermineCompilerABI_CXX.bin
│   │   │   ├── CMakeSystem.cmake
│   │   │   ├── CompilerIdC
│   │   │   │   ├── a.out
│   │   │   │   └── CMakeCCompilerId.c
│   │   │   └── CompilerIdCXX
│   │   │       ├── a.out
│   │   │       └── CMakeCXXCompilerId.cpp
│   │   ├── cmake.check_cache
│   │   ├── CMakeDirectoryInformation.cmake
│   │   ├── CMakeOutput.log
│   │   ├── CMakeTmp
│   │   ├── hello_cmake.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
├── main.cpp
----

All examples in this tutorial will use out-of-source builds.
// 该教程的所有示例均将采用外部编译

# Building the Examples

Below is sample output from building this example.
// 以下是该示例的编译过程

----
$ mkdir build

$ cd build

$ cmake ..
-- The C compiler identification is GNU 4.8.4
-- The CXX compiler identification is GNU 4.8.4
-- 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
-- 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
-- Configuring done
-- Generating done
-- Build files have been written to: /workspace/cmake-examples/01-basic/hello_cmake/build

$ make
Scanning dependencies of target hello_cmake
Building CXX object CMakeFiles/hello_cmake.dir/hello_cmake.cpp.o
Linking CXX executable hello_cmake
Built target hello_cmake

$ ./hello_cmake
Hello CMake!
----

B-hello-headers
= Hello Headers
:toc:
:toc-placement!:

toc::[]


# Introduction

Shows a hello world example which uses a different folder for source and include
files.
// 输出Hello Headers,对于源文件和头文件采用不同的目录
The files in this tutorial include:
// 本教程包含的文件如下

```
B-hello-headers$ tree
.
├── CMakeLists.txt
├── include
│   └── Hello.h
└── src
    ├── Hello.cpp
    └── main.cpp
```

* link:CMakeLists.txt - Contains the CMake commands you wish to run.
* link:include/Hello.h - The header file to include.
* link:src/Hello.cpp - A source file to compile.
* link:src/main.cpp - The source file with main.


# Concepts

## Directory Paths

CMake syntax specifies a number of https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/Useful-Variables
which can be used to help find useful directories in your project or source tree.
// CMake指定了许多可以在你的项目或源目录中查找有用的目录的语法
Some of these include:

|=======================================================================
|Variable |Info
|CMAKE_SOURCE_DIR |The root source directory
// 源码的根目录
|CMAKE_CURRENT_SOURCE_DIR |The current source directory if using sub-projects and directories.
// 同上
|PROJECT_SOURCE_DIR |The source directory of the current cmake project.
// 同上
|CMAKE_BINARY_DIR |The root binary / build directory. This is the directory where you ran the cmake command.
// CMake当前运行的目录
|CMAKE_CURRENT_BINARY_DIR |The build directory you are currently in.
// 同上
|PROJECT_BINARY_DIR |The build directory for the current project.
// 同上
|=======================================================================

## Source Files Variable

Creating a variable which includes the source files allows you to be
clearer about these files and easily add them to multiple commands, for example,
the +add_executable()+ function.
// 创建一个变量,该变量包含明确的文件,并且更容易的把它添加到其他命令中,例如,添加到add_excutable()中

----
# Create a sources variable with a link to all cpp files to compile
// 创建一个链接变量,该变量将代表所有要编译的Cpp文件
set(SOURCES
    src/Hello.cpp
    src/main.cpp
)

add_executable(${PROJECT_NAME} ${SOURCES})
----


====
An alternative to setting specific file names in the +SOURCES+ variable is
to use a GLOB command to find files using wildcard pattern matching.
// 设置指定文件名到SOURCES变量中的另一种方法是使用GLOB命令去查找文件,使用通配符匹配

----
file(GLOB SOURCES "src/*.cpp")
----
====



====
For modern CMake it is NOT recommended to use a variable for sources. Instead it is
typical to directly declare the sources in the add_xxx function.
// CMake不建议为SOURCES使用一个变量
// 典型的做法是直接在add_xxx中声明变量最好
This is particularly important for glob commands which may not always show you the
correct results if you add a new source file.
// 这个对于glob命令来说尤为重要,如果你添加一个新的源文件,那么可能不会总是为你显示正确的结果
====

## Including Directories

When you have different include folders, you can make your compiler aware of them using the
+target_include_directories()+ link:https://cmake.org/cmake/help/v3.0/command/target_include_directories.html. When compiling this target this will add these directories to the compiler with the -I flag e.g. `-I/directory/path`
// 当你拥有不同的头文件目录时,你可以使用target_include_directories()让你的编译器知晓
// 当编译该target,会添加这些目录到编译器 -I/directory/path

----
target_include_directories(target
    PRIVATE
      ${PROJECT_SOURCE_DIR}/include
)
----

The +PRIVATE+ identifier specifies the scope of the include. This is important for libraries and is explained in the next example. More details on the function is available link:https://cmake.org/cmake/help/v3.0/command/target_include_directories.html
// PAIVATE表示头文件的范围
// 这对于库文件来说非常重要,将在下一个示例中说明这一点
# Building the Example

## Standard Output

The standard output from building this example is presented below.
// 标准输出如下

----
$ mkdir build

$ cd build

$ cmake ..
-- The C compiler identification is GNU 4.8.4
-- The CXX compiler identification is GNU 4.8.4
-- 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
-- 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
-- Configuring done
-- Generating done
-- Build files have been written to: /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build

$ make
Scanning dependencies of target hello_headers
[ 50%] Building CXX object CMakeFiles/hello_headers.dir/src/Hello.cpp.o
Building CXX object CMakeFiles/hello_headers.dir/src/main.cpp.o
Linking CXX executable hello_headers
Built target hello_headers

$ ./hello_headers
Hello Headers!
----


## Verbose Output

In the previous examples, when running the make command the output only
shows the status of the build. To see the full output for debugging
purposes you can add +VERBOSE=1+ flag when running make.
// 在上一个例子中,运行make,紧紧输出显示了编译的状态
// 要想显示详细的debug信息,make时,可以加上VERBOSE=1标志
The VERBOSE output is show below, and a examination of the output shows
the include directories being added to the c++ compiler command.
// 详细的输出如下,该输出显示了头文件目录被添加到C++编译器命令的过程

----
$ make clean

$ make VERBOSE=1
/usr/bin/cmake -H/home/matrim/workspace/cmake-examples/01-basic/hello_headers -B/home/matrim/workspace/cmake-examples/01-basic/hello_headers/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build/CMakeFiles /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make: Entering directory `/home/matrim/workspace/cmake-examples/01-basic/hello_headers/build'
make -f CMakeFiles/hello_headers.dir/build.make CMakeFiles/hello_headers.dir/depend
make: Entering directory `/home/matrim/workspace/cmake-examples/01-basic/hello_headers/build'
cd /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/matrim/workspace/cmake-examples/01-basic/hello_headers /home/matrim/workspace/cmake-examples/01-basic/hello_headers /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build/CMakeFiles/hello_headers.dir/DependInfo.cmake --color=
make: Leaving directory `/home/matrim/workspace/cmake-examples/01-basic/hello_headers/build'
make -f CMakeFiles/hello_headers.dir/build.make CMakeFiles/hello_headers.dir/build
make: Entering directory `/home/matrim/workspace/cmake-examples/01-basic/hello_headers/build'
/usr/bin/cmake -E cmake_progress_report /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build/CMakeFiles 1
[ 50%] Building CXX object CMakeFiles/hello_headers.dir/src/Hello.cpp.o
/usr/bin/c++    -I/home/matrim/workspace/cmake-examples/01-basic/hello_headers/include    -o CMakeFiles/hello_headers.dir/src/Hello.cpp.o -c /home/matrim/workspace/cmake-examples/01-basic/hello_headers/src/Hello.cpp
/usr/bin/cmake -E cmake_progress_report /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build/CMakeFiles 2
Building CXX object CMakeFiles/hello_headers.dir/src/main.cpp.o
/usr/bin/c++    -I/home/matrim/workspace/cmake-examples/01-basic/hello_headers/include    -o CMakeFiles/hello_headers.dir/src/main.cpp.o -c /home/matrim/workspace/cmake-examples/01-basic/hello_headers/src/main.cpp
Linking CXX executable hello_headers
/usr/bin/cmake -E cmake_link_script CMakeFiles/hello_headers.dir/link.txt --verbose=1
/usr/bin/c++       CMakeFiles/hello_headers.dir/src/Hello.cpp.o CMakeFiles/hello_headers.dir/src/main.cpp.o-o hello_headers -rdynamic
make: Leaving directory `/home/matrim/workspace/cmake-examples/01-basic/hello_headers/build'
/usr/bin/cmake -E cmake_progress_report /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build/CMakeFiles1 2
Built target hello_headers
make: Leaving directory `/home/matrim/workspace/cmake-examples/01-basic/hello_headers/build'
/usr/bin/cmake -E cmake_progress_start /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build/CMakeFiles 0
----


PS:Markdown弄一下反而更丑,改太麻烦。

a952135763 发表于 2021-1-14 09:16

排版重要呀 我看起我从那里看看的啥都不晓得
页: [1]
查看完整版本: CMake教程