Qt unit test dependency problem - c++

Hee,
I'm kinda new to Qt and i started to add UnitTests to my Qt project. Qt demands that i put my unit tests in another project, so i did.
But now i have dependent source files in my first project. I made my 'main project' a dependency of my 'test project'.
I cannot seem to include any of the '.h' files from my 'main project'. The unit test them self run properly as long as i do not use classes from my 'main project'.
I looked into the Qt documentation, but i cannot find the solution for my problem. Am i missing something?

Did you try to include your dependencies to .pro file of your test project?
HEADERS += ../MyHeader.h
SOURCES += ../MyHeader.cpp \
tst_myUnitTestName.cpp

You can try adding the path of your main program in the includes (in the testProject.pro file)
INCLUDEPATH += .. .
(or just add the path to the project itself)
if you do this, you will then need to change your includes (in the .cpp files) from "" to <>
#include < MyHeader.h >
Adding the headers to the .pro file will mostly allow you to have easy access to the file itself if you're using QtCreator (and qmake will complain if it doesn't find the files), but it will not solve the actual dependencies within each .cpp file.

Related

Adding JSON file to plugin qmake project

When writing plugin libraries with Qt one can attach a JSON file containing some meta data to it using the Q_PLUGIN_METADATA macro. This JSON file is then linked into the library, for later usage with QPluginLoader::metaData().
Unfortunately when building the plugin library the associated JSON file is not by default seen as a dependency for the library binary by qmake. When the JSON file is modified the plugin library project has to be rebuild (especially re-linked) manually to force the modified JSON file into the library binary.
What would be the proper way to mention the JSON file in the .pro file so that it is automatically linked in when it is modified?
I typically use the following to make the json file a dependency of the generated moc file that contains the corresponding code. Assuming the class where you specify Q_PLUGIN_METADATA is located in a header file called myclass.h, the qmake code is as follows:
DISTFILES += myclass.json
json_target.target = moc_myclass.o
json_target.depends += $$PWD/myclass.json
QMAKE_EXTRA_TARGETS += json_target
Note: You might have to use json_target.target = $$OBJECTS_DIR/moc_myclass.o instead, if OBJECTS_DIR has previously been defined. Check the generated Makefile to see if the path of the dependency matches the one of the corresponding target.
Well, you could just add the JSON file to resources: create some *.qrc file, add yours there and then write in the .pro file something like RESOURCES += plugin_data.qrc.-
There is also DISTFILES variable, but AFAIK it's Unix-only and does not solve your problem.
Tried myself and it never worked, still the recipe from documentation works: INCLUDEPATH += JSON_FILE_LOCATION_DIR. It's true that qmake caches builds sometimes, but they say adding to include path should do the trick and make a proper build.

QT: ui_* files not generated

I know it is a topic already touched by a lot of user, but I don't find a valid solution; I have two form files created with QtDesigner:
interfaccia_test.ui
interfaccia.ui
I launch qmake -project command obtaing the following .pro file:
TEMPLATE = app
TARGET = qtgeo
INCLUDEPATH += . include
# Input
HEADERS += interfaccia.h include/localizzazione.hpp
FORMS += interfaccia.ui interfaccia_test.ui
SOURCES += interfaccia.cpp main.cpp src/localizzazione.cpp
src/SimpleSIFT.cpp
so i give qmake command but it doesn't generate ui_interfaccia.h and ui_interfaccia_test.h like I expected; then I try to make my project and I have
interfaccia.h:19:28: fatal error: ui_interfaccia.h: File o directory not found
#include "ui_interfaccia.h"
^
with interfaccia.h my file that use the GUI I made.
For any given project, you should ever only use qmake -project once. It's meant as a starting point if you have a bunch of files and want to get a project template. This template is then meant to be modified by a human being - you.
The normal way to build a qmake-based Qt project would be:
qmake
make
The ui_xxx.h files are generated by make, not qmake. Here's a list of what the various tools do:
qmake -project Generates a .pro file template for you to modify to suit the project. This should never be used by your end users, or by you after the project is going. It's your job to keep the .pro file up-to-date.
qmake or cmake Generates the makefile for the build system.
make or ninja Builds the project, generating all the other files.
There are two additional points:
The qmake won't generate the ui_xxx.h file if you've included a file that wouldn't be generated. So, for example, if it'd generate a file called ui_Interfaccia.h, but you've included ui_interfaccia.h, then the file with the wrong name nor the file with the correct name get generated.
This matters even if you're building everything on a case-insensitive OS/filesystem.
You're including the file with a wrong name. The correct name is ui_ClassName.h, where ClassName is the name of the class from the .ui file (look at the first few lines), with the same capitalization.

qt4 scons including a uic file in variant_dir

I'm using the qt4 tool for scons and having some troubles getting the .ui files to be handled correctly. I'm coming from a Cmake background with Qt and a beginner with scons.
In my SConstruct file I have
env.Uic4(Glob('*.ui'))
env.Program('test',Glob('*.cpp'))
The problem is that my source file can't find the resulting header files src/qt-test/sample_widget.cpp:3:23: error: ui_sample.h: No such file or directory. The header file is created, as is all moc processing done, thus I'm pretty sure everything is installed correctly and basically correct.
What I think is happening is because this is a recrusive SConstruct file, and the caller is using a variant_dir for the build. So possibly the problem is just getting the compiler to resolve headers in the build directory (and perhaps nothing to do with the qt4 tool). This was handled automatically in CMake (I think).
So how do I get this working (get the ui include file to be found)?
Use the CPPPATH construction variable to set the include paths as mentioned in the man pages:
http://scons.org/doc/production/HTML/scons-user/a4916.html
For example:
env.Append(CPPPATH = ['dir1', 'dir2'])
Brady

