编译Python代码以使用Cython静态链接可执行文件
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了编译Python代码以使用Cython静态链接可执行文件,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4801字,纯文字阅读大概需要7分钟。
内容图文
![编译Python代码以使用Cython静态链接可执行文件](/upload/InfoBanner/zyjiaocheng/705/57ba0b7d3bd54828b70ba077700e4bf8.jpg)
我有一个纯Python脚本,我想分发给具有未知Python配置的系统.因此,我想将Python代码编译为独立的可执行文件.
我运行cython –embed ./foo.py而没有问题给foo.c.然后,我跑了
gcc $(python3-config --cflags) $(python3-config --ldflags) ./foo.c
python3-config –cflags给出的位置
-I/usr/include/python3.5m -I/usr/include/python3.5m -Wno-unused-result -Wsign-compare -g -fdebug-prefix-map=/build/python3.5-MLq5fN/python3.5-3.5.3=. -fstack-protector-strong -Wformat -Werror=format-security -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes
和python3-config –ldflags给出
-L/usr/lib/python3.5/config-3.5m-x86_64-linux-gnu -L/usr/lib -lpython3.5m -lpthread -ldl -lutil -lm -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions
这样我就可以获得一个没有问题的动态链接可执行文件. ldd a.out收益率
linux-vdso.so.1 (0x00007ffcd57fd000)
libpython3.5m.so.1.0 => /usr/lib/x86_64-linux-gnu/libpython3.5m.so.1.0 (0x00007fda76823000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fda76603000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fda763fb000)
libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007fda761f3000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fda75eeb000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fda75b4b000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007fda7591b000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fda756fb000)
/lib64/ld-linux-x86-64.so.2 (0x00007fda77103000)
现在,我尝试将选项-static添加到gcc,但这会导致错误:
/usr/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie
collect2: error: ld returned 1 exit status
我检查了ldd给出的所有共享库也作为静态库安装.
那么,这与python3-config给出的选项有些不兼容吗?
解决方法:
经验丰富的问题??显然来自链接器(gcc在引擎盖下启动了一个链接器,看到它 – 只需用详细模式启动带有-v的gcc).那么让我们先简要提醒链接过程如何工作:
链接器保留其需要解析的所有符号的名称.在开始时它只是符号main.当链接器检查库时会发生什么?
>如果它是一个静态库,链接器将查看此库中的每个目标文件,如果此目标文件定义了一些查找符号,则包含整个目标文件(这意味着某些符号将被解析,但还有一些新的未解析符号)可以添加).链接器可能需要在静态库上多次传递.
>如果它是共享库,链接器将其视为由单个巨大目标文件组成的库(毕竟,我们必须在运行时加载此库,而不必多次传递和修剪未使用的符号):如果至少有一个需要的符号,整个库是“链接的”(并非真正的链接在运行时发生,这是一种干运行),如果不是 – 整个库被丢弃,再也没有看过.
例如,如果您链??接:
gcc -L/path -lpython3.x <other libs> foo.o
无论python3.x是共享库还是静态库,你都会遇到问题:当链接器看到它时,它只查找符号main,但是这个符号没有在python-lib中定义,所以它是python -lib被丢弃,再也没有看过了.只有当链接器看到对象文件foo.o时,才意识到需要整个Python-Symbols,但现在已经太晚了.
有一个简单的规则来处理这个问题:首先放置目标文件!这意味着:
gcc -L/path foo.o -lpython3.x <other libs>
现在,链接器在第一次看到python-lib时就会知道它需要什么.
还有其他方法可以实现类似的结果.
A)只要每次扫描添加至少一个新符号定义,就让链接器重复一组归档:
gcc -L/path --Wl,-start-group -lpython3.x <other libs> 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 <other libs> foo.o
实际上,默认的ld-behavior是–no-as-needed,但是gcc-frontend使用选项–as-needed调用ld,所以我们可以通过在python之前添加-no-as-needed来恢复行为 – 库然后再将其关闭.
现在你的静态链接问题.我不认为使用所有标准库的静态版本(以上都是glibc)是不可取的,你应该做的就是静态链接python-library.
链接的规则很简单:默认情况下,链接器首先尝试打开库的共享版本而不是静态版本.即对于库libmylib和路径A和B,即
-L/A -L/B lmylib
它尝试按以下顺序打开库:
A/libmylib.so
A/libmylib.a
B/libmylib.so
B/libmylib.a
因此,如果文件夹A只有静态版本,则使用此静态版本(无论文件夹B中是否存在共享版本).
因为实际上使用了库是非常不透明的 – 它取决于系统的设置,通常会通过-Wl打开链接器的记录,-verbose来进行故障排除.
通过使用-Bstatic选项,可以强制使用库的静态版本:
gcc foo.o -L/path -Wl,-Bstatic -lpython3.x -Wl,-Bdynamic <other libs> -Wl,-verbose -o foo
值得注意的事:
> foo.o在库之前链接.
>在python-library之后直接关闭静态模式,以便动态链接其他库.
现在:
gcc <cflags> L/paths foo.c -Wl,-Bstatic -lpython3.X -Wl,-Bdynamic <other libs> -o foo -Wl,-verbose
...
attempt to open path/libpython3.6m.a succeeded
...
ldd foo shows no dependency on python-lib
./foo
It works!
是的,如果您链??接静态glibc(我不建议),您将需要从命令行删除-Xlinker -export-dynamic.
在没有-Xlinker -export-dynamic的情况下编译的可执行文件将无法加载某些c-extension,这些扩展依赖于使用ldopen加载它们的可执行文件的这个属性.
内容总结
以上是互联网集市为您收集整理的编译Python代码以使用Cython静态链接可执行文件全部内容,希望文章能够帮你解决编译Python代码以使用Cython静态链接可执行文件所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。