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 设置构建的类型,调试模式还是发布模式
模式区别:
(2)project 初始化项目信息,并把当前CMakeLists.txt所在位置作为根目录
对于MSVC,会在buile里面生成hellocmake.sln作为“”“IDE眼中的项目”。
(4)四个目录的区别
(5)其他相关变量
(6)projecet的初始化:LANGUAGES字段
-
可以一开始就设置编译的文件语言
(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(8)project的初始化:VERSION字段(设置程序版本 )
(10)cmake_minimun_required指定最低所需的CMAKE版本
这里用到的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的使用
- 用法一:
- 用法二:
- 使用举例
(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进行处理,非常感谢!
-