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.
Showing the changes to scripts (2 of 2 files). Show all
Unified · Split
| @@ -73,10 +73,10 @@ endif · 72 unmodified lines | |||
| 73 | 73 | ||
| 74 | ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),) | 74 | ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),) |
| 75 | lib-target := $(obj)/lib.a | 75 | lib-target := $(obj)/lib.a |
| 76 | obj-y += $(obj)/lib-ksyms.o | 76 | real-obj-y += $(obj)/lib-ksyms.o |
| 77 | endif | 77 | endif |
| 78 | 78 | ||
| 79 | ifneq ($(strip $(obj-y) $(need-builtin)),) | 79 | ifneq ($(strip $(real-obj-y) $(need-builtin)),) |
| 80 | builtin-target := $(obj)/built-in.a | 80 | builtin-target := $(obj)/built-in.a |
| 81 | endif | 81 | endif |
| 82 | 82 | ||
| @@ -412,7 +412,7 @@ endif · 329 unmodified lines | |||
| 412 | $(obj)/%.o: $(src)/%.S $(objtool_dep) FORCE | 412 | $(obj)/%.o: $(src)/%.S $(objtool_dep) FORCE |
| 413 | $(call if_changed_rule,as_o_S) | 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 | targets += $(extra-y) $(MAKECMDGOALS) $(always) | 416 | targets += $(extra-y) $(MAKECMDGOALS) $(always) |
| 417 | 417 | ||
| 418 | # Linker scripts preprocessor (.lds.S -> .lds) | 418 | # Linker scripts preprocessor (.lds.S -> .lds) |
| @@ -455,12 +455,12 @@ cmd_make_empty_builtin = rm -f $@; $(AR) rcSTP$(KBUILD_ARFLAGS) · 36 unmodified lines | |||
| 455 | quiet_cmd_link_o_target = AR $@ | 455 | quiet_cmd_link_o_target = AR $@ |
| 456 | 456 | ||
| 457 | # If the list of objects to link is empty, just create an empty built-in.a | 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)),\ | 458 | cmd_link_o_target = $(if $(strip $(real-obj-y)),\ |
| 459 | $(cmd_make_builtin) $@ $(filter $(obj-y), $^) \ | 459 | $(cmd_make_builtin) $@ $(filter $(real-obj-y), $^) \ |
| 460 | $(cmd_secanalysis),\ | 460 | $(cmd_secanalysis),\ |
| 461 | $(cmd_make_empty_builtin) $@) | 461 | $(cmd_make_empty_builtin) $@) |
| 462 | 462 | ||
| 463 | $(builtin-target): $(obj-y) FORCE | 463 | $(builtin-target): $(real-obj-y) FORCE |
| 464 | $(call if_changed,link_o_target) | 464 | $(call if_changed,link_o_target) |
| 465 | 465 | ||
| 466 | targets += $(builtin-target) | 466 | targets += $(builtin-target) |
| @@ -534,23 +534,16 @@ $($(subst $(obj)/,,$(@:.o=-m)))), $^) · 67 unmodified lines | |||
| 534 | 534 | ||
| 535 | cmd_link_multi-link = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps) $(cmd_secanalysis) | 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 | quiet_cmd_link_multi-m = LD [M] $@ | 537 | quiet_cmd_link_multi-m = LD [M] $@ |
| 541 | cmd_link_multi-m = $(cmd_link_multi-link) | 538 | cmd_link_multi-m = $(cmd_link_multi-link) |
| 542 | 539 | ||
| 543 | $(multi-used-y): FORCE | ||
| 544 | $(call if_changed,link_multi-y) | ||
| 545 | $(call multi_depend, $(multi-used-y), .o, -objs -y) | ||
| 546 | |||
| 547 | $(multi-used-m): FORCE | 540 | $(multi-used-m): FORCE |
| 548 | $(call if_changed,link_multi-m) | 541 | $(call if_changed,link_multi-m) |
| 549 | @{ echo $(@:.o=.ko); echo $(link_multi_deps); \ | 542 | @{ echo $(@:.o=.ko); echo $(link_multi_deps); \ |
| 550 | $(cmd_undef_syms); } > $(MODVERDIR)/$(@F:.o=.mod) | 543 | $(cmd_undef_syms); } > $(MODVERDIR)/$(@F:.o=.mod) |
| 551 | $(call multi_depend, $(multi-used-m), .o, -objs -y -m) | 544 | $(call multi_depend, $(multi-used-m), .o, -objs -y -m) |
| 552 | 545 | ||
| 553 | targets += $(multi-used-y) $(multi-used-m) | 546 | targets += $(multi-used-m) |
| 554 | targets := $(filter-out $(PHONY), $(targets)) | 547 | targets := $(filter-out $(PHONY), $(targets)) |
| 555 | 548 | ||
| 556 | # Descending | 549 | # Descending |
| @@ -51,8 +51,9 @@ single-used-m := $(sort $(filter-out $(multi-used-m),$(obj-m))) · 50 unmodified lines | |||
| 51 | # tell kbuild to descend | 51 | # tell kbuild to descend |
| 52 | subdir-obj-y := $(filter %/built-in.a, $(obj-y)) | 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 | 54 | # Replace multi-part objects by their individual parts, |
| 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))) | 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 | 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 | 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 | # DTB | 59 | # DTB |
| @@ -66,14 +67,12 @@ extra-y := $(addprefix $(obj)/,$(extra-y)) · 7 unmodified lines | |||
| 66 | always := $(addprefix $(obj)/,$(always)) | 67 | always := $(addprefix $(obj)/,$(always)) |
| 67 | targets := $(addprefix $(obj)/,$(targets)) | 68 | targets := $(addprefix $(obj)/,$(targets)) |
| 68 | modorder := $(addprefix $(obj)/,$(modorder)) | 69 | modorder := $(addprefix $(obj)/,$(modorder)) |
| 69 | obj-y := $(addprefix $(obj)/,$(obj-y)) | ||
| 70 | obj-m := $(addprefix $(obj)/,$(obj-m)) | 70 | obj-m := $(addprefix $(obj)/,$(obj-m)) |
| 71 | lib-y := $(addprefix $(obj)/,$(lib-y)) | 71 | lib-y := $(addprefix $(obj)/,$(lib-y)) |
| 72 | subdir-obj-y := $(addprefix $(obj)/,$(subdir-obj-y)) | 72 | subdir-obj-y := $(addprefix $(obj)/,$(subdir-obj-y)) |
| 73 | real-obj-y := $(addprefix $(obj)/,$(real-obj-y)) | 73 | real-obj-y := $(addprefix $(obj)/,$(real-obj-y)) |
| 74 | real-obj-m := $(addprefix $(obj)/,$(real-obj-m)) | 74 | real-obj-m := $(addprefix $(obj)/,$(real-obj-m)) |
| 75 | single-used-m := $(addprefix $(obj)/,$(single-used-m)) | 75 | single-used-m := $(addprefix $(obj)/,$(single-used-m)) |
| 76 | multi-used-y := $(addprefix $(obj)/,$(multi-used-y)) | ||
| 77 | multi-used-m := $(addprefix $(obj)/,$(multi-used-m)) | 76 | multi-used-m := $(addprefix $(obj)/,$(multi-used-m)) |
| 78 | subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) | 77 | subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) |
| 79 | 78 | ||