I\'m trying to compile an executable (ELF file) that does not use a dynamic loader.
I used Cython
to compile Python to C:
cython3 -3 test.py --embed
As you can see, all of the undefined references in your failed linkage
lie in linked object files that are members of libpython3.5m.a
, which
is the static version of the python3 library requested in your linkage
commandline by pkg-config --libs --cflags python3
.
To link a fully static executable (-static
) when the linkage
includes libpython3.5m.a
, the linker must also find static (*.a
) versions of all the
libraries that libpython3.5m.a
depends upon1. The dynamic
(*.so
) versions of all those dependencies are installed on your system.
That is why:
gcc test.c -otest $(pkg-config --libs --cflags python3)
succeeds, without -static
. The static versions of those dependencies are
not all installed on your system. Hence all the undefined reference
linkage errors when you add -static
.
My own system has python3.6, and I see:
$ pkg-config --libs python-3.6
-lpython3.6m
and:
$ locate libpython3.6m.so
/usr/lib/python3.6/config-3.6m-x86_64-linux-gnu/libpython3.6m.so
/usr/lib/x86_64-linux-gnu/libpython3.6m.so.1
/usr/lib/x86_64-linux-gnu/libpython3.6m.so.1.0
The dynamic dependencies of libpython3.6m.so
are:
$ ldd /usr/lib/python3.6/config-3.6m-x86_64-linux-gnu/libpython3.6m.so
linux-vdso.so.1 => (0x00007ffc475af000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007fa87cf6e000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fa87cd51000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa87cb32000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fa87c92e000)
libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007fa87c72a000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa87c3d4000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa87bff4000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa87d85a000)
We can disregard the first and last ones, which don't look like regular libraries
and indeed aren't2. So, I'd conclude that
to satisfy the static dependencies of libpython3.6a
, I need to install the
static versions of:-
libexpat
libz
libpthread
libdl
libutil
libm
libc
which will be provided by the dev packages of those libraries. Since my system is 64 bit Ubuntu, I'd then filter those dev packages by:
$ dpkg --search libexpat.a libz.a libpthread.a libdl.a libutil.a libm.a libc.a | grep amd64
libexpat1-dev:amd64: /usr/lib/x86_64-linux-gnu/libexpat.a
zlib1g-dev:amd64: /usr/lib/x86_64-linux-gnu/libz.a
libc6-dev:amd64: /usr/lib/x86_64-linux-gnu/libpthread.a
libc6-dev:amd64: /usr/lib/x86_64-linux-gnu/libdl.a
libc6-dev:amd64: /usr/lib/x86_64-linux-gnu/libutil.a
libc6-dev:amd64: /usr/lib/x86_64-linux-gnu/libm.a
libc6-dev:amd64: /usr/lib/x86_64-linux-gnu/libc.a
and install them with:
sudo apt install libexpat1-dev zlib1g-dev libc6-dev
You haven't disclosed what your system is, but no doubt you can adapt this
thinking to discover the static dependencies of libpython3.5m.a
, whatever
your system is.
libpython3.5m.a
that you are linking depend upon,
but we won't be that pernickity.
[2] The first one is the library's vDSO, not a real file at all. The second one is the linux loader.