file分析linux,linux Makefile 分析

/*-------------------------------------------------------------------------------*/

VERSION = 2

PATCHLEVEL = 6

SUBLEVEL = 20

EXTRAVERSION = .7

NAME = Homicidal Dwarf Hamster

# 以上表明了内核版本。组合起来就是:2.6.20.7 ,yeah,这就是我分析的内核版本

# 注意写makefile时不要使用makefile的内建的规则和变量

#要想不打印"Entering directory ..."字样,请使用no-print-directory选项

MAKEFLAGS += -rR --no-print-directory

# 因为需要递归执行build, 所以必须注意要保证按照正确顺序执行make.

# 使用 'make V=1' 可以看到完整命令

ifdef V

ifeq ("$(origin V)", "command line")

KBUILD_VERBOSE = $(V)

endif

endif

ifndef KBUILD_VERBOSE

KBUILD_VERBOSE = 0

endif

# 使用 'make C=1' 仅检查需要重新使用c编译器编译的文件

# 使用 'make C=2' 检查所有c编译器编译的文件

ifdef C

ifeq ("$(origin C)", "command line")

KBUILD_CHECKSRC = $(C)

endif

endif

ifndef KBUILD_CHECKSRC

KBUILD_CHECKSRC = 0

endif

# 使用 make M=dir 表明需要编译的模块目录

# 旧的语法make ... SUBDIRS=$PWD 依然支持

# 这里通过环境变量 KBUILD_EXTMOD来表示

ifdef SUBDIRS

KBUILD_EXTMOD ?= $(SUBDIRS)

endif

ifdef M

ifeq ("$(origin M)", "command line")

KBUILD_EXTMOD := $(M)

endif

endif

# kbuild 可以把输出文件放到一个分开的目录下

# 定位输出文件目录有两种语法支持:

# 两种方法都要求工作目录是内核源文件目录的根目录

# 1) O=

# 使用 "make O=dir/to/store/output/files/"

#

# 2) 设置 KBUILD_OUTPUT

# 设置环境变量 KBUILD_OUTPUT 来指定输出文件存放的目录

# export KBUILD_OUTPUT=dir/to/store/output/files/

# make

#

# 但是 O= 方式优先于KBUILD_OUTPUT环境变量方式

# KBUILD_SRC 会再obj目录的make调用

# KBUILD_SRC 到目前还不是为了给一般用户使用的

ifeq ($(KBUILD_SRC),)

ifdef O

ifeq ("$(origin O)", "command line")

KBUILD_OUTPUT := $(O)

endif

endif

# 缺剩目标

PHONY := _all

_all:

ifneq ($(KBUILD_OUTPUT),)

# 调用输出目录的第二个make, 传递相关变量检查输出目录确实存在

saved-output := $(KBUILD_OUTPUT)

KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT) && /bin/pwd)

$(if $(KBUILD_OUTPUT),, \

$(error output directory "$(saved-output)" does not exist))

PHONY += $(MAKECMDGOALS)

$(filter-out _all,$(MAKECMDGOALS)) _all:

$(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \

KBUILD_SRC=$(CURDIR) \

KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile $@

# Leave processing to above invocation of make

skip-makefile := 1

endif # ifneq ($(KBUILD_OUTPUT),)

endif # ifeq ($(KBUILD_SRC),)

ifeq ($(skip-makefile),)

PHONY += all

ifeq ($(KBUILD_EXTMOD),)

_all: all

else

_all: modules

endif

srctree        := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR))

TOPDIR        := $(srctree)

# FIXME - TOPDIR is obsolete, use srctree/objtree

objtree        := $(CURDIR)

src        := $(srctree)

obj        := $(objtree)

VPATH        := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD))

export srctree objtree VPATH TOPDIR

# SUBARCH 告诉 usermode build 当前的机器是什么体系.  它是第一个设置的,并且如果

# 是usermode build ,命令行中的 "ARCH=um" 优先下面的 ARCH 设置. 如果是 native build ,

# 设置ARCH , 获取正常的数值, 将会忽略SUBARCH .

SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \

-e s/arm.*/arm/ -e s/sa110/arm/ \

-e s/s390x/s390/ -e s/parisc64/parisc/ \

