不借助第三方工具打包QT程序

准备工作:

项目/可执行文件名:QTAppName

打包项目存放的文件名:pack(这个文件名无所谓)

脚本名:

copylib.sh(类似ldd命令):用于将.so库文件的依赖项复制并放入自动生成的 “lib文件” 中。

QTAppName.sh(注:该脚本名为"可执行文件名.sh")“:用于最后执行可执行文件的脚本

  1. 将Qt项目使用Release模式编译运行一遍,确保生成可执行文件 QTAppName
  2. 脚本编写:

copylib.sh

#!/bin/bash
LibDir=$PWD"/lib"
Target=$1lib_array=($(ldd $Target | grep -o "/.*" | grep -o "/.*/[^[:space:]]*"))$(mkdir $LibDir)
for Variable in ${lib_array[@]}
docp "$Variable" $LibDir
done

QTAppName.sh

#!/bin/sh
appname=`basename $0 | sed s,\.sh$,,`dirname=`dirname $0`
tmp="${dirname#?}"if [ "${dirname%$tmp}" != "/" ]; then
dirname=$PWD/$dirname
fi
LD_LIBRARY_PATH=$dirname
export LD_LIBRARY_PATH
$dirname/$appname "$@"
  1. 权限给予

chmod 777 copylib.sh QTAppName.sh

