Compile Python code for a statically linked executable with Cython

I have a pure Python script that I would like to distribute on systems with an unconfirmed Python configuration. Therefore, I would like to compile Python code into a standalone executable.

I run cython --embed ./foo.pywithout problems by providing foo.c. Then i run

gcc $(python3-config --cflags) $(python3-config --ldflags) ./foo.c

where python3-config --cflagsgives

-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

and python3-config --ldflagsgives

-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

This way I get a dynamically linked executable that works without problems. ldd a.outgives

 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)

Now I am trying to add a parameter -staticto gcc, but this leads to an error:

/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

I have verified that all shared libraries provided by ldd are also installed as static libraries.

So, is this some kind of incompatibility with the parameters given by python3-config?

+4
1

, , (gcc , - gcc -v - ). , :

, . main. , ?

  • , , , , ( , , ). , .

  • , , ( , , ). , "" ( , ), - .

, :

gcc -L/path -lpython3.x <other libs> foo.o 

, , python3.x lib: , main, python-lib, python-lib . foo.o, , Python-, .

: ! :

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- - --no-as-needed, gcc-frontend ld --as-needed, , -no-as-needed python .


. , ( glibc), , , , python- .

: , . 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, .

:

 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!

, static glibc ( ), -Xlinker -export-dynamic .

-Xlinker -export-dynamic c-, , ldopen.

+3

Source: https://habr.com/ru/post/1693657/


All Articles