[cmake-developers] [PATCH] [CMake 0015674]: Windows: Correctly determine Windows version

James Johnston JamesJ at motionview3d.com
Fri Sep 11 11:45:38 EDT 2015


Well this is quite cool. :)  It's been an issue I've wanted to see addressed
as well but haven't had the time to look at it.  Not because of CMake itself
not having a manifest (the improper GetVersionEx detection didn't affect
me), but because I need to embed an app manifest in my own programs.

I have some ideas while you are on the subject:

1.  No documentation files were updated.  I wonder if there is a good place
in the docs for this?
2.  If the user doesn't use the Visual Studio generator, still support
embedding the manifest.  For example, if I use Ninja generator in
conjunction with Visual C++'s link.exe I'd like user-specified manifests to
be merged with mt.exe.

The second request is currently a big pain point with CMake to get working
correctly.  Ideally I want to reproduce the VS way of doing things, which
is:

a.  Have link.exe generate default manifest for referencing the CRT
side-by-side assemblies.
b.  Use mt.exe to put it all together in the output.

Because CMake already does *some* things with the linker it makes it
impossible for me to cleanly specify and use link.exe manifest-related
switches myself.  For example, it hard-codes usage of link.exe /MANIFESTFILE
and the user can't specify their own location.  And the locations it does
use are undocumented.  See Source/cmcmd.cxx and search for vs_link_exe to
see what I'm talking about.  (For that matter, git grep CMake for
vs_link_exe and vs_link_dll to see how those commands end up getting used in
the first place).

Ultimately for now I wound up with this kludge to get link.exe intermediate
manifest AND my own:

            if(CMAKE_CONFIGURATION_TYPES) # multiple-configuration
generator?
                # WARNING:  This magic directory location is an undocumented
aspect of the
                # Visual Studio generator.
                list(APPEND inputManifests
 
${CMAKE_CURRENT_BINARY_DIR}/${AAM_TARGET}.dir/$<CONFIG>/$<TARGET_FILE_NAME:$
{AAM_TARGET}>.intermediate.manifest
                    )
            else()
                # Can't change /MANIFESTFILE because CMake assumes the
default... (see above)
                list(APPEND inputManifests
$<TARGET_FILE:${AAM_TARGET}>.manifest)
            endif()
            list(APPEND inputManifests my_own_manifests.manifest)

Which is then fed into add_custom_command(<snip> POST_BUILD COMMAND mt.exe
-manifest ${inputManifests} <snip>).  Basically I'm hard-coding the
hard-coded /MANIFESTFILE: locations used by various CMake generators, since
it doesn't work for me to try to change it.  Obviously the situation is not
ideal because CMake makes no promises about where it puts the intermediate
manifests from the linker.

It would be certainly be nice if CMake supported user-provided manifests
across most/all Windows generators as first-class support, not just Visual
Studio 10.  Especially the make-like tools (various Makefile generators,
Ninja).  :)

Best regards,

James Johnston
------------------------------------
From: cmake-developers [mailto:cmake-developers-bounces at cmake.org] On Behalf
Of Gilles Khouzam
Sent: Thursday, September 10, 2015 23:25
To: Brad King
Cc: cmake-developers at cmake.org
Subject: [cmake-developers] [PATCH] [CMake 0015674]: Windows: Correctly
determine Windows version

This patch fixes the issue where on Windows 8 and above, by default the
system version returned is always Windows 8.

More info on this can be found on
http://blogs.msdn.com/b/cjacks/archive/2009/03/27/manifesting-for-compatibil
ity-on-windows-7.aspx

In order for GetVersionEx to work properly, a manifest must be embedded in
the exe telling it to ignore the new behavior and give the proper version.

This patch adds support to specify manifests and teaches CMake how to embed
them using Visual Studio.
This patch adds a simple version manifest Source\cmake.version.manifest to
the CMake executables.
This removes the use of RtlGetVersion and properly uses GetVersionEx which
will now return the proper operating system version for all operating
systems until Windows 10.
This patch also fixes a potential buffer overrun and improper call of
GetVersionEx in SystemTools.cxx where GetVersionExW is called with a
OSVERSIONINFOEXA struct causing a failure since the size is improper for the
API. Fixing this, GetVersionEx should never fail anymore.
Update the OSVersionAndName for new versions of Windows released after
Windows 7.

This change will require a double compile of CMake (I'm not sure if this is
what the dashboards are doing) to have the functionality enabled, since the
first step will build a new CMake that will know how to embed a manifest.
The second compile with the version of CMake that knows how to embed a
manifest, will then embed the manifest in CMake enabling this feature.

Thanks

~Gilles



More information about the cmake-developers mailing list