python擴展模塊交叉編譯

搞個啥

這篇主要是最近在工作上,需要在板子上跑python,有一些擴展比較麻煩,比方說spidev啥的,單純的使用

		pip install spidev	

是不行的,這個會報錯。如下:

	Looking in indexes: http://mirrors.aliyun.com/pypi/simple/
Collecting spidev
  Downloading http://mirrors.aliyun.com/pypi/packages/fb/14/4c2e1640f0cb04862c76d9d76ed7c945b0f67876e503ac02f7f675fe86a0/spidev-3.4.tar.gz
Installing collected packages: spidev
  Running setup.py install for spidev ... error
    ERROR: Complete output from command /usr/bin/python -u -c 'import setuptools, tokenize;__file__='"'"'/var/volatile/tmp/pip-install-JQUClU/spidev/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /var/volatile/tmp/pip-record-OgQGW6/install-record.txt --single-version-externally-managed --compile:
    ERROR: running install
    running build
    running build_ext
    building 'spidev' extension
    creating build
    creating build/temp.linux-armv7l-2.7
    arm-poky-linux-gnueabi-gcc -march=armv7ve -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7 -fno-strict-aliasing -O2 -pipe -g -feliminate-unused-debug-types -fdebug-prefix-map=/home/zhuanghj/Downloads/yocto/fsl-release-bsp/build/tmp/work/cortexa7hf-neon-poky-linux-gnueabi/python/2.7.11-r1=/usr/src/debug/python/2.7.11-r1 -fdebug-prefix-map=/home/zhuanghj/Downloads/yocto/fsl-release-bsp/build/tmp/sysroots/x86_64-linux= -fdebug-prefix-map=/home/zhuanghj/Downloads/yocto/fsl-release-bsp/build/tmp/sysroots/imx6ulevk= -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c spidev_module.c -o build/temp.linux-armv7l-2.7/spidev_module.o
    unable to execute 'arm-poky-linux-gnueabi-gcc': No such file or directory
    error: command 'arm-poky-linux-gnueabi-gcc' failed with exit status 1
    ----------------------------------------
ERROR: Command "/usr/bin/python -u -c 'import setuptools, tokenize;__file__='"'"'/var/volatile/tmp/pip-install-JQUClU/spidev/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /var/volatile/tmp/pip-record-OgQGW6/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /var/volatile/tmp/pip-install-JQUClU/spidev/

這就有點蛋疼了。
主要問題是在板子上沒有交叉編譯器,但是有一些C的文件需要編譯成庫供調用(性能原因??)。但是這樣的話就比較麻煩。要麼就是找一個for arm的編譯器(我自己是在 arm上使用的)。後來又找到了一個方案:把python擴展編譯爲egg。然後再放到板子上進行安裝。

編譯成egg怎麼搞。。。
以下以spidev3.0.4爲例:

zhuanghj@ubuntu:~/Downloads/spidev-3.4$ ls
CHANGELOG.md  PKG-INFO  README.md  setup.cfg  setup.py  spidev_module.c

按照網上一些直接運行

python setup.py bdist_egg

會出現報錯。

python setup.py bdist_egg
usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
   or: setup.py --help [cmd1 cmd2 ...]
   or: setup.py --help-commands
   or: setup.py cmd --help

找了一會兒,然後發現需要在setpu.py文件中加入一行

from setuptools import setup, find_packages

而且需要放在

from distutils.core import setup, Extension

上面否則會出現報錯。

error: each element of 'ext_modules' option must be an Extension instance or 2-tuple

完成這一步之後,我們就可以進行編譯了,但是我們是要編譯給arm平臺。所以要設置一些東西
大致是一些arch CC CXX之類的一些東西。在此不進行敘述。
然後運行:

python setup.py bdist_egg

還是出現報錯:

/usr/include/python2.7/pyconfig.h:24:12: fatal error: arm-linux-gnueabihf/python2.7/pyconfig.h: No such file or directory
 #  include <arm-linux-gnueabihf/python2.7/pyconfig.h>

缺少python頭文件。那就添加

export CFLAGS="-I/home/zhuanghj/Downloads/yocto/fsl-release-bsp/build/tmp/sysroots/imx6ulevk/usr/include/python2.7 $CFLAGS"

還是報錯:

x86_64-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -D_FORTIFY_SOURCE=2 -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -I/home/zhuanghj/Downloads/yocto/fsl-release-bsp/build/tmp/sysroots/imx6ulevk/usr/include/python2.7 -O2 -pipe -g -feliminate-unused-debug-types build/temp.linux-x86_64-2.7/spidev_module.o -o build/lib.linux-x86_64-2.7/spidev.so
/usr/bin/ld: build/temp.linux-x86_64-2.7/spidev_module.o: Relocations in generic ELF (EM: 40)
/usr/bin/ld: build/temp.linux-x86_64-2.7/spidev_module.o: Relocations in generic ELF (EM: 40)
/usr/bin/ld: build/temp.linux-x86_64-2.7/spidev_module.o: Relocations in generic ELF (EM: 40)
/usr/bin/ld: build/temp.linux-x86_64-2.7/spidev_module.o: Relocations in generic ELF (EM: 40)
/usr/bin/ld: build/temp.linux-x86_64-2.7/spidev_module.o: Relocations in generic ELF (EM: 40)
/usr/bin/ld: build/temp.linux-x86_64-2.7/spidev_module.o: Relocations in generic ELF (EM: 40)
build/temp.linux-x86_64-2.7/spidev_module.o: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status
error: command 'x86_64-linux-gnu-gcc' failed with exit status 1

不知道爲什麼沒有調用已經指定了的交叉編譯器的ld。
但是最終我還是通過手動編譯編譯出了spidev.so
然後在進行

python setup.py bdist_egg

編譯通過。

running bdist_egg
running egg_info
writing spidev.egg-info/PKG-INFO
writing top-level names to spidev.egg-info/top_level.txt
writing dependency_links to spidev.egg-info/dependency_links.txt
reading manifest file 'spidev.egg-info/SOURCES.txt'
writing manifest file 'spidev.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-x86_64/egg
running install_lib
running build_ext
creating build/bdist.linux-x86_64
creating build/bdist.linux-x86_64/egg
copying build/lib.linux-x86_64-2.7/spidev.so -> build/bdist.linux-x86_64/egg
creating stub loader for spidev.so
byte-compiling build/bdist.linux-x86_64/egg/spidev.py to spidev.pyc
creating build/bdist.linux-x86_64/egg/EGG-INFO
copying spidev.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO
copying spidev.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying spidev.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying spidev.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
writing build/bdist.linux-x86_64/egg/EGG-INFO/native_libs.txt
zip_safe flag not set; analyzing archive contents...
creating 'dist/spidev-3.4-py2.7-linux-x86_64.egg' and adding 'build/bdist.linux-x86_64/egg' to it
removing 'build/bdist.linux-x86_64/egg' (and everything under it)

還是有點偷懶,應該把ARCH從x86_64改過來的,但是文件已經編譯出來了,我也就沒有管了。
下次如果有比較複雜的擴展可以試試修改。

到這裏就結束。謝謝看完。如果有更好的方法或者有什麼問題,歡迎評論,謝謝。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章