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

cmake基于语法和应用

CMake中的变量

  • 变量和含义

    常用变量含义
    PROJECT_NAME工程名变量
    PROJECT_SOURCE_DIR顶层的项目目录
    PROJECT_BINARY_DIR使用cmake的路径
    CMAKE_ROOTCMAKE安装的根目录
    CMAKE_BUILD_TYPE编译类型:emptyDebugRelease
    CMAKE_SOURCE_DIR顶层的CMakeLists.txt所在路径
    CMAKE_BINARY_DIR顶层的CMakeLists.txtbuild所在目录
    CMAKE_<LANG>_COMPILER设定某个语言LANG的编译器,比如g++
    CMAKE_INSTALL_PREFIX指令install的路径
    CMAKE_CURRENT_SOURCE_DIR当前CMakeLists.txt所在路径
    CMAKE_CURRENT_BINARY_DIR当前CMakeLists.txtbuild所在目录
    EXECUTABLE_OUTPUT_PATH可执行文件输出路径
    LIBRARY_OUTPUT_PATH库输出路径
  • 个别变量解释
    源码目录结构

        jmudou   ├── build.sh├── CMakeLists.txt└── muduo└── base├── Atomic.h├── CMakeLists.txt├── copyable.h├── tests│   ├── Atomic_unittest.cc│   ├── CMakeLists.txt│   └── Timestamp_unittest.cc├── Timestamp.cc├── Timestamp.h└── Types.h
    

    三个CMakeLists.txt输出

        jmuduo/CMakeLists.txt: PROJECT_SOURCE_DIR= 11/jmuduoPROJECT_BINARY_DIR= 11/build/debug CMAKE_SOURCE_DIR= 11/jmuduo            # 指定顶层的CMakeLists.txt的,因此所有的都相同CMAKE_BINARY_DIR= 11/build/debug# 上面四项都是与整个项目相关,因此都是一致的。CMAKE_CURRENT_SOURCE_DIR= 11/jmuduo     # 指定当前层的CMakeLists.txt的,因此与层相关CMAKE_CURRENT_BINARY_DIR= 11/build/debugmuduo/base/test/CMakeLists.txt: PROJECT_SOURCE_DIR= 11/jmuduoPROJECT_BINARY_DIR= 11/build/debugCMAKE_SOURCE_DIR= 11/jmuduoCMAKE_BINARY_DIR= 11/build/debugCMAKE_CURRENT_SOURCE_DIR= 11/jmuduo/muduo/base/testsCMAKE_CURRENT_BINARY_DIR= 11/build/debug/muduo/base/testsmuduo/base/CMakeLists.txt: PROJECT_SOURCE_DIR= 11/jmuduoPROJECT_BINARY_DIR= 11/build/debugCMAKE_SOURCE_DIR= 11/jmuduoCMAKE_BINARY_DIR= 11/build/debugCMAKE_CURRENT_SOURCE_DIR= 11/jmuduo/muduo/baseCMAKE_CURRENT_BINARY_DIR= 11/build/debug/muduo/base
    

函数

