Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

kbuild: link $(real-obj-y) instead of $(obj-y) into built-in.a

In Kbuild, Makefiles can add the same object to obj-y multiple
times. So,

obj-y += foo.o
obj-y += foo.o

is fine.

However, this is not true when the same object is added multiple
times via composite objects. For example,

obj-y += foo.o bar.o
foo-objs := foo-bar-common.o foo-only.o
bar-objs := foo-bar-common.o bar-only.o

causes build error because two instances of foo-bar-common.o are
linked into the vmlinux.

Makefiles tend to invent ugly work-around, for example
- lib/zstd/Makefile
- drivers/net/ethernet/cavium/liquidio/Makefile

The technique used in Kbuild to avoid the multiple definition error
is to use $(filter $(obj-y), $^). Here, $^ lists the names of all
the prerequisites with duplicated names removed.

By replacing it with $(filter $(real-obj-y), $^) we can do likewise
for composite objects. For built-in objects, we do not need to keep
the composite object structure. We can simply expand them, and link
$(real-obj-y) to built-in.a.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>

+10 -18
+7 -14
scripts/Makefile.build
··· 73 73 74 74 ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),) 75 75 lib-target := $(obj)/lib.a 76 - obj-y += $(obj)/lib-ksyms.o 76 + real-obj-y += $(obj)/lib-ksyms.o 77 77 endif 78 78 79 - ifneq ($(strip $(obj-y) $(need-builtin)),) 79 + ifneq ($(strip $(real-obj-y) $(need-builtin)),) 80 80 builtin-target := $(obj)/built-in.a 81 81 endif 82 82 ··· 412 412 $(obj)/%.o: $(src)/%.S $(objtool_dep) FORCE 413 413 $(call if_changed_rule,as_o_S) 414 414 415 - targets += $(real-obj-y) $(real-obj-m) $(lib-y) 415 + targets += $(filter-out $(subdir-obj-y), $(real-obj-y)) $(real-obj-m) $(lib-y) 416 416 targets += $(extra-y) $(MAKECMDGOALS) $(always) 417 417 418 418 # Linker scripts preprocessor (.lds.S -> .lds) ··· 455 455 quiet_cmd_link_o_target = AR $@ 456 456 457 457 # If the list of objects to link is empty, just create an empty built-in.a 458 - cmd_link_o_target = $(if $(strip $(obj-y)),\ 459 - $(cmd_make_builtin) $@ $(filter $(obj-y), $^) \ 458 + cmd_link_o_target = $(if $(strip $(real-obj-y)),\ 459 + $(cmd_make_builtin) $@ $(filter $(real-obj-y), $^) \ 460 460 $(cmd_secanalysis),\ 461 461 $(cmd_make_empty_builtin) $@) 462 462 463 - $(builtin-target): $(obj-y) FORCE 463 + $(builtin-target): $(real-obj-y) FORCE 464 464 $(call if_changed,link_o_target) 465 465 466 466 targets += $(builtin-target) ··· 534 534 535 535 cmd_link_multi-link = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps) $(cmd_secanalysis) 536 536 537 - quiet_cmd_link_multi-y = AR $@ 538 - cmd_link_multi-y = rm -f $@; $(AR) rcSTP$(KBUILD_ARFLAGS) $@ $(link_multi_deps) 539 - 540 537 quiet_cmd_link_multi-m = LD [M] $@ 541 538 cmd_link_multi-m = $(cmd_link_multi-link) 542 - 543 - $(multi-used-y): FORCE 544 - $(call if_changed,link_multi-y) 545 - $(call multi_depend, $(multi-used-y), .o, -objs -y) 546 539 547 540 $(multi-used-m): FORCE 548 541 $(call if_changed,link_multi-m) ··· 543 550 $(cmd_undef_syms); } > $(MODVERDIR)/$(@F:.o=.mod) 544 551 $(call multi_depend, $(multi-used-m), .o, -objs -y -m) 545 552 546 - targets += $(multi-used-y) $(multi-used-m) 553 + targets += $(multi-used-m) 547 554 targets := $(filter-out $(PHONY), $(targets)) 548 555 549 556 # Descending
+3 -4
scripts/Makefile.lib
··· 51 51 # tell kbuild to descend 52 52 subdir-obj-y := $(filter %/built-in.a, $(obj-y)) 53 53 54 - # Replace multi-part objects by their individual parts, look at local dir only 55 - real-obj-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) 54 + # Replace multi-part objects by their individual parts, 55 + # including built-in.a from subdirectories 56 + real-obj-y := $(foreach m, $(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) 56 57 real-obj-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m))),$($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m)),$(m))) 57 58 58 59 # DTB ··· 67 66 always := $(addprefix $(obj)/,$(always)) 68 67 targets := $(addprefix $(obj)/,$(targets)) 69 68 modorder := $(addprefix $(obj)/,$(modorder)) 70 - obj-y := $(addprefix $(obj)/,$(obj-y)) 71 69 obj-m := $(addprefix $(obj)/,$(obj-m)) 72 70 lib-y := $(addprefix $(obj)/,$(lib-y)) 73 71 subdir-obj-y := $(addprefix $(obj)/,$(subdir-obj-y)) 74 72 real-obj-y := $(addprefix $(obj)/,$(real-obj-y)) 75 73 real-obj-m := $(addprefix $(obj)/,$(real-obj-m)) 76 74 single-used-m := $(addprefix $(obj)/,$(single-used-m)) 77 - multi-used-y := $(addprefix $(obj)/,$(multi-used-y)) 78 75 multi-used-m := $(addprefix $(obj)/,$(multi-used-m)) 79 76 subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) 80 77