开始打包

  1. 获得可执行文件的依赖

  • 将copylib.sh拷贝进对应项目的构建/build目录(例如:build-SmartCheckImgWidget_4_3-Desktop_Qt_5_15_2_GCC_64bit-Release)
  • 在Terminal中,输入./copylib.sh QTAppName
  • 将① QTAppName的可执行程序、② lib文件夹里面全部的文件**(不是直接复制lib文件夹,是文件夹的内容)** 复制到 pack文件夹中;
  • 复制完毕后,将lib文件夹删除即可。
  1. 获取Qt依赖

  • 进入Qt的安装目录,并将copylib.sh拷贝qt中的platforms目录下(我的目录:/opt/Qt/5.15.2/gcc_64/plugins/platforms)。
  • 执行 ./copylib.sh libqxcb.so(注:xcb是移植的重要文件,如果拷贝错误将不能在目标主机运行。)
  • 回到plugins(platforms的上级目录)将platforms整个文件夹拷贝到pack
  • 将libqxcb.so依赖库文件夹pack/platforms/lib/*)的东西全部放到pack目录下(可能会有重复项替换即可)。并删除pack/platforms/lib文件夹及其所属文件。(最后记得将原来Qt/5.15.2/gcc_64/plugins/platform/lib也删除了,虽然不删除也没啥事)
  1. 其他 + 扫尾工作

若是还有其他依赖项目,如:所编写的程序有操作数据库的动作,还需要将与platforms同级目录中的sqldrivers文件夹也拷贝到“pack文件夹”中

QTAppName.sh放入pack,并使用 ./QTAppName.sh 调用测试是否成功

可能问题:

问题一:打包后在其他设备上尝试 ./QTAppName.sh 运行,报错Inconsistency detected by ld.so: dl-deps.c: 622: _dl_map_object_deps: Assertion `nlist > 1‘ failed!

解决方案:该问题大概率是由libc(该库是linux底层的一个基本库)的版本不一致导致的,可以使用以下命令查看libc版本

ldd --version

在这里插入图片描述

若是版本不一致可以尝试更新libc6,但是并不推荐该方法,因为这是一个底层库这样做可能有风险,且该库的高版本并不一定兼容低版本,手动安装指定版本,系统可能会在安装的过程中崩溃。

sudo apt-get update
sudo apt-get install libc6

**推荐方法:**使打包主机和运行的环境主机的版本号(不是内核版本)一致,且没有更新过

cat /etc/os-release    //可以查看发行版本

问题二:依赖缺失

解决方案:

  • 模块缺失在上文的开始打包中仿照Qt依赖项的获取,添加对应的依赖即可
  • .so库的依赖缺失:使用ldd命令,查看库的依赖情况
ldd 依赖库名.so

决方案:

  • 模块缺失在上文的开始打包中仿照Qt依赖项的获取,添加对应的依赖即可
  • .so库的依赖缺失:使用ldd命令,查看库的依赖情况
ldd 依赖库名.so

尝试使用find查询打包主机上对应依赖项,并添加

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/811958.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vscode远程免密登录ssh

vscode远程免密登录ssh 1. 安装vscode2. 安装ssh3. 本地vscode配置免密登录远端开发机1. 本地配置秘钥2. 远程开发机配置秘钥 4. vscode常用小工具1. vscode怎么设置ctrl加滚轮放大字体 1. 安装vscode 2. 安装ssh 设置符号打开config配置文件,点击符号ssh连接新的远…

4. Django 探究FBV视图

4. 探究FBV视图 视图(Views)是Django的MTV架构模式的V部分, 主要负责处理用户请求和生成相应的响应内容, 然后在页面或其他类型文档中显示. 也可以理解为视图是MVC架构里面的C部分(控制器), 主要处理功能和业务上的逻辑. 我们习惯使用视图函数处理HTTP请求, 即在视图里定义def…

A complete evaluation of the Chinese IP geolocation databases(2015年)

下载地址:A Complete Evaluation of the Chinese IP Geolocation Databases | IEEE Conference Publication | IEEE Xplore 被引用次数:12 Li H, He Y, ** R, et al. A complete evaluation of the Chinese IP geolocation databases[C]//2015 8th International Conference…

2024年MathorCup数学应用挑战赛A题思路分析

文章目录 题目简介题目背景和重要性题目要求和目标 题目分析和解题思路理解PCI规划的基本原则PCI参考算法 建立数学模型定义决策变量建立目标函数确定约束条件唯一性约束:确保每个小区的PCI在整个网络中是唯一的。 设计优化算法目标函数分析约束条件分析问题规模分析…

客户端传日期格式字段(String),服务端接口使用java.util.Date类型接收报错问题

客户端传日期格式字段(string),服务端接口使用java.util.Date类型接收报错问题 问题演示第1种:客户端以URL拼接的方式传值第2种:客户端以body中的form-data方式提交第3种 客户端以Body中的json方式提交 问题解决(全局解…

softmax回归:多分类问题的解码器

随着人工智能技术的不断发展,分类问题在机器学习领域中的地位日益凸显。在众多分类算法中,softmax回归以其独特的优势和广泛的应用场景,成为了处理多分类问题的有力工具。本文将深入探讨softmax回归的原理、应用及其优缺点,以期为…

pytorch-多分类实战之手写数字识别

目录 1. 网络设计2. 代码实现2.1 网络代码2.2 train 3. 完整代码 1. 网络设计 输入是手写数字图片28x28,输出是10个分类0~9,有两个隐藏层,如下图所示: 2. 代码实现 2.1 网络代码 第一层将784降维到200,第二次使用…

ChatGPT基础(二) ChatGPT的使用和调优

文章目录 ChatGPT的特性采用关键词进行提问给ChatGPT指定身份提升问答质量的策略1.表述方式上的优化2.用"继续"输出长内容3.营造场景4.由浅入深,提升问题质量5.预设回答框架和风格 ChatGPT的特性 1.能够联系上下文进行回答 ChatGPT回答问题是有上下文的&…

uni-app web端使用getUserMedia,摄像头拍照

<template><view><video id"video"></video></view> </template> 摄像头显示在video标签上 var opts {audio: false,video: true }navigator.mediaDevices.getUserMedia(opts).then((stream)> {video document.querySelec…

【python】在pycharm创建一个新的项目

双击打开pycharm,选择create new project 选择create,后进入项目 右键项目根目录,选择new一个新的python file 随意命名一下 输入p 然后后面就会出现智能补全提示,此时轻敲一下tab,代码就写好了,非常的方便 右键执行一下代码,下面两个直接运行和debug运行都是可以的 小结 …

CentOS 8服务器搭建L2TP服务器(over IPsec)操作指南

正文共&#xff1a;1234 字 14 图&#xff0c;预估阅读时间&#xff1a;2 分钟 之前发过把我自己的服务器搬上公网的文章&#xff08;我用100块钱把物理服务器放到了公网&#xff0c;省了几万块&#xff01;&#xff09;&#xff0c;当时L2TP拨号用的是网络上的解决方案&#x…

微服务整合Spring Cloud Gateway动态路由

前置 创建 Spring Cloud项目 参考&#xff1a;创建Spring Cloud Maven工程-CSDN博客 1. 创建一个maven jar类型项目 在idea中右键父工程-》New-》Module 创建一个maven工程 2. 引入相关依赖 在POM文件中引入下面的依赖 <project xmlns"http://maven.apache.org/P…

C++设计模式|创建型 1.单例模式

1.什么是单例模式&#xff1f; 单例模式的的核⼼思想在创建类对象的时候保证⼀个类只有⼀个实例&#xff0c;并提供⼀个全局访问点来访问这个实例。 只有⼀个实例的意思是&#xff0c;在整个应⽤程序中&#xff0c;只存在该类的⼀个实例对象&#xff0c;⽽不是创建多个相同类…

【JAVA基础篇教学】第八篇:Java中List详解说明

博主打算从0-1讲解下java基础教学&#xff0c;今天教学第八篇&#xff1a;Java中List详解说明。 在 Java 编程中&#xff0c;List 接口是一个非常常用的集合接口&#xff0c;它代表了一个有序的集合&#xff0c;可以包含重复的元素。List 接口提供了一系列操作方法&#xff0c;…

72V电瓶电压降5V1.5A恒压WT7039

72V电瓶电压降5V1.5A恒压WT7039 WT6039是一款12V至72V宽电压降压DC-DC转换器芯片&#xff0c;集成了开关控制、参考电源、误差放大器等多重功能&#xff0c;并具备过热、限流和短路保护。它能在广泛输入功率下实现2A连续输出电流&#xff0c;并通过编程调整输出电压。适用于高…

文心一言

文章目录 前言一、首页二、使用总结 前言 今天给大家带来百度的文心一言,它基于百度的文心大模型,是一种全新的生成式人工智能工具。 一、首页 首先要登录才能使用,左侧可以看到以前的聊天历史 3.5的目前免费用,但是4.0的就需要vip了 二、使用 首先在最下方文本框输入你想要搜…

npm问题合集以及npm常规操作整理

问题一&#xff1a;npm install 卡在“sill idealTree buildDeps“ 可以尝试将网络切换为其他网络&#xff0c;我的是这么解决的。可以尝试重新设置镜像。 问题二&#xff1a;npm install 项目依赖报WARN deprecated 原因 依赖版本问题&#xff0c;下载最新版本。 解决方案 …

ElasticSearch中使用bge-large-zh-v1.5进行向量检索(一)

一、准备 系统&#xff1a;MacOS 14.3.1 ElasticSearch&#xff1a;8.13.2 Kibana&#xff1a;8.13.2 BGE是一个常见的文本转向量的模型&#xff0c;在很多大模型RAG应用中常常能见到&#xff0c;但是ElasticSearch中默认没有。BGE模型有很多版本&#xff0c;本次采用的是bg…

vue和react通用后台管理系统权限控制方案

1. 介绍 在任何企业级应用中&#xff0c;尤其是后台管理系统&#xff0c;权限控制是一个至关重要的环节。它确保了系统资源的安全性&#xff0c;防止非法访问和操作&#xff0c;保障业务流程的正常进行。本文件将详细解析后台管理系统中的权限控制机制及其实施策略。 那么权限…

算法思想总结:分治思想

一、颜色划分 . - 力扣&#xff08;LeetCode&#xff09; class Solution { public:void sortColors(vector<int>& nums) {//三路划分的思想int nnums.size();int left-1, rightn,cur0;while(cur<right){if(nums[cur]0) swap(nums[left],nums[cur]);else if(nums…