Automatic Copy of Dependent Files in Qt Creator - c++

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!

Related

Qt install won't copy files

I'm using Qt 5.5 for a project, and am trying to use the install feature to copy files into the build directory. I have in my .pro (this is a simplified version I am using to try and figure out the issue):
copy_files.path = $${OUT_PWD}/debug
copy_files.files = win32_libs/*
INSTALLS += copy_files
I have in the build configuration an extra step after "make" which is "Make install" for both debug and release (selected from the "Make" drop down item). After clean -> run qmake -> build, Qt absolutely refuses to copy any of the files in "win32_libs" into the debug build directory.
If I specify just "win32_libs" instead of "win32_libs/*", it will copy the directory (not helpful), and it turns out it will copy any directory, but no files unless they are CONTAINED in a directory (again, not helpful).
So how can I convince it to just copy the files?
After facing similar problem and no being able to solve it directly I decided to do the workaround for the Windows target like:
# post build copy dependencies
win32 {
# all the necessary files listed relative to the root project directory
OTHER_FILES += stuff\myfile1 stuff\myfile2
OTHER_FILES += stuff\myfile3 stuff\myfile4
DESTDIR_WIN = $$DESTDIR
DESTDIR_WIN ~= s,/,\\,g
# debug pro file statement
message(Destination WINDOWS $$DESTDIR_WIN)
PWD_WIN = $${PWD}
PWD_WIN ~= s,/,\\,g
for(FILE, OTHER_FILES){
QMAKE_POST_LINK += xcopy /d/y $${PWD_WIN}\\$${FILE} $${DESTDIR_WIN}$$escape_expand(\\n\\t)
}
}
And xcopy command provided with parameters to avoid actual unnecessary copy.

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.

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

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

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.

Problem installing QCA-OSSL (part of the Qt Cryptographic Architecture) plugin on Windows 7

I have been trying to use QCA (Link) on my Windows PC for a couple of days now, works fine on my linux box, just can't get it working with Windows.
So i followed all the instructions for installing QCA and then the ossl plugin for QCA. The QCA works fine but for some reason the plugin isn't showing up in my Qt Creator nor am I able to use some of the functions in the plugin.
I used the qcatool2.exe that comes with QCA to check my plugins using
qcatool2 plugins --debug
and get this error message:
plugin: qca-ossl2.dll: failed to load: The plugin 'C:/Qt/2010.05/qt/plugins/crypto/qca-ossl2.dll' uses incompatible Qt library. Expected build key "Windows mingw debug full-config", got "Windows mingw release full-config"
Now this seems to me as if qt requires the plugin to be compiled in debug mode (as to get the build key to contain debug rather than release) so I added
CONFIG += debug
to my plugin's project file and ran qmake and mingw32-make as usual but this seems to have had no effect.
My project file for the plugin is now:
TEMPLATE = lib
CONFIG += plugin
QT -= gui
DESTDIR = lib
VERSION = 2.0.0
unix:include(conf.pri)
windows:CONFIG += crypto
windows:include(conf_win.pri)
CONFIG += create_prl
SOURCES = qca-ossl.cpp
windows:{
load(winlocal.prf)
isEmpty(WINLOCAL_PREFIX) {
error("WINLOCAL_PREFIX not found. See http://delta.affinix.com/platform/#winlocal")
}
OPENSSL_PREFIX = $$WINLOCAL_PREFIX
DEFINES += OSSL_097
INCLUDEPATH += $$OPENSSL_PREFIX/include
LIBS += -L$$OPENSSL_PREFIX/lib
LIBS += -llibeay32 -lssleay32
LIBS += -lgdi32 -lwsock32
}
!debug_and_release|build_pass {
CONFIG(debug, debug|release) {
mac:TARGET = $$member(TARGET, 0)_debug
windows:TARGET = $$member(TARGET, 0)d
}
}
CONFIG += debug
Has anyone got any ideas? If you need anymore details just ask, I've tried to be as thorough as possible. Thanks
Tom
I've been struggling with a similar situation: qca-ossl builds fine on linux and not at all on windows. I just hit a breakthrough which might help you as well.
Versions and Patches
qtsdk-2010.05
qca-2.0.3
qca-ossl-r1190163 (from the repository)
openssl-1.0.0b
First of all, if you're using a newer version (0.9.7+, I think) of OpenSsl, you may need to use the qca-ossl version from the repository since it patches some incompatibilities. I also needed to comment out some lines in the new qca-ossl.cpp file dealing with SHA224, SHA256, SHA384, and SHA512 to avoid build errors. I'm using qca-ossl for the ciphers, so I'm not worried about hashing and didn't investigate the errors very much.
Fixing It
The windows build problems were many fold for me, but most of them stem from the shoddy build setup for the windows version of the plugin. It's nice having a little configure script for the linux side of things, but what about windows? We need to do a little extra work.
Some of this extra work is because I've chosen non-standard locations for the support libraries of my application. Qca and OpenSsl both exist within the project's directory structure in a libraries/ directory. My guess is that you've done something similar if you are trying to cross compile your application, but even if you didn't the following should help.
Finding OpenSsl
Qca-ossl wont build very well if it can't find the library it's supposed to connect to... :) So let's specify directly where it is. Comment out the lines relating to winlocal.prf and the changes that stem from it in qca-ossl.pro. We will directly specify where to find openSsl.
TEMPLATE = lib
CONFIG += plugin
QT -= gui
DESTDIR = lib
VERSION = 2.0.0
unix:include(conf.pri)
windows:CONFIG += crypto
windows:include(conf_win.pri)
CONFIG += create_prl
SOURCES = qca-ossl.cpp
windows:{
# Rather than rely on the winlocal.prf file, we will specify the location of the openssl
# by hand when running qmake.
#
# load(winlocal.prf)
# isEmpty(WINLOCAL_PREFIX) {
# error("WINLOCAL_PREFIX not found. See http://delta.affinix.com/platform/#winlocal")
# }
#
# OPENSSL_PREFIX = $$WINLOCAL_PREFIX
DEFINES += OSSL_097
INCLUDEPATH += $$OPENSSL_PREFIX/include
LIBS += -L$$OPENSSL_PREFIX/lib
LIBS += -llibeay32 -lssleay32
LIBS += -lgdi32 -lwsock32
}
!debug_and_release|build_pass {
CONFIG(debug, debug|release) {
mac:TARGET = $$member(TARGET, 0)_debug
windows:TARGET = $$member(TARGET, 0)d
}
}
Now we have direct access to the $$OPENSSL_PREFIX environment variable in the .pro file. We can set it when we call qmake by doing the following.
qmake.exe "OPENSSL_PREFIX=C:/path/to/openssl-1.0.0b"
You should be able to use backward slashes or forward slashes. Here I choose forward since Qt has deprecated them since 4.7.
Alternatively, you could set the OPENSSL_PREFIX variable directly in the .pro file.
Finding Qca
After comparing the unix and windows makefiles for qca-ossl, oddly enough, it never includes the qca libraries for building or linking! ?!?! This led to an "Undefined interface" error on the Q_INTERFACES(QCAPlugin) line of the opensslPlugin class definition at the end of qca-ossl.cpp.
To avoid this, we will need to explicitly define the include and library paths by hand. Expanding on the qmake line from the last section the final qmake line is as follows.
qmake.exe "OPENSSL_PREFIX=C:/path/to/openssl-1.0.0b" "INCLUDEPATH+=C:/path/to/qca-2.0.3/include/QtCrypto" "LIBS+=-LC:/path/to/qca-2.0.3/lib -lqca2"
"Installing" Qca-ossl
After running the qmake line above and running a plain ol' make, you'll need to install Qca-ossl. You can copy the resulting dll from the lib/ directory to your Qt's plugins directory, which if you're using my versions defaults to C:\Qt\2010.05\qt\plugins\crypto. Alternatively, you can move it to a crypto directory that's at the root level of your project's directory structure such as C:\path\to\my\project\crypto.
I hope this helps!
Actually, you can try this tutorial QCA+OpenSSL on Window. It's work well.
By the way, I can make use of QCA with AES 256 on Window. But i can't use it on Symbian. Any idea to do it?
Related Post