Cython+Pyinstaller Python编译与打包

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

你可能感兴趣的:(Cython)