How to make makefile generated by Qt without qmake dependency - c++

I use Qt creator in linux to make my non-Qt c++ project. I find that Qt creator would make a makefile for me. I want to move all the project into a computer without any qt or qmake, but I cannot really edit the makefile myself. As I google that someone says add a CONFIG -= qt flag can make a pure g++ makefile without any qt component but actually not.
the pro file in my project is like this:
QMAKE_LFLAGS += -no-pie
TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt
INCLUDEPATH += /home/MyName/opencvBuild/install/include/opencv4/
LIBS += -L/home/MyName/opencvBuild/install/lib/ \
-lopencv_core \
SOURCES += \
main.cpp \
helloopencv.cpp
HEADERS += \
helloopencv.hpp
and the makefile generate thousands of Qt dependencies like:
.....
###### Files
SOURCES = ../HelloOpenCV/main.cpp \
../HelloOpenCV/helloopencv.cpp
OBJECTS = main.o \
helloopencv.o
DIST = ../Qt/5.12.0/gcc_64/mkspecs/features/spec_pre.prf \
../Qt/5.12.0/gcc_64/mkspecs/common/unix.conf \
../Qt/5.12.0/gcc_64/mkspecs/common/linux.conf \
../Qt/5.12.0/gcc_64/mkspecs/common/sanitize.conf \
../Qt/5.12.0/gcc_64/mkspecs/common/gcc-base.conf \
.....
now when I call make command in terminal it would automatically link to qmake.
I don't want any "Qt" in my makefile. What should I do?

These are not "Qt"-dependencies, but rather "qmake"-dependencies: it's a list of files which qmake had processed in order to generate your Makefile. Stuff like gcc-base.conf is needed for some common gcc options, sanitize.conf for a bunch of -fsanitize= options, and so on.
Thus, it's the list of the files your Makefile itself depends on (used for auto-regeneration and such). Of course, if you don't intend to ever regenerate Makefile with the help of qmake, you can just delete all these lines at once.
You complain that despite of having CONFIG-=qt in your .pro, there is still a bunch of qt_config.prf and other such files mentioned in that list. This is true, however qmake startup scripts designed precisely in this way: first, all Qt-related stuff is unconditionally preconfigured; then the user project is processed; and then, only if CONFIG += qt, the relevant Qt stuff finally becomes enabled.
Just for fun, you can mess with qmake startup code: go to <prefix>/share/qt5/mkspecs/linux-g++-64 (or whatever your QMAKE_SPEC is); open the file qmake.conf; comment out the last string: #load(qt_config). Now your CONFIG -= qt project should be processed okay, but the resulting Makefile will be significantly smaller. But the price is that qmake cannot do Qt-enabled projects anymore (well, in fact, you can add load(qt_config) on top of your .pro file and it may even work - no warranties of any kind, of course ;-).

Related

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.

Compiling Qt Tool out of Qt source tree

I am trying to compile canbusutil found in qtserialbus/src/tools/canbusutil out of the Qt source tree. So i just copied the folder to another place and tried to compile. However, I end up with this error:
Project ERROR: Project has no top-level .qmake.conf file.
So I had a look into the canbusutil.pro file:
QT = core serialbus
SOURCES += main.cpp \
readtask.cpp \
canbusutil.cpp \
sigtermhandler.cpp
HEADERS += \
readtask.h \
canbusutil.h \
sigtermhandler.h
load(qt_tool)
Removing the last line leaves me with different errors complaining that some conversions are not allowed or inherited methods not available. Building as part of the Qt sources works just fine. How do I have to adjust the *.pro file to get this to compile out of the Qt source tree.
You need to set the template, and make it a console project:
QT = serialbus
TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
SOURCES += main.cpp \
readtask.cpp \
canbusutil.cpp \
sigtermhandler.cpp
HEADERS += \
readtask.h \
canbusutil.h \
sigtermhandler.h
When I try to build qttools\src\linguist\lrelease
the tools are looking for .qmake.conf in the directory that contains the linguist directory. So qttools\src\.qmake.conf
the contents of my .qmake.conf file is:
load(qt_build_config)
CONFIG += qt_example_installs
MODULE_VERSION = 5.8.0
Disclaimer:
My experience with this is on Windows so far. Linux may have different default behavior, and I'm not yet sure which environment variable it would be related to.

QtCreator unable to find Qxt headers on Linux?

