Skip to content

Commit 1fab595

Browse files
committed
Detection changes for VS IDE editions and VS2008 (develop and vcforpython).
Changes: * An express installation of the IDE binary is used when no other IDE edition is detected. * A full development edition (e.g., Professional) of VS2008 is elected before a Visual C++ For Python edition. * Update detection order in README.rst and remove hard tabs. * Minor fixes lingering from original VSWHERE implementation where all call chains were not updated when the environment argument was added.
1 parent a20098e commit 1fab595

File tree

9 files changed

+102
-77
lines changed

9 files changed

+102
-77
lines changed

CHANGES.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
4343
method so that the generated function argument list matches the function's
4444
prototype when including a header file.
4545
- For msvc version specifications without an 'Exp' suffix, an express installation
46-
is used when no other edition is detected for the msvc version.
46+
is used when no other edition is detected for the msvc version. Similarly, an
47+
express installation of the IDE binary is used when no other IDE edition is
48+
detected.
4749
- VS2015 Express (14.0Exp) does not support the sdk version argument. VS2015 Express
4850
does not support the store argument for target architectures other than x86.
4951
Script argument validation now takes into account these restrictions.
@@ -72,6 +74,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
7274
(i.e., msiexec /i VCForPython27.msi ALLUSERS=1), the registry keys are written to
7375
HKEY_LOCAL_MACHINE rather than HKEY_CURRENT_USER. An entry was added to query the
7476
Visual C++ For Python keys in HKLM following the HKCU query, if necessary.
77+
- For VS2008, a full development edition (e.g., Professional) is now selected before
78+
a Visual C++ For Python edition. Prior to this change, Visual C++ For Python was
79+
selected before a full development edition when both editions are installed.
7580
- The registry detection of VS2015 (14.0), and earlier, is now cached at runtime and
7681
is only evaluated once for each msvc version.
7782
- The vswhere detection of VS2017 (14.1), and later, is now cached at runtime and is

RELEASE.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ CHANGED/ENHANCED EXISTING FUNCTIONALITY
3838
installation is used when no other edition is detected for the msvc version.
3939
This was the behavior for Visual Studio 2008 (9.0) through Visual Studio 2015
4040
(14.0). This behavior was extended to Visual Studio 2017 (14.1) and Visual
41-
Studio 2008 (8.0).
41+
Studio 2008 (8.0). An express installation of the IDE binary is used when no
42+
other IDE edition is detected.
4243

4344
FIXES
4445
-----
@@ -70,6 +71,10 @@ FIXES
7071
msiexec /i VCForPython27.msi ALLUSERS=1
7172
When installed for all users, Visual Studio 2008 (9.0) Visual C++ For Python is
7273
now correctly detected.
74+
- MSVC: For Visual Studio 2008 (9.0), a full development edition (e.g., Professional)
75+
is now selected before a Visual C++ For Python edition. Prior to this change,
76+
Visual C++ For Python was selected before a full development edition when both
77+
editions are installed.
7378
- MSVC: The installed vcs and visual studios lists were constructed and cached
7479
during their initial invocations. If a vswhere executable was specified via the
7580
construction variable VSWHERE and found additional msvc installations, the new

