如何使弱链接与 GCC 一起工作?
似乎有 3 种方法告诉 GCC 弱链接符号:
__attribute__((weak_import))
__attribute__((weak))
#pragmaweaksymbol_name
code>
这些都不适合我:
#pragma weak asdf
extern void asdf(void) __attribute__((weak_import, weak));
...
{
if(asdf != NULL) asdf();
}
我总是收到这样的链接错误:
Undefined symbols: "_asdf", referenced from: _asdf$non_lazy_ptr in ccFA05kN.o ld: symbol(s) not found collect2: ld returned 1 exit status
我在 OS X 10.5.5 上使用 GCC 4.0.1。 我究竟做错了什么?
There seem to be 3 ways of telling GCC to weak link a symbol:
__attribute__((weak_import))
__attribute__((weak))
#pragma weak symbol_name
None of these work for me:
#pragma weak asdf
extern void asdf(void) __attribute__((weak_import, weak));
...
{
if(asdf != NULL) asdf();
}
I always get a link error like this:
Undefined symbols: "_asdf", referenced from: _asdf$non_lazy_ptr in ccFA05kN.o ld: symbol(s) not found collect2: ld returned 1 exit status
I am using GCC 4.0.1 on OS X 10.5.5. What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我只是对此进行了研究,并认为其他一些人可能会对我的发现感兴趣。
使用weak_import 的弱链接实际上只适用于动态库。 您可以让它与静态链接一起使用(通过指定上面建议的 -undefinedynamic_lookup ),但这并不是一个热门主意。 这意味着在运行时之前不会检测到未定义的符号。 就我个人而言,这是我在生产代码中要避免的事情。
下面是一个 Mac OS X 终端会话,展示了如何使其工作:
这是 fc
这是 Whatnof.c
从 fc 制作动态库:
编译并链接动态库,列出动态库。
运行whatnof看看会发生什么:
现在用一个空库(没有符号)替换f.dylib:
运行相同的whatnof看看会发生什么:
weak_import的基本思想(或“用例”)是它可以让你链接到一个集合动态(共享)库,但随后针对同一库的早期版本运行相同的代码。 您可以根据 NULL 检查函数,以查看代码当前运行的特定动态库是否支持它们。 这似乎是Xcode支持的基本开发模型的一部分。 我希望这个例子有用; 它让我对 Xcode 设计的这一部分感到放心。
I just looked into this and thought some others might be interested in my findings.
Weak linking with weak_import really only works well with dynamic libraries. You can get it to work with static linking (by specifying -undefined dynamic_lookup as suggested above) but this isn't such a hot idea. It means that no undefined symbols will be detected until runtime. This is something I would avoid in production code, personally.
Here is a Mac OS X Terminal session showing how to make it work:
Here is f.c
Here is whatnof.c
Make a dynamic library from f.c:
Compile and link against the dynamic lib, list dynamic libs.
Run whatnof to see what happens:
Now replace f.dylib with an empty library (no symbols):
Run same whatnof to see what happens:
The basic idea (or "use case") for weak_import is that it lets you link against a set of dynamic (shared) libraries, but then run the same code against earlier versions of the same libraries. You can check functions against NULL to see if they're supported in the particular dynamic library that the code is currently running against. This seems to be part of the basic development model supported by Xcode. I hope this example is useful; it has helped put my mind at ease about this part of the Xcode design.
将
-Wl,-flat_namespace,-undefined,dynamic_lookup
添加到用于执行最终链接的 gcc 编译器行。Add
-Wl,-flat_namespace,-undefined,dynamic_lookup
to the gcc compiler line that you use to do the final link.最小可运行 Linux 示例
main.c
notmain.c
使用两个对象编译并运行:
输出:
不使用
notmain.o
编译并运行:输出:
GitHub 上游。
因此我们看到,如果在
notmain.o
上给出,那么非弱符号将按预期优先。我们可以分析 ELF 目标文件 符号:
给出:
然后:
包含:
但是,如果处理
.a
静态库,您可能必须使用-Wl,--whole-archive
,如下所述:如何使 gcc 链接静态库中的强符号来覆盖弱符号?弱符号也可以保留未定义,这在 Binutils 中会导致“平台特定行为”,请参阅:未解决的弱函数的 GCC 行为
在 Ubuntu 18.10、GCC 8.2.0 上测试。
Minimal runnable Linux example
main.c
notmain.c
Compile and run with both objects:
Output:
Compile and run without
notmain.o
:Output:
GitHub upstream.
So we see that if given on
notmain.o
, then the non-weak symbol takes precedence as expected.We can analyze the ELF object file symbols with:
which gives:
and then:
contains:
If dealing with
.a
static libraries however, you might have to use-Wl,--whole-archive
as explained at: How to make gcc link strong symbol in static library to overwrite weak symbol?Weak symbols can also be left undefined, which in Binutils leads to "platform specific behaviour", see: GCC behavior for unresolved weak functions
Tested on Ubuntu 18.10, GCC 8.2.0.
您需要将 MACOSX_DEPLOYMENT_TARGET 变量设置为 10.2 或更高版本。 请参阅 Apple 文档 及其 关于弱链接的技术说明。
You need to set the MACOSX_DEPLOYMENT_TARGET variable to 10.2 or later. See Apple's documentation and their technote on weak linking.
来自 gcc 文档手册:
弱
这意味着对象可以合法地覆盖弱符号(在另一个对象/库中定义),而不会在链接时出现错误。 不清楚的是您是否将库与弱符号链接。 看来您还没有定义符号并且库没有正确链接。
From the gcc doc manual:
weak
which means that an object is legitimated to overwrite a weak symbol (defined in another object/library) without getting errors at link time. What is unclear is whether you are linking the library with the weak symbol or not. It's seems that both you have not defined the symbol and the library is not properly linked.