I'm working on a Qt5/QtQuick/QML application that's supposed to use QxtGlobalShortcut for hotkey control when the application is hidden or out of focus. I've been developing it using QtCreator on Linux, and I'm not entirely familiar with Linux development so I may have missed something simple.
First off, I tried cloning the master branch of the Qxt git repo from here. But for some reason ./configure failed to create a makefile according to an error that I was getting from make and make install. I'm not very experienced in building other people's projects/libraries from source, and the output I was getting from ./configure wasn't specific enough for me to figure out what was going on..
So instead, I decided to grab libqxt-dev from (X)ubuntu's APT repo. After it finished installing I added these lines to the bottom of my QtCreator project file:
INCLUDEPATH = usr/include
CONFIG += qxt
QXT += core gui
After setting up a basic global shortcut based totally off the Qxt documentation's example. I got a few compilation errors. First of all, the Qxt seem to use:
#include <QxtGlobalShortcut>
But QtCreator couldn't find that file, so I changed it to this:
#include <qxt/QxtGui/QxtGlobalShortcut>
Now it could find the Global Shortcut class header, and QtCreator stopped grumbling at me. Unfortunately, upon compilation QtCreator shot out this error message:
/usr/include/qxt/QxtGui/qxtglobalshortcut.h:28: error: qxtglobal.h: No such file or directory
I think this is caused by a problem in my project's INCLUDE path or something, but even having tried changing my projects INCLUDE path to this:
INCLUDEPATH = usr/include
usr/include/qxt/QxtCore
usr/include/qxt/QxtGui
CONFIG += qxt
QXT += core gui
I still get the same error message that QxtGlobal.h (which is being #included in QxtGlobalShortcut.h) can't be found..
So, I'm really not sure what I've done wrong, and I'm out of ideas about how to fix this.
Hopefully someone can help me understand what step I've skipped so that I can continue coding! Thanks!
EDIT: Here's what I have for my entire Qt project .pro file:
TEMPLATE = app
QT += qml quick
SOURCES += main.cpp \
Gamepad.cpp \
Script.cpp \
System.cpp
RESOURCES += qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Default rules for deployment.
include(deployment.pri)
HEADERS += \
Gamepad.h \
Script.h \
System.h
LIBS += -L/usr/lib -lSDL2
CONFIG += qxt
QXT += core gui
Everything before LIBS was automatically generated by QtCreator for my project. I added the LIBS, CONFIG, and QXT elements as per the user instructions for SDL2 and Qxt.
This is a big problem here:
INCLUDEPATH = usr/include
1) You are using relative path from the current working directory, so not /usr/include from the root of the filesystem.
2) You are deleting everything in the INCLUDEPATH because you set rather than append with +=.
3) It is unnecessary to add that line anyway since /usr/include will be looked up by default.
4) Even if it was not, you have #include "qxtglobal.h" instead of #include <qxtglobal.h>.
I would suggest to delete that line and then it should just work.

Build a 3rd party library from source within an existing Qt project

