因为考虑安全性需要将代码加密搜了一下编译成.so文件是比较合适的。而又因为是运行在树莓派的所以考虑使用交叉编译不然每次编译都要使用树莓派。流程1.编写Dockefile文件这里的镜像使用的arm32v7的因为树莓派是armv7的一般镜像不行。FROM arm32v7/python:2.7 RUN echo deb http://archive.debian.org/debian buster main /etc/apt/sources.list \ echo deb http://archive.debian.org/debian buster-updates main /etc/apt/sources.list \ apt-get update apt-get install -y gcc python-dev \ pip install cython0.30 WORKDIR /work CMD [python, setup.py, build_ext, --inplace]2.编译脚本setup.py这个脚本做了很多的优化1.extra_link_args [-Wl,-s] # strip 符号表减小 .so 体积增加反查难度2.binding: False, # 不生成 Python 绑定减小体积3. embedsignature: False, # 不嵌入函数签名docstring 进一步减小体积4.language_level: 2, # 强制 Python 2 语法5.annotateFalse, # 不生成 HTML 分析报告纯编译加速6.forceTrue, # 强制重新生成 .c即使 .c 已存在也强制重新 Cythonize确保源码变更一定生效7.-Wl,-s 在链接阶段 去除 ELF 符号表 实测.so的编译文件大小从几十兆缩小到只有几兆# -*- coding: utf-8 -*- Cython 编译脚本Python 2.7 用法: python setup.py build_ext --inplace from distutils.core import setup from distutils.command.build_ext import build_ext from Cython.Build import cythonize import os import shutil import sys # 清理上次编译残留强制重新编译 BUILD_DIR build if os.path.isdir(BUILD_DIR): shutil.rmtree(BUILD_DIR) for f in [test1.c, test2.c]: if os.path.isfile(f): os.remove(f) extra_link_args [-Wl,-s] # strip 符号表减小 .so 体积增加反查难度 ext_modules cythonize( [ test1.py, test2.py, ], compiler_directives{ language_level: 2, # 强制 Python 2 语法 binding: False, # 不生成 Python 绑定减小体积 embedsignature: False, # 不嵌入函数签名 }, annotateFalse, # 不需要 HTML 分析报告 forceTrue, # 强制重新生成 .c quietFalse, # 显示编译进度 ) # 给每个编译目标加上 strip 参数 for ext in ext_modules: ext.extra_link_args extra_link_args setup( nametest_encrypted, ext_modulesext_modules, )3.运行编译--rm 容器退出后删除。--platform linux/arm/v7 指定目标平台为32位的ARM强制 Docker 用 QEMU 模拟 armv7l 环境运行容器编译出的 .so 才能在树莓派 4B 32 位系统上加载-v ${PWD}:/work 挂载卷 。把当前目录 d:\code\python_work\frp\new_feature\加密 映射到容器内的 /work 。容器里生成的文件 .so 、 build/ 会直接出现在宿主机当前目录py2-arm-builder 使用的镜像名。通过 docker buildx build -t py2-arm-builder . 构建的里面预装了 Python 2.7 gcc Cythondocker run --rm --platform linux/arm/v7 -v ${PWD}:/work py2-arm-builder这里需要到程序的目录执行或者是指定-v挂载的目录运行后就等着就可以了一般要十几分钟到半小时根据文件大小判断。总结使用交叉编译大大简化了编译的步骤后续代码更新后只需要在程序目录运行docker容器执行编译就可以了。而且setup.py编译脚本也做了优化压缩了.so文件大小而且加上strip去除符号表进一步增加反向分析的难度。