Win32 static linking?



  • Using: Qt/QML 5.12.0, MSVC 2017, Windows 7, all 32-bit.

    I tried building Qt static libraries using instructions here. The first discrepancy is that nmake sub-src complains about no such target. So I just did nmake. More than an hour later, I got the following errors:

            cl -c -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -O2 -MD -utf-8 /wd4530 /wd4577 -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -DUNICODE -D_UNICODE -DWIN32 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -DQT_NO_EXCEPTIONS -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DGL_APICALL= -DEGLAPI= -DNDEBUG -I. -I..\..\..\..\include -I..\..\..\..\include\QtWidgets -I..\..\..\..\include\QtGui -I..\..\..\..\include\QtANGLE -I..\..\..\..\include\QtCore -I.moc\release -I..\..\..\..\mkspecs\win32-msvc -Fo.obj\release\ @C:\Users\PAULD\AppData\Local\Temp\nmB577.tmp
    main.cpp
    tetrixboard.cpp
    tetrixpiece.cpp
    tetrixwindow.cpp
    .\tetrixwindow.cpp(92): error C2065: 'qOverload': undeclared identifier
    .\tetrixwindow.cpp(92): error C2062: type 'int' unexpected
    .\tetrixwindow.cpp(94): error C2065: 'qOverload': undeclared identifier
    .\tetrixwindow.cpp(94): error C2062: type 'int' unexpected
    .\tetrixwindow.cpp(96): error C2065: 'qOverload': undeclared identifier
    .\tetrixwindow.cpp(96): error C2062: type 'int' unexpected
    tetrix_plugin_import.cpp
    Generating Code...
    NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\bin\HostX86\x86\cl.EXE"' : return code '0x2'
    Stop.
    NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\bin\HostX86\x86\nmake.exe"' : return code '0x2'
    Stop.
    NMAKE : fatal error U1077: 'cd' : return code '0x2'
    Stop.
    NMAKE : fatal error U1077: 'cd' : return code '0x2'
    Stop.
    NMAKE : fatal error U1077: 'cd' : return code '0x2'
    Stop.
    NMAKE : fatal error U1077: 'cd' : return code '0x2'
    Stop.
    NMAKE : fatal error U1077: 'cd' : return code '0x2'
    Stop.
    

    This appears to be QTBUG-61667, but I'm not sure what I should do, since no workaround is provided.

    Anyway, I found the tetrix stuff, and it's under examples. The README that accompanies the source says I can build without tools or examples, so I reran configure with the appropriate options, then did nmake again. An hour later, I got the same errors.

    I thought I'd try building my app anyway, since the necessary libraries may have been built by the time the error occurred. I added static to my CONFIG, and manually ran qmake and then nmake release. I wound up with a smaller executable than I had before, so it's obviously not linked with static libraries. I also followed the directions, and tried the mt.exe command, but it failed because there is no .manifest file.

    Before I built the source, I had everything under a directory called C:\Qt\Qt5.12.0. Now there's a bunch of new stuff in C:\Qt\Qt-5.12.0. Notice the hyphen. Is that a mistake? How is the build process supposed to find these new libraries?


  • Lifetime Qt Champion

    Hi,

    Since you are building the whole of Qt, you really should disable both the examples and tests building. This is just wasting disk space and time.

    You should also consider using jom rather than nmake as it will parallelise the build better.

    One last point, don't forget the licensing constraints that comes with a static build.



  • @SGaist Well, I thought I was disabling the tests and examples. I guess there was some cruft left around from the previous configuration.

    So I installed 5.12.2, and started over. This time I ran configure -static -release -platform win32-msvc -nomake tests -nomake examples, and followed it with nmake (there is still no sub-src target, so the docs are wrong), and came back later to see it built successfully.

    But I still can't build my application. Where the 5.12.0 version put the result somewhere in the (possibly erroneous) C:\Qt\Qt-5.12.0 tree, the 5.12.2 version scatters the static .lib files in C:\Qt\Qt5.12.0\src\*\lib\*.lib.

    When I follow the wiki directions, the first error is that cmake isn't in the PATH. Well, that's easy enough to fix. But when I run it and nmake release, I get an exe file that's dynamically linked, even though it says static in my CONFIG. Something is missing. How are these new libraries supposed to be found? I must have to Do Something to either create makefiles that specify the library locations, or set an environment variable with a path to all the various libraries, or copy all the scattered libraries into a specific location that the build already knows about, or something else. But what???

    Oh, and I would still like to be able to do dynamic builds while debugging, even in the release build, since it will probably build much faster. I only want a static build for deployment.


  • Lifetime Qt Champion

    Did you call nmake install after the build ?



  • @SGaist said in Win32 static linking?:

    Did you call nmake install after the build ?

    No. Where does it say that? It isn't mentioned in https://wiki.qt.io/Build_Standalone_Qt_Application_for_Windows or in https://doc.qt.io/qt-5/windows-deployment.html or in the README in the source directory, or in any of the various pages I read while Googling for this.

    So now that I've done this, I've got a whole new directory called C:\Qt\Qt-5.12.2, which has static libraries in it. Cleaning my project, deleting the old release and debug directories, manually running cmake -config release, then nmake, still doesn't find the static libraries, and builds a small executable that requires DLLs.

    So what's the next completely undocumented step that I have to take?


  • Lifetime Qt Champion

    @pderocco said in Win32 static linking?:

    No. Where does it say that? It isn't mentioned in https://wiki.qt.io/Build_Standalone_Qt_Application_for_Windows or in https://doc.qt.io/qt-5/windows-deployment.html or in the README in the source directory, or in any of the various pages I read while Googling for this.

    Well, to be fair, it's a pretty standard step when building most projects:

    1. configure
    2. make
    3. make install

    Replace make by nmake, jom or mingw32-make on Windows.

    Are you sure cmake is picking the correct version of Qt ?



  • @SGaist said in Win32 static linking?:

    Well, to be fair, it's a pretty standard step when building most projects:

    1. configure
    2. make
    3. make install

    Not in Windows-world, it isn't. ;-)

    Oddly, when I tried this with 5.12.0, I don't recall typing nmake install, but the partial build (aborted by the error mentioned in the original post) wound up in C:\Qt\Qt-5.12.0. With 5.12.2, it needed nmake install to create the analogous tree with the hyphen in the name.

    Are you sure cmake is picking the correct version of Qt ?

    That was a typo in my post. I'm not using cmake, I'm using qmake. However, I've discovered the problem. I didn't realize that building the static libraries also built all the tools, and the tools have builtin paths where they look for things. I had C:\Qt\Qt5.12.2\5.12.2\msvc2017\bin in my PATH, so it was running the stock qmake.

    This is a uniquely Linux-like way of doing things. When there are instructions for how to build something for Windows, it ought to be written with Windows programmers in mind. I'll file a bug report on the docs.

    Now that I'm running the right qmake, it's building a much larger version of my app. But I'm still getting a DLL error: The procedure entry point CreateDXGIFactory2 could not be located in the dynamic link library dxgi.dll. Google turned up an explanation and fix for this, but it means I have to reconfigure Qt and rebuild it. I'll start that when I go to bed, and report back tomorrow whether it worked.

    Thanks so much for your help on this.


  • Lifetime Qt Champion

    @pderocco said in Win32 static linking?:

    Not in Windows-world, it isn't. ;-)

    Sorry, working on so many OSes made me forgot that.

    @pderocco said in Win32 static linking?:

    This is a uniquely Linux-like way of doing things. When there are instructions for how to build something for Windows, it ought to be written with Windows programmers in mind. I'll file a bug report on the docs.

    Not only Linux, macOS is the same. Beside the bug report, you could even submit a patch to improve the documentation :-)


  • Qt Champions 2018

    Hi @pderocco

    'll file a bug report on the docs.

    Please provide a link to the report here. Thanks!



  • @SGaist

    Well, it took a while, but I got it running. I had to add -no-feature-d3d12 to the configure command to eliminate the DLL error described above. But I'm not out of the woods yet. When I run it on the 32-bit Win7 machine I used to build it, it doesn't complain, but it only draws the window frame. I tried running it over the network from my 64-bit Win7 machine, and it works fine, so it must be something about the system.

    Admittedly, this 32-bit machine is old. It was the top-of-the-line Dell gaming machine from about 13 years ago, but it does have Win7 with all the updates, and it does support OpenGL (I run Google Earth that way). And it works fine on this machine if I run it with dynamic libraries. The reason I'm using this machine to build is that I want this to be a 32-bit program, and I can't figure out how to do that with 64-bit QtQcreator and MSVC2017.

    Is there any way to tweak the build of my project so that I get more warning outputs if I run it from a command line? You'd think that some part of the software would "know" that it its drawing commands aren't getting through, and would complain about it. Or is there some other configure tweak that might help? I don't want to fall all the way back to software rendering, though, unless it could automatically do that only if necessary.


  • Lifetime Qt Champion

    Qt Creator architecture has nothing to do with the architecture of your application.

    To build a 32bit version of your application, use the 32bit package for MSVC2017. The same goes for the 64bit version.

    I currently don't know for the static version, however when building the dynamic version you can say to configure that it should build dynamic backend selection.



  • @SGaist said in Win32 static linking?:

    Qt Creator architecture has nothing to do with the architecture of your application.

    To build a 32bit version of your application, use the 32bit package for MSVC2017. The same goes for the 64bit version.

    Yeah, that worked. When I tried it in 5.12.0 and failed, there must have been something misconfigured.

    I currently don't know for the static version, however when building the dynamic version you can say to configure that it should build dynamic backend selection.

    Following some info from another post, I tried the following configure.bat options:

    -prefix "C:\Qt\Qt5.12.2\5.12.2\msvc2017sr"
    -release
    -platform win32-msvc
    -confirm-license
    -opensource
    -nomake examples
    -nomake tests
    -static
    -static-runtime
    -opengl dynamic
    -angle
    -combined-angle-lib
    -no-feature-d3d12
    

    Now it works on the 32-bit Windows machine I used to build Qt and the application (and still works fine on the 64-bit machine I can also build it on), but when I run it on another Win7 64-bit machine that has never had Qt installed on it, I just get the window frame again. Is it looking for a DLL? I only have a nebulous idea of what some of those configure options actually mean, so I don't know what to try next.