SCons/Tool/MSCommon/README.rst

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -36,31 +36,31 @@ installation is used only when no other installation is detected.
3636
======= ======= ========================================================
3737
Product VCVer Priority
3838
======= ======= ========================================================
39-
VS2022 14.3 Enterprise, Professional, Community, BuildTools
39+
VS2022 14.3 Enterprise, Professional, Community, BuildTools
4040
------- ------- --------------------------------------------------------
4141
VS2019 14.2 Enterprise, Professional, Community, BuildTools
4242
------- ------- --------------------------------------------------------
4343
VS2017 14.1 Enterprise, Professional, Community, BuildTools, Express
4444
------- ------- --------------------------------------------------------
4545
VS2017 14.1Exp Express
4646
------- ------- --------------------------------------------------------
47-
VS2015 14.0 [Develop, BuildTools, CmdLine], Express
47+
VS2015 14.0 [Develop, BuildTools, CmdLine], Express
4848
------- ------- --------------------------------------------------------
4949
VS2015 14.0Exp Express
5050
------- ------- --------------------------------------------------------
51-
VS2013 12.0 Develop, Express
51+
VS2013 12.0 Develop, Express
5252
------- ------- --------------------------------------------------------
5353
VS2013 12.0Exp Express
5454
------- ------- --------------------------------------------------------
55-
VS2012 11.0 Develop, Express
55+
VS2012 11.0 Develop, Express
5656
------- ------- --------------------------------------------------------
5757
VS2012 11.0Exp Express
5858
------- ------- --------------------------------------------------------
5959
VS2010 10.0 Develop, Express
6060
------- ------- --------------------------------------------------------
6161
VS2010 10.0Exp Express
6262
------- ------- --------------------------------------------------------
63-
VS2008 9.0 VCForPython, Develop, Express
63+
VS2008 9.0 Develop, VCForPython, Express
6464
------- ------- --------------------------------------------------------
6565
VS2008 9.0Exp Express
6666
------- ------- --------------------------------------------------------
@@ -105,20 +105,20 @@ and/or linker build failures.
105105
The VS2015 BuildTools ``vcvarsall.bat`` batch file dispatches to the stand-alone buildtools
106106
batch file under certain circumstances. A fragment from the vcvarsall batch file is:
107107
::
108-
if exist "%~dp0..\common7\IDE\devenv.exe" goto setup_VS
109-
if exist "%~dp0..\common7\IDE\wdexpress.exe" goto setup_VS
110-
if exist "%~dp0..\..\Microsoft Visual C++ Build Tools\vcbuildtools.bat" goto setup_buildsku
108+
if exist "%~dp0..\common7\IDE\devenv.exe" goto setup_VS
109+
if exist "%~dp0..\common7\IDE\wdexpress.exe" goto setup_VS
110+
if exist "%~dp0..\..\Microsoft Visual C++ Build Tools\vcbuildtools.bat" goto setup_buildsku
111111

112-
:setup_VS
112+
:setup_VS
113113

114-
...
114+
...
115115

116-
:setup_buildsku
117-
if not exist "%~dp0..\..\Microsoft Visual C++ Build Tools\vcbuildtools.bat" goto usage
118-
set CurrentDir=%CD%
119-
call "%~dp0..\..\Microsoft Visual C++ Build Tools\vcbuildtools.bat" %1 %2
120-
cd /d %CurrentDir%
121-
goto :eof
116+
:setup_buildsku
117+
if not exist "%~dp0..\..\Microsoft Visual C++ Build Tools\vcbuildtools.bat" goto usage
118+
set CurrentDir=%CD%
119+
call "%~dp0..\..\Microsoft Visual C++ Build Tools\vcbuildtools.bat" %1 %2
120+
cd /d %CurrentDir%
121+
goto :eof
122122

123123
VS2015 Express
124124
--------------
@@ -136,19 +136,19 @@ architecture. The generated ``store`` library paths include directories that do
136136

137137
The store library paths appear in two places in the ``vcvarsx86_amd64`` batch file:
138138
::
139-
:setstorelib
140-
@if exist "%VCINSTALLDIR%LIB\amd64\store" set LIB=%VCINSTALLDIR%LIB\amd64\store;%LIB%
141-
...
142-
:setstorelibpath
143-
@if exist "%VCINSTALLDIR%LIB\amd64\store" set LIBPATH=%VCINSTALLDIR%LIB\amd64\store;%LIBPATH%
139+
:setstorelib
140+
@if exist "%VCINSTALLDIR%LIB\amd64\store" set LIB=%VCINSTALLDIR%LIB\amd64\store;%LIB%
141+
...
142+
:setstorelibpath
143+
@if exist "%VCINSTALLDIR%LIB\amd64\store" set LIBPATH=%VCINSTALLDIR%LIB\amd64\store;%LIBPATH%
144144

