Linux
Linux software install
Google repo的使用
Vector AP StartApplication编译脚本解析
Yocto的cmake版本升级
不能自动安装的解决方式
S32G-BSP35.0-SDK使用方法
S32G从SDK生成文件系统的制作过程
Linux Samba设置
Linux添加双网卡
S32G USB-Redirector安装指南
VS code自动生成Doxygen格式注释
Linux下使用多线程下载
使用pandoc 生成带中文的pdf
minicom无法输入的问题解决办法
使用 systemd unit 添加一条路由规则
CMake 教程
步骤 1:基本起点
步骤 2:添加lib库
步骤 3:为库添加使用要求
步骤 4:添加生成器表达式
步骤 5:安装和测试
步骤 6:添加支持测试仪表板
步骤 7: 添加系统内省
步骤 8:自定义命令和生成的文
步骤 9:打包安装程序
步骤 10:选择静态库或共享库
步骤 11:添加导出配置
步骤 12:打包 Debug 和 Release
添加虚拟网卡
Vector AP 去掉防篡改校验
Vector AP startapplication编译与使用
Vector AP问题汇总
Vector AP大型项目开发流程
Vector AP EM
Vector AP 最简单的开发示例
Linux kernel 版本降级
Vector AP StartApplicaiton
startappplication-machine-design
startapplicaiton-machine-integration
amsr-vector-fs-em-executionmanager-design
amsr-vector-fs-em-executionmanager
Vector AP 复杂模型的开发
第一章 Machine和MachineDesign
第二章 Execute Manager
第三章 Log
第四章 State Manager
第五章 State Manager 源码的理解
第六章 Someip daemon
第七章 IPC Service Discovery Daemon
crond的使用方法
解决蓝牙鼠标在 Ubuntu 中单位时间内断开的问题
VPS服务器自建教程
v2rayA的客户端使用配置
GDB调试指南入门篇:揭开程序运行世界的神秘面纱
GDB调试指南高级篇:成为调试专家,掌控程序的命运
Linux安装PyQt5并配置Qt Designer
ADB 命令大全
GoogleTest(一)
GoogleTest(二)简单的TEST宏
GoogleTest(三)简单类函数测试
C++ Template
1. 函数模板
2. 类模板
3. 非类型模板参数
软件版本号规范
EPOLL
C++手札
C++ 使用{}初始化有哪些好处?
现代 C++ decltype 深入解析
函数对象(functor)
Linux性能剖析:CPU、内存、网络与I/O压力测试
AP StateManager
C++ Lambda表达式
C++ 中的Lambda表达式
Lambda 表达式语法
Lambda 表达式的示例
手动发送UDP数据包
pyqt5生成的UI界面不能输入中文
自己搭建repo镜像
摄影
Sony仿富士PP值设置
诗词歌赋
本文档使用 MrDoc 发布
-
+
首页
步骤 2:添加lib库
# 步骤 2:添加一个库 到目前为止,我们已经学习了如何使用 CMake 创建一个基本项目。在这一步中,我们将学习如何在项目中创建和使用库,并了解如何使我们的库的使用变成可选的。 ## 练习 1 - 创建一个库 要在 CMake 中添加一个库,使用 `add_library()` 命令并指定应该组成库的源文件。 与其将所有源文件放在一个目录中,不如使用一个或多个子目录来组织我们的项目。在这种情况下,我们将为我们的库创建一个专门的子目录。在这里,我们可以添加一个新的 `CMakeLists.txt` 文件和一个或多个源文件。在顶层 `CMakeLists.txt` 文件中,我们将使用 `add_subdirectory()` 命令将子目录添加到构建中。 创建库后,可以通过 `target_include_directories()` 和 `target_link_libraries()` 将其连接到我们的可执行目标。 ### Goal 添加和使用一个库 ### Helpful Resources + `add_library()` + `add_subdirectory()` + `target_include_directories()` + `target_link_libraries()` + `PROJECT_SOURCE_DIR` ### Files to Edit + `CMakeLists.txt` + `tutorial.cxx` + `MathFunctions/CMakeLists.txt` ### Getting Started 在这个练习中,我们将向我们的项目中添加一个库,其中包含我们自己实现的计算平方根的函数。可执行文件可以使用这个库而不是编译器提供的标准平方根函数。 对于这个教程,我们将把库放在一个名为 `MathFunctions` 的子目录中。该目录已经包含了头文件 `MathFunctions.h` 和 `mysqrt.h`。它们各自的源文件 `MathFunctions.cxx` 和 `mysqrt.cxx` 也已提供。我们不需要修改这些文件。`mysqrt.cxx` 有一个名为 `mysqrt` 的函数,提供了类似于编译器的 `sqrt` 函数的功能。`MathFunctions.cxx` 包含一个名为 `sqrt` 的函数,用于隐藏 `sqrt` 的实现细节。 从 `Help/guide/tutorial/Step2` 目录开始,完成 `TODO 1` 到 `TODO 6`。 首先,在 `MathFunctions` 子目录中填写一行 `CMakeLists.txt`。 接下来,编辑顶层的 `CMakeLists.txt`。 最后,在 `tutorial.cxx` 中使用新创建的 `MathFunctions` 库。 ### Build and Run 运行 `cmake` 可执行文件或 `cmake-gui` 来配置项目,然后使用您选择的构建工具构建项目。 以下是从命令行执行的示例: ```shell mkdir Step2_build cd Step2_build cmake ../Step2 cmake --build . ``` 尝试使用新构建的 `Tutorial` 并确保它仍然产生准确的平方根值。 ### Solution 在`MathFunctions`目录中的`CMakeLists.txt`文件中,我们使用`add_library()` 创建一个名为`MathFunctions`的库目标。库的源文件作为参数传递给`add_library()`。示例如下所示: #### TODO 1: MathFunctions/CMakeLists.txt ```cmake add_library(MathFunctions MathFunctions.cxx mysqrt.cxx) ``` 为了使用新的库,我们将在顶层`CMakeLists.txt`文件中添加一个`add_subdirectory()` 调用,以便构建该库。 #### TODO 2: CMakeLists.txt ```cmake add_subdirectory(MathFunctions) ``` 接下来,使用 `target_link_libraries()` 将新的库目标链接到可执行目标。 #### TODO 3: CMakeLists.txt ```cmake target_link_libraries(Tutorial PUBLIC MathFunctions) ``` 最后,我们需要指定库的头文件位置。修改现有的 `target_include_directories()` 调用,将 `MathFunctions` 子目录添加为一个包含目录,以便可以找到 `MathFunctions.h` 头文件。 #### TODO 4: CMakeLists.txt ```cmake target_include_directories(Tutorial PUBLIC "${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/MathFunctions" ) ``` 现在我们来使用库。 在 `tutorial.cxx`, 中include `MathFunctions.h`: #### TODO 5: tutorial.cxx ```cmake #include "MathFunctions.h" ``` 最后, 用 `mathfunctions::sqrt` 替换 `sqrt` 。 #### TODO 6: tutorial.cxx ```cpp const double outputValue = mathfunctions::sqrt(inputValue); ``` ## Exercise 2 - Adding an Option 现在让我们在 `MathFunctions` 库中添加一个选项,允许开发者选择使用自定义的平方根实现还是内置的标准实现。虽然对于本教程实际上没有这样的需求,但对于更大的项目来说,这是一种常见的情况。 CMake 可以使用 `option()` 命令来实现这一点。这给用户一个变量,他们可以在配置他们的 cmake 构建时更改。此设置将存储在缓存中,以便用户无需每次在构建目录上运行 CMake 时都设置该值。 ### Goal 添加一个选项,允许在不使用 MathFunctions 的情况下构建。 ### Helpful Resources + `if()` + `option()` + `target_compile_definitions()` ### Files to Edit + `MathFunctions/CMakeLists.txt` + `MathFunctions/MathFunctions.cxx` ### Getting Started 从练习1的结果文件开始。完成 `TODO 7` 到 `TODO 14`。 首先,在 `MathFunctions/CMakeLists.txt` 中使用 `option()` 命令创建一个名为 `USE_MYMATH` 的变量。在同一个文件中,使用该选项向 `MathFunctions` 库传递一个编译定义。 然后,根据 `USE_MYMATH` 更新 `MathFunctions.cxx` 以根据其进行编译重定向。 最后,通过将其置于 `MathFunctions/CMakeLists.txt` 中 `USE_MYMATH` 块的内部,防止在 `USE_MYMATH` 打开时编译 `mysqrt.cxx`。 ### Build and Run 由于我们已经在练习1中配置了构建目录,因此我们可以通过简单地调用以下命令来重新构建: ```shell cd ../Step2_build cmake --build . ``` 接下来,对几个数字运行`Tutorial`可执行文件以验证其是否仍然正确。 现在让我们将`USE_MYMATH`的值更新为`OFF`。最简单的方法是使用[`cmake-gui`](../../manual/cmake-gui.1.html#manual:cmake-gui(1) "cmake-gui(1)")或者在终端中使用[`ccmake`](../../manual/ccmake.1.html#manual:ccmake(1) "ccmake(1)")。或者,如果你想从命令行更改选项,请尝试: ```shell cmake ../Step2 -DUSE_MYMATH=OFF ``` 现在,请使用以下命令重新构建代码: ```shell cmake --build . ``` 然后,再次运行可执行文件,确保它在`USE_MYMATH`设置为`OFF`时仍然能够正常工作。哪个函数提供了更好的结果,`sqrt`还是`mysqrt`? ### Solution 首先,添加一个选项到 `MathFunctions/CMakeLists.txt` 文件中。该选项将在 `cmake-gui` 和 `ccmake` 中显示,并且默认值为 `ON`,用户可以修改该值。 #### TODO 7: MathFunctions/CMakeLists.txt ```cmake option(USE_MYMATH "Use tutorial provided math implementation" ON) ``` 接下来,使用这个新选项来条件性地构建和链接我们的库,使用 `mysqrt` 函数。 创建一个 `if()` 语句来检查 `USE_MYMATH` 的值。在 `if()` 块内部,使用 `target_compile_definitions()` 命令,添加编译定义 `USE_MYMATH`。 #### TODO 8: MathFunctions/CMakeLists.txt ```cmake if (USE_MYMATH) target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH") endif() ``` 当 `USE_MYMATH` 是 `ON` 时,编译定义 `USE_MYMATH` 将被设置。然后,我们可以使用这个编译定义来启用或禁用源代码的部分。 源代码的相应更改非常简单。在 `MathFunctions.cxx` 中,我们让 `USE_MYMATH` 控制使用哪个平方根函数: #### TODO 9: MathFunctions/MathFunctions.cxx ```cmake #ifdef USE_MYMATH return detail::mysqrt(x); #else return std::sqrt(x); #endif ``` 接下来,如果定义了 `USE_MYMATH`,我们需要包含 `mysqrt.h`。 #### TODO 10: MathFunctions/MathFunctions.cxx ```cpp #ifdef USE_MYMATH #include "mysqrt.h" #endif ``` 最后,由于我们正在使用 `std::sqrt`,我们现在需要包含 `cmath`。 #### TODO 11 : MathFunctions/MathFunctions.cxx ```cpp #include <cmath> ``` 此时,如果 `USE_MYMATH` 是 `OFF`,`mysqrt.cxx` 将不会被使用,但它仍然会被编译,因为 `MathFunctions` 目标在源文件中列出了 `mysqrt.cxx`。 有几种方法可以解决这个问题。第一种选择是使用 `target_sources()` 在 `USE_MYMATH` 块中添加 `mysqrt.cxx`。另一个选项是在 `USE_MYMATH` 块中创建一个额外的库,负责编译 `mysqrt.cxx`。对于本教程而言,我们将创建一个额外的库。 首先,在 `USE_MYMATH` 中创建一个名为 `SqrtLibrary` 的库,其源文件为 `mysqrt.cxx`。 #### TODO 12 : MathFunctions/CMakeLists.txt ```cmake add_library(SqrtLibrary STATIC mysqrt.cxx ) # TODO 6: Link SqrtLibrary to tutorial_compiler_flags target_link_libraries(MathFunctions PRIVATE SqrtLibrary) ``` 接下来,当启用 `USE_MYMATH` 时,我们将 `SqrtLibrary` 链接到 `MathFunctions` 上。 #### TODO 13 : MathFunctions/CMakeLists.txt ```cmake target_link_libraries(MathFunctions PRIVATE SqrtLibrary) ``` 最后,我们可以从 `MathFunctions` 库的源代码列表中删除 `mysqrt.cxx`,因为在包含 `SqrtLibrary` 时它会被引入。 #### TODO 14 : MathFunctions/CMakeLists.txt ```cmake add_library(MathFunctions MathFunctions.cxx) ``` 通过这些更改,`mysqrt` 函数现在完全是可选的,可以由构建和使用 `MathFunctions` 库的人来控制。用户可以切换 `USE_MYMATH` 来操作构建中使用的库。
admin
2024年3月1日 11:15
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码