zoukankan      html  css  js  c++  java
  • Qt实战1.如何让Qt应用程序集成编译功能?

    1 需求描述

    1. 软件能够编译c/c++源代码;
    2. 软件内部实现编译功能,无需安装其它开发工具。

    2 设计思路

    2.1 如何实现?

    最开始的时候其实软件也是支持编译功能的,只是借助了Visual Studio开发工具中的编译器,这样用户在安装软件后还要安装Visual Studio才行,如此一来显得特别麻烦。后来想着把Visual Studio中的编译功能集成到软件中,但是发现可行性并不高。
    那,有没有一种简单可行的办法,让软件不安装Visual Studio也能够编译代码?答案是肯定,使用MinGW编译套件即可实现集成编译功能。

    MinGW,是Minimalist GNUfor Windows的缩写。它是一个可自由使用和自由发布的Windows特定头文件和使用GNU工具集导入库的集合,允许你在GNU/Linux和Windows平台生成本地的Windows程序而不需要第三方C运行时(C Runtime)库。

    2.2 如何获取MinGW编译套件?

    其实,在安装Qt的时候只要勾选了MinGW组件就能获取到套件,如下:

    ok,安装完成后套件就获取到套件了。
    套件路径示例:D:ProgramQtQt5.12.6Toolsmingw730_32

    2.3 如何集成?

    获取到套件后集成就很简单了,在Qt可执行程序目录下创建一个Tools目录(名字自拟),将mingw730_32中的内容全部复制进去即可。

    3 代码实现

    3.1 套件获取到了如何编译?

    完成上述步骤后,接下来就是写代码了,这里使用QProcess调用脚本的方式进行编译,编译过程信息可通过信号槽获取,然后显示到界面上,是不是感觉很专业。

    void CompileUtil::startCompilation(const QString &buildPath)
    {
        m_buildPath = buildPath;
    
        //清空构建目录下可执行程序
        clearFiles("exe");
    
        //创建构建脚本
        QFileInfo batInfo(QDir(buildPath), "build.bat");
    
        QFile file(batInfo.absoluteFilePath());
        file.open(QIODevice::WriteOnly);
    
        QTextStream out(&file);
        out << QString("set PATH=%1\Tools\bin;%PATH%").arg(QDir::toNativeSeparators(QApplication::applicationDirPath())) << endl;
        out << QString(QString("cd /D %1").arg(QDir::toNativeSeparators(buildPath))) << endl;
        out << QString("g++ *.cpp --verbose -o %1 -lwsock32").arg(OUTPUT_PROCESS_NAME) << endl;
        file.close();
    
        //执行构建脚本
        m_process.setWorkingDirectory(buildPath);
        m_process.setProcessChannelMode(QProcess::MergedChannels);
        m_process.start(batInfo.absoluteFilePath());
    }
    

    3.2 编译完成后获取可执行文件

    顺利的话,编译完成后会在源码路径生成exe可执行程序,这时便可获取到它了。

    QString CompileUtil::getExecuteFile()
    {
        QDir dir(m_buildPath);
        QFileInfoList infoList = dir.entryInfoList(QDir::Files);
    
        foreach (QFileInfo info, infoList) {
            if ("exe" == info.suffix().toLower()) {
                return info.absoluteFilePath();
            }
        }
    
        return QString();
    }
    

    3.3 复制可执行文件依赖的dll库

    此时,生成的可执行程序还不能直接执行,它依赖一些动态库,现在把相关动态库复制到可执行文件目录下。

    void CompileUtil::copyDependentDllFiles()
    {
        QDir sourceDir(QApplication::applicationDirPath() + "/Tools/bin");
        QDir destDir(m_buildPath);
    
        QStringList destList;
        QStringList sourceList;
    
        QFileInfoList infoList = sourceDir.entryInfoList(QDir::Files);
        foreach (QFileInfo info, infoList) {
            if ("dll" == info.suffix().toLower()) {
                sourceList.append(info.absoluteFilePath());
            }
        }
    
        infoList = destDir.entryInfoList(QDir::Files);
        foreach (QFileInfo info, infoList) {
            if ("dll" == info.suffix().toLower()) {
                destList.append(info.absoluteFilePath());
            }
        }
    
        foreach (QString fileName, sourceList) {
            if (!destList.contains(fileName)) {
                QFileInfo sourceInfo(fileName);
                QFileInfo destInfo(m_buildPath, sourceInfo.fileName());
    
                QFile file(fileName);
                file.copy(destInfo.absoluteFilePath());
            }
        }
    }
    

    这里的处理比较简单,直接把/Tools/bin目录下所有的dll复制过来,简单且有效。
    到此,通过集成的MinGW套件编译的可执行程序就可以正常执行了。

    4 总结

    让Qt应用程序集成编译功能步骤如下:

    1. 集成MinGW编译套件,其实就是一个目录;
    2. 编写并调用编译脚本;
    3. 复制依赖的dll文件。

    强烈建议MinGW位数和Qt应用程序位数保持一致。

    5 下载

    相关代码

  • 相关阅读:
    android代码控制seekbar的样式
    在Android中显示GIF动画
    一个带动画效果的颜色选择对话框控件AnimatedColorPickerDialog
    史上最强Android 开启照相或者是从本地相册选中一张图片以后先裁剪在保存并显示的讲解附源码
    Linux System Programming note 8 ——File and Directory Management
    Spring它不支持依赖注入static静态变量
    举例说,在命令模式(Command Pattern)
    log4j 日志大小限制 分成30一个 不按日期分日志 按大小分成 按生产日期
    JavaScript获取路径
    awk与sed:关于多行的样本
  • 原文地址:https://www.cnblogs.com/luoxiang/p/13447513.html
Copyright © 2011-2022 走看看