补充番外14:cmake笔记

linux更新cmake版本(sudo pacman -S cmake)

零、cmake的构建步骤

  • 步骤

1)第一步是cmake -B build,成为配置阶段(configure),这时候只检测环境并生成构建规则,会在build目录下生成本地构建系统能识别的项目文件(Makefile或是.sln)

2)第二步是cmake –build build ,成为构建阶段(build),这时候才实际调用编译器来编译代码

一、Cmake -B和–build指令(跨平台兼容)

1)cmake -B build

在源码目录用-B直接创建build目录并生成build/Makefile,免去了先创建目录再切换进去制定源码目录的麻烦

2)cmake –build build -j4 (统一了不同平台,linux上会调用make,Windows会调用devenv.exe)

自动调用本地的构建系统在build里面构建,即 :

3)sudo cmake –build build –target install

调用本地的构建系统执行install这个目标,即安装

二、Cmake -D 选项:制定配置变量(又称缓存变量,前面有提到)

三、Cmake -G选项 制定要用的生成器

  • 说明
    1)linux默认cmake使用Unix Makefile生成器;windows默认是vs2019生成器;MacOS系统默认是Xcode生成器
    2)可以用-G参数改用别的生成器,例如cmake -GNinja -B build
    3)ninja是专为性能优化的构建系统,和cmake都是行业标准
    4)pip install ninja
    5)ninja是跨平台的
    6)MSBuild是单线程的,比较慢

四、正式开始

1)第一章 添加源文件(add_executable生成可执行文件)

  • 法一
    main.cpp是文件,main是执行文件
  • 法二

假如多个源文件

  • 法三:使用变量来存储
  • 法四(对比法三是增加了批量获取当前目录的.h和.c文件)

GLOB会自动遍历所有文件
CONFIGURE_DEPENDS 每次编译都会重新查找文件

2)第二章添加子目录的文件aux_source_directory

GLOB只能指定一个目录,这里指定了当前目录和当前目录下mylib目录的所有文件

  • 法一
  • 法二

GLOB_RECURSE当前目录下递归搜索,但是这个会把build目录下生成的临时cpp文件也加进来

解决方法:
把源码统一放到src目录下

3)第三章 项目配置变量

(1)CMAKE_BUILD_TYPE 设置构建的类型,调试模式还是发布模式

模式区别:

补充番外14:cmake笔记

(2)project 初始化项目信息,并把当前CMakeLists.txt所在位置作为根目录

对于MSVC,会在buile里面生成hellocmake.sln作为“”“IDE眼中的项目”。

补充番外14:cmake笔记

(4)四个目录的区别

补充番外14:cmake笔记

(5)其他相关变量

补充番外14:cmake笔记

(6)projecet的初始化:LANGUAGES字段

补充番外14:cmake笔记
  • 可以一开始就设置编译的文件语言

    补充番外14:cmake笔记

    (7)CMAKE_CXX_STANDARD变量设置C++标准

    • CMAKE_CXX_STANDARD_REQUIRED是BOOL类型,可以为ON或OFF,默认OFF
      表示是否一定要支持你制定的C++标准,为ON则发现不支持就报错,用了ON更安全

    • CMAKE_CXX_EXTENSIONS也是BOOL类型,默认为ON。设为ON表示启动GCC特有的一些扩展功能;OFF则关闭GCC的扩展功能,只能用标准的C++


    1)要兼容其他编译器(如MSVC)的项目,都会设为OFF防止不小心用了GCC才有的特性。
    2)用来添加-std=c++17有个缺陷:
    GCC用户指定了-std=C++17,不兼容MSVC

    补充番外14:cmake笔记

    (8)project的初始化:VERSION字段(设置程序版本号)

    补充番外14:cmake笔记

    (10)cmake_minimun_required指定最低所需的CMAKE版本

    补充番外14:cmake笔记
    综上,对于一些在整个项目中通用的编译选项可以使用add_compile_options命令来添加比较方便,对于各个模块中的独立选项则使用CMAKE_CXX_FLAGS变量更好。

    这里用到的CMAKE_CXX_FLAGS变量是只针对C++编译器的选项,对于其他编程语言,只要替换部分就可以,在当前cmake版本(3.17.2)中支持如下语言:

    (4)实用举例

    (13)target_include_directories

    该命令可以指定目标(exe或者so文件)需要包含的头文件路径。命名的<目标>必须是由add_executable()或add_library()之类的命令创建的,并且不能是ALIAS目标。通过显式地使用AFTER或BEFORE,就可以在附加和预挂之间进行选择,而不是依赖默认值。

    • 备注

    private,public,interface的使用

    • 例子
      有如下文件的目录,一个math库,main.cc文件来调用math库,math库实现了一个整数的幂运算
      补充番外14:cmake笔记

      (14)add_library(有对对象库的定义)

      使用该命令可以生成(静态/动态)库so或者.a文件,它有两种命令格式

      • 用法一:

      生成一个名为 < name > 的library,在项目中必须是全局唯一的。

      1.1、< name > 应该保证在一个项目中的唯一性。
      1.2、实际的library文件名基于Native平台的约定规则,比如:lib< name >.a, < name >.lib等
      1.3、STATIC,SHARED,MODULE用于指定创建的library类型。
      STATIC库:是object文件的归档,用于链接其他targets。
      SHARED库:是动态链接,并于运行时加载。
      MODULE库:不能链接到其他targets,但是可以用dlopen之类的方法在运行时动态加载。
      1.4、如果没有明确指定上述类型,那么如果BUILD_SHARED_LIBS变量值为ON,则默认是SHARED,否则默认STATIC。
      1.5、对于SHARED和MODULE类型的库,POSITION_INDEPENDENT_CODE属性自动置为ON。
      1.6、EXCLUDE_FROM_ALL:表明该target是否从默认构建target中排除。
      1.7、source参数可以使用generator表达式($ <…>)。

      • 用法二:

      创建一个object对象库,该对象库只编译源文件,但不链接。

      由add_library()或 add_executable()创建的目标可以使用$<TARGET_OBJECTS:name>这样的表达式作为源引用对象,其中,name是对象库的名称。格式如下:

      • 使用举例

      来源:谢白羽

      声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年6月10日
下一篇 2022年6月10日

相关推荐