使用其他编译器编译QT代码

Compiling QT code with other compilers

本文关键字:QT 代码 编译 编译器 其他      更新时间:2023-10-16

我正在编译执行数值密集型计算的科学代码。我的流程如下:

针对CPU的代码由"英特尔C++编译器"编译
针对GPU的代码由NVCC
然后使用"英特尔C++编译程序"链接对象文件

为此,我编写了一个makefile来执行必要的步骤,所有操作都在命令行中执行。现在,我想在程序中添加一个GUI,使用Qt,但不使用QtCreator。作为测试,我正在尝试编译这里给出的"Hello World!桌面应用程序":https://wiki.qt.io/Getting_Started_on_the_Commandline

我的解释如下:

#include <QtGuiQtGui>
#include <QtWidgetsQApplication>
#include <QtWidgetsQLabel>
void test_qt()
{
QApplication app();
QLabel label("Hello, world!");
label.show();
app.exec();
}

我在一个main.cpp文件中调用该函数。在我的makefile中,我链接了Qt5core.lib、Qt5Gui.lib和Qt5Widgets.lib,根据makefile规则,这是用英特尔C++编译器编译的。然而,它给出了以下错误:

error: expression must have class type  
app.exec();  
^

我的问题如下:如何编辑我的makefile来编译Qt代码?我将需要信号和插槽,因此可能需要moc,根据我可以在没有qmake或Qt Creator的情况下使用Qt吗?但我不会使用uic。

根据以下讨论进行更新:

查看QApplication构造函数引用,它似乎是用main()中获得的命令行参数argc和argv初始化的。这使得可以将Qt特定的标志传递给Qt基础设施。因此,不能像您的示例中那样在没有参数的情况下创建它——您需要从main传递argc和argc。

至于编译包含信号和插槽的文件,这些功能不是标准的C++,因此需要通过知道其含义的工具对其进行预处理。如果我理解正确的话,moc将这些Qt特定的特性转换为标准C++代码,然后必须使用编译器进行编译。因此:

  1. 对Qt特定的cpp文件使用命名约定,这样您就可以创建一个makefile模式来用moc处理它们。例如:文件.moc.cpp
  2. 在makefile中创建对file.cpp的依赖项,该依赖项依赖于file.moc.cpp
  3. 创建一个从.moc.cpp文件创建.cpp文件的规则,并在该规则中调用moc
  4. 对.cpp文件调用普通编译器。不要忘记您的包含目录等
  5. 请确保您没有签入这些生成的文件,因为每次.moc.cpp文件更改时,它们都会更改。也许可以将它们转储到被您的修订控制忽略的临时目录中?您可能想四处搜索,看看其他示例项目是如何做到这一点的

旁注:在不使用括号的情况下声明app可能会导致出现the Most Vexing Parse的情况。https://en.wikipedia.org/wiki/Most_vexing_parse

当声明了一个对象,但括号为空时,编译器最终会将该行解释为一个不带参数并返回QApplication的函数的函数原型。