所有的函数列表中,<>表示的参数必须要有,[]表示的参数为可选。

  • set
    可以设置三个类型的变量值:正常变量,cache variable、环境变量。

    • Normal Variable:set(<variable> <value>... [PARENT_SCOPE])
    • cacheset(<variable> <value>... CACHE <type> <docstring> [FORCE])
    • envset(ENV{<variable>} [<value>])
  • OPTION:提供用户可以选择的选项

    • 格式:option(<variable> "description" [initial value])
    • 比如:
          option(USE_MYPATH"user path"ON)
      
  • aux_source_directory

    • 语法:aux_source_directory(<dir> <variable>)
    • 查找目录dir下的所有源文件(即.c, .cpp, .cc等文件),并将名称保存到 variable 变量
  • add_subdirectory

    • add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
    • 添加一个将被编译的子目录。指明CMakeLists.txt所在目录下包含了一个子目录source_dir。这样source_dir下的源文件和CMakeLists.txt等也会被处理。
  • target_link_libraries

    • target_link_libraries(exec libs)
    • 表示可执行程序exec需要链接到一个名为libs的链接库。
  • add_library

    • add_library (name dir)
    • 用在目录dir下的源文件生成一个名为name的静态链接库:libname.a
  • configure_file

    • 加入一个配置头文件,用于处理 CMake 对源码的设置
          configure_file ("${PROJECT_SOURCE_DIR}/config.h.in" # config.h.in文件目录"${PROJECT_BINARY_DIR}/config.h"    # config.h 生成的头文件目录)
      
      在配置文件config.h中,配置相关项,比如options中的USE_MYPATH
          #cmakedefine USE_MYMATH
      
  • include

    • include(file [optional]):读取CMake的相关文件。
    • include(moudle [optional])
      the file with name .cmake is searched in the CMAKE_MODULE_PATH
  • include_directories

        include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
    

    添加指定目录到编译器搜索路径。

  • install
    使用:cmake之后,sudo make install就可以执行相应的库和头文件的安装。

    • TARGET格式
      install(TARGETS targets...[[ARCHIVE|LIBRARY|RUNTIME][DESTINATION <dir>][PERMISSIONS permissions...][CONFIGURATIONS [Debug|Release|...]][COMPONENT <component>]  [OPTIONAL]] [...])
      
    • targets的类型
      可以安装的库有[ARCHIVE|LIBRARY|RUNTIME]三种:
        1) 可执行程序视为runtime
        2) 静态库视为archieve
        3) Module Library视为library
        4) 共享库和平台有关
    • 参数
      • DESTINATION
        指定一个文件将要被安装的目录。如果给的是一个全路径,那么就直接使用;如果是相对路径,默认是相对CMAKE_INSTALL_PREFIX,其值默认是/usr/local/
          1) 头文件:inclide
          2) 可执行文件:bin
          3) 库:lib

      • PERMISSIONS: 指定安装文件的权限:
          1) user : OWNER_READ, OWNER_WRITE, OWNER_EXECUTE
          2) group:GROUP_READ, GROUP_WRITE, GROUP_EXECUTE
          3) other:WORLD_READ, WORLD_WRITE, WORLD_EXECUTE
          4) uid : SETUID, and SETGID

      • CONFIGURATIONS:为安装规则建立一个配置文件列表。

  • install

    • FILES格式
      INSTALL(FILES files... DESTINATION <dir>[PERMISSIONS permissions...][CONFIGURATIONS [Debug|Release|...]][COMPONENT <component>][RENAME <name>] [OPTIONAL])
      
      • files:即文件名
  • 测试

    • enanle_testing():启动测试
    • add_test(testname Exename arg1 arg2 ...)
      • 需要先运行测试程序enanle_testing(),这个指令才有效。
      • Exename是可执行程序名,参数arg1, arg2
    • set_tests_properties(...)
      • 括号内格式:(Exename [Exename2...] PROPERTIES prop1 value1 prop2 value2),其中PROPERTIES是固定的单词不能改
      • Exename设置属性,如果没有这个属性,就报错,有如下属性:
          1) WILL_FAIL:如果设置为true,那么会反转测试结果的pass/fail标志。
          2) PASS_REGULAR_EXPRESSION: 匹配正则表达式,只少有一个匹配,则pass
          2) FAIL_REGULAR_EXPRESSION: 匹配正则表达式,则fail
    • 宏测试
          macro(<name> [arg1 [arg2 [arg3 ...]]])COMMAND1(ARGS ...)COMMAND2(ARGS ...)...endmacro(<name>)
      
      就类似于写一个函数,用宏实现,调用:name(arg1,arg2,...)
  • 设置项目的版本号

    • 在顶层的CMakeLists.txt中:
          # 加入版本号是 1.0set (Project_VERSION_MAJOR 1) # 主版本号set (Project_VERSION_MINOR 0) # 副版本号
      
    • 在配置文件config.h.in中设置:
          #define Project_VERSION_MAJOR @Project_VERSION_MAJOR@#define Project_VERSION_MINOR @Project_VERSION_MINOR@
      
    • main函数中就可以直接使用这两个宏,代表版本号:
          printf("Version %d.%d\n",Project_VERSION_MAJOR,Project_VERSION_MINOR);
      
  • 生成安装包
    需要利用CPack工具,也是CMake提供的工具。

    • 先在顶层CMakeLists.txt中末尾添加:
          # 构建一个 CPack 安装包include(InstallRequiredSystemLibraries)set (CPACK_RESOURCE_FILE_LICENSE"${CMAKE_CURRENT_SOURCE_DIR}/License.txt")set (CPACK_PACKAGE_VERSION_MAJOR "${Project_VERSION_MAJOR}")set (CPACK_PACKAGE_VERSION_MINOR "${Project_VERSION_MINOR}")include (CPack)
      
      • 导入InstallRequiredSystemLibraries模块,以便之后导入CPack模块
      • 设置一些CPack相关变量,包括版权信息和版本信息,其中版本信息用了上一节定义的版本号
      • 导入CPack模块
    • 生成二进制安装包:cpack -C CPackConfig.cmake
    • or 生成源码安装包
      • 格式:cpack -C CPackSourceConfig.cmake
        在执行该命令的目录下得到:
            # Demo8是项目名$ ls -l | grep Demo8-rwxrwxrwx 1 szz szz  8631 Dec 12 22:03 Demo8-1.0.1-Linux.sh-rw-rw-r-- 1 szz szz  3709 Dec 12 22:03 Demo8-1.0.1-Linux.tar.gz-rw-rw-r-- 1 szz szz  4982 Dec 12 22:03 Demo8-1.0.1-Linux.tar.Z
        
      • 安装:sh Demo8-1.0.1-Linux.sh
        默认的安装路径:
            By default the Demo8 will be installed in:"~/Study/SystemProgram/CMakeExe/Demo8/build/Demo8-1.0.1-Linux"Do you want to include the subdirectory Demo8-1.0.1-Linux?Saying no will install in: "~/Study/SystemProgram/CMakeExe/Demo8/build" [Yn]: 
        
      • 运行。安装后,就运行该程序
            $ ./Demo8-1.0.1-Linux/bin/Demo 2 5Now we use our own Math library. 2 ^ 5 is 32
        
      • Demo8-1.0.1-Linux下的目录结果
            Demo8-1.0.1-Linux├── bin│   └── Demo        # 可执行程序├── include         # 头文件│   ├── config.h│   └── MathFunctions.h└── lib             # 静态库└── libMathFunctions.a
        
  • target_compile_definitions

    • 格式
          target_compile_definitions(<target><INTERFACE|PUBLIC|PRIVATE> [items1...][<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
      
    • 作用:编译时定义的宏
  • string

    • REPLACE
          string(REPLACE <match_string> <replace_string> <output_variable> <input> [<input>...])
      
      将所有input中出现的match_String替换为replace_string,并且将结果存在output_variable
  • message

        message([<mode>] "message to display" ...)
    
    • 显示信息给用户
      mode取决于信息的类型:
      • STATUS:以简洁的方式显示用户感兴趣的信息。
            message(STATUS "CXX_FLAGS = " ${CMAKE_CXX_FLAGS} " " ${CMAKE_CXX_FLAGS_${BUILD_TYPE}})
        
        可以理解为printf,把后面的几个信息以空格相间,然后打印出来。显示结果为(和上面对应分成三段):
            CXX_FLAGS = -g -D_FILE_OFFSET_BITS=64 -Wall -Wextra -Werror -Wconversion -Wno-unused-parameter -Wold-style-cast -Woverloaded-virtual -Wpointer-arith -Wshadow -Wwrite-strings -march=native -rdynamic -O0
        
  • find_package

        find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE][REQUIRED] [[COMPONENTS] [components...]][OPTIONAL_COMPONENTS components...][NO_POLICY_SCOPE])
    

    主要是寻找和加载外部项目。如果PackageName找到了,PackageName-found会显出,当没有找到时,默认显示
    PackageName-not found。通过模式的选择,可以处理在没有找到包时的解决方案。

    • QUIET:不显示有用信息,
    • REQUIRED:报错
  • find_path

        find_path (<VAR> name0|NAMES name1 [path1 path2 ...])
    

    用以寻找包含着name1文件的目录,如果找到了结果存储在VAR,没有找到结果结果是VAR-not found。成功时,变量被清除find_path再次搜索,没有成功,fin_path再次以相同的变量被调用时搜索。

  • find_library
    同上find_path

        find_library (<VAR> name0|NAMES name1 [path1 path2 ...])
    
    • OPTIONS
      • NAMES
        library指定一个或多个可能的名字。

  • 参考
    • CMake官方文档
    • CMake API搜索
    • CMake tutorial

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【Go】 HTTP编程3-路由httprouter
  • VisionPro二次开发学习笔记12-使用CogToolGroup控件进行图像检测
  • 五. TensorRT API的基本使用-custom-trt-plugin
  • js入门经典学习小结
  • 【Python】PyWebIO 初体验:用 Python 写网页
  • 006 | 资本资产定价模型 (CAPM)
  • MySQL学习(20):InnoDB引擎逻辑架构、物理架构
  • Unity入门2——编辑器常用功能
  • 投资 - 什么叫有资金托底
  • 当node节点kubectl 命令无法连接到 Kubernetes API 服务器
  • k8s创建secret并在container中获取secret
  • Spring框架面试总结
  • java最强本地缓存-Caffeine
  • 「数组」随机快速选择 / LeetCode LCR 076(C++)
  • VMWare虚拟机磁盘扩容
  • 【EOS】Cleos基础
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • Consul Config 使用Git做版本控制的实现
  • mysql中InnoDB引擎中页的概念
  • spark本地环境的搭建到运行第一个spark程序
  • swift基础之_对象 实例方法 对象方法。
  • Vim Clutch | 面向脚踏板编程……
  • 百度小程序遇到的问题
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 后端_MYSQL
  • 区块链共识机制优缺点对比都是什么
  • 鱼骨图 - 如何绘制?
  • 栈实现走出迷宫(C++)
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • ​iOS实时查看App运行日志
  • ​埃文科技受邀出席2024 “数据要素×”生态大会​
  • ​如何使用QGIS制作三维建筑
  • #if #elif #endif
  • #VERDI# 关于如何查看FSM状态机的方法
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • (2)Java 简介
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (简单) HDU 2612 Find a way,BFS。
  • (六)Flink 窗口计算
  • (删)Java线程同步实现一:synchronzied和wait()/notify()
  • (学习日记)2024.02.29:UCOSIII第二节
  • (一)springboot2.7.6集成activit5.23.0之集成引擎
  • (一)插入排序
  • (译)2019年前端性能优化清单 — 下篇
  • (转)原始图像数据和PDF中的图像数据
  • .bat批处理(六):替换字符串中匹配的子串
  • .form文件_SSM框架文件上传篇
  • .NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)
  • .NET 漏洞分析 | 某ERP系统存在SQL注入
  • .net 受管制代码
  • ::before和::after 常见的用法
  • [Android]常见的数据传递方式
  • [Android学习笔记]ScrollView的使用
  • [BJDCTF2020]The mystery of ip1
  • [C++]C++入门--引用