init-y := $(patsubst %/, %/built-in.o, $(init-y)) ## 表示将$(init-y)列表中"/"替换为"/built-in.o",也就是最终init-y == init/built-in.o
include $(srctree)/arch/$(SRCARCH)/Makefile
vmlinux映像生成的一般规则综述
通过以上分析路径
all --> vmlinux --> $(vmlinux-lds) $(vmlinux-init) --> $(head-y) $(init-y) --
--> built-in.o head32.o head_32.o init_task.o --> *.c *.S
$@ 表示目标文件
$^ 表示所有的依赖文件
$< 表示第一个依赖文件
$? 表示比目标还要新的依赖文件列表
% 仅当目标是函数库文件中,表示规则中的目标成员名。例如,如果一个目标是“foo.a(bar.o)”,那么,“ %”就是“bar.o”,“$@”就是“foo.a”。如果目标不是函数库文件(Unix下是[.a],Windows下是[.lib]),那么,其值为空。
+ 这 个 变 量 很 像 “ + 这个变量很像“ +这个变量很像“^”,也是所有依赖目标的集合。只是它不去除重复的依赖目标。
∗
这
个
变
量
表
示
目
标
模
式
中
“
* 这个变量表示目标模式中“%”及其之前的部分。如果目标是“dir/a.foo.b”,并且目标的模式是“a.%.b”,那么,“
∗这个变量表示目标模式中“”的值就是“dir/a.foo”。这个变量对于构造有关联的文件名是比较有较。如果目标中没有模式的定义,那么“
∗
”
也
就
不
能
被
推
导
出
,
但
是
,
如
果
目
标
文
件
的
后
缀
是
m
a
k
e
所
识
别
的
,
那
么
“
*”也就不能被推导出,但是,如果目标文件的后缀是make所识别的,那么“
∗”也就不能被推导出,但是,如果目标文件的后缀是make所识别的,那么“”就是除了后缀的那一部分。例如:如果目标是“foo.c”,因为“.c”是make所能识别的后缀名,所以,“
∗
”
的
值
就
是
“
f
o
o
”
。
这
个
特
性
是
G
N
U
m
a
k
e
的
,
很
有
可
能
不
兼
容
于
其
它
版
本
的
m
a
k
e
,
所
以
,
你
应
该
尽
量
避
免
使
用
“
*”的值就是“foo”。这个特性是GNU make的,很有可能不兼容于其它版本的make,所以,你应该尽量避免使用“
∗”的值就是“foo”。这个特性是GNUmake的,很有可能不兼容于其它版本的make,所以,你应该尽量避免使用“”,除非是在隐含规则或是静态模式中。如果目标中的后缀是make所不能识别的,那么“$”就是空值。
Makefile 标志
' $ '符号的使用
美元符号$,主要扩展打开makefile中定义的变量
' $$ '符号的使用
$$ 符号主要扩展打开makefile中定义的shell变量
1、wildcard : 扩展通配符
2、notdir : 去除路径
3、patsubst :替换通配符
.PHONY: all clean
MAKE = mingw32-make
MKDIR = mkdir
RM = rm
RMFLAGS = -fr
CC = gcc
DIR_OBJS = objs
DIR_EXES = exes
DIR_DEPS = deps
DIRS = $(DIR_OBJS) $(DIR_EXES) $(DIR_DEPS)
EXE = complicated.exe #最终可执行文件
EXE := $(addprefix $(DIR_EXES)/, $(EXE))
SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o) #中间编译文件
OBJS := $(addprefix $(DIR_OBJS)/, $(OBJS))
DEPS = $(SRCS:.c=.dep)
DEPS := $(addprefix $(DIR_DEPS)/, $(DEPS))
all: $(DIRS) $(DEPS) $(EXE) #指定编译顺序
$(DIRS):
$(MKDIR) $@
$(EXE): $(OBJS)
$(CC) -o $@ $^
$(DIR_OBJS)/%.o: %.c
$(CC) -o $@ -c $^
$(DIR_DEPS)/%.dep: %.c
@echo "Creating $@ ..."
@set -e;\
$(RM) $(RMFLAGS) $@.tmp ;\
$(CC) -E -MM $^ > $@.tmp ;\
sed 's,\(.*\)\.o[ :]*,objs/\1.o: ,g' < $@.tmp > $@ ;\
$(RM) $(RMFLAGS) $@.tmp
clean:
$(RM) $(RMFLAGS) $(DIRS)
lsm_dem
| 目录名 | 包含文件 | Makefile内容 |
|---|---|---|
| cmd | qax-ctl.c qax-manger.c Makefile | |
| config | policies.db rules.db Makefile | |
| include | audit.h ctl.h lib.h list.h policy.h rules.h | |
| lib | lib_config.c lib_config.h lib_ctl.c lib_ctl.h lib_policy.c lib_policy.h lib_ruels.c lib_ruels.h lib_sqlite.c lib_sqlite.h Makefile sqlite3.c sqlite3.h | |
| mod | audit.c avc.c common.h file.c hooks.c kernel_symbols.h lsm_prc.c policy.c pr.c qaxfs.c rules.c task.c Makefile | |
| test | uc_01/ uc_02/ uc_03/ uc_04/ uc_0/5 uc_06/ Makefile | |
| ./ | Makefile |
CMDS=qax-manager qax-ctl
CFLAGS=-I../include/
LIB_DIR=../lib
LIBS=\
$(LIB_DIR)/lib_rules.a \
$(LIB_DIR)/lib_ctl.a \
$(LIB_DIR)/lib_policy.a \
$(LIB_DIR)/lib_sqlite.a \
$(LIB_DIR)/lib_config.a \
$(LIB_DIR)/sqlite3.a
APP_LIBS=-lpthread -ldl
%: %.c
gcc $(CFLAGS) -o $@ $< $(LIBS) $(APP_LIBS)
all: $(CMDS)
clean:
rm -rf $(CMDS)
install:
install -m 777 -d $(INS_DIR)/cmd
install -m 555 -D qax-manager $(INS_DIR)/cmd
install -m 555 -D qax-ctl $(INS_DIR)/cmd
all:
clean:
install:
install -m 777 -d $(INS_DIR)/config
install -m 666 -D rules.db $(INS_DIR)/config
install -m 666 -D policies.db $(INS_DIR)/config
LIBS=lib_qax_ctl.a lib_qax_rules.a lib_qax_policy.a lib_qax_sqlite.a lib_qax_config.a sqlite3.a
#
INC_CFLAGS=-I../include/
APP_LIBS=-lpthread -ldl
%.o: %.c
gcc -c $(INC_CFLAGS) -o $@ $*.c
#lib_qax_sqlite.a: lib_qax_sqlite.o sqlite3.o
# ar -r $@ $?
#lib_qax_policy.a: lib_qax_policy.o
# ar -r $@ $?
%.a: %.o
ar -r $@ $<
all:$(LIBS)
clean:
rm -rf $(LIBS) *.o
install:
PWD := $(shell pwd)
KDIR := /lib/modules/$(shell uname -r)/build
ccflags-y = -I$(src)/../include
obj-m := qax_lsm_demo.o
qax_lsm_demo-objs := hooks.o audit.o task.o qaxfs.o policy.o pr.o rules.o file.o avc.o
default: header_files
echo $(EXTRA_CFLAGS)
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
hooks.o: $(PWD)/../include/qax_policy.h
clean:
echo $(PWD)/../include
rm -rf *.o core mklog Module.symvers Module.markers
rm -rf kernel_symbols.h
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
install:
install -m 777 -d $(INS_DIR)/mod
install -m 555 -D qax_lsm_demo.ko $(INS_DIR)/mod
load: qax_lsm_demo.ko
insmod qax_lsm_demo.ko
unload:
rmmod qax_lsm_demo.ko
all: default
header_files:
@(SYM=`grep security_hook_heads /proc/kallsyms | awk "{print \\$$1}"`;\
echo "#define SYM_ADDR_security_hook_heads 0x$$SYM" > kernel_symbols.h)
all:
gcc -o uc_04/file_read uc_04/file_read.c
gcc -o uc_04/file_write uc_04/file_write.c
@(cd uc_01; make; )
install:
install -m 777 -d $(INS_DIR)/test
install -m 777 -d $(INS_DIR)/test/uc_01
install -m 555 -D uc_01/hello_mod.ko $(INS_DIR)/test/uc_01
install -m 777 -d $(INS_DIR)/test/uc_02
install -m 777 -D uc_02/prep.sh $(INS_DIR)/test/uc_02
install -m 777 -D uc_02/run.sh $(INS_DIR)/test/uc_02
install -m 777 -d $(INS_DIR)/test/uc_03
install -m 777 -D uc_03/prep.sh $(INS_DIR)/test/uc_03
install -m 777 -D uc_03/run.sh $(INS_DIR)/test/uc_03
install -m 777 -d $(INS_DIR)/test/uc_04
install -m 777 -D uc_04/prep.sh $(INS_DIR)/test/uc_04
install -m 777 -D uc_04/run.sh $(INS_DIR)/test/uc_04
install -m 777 -D uc_04/file_read $(INS_DIR)/test/uc_04
install -m 777 -D uc_04/file_write $(INS_DIR)/test/uc_04
install -m 777 -d $(INS_DIR)/test/uc_05
install -m 777 -D uc_05/uc05_test.sh $(INS_DIR)/test/uc_05
install -m 777 -d $(INS_DIR)/test/uc_06
install -m 777 -D uc_06/prep.sh $(INS_DIR)/test/uc_06
install -m 777 -D uc_06/run.sh $(INS_DIR)/test/uc_06
clean:
rm -rf uc_04/file_read uc_04/file_write
@(cd uc_01; make clean; )
PWD=$(shell pwd)
SUBDIRS=lib cmd mod config test
INS_DIR=$(PWD)/output
all:
@(for SUBDIR in $(SUBDIRS); \
do \
cd $(PWD)/$$SUBDIR; make all; \
done)
install:
install -m 777 -d $(INS_DIR)
@(for SUBDIR in $(SUBDIRS); \
do \
cd $(PWD)/$$SUBDIR; make install INS_DIR=$(INS_DIR); \
done)
clean:
@(for SUBDIR in $(SUBDIRS); \
do \
cd $(PWD)/$$SUBDIR; make clean; \
done)
我这里自己写了个,遍历kenel 文件夹,生成对应的.o文件:
├── boot
├── fs
├── include
├── init
│ ├── main.c
│ └── main.o
├── kernel
│ ├── asm.s
│ ├── blk_drv
│ ├── exit.c
│ ├── fork.c
│ ├── Makefile
│ ├── math
│ ├── mktime.c
│ ├── mktime.o
│ ├── panic.c
│ ├── panic.o
│ ├── printk.c
│ ├── printk.o
│ ├── sched.c
│ ├── signal.c
│ ├── sys.c
│ ├── sys_call.s
│ ├── traps.c
│ └── vsprintf.c
├── lib
├── Rules.make
└── tools
└── build.c
CC = gcc
DIR_KER = kernel
SRC = $(wildcard *.c)
OBJS = $(SRC:.c = .o)
KER_FILES = $(foreach dir,$(DIR_KER),$(wildcard $(DIR_KER)/*.c))
KER_OBJS = $(patsubst %.c,%.o, $(KER_FILES))
all: init/main.o $(KER_OBJS) main
CFLAGS = -w
main:init/main.o kernel/mktime.o
echo $(KER_OBJS)
$(CC) $(CFLAGS) -o $@ $^
init/main.o : init/main.c
$(CC) $(CFLAGS) -o $@ -c $^ -I ./include
$(KER_OBJS):%.o: %.c
$(CC) $(CFLAGS) -o $@ -c $^ -I ./include
clean:
rm -f Image System.map tmp_make core boot/bootsect boot/setup \
boot/bootsect.s boot/setup.s
rm -f init/*.o tools/system tools/build boot/*.o
(cd mm;make clean)
(cd fs;make clean)
(cd kernel;make clean)
(cd lib;make clean)
#CONFIG_ECAT_DRV为m时编译为模块,为y时编进内核
PWD := $(shell pwd)
#生成模块文件和其中间文件
obj-m += syshook.o
#-objs指定依赖的多个.o文件
syshook-objs := stack/dumpstack.o main.o
ccflags-y += -I$(src)/include
KERNELDIR = /lib/modules/$(shell uname -r)/build
all:
echo $(PWD)
make -C $(KERNELDIR) M=$(PWD) modules
clean:
rm *.o *.ko *~ *.mod.c *.order *.symvers
CmakeLists.txt 联合Makefile
| 目录 | 文件 |
|---|---|
| core | CMakeLists/Makefile /module.c |
| inc | linux// CMakeLists.txt/Makefile |
| other | CMakeList/Makefile |
| kclib | linux//CMakeLists.txt/atomic.c dump_data.c/CMakeLists.txt/ |
CMakeLists.txt
add_subdirectory(pub)
add_subdirectory(inc)
add_subdirectory(kclib)
add_subdirectory(core)
core/CMakeLists
set( QAX_KMOD_NAME
fccore
)
set( KMOD_OBJS
module.o
../kclib/log.o
../kclib/dump_data.o
../kclib/linux/slab.o
../kclib/linux/atomic.o
../kclib/linux/file.o
../kclib/linux/mem.o
)
set( QAX_KMOD_FLAGS
-I${PUB_GENERATED_DIR}
-I${PUB_INC_DIR}
-I${INC_DIR}
)
add_custom_target(
build_core_mod ALL
COMMAND ${CMAKE_MAKE_PROGRAM} QAX_KMOD_NAME=${QAX_KMOD_NAME} QAX_KMOD_FLAGS="${QAX_KMOD_FLAGS}" QAX_KMOD_OBJS="${QAX_KMOD_OBJS}" rebuild
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
inc/CMakeLists.txt
set( INC_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE STRING INTERNAL )
set( INC_DIRS
${INC_DIR}
${PUB_DIRS}
CACHE STRING INTERNAL )
kclib/CMakeLists.txt
add_subdirectory(linux)
set( KCLIB_FILES
${CMAKE_CURRENT_SOURCE_DIR}/fc_log.o
${CMAKE_CURRENT_SOURCE_DIR}/fc_dump_data.o
${CMAKE_CURRENT_SOURCE_DIR}/linux/fc_atomic.o
CACHE string INTERNAL)
本文深入解析Makefile的原理及应用,涵盖变量扩展、通配符处理、依赖关系构建等核心概念,通过实例演示如何利用Makefile自动化软件构建流程,包括多级目录编译、动态生成目标文件列表等高级技巧。
1849

被折叠的 条评论
为什么被折叠?



