源代码如下所示,
```setup.py```
import sys
arg_list = sys.argv
f_name = arg_list[1]
sys.argv.pop(1)
from distutils.core import setup
from Cython.Build import cythonize
print(sys.argv, f_name)
setup(ext_modules=cythonize(f_name))
```su_main.py```
import os
ignore_files = ['setup.py', 'manage.py', 'su_main.py', 'main.py', 'build', 'extra_apps', 'static', 'templates', 'logs', 'JEIME', 'package'] # 根目录下不用(能)转译的文件(夹)名, 入口文件一定要加进来
ignore_names = ['migrations', 'apps.py', 'models.py'] # 不用(能)转译的文件(夹)名
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
ignore_files = [os.path.join(BASE_DIR, x) for x in ignore_files]
package = True # 是否打包到一个文件夹内
package_path = os.path.join(BASE_DIR, 'package') //打包文件夹路径
if not os.path.exists(package_path):
os.mkdir(package_path)
translate_pys = []
def translate_dir(path):
pathes = os.listdir(path)
if path != BASE_DIR and not '__init__.py' in pathes:
with open(os.path.join(path, '__init__.py'), 'w', encoding='utf8') as f:
pass
for p in pathes:
if p in ignore_names:
continue
if p.startswith('__') or p.startswith('.') or p.startswith('build'):
continue
f_path = os.path.join(path, p)
if f_path in ignore_files:
continue
if os.path.isdir(f_path):
translate_dir(f_path)
else:
if not f_path.endswith('.py') and not f_path.endswith('.pyx'):
continue
if f_path.endswith('__init__.py') or f_path.endswith('__init__.pyx'):
continue
with open(f_path, 'r', encoding='utf8') as f:
content = f.read()
if not content.startswith('# cython: language_level=3'):
content = '# cython: language_level=3\n' + content
with open(f_path, 'w', encoding='utf8') as f1:
f1.write(content)
os.system('python setup.py ' + f_path + ' build_ext --inplace')
translate_pys.append(f_path)
f_name = '.'.join(f_path.split('.')[:-1])
py_file = '.'.join([f_name, 'py'])
c_file = '.'.join([f_name, 'c'])
if os.path.exists(c_file):
os.remove(c_file)
def remove_dir(path, rm_path=True):
if not os.path.exists(path):
return
pathes = os.listdir(path)
for p in pathes:
f_path = os.path.join(path, p)
if os.path.isdir(f_path):
remove_dir(f_path, False)
os.rmdir(f_path)
else:
os.remove(f_path)
if rm_path:
os.rmdir(path)
def mv_to_packages(path=BASE_DIR):
pathes = os.listdir(path)
for p in pathes:
if p.startswith('.'):
continue
f_path = os.path.join(path, p)
if f_path == package_path:
continue
p_f_path = f_path.replace(BASE_DIR, package_path)
if os.path.isdir(f_path):
if not os.path.exists(p_f_path):
os.mkdir(p_f_path)
mv_to_packages(f_path)
else:
if not f_path.endswith('.py') or f_path not in translate_pys:
with open(f_path, 'rb') as f:
content = f.read()
with open(p_f_path, 'wb') as f:
f.write(content)
if f_path.endswith('.pyd'):
os.remove(f_path)
def run():
translate_dir(BASE_DIR)
remove_dir(os.path.join(BASE_DIR, 'build'))
if package:
mv_to_packages()
if __name__ == '__main__':
run()
su_man为打包入口文件, 拖入到项目根目录下, 正确配置即可通过进行运行
注意: 各文件夹内需要有__init__.py, 不然生成的文件都在根目录, 这是Cython决定的, 代码中已包含自动生成。