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

Cross compilation workflow #1330

Closed
photex opened this issue Mar 21, 2018 · 11 comments
Closed

Cross compilation workflow #1330

photex opened this issue Mar 21, 2018 · 11 comments

Comments

@photex
Copy link

photex commented Mar 21, 2018

Howdy!

Say I have a cross-compiled python setup and want to build against that. Currently pybind appears to be tightly coupled to the system python in it's cmake configuration.

How could this be approached? I'm happy to work on this and submit a PR.

My use case is building native modules for aarch64-linux-gnu in a relatively controlled environment.

@gocarlos
Copy link

gocarlos commented May 16, 2018

Related to #99

I’m cross compiling with yocto, this fails because the find package executes python to get the path, but the target system ist not available aka cmake executes python on the host..

@bstaletic
Copy link
Collaborator

A workaround would be to forget about Pybind11's cmake and just add the header directory in your own cmake (or whatever).

@garry-jeromson
Copy link

garry-jeromson commented Jan 10, 2019

Did you ever find a way to get this up and running? I'm in a similar situation: I'd like to build an extension for a 32-bit ARM target using as close to the standard CMake workflow as possible, but am running into issues because the system python is 64-bit.

@gocarlos
Copy link

gocarlos commented Jan 10, 2019

No, i did not, though did not invest much time on it.. right now im just using systemd and dbus to launch python scripts on the target board

@mdenna-nviso
Copy link

Hi, I also have the same issue, I'm cross compiling for ARM on an intel machine, and pybind11 finds the Python installation for the host, so of course the build fails:

CMake Error at deps-base/pkg-pybind11/src/tools/FindPythonLibsNew.cmake:125 (message):
  Python config failure: Python is 64-bit, chosen compiler is 32-bit
Call Stack (most recent call first):
  deps-base/pkg-pybind11/src/tools/pybind11Tools.cmake:16 (find_package)
  deps-base/pkg-pybind11/src/CMakeLists.txt:33 (include)

Any indication on how to direct pybind11 to the python installation for the target?

@garry-jeromson
Copy link

garry-jeromson commented Apr 21, 2019

I ended up just commenting out the bit-width check in FindPythonLibsNew.cmake (lines 121-131) - hacky, but the only solution I could find.

The order of inclusion of pybind11 and Python in CMake also has a few gotchas that need to be noted, see https://github.com/pybind/pybind11/blob/master/docs/faq.rst#user-content-inconsistent-detection-of-python-version-in-cmake-and-pybind11.

@mdenna-nviso
Copy link

Hi, thanks for the above hint about inclusion order!
Yes commentig out the check can work in some cases, but fails in others, as the target platform might have a different python version from the host or no python installation at all.

@romansavrulin
Copy link

On build machine you can work-around this by doing

dpkg --add-architecture i386
apt install -y python2.7:i386

You maybe need to remove amd64 package of python too.

But my full solution was building a docker image with necessary dev packages and tools to keep host machine clean. Assuming, following files are in the same directory, run build-docker.sh

Dockerfile

FROM ubuntu:18.04

RUN dpkg --add-architecture i386
RUN apt update.
RUN apt install -y debootstrap python2.7:i386 cmake make build-essential binutils-arm-linux-gnueabihf \
gcc-6-arm-linux-gnueabihf g++-6-arm-linux-gnueabihf debootstrap qemu-user-static

ENV SYSROOT=/sysroot
RUN mkdir ${SYSROOT}
RUN debootstrap --foreign --variant=minbase --arch=armhf stretch "${SYSROOT}" http://deb.debian.org/debian/
RUN cp /usr/bin/qemu-arm-static "${SYSROOT}"/usr/bin/ && cp /etc/resolv.conf "${SYSROOT}"/etc/
RUN apt-get clean

RUN mkdir /build
WORKDIR /build

Build docker image build-docker.sh

#!/bin/bash
set -e
SOURCE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $SOURCE_DIR/

docker run --privileged linuxkit/binfmt:v0.6

docker build -t image:latest .

docker run --privileged -it image:latest /bin/sh -c 'chroot /sysroot /debootstrap/debootstrap --second-stage'
docker commit `docker ps -l --format="{{.ID}}"` image:latest
docker run --privileged -it image:latest /bin/sh -c 'chroot /sysroot apt install \
--allow-unauthenticated -y libc6-dev libjsoncpp-dev libboost-filesystem-dev libboost-regex-dev \
libboost-python-dev libboost-thread-dev libboost-date-time-dev libboost-program-options-dev libssl-dev libz-dev && apt-get clean'
docker commit `docker ps -l --format="{{.ID}}"` image:latest

