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?
On Fri, Jul 25, 2025 at 12:36:34PM +0200, Thomas Weißschuh wrote:
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.
Yes, I believe this is the issue we had for tracking using ld.lld with UML: https://github.com/ClangBuiltLinux/linux/issues/1715
I had not considered that it could be a linker script handling difference. I will have to look into that soon.
Longterm --ld-path should probably be added to the global KBUILD_CFLAGS, too.
'--ld-path' is only relevant when the linking phase is run by the compiler, which is not really normal for the primary kernel build, as calling the linker directly with $(LD) is preferred. Doing that would break the build because of -Werror=unused-command-line-argument, which is needed to make cc-option work correctly.
$ echo 'int main(void) { return 0; }' | /usr/bin/clang --ld-path=/usr/bin/ld.lld -c -o /dev/null -x c - clang: warning: argument unused during compilation: '--ld-path=/usr/bin/ld.lld' [-Wunused-command-line-argument]
$ echo 'int main(void) { return 0; }' | /usr/bin/clang --ld-path=/usr/bin/ld.lld -o /dev/null -x c -
No, it isn't respected. On the other hand I didn't yet run into any issues. Do we want to fix it proactively?
No, I think it is fine to just leave it as is and fix it if it comes up in the future, as I believe getting LLVM_IAS=1 working for sparc64 is the next major focus of the whole LLVM sparc endeavour.
Cheers, Nathan
linux-stable-mirror@lists.linaro.org