My project requires a version of zlib that isn't present on all target machines, so I want to build zlib from source in my project. Then when I make my project, it should first build zlib so it can be linked to when compiling my project.
One complication is that zlib requires configure to be run before make can be run.
I'm not even sure where to start here. Is there functionality built in to Qt Creator for importing 3rd party library source code like this, or do I need to code out a custom .pro file?
I tried the "Add Library..." menu that appears when right-clicking on my project, but it doesn't recognize the library - likely because no .pro file exists. I also tried to create a .pro file by File -> New Project -> Import Existing Project, and it's able to compile zlib once configure has been run, but it still doesn't generate a .pro file.
I thought that maybe the subdirs might be useful, but I'm not sure if that is the right route in this situation, and even if it is I am not sure whether I can auto-create the necessary .pro file, or I have to create it myself.
Given the source code for a 3rd party library like zlib, how do I integrate that into an existing Qt project such that I can compile the library from source, and use it in my project?
Yes, you need to create a project file for it. You can find my version below what I used for several projects.
zlib.pro
QT -= core gui
TARGET = zlib
TEMPLATE = lib
# Use this for static zlib rather than the default dynamic
# CONFIG += staticlib
include(zlib.pri)
zlib.pri
HEADERS += \
$$PWD/crc32.h \
$$PWD/deflate.h \
$$PWD/gzguts.h \
$$PWD/inffast.h \
$$PWD/inffixed.h \
$$PWD/inflate.h \
$$PWD/inftrees.h \
$$PWD/trees.h \
$$PWD/zconf.h \
$$PWD/zlib.h \
$$PWD/zutil.h
SOURCES += \
$$PWD/adler32.c \
$$PWD/compress.c \
$$PWD/crc32.c \
$$PWD/deflate.c \
$$PWD/gzclose.c \
$$PWD/gzlib.c \
$$PWD/gzread.c \
$$PWD/gzwrite.c \
$$PWD/infback.c \
$$PWD/inffast.c \
$$PWD/inflate.c \
$$PWD/inftrees.c \
$$PWD/trees.c \
$$PWD/uncompr.c \
$$PWD/zutil.c
INCLUDEPATH += $$PWD
Then in the project file including this one, you can do something like this:
main.pro
# CONFIG += order # If you wanna make sure about order. This is optional.
SUBDIRS += \
zlib \
...
If you wanna go even a bit more advanced with qmake, you can do something like this:
SUBDIRS += \
src_zlib \
src_mylib \
...
src_zlib.subdir = $$PWD/zlib
src_zlib.target = sub-zlib
src_zlib.depends =
src_mylib.subdir = $$PWD/mylib
src_mylib.target = sub-mylib
src_mylib.depends = src_zlib
As you can see this way, you would have a lot more reasonable control among the dependencies regardless the order set. For instance, you could still keep the entries in alphabetical order which is helpful with proper maintenance in the long run.
Then, you will need a line like this in the project file (.pro) of your subproject, let us say "foo", which depends on zlib.
foo.pro
LIBS += -L$${PROJECTROOT}/$${SUBDIR_TO_ZLIB} -lz
# These lines are only option, and you do not necessarily need them.
# win32:LIBNAME = zlib.dll
# unix:LIBNAME = libzlib.so
# PRE_TARGETDEPS += $${PROJECTROOT}/$${BUILD_SUBDIR_LIBS}/$${LIBNAME}
Following are instructions for adding a 3rd party repository to your Qt project and building it from source.
Some are able to add such libraries via Qt Creator, but I could never get that to work. So these are instructions on how to create the necessary .pro and .pri files instead. In this post, I will use zlib as an example, although other libraries should be similar.
Setup Build Order
Since your application depends on this library, we need to ensure that the library is built first. To do this, the 3rd party library and the source code for your application should be in sibling directories.
~/myApp $ ls myApp
src zlib
You probably already have a myApp.pro file that correctly builds your application. I recommend renaming it to src.pro, and you'll see why in the next step.
mv src/myApp.pro src/src.pro
Now you can create a new myApp.pro in the root directory.
~/myApp $ touch myApp.pro
~/myApp $ ls
myApp.pro src zlib
This is a rather simple .pro file that merely says "build zlib before myApp."
# ~/myApp/myApp.pro
TEMPLATE = subdirs
CONFIG += ordered # This tells Qt to compile the following SUBDIRS in order
SUBDIRS = zlib src
Create Library .pro File
Now we need to tell Qt how to build our 3rd party library. We do this by creating a new .pro file:
# ~/myApp/zlib/zlib.pro
TARGET = z # The name of the output library - can be whatever you want
TEMPLATE = lib # Tells Qt that we are compiling a library so the output will be bundled into a .a or .so file
CONFIG += staticlib # Tells Qt that we want a static library, so a .a file. Remove this and you will get a .so file
QMAKE_CFLAGS_WARN_ON -= -Wall # Optional - disable warnings when compiling this library
QMAKE_CXXFLAGS_WARN_ON -= -Wall # Optional - disable warnings when compiling this library
HEADERS += \
crc32.h \
deflate.h \
gzguts.h \
inffast.h \
inffixed.h \
inflate.h \
inftrees.h \
trees.h \
zconf.h \
zlib.h \
zutil.h
SOURCES += \
adler32.c \
compress.c \
crc32.c \
deflate.c \
gzclose.c \
gzlib.c \
gzread.c \
gzwrite.c \
infback.c \
inffast.c \
inflate.c \
inftrees.c \
trees.c \
uncompr.c \
zutil.c
If you are building something other than zlib, just change TARGET to the name of the library, and replace the contents of HEADERS and SOURCES with the files that need to be compiled for your library.
You can go ahead now and test out this .pro file.
~/myApp/zlib/ $ qmake
~/myApp/zlib/ $ make
...
~/myApp/zlib/ $ ls libz.a
libz.a
Yay!
Link The Library Into Your Application
Finally, we need to update the .pro file of your application to link in the 3rd party library. There are two parts to this:
Add library header files to your include path so the compiler can get the defined symbols from there.
Link the static (or shared) library during compile and linking time so the applicable object code can get linked into your application.
First, we'll add the header files into the include path. Add this line to src.pro.
INCLUDEPATH += zlib
This allows you to reference zlib.h in your code like so:
#include "zlib.h"
Otherwise, you would have to specify the full relative path of the header like this:
#include "zlib/zlib.h"
If you're fine with the second method, then there should be no need to update the INCLUDEPATH variable.
Second, we need to add the arguments the linker needs to find the static (or shared) library itself. Add this line to src.pro.
LIBS += -L$$PWD/../zlib -lz
The first part (-L$$PWD/../zlib) says that the folder containing the library is at ../zlib, which should be correct since zlib is a sibling folder to src. The second part (-lz) says that the name of the library is z. The linker infers from this that the library is actually located in the file libz.a.
Done
At this point, you may have to clean your build by doing a make distclean. But from there you should be able to build your project with the 3rd party library included by going to your base directory and running qmake and make.
cd ~/myApp
qmake -r
make
Note: Big thanks go to #LaszloPapp for getting this process started. Much of the source material for this answer came from his answer.
Alternatively if you are using QT Creator you could try to investigate "Project Settings" -> "Add Build Step" -> "Custom build step" and add script file there.
This could help to build lib before and then you just need to link it to your project.
I'm not sure, but most likelly you could pass the compilers settings like an argument to this script. I'm triing to solve it right now.

