-
Notifications
You must be signed in to change notification settings - Fork 2
/
herc_setWindowsTarget.cmake
155 lines (129 loc) · 6.66 KB
/
herc_setWindowsTarget.cmake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# herc_setWindowsTarget.cmake - Set Windows API target version
#[[ Copyright 2017 by Stephen Orso.
Distributed under the Boost Software License, Version 1.0.
See accompanying file BOOST_LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
]]
macro( herc_setWindowsTarget WinTarget Windows_version )
#[[ ########### macro herc_setWindowsTarget ###########
Function/Operation
- Translates a symbolic Windows target version into a descriptive
target version.
- If a specific version of Windows is the target, the variables
WINVER, _WIN32_WINNT, and NTDDI_VERSION are set to the hex values
that correspond to the target.
- If an invalid target version is specified, the returned descriptive
target version is set to ${Windows_version}-NOTFOUND.
Input Parameters
- WinTarget: symbolic name of the minimum Windows version that compiled
code should target. In addition to the Windows version names listed
in the variable Windows_versions, the following symbolic values are
allowed:
- DIST: Target the oldest version of Windows listed in Windows_versions.
"DIST" means code is being compiled for distribution.
- HOST: Target the version of Windows being used to compile. In this
case, WINVER, _WIN32_WINNT, and NTDDI_VERSION are not set, and the
Windows userland will build for the host.
- <blank>: a synonym for HOST.
Output
- If the symbolic target "DIST" is passed, then Windows_version is set
the first value in the Windows_version list, and WINVER, _WIN32_WINNT,
and NTDDI_VERSION are set to the hex values corresponding to that
version.
- If the symbolic target "HOST" is passed, the host Windows header
sdkddtver.h is analyzed to extract the WINVER hex string, that hex
string is translated into the corresponding Windows version text, and
WINVER, _WIN32_WINNT, and NTDDI_VERSION are not set.
- If the hex string indicates a Windows version newer than the highest
supported version of Windows, the highest supported version of
Windows is reported with a "+" suffix.
- If the hex string indicates a Windows version lower than the lowest
supported version of Windows, Windows_version is set to
${Windows_version}-NOTFOUND.
- If any other version of Windows is requested, WINVER, _WIN32_WINNT,
and NTDDI_VERSION are set to the hex values for that Windows version.
- If an invalid symbolic target version is passed, Windows_version is
set to ${Windows_version}-NOTFOUND.
- If the build will target a valid Windows version, a message is issued
naming the target Windows version.
Notes
- Windows target version names and codes are defined in Windows_versions
and Windows_vercodes, respectively. The version names names are our
own invention; the hex strings are defined by Microsoft and documented
here:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa383745(v=vs.85).aspx
They are also defined in Windows header SDKDDKVer.h (the source for
the Windows 10 values).
- The lowest supported version of Windows and its corresponding hex code
must be the first element in the list, in orderby hex code.
- The highest supported version of Windows and its corresponding hex code
must be the last element in the list, in orderby hex code.
]]
set( Windows_versions WINXP364 WINVISTA WIN7 WIN8 WIN10 )
set( Windows_vercodes 0x0502 0x0600 0x0601 0x0602 0x0A00 )
list( LENGTH Windows_vercodes __winvercode_max )
math( EXPR __winvercode_max "${__winvercode_max} - 1" ) # decrement max into rel 0 index
list( GET Windows_vercodes "${__winvercode_max}" Windows_vercode_max )
list( GET Windows_versions "${__winvercode_max}" Windows_version_max )
string( TOUPPER "${WinTarget}" __WinTarget )
if( "${__WinTarget}" STREQUAL "DIST" )
# DIST means use the lowest supported Windows version as the target
# for compilations.
list( GET Windows_versions 0 ${Windows_version} )
set ( __winvercode_index 0 )
elseif( ("${__WinTarget}" STREQUAL "HOST") OR ("${__WinTarget}" STREQUAL "" ) )
# HOST or blank means target for the Windows version of the host
# System. See if the host is at least at the minimum version and
# determine the appropriate descriptive string.
find_path( __sdkddkver_h_path sdkddkver.h )
file( STRINGS ${__sdkddkver_h_path}/sdkddkver.h __define_winver REGEX "#define *WINVER *0" )
# Only one line in sdkddkver.h will match the above REGEX. Extract
# the Windows version code.
string( REGEX REPLACE "^#define +WINVER +" "" Windows_vercode "${__define_winver}" )
list( FIND Windows_vercodes "${Windows_vercode}" __winvercode_index )
if( "${Windows_vercode_max}" STRLESS "${Windows_vercode}" )
# NOTE: above test fails on EBCDIC systems because numbers colate
# higher than letters on such systems. ***************************
# Target system Windows version higher than current highest known
# supported Windows Version. It will probably work. Label it
# WIN10+ and leave the target variables unset to accept the host
# version as the target version.
set( Windows_version "${Windows_version_max}+" )
else( )
# Host Windows version at or below highest supported, or is an
# invalid Windows version string.
list( FIND Windows_vercodes "${Windows_vercode}" __winvercode_index )
if( __winvercode_index LESS 0 ) # Host is too old, not supported.
set( Windows_version "${Windows_version}-${Windows_vercode}-NOTFOUND" )
else( ) # Host is supported. Get descriptor
list( GET Windows_versions "${__winvercode_index}" Windows_version )
endif( )
unset( __winvercode_index )
endif( )
else( )
# A Windows version was specified. It must be in the list.
list( FIND Windows_versions "${__WinTarget}" __winvercode_index )
if( __winvercode_index LESS 0 ) # Host is not in list, invalid,
set( Windows_version "${Windows_version}-${WinTarget}-NOTFOUND" )
unset( __winvercode_index )
else( ) # Host is supported. Get descriptor
list( GET Windows_versions "${__winvercode_index}" Windows_version )
endif( )
endif( )
set( __WinTarget "${${Windows_version}}" )
if( __WinTarget )
message( STATUS "Windows system target is ${${Windows_version}}" )
endif( )
# Set the Windows version codes if required because a caller specified
# DIST or a specific version of Windows.
if( NOT "${__winvercode_index}" STREQUAL "" )
list( GET Windows_vercodes "${__winvercode_index}" Windows_vercode )
set( WINVER "${Windows_vercode}" )
set( _WIN32_WINNT "${WINVER}" )
set( NTDDI_VERSION "${WINVER}0000" )
endif( )
unset( __sdkddkver_h_path )
unset( __define_winver )
unset( __winvercode_index )
unset( __WinTarget )
endmacro( )