benfogle / crossenv

Cross-compiling virtualenv for Python
MIT License
108 stars 22 forks source link

can't build matplotlib #69

Open paleozogt opened 3 years ago

paleozogt commented 3 years ago

I'm unable to build matplotlib with crossenv. A project that demonstrates the problem is here.

After compiling host and build python and setting up the crossenv venv, the demo does:

ADD requirements.txt /
RUN $CROSS_VENV/bin/build-pip install -r requirements.txt
RUN $CROSS_VENV/bin/cross-pip install -r requirements.txt

where requirements.txt is:

cython==0.29.23
numpy==1.19.5
matplotlib==3.3.3

The cross build falls down in matplotlib, seemingly due to cython. The error is very long, so I've attached it to this issue (here).

benfogle commented 3 years ago

Wow. Awesome job making a reproducible test case!

I think I know what's happening: numpy is a build dependency of matplotlib, and since it isn't installed when you call cross-pip install, pip attempts to download and install a copy local to the matplotlib source directory. The fact that you're trying to install it at the same time isn't considered. Unfortunately, it will cross-compile this version of numpy like all the rest, and crash when it can't run the aarch64 version on an x86-64 system. The file not found error is actually a cryptic result of that; the files do actually exist.

I don't have a good way to switch back to a native build for build dependencies, so your best bet is to install cython and numpy first, then matplotlib as a separate step. When I do that, matplotlib proceeds to a different error that seems to be caused by natively compiling FreeType and then attempting to link that in with the cross-compiled object files.

paleozogt commented 3 years ago

I had that same observation about numpy. I ended up working around the problem with:

RUN $CROSS_VENV/bin/build-pip install -r requirements.txt
RUN $CROSS_VENV/bin/cross-pip install $(grep numpy requirements.txt)
RUN $CROSS_VENV/bin/cross-pip install -r requirements.txt

But then like you saw, matplotlib falls down for a completely different reason:

aarch64-linux-gnu-g++ -shared build/temp.linux-aarch64-3.7/src/checkdep_freetype2.o build/temp.linux-aarch64-3.7/src/ft2font.o build/temp.linux-aarch64-3.7/src/ft2font_wrapper.o build/temp.linux-aarch64-3.7/src/mplutils.o build/temp.linux-aarch64-3.7/src/py_converters.o build/freetype-2.6.1/objs/.libs/libfreetype.a -o build/lib.linux-aarch64-3.7/matplotlib/ft2font.cpython-37m-aarch64-linux-gnu.so
lto1: error: unknown value ‘x86-64’ for -march
lto1: note: valid arguments are: armv8-a armv8.1-a armv8.2-a armv8.3-a armv8.4-a
lto-wrapper: fatal error: aarch64-linux-gnu-g++ returned 1 exit status
compilation terminated.
/usr/lib/gcc-cross/aarch64-linux-gnu/8/../../../../aarch64-linux-gnu/bin/ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status
error: command 'aarch64-linux-gnu-g++' failed with exit status 1

I was able to work around the link error by disabling LTO:

RUN $CROSS_VENV/bin/build-pip install -r requirements.txt
RUN $CROSS_VENV/bin/cross-pip install $(grep numpy requirements.txt)
RUN CFLAGS=-fno-lto CXXFLAGS=-fno-lto \
    $CROSS_VENV/bin/cross-pip install -r requirements.txt

I'd like to avoid the LTO hack, but I'm not sure where the bad -march is coming from.