Solved ui_somedialog.h goes missing after including somedialog.h to test cpp file
-
-
@aha_1980 Thanks for the input, here's the compiler output for the test as requested:
g++ -c -pipe -g -std=gnu++1y -Wall -W -D_REENTRANT -fPIC -DQT_QML_DEBUG -DQT_GUI_LIB -DQT_TESTLIB_LIB -DQT_CORE_LIB -DQT_TESTCASE_BUILDDIR='"/home/someuser/Programming/AppProject/build-AppProject-Desktop-Debug/Tests"' -I../../AppProject/Tests -I. -I../../AppProject/MyApp -I../../AppProject/GoogleTest/googletest/googletest/include -I../../AppProject/GoogleTest/googletest/googlemock/include -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtGui -isystem /usr/include/qt5/QtTest -isystem /usr/include/qt5/QtCore -I. -isystem /usr/include/libdrm -I/usr/lib64/qt5/mkspecs/linux-g++ -o main.o ../../AppProject/Tests/main.cpp g++ -pipe -g -std=gnu++1y -Wall -W -dM -E -o moc_predefs.h /usr/lib64/qt5/mkspecs/features/data/dummy.cpp /usr/lib64/qt5/bin/moc -DQT_QML_DEBUG -DQT_GUI_LIB -DQT_TESTLIB_LIB -DQT_CORE_LIB -DQT_TESTCASE_BUILDDIR='"/home/someuser/Programming/AppProject/build-AppProject-Desktop-Debug/Tests"' --include /home/someuser/Programming/AppProject/build-AppProject-Desktop-Debug/Tests/moc_predefs.h -I/usr/lib64/qt5/mkspecs/linux-g++ -I/home/someuser/Programming/AppProject/Tests -I/home/someuser/Programming/AppProject/MyApp -I/home/someuser/Programming/AppProject/GoogleTest/googletest/googletest/include -I/home/someuser/Programming/AppProject/GoogleTest/googletest/googlemock/include -I/usr/include/qt5 -I/usr/include/qt5/QtGui -I/usr/include/qt5/QtTest -I/usr/include/qt5/QtCore -I. -I/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/include/g++-v8 -I/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/include/g++-v8/x86_64-pc-linux-gnu -I/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/include/g++-v8/backward -I/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/include -I/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/include-fixed -I/usr/include ../../AppProject/Tests/tst_somedialog.cpp -o tst_somedialog.moc g++ -c -pipe -g -std=gnu++1y -Wall -W -D_REENTRANT -fPIC -DQT_QML_DEBUG -DQT_GUI_LIB -DQT_TESTLIB_LIB -DQT_CORE_LIB -DQT_TESTCASE_BUILDDIR='"/home/someuser/Programming/AppProject/build-AppProject-Desktop-Debug/Tests"' -I../../AppProject/Tests -I. -I../../AppProject/MyApp -I../../AppProject/GoogleTest/googletest/googletest/include -I../../AppProject/GoogleTest/googletest/googlemock/include -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtGui -isystem /usr/include/qt5/QtTest -isystem /usr/include/qt5/QtCore -I. -isystem /usr/include/libdrm -I/usr/lib64/qt5/mkspecs/linux-g++ -o tst_somedialog.o ../../AppProject/Tests/tst_somedialog.cpp In file included from ../../AppProject/Tests/tst_somedialog.cpp:3: ../../AppProject/MyApp/somedialog.h:4:10: fatal error: ui_somedialog.h: No such file or directory #include "ui_somedialog.h" ^~~~~~~~~~~~~~~~~~~~~ compilation terminated. make: *** [Makefile:889: tst_somedialog.o] Error 1
If I check the ui_xxxx.h file in the build folder, it is there.
Adding "Tests.depends = MyApp" to the master AppProject.pro file doesn't help either. -
@pusrob said in ui_somedialog.h goes missing after including somedialog.h to test cpp file:
If I check the ui_xxxx.h file in the build folder, it is there.
Yeah, if I get it correctly, the include directives only point to the source directories, but not the build dirs.
I'll need to make up my mind about that, that's probably a situation that is not thought like that.
Usually you have a library that you test or you compile the classes again for the test. But in your case it's a bit distributed, and I have no quick idea how to solve that.
Regards
-
Hi,
In such a case, the project can be:
- library
- app
- tests
The library contains all the elements that will be tested and the app just assembles the bits needed.
-
@sgaist Thanks for the suggestion, but the library version will not work either, as it generates the exact same error. Here's a stackoverflow post describing the exact setup and related source code.
-
My bad, I see the issue now...
So in fact you need to either add the shadow build folder (using OUT_PWD) to INCLUDEPATH or force the generated file to be put in the sources.As @aha_1980 wrote below, this is wrong. The correct way to do that is to forward declare your UI element in your header and then include the generate header in your .cpp file. So it won't "leak" anywhere else.
-
or force the generated file to be put in the sources.
please not. that will create more problems than it solves.
Put it the other way round, don't expose internal details. The ui_xxx.h is such a detail that should not appear in a header used by someone else (like the test).
Regards
-
@sgaist Thanks again for your time and suggestions, but I already tried adding OUT_PWD to INCLUDEPATH before posting any thread anywhere, and unfortunately that doesn't help either. That is why I posted to two forums, because I truly believe I ran out of options. I'm starting to think this is a bug or omission somewhere in qmake, as there is no rational reason (that I can think of) why this shouldn't work with the presented solutions/setup.
-
-
@sgaist I'd love to, but it would seem your changes to your post got lost somehow. Could you post it again, please?
And this is an open question to the board: What do you think is the best way to hide the ui_xxx.h file? Unfortunately I'm not all that experienced with this stuff. Thanks guys. -
Quoting the interesting bits:
@sgaist said in ui_somedialog.h goes missing after including somedialog.h to test cpp file:
As @aha_1980 wrote below, this is wrong. The correct way to do that is to forward declare your UI element in your header and then include the generate header in your .cpp file. So it won't "leak" anywhere else.
See the Notepad tutorial and associated code, it shows that technique I wrote about.
-
@sgaist OK, I tried your suggestion as the notepad tutorial showed, and the missing ui_xxx.h file error is gone. Now I get
error: undefined reference to `vtable for SomeDialog'
for the somedialog.h file and a similar error
error: undefined reference to `SomeDialog::SomeDialog(QWidget*)'
for the tst_somedialog.cpp file, when I try to default construct an instance.
Any ideas how to fix that? Thanks.P.S.: I already tried rerunning qmake and deleting the build folder, it didn't work.
-
Can you show the declaration of your SomeDialog class ?
-
@sgaist Sure thing, here it is: somedialog.h
-
Might be a silly question but did you properly implement the constructor ? I just realized the corresponding symbol is not found.
If you did so then are you sure that the .cpp file is compiled ?
Check your SOURCES variable. Especially if you put one file per line, you might be missing a backslash.
-
@sgaist The constructor is fine, as I am able to use the class normally in the MyApp project. The problems only start to occur if I want to use the SomeDialog class in the test project as well. Anyway, I tried to add somedialog.cpp to the SOURCES variable just in case, but then I'm back to square one: the compiler reports that ui_xxx.h is missing.
Also, as far as I know, adding class files to SOURCES and HEADERS in the test .pro file is unnecessary, as non-GUI classes tested with GTest do not require it. In this very same project I have dozens of such tests and all of them work just fine without further additions to SOURCES or HEADERS. I guess the problem lies in how MOC and UIC generated files are treated by qmake.
Finally, if I check the build folder, the moc_somedialog.cpp gets generated, though the object file is missing (probably because of the aforementioned errors).
-
Did you modify the project as I suggested to have a library so you can link your tests and your application against it ?
-
@SGaist Hi. Moving the dialog class into a library made it possible to compile both the main app and the tests, which also executes once I set the LD_LIBRARY_PATH env variable in the Project setup. Thanks for all the help and your patience, I'm really grateful that with your help a solution could be finally found.
So, for future reference, here's what needs to be done in such cases:
- move the ui_xxx.h include to the source file by having only a pointer to the ui class in the dialog class (PIMPL idiom).
- move all dialog related sources (.h, .cpp, .ui) to a separate library project
- modify project files for both app and test projects to include this newly created gui lib (INCLUDEPATH, LIBS)
- If project won't start due to missing libs, edit the LD_LIBRARY_PATH env variable in Project setup to include the output directory of the lib project
One small question remains though, which is strictly related to Qt Creator itself: I created a separate GUITests subdirs project, and it would seem it hijacked the main"play" button on the left side of the pane. What I mean here, is that it will only execute the test executable but not the normal app executable. Tests should be started in the Test Results tab and not by the big button. How can I make it to execute the app only again? Thanks.
-
@PusRob you can select the currently active executable with the monitor button just above the green play button.
Regards