Makefile通用編寫規則

#簡單實用的Makefile模板:
 
objs := a.o b.o
 
test:$(objs)
    gcc -o test $^
 
# .a.o.d .b.o.d
dep_files := $(foreach f,$(objs),.$(f).d)
dep_files := $(wildcard $(dep_files))
 
ifneq ($(dep_files),)
  include $(dep_files)
endif
 
%.o : %.c 
    gcc -Wp,-MD,.$@.d -c -o $@ $<
 
clean:
    rm *.o test 
 
#/*關鍵解釋*/    
這裏面用到了一些Makefile函數,首先咱們來講一下Makefile函數的格式:
$(函數名 參數,參數,......)
這裏用到了兩個函數,咱們分別來講一下:
一、dep_files := $(foreach f,$(objs),.$(f).d)
依次取出objs中的成員,放在f中,而後加上.d後綴,組成一個字符串(各個成員以空格分開),返回給dep_files !
二、dep_files := $(wildcard $(dep_files))
展開當前目錄下名字爲符合dep_files的文件名,並組成字符串返回給dep_files
 
此外還有一點要說的是:
gcc -Wp,-MD,.$@.d -c -o $@ $<
一、-Wp,-MD:表示生成依賴文件,後跟依賴文件的名字
二、$@:表示規則的目標
      $^:全部的依賴
      $<:第一個依賴
      $?:表明依賴文件列表中被改變過的全部文件
 
# 第一次執行,沒有依賴文件,這個ifneq不執行,
# 當修改.h文件以後,判斷執行這個include $(dep_files)
ifneq ($(dep_files),)
  include $(dep_files)
endif
 
參考內核的Makefile編寫包括Makefile和Makefile.build
 
#Makefile 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 += -I $(shell pwd)/include
 
LDFLAGS := -lm -lfreetype
 
export 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
    $(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.build file 
 
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 依賴當前目錄下的build-in.o 
built-in.o : $(cur_objs) $(subdir_objs)
    $(LD) -r -o $@ $^
 
dep_file = .$@.d
 
%.o : %.c
    $(CC) $(CFLAGS) -Wp,-MD,$(dep_file) -c -o $@ $<
    
.PHONY : $(PHONY)
 
關鍵點說明:linux

相關文章
相關標籤/搜索