Skip to content

Commit

Permalink
[Squash] Treewide: Update for ld.lld usage
Browse files Browse the repository at this point in the history
kbuild: Allow forcing the alternative LLD linker via Kconfig

LLD is a relatively new linker from the LLVM Project that aims to be a
faster and more modern alternative to the GNU gold and bfd linkers from
binutils: https://lld.llvm.org/

I've also found that it offers more insightful diagnostics when
something goes wrong, e.g. when there are undefined references. It does
also appear to speed up the overall build time by 4-10s as compared to
ld.bfd.

These new config options will only allow fully-working configurations:
  - gold/lld when Clang LTO is enabled
  - bfd/lld otherwise

Signed-off-by: Danny Lin <[email protected]>
Signed-off-by: Adam W. Willis <[email protected]>
Signed-off-by: Yaroslav Furman <[email protected]>

BACKPORT: FROMLIST: Makefile: lld: set -O2 linker flag when linking w…

…ith LLD

For arm64:
0.34% size improvement with lld -O2 over lld for vmlinux.
3.3% size improvement with lld -O2 over lld for Image.lz4-dtb.

Link: ClangBuiltLinux/linux#343
Suggested-by: Rui Ueyama <[email protected]>
Suggested-by: Nathan Chancellor <[email protected]>
Reviewed-by: Nathan Chancellor <[email protected]>
Tested-by: Nathan Chancellor <[email protected]>
Signed-off-by: Nick Desaulniers <[email protected]>
(am from https://patchwork.kernel.org/patch/10806729/)
Signed-off-by: Adam W. Willis <[email protected]>
Signed-off-by: Yaroslav Furman <[email protected]>

BACKPORT: FROMLIST: Makefile: lld: tell clang to use lld

This is needed because clang doesn't select which linker to use based on
$LD but rather -fuse-ld={bfd,gold,lld,<absolute path to linker>}.  This
is problematic especially for cc-ldoption, which checks for linker flag
support via invoking the compiler, rather than the BACKPORT: FROMLIST: Makefile: lld: tell clang to use lld

This is needed because clang doesn't select which linker to use based on
$LD but rather -fuse-ld={bfd,gold,lld,<absolute path to linker>}.  This
is problematic especially for cc-ldoption, which checks for linker flag
support via invoking the compiler, rather than the linker.

Select the linker via absolute path from $PATH via `which`. This allows
you to build with:

$ make LD=ld.lld
$ make LD=ld.lld-8
$ make LD=/path/to/ld.lld

Add -Qunused-arguments to KBUILD_CPPFLAGS sooner, as otherwise
Clang likes to complain about -fuse-lld= being unused when compiling but
not linking (-c) such as when cc-option is used. There's no need to
guard with cc-option.

Link: ClangBuiltLinux/linux#342
Link: ClangBuiltLinux/linux#366
Link: ClangBuiltLinux/linux#357
Suggested-by: Nathan Chancellor <[email protected]>
Suggested-by: Masahiro Yamada <[email protected]>
Signed-off-by: Nick Desaulniers <[email protected]>
Reviewed-by: Nathan Chancellor <natechancellor@gmail
Signed-off-by: Divyanshu-Modi <[email protected]>
Signed-off-by: Kunmun <[email protected]>
  • Loading branch information
Divyanshu-Modi authored and Ivy-Tokito committed Oct 11, 2024
1 parent ffad075 commit b9ab70c
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 18 deletions.
19 changes: 13 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ include scripts/Kbuild.include
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
LDGOLD = $(CROSS_COMPILE)ld.gold
LDLLD = ld.lld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR ?= $(CROSS_COMPILE)ar
Expand Down Expand Up @@ -641,8 +642,9 @@ KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior)
KBUILD_CFLAGS += $(call cc-option, -no-integrated-as)
KBUILD_AFLAGS += $(call cc-option, -no-integrated-as)
ifeq ($(ld-name),lld)
KBUILD_CFLAGS += -fuse-ld=lld
KBUILD_CFLAGS += -fuse-ld=$(shell which $(LD))
endif
KBUILD_CPPFLAGS += -Qunused-arguments
endif

