久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

《Linux內(nèi)核Makefile分析》之The Linux Kernel Makefile

 eydwyz 2014-01-23
 

The Linux Kernel Makefile

分類: Linux kernelBuild 194人閱讀 評論(0) 收藏 舉報(bào)

The Linux kernel makefile is anexcellent example of usingmake in a complex build environment. While it is beyond the scope of this book to explain how the Linux kernel is structured and built, we can examine several interesting uses of make employed by the kernel build system. Seehttp://macarchive./ols2003/Proceedings/All-Reprints/Reprint-Germaschewski-OLS2003.pdffor a more complete discussion of the 2.5/2.6 kernel build processand its evolution from the 2.4 approach.

Since the makefile has so many facets, we will discuss just a few features that are applicable to a variety of applications. First, we'll look at how single-lettermake variables are used to simulate single-letter command-line options. We'll see how the source and binary trees are separated in a way that allows users to invokemake from the source tree. Next,we'll examine the way themakefile controls the verboseness of the output.Then we'll review the most interesting user-definedfunctions and see how they reduce code duplication, improvereadability, and provide encapsulation. Finally,we'll look at the way themakefile implements a simple help facility.

The Linux kernel build follows the familiar configure, build, installpattern used by my most free software. While many free and opensoftware packages use a separateconfigurescript (typically built byautoconf), the Linuxkernel makefile implements configuration withmake, invoking scripts and helper programsindirectly.

When the configuration phase is complete, a simplemake ormakeall will build the bare kernel, all the modules,and produce a compressed kernel image (these are thevmlinux,modules, andbzImage targets, respectively). Each kernel buildis given a unique version number in the fileversion.o linked into the kernel. This number(and theversion.o file) are updated by themakefile itself.

Some makefile features you might want to adaptto your ownmakefile are: the handling ofcommand line options, analyzing command-line goals, saving buildstatus between builds, and managing the output ofmake.

11.2.1 Command-Line Options

The first part of the makefile contains code for setting common build options from the command line. Here is an excerpt that controls theverbose flag:

  1. # To put more focus on warnings, be less verbose as default  
  2. # Use 'make V=1' to see the full commands  
  3. ifdef V  
  4.     ifeq ("$(origin V)""command line")  
  5.         KBUILD_VERBOSE = $(V)  
  6.     endif  
  7. endif  
  8.   
  9. ifndef KBUILD_VERBOSE  
  10.     KBUILD_VERBOSE = 0  
  11. endif  

The nested(嵌套) ifdef/ifeq pair ensures that theKBUILD_VERBOSE variable is set only ifV is set on the command line. SettingV in the environment ormakefile has no effect. The followingifndef conditional will then turn off the verboseoption ifKBUILD_VERBOSE has not yet been set. Toset the verbose option from either the environment ormakefile, you must setKBUILD_VERBOSE and notV.

Notice, however, that setting KBUILD_VERBOSEdirectly on the command line is allowed and works as expected. Thiscan be useful when writing shell scripts (or aliases) to invoke themakefile. These scripts would then be moreself-documenting, similar to using GNU longoptions.

The other command-line options, sparse checking (C)and external modules (M), both use the same carefulchecking to avoid accidentally setting them from within themakefile.

