1. gcc编译器
1.1. 常用选项
选项 | 说明 |
---|---|
-E | 预处理,开发过程中想快速确定某个宏可以使用“-E -dM” |
-c | 把预处理、编译、汇编都做了,但是不链接 |
-o | 指定输出文件 |
-I | 指定头文件目录 |
-L | 指定链接时库文件目录 |
-l | 指定链接哪一个库文件 |
1.2. 很有用的选项
gcc -E main.c # 查看预处理结果,比如头文件是哪个
gcc -E -dM main.c > 1.txt # 把所有的宏展开,存在 1.txt 里
gcc -Wp,-MD,abc.dep -c -o main.o main.c # 生成依赖文件 abc.dep,后面 Makefile 会用
echo 'main(){}'| gcc -E -v - # 它会列出头文件目录、库目录(LIBRARY_PATH)
2. MakeFile
2.1. 基本格式
目标(target)...: 依赖(prerequiries)...
<tab>命令(command)
2.2. 常用语法
2.2.1. 通配符
通配符 | 说明 |
---|---|
% | 文件名 |
$@ | 表示目标 |
$< | 表示第一个依赖 |
$^ | 表示所有依赖 |
2.2.2. PHONY 假想目标
假想目标,make时不会去判断目标文件是否存在
eg:
test: a.o b.o c.o
gcc -o $@ $^
%.o: %.c
gcc -c -o $<
clean:
rm *.o test
.PHONY: clean
2.2.3. 变量赋值
语法 | 说明 |
---|---|
:= | 即时变量,变量值即可确定 |
= | 延时变量,变量值在试用时确定 |
?= | 延时变量,如果变量值在前面已经定义则不生效 |
+= | 附加,即时or延时取决于前面变量的定义 |
2.3. 函数
2.3.1. $(foreach var, list, text)
对
list
中的每一个元素,取出来赋给var
,然后把var
改为text
所描述的形式。
eg:
objs:=a.o b.o
dep_files:=$(foreach f, $(objs), .$(f).d) # dep_files = .a.o.d .b.o.d
2.3.2. $(wildcard pattern)
pattern
所列出的文件是否存在,把存在的文件都列出来。
eg:
src_files:=$(wildcard *.c) # src_files为当前目录下所有的c文件
2.3.3. $(filter patten..., text)
返回在
text
中由空格隔开且匹配格式pattern...
的字,去除不符合格式pattern...
的字。$(filter-out patten..., text) 返回不匹配的字
eg:
A = a b c d/
B = $(filter %/, %(A))
C = $(filter-out %/, %(A))
all:
@echo B = $(B) # B = d/
@echo C = $(C) # C = a b c
2.3.4. $(patsubst pattern,replacement,text)
寻找
text
中符合格式pattern
的字,用replacement
替换它们。pattern
和replacement
中可以使用通配符。
eg:
A = a.c b.c c.h
B = $(patsubst %.c, %.o, $(A))
all:
@echo B = %(B) # B = a.o b.o c.h
2.4. 改进
2.4.1. 写入依赖
将c文件依赖的h文件写入makefile,防止h文件更新后make仍是最新版本
gcc -M main.c # 打印出依赖
gcc -M -MF main.d main.c # 把依赖写入文件mian.d
gcc -c -o main.o main.c -MD -MF main.d # 编译main.o,把依赖写入main.d
2.4.2. 添加CFLAGS
增加编译选项
选项 | 说明 |
---|---|
-Werror | 把警报转为错误,更严谨 |
-I[dir] | 编译器寻找头文件的路径dir |
2.5. 综合案例
要求: 多c文件,多h文件(单独放一个目录),参考文件树
2.5.1. 文件树
├── include
│ ├── a.h
│ └── b.h
├── a.c
├── b.c
├── main.c
└── Makefile
2.5.2. 代码
objs = main.o a.o b.o
dep_files := $(patsubst %, .%.d, $(objs))
dep_files := $(wildcard $(dep_files))
CFLAGS = -Werror -Iinclude
test: $(objs)
gcc -o $@ $^
ifneq ($(dep_files),)
include $(dep_files)
endif
%.o : %.c
gcc $(CFLAGS) -c -o $@ $< -MD -MF .$@.d
clean:
rm *.o test $(dep_files)
.PHONY: clean
声明:
本文采用
BY-NC-SA
协议进行授权,如无注明均为原创,转载请注明转自
挺着将军肚
本文地址: Linux应用层之GGC与Makefile
本文地址: Linux应用层之GGC与Makefile