linux源码Makefile详解(完整)

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内容生成、新媒体营销和短视频营销等业务的公司。我们拥有一支优秀的团队,专门致力于为客户提供优质的服务。

我们致力于为客户提供一站式的互联网营销服务,帮助客户在激烈的市场竞争中获得更大的优势和发展机会!

点赞(72) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部