The next section of the makefile handles the output directory option (O).This is a fairly involved piece of code. To high light its structure,we've replaced some parts of this excerpt with ellipses:

  1. # kbuild supports saving output files in a separate directory.  
  2. # To locate output files in a separate directory two syntax'es are supported.  
  3. # In both cases the working directory must be the root of the kernel src.  
  4. # 1) O=  
  5. # Use "make O=dir/to/store/output/files/"  
  6. #  
  7. # 2) Set KBUILD_OUTPUT  
  8. # Set the environment variable KBUILD_OUTPUT to point to the directory  
  9. # where the output files shall be placed.  
  10. # export KBUILD_OUTPUT=dir/to/store/output/files/  
  11. # make  
  12. #  
  13. # The O= assigment takes precedence over the KBUILD_OUTPUT environment variable.  
  14. # O= 賦值的優(yōu)先級高于環(huán)境變量KBUILD_OUTPUT  
  15. # KBUILD_SRC is set on invocation of make in OBJ directory  
  16. # KBUILD_SRC is not intended to be used by the regular user (for now)  
  17.   
  18. ifeq ($(KBUILD_SRC), )  
  19.          # OK, Make called in directory where kernel src resides  
  20.         # Do we want to locate output files in a separate directory?  
  21.         ifdef O  
  22.                 ifeq ("$(origin O)""command line")  
  23.                         KBUILD_OUTPUT := $(O)  
  24.                 endif  
  25.         endif  
  26.         ...  
  27.         ifneq ($(KBUILD_OUTPUT),)  
  28.                 ...  
  29.                 #make執(zhí)行時設(shè)置一個特殊變量“MAKECMDGOALS”,,此變量記錄了  
  30.                 #命令行參數(shù)指定的終極  
  31.                 #目標(biāo)列表,,沒有通過參數(shù)指定終極目標(biāo)時此變量為空。  
  32.                .PHONY: $(MAKECMDGOALS)  
  33.                $(filter-out _all,$(MAKECMDGOALS))  _all:  
  34.   
  35.                 #對于一個已經(jīng)定義的變量,,可以使用“替換引用”將其值使用指定的字符(字符串)進(jìn)行  
  36.                 #替換格式為“$(VAR:A=B)”(或者“${VAR:A=B}”),,意思是,#替換變量“VAR”中  
  37.                 #所有“A”字符結(jié)尾的字為“B”結(jié)尾的字,?!敖Y(jié)尾”的含義是空格之前(變量值的多個字  
  38.                 #以空格分開)。而對于變量其它部分的“A”字符不進(jìn)行替換,。  
  39.   
  40.                 $(if $(KBUILD_VERBOSE:1=),@) $(MAKE) -C $(KBUILD_OUTPUT)        \             
  41.                 KBUILD_SRC=$(CURDIR)         KBUILD_VERBOSE=$(KBUILD_VERBOSE)  \              
  42.                 KBUILD_CHECK=$(KBUILD_CHECK) KBUILD_EXTMOD="$(KBUILD_EXTMOD)"  \              
  43.                 -f $(CURDIR)/Makefile $@      
  44.                 # Leave processing to above invocation of make      
  45.                skip-makefile := 1    
  46.         endif # ifneq ($(KBUILD_OUTPUT),)  
  47. endif # ifeq ($(KBUILD_SRC),)  
  48. # We process the rest of the Makefile if this is the final invocation of make   
  49. #ifeq ($(skip-makefile),)  ...the rest of the makefile here...endif     
  50. # skip-makefile  

Essentially, this says that if KBUILD_OUTPUT is set, invokemake recursively(遞歸) in the output directory defined byKBUILD_OUTPUT. Set KBUILD_SRC to the directory where make was originally executed, and grab the makefilefrom there as well. The rest of the makefile will not be seen by make, sinceskip-makefile will be set. The recursivemake will reread this same makefile again, only this time KBUILD_SRC will be set, soskip-makefile will be undefined, and the rest ofthemakefile will be read and processed.

This concludes the processing of command-line options. The bulk o fthe makefile follows in the ifeq($(skip-makefile),) section.

11.2.2 Configuration Versus Building

The makefile contains configuration targets and build targets.The configuration targets have the formmenuconfig,defconfig, etc. Maintenance targets likeclean are treated as configuration targets aswell. Other targets such asall,vmlinux, andmodules are build targets. The primary result of invoking a configuration target is two files:.config and.config.cmd. These two files are included by themakefile for build targets but are not included for configuration targets (since the configuration target creates them). It is also possible to mix both configuration targets and build targets on a singlemake invocation, suchas:

$ make oldconfig all

In this case, the makefile invokes itself recursively handling each target individually, thus handling configuration targets separately from build targets.

The code controlling configuration, build, and mixed targets begin swith:

  1. # To make sure we do not include .config for any of the *config targets  
  2. # catch them early, and hand them over to scripts/kconfig/Makefile  
  3. # It is allowed to specify more targets when calling make, including  
  4. # mixing *config targets and build targets.  
  5. # For example 'make oldconfig all'.  
  6. # Detect when mixed targets is specified, and make a second invocation  
  7. # of make so .config is not included in this case either (for *config).  
  8. no-dot-config-targets := clean mrproper distclean \  
  9.                          cscope TAGS tags help %docs check%  
  10. config-targets := 0  
  11. mixed-targets  := 0  
  12. dot-config     := 1  

