[PATCH u-boot 16/39] build: use thin archives instead of incremental linking

Bin Meng bmeng.cn at gmail.com
Tue Mar 9 14:00:00 CET 2021


On Sun, Mar 7, 2021 at 12:26 PM Marek Behún <marek.behun at nic.cz> wrote:
>
> Currently we use incremental linking (ld -r) to link several object
> files from one directory into one built-in.o object file containing the
> linked code from that directory (and its subdirectories).
>
> Linux has, some time ago, moved to thin archives instead.
>
> Thin archives are archives (.a) that do not really contain the object
> files, only references to them.
>
> Using thin archives instead of incremental linking
> - saves disk space
> - apparently works better with dead code elimination
> - makes things easier for LTO
>
> The third point is the important one for us. With incremental linking
> there are several options how to do LTO, and that would unnecessarily
> complicate things.
>
> On the other hand, by using thin archives we can make (via the
> --whole-archive use flag) the final linking behave as if we passed all
> the object files from the archives to the linking program as arguments.
>
> We also need to use the P flag for ar, otherwise final linking may fail.
>
> Signed-off-by: Marek Behún <marek.behun at nic.cz>
> ---
>  Makefile               |  4 ++--
>  arch/sandbox/config.mk | 10 +++++++---
>  scripts/Makefile.build | 16 ++++++++--------
>  scripts/Makefile.spl   |  4 ++--
>  4 files changed, 19 insertions(+), 15 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index 7b0ba9df9a..6dc47810ea 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1754,9 +1754,9 @@ ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(ARCH)/Makefile.postlink)
>  quiet_cmd_u-boot__ ?= LD      $@
>        cmd_u-boot__ ?= $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_u-boot) -o $@          \
>                 -T u-boot.lds $(u-boot-init)                                    \
> -               --start-group                                                   \
> +               --start-group --whole-archive                                   \

--start-group is useless now.

>                         $(u-boot-main)                                          \
> -               --end-group                                                     \
> +               --no-whole-archive --end-group                                  \

and --end-group

>                 $(PLATFORM_LIBS) -Map u-boot.map;                               \
>                 $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
>
> diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk
> index 189e9c2b0c..d11b9c63c9 100644
> --- a/arch/sandbox/config.mk
> +++ b/arch/sandbox/config.mk
> @@ -17,13 +17,17 @@ PLATFORM_CPPFLAGS += $(shell $(SDL_CONFIG) --cflags)
>  endif
>
>  cmd_u-boot__ = $(CC) -o $@ -Wl,-T u-boot.lds $(u-boot-init) \
> -       -Wl,--start-group $(u-boot-main) -Wl,--end-group \
> +       -Wl,--start-group -Wl,--whole-archive \
> +               $(u-boot-main) \
> +       -Wl,--no-whole-archive -Wl,--end-group \
>         $(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot.map
>
>  cmd_u-boot-spl = (cd $(obj) && $(CC) -o $(SPL_BIN) -Wl,-T u-boot-spl.lds \
>         $(patsubst $(obj)/%,%,$(u-boot-spl-init)) \
> -       -Wl,--start-group $(patsubst $(obj)/%,%,$(u-boot-spl-main)) \
> -       $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) -Wl,--end-group \
> +       -Wl,--start-group -Wl,--whole-archive \
> +               $(patsubst $(obj)/%,%,$(u-boot-spl-main)) \
> +               $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) \
> +       -Wl,--no-whole-archive -Wl,--end-group \
>         $(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot-spl.map -Wl,--gc-sections)
>
>  CONFIG_ARCH_DEVICE_TREE := sandbox
> diff --git a/scripts/Makefile.build b/scripts/Makefile.build
> index 705a886cb9..a9a02d7d33 100644
> --- a/scripts/Makefile.build
> +++ b/scripts/Makefile.build
> @@ -331,12 +331,11 @@ $(sort $(subdir-obj-y)): $(subdir-ym) ;
>  # Rule to compile a set of .o files into one .o file
>  #
>  ifdef builtin-target
> -quiet_cmd_link_o_target = LD      $@
> +quiet_cmd_link_o_target = AR      $@
>  # If the list of objects to link is empty, just create an empty built-in.o
>  cmd_link_o_target = $(if $(strip $(obj-y)),\
> -                     $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^) \
> -                     $(cmd_secanalysis),\
> -                     rm -f $@; $(AR) rcs$(KBUILD_ARFLAGS) $@)
> +                     rm -f $@; $(AR) cDPrsT $@ $(filter $(obj-y), $^), \
> +                     rm -f $@; $(AR) cPrsT$(KBUILD_ARFLAGS) $@)

nits: should we use D for the empty one for consistency?

>
>  $(builtin-target): $(obj-y) FORCE
>         $(call if_changed,link_o_target)
> @@ -362,7 +361,7 @@ $(modorder-target): $(subdir-ym) FORCE
>  #
>  ifdef lib-target
>  quiet_cmd_link_l_target = AR      $@
> -cmd_link_l_target = rm -f $@; $(AR) rcs$(KBUILD_ARFLAGS) $@ $(lib-y)
> +cmd_link_l_target = rm -f $@; $(AR) cPrs$(KBUILD_ARFLAGS) $@ $(lib-y)

It looks this line change is not needed

>
>  $(lib-target): $(lib-y) FORCE
>         $(call if_changed,link_l_target)
> @@ -382,10 +381,11 @@ $(filter $(addprefix $(obj)/,         \
>  $($(subst $(obj)/,,$(@:.o=-objs)))    \
>  $($(subst $(obj)/,,$(@:.o=-y)))), $^)
>
> -quiet_cmd_link_multi-y = LD      $@
> -cmd_link_multi-y = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps) $(cmd_secanalysis)
>
> -quiet_cmd_link_multi-m = LD [M]  $@
> +quiet_cmd_link_multi-y = AR      $@
> +cmd_link_multi-y = rm -f $@; $(AR) cDPrsT $@ $(link_multi_deps)
> +
> +quiet_cmd_link_multi-m = AR [M]  $@
>  cmd_link_multi-m = $(cmd_link_multi-y)
>
>  $(multi-used-y): FORCE
> diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
> index 3b5f5046c9..889debb93c 100644
> --- a/scripts/Makefile.spl
> +++ b/scripts/Makefile.spl
> @@ -423,10 +423,10 @@ quiet_cmd_u-boot-spl ?= LD      $@
>        cmd_u-boot-spl ?= (cd $(obj) && \
>                 $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_$(@F))                \
>                 $(patsubst $(obj)/%,%,$(u-boot-spl-init))               \
> -               --start-group                                           \
> +               --start-group --whole-archive                           \
>                         $(patsubst $(obj)/%,%,$(u-boot-spl-main))       \
>                         $(patsubst $(obj)/%,%,$(u-boot-spl-platdata))   \
> -               --end-group                                             \
> +               --no-whole-archive --end-group                          \
>                 $(PLATFORM_LIBS) -Map $(SPL_BIN).map -o $(SPL_BIN)      \
>                         )
>

Otherwise LGTM:
Reviewed-by: Bin Meng <bmeng.cn at gmail.com>

Regards,
Bin


More information about the U-Boot mailing list