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)

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.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

单独编译驱动时Makefile必须指定的东西

交叉编译工具链
arch
内核路径

Makefile调试方法

$(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的使用和源码

Elasticsearch系列---全面了解Document

Makefile学习笔记系列4:Makefile模板化

Makefile学习笔记系列4:Makefile模板化

Makefile

云讲堂 | 5期视频带你全面了解滴滴Logi-KafkaManager