PDA

View Full Version : QMake INSTALLS skips files that don't exist (yet)



Brecht
25th October 2012, 14:57
I'm trying to set up a simple subdirs project with 1 application and 1 dll (on windows)

My application has this in the .pro file: (simplified it)
dll.path = $$OUT_PWD/debug
dll.files += $$OUT_PWD/../lib/debug/lib.dll
INSTALLS += dll

the dll project is called 'lib'.

When running qmake after a clean, the makefile does NOT have 'make install' rules for copying the file.
Only when I build the library, and the .DLL actually exists, will a second invoke of qmake update the makefile with a 'make install' rule that does the copying.

Am I missing something? Is this a bug?

I've tried doing it the other way around, letting the library install itself to the application build dir, but the problem remains. The .dll must exist for qmake to accept it as an install rule... (???)

Brecht
26th October 2012, 08:17
Just for the reference:
I've solved it, but using QMAKE_EXTRA_TARGETS and a PRE_TARGETDEPS.

It seems INSTALLS only works for external files.
It's a pity the documentation for INSTALLS is so brief.

wysota
26th October 2012, 10:21
What you want can be done using INSTALLS if lib.dll is the target of your project. Call the install target "target", don't set its "files" variable, only the "path" variable. I think you could also set some flag (nocheck_exists or something like that) on the install target and qmake will assume the files passed in "files" are valid.

Brecht
26th October 2012, 10:35
Thanks for the insight. Using the preconfigured install target "target" would indeed be sufficient for this small example.

Sadly, the real scenario is more complicated.
We have multiple applications (.exe files): the main app, the unit tests, and some prototypes or demo applications.
They should all use the same .dll.

So, it should be the application project that reaches out and fetches the .dll it needs and copies it to the proper location.
The dll project itself is not aware of the applications that use it, and should not copy the dll to multiple locations.

I've come up with a working solution using custom build targets:


utilDll.target = utilDll
utilDll.commands = $$OScopy($$BUILD_DIR/Util/$$CONFIGDIR/Util.dll ./$$CONFIGDIR/)
utilDll.depends = FORCE
QMAKE_EXTRA_TARGETS += utilDll
PRE_TARGETDEPS += utilDll

I guess INSTALLS only handles installation of the build target, or 3rd party libraries that were built before qmake is invoked.

One benifit from using custom build targets is: no need to run 'nmake install', or add this step to the build steps in QtCreator.

wysota
26th October 2012, 13:59
Thanks for the insight. Using the preconfigured install target "target" would indeed be sufficient for this small example.

Sadly, the real scenario is more complicated.
We have multiple applications (.exe files): the main app, the unit tests, and some prototypes or demo applications.
They should all use the same .dll.

So, it should be the application project that reaches out and fetches the .dll it needs and copies it to the proper location.
The dll project itself is not aware of the applications that use it, and should not copy the dll to multiple locations.
In my opinion copying the DLL to multiple locations defeats the purpose of using a DLL. You can circumvent that by placing the library in a path where all apps can find it.


I guess INSTALLS only handles installation of the build target, or 3rd party libraries that were built before qmake is invoked.
Not really, I'm succesfully using it to deploy other things too.

Brecht
26th October 2012, 14:49
In my opinion copying the DLL to multiple locations defeats the purpose of using a DLL. You can circumvent that by placing the library in a path where all apps can find it.
Seems very logical when you put it that way, but the problem is getting the apps to use that dll.

On windows, this means modifying the PATH environment variable to include this 'common' directory where all dlls are located.
According to the MSDN (http://msdn.microsoft.com/en-us/library/ms682586%28VS.85%29.aspx) the PATH directories are searched last, so there's a risk another DLL gets loaded.
The application direction is always the first folder to be searched, and that way you are 100% sure you are loading the correct dll.
I prefer to put them in the same folder as the exe.

And most of all, when someone checks out the project source from GIT, I don't want him to be forced to modify the PATH to be able to run it.

bcastalia
27th August 2014, 07:21
For the record:

no_check_exist can be added to the CONFIG property of a custom install target to prevent qmake from checking that the file to be installed exists. See the Custom install config section of the Undocumented qmake (http://www.qtcentre.org/wiki/index.php?title=Undocumented_qmake) wiki article.