145145
The correct store library paths would be:
146146
::
147-
:setstorelib
148-
@if exist "%VCINSTALLDIR%LIB\store\amd64" set LIB=%VCINSTALLDIR%LIB\store\amd64;%LIB%
149-
...
150-
:setstorelibpath
151-
@if exist "%VCINSTALLDIR%LIB\store\amd64" set LIBPATH=%VCINSTALLDIR%LIB\store\amd64;%LIBPATH%
147+
:setstorelib
148+
@if exist "%VCINSTALLDIR%LIB\store\amd64" set LIB=%VCINSTALLDIR%LIB\store\amd64;%LIB%
149+
...
150+
:setstorelibpath
151+
@if exist "%VCINSTALLDIR%LIB\store\amd64" set LIBPATH=%VCINSTALLDIR%LIB\store\amd64;%LIBPATH%
152152

153153
arm Target Architecture
154154
^^^^^^^^^^^^^^^^^^^^^^^
@@ -158,19 +158,19 @@ architecture. The generated ``store`` library paths include directories that do
158158

159159
The store library paths appear in two places in the ``vcvarsx86_arm`` batch file:
160160
::
161-
:setstorelib
162-
@if exist "%VCINSTALLDIR%LIB\ARM\store" set LIB=%VCINSTALLDIR%LIB\ARM\store;%LIB%
163-
...
164-
:setstorelibpath
165-
@if exist "%VCINSTALLDIR%LIB\ARM\store" set LIBPATH=%VCINSTALLDIR%LIB\ARM\store;%LIBPATH%
161+
:setstorelib
162+
@if exist "%VCINSTALLDIR%LIB\ARM\store" set LIB=%VCINSTALLDIR%LIB\ARM\store;%LIB%
163+
...
164+
:setstorelibpath
165+
@if exist "%VCINSTALLDIR%LIB\ARM\store" set LIBPATH=%VCINSTALLDIR%LIB\ARM\store;%LIBPATH%
166166

167167
The correct store library paths would be file:
168168
::
169-
:setstorelib
170-
@if exist "%VCINSTALLDIR%LIB\store\ARM" set LIB=%VCINSTALLDIR%LIB\store\ARM;%LIB%
171-
...
172-
:setstorelibpath
173-
@if exist "%VCINSTALLDIR%LIB\store\ARM" set LIBPATH=%VCINSTALLDIR%LIB\store\ARM;%LIBPATH%
169+
:setstorelib
170+
@if exist "%VCINSTALLDIR%LIB\store\ARM" set LIB=%VCINSTALLDIR%LIB\store\ARM;%LIB%
171+
...
172+
:setstorelibpath
173+
@if exist "%VCINSTALLDIR%LIB\store\ARM" set LIBPATH=%VCINSTALLDIR%LIB\store\ARM;%LIBPATH%
174174

175175

176176
Known Issues

SCons/Tool/MSCommon/sdk.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ def mssdk_setup_env(env):
372372
return
373373
msvs_version = env.subst(msvs_version)
374374
from . import vs
375-
msvs = vs.get_vs_by_version(msvs_version)
375+
msvs = vs.get_vs_by_version(msvs_version, env)
376376
debug('mssdk_setup_env:msvs is :%s', msvs)
377377
if not msvs:
378378
debug('mssdk_setup_env: no VS version detected, bailingout:%s', msvs)

SCons/Tool/MSCommon/vc.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class BatchFileExecutionError(VisualCException):
103103
# MSVC 9.0 preferred query order:
104104
# True: VCForPython, VisualStudio
105105
# False: VisualStudio, VCForPython
106-
_VC90_Prefer_VCForPython = True
106+
_VC90_Prefer_VCForPython = False
107107

108108
# Dict to 'canonalize' the arch
109109
_ARCH_TO_CANONICAL = {
@@ -923,6 +923,21 @@ def msvc_version_to_maj_min(msvc_version):
923923
os.path.expandvars(r"%SCOOP%\shims"),
924924
]]
925925

