Mingw-w64 Unable to link version library

For an open windows source-project to be built with Mingw-w64 I figured, it was nice, if the application was conscious of its version.

To get this, I copied/pastes/edited a small wrapper, which would read the version-information from the application’s own resources. This code builds well, when being done with Visual Studio environment (using vcvars32.bat).

However, when I try to build it with MinGw, the compiler runs through nicely, but the linker does not. There’s an error, that a functions from the version.dll is not found:

VersSample.cpp:(.text+0x14f): undefined reference to VerQueryValueW

I did add the –lversion compiler-switch in the build-command-line, but it appears, not to work. Anybody a hint, what I am missing?

The build-command looks as follows:

set PATH=C:\Tools\MinGw\mingw64\bin\;%PATH%
windres VersSample.rc -O coff -o VersSample.res
g++ -o VersSample.exe -mwindows -static-libgcc -static-libstdc++ -lversion VersSample.cpp VersSample.res

BTW: I did not want to make this bigger as needed, but if there's some nterest, I could post the whole function.

1 answer

  • answered 2018-10-12 18:26 Jay.Dee.S

    Gosh, I got it.
    I can't tell why, but the postition of the -lversion seemed to be of importance. I placed it at the end of the g++ call, and it worked:

    g++ -o VersSample.exe -mwindows -static-libgcc -static-libstdc++ VersSample.cpp VersSample.res -lversion
    

    For anyone interested, the whole function looks as follows:

    void AddVersionInfo(WCHAR* pszwOutput, const WCHAR* pszwEntry) {
    /** Variables: */
    DWORD vLen, langD;
    BOOL retVal;
    LPVOID retbuf = NULL;
    WCHAR fileEntry[256];
    /** Fetch-Code: */
    HRSRC hVersion = FindResource(NULL, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);
    if (hVersion != NULL) {
        HGLOBAL hGlobal = LoadResource(NULL, hVersion);
        if (hGlobal != NULL) {
            LPVOID versionInfo = LockResource(hGlobal);
            if (versionInfo != NULL) {
                swprintf(fileEntry, L"\\VarFileInfo\\Translation");
                retVal = VerQueryValue(versionInfo, fileEntry, &retbuf, (UINT *)&vLen);
                if (retVal && vLen == 4) {
                    memcpy(&langD, retbuf, 4);
                    #ifdef _MSC_VER
                    swprintf(fileEntry, L"\\StringFileInfo\\%02X%02X%02X%02X\\%s",
                        (langD & 0xff00) >> 8, langD & 0xff, (langD & 0xff000000) >> 24,
                        (langD & 0xff0000) >> 16, pszwEntry);
                    #else
                    swprintf(fileEntry, L"\\StringFileInfo\\%02X%02X%02X%02X\\%S",
                        (langD & 0xff00) >> 8, langD & 0xff, (langD & 0xff000000) >> 24,
                        (langD & 0xff0000) >> 16, pszwEntry);
                    #endif
                }else{
                    swprintf(fileEntry, L"\\StringFileInfo\\%04X04B0\\%s",
                        GetUserDefaultLangID(), pszwEntry);
                }
                if (VerQueryValue(versionInfo, fileEntry, &retbuf, (UINT *)&vLen)) {
                    wcscat(pszwOutput, (WCHAR*)retbuf);
                }
            }
        }
        UnlockResource(hGlobal);
        FreeResource(hGlobal);
    }
    

    }

    Note, that I had to add a compiler-switch to distinguish between the MS VS and the MinGw environment, since they appear to handle markers in sprintf (resp. swprintf) differently.

    With this, given that a complete VersionInfo block is in the ressources, the data can be accessed and used as:

    AddVersionInfo(buffer, L"FileVersion");