此文章为学习韦东山嵌入式Linux教程学习所做笔记
gcc的编译器的使用
一个C/C++文件要经过预处理,编译,汇编和链接等四步才可以变成可执行文件
1.预处理
.c/.cpp xx-gcc -E -o hello.i hello.c
2.编译(cc1命令可以完成1.2两步)
.i xx-gcc -S -o hello.s hello.i
3.汇编(as命令)
.s xx-gcc -c -o hello.o hello.s
4.链接(collect2命令)
.o xx-gcc -o hello hello.o 其他.o
编译多个程序
gcc -c -o a.o a.c
gcc -c -o b.o b.c
gcc -o test sub.o main.o
Makefile模式规则
Makefile规则:当依赖比目标文件新时,重新生成目标文件
target(目标):prerequiries(依赖) command(命令)
简单例子,现在有三个文件a.c b.h b.c内容为:
---------------------a.c--------------
#include <stdio.h>
#include <stdlib.h>
#include "b.h"
int main(int argc,char **argv)
{
int c;
c=add(1,2);
printf("c = %d\n",c);
return 0;
}
---------------------b.c-----------------
#include "b.h"
int add(int a,int b)
{
return a+b;
}
---------------------b.h------------------
#ifndef _B_H
#define _B_H
int add(int a,int b);
#endif
下面了解几个变量的含义:
| 符合 | 含义 |
|---|---|
| $@ | 规则中的目标集合,在模式规则中,如果有多个目标的话,“$@”表示匹配模式中定义的目标集合 |
| $< | 依赖文件集合中的第一个文件,如果依赖文件是以模式(即“%” )定义的,那么“$<”就是符合模式的一系列的文件集合 |
| $^ | 所有依赖文件的集合,使用空格分开,如果在依赖文件中有多个重复的文件,“$^”会去除重复的依赖文件,值保留一份。 |
简单Makefile编写:
test : a.c b.c b.h
gcc -o test a.c b.c
clean:
rm *.o test -f
改进:
#变量表示
objs = a.o b.o
#$^表示所有依赖
test:$(objs)
gcc -o test $^
#$@:目标集合 #变量表示
objs = a.o b.o
#$^表示所有依赖
test:$(objs)
gcc -o test $^
#$@:目标集合 $<:依赖文件集合
%.o : %.c
gcc -c -o $@ $<
#.PHONY伪目标,这样子不会判断同一目录下是否有clean文件存在
.PHONY clean:
rm test *.o -rf
lt;:依赖文件集合
%.o : %.c
gcc -c -o $@ #变量表示
objs = a.o b.o
#$^表示所有依赖
test:$(objs)
gcc -o test $^
#$@:目标集合 $<:依赖文件集合
%.o : %.c
gcc -c -o $@ $<
#.PHONY伪目标,这样子不会判断同一目录下是否有clean文件存在
.PHONY clean:
rm test *.o -rf
lt;
#.PHONY伪目标,这样子不会判断同一目录下是否有clean文件存在
.PHONY clean:
rm test *.o -rf
Makefile中的变量
Makefile中的变量分为三种:简单变量,延时变量,export变量
A := XXX:A的值定义时就确定为XXXB = XXX:B的值用到才确定下来C ?= XXX:第一次定义才起效,前面若已经定义,则忽略
示例:
A := 123
B = $(C)
C = abc
D = 100ASK
D ?= ASK
print:
@echo $(A)
@echo $(B)
@echo $(C)
@echo $(D)
结果:
Makefile的简单函数
- $(foreach var,list,test),遍历list,将list中的每个变量赋给var,再将var代入test中 示例:将A中的每个变量都添加.o后缀
A = a b c
B = $(foreach f,$(A),$(f).o)
print:
@echo B=$(B)
结果:
- $(filter pattern ....,text):在text中取出符合pattern格式的值
- $(filter-out pattern ....,text):在text中取出不符合pattern格式的值
示例:
C = a b c d/
D = $(filter %/,$(C))
E = $(filter-out %/,$(C))
print:
@echo D=$(D)
@echo E=$(E)
结果:
- $(wildcard pattern):取出符合pattern格式的文件
示例:取出真实存在的文件,我的某个目录下有
a.c b.c c.c三个文件
files = a.c b.c c.c d.c
files2 = $(wildcard $(files))
print:
@echo files2 = $(files2)
结果:
(var)):将var所有满足pattern格式的文件全部替换为replacement格式 示例:将所有files中所有
.c文件替换为.d文件
files = a.c b.c c.c d.c
files2 = $(patsubst %.c,%.d,$(files))
print:
@echo files2 = $(files2)
结果:
Makefile实例
gcc -M a.c可以得到a.c的依赖文件gcc -M -MF a.d a.c可以将a.c的依赖文件全部写入a.d文件中示例:有三个文件
a.c b.c b.h
objs = a.o b.o
#依赖,判断是否存在依赖a.d,b.d
dep_files :=$(patsubst %,%.d,$(objs))
dep_files :=$(wildcard $(dep_files))
#编译选项
CFLAGS = -Werror -Iinclude
test:$(objs)
gcc -o test $^
#判断是否存在,注意空格
ifneq ($(dep_files),)
include $(dep_files)
endif
%.o:%.c
gcc $(CFLAGS) -c -o $@ objs = a.o b.o
#依赖,判断是否存在依赖a.d,b.d
dep_files :=$(patsubst %,%.d,$(objs))
dep_files :=$(wildcard $(dep_files))
#编译选项
CFLAGS = -Werror -Iinclude
test:$(objs)
gcc -o test $^
#判断是否存在,注意空格
ifneq ($(dep_files),)
include $(dep_files)
endif
%.o:%.c
gcc $(CFLAGS) -c -o $@ $< -MD -MF $@.d
clean:
rm test *.o -rf
distclean:
rm $(dep_files)
.PHONY: clean
lt; -MD -MF $@.d
clean:
rm test *.o -rf
distclean:
rm $(dep_files)
.PHONY: clean
本文使用 mdnice 排版