一个在ubuntu上开发的qt打包工具
文章目录
实现功能
具备2个功能
1、对可执行文件进行检查,找出需要调用那些库,并拷贝到和可执行文件一个文件夹中;
2、针对打包出现的问题,比如说:同一个库出现2个版本,进行搜素,找出那个库调用了冲突库;
一、软件界面
二、程序编写
1.mainwindow.ui
代码如下 :
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>795</width>
<height>577</height>
</rect>
</property>
<property name="windowTitle">
<string>Linux程序打包软件</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>选择exe所在路径</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>选择</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>目标库名称</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_2"/>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="pushButton_3">
<property name="text">
<string>搜索</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>打包信息</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_2">
<property name="text">
<string>打包</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QTextEdit" name="textEdit"/>
</item>
</layout>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
2.mainwindow.h
代码如下 :
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
typedef enum _CMD_TYPE_
{
user,
super
}CMD_TYPE;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
//调用QProcess执行命令
QString qprocess_exe_cmd( CMD_TYPE type ,QString cmd , QStringList arg );
//
void on_pushButton_2_clicked();
//批量拷贝文件
void copy_files( QStringList files );
void on_pushButton_3_clicked();
//查找库是否需要另一个库
bool find_needed_lib_has( QString lib_path , QString tar_lib );
private:
Ui::MainWindow *ui;
QString exe_path; //获取exe所在路径
QString exe_dir; //exe路径
QStringList lib_list_path; //库路径
};
#endif // MAINWINDOW_H
3.mainwindow.cpp
代码如下 :
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QProcess>
#include <QFileDialog>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
///
/// \brief MainWindow::on_pushButton_clicked
/// 获取exe所在路径
void MainWindow::on_pushButton_clicked()
{
QString home_path = ".";
if( !exe_path.isEmpty() )
home_path = exe_path;
exe_path = QFileDialog::getOpenFileName(this, tr("Open File"),
exe_path,
tr("*"));
QString log = "执行文件所在路径:" + exe_path;
ui->lineEdit->setText(log);
//获取exe路径
exe_dir = "";
QString path_temp = exe_path;
QStringList temp_list = path_temp.split("/");
for( auto path_temp = temp_list.begin() ; path_temp < temp_list.end() - 1 ; path_temp++ )
{
if( !path_temp->isEmpty() )
{
qDebug() << *path_temp;
exe_dir += R"(/)" + *path_temp;
}
}
exe_dir += "/";
log = "执行文件所在文件夹:" + exe_dir;
ui->textEdit->append(log);
}
///
/// \brief MainWindow::qprocess_exe_cmd
/// \param cmd
/// \param arg
/// \return
/// linux系统下软件打包工具
QString MainWindow::qprocess_exe_cmd( CMD_TYPE type , QString cmd , QStringList arg )
{
QProcess process;
QString cmd_temp;
//普通权限执行命令
if( type == user )
{
cmd_temp = cmd;
}
//超级管理员权限
if( type == super )
{
cmd_temp = "sh -c" ;
cmd_temp += " \"echo ";
cmd_temp += "930716"; //密码
cmd_temp += " | sudo -S ";
cmd_temp += cmd;
cmd_temp += "\"";
}
qDebug() << cmd_temp;
process.start(cmd_temp);
process.waitForFinished();
QString output = process.readAllStandardOutput();
QProcess::ProcessError err = process.error();
//qDebug() << output;
return output;
}
///
/// \brief MainWindow::copy_files
/// \param files
/// 批量复制文件
void MainWindow::copy_files( QStringList files )
{
for(auto file : files )
{
QString temp_file = file;
QStringList List_temp = temp_file.split("/");
QString cmd = "cp " + file + " " + exe_dir + List_temp.at(List_temp.size()-1);
//qDebug() << cmd;
qprocess_exe_cmd(super,cmd,QStringList());
}
}
///
/// \brief MainWindow::on_pushButton_2_clicked
/// 执行打包命令
void MainWindow::on_pushButton_2_clicked()
{
QString cmd = "ldd " + exe_path;
qDebug() << cmd;
QString cmd_ldd = qprocess_exe_cmd( user ,cmd , QStringList());
ui->textEdit->append(cmd_ldd);
ui->textEdit->append("解析后需要的库:");
//解析
QStringList lib_name = cmd_ldd.split("\n\t");
for( auto str : lib_name )
{
qDebug() << str;
}
//解析lib
QStringList lib_path_list;
for( auto str : lib_name )
{
QStringList list_temp = str.split(" ");
if( list_temp.size() > 2 )
{
lib_path_list.push_back(list_temp.at(2));
ui->textEdit->append(list_temp.at(2));
}
}
//赋值文件到当地
copy_files(lib_path_list);
lib_list_path = lib_path_list;
}
///
/// \brief MainWindow::find_needed_lib_has
/// \param lib_path:库全路径
/// \param tar_lib:目标库
/// \return
///
bool MainWindow::find_needed_lib_has( QString lib_path , QString tar_lib )
{
QString cmd = "ldd " + lib_path;
QString cmd_ldd = qprocess_exe_cmd( user ,cmd , QStringList());
//
return cmd_ldd.contains(tar_lib, Qt::CaseInsensitive);
}
///
/// \brief MainWindow::on_pushButton_3_clicked
/// 搜索那个库使用了目标库
void MainWindow::on_pushButton_3_clicked()
{
QString tar_lib = ui->lineEdit_2->text();
QRegExp reg(".so*");
//查看输入的是否是.so文件
//if( reg.exactMatch(tar_lib) )
{
//查找
for( auto lib : lib_list_path )
{
if( find_needed_lib_has(lib,tar_lib) )
{
QString log = R"(<font color = "#0000FF">)";
log += lib;
log += "需要";
log += tar_lib;
log += R"(<\font>)";
ui->textEdit->append(log);
}
}
}
//else
{
// ui->textEdit->append(R"(<font color= "#FF0000" >输入的不是.so名,请检查</font>)");
}
}
4.总结
1、主要是利用linux ldd 命令对可执行文件进行分析,提取ldd命令输出;
2、涉及利用QProcess执行超级用户命令;
三、开源下载链接
地址:qitee下载地址
四、打包之后可能遇到的问题
- 无法启动可执行文件,是因为库所在路径不是系统默认加载的动态库路径,设置环境变量就可以,因此可以编写启动脚本
#! /bin/bash
export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH
./intelligent_inspection_robot