Cython+Pyinstaller Python編譯與打包
示例一
轉載於:https://zhuanlan.zhihu.com/p/90734129
示例項目結構:
➜ cpdemo tree
.
|-- libs
| |-- A
| | `-- a.py
| `-- B
| `-- b.py
`-- setup
|-- build_pyd.py
`-- main.py
總共四個文件,A 和 B分別是兩個類,其中mian.py 引用a, a引用b:
build_pyd.py文件內容如下,自行添加要編譯的文件路徑到cythonize的第一個參數列表裏。每個文件會單獨編譯成一個.so文件。
from distutils.core import setup
from Cython.Build import cythonize
setup(
name='Anything you want',
ext_modules=cythonize(["../libs/A/*.py", "../libs/B/*.py"
], language_level=3
),
)
- 執行步驟:
-
cd setup
python3 build_pyd.py build_ext --inplace
# Cython編譯,生成兩個.so文件
pyinstaller -F main.py
# Pyinstaller 打包,生成:dist/main.so - 驗證:
-
cd dist
./main.so
# 報錯:ModuleNotFoundError: No module named ‘b’ - 修改生成的main.spec文件:10行改成:
hiddenimports=["b"]
-
cd ../setup
pyinstaller main.spec
# 再次打包cd dist
./main.so
# 執行
示例二
多個文件編譯成一個文件
若需要將幾個不同的文件編譯成一個文件,也就是打包成一個二進制包:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy as np
ext_modules = [Extension('RC', sources=['./lib/demo.pyx'],
language='c++')]
setup(
name = 'demo',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules,
include_dirs=[np.get_include()]
)
=================== 其中demo.pyx文件內容如下:=================
include "lib1.pyx"
include "lib2.pyx"
include "lib3.pyx"
多個文件分別編譯
文件目錄
main/
| - run.py
| - __init__.py
| - cls/
| |- __init__.py
| |- water.pyx
| |- land.py
| - funcs/
|- __init__.py
|- func1.pyx
|- func2.py
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
import numpy as np
extensions = [
Extension(
"main.funcs.func1",["main/funcs/func1.pyx"]
),
Extension(
"main.cls.water",["main/cls/water.pyx"]
)
]
setup(
name = "test",
ext_modules=cythonize(extensions),
)
=================== 古關於編譯參數如下: ===================
setup(ext_modules = cythonize(Extension(
'test', # 編譯後的名字,需要編譯的文件名
sources=['cython_evan.pyx'], # 需要編譯的文件名
language='c', # language 默認是 c,如果要用 C++,改成 c++
include_dirs=[np.get_include()], # 傳給 gcc 的 -I 參數(示例:numpy.get_include())
library_dirs=[], # 傳給 gcc 的 -L 參數 (庫文件所在位置)
libraries=[], # 傳給 gcc 的 -l 參數 (c庫文件的名稱:若庫爲libc_lib_name.so,這裏就要寫libraries=["c_lib_name"])
extra_compile_args=[], # 傳給 gcc 的額外的編譯參數,比如傳一個 -std=c++11
extra_link_args=[] # 傳給 gcc 的額外的鏈接參數(也就是生成動態鏈接庫的時候用的)
)))
參考:https://www.jianshu.com/p/abc86ff9fafa