当前位置: 首页 > article >正文

CMake 教程(五):安装和测试

通常,只构建出可执行程序是不够的,还需要能够安装可执行程序。在 CMake 中,我们可以使用 install() 指令指明安装规则。这条指令能够用来指明安装的程序、位置和文件。

本节使用的源代码材料是官网的 Step5 目录。下面开始本节的练习。

练习1:安装规则(Install Rules)

本项目的安装规则如下:

  • 对于 MathFunctions,需要将库和头文件分别安装到 libinclude 目录当中。
  • 对于 Tutorial 可执行文件,需要把可执行文件和配置头文件分别安装到 bininclude 目录当中。

首先,修改 MathFunctions/CMakeLists.txt 文件:

set(installable_libs MathFunctions tutorial_compiler_flags)
if(TARGET SqrtLibrary)
  list(APPEND installable_libs SqrtLibrary)
endif()
install(TARGETS ${installable_libs} DESTINATION lib)

install(FILES MathFunctions.h DESTINATION include)

上面指令的文字翻译:
• 首先,定义了一个要安装的目标库列表 installable_libs,包含 MathFunctionstutorial_compiler_flags
• 然后,判断是否存在名为 SqrtLibrary 的目标,如果存在,将它追加到 installable_libs 中。
• 最后,将 installable_libs 列表中的所有目标安装到 lib 目录下。

在顶层目录的 CMake 文件,我们需要做出如下修改:

install(TARGETS Tutorial DESTINATION bin)
install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
  DESTINATION include
  )

构建和安装

接下来,我们使用带有 --install 选项的 cmake 指令安装。

  • cmake --install .:会把头文件、库和可执行文件安装到合适的目录当中,通常是系统目录:
    使用 cmake 指令安装程序时,需要以 sudo 权限。否则,会报出复制文件权限不足的错误。
    在这里插入图片描述
    或者,我们在使用 cmake 命令时,指定安装的目录为不需要 sudo 权限就可以写的目录。
    使用命令:
cmake --install . --prefix  "/home/coder/installdir/"

执行结果如下:
在这里插入图片描述
在这里插入图片描述

  • cmake --install . --config Release:对于多配置工具,需要用参数 --config 指明配置。

练习2:测试支持(Testing Support)

题解步骤

CTest 为项目提供了测试支持。可以通过 add_test() 指令添加测试。本节练习我们使用 CTest 编写简单的测试用例,需要完成 TODO5TODO9

首先,我们需要启用测试。然后,使用 add_test() 指令添加几条简单的测试。下面是详细的步骤说明。

在顶层的 CMakeLists.txt 文件当中,需要我们启用测试:

enable_testing()

然后,添加几个基本的测试用以验证应用程序能够正确地运行。首先,添加一条测试,这条测试以参数 25 运行可执行文件 Tutorial。我们并不打算用这条测试验证程序的计算结果。该测试只是用来验证程序可以正常运行,例如不会发生段错误或者其他的崩溃。

add_test(NAME Runs COMMAND Tutorial 25)

接着,使用 PASS_REGULAR_EXPRESSION 测试属性来验证测试的输出包括了必要的字符串。在本例中,当提供了不正确的参数时,应该打印用法信息。

add_test(NAME Usage COMMAND Tutorial)
set_tests_properties(Usage
  PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number"
  )

插播介绍一下上面两条指令的含义。

  1. add_test(NAME StandardUse COMMAND Tutorial 4)

    add_test() 是 CMake 中用于添加测试的命令。
    NAME StandardUse:给这个测试命名为 StandardUse,这个名字会在后续调用测试时使用。
    COMMAND Tutorial 4:指定测试时运行的命令。在这个例子中,命令是运行 Tutorial 程序,并传递参数 4。也就是说,运行 Tutorial 4 这个命令。

  2. set_tests_properties(StandardUse PROPERTIES PASS_REGULAR_EXPRESSION "4 is 2")

    set_tests_properties() 用于为特定测试设置属性。
    StandardUse:这是要设置属性的测试的名称(在这里就是前面定义的 StandardUse 测试)。
    PROPERTIES PASS_REGULAR_EXPRESSION "4 is 2":这是为测试指定属性,PASS_REGULAR_EXPRESSION 表示通过测试的正则表达式。这意味着该测试的输出中必须包含字符串 “4 is 2”,否则测试会失败。

