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

相关代码

原文地址:https://www.cnblogs.com/luoxiang/p/13447513.html