From 05acd0bae2044d886a722538de2e3f815e2a8cef Mon Sep 17 00:00:00 2001 From: xiaowei Date: Sat, 19 Oct 2019 21:39:51 +0800 Subject: [PATCH] update chapter 10 --- content/chapter10/10.1-chinese.md | 53 +++++++++++++------------- content/chapter10/10.2-chinese.md | 8 ++-- content/chapter10/10.3-chinese.md | 62 +++++++++++++++---------------- content/chapter10/10.4-chinese.md | 38 +++++++++---------- 4 files changed, 81 insertions(+), 80 deletions(-) diff --git a/content/chapter10/10.1-chinese.md b/content/chapter10/10.1-chinese.md index 1b7b8fe..15e83d4 100644 --- a/content/chapter10/10.1-chinese.md +++ b/content/chapter10/10.1-chinese.md @@ -12,15 +12,15 @@ . ├── CMakeLists.txt ├── src -│ ├── CMakeLists.txt -│ ├── hello-world.cpp -│ ├── Message.cpp -│ └── Message.hpp +│ ├── CMakeLists.txt +│ ├── hello-world.cpp +│ ├── Message.cpp +│ └── Message.hpp └── tests - └── CMakeLists.txt + └── CMakeLists.txt ``` -我们已经看到,有三个CMakeLists.txt,一个是主CMakeLists.txt,另一个是位于src目录下的,还有一个是位于test目录下的。 +我们已经看到,有三个`CMakeLists.txt`,一个是主`CMakeLists.txt`,另一个是位于`src`目录下的,还有一个是位于`test`目录下的。 ` Message.hpp`头文件包含以下内容: @@ -100,7 +100,7 @@ int main() ## 具体实施 -我们先来看一下主CMakeLists.txt: +我们先来看一下主`CMakeLists.txt`: 1. 声明CMake最低版本,并定义一个C++11项目。请注意,我们已经为我们的项目设置了一个版本,在`project`中使用`VERSION`进行指定: @@ -172,7 +172,7 @@ int main() endforeach() ``` -7. 主CMakeLists.txt文件中的最后一个指令添加`src`子目录,启用测试,并添加`tests`子目录: +7. 主`CMakeLists.txt`文件中的最后一个指令添加`src`子目录,启用测试,并添加`tests`子目录: ```cmake add_subdirectory(src) @@ -304,7 +304,7 @@ int main() ) ``` -`tests`目录中的CMakeLists.txt文件包含简单的指令,以确保“Hello, World”可执行文件能够正确运行: +`tests`目录中的`CMakeLists.txt`文件包含简单的指令,以确保“Hello, World”可执行文件能够正确运行: ```cmake add_test( @@ -327,15 +327,15 @@ GNU/Linux构建目录的内容如下: ```shell build ├── bin -│ └── hello-world_wDSO +│ └── hello-world_wDSO ├── CMakeCache.txt ├── CMakeFiles ├── cmake_install.cmake ├── CTestTestfile.cmake ├── install_manifest.txt ├── lib64 -│ ├── libmessage.so -> libmessage.so.1 -│ └── libmessage.so.1 +│ ├── libmessage.so -> libmessage.so.1 +│ └── libmessage.so.1 ├── Makefile ├── src ├── Testing @@ -347,13 +347,13 @@ build ```shell $HOME/Software/recipe-01/ ├── bin -│ └── hello-world_wDSO +│ └── hello-world_wDSO ├── include -│ └── message -│ └── Message.hpp +│ └── message +│ └── Message.hpp └── lib64 - ├── libmessage.so -> libmessage.so.1 - └── libmessage.so.1 + ├── libmessage.so -> libmessage.so.1 + └── libmessage.so.1 ``` 这意味着安装指令中给出的位置,是相对于用户给定的`CMAKE_INSTALL_PREFIX`路径。 @@ -370,11 +370,11 @@ $HOME/Software/recipe-01/ 对于项目的安装来说,什么是好的布局呢?如果只有自己使用该项目,那就无所谓好或坏的布局。然而,一旦向外部发布产品,和他人共用该项目,就应该在安装项目时提供一个合理的布局。幸运的是,我们可以遵循一些标准,CMake可以帮助我们做到这一点。实际上,`GNUInstallDirs.cmake `模块所做的就是定义这样一组变量,这些变量是安装不同类型文件的子目录的名称。在例子中,使用了以下内容: -* CMAKE_INSTALL_BINDIR:这将用于定义用户可执行文件所在的子目录,即所选安装目录下的`bin`目录。 -* CMAKE_INSTALL_LIBDIR:这将扩展到目标代码库(即静态库和动态库)所在的子目录。在64位系统上,它是`lib64`,而在32位系统上,它只是`lib`。 -* CMAKE_INSTALL_INCLUDEDIR:最后,我们使用这个变量为C头文件获取正确的子目录,该变量为`include`。 +* ***CMAKE_INSTALL_BINDIR**:这将用于定义用户可执行文件所在的子目录,即所选安装目录下的`bin`目录。 +* **CMAKE_INSTALL_LIBDIR**:这将扩展到目标代码库(即静态库和动态库)所在的子目录。在64位系统上,它是`lib64`,而在32位系统上,它只是`lib`。 +* **CMAKE_INSTALL_INCLUDEDIR**:最后,我们使用这个变量为C头文件获取正确的子目录,该变量为`include`。 -然而,用户可能希望覆盖这些选项。我们允许在主CMakeLists.txt文件中使用以下方式覆盖选项: +然而,用户可能希望覆盖这些选项。我们允许在主`CMakeLists.txt`文件中使用以下方式覆盖选项: ```cmake # Offer the user the choice @@ -396,7 +396,7 @@ PATH "Installation directory for header files") 让我们更仔细地看看在动态库目标上设置的属性,需要设置以下内容: * `POSITION_INDEPENDENT_CODE 1`:设置生成位置无关代码所需的编译器标志。有关更多信息,请参考https://en.wikipedia.org/wiki/position-independentent_code -* `SOVERSION ${PROJECT_VERSION_MAJOR}` : 这是动态库提供的应用程序编程接口(API)版本。在、设置语义版本之后,将其设置为与项目的主版本一致。CMake目标也有一个版本属性,可以用来指定目标的构建版本。注意,`SOVERSION`和`VERSION`有所不同:随着时间的推移,提供相同API的多个构建版本。本例中,我们不关心这种的粒度控制:仅使用`SOVERSION`属性设置API版本就足够了,CMake将为我们将`VERSION`设置为相同的值。相关详细信息,请参考官方文档:https://cmake.org/cmake/help/latest/prop_tgt/SOVERSION.html +* `SOVERSION ${PROJECT_VERSION_MAJOR}` : 这是动态库提供的应用程序编程接口(API)版本。在设置语义版本之后,将其设置为与项目的主版本一致。CMake目标也有一个版本属性,可以用来指定目标的构建版本。注意,`SOVERSION`和`VERSION`有所不同:随着时间的推移,提供相同API的多个构建版本。本例中,我们不关心这种的粒度控制:仅使用`SOVERSION`属性设置API版本就足够了,CMake将为我们将`VERSION`设置为相同的值。相关详细信息,请参考官方文档:https://cmake.org/cmake/help/latest/prop_tgt/SOVERSION.html * `OUTPUT_NAME "message"`:这告诉CMake库的名称`message`,而不是目标` message-shared `的名称,` libmessage.so.1 `将在构建时生成。从前面给出的构建目录和安装目录的也可以看出,` libmessage.so`的符号链接也将生成。 * `DEBUG_POSTFIX "_d" `:这告诉CMake,如果我们以Debug配置构建项目,则将`_d`后缀添加到生成的动态库。 * `PUBLIC_HEADER "Message.hpp"`:我们使用这个属性来设置头文件列表(本例中只有一个头文件),声明提供的API函数。这主要用于macOS上的动态库目标,也可以用于其他操作系统和目标。有关详细信息,请参见官方文档:https://cmake.org/cmake/help/v3.6/prop_tgt/PUBLIC_HEADER.html @@ -512,7 +512,8 @@ libmessage.so.1 => /home/roberto/Software/ch10r01/bin/../lib64/libmessage.so.1 ( 我们使用了带有目标参数的CMake安装命令,因为我们需要安装构建目标。而该命令还有另外4个参数: -* `FILES`和`PROGRAMS`,分别用于安装文件或程序。安装后,并设置安装文件适当的权限。对于文件,对所有者具有读和写权限,对组以及其他用户和组具有读权限。对于程序,将授予执行权限。注意,`PROGRAMS`要与非构建目标的可执行程序一起使用。参见: https://cmake.org/cmake/help/v3.6/command/install.html#installing-files -* `DIRECTORY`,用于安装目录。当只给出一个目录名时,它通常被理解为相对于当前源目录。可以对目录的安装粒度进行控制。请参考在线文档: https://cmake.org/cmake/help/v3.6/command/install.html#installing-directories -* `SCRIPT`,可以使用它在CMake脚本中定义自定义安装规则。参见: https://cmake.org/cmake/help/v3.6/command/install.html#custom-installation-logic -* `EXPORT`,我们将此参数的讨论推迟到第3节,该参数用于导出目标。 \ No newline at end of file +* **FILES**和**PROGRAMS**,分别用于安装文件或程序。安装后,并设置安装文件适当的权限。对于文件,对所有者具有读和写权限,对组以及其他用户和组具有读权限。对于程序,将授予执行权限。注意,`PROGRAMS`要与非构建目标的可执行程序一起使用。参见: https://cmake.org/cmake/help/v3.6/command/install.html#installing-files +* **DIRECTORY**,用于安装目录。当只给出一个目录名时,它通常被理解为相对于当前源目录。可以对目录的安装粒度进行控制。请参考在线文档: https://cmake.org/cmake/help/v3.6/command/install.html#installing-directories +* **SCRIPT**,可以使用它在CMake脚本中定义自定义安装规则。参见: https://cmake.org/cmake/help/v3.6/command/install.html#custom-installation-logic +* **EXPORT**,我们将此参数的讨论推迟到第3节,该参数用于导出目标。 + diff --git a/content/chapter10/10.2-chinese.md b/content/chapter10/10.2-chinese.md index e296f66..c934e73 100644 --- a/content/chapter10/10.2-chinese.md +++ b/content/chapter10/10.2-chinese.md @@ -43,7 +43,7 @@ std::string getUUID(); ## 具体实施 -除了项目的名称外,主CMakeLists.txt文件没有改变。首先,看看`src`子目录中的CMakeLists.txt文件,所有工作实际上都在这里进行。我们将重点展示对之前示例的修改之处: +除了项目的名称外,主`CMakeLists.txt`文件没有改变。首先,看看`src`子目录中的`CMakeLists.txt`文件,所有工作实际上都在这里进行。我们将重点展示对之前示例的修改之处: 1. 为消息传递库声明`SHARED`库目标及其源。注意,编译定义和链接库没有改变: @@ -139,7 +139,7 @@ std::string getUUID(); ) ``` -3. 我们还设置了` message-static `目标的属性。这些将在下一节讨论: +3. 还设置了` message-static `目标的属性: ```cmake set_target_properties(message-static @@ -152,7 +152,7 @@ std::string getUUID(); ) ``` -4. 除了链接到消息动态库目标的`hello-world_wDSO`可执行目标之外,我们还定义了另一个可执行目标`hello-world_wAR`,这个链接指向静态库: +4. 除了链接到消息动态库目标的`hello-world_wDSO`可执行目标之外,还定义了另一个可执行目标`hello-world_wAR`,这个链接指向静态库: ```cmake add_executable(hello-world_wAR hello-world.cpp) @@ -189,7 +189,7 @@ std::string getUUID(); ## 工作原理 -此示例演示了,如何设置动态库的符号可见性。最好的方式是在默认情况下隐藏所有符号,显式地只公开那些需要使用的符号。这需要分为两步实现。首先,需要指示编译器隐藏符号。当然,不同的编译器将有不同的可用选项,并且直接在CMakeLists.txt中设置这些选项并不是是跨平台的。CMake通过在动态库目标上设置两个属性,提供了一种健壮的跨平台方法来设置符号的可见性: +此示例演示了,如何设置动态库的符号可见性。最好的方式是在默认情况下隐藏所有符号,显式地只公开那些需要使用的符号。这需要分为两步实现。首先,需要指示编译器隐藏符号。当然,不同的编译器将有不同的可用选项,并且直接在`CMakeLists.txt`中设置这些选项并不是是跨平台的。CMake通过在动态库目标上设置两个属性,提供了一种健壮的跨平台方法来设置符号的可见性: * `CXX_VISIBILITY_PRESET hidden`:这将隐藏所有符号,除非显式地标记了其他符号。当使用GNU编译器时,这将为目标添加`-fvisibility=hidden`标志。 * `VISIBILITY_INLINES_HIDDEN 1`:这将隐藏内联函数的符号。如果使用GNU编译器,这对应于` -fvisibility-inlines-hidden ` diff --git a/content/chapter10/10.3-chinese.md b/content/chapter10/10.3-chinese.md index f9ff133..6d4ca19 100644 --- a/content/chapter10/10.3-chinese.md +++ b/content/chapter10/10.3-chinese.md @@ -11,25 +11,25 @@ ```shell . ├── cmake -│ └── messageConfig.cmake.in +│ └── messageConfig.cmake.in ├── CMakeLists.txt ├── src -│ ├── CMakeLists.txt -│ ├── hello- world.cpp -│ ├── Message.cpp -│ └── Message.hpp +│ ├── CMakeLists.txt +│ ├── hello- world.cpp +│ ├── Message.cpp +│ └── Message.hpp └── tests - ├── CMakeLists.txt - └── use_target - ├── CMakeLists.txt - └── use_message.cpp + ├── CMakeLists.txt + └── use_target + ├── CMakeLists.txt + └── use_message.cpp ``` 注意,cmake子目录中添加了一个`messageConfig.cmake.in`。这个文件将包含导出的目标,还添加了一个测试来检查项目的安装和导出是否按预期工作。 ## 具体实施 -同样,主CMakeLists.txt文件相对于前一个示例来说没有变化。移动到包含我们的源代码的子目录`src`中: +同样,主`CMakeLists.txt`文件相对于前一个示例来说没有变化。移动到包含我们的源代码的子目录`src`中: 1. 需要找到UUID库,可以重用之前示例中的代码: @@ -160,7 +160,7 @@ ) ``` -2. 自动生成的导出目标文件称为` messageTargets.cmake`,需要显式地指定它的安装规则。这个文件的目标是`INSTALL_CMAKEDIR`,在主CMakeLists.txt文件中定义: +2. 自动生成的导出目标文件称为` messageTargets.cmake`,需要显式地指定它的安装规则。这个文件的目标是`INSTALL_CMAKEDIR`,在主`CMakeLists.txt`文件中定义: ```cmake install( @@ -263,26 +263,26 @@ $ cmake --build . --target install ```shell $HOME/Software/recipe-03/ ├── bin -│ ├── hello-world_wAR -│ └── hello-world_wDSO +│ ├── hello-world_wAR +│ └── hello-world_wDSO ├── include -│ └── message -│ ├── messageExport.h -│ └── Message.hpp +│ └── message +│ ├── messageExport.h +│ └── Message.hpp ├── lib64 -│ ├── libmessage_s.a -│ ├── libmessage.so -> libmessage.so.1 -│ └── libmessage.so.1 +│ ├── libmessage_s.a +│ ├── libmessage.so -> libmessage.so.1 +│ └── libmessage.so.1 └── share - └── cmake - └── recipe-03 - ├── messageConfig.cmake - ├── messageConfigVersion.cmake - ├── messageTargets.cmake - └── messageTargets-release.cmake + └── cmake + └── recipe-03 + ├── messageConfig.cmake + ├── messageConfigVersion.cmake + ├── messageTargets.cmake + └── messageTargets-release.cmake ``` -出现了一个`share`子目录,其中包含我们要求CMake自动生成的所有文件。现在开始,消息库的用户可以在他们自己的CMakeLists.txt文件中找到消息库,只要他们设置`message_DIR `的CMake变量,指向安装树中的`share/cmake/message`目录: +出现了一个`share`子目录,其中包含我们要求CMake自动生成的所有文件。现在开始,消息库的用户可以在他们自己的`CMakeLists.txt`文件中找到消息库,只要他们设置`message_DIR `的CMake变量,指向安装树中的`share/cmake/message`目录: ```cmake find_package(message 1 CONFIG REQUIRED) @@ -301,7 +301,7 @@ find_package(message 1 CONFIG REQUIRED) 2. 描述目标的安装规则,包括生成文件的名称。 -3. 描述CMake生成的导出文件的安装规则`messageTargets.cmake`文件将安装到`INSTALL_CMAKEDIR`。目标导出文件的安装规则的名称空间选项,将把给定字符串前置到目标的名称中,这有助于避免来自不同项目的目标之间的名称冲突。`INSTALL_CMAKEDIR`变量是在主CMakeLists.txt文件中设置的: +3. 描述CMake生成的导出文件的安装规则`messageTargets.cmake`文件将安装到`INSTALL_CMAKEDIR`。目标导出文件的安装规则的名称空间选项,将把给定字符串前置到目标的名称中,这有助于避免来自不同项目的目标之间的名称冲突。`INSTALL_CMAKEDIR`变量是在主`CMakeLists.txt`文件中设置的: ```cmake if(WIN32 AND NOT CYGWIN) @@ -312,7 +312,7 @@ find_package(message 1 CONFIG REQUIRED) set(INSTALL_CMAKEDIR ${DEF_INSTALL_CMAKEDIR} CACHE PATH "Installation directory for CMake files") ``` - CMakeLists.txt的最后一部分生成配置文件。包括` CMakePackageConfigHelpers.cmake`模块,分三步完成: +`CMakeLists.txt`的最后一部分生成配置文件。包括` CMakePackageConfigHelpers.cmake`模块,分三步完成: 1. 调用`write_basic_package_version_file`函数生成一个版本文件包。宏的第一个参数是版本控制文件的路径:` messageConfigVersion.cmake`。版本格式为`Major.Minor.Patch`,并使用`PROJECT_VERSION`指定版本,还可以指定与库的新版本的兼容性。例子中,当库具有相同的主版本时,为了保证兼容性,使用了相同的`SameMajorVersion`参数。 2. 接下来,配置模板文件`messageConfig.cmake.in `,该文件位于`cmake`子目录中。 @@ -320,7 +320,7 @@ find_package(message 1 CONFIG REQUIRED) ## 更多信息 -消息库的客户现在非常高兴,因为终于可以在自己的系统上安装这个库,对自己的CMakeLists.txt进行简单的修改,就能找到消息库: +消息库的客户现在非常高兴,因为终于可以在自己的系统上安装这个库,对自己的`CMakeLists.txt`进行简单的修改,就能找到消息库: ```cmake find_package(message VERSION 1 REQUIRED) @@ -338,8 +338,8 @@ $ cmake -Dmessage_DIR=/path/to/message/share/cmake/message .. tests/ ├── CMakeLists.txt └── use_target - ├── CMakeLists.txt - └── use_message.cpp + ├── CMakeLists.txt + └── use_message.cpp ``` 这个目录包含一个使用导出目标的小项目。有趣的部分是在CMakeLists.txt文件中指定的测试: diff --git a/content/chapter10/10.4-chinese.md b/content/chapter10/10.4-chinese.md index d2566a6..cafe3dc 100644 --- a/content/chapter10/10.4-chinese.md +++ b/content/chapter10/10.4-chinese.md @@ -10,20 +10,20 @@ ```shell ├── cmake -│ ├── install_hook.cmake.in -│ └── print_rpath.py +│ ├── install_hook.cmake.in +│ └── print_rpath.py ├── CMakeLists.txt ├── external -│ └── upstream -│ ├── CMakeLists.txt -│ └── message -│ └── CMakeLists.txt +│ └── upstream +│ ├── CMakeLists.txt +│ └── message +│ └── CMakeLists.txt └── src - ├── CMakeLists.txt - └── use_message.cpp + ├── CMakeLists.txt + └── use_message.cpp ``` -主CMakeLists.txt文件配合超级构建,`external`子目录包含处理依赖项的CMake指令。`cmake`子目录包含一个Python脚本和一个模板CMake脚本。这些将用于安装方面的微调,CMake脚本首先进行配置,然后调用Python脚本打印`use_message`可执行文件的`RPATH`: +主`CMakeLists.txt`文件配合超级构建,`external`子目录包含处理依赖项的CMake指令。`cmake`子目录包含一个Python脚本和一个模板CMake脚本。这些将用于安装方面的微调,CMake脚本首先进行配置,然后调用Python脚本打印`use_message`可执行文件的`RPATH`: ```python import shlex @@ -51,7 +51,7 @@ if __name__ == "__main__": 使用平台原生工具可以轻松地打印`RPATH`,稍后我们将在本示例中讨论这些工具。 -最后,`src`子目录包含项目的CMakeLists.txt和源文件。`use_message.cpp`源文件包含以下内容: +最后,`src`子目录包含项目的`CMakeLists.txt`和源文件。`use_message.cpp`源文件包含以下内容: ```c++ #include @@ -83,7 +83,7 @@ int main() ## 具体实施 -我们将从主CMakeLists.txt文件开始,它用来协调超级构建: +我们将从主`CMakeLists.txt`文件开始,它用来协调超级构建: 1. 与之前的示例相同。首先声明一个C++11项目,设置了默认安装路径、构建类型、目标的输出目录,以及安装树中组件的布局: @@ -224,7 +224,7 @@ int main() endif() ``` -`-Dmessage_DIR=${message_DIR}`已作为CMake参数传递给项目,这将正确设置消息库依赖项的位置。`message_DIR`的值在`external/upstream/message`目录下的CMakeLists.txt文件中定义。这个文件处理依赖于消息库,让我们看看是如何处理的: +`-Dmessage_DIR=${message_DIR}`已作为CMake参数传递给项目,这将正确设置消息库依赖项的位置。`message_DIR`的值在`external/upstream/message`目录下的`CMakeLists.txt`文件中定义。这个文件处理依赖于消息库,让我们看看是如何处理的: 1. 首先,搜索并找到包。用户可能已经在系统的某个地方安装了,并在配置时传递了`message_DIR`: @@ -241,7 +241,7 @@ int main() add_library(message_external INTERFACE) # dummy ``` -3. 如果没有找到这个库,我们将把它添加为一个外部项目,从在线Git存储库下载它,然后编译它。安装路径、构建类型和安装目录布局都是由主CMakeLists.txt文件设置,C++编译器和标志也是如此。项目将安装到`STAGED_INSTALL_PREFIX`下,然后进行测试: +3. 如果没有找到这个库,我们将把它添加为一个外部项目,从在线Git存储库下载它,然后编译它。安装路径、构建类型和安装目录布局都是由主`CMakeLists.txt`文件设置,C++编译器和标志也是如此。项目将安装到`STAGED_INSTALL_PREFIX`下,然后进行测试: ```cmake else() @@ -273,7 +273,7 @@ int main() ) ``` -4. 最后,将`message_DIR`目录进行设置,为指向新构建的` messageConfig.cmake`文件指明安装路径。注意,这些路径被保存到CMakeCache中: +4. 最后,将`message_DIR`目录进行设置,为指向新构建的` messageConfig.cmake`文件指明安装路径。注意,这些路径被保存到`CMakeCache`中: ```cmake if(WIN32 AND NOT CYGWIN) @@ -454,11 +454,11 @@ int main() ## 工作原理 -CMake工具箱中,超级构建是非常有用的模式。它通过将复杂的项目划分为更小、更容易管理的子项目来管理它们。此外,可以使用CMake作为构建项目的包管理器。CMake可以搜索依赖项,如果在系统上找不到依赖项,则重新构建它们。这里需要三个CMakeLists.txt文件: +CMake工具箱中,超级构建是非常有用的模式。它通过将复杂的项目划分为更小、更容易管理的子项目来管理它们。此外,可以使用CMake作为构建项目的包管理器。CMake可以搜索依赖项,如果在系统上找不到依赖项,则重新构建它们。这里需要三个`CMakeLists.txt`文件: -* 主CMakeLists.txt文件包含项目和依赖项共享的设置,还包括我们自己的项目(作为外部项目)。本例中,我们选择的名称为`${PROJECT_NAME}_core`;也就是`recipe-04_core`,因为项目名称`recipe-04`用于超级构建。 -* 外部CMakeLists.txt文件将尝试查找上游依赖项,并在导入目标和构建目标之间进行切换,这取决于是否找到了依赖项。对于每个依赖项,最好有单独的子目录,其中包含一个CMakeLists.txt文件。 -* 最后,我们项目的CMakeLists.txt文件,可以构建一个独立的CMake项目。在原则上,我们可以自己配置和构建它,而不需要超级构建提供的依赖关系管理工具。 +* 主`CMakeLists.txt`文件包含项目和依赖项共享的设置,还包括我们自己的项目(作为外部项目)。本例中,我们选择的名称为`${PROJECT_NAME}_core`;也就是`recipe-04_core`,因为项目名称`recipe-04`用于超级构建。 +* 外部`CMakeLists.txt`文件将尝试查找上游依赖项,并在导入目标和构建目标之间进行切换,这取决于是否找到了依赖项。对于每个依赖项,最好有单独的子目录,其中包含一个`CMakeLists.txt`文件。 +* 最后,我们项目的`CMakeLists.txt`文件,可以构建一个独立的CMake项目。在原则上,我们可以自己配置和构建它,而不需要超级构建提供的依赖关系管理工具。 当对消息库的依赖关系未得到满足时,将首先考虑超级构建: @@ -540,7 +540,7 @@ install( 注意使用`.`而不是绝对路径`${CMAKE_INSTALL_PREFIX}`,这样CPack工具就可以正确理解该规则。CPack的用法将在第11章中介绍。 -`recipe-04_core`项目构建一个简单的可执行目标,该目标链接到消息动态库。正如本章前几节所讨论,为了让可执行文件正确运行,需要正确设置`RPATH`。本章的第1节展示了,如何在CMake的帮助下实现这一点,同样的模式在CMakeLists.txt中被重用,用于创建`use_message`的可执行目标: +`recipe-04_core`项目构建一个简单的可执行目标,该目标链接到消息动态库。正如本章前几节所讨论,为了让可执行文件正确运行,需要正确设置`RPATH`。本章的第1节展示了,如何在CMake的帮助下实现这一点,同样的模式在`CMakeLists.txt`中被重用,用于创建`use_message`的可执行目标: ```cmake file(RELATIVE_PATH _rel ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR} ${CMAKE_INSTALL_PREFIX})