仅打包cythonized二进制python文件和资源数据,但忽略python .py源文件

时间:2019-05-07 13:57:16

标签: python cython obfuscation setuptools packaging

我需要混淆我的python代码,要实现它,我正在使用cythonize扩展,我能够实现它,并从a.py文件中获取二进制编译的a.so文件,但是在执行bdist_wheel之后,仅.whl包会打包a.so文件,并忽略resource_folder。

我的项目文件结构是

|main_project
|__,setup.py
|__,main_folder
|____,a.py
|____,__init__.py
|____resource_folder
     |__,a.model
     |__,a.json

我使用以下链接制作了模糊的python wheel包,

https://bucharjan.cz/blog/using-cython-to-protect-a-python-codebase.html

https://medium.com/@xpl/protecting-python-sources-using-cython-dcd940bb188e

Package only binary compiled .so files of a python library compiled with Cython

以下是我的setup.py中的摘录

packages = find_packages(exclude=('tests',))

def get_package_files_in_directory(directory):
    paths = []
    for (path, directories, filenames) in os.walk(directory):
        for filename in filenames:
            paths.append(os.path.join('..', path, filename))
    return paths


setup(
    packages=[],

    ext_modules=cythonize(
        [
           Extension("main_folder.*", ["main_folder/*.py"])

        ],
        build_dir="build",
        compiler_directives=dict(
        always_allow_keywords=True
        )),
package_data={p: package_files + get_package_files_in_directory(os.path.join(here, p, 'resources')) for p in packages},
,....
,...
)

要打包,我正在使用以下命令

python setup.py build_ext

python setup.py bdist_wheel


预期结果是包含.so文件和资源文件夹的.whl文件

实际结果是.whl文件仅包含一个.so文件。


还按照此链接“({How do you add additional files to a wheel?)”中的建议,打包了我使用的get_package_files_in_directory()函数,但这对我也不起作用

1 个答案:

答案 0 :(得分:0)

基于Answer@hoefling,我可以打包resource_folder并混淆二进制a.so文件。

更新的合并设置。py

from Cython.Distutils import build_ext
from Cython.Build import cythonize
from setuptools.extension import Extension
from setuptools.command.build_py import build_py as build_py_orig

packages = find_packages(exclude=('tests',))

    def get_package_files_in_directory(directory):
        paths = []
        for (path, directories, filenames) in os.walk(directory):
            for filename in filenames:
                paths.append(os.path.join('..', path, filename))
        return paths
    #to copy the __init__.py as specified in above references links

    class MyBuildExt(build_ext):
        def run(self):
            build_ext.run(self)

            build_dir = Path(self.build_lib)
            root_dir = Path(__file__).parent

            target_dir = build_dir if not self.inplace else root_dir

            self.copy_file(Path('main_folder') / '__init__.py', root_dir, target_dir)


        def copy_file(self, path, source_dir, destination_dir):
            if not (source_dir / path).exists():
                return

            shutil.copyfile(str(source_dir / path), str(destination_dir / path))

    #as specified by @hoefling to ignore .py and not resource_folder
    class build_py(build_py_orig):
        def build_packages(self):
            pass

    setup(
        packages=find_packages(),  # needed for obfuscation
        install_requires=install_requires,
        ext_modules=cythonize(
            [
               Extension("main_folder.*", ["main_folder/*.py"])

            ],
            build_dir="build",
            compiler_directives=dict(
            always_allow_keywords=True
            )),
        package_data={p: package_files + get_package_files_in_directory(os.path.join(here, p, 'resource_folder')) for p in packages}, #package_data as found in another reference
        cmdclass={
            'build_py': build_py
        },
        entry_points={
        },
    )

要创建混淆的* .whl软件包命令集

python setup.py build_ext  #creates the a.so
python setup.py build_py   #copies the resource_folder excluding .py
python setup.py bdist_wheel # then whl generation