The right way to structure my c++ project with cmake?

I have been struggling with this for quite a while, and my adventures with cmake have only resulted in hackish solutions that I am pretty sure are not correct.
I created a library that consists of several files, as follows:
-libfolder
-codepart1folder
-CMakeLists.txt
-codepart1.cpp
-codepart1.hpp
-codepart2folder
-codepart3folder
-lib.cpp
-lib.hpp
-CMakeLists.txt
I wrote a CMakeLists file to compile the library (after some experimentation), and I can generate a lib.a file. Now I would like to include this code as a library in other projects, and access it through the interface in lib.hpp. What is the best way to do this, in terms of directory structure, and what I need to put into CMakeLists.txt in my root project?
My current attempt has been to add -libfolder as a subfolder to my current project, and add the commands:
include_directories(${PROJECT_SOURCE_DIR}/libfolder)
link_directories(${PROJECT_BINARY_DIR}/libfolder)
add_subdirectory(libfolder)
target_link_libraries(project lib)
When I run make, the library compiles fine, but when project.cpp compiles, it complains that it cannot find codepart1.hpp (which is included in lib.hpp, included from project.cpp).
I suspect that this is the wrong way about doing this, but I cannot wade through the CMake documentation and find a good tutorial on setting up projects like this. Please help, CMake gurus!
The clean way to import one CMake project into another is via the find_package command. The package declaration is done by using the export command. An advantage of using find_package is that it eliminates the need to hard-code paths to the package's files.
Regarding the missing hpp file, you didn't include codepart1folder, so it's not on the include path.
Ok, so after consulting a coworker of mine who is a CMake guru, it seems CMake does not have support for what I am trying to do, leaving one with 3 options:
Add all of the dependencies to the parent projects CMakeLists.txt - not very clean, but it will get the thing to work. You'll have to do this for every project you add the code to, and go back and fix things if your library changes.
clean up your library headers. This is done through some compiler hackery. The idea is to forward-declare every class, and use only pointers or boost::shared_ptr, and then include the dependencies only in the cpp file. That way you can build the cpp file using all the findpackage stuff, and you get the bonus of being able to use the lib by only including the header and linking to the library.
Look into build systems. Having portable code and fast code compilation with complex dependencies is not a solved problem! From my investigations it turned out to be quite complicated. I ended up adopting my coworkers build system which he created himself in cmake, using things he picked up from Google.
Looking at your post you don't seem to add 'codepart1folder' to the includes anywhere. How are you including codepart1.hpp as:
#include <codepart1.hpp>
#include "codepart1folder/codepart1.hpp"
I don't think there is a standard accepted way to structure cmake projects. I've looked at a bunch of cmake repos and they tend to have differences. Personally I do the following:
-project
CMakeLists.txt
-build
-cmake
OptionalCmakeModule.cmake
-src
-Main
Main.cpp
Main.hpp
-DataStructs
SomeTree.hpp
SomeObject.hpp
-Debug
Debug.hpp
-UI
Window.hpp
Window.cpp
Basically that dumps all the source code into 1 directory, then you perform an out of source build with: 'mkdir build && cd build && cmake .. && make' in the projects root folder.
If you have separate libs as part of your project, then you might want a separate libs directory with another subfolder for your specific lib.
I have some of my repos on: https://github.com/dcbishop/ if you want to look at the CMakeLists.txt files.
The main problems with my project structure are that I use the FILE_GLOB which is apparently the 'wrong' way to do things (if you add files after running 'cmake ..' then they won't be picked up hen you do a 'make'). I haven't figured out what the 'right' way to do it is (from what I can see it involves keeping a separate list of files) I also only use 1 CMakeLists.txt file.
Some projects also choose to separate their cpp and hpp files into separate directories. So you would have an include and src folders (at least for the hpp files that are intended to be used externally). I think that would mainly be for projects that are mainly large libraries. Would also make installing header files much easier.
You are probably missing
include_directories(${PROJECT_SOURCE_DIR}/libfolder/codepart1folder)
In such a case you might want to set( CMAKE_INCLUDE_CURRENT_DIR on) to add all folders to the include directory path variable.
Check cmake's output on the command line whether the correct include folders are set or not. Additionally you can always use message() as "print debugging" for cmake variables.
In case of include directories however you need to read the directory property to see what is actually in the include directories.
get_property(inc_dirs DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
message("inc_dirs = ${inc_dirs}")
I hope this helps you figuring out what is missing.
Edit
I just saw your comment about added codepart1folder in the libfolder. It is only available in the libfolder's include_directory path and not propagated to the root folder.
Since the include codepart1.hpp is present in the lib.hpp however you need to have it also available in the project path otherwise you will get missing declaration errors when you build your project.

QAction: No such file or directory

I'm getting the error
QAction: No such file or directory
when I try to compile a project for plugin (C++ Library template). Weird, because I have a project for my app which also includes this header and there is no error. What might cause this?
For me I had some stale moc_ and ui_ files left over from compiling under a different version and configuration of Qt, so removing them solved the problem for me.
rm moc_* ui_* *.o
Make sure that you have the right include paths set up.
If you use QMake the *.pro should contain these settings if you want to include files from QtGui. They should be set by default but some templates may not set them.
CONFIG += qt
QT += gui
If you use another build system then make sure that you either use
#include <QtGui/QAction>
or you add $QTDIR/include/QtGui and not just $QTDIR/include to your include path