Skip to content

Commit

Permalink
update chapter 3
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoweiChen committed Oct 12, 2019
1 parent 718e89f commit 42f2ce3
Show file tree
Hide file tree
Showing 6 changed files with 17 additions and 17 deletions.
6 changes: 3 additions & 3 deletions content/chapter3/3.10-chinese.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@

此示例的主`CMakeLists.txt`在使用`FindZeroMQ.cmake`时,与前一个示例中使用的`CMakeLists.txt`不同。这个模块使用`find_path``find_library` CMake内置命令,搜索ZeroMQ头文件和库,并使用`find_package_handle_standard_args`设置相关变量,就像我们在第3节中做的那样。

1. `FindZeroMQ.cmake`中,检查了`ZeroMQ_ROOT`变量是否设置。此变量可用于将ZeroMQ库的检测,并引导到非标准安装目录。用户可能设置了`ZeroMQ_ROOT`作为环境变量,我们也会进行检查了:
1. `FindZeroMQ.cmake`中,检查了`ZeroMQ_ROOT`变量是否设置。此变量可用于ZeroMQ库的检测,并引导到自定义安装目录。用户可能设置了`ZeroMQ_ROOT`作为环境变量,我们也会进行检查了:

```cmake
if(NOT ZeroMQ_ROOT)
Expand Down Expand Up @@ -187,9 +187,9 @@

目前,并不是所有的包供应商都提供CMake的Find文件,不过正变得越来越普遍。因为导出CMake目标,使得第三方代码很容易使用它所依赖的库和/或程序附加的依赖。

从一开始,`Find-module`就一直是CMake中定位依赖的主流手段。但是,它们中的大多数仍然依赖于设置依赖项使用的变量,比如`Boost_INCLUDE_DIRS``PYTHON_INTERPRETER`等等。这种方式很难在第三方要发布自己的包时,确保依赖关系始终被满足
从一开始,`Find-module`就一直是CMake中定位依赖的主流手段。但是,它们中的大多数仍然依赖于设置依赖项使用的变量,比如`Boost_INCLUDE_DIRS``PYTHON_INTERPRETER`等等。这种方式很难在第三方发布自己的包时,确保依赖关系被满足

使用`pkg-config`的方法可以很好地工作,因为它已经成为Unix系统的标准。然而,也由于这个原因,它不是一个完全跨平台的方法。此外,如CMake文档所述,在某些情况下,用户可能会意外地覆盖包检测,并导致`pkg-config`提供不正确的信息。
使用`pkg-config`的方法可以很好地进行适配,因为它已经成为Unix系统的标准。然而,也由于这个原因,它不是一个完全跨平台的方法。此外,如CMake文档所述,在某些情况下,用户可能会意外地覆盖检测包,并导致`pkg-config`提供不正确的信息。

最后的方法是编写自己的查找模块脚本,就像本示例中那样。这是可行的,并且依赖于`FindPackageHandleStandardArgs.cmake `。然而,编写一个全面的查找模块脚本绝非易事;有需要考虑很多可能性,我们在Unix和Windows平台上,为查找ZeroMQ库文件演示了一个例子。

Expand Down
6 changes: 3 additions & 3 deletions content/chapter3/3.5-chinese.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ end program

## 工作原理

我们的示例很简单:编译代码,并运行在多个内核上时,我们会看到加速效果。加速效果并不是`OMP_NUM_THREADS`的倍数,不过本示例中并不关心,因为我们更关注的是如何使用CMake配置需要使用OpenMP的项目。我们发现链接到OpenMP非常简单,这要感谢`FindOpenMP`模块提供的目标:
我们的示例很简单:编译代码,并运行在多个内核上时,我们会看到加速效果。加速效果并不是`OMP_NUM_THREADS`的倍数,不过本示例中并不关心,因为我们更关注的是如何使用CMake配置需要使用OpenMP的项目。我们发现链接到OpenMP非常简单,这要感谢`FindOpenMP`模块:

```cmake
target_link_libraries(example
Expand All @@ -160,7 +160,7 @@ target_link_libraries(example
)
```

我们不关心编译标志或包含目录——这些设置和依赖项是在`OpenMP::OpenMP_CXX`的定义中已定义的,是`IMPORTED`类型。如第1章第3节中提到的,`IMPORTED`库是伪目标,它完全是我们自己项目的外部依赖项。要使用OpenMP,需要设置一些编译器标志,包括目录和链接库。所有这些都包含在`OpenMP::OpenMP_CXX`的属性上,并通过使用`target_link_libraries`命令传递到我们的`example`目标。这使得在CMake中,使用库变得非常容易。我们可以使用`cmake_print_properties`命令打印接口的属性,该命令由`CMakePrintHelpers.CMake`模块提供:
我们不关心编译标志或包含目录——这些设置和依赖项是在`OpenMP::OpenMP_CXX`中定义的(`IMPORTED`类型)。如第1章第3节中提到的,`IMPORTED`库是伪目标,它完全是我们自己项目的外部依赖项。要使用OpenMP,需要设置一些编译器标志,包括目录和链接库。所有这些都包含在`OpenMP::OpenMP_CXX`的属性上,并通过使用`target_link_libraries`命令传递给`example`。这使得在CMake中,使用库变得非常容易。我们可以使用`cmake_print_properties`命令打印接口的属性,该命令由`CMakePrintHelpers.CMake`模块提供:

```cmake
include(CMakePrintHelpers)
Expand All @@ -176,7 +176,7 @@ cmake_print_properties(

所有属性都有`INTERFACE_`前缀,因为这些属性对所需目标,需要以接口形式提供,并且目标以接口的方式使用OpenMP。

对于低于3.9的CMake版本,我们有更多的工作量:
对于低于3.9的CMake版本:

```cmake
add_executable(example example.cpp)
Expand Down
4 changes: 2 additions & 2 deletions content/chapter3/3.6-chinese.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ int main(int argc, char **argv)
## 具体实施
这个示例中,我们先查找MPI实现:库、头文件、编译器包装器和启动器。为此,我们将用到`FindMPI.cmake`标准cmake模块:
这个示例中,我们先查找MPI实现:库、头文件、编译器包装器和启动器。为此,我们将用到`FindMPI.cmake`标准CMake模块:
1. 首先,定义了CMake最低版本、项目名称、支持的语言和语言标准:
Expand Down Expand Up @@ -87,7 +87,7 @@ int main(int argc, char **argv)
```shell
$ mkdir -p build
$ cd build
$ cmake -D CMAKE_CXX_COMPILER=mpicxx ..
$ cmake .. # -D CMAKE_CXX_COMPILER=mpicxx C++例子中可加,加与不加对于构建结果没有影响╭(╯^╰)╮

-- ...
-- Found MPI_CXX: /usr/lib/openmpi/libmpi_cxx.so (found version "3.1")
Expand Down
12 changes: 6 additions & 6 deletions content/chapter3/3.7-chinese.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

BLAS库为矩阵和向量操作提供了标准化接口。不过,这个接口用Fortran语言书写。虽然已经展示了如何使用C++直接使用这些库,但在现代C++程序中,希望有更高级的接口。

纯头文件实现的Eigen库,使用模板编程来提供接口。矩阵和向量类型易于使用,会在编译时提供类型检查,以确保没有不兼容的矩阵维度。密集和稀疏矩阵的运算,也可使用表达式模板高效的进行实现,如:矩阵-矩阵乘积,线性系统求解器,和特征值问题。从3.3版开始,Eigen可以链接到BLAS和LAPACK库,这可以将某些操作实现进行卸载,使库的实现更加灵活,从而获得更多的性能收益。
纯头文件实现的Eigen库,使用模板编程来提供接口。矩阵和向量的计算,会在编译时进行数据类型检查,以确保兼容所有维度的矩阵。密集和稀疏矩阵的运算,也可使用表达式模板高效的进行实现,如:矩阵-矩阵乘积,线性系统求解器和特征值问题。从3.3版开始,Eigen可以链接到BLAS和LAPACK库中,这可以将某些操作实现进行卸载,使库的实现更加灵活,从而获得更多的性能收益。

本示例将展示如何查找Eigen库,使用OpenMP并行化,并将部分工作转移到BLAS库。

Expand Down Expand Up @@ -128,7 +128,7 @@ int main(int argc, char **argv)
find_package(BLAS)
```

7. 如果找到BLAS,我们可为可执行目标,设置相应的编译定义和链接库:
7. 如果找到BLAS,我们可为可执行目标,设置相应的宏定义和链接库:

```cmake
if(BLAS_FOUND)
Expand Down Expand Up @@ -192,11 +192,11 @@ int main(int argc, char **argv)

## 工作原理

Eigen支持CMake,这样设置C++项目就会变得很容易。从3.3版开始,Eigen提供了CMake模块,这些模块将导出相应的目标`Eigen3::Eigen`
Eigen支持CMake查找,这样配置项目就会变得很容易。从3.3版开始,Eigen提供了CMake模块,这些模块将导出相应的目标`Eigen3::Eigen`

`find_package`命令可以用于配置选项。向CMake发出信号,表明包搜索将不会使用`FindEigen3.cmake`模块,而是通过 `Eigen3Config.cmake``Eigen3ConfigVersion.cmake``Eigen3Targets.cmake`提供Eigen3安装的标准位置`<installation-prefix>/share/eigen3/cmake`。这种包定位模式被称为“Config”模式,比我们一直使用的` Find<package>.cmake `方式更通用。有关“模块”模式和“配置”模式的更多信息,可参考官方文档 https://cmake.org/cmake/help/v3.5/command/find_package.html
`find_package`可以通过选项传递,届时CMake将不会使用`FindEigen3.cmake`模块,而是通过特定的`Eigen3Config.cmake``Eigen3ConfigVersion.cmake``Eigen3Targets.cmake`提供Eigen3安装的标准位置(`<installation-prefix>/share/eigen3/cmake`)。这种包定位模式称为“Config”模式,` Find<package>.cmake `方式更加通用。有关“模块”模式和“配置”模式的更多信息,可参考官方文档 https://cmake.org/cmake/help/v3.5/command/find_package.html

虽然Eigen3、BLAS和OpenMP声明为` PUBLIC`依赖项,但`EIGEN_USE_BLAS`编译定义声明为`PRIVATE`可以在单独的库目标中收集库依赖项,而不是直接链接可执行文件。使用`PUBLIC/PRIVATE`关键字,可以根据库目标的依赖关系调整相应标志和定义。
虽然Eigen3、BLAS和OpenMP声明为` PUBLIC`依赖项,但`EIGEN_USE_BLAS`编译定义声明为`PRIVATE`可以在单独的库目标中汇集库依赖项,而不是直接链接可执行文件。使用`PUBLIC/PRIVATE`关键字,可以根据库目标的依赖关系调整相应标志和定义。

## 更多信息

Expand All @@ -211,7 +211,7 @@ CMake将在预定义的位置层次结构中查找配置模块。首先是`CMAKE
2. 通过传递配置文件的位置作为`Eigen3_DIR`:

```shell
$ cmake -D Eigen3_DIR=<installation-prefix>/share/eigen3/cmake/
$ cmake -D Eigen3_DIR=<installation-prefix>/share/eigen3/cmake ..
```


4 changes: 2 additions & 2 deletions content/chapter3/3.8-chinese.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,10 @@ Boost由许多不同的库组成,这些库可以独立使用。CMake可将这

## 工作原理

`FindBoost.cmake `是本示例中所使用的CMake模块,其会在标准系统安装目录中找到Boost库。由于我们链接到导入的是`Boost::filesystem`目标,CMake将自动设置包含目录并调整编译和链接标志。如果Boost库安装在非标准位置,可以在配置时使用`BOOST_ROOT`变量传递Boost安装的根目录,以便让CMake搜索非标准路径:
`FindBoost.cmake `是本示例中所使用的CMake模块,其会在标准系统安装目录中找到Boost库。由于我们链接的是`Boost::filesystem`,CMake将自动设置包含目录并调整编译和链接标志。如果Boost库安装在非标准位置,可以在配置时使用`BOOST_ROOT`变量传递Boost安装的根目录,以便让CMake搜索非标准路径:

```shell
$ cmake -D BOOST_ROOT=/custom/boost/
$ cmake -D BOOST_ROOT=/custom/boost
```

或者,可以同时传递包含头文件的`BOOST_INCLUDEDIR`变量和库目录的`BOOST_LIBRARYDIR`变量:
Expand Down
2 changes: 1 addition & 1 deletion content/chapter3/3.9-chinese.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,5 @@ pkg_search_module(

这里,第一个参数是前缀,它将用于命名存储搜索ZeroMQ库结果的目标:`PkgConfig::ZeroMQ`。注意,我们需要为系统上的库名传递不同的选项:`libzeromq``libzmq``lib0mq`。这是因为不同的操作系统和包管理器,可为同一个包选择不同的名称。

**NOTE**:*`pkg_check_modules``pkg_search_module`函数添加了`IMPORTED_TARGET`选项,并在CMake 3.6中定义导入目标的功能。3.6之前的版本,只定义了变量`ZeroMQ_INCLUDE_DIRS`(用于include目录)和`ZeroMQ_LIBRARIES(`用于链接库),供后续使用。*
**NOTE**:*`pkg_check_modules``pkg_search_module`函数添加了`IMPORTED_TARGET`选项,并在CMake 3.6中定义导入目标的功能。3.6之前的版本,只定义了变量`ZeroMQ_INCLUDE_DIRS`(用于include目录)和`ZeroMQ_LIBRARIES`(用于链接库),供后续使用。*

0 comments on commit 42f2ce3

Please sign in to comment.