编译工具
- 跟我一起写Makefile
- 《嵌入式 Linux C 语言程序设计》,make
1 CMake
推荐 out of source builds,输出不混在一起,git 工具好管理,可以创建多个 build,如 debug/release。build 与 source 同一等级,不在 source 内部
在多个平台测试以避免写出平台相关的 cmake
选择编译器和 Generator,两者不同搭配可有不同的 build 目录,只需指定一次
1
cmake -B build -G "MinGW Makefiles" -D CMAKE_MAKE_PROGRAM="D:/soft/mingw64/bin/mingw32-make.exe"
生成和编译始终在源码根目录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# 生成 build system
cmake -B build
# 编译
cmake --build build
# verbose and N parallel build
cmake --build build -v -j N
# 列出 target
cmake --build build -t help
# 编译 target
cmake --build build -t Tutorial
cmake --build /pathTo/build --config Debug --target MyApp
# 列出可设置的选项
cmake -LH build
# 设置选项
-调试 CMake
1
2# 用 --trace 打印太多了,所以一般 --trace-source 指定源码根目录的 CMakeLists.txt
cmake -B build --trace-source="CMakeLists.txt" -DUSE_MYMATH:BOOL=OFFtarget 可以是虚拟的
变量都是字符串类型,值有空格要加引号,多个值用分号连起来。未定义的变量是空字符串。${} 可以嵌套引用,可作为变量名
unset(myVar) / set(myVar) 用来 unset 变量
ENV{varName} 修改环境变量,环境变量只影响这次 cmake 执行
cache 和普通变量同名,普通变量会掩盖 cache 变量,但在一些情况 P26 会相反,cache 变量会被使用。正因为有同名情况,所以要给一个变量明确置空 set(foo “”) 而非使用 unset(foo)
cache 变量的修改需要 force 关键字
命令行定义 cache 变量,建议指定类型;-U 取消定义
cmake-gui 一直 (配置 + 点 Configure) 直到没有红色然后点 Generate
给 cache 变量一个下划线结尾的前缀方便 cmake-gui 分组,项目相关的也用前缀方便以后给其它项目使用
文件的 IS_NEWER_THAN 要用 NOT 方式使用,因为 P44
不使用加引号的字符串,避免 3.1 以下版本解释为变量,进行变量替换
函数传参,引号分割的字符串会被当作不同的参数,要注意何时用引号括起来
尽量用函数而非宏来更好隔离
2 介绍
- 编译、链接、库 等原理
- 三要素,目标、依赖、命令,依赖比目标或目标不存在新就执行命令。找到关系树的末端再从末端进行判断,末端比根旧则什么都不做,新则执行命令。
- 不要用环境变量 MAKEFILES
- Makefile 的组成
- 显示规则,我们写的
- 隐含规则,.o 自动生成 .c 依赖的关系 和 编译命令
- 变量定义
- 文件指示
include <filename>
#if
- 多行命令
- 注释,# 转义
3 规则
规则中可以用通配符
变量中的通配符不会展开,除非
1
2
3
4# 文件夹下所有的 .c
objects := $(wildcard *.c)
# 文件夹下所有的 .o
objects := $(patsubst %.c,%.o,$(wildcard *.c))用 vpath 指定多个搜索目录
伪目标两个作用 1. clean 2. 一次生成多个目标
静态模式与多目标 %,具体看参考
依赖的头文件自动生成的方法,具体看参考
4 命令
- @ 可以不显示这条命令
- 语句前加 - 可以忽略错误继续执行
- 嵌套执行 makefile
- $(MAKE) -C subdir
- export variable = value 或者 unexport 或者 export 导出所有变量到下级
- MAKEFLAGS 和 SHELL 永远被传递给下级,除非见参考文档
- 常用命令可以定义成命令包
5 变量
建议小写作为变量名,大写作为控制隐含规则和用户重载命令选项时使用
递归展开,无法追加 VAR=var
简单展开 VAR:=var
?= 被定义过什么都不做,没定义则赋值
变量使用 $(VAR)
预定义变量,比如 CC、RM、CFLAGS
自动变量,比如 $@、$<、$^
make 启动时自动创建与系统相同数值的环境变量
6 make
有一些 GNU 约定好的目标表示名称,可以作为写 makefile 的参考,比如 install
用来调试 makefile
参数 | 作用 |
---|---|
-n | dry run |
-t | 只更新(touch)目标的时间,假装编译 |
-q | 看看某个目标在 makefile 中存在吗 |
–debug | 打印调试 |
-w | 打印目录,用来调试嵌套 make 调用 |
其它参数见 man 或者 上面的参考文档
7 隐含规则
- C程序隐含规则,$(CC) –c $(CPPFLAGS) $(CFLAGS),其它程序规则见参考文档
- 隐含规则使用的变量,如 CC、CFLAGS 具体见文档
- 模式规则 %,与自动化变量。if 判断中不能使用自动化变量