926+
def msvc_find_vswhere():
927+
""" Find the location of vswhere """
928+
# For bug 3333: support default location of vswhere for both
929+
# 64 and 32 bit windows installs.
930+
# For bug 3542: also accommodate not being on C: drive.
931+
# NB: this gets called from testsuite on non-Windows platforms.
932+
# Whether that makes sense or not, don't break it for those.
933+
vswhere_path = None
934+
for pf in VSWHERE_PATHS:
935+
if os.path.exists(pf):
936+
vswhere_path = pf
937+
break
938+
939+
return vswhere_path
940+
926941
# normalize user-specified vswhere paths
927942

928943
_cache_user_vswhere_paths = {}
@@ -965,13 +980,7 @@ def _vswhere_user_path(pval):
965980

966981
return vswhere_path
967982

968-
# normalized default vswhere path
969-
970-
_vswhere_paths_processed = [
971-
MSVC.Util.normalize_path(pval)
972-
for pval in VSWHERE_PATHS
973-
if os.path.exists(pval)
974-
]
983+
# normalize default vswhere path
975984

976985
_vswhere_path_default = UNDEFINED
977986

@@ -981,6 +990,12 @@ def _msvc_default_vswhere():
981990

982991
if _vswhere_path_default == UNDEFINED:
983992

993+
_vswhere_paths_processed = [
994+
MSVC.Util.normalize_path(pval)
995+
for pval in VSWHERE_PATHS
996+
if os.path.exists(pval)
997+
]
998+
984999
if _vswhere_paths_processed:
9851000
vswhere_path = _vswhere_paths_processed[0]
9861001
else:
@@ -991,21 +1006,6 @@ def _msvc_default_vswhere():
9911006

9921007
return _vswhere_path_default
9931008

994-
def msvc_find_vswhere():
995-
""" Find the location of vswhere """
996-
# For bug 3333: support default location of vswhere for both
997-
# 64 and 32 bit windows installs.
998-
# For bug 3542: also accommodate not being on C: drive.
999-
# NB: this gets called from testsuite on non-Windows platforms.
1000-
# Whether that makes sense or not, don't break it for those.
1001-
vswhere_path = None
1002-
for pf in VSWHERE_PATHS:
1003-
if os.path.exists(pf):
1004-
vswhere_path = pf
1005-
break
1006-
1007-
return vswhere_path
1008-
10091009
class _VSWhere:
10101010

10111011
reset_funcs_list = []

SCons/Tool/MSCommon/vs.py

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,22 @@
4848
)
4949

5050

51+
# Visual Studio express version policy when unqualified version is not installed:
52+
# True: use express version for unqualified version (e.g., use 12.0Exp for 12.0)
53+
# False: do not use express version for unqualified version
54+
_VSEXPRESS_USE_VERSTR = True
55+
56+
5157
class VisualStudio:
5258
"""
5359
An abstract base class for trying to find installed versions of
5460
Visual Studio.
5561
"""
5662
def __init__(self, version, **kw) -> None:
5763
self.version = version
58-
self.vernum = float(get_msvc_version_numeric(version))
64+
self.verstr = get_msvc_version_numeric(version)
65+
self.vernum = float(self.verstr)
66+
self.is_express = True if self.verstr != self.version else False
5967
kw['vc_version'] = kw.get('vc_version', version)
6068
kw['sdk_version'] = kw.get('sdk_version', version)
6169
self.__dict__.update(kw)
@@ -454,9 +462,17 @@ def get_installed_visual_studios(env=None):
454462
if vs.get_executable(env):
455463
debug('found VS %s', vs.version)
456464
InstalledVSList.append(vs)
465+
if vs.is_express and vs.verstr not in InstalledVSMap:
466+
if _VSEXPRESS_USE_VERSTR:
467+
InstalledVSMap[vs.verstr] = vs
457468
InstalledVSMap[vs.version] = vs
458469
return InstalledVSList
459470