下一步需要验证的是程序的计算值等于它的真正的平方根。

add_test(NAME StandardUse COMMAND Tutorial 4)
set_tests_properties(StandardUse
  PROPERTIES PASS_REGULAR_EXPRESSION "4 is 2"
  )

当然仅仅编写这几个测试是远远不够的。为了容易地添加更多的测试,写了一个叫做 do_test() 的函数,用来运行应用程序并验证给定输入平方根的值是否正确。do_test() 函数是在 cmake 文件当中定义的,函数的参数是名称、输入和期望的结果。

function(do_test target arg result)
  add_test(NAME Comp${arg} COMMAND ${target} ${arg})
  set_tests_properties(Comp${arg}
    PROPERTIES PASS_REGULAR_EXPRESSION ${result}
    )
endfunction()

# do a bunch of result based tests
do_test(Tutorial 4 "4 is 2")
do_test(Tutorial 9 "9 is 3")
do_test(Tutorial 5 "5 is 2.236")
do_test(Tutorial 7 "7 is 2.645")
do_test(Tutorial 25 "25 is 5")
do_test(Tutorial -25 "-25 is (-nan|nan|0)")
do_test(Tutorial 0.0001 "0.0001 is 0.01")

构建和运行

进入到 Step5_build 目录并重新构建程序。接着,运行 ctest 可执行文件:ctest -Nctest -VV。对于多配置的生成器(例如:Visual Studio),配置类型必须用 -C <mode> 指定。例如,以 Debug 模式运行所有的测试,在 build 目录需要使用命令 ctest -C Debug -VV。发行模式需要在 build 目录使用 -C Release
ctest -N 可以用来查看都有哪些测试:
在这里插入图片描述
ctest -VV 用来运行所有测试,与此同时,输出每次测试的详细信息:
在这里插入图片描述
执行 ctest 会得到所有测出的执行结果:
在这里插入图片描述
如果只想执行某个测试用例,可以使用命令 ctest -R 测试用例名,例如 ctest -R Comp9
在这里插入图片描述

最后,放上本文修改后的 CMake 文件。
顶层的 CMake 文件:

cmake_minimum_required(VERSION 3.15)

# set the project name and version
project(Tutorial VERSION 1.0)

# specify the C++ standard
add_library(tutorial_compiler_flags INTERFACE)
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)

# add compiler warning flags just when building this project via
# the BUILD_INTERFACE genex
set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
target_compile_options(tutorial_compiler_flags INTERFACE
  "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
  "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
)

# configure a header file to pass some of the CMake settings
# to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h)

# add the MathFunctions library
add_subdirectory(MathFunctions)

# add the executable
add_executable(Tutorial tutorial.cxx)

target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)

# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
target_include_directories(Tutorial PUBLIC
                           "${PROJECT_BINARY_DIR}"
                           )

# TODO 3: Install Tutorial in the bin directory
# Hint: Use the TARGETS and DESTINATION parameters
# Target后跟要安装的目标,DESTINATION后跟安装到的目录
install(TARGETS Tutorial DESTINATION bin)
# TODO 4: Install TutorialConfig.h to the include directory
# Hint: Use the FILES and DESTINATION parameters
install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
        DESTINATION include)
# TODO 5: Enable testing
enable_testing()
# TODO 6: Add a test called Runs which runs the following command:
# $ Tutorial 25
add_test(NAME Runs COMMAND Tutorial 25)
# TODO 7: Add a test called Usage which runs the following command:
# $ Tutorial
# Make sure the expected output is displayed.
# Hint: Use the PASS_REGULAR_EXPRESSION property with "Usage.*number"
add_test(NAME Usage COMMAND Tutorial)
set_tests_properties(Usage
  PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number"
  )
