将 python 文件编译成 .so 文件

2023-10-24 14:34:54 浏览数 (1)

需求

首先 Python 是一种面向对象的解释型程序语言,运行 Python 程序时是将 *.py 编译为独有的二进制编码 pyc 文件,然后对 pyc 中的指令进行解释执行,但是对 pyc 文件进行反编译也是比较简单的,可直接反编译为源码。

如果将基于Python 的产品发布到外部时,需要对源码进行保护,不被 crtl c, ctrl v , 因此需要将python文件打成so文件。

另外就是 如果某些源码中包含 秘钥,key 等核心私密数据时,同样需要解决数据安全风险。

编译 py 为 .so 文件

准备工作

linux 环境:

yum install -y python-devel , gcc

python 安装: cython

pip3 install cython

编译目标文件为 so
目标文件
代码语言:javascript复制
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

KEY = 'WmsdofwmPsyqQXIkBp'

def ops_key(k):
    if k == KEY:
      result = True
    else:
      result = False
    return result
设置 setup.py
代码语言:javascript复制
from distutils.core import setup
from Cython.Build import cythonize

setup(ext_modules = cythonize(["ops.py"]))
编译

python3 setup.py build_ext

代码语言:javascript复制
creating build/lib.macosx-10.14-arm64-3.8
clang -bundle -undefined dynamic_lookup -arch arm64 -arch x86_64 -Wl,-headerpad,0x1000 build/temp.macosx-10.14-arm64-3.8/ops.o -o build/lib.macosx-10.14-arm64-3.8/ops.cpython-38-darwin.so

上述命令会在同级目录下生成 ops.c 的文件以及一个 build 文件夹,在 build 文件夹里面有temp 文件 还有我们所需要的编译好的 .so文件。直接拷贝复用 .so 文件即可。

测试

创建测试文件

当前目录只有文件 ops.cpython-38-darwin.so , 在ipython中调用 ops.py中的 函数 ops_key

代码语言:javascript复制
In [4]: ls
build/                    ops.cpython-38-darwin.so* setup.py

In [5]: ll
total 328
drwxr-xr-x  4 yangyi  staff     128 10 20 23:54 build/
-rwxr-xr-x  1 yangyi  staff  160789 10 20 23:54 ops.cpython-38-darwin.so*
-rw-r--r--  1 yangyi  staff     112 10 20 23:51 setup.py

In [6]: from ops import ops_key

In [7]: ops_key('11111')
Out[7]: False

In [8]: ops_key('WmsdofwmPsyqQXIkBp')
Out[8]: True

注意事项

如果要打包的文件里面有引用其他文件目录下的 py 程序,执行的时候 会报错 ,搜索了资料,目前还没解决, 比如 ops.py 文件中

代码语言:javascript复制
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

from  log_base import init_log  ### 这一行会报错
alert_log = init_log('ops', 'info')
KEY = 'WmsdofwmPsyqQXIkBp'

def ops_key(k):
    alert_log.info('this is a test  func ')  
    if k == KEY:
      result = True
    else:
      result = False
    return result
代码语言:javascript复制
### temp 目录下的内容
 yangyi@yangyiDBA  ~/python/temp  ll
total 336
drwxr-xr-x  4 yangyi  staff   128B 10 20 23:54 build
-rw-r--r--  1 yangyi  staff   314B 10 21 00:06 old.ops_mod.py
-rwxr-xr-x  1 yangyi  staff   157K 10 20 23:54 ops.cpython-38-darwin.so
-rw-r--r--  1 yangyi  staff   116B 10 21 00:06 setup.py
drwxr-xr-x  4 yangyi  staff   128B 10 21 00:11 util

### util 目录下的内容
 yangyi@yangyiDBA  ~/python/temp/util  ll
total 328
-rw-r--r--@ 1 yangyi  staff   1.8K 10 21 00:06 log_base.py
-rwxr-xr-x  1 yangyi  staff   158K 10 21 00:08 ops_mod.cpython-38-darwin.so


### 从 其他文件夹 引用 util 中的 ops_mod  so 文件 
 yangyi@yangyiDBA  ~/python/temp  ipython3
Python 3.8.9 (default, Apr 13 2022, 08:48:06)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.28.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from util.ops_mod import ops_key
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-1-2166f8144e2a> in <module>
----> 1 from util.ops_mod import ops_key
~/python/temp/util/ops_mod.cpython-38-darwin.so in init ops_mod()
ModuleNotFoundError: No module named 'log_base'
In [2]:

0 人点赞