Cython: Compile a Standalone Static Executable

前端 未结 1 821
醉话见心
醉话见心 2021-02-04 18:07

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         


        
相关标签:
1条回答
  • 2021-02-04 18:51

    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.


    [1] Strictly, all libraries that the members of 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.

    0 讨论(0)
提交回复
热议问题