python文件编译为so和可执行文件

1 准备setup.py文件

#!/usr/bin/env python
# encoding = utf-8
from distutils.core import setup, Extension
from Cython.Build import cythonize
import os, os.path as osp
import glob

"""
python3.7 -m pip install pycrypto
python3.7 -m pip install Cython # 编译其他模块为so python3.7 setup.py # 编译入口启动脚本为 可执行文件 cython main.py --embed && \ gcc -c main.c -I/usr/include/python3.7m -o main.o && \ gcc main.o -L/usr/lib/python3.7/config-3.7m-aarch64-linux-gnu -lpython3.7m -o main rm -r ./*.c && rm -r ./*.o
""" build_dir = "build_so" build_tmp_dir = build_dir + "/temp" skip_files = [ 'main.py' ] def compile_to_so(pyfile): # compile so setup( name='export_so', version='1.0 build 20220818.2212', # single file ext_modules=cythonize(pyfile, nthreads=2), script_args=["build_ext", "-b", build_dir, "-t", build_tmp_dir] ) # remove tmp files for f in glob.glob(f'./**/*.c', recursive=True): os.remove(f) def compile_all_files(): os.makedirs(f'./{build_dir}', exist_ok=True) os.makedirs(f'./{build_tmp_dir}', exist_ok=True) for f in glob.glob(f'./**/*.py', recursive=True): fname = osp.basename(f) if '__init__' in fname or 'setup' in fname: continue elif fname in skip_files: continue try: compile_to_so(f) except Exception as e: print(e) os.removedirs(build_tmp_dir) print('done.') if __name__ == '__main__': compile_all_files() # compile_to_so('./xx/xx.py')

2  先执行setup.py 生成so文件, 生成的目录结构和原来一样

3 再执行sh命令,把入口py编译为 二进制文件

cython main.py --embed && \
gcc -c main.c -I/usr/include/python3.7m -o main.o && \
gcc main.o -L/usr/lib/python3.7/config-3.7m-aarch64-linux-gnu -lpython3.7m  -o main
rm -r ./*.c && rm -r ./*.o

#如果gcc编译失败,则使用py_compile来编译成 .pyc文件
#如果cython编译二进制执行文件失败,则使用py_compile生成.pyc  
输出位置在: ./__pycache__/xx.cpython-37.pyc
python -m py_compile xx.py
cp __pycache__/xx.cpython-37.pyc ./

启动程序:
python3.7 xx.cpython-37.pyc

 

posted @ 2022-11-09 22:33  dangxusheng  阅读(880)  评论(0编辑  收藏  举报