Copying .dlls into target directory



  • Hi, all -

    I'm sure this must be a dupe, but I've searched the forum and haven't found anything. The answers on Stack Exchange don't work for me, so I figured I'd better ask the experts.

    I'm building a small app using Creator and MinGW. There are a handful of .dlls that the app needs, and I'd like to copy them to the target directory (for ease of making an installation package). Can someone please tell me how this is done?

    Using Creator 4.1 with the included MinGW package, on Windows 7.

    Thanks...


  • Moderators

    Hi,

    Some clarifications first:

    1. Do you mean Qt DLLs, or 3rd-party DLLs, or both?
    2. Which answers from Stack Exchange have you tried? (So that you don't get answers telling you to do something you've already done)
    3. Are you able to run your app properly from within Qt Creator?

    Anyway, as a starting point, have a look at windeployqt: http://doc.qt.io/qt-5/windows-deployment.html



  • Hi, JKSH -

    1. I mean third-party libraries. These are to be found in the MinGW directory tree.
    2. here are a few answers:
      other answers
      the first suggestion is more complicated than I want to try, and the second answer doesn't work because it says that the extra_libs.path path isn't defined. (Do I need to define DESTDIR myself? I thought it was a built-in variable.
    3. yes.

    Thank you.


  • Moderators

    The answers in your link were complicated because the asker wanted everything done automatically. This is not strictly necessary (but it does save you a minute or so each time you want to deploy)

    From the Windows command line, do this:

    1. Navigate to the folder which contains your Qt DLLs
    2. Add the MinGW directory to your PATH
    3. Run the deployment tool, tell it where to find your built executable (see http://doc.qt.io/qt-5/windows-deployment.html)

    Example: (Assumes that you installed Qt into C:\Qt, that you're using Qt 5.6.2,, and that you have compiled your app into D:\Projects\MyApp\build-MyApp-Desktop_Qt_5_6_2_MinGW_32bit-Release\release)

    > cd C:\Qt\5.6\mingw49_32\bin
    > set path=%path%;C:\Qt\Tools\mingw492_32\bin
    > windeployqt.exe D:\Projects\MyApp\build-MyApp-Desktop_Qt_5_6_2_MinGW_32bit-Release\release
    


  • as an altrenative, in your .pro file just add to INSTALLS the libraries you want and calling make install will copy them over



  • Thank you both.

    I think I prefer the solution proposed by VRonin, mainly because I understand it better. Unfortunately, I'm getting this error when I try to build:

    :-1: warning: C:/Qt/5.7/mingw53_32/bin\libgcc_s_dw2-1.dll.path is not defined: install target not created

    The path is definitely there, and the file exists. What am I doing wrong?

    Thanks...



  • Could you post the content of the pro file?

    Maybe just running qmake again is enough to fix this problem



  • Hi, Vronin -

    I fixed that problem by following the syntax used in the examples I posted above (with the .path and the .files).

    Now I get no errors, but the file still doesn't move to the target directory (in this case, the debug directory).

    .pro file:

    TEMPLATE = app
    CONFIG += CONSOLE
    CONFIG -= qt
    TARGET = storefile
    SOURCES += \
    	storefile_client.cpp
    
    #win32:QMAKE_CXXFLAGS += /MD
    
    HEADERS += \
    	storefile_client.h \
    
    win32:LIBS += "C:\Program Files (x86)\Windows Kits\8.0\Lib\win8\um\x86\ws2_32.lib"
    
    INCLUDEPATH += "../ARM/inc/"
    
    win32 {
        libsto_copy.files += $$QMAKE_LIBDIR_QT/libgcc_s_dw2-1.dll
    }
    libs_to_copy.path = $$OUT_PWD/$$OUTDIR
    INSTALLS += libs_to_copy
    #INSTALLS += $$[QT_INSTALL_BINS]\libgcc_s_dw2-1.dll
    #INSTALLS += C:\Qt\5.7\mingw53_32\bin\libgcc_s_dw2-1.dll
    
    

    Thank you.



  • fixed the typo; still doesn't work:

    TEMPLATE = app
    CONFIG += CONSOLE
    CONFIG -= qt
    TARGET = storefile
    SOURCES += \
    	storefile_client.cpp
    
    #win32:QMAKE_CXXFLAGS += /MD
    
    HEADERS += \
    	storefile_client.h \
    
    win32:LIBS += "C:\Program Files (x86)\Windows Kits\8.0\Lib\win8\um\x86\ws2_32.lib"
    
    INCLUDEPATH += "../ARM/inc/"
    
    libs_to_copy.files = $$QMAKE_LIBDIR_QT/libgcc_s_dw2-1.dll
    libs_to_copy.path = $$OUT_PWD/$$OUTDIR
    INSTALLS += libs_to_copy
    #INSTALLS += $$[QT_INSTALL_BINS]\libgcc_s_dw2-1.dll
    #INSTALLS += C:\Qt\5.7\mingw53_32\bin\libgcc_s_dw2-1.dll
    

    Oddly enough, it's copying the .o file, but not the .dll I want.


  • Qt Champions 2016

    Hi
    Im wondering if mixing

    / and  \ is ok?
     C:/Qt/5.7/mingw53_32/bin\libgcc_s_dw2-1.dll. 
                             ^
    


  • @mrjj said in copying .dlls into target directory:

    Hi
    Im wondering if mixing

    / and  \ is ok?
     C:/Qt/5.7/mingw53_32/bin\libgcc_s_dw2-1.dll. 
                             ^
    

    Good question. In my hard-coded tests, I tried it with all "/" and all "" and get the same error, though.

    Does qmake have some kind of echo function where I can output the value of variables?

    Thanks.


  • Qt Champions 2016

    Ok, was just a thought.
    You can outout with

    message($$VAR)



  • Well, I'm still stuck on this. The problem appears to be in this area:

    DESTDIR = $$(OUT_PWD)
    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
    

    I get this error (warning):

    :-1: warning: extra_libs.path is not defined: install target not created

    OUT_PWD appears to be OK. I don't really know what I'm doing with the variable "extra_lib" as that was just yanked from an example above. I assumed the .files and .path were properties of the variable, but now I'm questioning what I'm doing.

    Anyone able to shed some light onto this?

    Thanks.

    UPDATE:

    I just clicked on the "see more replies" part of the answer I was trying to copy -- someone claims that INSTALLS doesn't work on Windows. Can anyone confirm or deny this? I don't find anything about this limitation in the docs. I tried invoking the make from the command line, and got this:

    C:\Qt\Tools\mingw530_32\bin>.\mingw32-make.exe install
    mingw32-make: *** No rule to make target 'install'.  Stop.
    

    So I guess it is true...?


  • Moderators

    Try using hard-coded paths first and see if you can get that to work. After you succeed, replace the hard-coded paths with variables.

    (I haven't used INSTALLS before and don't currently have access to a computer to try it myself)



  • Now using:

    C:\Qt\5.7\mingw53_32\bin
    

    Same results.


  • Qt Champions 2016

    well I was under the impression that make install was a unix thing as doc mentioned but
    then i read that mingw-make does have "install". I have however never tried it.

    But the plugandpaint example has

    target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/plugandpaint
    INSTALLS += target
    which maps to
    C:/Qt/Examples/Qt-5.7/widgets/tools/plugandpaint
    But nothing is copied there so Im not sure it does work.


  • Qt Champions 2016

    @mrjj said in copying .dlls into target directory:

    well I was under the impression that make install was a unix thing as doc mentioned but

    No, it's a make thing. Any self-respecting make implementation (including MS's nmake) should provide the install target out of the box. :)

    But the plugandpaint example has

    Well, how did you install? Did you call make install (or equivalent) from the Qt source's base path? If not, you've erred, because there's a chain of pro files (and mkspecs and other goodies that get included and ultimately the QT_INSTALL_EXAMPLES is set for you). But anyway, that's another matter altogether.

    @mzimmers

    I suggest you run qmake manually with -d or -d -d to get some debug info back. It is possible that the qmake's makefile generator doesn't respect the INSTALLS variable (although I see no reason it shouldn't).

    Kind regards.



  • @kshegunov - thank you for the suggestion. I tried this and got ~6700 error messages; I'm not sure I did it correctly.

    I do have another question: my build steps are to run make first, then qmake. If qmake is a "meta-make" tool, shouldn't the order be 1) qmake and 2) make?

    Thank you.


  • Moderators

    @mzimmers Yes qmake should be the first one



  • Well, somehow they got switched (I probably fat-fingered it). I put them in the correct order (qmake, make, make install) and still it doesn't copy the files. Here's the compiler output:

    08:42:17: Running steps for project storefile_client...
    08:42:17: Configuration unchanged, skipping qmake step.
    08:42:17: Starting: "C:\Qt\Tools\mingw530_32\bin\mingw32-make.exe" 
    C:/Qt/Tools/mingw530_32/bin/mingw32-make -f Makefile.Debug
    mingw32-make[1]: Entering directory 'C:/Users/mzimmers/Wideband/Peninsula/build-storefile_client-Desktop_Qt_5_7_0_MinGW_32bit-Debug'
    g++ -c -pipe -fno-keep-inline-dllexport -g -std=gnu++11 -frtti -Wall -Wextra -fexceptions -mthreads -DUNICODE -DQT_QML_DEBUG -I..\storefile_client -I. -I..\ARM\inc -IC:\Qt\5.7\mingw53_32\mkspecs\win32-g++  -o debug\storefile_client.o ..\storefile_client\storefile_client.cpp
    g++ -Wl,-subsystem,console -mthreads -o debug\storefile.exe debug/storefile_client.o  "C:\Program Files (x86)\Windows Kits\8.0\Lib\win8\um\x86\ws2_32.lib" 
    mingw32-make[1]: Leaving directory 'C:/Users/mzimmers/Wideband/Peninsula/build-storefile_client-Desktop_Qt_5_7_0_MinGW_32bit-Debug'
    08:42:18: The process "C:\Qt\Tools\mingw530_32\bin\mingw32-make.exe" exited normally.
    08:42:18: Starting: "C:\Qt\Tools\mingw530_32\bin\mingw32-make.exe" install
    C:/Qt/Tools/mingw530_32/bin/mingw32-make -f Makefile.Debug install
    mingw32-make[1]: Entering directory 'C:/Users/mzimmers/Wideband/Peninsula/build-storefile_client-Desktop_Qt_5_7_0_MinGW_32bit-Debug'
    **mingw32-make[1]: Nothing to be done for 'install'.**
    mingw32-make[1]: Leaving directory 'C:/Users/mzimmers/Wideband/Peninsula/build-storefile_client-Desktop_Qt_5_7_0_MinGW_32bit-Debug'
    08:42:19: The process "C:\Qt\Tools\mingw530_32\bin\mingw32-make.exe" exited normally.
    08:42:19: Elapsed time: 00:02.
    

    To my layman eyes, it's looking more like the make that comes with mingw doesn't honor installs?


  • Qt Champions 2016

    Honestly, I have no idea. Could you attach the make file and the pro you're currently using?



  • @kshegunov : I don't know how to attach files, so I uploaded them to here.

    You should be able to view and/or download from there. If not, please let me know.

    Thanks...


  • Qt Champions 2016

    I don't know how to attach files

    That's what I meant - upload and post the link.

    From what I can see in the makefile your install target is empty (FORCE goes to the end):

    install:  FORCE
    

    And there's something suspicious about the .pro, you've commented INSTALLS += libs_to_copy and used INSTALLS += C:\Qt\5.7\mingw53_32\bin\libgcc_s_dw2-1.dll instead.

    I suggest setting a hard path (not through a var) for the libs_to_copy contents and trying with INSTALLS += libs_to_copy. After modifying the file, don't forget to run qmake and then make, make install.



  • I tried this:

    libs_to_copy = "C:/Qt/5.7/mingw53_32/bin/libgcc_s_dw2-1.dll"
    INSTALLS += libs_to_copy

    and I get this error:

    :-1: warning: libs_to_copy.path is not defined: install target not created

    When I do this:
    libs_to_copy.files = $$(QMAKE_LIBDIR_QT)/libgcc_s_dw2-1.dll
    libs_to_copy.path = $$(OUT_PWD)/$$(OUTDIR)
    INSTALLS += libs_to_copy

    I don't get the error, but the file doesn't copy.


  • Qt Champions 2016

    @mzimmers said in Copying .dlls into target directory:

    libs_to_copy.files = $$(QMAKE_LIBDIR_QT)/libgcc_s_dw2-1.dll
    libs_to_copy.path = $$(OUT_PWD)/$$(OUTDIR)
    INSTALLS += libs_to_copy
    

    I don't get the error, but the file doesn't copy.

    What about this:

    libs_to_copy.files = C:/Qt/5.7/mingw53_32/bin/libgcc_s_dw2-1.dll
    libs_to_copy.path = $$(OUT_PWD)
    
    INSTALLS += libs_to_copy
    

    ?

    Alternatively you could try to add an additional target.



  • @kshegunov said in Copying .dlls into target directory:

    @mzimmers said in Copying .dlls into target directory:

    libs_to_copy.files = $$(QMAKE_LIBDIR_QT)/libgcc_s_dw2-1.dll
    libs_to_copy.path = $$(OUT_PWD)/$$(OUTDIR)
    INSTALLS += libs_to_copy
    

    I don't get the error, but the file doesn't copy.

    What about this:

    libs_to_copy.files = C:/Qt/5.7/mingw53_32/bin/libgcc_s_dw2-1.dll
    libs_to_copy.path = $$(OUT_PWD)
    
    INSTALLS += libs_to_copy
    

    ?

    That gives me this error:

    :-1: warning: libs_to_copy.path is not defined: install target not created

    Alternatively you could try to add an additional target.

    I may have to fall back to this, if it turns out that the INSTALLS directive doesn't work.

    Thanks...



  • @mzimmers ... Your solution for copying looks pretty good. I am going to remember it. You mentioned modifying DESTDIR. I actually prefer doing that as well as setting the MOC_DIR and OBJECTS_DIR to make the build where I know things are located. It also makes it clean. When doing this, I turn off the shadow build into that horrendously long path. My structure is typically as follows (only release config):

    <root>
       bin
          plugins
          ,,,
       build
          <subproject>
             release
                moc
                obj
          ...
          <main app>
             release
                moc
                obj
       lib
          release
    

    As you can see it is relatively clean and you know where things are built. I use MSYS2 for development because I can get 32 and 64 bit development. QtCreator 4.1.x for IDE.

    I copy my 3rd party DLLs (except MSYS) into bin for testing. Typically I have only needed a few MSYS dlls so it is not too hateful.

    [edit: code tags added: mrjj]



  • @Buckwheat I wish I knew how to make indents in the forum ;D


  • Qt Champions 2016

    @Buckwheat
    use the code tag ``` ( before and after)
    and it wont eat indentation :)



  • @mrjj Thanks!


  • Qt Champions 2016

    @mzimmers said in Copying .dlls into target directory:

    That gives me this error:
    :-1: warning: libs_to_copy.path is not defined: install target not created

    Sorry, I might've mislead you. Try with:

    libs_to_copy.path = $$OUT_PWD
    

    Notice the lack of parenthesis. It's a bit cumbersome like this, but I don't have a windows machine on hand to test. If you continue to get an error run qmake with -d and attach the output, e.g.

    qmake -d myproject.pro
    


  • @kshegunov said in Copying .dlls into target directory:

    Notice the lack of parenthesis. It's a bit cumbersome like this, but I don't have a windows machine on hand to test. If you continue to get an error run qmake with -d and attach the output, e.g.
    qmake -d myproject.pro

    Here's the output:

    link text

    LOTS of stuff there, and I don't understand most of it.


  • Qt Champions 2016

    @mzimmers said in Copying .dlls into target directory:

    and I don't understand most of it.

    No one does, perhaps with the exception of the qmake's developers. ;)
    Anyway, there seems to be a problem with the paths:

    DEBUG 1: C:/Users/mzimmers/Wideband/Peninsula/storefile_client/storefile_client.pro:17: libs_to_copy.files := /libgcc_s_dw2-1.dll
    DEBUG 1: C:/Users/mzimmers/Wideband/Peninsula/storefile_client/storefile_client.pro:19: libs_to_copy.path := C:/Users/mzimmers/Wideband/Peninsula/build-storefile_client-Desktop_Qt_5_7_0_MinGW_32bit-Debug
    ...
    DEBUG 1: Dependency Directories: ..\storefile_client :: . :: ..\ARM\inc :: C:\Qt\5.7\mingw53_32\mkspecs\win32-g++
    DEBUG 1: c:\Users\qt\work\qt\qtbase/qmake/generators/makefile.cpp:321 Failure to find /libgcc_s_dw2-1.dll in vpath ()
    DEBUG 1: no definition for install libs_to_copy: install target not created
    

    See that the dll file's path is truncated for some reason.



  • Well, look at that...it sure is.

    I don't know what to make of that (so to speak). Is it possible we've uncovered a bug?



  • It's probably one of those lovely windows gotchas, I think it does not like the dot in 5.7, try adding quotes

    libs_to_copy.files = "C:/Qt/5.7/mingw53_32/bin/libgcc_s_dw2-1.dll"

    and make sure you rerun qmake!



  • Hi, Vronin -

    This is somewhat embarrassing. I tried your suggestion, and it worked. I looked at the compiler output and actually saw the xcopy command, and the file did copy.

    Unfortunately, it was copying to:

    C:\Users\mzimmers\build-storefile_client-Desktop_Qt_5_7_0_MinGW_32bit-Debug

    instead of to:

    C:\Users\mzimmers\build-storefile_client-Desktop_Qt_5_7_0_MinGW_32bit-Debug\debug

    So, I went in and fiddled with it, to no avail. I tried to put it back so it would at least re-copy, and...I can't make it work again!!

    I'm still encouraged, because it shows that the INSTALLS part of MinGW make does work. It's just a matter of getting the syntax in the .pro file correct.

    I'm trying to understand the libs_to_copy construct that I copied from somewhere else. This doesn't seem to be an ordinary qmake variable, and I can't get it to display using message(). Can you possibly point me to an explanation of it?

    Thanks a lot...I do think we're getting close.



  • Found it!

    The problem was the trailing backslash in the definition of:

    libs_to_copy.path = "C:\Users\mzimmers\Wideband\Peninsula\build-storefile_client-Desktop_Qt_5_7_0_MinGW_32bit-Debug\"
    

    This occurs whether or not I enclose the path in double quotes. Seems like a bug to me...anyone disagree?

    There's also the issue of why this line:

    libs_to_copy.path = $$(OUT_PWD)
    

    results in an error message ":-1: warning: libs_to_copy.path is not defined: install target not created."

    But, at least I've solved the problem that prompted me to start this thread.

    THANK YOU TO EVERYONE WHO PARTICIPATED IN THIS.


  • Qt Champions 2016

    @mzimmers said in Copying .dlls into target directory:

    $$(OUT_PWD)

    It's not defined. Try $$OUT_PWD instead.



  • @kshegunov : yes, that was it. Thank you. I guess I'm still not clear on the rules of parsing variables.

    I do have one remaining glitch: one of the three files I want to copy produces an error:

    copy /y C:\Qt\5.7\mingw53_32\bin\libgcc_s_dw2-1.dll C:\Users\mzimmers\Wideband\Peninsula\build-storefile_client-Desktop_Qt_5_7_0_MinGW_32bit-Debug\debug
            1 file(s) copied.
    copy /y C:\Qt\5.7\mingw53_32\bin\libwinpthread-1.dll C:\Users\mzimmers\Wideband\Peninsula\build-storefile_client-Desktop_Qt_5_7_0_MinGW_32bit-Debug\debug
            1 file(s) copied.
    copy /y C:\Qt\5.7\mingw53_32\bin\libstdc++-6.dll C:\Users\mzimmers\Wideband\Peninsula\build-storefile_client-Desktop_Qt_5_7_0_MinGW_32bit-Debug\debug
    The system cannot find the file specified.
    

    This file fails to copy whether it's the first, second or last file in the list. It also occurs whether I form libs_to_copy.files with three assignments, or one (multi-line).
    Somehow I suspect it's the "+" in the filename. I made a copy of this dll without the "+" characters, and it worked. Is there some way to escape them in the string?"

    Found this: it's a known problem. Not sure what to make of it...



  • This is due to a bug in Qt: https://bugreports.qt.io/browse/QTBUG-16372 but the solution is not easy to implement, see https://codereview.qt-project.org/#/c/85161/
    This was the reason I first started using CMake as a build tool instead of qmake and now I wouldn't go back.

    KDE is using Cmake.

    An alternative (but I never tried it) is Qt Build system: http://doc.qt.io/qbs/


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.