【问题标题】:Using cython to cross compile project from intel ubuntu to arm使用 cython 将项目从 intel ubuntu 交叉编译到 arm
【发布时间】:2016-11-18 05:35:49
【问题描述】:

我的 ubuntu 16 x86_64 上有简单的 python + cython 项目(来自http://docs.cython.org/src/tutorial/cython_tutorial.html 的hello world 示例)。我可以用 cython for x86_64 构建这个项目。

如何在不使用真正的 armv7 板/cpu 的情况下为 ubuntu 15 的 armv7 版本构建项目?

我有arm-linux-gnueabihf-gcc (http://packages.ubuntu.com/xenial/devel/gcc-arm-linux-gnueabihf),它可以为 armv7 编译简单的 C 程序。如何更改 cython 的设置以使用交叉编译器为 arm 构建共享对象?

【问题讨论】:

标签: python gcc cross-compiling cython


【解决方案1】:

交叉编译需要依赖架构的库和头文件。

在测试dpkg --add-architecture armhfapt-get update后是否可以安装python3.5-dev包等(对sources.list进行一些修改后),结果基本是这样。

python3.5-dev:armhf : Depends: python3.5:armhf (= 3.5.1-10) but it is not going to be installed

apt-get install python3.5:armhf 是行不通的,see

现有提案允许同时安装库和 不同架构的标头,但(还)不是二进制文件。

QEMU 和 chroot 提供了一种不需要“完整”虚拟机的可能解决方案。可以通过debootstrap 命令为chroot 创建一个合适的目录。创建后,schroot 可以授予对该环境的访问权限。

在以下命令中替换 <DIRECTORY><USER>

apt-get install -y debootstrap qemu-user-static binfmt-support schroot
debootstrap --arch=armhf --foreign --include=gcc,g++,python3.5-dev xenial <DIRECTORY>
cp /usr/bin/qemu-arm-static <DIRECTORY>/usr/bin
chroot <DIRECTORY>
/debootstrap/debootstrap --second-stage
echo "deb http://ports.ubuntu.com/ubuntu-ports xenial universe" >> /etc/apt/sources.list
echo "deb http://ports.ubuntu.com/ubuntu-ports xenial multiverse" >> /etc/apt/sources.list
apt-get update
apt-get install -y cython cython3
exit
cat <<END > /etc/schroot/chroot.d/xenial-armhf
[xenial-armhf]
description=Ubuntu xenial armhf
type=directory
directory=/home/xenial-armhf
groups=sbuild,root
root-groups=sbuild,root
users=root,<USER>
END

环境应该是可以访问的

schroot -c chroot:xenial-armhf

对于 root 用户会话(用户必须在 root-groups 中列出的组中),

schroot -c chroot:xenial-armhf -u root

在此之后,也可以交叉编译一个cython模块:

你好.pyx:

print("hello world")

编译(python3.5-config --cflagspython3.5-config --libs 在 chroot 中作为选项,注意 -fPIC):

cython hello.pyx
arm-linux-gnueabihf-gcc --sysroot <DIRECTORY> -I/usr/include/python3.5m -I/usr/include/python3.5m  -Wno-unused-result -Wsign-compare -g -fstack-protector-strong -Wformat -Werror=format-security  -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -c hello.c
arm-linux-gnueabihf-gcc --shared --sysroot <DIRECTORY> -lpython3.5m -lpthread -ldl  -lutil -lm hello.o -o hello.so

然后可以测试模块

schroot -c chroot:xenial-armhf
python3
import hello

交叉编译基于 cython 的 python 模块也可以工作。使用 setup.py

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

import os

os.environ['CC'] = 'arm-linux-gnueabihf-gcc'
os.environ['LDSHARED'] = 'arm-linux-gnueabihf-gcc -shared'
sysroot_args=['--sysroot', '/path/to/xenial-armhf']

setup(cmdclass = {'build_ext': build_ext},
      ext_modules= [ Extension("hello", ["hello.pyx"],
                                extra_compile_args=sysroot_args,
                                extra_link_args=sysroot_args) ])

通过这种方式可以构建一个简单的hello world 模块。模块的文件名错误,在本例中为hello.cpython-35m-x86_64-linux-gnu.so。重命名为hello.so 后就可以导入了。

【讨论】:

  • 我可以将需要的 armhf deb 包解压缩到子目录中,并且仍然使用非模拟(由本机 cpu 直接执行)编译器来输出 armhf 二进制文件吗?我的真实项目比 hello world 大一点,它有几兆字节的“c”代码和很多 c++ 头文件;模拟编译器会运行很长时间。
  • @osgx 我希望这可以解释schroot 命令
  • @osgx 是的,使用 qemu 编译 C/C++ 代码会慢很多。使用debootstrap 构建的环境也应该可用于C/C++ 交叉编译器(通过调整库/包含文件路径),并且可以在chroot 之后使用apt-get install 安装额外的开发包。对于像python setup.py build 这样构建的python 软件,qemu/chroot 解决方案应该工作得更好。基于 Cython 的模块通常是这样构建的,所以我相应地写了我的答案
  • python setup.py build 通常会为主机构建。如何指示跨系统构建?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-05
  • 1970-01-01
  • 2015-03-28
相关资源
最近更新 更多