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

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