Skip to content

Commit

Permalink
update chapter 15
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoweiChen committed Oct 19, 2019
1 parent a1e54e1 commit 2ca17d6
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 20 deletions.
16 changes: 8 additions & 8 deletions content/chapter15/15.1-chinese.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
$ git clone --single-branch -b v8.1.0290 https://github.com/vim/vim.git
```

或者,我们的解决方案可以在`cmake-suppor`t分支上找到,网址是 https://github.com/dev-cafe/vim ,并使用以下方法克隆下来:
或者,我们的解决方案可以在`cmake-support`分支上找到,网址是 https://github.com/dev-cafe/vim ,并使用以下方法克隆下来:

```shell
$ git clone --single-branch -b cmake-support https://github.com/dev-cafe/vim
Expand All @@ -23,7 +23,7 @@ $ git clone --single-branch -b cmake-support https://github.com/dev-cafe/vim

## 创建一个主CMakeLists.txt

首先,我们在源代码存储库的根目录中创建主CMakeLists.txt,在这里我们设置了最低CMake版本、项目名称和支持的语言,在本例中是C:
首先,我们在源代码存储库的根目录中创建主`CMakeLists.txt`,在这里我们设置了最低CMake版本、项目名称和支持的语言,在本例中是C:

```cmake
cmake_minimum_required(VERSION
Expand Down Expand Up @@ -64,7 +64,7 @@ $ cmake --build .

## 如何让常规和CMake配置共存

CMake的一个特性是在源代码之外构建,构建目录可以是任何目录,而不必是项目目录的子目录。这意味着,我们可以将一个项目移植到CMake,而不影响以前/现在的配置和构建机制。对于一个重要项目的迁移,CMake文件可以与其他构建框架共存,从而允许一个渐进的迁移,包括选项、特性和可移植性,并允许开发社区人员适应新的框架。为了允许传统配置和CMake配置共存一段时间,一个典型的策略是收集CMakeLists.txt文件中的所有CMake代码,以及CMake子目录下的所有辅助CMake源文件。的示例中,我们不会引入CMake子目录,而是保持辅助文件要求他们接近目标和来源,但会顾及使用的传统Autotools构建修改的所有文件,但有一个例外:我们将一些修改自动生成文件构建目录下,而不是在源代码树中。
CMake的一个特性是在源代码之外构建,构建目录可以是任何目录,而不必是项目目录的子目录。这意味着,我们可以将一个项目移植到CMake,而不影响以前/现在的配置和构建机制。对于一个重要项目的迁移,CMake文件可以与其他构建框架共存,从而允许一个渐进的迁移,包括选项、特性和可移植性,并允许开发社区人员适应新的框架。为了允许传统配置和CMake配置共存一段时间,一个典型的策略是收集`CMakeLists.txt`文件中的所有CMake代码,以及CMake子目录下的所有辅助CMake源文件的示例中,我们不会引入CMake子目录,而是保持辅助文件要求他们接近目标和来源,但会顾及使用的传统Autotools构建修改的所有文件,但有一个例外:我们将一些修改自动生成文件构建目录下,而不是在源代码树中。

```shell
$ ./configure --enable-gui=no
Expand All @@ -74,7 +74,7 @@ $ ./configure --enable-gui=no
$ make > build.log
```

在我们的示例中(这里没有显示build.log的内容),我们能够验证编译了哪些源文件以及使用了哪些编译标志(`-I. -Iproto -DHAVE_CONFIG_H -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1`)。日志文件中,我们可以做如下推断:
我们的示例中(这里没有显示build.log的内容),我们能够验证编译了哪些源文件以及使用了哪些编译标志(`-I. -Iproto -DHAVE_CONFIG_H -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1`)。日志文件中,我们可以做如下推断:

* 所有对象文件都链接到二进制文件中
* 不生成库
Expand All @@ -84,7 +84,7 @@ $ make > build.log

## 获取传统构建的记录

在向配置添加任何目标之前,通常有必要看看传统构建的行为,并将配置和构建步骤的输出保存到日志文件中。对于我们的Vim示例,可以使用以下方法实现:
向配置添加任何目标之前,通常有必要看看传统构建的行为,并将配置和构建步骤的输出保存到日志文件中。对于我们的Vim示例,可以使用以下方法实现:

```shell
$ ./configure --enable-gui=no
Expand Down Expand Up @@ -180,9 +180,9 @@ add_executable(vim
.
├── CMakeLists.txt
└── src
├── CMakeLists.txt
└── libvterm
└── CMakeLists.txt
├── CMakeLists.txt
└── libvterm
└── CMakeLists.txt
```

顶层文件使用`add_subdirectory(src)`添加`src/CMakeLists.txt``src/CMakeLists.txt`文件包含三个目标(一个可执行文件和两个库),每个目标都带有编译定义和包含目录。首先定义可执行文件:
Expand Down
2 changes: 1 addition & 1 deletion content/chapter15/15.2-chinese.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ endfunction()
/* ... */
```

生成的src/config.h示例类似如下情况(定义可以根据环境的不同而不同):
生成的`src/config.h`示例类似如下情况(定义可以根据环境的不同而不同):

```c++
/* Define if we have EBCDIC code */
Expand Down
2 changes: 1 addition & 1 deletion content/chapter15/15.7-chinese.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 15.7 进一步迁移的措施

成功地移植到CMake之后,下一步应该本地化目标和变量的范围:考虑将选项、目标和变量移到更靠近使用和修改它们的地方。避免全局变量,因为它们将按CMake命令顺序进行创建,而这个顺序可能不明显,从而会导致CMake代码变得混乱。强制分离变量范围的一种方法是将较大的项目划分为CMake项目,这些项目使用超构建块组成。从而,可考虑将大型CMakeLists.txt文件分割成更小的模块
成功地移植到CMake之后,下一步应该本地化目标和变量的范围:考虑将选项、目标和变量移到更靠近使用和修改它们的地方。避免全局变量,因为它们将按CMake命令顺序进行创建,而这个顺序可能不明显,从而会导致CMake代码变得混乱。强制分离变量范围的一种方法是将较大的项目划分为CMake项目,这些项目使用超构建块组成。从而,可考虑将大型`CMakeLists.txt`文件分割成更小的模块

接下来的步骤,可以是在其他平台和操作系统上进行配置和编译,以便增强CMake代码的鲁棒性,使其更具可移植性。

Expand Down
20 changes: 10 additions & 10 deletions content/chapter15/15.8-chinese.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@
.
├── CMakeLists.txt
└── src
├── autogenerate.cmake
├── CMakeLists.txt
├── config.h.cmake.in
├── libvterm
└── CMakeLists.txt
├── pathdef.c.in
└── testdir
├── CMakeLists.txt
└── test.cmake
├── autogenerate.cmake
├── CMakeLists.txt
├── config.h.cmake.in
├── libvterm
└── CMakeLists.txt
├── pathdef.c.in
└── testdir
├── CMakeLists.txt
└── test.cmake
```

可以在线查看修改: https://github.com/dev-cafe/vim/compare/b476cb7...cmake-support
Expand All @@ -29,7 +29,7 @@

在结束讨论之前,我们想指出一些迁移到CMake时常见的问题。

* **全局变量代码异味**:这点适用于任何编程语言,CMake也不例外。跨CMake文件的变量,特别是从子到父CMakeLists.txt文件的“向上”传递的变量,这是明显的“异味代码”。通常,会有一种更好的方法来传输依赖关系。理想情况下,依赖项应该通过目标导入。与其将库列表组装成一个变量并在文件之间携带该变量,不如逐个链接到定义库的地方。不是将源文件组装成变量,而是使用`target_sources`添加源文件。当链接到库时,在可用时使用导入的目标,而不是变量。
* **全局变量代码异味**:这点适用于任何编程语言,CMake也不例外。跨CMake文件的变量,特别是从子到父`CMakeLists.txt`文件的“向上”传递的变量,这是明显的“异味代码”。通常,会有一种更好的方法来传输依赖关系。理想情况下,依赖项应该通过目标导入。与其将库列表组装成一个变量并在文件之间携带该变量,不如逐个链接到定义库的地方。不是将源文件组装成变量,而是使用`target_sources`添加源文件。当链接到库时,在可用时使用导入的目标,而不是变量。
* **最小化顺序的影响**:CMake不是一种声明性语言,但是也不应该使用命令式范式进行处理。执行严格命令的代码往往是脆弱的,这也与变量有关(见上一段)。一些语句和模块的顺序是必要的,但是为了实现健壮的CMake框架,我们应该避免不必要的顺序强制。应该多使用`target_sources``target_compile_definition``target_include_directory``target_link_libraries`。避免使用全局范围语句,如`add_definition``include_directory``link_libraries`,从而避免定义全局编译标志。如果可能,为每个目标定义编译标志。
* **不在build目录之外生成文件**:强烈建议不要将生成的文件放在构建目录之外。原因是生成的文件通常依赖于所选择的选项、编译器或构建类型。如果写入原目录树,我们就放弃了用同一套源码维护多个构建的可能性,并且会使构建步骤的重现复杂化。
* **尽可能使用函数,而不是宏**:它们的作用范围不同,功能范围也有限定。所有变量修改都需要显式标记,这也向读者展示了重新定义的变量。如果可以最好使用函数,必要时再使用宏。
Expand Down

0 comments on commit 2ca17d6

Please sign in to comment.