• CMake:配置时运行自定义命令


    导言

    已经好久好久没有更新这个系列了,但是无论如何这个系列一定会以较全面的形式更新完成,只是在时间上可能比较拖沓。没有更新的原因也是最近一个月在做一个项目,没日没夜的度过了一个多月的加班加点的生活。

    我们言归正传,通过前面的学习,我们已经了解了CMake如何在配置时运行许多子任务,以便找到工作的编译器和必要的依赖项。本篇,我们将学习使用execute_process命令在配置时运行定制化命令。

    项目结构

    本篇比较简单,只有一个简单的CMakeLists.txt。
    相关源码:

    https://gitee.com/jiangli01/tutorials/tree/master/cmake-tutorial/chapter5/01

    CMakeLists.txt

    cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
    
    project(test_exe_proc LANGUAGES NONE)
    
    find_package(PythonInterp REQUIRED)
    
    # this is set as variable to prepare for abstraction using loops or functions
    set(module_name "cffi")
    execute_process(
      COMMAND
          ${PYTHON_EXECUTABLE} "-c" "import ${module_name}; print(${module_name}.__version__)"
      OUTPUT_VARIABLE stdout
      ERROR_VARIABLE stderr
      OUTPUT_STRIP_TRAILING_WHITESPACE
      ERROR_STRIP_TRAILING_WHITESPACE
    )
    
    if(stderr MATCHES "ModuleNotFoundError")
        message(STATUS "Module ${module_name} not found")
    else()
        message(STATUS "Found module ${module_name} v${stdout}")
    endif()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    execute_process命令将从当前正在执行的CMake进程中派生一个或多个子进程,从而提供了在配置项目时运行任意命令的方法。可以在一次调用execute_process时执行多个命令。注意,每个命令的输出将通过管道传输到下一个命令中。该命令接受多个参数:

    • WORKING_DIRECTORY,指定应该在哪个目录中执行命令。
    • RESULT_VARIABLE将包含进程运行的结果。这要么是一个整数,表示执行成功,要么是一个带有错误条件的字符串。
    • OUTPUT_VARIABLEERROR_VARIABLE将包含执行命令的标准输出和标准错误。由于命令的输出是通过管道传输的,因此只有最后一个命令的标准输出才会保存到OUTPUT_VARIABLE中。
    • INPUT_FILE指定标准输入重定向的文件名
    • OUTPUT_FILE指定标准输出重定向的文件名
    • ERROR_FILE指定标准错误输出重定向的文件名
    • 设置OUTPUT_QUIETERROR_QUIET后,CMake将静默地忽略标准输出和标准错误。
    • 设置OUTPUT_STRIP_TRAILING_WHITESPACE,可以删除运行命令的标准输出中的任何尾随空格
    • 设置ERROR_STRIP_TRAILING_WHITESPACE,可以删除运行命令的错误输出中的任何尾随空格
    execute_process(
      COMMAND
          ${PYTHON_EXECUTABLE} "-c" "import ${module_name}; print(${module_name}.__version__)"
      OUTPUT_VARIABLE stdout
      ERROR_VARIABLE stderr
      OUTPUT_STRIP_TRAILING_WHITESPACE
      ERROR_STRIP_TRAILING_WHITESPACE
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    该命令检查python -c "import cffi; print(cffi.__version__)"的输出。如果没有找到模块,stderr将包含ModuleNotFoundError,我们将在if语句中对其进行检查。本例中,我们将打印Module cffi not found。如果导入成功,Python代码将打印模块的版本,该模块通过管道输入stdout,这样就可以打印如下内容:

    message(STATUS "Found module ${_module_name} v${stdout}")
    
    • 1

    运行结果

    mkdir build
    cd build
    cmake ..
    
    • 1
    • 2
    • 3
    -- Found PythonInterp: /usr/bin/python3.8 (found version "3.8.10") 
    -- Module cffi not found
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /home/jiangli/repo/tutorials/cmake-tutorial/chapter5/01/build
    
    • 1
    • 2
    • 3
    • 4
    • 5
    sudo pip3 install cffi
    mkdir build
    cd build
    cmake ..
    
    • 1
    • 2
    • 3
    • 4
    -- Found module cffi v1.16.0
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /home/jiangli/repo/tutorials/cmake-tutorial/chapter5/01/build
    
    • 1
    • 2
    • 3
    • 4

    补充说明

    本篇,只打印了结果,但实际项目中,可以警告、中止配置,或者设置可以查询的变量,来切换某些配置选项。

  • 相关阅读:
    Swift中TableView的原理
    安卓端App页面狂刷问题记录
    Vue前端项目安装及相关问题解决
    vue学习之事件绑定
    自动化测试的生命周期是什么?
    NLP_Transformer架构
    vue项目适配屏幕分辨率与屏幕的缩放适配详细教程
    这绝对是总结的最详细的自动化测试基础知识学习
    Nocalhost安装操作步骤详解
    C语言——动态内存分配
  • 原文地址:https://blog.csdn.net/jjjstephen/article/details/133898005