使用cython混淆python项目代码

有时候交付python项目,但是不希望对方看到自己的源码,所以在此记录一个用cython编译项目的脚本,这个脚本能够将python项目一键编译成c输出文件。

1. 安装cython

pip install Cython

2. 在项目根目录新建compile.py 文件,内容如下:

from distutils.core import setup
from distutils.extension import Extension
from pathlib import Path
from Cython.Build import cythonize
import glob, shutil, os

root_dir = os.path.dirname(__file__)
# 编译过程会产生build目录
cache_dir = os.path.join(root_dir, 'build')
# 输出到dist目录
output_dir = os.path.join(root_dir, 'dist')

# 要混淆的代码目录
target_dirs = ['app']

# 忽略的文件名
exclude_files = []

# 删除已存在输出目录
shutil.rmtree(output_dir)

### 遍历目录 ###
for dir in target_dirs:

	# 遍历目录下所有py文件
    for file in list(Path(os.path.join(root_dir, dir)).glob('**/*.py')):
        filename = Path(file).resolve().stem
        if filename not in exclude_files:
            relpath = os.path.relpath(os.path.dirname(file.absolute().as_posix()), root_dir)
            package_name = relpath.replace('/', '.') + '.' + filename if relpath != '.' else filename
            # 执行编译
            setup(ext_modules=cythonize([Extension(package_name, [str(file)])], compiler_directives={
                'c_string_type': 'str',
                'c_string_encoding': 'utf8',
                'language_level': 3}))

# 移动so文件到输出目录
for dir in target_dirs:
    target_path = os.path.join(root_dir, dir)
    for file in list(Path(os.path.join(root_dir, dir)).glob('**/*.so')):
        filepath = file.absolute().as_posix()
        new_path = os.path.join(output_dir, os.path.relpath(filepath, root_dir))
        new_dir = os.path.dirname(new_path)
        if not os.path.exists(new_dir):
            os.makedirs(new_dir)
        shutil.move(filepath, new_path)

# 删除指定后缀文件
def delete_files(file_type):
    for dir in target_dirs:
        cfiles = list(Path(os.path.join(root_dir, dir)).glob('**/*.' + file_type))
        for cfile in cfiles:
            cfile.unlink()
            
# 删除产生的多余文件
delete_files('c')
delete_files('pyc')
shutil.rmtree(cache_dir)

3. 执行compile.py脚本

执行脚本后,会把所有so文件移动到dist目录

python compile.py build_ext --inplace
  • build_ext 打包为动态库so文件
  • --inplace 产出文件存在原目录

4. 完成

进入输出的dist目录,执行原命令

注意: cython对新版本python的部分语法编译会出错,修改后重新编译即可

你可能感兴趣的:(Python,python,开发语言,cython,混淆)