使用gcc从静态链接的文件中查找可选符号
Find an optional symbol from statically linked file with gcc?
我想支持一些加速的AVX/SSE功能,但我希望能够选择性地包含它。我可以将dlsym((与共享对象一起使用,但为了更便携的二进制文件,我尽可能避免共享链接。
如果静态符号成功地链接进来,我是否可以使用一种机制来使用它,否则就回到泛型函数?
您可以使用弱符号,标记为__attribute__ ((weak))
,声明如下:
void avx_function (void) __attribute__ ((weak));
然后在调用函数之前检查NULL
if (avx_function != NULL)
avx_function ();
else
fallback_implementation ();
但这并不适用于替代实现,只适用于通过其他方式链接的可选功能:您需要一种机制来实际引入avx_function
,因为弱符号无法做到这一点。
但编译时或链接时功能选择不会让您获得可移植二进制文件。如果您需要可移植的二进制文件,您可能会更好地使用运行时检查和通过函数指针的间接操作(用于复杂的功能选择(。
如果理解正确,您有一些链接,例如:
gcc -o prog main.o ...
其中调用了一些avx_func
,并且您希望它是这样的如果CCD_ 5不静态链接CCD_ 6的真实定义,则它将静态链接通用代理。
如果这是正确的,您可以简单地利用链接器将解析的事实它在链接序列中找到的第一个定义的符号,并且不会链接任何其他定义,除非它被强制(在这种情况下是多重定义错误是通常的结果(。因此,例如
main.cpp
extern void avx_func();
int main()
{
avx_func();
return 0;
}
avx_or_not.cpp
#ifdef HAVE_REAL_AVX
#include <iostream>
void avx_func()
{
std::cout << "The real " << __PRETTY_FUNCTION__ << std::endl;
}
#endif
avx_fallback.cpp
#include <iostream>
void avx_func()
{
std::cout << "The fallback " << __PRETTY_FUNCTION__ << std::endl;
}
制作静态库libavxfallback.a
:
$ g++ -Wall -Wextra -c avx_fallback.cpp
$ ar rcs libavxfallback.a avx_fallback.o
编译另一个源,假设真实的AVX:
$ g++ -Wall -Wextra -DHAVE_REAL_AVX -c avx_or_not.cpp main.cpp
链接程序:
$ g++ -o prog main.o avx_or_not.o -L. -lavxfallback
运行:
$ ./prog
The real void avx_func()
再次编译另一个源,这次假设没有真正的AVX:
$ g++ -Wall -Wextra -c avx_or_not.cpp main.cpp
重新链接并重新运行:
$ g++ -o prog main.o avx_or_not.o -L. -lavxfallback
$ ./prog
The fallback void avx_func()
在链接时,您不需要知道调用avx_func()
或定义avx_func()
的-lavxfallback
之前的链接:您仍然知道,如果调用它,链接中的第一个定义将被链接,如果没有更早的,它将是libavxfallback
中的那个。
- 使用gcc从静态链接的文件中查找可选符号
- 与Qt交叉编译到Raspberry Pi 3B+通讯录(协议缓冲区)-错误符号查找错误
- 符号查找错误未定义的符号:curl_mime_init
- 即使存在NM报告符号,在运行时的符号查找错误也是如此
- 使用 dlsym 查找命名空间中符号的符号
- 指向符号的指针与常规符号查找的 ABI 稳定性
- Orocos LTTng 符号查找错误:/path/to/liborocos-rtt-traces-gnulinux.s
- caffe convert_imageset:符号查找错误
- 建筑x86_64的未定义符号 - 如何查找丢失的文件
- 动态链接到 c++ 静态成员字段时符号查找失败
- 部署后的Linux qt应用程序-符号查找错误:libQt5Core.so.5未定义的符号:uncv_getDefaul
- 查找最大的无符号 int ....为什么这不起作用?
- 访问Boost Bind时,共享库中的C 符号查找错误
- C 需要从数组中查找符号
- 查找符号时,程序不会从正确的库中搜索
- LD_BIND_NOW:符号查找错误,但可执行文件仍在运行
- 如何捕捉符号查找错误
- 查找符号链接指向的位置(Windows)
- GCC—gc-sections和查找符号依赖项
- 查找符号相关性的起源