ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

利用cx_Freeze在linux下打包python程序

2021-11-28 14:32:56  阅读:174  来源: 互联网

标签:python setup py 程序 Freeze cx file path os


Linux 下打包方法总结

1. 安装 patchelf

  在安装 patchelf 前,须保证系统安装 wget、autoconf、automake、libtool 等工具,安命令如下:

sudo apt install wget autoconf automake libtool -y

  1.1 使用以下命令下载patchelf:

wget https://github.com/NixOS/patchelf/archive/refs/tags/0.12.tar.gz

  1.2 使用以下命令解压并进入该文件夹

tar -axf  0.12.tar.gz
cd patchelf-0.12/

在这里插入图片描述
  1.3 依次输入并运行./bootstrap.sh./configure以及make命令
  1.4 输入并运行make install命令,若出现文件拒绝访问的错误,可改用sudo make install命令解决。
在这里插入图片描述
  1.5 安装完成后,使用patchelf –version命令验证安装是否成功。
在这里插入图片描述

2. 使用cx_Freeze进行打包

  本文使用 cx_Freezeidna 进行打包,下载命令为 pip install cx_Freeze idna
  2.1 在需打包的目录下,复制附录代码中的 setup.pyslim.pyone_step.py 粘贴到需打包程序入口文件的同级目录下,修改setup.py文件,将Executable函数内的路径改为程序的入口文件,将用到的包的名字以字符串列表的形式写入packages。需要特别注意的是,程序下自己写的包,包括下级及以上目录下的自己写的文件需要按照下图所示写入到packages中,粒度为文件,无需对文件内的函数进行标识
在这里插入图片描述
  2.2 若需要移入文件,则需要修改setup.py文件中的列表include_files。列表的每一项可以为待移入文件的路径,也可以为由源地址与目的地址组成的二元组,且目的地址只可为相对路径
  2.3 可以对setup.pysetup函数的nameversiondescription等等参数进行修改,修改后的name将作为程序名。也可以在Executable函数内添加icon参数,给程序增加图标
  2.4 使用python3 setup.py build命令对程序进行打包,打包后的文件可能会缺失部分pytorch的lib和bin文件,需要手动移入,目前尚未找到问题原因。同时可以修改并运行附件one_step.py来解决,详情见4.半自动化处理

3. 追踪程序

  3.1 使用以下命令对程序进行追踪,如strace -f -F -o ./dcop-strace.txt ./build/exe.linux-x86_64-3.8/api_server。此命令将运行./build/exe.linux-x86_64-3.8/api_server程序,追踪程序对文件操作的系统调用,结果将保存在dcop-strace.txt

strace -f -F -o ./dcop-strace.txt app_name

  3.2 保持3.1中的命令的运行,对程序进行详细的测试后,按Ctrl+C终止strace命令
  3.3 修改slim.py文件中的路径并运行,即可完成瘦身

4.半自动化处理

  本文提供了半自动化处理脚本one_step.py,读者可修改其中的代码以加快速度。由于未进行详细测试,因此不保证脚本的安全性和可用性,请谨慎使用。
  在进行以下步骤前,请确保setup.pyslim.py已完成修改。
  4.1 修改path_torchtorch的路径,修改path_dist_app,如’./build/exe.linux-x86_64-3.8’,linux表示目标程序的运行系统(不同的linux系统可能也会有区别),x86_64为处理器架构,3.8python的版本,读者可根据具体情况进行修改。
  4.2 修改app_name,使之成为运行生成程序的命令,如

./build/exe.linux-x86_64-3.8/api_server

4.3 运行one_step.py脚本,脚本会两次打开生成的程序。第一次为记录程序访问过的文件,因此需要在运行期间进行详细测试,测试完成后,按Ctrl+C终止测试;第二次打开程序为瘦身后验证程序的可执行性,按需进行验证即可。

代码附录

one_step.py

import os 
import shutil


#troch存在的目录
path_torch='/home/lfyu/.local/lib/python3.8/site-packages/torch' 

#生成程序的目录,需要根据说明文档进行修改
path_dist_app=r'./build/exe.linux-x86_64-3.8'

#生成程序的程序名,需和setup.py内的name保持一致
app_name=path_dist_app+'/api_server'

#使用cx_Freeze进行打包,在运行脚本前需要根据说明文档修改setup.py
os.system('python3 setup.py build')


print('Build app success,starting to copy lack file...')

#复制可能会缺少的库文件
def copydirs(from_file, to_file):
    if not os.path.exists(to_file):
        os.makedirs(to_file)
    files = os.listdir(from_file)
    for f in files:
        if os.path.isdir(from_file + '/' + f): 
            copydirs(from_file + '/' + f, to_file + '/' + f)
        else:
            shutil.copy(from_file + '/' + f, to_file + '/' + f)


copydirs(path_torch+'/lib',path_dist_app+'/lib/torch/lib')
copydirs(path_torch+'/bin',path_dist_app+'/lib/torch/bin')

print('Complete the copy of the file,please starting to test your program!')

#追踪程序的系统调用,需要进行详细的测试
os.system('strace -f -F -o ./dcop-strace.txt {:s}'.format(app_name))

print('Complete the test and start the program to slim down!')

#运行瘦身程序
os.system('python3 slim.py')

print('Slimming is complete, the dist program opens again to help you test availability!')

#验证程序的可行性
os.system(app_name)

steup.py

from cx_Freeze import setup, Executable

base = None    

executables = [Executable("api_server.py", base=base)]

packages = ['idna','cv2','numpy','traceback',
'onnxruntime','flask','openpyxl','torch',
'dominate','yaml','requests','tqdm','base64','time','json',
'utils.torch_utils','utils.activations','utils.autoanchor','utils.datasets','utils.general','utils.loss','utils.google_utils','utils.metrics']

include_files=[('./models/best.onnx','./models/best.onnx')]
options = {
    'build_exe': {    
        'packages':packages,
        'include_files':include_files
    },    
}

setup(
    name = "api_server",
    options = options,
    version = "0.0.1",
    description = '<any description>',
    executables = executables
)

slim.py

import glob 
import os 

path_txt=r'./dcop-strace.txt'
path_lib=r'./build/exe.linux-x86_64-3.8/lib'
fp=open(path_txt)
file=[os.path.abspath(line.split('"')[1]) for line in fp.readlines() if '"' in line]

size1=0
size2=0

def find_file(path):
    global size1,size2
    for p in glob.glob(path+'/*'):
        p=os.path.abspath(p) 
        if os.path.isfile(p) :
            size1=size1+os.path.getsize(p)
            if p not in file:
                size2=size2+os.path.getsize(p)
                print('removing file: %s',p)
                os.remove(p)
        else:
            find_file(p)


cnt=0

def delete_gap_dir(dir):
    global cnt
    if os.path.isdir(dir):
        for d in os.listdir(dir):
            delete_gap_dir(os.path.join(dir, d))
        if not os.listdir(dir):
            os.rmdir(dir)
            cnt=cnt+1

find_file(path_lib)
delete_gap_dir(path_lib)
print('Success,reduced {}MB files and {} file folders'.format((size2)/(1024**2),cnt))

标签:python,setup,py,程序,Freeze,cx,file,path,os
来源: https://blog.csdn.net/weixin_42457073/article/details/121590678

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有