471+
def _get_installed_vss(env=None):
472+
get_installed_visual_studios(env)
473+
versions = list(InstalledVSMap.keys())
474+
return versions
475+
460476
def reset_installed_visual_studios() -> None:
461477
global InstalledVSList
462478
global InstalledVSMap
@@ -519,15 +535,15 @@ def _reset_installed_vswhere_visual_studios():
519535
def msvs_exists(env=None) -> bool:
520536
return len(get_installed_visual_studios(env)) > 0
521537

522-
def get_vs_by_version(msvs):
538+
def get_vs_by_version(msvs, env=None):
523539
global InstalledVSMap
524540
global SupportedVSMap
525541

526542
debug('called')
527543
if msvs not in SupportedVSMap:
528544
msg = "Visual Studio version %s is not supported" % repr(msvs)
529545
raise SCons.Errors.UserError(msg)
530-
get_installed_visual_studios()
546+
get_installed_visual_studios(env)
531547
vs = InstalledVSMap.get(msvs)
532548
debug('InstalledVSMap:%s', InstalledVSMap)
533549
debug('found vs:%s', vs)
@@ -556,7 +572,7 @@ def get_default_version(env):
556572
"""
557573
if 'MSVS' not in env or not SCons.Util.is_Dict(env['MSVS']):
558574
# get all versions, and remember them for speed later
559-
versions = [vs.version for vs in get_installed_visual_studios()]
575+
versions = _get_installed_vss(env)
560576
env['MSVS'] = {'VERSIONS' : versions}
561577
else:
562578
versions = env['MSVS'].get('VERSIONS', [])
@@ -602,7 +618,7 @@ def merge_default_version(env) -> None:
602618

603619
# TODO: refers to versions and arch which aren't defined; called nowhere. Drop?
604620
def msvs_setup_env(env) -> None:
605-
msvs = get_vs_by_version(version)
621+
msvs = get_vs_by_version(version, env)
606622
if msvs is None:
607623
return
608624
batfilename = msvs.get_batch_file()
@@ -614,7 +630,7 @@ def msvs_setup_env(env) -> None:
614630

615631
vars = ('LIB', 'LIBPATH', 'PATH', 'INCLUDE')
616632

617-
msvs_list = get_installed_visual_studios()
633+
msvs_list = get_installed_visual_studios(env)
618634
vscommonvarnames = [vs.common_tools_var for vs in msvs_list]
619635
save_ENV = env['ENV']
620636
nenv = normalize_env(env['ENV'],
@@ -629,11 +645,10 @@ def msvs_setup_env(env) -> None:
629645
for k, v in vars.items():
630646
env.PrependENVPath(k, v, delete_existing=1)
631647

632-
def query_versions():
648+
def query_versions(env=None):
633649
"""Query the system to get available versions of VS. A version is
634650
considered when a batfile is found."""
635-
msvs_list = get_installed_visual_studios()
636-
versions = [msvs.version for msvs in msvs_list]
651+
versions = _get_installed_vss(env)
637652
return versions
638653

639654
# Local Variables:

SCons/Tool/msvsTests.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -635,9 +635,9 @@ def _TODO_test_merge_default_version(self) -> None:
635635
"""Test the merge_default_version() function"""
636636
pass
637637

638-
def test_query_versions(self) -> None:
638+
def test_query_versions(self, env=None) -> None:
639639
"""Test retrieval of the list of visual studio versions"""
640-
v1 = query_versions()
640+
v1 = query_versions(env)
641641
assert not v1 or str(v1[0]) == self.highest_version, \
642642
(v1, self.highest_version)
643643
assert len(v1) == self.number_of_versions, v1

test/MSVC/query_vcbat.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
# print k, v
5252
#MergeMSVSBatFile(env, 9.0)
5353
#print(env['ENV']['PATH'])
54-
print(query_versions())
54+
print(query_versions(env=None))
5555
""")
5656

5757
test.run(stderr=None)

0 commit comments

Comments
 (0)