Makefile学习记录1

参考1:王利涛linux三剑客Makefile
参考2:宅学部落


1-1 开始

hello:helloworld.o 
	gcc -o hello helloworld.o
helloworld.o:helloworld.c
	gcc -o helloworld.o -c helloworld.c
clean:
	rm hello helloworld.o

2-1 条件变量复制及默认参数


DEBUG ?= false//默认false   ?= 是当DEBUG没有值的时候会赋值
ifeq ($(DEBUG),"true")
CC = gcc -g// 生成调试信息,可以用gdb等工具做调试
else
CC = gcc
endif


all:hello
hello:lcd.o player.o
	$(CC) -o hello lcd.o player.o
player.o:player.c
	$(CC) -o player.o -c player.c
lcd.o:lcd.c
	$(CC) -o lcd.o -c lcd.c
clean:
	rm lcd.o hello player.o

2-2

.PHONY:_all clean //伪目标,all,clean 对应伪target,不生成具体的文件

.PONHY:all clean
ifeq ($(DEBUG),"true")
CC = gcc -g
else
CC = gcc
endif
all:test1
all:test2
test1 :
	@echo "Just for test1:$@"
test2:
	@echo "Just for test2"

hello:lcd.o player.o
	@echo "start build hello"
	$(CC) -o hello lcd.o player.o
	@echo "build hello sucess"
#%.o:%.c
#	$(CC) -o $@ -c $^

clean:
	rm -f lcd.o hello player.o

在这里插入图片描述

2-3-1

.PHONY:clean

CC = gcc
BIN = hello
OBJS = player.o lcd.o
$(BIN): $(OBJS)
	$(CC) -o $(BIN) $(OBJS)

player.o:player.c
	$(CC) -o player.o -c player.c
lcd.o:lcd.c
	$(CC) -o lcd.o -c lcd.c
clean:
	rm -f player.o lcd.o hello

2-3-2

$(info $(MESSAGE)) // info 是makefile 内置函数,用于向控制台打印信息

.PHONY:all

HELLO = Good
TIME = morning!
STRING = $(HELLO) $(TIME)
$(info $(STRING))
TIME = afternoon!
$(info $(STRING))

all:
	@echo "done"

2-3-3 变量的重定义,作用范围

//类似于C语言中的全局变量,局部变量

.PHONY:clean

OBJS = player.o lcd.o
BIN  = mp3
N = 1
$(BIN): N = 2
$(BIN):$(OBJS)
	@echo "BIN: N = $(N)"
	gcc -o $(BIN) $(OBJS)
player.o:N= 3
player.o:player.c
	@echo "player.o: N = $(N)"
	gcc -o player.o -c player.c
lcd.o:lcd.c
	@echo "lcd.o: N = $(N)"
	gcc -o lcd.o -c lcd.c
clean:
	@echo "clean: N = $(N)"
	rm -f  $(BIN) $(OBJS)

输出
在这里插入图片描述

2-3-4

变量的作用范围

.PHONY:clean
N = 1
OBJS = player.o lcd.o
BIN  = mp3
$(BIN):$(OBJS)
	@echo "BIN:N=$(N)"
	gcc -o $(BIN) $(OBJS)
$(BIN): N = 2
%.o: N = 3 // 对每个target %.o都有一个变量N = 3
player.o:player.c
	@echo "player.o:N=$(N)"
	gcc -o player.o -c player.c
lcd.o:lcd.c
	@echo "lcd.o:N=$(N)"
	gcc -o lcd.o -c lcd.c
clean:
	@echo "clean: N = $(N)"
	rm  $(BIN) $(OBJS)



在这里插入代码片

2-3-5

// 根据依赖的顺序,去构建依赖
$@ 当前target
$^ 当前依赖

.PHONY:clean
OBJS = player.o lcd.o
BIN  = mp3
$(BIN):$(OBJS)
	@echo "BIN------------$@:$^"
	gcc -o $@ $^ 
player.o:player.c
	@echo "------------$@:$^"
	gcc -o $@ -c $^
