Linux内核Makefile用于日常工程
我当前的目录结构:
zxf@zxf-virtual-machine:com_make$ ls
a b c d include main.c Makefile Makefile.build
zxf@zxf-virtual-machine:com_make$ tree
.
├── a
│ ├── a.c
│ └── Makefile
├── b
│ ├── b.c
│ └── Makefile
├── c
│ ├── c.c
│ └── Makefile
├── d
│ ├── d.c
│ └── Makefile
├── include
│ ├── a.h
│ ├── b.h
│ ├── c.h
│ └── d.h
├── main.c
├── Makefile
└── Makefile.build
5 directories, 15 files
zxf@zxf-virtual-machine:com_make$
顶层目录下的Makefile 和Makefile.build
zxf@zxf-virtual-machine:com_make$ cat Makefile
# 定义全局变量
CROSS_COMPILE =
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 -I /usr/include/
# 指定链接库
LDFLAGS :=
# 将符号导出
export CFLAGS LDFLAGS
# 获得当前工程的顶层路经,并导出
TOPDIR := $(shell pwd)
export TOPDIR
# 定义最终目标文件名
TARGET := main
# 定义顶层目录下的文件及目录结构
obj-y += main.o
obj-y += a/
obj-y += b/
obj-y += c/
obj-y += d/
# -C 指定目录;-f 指定该文件为Makefile
# 根据build-in.o 进行编译
#
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)
zxf@zxf-virtual-machine:com_make$ cat Makefile.build
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 : $(cur_objs) $(subdir_objs)
$(LD) -r -o $@ $^
dep_file = .$@.d
%.o : %.c
$(CC) $(CFLAGS) -Wp,-MD,$(dep_file) -c -o $@ $<
.PHONY : $(PHONY)
zxf@zxf-virtual-machine:com_make$
其它目录的内容及结构
zxf@zxf-virtual-machine:com_make$ ls
a b c d include main.c Makefile Makefile.build
zxf@zxf-virtual-machine:com_make$ cd a/
zxf@zxf-virtual-machine:a$ cat a.c
#include "a.h"
#include "stdio.h"
void fun_a(void)
{
printf("fun_a A = %d\n",A);
}
zxf@zxf-virtual-machine:a$ cat Makefile
obj-y += a.o
zxf@zxf-virtual-machine:a$ cd ..
zxf@zxf-virtual-machine:com_make$ ls
a b c d include main.c Makefile Makefile.build
zxf@zxf-virtual-machine:com_make$ cd b/
zxf@zxf-virtual-machine:b$ ls
b.c Makefile
zxf@zxf-virtual-machine:b$ cat b.c
#include "stdio.h"
#include "b.h"
void fun_b(void)
{
printf("fun_b B = %d\n",B);
}
zxf@zxf-virtual-machine:b$ cat Makefile
obj-y += b.o
zxf@zxf-virtual-machine:b$ ls
b.c Makefile
zxf@zxf-virtual-machine:b$ cd ..
zxf@zxf-virtual-machine:com_make$ ls
a b c d include main.c Makefile Makefile.build
zxf@zxf-virtual-machine:com_make$ cd include/
zxf@zxf-virtual-machine:include$ ls
a.h b.h c.h d.h
zxf@zxf-virtual-machine:include$ cat a.h
#ifndef _A_H_
#define _A_H_
#define A 1
#endif
zxf@zxf-virtual-machine:include$ cat b.h
#ifndef _B_H_
#define _B_H_
#define B 1
#endif
zxf@zxf-virtual-machine:com_make$ ls
a b c d include main.c Makefile Makefile.build
zxf@zxf-virtual-machine:com_make$ make
make -C ./ -f /home/zxf/Desktop/farsightworkspace/code/com_make/Makefile.build
make[1]: Entering directory `/home/zxf/Desktop/farsightworkspace/code/com_make'
make -C a -f /home/zxf/Desktop/farsightworkspace/code/com_make/Makefile.build
make[2]: Entering directory `/home/zxf/Desktop/farsightworkspace/code/com_make/a'
gcc -Wall -O2 -g -I /home/zxf/Desktop/farsightworkspace/code/com_make/include -I /usr/include/ -Wp,-MD,.a.o.d -c -o a.o a.c
ld -r -o built-in.o a.o
make[2]: Leaving directory `/home/zxf/Desktop/farsightworkspace/code/com_make/a'
make -C b -f /home/zxf/Desktop/farsightworkspace/code/com_make/Makefile.build
make[2]: Entering directory `/home/zxf/Desktop/farsightworkspace/code/com_make/b'
gcc -Wall -O2 -g -I /home/zxf/Desktop/farsightworkspace/code/com_make/include -I /usr/include/ -Wp,-MD,.b.o.d -c -o b.o b.c
ld -r -o built-in.o b.o
make[2]: Leaving directory `/home/zxf/Desktop/farsightworkspace/code/com_make/b'
make -C c -f /home/zxf/Desktop/farsightworkspace/code/com_make/Makefile.build
make[2]: Entering directory `/home/zxf/Desktop/farsightworkspace/code/com_make/c'
gcc -Wall -O2 -g -I /home/zxf/Desktop/farsightworkspace/code/com_make/include -I /usr/include/ -Wp,-MD,.c.o.d -c -o c.o c.c
ld -r -o built-in.o c.o
make[2]: Leaving directory `/home/zxf/Desktop/farsightworkspace/code/com_make/c'
make -C d -f /home/zxf/Desktop/farsightworkspace/code/com_make/Makefile.build
make[2]: Entering directory `/home/zxf/Desktop/farsightworkspace/code/com_make/d'
gcc -Wall -O2 -g -I /home/zxf/Desktop/farsightworkspace/code/com_make/include -I /usr/include/ -Wp,-MD,.d.o.d -c -o d.o d.c
ld -r -o built-in.o d.o
make[2]: Leaving directory `/home/zxf/Desktop/farsightworkspace/code/com_make/d'
gcc -Wall -O2 -g -I /home/zxf/Desktop/farsightworkspace/code/com_make/include -I /usr/include/ -Wp,-MD,.main.o.d -c -o main.o main.c
ld -r -o built-in.o main.o a/built-in.o b/built-in.o c/built-in.o d/built-in.o
make[1]: Leaving directory `/home/zxf/Desktop/farsightworkspace/code/com_make'
gcc -o main built-in.o
zxf@zxf-virtual-machine:com_make$