1.一个程序要经过
a.预编译(就是检查语法错误,把宏 展开,把头文件包括就来)
b.编译(.c——>.S)转成汇编
c.汇编(.S——>.o)转成机器码
d.链接(.o+库文件=可执行程序)
才能形成可执行程序
通常把1-3点叫做编译
用arm-linux-gcc -o a a.c 可以执行上面四个步骤,生成可执行程序,也可以用arm-linux-gcc -v -o a a.c列出四个步骤生成可执行文件的过程
2.为什么要使用Makefile
使用gcc -o test a.c b.c ......c会编译所有的文件
假如你在写代码过程中只修改了a.c又要重新编译所有的文件,在文件很多的情况下,就很浪费时间。
Makefile帮为做到,修改了多少个文件,就编译这些文件,没有修改的就不重新编译。
插:gcc -I 可以指定头文件目录作为依赖
-L可以指定库文件目录作为依赖
编写Makefile可参看内核Makefile:E:\linux-3.4.2\scripts\Makefile.build
1.编写工程项目的Makefile
编写子目录下的makefile(例如子目录下有a.c,b.c,c.c还有一个更底层的子目录file)
CROSS_COMPILE = arm-linux- //指定工具链
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
export AS LD CC CPP AR NM //导出上面的变量(为了以后我们进入各种子目录的时候,使用这些变量)
export STRIP OBJCOPY OBJDUMP
CFLAGS := -Wall -O2 -g //CFLAGS表示用于 C 编译器的选项,-Wall是列出所有的警告信息 -O2:优化选项 -g:调试信息
//这里为什么用冒号,看GNU Make 使用手册
CFLAGS += -I $(shell pwd)/include //指定当前目录下的include作为编译时要去搜索的目录
LDFLAGS := -lm -lfreetype //链接参数 -lm -lfreetype 这里指数学库和freetype库
export CFLAGS LDFLAGS //导出CFLAGS LDFLAGS变量
TOPDIR := $(shell pwd)
export TOPDIR
TARGET := show_file //指出最终目标文件
obj-y += main.o
obj-y += display/
obj-y += draw/
obj-y += encoding/
obj-y += fonts/
all :
make -C ./ -f $(TOPDIR)/Makefile.build //编译Makefile.build
$(CC) $(LDFLAGS) -o $(TARGET) built-in.o //生成目标文件
clean:
rm -f $(shell find -name "*.o")
rm -f $(TARGET)
distclean:
rm -f $(shell find -name "*.o")
rm -f $(shell find -name "*.d")
rm -f $(TARGET)
上面的Makefile严重依赖于Makefile.build
PHONY := __build
__build:
obj-y :=
subdir-y :=
include Makefile
# obj-y := a.o b.o c/ d/
# $(filter %/, $(obj-y)) : c/ d/
# __subdir-y : c d
# subdir-y : c d
__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
subdir-y += $(__subdir-y)
# c/built-in.o d/built-in.o
subdir_objs := $(foreach f,$(subdir-y),$(f)/built-in.o)
# a.o b.o
cur_objs := $(filter-out %/, $(obj-y))
dep_files := $(foreach f,$(cur_objs),.$(f).d)
dep_files := $(wildcard $(dep_files))
ifneq ($(dep_files),)
include $(dep_files)
endif
PHONY += $(subdir-y)
__build : $(subdir-y) built-in.o
$(subdir-y):
make -C $@ -f $(TOPDIR)/Makefile.build
built-in.o : $(cur_objs) $(subdir_objs)
$(LD) -r -o $@ $^
dep_file = [email protected]
%.o : %.c
$(CC) $(CFLAGS) -Wp,-MD,$(dep_file) -c -o $@ $<
.PHONY : $(PHONY)