Installing files using qmake: how to get the executable too? - c++

I'm building my app with qmake.
my project.pro file looks something like:
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += [all source files]
HEADERS += [all headers]
After a build, I want "make install" to copy everything required in a subfolder, so I added the following:
package.path = $${OUT_PWD}/package
package.files += myapp.exe myapp.ini [other dlls]
package.CONFIG = no_check_exist
INSTALLS += package
I cannot have in any way my compiled binary to be copied alongside; I prefixed it with $$OBJECTS_DIR/ and others, but I can't find the right variable containing the path to the build directory!
It seems these variables are meant as a way to change qmake's behaviour, for example to change the build directory. I don't want to change it; I want to access it!
Is there any other variable I could use? Basically, I want to put in "package.files" the full path to the compiled executable binary.
Thanks!

qmake puts the complied executable (or library) in the location pointed to by DESTDIR.
Usually, when I want to put the binary and support files, I will set DESTDIR to the location I want to install stuff, then set any INSTALLS.path to DESTDIR.
DESTDIR = $${OUT_PWD}/package
package.path = $${DESTDIR}
package.files += myapp.exe myapp.ini [other dlls]
package.CONFIG = no_check_exist
INSTALLS += package

Related

UI_project.h not found for QT project

I made a QT GUI project in VS 2019. It ran perfectly through VS. Copied the entire project files directory to Linux partition. Ran qmake -project in the directory containing the 'test2.sln' file to create a 'test2.pro' file. Opened the '*.pro' file through QT Creator. It imported everything fine. But, when building it it errors out saying "ui_test2.h file not found".
The test2.pro contains:
TEMPLATE = app
TARGET = test2
INCLUDEPATH += .
DEFINES += QT_DEPRECATED_WARNINGS
HEADERS += test2/test2.h test2/x64/Release/uic/ui_test2.h
FORMS += test2/test2.ui
SOURCES += test2/main.cpp test2/test2.cpp test2/x64/Release/rcc/qrc_test2.cpp
RESOURCES += test2/test2.qrc
What should I do to fix this?
1) remove folder with build (rm -r nameOfFolder)
2) rename your UI file (test2.ui -> mainwindow.ui) for example
3) check out name of own class and name of qt class in UI file (you can open it via vim or nano)
After that try to rebuild your project!
I hope you'll have done this with good results!

Standalone Application Qt

