编译Linux内核时,CC,LD和CC [M]输出的代码是什么?

Mik*_*e G 9 linux makefile linux-kernel kbuild

从头开始编译Linux时,我意识到编译时会出现编译代码.

例如CC文件名,LD文件名,CC [M]文件名.

这些代码是什么意思?

小智 14

不同的标记指定以下内容

  • [CC] - 将C文件编译为指定的目标文件.目标文件包含该.c文件的archicture汇编程序代码.因为它也可能引用其范围之外的部分.例如,在另一个.c文件中调用另一个函数.函数调用在目标文件中保持打开状态,稍后链接器将其包含在内.因此
  • [LD]是将编译对象链接在一起的过程,并连接编译器保持打开的函数调用.但是,许多部分链接在一起作为内核的核心部分,而某些部分则被省略.因此你看
  • [CC(M)]用于编译为在运行时加载到内核中的点的那些部分.但是在内核的整体部分没有链接在一起.但是在内核启动时可以插入.


Cir*_*四事件 7

让我们举一个具体的例子,弄清楚它在内核4.1中的作用,例如IHEX.

找到代码的作用

赶紧跑:

make SHELL='sh -x'
Run Code Online (Sandbox Code Playgroud)

工作原理:https://stackoverflow.com/a/32010960/895245

如果我们为输出grep IHEX,我们找到以下行:

+ echo   IHEX    firmware/e100/d101s_ucode.bin
  IHEX    firmware/e100/d101s_ucode.bin
+ objcopy -Iihex -Obinary /home/ciro/git/kernel/src/firmware/e100/d101s_ucode.bin.ihex firmware/e100/d101s_ucode.bin
Run Code Online (Sandbox Code Playgroud)

因此,我们得出这样的结论IHEX做了objcopy -Iihex.

查找代码的定义位置

必须使用以下内容定义每个内核命令:

quiet_cmd_ihex  = IHEX    $@
      cmd_ihex  = $(OBJCOPY) -Iihex -Obinary $< $@

$(obj)/%: $(obj)/%.ihex
        $(call cmd,ihex)
Run Code Online (Sandbox Code Playgroud)

用于详细程度设置(例如V=1make -s).

所以一般来说,你只需要

git grep 'cmd.* = CODE'
Run Code Online (Sandbox Code Playgroud)

找到CODE.

我已详细解释了该系统的工作原理:https://stackoverflow.com/a/32023861/895245

获取所有代码的列表

make | grep -E '^  ' | sort -uk1,1
Run Code Online (Sandbox Code Playgroud)

CC和CC [M]

定义于scripts/Makefile.build:

quiet_cmd_cc_o_c = CC $(quiet_modtag)  $@
      cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
Run Code Online (Sandbox Code Playgroud)

并且[M]来自目标特定变量:

$(real-objs-m)        : quiet_modtag := [M]
$(real-objs-m:.o=.i)  : quiet_modtag := [M]
$(real-objs-m:.o=.s)  : quiet_modtag := [M]
$(real-objs-m:.o=.lst): quiet_modtag := [M]
$(obj-m)              : quiet_modtag := [M]
Run Code Online (Sandbox Code Playgroud)

然后通过以下方式调用:

$(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE
    [...]
    $(call if_changed_rule,cc_o_c)

define rule_cc_o_c
    [...]
    $(call echo-cmd,cc_o_c) $(cmd_cc_o_c);                \
Run Code Online (Sandbox Code Playgroud)

其中if_changed_rule定义scripts/Kbuild.include如下:

if_changed_rule = $(if $(strip $(any-prereq) $(arg-check) ),                 \
    @set -e;                                                             \
    $(rule_$(1)))
Run Code Online (Sandbox Code Playgroud)

Kbuild.include被包含在顶层的Makefile.

LD

有几个版本,但最简单的似乎是:

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

$(builtin-target): $(obj-y) FORCE
    $(call if_changed,link_o_target)
Run Code Online (Sandbox Code Playgroud)

并在scripts/Kbuild.include:

# Execute command if command has changed or prerequisite(s) are updated.
#
if_changed = $(if $(strip $(any-prereq) $(arg-check)),                       \
    @set -e;                                                             \
    $(echo-cmd) $(cmd_$(1));                                             \
    printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd)
Run Code Online (Sandbox Code Playgroud)