QMake 'subdirs' template - executing a target? - c++

I am putting together a build system for my Qt app using a qmake .pro file that uses the 'subdirs' template. This works fine, and allows me to specify the order that each target is built, so dependencies work nicely. However, I have now added a tool to the project that generates a version number (containing the build date, SVN revision, etc,) that is used by the main app - I can build this version tool first but when it is built I want to execute it before any more targets are built (it generates a header file containing the version number that the main app includes.)
For example, my simple qmake file looks like something this:
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS = version \
lib \
tests \
mainapp
When 'version' is built I want to execute it (passing some arguments on the command-line) before 'lib' is built.
Does anyone know if this is possible? I see that qmake has a 'system' command that can execute apps, but I don't know how I could leverage this.
A related question concerns my unit tests. These live in the 'test' project and use the QTest framework. I want to execute the tests exe before building 'mainapp' and if the tests fail (i.e. the tests exe doesn't return zero) I want to quit the build process.
I realise that qmake is designed to generate makefiles, so I may be wishing for a little too much here but if anyone can give me some pointers it would be very welcome.

I currently use qmake to exec my unit tests automatically for two years - and it works fine.
Have a look here - I made a mini-howto for that:
Qt: Automated Unit Tests with QMAKE
Abridged summary:
Structure
/myproject/
myproject.h
myproject.cpp
main.cpp
myproject.pro
/myproject/tests/
MyUnitTest.h
MyUnitTest.cpp
main.cpp
tests.pro
Using QMake to automatically run unit tests on build
The QMake target QMAKE_POST_LINK will run a user defined command after linking.
tests.pri (common file)
TEMPLATE = app
DEPENDPATH += . ../
INCLUDEPATH += . ../
DESTDIR = ./
CONFIG += qtestlib
unix:QMAKE_POST_LINK=./$$TARGET
win32:QMAKE_POST_LINK=$${TARGET}.exe
tests.pro (project-specific file)
TARGET = MyUnitTest
HEADERS += MyUnitTest.h
SOURCES += MyUnitTest.cpp main.cpp
include(tests.pri)
Running multiple unit tests in a single main()
main.cpp
#include "MyUnitTest1.h"
#include "MyUnitTest2.h"
int main(int argc, char** argv) {
QApplication app(argc, argv);
int retval(0);
retval +=QTest::qExec(&MyTest1(), argc, argv);
retval +=QTest::qExec(&MyTest2(), argc, argv);
return (retval ? 1 : 0);
}
This runs your tests on each build and aborts if an error is found.
Note
If you get linker errors such as "LNK2005: xxx already defined...", add a new .cpp file for each test class header and move some test method implementations.
You can use exactly that mechanism to exec your versioning tool after compile/building - so your questions should be solved :-)
If you have any further questions don't hesitate to ask me.
PS: Here you can find more (undocumented) tricks around QMake: Undocumented QMake

I posted a message on the Qt Interest mailing list about a 'pre build' step and it can be done using a combination of PRE_TARGETDEPS and QMAKE_EXTRA_TARGETS. Here is the response:
You can specify custom build steps,
eg. this would call makemyversion.sh
to create myversion.cpp every time
before it builds something:
versiontarget.target = myversion.cpp
versiontarget.commands = ./makemyversion.sh
versiontarget.depends = FORCE
PRE_TARGETDEPS += myversion.cpp
QMAKE_EXTRA_TARGETS += versiontarget
I am now using something similar to this to generate my app's version number each time it is built.

I've tried to do a lot of stuff with qmake as a build system over the years. Eventually I just resorted to having a pre-qmake step. Ie. a configure script.
You can build your version tool in there and then execute it before calling qmake to generate the Makefiles.
I found the easiest way to get data into the pro files, if you need that too, is to generate a .pro.inc file and include it from your main pro.

As 3DH mentioned, you want a QMAKE_POST_LINK option specified in your .pro files that contain something you want executed. So for your example, I would do something like this with the version.pro file:
TEMPLATE = app
TARGET = version
HEADERS = version.h
SOURCES = version.cpp
QMAKE_POST_LINK=./version
Something similar should work with your test directory.

Related

Where do I put the QT5 clone in this project

