国内用 Python 的人不多,用 WinCE 的也很少,用 PythonCE 的更是少之又少,至于在 PythonCE 上用 Numpy 的人…… =_,= Numpy for WinCE (ARM) 的工作在 PythonCE 社区也是拖了又拖没人发布,最后只好自己动手了。花了几天时间,试了 VS2008 、EVC4 、CeGCC 、MingW32ce 、PocketGCC 五个编译器,最后总算用 EVC4+Scons 再改一堆代码解决了…… Python 模块主要包括两类文件:Python 程序 pyc 或 pyo ,由 py 编译,这是平台无关的,但是和 Python 的版本有关,所以可以用 Python 2.5 编译给 PythonCE 2.5 用,但不能用 PythonCE 2.4 编译给 PythonCE 2.5 用;动态链接库 pyd ,等同 Windows 的 dll 或 Linux 的 so ,一般由 c 源文件编译,这是和 CPU 以及操作系统都有关系的,需要在 PC 上交叉编译。Python 模块的移植,主要问题就是 pyd 的编译。当然,对于一些依赖于外部动态链接库的模块(如 pygame)还要依赖库有 WinCE 的版本。 1、系统需求: Python 2.5 for Windows Microsoft eMbedded Visual C++ 4.0 with Service Pack 4 Pocket PC 2003 SDK 2、下载 numpy (这里用的是 1.3.0 )和 PythonCE (这里用的是 build 20061219 ,source 和 dev 都需要)。 3、选某一目录作为工作目录,将 numpy-1.3.0.zip/numpy-1.3.0 、PythonCE-2.5-20061219-dev.zip/Python-2.5-wince-dev 以及 PythonCE-2.5-20061219-source.zip/Python-2.5-wince/PCbuild/WinCE 下的 scons-local-0.96.1 、scons.py 、sconsign.py 、scons.bat 和 msevc.py 解压到该目录,建立一个 build 子目录和一个文本文档 SConstruct (无后缀名),最终目录结构如下: build(目录) numpy-1.3.0(目录) Python-2.5-wince-dev(目录) scons-local-0.96.1(目录) SConstruct msevc.py scons.bat scons.py sconsign.py 4、执行 python numpy-1.3.0/setup.py build 。如果装了 Mingw32 ,也可以加上 -c mingw32 的参数,注意 python 为 Python25 ,如果装了多个 Python 版本,最好前面加上 Python25 的路径。按 Win32 编译的结果当然不能拿到 WinCE 运行,这一步的左右仅仅是 configure ,把诸如 *.in 、*.inc 、*.src 的文件生成相应的代码文件,方便下一步的 WinCE build 。当然,configure 也只是针对 Win32 的,所以后边还要进行调整。 5、编辑 SConstruct : SConstruct pythonce_path = r'Python-2.5-wince-dev' numpy_path = r'numpy-1.3.0/numpy' numpy_build_path = r'numpy-1.3.0/build/src.win32-2.5/numpy' build_path = r'build' class CEBuildEnvironment(Environment): def __init__(self): Environment.__init__(self, MSEVC_PLATFORM = 'POCKET PC 2003', MSEVC_SUBPLATFORM = 'Win32 (WCE ARMV4)', tools = ['mslink', 'msevc', 'zip'], toolpath = '.' ) class PythonCEBuildEnvironment(CEBuildEnvironment): def __init__(self): CEBuildEnvironment.__init__(self) self.Append(CPPDEFINES = ['WIN32'], LIBS=[ 'python25' ], CPPPATH=[ pythonce_path+r'/include', numpy_path+r'/core/include', numpy_build_path+r'/core/include/numpy' ], LIBPATH=[ pythonce_path+r'/lib' ]) def PythonExtension(self, target, sources, **kw): self.SharedLibrary(target, sources, SHLIBSUFFIX='.pyd', **kw) npymath_env = PythonCEBuildEnvironment() npymath_env.Append(CPPPATH = [ numpy_path+r'/core/src' ]) npymath_env.StaticObject(build_path+r'/npymath.lib', numpy_build_path+r'/core/src/npy_math.c') core_env = PythonCEBuildEnvironment() core_env.Append(CPPPATH = [ numpy_path+r'/core/src', numpy_build_path+r'/core/src' ]) core_env.Append(LIBPATH = [ build_path ]) core_env.Append(LIBS = [ 'npymath' ]) core_env.PythonExtension(build_path+r'/core/multiarray.pyd', numpy_path+r'/core/src/multiarraymodule.c') core_env.PythonExtension(build_path+r'/core/umath.pyd', numpy_build_path+r'/core/src/umathmodule.c') core_env.PythonExtension(build_path+r'/core/umath_tests.pyd', numpy_build_path+r'/core/src/umath_tests.c') core_env.PythonExtension(build_path+r'/core/scalarmath.pyd', numpy_build_path+r'/core/src/scalarmathmodule.c') core_env.PythonExtension(build_path+r'/core/_sort.pyd', numpy_build_path+r'/core/src/_sortmodule.c') fft_env = core_env.Copy() fft_env.Append(CPPPATH = [ numpy_path+r'/fft' ]) fft_env.PythonExtension(build_path+r'/fft/fftpack_lite.pyd', [ numpy_path+r'/fft/fftpack.c', numpy_path+r'/fft/fftpack_litemodule.c' ]) lib_env = core_env.Copy() lib_env.Append(CPPPATH = [ numpy_path+r'/lib/src' ]) lib_env.PythonExtension(build_path+r'/lib/_compiled_base.pyd', numpy_path+r'/lib/src/_compiled_base.c') linalg_env = core_env.Copy() linalg_env.Append(CPPPATH = [ numpy_path+r'/linalg' ]) linalg_env.PythonExtension(build_path+r'/linalg/lapack_lite.pyd', [ numpy_path+r'/linalg/blas_lite.c', numpy_path+r'/linalg/dlamch.c', numpy_path+r'/linalg/dlapack_lite.c', numpy_path+r'/linalg/f2c_lite.c', numpy_path+r'/linalg/lapack_litemodule.c', numpy_path+r'/linalg/python_xerbla.c', numpy_path+r'/linalg/zlapack_lite.c' ]) numarray_env = core_env.Copy() numarray_env.Append(CPPPATH = [ numpy_path+r'/numarray/numpy' ]) numarray_env.PythonExtension(build_path+r'/numarray/_capi.pyd', numpy_path+r'/numarray/_capi.c') random_env = core_env.Copy() random_env.Append(CPPPATH = [ numpy_path+r'/random/mtrand' ]) random_env.PythonExtension(build_path+r'/random/mtrand.pyd', [ numpy_path+r'/random/mtrand/distributions.c', numpy_path+r'/random/mtrand/initarray.c', numpy_path+r'/random/mtrand/mtrand.c', numpy_path+r'/random/mtrand/randomkit.c' ]) 6、编辑 scons.bat ,把 python 的路径改为自己电脑上 Python25 的路径,然后运行,以上便是移植 Python 模块到 WinCE 的一般模式。话虽如此,实际操作结果往往是编译失败(……),因而对于特定模块比如 numpy 这样,还要耐心地一个一个问题去解决…… 7、不知为何 msevc.py 在我的电脑上找不到 EVC4 ,在 line 382: exe_path = defpaths[2] 出错,我把这行改为: exe_path = r'M:/Program Files/Microsoft eMbedded C++ 4.0/EVC/wce500/bin' 8、首先是 npy_cpu.h 的 Unknown CPU 错误。numpy 支持的 CPU 包括 X86 、AMD64 、PPC 、PPC64 、SPARC 、S390 、IA64 、PARISC ,ARM 跟哪个比较像?……我也不清楚,于是鲁莽地当作是 X86 好了…… #error Unknown CPU, please report this to numpy maintainers with / information about your platform (OS, CPU and compiler) 改为: #define NPY_CPU_X86 9、Microsoft Specific ,修改 numpyconfig.h numpyconfig.h #define NPY_SIZEOF_SHORT 2 #define NPY_SIZEOF_INT 4 #define NPY_SIZEOF_LONG 4 #define NPY_SIZEOF_FLOAT 4 #define NPY_SIZEOF_DOUBLE 8 #define NPY_SIZEOF_LONGDOUBLE 12 #define NPY_SIZEOF_PY_INTPTR_T 4 #define NPY_SIZEOF_PY_LONG_LONG 8 #define NPY_SIZEOF_LONGLONG 8 #define NPY_NO_SIGNAL 1 #define NPY_NO_SMP 0 //#define NPY_HAVE_DECL_ISNAN //#define NPY_HAVE_DECL_ISINF //#define NPY_HAVE_DECL_SIGNBIT //#define NPY_HAVE_DECL_ISFINITE #define NPY_USE_C99_FORMATS 1 #define NPY_INLINE __inline #ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS 1 #endif 10、修改 config.h ,去掉 CPU 不支持的数学函数。简单来说就是,哪个出现 LNK2019 错误就注释掉哪个…… config.h #define SIZEOF_SHORT 2 #define SIZEOF_INT 4 #define SIZEOF_LONG 4 #define SIZEOF_FLOAT 4 #define SIZEOF_DOUBLE 8 #define SIZEOF_PY_INTPTR_T 4 #define SIZEOF_PY_LONG_LONG 8 #define MATHLIB #define HAVE_SIN #define HAVE_COS #define HAVE_TAN #define HAVE_SINH #define HAVE_COSH #define HAVE_TANH #define HAVE_FABS #define HAVE_FLOOR #define HAVE_CEIL #define HAVE_SQRT #define HAVE_LOG10 #define HAVE_LOG #define HAVE_EXP #define HAVE_ASIN #define HAVE_ACOS #define HAVE_ATAN #define HAVE_FMOD #define HAVE_MODF #define HAVE_FREXP #define HAVE_LDEXP //#define HAVE_EXPM1 //#define HAVE_LOG1P //#define HAVE_ACOSH //#define HAVE_ASINH //#define HAVE_ATANH //#define HAVE_RINT //#define HAVE_TRUNC //#define HAVE_EXP2 //#define HAVE_LOG2 //#define HAVE_SINF //#define HAVE_COSF //#define HAVE_TANF //#define HAVE_SINHF //#define HAVE_COSHF //#define HAVE_TANHF //#define HAVE_FABSF //#define HAVE_FLOORF //#define HAVE_CEILF //#define HAVE_RINTF //#define HAVE_TRUNCF //#define HAVE_SQRTF //#define HAVE_LOG10F //#define HAVE_LOGF //#define HAVE_LOG1PF //#define HAVE_EXPF //#define HAVE_EXPM1F //#define HAVE_ASINF //#define HAVE_ACOSF //#define HAVE_ATANF //#define HAVE_ASINHF //#define HAVE_ACOSHF //#define HAVE_ATANHF //#define HAVE_HYPOTF //#define HAVE_ATAN2F //#define HAVE_POWF //#define HAVE_FMODF //#define HAVE_MODFF //#define HAVE_FREXPF //#define HAVE_LDEXPF //#define HAVE_EXP2F //#define HAVE_LOG2F //#define HAVE_SINL //#define HAVE_COSL //#define HAVE_TANL //#define HAVE_SINHL //#define HAVE_COSHL //#define HAVE_TANHL //#define HAVE_FABSL //#define HAVE_FLOORL //#define HAVE_CEILL //#define HAVE_RINTL //#define HAVE_TRUNCL //#define HAVE_SQRTL //#define HAVE_LOG10L //#define HAVE_LOGL //#define HAVE_LOG1PL //#define HAVE_EXPL //#define HAVE_EXPM1L //#define HAVE_ASINL //#define HAVE_ACOSL //#define HAVE_ATANL //#define HAVE_ASINHL //#define HAVE_ACOSHL //#define HAVE_ATANHL //#define HAVE_HYPOTL //#define HAVE_ATAN2L //#define HAVE_POWL //#define HAVE_FMODL //#define HAVE_MODFL //#define HAVE_FREXPL //#define HAVE_LDEXPL //#define HAVE_EXP2L //#define HAVE_LOG2L //#define HAVE_DECL_ISNAN //#define HAVE_DECL_ISINF //#define HAVE_DECL_SIGNBIT //#define HAVE_DECL_ISFINITE #define __NPY_PRIVATE_NO_SIGNAL #define FORCE_NO_LONG_DOUBLE_FORMATTING #ifndef __cplusplus /* #undef inline */ #endif 11、因为 WinCE 不支持 localeconv() ,修改 numpyos.c : struct lconv *locale_data = localeconv(); const char *decimal_point = locale_data->decimal_point; 改为: const char *decimal_point = "."; 一共有两处。 12、因为 WinCE 不支持 abort() ,修改 f2c_lite.c : abort(); 改为: TerminateProcess(GetCurrentProcess(), 0); 当然,还要 #i nclude 。 13、EVC 只支持 2048 字节的字符常量( C++ 标准是 64K ),所以 mtrand.c 会出现一堆的 C2026: string too big 错误。解决方法么……要么自己去整资源文件,要么……反正也就是帮助而已,都改成 "Unavailable" 好了 Orz 14、randomkit.c 需要 errno.h ,WinCE 没有,从 PC 的(如 VC 的 include )拷一个过去好了。 15、时间函数的关系,randomkit.c 的 rk_randomseed 要修改(反正是随机数种子罢了,随便了): randomkit.c 的 rk_randomseed rk_error rk_randomseed(rk_state *state) { SYSTEMTIME tv; int i; if(rk_devfill(state->key, sizeof(state->key), 0) == RK_NOERR) { state->key[0] |= 0x80000000UL; /* ensures non-zero key */ state->pos = RK_STATE_LEN; state->has_gauss = 0; state->has_binomial = 0; for (i=0; i<624; i++) { state->key[i] &= 0xffffffffUL; } return RK_NOERR; } GetSystemTime(&tv); rk_seed(rk_hash(tv.wYear) ^ rk_hash(tv.wMonth) ^ rk_hash(tv.wDay) ^ rk_hash(tv.wHour) ^ rk_hash(tv.wMinute) ^ rk_hash(tv.wSecond) ^ rk_hash(tv.wMilliseconds), state); return RK_ENODEV; } 另外去掉 #i nclude ;加上 #i nclude 。 16、运行 scons.bat 。至此我成功编译了所有 pyd ,如果你还有问题的话……耐心解决吧||| 17、用类似这样的脚本编译 py 为 pyc : compile.py import os, compiler for root, dirs, files in os.walk(r'numpy-1.3.0/build/lib.win32-2.5/numpy'): for name in files: if name[-3:] == '.py': compiler.compileFile(os.path.join(root, name)) 18、用 build 下的(pyd)文件替换 numpy-1.3.0/build/lib.win32-2.5/numpy 下的,然后删除后者中除 pyc 和 pyd 外的所有文件,还可以删去 distutils 文件夹以及各文件夹下的 setup.pyc 和 setupscons.pyc,把整理好的这个 numpy 文件夹拷到 PythonCE 的 Lib 文件夹下,大功告成。 阅读全文(1082) | 回复(17) |反映问题 | 引用通告(0) | 编辑 标签:Python PythonCE Numpy 魅族M8 Scons 上一篇:魅族 M8 入手 下一篇:整理书签,备份几个网站 Re:Numpy for WinCE 移植笔记 houkai(游客) 发表于 - 2010-2-3 11:37:00 感谢 作者提供这么好的软件 我也喜欢python和m8 个人主页 | 引用 | 返回 | 删除 | 回复 Re:Numpy for WinCE 移植笔记 YK(游客) 发表于 - 2010-1-9 11:28:00 楼主可否跟新下PythonCE,或者简单修改下,让它可以在新固件下运行,谢谢 个人主页 | 引用 | 返回 | 删除 | 回复 Re:Numpy for WinCE 移植笔记 访客t85Bre(游客) 发表于 - 2009-11-8 23:21:00 来支持一下 python的爱好者。 个人主页 | 引用 | 返回 | 删除 | 回复 Re:Numpy for WinCE 移植笔记 访客13Am15(游客) 发表于 - 2009-10-19 13:47:00 路过。。 刚开始学python, 个人主页 | 引用 | 返回 | 删除 | 回复 Re:Numpy for WinCE 移植笔记 访客uAQc6G(游客) 发表于 - 2009-8-2 10:46:00 不行啊 在m8fans下载的cab安装版本 装上之后import numpy 不成功啊 试了个简单while循环也出现identationerror 个人主页 | 引用 | 返回 | 删除 | 回复 Re:Numpy for WinCE 移植笔记 ieph 发表于 - 2009-5-20 13:10:00 Numpy 需要修改的比较少,上面的都写了,源码也被我弄得面目全非了,就不放了吧…… 论坛上的版本应该是 ARM WinCE/WM 通用的: http://bbs.meizu.com/thread-888785-1-1.html 最近事情比较多,Matplot 要迟些才能弄,另一个问题也是 Tk 在 M8 上有些诡异的问题。 我计划移植的还有 pygame ,虽然很想移植 scilab ,但那东西工作量大得恐怖,基本上放弃了。 个人主页 | 引用 | 返回 | 删除 | 回复 Re:Numpy for WinCE 移植笔记 Beeven(游客) 发表于 - 2009-5-20 11:52:00 PIL要另外build的几个模块,就只有libjpeg,zlib,freetype2而已。那些代码可能帮不到你了。放到网上了: http://pilce.googlecode.com matplot不错啊。只是MatLab也没有怎么用过,都要毕业了,估计以后也用不着了..:( 期待你完成的Matplot呢。numpy的代码也放出来吧。:) 图形界面方面,wxpyce有pythonce 2.4的source,要弄到2.5上也有一番要修改呢。暂时用ppygui代替了。还有那些比较有用的lib吗? 个人主页 | 引用 | 返回 | 删除 | 回复 Re:Numpy for WinCE 移植笔记 ieph 发表于 - 2009-5-19 23:31:00 很期待啊~我弄 Matplot 的时候被几个图片格式的模块弄烦了,希望能看下你的代码~ 个人主页 | 引用 | 返回 | 删除 | 回复 PIL for PythonCE Beeven(游客) 发表于 - 2009-5-19 22:18:00 嘛... 刚刚弄了几天,把Python Imaging Library 1.1.6 弄到PythonCE上去了。 之前用Cegcc、mingw32ce、Scons+eVC4+WindowsMobile2003SDK都没有办法,后来是用VS2008+WM6SDK解决了,把几个不支持的函数重写了一下,除了tkinter模块没有加进去(我自己也没有安装tk),其他的功能都全了。 我的是ARM架构的Windows Mobile 6的手机,论坛看到你用M8,如果需要,我放源代码出来大家改进一下。 Googlecode刚好维护...明天再放了... 个人主页 | 引用 | 返回 | 删除 | 回复 Re:Numpy for WinCE 移植笔记 Beeven(游客) 发表于 - 2009-5-19 22:17:00 嘛... 刚刚弄了几天,把Python Imaging Library 1.1.6 弄到PythonCE上去了。 之前用Cegcc、mingw32ce、Scons+eVC4+WindowsMobile2003SDK都没有办法,后来是用VS2008+WM6SDK解决了,把几个不支持的函数重写了一下,除了tkinter模块没有加进去(我自己也没有安装tk),其他的功能都全了。 我的是ARM架构的Windows Mobile 6的手机,论坛看到你用M8,如果需要,我放源代码出来大家改进一下。 Googlecode刚好维护...明天再放了... 个人主页 | 引用 | 返回 | 删除 | 回复 Re:Numpy for WinCE 移植笔记 ieph 发表于 - 2009-5-9 21:20:00 嗯……现在移植 Matplot 的时候遇到点麻烦,暂时放一放吧…… 个人主页 | 引用 | 返回 | 删除 | 回复 Re:Numpy for WinCE 移植笔记 renzaoren615(游客) 发表于 - 2009-5-9 11:26:00 大哥,还能移植其他的类似的软件吗,很棒啊 个人主页 | 引用 | 返回 | 删除 | 回复 Re:Numpy for WinCE 移植笔记 访客uaq0TG(游客) 发表于 - 2009-4-22 14:52:00 纯支持,python不会啊 个人主页 | 引用 | 返回 | 删除 | 回复 Re:Numpy for WinCE 移植笔记 ieph 发表于 - 2009-4-21 20:35:00 确认 numpy 文件夹在 /Disk/Programs/Python25/Lib 下; 或者, import sys sys.path 确认 numpy 文件夹在其中任一目录下。 个人主页 | 引用 | 返回 | 删除 | 回复 Re:Numpy for WinCE 移植笔记 误入围城(游客) 发表于 - 2009-4-21 20:13:00 输入 import numpy后提示no module named numpy,怎么回事呢? 个人主页 | 引用 | 返回 | 删除 | 回复 Re:Numpy for WinCE 移植笔记 ieph 发表于 - 2009-4-21 19:58:00 是的,只要你能 import numpy 就算成功了。 个人主页 | 引用 | 返回 | 删除 | 回复 Re:Numpy for WinCE 移植笔记 误入围城(游客) 发表于 - 2009-4-21 19:55:00 问一下,要用numpy只要把numpy文件夹复制到lib下面就行了吗?搞了半天没弄懂怎么调用……