LINUX编译系统(3)

4.增强编译工具

4.1增强编译工具

4.1.1 基本编译工具

gcc

binutils

对于POWERPC系列:

# Ensure this is binutils 2.12.1 (or 2.12.90.0.7) or later for altivec
# instructions.
# gcc-3.4 and binutils-2.14 are a fatal combination.

make 
4.1.1 增强编译工具

编译系统要解决的问题中依赖关系的建立是一个重要的内容。同时,方便编写MAKEFILE也需要增加工具。比如同一类型的目标可能需要多个步骤,可以考虑把多个步骤作为一个命令加以执行以方便编写。

在编写包含多个命令的新命令时,需要考虑参数问题。LINUX编译系统使用2种传递参数的方法

1. 类似于C语言

2.环境变量如$@ $<

 

4.1.1.1 变量

dot-target = $(dir $@).$(notdir $@)  

depfile = $(subst $(comma),_,$(dot-target).d)   /* 依赖文件的名字,不允许 , */

 

4.1.1.2 函数

特殊字符的处理

escsq = $(subst $(squote),'/$(squote)',$1)

make-cmd = $(subst /#,///#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1)))))

打印字符串
#compare if two command is equal
echo-cmd = $(if $($(quiet)cmd_$(1)),  echo '  $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';)
echo-why = $(call escsq, $(strip $(why))

调用命令,打印命令内容

cmd = @$(echo-cmd) $(cmd_$(1))
调整编译搜索目录
# Find all -I options and add $(srctree) if it is not abstract directory
flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o)))
    addtree = $(if $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1))) $(1)
# Add $(obj)/ for paths that is not absolute
objectify = $(foreach o,$(1),$(if $(filter /%,$(o)),$(o),$(obj)/$(o)))

调整编译器选项

as-option, as-option1,as-option2  返回as支持的option

as-instr, intruction, option1, option2 若AS支持intruction,使用option1,否则option2

cc-option,  gcc-option1,gcc-option2  类as-option

cc-option-yn, gcc-option  支持返回y,否则返回n

cc-option-align  /* Prefix align with either -falign or -malign*/

cc-version,compiler-name  /* get compiler's version */

cc-ifversion, operator, operand, gcc-options  /* if [ gcc version operator operand ] return gcc-options */

ld-option,ld-option1,ld-option2  类as-option

依赖检查和调用目标更新的复合命令

arg-check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@))   $(filter-out $(cmd_$@),   $(cmd_$(1))) )
any-prereq = $(filter-out $(PHONY),$?) $(filter-out $(PHONY) $(wildcard $^),$^)

filechk  调用方式 call filechk,sample。以$<为参数调用filechk_sample,比较其结果和$@,若不同,更新$@

if_changed 和 if_changed_dep的差别在于if_changed适用于非源文件,因为其不根据源文件中定义的宏增加对位header文件的依赖关系

if_changed = $(if $(strip $(any-prereq) $(arg-check)),                       /
 @set -e;                                                             /
 $(echo-cmd) $(cmd_$(1));                                             /
 echo 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd)

# execute the command and also postprocess generated .d dependencies
# file
if_changed_dep = $(if $(strip $(any-prereq) $(arg-check) ),                  /
 @set -e;                                                             /
 $(echo-cmd) $(cmd_$(1));                                             /
 scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).tmp;/
 rm -f $(depfile);                                                    /
 mv -f $(dot-target).tmp $(dot-target).cmd)

 

# Usage: $(call if_changed_rule,foo)
if_changed_rule = $(if $(strip $(any-prereq) $(arg-check) ),                 /
     @set -e;                                                             /
     $(rule_$(1)))

所有目标的实际make rule

cmd_files := $(wildcard .*.cmd $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))

 

cmd_gzip = gzip -f -9 < $< > $@

cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
cmd_ld = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_$(@F))  $(filter-out FORCE,$^) -o $@

cmd_rmfiles = rm -f $(rm-files)

目标生成命令cmd_xxx

根据.o生成可重定位的.o

cmd_link_o_target = $(if $(strip $(obj-y)),/
        $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^),/
        rm -f $@; $(AR) rcs $@)

根据.o生成.a

cmd_link_l_target = rm -f $@; $(AR) $(EXTRA_ARFLAGS) rcs $@ $(lib-y)

同cmd_link_o_target 但依赖不同