The variable no-dot-config-targets lists additional targets that do not require a.configfile. The code then initializes theconfig-targetsmixed-targets,and dot-config variables. Theconfig-targets variable is 1 if there are any configuration targets on the command line.The dot-config variable is 1 if there are build targets on the command line.Finally,mixed-targets is 1 if there are both configuration and build targets.

The code to set dot-config is:

  1. ifneq ( $(filter $(no-dot-config-targets), $(MAKECMDGOALS)), )   
  2.   #到這里,,說明命令行中有 $no-dot-config-targets  
  3.   ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)  
  4.          #這里說明除了$no-dot-config-targets,沒別的了,也就是說命令行只有$no-dot-config-targets  
  5.         dot-config := 0  
  6.   endif  
  7. endif  

The filter expression is non-empty if there are configuration targets inMAKECMDGOALS. The ifneq part is true if thefilter expression is not empty. The code is hard to follow partly because it contains a double negative.Theifeq expression is true if MAKECMDGOALS contains only configuration targets.So,dot-config will be set to 0 if there are configuration targets and only configuration targets inMAKECMDGOALS. A more verbose implementation might make the meaning of these two conditionals more clear:

  1. config-target-list := clean mrproper distclean \  
  2.                          cscope TAGS tags help %docs check%  
  3. config-target-goal := $(filter $(config-target-list), $(MAKECMDGOALS))  
  4. build-target-goal := $(filter-out $(config-target-list), $(MAKECMDGOALS))  
  5. ifdef config-target-goal  
  6.   ifndef build-target-goal  
  7.     dot-config := 0  
  8.   endif  
  9. endif  

The ifdef form can be used instead of ifneq, becauseempty variables are treated as undefined, but care must be taken to ensure a variable does not contain merely a string of blanks (which would cause it to be defined).

The config-targets and mixed-targets variables are set in the next code block:

  1. ifeq ($(KBUILD_EXTMOD),)  
  2.   ifneq ($(filter config %config,$(MAKECMDGOALS)),)  
  3.     config-targets := 1  
  4.     ifneq ($(filter-out config %config,$(MAKECMDGOALS)),)  
  5.       mixed-targets := 1  
  6.     endif  
  7.   endif  
  8. endif  

KBUILD_EXTMOD 在makefile 開始部分的賦值過程

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

  KBUILD_EXTMOD := $(M)
endif
在編譯模塊時,M=選項(xiàng)讓該makefile在構(gòu)造目標(biāo)之前返回到模塊源代碼目錄??梢詤⒖糒DD第三版 29頁

KBUILD_EXTMOD will be non-empty when external modules are being built, but not during normal builds.The firstifneq will be true when MAKECMDGOALS contains a goal with theconfig suffix. The second ifneq will be true when MAKECMDGOALS contains nonconfigtargets, too.

Once the variables are set, they are used in an if-else chain with four branches. The code has been condensed and indented to hig hlight its structure:

  1. ifeq ($(mixed-targets),1)  
  2.         # We're called with mixed targets (*config and build targets).  
  3.         # Handle them one by one.  
  4.         %:: FORCE  
  5.                 $(Q)$(MAKE) -C $(srctree) KBUILD_SRC= $@  
  6. else  
  7.         ifeq ($(config-targets),1)  
  8.                 # *config targets only - make sure prerequisites are updated, and descend  
  9.                 # in scripts/kconfig to make the *config target  
  10.                 %config: scripts_basic FORCE  
  11.                         $(Q)$(MAKE) $(build)=scripts/kconfig $@  
  12.         else  
  13.             # Build targets only - this includes vmlinux, arch specific targets, clean  
  14.             # targets and others. In general all targets except *config targets.  
  15.             ...  
  16.             ifeq ($(dot-config),1)  
  17.                   # In this section, we need .config  
  18.                   # Read in dependencies to all Kconfig* files, make sure to run  
  19.                   # oldconfig if changes are detected.  
  20.                     
  21.                   -include .config.cmd  
  22.                   include .config  
  23.   
  24.                   # If .config needs to be updated, it will be done via the dependency  
  25.                   # that autoconf has on .config.  
  26.                   # To avoid any implicit rule to kick in, define an empty command  
  27.                   .config: ;  
  28.                   # If .config is newer than include/linux/autoconf.h, someone tinkered  
  29.                   # with it and forgot to run make oldconfig  
  30.                   include/linux/autoconf.h: .config  
  31.                           $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig  
  32.             else  
  33.                   # Dummy target needed, because used as prerequisite  
  34.                   include/linux/autoconf.h: ;  
  35.             endif  
  36.             include $(srctree)/arch/$(ARCH)/Makefile  
  37.             ... lots more make code ...  
  38.       endif #ifeq ($(config-targets),1)  
  39. endif #ifeq ($(mixed-targets),1)  

