您的位置:首页 > 编程语言 > Python开发

Python交叉编译和移植

2013-05-02 13:32 567 查看
参考:http://blog.csdn.net/AIXT2006/article/details/4229779

1、交叉编译之前要确定PC上安装对应版本的python

2、下载python http://www.python.org/ftp/python/2.7/Python-2.7.tar.bz2
3、解压 tar xjvf Python-2.7.tar.bz2

4、由于在编译python的时候,需要先编译一个叫pgen的程序出来,用于生成语法解析器,所以要先生成一个pc版本的pgen,而且还需要编译一个完整PC版本的python:

mkdir build.pc

cd build.pc

../configure

make

然后ls Parser一下,应该就能看到有pgen了,而且在当前目录生成了python。

cd .. 准备编译;

5、配置:

./configure --prefix=/home/pub/johnny/xbmc/python_install --host=mips-linux-gnu "CC=mips-linux-gnu-gcc -EL" "CFLAGS=-EL" "LDFLAGS=-EL" --enable-shared --disable-ipv6 --with-libc="-L/opt/ali_sdk/staging/lib -lc" "LIBS=-L/opt/ali_sdk/staging/lib"

6、修改setup.py

detect_modules函数:

函数的前两行是把/usr/local加到搜索目录中,我们的cross compiler一般不会直接安装在 /usr/local里面的,所以这两行去掉:

add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib')

add_dir_to_list(self.compiler.include_dirs, '/usr/local/include')

7、之后就要对Makefile做一些修改:

(1)把

# OPT= -DNDEBUG -g -O3 -Wall -Wstrict-prototypes

OPT= -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes

一行中,去掉-g,我们不要debug python,-O3改为-O2,空间紧张O2就可以了。

(2)在:

PGEN= Parser/pgen$(EXE)

一行的下面加上:

PGEN_HOST= build.pc/Parser/pgen$(EXE)

表明我们在HOST上运行的pgen。

(3)在要使用PGEN的地方改为PGEN_HOST:

$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT)

-$(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)

改为:

$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT)

-$(PGEN_HOST) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)

(4)修改所有使用新生成的python的地方。

在BUILDPYTHON变量下面定义一个变量:PYTHON_HOST=build.pc/python$(EXE),然后将所有./$(BUILDPYTHON)的地方都换成./$(PYTHON_HOST),如果你使用vi,可以直接这么替换:%s/.\/$(BUILDPYTHON)/.\/$(PYTHON_HOST)/g

8、make 出现错误:

Include/pyport.h:243: error: #error "This platform's pyconfig.h needs to define PY_FORMAT_LONG_LONG"

修改pyconfig.h: 找到#undef PY_FORMAT_LONG_LONG 处加:#define PY_FORMAT_LONG_LONG "ll"

9、make,make test ,make install;

10、make test时发现有些模块test不通过;

319 tests OK.
23 tests failed:
test___all__ test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp
test_codecmaps_kr test_codecmaps_tw test_cookielib test_distutils
test_hashlib test_hmac test_md5 test_multiprocessing
test_normalization test_pep247 test_sha test_smtplib test_sundry
test_tarfile test_unicodedata test_urllib2 test_urllib2_localnet
test_urllib2net test_uuid
42 tests skipped:
test_aepack test_al test_applesingle test_bsddb test_bsddb185
test_bsddb3 test_bz2 test_cd test_cl test_crypt test_curses
test_dbm test_dl test_gdbm test_gl test_gzip test_imageop
test_imgfile test_kqueue test_linuxaudiodev test_macos
test_macostools test_nis test_ossaudiodev test_readline
test_scriptpackages test_smtpnet test_socketserver test_sqlite
test_ssl test_startfile test_sunaudiodev test_tcl test_timeout
test_tk test_ttk_guionly test_ttk_textonly test_urllibnet
test_winreg test_winsound test_zipfile64 test_zlib


11、在开发板上通过nfs进入到当前路径执行./python,成功;

