📄 makefiles.txt
字号:
The kernel modules gus.o, pas2.o, and sb.o are the *composite files*. The object files gus_card.o, gus_midi.o, gus_vol.o, gus_wave.o, ics2101.o, pas2_card.o, pas2_midi.o, pas2_mixer.o, pas2_pcm.o, and sb_card.o are *component files*. The component files are also called *intermediate files*. In another part of drivers/sound/Makefile (not shown), all of the component files are split out. For the resident drivers: the component object files go onto $(O_OBJS) and $(OX_OBJS) lists, depending on whether they export symbols or not; and the composite files are never built. For the kernel modules: the component object files go onto $(MI_OBJS) and $(MIX_OBJS); the composite files go onto $(M_OBJS). The subdirectory Makefile must also specify the linking rule for a multi-object-file module: # drivers/sound/Makefile gus.o: $(gus-objs) $(LD) -r -o $@ $(gus-objs) pas2.o: $(pas2-objs) $(LD) -r -o $@ $(pas2-objs) sb.o: $(sb-objs) $(LD) -r -o $@ $(sb-objs) As is mentioned in section 7.2 ("Object file goals"), $(MIX_OBJS) can also be used simply to list all objects that export any symbols. If this approach is taken, then $(O_OBJS), $(L_OBJS), $(M_OBJS) and $(MI_OBJS) should simply lists all of the vmlinux object files, library object files, module object files and intermediate module files respectively. Duplication between $(MI_OBJS) and $(MIX_OBJS) is not a problem.--- 7.6 Compilation flags EXTRA_CFLAGS, EXTRA_AFLAGS, EXTRA_LDFLAGS, EXTRA_ARFLAGS $(EXTRA_CFLAGS) specifies options for compiling C files with $(CC). The options in this variable apply to all $(CC) commands for files in the current directory. Example: # drivers/sound/emu10k1/Makefile EXTRA_CFLAGS += -I. ifdef DEBUG EXTRA_CFLAGS += -DEMU10K1_DEBUG endif $(EXTRA_CFLAGS) does not apply to subdirectories of the current directory. Also, it does not apply to files compiled with $(HOSTCC). This variable is necessary because the top Makefile owns the variable $(CFLAGS) and uses it for compilation flags for the entire tree. $(EXTRA_AFLAGS) is a similar string for per-directory options when compiling assembly language source. Example: at the time of writing, there were no examples of $(EXTRA_AFLAGS) in the kernel corpus. $(EXTRA_LDFLAGS) and $(EXTRA_ARFLAGS) are similar strings for per-directory options to $(LD) and $(AR). Example: at the time of writing, there were no examples of $(EXTRA_LDFLAGS) or $(EXTRA_ARFLAGS) in the kernel corpus. CFLAGS_$@, AFLAGS_$@ $(CFLAGS_$@) specifies per-file options for $(CC). The $@ part has a literal value which specifies the file that it's for. Example: # drivers/scsi/Makefile CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ \ -DGDTH_STATISTICS CFLAGS_seagate.o = -DARBITRATE -DPARITY -DSEAGATE_USE_ASM These three lines specify compilation flags for aha152x.o, gdth.o, and seagate.o $(AFLAGS_$@) is a similar feature for source files in assembly languages. Example: # arch/arm/kernel/Makefile AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) -traditional AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional Rules.make has a feature where an object file depends on the value of $(CFLAGS_$@) that was used to compile it. (It also depends on the values of $(CFLAGS) and $(EXTRA_CFLAGS)). Thus, if you change the value of $(CFLAGS_$@) for a file, either by editing the Makefile or overriding the value some other way, Rules.make will do the right thing and re-compile your source file with the new options. Note: because of a deficiency in Rules.make, assembly language files do not have flag dependencies. If you edit $(AFLAGS_$@) for such a file, you will have to remove the object file in order to re-build from source. LD_RFLAG This variable is used, but never defined. It appears to be a vestige of some abandoned experiment.--- 7.7 Miscellaneous variables IGNORE_FLAGS_OBJS $(IGNORE_FLAGS_OBJS) is a list of object files which will not have their flag dependencies automatically tracked. This is a hackish feature, used to kludge around a problem in the implementation of flag dependencies. (The problem is that flag dependencies assume that a %.o file is built from a matching %.S or %.c file. This is sometimes not true). USE_STANDARD_AS_RULE This is a transition variable. If $(USE_STANDARD_AS_RULE) is defined, then Rules.make will provide standard rules for assembling %.S files into %.o files or %.s files (%.s files are useful only to developers). If $(USE_STANDARD_AS_RULE) is not defined, then Rules.make will not provide these standard rules. In this case, the subdirectory Makefile must provide its own private rules for assembling %.S files. In the past, all Makefiles provided private %.S rules. Newer Makefiles should define USE_STANDARD_AS_RULE and use the standard Rules.make rules. As soon as all the Makefiles across all architectures have been converted to USE_STANDARD_AS_RULE, then Rules.make can drop the conditional test on USE_STANDARD_AS_RULE. After that, all the other Makefiles can drop the definition of USE_STANDARD_AS_RULE.=== 8 New-style variablesThe "new-style variables" are simpler and more powerful than the"old-style variables". As a result, many subdirectory Makefiles shrankmore than 60%. This author hopes that, in time, all arch Makefiles andsubdirectory Makefiles will convert to the new style.Rules.make does not understand new-style variables. Thus, each new-styleMakefile has a section of boilerplate code that converts the new-stylevariables into old-style variables. There is also some mixing, wherepeople define most variables using "new style" but then fall back to"old style" for a few lines.--- 8.1 New variables obj-y obj-m obj-n obj- These variables replace $(O_OBJS), $(OX_OBJS), $(M_OBJS), and $(MX_OBJS). Example: # drivers/block/Makefile obj-$(CONFIG_MAC_FLOPPY) += swim3.o obj-$(CONFIG_BLK_DEV_FD) += floppy.o obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o Notice the use of $(CONFIG_...) substitutions on the left hand side of an assignment operator. This gives Gnu Make the power of associative indexing! Each of these assignments replaces eight lines of code in an old-style Makefile. After executing all of the assignments, the subdirectory Makefile has built up four lists: $(obj-y), $(obj-m), $(obj-n), and $(obj-). $(obj-y) is a list of files to include in vmlinux. $(obj-m) is a list of files to build as single-file modules. $(obj-n) and $(obj-) are ignored. Each list may contain duplicates items; duplicates are automatically removed later. Also, if a file appears in both $(obj-y) and $(obj-m), it will automatically be removed from the $(obj-m) list. Example: # drivers/net/Makefile ... obj-$(CONFIG_OAKNET) += oaknet.o 8390.o ... obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o ... obj-$(CONFIG_STNIC) += stnic.o 8390.o ... obj-$(CONFIG_MAC8390) += daynaport.o 8390.o ... In this example, four different drivers require the code in 8390.o. If one or more of these four drivers are built into vmlinux, then 8390.o will also be built into vmlinux, and will *not* be built as a module -- even if another driver which needs 8390.o is built as a module. (The modular driver is able to use services of the 8390.o code in the resident vmlinux image). export-objs $(export-objs) is a list of all the files in the subdirectory which potentially export symbols. The canonical way to construct this list is: grep -l EXPORT_SYMBOL *.c (but watch out for sneaky files that call EXPORT_SYMBOL from an included header file!) This is a potential list, independent of the kernel configuration. All files that export symbols go into $(export-objs). The boilerplate code then uses the $(export-objs) list to separate the real file lists into $(*_OBJS) and $(*X_OBJS). Experience has shown that maintaining the proper X's in an old-style Makefile is difficult and error-prone. Maintaining the $(export-objs) list in a new-style Makefile is simpler and easier to audit. list-multi $(foo)-objs Some kernel modules are composed of multiple object files linked together. $(list-multi) is a list of such kernel modules. This is a static list; it does not depend on the configuration. For each kernel module in $(list-multi) there is another list of all the object files which make up that module. For a kernel module named foo.o, its object file list is foo-objs. Example: # drivers/scsi/Makefile list-multi := scsi_mod.o sr_mod.o initio.o a100u2w.o ... scsi_mod-objs := hosts.o scsi.o scsi_ioctl.o constants.o \ scsicam.o scsi_proc.o scsi_error.o \ scsi_obsolete.o scsi_queue.o scsi_lib.o \ scsi_merge.o scsi_dma.o scsi_scan.o \ scsi_syms.o sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o initio-objs := ini9100u.o i91uscsi.o a100u2w-objs := inia100.o i60uscsi.o The subdirectory Makefile puts the modules onto obj-* lists in the usual configuration-dependent way: obj-$(CONFIG_SCSI) += scsi_mod.o obj-$(CONFIG_BLK_DEV_SR) += sr_mod.o obj-$(CONFIG_SCSI_INITIO) += initio.o obj-$(CONFIG_SCSI_INIA100) += a100u2w.o Suppose that CONFIG_SCSI=y. Then vmlinux needs to link in all 14 components of scsi_mod.o, so these components will go onto $(O_OBJS) and $(OX_OBJS). The composite file scsi_mod.o will never be created. The boilerplate conversion code produces this result with a few lines of list processing commands. Suppose that CONFIG_BLK_DEV_SR=m. Then the 3 components of sr_mod.o will linked together with "$(LD) -r" to make the kernel module sr_mod.o, so these 3 components need to go onto the $(MI_OBJS) and $(MIX_OBJS) lists; the composite file sr_mod.o goes onto $(M_OBJS). The boilerplate conversion code takes care of this, too. And suppose CONFIG_SCSI_INITIO=n. Then initio.o goes onto the $(obj-n) list and that's the end of it. Its component files are not compiled, and the composite file is not created. Finally, the subdirectory Makefile needs to define rules to build each multi-object kernel module from its component list. Example: # drivers/scsi/Makefile scsi_mod.o: $(scsi_mod-objs) $(LD) -r -o $@ $(scsi_mod-objs) sr_mod.o: $(sr_mod-objs) $(LD) -r -o $@ $(sr_mod-objs) initio.o: $(initio-objs) $(LD) -r -o $@ $(initio-objs) a100u2w.o: $(a100u2w-objs) $(LD) -r -o $@ $(a100u2w-objs) These rules are very regular; it would be nice for the boilerplate code or Rules.make to synthesize these rules automatically. But until that happens, the subdirectory Makefile needs to define these rules explicitly. subdir-y subdir-m subdir-n subdir- These variables replace $(ALL_SUB_DIRS), $(SUB_DIRS) and $(MOD_SUB_DIRS). Example: # drivers/Makefile subdir-$(CONFIG_PCI) += pci subdir-$(CONFIG_PCMCIA) += pcmcia subdir-$(CONFIG_MTD) += mtd subdir-$(CONFIG_SBUS) += sbus These variables work similar to obj-*, but are used for subdirectories instead of object files. After executing all of the assignments, the subdirectory Makefile has built up four lists: $(subdir-y), $(subdir-m), $(subdir-n), and $(subdir-). $(subdir-y) is a list of directories that should be entered for making vmlinux. $(subdir-m) is a list of directories that should be entered for making modules. $(subdir-n) and $(subdir-) are only used for collecting a list of all subdirectories of this directory. Each list besides subdir-y may contain duplicates items; duplicates are automatically removed later. mod-subdirs $(mod-subdirs) is a list of all the the subdirectories that should be added to $(subdir-m), too if they appear in $(subdir-y) Example: # fs/Makefile mod-subdirs := nls This means nls should be added to (subdir-y) and $(subdir-m) if CONFIG_NFS = y.--- 8.2 Converting to old-style The following example is taken from drivers/usb/Makefile. Note that this uses MIX_OBJS to avoid the need for OX_OBJS and MX_OBJS and thus to maintain the ordering of objects in $(obj-y) # Translate to Rules.make lists. multi-used := $(filter $(list-multi), $(obj-y) $(obj-m)) multi-objs := $(foreach m, $(multi-used), $($(basename $(m))-objs)) active-objs := $(sort $(multi-objs) $(obj-y) $(obj-m)) O_OBJS := $(obj-y) M_OBJS := $(obj-m) MIX_OBJS := $(filter $(export-objs), $(active-objs)) An example for libraries from drivers/acorn/scsi/Makefile: # Translate to Rules.make lists. L_OBJS := $(filter-out $(export-objs), $(obj-y)) LX_OBJS := $(filter $(export-objs), $(obj-y)) M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) As ordering is not so important in libraries, this still uses LX_OBJS and MX_OBJS, though (presumably) it could be changed to use MIX_OBJS as follows: active-objs := $(sort $(obj-y) $(obj-m)) L_OBJS := $(obj-y) M_OBJS := $(obj-m) MIX_OBJS := $(filter $(export-objs), $(active-objs)) which is clearly shorted and arguably clearer.=== 9 Compatibility with Linux Kernel 2.2Most of the information in this document also applies to 2.2, althoughthere is no indication of which things have changed when. Here are somehints for writing subdirectory Makefiles that are compatible with Linuxkernel 2.2.You can write either an old-style Makefile or a new-style Makefilewith a boilerplate adapter section. See the 2.2 version ofdrivers/sound/Makefile for a copy of the boilerplate code.In 2.2, Rules.make makes a distinction between $(MOD_SUB_DIRS)and $(MOD_IN_SUB_DIRS). If you have a single directory with nosubdirectories, this will not matter to you. If you have a wholetree, then you need to know the difference between $(MOD_SUB_DIRS)and $(MOD_IN_SUB_DIRS). For example code: $(MOD_SUB_DIRS) is usedextensively in fs/Makefile; $(MOD_IN_SUB_DIRS) is used extensively indrivers/net/Makefile.If you are already using MOD_LIST_NAME, go ahead and keep using it.If you don't already have a MOD_LIST_NAME, go ahead and keep not usingone; your module will be a 'misc' module in 2.2.Assembly language rules were a mess in 2.2. If you have assembly languagefiles, this author recommends that you write your own explicit rulesfor each file by name.=== 10 CreditsThanks to the members of the linux-kbuild mailing list for reviewingdrafts of this document, with particular thanks to Peter Samuelsonand Thomas Molina.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -