我有一个纯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)
现在,我尝试向gcc添加选项-static
,但结果出现错误:
/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给出的选项不兼容引起的呢?
-export-dynamic
看起来像一个嫌疑犯吗? - chrisb/usr/bin/ld: unrecognized option '-Wl,-O1'
。gcc将不再识别“-Wl”选项。然而,如果没有这些选项,我会得到“文件格式不被识别”的错误。 - phlegmax-Xlinker -export-dynamic
是一个标志 - (XLinker将该标志转发给链接器)。尝试整体删除它? - chrisbfoo.o
应该在静态链接库之前。 - eadgcc $(python3-config --cflags) $(python3-config --ldflags) -static ./foo.c
。 - phlegmax