PDA

View Full Version : qmake behavior



Radek
19th August 2013, 08:35
For some unknown reason, my qmake seems to ignore changes in header files and in .ui files. Only newer "source code" files are processed. When I make a change in a *.hpp or in a *.ui, the project isn't recompiled properly. I need to rebuild the whole project whenever I update a *.hpp or .ui .

As long as the project is small, it is a nuisance but so be it. As the project grows, the need for rebuilding becomes less and less bearable. At present, I have about 80 files and I am calling help: Every time I make a change in a single .hpp which affects only a few files in the project, I have to recompile everything. I know that the project will be bigger and that I will continue tuning my headers...

I am using standard tools: Qt Creator and Qt Designer. Debian Wheezy KDE, 64-bit, Qt 4.8.2 . What should I set to persuade "build" of the Creator to take changed headers into consideration?

wysota
19th August 2013, 09:09
Can you show us your .pro file?

Radek
19th August 2013, 09:24
viewer-qt.pro



TEMPLATE = app
TARGET = viewer-qt
FORMS = viewer.ui \
opendlg.ui
QT = core gui
QMAKE_CXXFLAGS += -std=c++11
INCLUDEPATH += hpp
RESOURCES = viewer.qrc
LIBS += /usr/lib/libkdeui.so

HEADERS += \
hpp/myframe.hpp \
hpp/myapp.hpp \
hpp/tree.hpp \
hpp/treeitem.hpp \
hpp/text.hpp \
hpp/appconf.hpp \
hpp/treetraverser.hpp \
hpp/dirtraverser.hpp \
hpp/opendlgitem.hpp \
hpp/opendlg.hpp \
hpp/textparser.hpp

SOURCES += \
main/main.cpp \
myapp/myapp-ctor1.cpp \
myapp/myapp-dtor.cpp \
myframe/myframe-ctor1.cpp \
myframe/myframe-dtor.cpp \

<other .cpp files follow>
<end of profile, no other commands follow>

wysota
19th August 2013, 09:42
The project file looks ok, provided that in your source files refer to the header files using appropriate paths. GCC should be able to detect dependencies then and the project should be rebuilt automatically. If this does not happen, then most probably your include statements are not correct. Somehow gcc cannot generate proper dependency information.

Radek
19th August 2013, 10:41
The #includes, placements and compiler settings should be ok, Wysota. Otherwise, rebuild would not build correctly. The problem seems to consist in the KDE build of Qt somehow. I do not believe that Qt itself is buggy - there are too many Qt users around.

wysota
19th August 2013, 12:00
Rebuild is one thing, dependency generation is another. The issue you have is not related to Qt but rather more to "gcc -E" and is likely caused by your project configuration (and by that I mean not only the project file but also your actual source code).

Radek
19th August 2013, 15:41
The code is a completely standard one, all headers are included using #include. The project configuration is default. I haven't meddled with this at all. I have written a core or the .pro file (lines 1 .. 9) and let the Creator to do the rest.

The only possible suspect can be #pragma once instead of #ifndef #define #endif (I prefer #pragma once from #ifndef etc.). I am sure that g++ processes #pragma once correctly. Does Qt Creator dependency building process #pragma once correctly?

wysota
19th August 2013, 15:53
The code is a completely standard one, all headers are included using #include.
It is not as your source files reside in different directories. I would consider a "standard" code layout such, that is all within a single directory.


Does Qt Creator dependency building process #pragma once correctly?
Qt Creator does not do any dependency building. QMake does through your compiler (e.g. gcc -M). From what I see there is a number of threads in the Internet about issues with dependency generation for files scattered across different directories. As a simple experiment I'd suggest to move all your source files to one directory, all your header files to a second directory and see if the problem persists.

Radek
19th August 2013, 17:11
IMO, it's not a GCC problem. In my Gnome times, I developed with Code Blocks and wxWidgets and I never met a problem like this. But then Gnome 3 arrived and I run away from Gnome as fast as I could. KDE is okay for me but I have lost both wxWidgets and Code Blocks. Therefore, Qt.

I will return to rebuilding. A single directory is unmanageable for me even if it solved my problem.

