0

I am compiling scientific code that performs numerically intensive calculations. My process is the following:

Code targeted for the CPU is compiled by the Intel C++ Compiler
Code targeted for the GPU is compiled by NVCC
The object files are then linked using the Intel C++ Compiler

To do this, I have written a makefile to perform the necessary steps, and everything is carried out on the command line. Now, I wish to add on a GUI to the program, using Qt, but without using Qt Creator. As a test, I am trying to compile the "Hello World! Desktop application" given here: https://wiki.qt.io/Getting_Started_on_the_Commandline

My interpretation is as follows:

#include <QtGui\QtGui>
#include <QtWidgets\QApplication>
#include <QtWidgets\QLabel>

void test_qt()
{
    QApplication app();
    QLabel label("Hello, world!");
    label.show();
    app.exec();
}

I call the function in a main.cpp file. In my makefile, I link with Qt5core.lib, Qt5Gui.lib and Qt5Widgets.lib, and as per the makefile rules, this is compiled with the Intel C++ compiler. However, it gives the following error:

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

My question is as follows: How can I edit my makefile to compile Qt code? I will be needing signals and slots, so moc may be needed according to Can I use Qt without qmake or Qt Creator? but I will not be using uic.

HamzaAB
  • 67
  • 6

1 Answers1

0

Update based on the discussion below:

Looking at the QApplication constructor reference, it would appear that it is initialized with the command line arguments argc and argv obtained in main(). This makes it possible to pass Qt-specific flags to the Qt infrastructure. Thus, it cannot be created with no arguments as in your example -- you need to pass argc and argc from main.

As for compiling the files containing signals and slots - these features are not standard C++, so they need to be preprocessed by a tool that knows what they mean. If I understand correctly, moc converts these Qt-specific features into standard C++ code which must then be compiled using your compiler. So:

  1. Use a naming convention for your Qt-specific cpp files so you can create a makefile pattern to process them with moc. ex: file.moc.cpp
  2. Create a dependency on file.cpp in your makefile, which depends on file.moc.cpp
  3. Create a rule for creating .cpp files from .moc.cpp files and invoke moc in that rule.
  4. Call your normal compiler on the .cpp files. Don't forget your include directories, etc.
  5. Make sure you do not check in these generated files, as they will change each time your .moc.cpp file changes. Maybe dump them in a temp directory that is ignored by your revision control? You may want to search around to see how other sample projects do it.

Side Note: declaring app without the parentheses could lead to a case of The Most Vexing Parse. https://en.wikipedia.org/wiki/Most_vexing_parse

When an object is declared, but the parentheses are empty, the compiler ends up interpreting the line as a a function prototype for a function that takes no arguments and returns a QApplication.

BareMetalCoder
  • 569
  • 5
  • 17
  • I then get the following error: no default constructor exists for class "QApplication" – HamzaAB Jul 17 '18 at 12:43
  • @HamzaAB Check the [documentation](http://doc.qt.io/qt-5/qapplication.html#QApplication) for the `QApplication` ctor. – G.M. Jul 17 '18 at 12:48
  • @BareMetalCoder doing so still gives me the same error at the point where I perform `app.exec()`, which it seems is the problem area. I will now check adding argc & argv. – HamzaAB Jul 17 '18 at 12:53
  • Looks like I'm too rusty here - have you taken a look at https://stackoverflow.com/questions/11395562/what-is-qapplication-appargc-argv-trying-to-do ? I have updated my response accordingly – BareMetalCoder Jul 17 '18 at 12:56
  • @BareMetalCoder argc & argv do the job! If I wish to use signals and slots, do I call moc on files that contain them and then link the generated object files using any c++ compiler? – HamzaAB Jul 17 '18 at 13:43
  • @HamzaAB - Unfortunately, I am not familiar with that process. However, it would seem that `moc` converts a Qt file containing signals and slots into a standard CPP file that can be compiled (signals and slots and Q_OBJECT code are likely stripped out and replaced with standard C++ code). So step 1: use `moc` to convert the "QT" .cpp files into standard .cpp files, then use your compiler to compile the generated .cpp files (and don't check these generated files into revision control!). The link you provided above gives you a good start. – BareMetalCoder Jul 17 '18 at 14:01
  • @BareMetalCoder Thank you for your input. I think I am now getting somewhere with moc. I think you should add that to the main answer, as you were correct. – HamzaAB Jul 17 '18 at 21:33
  • My pleasure, to be honest, it was a bit of a learning experience for me too. :) – BareMetalCoder Jul 18 '18 at 12:52