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 下载

    相关代码

  • 相关阅读:
    加油 ^_^
    ES6 小记
    Angular2 初学小记
    Round 4
    react中iconfont字体图标不显示问题
    react 实现组件嵌套以及子组件与父组件之间的通信
    wamp&花生壳 在本地搭建自己的网站
    深入浅出CSS(二):关于雪碧图、background-position与steps函数的三角恋情
    深入浅出CSS(一):line-height与vertical-align的性质
    十进制字符编号
  • 原文地址:https://www.cnblogs.com/luoxiang/p/13447513.html
Copyright © 2011-2022 走看看