Linux源码中的Makefile是用来管理和构建Linux内核的文件。它使用GNU Make命令解析并执行Makefile中的规则,以完成内核的编译、模块的链接、安装等工作。
Makefile的基本结构如下:
```
target: prerequisites
recipe
```
target是目标,prerequisites是依赖,recipe是要执行的命令。Makefile中可以定义多个规则,每个规则都以目标、依赖和命令组成。
下面是一个简单Makefile的示例:
```
obj-y := file1.o file2.o
CFLAGS := -Wall
all: $(obj-y)
gcc $(CFLAGS) -o myprogram $(obj-y)
clean:
rm -f *.o myprogram
```
这个Makefile定义了两个规则,一个是all,一个是clean。all规则的目标是myprogram,依赖是$(obj-y),命令是将$(obj-y)编译成可执行文件myprogram。clean规则的目标是clean,命令是删除.o文件和myprogram可执行文件。
在编译Linux内核时,Makefile中的规则会根据依赖关系自动编译和链接相关的源文件,并生成内核镜像文件。通过make命令执行Makefile,可以根据需求选择编译内核、编译模块、安装内核、清除编译结果等操作。
下面是一个完整的Linux内核Makefile示例:
```makefile
###############################################################################
# Makefile for the Linux kernel.
###############################################################################
# version
VERSION = 5
PATCHLEVEL = 2
SUBLEVEL = 0
EXTRAVERSION =
NAME = Kleptomaniac Meddling
# GCC version check
GCCVERSION := $(shell gcc --version | grep gcc | cut -d' ' -f3 | cut -d'.' -f1)
__GCC_LIN = $(shell expr $(GCCVERSION) \>= 3)
# GCC plugins support
ifdef CONFIG_GCC_PLUGIN_SUPPORT
ifndef __GCC_HAS_PLUGIN_SUPPORT
ifndef CONFIG_CC_STACKPROTECTOR
CC_STACKPROTECTOR := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-stack-protector.sh $(CC))
endif
endif
ifndef __GCC_HAS_PLUGIN_SUPPORT
$(error Your GCC and binutils do not support plugins!)
endif
endif
# CONFIG_STACK_VALIDATION must imply CONFIG_DEBUG_STACK_USAGE,
# but gcc-3.1's frame pointer elimination breaks in that case.
ifndef __GCC_USE_ASM_FOR_STACK_VALIDATION
ifdef CONFIG_STACK_VALIDATION
ifdef CONFIG_DEBUG_STACK_USAGE
ifeq ($(strip $(call try-run,echo -e ".byte 0xd9\n.byte 0xc1" | $(CC) $(CC_FLAGS) $(KBUILD_CFLAGS) -x assembler -c - -o $(obj)/validate/c-flag-test.o 2> /dev/null && echo "y")),y)
__GCC_USE_ASM_FOR_STACK_VALIDATION := y
endif
endif
endif
# Statements to determine applications to build
# Check for assembler
ifeq ($(wildcard $(srctree)/arch/$(SRCARCH)/Makefile),)
AS := $(if $(strip $(AS)), $(AS), as)
else
AS := $(if $(strip $(AS)), $(AS), $(shell if [ -f $(srctree)/arch/$(SRCARCH)/scripts/$(AS) ];then echo "$(srctree)/arch/$(SRCARCH)/scripts/$(AS)";else echo "$(srctree)/scripts/$(AS)";fi;))
endif
# Check for proper options
ifeq ($(shell uname -s | sed -e 's/64.*/64/'),Linux-64)
KASFLAGS += --32
# Default target
ifeq ($(ARCH),um)
CHECKFLAGS += $(CFLAGS_$(subst -,_,$(ARCH))) $(CFLAGS_KASAN) $(CFLAGS_KASAN_EXTRA)
else
CHECKFLAGS += $(CFLAGS_$(subst -,_,$(ARCH))) $(CFLAGS_KASAN_EXTRA)
endif
endif
ifeq ($(strip $(ld-option)),)
ld-option = $(shell if $(CC) $(KBUILD_AFLAGS) $(CFLAGS) -Wno-unused -E -nostdinc \
-x assembler-with-cpp -c /dev/null -o "$$TMP"; \
then echo "`cat $$TMP`"; rm -f $$TMP; else exit 1; fi)
endif
# PIC/PIE
check_cflag = $(shell $(CONFIG_SHELL) $(srctree)/scripts/check_cflag.sh $(CC) $(CFLAGS) $(1))
cc-supports = $(shell $(CONFIG_SHELL) $(srctree)/scripts/cc-supports.sh $(CC) $(CFLAGS) $(1))
cc-option = $(call cc-option-,$(CC),$(CFLAGS),$(1))
cc-option- = $(shell if $(cc-supports) $(2) $(1)$(comma)$(3); then echo "$(1)$(comma)$(3)"; else echo "$(2)"; fi | sed -e 's/[^a-zA-Z0-9_]/_/g')
cc-disable-warning = $(call cc-option,-Wno-$1,$(call cc-option,-Wno$(comma)-$1))
cc-disable-extra-warning = $(call cc-option,-Wno-extra-$1,$(call cc-disable-warning,unused-$1))
ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
LD_DEAD_CODE_DATA_ELIMINATION := $(call cc-option,-ffunction-sections,)
else
LD_DEAD_CODE_DATA_ELIMINATION := $(call cc-disable-option,-ffunction-sections,)
endif
export LD_DEAD_CODE_DATA_ELIMINATION
ifdef CONFIG_LD_DEAD_CODE_RODATA_ELIMINATION
LD_DEAD_CODE_RODATA_ELIMINATION := $(call cc-option,-fdata-sections,)
else
LD_DEAD_CODE_RODATA_ELIMINATION := $(call cc-disable-option,-fdata-sections,)
endif
export LD_DEAD_CODE_RODATA_ELIMINATION
# ld does support --gc-sections and --icf-iterations,
# but only as linker script commands, not on the command line.
LDFLAGS_STRIP := $(call ld-option, -Wl$(comma)--strip-debug)
LDFLAGS_USE_SECTION := $(call ld-option, -Wl$(comma)--gc-sections,)
LDFLAGS_USE_GOLD := $(call ld-option, -fuse-ld=gold$(comma)--plugin-opt=emit-asm )
LDFLAGS_USE_LD := $(call ld-option, -fuse-ld=bfd)
LDFLAGS_COMBINE := $(call ld-option, -Wl$(comma)--build-id=none -Wl$(comma)--hash-style=sysv -Wl$(comma)--no-copy-dt-needed-entries)
LDFLAGS_LTO := $(call ld-option, -flto)
LDFLAGS_ICF := $(call ld-option, -Wl$(comma)--icf-iterations=4)
# Flags passed to the C preprocessor.
CPPFLAGS := -D__KERNEL__ -D__${ARCH}__ $(BASE_CPPFLAGS) -I$(srctree)/arch/$(SRCARCH)/include/uapi -I$(objtree)/arch/$(SRCARCH)/include/generated/uapi -I$(srctree)/include -I$(objtree)/include/generated/uapi -include $(srctree)/include/linux/kconfig.h
# Flags passed to the linkers.
LDFLAGS :=
# Debugging option -g
ifdef CONFIG_DEBUG_INFO
ifeq ($(call cc-disable-warning, unused-but-set-variable),)
KBUILD_CFLAGS += -g
KBUILD_AFLAGS += -gdwarf-2
export CONFIG_DEBUG_INFO_REDUCED
endif
endif
# Debugging option -pg
ifdef CONFIG_DEBUG_KERNEL
ifdef CONFIG_PROFILE_ALL_BRANCHES
KBUILD_CFLAGS += -pg
endif
endif
# Tells gcc to emit stack smashing protectors
KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector)
ifdef CONFIG_CC_STACKPROTECTOR
ifneq ($(call cc-disable-warning,unused-function),)
KBUILD_CFLAGS += $(call cc-disable-warning,unused-function)
else
KBUILD_CFLAGS += -Wno-unused-function
endif
ifneq ($(call cc-disable-warning,unused-variable),)
KBUILD_CFLAGS += $(call cc-disable-warning,unused-variable)
endif
endif # stack protector
# KBUILD_CFLAGS is the final set of flags passed to the compiler
# KBUILD_AFLAGS is the final set of flags passed to as
# KBUILD_LDFLAGS is the final set of flags passed to ld
# KBUILD_{C,A,L}FLAGS_* are the cached final values of the respective
# KBUILD_* flags after Makefile parsing.
KBUILD_CFLAGS += -pipe
KBUILD_CFLAGS += -Wformat-security
KBUILD_CFLAGS += -Wformat
ifdef CONFIG_FRAME_WARN
KBUILD_CFLAGS += -Wframe-larger-than=$(CONFIG_FRAME_WARN)
endif
ifdef CONFIG_DEBUG_SECTION_MISMATCH
KBUILD_CFLAGS += -Wsection-larger-than=$(CONFIG_DEBUG_SECTION_MISMATCH)
endif
ifeq ($(cc-name),clang)
KBUILD_CPPFLAGS += -Qunused-arguments
# warn about C99 declaration after statement
KBUILD_CFLAGS += -Wdeclaration-after-statement
endif
# Take out some time-consuming optimizations for debugging purposes
ifndef CONFIG_OPTIMIZE_INLINING
KBUILD_CFLAGS += $(call cc-disable-optimize,-freorder-blocks,$(call cc-disable-optimize,-freorder-functions,))
endif
# arch Makefile may override CC so keep this after arch Makefile is included
export ARCH SRCARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
export CPP AR NM STRIP OBJCOPY OBJDUMP
export MAKE HOSTAR HOSTAS UNifdef UTS_MACHINE AWK GENKSYMS INSTALLKERNEL LYNX
LD := $(CROSS_COMPILE)ld
CC := $(CROSS_COMPILE)gcc
AS := $(CROSS_COMPILE)$(AS)
ifneq ($(CROSS_COMPILE),)
# We need some generic definitions
include $(srctree)/arch/$(SRCARCH)/Makefile.platform
# Cross compiling and assembler is a generic ELF.
LDFLAGS += -m elf_x86_64
CHECKFLAGS += -D__x86_64__
AFLAGS += -m elf
endif
ifeq ($(SRCARCH),x86)
# whatever gcc wants to use..
LDFLAGS_vmlinux += --build-id
LDFLAGS_vmlinux += -z max-page-size=4096
endif
ifeq ($(src)/arch/$(SRCARCH)/Makefile,$(wildcard $(src)/arch/$(SRCARCH)/Makefile))
include $(src)/arch/$(SRCARCH)/Makefile
endif
ifdef CONFIG_HEADERS_CHECK
__cflags = $(CFLAGS) $(KBUILD_CPPFLAGS) \
$(shell $(CONFIG_SHELL) $(srctree)/scripts/headers_check.sh -kcflags)
.PHONY: headers_check
headers_check:
$(Q)$(MAKE) $(build)=scripts/$@
else
__cflags = $(CFLAGS)
endif
PHONY += prepare scripts
# Recurse until adjust_env
# Store (new) KERNELVERSION and KERNELPATCHLEVEL
NEWKERNELVER := $(KERNELVERSION)
NEWPATCHLEVEL := $(KERNELPATCHLEVEL)
archscripts: scripts_basic
$(Q)$(MAKE) $(build)=arch/$(SRCARCH)/scripts
scripts_basic:
$(Q)$(MAKE) $(build)=scripts/basic
$(Q)rm -f .tmp_quiet_recordmcount
prepare: archscripts scripts_basic include/generated/autoksyms.h \
include/config/auto.conf
$(Q)$(MAKE) $(build)=.
quiet_cmd_vmlinux__ ?= LINK $@
cmd_link-vmlinux__ = $(CONFIG_SHELL) $< $(LD) $(LDFLAGS.vmlinux) -o $@
ifdef CONFIG_CMD_LINK_OBJECTS
quiet_cmd_link-vmlinux = LINK $@
init-y := $(filter-out %.o FORCE,$(init-y))
init-y := $(foreach f,$(init-y),$(obj)/$(f))
quiet_cmd_vmlinux__ := LD $@
cmd_vmlinux__ = $(if $(strip $(init-y)), $(CONFIG_SHELL) $< $(LD) $(LDFLAGS.vmlinux) -r $(KBUILD_LDFLAGS) $(LDFLAGS.vmlinux-y) $(init-y) -o $@, $(CONFIG_SHELL) $< $(LD) $(LDFLAGS.vmlinux) -o $@)
else
quiet_cmd_link-vmlinux = $(CONFIG_SHELL) $< $(LD) $(LDFLAGS.vmlinux) -o $@
quiet_cmd_vmlinux__ :=
ifeq ($(strip $(use-initramfs)),1)
cmd_vmlinux__ = $(CONFIG_SHELL) $< $(LD) $(LDFLAGS.vmlinux) -r -b binary -o $(objtree)/usr/initramfs_data.o $@; \
$(CONFIG_SHELL) $< $(LD) $(LDFLAGS.vmlinux) -b elf64-x86-64 -T $(src)/usr/initramfs.lds -o $@ ;else \
$(CONFIG_SHELL) $< $(LD) $(LDFLAGS.vmlinux) -o $@ ;fi
endif
__build: __build_main
ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE
$(Q)$(MAKE) $(build)=scripts
endif
#define /tmp/make.log and tools record_mcount
recordmcount: init /tmp/make.log
$(if $(CONFIG_VEXPRESS_CONFIG)$(CONFIG_ARCH_MULTIPLATFORM), \
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/recordmcount $(VMLINUX_LOAD_ADDRESS) \
$(OBJTREE)/vmlinux)
/tmp/make.log:
$(Q)trap 'rm -f $@; exit' INT HUP QUIT PIPE TERM EXIT; \
$(CONFIG_SHELL) $(srctree)/scripts/gen_initramfs_list.sh $(objtree) $(initramfsls); \
$(if $(word 1,$(initramfsls)), \
$(Q)chmod u+x $(word 1,$(initramfsls)); \
$(Q)grep -v '/$$' $(wordlist 2,$(words $(initramfsls)),$(initramfsls)) | \
$(CONFIG_SHELL) $(srctree)/scripts/bloat-o-meter $(word 1,$(initramfsls)) $(KBUILD_EMPTY_CMDFILES); \
cp $(word 1,$(initramfsls)) $(word 1,$(initramfsls)).tmp; \
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/strip $(word 1,$(initramfsls)) $(word 1,$(initramfsls)).tmp; \
mv $(word 1,$(initramfsls)).tmp $(word 1,$(initramfsls)); \
mv $(objtree)/usr/initramfs_data.o $(SRCTREE)/usr/initramfs_data.o; \
true)
build: recordmcount __build
.PHONY: __build
###############################################################################
# Clang support
ifdef CONFIG_ENABLE_LLVM_CLANG
ifdef CONFIG_MODULE_SIG
ifdef CONFIG_MODULE_SIG_FORCE
ifdef CONFIG_MODULE_SIG_ALL
CLANG_FLAGS := -ffunction-sections -fdata-sections
else
CLANG_FLAGS := -fno-function-sections -fno-data-sections
endif
else
ifdef CONFIG_MODULE_SIG_FORCE_ALL_MODULES
CLANG_FLAGS := -fdata-sections -ffunction-sections
endif
endif
endif
ifeq ($(cl-implicit-fallthrough),)$(cl-implicit-fallthrough-y)
CLANG_FLAGS += -Wno-implicit-fallthrough
endif
cc-ldoption = $(call cc-ldoption-$(2),$(1),$(CLANG_FLAGS))
cc-ldoption-y := $(call cc-ldoption,$(CC))
CLFAGS_REMOVE = $(strip $(shell $(CONFIG_SHELL) $(srctree)/scripts/clang-suppress-$(CONFIG_ARCH) $(call cc-ldoption-y)))
suppress-clang-$(CONFIG_ARCH) = $(srctree)/scripts/clang-suppress-$(CONFIG_ARCH)
CLANG_SRCTREE = $(if $(wildcard $(suppress-clang-$(CONFIG_ARCH))),$(srctree),)
CLANG_FLAGS += -Wno-date-time -Wno-unknown-warning-option \
-Wno-sign-compare
# Clang has problems with too many warnings
KBUILD_CFLAGS += $(CLANG_FLAGS)$(CLFAGS_REMOVE)
AFLAGS_REMOVE = $(strip $(shell $(CONFIG_SHELL) $(srctree)/scripts/clang-suppress-$(SRCARCH) -as ))
KBUILD_AFLAGS += $(CLANG_FLAGS)$(AFLAGS_REMOVE)
MODARFLAGS = rcv
cc-$(CONFIG_MODVERSIONS) = $(CC) -MD $< $(KBUILD_CFLAGS) -c -o $*.o
cc-ifversiongt-030304 = $(CC) -MD $< $(KBUILD_CFLAGS) -c -o $*.o
else
MODARFLAGS = rcs
cc-$(CONFIG_MODVERSIONS) = $(CC) -MD $< $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -c -o $*.o
endif
# Assemble bare application
ifeq ($(wildcard $(srctree)/arch/$(SRCARCH)/Makefile),)
extra-y = $(crtbegin-y) $(crtend-y)
PHONY += x86_32 x86_64
x86_32:
$(Q)$(MAKE) $(build)=$(src) arch=386 $(extra-y) $(all-obj-y)
x86_64:
$(Q)$(MAKE) $(build)=$(src) arch=x86_64 $(extra-y) $(all-obj-y)
endif
# Modules
ifdef CONFIG_MODULES
# $(modname).ko: $(
壹涵网络我们是一家专注于网站建设、企业营销、网站关键词排名、AI内容生成、新媒体营销和短视频营销等业务的公司。我们拥有一支优秀的团队,专门致力于为客户提供优质的服务。
我们致力于为客户提供一站式的互联网营销服务,帮助客户在激烈的市场竞争中获得更大的优势和发展机会!
发表评论 取消回复