Makefile系列--全面讲解

满堂花醉三千客,一剑霜寒十四州。这篇文章主要讲述Makefile系列--全面讲解相关的知识,希望能为你提供帮助。

应用与驱动Makefile示例应用Makefile

target := test objs :=test1.o test.o$(target) : $(objs) gcc -o$@ $^ -lpthread -lrt -lm -Wall%.o : %.c gcc -c -o $@ $< clean: rm $(target) *.o

驱动Makefile
PWD := $(shell pwd) ARCH := arm PLAT := samsungifeq ($(PLAT) , samsung) CROSS_COMPILE := arm-linux-gnueabi- KDIR := /work/plat/samsung endifmodules: make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KDIR) M=$(PWD) modules clean: make -C $(KDIR) M=$(PWD) cleanobj-m += test_drv.o

Makefile例子详解
CC= arm-linux-gcc#编译工具 LD= arm-linux-ld#连接工具 AR= arm-linux-ar#将多个.o文件合并成一个.O或者静态库文件(.a文件) OBJCOPY = arm-linux-objcopy#复制一个目标的内容到另一个文件中,例:将elf转化成bin文件 OBJDUMP = arm-linux-objdump#用于显示二进制文件信息,将elf文件反汇编 INCLUDEDIR := $(shell pwd)/include #shell函数,本句是在当前目录下的include文件夹下 CFLAGS := -Wall -O2#CFLAGS为C语言编译器参数,-Wall打开警告和优化级别为O2 CPPFLAGS:= -nostdinc -I$(INCLUDEDIR) # CPPFALGS 为c++语言预处理参数,这里-nostdinc的意思是:Do not search the standard # system directories for header files。 -I 指定只对#include “file”的头文件搜集目录 LDFLAGS := -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc #LDFLAGS为链接器,参数-print-libgcc-file-name:打印编译器伴随库的名称 export CC LD OBJCOPY OBJDUMP INCLUDEDIR CFLAGS CPPFLAGS AR #用export声明这些变量使得他们可以被子目录的Makefile使用 objs := head.o init.o nand.o interrupt.o adc_ts.o serial.o main.o lib/libc.a #objs 为变量,代替后面.o程序。lib/libc.a为连接库文件 adc_ts.bin: $(objs) ${LD} -Tadc_ts.lds -o adc_ts_elf $^ ${LDFLASG} ${OBJCOPY} -O binary -S adc_ts_elf $@ ${OBJDUMP} -D -m arm adc_ts_elf > adc_ts.dis # \'-m\'后面跟的是cpu构架,arm就表示是arm构架cpu,\'> \' 表示将这个程序的反汇编程序写入 #到led.dis,在终端中不显示出来.当你打开led.dis这个文件时就会看到上面命令的输出的反汇编程序了 .PHONY : lib/libc.a#.PHONY用来声明一个伪目标 lib/libc.a: cd lib; make; cd .. %.o:%.c ${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $< #将所有的[.C]文件都编译成[.O]文件 %.o:%.S ${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $< #将所有的[.s]文件都编译成[.O]文件 clean:#删除文件 make clean -C lib rm -f adc_ts.bin adc_ts_elf adc_ts.dis *.o

注意:
CC,LD,AR等是Makefile的隐藏命令变量。
CFLAGS,CPPFLAGS,LDFLAGS,LIBS等是Makefile的隐藏参数变量。
隐藏命令变量和隐藏参数变量见《Makefile手册中文版》=> 10.3隐含变量
另见:
网页收藏“Makefile $@ $^ $< _飞鹰0苍狼_新浪博客”
第3期 “第1课第4节_数码相框_编写通用的Makefile_P”
网页收藏 “GNU Make 使用手册(中译版)(于凤昌)” (对应的英文版是 make.pdf)
Makefile用法make详细使用手册见:
网页收藏 “GNU Make 使用手册(中译版)(于凤昌)”(对应的英文版是 make.pdf)

目标 : 依赖1 依赖2 ...
[TAB]命令

例:
test : a.o b.o gcc -o $@ $^ %.o : %.c gcc -c -o $@ $< ; clean: rm *.o test

1. 执行命令可以由以下两个原因引起
·"目标文件"不存在,
·某个依赖文件比目标文件"新"
2. 若直接make ,则会生成第一个目标。
本处,直接make,会直接进行生成test相关的操作,执行make clean会清除
3.make时可以传入变量的值。例如 make gcc=arm-linux-gcc
4. make时,会读入整个Makefile文件,设置好所有的变量,然后会进行生成第一个目标的操作。
5.如果@gcc -o test $^,则执行此命令的时候不会打印,如果没有@,则会打印gcc -o test a.o b.o
Makefile添加头文件等依赖文件示例
objs = a.o b.o c.odep_files := $(patsubst %,.%.d, $(objs)) dep_files := $(wildcard $(dep_files))CFLAGS = -Werror -Iincludetest: $(objs) gcc -o test $^ifneq ($(dep_files),) include $(dep_files) endif # 这个宏判断,第一次执行Make时为假(没有dep_files),不会执行。 # 只有执行一次之后,生成了依赖文件,之后make才会执行%.o : %.c gcc $(CFLAGS) -c -o $@ $< -MD -MF .$@.d @echo $^ # -MD -MF .$@.d可以生成依赖文件到.$@.d中。例如:当执行到c.o时, # 写到.c.o.d的内容是:c.o : c.c c.h ...第二次及以后执行时, # 会通过识别这些依赖的.c,.h文件来确定是否用新的文件编译。clean: rm *.o testdistclean: rm $(dep_files).PHONY: clean

其他:
1.依赖文件的追加的问题
例:
2.gcc -M c.c // 打印出依赖(包括编译器的库)
gcc -MM c.c//打印出依赖(不包括编译器的库)
gcc -M -MF c.d c.c// 把依赖写入文件c.d
gcc -c -o c.o c.c -MD -MF c.d// 编译c.o, 把依赖写入文件c.d
单独编译驱动时Makefile必须指定的东西交叉编译工具链
arch
内核路径
Makefile调试方法$(warning text):text为字符串例如:$(warning "hehe")
$(warning $(xxx)):可以输出xxx变量
$(errortext):text为字符串例如:$(error"hehe")
$(error$(xxx)): 可以输出xxx变量
warning和error区别:warning可以继续运行,而error会立刻中断运行
【Makefile系列--全面讲解】这个$(warning text)、$(error text)可以放在Makefile任何位置。

    推荐阅读