# TODO 8: Add a test which runs the following command:
# $ Tutorial 4
# Make sure the result is correct.
# Hint: Use the PASS_REGULAR_EXPRESSION property with "4 is 2"
add_test(NAME StandardUse COMMAND Tutorial 4)
set_tests_properties(StandardUse
  PROPERTIES PASS_REGULAR_EXPRESSION "4 is 2"
  )
# TODO 9: Add more tests. Create a function called do_test to avoid copy +
# paste. Test the following values: 4, 9, 5, 7, 25, -25 and 0.0001.
function(do_test target arg result)
  add_test(NAME Comp${arg} COMMAND ${target} ${arg})
  set_tests_properties(Comp${arg}
    PROPERTIES PASS_REGULAR_EXPRESSION ${result}
    )
endfunction()

# do a bunch of result based tests
do_test(Tutorial 4 "4 is 2")
do_test(Tutorial 9 "9 is 3")
do_test(Tutorial 5 "5 is 2.236")
do_test(Tutorial 7 "7 is 2.645")
do_test(Tutorial 25 "25 is 5")
do_test(Tutorial -25 "-25 is (-nan|nan|0)")
do_test(Tutorial 0.0001 "0.0001 is 0.01")

MathFunctions 目录下 CMake 文件:

add_library(MathFunctions MathFunctions.cxx)

# state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't.
target_include_directories(MathFunctions
                           INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
                           )

# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
if (USE_MYMATH)
  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")

  # library that just does sqrt
  add_library(SqrtLibrary STATIC
              mysqrt.cxx
              )

  # link SqrtLibrary to tutorial_compiler_flags
  target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)

  target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()

# link MathFunctions to tutorial_compiler_flags
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)

# TODO 1: Create a variable called installable_libs that is a list of all
# libraries we want to install (e.g. MathFunctions and tutorial_compiler_flags)
# Then install the installable libraries to the lib folder.
# Hint: Use the TARGETS and DESTINATION parameters
set(installable_libs MathFunctions tutorial_compiler_flags)
if(TARGET SqrtLibrary)
  list(APPEND installable_libs SqrtLibrary)
endif()
install(TARGETS ${installable_libs} DESTINATION lib)
# TODO 2: Install the library headers to the include folder.
# Hint: Use the FILES and DESTINATION parameters
install(FILES MathFunctions.h DESTINATION include)

各位道友,码字不易,如有收获,记得一键三连啊。
看完觉得有帮助的道友,可以关注我的公众号,里面会分享一些高质量的个人成长类读书笔记、生活随笔以及职场经验等等。
在这里插入图片描述


http://www.kler.cn/a/316488.html

相关文章:

  • 阅读2020-2023年《国外军用无人机装备技术发展综述》笔记_技术趋势
  • 大数据开发面试宝典
  • JQuery封装的ajax
  • 数据结构-集合
  • ReactPress技术揭秘
  • 深度学习之 LSTM
  • [全网首篇]关于 VMSA-2024-0019 安全公告(CVE-2024-38812、CVE-2024-38813)的说明与解决方案
  • 【系统架构设计师】软件架构的概念(经典习题)
  • Vue3.5+ 更新 - 模板引用
  • 【Go】Go语言中深拷贝和浅拷贝
  • PlantUML的使用以及各种图表示例
  • HOJ网站开启https访问 申请免费SSL证书 部署证书详细操作指南
  • 无法将ggplot图保存为PDF文件怎么办
  • 数组高阶应用(C++版)
  • TypeError: expected string or buffer - Langchain, OpenAI Embeddings
  • 力扣3290.最高乘法得分
  • 【PHP小课堂】PHP中的函数相关处理方法学习
  • 【计算机网络 - 基础问题】每日 3 题(十六)
  • 目标检测:滑块验证
  • 2012年408考研真题-数据结构
  • 领夹麦克风哪个品牌好,无线领夹麦克风品牌排名,麦克风品牌大全
  • Python ORM 框架 SQLModel 快速入门教程
  • 每日一道算法题(二)—快乐数
  • STaR: Bootstrapping Reasoning With Reasoning
  • Android 如何实现搜索功能:本地搜索?数据模型如何设计?数据如何展示和保存?
  • 基于YOLOv8+LSTM的商超扶梯场景下行人安全行为姿态检测识别