This is my first time every using C++ so please go easy on me. I have about 7000 hours of Python experience so I'm not completely clueless. I'm trying to read the code written for the Collatinus software found here. collatinus. It seems that the initial file is this:
VERSION = "11.2"
DEFINES += VERSION=\\\"$$VERSION\\\"
DEFINES += MEDIEVAL
TEMPLATE = app
TARGET = collatinusd
INCLUDEPATH += . src
DEPENDPATH += .
DESTDIR = bin
OBJECTS_DIR= obj/
MOC_DIR = moc/
QMAKE_DISTCLEAN += $${DESTDIR}/collatinus
CONFIG += console
CONFIG -= app_bundle
CONFIG += release_binary
QT += core
QT -= gui
QT += xmlpatterns
QT += network
I've downloaded qt from qt and got the open source qt5. Now I cannot figure out where to put the file. I have tried putting it in the same folder as the above mentioned code. I have also tried putting in the folder marked src. In the src folder there are many files which use QT but it seems like the files are supposed to be taken out of the QT folder. For example in this file we have the syntax on line 28
#include <QDebug>
The QDebug file is in the QT folder. But when I put the qt folder in either the topmost folder or the src folder I get the error message:
fatal error: 'QtCore' file not found
#include <QtCore>
So the file structure is as follows:
/collatinus-daemon
collatinus.pro (and other files)
//src
flexion.cpp (and other files)
So where do I put the qt folder? Also, I renamed it qt from qt5 since the syntax had the line:
QT += core
###################
Ok, I've got the QT creator up and running. Here is the pro file
QT += network widgets
QT += core
QT -= gui
TARGET = Client_C11
VERSION = "1.0"
#CONFIG += console
#CONFIG -= app_bundle
CONFIG += release_binary
TEMPLATE = app
SOURCES += src/client_main.cpp
OBJECTS_DIR= obj/
MOC_DIR = moc/
unix:!macx:DESTDIR = bin
macx:{
# Commandes spéciales pour déployer l'application sur Mac.
# J'ignore s'il faut l'équivalent pour Linux ou Windows.
# Philippe. Octobre 2016
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.8
ICON = collatinus_bw.icns
deploy.commands = macdeployqt Client_C11.app
QMAKE_EXTRA_TARGETS += deploy
}
Here are some screenshots of my folders:
And here is the error message I'm getting:
Here also is the code for the client main
#include <QCoreApplication>
#include <iostream>
#include <QtWidgets>
#include <QtNetwork>
class QTcpSocket;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString req = "";
if (argc > 1)
{
int i = 1;
while (i < argc)
{
QString suite(argv[i]);
req += " " + suite;
i++;
}
}
else req = "-?"; // pour afficher l'aide.
QTcpSocket * tcpSocket = new QTcpSocket();
tcpSocket->abort();
tcpSocket->connectToHost(QHostAddress::LocalHost, 5555);
QByteArray ba = req.toUtf8();
tcpSocket->write(ba);
tcpSocket->waitForBytesWritten();
tcpSocket->waitForReadyRead();
ba = tcpSocket->readAll();
tcpSocket->disconnectFromHost();
tcpSocket->close();
QString rep(ba);
std::cout << rep.toStdString();
a.quit();
}
I don't understand what I'm supposed to do with qmake and cmakelists
Where do I put the QT5 clone in this project
You don't :)
Qt installations up to 5.14 are not relocatable. That means that once Qt is installed, if you move it to another path, it'll break. Just don't mess with it: once installed, you leave it alone, and it'll work just fine.
Qt source code has to be built before it can be used. I presume that you downloaded the source code and want to stick it into the project and build the two that way. It's not designed to work that way at all.
Qt build requires several other tools to be installed (iirc python, ruby, perl), and other optional dependencies to get the full feature set, and if it fails for whatever reason, figuring it out is unnecessary effort initially. So it's best to start with pre-built Qt.
I've downloaded qt from qt and got the open source qt5. Now I cannot figure out where to put the file.
Downloading "qt" doesn't mean much, since everyone means something else by that. If you've downloaded the source code, then delete it - last thing you want is to mess with compiling Qt right now.
Normally, Qt is installed using an installer, so what you'd download is an executable installer, and use that to select the Qt components you want to install. On Windows, pick the mingw-based Qt version, since that also installs the build environment (compilers) if you don't have them already. Otherwise you'd use the MSVC-based version if you got MSVC installed on Windows.
On Unix, you'd want to install Qt using the "native" package manager - one that came with your linux distribution, or macports (really preferred) on MacOS.
Once Qt is installed, you'd use Qt Creator IDE to open the collatinus project (its .pro file). And everything will "just work" from that point onwards - it'll let you build it and run whatever executable targets it produced. Of course you can build from the command line, but for a beginner it's just an extra layer of complication and unnecessary.
In any case, the .pro file you refer to would be processed by qmake to generate the build system that builds the project. qmake itself is the means you use to select what Qt version you build with: there's one qmake per each Qt installation. So, after qmake has ran, you'd make the thus-configured build, and there'll be no problems with finding Qt headers. It's the job of qmake in that case to set everything up so that the compiler will be told where to find Qt. You are not expected to have to mess with it manually.
If there's a CMakeLists.txt file in the project, you'd probably prefer to use that instead of qmake, since cmake is a widely used tool with lots of knowledge available online, whereas qmake is now obsolete. Still, older projects may only supply a .pro file that needs to be used with qmake and not cmake.
Your question doesn't nearly provide enough detail for a more focused answer - please tell us exactly what you did, and what Qt elements you installed (whether using Qt Installer program, or using a unix package manager).

Qt Creator (not CMake) how to specify different files for different build configurations?