later-on you can use it with

docker run  -it --rm -v "$(pwd)":/build image:latest /bin/bash

and issue cmake/build from container's /build directory

knarfS added a commit to knarfS/pybind11 that referenced this issue Feb 8, 2020
This is needed when using linuxdeploy / appimagecraft to create an AppImage
and when cross compiling (f.e. with MXE) to find the python libraries.
You may need to set CMAKE_FIND_ROOT_PATH_MODE_LIBRARY to BOTH when cross
compiling.

This may fix issues pybind#1718, pybind#1159, pybind#1330 and pybind#99.
knarfS added a commit to knarfS/pybind11 that referenced this issue Apr 11, 2020
This is needed when using linuxdeploy / appimagecraft to create an AppImage
and when cross compiling (f.e. with MXE) to find the python libraries.
You may need to set CMAKE_FIND_ROOT_PATH_MODE_LIBRARY to BOTH when cross
compiling.

This may fix issues pybind#1718, pybind#1159, pybind#1330 and pybind#99.
knarfS added a commit to knarfS/pybind11 that referenced this issue Apr 20, 2020
This is needed when using linuxdeploy / appimagecraft to create an AppImage
and when cross compiling (f.e. with MXE) to find the python libraries.
You may need to set CMAKE_FIND_ROOT_PATH_MODE_LIBRARY to BOTH when cross
compiling.

This may fix issues pybind#1718, pybind#1159, pybind#1330 and pybind#99.
@mdenna-nviso
Copy link

At the end I've been able to generate a python wrapper with pybind11 also when cross compiling.
In cross compilation mode pybind11 needs the python include and libraries of the target installation, not the ones of the host. The point is that when cross-compiling one normally already have a root file system of the target with everything installed (at least this is my case) the point is how to direct pybind11 to this installation.

It turns out this can be done quite easily, no need to change pybind11 build system, I just added a couple of variables in my own cmake before including pybind11:

# Tell pybind11 where the target python installation is
set(PYTHON_INCLUDE_DIRS ${MY_TARGET_PYTHON_INCLUDE_DIRS} CACHE INTERNAL "Cross python include path")
set(PYTHON_MODULE_EXTENSION ".so" CACHE INTERNAL "Cross python lib extension")

# Disable pybind11 python search mechanism
set(PYTHONLIBS_FOUND TRUE CACHE INTERNAL "")

# include pybind11 cmake
add_subdirectory(pybind11)

@YannickJadoul
Copy link
Collaborator

At the end I've been able to generate a python wrapper with pybind11 also when cross compiling.

I'll interpret this as "issue resolved". Thanks for the write-up of your solution!

knarfS added a commit to knarfS/pybind11 that referenced this issue Aug 15, 2020
This is needed when using linuxdeploy / appimagecraft to create an AppImage
and when cross compiling (f.e. with MXE) to find the python libraries.
You may need to set CMAKE_FIND_ROOT_PATH_MODE_LIBRARY to BOTH when cross
compiling.

This may fix issues pybind#1718, pybind#1159, pybind#1330 and pybind#99.
@DhanushLingeswaran15
Copy link

At the end I've been able to generate a python wrapper with pybind11 also when cross compiling. In cross compilation mode pybind11 needs the python include and libraries of the target installation, not the ones of the host. The point is that when cross-compiling one normally already have a root file system of the target with everything installed (at least this is my case) the point is how to direct pybind11 to this installation.

It turns out this can be done quite easily, no need to change pybind11 build system, I just added a couple of variables in my own cmake before including pybind11:

# Tell pybind11 where the target python installation is
set(PYTHON_INCLUDE_DIRS ${MY_TARGET_PYTHON_INCLUDE_DIRS} CACHE INTERNAL "Cross python include path")
set(PYTHON_MODULE_EXTENSION ".so" CACHE INTERNAL "Cross python lib extension")

# Disable pybind11 python search mechanism
set(PYTHONLIBS_FOUND TRUE CACHE INTERNAL "")

# include pybind11 cmake
add_subdirectory(pybind11)

i tried this. now the pybind takes the correct python directory but still the architecture of the generated .so file is x86_64 (my host machine architecture). However i am trying to do a cross build for aarch64 architecture.
Any help would great.

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

8 participants