[Lldb-commits] [lldb] [lldb][test] When an external stdlib is specified do not link to the system stdlib (PR #164462)
Michael Buch via lldb-commits
lldb-commits at lists.llvm.org
Wed Oct 22 07:21:30 PDT 2025
================
@@ -386,6 +386,11 @@ ifeq (,$(filter 1, $(USE_LIBSTDCPP) $(USE_LIBCPP) $(USE_SYSTEM_STDLIB)))
ifneq "$(LIBCPP_INCLUDE_TARGET_DIR)" ""
CXXFLAGS += -cxx-isystem $(LIBCPP_INCLUDE_TARGET_DIR)
endif
+
+ # If `-nostdlib++` is not passed, clang will link to the system's stdlib.
+ ifeq ($(LDC), clang)
+ LDFLAGS += -nostdlib++ -nostdinc++
----------------
Michael137 wrote:
> nostdlib is for C standard library and nostdlib++ is for C++ standard library
I meant the two are synonymous w.r.t to their effect on the link line. E.g., on Darwin I see:
```
$ clang++ stdlib.o -### 2>&1 | grep "\-lc++"
"/usr/bin/ld" "-demangle" "-lto_library" "/usr/lib/libLTO.dylib" "-dynamic" "-arch" "arm64" "-platform_version" "macos" "14.4.0" "14.4" "-o" "a.out" "-L." "-L/opt/homebrew/lib" "-L/opt/homebrew/lib" "-L/usr/local/lib" "stdlib.o" "-lc++" "-lSystem" "/lib/darwin/libclang_rt.osx.a"
~
$ clang++ stdlib.o -nostdlib++ -### 2>&1 | grep "\-lc++"
~
$ clang++ stdlib.o -nostdlib -### 2>&1 | grep "\-lc++"
~
$ clang++ stdlib.o -nostdlib++ -stdlib=libc++ -### 2>&1 | grep "\-lc++"
~
```
I.e., the effect of these flags on Clang, is that it won't pass `-lc++` (or `-lstdc++` on Linux) to the linker.
The reason I was confused was that we already pass these flags to Clang. So how come it doesn't do the right thing? The reason *I think* this doesn't work properly at the moment is that if you pass `-lc++` *and* `-nostdlib++` to Clang, then Clang ignores the `-nostdlib++`. Which is kind of surprising to me, but maybe how it's supposed to work? Not sure:
```
$ clang++ stdlib.cpp -stdlib=libc++ -nostdlib++ -lc++ -### 2>&1 | grep "\lc++"
"/usr/bin/ld" "-demangle" "-lto_library" "/usr/lib/libLTO.dylib" "-no_deduplicate" "-dynamic" "-arch" "arm64" "-platform_version" "macos" "14.4.0" "14.4" "-o" "a.out" "-L." "-L/opt/homebrew/lib" "-L/opt/homebrew/lib" "-L/usr/local/lib" "/var/folders/66/1r54zpmx3nz7rsmcpqn1r5c80000gn/T/stdlib-9d234c.o" "-lc++" "-lSystem" "/lib/darwin/libclang_rt.osx.a"
```
By adding it to `LDFLAGS`, you are now passing `-nostdlib++` to the linker. This is an option not recognised by all linkers. GNU LD does know about it, and the [docs say](https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html):
```
-nostdlib++
Do not implicitly link with standard C++ libraries.
```
So I suspect this fixes the issue because `-lc++` and `-nostdlib++` for GNU LD ends up favouring the latter.
But, e.g., ld64 on Darwin doesn't know about it. So we would get:
```
$ clang++ stdlib.cpp -stdlib=libc++ -Wl,-lnostdlib++
ld: library not found for -lnostdlib++
clang: error: linker command failed with exit code 1 (use -v to see invocation)
```
Let me know if any of the above doesn't hold on Linux or I'm misunderstanding. My questions are:
1. Am I understanding correctly that the *real* issue is that we pass both `-lc++` *and* `-nostdlib++` to Clang, so the latter never has an affect? And we end up forwarding `-lc++` to the linker anyway?
2. Does your change work on Darwin? What is the `$(LDC)` value there? And is passing `-nostdlib++` to the linker (via `LDFLAGS`) there fine? How about LLD on linux?
3. Do we need to pass `-nostdinc++` too? What effect does that have on the linker?
https://github.com/llvm/llvm-project/pull/164462
More information about the lldb-commits
mailing list