-e s/ppc.*/powerpc/ -e s/mips.*/mips/ )

# 交叉编译和选择不同的gcc/bin-utils

# ---------------------------------------------------------------------------

#

# 当交叉编译其他体系的内核时,ARCH 应该设置为目标体系.

# ARCH 可以再make执行间设置:

# make ARCH=ia64

# 另外一种方法是设置 ARCH 环境变量.

# 默认 ARCH 是当前执行的宿主机.

# CROSS_COMPILE 作为编译时所有执行需要使用的前缀

# 只有gcc 和 相关的 bin-utils 使用 $(CROSS_COMPILE)设置的前缀.

# CROSS_COMPILE 可以再命令行设置:

# make CROSS_COMPILE=ia64-linux-

# 另外 CROSS_COMPILE 也可以再环境变量中设置.

# CROSS_COMPILE 的默认值是空的

# Note: 一些体系的 CROSS_COMPILE 是再其 arch/*/Makefile中设置的

ARCH        ?= $(SUBARCH)

CROSS_COMPILE    ?=

# Architecture as present in compile.h

UTS_MACHINE := $(ARCH)

KCONFIG_CONFIG    ?= .config

# SHELL used by kbuild

CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \

else if [ -x /bin/bash ]; then echo /bin/bash; \

else echo sh; fi ; fi)

HOSTCC      = gcc

HOSTCXX      = g++

HOSTCFLAGS  = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer

HOSTCXXFLAGS = -O2

# Decide whether to build built-in, modular, or both.

# Normally, just do built-in.

KBUILD_MODULES :=

KBUILD_BUILTIN := 1

#    如果仅编译模块 "make modules", 就不会编译内建的 objects.

#    当使用modversions编译 modules 时 , 就需要考虑build-in objects,

#    目的是再记录前确认 checksums 已经更新.

ifeq ($(MAKECMDGOALS),modules)

KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1)

endif

#    If we have "make modules", compile modules

#    in addition to whatever we do anyway.

#    Just "make" or "make all" shall build modules as well

ifneq ($(filter all _all modules,$(MAKECMDGOALS)),)

KBUILD_MODULES := 1

endif

ifeq ($(MAKECMDGOALS),)

KBUILD_MODULES := 1

endif

export KBUILD_MODULES KBUILD_BUILTIN

export KBUILD_CHECKSRC KBUILD_SRC KBUILD_EXTMOD

# Beautify output

# ---------------------------------------------------------------------------

#

# 一般,make再执行命令前会打印整个命令信息. 现在通过$($(quiet)$(cmd))方式

# 可以设置 $(quiet) 来选择不同的命令输出方式等.

#

#        quiet_cmd_cc_o_c = Compiling $(RELDIR)/$@

#        cmd_cc_o_c      = $(CC) $(c_flags) -c -o $@ $<

#

# 如果 $(quiet) 为空, 整个命令行将会打印.

# 如果 $(quiet)设置为 "quiet_", 只打印简短的版本信息.

# 如果 $(quiet)设置为 "silent_", 将不会打印任何信息, 因为没有$(silent_cmd_cc_o_c) 变量存在.

#

# 一个简单的前缀 $(Q)放到命令前面,以便再 non-verbose 模式下可以隐藏命令:

#

#    $(Q)ln $@ :<

#

# 如果 KBUILD_VERBOSE 等于 0 ,那么上面的命令将隐藏.

# 如果 KBUILD_VERBOSE 等于 1 ,那么上面的命令将显示.

ifeq ($(KBUILD_VERBOSE),1)

quiet =

Q =

else

quiet=quiet_

Q = @

endif

# 如果make -s (silent mode), 不会显示命令

ifneq ($(findstring s,$(MAKEFLAGS)),)

quiet=silent_

endif

export quiet Q KBUILD_VERBOSE

# Look for make include files relative to root of kernel src

MAKEFLAGS += --include-dir=$(srctree)

# We need some generic definitions.

include $(srctree)/scripts/Kbuild.include

# Make variables (CC, etc...)

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

AWK        = awk

GENKSYMS    = scripts/genksyms/genksyms

DEPMOD        = /sbin/depmod

KALLSYMS    = scripts/kallsyms

PERL        = perl

CHECK        = sparse

