The userprogs infrastructure does not expect clang being used with GNU ld and in that case uses /usr/bin/ld for linking, not the configured $(LD). This fallback is problematic as it will break when cross-compiling. Mixing clang and GNU ld is used for example when building for SPARC64, as ld.lld is not sufficient; see Documentation/kbuild/llvm.rst.
Relax the check around --ld-path so it gets used for all linkers.
Fixes: dfc1b168a8c4 ("kbuild: userprogs: use correct lld when linking through clang") Cc: stable@vger.kernel.org Signed-off-by: Thomas Weißschuh thomas.weissschuh@linutronix.de --- Nathan, you originally proposed the check for $(CONFIG_LD_IS_LLD) [0], could you take a look at this?
[0] https://lore.kernel.org/all/20250213175437.GA2756218@ax162/ --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile index c09766beb7eff4780574682b8ea44475fc0a5188..e300c6546c845c300edb5f0033719963c7da8f9b 100644 --- a/Makefile +++ b/Makefile @@ -1134,7 +1134,7 @@ KBUILD_USERCFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CPPFLAGS) $(KBUILD KBUILD_USERLDFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS))
# userspace programs are linked via the compiler, use the correct linker -ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_LD_IS_LLD),yy) +ifneq ($(CONFIG_CC_IS_CLANG),) KBUILD_USERLDFLAGS += --ld-path=$(LD) endif
--- base-commit: 6832a9317eee280117cd695fa885b2b7a7a38daf change-id: 20250723-userprogs-clang-gnu-ld-7a1c16fc852d
Best regards,
On Thu, Jul 24, 2025 at 10:32:45AM +0200, Thomas Weißschuh wrote:
The userprogs infrastructure does not expect clang being used with GNU ld and in that case uses /usr/bin/ld for linking, not the configured $(LD). This fallback is problematic as it will break when cross-compiling. Mixing clang and GNU ld is used for example when building for SPARC64, as ld.lld is not sufficient; see Documentation/kbuild/llvm.rst.
Relax the check around --ld-path so it gets used for all linkers.
Fixes: dfc1b168a8c4 ("kbuild: userprogs: use correct lld when linking through clang") Cc: stable@vger.kernel.org Signed-off-by: Thomas Weißschuh thomas.weissschuh@linutronix.de
Nathan, you originally proposed the check for $(CONFIG_LD_IS_LLD) [0], could you take a look at this?
I would expect this to be okay but I have not explicitly tested it. I had not considered the case of GNU ld being used since aside from sparc64, there is not another architecture that supports clang but not ld.lld.
Reviewed-by: Nathan Chancellor nathan@kernel.org
Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile index c09766beb7eff4780574682b8ea44475fc0a5188..e300c6546c845c300edb5f0033719963c7da8f9b 100644 --- a/Makefile +++ b/Makefile @@ -1134,7 +1134,7 @@ KBUILD_USERCFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CPPFLAGS) $(KBUILD KBUILD_USERLDFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS))
Does KBUILD_USERCFLAGS respect LLVM_IAS? sparc64 does not use the integrated assembler yet (as far as I am aware) so I think we probably need to filter '--prefix=' and '-fno-integrated-as' to avoid further issues with assembling?
# userspace programs are linked via the compiler, use the correct linker -ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_LD_IS_LLD),yy) +ifneq ($(CONFIG_CC_IS_CLANG),)
At this point, I think this can just become
ifdef CONFIG_CC_IS_CLANG
KBUILD_USERLDFLAGS += --ld-path=$(LD) endif
base-commit: 6832a9317eee280117cd695fa885b2b7a7a38daf change-id: 20250723-userprogs-clang-gnu-ld-7a1c16fc852d
Best regards,
Thomas Weißschuh thomas.weissschuh@linutronix.de
On Thu, Jul 24, 2025 at 04:10:25PM -0700, Nathan Chancellor wrote:
On Thu, Jul 24, 2025 at 10:32:45AM +0200, Thomas Weißschuh wrote:
The userprogs infrastructure does not expect clang being used with GNU ld and in that case uses /usr/bin/ld for linking, not the configured $(LD). This fallback is problematic as it will break when cross-compiling. Mixing clang and GNU ld is used for example when building for SPARC64, as ld.lld is not sufficient; see Documentation/kbuild/llvm.rst.
Relax the check around --ld-path so it gets used for all linkers.
Fixes: dfc1b168a8c4 ("kbuild: userprogs: use correct lld when linking through clang") Cc: stable@vger.kernel.org Signed-off-by: Thomas Weißschuh thomas.weissschuh@linutronix.de
Nathan, you originally proposed the check for $(CONFIG_LD_IS_LLD) [0], could you take a look at this?
I would expect this to be okay but I have not explicitly tested it. I had not considered the case of GNU ld being used since aside from sparc64, there is not another architecture that supports clang but not ld.lld.
FWIW some architectures use GNU ld implicitly with clang because they also link through $(CC) but do not use --ld-path. One example is UML, where the vDSO and vmlinux are linked this way. But linking vmlinux of UML with ld.lld will require changes to at least the linker script. Something for the ClangBuiltLinux TODO? There were more examples, but I don't remember them right now.
Longterm --ld-path should probably be added to the global KBUILD_CFLAGS, too.
Reviewed-by: Nathan Chancellor nathan@kernel.org
Thanks!
Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile index c09766beb7eff4780574682b8ea44475fc0a5188..e300c6546c845c300edb5f0033719963c7da8f9b 100644 --- a/Makefile +++ b/Makefile @@ -1134,7 +1134,7 @@ KBUILD_USERCFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CPPFLAGS) $(KBUILD KBUILD_USERLDFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS))
Does KBUILD_USERCFLAGS respect LLVM_IAS? sparc64 does not use the integrated assembler yet (as far as I am aware) so I think we probably need to filter '--prefix=' and '-fno-integrated-as' to avoid further issues with assembling?
No, it isn't respected. On the other hand I didn't yet run into any issues. Do we want to fix it proactively?
# userspace programs are linked via the compiler, use the correct linker -ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_LD_IS_LLD),yy) +ifneq ($(CONFIG_CC_IS_CLANG),)
At this point, I think this can just become
ifdef CONFIG_CC_IS_CLANG
Absolutetly. The existing conditional above this hunk uses the ifneq pattern, so I tried to keep it consistent. But the one above uses plain ifdef again... Personally I don't care one way or another.
KBUILD_USERLDFLAGS += --ld-path=$(LD) endif
base-commit: 6832a9317eee280117cd695fa885b2b7a7a38daf change-id: 20250723-userprogs-clang-gnu-ld-7a1c16fc852d
Best regards,
Thomas Weißschuh thomas.weissschuh@linutronix.de
On Fri, Jul 25, 2025 at 7:36 PM Thomas Weißschuh thomas.weissschuh@linutronix.de wrote:
On Thu, Jul 24, 2025 at 04:10:25PM -0700, Nathan Chancellor wrote:
On Thu, Jul 24, 2025 at 10:32:45AM +0200, Thomas Weißschuh wrote:
The userprogs infrastructure does not expect clang being used with GNU ld and in that case uses /usr/bin/ld for linking, not the configured $(LD). This fallback is problematic as it will break when cross-compiling. Mixing clang and GNU ld is used for example when building for SPARC64, as ld.lld is not sufficient; see Documentation/kbuild/llvm.rst.
Relax the check around --ld-path so it gets used for all linkers.
Fixes: dfc1b168a8c4 ("kbuild: userprogs: use correct lld when linking through clang") Cc: stable@vger.kernel.org Signed-off-by: Thomas Weißschuh thomas.weissschuh@linutronix.de
Nathan, you originally proposed the check for $(CONFIG_LD_IS_LLD) [0], could you take a look at this?
I would expect this to be okay but I have not explicitly tested it. I had not considered the case of GNU ld being used since aside from sparc64, there is not another architecture that supports clang but not ld.lld.
FWIW some architectures use GNU ld implicitly with clang because they also link through $(CC) but do not use --ld-path. One example is UML, where the vDSO and vmlinux are linked this way. But linking vmlinux of UML with ld.lld will require changes to at least the linker script. Something for the ClangBuiltLinux TODO? There were more examples, but I don't remember them right now.
Longterm --ld-path should probably be added to the global KBUILD_CFLAGS, too.
Reviewed-by: Nathan Chancellor nathan@kernel.org
Thanks!
Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile index c09766beb7eff4780574682b8ea44475fc0a5188..e300c6546c845c300edb5f0033719963c7da8f9b 100644 --- a/Makefile +++ b/Makefile @@ -1134,7 +1134,7 @@ KBUILD_USERCFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CPPFLAGS) $(KBUILD KBUILD_USERLDFLAGS += $(filter -m32 -m64 --target=%, $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS))
Does KBUILD_USERCFLAGS respect LLVM_IAS? sparc64 does not use the integrated assembler yet (as far as I am aware) so I think we probably need to filter '--prefix=' and '-fno-integrated-as' to avoid further issues with assembling?
No, it isn't respected. On the other hand I didn't yet run into any issues. Do we want to fix it proactively?
# userspace programs are linked via the compiler, use the correct linker -ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_LD_IS_LLD),yy) +ifneq ($(CONFIG_CC_IS_CLANG),)
At this point, I think this can just become
ifdef CONFIG_CC_IS_CLANG
Absolutetly. The existing conditional above this hunk uses the ifneq pattern, so I tried to keep it consistent. But the one above uses plain ifdef again... Personally I don't care one way or another.
Could you use "ifdef CONFIG_CC_IS_CLANG" please?
linux-stable-mirror@lists.linaro.org