The first branchifeq ($(mixed-targets),1),handles mixed command-line arguments. The only target in this branch is a completely generic pattern rule. Since there are no specific rules to handle targets (those rules are in another conditional branch), each target invokes the pattern rule once. This is how a command line with both configuration targets and build targets is separated into a simpler command line. The command script for the generic pattern rule invokes make recursively for each target, causing this same logic to be applied, only this time with no mixed command-line targets. TheFORCEprerequisite(依賴) is used instead of .PHONY, because pattern rules like:

%:: FORCE

cannot be declared .PHONY. So it seems reasonable to useFORCE consistently everywhere.

The second branch of theif-else chain,ifeq($(config-targets),1), is invoked when there are only configuration targets on the commandline. Here the primary target in the branch is the pattern rule %config(other targets have been omitted). The command script invokesmake recursively in thescripts/kconfigsubdirectory and passes along the target.The curious$(build) construct is defined at the end of themakefile:

  1. # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=dir  
  2. # Usage:  
  3. # $(Q)$(MAKE) $(build)=dir  
  4. build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj  

If KBUILD_SRC is set, the-foption is given a full path to the scripts makefile, otherwise a simple relative path is used. Next, theobj variable is set to the righthand side of the equals sign.

The third branchifeq($(dot-config),1),handles build targets that require including the two generated configuration files,.config and.config.cmd.The final branch merely includes a dummy target for autoconf.h to allow it to be used as aprerequisite, even if it doesn't exist.

Most of the remainder of the makefile follows the third and fourth branches. It contains the code for building thekernel and modules.

11.2.3 Managing Command Echo

The kernel makefiles use a noveltechnique for managing the level of detailechoed by commands. Each significant task is represented in both averbose and a quiet version. The verbose version is simply thecommand to be executed in its natural form and is stored in avariable namedcmd_action. The briefversion is a short message describing the action and is stored in avariable namedquiet_cmd_action. Forexample, the command to produce emacs tags is:

  1. quiet_cmd_TAGS = MAKE $@  
  2.       cmd_TAGS = $(all-sources) | etags -  

A command is executed by calling the cmdfunction:

  1. # If quiet is set, only print short version of command  
  2. cmd = @$(if $($(quiet)cmd_$(1)),\  
  3.          echo '  $($(quiet)cmd_$(1))' &&) $(cmd_$(1))  

To invoke the code for building emacs tags, themakefile would contain:

  1. TAGS:  
  2.         $(call cmd,TAGS)  

Notice the cmd function begins with an@, so the only text echoed by the function is textfrom theecho command. In normal mode, thevariablequiet is empty, and the test in theif,$($(quiet)cmd_$(1)),expands to$(cmd_TAGS). Since this variable is notempty, the entire function expands to:

  1. echo '  $(all-sources) | etags -' && $(all-sources) | etags -  

If the quiet version is desired, the variablequiet contains the valuequiet_and the function expands to:

  1. echo '  MAKE $@' && $(all-sources) | etags -  

The variable can also be set to silent_. Sincethere is no commandsilent_cmd_TAGS, this valuecauses thecmdfunction to echo nothing at all.

Echoing the command sometimes becomes more complex, particularly ifcommands contain single quotes. In these cases, themakefile contains this code:

  1. echo '  MAKE $@' && $(all-sources) | etags -  

Here the echo command contains a substitution thatreplaces single quotes with escaped single quotes to allow them to beproperly echoed.

Minor commands that do not warrant the trouble of writingcmd_ andquiet_cmd_ variablesare prefixed with$(Q), which contains eithernothing or@:

  1. ifeq ($(KBUILD_VERBOSE),1)  
  2.   quiet =  
  3.   Q =  
  4. else  
  5.   quiet=quiet_  
  6.   Q = @  
  7. endif  
  8. # If the user is running make -s (silent mode), suppress echoing of  
  9. # commands  
  10. ifneq ($(findstring s,$(MAKEFLAGS)),)  
  11.   quiet=silent_  
  12. endif  

11.2.4 User-Defined Functions