I have a Qt application that needs a specific folder and some files. This folder is now located inside the project folder. Is there any way to make this folder be "generated" when I use the make command to create the Standalone version of the program.
I was thinking about changing something in my .pro file but could not figure out any solution that way.
The folder contains some .lua code that I need to make the software work properly if the user select some functionalities.
One solution that copy these resources to destination folder the binary installed via qmake. Please refer to the link enter link description here
Some answers are out-of-date but inspire enough.
Possible solution(see http://doc.qt.io/qt-5/qmake-advanced-usage.html):
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
# Input
SOURCES += main.cpp
lua_dir.target = .makedir
lua_dir.commands = test -d lua_dir || mkdir lua_dir
QMAKE_EXTRA_TARGETS += lua_dir
PRE_TARGETDEPS += .makedir
You should replace lua_dir.commands = test -d lua_dir || mkdir lua_dir with appropriate to you command, I use bash command intepreter here.
you can change DESTDIR qmake variable to compile binary file straight to specified directory.
you can use INSTALLS:
someTarget.path = $$OUT_PWD/MyFolder
someTarget.files = $$PWD/SomeDirToCopy/*
INSTALLS += someTarget
this will copy all files from ProjectDirectory/SomeDirToCopy folder to BuildDirecory/MyFolder after you run make install in build directory.

Copy exe file to Qt build directory

I am trying to write a Qt application that will use QProcess to call ffmpeg.exe to convert media files. I cannot figure out the best way to make sure that the ffmpeg.exe file gets copied from my development directory to the build directory so that the built (and later deployed) application will have access to it.
I have seen information about using the INSTALLS parameter in my .pro file (https://stackoverflow.com/a/13168287) but the qmake docs say:
Note that qmake will skip files that are executable.
with all of the above said, how should one go about making sure that the exe file I want to use for QProcess ends up in the build directory (ready to be deployed later)?
You can use QMAKE_POST_LINK to execute a copy command when the application is built. Just put this in your .pro file :
win32:{
file_pathes += "\"$$PWD/Path/To/Files/ffmpeg.exe\""
CONFIG(release, debug|release):{
destination_pathes += $$OUT_PWD/release/
destination_pathes += Path/To/Deploy/Directory
}
else:CONFIG(debug, debug|release):{
destination_pathes += $$OUT_PWD/debug/
}
for(file_path,file_pathes){
file_path ~= s,/,\\,g
for(dest_path,destination_pathes){
dest_path ~= s,/,\\,g
QMAKE_POST_LINK += $$quote(xcopy $${file_path} $${dest_path} /I /Y $$escape_expand(\n\t))
}
}
}
You should add the paths for the files that you want to be copied to file_pathes variable and the paths to the destination directories to destination_pathes variable. Then all files would be copied to all the destinations when the application is built.
Here ffmpeg.exe gets copied to application build and deploy directories in release mode and to build directory in debug mode.

How to copy Qt runtime DLLs to project output

I have a simple project created in Qt Creator (installed using Qt SDK 1.1.4). It runs just fine from within Qt Creator, but if I then browse to the output directory in Windows and double-click the EXE, I'll get an error like:
The program can't start because QtCored4.dll is missing from your computer.
Try reinstalling the program to fix this problem.
That's obviously because Qt isn't in my PATH (and I don't want it to be, in case I have multiple versions of Qt on my computer), and Qt Creator / qmake didn't copy the Qt DLLs to the project output.
What I would like to do is use qmake to copy the necessary Qt files to the project output directory - wherever it may be. How do I do this?
(I tried creating a custom target in qmake, but I'm not getting too far...)
UPDATE July 19, 2016: Just to clarify, the above post was concerning Qt4. On Qt5, you should instead look into calling windeployqt. This Qt5 tool will read your binary, determine which Qt5 runtime files you need, and copy them to your binary directory. Also note that it will fix absolute paths in the Qt5::Core library that are specific to your PC - so use of this tool is basically mandatory unless you want to provide a qt.conf file yourself.
OK, here's an ugly hack:
# Copy required DLLs to output directory
CONFIG(debug, debug|release) {
QtCored4.commands = copy /Y %QTDIR%\\bin\\QtCored4.dll debug
QtCored4.target = debug/QtCored4.dll
QtGuid4.commands = copy /Y %QTDIR%\\bin\\QtGuid4.dll debug
QtGuid4.target = debug/QtGuid4.dll
QMAKE_EXTRA_TARGETS += QtCored4 QtGuid4
PRE_TARGETDEPS += debug/QtCored4.dll debug/QtGuid4.dll
} else:CONFIG(release, debug|release) {
QtCore4.commands = copy /Y %QTDIR%\\bin\\QtCore4.dll release
QtCore4.target = release/QtCore4.dll
QtGui4.commands = copy /Y %QTDIR%\\bin\\QtGui4.dll release
QtGui4.target = release/QtGui4.dll
QMAKE_EXTRA_TARGETS += QtCore4 QtGui4
PRE_TARGETDEPS += release/QtCore4.dll release/QtGui4.dll
} else {
error(Unknown set of dependencies.)
}
Here's some of what I don't like about it:
Uses %QTDIR% environment variable; this variable isn't evaluated until the copy command is actually run. Seems like something along the lines of QMAKE_LIBS_QT_DLL would be more appropriate, but I couldn't get that working for some reason.
Hard-coded "debug" and "release" names; seems like there ought to be some kind of variable to use for that.
Calling out to the environment by using the "copy" command.
I'll accept another answer if somebody can clean this up a good bit, for example by shortening it and/or addressing some of my concerns, or just finding a better way in general.
A bit cleaner method, but it will require doing a make install after a make. It will work on Windows, but would need tweaking for other platforms.
debug { DESTDIR = debug }
release { DESTDIR = release }
debug_and_release { DESTDIR = bin }
myqtlibs.path = $$DESTDIR
myqtlibs.files = $$QMAKE_LIBDIR_QT/*.dll junk.txt fred.out
myqtlibs.CONFIG = no_check_exist
INSTALLS += myqtlibs
If qmake is run just for debug, all output will go into ./debug . If it is just for release, all output goes in ./release . If both, then into ./bin .
I did notice that enabling shadow building in QtCreator caused the executable not to end up in the DESTDIR. I'm not quite sure why.
Copy Dependencies with windeployqt
# Deployment - Automatically Detect and Copy Dependencies to Build Folder
TARGET_CUSTOM_EXT = .exe
DEPLOY_COMMAND = windeployqt
DEPLOY_OPTIONS = "--no-svg --no-system-d3d-compiler --no-opengl --no-angle --no-opengl-sw"
CONFIG( debug, debug|release ) {
# debug
DEPLOY_TARGET = $$shell_quote($$shell_path($${OUT_PWD}/debug/$${TARGET}$${TARGET_CUSTOM_EXT}))
DEPLOY_OPTIONS += "--debug"
} else {
# release
DEPLOY_TARGET = $$shell_quote($$shell_path($${OUT_PWD}/release/$${TARGET}$${TARGET_CUSTOM_EXT}))
DEPLOY_OPTIONS += "--release"
}
# Uncomment the following line to help debug the deploy command when running qmake
#message($${DEPLOY_COMMAND} $${DEPLOY_OPTIONS} $${DEPLOY_TARGET})
QMAKE_POST_LINK = $${DEPLOY_COMMAND} $${DEPLOY_OPTIONS} $${DEPLOY_TARGET}
or Copy dependencies manually
# Deployment - Copy Dependencies to Build Folder
dlls.path = $${DESTDIR}
dlls.files += $$[QT_INSTALL_BINS]/icudt51.dll
dlls.files += $$[QT_INSTALL_BINS]/icuin51.dll
dlls.files += $$[QT_INSTALL_BINS]/icuuc51.dll
dlls.files += $$[QT_INSTALL_BINS]/libgcc_s_dw2-1.dll
dlls.files += $$[QT_INSTALL_BINS]/libstdc++-6.dll
dlls.files += $$[QT_INSTALL_BINS]/libwinpthread-1.dll
dlls.files += $$[QT_INSTALL_BINS]/Qt5Core.dll
dlls.files += $$[QT_INSTALL_BINS]/Qt5Network.dll
dlls.files += $$[QT_INSTALL_BINS]/Qt5Gui.dll
dlls.files += $$[QT_INSTALL_BINS]/Qt5Widgets.dll
dllA.path += $${DESTDIR}/platforms
dllA.files += $$[QT_INSTALL_PLUGINS]/platforms/qwindows.dll
dllB.path += $${DESTDIR}/plugins/imageformats/
dllB.files += $$[QT_INSTALL_PLUGINS]/imageformats/qico.dll
dllB.files += $$[QT_INSTALL_PLUGINS]/imageformats/qwbmp.dll
INSTALLS += dlls dllA dllB
Referencing: http://doc.qt.io/qt-5/qmake-variable-reference.html#deployment
In case you need to identify prerequisites / dependencies cross-platform, please take a look at CMake's getPrerequisites(). It uses dumpbin, objbin, ldd, otool for the identification of dependencies.
Referencing: https://cmake.org/cmake/help/v3.0/module/GetPrerequisites.html
I ran into the same problem and jwernerny's solution helped me a lot. However, I was using Shadow Build on Window 7 and it needed a bit more tweeking.
I also needed to set the DESTDIR according to the current configuration.
In my case I wanted to copy *.qml files, that's how I achieved it:
CONFIG(release, debug|release): DESTDIR = $$OUT_PWD/release
CONFIG(debug, debug|release): DESTDIR = $$OUT_PWD/debug
QmlFiles.path = $$DESTDIR/Qml
QmlFiles.files += $$files(Qml/*.qml)
INSTALLS += QmlFiles
EDIT :
Since I use Shadow Build I need to use $$OUT_PWD to get the output folder.

Automatic Copy of Dependent Files in Qt Creator

I've build a program using Qt Creator 2.2.1 and Qt 4.7.4 (32 bit) whose output is an executable. Opening the exe using DependencyWalker it shows that the exe uses following DLLs:
KERNEL32.DLL
MSVCRT.DLL
MINGWM10.DLL
LIBGCC_S_DW2-1.DLL
QTCORE4.DLL
QTGUI4.DLL
I want after the build all dependent files (which may be different in some other project) except Windows specific files (the first two in the above list) to be automatically copied in the directory where the exe is located.
How can I do it in Qt Creator or Qt system without using command line scripting? Thanks.
In QT 5.3, you may be able to use the windeployqt qt tool to automatically copy the needed libraries.
The following additions to the project's .pro file should do the trick, but you might have to make some adjustments based on your particular situation.
isEmpty(TARGET_EXT) {
win32 {
TARGET_CUSTOM_EXT = .exe
}
macx {
TARGET_CUSTOM_EXT = .app
}
} else {
TARGET_CUSTOM_EXT = $${TARGET_EXT}
}
win32 {
DEPLOY_COMMAND = windeployqt
}
macx {
DEPLOY_COMMAND = macdeployqt
}
CONFIG( debug, debug|release ) {
# debug
DEPLOY_TARGET = $$shell_quote($$shell_path($${OUT_PWD}/debug/$${TARGET}$${TARGET_CUSTOM_EXT}))
} else {
# release
DEPLOY_TARGET = $$shell_quote($$shell_path($${OUT_PWD}/release/$${TARGET}$${TARGET_CUSTOM_EXT}))
}
# # Uncomment the following line to help debug the deploy command when running qmake
# warning($${DEPLOY_COMMAND} $${DEPLOY_TARGET})
# Use += instead of = if you use multiple QMAKE_POST_LINKs
QMAKE_POST_LINK = $${DEPLOY_COMMAND} $${DEPLOY_TARGET}
I would modify your *.pro file for the project and use INSTALLS. To actually cause the files to be moved, you will need to run make install. In Qt Creator, you can add it as part of your normal build process by going into the "Projects" section and adding a new build step.
## This sets MY_LIB_FILES the libs you want and should also correctly resolve
## the location of the libs.
win32 { ## For Windows builds
# Note: Check to make sure of file name case
MY_LIB_FILES += $$QMAKE_LIBDIR_QT/MINGWM10.DLL
MY_LIB_FILES += $$QMAKE_LIBDIR_QT/LIBGCC_S_DW2-1.DLL
MY_LIB_FILES += $$QMAKE_LIBDIR_QT/QTCORE4.DLL
MY_LIB_FILES += $$QMAKE_LIBDIR_QT/QTGUI4.DLL
}
unix { ## For unix builds
# MY_LIB_FILES += $$QMAKE_LIBDIR_QT/...xxxxxx....
}
## Define what files are 'extra_libs' and where to put them
extra_libs.files = MY_LIB_FILES
extra_libs.path = $$DESTDIR
## Tell qmake to add the moving of them to the 'install' target
INSTALLS += extra_libs
Even though not totally automatic, you can with little effort do what you want with QtCreator.
Add the "INSTALLS" directive to your project (.pro) file (similar to what was suggested by jwernerny):
win32 {
libstocopy.files = $$QMAKE_LIBDIR_QT/MINGWM10.DLL \
... (add other files)
}
# If using MSVC the code may end up in "release" or "debug" sub dir
# Remove this if that is not the case
win32 {
CONFIG(debug, debug|release): OUTDIR = debug
else: OUTDIR = release
}
libstocopy.path = $$OUT_PWD/$$OUTDIR
INSTALLS += libstocopy
In the "Projects" tab of QtCreator (my version=2.4.1) you now add an extra build step:
Hit "Add Build Step"
Select "Make"
Leave "Override ..." empty
Enter "install" at "Make arguments:"
Since these settings are not saved with your project file you have to do the second part (Add Build Step) each time you create a new build configuration (e.g. one each for release and debug) or check out your project to a new location.
No-no-no 0_o :)
Create some directory to deploy files, i.e. "bin".
In every .pro file write
DLLDESTDIR = ../../myproject/bin (... some dir's struct ...)
QMAKE_POST_LINK = windeployqt --compiler-runtime $$DLLDESTDIR
DLLDESTDIR -- full path with file name TARGET (dll and exe).
End!