How to reference 3rd party dlls/libraries in Qt projects

Been trying to figure this out for an hour now. What I have is a simple Qt Project open in Qt Creator. What I would like to do is use the SDL library (dll) with my Qt project.
In visual Studio, what I would normall do is add a reference to this dll using VS tool that provides for that. In Qt creator, I opened the .pro file for my project, and added a LIB entry for the STD dll
# Add more folders to ship with the application, here
folder_01.source = qml/BoxGame
folder_01.target = qml
DEPLOYMENTFOLDERS = folder_01
# Additional import path used to resolve QML modules in Creator's code model
QML_IMPORT_PATH =
symbian:TARGET.UID3 = 0xEED812B5
# Smart Installer package's UID
# This UID is from the protected range and therefore the package will
# fail to install if self-signed. By default qmake uses the unprotected
# range value if unprotected UID is defined for the application and
# 0x2002CCCF value if protected UID is given to the application
#symbian:DEPLOYMENT.installer_header = 0x2002CCCF
# Allow network access on Symbian
symbian:TARGET.CAPABILITY += NetworkServices
# If your application uses the Qt Mobility libraries, uncomment the following
# lines and add the respective components to the MOBILITY variable.
# CONFIG += mobility
# MOBILITY +=
LIBS += C:\Users\vata\Desktop\DskProj\Dsk-build-desktop\debug\SDL.dll
# The .cpp file which was generated for your project. Feel free to hack it.
SOURCES += main.cpp \
blockboxes.cpp \
block.cpp \
boxengine.cpp \
boxgame.cpp \
point.cpp \
gamecontroller.cpp \
gamecontrollermod.cpp
# Please do not modify the following two lines. Required for deployment.
include(qmlapplicationviewer/qmlapplicationviewer.pri)
qtcAddDeployment()
HEADERS += \
blockboxes.h \
block.h \
boxengine.h \
boxgame.h \
Globals.h \
point.h \
gamecontroller.h \
gamecontrollermod.h \
controller.h
However, that does not seem to include the Library in Qt for my use. When I compile, I still get an SDL.h: No such file or directory error message. Would appreciate any help in figuring this out and probably learning for the future as I intend to use Qt more often than not for my development work.
Running build steps for project Tetris...
Starting: "C:\QtSDK\mingw\bin\mingw32-make.exe" clean
C:/QtSDK/mingw/bin/mingw32-make -f Makefile.Debug clean
SDL.h is a C header file, not a library. For the compiler to find it, you need to add its directory to qmake's INCLUDEPATH. For example:
INCLUDEPATH += C:/Dir/Where/SDL/Headers/Are/Found
(Tip: you can use / instead of \ to stay clear of possible interpretations of \ as an escape character.)
Try something like:
LIBS += -LC:\\Users\\vata\\Desktop\\DskProj\\Dsk-build-desktop\\debug -lsdl