The kernel makefile defines anumber of functions. Here wecover the most interesting ones. The code has been reformatted toimprove readability.

The check_gcc function is used to select agcc command-line option.

  1. # $(call check_gcc,preferred-option,alternate-option)  
  2. check_gcc =                                                                  \  
  3.                 $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null \  
  4.                 -xc /dev/null > /dev/null 2>&1;      \  
  5.                then                                    \  
  6.                echo "$(1)";                          \  
  7.                else                                    \  
  8.                echo "$(2)";                          \  
  9.                fi ;)  


The function works by invoking gcc on a null inputfile with the preferred command-line option. The output file,standard output, and standard error files are discarded. If thegcc command succeeds, it means the preferredcommand-line option is valid for this architecture and is returned bythe function. Otherwise, the option is invalid and the alternateoption is returned. An example use can be found inarch/i386/Makefile:

  1. # prevent gcc from keeping the stack 16 byte aligned  
  2. CFLAGS += $(call check_gcc,-mpreferred-stack-boundary=2,)  

The if_changed_dep function generates dependencyinformation using a remarkable technique.

  1. # execute the command and also postprocess generated  
  2. # .d dependencies file  
  3. if_changed_dep =                                        \  
  4.     $(if                                                \  
  5.       $(strip $?                                        \  
  6.         $(filter-out FORCE $(wildcard $^),$^)           \  
  7.         $(filter-out $(cmd_$(1)),$(cmd_$@))             \  
  8.         $(filter-out $(cmd_$@),$(cmd_$(1)))),           \  
  9.       @set -e;                                          \  
  10.       $(if $($(quiet)cmd_$(1)),                         \  
  11.         echo '  $(subst ','\'',$($(quiet)cmd_$(1)))';)  \  
  12.  $(cmd_$(1));                                      \  
  13.       scripts/basic/fixdep                              \  
  14.    $(depfile)                                     \  
  15.     $@                                             \  
  16.          '$(subst $,$$,$(subst ','\'',$(cmd_$(1))))' \  
  17.          > $(@D)/.$(@F).tmp;                            \  
  18.       rm -f $(depfile);                                 \  
  19.       mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd)  



The function consists of a single if clause. Thedetails of the test are pretty obscure, but it is clear the intent isto be non-empty if the dependency file should be regenerated. Normaldependency information is concerned with the modification timestampson files. The kernel build system adds another wrinkle to this task.The kernel build uses a wide variety of compiler options to controlthe construction and behavior of components. To ensure thatcommand-line options are properly accounted for during a build, themakefile is implemented so that if command-lineoptions used for a particular target change, the file is recompiled.Let's see how this is accomplished.

In essence, the command used to compile each file in the kernel issaved in a.cmd file. When a subsequent build isexecuted,make reads the .cmdfiles and compares the current compile command with the last command.If they are different, the.cmd dependency fileis regenerated causing the object file to be rebuilt. The.cmd file usually contains two items: thedependencies that represent actual files for the target file and asingle variable recording the command-line options. For example, thefilearch/i386/kernel/cpu/mtrr/if.c yields this(abbreviated) file:

  1. cmd_arch/i386/kernel/cpu/mtrr/if.o := gcc -Wp,-MD ...; if.c  
  2. deps_arch/i386/kernel/cpu/mtrr/if.o := \  
  3.   arch/i386/kernel/cpu/mtrr/if.c \  
  4.   ...  
  5. arch/i386/kernel/cpu/mtrr/if.o: $(deps_arch/i386/kernel/cpu/mtrr/if.o)  
  6. $(deps_arch/i386/kernel/cpu/mtrr/if.o):  

Getting back to the if_changed_dep function, thefirst argument to thestrip is simply theprerequisites that are newer than the target, if any. The secondargument tostrip is all the prerequisites otherthan files and the empty target FORCE. The reallyobscure bit is the last two filter-out calls:

  1. $(filter-out $(cmd_$(1)),$(cmd_$@))  
  2. $(filter-out $(cmd_$@),$(cmd_$(1)))  

One or both of these calls will expand to a non-empty string if thecommand-line options have changed. The macro$(cmd_$(1)) is the current command and$(cmd_$@) will be the previous command, forinstance the variablecmd_arch/i386/kernel/cpu/mtrr/if.o just shown. Ifthe new command contains additional options, the firstfilter-out will be empty, and the second willexpand to the new options. If the new command contains fewer options,the first command will contain the deleted options and the secondwill be empty. Interestingly, sincefilter-outaccepts a list of words (each treated as an independent pattern), theorder of options can change and thefilter-outwill still accurately identify added or removed options. Prettynifty.