# These warnings generated too much noise in a regular build.
Expand All @@ -651,11 +653,16 @@ KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable)

# Make toolchain changes before including arch/$(SRCARCH)/Makefile to ensure
# ar/cc/ld-* macros return correct values.
ifdef CONFIG_LTO_CLANG
ifneq ($(ld-name),lld)
# use GNU gold with LLVMgold for LTO linking, and LD for vmlinux_link
ifdef CONFIG_LD_GOLD
LDFINAL_vmlinux := $(LD)
LD := $(LDGOLD)
endif
ifdef CONFIG_LD_LLD
LD := $(LDLLD)
endif
ifdef CONFIG_LTO_CLANG
# use GNU gold with LLVMgold or LLD for LTO linking, and LD for vmlinux_link
ifeq ($(ld-name),gold)
LDFLAGS += -plugin LLVMgold.so
endif
# use llvm-ar for building symbol tables from IR files, and llvm-dis instead
Expand Down Expand Up @@ -803,7 +810,7 @@ ifdef CONFIG_KCOV
endif

ifeq ($(ld-name),lld)
LDFLAGS += -O2
LDFLAGS += -O3
endif

KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable)
Expand Down Expand Up @@ -1174,7 +1181,7 @@ ifdef CONFIG_LTO_CLANG
endif
ifneq ($(ld-name),lld)
ifneq ($(call gold-ifversion, -ge, 112000000, y), y)
@echo Cannot use CONFIG_LTO_CLANG: requires GNU gold 1.12 or later >&2 && exit 1
@echo Cannot use CONFIG_LTO_CLANG: requires LLD or GNU gold 1.12 or later >&2 && exit 1
endif
endif
endif
Expand Down
32 changes: 32 additions & 0 deletions arch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,37 @@ config THIN_ARCHIVES
Select this if the architecture wants to use thin archives
instead of ld -r to create the built-in.o files.

choice
prompt "Kernel linker"
default LD_BFD if !LTO_CLANG
default LD_GOLD if LTO_CLANG
help
This selects the linker that will be used to link the kernel and
its composite objects.

Note that using either ld.gold or lld is required for Clang LTO.
ld.bfd will not work.

config LD_BFD
bool "bfd"
depends on !LTO_CLANG
help
Use the standard ld.bfd linker from binutils, which is usually the
default. This linker does not work with Clang LTO.

config LD_GOLD
bool "gold"
depends on LTO_CLANG
help
Use the alternative ld.gold linker from binutils.

config LD_LLD
bool "lld"
help
Use the alternative lld linker from LLVM.

endchoice

config LD_DEAD_CODE_DATA_ELIMINATION
bool
help
Expand Down Expand Up @@ -483,6 +514,7 @@ config LTO_CLANG
select LTO
select THIN_ARCHIVES
select LD_DEAD_CODE_DATA_ELIMINATION
select LD_GOLD
help
This option enables clang's Link Time Optimization (LTO), which allows
the compiler to optimize the kernel globally at link time. If you
Expand Down
13 changes: 1 addition & 12 deletions scripts/Kbuild.include
Original file line number Diff line number Diff line change
Expand Up @@ -208,18 +208,7 @@ ar-option = $(call try-run, $(AR) rc$(1) "$$TMP",$(1),$(2))

# ld-name
# Expands to either bfd, gold, or lld
ifneq (,$(LD))
__ld-name = $(shell $(LD) -v 2>&1)
endif
ifneq (,$(findstring GNU gold,$(__ld-name)))
ld-name = gold
else
ifneq (,$(findstring LLD,$(__ld-name)))
ld-name = lld
else
ld-name = bfd
endif
endif
ld-name = $(shell if $(LD) -v 2>&1 | grep -q "GNU gold"; then echo gold; elif $(LD) -v 2>&1 | grep -q "LLD"; then echo lld; else echo bfd; fi)

# ld-version
# Note this is mainly for HJ Lu's 3 number binutil versions
Expand Down

0 comments on commit b9ab70c

Please sign in to comment.