CHECKFLAGS    := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -Wbitwise $(CF)

MODFLAGS    = -DMODULE

CFLAGS_MODULE  = $(MODFLAGS)

AFLAGS_MODULE  = $(MODFLAGS)

LDFLAGS_MODULE  = -r

CFLAGS_KERNEL    =

AFLAGS_KERNEL    =

# Use LINUXINCLUDE when you must reference the include/ directory.

# Needed to be compatible with the O= option

LINUXINCLUDE    := -Iinclude \

$(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \

-include include/linux/autoconf.h

CPPFLAGS        := -D__KERNEL__ $(LINUXINCLUDE)

CFLAGS          := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \

-fno-strict-aliasing -fno-common

AFLAGS          := -D__ASSEMBLY__

# Read KERNELRELEASE from include/config/kernel.release (if it exists)

KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)

KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)

export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION

export ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC

export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE

export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS

export CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS

export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE

export AFLAGS AFLAGS_KERNEL AFLAGS_MODULE

# When compiling out-of-tree modules, put MODVERDIR in the module

# tree rather than in the kernel tree. The kernel tree might

# even be read-only.

export MODVERDIR := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_versions

# Files to ignore in find ... statements

RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS -o -name .pc -o -name .hg -o -name .git \) -prune -o

export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS --exclude .pc --exclude .hg --exclude .git

# ===========================================================================

# 下面是设置config和build 内核时共同使用的规则

# scripts里面是最基本的帮助builds,在scripts/basic目录下的makefile是所有build时都会用到的工具:fixdep/

PHONY += scripts_basic

scripts_basic:

$(Q)$(MAKE) $(build)=scripts/basic

# 把对scripts/basic/makefile转化到scripts_basic处理

scripts/basic/%: scripts_basic ;

#这里先说说script目录里面的makefile文件作用

#makefile:配置目标,包括编译岛内核和模块方式的target

#makefile_clean:当然是删除了

#kbuild_include:一般的配置选项,会在makefile_build中调用

#makefile_build:build配置

#makefile_lib:module,vmlinux的配置

#makefile_host:配置binary

#makefile_modinst:安装module

#makefile_modpost:

PHONY += outputmakefile

# outputmakefile规则目的是在输出目录产生一个makefile文件。这会为make提供方便。这里是调用scripts/mkmakefile创建makfile文件

outputmakefile:

ifneq ($(KBUILD_SRC),)

$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \

$(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)

endif

# 设置是.config,还是module,还是build命令

no-dot-config-targets := clean mrproper distclean \

cscope TAGS tags help %docs check% \

include/linux/version.h headers_% \

kernelrelease kernelversion

config-targets := 0

mixed-targets  := 0

dot-config    := 1

ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)

ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)

dot-config := 0

endif

endif

ifeq ($(KBUILD_EXTMOD),)

ifneq ($(filter config %config,$(MAKECMDGOALS)),)

config-targets := 1

ifneq ($(filter-out config %config,$(MAKECMDGOALS)),)

mixed-targets := 1

endif

endif

endif

ifeq ($(mixed-targets),1)

# ===========================================================================

# We're called with mixed targets (*config and build targets).

# Handle them one by one.

%:: FORCE

$(Q)$(MAKE) -C $(srctree) KBUILD_SRC= $@

else

ifeq ($(config-targets),1)

# ===========================================================================

#仅配置linux

# Read arch specific Makefile to set KBUILD_DEFCONFIG as needed.

# KBUILD_DEFCONFIG may point out an alternative default configuration

# used for 'make defconfig'

include $(srctree)/arch/$(ARCH)/Makefile

export KBUILD_DEFCONFIG

config %config: scripts_basic outputmakefile FORCE

$(Q)mkdir -p include/linux include/config

$(Q)$(MAKE) $(build)=scripts/kconfig $@

else

# ===========================================================================

# 仅编译内核

ifeq ($(KBUILD_EXTMOD),)

# Additional helpers built in scripts/

# Carefully list dependencies so we do not try to build scripts twice

# in parallel

PHONY += scripts

scripts: scripts_basic include/config/auto.conf

$(Q)$(MAKE) $(build)=$(@)

#下面就不用说了吧

# Objects we will link into vmlinux / subdirs we need to visit

init-y        := init/

