Makefile系列--全面讲解
Posted IT利刃出鞘
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 := samsung
ifeq ($(PLAT) , samsung)
CROSS_COMPILE := arm-linux-gnueabi-
KDIR := /work/plat/samsung
endif
modules:
make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) clean
obj-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)
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.o
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
# 这个宏判断,第一次执行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 test
distclean:
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
交叉编译工具链
arch
内核路径
$(warning text) :text为字符串 例如:$(warning "hehe")
$(warning $(xxx)) :可以输出xxx变量
$(error text) : text为字符串 例如:$(error"hehe")
$(error $(xxx)) : 可以输出xxx变量
warning和error区别:warning可以继续运行,而error会立刻中断运行
这个$(warning text)、$(error text)可以放在Makefile任何位置。
以上是关于Makefile系列--全面讲解的主要内容,如果未能解决你的问题,请参考以下文章
源码详解系列 ------ 全面讲解logback的使用和源码