Linux内核编译时输出的CC、LD、CC[M]等代码是什么?
-
13-12-2019 - |
题
从头开始编译Linux时,我发现编译时会出现编译代码。
例如 CC 文件名、LD 文件名、CC[M] 文件名。
这些代码是什么意思?
解决方案
不同的标记指定以下
- [CC] - 将C文件编译为指定的对象文件。对象文件包含该.c文件的遗产汇编程序代码。因为它也可能参考其范围之外的部分。例如在另一个.c文件中调用另一个函数。函数调用在对象文件中左侧打开,稍后包含链接器。因此
- [ld]是将编译对象链接在一起的过程,并加入编译器打开的函数调用。然而,许多部件作为内核的核心部分连接在一起,而一些部分则被遗漏。因此你看到
- [CC(M)]对于编译为在运行时以要加载到内核中的点的部分。但是,它没有在内核的整体部分中连接在一起。但是,当启动内核时,可以插入。
其他提示
让我们举一个具体的例子,看看它在内核 4.1 中做了什么,例如 IHEX
.
查找代码的作用
赶紧跑:
make SHELL='sh -x'
这是如何运作的: 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
所以我们的结论是 IHEX
做了一个 objcopy -Iihex
.
查找定义代码的位置
每个内核命令都必须定义如下:
quiet_cmd_ihex = IHEX $@
cmd_ihex = $(OBJCOPY) -Iihex -Obinary $< $@
$(obj)/%: $(obj)/%.ihex
$(call cmd,ihex)
对于详细程度设置(例如 V=1
和 make -s
) 上班。
所以一般来说,你只需要
git grep 'cmd.* = CODE'
找到 CODE
.
我已经详细解释了这个系统的工作原理: https://stackoverflow.com/a/32023861/895245
获取所有代码的列表
make | grep -E '^ ' | sort -uk1,1
抄送与抄送[M]
定义于 scripts/Makefile.build
:
quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
和 [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]
然后通过以下方式调用:
$(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); \
在哪里 if_changed_rule
定义于 scripts/Kbuild.include
作为:
if_changed_rule = $(if $(strip $(any-prereq) $(arg-check) ), \
@set -e; \
$(rule_$(1)))
和 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)
并在 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)
它应该显示:
-
CC
在编译内核的核心部分时 -
CC [M]
编译模块 -
LD
链接时
不隶属于 StackOverflow