Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

DavidSpickett
Copy link
Collaborator

@DavidSpickett DavidSpickett commented Sep 12, 2025

Some time between Clang 19 and Clang 21, changes were made to the bare metal toolchain driver, and on top of that we (Linaro) updated our host OS to Ubuntu Jammy. This has caused the tests to not build with clang-21.

  1. The host version of ld (2.38) not being able to parse certain DWARFv5 constructs.

Normally I would switch to lld instead. However when I did this, I found that Picolibc's ARM linker script uses ALIGN_WITH_INPUT, which lld does not support.

So instead I'm sticking with ld and falling back to DWARFv4. Until such time as we upgrade the host to Ubuntu Noble.

(if you're wondering how we can use ld in the first place, given the host is AArch64, the AArch64 ld is also capable of linking ARM 32-bit binaries)

  1. Many missing symbol errors.

This is solved in two parts:

  • Adding libunwind to the testing linker flags.
  • Putting the libraries in a group so that the ordering does not matter.

And finally for exception_guard.odr.sh.cpp, I have moved the object files to before the linker flags. ld is sensitive to the order of objects on the command line, and this should not break other configurations.

I've tested these with 19.1.7 too so my plan is to land these changes first, then proceed with upgrading to 21.x.

Some time between Clang 19 and Clang 21, changes were made to the
bare metal toolchain driver, and on top of that we (Linaro) updated
our host OS to Ubuntu Jammy. This has caused the tests to not
build with clang-21.

1. The host version of ld (2.38) not being able to parse certain
   DWARFv5 constructs.

Normally I would switch to lld instead. However when I did this,
I found that Picolib's ARM linker script uses ALIGN_WITH_INPUT,
which lld does not support.

So instead I'm sticking with ld and falling back to DWARFv4.
Until such time as we upgrade the host to Ubuntu Noble.

(if you're wondering how we can use ld in the first place, given
the host is AArch64, the AArch64 ld is also capable of linking
ARM 32-bit binaries)

2. Many missing symbol errors.

This is solved in two parts:
* Adding libunwind to the testing linker flags.
* Putting the libraries in a group so that the ordering does
  not matter.

And finally for exception_guard.odr.sh.cpp, I have moved the
object files to before the linker flags. ld is sensitive to
the order of objects on the command line, and this should not
break other configurations.

I've tested these with 19.1.7 too so my plan is to land these
changes first, then proceed with upgrading to 21.x.
@DavidSpickett DavidSpickett requested review from a team as code owners September 12, 2025 14:10
@llvmbot llvmbot added libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. libc++abi libc++abi C++ Runtime Library. Not libc++. libunwind labels Sep 12, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 12, 2025

@llvm/pr-subscribers-libunwind
@llvm/pr-subscribers-libcxxabi

@llvm/pr-subscribers-libcxx

Author: David Spickett (DavidSpickett)

Changes

Some time between Clang 19 and Clang 21, changes were made to the bare metal toolchain driver, and on top of that we (Linaro) updated our host OS to Ubuntu Jammy. This has caused the tests to not build with clang-21.

  1. The host version of ld (2.38) not being able to parse certain DWARFv5 constructs.

Normally I would switch to lld instead. However when I did this, I found that Picolib's ARM linker script uses ALIGN_WITH_INPUT, which lld does not support.

So instead I'm sticking with ld and falling back to DWARFv4. Until such time as we upgrade the host to Ubuntu Noble.

(if you're wondering how we can use ld in the first place, given the host is AArch64, the AArch64 ld is also capable of linking ARM 32-bit binaries)

  1. Many missing symbol errors.

This is solved in two parts:

  • Adding libunwind to the testing linker flags.
  • Putting the libraries in a group so that the ordering does not matter.

And finally for exception_guard.odr.sh.cpp, I have moved the object files to before the linker flags. ld is sensitive to the order of objects on the command line, and this should not break other configurations.

I've tested these with 19.1.7 too so my plan is to land these changes first, then proceed with upgrading to 21.x.


Full diff: https://github.com/llvm/llvm-project/pull/158300.diff

6 Files Affected:

  • (modified) libcxx/cmake/caches/Armv7M-picolibc.cmake (+2-2)
  • (modified) libcxx/test/configs/armv7m-picolibc-libc++.cfg.in (+3-3)
  • (modified) libcxx/test/libcxx/utilities/exception_guard.odr.sh.cpp (+1-1)
  • (modified) libcxx/utils/ci/build-picolibc.sh (+1-1)
  • (modified) libcxxabi/test/configs/armv7m-picolibc-libc++abi.cfg.in (+3-3)
  • (modified) libunwind/test/configs/armv7m-picolibc-libunwind.cfg.in (+3-3)
diff --git a/libcxx/cmake/caches/Armv7M-picolibc.cmake b/libcxx/cmake/caches/Armv7M-picolibc.cmake
index 0f8189b457285..7ad2bb6db9856 100644
--- a/libcxx/cmake/caches/Armv7M-picolibc.cmake
+++ b/libcxx/cmake/caches/Armv7M-picolibc.cmake
@@ -1,8 +1,8 @@
 set(CMAKE_ASM_COMPILER_TARGET "armv7m-none-eabi" CACHE STRING "")
 set(CMAKE_CXX_COMPILER_TARGET "armv7m-none-eabi" CACHE STRING "")
-set(CMAKE_CXX_FLAGS "-mfloat-abi=soft" CACHE STRING "")
+set(CMAKE_CXX_FLAGS "-mfloat-abi=soft -gdwarf-4" CACHE STRING "")
 set(CMAKE_C_COMPILER_TARGET "armv7m-none-eabi" CACHE STRING "")
-set(CMAKE_C_FLAGS "-mfloat-abi=soft" CACHE STRING "")
+set(CMAKE_C_FLAGS "-mfloat-abi=soft -gdwarf-4" CACHE STRING "")
 set(CMAKE_SYSTEM_NAME Generic CACHE STRING "")
 set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY CACHE STRING "")
 set(COMPILER_RT_BAREMETAL_BUILD ON CACHE BOOL "")
diff --git a/libcxx/test/configs/armv7m-picolibc-libc++.cfg.in b/libcxx/test/configs/armv7m-picolibc-libc++.cfg.in
index 9bff5021494ef..c1a1a99972a22 100644
--- a/libcxx/test/configs/armv7m-picolibc-libc++.cfg.in
+++ b/libcxx/test/configs/armv7m-picolibc-libc++.cfg.in
@@ -5,7 +5,7 @@ libc_linker_script = '@CMAKE_INSTALL_PREFIX@/lib/picolibcpp.ld'
 config.substitutions.append(('%{flags}', '--sysroot=@CMAKE_INSTALL_PREFIX@'))
 
 config.substitutions.append(('%{compile_flags}',
-    '-nostdinc++ -I %{include-dir} -I %{target-include-dir} -I %{libcxx-dir}/test/support'
+    '-nostdinc++ -I %{include-dir} -I %{target-include-dir} -I %{libcxx-dir}/test/support -gdwarf-4'
 
     # Disable warnings in the <atomic> implementation:
     # "large atomic operation may incur significant performance penalty; the
@@ -13,8 +13,8 @@ config.substitutions.append(('%{compile_flags}',
     ' -Wno-atomic-alignment'
 ))
 config.substitutions.append(('%{link_flags}',
-    '-nostdlib -nostdlib++ -L %{lib-dir} -lc++ -lc++abi'
-    ' -lc -lm -lclang_rt.builtins -lsemihost -lcrt0-semihost' +
+    '-nostdlib -nostdlib++ -L %{lib-dir} -Wl,--start-group -lc++ -lc++abi'
+    ' -lunwind -lc -lm -lclang_rt.builtins -lsemihost -lcrt0-semihost -Wl,--end-group' +
     ' -T {}'.format(libc_linker_script) +
     ' -Wl,--defsym=__flash=0x0'
     ' -Wl,--defsym=__flash_size=0x400000'
diff --git a/libcxx/test/libcxx/utilities/exception_guard.odr.sh.cpp b/libcxx/test/libcxx/utilities/exception_guard.odr.sh.cpp
index f6b8a29d36821..a1a4ad84e61d9 100644
--- a/libcxx/test/libcxx/utilities/exception_guard.odr.sh.cpp
+++ b/libcxx/test/libcxx/utilities/exception_guard.odr.sh.cpp
@@ -14,7 +14,7 @@
 
 // RUN: %{cxx} %s %{flags} %{compile_flags} -c -o %t.except.o   -O1 -fexceptions
 // RUN: %{cxx} %s %{flags} %{compile_flags} -c -o %t.noexcept.o -O1 -fno-exceptions
-// RUN: %{cxx} %{flags} %{link_flags} -o %t.exe %t.except.o %t.noexcept.o
+// RUN: %{cxx} %{flags} -o %t.exe %t.except.o %t.noexcept.o %{link_flags}
 // RUN: %{run}
 
 #include <__utility/exception_guard.h>
diff --git a/libcxx/utils/ci/build-picolibc.sh b/libcxx/utils/ci/build-picolibc.sh
index 521c1bef9fc7e..f480368dacbf1 100755
--- a/libcxx/utils/ci/build-picolibc.sh
+++ b/libcxx/utils/ci/build-picolibc.sh
@@ -78,7 +78,7 @@ rm -rf "${picolibc_source_dir}/picolibc-${picolibc_commit}"
 
 cat <<EOF > "${picolibc_build_dir}/meson-cross-build.txt"
 [binaries]
-c = ['${CC:-cc}', '--target=${target}', '-mfloat-abi=soft', '-nostdlib']
+c = ['${CC:-cc}', '--target=${target}', '-mfloat-abi=soft', '-nostdlib', '-gdwarf-4']
 ar = 'llvm-ar'
 as = 'llvm-as'
 ld = 'lld'
diff --git a/libcxxabi/test/configs/armv7m-picolibc-libc++abi.cfg.in b/libcxxabi/test/configs/armv7m-picolibc-libc++abi.cfg.in
index b4744f935ad85..12e15fbfc6efe 100644
--- a/libcxxabi/test/configs/armv7m-picolibc-libc++abi.cfg.in
+++ b/libcxxabi/test/configs/armv7m-picolibc-libc++abi.cfg.in
@@ -5,11 +5,11 @@ libc_linker_script = '@CMAKE_INSTALL_PREFIX@/lib/picolibcpp.ld'
 config.substitutions.append(('%{flags}', '--sysroot=@CMAKE_INSTALL_PREFIX@'))
 
 config.substitutions.append(('%{compile_flags}',
-    '-nostdinc++ -I %{include} -I %{cxx-include} -I %{cxx-target-include} %{maybe-include-libunwind} -I %{libcxx}/test/support -I %{libcxx}/src -D_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS'
+    '-nostdinc++ -I %{include} -I %{cxx-include} -I %{cxx-target-include} %{maybe-include-libunwind} -I %{libcxx}/test/support -I %{libcxx}/src -D_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS -gdwarf-4'
 ))
 config.substitutions.append(('%{link_flags}',
-    '-nostdlib -nostdlib++ -L %{lib} -lc++ -lc++abi'
-    ' -lc -lm -lclang_rt.builtins -lsemihost -lcrt0-semihost' +
+    '-nostdlib -nostdlib++ -L %{lib} -Wl,--start-group -lc++ -lc++abi'
+    ' -lunwind -lc -lm -lclang_rt.builtins -lsemihost -lcrt0-semihost -Wl,--end-group' +
     ' -T {}'.format(libc_linker_script) +
     ' -Wl,--defsym=__flash=0x0'
     ' -Wl,--defsym=__flash_size=0x400000'
diff --git a/libunwind/test/configs/armv7m-picolibc-libunwind.cfg.in b/libunwind/test/configs/armv7m-picolibc-libunwind.cfg.in
index e8f68a51fc53f..494fb13945f56 100644
--- a/libunwind/test/configs/armv7m-picolibc-libunwind.cfg.in
+++ b/libunwind/test/configs/armv7m-picolibc-libunwind.cfg.in
@@ -5,11 +5,11 @@ libc_linker_script = '@CMAKE_INSTALL_PREFIX@/lib/picolibcpp.ld'
 config.substitutions.append(('%{flags}', '--sysroot=@CMAKE_INSTALL_PREFIX@'))
 
 config.substitutions.append(('%{compile_flags}',
-    '-nostdinc++ -I %{include}'
+    '-nostdinc++ -I %{include} -gdwarf-4'
 ))
 config.substitutions.append(('%{link_flags}',
-    '-nostdlib -nostdlib++ -L %{lib} -lunwind'
-    ' -lc -lm -lclang_rt.builtins -lsemihost -lcrt0-semihost' +
+    '-nostdlib -nostdlib++ -L %{lib} -Wl,--start-group -lunwind'
+    ' -lc -lm -lclang_rt.builtins -lsemihost -lcrt0-semihost -Wl,--end-group' +
     ' -T {}'.format(libc_linker_script) +
     ' -Wl,--defsym=__flash=0x0'
     ' -Wl,--defsym=__flash_size=0x400000'

@DavidSpickett
Copy link
Collaborator Author

Will get someone from Arm to review as well since they are consumers of Picolib and libcxx.

@vhscampos
Copy link
Member

LGTM. Just a few typos: it's "picolibc" rather than "picolib". Missing the final 'c'.

@DavidSpickett DavidSpickett changed the title [libcxx][CI] Prepare ARM Picolib builds for upgrade to clang 21 [libcxx][CI] Prepare ARM Picolibc builds for upgrade to clang 21 Sep 12, 2025
@DavidSpickett
Copy link
Collaborator Author

Thanks for reviewing! I've fixed the spellings.

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM w/ passing CI!

@DavidSpickett
Copy link
Collaborator Author

Arm colleagues alerted me to the fact that picolibc does have some code to handle this ALIGN_WITH_INPUT thing when lld is used. Either CI is using a too old verison of picolibc, or that code is not triggering.

To keep each change simple, I'm going ahead with this PR, then I'll work out if we can in fact get lld working and send another PR if so.

@arichardson
Copy link
Member

Arm colleagues alerted me to the fact that picolibc does have some code to handle this ALIGN_WITH_INPUT thing when lld is used. Either CI is using a too old verison of picolibc, or that code is not triggering.

To keep each change simple, I'm going ahead with this PR, then I'll work out if we can in fact get lld working and send another PR if so.

I added LLD support to picolibc in picolibc/picolibc#376, so it should all work out of the box.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++abi libc++abi C++ Runtime Library. Not libc++. libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. libunwind
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants