Qt installation directory woes - visual-studio-2010

I want to use Qt in my new project. An installer for my target compiler (VS2010 64bit), does not exist.
I am using Windows 7 64-bit with Qt 5.1.1.
A colleague of mine is also planning on using Qt and has managed to compile it for my target compiler (which he uses as well). He has built it in some directory, say DirA. He graciously gives me a copy of his entire Qt SDK build (binaries, examples, headers, and all), and I copy it to DirB on my machine.
I need it in DirB, because that is where all my 3rd party libraries are installed, and my CMake scripts know how to find them. I also added the Qt bin folder to my path.
Problems ensue. Qt binaries for some reason have the install path (in this case the build path) hard coded within them. So even though the Qt bin folder is in my path (so DLLs are found), Qt's DLL(s) are looking in the wrong place for the windows "plugin". They are looking in DirA, which does not exist on my machine.
So from what I found researching, using a qt.conf file specifying the install path root, is supposed to be the way to go. I add one to my Qt bin dir, and now Qt binaries (assistant, qmake, etc) can run.
But now I build one of the examples. Builds fine. Run the exe, Qt DLLs load, and then it crashes because it can't find plugin directory.
A work-around my colleague and I found that seems to work, is to copy my qt.conf file to the directory my exe resides in. After doing that the exe runs.
But this does not seem right. My exe can find the Qt DLLs, but the Qt DLLs it loads can't find qt.conf. They don't know to look in their own containing folder. I must have qt.conf in my working directory (my exe dir) for it to be found and used.
Does anyone know why this might be happening, and know of a way for me not to be forced to have a qt.conf file in my exe's dir? I can't accept this requires a rebuild of Qt. There must be some other way.

You can put qt.conf into your binary. Using the resource system.
From the Qt docs:
Without qt.conf, the Qt libraries will use the hard-coded paths to
look for plugins, translations, and so on. These paths may not exist
on the target system, or they may not be accesssible. Because of this,
you need qt.conf to make the Qt libraries look elsewhere.
QLibraryInfo will load qt.conf from one of the following locations:
:/qt/etc/qt.conf using the resource system
Or:
Using QApplication::addLibraryPath() or
QApplication::setLibraryPaths(). This approach is recommended if you
only have one executable that will use the plugin.
If you add a custom path using QApplication::addLibraryPath it could look like this:
qApp->addLibraryPath("C:/customPath/plugins");

Related

Make Qt's Debugger Aware of DLL Dependency in CMake (Windows)

In Windows, I have a CMake build under Qt that locates, via a find_library command, an A.lib file that is in a separate directory relative to its A.dll file. The A.lib file is then linked using a target_link_libraries command.
As far as the build goes, CMake has no problem not having the symbols in the .lib file defined until runtime.
At runtime, I use windeployqt to successfully assemble all dependent libraries (indluding the A.dll file) into a separate deploy directory from the build directory, and I'm able to run there just fine.
However, to run via Qt's debugger, Qt runs the executable from the build folder rather than the deploy folder. By default, Qt attempts to add the build library folders to the PATH variable as well. Admirably, it also attempts to scan dependencies such as the Qt libraries and the path to A.lib and adds them to the PATH as well. Unfortunately, it does not add the path to A.dll, resulting in a failed DLL dependency error in the launched thread.
I can easily get around this by adding the path to A.dll to the PATH in Qt's run section of the Project tab. However, I'm curious, is it possible to make Qt catch this dependency via some CMake command and automatically add A.dll to the PATH, similar to how it caught other dependencies correctly? I'm not sure how Qt attempts to find dependencies, but in a previous QMake iteration of the build, the path to A.dll was appended automatically.
As of Qt 7.0.1, Qt added a workaround that allows the user to add dll paths to CMake via a target_link_directories command and have those parsed by Qt from the Cmake file-api to add to the PATH variable in Windows.
This fix is in Qt Creator 7.0.1, see the change summary here:
https://codereview.qt-project.org/c/qt-creator/qt-creator/+/404290
And the issue prompting this change on the official Qt website (which is where I should've looked first):
https://bugreports.qt.io/browse/QTCREATORBUG-27201?workflowName=Qt+Bug+Tracking+v2.4&stepId=8
It should be noted that a workaround for this issue was added to Qt Creator at an earlier point (I'm not sure exactly when) that looked one directory above the \lib folder for a \bin folder (see the code that implements this workaround, and performs the CMake file-api queries in general here).
The latter workaround happened to not work for my particular MSVC-built library folders, since there the lib and bin folders are themselves in folders with architecture and OS information, with a common parent three and two folders above, respectively.
Updating Qt Creator to 7.0.1 and using the target_link_directories command solves this issue.

Where does mac osx app require dependent libraries?

I have built a Qt project under mac, but I have problems executing.
Its dependencies have several dylib .
When building the project, the make tool only asks for one of the libs (for example lib.1.0.0,dylib out of lib.1.dylib, lib.1.0.dylib, lib.1.0.0.dylib, lib.1.0.0.0.dylib) - so I know to put it in the .pro file
Some look like links - but it is not always the lib version that looks like a file that is required as a dependency.
But at run time, I don't know which dylib I need, and where to put it.
I tried to place all 4 lib versions in the folder where the app was created - the project folder - but the app didn't execute.
Having done the same in Linux, I had to put the libs in a place set on path - like /usr/local/libs
Where does mac like its libs (shared libs ?) in order to run ?
You should read this document on deploying Qt applications. It will answer your questions. Moving your libraries to a system library path is usually not a good idea.
http://qt-project.org/doc/qt-5/macosx-deployment.html
To sum this up though you need to change the binaries to tell them where the libs are using the otool command.

QT Not including the correct library when running a build

I'm building a program Using Qt Creator 5.2.1 (32 bit) with Mingw. One of the dependencies of this program is the libcurl library.
QT was building the file properly, however, when running, it would throw an error 139.
After running the dependency walker on the binary, I noticed that the libcurl dll in turn depends upon another dll called "libeay32.dll".
I did the following:
Copied the my program along with all required libraries(including
libeay32.dll) externally to Qt and ran it (this was successful).
After that I tried running from within QT, but having the libeay32 library in the build before running (this was successful)
Logically, I presumed afterward, that if I put the path to the libeay32 prior to any other paths within my PATH variable, that It would pull the correct version of the lib (re: answer to question here). However this did not work, throwing the same error 139 (it's apparently not finding the library)
I know I could run and test my program by simply copying the file into my working directory, however, for information purposes, I was wondering;
Is there any way of doing this without having to copy this DLL?
My instinct would have been that fixing the Path to point to this firstly would have helped as this would ensure that the DLL is pulled used before any other occurrences that may be there in other dirs.
Note: In referring to the PATH variable, I mean both the SYSTEM path and checking for the PATH Qt uses (Qt adds a few dirs to the path)
Thanks in advance for any help.
Either you link static, or you have to ensure that your library is located in one of the following locations (http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586(v=vs.85).aspx#standard_search_order_for_desktop_applications):
The directory from which the application loaded.
The current directory.
The system directory. Use the GetSystemDirectory function to get the path of this directory.
The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.

How do I run a program linked against a DLL in MSYS?

I've successfully built a demo app using opencv on windows with the MSYS shell environment.
I did NOT use the prebuilt opencv installer, I downloaded and compiled the source locally (this is the recommended method).
After building opencv and running make install, all the files are happily in:
/e/deps/libopencv/build/install/
I can successfully build a sample application against this using cmake directives along the lines of:
find_package(OPENCV REQUIRED)
link_directory(${OpenCV_LIB_DIR})
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(target ${OpenCV_LIBS})
To be completely clear here: building the binary is successful.
Now, when I run it from the shell I get the message:
The program can't start because libopencv_core231.dll is missing from your computer.
Try reinstalling the program to fix this problem.
So... I know where the libraries are:
$ ls /e/deps/libopencv/build/install/lib/
libopencv_calib3d231.dll.a libopencv_features2d231.dll.a libopencv_highgui231.dll.a libopencv_ml231.dll.a libopencv_video231.dll.a
libopencv_contrib231.dll.a libopencv_flann231.dll.a libopencv_imgproc231.dll.a libopencv_objdetect231.dll.a
libopencv_core231.dll.a libopencv_gpu231.dll.a libopencv_legacy231.dll.a libopencv_ts231.a
What now?
I guess I could try to make cmake build a static binary, but that seems pretty extreme.
How can I somehow make either 1) windows, or 2) the MSYS environment happy. Something like LD_LIBRARY_PATH on windows?
Or is this not the problem, and I've actually (despite appearances) somehow messed up the way the binary was compiled?
Edit:
NB. For whatever reason it seems that my libraries are .dll.a files, not .dlls (see the ls result) if that's remotely relevant.
windows searches the same directory as the exe, any directory in the %PATH% (Windows) or $PATH (msys) directories, as well as a few special ones in the windows folder
You could add /e/deps/libopencv/build/install/lib to your $PATH. I am not sure if this will work for msys, you may need to add E:\deps\libopencv\build\install\lib to %PATH% in windows instead.
The typical solution for this if you are giving the program to others is to include a copy of the DLL in the same directory as the EXE. you can get this same effect by making a symbolic link to it with the command
ln -s /e/deps/libopencv/build/install/lib/libopencv_core231.dll libopencv_core231.dll
while in the /e/deps/libopencv/build/install/ directory

How to install Qt on Windows after building?

I can't find any information on how to install Qt built on Windows.
In wiki article How to set up shadow builds on Mac and Linux there's description of -prefix option in configure script but this option is not available on Windows.
I know I can use Qt right from the build folder but it does not seem the right thing not to perform an install step. One problem with this approach is size; Qt's build folder takes about 4GB space whereas after installing using binary installer Qt takes about 1GB space. I guess the difference is due to temporary files created during building. I hope some install procedure would install (copy) only needed files leaving temporary files in the build folder.
As İsmail said there's no install step for Qt on Windows.
However one can try to approximate it by performing the following operations.
Cleaning
Run make clean in the build folder to remove all temporary files.
Moving
Copy build folder to the place where you want Qt "installed". Let's call it INSTALL_DIR.
Fixing paths hardcoded in the qmake.exe executable
Run qmake -query to see what paths are compiled (hardcoded) into qmake and
a. Fix paths containing the build folder by replacing it with the INSTALL_DIR using qmake -set (1).
or
b. Create a qt.conf file in the bin subfolder of the INSTALL_DIR specifing new Qt paths inside it.
Adding current directory to include path
In Qt's provided binary distributions, the pwd is included in the QMAKE_INCDIR and thus ends up in your projects include path as ".". This does not happen by default in a custom built Qt, so you have to add the following line to mkspecs/YOUR-PLATFORM-HERE/qmake.conf file:
QMAKE_INCDIR += "."
Fixing prl files
When you add a Qt component to a project file (such as CONFIG += uitools), Qt looks in %QTDIR%/lib/QtUiTools.prl to find the library dependencies of that component. These files will have the hard coded path of the directory in which Qt was configured and built. You have to replace that build directory with the one to which you moved Qt for all lib/*.prl files.
Making source available
If you made a shadow build (build made inside folder other than the one containg sources), headers in the include subfolder only forward to the original headers. For example; BUILD_DIR\include\QtCore\qabstractanimation.h looks like this
#include "SRC_DIR/src/corelib/animation/qabstractanimation.h"
If you don't want to depend on the existence of the folder containg sources you have to copy SRC_DIR/src subfolder to your destination folder and fix all headers in the include folder so that they forward to the new location of src subfolder.
The bottom line:
The build process of Qt under Windows makes it really akward to move (install) Qt after building. You should do this only if ... well I can't find any good reason to go through all this trouble.
Remember
The easy way is to place Qt's sources in the folder where you want Qt to stay after building and make a build in this folder. This makes all steps but 1 and 4 above unnecessary.
1)
The variables you set with qmake -set are saved in the registry key
HKEY_CURRENT_USER\Software\Trolltech\QMake\<QMAKE_VERSION>.
Because of this you might have a problem when you would like to have different projects using different versions of Qt which happen to have the same version of qmake. In this case the better solution is to use qt.conf file (actually files as you need one file for each Qt installation) (option 3b).
Many of the information above come from the RelocationTricks wiki page authored by Gabe Rudy. Check out his Qt (Qt4) Opensource Windows Installers of Pre-built Binaries with MSVC 2008 project which gives you easy solution of above problems.
This answer is a replacement for steps 3 and 5 of Piotr's (currently top rated) answer above, but you may still need the other steps in his answer, depending what you're trying to achieve.
This is the operation which the official installer uses to fix the hardcoded paths during the installation: qt.520.win32_msvc2012.addons/meta/installscript.qs
This is how the operation is implemented: qtpatchoperation.cpp
This is the list of files that it fixes: files-to-patch-windows-qt5
And this shows how to invoke an installer operation as a standalone command from the commandline: Operations (Qt Installer Framework Manual)
To summarize: after moving your Qt directory to where you want it, download any one of the official Qt installers and run it with the following commandline arguments:
cd <path>
installer.exe --runoperation QtPatch windows <path> qt5
Replace <path> with the full path of your Qt directory after you moved it (the qtbase directory if you are using Qt 5). Omit the final qt5 argument if you are using Qt 4.
This will fix the hardcoded paths in qmake.exe, .prl files, and others. It gives you the exact same behaviour that the official installers have in that respect.
For the initial move, nmake "INSTALL_ROOT=\somewhere" install works for me. So that's steps 1 and 2 of Piotr's answer covered. And I haven't needed steps 4 or 6, FWIW.
I can configure QT 5 on WINDOWS (Visual Studio build) with the prefix option like:
configure -prefix C:\the\path\I\want ...
then call:
nmake
nmake install
and the latter will install Qt in C:\the\path\I\want.
I did it without problems with Qt 5.2.1 and 5.3.x, so far. So, any earlier problems seem to be fixed by now.
It's very odd people claim that there is no "make install" on Windows.
I have used it many times, and I agree that it's not what it is on other platforms, but it serves its purpose.
How I use Qt's make install on Windows (from cmd):
configure
(n/mingw32-)make
(n/mingw32-)make docs
(n/mingw32-)make install
The make install bit copies all necessary headers to be able to delete your source directory. Delete all objects and unecessary stuff:
del /S /Q *.obj lib\*.dll
rmdir /S /Q docs-build qmake tools src
This allows you to remove the source directory. I don't know what impact this has on debugging Qt source code, but it sure reduces the size of a shadow build. I use it to maintain 32 and 64 bit builds with minimal size.
Qt on Windows is not installable with make install, you will notice that Qt installer for Windows just patches dlls & pdbs for the new install location.
What I would suggest is to do a shadow build in the place you would like to install it. You can manually remove *.obj files to save up space.
Qt's own build instructions show how this is done, by search/replace within each Makefile. Assuming the source was extracted to C:\qt-4.8.3 and build was performed within that directory, then do this:
fart -c -i -r Makefile* $(INSTALL_ROOT)\qt-4.8.3 $(INSTALL_ROOT)\my-install-dir
set INSTALL_ROOT=
mingw32-make install
Then create a config file that tells qmake about its new installation path. Create a textfile C:\my-install-dir\bin\qt.conf:
[Paths]
Prefix=C:/my-install-dir
Translations = translations
Then as a final step (as Randy kindly pointed out) you need to patch qmake.exe, which can be done using a simple utility called QtMove. This same tool also automatically updates all the prl files.
Step 1: Move Qt
Cut and Paste
Current directory - C:\tools\Qt
Destination directory -C:\sim\dep\Qt
Step 2: Get Old Qt Directory
Go to C:\sim\dep\Qt\2010.02.1\Qt
Open .qmake.cache
Find variable QT_SOURCE_TREE
Note the value of QT_SOURCE_TREE
Mine was C:\tools\Qt\2010.02.1\Qt
Step 3: Patch Qt
Go to C:\sim\dep\Qt\2010.02.1\bin
The syntax is qpatch.exe list oldDir newDir
qpatch.exe files-to-patch-windows C:\tools\Qt\2010.02.1\Qt C:\sim\dep\Qt\2010.02.1\Qt
Step 4: Set Environment Variables
set QTDIR=C:\sim\dep\Qt\2010.02.1\Qt
set QMAKESPEC=C:\sim\dep\Qt\2010.02.1\Qt\mkspecs\win32-g++
set PATH=%path%;C:\sim\dep\Qt\2010.02.1\Qt\bin
set PATH=%path%;C:\sim\dep\Qt\2010.02.1\bin
You can do all of this with a batch file. This took me a fair while to work out and it has saved me a lot of time since. It's a script to automatically update a Qt installation to new locations. The batch file is available here.
There is a simple utility QtMove (http://www.runfastsoft.com) can do this easily.
Runs the relocated qmake.exe build your .pro file and everything should be linked with new Qt libs.

Resources