Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

python binding cannot be cross-compiled #16

Open
uhoreg opened this issue Jan 18, 2019 · 5 comments
Open

python binding cannot be cross-compiled #16

uhoreg opened this issue Jan 18, 2019 · 5 comments

Comments

@uhoreg
Copy link
Member

uhoreg commented Jan 18, 2019

Received this report from Nathan O.:

Update, seem cffi causes issues when cross-compiling for a different
arch, as it wants to use host's LD instead of target's even though I
am telling it to use target's

@jonnius
Copy link

jonnius commented Apr 19, 2020

I am failing to cross-compile pantalaimon, due to an issue with cross-compiling python-olm. Is this the same or should I open a new issue?

@poljar
Copy link

poljar commented Apr 22, 2020

This seems to be a peculiarity of CFFI, other people seem to have solved this by installing the target CFFI besides the host one.

Trying to do this myself I experienced the same isssue

DEVELOP=1 CC=aarch64-linux-gnu-gcc CFLAGS="-march=armv8-a" python olm_build.py
mkdir -p include/olm
aarch64-linux-gnu-gcc -E -I dummy -I ../include ../include/olm/olm.h -o include/olm/olm.h
echo 'void *memset(void *s, int c, size_t n);' >> include/olm/olm.h
aarch64-linux-gnu-gcc -E -I dummy -I ../include ../include/olm/pk.h -o include/olm/pk.h
aarch64-linux-gnu-gcc -E -I dummy -I ../include ../include/olm/sas.h -o include/olm/sas.h
generating ./_libolm.c
the current directory is '/home/poljar/werk/misc/olm/python'
running build_ext
building '_libolm' extension
aarch64-linux-gnu-gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fno-semantic-interposition -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -march=armv8-a -fPIC -I/usr/include/python3.8 -c _libolm.c -o ./_libolm.o -I../include
gcc -pthread -shared -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fno-semantic-interposition -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -march=armv8-a ./_libolm.o -L/usr/lib -lolm -o ./_libolm.cpython-38-x86_64-linux-gnu.so -L../build -Wl,-rpath=../build
/usr/bin/ld: ./_libolm.o: Relocations in generic ELF (EM: 183)
/usr/bin/ld: ./_libolm.o: Relocations in generic ELF (EM: 183)
/usr/bin/ld: ./_libolm.o: Relocations in generic ELF (EM: 183)
/usr/bin/ld: ./_libolm.o: Relocations in generic ELF (EM: 183)
/usr/bin/ld: ./_libolm.o: Relocations in generic ELF (EM: 183)
/usr/bin/ld: ./_libolm.o: Relocations in generic ELF (EM: 183)
/usr/bin/ld: ./_libolm.o: Relocations in generic ELF (EM: 183)
/usr/bin/ld: ./_libolm.o: error adding symbols: file in wrong format
collect2: error: ld returned 1 exit status

We can see that it first invokes the correct gcc with aarch64-linux-gnu-gcc, it compiles the module fine but the linking step uses the default host gcc.

It also leaves a bunch of -march flags setting the arch to x86_64

The build creates a single C file that needs to be compiled so running the compile and link step manually is another valid workaround.

To compile i ran this:

$ aarch64-linux-gnu-gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -mtune=generic -O3 -pipe -fno-plt -fno-semantic-interposition -mtune=generic -O3 -pipe -fno-plt -mtune=generic -O3 -pipe -fno-plt -march=armv8-a -fPIC -I/usr/include/python3.8 -c _libolm.c -o ./_libolm.o -I../include

This picks up the cross compiled libolm from the ../build dir.

Linking it worked with

$ aarch64-linux-gnu-gcc -pthread -shared -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fno-semantic-interposition -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -march=armv8-a ./_libolm.o -L/usr/lib -lolm -o ./_libolm.cpython-38-aarch64-linux-gnu.so -L../build -Wl,-rpath=../build

The resulting file

$ file _libolm.cpython-38-aarch64-linux-gnu.so 
_libolm.cpython-38-aarch64-linux-gnu.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), statically linked, BuildID[sha1]=2880cebb2fe27ffd56e449303f98061615944cda, with debug_info, not stripped

@jonnius
Copy link

jonnius commented Apr 24, 2020

Thanks for the useful hints. My issue was not with the linker but rather the cross-compiling itself.

What I am trying to do is to simply compile it via python3.7 -m pip install -t $TARGET_DIR python-olm (the ultimate goal is to build pantalaimon via python3.7 -m pip install -t $TARGET_DIR pantalaimon) in a cross-compiling-prepared docker container (provided by Clickable), which results in:

   Running setup.py install for python-olm: finished with status 'error'
    ERROR: Command errored out with exit status 1:
     command: /usr/bin/python3.7 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-2bi8y70r/python-olm/setup.py'"'"'; __file__='"'"'/tmp/pip-install-2bi8y70r/python-olm/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-r6bgi257/install-record.txt --single-version-externally-managed --home /tmp/pip-target-rka1p523 --compile --install-headers /tmp/pip-target-rka1p523/include/python/python-olm
         cwd: /tmp/pip-install-2bi8y70r/python-olm/
    Complete output (23 lines):
    WARNING: The wheel package is not available.
    WARNING: The wheel package is not available.
    make: *** No rule to make target '../include/olm/olm.h', needed by 'include/olm/olm.h'.  Stop.
    running install
    running build
    running build_py
    creating build
    creating build/lib.linux-x86_64-3.7
    creating build/lib.linux-x86_64-3.7/olm
    copying olm/_finalize.py -> build/lib.linux-x86_64-3.7/olm
    copying olm/_compat.py -> build/lib.linux-x86_64-3.7/olm
    copying olm/account.py -> build/lib.linux-x86_64-3.7/olm
    copying olm/pk.py -> build/lib.linux-x86_64-3.7/olm
    copying olm/__init__.py -> build/lib.linux-x86_64-3.7/olm
    copying olm/session.py -> build/lib.linux-x86_64-3.7/olm
    copying olm/group_session.py -> build/lib.linux-x86_64-3.7/olm
    copying olm/sas.py -> build/lib.linux-x86_64-3.7/olm
    copying olm/__version__.py -> build/lib.linux-x86_64-3.7/olm
    copying olm/utility.py -> build/lib.linux-x86_64-3.7/olm
    running build_ext
    generating cffi module 'build/temp.linux-x86_64-3.7/_libolm.c'
    creating build/temp.linux-x86_64-3.7
    error: don't know how to compile C/C++ code on platform 'posix' with 'aarch64-linux-gnu-gcc' compiler

I set the compiler to aarch64-linux-gnu-gcc in ~/.pydistutils.cfg.

Any chance I can get along with this approach or do I need to setup a build script that downloads python-olm sources and builds it as you suggested above?

@poljar
Copy link

poljar commented Apr 27, 2020

Not sure if pydistutils is supposed to work, did you try with overriding CC and CFLAGS, perhaps it just works™ if you have the target CFFI installed.

@jonnius
Copy link

jonnius commented May 8, 2020

I finally got it cross-compiled within the Clickable docker image building olm as a shared library and overriding some env vars like:

"CC": "${ARCH_TRIPLET}-gcc",
"CFLAGS": "-I${OLM_DIR}/include -I${OLM_DIR}/include",
"LDFLAGS": "-L${OLM_DIR}/lib/${ARCH_TRIPLET} -shared",
"LDSHARED": "${ARCH_TRIPLET}-gcc",
"LD": "${ARCH_TRIPLET}-gcc"

Thanks for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants