经验丰富的问题??显然来自链接器(gcc在引擎盖下启动了一个链接器,看到它 – 只需用详细模式启动带有-v的gcc).那么让我们先简要提醒链接过程如何工作:
链接器保留其需要解析的所有符号的名称.在开始时它只是符号main.当链接器检查库时会发生什么?
>如果它是一个静态库,链接器将查看此库中的每个目标文件,如果此目标文件定义了一些查找符号,则包含整个目标文件(这意味着某些符号将被解析,但还有一些新的未解析符号)可以添加).链接器可能需要在静态库上多次传递.
>如果它是共享库,链接器将其视为由单个巨大目标文件组成的库(毕竟,我们必须在运行时加载此库,而不必多次传递和修剪未使用的符号):如果至少有一个需要的符号,整个库是“链接的”(并非真正的链接在运行时发生,这是一种干运行),如果不是 – 整个库被丢弃,再也没有看过.
例如,如果您链??接:
python可执行程序、gcc -L/path -lpython3.x foo.o
无论python3.x是共享库还是静态库,你都会遇到问题:当链接器看到它时,它只查找符号main,但是这个符号没有在python-lib中定义,所以它是python -lib被丢弃,再也没有看过了.只有当链接器看到对象文件foo.o时,才意识到需要整个Python-Symbols,但现在已经太晚了.
有一个简单的规则来处理这个问题:首先放置目标文件!这意味着:
gcc -L/path foo.o -lpython3.x
现在,链接器在第一次看到python-lib时就会知道它需要什么.
还有其他方法可以实现类似的结果.
python类方法和静态方法、A)只要每次扫描添加至少一个新符号定义,就让链接器重复一组归档:
gcc -L/path --Wl,-start-group -lpython3.x foo.o -Wl,-end-group
链接器选项-Wl,-start-group和-Wl,-end-group表示链接器在这组归档上不止一次迭代,因此链接器有第二次机会(或更多)包含符号.此选项可能会导致更长的链接时间.
B)启用选项–no-as-needed将导致链接的共享库(并且只有共享库),无论在此库中是否需要定义符号.
gcc -L/path -Wl,-no-as-needed -lpython3.x -Wl,-as-needed foo.o
实际上,默认的ld-behavior是–no-as-needed,但是gcc-frontend使用选项–as-needed调用ld,所以我们可以通过在python之前添加-no-as-needed来恢复行为 – 库然后再将其关闭.
python重写类方法和静态方法?现在你的静态链接问题.我不认为使用所有标准库的静态版本(以上都是glibc)是不可取的,你应该做的就是静态链接python-library.
链接的规则很简单:默认情况下,链接器首先尝试打开库的共享版本而不是静态版本.即对于库libmylib和路径A和B,即
-L/A -L/B lmylib
它尝试按以下顺序打开库:
A/libmylib.so
A/libmylib.a
python用什么编译器。B/libmylib.so
B/libmylib.a
因此,如果文件夹A只有静态版本,则使用此静态版本(无论文件夹B中是否存在共享版本).
因为实际上使用了库是非常不透明的 – 它取决于系统的设置,通常会通过-Wl打开链接器的记录,-verbose来进行故障排除.
通过使用-Bstatic选项,可以强制使用库的静态版本:
gcc foo.o -L/path -Wl,-Bstatic -lpython3.x -Wl,-Bdynamic -Wl,-verbose -o foo
python代码编译。值得注意的事:
> foo.o在库之前链接.
>在python-library之后直接关闭静态模式,以便动态链接其他库.
现在:
gcc L/paths foo.c -Wl,-Bstatic -lpython3.X -Wl,-Bdynamic -o foo -Wl,-verbose
...
python静态变量、attempt to open path/libpython3.6m.a succeeded
...
ldd foo shows no dependency on python-lib
./foo
It works!
是的,如果您链??接静态glibc(我不建议),您将需要从命令行删除-Xlinker -export-dynamic.
python编译环境?在没有-Xlinker -export-dynamic的情况下编译的可执行文件将无法加载某些c-extension,这些扩展依赖于使用ldopen加载它们的可执行文件的这个属性.
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态