12、编译测试程序:

mips-linux-gnu-gcc -EL test.c -L. -lpython2.7

#include "./Include/Python.h"

int main()

{

printf("1111\n");

Py_Initialize();

PyRun_SimpleString("print 'hi,python!'");

Py_Finalize();

return 0;

}

13、执行测试程序

14、如果我们测试 import urllib,会有如下错误:

ImportError: No module named _socket

如果我们print sys.path,结果如下:

['', '/home/pub/johnny/xbmc/test/test2/install/lib/python27.zip', '/root/xbmc/test/test2/Python-2.7/Lib', '/root/xbmc/test/test2/Python-2.7/Lib/plat-linux3', '/root/xbmc/test/test2/Python-2.7/Lib/lib-tk', '/root/xbmc/test/test2/Python-2.7/Lib/lib-old', '/root/xbmc/test/test2/Python-2.7/build/lib.linux-mips-2.7']

我们发现在build下面并没有lib.linux-mips-2.7,而只有lib.linux-x86_64-2.7 目录,而且下面有_socket_failed.so;

那么就把lib.linux-x86_64-2.7 复制成lib.linux-mips-2.7,并把_socket_failed.so以及其他一些需要的so的_failed去掉,批量更改的方法:rename 's/_failed//' *.so;即改成_socket.so等,发现import urllib成功了!

如果把所有的so的_failed去掉,继续make test时发现缺少_sha256等模块,仍然过不了;

http://mail.python.org/pipermail/spambayes/2004-April/012138.html

按照http://blog.sina.com.cn/s/blog_3c8ced580100zxq9.html来修改Module/Setup文件仍然不行;

15、后来在setup.py中搜索_sha256,发现如下程序:

if COMPILED_WITH_PYDEBUG or openssl_ver < min_sha2_openssl_ver:
# OpenSSL doesn't do these until 0.9.8 so we'll bring our own hash
exts.append( Extension('_sha256', ['sha256module.c']) )
exts.append( Extension('_sha512', ['sha512module.c']) )


是不是这个if条件不成立所以没有编译呢?把

if COMPILED_WITH_PYDEBUG or openssl_ver < min_sha2_openssl_ver:

改成if 1:

就生成了_sha512_failed.so和_sha256_failed.so,改成_sha256.so和_sha512.so刚才的import urllib2也成功了!

16、如果在py文件中import gzip,会发现找不到zlib模块;

通过在setup.py中的zlib编译出添加打印信息发现:在if (self.compiler.find_library_file(lib_dirs, 'z')):条件不成立,没有执行的到exts.append,而是执行到了 missing.append('zlib');

在if (self.compiler.find_library_file(lib_dirs, 'z')):处添加(self.compiler.find_library_file(lib_dirs+['/usr/lib32'], 'z')):,将zlib模块添加到编译列表中(不同的编译环境此处可能不一样);

仍然不能编译出zlib.so,通过make过程中的log发现,链接时ld不到libz,就在detect_modules中通过add_dir_to_list(self.compiler.library_dirs, './'),然后将交叉编译环境下的libz.so复制到当前目录下;

还需要修改Modules/binascii.c和Modules/zlibmodule.c的路径,为#include "zlib/zlib.h",否则会出现 fatal error: zlib.h: No such file or directory的错误;

再次make,发现生成了zlib.so,此时import gzip也成功了;

17、在开发板上执行时,如果出现如下错误:

Could not find platform independent libraries <prefix>
Could not find platform dependent libraries <exec_prefix>
Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
ImportError: No module named site


需要在当前环境变量中或者在/etc/profile中添加:

export PYTHONHOME=/root/xbmc/python_install-test
export PYTHONPATH=$PYTHONHOME:$PYTHONHOME/lib/python2.7:$PYTHONHOME/lib:$PYTHONHOME/lib/python2.7/site-packages
export PATH=$PATH:$PYTHONHOME:$PYTHONPATH


即可;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: