本文共 2359 字,大约阅读时间需要 7 分钟。
#主Makefile#终极目标TGT = target#子目录SUB_DIR = main test#子目标export SUB_TGT = built-in.o#顶层目录export TOP_DIR = $(shell pwd)#头文件目录export HEAD_DIR = $(TOP_DIR)/head#交叉编译器#CROSS_COMPILE = arm-linux-gnueabihf-export CC = $(CROSS_COMPILE)gcc#编译选项export CFLAGS = -I$(HEAD_DIR) -Wall#编译链接器export LD = ld#编译链接选项export LDFLAGS = #终极目标规则$(TGT): $(SUB_DIR) $(CC) $(CFLAGS) $(^:=/$(SUB_TGT)) -o $@#如何进入子目录规则$(SUB_DIR): make -C $@clean: rm -vf $(TGT) for dir in $(SUB_DIR); do \ make -C $$dir clean; \ done.PHONY: clean $(SUB_DIR)
make中有三条规则1. $(TGT) 链接生成最终目标规则2. $(SUB_DIR) 第一条规则的依赖,因为依赖是个目录,所以要有一个规则来说明如何进入到此目录3. clean 清理规则
#子Makefile:用来告诉make如何生成当前目录下的子目标built-in.oSRCS = test.cSUB_DIR = foo$(SUB_TGT): $(SRCS:.c=.o) $(SUB_DIR) $(LD) $(LDFLAGS) $(SRCS:.c=.o) $(SUB_DIR:=/$(SUB_TGT)) -r -o $@%.o: %.c $(CC) $(CFLAGS) -c $<%.d: %.c $(CC) $(CFLAGS) $< -MM > $@sinclude $(SRCS:.c=.d)$(SUB_DIR): make -C $@clean: rm -vf $(SUB_TGT) $(SRCS:.c=.o) $(SRCS:.c=.d) for dir in $(SUB_DIR); do \ make -C $$dir clean; \ done.PHONY: clean $(SUB_DIR)
图解:
├── main.c ├── Makefile └── test.cgcc -c main.c -o main.ogcc -c test.c -o test.o #生成对应的.old main.o test.o -r -o main #链接 -r:生成可重定位的输出(称为部分连接)gcc main -o a.out #生成终极目标
#当前目录 的上一级目录 关键字direxport HEAD_DIR = $(dir $(TOP_DIR))include
ifeq ("$(origin O)", "command line") KBUILD_OUTPUT := $(O)endif
上述代码中先使用 ifeq 来判断"$(origin O)"和"command line"是否相等。这里用到了 Makefile
中的函数 origin,origin 和其他的函数不一样,它不操作变量的值,origin 用于告诉你变量是哪 来的,语法为:$(origin)
variable 是变量名,origin 函数的返回值就是变量来源,因此$(origin O)就是变量 O 的来源。如果变量 O 是在命令行定义的那么它的来源就是"command line",这样"$(origin O)"和"command line"就相等了。当这两个相等的时候变量 KBUILD_OUTPUT 就等于 O 的值,比如在命令行中输入“make O=/home/zys/linux/uboot/out “ 的 话 那 么 KBUILD_OUTPUT =/home/zys/linux/uboot/out 。如果没有在命令行输入 O 的 话KBUILD_OUTPUT = 空。
参考来自uboot的主Makefile
ifneq ($(KBUILD_OUTPUT),)KBUILD_OUTPUT := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) \ && /bin/pwd)$(if $(KBUILD_OUTPUT),, \ $(error failed to create output directory "$(saved-output)")) endif
转载地址:http://fxqqj.baihongyu.com/