qmake does not generate /SUBSYSTEM:WINDOWS,5.01 in my .vcxproj file



  • I am trying to cross-compile a Qt program for Windows XP on a Windows 7 machine using Visual Studio 2012, following the guidelines at http://blogs.msdn.com/b/vcblog/archive/2012/10/08/10357555.aspx. One of the things that needs to be done, is to use the linker flag /SUBSYSTEM:CONSOLE,5.01 (notice the version number!).

    I have compiled Qt myself (we are still using 4.8.6 and I currently cannot upgrade) and I also have adapted some variables in mkspecs/win32-msvc2012/qmake.conf as follows

    DEFINES                 += UNICODE WIN32 _USING_V110_SDK71_
    QMAKE_CFLAGS            = -nologo -Zm200 -Zc:wchar_t- -arch:IA32
    QMAKE_LFLAGS_CONSOLE    = /SUBSYSTEM:CONSOLE,5.01
    QMAKE_LFLAGS_WINDOWS    = /SUBSYSTEM:WINDOWS,5.01
    

    To illustrate my problem, I have created the following hello world program:

    #include <iostream>
    
    int main()
    {
        std::cout << "Hello World!" << std::endl;
    }
    

    My .pro file simply consists of

    TEMPLATE = app
    SOURCES += subsystem.cpp
    

    I generate a .vcxproj file using the command

    qmake -tp vc -d subsystem.pro
    

    In the qmake debug output, I clearly see the /SUBSYSTEM:WINDOWS,5.01 (including the version number!) in the QMAKE_LFLAGS* variables:

    DEBUG 1: QMAKE_LFLAGS === /NOLOGO :: /DYNAMICBASE :: /NXCOMPAT :: /DEBUG :: /SUBSYSTEM:WINDOWS,5.01 :: "/MANIFESTDEPENDENCY:type='win32' :: name='Microsoft.Windows.Common-Controls' :: version='6.0.0.0' :: publicKeyToken='6595b64144ccf1df' :: language='*' :: processorArchitecture='*'"
    DEBUG 1: QMAKE_LFLAGS_CONSOLE === /SUBSYSTEM:CONSOLE,5.01
    DEBUG 1: QMAKE_LFLAGS_WINDOWS === /SUBSYSTEM:WINDOWS,5.01
    

    so it appears that qmake correctly parsed the .pro file and assigned subsystem version 5.01. However, the 5.01 version number is nowhere in the generated .vcxproj file. All I see
    is

    <Link>
        ...
        <SubSystem>Windows</SubSystem>
        ...
    </Link>
    

    Where I would expect

    <Link>
       ...
       <SubSystem>Windows</SubSystem>
       ...
       <MinimumRequiredVersion>5.01</MinimumRequiredVersion>
       ...
    </Link>
    

    Therefore, when building with msbuild, I get /SUBSYSTEM:WINDOWS as linker option instead of /SUBSYSTEM:WINDOWS,5.01:

    Link:
      C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\link.exe /ERRORREPORT:QUEUE /OUT:"debug\\subsystem.exe" /NOLOGO /LIBPATH:"d:\qt-everywhere-opensource-src-4.8.6-xp\lib" /LIBPATH:"D:\OpenSSL\win32-xp-build" "d:\qt-everywhere-opensource-src-4.8.6-xp\lib\qtmaind.lib" "d:\qt-everywhere-opensource-src-4.8.6-xp\lib\QtGuid4.lib" "d:\qt-everywhere-opensource-src-4.8.6-xp\lib\QtCored4.lib" kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"debug\subsystem.pdb" /SUBSYSTEM:WINDOWS /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /SAFESEH "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" debug\subsystem.obj
      subsystem.vcxproj -> D:\GIT\Qt\tests\subsystem\debug\subsystem.exe
    

    When I let qmake generate Makefiles and compile with nmake instead of generating a .vcxproj file and building with msbuild, I do get the correct linker flag (/SUBSYSTEM:WINDOWS,5.01).

    What can I do to have this 5.01 version also in my .vcxproj and be able to build with msbuild? Upgrading to a higher version of Qt is currently not an option (I know later versions have the -target xp configure option, but i cannot upgrade for now).



  • Hi, if you have problems with getting /SUBSYSTEM:WINDOWS,5.01 stuffed into your .exe file during the build proces, you can also binary edit the .exe file to make it run nicely on XP, check out my blog post



  • Going through the source code of Qt 4.8.6, I find the following snipped of code:

    case 0x78dc00d: // /SUBSYSTEM:{CONSOLE|EFI_APPLICATION|EFI_BOOT_SERVICE_DRIVER|EFI_ROM|EFI_RUNTIME_DRIVER|NATIVE|POSIX|WINDOWS|WINDOWSCE}[,major[.minor]]
        {
            // Split up in subsystem, and version number
            QStringList both = QString(option+11).split(",");
            switch (elfHash(both[0].toLatin1())) {
            case 0x8438445: // CONSOLE
                SubSystem = subSystemConsole;
                break;
            case 0xbe29493: // WINDOWS
                SubSystem = subSystemWindows;
                break;
            // The following are undocumented, so add them to AdditionalOptions
            case 0x240949e: // EFI_APPLICATION
            case 0xe617652: // EFI_BOOT_SERVICE_DRIVER
            case 0x9af477d: // EFI_ROM
            case 0xd34df42: // EFI_RUNTIME_DRIVER
            case 0x5268ea5: // NATIVE
            case 0x05547e8: // POSIX
            case 0x2949c95: // WINDOWSCE
            case 0x4B69795: // windowsce
                AdditionalOptions += option;
                break;
            default:
                found = false;
            }
        }
        break;
    

    Notice that although the major.minor version number is available in both[1] after the string split, it is not being used. I assume that is the reason why I am not seing it in the .vcxproj output, so I guess it's simply not possible with 4.8.6. I have therefore decided to manually add the <MinimumRequiredVersion> element in the generated XML from the .vcxproj once qmake has finished. I'm still open for other elegant solutions however.



  • For what it's worth, qmake in Qt 5.5.1 doesn't seem any better. I would like to set /SUBSYSTEM:WINDOWS,6.1 to specify that only Windows 7 and later are allowed, but qmake is still ignoring the version part when generating the vcxproj.



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