lcd.o:lcd.c
	@echo "---------$@:$^"
	gcc -o $@ -c $^
clean:
	rm -f $(BIN) $(OBJS)

在这里插入图片描述

2-3-6

.PHONY:all
CFLAGS = -g
all:
	@echo "CFLAGS = $(CFLAGS)"
	@echo "SHELL = $(SHELL)"
	@echo "MAKE = $(MAKE)"
#   @echo "HOSTNAME = $(HOSTNAME)" 这里要用下面的方式
	@echo "HOSTNAME = $(shell hostname)"

输出
在这里插入图片描述

2-3-7

export 导出变量后,变量的值

#./ makefile路径
.PHONY:all

export N = 3
#N = 3
all:
	@echo "build...."
#	cd test && make N=$(N)
	cd test && make 
	make -C lcd 

#./lcd/makefile
.PHONY:all
all:
	@echo "build lcd"
	@echo "N = $(N)"

在这里插入图片描述

2-4

.PHONY:all

DEBUG = true
ifeq ($(DEBUG),true)
VERSION = debug
CC = gcc -g
else
VERSION = release
CC = gcc
endif

hello:hello.c
	@echo "build $(VERSION) mode"
	$(CC) -o $@ $^
clean:
	rm hello

输出

在这里插入图片描述

2-5-1 列表处理的内建函数