I have project in QT Creator (as .pro file, not as CMake). Now I want to add tests (gtest) as another build configuration, so I've added build configuration "debug_tests" (Projects -> Add -> Debug with name debug_tests).
Now I want to add specific main file for "debug_tests" and exclude from build my normal main file when the build configuration is choosen.
So I've tried:
test_debug:{
message("Running tests:")
SOURCES += \
tests/MultiCellArticleModelTests.cpp \
tests/main_tests.cpp
LIBS += \
-lgtest
}
But it is not working, it is working when I do like that:
!debug_and_release:{
message("Running tests:")
SOURCES += \
tests/MultiCellArticleModelTests.cpp \
tests/main_tests.cpp
LIBS += \
-lgtest
}
But it is not good solution if I want to add more configurations.
Another solution which I see is to just add defines to compilation and have ifdef in my code.
Usually, tests are in their own sub-projects rather than part of some scope in your main source tree.
This allows you to keep them cleanly separated from your main code and you can run them easily. You can even call make check to run the whole test suite that you created for your library/application.

Integrate vera++ (or other coding-convention tool) with Qt/QtCreator

We are developing a application with Qt and in the server we have genkin server for auto build and auto tests.
We want to have a Coding-Convention Test tool like vera++. We have no experience in vera++ or other tools but all we want is to make vera++ process every files of the Qt project (.pro). Also, is it possible to integrate this tool in QtCreator?
I couldn't find anything in Internet.
Thanks.
Solution
I have integrated vera++ in a composite qmake project by adding the following lines in the file .qmake.conf in the root directory of the project:
defineReplace(absolute_paths) {
result =
for(path, ARGS) {
result += $$absolute_path($$path, $$_PRO_FILE_PWD_)
}
return($$result)
}
equals(TEMPLATE, subdirs): prepareRecursiveTarget(vera++)
else {
# We prefix the report file name with the project file base name to prevent name collisions.
VERA_TARGET = $$basename(_PRO_FILE_).vera++.xml
vera++.commands = vera++ --checkstyle-report $$VERA_TARGET --show-rule $$absolute_paths($$HEADERS) $$absolute_paths($$SOURCES)
QMAKE_CLEAN += $$VERA_TARGET
}
QMAKE_EXTRA_TARGETS += vera++
This adds a recursive make target vera++ that processes all the header and source files in each of the non-subdirs sub-projects.
To generate the XML reports, call the following commands:
qmake
make qmake_all
make vera++
Additional information
.qmake.conf is automatically included in all the .pro files in all subdirectories.
qmake
defineReplace()
prepareRecursiveTarget()
vera++

dyld: Library not loaded: myOwnLibrary

Context
I'm developing an app in Qt with Qt Creator in OS X. Right now my file organization is a mess (every file is the same folder) so I've decided to move to another project structure that also allows me to also run unit tests.
What have I tried
Following this blog entry I tried to create the same project (just for testing purposes).
Problem
Everything compiles but when executing it gives an error Library not loaded.
I thought that maybe I was doing something wrong so I cloned the example repo and try it again with a working example. But it gives me the same error:
dyld: Library not loaded: libmyapp.1.dylib
Referenced from: /Users/(my build folder)/app/app
Reason: image not found
The example is supposed to be right. The only changed I made is to remove the test subdir as I haven't installed yet UnitTest++ so my .pro file is like this:
TEMPLATE = subdirs
CONFIG+=ordered
SUBDIRS = \
src \
app
app.depends = src
OTHER_FILES += \
defaults.pri
Am I doing something wrong? Is there any step that I forgot?
Edit 1:
Creating manually a Frameworks folder and adding the libmyapp.1.dylib inside the bundle makes the app work. But I think this step should be done automatically
Edit 2:
I've tried to run macdeployqt as suggested. It seems that the app is trying to get the library from the system path instead of the provided:
macdeployqt app.app
ERROR: no file at "/usr/lib/libmyapp.1.dylib"
I have done the following to get the correct dependencies on a lib in the executable...
This code in the application pro file sets dependencies and also places the files directly into the Contents/Framework folder inside bundle (I chose to make the executable do all the work)
# to get the dependencies
INCLUDEPATH += ../libmyapp
macx {
LIBS += ../libmyapp/libmyapp.1.dylib
PRE_TARGETDEPS += ../libmyapp/libmyapp.1.dylib
MY.path = Contents/Frameworks
MY.files = ../libmyapp/libmyapp.1.dylib
QMAKE_BUNDLE_DATA += MY
}
Alternatively you can make your lib become a framework .. 2 options in this post:
How to create a Bundle Library (mh_bundle) with qmake on Mac OS X?
Would be good to read on the process of deploying an app on OS X... The tool trojanfoe was thinking of, for deploying qt apps, is called macdeployqt
Working with bundles of C++ programs with dependencies on Mac OS X can be a real pain. A workaround until you actually need to ship your app as a bundle is tell Qt not to create a bundle at all. Add the following to your app.pro file:
CONFIG -= app_bundle
Then you may add the dylib to the output directory yourself and it should hopefully work fine.
Another option is to set/add the environment variable LD_LIBRARY_PATH in the Run settings for your project in Qt Creator to point to the path where your compiled dylib is located.
I'm not sure that the above works, but those are my best guesses from earlier experience with similar issues. Also, make sure you are using the newest versions of Qt and Qt Creator.

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.