You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用--no-undefined与--as-needed链接时弱符号引发的链接问题

Why pthread_create is missing when linking with --as-needed and --no-undefined

Let’s break down the root causes of your issue and how to fix it:

Key Background

First, clarify what each linker option does in this context:

  • --as-needed: The linker only includes a shared library (like -lpthread) if there’s a strong, unresolved reference to symbols it provides. Weak references don’t trigger inclusion.
  • --no-undefined: The linker rejects any shared library with unresolved symbols—this applies to both strong and weak references, even though weak symbols can technically be undefined at runtime.
  • libstdc++_nonshared.a: This static archive contains code for C++ standard library features like std::thread, which makes strong references to pthread_create (since std::thread relies on pthread for implementation on Linux).

Why the Error Happens

When using both options together:

  1. The linker processes your code and pulls in thread48.o from libstdc++_nonshared.a (because you’re using std::thread). This object file has a strong reference to pthread_create.
  2. If -lpthread is in the wrong order (before libstdc++) or isn’t explicitly forced to be included, --as-needed skips -lpthread—since at the time the linker processes -lpthread, there are no unresolved strong references to its symbols yet.
  3. --no-undefined then throws an error because pthread_create remains unresolved (even if your own code only has weak references to it, the strong reference from libstdc++ is enough to trigger this).

Why Your Workarounds Work

  • Removing --as-needed: The linker includes -lpthread unconditionally, resolving pthread_create and satisfying --no-undefined. ldd shows pthread.so as a dependency because it’s included regardless of need.
  • Removing --no-undefined: The linker allows unresolved symbols (including the strong pthread_create reference from libstdc++), so linking succeeds. --as-needed skips -lpthread (since your code doesn’t have strong references to it), so ldd doesn’t list it as a dependency. However, this is risky—your code will crash at runtime if pthread isn’t loaded when std::thread is used.

Fixes

1. Correct Library Order

Ensure -lpthread comes after libstdc++ (or any libraries that reference pthread symbols) in your link command. This way, when the linker processes -lpthread, it sees the unresolved pthread_create reference from libstdc++ and includes the library:

gcc -shared -o libfoo.so foo.o -Wl,--as-needed,--no-undefined -lstdc++ -lpthread

2. Force Inclusion of pthread

If you can’t adjust the library order, use --no-as-needed around -lpthread to override the --as-needed behavior for this library:

gcc -shared -o libfoo.so foo.o -Wl,--as-needed,--no-undefined -lstdc++ -Wl,--no-as-needed,-lpthread,--as-needed

This forces the linker to include -lpthread even if it wouldn’t otherwise be considered "needed," resolving the pthread_create symbol.

3. Verify Weak vs Strong References

Run nm -C libstdc++_nonshared.a | grep pthread_create to check if the reference from libstdc++ is strong (marked with U for undefined, no W or w). If it’s a strong reference, you must link -lpthread to satisfy --no-undefined.


内容的提问来源于stack exchange,提问作者daltairwalter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 20:25:00