makefile内建函数使用
$(strip $(SRCS)) //去除SRCS中文件名间多余的空格
( s u b s t . c , . o , (subst .c,.o, (subst.c,.o,(strip $(SRCS))) // 把(第三个)变量文件名,格式替换 .c 后缀(第一个)-> .o后缀(第二个)
subst 用于生成对象文件的列表
( p a t s u b s t (patsubst %.c,%.d, (patsubst(SRCS))// 将.c后缀替换为.d后缀,用于生成依赖文件列表
$(SRCS:.c=.d)// 类似于 patsubst , 也是生成依赖文件列表

( f i n d s t r i n g u s b , (findstring usb, (findstringusb,(SRCS))//findstring 去找字符串,如果找到返回字符串;否则返回空
$(filter %.c %.h, $(SRCS))// 从 SRCS列表中,帅选出后缀为.c , .h 的文件

.PHONY:all
SRCS = player.c lcd.c usb.c media.c hello.h main.txt
OBJS = $(subst .c,.o,$(strip $(SRCS)))
DEPS = $(patsubst %.c,%.d,$(SRCS))
DEPS2 = $(SRCS:.c=.d)
FIND = $(findstring usb,$(SRCS))
FILTER = $(filter %.c %.h, $(SRCS))
all:
	@echo "OBJS = $(OBJS)"	
	@echo "DEPS = $(DEPS)"
	@echo "DEPS2 = $(DEPS2)"
	@echo "FIND = $(FIND)"
	@echo "FILTER = $(FILTER)"

输出
在这里插入图片描述

OBJS = $(subst .c,.o,$(SRCS)) 这样修改时

在这里插入图片描述

2-5-2 文件名操作的内建函数

.PHONY:all
LIB = /home/hello/libhello.a
#获得路径
LIB1 = $(dir $(LIB)) 
#滤除路径
LIB2 = $(notdir $(LIB)) 
#获得后缀
LIB3 = $(suffix $(LIB))
#滤除后缀
LIB4 = $(basename $(LIB))
#添加后缀,在LIB4的基础上
LIB5 = $(addsuffix .c,$(LIB4))
#添加前缀,在LIB2的基础上
LIB6 = $(addprefix /usr/lib/,$(LIB2))
#找出当前路径的.c后缀文件
SRCS = $(wildcard *.c)
all:
	@echo "LIB1 = $(LIB1)"
	@echo "LIB2 = $(LIB2)"
	@echo "LIB3 = $(LIB3)"
	@echo "LIB4 = $(LIB4)"
	@echo "LIB5 = $(LIB5)"
	@echo "LIB6 = $(LIB6)"	
	@echo "SRCS = $(SRCS)"

输出
在这里插入图片描述

.PHONY:all
LIB = /home/hello/libhello.a
LIB1 = $(dir $(LIB))
LIB2 = $(notdir $(LIB))
LIB3 = $(suffix $(LIB))
LIB4 = $(basename $(LIB))
LIB5 = $(addsuffix .c,$(LIB2))
LIB6 = $(addprefix /usr/lib/,$(LIB5))
SRCS = $(wildcard *.c *.h)
all:
	@echo "LIB1 = $(LIB1)"
	@echo "LIB2 = $(LIB2)"
	@echo "LIB3 = $(LIB3)"
	@echo "LIB4 = $(LIB4)"
	@echo "LIB5 = $(LIB5)"
	@echo "LIB6 = $(LIB6)"	
	@echo "SRCS = $(SRCS)"

在这里插入图片描述

2-5-3 foreach & shell

foreach 使用


A = 1 3 4 5 6 7 8 9
# 第一个元素: i 变量 对应A立刻表中的某个元素
# 第二个元素: A 列表,需要遍历的列表
# 第三个操作: 遍历到某个元素,都会将元素值赋值给i,并操作当前的操作
B = $(foreach i,$(A),$(addprefix 0.,$(i)))
C = $(foreach i,$(A),$(addsuffix .0,$(i)))


all:
	@echo "A = $(A)"
	@echo "B = $(B)"
	@echo "C = $(C)"

在这里插入图片描述

shell cmd的使用

.PHONY:all clean
$(shell mkdir -p s1)
$(shell mkdir -p s2)
all:
	@echo "hello world"
clean:
	rm -r s1 s2

make 后, 构建了两个目录 s1, s2

2-6 构建 static & dll 库

2-6-1 static 库

.PHONY:clean

libmath.a:libmath.o
	ar rcs $@ $^
libmath.o:libmath.c libmath.h

A:main.o 
	gcc -o $@ main.o  -I. -L. -lmath
main.o:main.c
	gcc -o $@ -c $^ 
clean:
	rm libmath.a libmath.o
	rm A main.o

2-6-2 dll库

.PHONY:clean AA

libdll.so:dll.o
	gcc -o $@ -shared $^
dll.o:dll.c
	gcc -o $@ -fPIC -c $^ 

SOURCE2 = main.c 
DE_SOURCE2 = $(subst .c,.o,$(strip $(SOURCE2)))
CFLAGS = -I.
DLLLIBS = -L. -ldll
$(info $(DE_SOURCE2))
TA = A
 

AA: $(TA)

$(TA): $(DE_SOURCE2)
	gcc -o $@ $^ $(CFLAGS) $(DLLLIBS)
%.o:%.c
	gcc -o $@ -fPIC -c $^

clean:
	rm libdll.so dll.o
	rm $(TA) $(SOURCE2)

2-8

2-8-1

.PHONY:clean

hello:hello.o
	gcc -o hello hello.o
#hello.o:hello.c
#	gcc -o $@ -c $^
clean:
	rm hello hello.o

2-8-2 测试环境变量的值


.PHONY:all
all:
	@echo "CC = $(CC)"
	@echo "AS = $(AS)"
	@echo "CXX = $(CXX)"
	@echo "AR = $(AR)"
	@echo "CFLAGS = $(CFLAGS)"
	@echo "CXXFLAGS = $(CXXFLAGS)"
	@echo "ASFLAGS = $(ASFLAGS)"
	@echo "ARFLAGS = $(ARFLAAGS)"
	@echo "LDFLAGS = $(LDFLAGS)"

输出
在这里插入图片描述

2-8-3

.PHONY: clean

test1 test2:// 这里target是test1 (那意思是字符后第一个空格就分出了target)
	@echo "test:$@"

hello:player.o lcd.o media.o
	gcc -o  $@ $^
%.o:%.c
	gcc -o $@ -c $^
clean:
	rm *.o hello

在这里插入图片描述

3.1

.PHONY:all clean

SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)
BIN  = mp3
all: $(BIN)

$(BIN):$(OBJS)
	@echo "SRCS =$(SRCS)"
	@echo "OBJS =$(OBJS)"
	gcc -o $@ $^
%.o:%.c
	gcc -o $@ -c $^
clean:
	rm -f  $(BIN) $(OBJS)

输出
在这里插入图片描述

3.2

// gcc -MM 是生成依赖文件,不进行编译什么的,这个xxx.d的依赖能够保证依赖的完整性,在include后
// 这里的运发,文件列表,都是文件名的列表,不一定真实存在
// 所以*.d 是不存在的,再gcc -MM 生成的时候,是一个空的文件,使用> 或者>> 效果是等效的

.PHONY:all clean

SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)
DEPS = $(SRCS:.c=.d)
BIN  = mp3
all: $(BIN) $(DEPS)
ifneq ("$(wildcard $(DEPS))","")	
include $(DEPS)
endif
$(BIN):$(OBJS)
	gcc -o $@ $^
%.o:%.c
	gcc -o $@ -c $(filter %.c,$^)
%.d:%.c
	gcc -MM $^ > $@
clean:
	rm -f  $(BIN) $(OBJS) $(DEPS)

输出
在这里插入图片描述

3.3 多级makefile与include

//使用include 文件,
//make -C path 执行指定路径的makefile

源目录结构
在这里插入图片描述

./makefile

.PHONY:all clean

all:
	make -C lcd
	make -C usb
	make -C media
	make -C app

clean:
	rm -fr app/player.o app/player.d app/mp3
	rm -fr usb/usb.o usb/usb.d
	rm -fr lcd/lcd.o lcd/lcd.d
	rm -fr media/media.o media/media.d

./common.mk

.PHONY:all clean

SRCS = $(wildcard *.c)
$(info $(SRCS))
OBJS = $(SRCS:.c=.o)
DEPS = $(SRCS:.c=.d)
 
all: $(DEPS) $(OBJS) $(BIN)

ifneq ("$(wildcard $(DEPS))","")	
include $(DEPS)
endif
$(BIN):$(OBJS)
	gcc -o $@ $^ ../lcd/lcd.o ../usb/usb.o ../media/media.o
%.o:%.c
	gcc -o $@ -c $(filter %.c,$^)
%.d:%.c
	gcc -MM $^ > $@
AA: AB AC

AB: 1.c 2.c 3.c 
AB: 4.c 
	echo "$@ $^"

clean:
	rm -f  $(BIN) $(OBJS) $(DEPS)

./app/makefile


BIN = mp3 

include ../common.mk

./usb/makefile


BIN = 

include ../common.mk

./media/makefile


BIN = 

include ../common.mk

./lcd/makefile


BIN = 

include ../common.mk

在这里插入图片描述

3.4 对OBJS和BIN 引入LINK_OBJ_DIR & addprefix

与3.3 对比,3.4改动了./common.mk和 ./makefile文件
在这里插入图片描述

源文件

./makefile

.PHONY:all clean

all:
	make -C lcd
	make -C usb
	make -C media
	make -C app

clean:
	rm -f  mp3
	rm -fr app/link_obj/*.o app/player.d
	rm -fr usb/usb.o usb/usb.d
	rm -fr lcd/lcd.o lcd/lcd.d
	rm -fr media/media.o media/media.d
	rm -rf app/link_obj

与3.3对比
在这里插入图片描述
./common.mk

.PHONY:all clean

SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)
DEPS = $(SRCS:.c=.d)
BIN := $(addprefix /home/mp3/,$(BIN))

LINK_OBJ_DIR =/home/mp3/app/link_obj
$(shell mkdir -p $(LINK_OBJ_DIR))

OBJS := $(addprefix $(LINK_OBJ_DIR)/,$(OBJS))

LINK_OBJ = $(wildcard $(LINK_OBJ_DIR)/*.o)
LINK_OBJ +=$(OBJS)
all: $(DEPS) $(OBJS) $(BIN)
ifneq ("$(wildcard $(DEPS))","")	
include $(DEPS)
endif
$(BIN):$(LINK_OBJ)
	@echo "LINK_OBJ=$(LINK_OBJ)"
	gcc -o $@ $^ 
$(LINK_OBJ_DIR)/%.o:%.c
	gcc -o $@ -c $(filter %.c,$^)
%.d:%.c
	gcc -MM $^ | sed 's,\(.*\).o[ :]*,$(LINK_OBJ_DIR)/\1.o:,g' > $@
clean:
	rm -f  $(BIN) $(OBJS) $(DEPS)

对BIN,OBJS等引入了prefix,将生成的BIN,OBJS放入了LINK_OBJ_DIR
在这里插入图片描述

3.5 引入shell pwd 项目路径

在3.4的基础上,将绝对路径改为pwd 的项目路径
编译前
在这里插入图片描述
编译后
在这里插入图片描述
相关改动./app/makefile, ./makefile, common.mk

./app/makefile


BIN = mp3 

include $(BUILD_ROOT)/common.mk

在这里插入图片描述

./makefile

.PHONY:all clean
export BUILD_ROOT = $(shell pwd) // 获得当前项目的根目录
all:
	make -C lcd
	make -C usb
	make -C media
	make -C app

clean:
	rm -rf app/link_obj app/dep mp3

在这里插入图片描述

./common.mk

.PHONY:all clean

SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)
DEPS = $(SRCS:.c=.d)
BIN := $(addprefix $(BUILD_ROOT)/,$(BIN))

LINK_OBJ_DIR = $(BUILD_ROOT)/app/link_obj
$(shell mkdir -p $(LINK_OBJ_DIR))
DEP_DIR = $(BUILD_ROOT)/app/dep
$(shell mkdir -p $(DEP_DIR))

OBJS := $(addprefix $(LINK_OBJ_DIR)/,$(OBJS))
DEPS := $(addprefix $(DEP_DIR)/,$(DEPS))

LINK_OBJ = $(wildcard $(LINK_OBJ_DIR)/*.o)
LINK_OBJ +=$(OBJS)
all: $(DEPS) $(OBJS) $(BIN)
ifneq ("$(wildcard $(DEPS))","")	
include $(DEPS)
endif
$(BIN):$(LINK_OBJ)
	@echo "LINK_OBJ=$(LINK_OBJ)"
	gcc -o $@ $^ 
$(LINK_OBJ_DIR)/%.o:%.c
	gcc -o $@ -c $(filter %.c,$^)
$(DEP_DIR)/%.d:%.c
	gcc -MM $(filter %.c,$^) | sed 's,\(.*\).o[ :]*,$(LINK_OBJ_DIR)/\1.o $@:,g' > $@
clean:
	rm -f  $(BIN) $(OBJS) $(DEPS)

在这里插入图片描述

3.6 引入HEAD_PATH 头文件目录

与3.5的变化
1. buil_root 目录中添加一个方头文件的目录
2. 在makefile 文件中引入了相关处理的参数

编译前后对比

编译前
在这里插入图片描述
编译后
在这里插入图片描述

相关源文件 ./makefile, ./common.mk,

./makefile

.PHONY:all clean
export BUILD_ROOT = $(shell pwd)
export HEAD_PATH = $(BUILD_ROOT)/inc
all:
	make -C lcd
	make -C usb
	make -C media
	make -C app

clean:
	rm -rf app/link_obj app/dep mp3

在这里插入图片描述

./common.mk

.PHONY:all clean

SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)
DEPS = $(SRCS:.c=.d)
BIN := $(addprefix $(BUILD_ROOT)/,$(BIN))

LINK_OBJ_DIR = $(BUILD_ROOT)/app/link_obj
$(shell mkdir -p $(LINK_OBJ_DIR))
DEP_DIR = $(BUILD_ROOT)/app/dep
$(shell mkdir -p $(DEP_DIR))

OBJS := $(addprefix $(LINK_OBJ_DIR)/,$(OBJS))
DEPS := $(addprefix $(DEP_DIR)/,$(DEPS))

LINK_OBJ = $(wildcard $(LINK_OBJ_DIR)/*.o)
LINK_OBJ +=$(OBJS)
all: $(DEPS) $(OBJS) $(BIN)
ifneq ("$(wildcard $(DEPS))","")	
include $(DEPS)
endif
$(BIN):$(LINK_OBJ)
	@echo "LINK_OBJ=$(LINK_OBJ)"
	gcc -o $@ $^ 
$(LINK_OBJ_DIR)/%.o:%.c
	gcc -I$(HEAD_PATH) -o $@ -c $(filter %.c,$^)
$(DEP_DIR)/%.d:%.c
	gcc -I$(HEAD_PATH) -MM $(filter %.c,$^) | sed 's,\(.*\)\.o[ :]*,$(LINK_OBJ_DIR)/\1.o $@:,g' > $@
clean:
	rm -f  $(BIN) $(OBJS) $(DEPS)

在这里插入图片描述

3.7 引入static lib 构建

与3.6的变化在./common.mk中引入了lib相关的编译,在需要生成lib的模块中,子 makefile 添加LIB变量

源文件

./makefile 输出构建的内容

.PHONY:all clean
export BUILD_ROOT = $(shell pwd)
export HEAD_PATH = $(BUILD_ROOT)/inc
all:
	make -C lcd
	make -C usb
	make -C media
	make -C app

clean:
	rm -rf app/link_obj app/dep app/lib_obj mp3
	rm -rf lib/*.a

在这里插入图片描述
./common.mk

.PHONY:all clean

SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)
DEPS = $(SRCS:.c=.d)
BIN := $(addprefix $(BUILD_ROOT)/,$(BIN))

LINK_OBJ_DIR = $(BUILD_ROOT)/app/link_obj
$(shell mkdir -p $(LINK_OBJ_DIR))
DEP_DIR = $(BUILD_ROOT)/app/dep
$(shell mkdir -p $(DEP_DIR))
LIB_OBJ_DIR = $(BUILD_ROOT)/app/lib_obj
$(shell mkdir -p $(LIB_OBJ_DIR))
LIB_DIR = $(BUILD_ROOT)/lib
$(shell mkdir -p $(LIB_OBJ_DIR))

OBJ_DIR = $(LINK_OBJ_DIR)
ifneq ("$(LIB)","")
OBJ_DIR = $(LIB_OBJ_DIR)
endif

OBJS := $(addprefix $(OBJ_DIR)/,$(OBJS))
DEPS := $(addprefix $(DEP_DIR)/,$(DEPS))
LIB  := $(addprefix $(LIB_DIR)/,$(LIB))

LINK_OBJ = $(wildcard $(LINK_OBJ_DIR)/*.o)
LINK_OBJ +=$(OBJS)

LIB_DEP = $(wildcard $(LIB_DIR)/*.a)
LINK_LIB_NAME = $(patsubst lib%,-l%,$(basename $(notdir $(LIB_DEP))))

all: $(DEPS) $(OBJS) $(LIB) $(BIN)
ifneq ("$(wildcard $(DEPS))","")	
include $(DEPS)
endif
$(BIN):$(LINK_OBJ) $(LIB_DEP)
	@echo "LINK_LIB_NAME=$(LINK_LIB_NAME)"
	gcc -o $@ $^ -L$(LIB_DIR) $(LINK_LIB_NAME)
$(LIB):$(OBJS)
	ar rcs $@ $^
$(OBJ_DIR)/%.o:%.c
	gcc -I$(HEAD_PATH) -o $@ -c $(filter %.c,$^)
$(DEP_DIR)/%.d:%.c
	gcc -I$(HEAD_PATH) -MM $(filter %.c,$^) | sed 's,\(.*\)\.o[ :]*,$(OBJ_DIR)/\1.o $@:,g' > $@
clean:
	rm -f  $(BIN) $(OBJS) $(DEPS)

在这里插入图片描述
需要构建static 文件的子模块的makefile,引入LIB


BIN = 
LIB = libmedia.a
include ../common.mk

3.8 引入动态库dll lib

关注./makefile, ./common.mk, 需要构建dll lib模块的子makefile

源文件

./makefile
添加了math模块,对应生成dll lib

.PHONY:all clean
export BUILD_ROOT = $(shell pwd)
export HEAD_PATH = $(BUILD_ROOT)/inc
all:
	make -C lcd
	make -C usb
	make -C media
	make -C math
	make -C app

clean:
	rm -rf app/link_obj app/dep app/lib_obj mp3
	rm -rf lib/*.a lib/*.so

在这里插入图片描述
./common.mk

.PHONY:all clean

SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)
DEPS = $(SRCS:.c=.d)
BIN := $(addprefix $(BUILD_ROOT)/,$(BIN))

LINK_OBJ_DIR = $(BUILD_ROOT)/app/link_obj
$(shell mkdir -p $(LINK_OBJ_DIR))
DEP_DIR = $(BUILD_ROOT)/app/dep
$(shell mkdir -p $(DEP_DIR))
LIB_OBJ_DIR = $(BUILD_ROOT)/app/lib_obj
$(shell mkdir -p $(LIB_OBJ_DIR))
LIB_DIR = $(BUILD_ROOT)/lib


OBJ_DIR = $(LINK_OBJ_DIR)
ifneq ("$(LIB)","")
OBJ_DIR = $(LIB_OBJ_DIR)
endif
ifneq ("$(DLL)","")
OBJ_DIR = $(LIB_OBJ_DIR)
PIC     = -fPIC
endif


OBJS := $(addprefix $(OBJ_DIR)/,$(OBJS))
DEPS := $(addprefix $(DEP_DIR)/,$(DEPS))
LIB  := $(addprefix $(LIB_DIR)/,$(LIB))
DLL  := $(addprefix $(LIB_DIR)/,$(DLL))

LINK_OBJ = $(wildcard $(LINK_OBJ_DIR)/*.o)
LINK_OBJ += $(OBJS)

LIB_DEP = $(wildcard $(LIB_DIR)/*.a) $(wildcard $(LIB_DIR)/*.so)
LINK_LIB_NAME = $(patsubst lib%,-l%,$(basename $(notdir $(LIB_DEP))))

all: $(DEPS) $(OBJS) $(LIB) $(DLL) $(BIN)
ifneq ("$(wildcard $(DEPS))","")	
include $(DEPS)
endif
$(BIN):$(LINK_OBJ)

	gcc -o $@ $^ -L$(LIB_DIR) $(LINK_LIB_NAME)
$(LIB):$(OBJS)
	ar rcs $@ $^
$(DLL):$(OBJS)
	gcc -shared -o $@ $^
$(OBJ_DIR)/%.o:%.c
	gcc -I$(HEAD_PATH) -o $@ -c $(PIC) $(filter %.c,$^)
$(DEP_DIR)/%.d:%.c
	gcc -I$(HEAD_PATH) -MM $(filter %.c,$^) | sed 's,\(.*\)\.o[ :]*,$(OBJ_DIR)/\1.o $@:,g' > $@
clean:
	rm -f  $(BIN) $(OBJS) $(DEPS)

在这里插入图片描述
生成dll lib模块的子makefile文件

BIN =
LIB =
DLL = libmath.so
include $(BUILD_ROOT)/common.mk

3.9 引入ext lib到当前项目

在./common.mk中引入了对外部库的支持

源文件

.PHONY:all clean

SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)
DEPS = $(SRCS:.c=.d)
BIN := $(addprefix $(BUILD_ROOT)/,$(BIN))

LINK_OBJ_DIR = $(BUILD_ROOT)/app/link_obj
$(shell mkdir -p $(LINK_OBJ_DIR))
DEP_DIR = $(BUILD_ROOT)/app/dep
$(shell mkdir -p $(DEP_DIR))
LIB_OBJ_DIR = $(BUILD_ROOT)/app/lib_obj
$(shell mkdir -p $(LIB_OBJ_DIR))
LIB_DIR = $(BUILD_ROOT)/lib

OBJ_DIR = $(LINK_OBJ_DIR)
ifneq ("$(LIB)","")
OBJ_DIR = $(LIB_OBJ_DIR)
endif
ifneq ("$(DLL)","")
OBJ_DIR = $(LIB_OBJ_DIR)
PIC     = -fPIC
endif


OBJS := $(addprefix $(OBJ_DIR)/,$(OBJS))
DEPS := $(addprefix $(DEP_DIR)/,$(DEPS))
LIB  := $(addprefix $(LIB_DIR)/,$(LIB))
DLL  := $(addprefix $(LIB_DIR)/,$(DLL))

LINK_OBJ = $(wildcard $(LINK_OBJ_DIR)/*.o)
LINK_OBJ += $(OBJS)

LIB_DEP = $(wildcard $(LIB_DIR)/*.a) $(wildcard $(LIB_DIR)/*.so)
LIB_DEP += $(wildcard $(LIB_DIR)/ext_lib/*.a) $(wildcard $(LIB_DIR)/ext_lib/*.so)
LINK_LIB_NAME = $(patsubst lib%,-l%,$(basename $(notdir $(LIB_DEP))))

all: $(DEPS) $(OBJS) $(LIB) $(DLL) $(BIN)
ifneq ("$(wildcard $(DEPS))","")	
include $(DEPS)
endif
$(BIN):$(LINK_OBJ)
	gcc -o $@ $^ -L$(LIB_DIR) -L$(LIB_DIR)/ext_lib $(LINK_LIB_NAME)
$(LIB):$(OBJS)
	ar rcs $@ $^
$(DLL):$(OBJS)
	gcc -shared -o $@ $^
$(OBJ_DIR)/%.o:%.c
	gcc -I$(HEAD_PATH) -o $@ -c $(PIC) $(filter %.c,$^)
$(DEP_DIR)/%.d:%.c
	gcc -I$(HEAD_PATH) -MM $(filter %.c,$^) | sed 's,\(.*\)\.o[ :]*,$(OBJ_DIR)/\1.o $@:,g' > $@
clean:
	rm -f  $(BIN) $(OBJS) $(DEPS)

在这里插入图片描述

3.10 引入install & uninstall

相关文件./makefile

.PHONY:all clean
export BUILD_ROOT = $(shell pwd)
export HEAD_PATH = $(BUILD_ROOT)/inc
all:
	make -C lcd
	make -C usb
	make -C media
	make -C math
	make -C app

clean:
	rm -rf app/link_obj app/dep app/lib_obj mp3
	rm -rf lib/*.a
	rm -rf lib/*.so
install:
	cp mp3 /usr/bin
	cp lib/libmath.so /usr/lib
	cp lib/ext_lib/librmvb.so /usr/lib
uninstall:
	rm /usr/bin/mp3
	rm /usr/lib/libmath.so
	rm /usr/lib/librmvb.so

3.11 引入配置文件

./makefile ./config.mk 两个相关文件

源文件

./config.mk

#---------------------------------
# ZHAIXUE_MAKEFILE
# Description: a project makefile demo
# Author     : ddblog@qq.com
# Date	     : 2016.12.23
#---------------------------------
# build root directory
export BUILD_ROOT = $(shell pwd)

# Head files PATH
export HEAD_PATH = $(BUILD_ROOT)/inc

#build directory
#when you add a module,you need add you directory
# here
BUILD_DIR = $(BUILD_ROOT)/lcd/ \
	    $(BUILD_ROOT)/usb/ \
	    $(BUILD_ROOT)/media/ \
	    $(BUILD_ROOT)/math/ \
	    $(BUILD_ROOT)/app/

DEBUG = true
ARCH  = arm

./makefile

.PHONY:all clean install uninstall
include config.mk

all:
	@for dir in $(BUILD_DIR); \
	do \
		make -C $$dir; \
	done
clean:
	rm -rf app/link_obj app/dep app/lib_obj mp3
	rm -rf lib/*.a
	rm -rf lib/*.so
install:
	cp mp3 /usr/bin
	cp lib/libmath.so /usr/lib
	cp lib/ext_lib/librmvb.so /usr/lib
uninstall:
	rm -f /usr/bin/mp3
	rm /usr/lib/libmath.so
	rm /usr/lib/librmvb.so

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刀法孜然

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值