wysota
19th August 2013, 19:37
IMO, it's not a GCC problem. In my Gnome times, I developed with Code Blocks and wxWidgets and I never met a problem like this.
I don't have such problems with Qt as well however since the only two tools involved in building your project are make and the compiler, somehow it doesn't suprise me. "Qt" (read qmake) is not part of the build chain here.

ChrisW67
19th August 2013, 21:43
This is an experiment, not a description of a solution I know works...
Try adding


DEPENDPATH += hpp

To the pro fle and rerun qmake. Inspect the Makefile to see what each cpp file is dependent on efore and after doing this.

Radek
20th August 2013, 06:13
Thanks ChrisW67! This seems to work! I added "int trythis;" into a header, recompiled (not so long recompiling, not everything got rebuilt evidently), run debug and inspected the class. It contained "trythis" as it should do. My makefile now contains references to header files. It did not before.

wysota
20th August 2013, 08:16
Out of curiosity (I didn't get a response last time I indirectly asked about it) -- how exactly do you include statements look like? Do they use relative paths? I mean do they look like:


#include "../hpp/myframe.hpp"

or rather


#include "myframe.hpp" // or <myframe.hpp>

?

If DEPENDPATH helps then it is likely you are using the latter.

Radek
20th August 2013, 18:08
#include <myframe.hpp> with all my headers. That's why I have set INCLUDEPATH.

wysota
20th August 2013, 18:35
For that you need DEPENDPATH as well :)

See the docs (underlined by me):




This variable contains the list of all directories to look in to resolve dependencies. This will be used when crawling through included files.

INCLUDEPATH is only used for compilation (e.g. it makes no sense to make your app dependent of /usr/include/*, right?).

starling13
6th February 2014, 09:12
I don't wish to start new thread for this small question:

I have the source code tree of existing project, where every .cpp file for class, inherited from QObject, ends with inclusion of "class_name.moc" file.
I try to make the Qt project file to use with QtCreator for this sources.
The problem is in that qmake generates makefile, where *.cpp file depends on corresponding *.moc file, but the *,moc file rules only generated for *.cpp, wich declares private classes, inherited from QObject.

Is it possible to generate makefile with rules to make *.moc files for every *.cpp with *.moc inclusion?

Example:
class1.h


#include <qt4/QtCore/QObject>
class Class1 : public QObject
{
Q_OBJECT
public:
Class1();
};


class1.cpp


#include "class1.h"

Class1::Class1()
{
}
#include "class1.moc"


class1.pro


TEMPLATE = lib
INCLUDEPATH += .

HEADERS += class1.h
SOURCES += class1.cpp


qmake
make
...
No rule to make target `class1.moc', needed by `class1.o'.

But if cpp will be modified:
class1.cpp


#include "class1.h"

class Private : public QObject
{
Q_OBJECT
};

Class1::Class1()
{
}

#include "class1.moc"

then lib is generated correctly.

Radek
6th February 2014, 12:05
I have seen such #includes, too, but, luckily, I didn't need to compile it :) I am still a beginner but, IMO, the *.moc files are some relic of Qt3. In a Qt4 project, you do not create *.moc files. AFAIK, the *.moc files aren't a part of a Qt4 project directly: you find files like moc_class1.o in the compiled project but no class1.moc file.

I recommend checking whether the *.moc files contain something what should be in your *.cpp and *.hpp files. If they do then update the source files accordingly. If they don't (they contain only dependencies, includes and similar things) then comment all "#include something.moc" out, create a Qt4 project, add all sources and headers and compile. You should pass (if it is a Qt3 project, you might need the Qt3 support). The MOC info should be processed by qmake without your intervention.

anda_skoa
6th February 2014, 12:53
IMO, the *.moc files are some relic of Qt3.

No, they are just a different way of dealing with the code generated by MOC.

Without the include the behavior is to generate cpp files which are then compiled separately and linked like any other object file.

The alternative with the include is used in three scenarios:
1) when the Q_OBJECT using class declaration is inside the cpp file, not in a header
2) when the code generated by moc needs to see some declarations that are private to the cpp file
3) to speed up builds (no extra invocation of compiler for the moc generated file)

Not sure why it doesn't work for starling13 though.

Cheers,
_