drivers-y    := drivers/ sound/

net-y        := net/

libs-y        := lib/

core-y        := usr/

endif # KBUILD_EXTMOD

ifeq ($(dot-config),1)

# Read in config

-include include/config/auto.conf

ifeq ($(KBUILD_EXTMOD),)

# Read in dependencies to all Kconfig* files, make sure to run

# oldconfig if changes are detected.

-include include/config/auto.conf.cmd

# To avoid any implicit rule to kick in, define an empty command

$(KCONFIG_CONFIG) include/config/auto.conf.cmd: ;

# If .config is newer than include/config/auto.conf, someone tinkered

# with it and forgot to run make oldconfig.

# if auto.conf.cmd is missing then we are probably in a cleaned tree so

# we execute the config step to be sure to catch updated Kconfig files

include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd

$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig

else

# external modules needs include/linux/autoconf.h and include/config/auto.conf

# but do not care if they are up-to-date. Use auto.conf to trigger the test

PHONY += include/config/auto.conf

include/config/auto.conf:

$(Q)test -e include/linux/autoconf.h -a -e $@ || (        \

echo;                                \

echo "  ERROR: Kernel configuration is invalid.";        \

echo "        include/linux/autoconf.h or $@ are missing.";    \

echo "        Run 'make oldconfig && make prepare' on kernel src to fix it.";    \

echo;                                \

/bin/false)

endif # KBUILD_EXTMOD

else

# Dummy target needed, because used as prerequisite

include/config/auto.conf: ;

endif # $(dot-config)

# ===========================================================================

# 仅编译内核

ifeq ($(KBUILD_EXTMOD),)

# Additional helpers built in scripts/

# Carefully list dependencies so we do not try to build scripts twice

# in parallel

PHONY += scripts

scripts: scripts_basic include/config/auto.conf

$(Q)$(MAKE) $(build)=$(@)

#下面就不用说了吧

# Objects we will link into vmlinux / subdirs we need to visit

init-y        := init/

drivers-y    := drivers/ sound/

net-y        := net/

libs-y        := lib/

core-y        := usr/

endif # KBUILD_EXTMOD

.....

all: vmlinux

#配置gcc选项

ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE

CFLAGS        += -Os

else

CFLAGS        += -O2

endif

....

# 缺剩的编译的内核镜像

export KBUILD_IMAGE ?= vmlinux

#

# vmlinux与map安装路径,默认时boot目录

export    INSTALL_PATH ?= /boot

#

#module安装目录

#

MODLIB    = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)

export MODLIB

#

#  如果定义了INSTALL_MOD_STRIP,在安装module后会strip这些安装的modules

ifdef INSTALL_MOD_STRIP

ifeq ($(INSTALL_MOD_STRIP),1)

mod_strip_cmd = $(STRIP) --strip-debug

else

mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP)

endif # INSTALL_MOD_STRIP=1

else

mod_strip_cmd = true

endif # INSTALL_MOD_STRIP

export mod_strip_cmd

#如果不是安装module

ifeq ($(KBUILD_EXTMOD),)

core-y        += kernel/ mm/ fs/ ipc/ security/ crypto/ block/

vmlinux-dirs    := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \

$(core-y) $(core-m) $(drivers-y) $(drivers-m) \

$(net-y) $(net-m) $(libs-y) $(libs-m)))

vmlinux-alldirs    := $(sort $(vmlinux-dirs) $(patsubst %/,%,$(filter %/, \

$(init-n) $(init-) \

$(core-n) $(core-) $(drivers-n) $(drivers-) \

$(net-n)  $(net-)  $(libs-n)    $(libs-))))

init-y        := $(patsubst %/, %/built-in.o, $(init-y))

core-y        := $(patsubst %/, %/built-in.o, $(core-y))

drivers-y    := $(patsubst %/, %/built-in.o, $(drivers-y))

net-y        := $(patsubst %/, %/built-in.o, $(net-y))

libs-y1        := $(patsubst %/, %/lib.a, $(libs-y))

libs-y2        := $(patsubst %/, %/built-in.o, $(libs-y))

libs-y        := $(libs-y1) $(libs-y2)

# Build vmlinux

...

#配置syms

...

#以下是内核link时的配置

....

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值