The first statement in the command script sets a shell option to exitimmediately on error. This prevents the multiline script fromcorrupting files in the event of problems. For simple scripts anotherway to achieve this effect is to connect statements with&& rather than semicolons.

The next statement is an echo command writtenusing the techniques described inSection 11.2.3 earlier in this chapter,followed by the dependency generating command itself. The commandwrites$(depfile), which is then transformed byscripts/basic/fixdep. The nestedsubst function in thefixdepcommand line first escapes single quotes, then escapes occurrences of$$ (the current process number in shell syntax).

Finally, if no errors have occurred, the intermediate file$(depfile) is removed and the generated dependencyfile (with its.cmd suffix) is moved into place.

The next function, if_changed_rule, uses thesame comparison technique asif_changed_dep tocontrol the execution of a command:

  1. # Usage: $(call if_changed_rule,foo)  
  2.   
  3. # will check if $(cmd_foo) changed, or any of the prequisites changed,  
  4.   
  5. # and if so will execute $(rule_foo)  
  6.   
  7.   
  8.   
  9. if_changed_rule =                                   \  
  10.   
  11.     $(if $(strip $?                                 \  
  12.   
  13.            $(filter-out $(cmd_$(1)),$(cmd_$(@F)))   \  
  14.   
  15.            $(filter-out $(cmd_$(@F)),$(cmd_$(1)))), \  
  16.   
  17.       @$(rule_$(1)))  



In the topmost makefile, this function is usedto link the kernel with these macros:

  1. # This is a bit tricky: If we need to relink vmlinux, we want  
  2.   
  3. # the version number incremented, which means recompile init/version.o  
  4.   
  5. # and relink init/init.o. However, we cannot do this during the  
  6.   
  7. # normal descending-into-subdirs phase, since at that time  
  8.   
  9. # we cannot yet know if we will need to relink vmlinux.  
  10.   
  11. # So we descend into init/ inside the rule for vmlinux again.  
  12.   
  13. ...  
  14.   
  15.   
  16.   
  17. quiet_cmd_vmlinux_ _ = LD $@  
  18.   
  19. define cmd_vmlinux_ _  
  20.   
  21.   $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \  
  22.   
  23.     ...  
  24.   
  25. endef  
  26.   
  27.   
  28.   
  29. # set -e makes the rule exit immediately on error  
  30.   
  31.   
  32.   
  33. define rule_vmlinux_ _  
  34.   
  35.   +set -e;                                              \  
  36.   
  37.   $(if $(filter .tmp_kallsyms%,$^),,                    \  
  38.   
  39.     echo '  GEN     .version';                          \  
  40.   
  41.     . $(srctree)/scripts/mkversion > .tmp_version;      \  
  42.   
  43.     mv -f .tmp_version .version;                        \  
  44.   
  45.     $(MAKE) $(build)=init;)                             \  
  46.   
  47.   $(if $($(quiet)cmd_vmlinux_ _),                        \  
  48.   
  49.     echo '  $($(quiet)cmd_vmlinux_ _)' &&)               \  
  50.   
  51.   $(cmd_vmlinux_ _);                                     \  
  52.   
  53.   echo 'cmd_$@ := $(cmd_vmlinux_ _)' > $(@D)/.$(@F).cmd  
  54.   
  55. endef  
  56.   
  57.   
  58.   
  59. define rule_vmlinux  
  60.   
  61.   $(rule_vmlinux_ _);          \  
  62.   
  63.   $(NM) $@ |                  \  
  64.   
  65.   grep -v '\(compiled\)\|...' | \  
  66.   
  67.   sort > System.map  
  68.   
  69. endef  



The if_changed_rule function is used to invokerule_vmlinux, which performs the link and buildsthe finalSystem.map. As the comment in themakefile notes, therule_vmlinux__ function must regenerate the kernel version file andrelinkinit.o before relinkingvmlinux. This is controlled by the firstif inrule_vmlinux_ _. Thesecondif controls the echoing of the linkcommand,$(cmd_vmlinux_ _). After the linkcommand, the actual command executed is recorded in a.cmd file for comparison in the next build.

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多