#include files in moc cpp files for cmake...
-
I've been working on a C++ project that has a number of objects that reference each other. Class A has a reference to B, and B has a reference to A, etc. A number of classes have references to other classes. After a while, I started running into problems for header files that #include other header files. I'm well aware that forward declarations are often needed in these situations to satisfy the C++ compiler, but when you wind up with circular #include's, it just starts to get ugly. A friend of mine recommended placing all #include files for project header files in .cpp files only. Thus project header files would not #include other project header files.
However, the problem is that moc generates .cpp files that automatically #include project header files. If a project header file requires #includes for other projec tfiles in order to run, the only two options are to #include the project files in the header or to make sure the headers are #included in the moc cpp file. Since I am using cmake, all moc files are regenerated each time cmake is run.
I found this option, which works with AUTOMOC in cmake:
set(CMAKE_AUTOMOC_MOC_OPTIONS
-f file.h
)Using this command puts #include "file.h" in EVERY generated moc file, which of course does not work. Unfortunately, these options only apply to the next build target, and I can only specify the source files for a build target once in cmake.
I also looked into AUTOUIC, but I'm not sure this will work here. (See: http://www.cmake.org/cmake/help/v3.0/manual/cmake-qt.7.html#manual:cmake-qt(7))
I'm guessing I must invoke moc manually, once for each file or something, with the appropriate options.
If anyone is able to provide any tips, it would be much appreciated. I am going to have to go back to troubleshooting circular #includes and doing weird code hacks for now. -
Hi and welcome to devnet,
From the looks of it you are trying to solve the wrong problem. If you have that much circular dependencies then there might be a design problem. I don't say that circular dependencies should not happen but when there's need to start doing strange hacks to make them work then you end up with an unmaintainable monster.
-
The most straightforward solution is probably to make better use of QT's event system to request widget paint events from one object to another (or see if custom events are possible in other cases). Some of the circular references are a result of objects wanting to call each other's update() methods.
I would still be interested in knowing how to use the CMAKE_AUTOMOC_MOC_OPTIONS setting. Does anyone know how to use this?
-
Then indeed, you have a design flaw there. All your widgets knowing each other only to do some refresh is bad.
You can also use signals and slots to call repaint
AFAIK, you can put there arguments for moc the same way you would if you called it from the command line (I haven't tested it though)