天天看點

Numpy for WinCE 移植筆記

國内用 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 #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; 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下面就行了嗎?搞了半天沒弄懂怎麼調用……