cmd_link_multi-y = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps)

同cmd_link_multi-y但采用不同的连接选项

cmd_link_multi-m = $(LD) $(ld_flags) $(LDFLAGS_MODULE) -o $@ $(link_multi_deps)

 

连接生成LINUX

cmd_vmlinux__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) -o $@ /
      -T $(vmlinux-lds) $(vmlinux-init)                          /
      --start-group $(vmlinux-main) --end-group                  /
      $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) FORCE ,$^)

cmd_ksym_ld = $(cmd_vmlinux__)

 

生成与系统调用相关可加载软件模块

cmd_syscall = $(CC) -m elf_i386 -nostdlib $(SYSCFLAGS_$(@F)) /
            -Wl,-T,$(filter-out FORCE,$^) -o $@

 

# Generate .S file with all kernel symbols

cmd_kallsyms = $(NM) -n $< | $(KALLSYMS)    $(if $(CONFIG_KALLSYMS_ALL),--all-symbols) > $@

 

获得符号表vmlinux-->system.map

cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap

 

如果.o中有系统符号,计算出CRC,并连接入此.o

cmd_modversions =       /
 if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then /
  $(CPP) -D__GENKSYMS__ $(c_flags) $<   /
  | $(GENKSYMS) $(if $(KBUILD_SYMTYPES),   /
         -T $(@D)/$(@F:.o=.symtypes)) -a $(ARCH) /
  > $(@D)/.tmp_$(@F:.o=.ver);    /
         /
  $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F)   /
   -T $(@D)/.tmp_$(@F:.o=.ver);   /
  rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); /
 else        /
  mv -f $(@D)/.tmp_$(@F) $@;    /
 fi;
endif

 

from .s--> .s

cmd_cc_s_c       = $(CC) $(c_flags) -fverbose-asm -S -o $@ $<

from .c --> .i

cmd_cc_i_c       = $(CPP) $(c_flags)   -o $@ $<

从.c获得系统符号

cmd_cc_symtypes_c    =   $(CPP) -D__GENKSYMS__ $(c_flags) $<    | $(GENKSYMS) -T $@ >/dev/null;    test -s $@ || rm -f $@
反汇编.o但获得在LINUX中的地址而不是从0开始的地址

cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< &&   $(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o  System.map $(OBJDUMP) > $@

预扫描.S 到 .s

cmd_as_s_S       = $(CPP) $(a_flags)   -o $@ $<

 

from .S --> .o
cmd_as_o_S       = $(CC) $(a_flags) -c -o $@ $<

.lds --> ld

cmd_cpp_lds_S = $(CPP) $(cpp_flags) -D__ASSEMBLY__ -o $@ $<

目标生成命令rule_xxx

define rule_ksym_ld
 :
 +$(call cmd,vmlinux_version)
 $(call cmd,vmlinux__)
 $(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
endef

 

define rule_vmlinux__
 :
 $(if $(CONFIG_KALLSYMS),,+$(call cmd,vmlinux_version))

 $(call cmd,vmlinux__)
 $(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd

 $(Q)$(if $($(quiet)cmd_sysmap),                                      /
   echo '  $($(quiet)cmd_sysmap)  System.map' &&)                     /
 $(cmd_sysmap) $@ System.map;                                         /
 if [ $$? -ne 0 ]; then                                               /
  rm -f $@;                                                    /
  /bin/false;                                                  /
 fi;
 $(verify_kallsyms)
endef

 

define rule_cc_o_c
 $(call echo-cmd,checksrc) $(cmd_checksrc)     /
 $(call echo-cmd,cc_o_c) $(cmd_cc_o_c);      /
 $(cmd_modversions)        /
 scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' >    /
                                               $(dot-target).tmp;  /
 rm -f $(depfile);        /
 mv -f $(dot-target).tmp $(dot-target).cmd
endef

rule_cc_o_c比cmd_cc_o_c在于增加了符号crc的值。
安装使用命令

cmd_depmod = if [ -r System.map -a -x $(DEPMOD) ]; then   $(DEPMOD) -ae -F System.map             /
        $(if $(strip $(INSTALL_MOD_PATH)),        -b $(INSTALL_MOD_PATH) -r)              /
        $(KERNELRELEASE);                       /
        fi

你可能感兴趣的:(Linux,linux,cmd,wildcard,filter,工具,assembly)