满堂花醉三千客,一剑霜寒十四州。这篇文章主要讲述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任何位置。
推荐阅读
- Linux 3
- linux之chsh命令
- K8s Get "http://127.0.0.1:10252/healthz": dial tcp
- 前端软件系列--curl
- 重新学习C语言day07
- 入门学Python一定要知道的requests模块安装及使用
- 思科--nat
- 你知道线程池是如何退出程序的吗()
- 重新学习C语言day08