diff --git a/CHANGES.txt b/CHANGES.txt
index c53fce3284..098bba3c9b 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -13,8 +13,52 @@ NOTE: Python 3.6 support is deprecated and will be dropped in a future release.
RELEASE VERSION/DATE TO BE FILLED IN LATER
From Joseph Brill:
- - Added error handling when creating MS VC detection debug log file specified by
- SCONS_MSCOMMON_DEBUG
+ - Added error handling when creating MSVC detection debug log file specified by
+ SCONS_MSCOMMON_DEBUG.
+ - MSVS: Added default HOST_ARCH values to sconstruct/sconscript environment for
+ select msvs test scripts to allow tests to run on platforms not recognized by
+ the msvs/msvc tool implementations. Fixes #4608.
+ - MSVS: Fix early exit after the first msvc version loop execution in select msvs
+ test scripts. Select msvs test scripts were being invoked for msvc version 8.0
+ only. Fixes #4609.
+ - MSVS: Additional minor select msvs test script fixes as a result of the msvs
+ tests being invoked for all msvc versions: fix vs version number for vc version
+ 14.3, fix expected platform toolset version, add and use a default known
+ project GUID for some select tests, add AdditionalOptions Condition to expected
+ vcx project file.
+ - MSVS: Additional minor changes to the msvs tool as a result of the msvs tests
+ being invoked for all msvc versions: use environment MSVS_PROJECT_GUID when
+ generating project files information, fix the visual studio string for VS2015,
+ add .vcxproj as an expected suffix for assigning the name to the file basename.
+ - MSVS: Add additional msvs tests for multi-project and solution builds.
+ - MSVS: Check for variant directory build of MSVSSolution and adjust the source
+ node similar to the handling for MSVSProject. The solution was generated in
+ the build directory instead of the source directory. The placeholder solution
+ file is not generated in the build directory and the solution file is generated
+ in the source directory similar to the handling for project files.
+ Fixes #4612.
+ - MSVS: Add project dsp nodes to the dsw source node list in the msvs tool. This
+ appears to always cause the project files to be generated before the solution
+ files which is necessary to retrieve the project GUIDs for use in the solution
+ file. This does change the behavior of clean for a project generated with
+ auto_build_solution disabled and explicit solution generation: when the
+ solution files are cleaned, the project files are also cleaned. The tests for
+ vs 6.0-7.1 were changed accordingly.
+ - MSVS: Add an optional keyword argument, auto_filter_projects, to MSVSSolution.
+ Accepted values for auto_filter_projects are:
+ - None [default]: raise an exception when solution file names or nodes are
+ detected in the projects argument list.
+ - True or evaluates True: automatically remove solution file names and nodes
+ from the project argument list.
+ - False or evaluates False: leave solution file names and nodes in the project
+ argument list. An exception is not raised.
+ Solution file names and/or nodes in the project argument list cause erroneous
+ Project records to be produced in the generated solution file. As a
+ convenience, an end-user may elect to ignore solution file names and nodes in
+ the projects argument list rather than manually removing solution file names
+ and nodes from the MSVSProject return values. Resolves #4613.
+ - MSVS: Remove the platform specification (i.e., platform = 'win32') from select
+ test script environments. The platform specification appears superfluous.
From Alex James:
- On Darwin, PermissionErrors are now handled while trying to access
diff --git a/RELEASE.txt b/RELEASE.txt
index baa9d1dbf7..6ba7fc06f7 100644
--- a/RELEASE.txt
+++ b/RELEASE.txt
@@ -36,6 +36,26 @@ CHANGED/ENHANCED EXISTING FUNCTIONALITY
- Added support for tracking beamer themes in the LaTeX scanner.
+- MSVS: msvs project files are always generated before the corresponding
+ msvs solution files. This changes the behavior of clean for a project
+ generated with auto_build_solution disabled and explicit solution
+ generation: when the solution files are cleaned, the project files are
+ also cleaned. The tests for vs 6.0-7.1 were updated accordingly.
+
+- MSVS: Add an optional keyword argument, auto_filter_projects, to
+ MSVSSolution. Accepted values for auto_filter_projects are:
+ - None [default]: raise an exception when solution file names or nodes
+ are detected in the projects argument list.
+ - True or evaluates True: automatically remove solution file names and
+ nodes from the project argument list.
+ - False or evaluates False: leave solution file names and nodes in the
+ project argument list. An exception is not raised.
+ Solution file names and/or nodes in the project argument list cause
+ erroneous Project records to be produced in the generated solution file.
+ As a convenience, a user may elect to ignore solution file names and nodes
+ in the projects argument list rather than manually removing solution file
+ names and nodes from the MSVSProject return values.
+
- Add a tag to each CacheDir to let systems ignore backing it up
(per https://bford.info/cachedir/). Update the way a CacheDir
is created, since it now has to create two files.
@@ -58,11 +78,31 @@ FIXES
- Fix a problem with compilation_db component initialization - the
entries for assembler files were not being set up correctly.
+
- On Darwin, PermissionErrors are now handled while trying to access
/etc/paths.d. This may occur if SCons is invoked in a sandboxed environment
(such as Nix).
-- Added error handling when creating MS VC detection debug log file specified by
- SCONS_MSCOMMON_DEBUG
+
+- Added error handling when creating MSVC detection debug log file specified
+ by SCONS_MSCOMMON_DEBUG.
+
+- MSVS: Modify select msvs test scripts to run on platforms not supported by
+ the msvs/msvc tool implementation via a default host architecture for
+ unsupported platforms.
+
+- MSVS: Fixed early loop exit in select msvs test scripts. Select msvs test
+ scripts were being invoked for msvc version 8.0 only. Additional msvs
+ tool and test changes due to the msvs test scripts being run for all msvc
+ versions (i.e., minor test and tool issues went undetected).
+
+- MSVS: for variant build configurations, msvs solution files are
+ generated in the source directory and a placeholder file is generated in
+ the variant build directory. This mirrors the behavior of generated
+ msvs project files.
+
+- MSVS: msvs project files are generated before the corresponding msvs
+ solution file. User-specified project GUIDs should now be correctly
+ written to the solution file.
- Fix nasm test for missing include file, cleanup.
diff --git a/SCons/Tool/msvs.py b/SCons/Tool/msvs.py
index 12974489a4..b327653160 100644
--- a/SCons/Tool/msvs.py
+++ b/SCons/Tool/msvs.py
@@ -124,6 +124,21 @@ def _generateGUID(slnfile, name, namespace=external_makefile_guid):
return '{' + str(solution).upper() + '}'
+def _projectGUID(env, dspfile):
+ """Generates a GUID for the project file to use.
+
+ In order of preference:
+ * MSVS_PROJECT_GUID in environment
+ * Generated from the project file name (dspfile)
+
+ Returns (str)
+ """
+ project_guid = env.get('MSVS_PROJECT_GUID')
+ if not project_guid:
+ project_guid = _generateGUID(dspfile, '')
+ return project_guid
+
+
version_re = re.compile(r'(\d+\.\d+)(.*)')
@@ -436,6 +451,10 @@ def __init__(self, dspfile, source, env) -> None:
else:
self.dspabs = get_abspath()
+ self.project_guid = _projectGUID(env, self.dspfile)
+ dspnode = env.File(self.dspfile)
+ dspnode.Tag('project_guid', self.project_guid)
+
if 'variant' not in env:
raise SCons.Errors.InternalError("You must specify a 'variant' argument (i.e. 'Debug' or " +\
"'Release') to create an MSVSProject.")
@@ -571,7 +590,7 @@ def GetKeyFromEnv(env, key, variants):
self.configs = {}
self.nokeep = 0
- if 'nokeep' in env and env['variant'] != 0:
+ if 'nokeep' in env and env['nokeep'] != 0:
self.nokeep = 1
if self.nokeep == 0 and os.path.exists(self.dspabs):
@@ -912,8 +931,9 @@ def __init__(self, dspfile, source, env) -> None:
def PrintHeader(self) -> None:
env = self.env
- versionstr = self.versionstr
name = self.name
+ versionstr = self.versionstr
+ project_guid = self.project_guid
encoding = self.env.subst('$MSVSENCODING')
scc_provider = env.get('MSVS_SCC_PROVIDER', '')
scc_project_name = env.get('MSVS_SCC_PROJECT_NAME', '')
@@ -923,9 +943,6 @@ def PrintHeader(self) -> None:
scc_local_path_legacy = env.get('MSVS_SCC_LOCAL_PATH', '')
scc_connection_root = env.get('MSVS_SCC_CONNECTION_ROOT', os.curdir)
scc_local_path = os.path.relpath(scc_connection_root, os.path.dirname(self.dspabs))
- project_guid = env.get('MSVS_PROJECT_GUID', '')
- if not project_guid:
- project_guid = _generateGUID(self.dspfile, '')
if scc_provider != '':
scc_attrs = '\tSccProjectName="%s"\n' % scc_project_name
if scc_aux_path != '':
@@ -1209,8 +1226,8 @@ def PrintHeader(self) -> None:
env = self.env
name = self.name
versionstr = self.versionstr
+ project_guid = self.project_guid
encoding = env.subst('$MSVSENCODING')
- project_guid = env.get('MSVS_PROJECT_GUID', '')
scc_provider = env.get('MSVS_SCC_PROVIDER', '')
scc_project_name = env.get('MSVS_SCC_PROJECT_NAME', '')
scc_aux_path = env.get('MSVS_SCC_AUX_PATH', '')
@@ -1219,8 +1236,6 @@ def PrintHeader(self) -> None:
scc_local_path_legacy = env.get('MSVS_SCC_LOCAL_PATH', '')
scc_connection_root = env.get('MSVS_SCC_CONNECTION_ROOT', os.curdir)
scc_local_path = os.path.relpath(scc_connection_root, os.path.dirname(self.dspabs))
- if not project_guid:
- project_guid = _generateGUID(self.dspfile, '')
if scc_provider != '':
scc_attrs = '\t\t%s\n' % scc_project_name
if scc_aux_path != '':
@@ -1465,6 +1480,42 @@ def Build(self):
_GenerateV10User.Build(self)
+def _projectDSPNodes(env):
+ auto_filter_projects = env.get('auto_filter_projects', None)
+ if 'projects' not in env:
+ raise SCons.Errors.UserError("You must specify a 'projects' argument to create an MSVSSolution.")
+ projects = env['projects']
+ if not SCons.Util.is_List(projects):
+ raise SCons.Errors.InternalError("The 'projects' argument must be a list of nodes.")
+ projects = SCons.Util.flatten(projects)
+ if len(projects) < 1:
+ raise SCons.Errors.UserError("You must specify at least one project to create an MSVSSolution.")
+ sln_suffix = os.path.normcase(env.subst('$MSVSSOLUTIONSUFFIX'))
+ dspnodes = []
+ for p in projects:
+ node = env.File(p)
+ if os.path.normcase(str(node)).endswith(sln_suffix):
+ # solution node detected (possible issues when opening generated solution file with VS IDE)
+ if auto_filter_projects is None:
+ nodestr = str(node)
+ errmsg = (
+ f"An msvs solution file was detected in the MSVSSolution 'projects' argument: {nodestr!r}.\n"
+ " Add MSVSSolution argument 'auto_filter_projects=True' to suppress project solution nodes.\n"
+ " Add MSVSSolution argument 'auto_filter_projects=False' to keep project solution nodes.\n"
+ " Refer to the MSVSSolution documentation for more information."
+ )
+ raise SCons.Errors.UserError(errmsg)
+ elif auto_filter_projects:
+ # skip solution node
+ continue
+ else:
+ # keep solution node
+ pass
+ dspnodes.append(node)
+ if len(dspnodes) < 1:
+ raise SCons.Errors.UserError("You must specify at least one project node to create an MSVSSolution.")
+ return dspnodes
+
class _DSWGenerator:
""" Base class for DSW generators """
def __init__(self, dswfile, source, env) -> None:
@@ -1472,15 +1523,8 @@ def __init__(self, dswfile, source, env) -> None:
self.dsw_folder_path = os.path.dirname(os.path.abspath(self.dswfile))
self.env = env
- if 'projects' not in env:
- raise SCons.Errors.UserError("You must specify a 'projects' argument to create an MSVSSolution.")
- projects = env['projects']
- if not SCons.Util.is_List(projects):
- raise SCons.Errors.InternalError("The 'projects' argument must be a list of nodes.")
- projects = SCons.Util.flatten(projects)
- if len(projects) < 1:
- raise SCons.Errors.UserError("You must specify at least one project to create an MSVSSolution.")
- self.dspfiles = list(map(str, projects))
+ dspnodes = _projectDSPNodes(env)
+ self.dsp_srcnodes = [dspnode.srcnode() for dspnode in dspnodes]
if 'name' in self.env:
self.name = self.env['name']
@@ -1519,7 +1563,7 @@ def __init__(self, dswfile, source, env) -> None:
self.configs = {}
self.nokeep = 0
- if 'nokeep' in env and env['variant'] != 0:
+ if 'nokeep' in env and env['nokeep'] != 0:
self.nokeep = 1
if self.nokeep == 0 and os.path.exists(self.dswfile):
@@ -1554,7 +1598,9 @@ def AddConfig(self, variant, dswfile=dswfile) -> None:
if not (p.platform in seen or seen.add(p.platform))]
def GenerateProjectFilesInfo(self) -> None:
- for dspfile in self.dspfiles:
+ for dspnode in self.dsp_srcnodes:
+ project_guid = dspnode.GetTag('project_guid')
+ dspfile = str(dspnode)
dsp_folder_path, name = os.path.split(dspfile)
dsp_folder_path = os.path.abspath(dsp_folder_path)
if SCons.Util.splitext(name)[1] == '.filters':
@@ -1565,8 +1611,10 @@ def GenerateProjectFilesInfo(self) -> None:
dsp_relative_file_path = name
else:
dsp_relative_file_path = os.path.join(dsp_relative_folder_path, name)
+ if not project_guid:
+ project_guid = _generateGUID(dspfile, '')
dspfile_info = {'NAME': name,
- 'GUID': _generateGUID(dspfile, ''),
+ 'GUID': project_guid,
'FOLDER_PATH': dsp_folder_path,
'FILE_PATH': dspfile,
'SLN_RELATIVE_FOLDER_PATH': dsp_relative_folder_path,
@@ -1615,7 +1663,7 @@ def PrintSolution(self) -> None:
elif self.version_num >= 14.2:
# Visual Studio 2019 is considered to be version 16.
self.file.write('# Visual Studio 16\n')
- elif self.version_num > 14.0:
+ elif self.version_num >= 14.0:
# Visual Studio 2015 and 2017 are both considered to be version 15.
self.file.write('# Visual Studio 15\n')
elif self.version_num >= 12.0:
@@ -1632,7 +1680,7 @@ def PrintSolution(self) -> None:
for dspinfo in self.dspfiles_info:
name = dspinfo['NAME']
base, suffix = SCons.Util.splitext(name)
- if suffix == '.vcproj':
+ if suffix in ('.vcxproj', '.vcproj'):
name = base
self.file.write('Project("%s") = "%s", "%s", "%s"\n'
% (external_makefile_guid, name, dspinfo['SLN_RELATIVE_FILE_PATH'], dspinfo['GUID']))
@@ -1645,7 +1693,7 @@ def PrintSolution(self) -> None:
env = self.env
if 'MSVS_SCC_PROVIDER' in env:
- scc_number_of_projects = len(self.dspfiles) + 1
+ scc_number_of_projects = len(self.dsp_srcnodes) + 1
slnguid = self.slnguid
scc_provider = env.get('MSVS_SCC_PROVIDER', '').replace(' ', r'\u0020')
scc_project_name = env.get('MSVS_SCC_PROJECT_NAME', '').replace(' ', r'\u0020')
@@ -1777,7 +1825,7 @@ class _GenerateV6DSW(_DSWGenerator):
def PrintWorkspace(self) -> None:
""" writes a DSW file """
name = self.name
- dspfile = os.path.relpath(self.dspfiles[0], self.dsw_folder_path)
+ dspfile = os.path.relpath(str(self.dsp_srcnodes[0]), self.dsw_folder_path)
self.file.write(V6DSWHeader % locals())
def Build(self):
@@ -1867,7 +1915,22 @@ def GenerateProject(target, source, env):
GenerateDSW(dswfile, source, env)
def GenerateSolution(target, source, env) -> None:
- GenerateDSW(target[0], source, env)
+
+ builddswfile = target[0]
+ dswfile = builddswfile.srcnode()
+
+ if dswfile is not builddswfile:
+
+ try:
+ bdsw = open(str(builddswfile), "w+")
+ except OSError as detail:
+ print('Unable to open "' + str(dspfile) + '" for writing:',detail,'\n')
+ raise
+
+ bdsw.write("This is just a placeholder file.\nThe real workspace file is here:\n%s\n" % dswfile.get_abspath())
+ bdsw.close()
+
+ GenerateDSW(dswfile, source, env)
def projectEmitter(target, source, env):
"""Sets up the DSP dependencies."""
@@ -1961,7 +2024,7 @@ def projectEmitter(target, source, env):
sourcelist = source
if env.get('auto_build_solution', 1):
- env['projects'] = [env.File(t).srcnode() for t in targetlist]
+ env['projects'] = [env.File(t) for t in targetlist]
t, s = solutionEmitter(target, target, env)
targetlist = targetlist + t
@@ -2028,6 +2091,9 @@ def solutionEmitter(target, source, env):
source = source + ' "%s"' % str(target[0])
source = [SCons.Node.Python.Value(source)]
+ dsp_nodes = _projectDSPNodes(env)
+ source.extend(dsp_nodes)
+
return ([target[0]], source)
projectAction = SCons.Action.Action(GenerateProject, None)
diff --git a/SCons/Tool/msvs.xml b/SCons/Tool/msvs.xml
index cc4220c787..ad3a7569be 100644
--- a/SCons/Tool/msvs.xml
+++ b/SCons/Tool/msvs.xml
@@ -540,6 +540,74 @@ env.MSVSProject(
+
+ In addition to the mandatory arguments above, the following optional
+ values may be specified as keyword arguments:
+
+
+
+ auto_filter_projects
+
+
+ Under certain circumstances, solution file names or
+ solution file nodes may be present in the
+ projects argument list.
+ When solution file names or nodes are present in the
+ projects argument list, the generated
+ solution file may contain erroneous Project records resulting
+ in VS IDE error messages when opening the generated solution
+ file.
+ By default, an exception is raised when a solution file
+ name or solution file node is detected in the
+ projects argument list.
+
+
+ The accepted values for auto_filter_projects
+ are:
+
+
+
+ None
+
+
+ An exception is raised when a solution file name or solution
+ file node is detected in the projects
+ argument list.
+
+
+ None is the default value.
+
+
+
+
+ True or evaluates True
+
+
+ Automatically remove solution file names and solution file
+ nodes from the projects argument list.
+
+
+
+
+ False or evaluates False
+
+
+ Leave the solution file names and solution file nodes
+ in the projects argument list.
+ An exception is not raised.
+
+
+ When opening the generated solution file with the VS IDE,
+ the VS IDE will likely report that there are erroneous
+ Project records that are not supported or that need to be
+ modified.
+
+
+
+
+
+
+
Example Usage:
env.MSVSSolution(
diff --git a/SCons/Tool/msvsTests.py b/SCons/Tool/msvsTests.py
index 7893cafdcc..dd423d4bd9 100644
--- a/SCons/Tool/msvsTests.py
+++ b/SCons/Tool/msvsTests.py
@@ -420,6 +420,9 @@ def get(self, name, value=None):
def Dir(self, name):
return self.fs.Dir(name)
+ def File(self, name):
+ return self.fs.File(name)
+
def subst(self, key):
if key[0] == '$':
key = key[1:]
diff --git a/test/MSVS/common-prefix.py b/test/MSVS/common-prefix.py
index ea95c032a0..070ce0d0e4 100644
--- a/test/MSVS/common-prefix.py
+++ b/test/MSVS/common-prefix.py
@@ -38,6 +38,8 @@
msg = "Skipping Visual Studio test on non-Windows platform '%s'\n" % sys.platform
test.skip_test(msg)
+project_guid = TestSConsMSVS.PROJECT_GUID
+
vcproj_template = """\
"""
-
-
SConscript_contents = """\
env=Environment(tools=['msvs'], MSVS_VERSION = '8.0')
testsrc = %(testsrc)s
env.MSVSProject(target = 'Test.vcproj',
+ MSVS_PROJECT_GUID = '%(project_guid)s',
slnguid = '{SLNGUID}',
srcs = testsrc,
buildtarget = 'Test.exe',
@@ -98,8 +99,6 @@
auto_build_solution = 0)
"""
-
-
test.subdir('work1')
testsrc = repr([
@@ -142,8 +141,6 @@
# don't compare the pickled data
assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
-
-
test.subdir('work2')
testsrc = repr([
@@ -170,8 +167,6 @@
# don't compare the pickled data
assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
-
-
test.pass_test()
# Local Variables:
diff --git a/test/MSVS/runfile.py b/test/MSVS/runfile.py
index d2319f330a..08c8f31633 100644
--- a/test/MSVS/runfile.py
+++ b/test/MSVS/runfile.py
@@ -38,6 +38,8 @@
msg = "Skipping Visual Studio test on non-Windows platform '%s'\n" % sys.platform
test.skip_test(msg)
+sconscript_dict = {'PROJECT_GUID': TestSConsMSVS.PROJECT_GUID}
+
expected_vcprojfile = """\
"""
-
-
SConscript_contents = """\
env=Environment(tools=['msvs'], MSVS_VERSION = '8.0')
env.MSVSProject(target = 'Test.vcproj',
+ MSVS_PROJECT_GUID = '%(PROJECT_GUID)s',
slnguid = '{SLNGUID}',
srcs = ['test.cpp'],
buildtarget = 'Test.exe',
@@ -104,11 +105,9 @@
auto_build_solution = 0)
"""
-
-
test.subdir('work1')
-test.write(['work1', 'SConstruct'], SConscript_contents)
+test.write(['work1', 'SConstruct'], SConscript_contents % sconscript_dict)
test.run(chdir='work1', arguments="Test.vcproj")
@@ -118,8 +117,6 @@
# don't compare the pickled data
assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
-
-
test.pass_test()
# Local Variables:
diff --git a/test/MSVS/vs-6.0-clean.py b/test/MSVS/vs-6.0-clean.py
index 0cbadba2f4..3f99d650d3 100644
--- a/test/MSVS/vs-6.0-clean.py
+++ b/test/MSVS/vs-6.0-clean.py
@@ -34,21 +34,16 @@
test = TestSConsMSVS.TestSConsMSVS()
host_arch = test.get_vs_host_arch()
-
-
# Make the test infrastructure think we have this version of MSVS installed.
test._msvs_versions = ['6.0']
-
-
expected_dspfile = TestSConsMSVS.expected_dspfile_6_0
expected_dswfile = TestSConsMSVS.expected_dswfile_6_0
-
-
test.write('SConstruct', """\
-env=Environment(platform='win32', tools=['msvs'],
- MSVS_VERSION='6.0',HOST_ARCH='%(HOST_ARCH)s')
+env=Environment(tools=['msvs'],
+ MSVS_VERSION='6.0',
+ HOST_ARCH='%(HOST_ARCH)s')
testsrc = ['test.c']
testincs = ['sdk.h']
@@ -95,16 +90,14 @@
test.must_exist(test.workpath('Test.dsp'))
test.must_exist(test.workpath('Test.dsw'))
-test.run(arguments='-c Test.dsw')
-
-test.must_exist(test.workpath('Test.dsp'))
-test.must_not_exist(test.workpath('Test.dsw'))
-
test.run(arguments='-c Test.dsp')
test.must_not_exist(test.workpath('Test.dsp'))
+test.must_exist(test.workpath('Test.dsw'))
+test.run(arguments='-c Test.dsw')
+test.must_not_exist(test.workpath('Test.dsw'))
test.pass_test()
diff --git a/test/MSVS/vs-7.0-clean.py b/test/MSVS/vs-7.0-clean.py
index 1194cc1fac..627c5addb9 100644
--- a/test/MSVS/vs-7.0-clean.py
+++ b/test/MSVS/vs-7.0-clean.py
@@ -34,20 +34,16 @@
test = TestSConsMSVS.TestSConsMSVS()
host_arch = test.get_vs_host_arch()
-
# Make the test infrastructure think we have this version of MSVS installed.
test._msvs_versions = ['7.0']
-
-
expected_slnfile = TestSConsMSVS.expected_slnfile_7_0
expected_vcprojfile = TestSConsMSVS.expected_vcprojfile_7_0
-
-
test.write('SConstruct', """\
-env=Environment(platform='win32', tools=['msvs'],
- MSVS_VERSION='7.0',HOST_ARCH='%(HOST_ARCH)s')
+env=Environment(tools=['msvs'],
+ MSVS_VERSION='7.0',
+ HOST_ARCH='%(HOST_ARCH)s')
testsrc = ['test1.cpp', 'test2.cpp']
testincs = ['sdk.h']
@@ -56,6 +52,7 @@
testmisc = ['readme.txt']
p = env.MSVSProject(target = 'Test.vcproj',
+ MSVS_PROJECT_GUID='%(PROJECT_GUID)s',
srcs = testsrc,
incs = testincs,
localincs = testlocalincs,
@@ -69,7 +66,7 @@
slnguid = '{SLNGUID}',
projects = [p],
variant = 'Release')
-"""%{'HOST_ARCH':host_arch})
+""" % {'HOST_ARCH':host_arch, 'PROJECT_GUID': TestSConsMSVS.PROJECT_GUID})
test.run(arguments=".")
@@ -95,16 +92,13 @@
test.must_exist(test.workpath('Test.vcproj'))
test.must_exist(test.workpath('Test.sln'))
-test.run(arguments='-c Test.sln')
-
-test.must_exist(test.workpath('Test.vcproj'))
-test.must_not_exist(test.workpath('Test.sln'))
-
test.run(arguments='-c Test.vcproj')
-
test.must_not_exist(test.workpath('Test.vcproj'))
+test.must_exist(test.workpath('Test.sln'))
+test.run(arguments='-c Test.sln')
+test.must_not_exist(test.workpath('Test.sln'))
test.pass_test()
diff --git a/test/MSVS/vs-7.0-files.py b/test/MSVS/vs-7.0-files.py
index 9dc33b70d5..202036ce90 100644
--- a/test/MSVS/vs-7.0-files.py
+++ b/test/MSVS/vs-7.0-files.py
@@ -35,20 +35,16 @@
test = TestSConsMSVS.TestSConsMSVS()
host_arch = test.get_vs_host_arch()
-
+sconscript_dict = {'HOST_ARCH': host_arch, 'PROJECT_GUID': TestSConsMSVS.PROJECT_GUID}
# Make the test infrastructure think we have this version of MSVS installed.
test._msvs_versions = ['7.0']
-
-
expected_slnfile = TestSConsMSVS.expected_slnfile_7_0
expected_vcprojfile = TestSConsMSVS.expected_vcprojfile_7_0
SConscript_contents = TestSConsMSVS.SConscript_contents_7_0
-
-
-test.write('SConstruct', SConscript_contents%{'HOST_ARCH': host_arch})
+test.write('SConstruct', SConscript_contents % sconscript_dict)
test.run(arguments="Test.vcproj")
@@ -79,8 +75,6 @@
test.must_not_exist(test.workpath('Test.vcproj'))
test.must_not_exist(test.workpath('Test.sln'))
-
-
# Test that running SCons with $PYTHON_ROOT in the environment
# changes the .vcproj output as expected.
os.environ['PYTHON_ROOT'] = 'xyzzy'
@@ -95,8 +89,6 @@
# don't compare the pickled data
assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
-
-
test.pass_test()
# Local Variables:
diff --git a/test/MSVS/vs-7.0-scc-files.py b/test/MSVS/vs-7.0-scc-files.py
index f1f77db2e9..2c5c520e60 100644
--- a/test/MSVS/vs-7.0-scc-files.py
+++ b/test/MSVS/vs-7.0-scc-files.py
@@ -33,22 +33,23 @@
import TestSConsMSVS
test = TestSConsMSVS.TestSConsMSVS()
+host_arch = test.get_vs_host_arch()
# Make the test infrastructure think we have this version of MSVS installed.
test._msvs_versions = ['7.0']
-
-
expected_slnfile = TestSConsMSVS.expected_slnfile_7_0
expected_vcprojfile = TestSConsMSVS.expected_vcprojfile_7_0
SConscript_contents = \
-r"""env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='7.0',
- CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
- CPPPATH=['inc1', 'inc2'],
- MSVS_SCC_CONNECTION_ROOT='.',
- MSVS_SCC_PROVIDER='MSSCCI:Perforce SCM',
- MSVS_SCC_PROJECT_NAME='Perforce Project',
- MSVS_SCC_AUX_PATH='AUX')
+r"""env=Environment(tools=['msvs'],
+ MSVS_VERSION='7.0',
+ CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
+ CPPPATH=['inc1', 'inc2'],
+ MSVS_SCC_CONNECTION_ROOT='.',
+ MSVS_SCC_PROVIDER='MSSCCI:Perforce SCM',
+ MSVS_SCC_PROJECT_NAME='Perforce Project',
+ MSVS_SCC_AUX_PATH='AUX',
+ HOST_ARCH='%(HOST_ARCH)s')
testsrc = ['test1.cpp', 'test2.cpp']
testincs = ['sdk.h']
@@ -57,6 +58,7 @@
testmisc = ['readme.txt']
env.MSVSProject(target = 'Test.vcproj',
+ MSVS_PROJECT_GUID='%(PROJECT_GUID)s',
slnguid = '{SLNGUID}',
srcs = testsrc,
incs = testincs,
@@ -65,7 +67,7 @@
misc = testmisc,
buildtarget = 'Test.exe',
variant = 'Release')
-"""
+""" % {'HOST_ARCH':host_arch, 'PROJECT_GUID': TestSConsMSVS.PROJECT_GUID}
expected_sln_sccinfo = """\
\tGlobalSection(SourceCodeControl) = preSolution
@@ -89,7 +91,6 @@
\tSccProvider="MSSCCI:Perforce SCM"
"""
-
test.write('SConstruct', SConscript_contents)
test.run(arguments="Test.vcproj")
@@ -108,7 +109,6 @@
# don't compare the pickled data
assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
-
test.pass_test()
# Local Variables:
diff --git a/test/MSVS/vs-7.0-scc-legacy-files.py b/test/MSVS/vs-7.0-scc-legacy-files.py
index a180b8ad6a..00ce397d45 100644
--- a/test/MSVS/vs-7.0-scc-legacy-files.py
+++ b/test/MSVS/vs-7.0-scc-legacy-files.py
@@ -33,20 +33,21 @@
import TestSConsMSVS
test = TestSConsMSVS.TestSConsMSVS()
+host_arch = test.get_vs_host_arch()
# Make the test infrastructure think we have this version of MSVS installed.
test._msvs_versions = ['7.0']
-
-
expected_slnfile = TestSConsMSVS.expected_slnfile_7_0
expected_vcprojfile = TestSConsMSVS.expected_vcprojfile_7_0
SConscript_contents = """\
-env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='7.0',
+env=Environment(tools=['msvs'],
+ MSVS_VERSION='7.0',
CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
CPPPATH=['inc1', 'inc2'],
MSVS_SCC_LOCAL_PATH=r'C:\\MyMsVsProjects',
- MSVS_SCC_PROJECT_NAME='Perforce Project')
+ MSVS_SCC_PROJECT_NAME='Perforce Project',
+ HOST_ARCH='%(HOST_ARCH)s')
testsrc = ['test1.cpp', 'test2.cpp']
testincs = ['sdk.h']
@@ -55,6 +56,7 @@
testmisc = ['readme.txt']
env.MSVSProject(target = 'Test.vcproj',
+ MSVS_PROJECT_GUID='%(PROJECT_GUID)s',
slnguid = '{SLNGUID}',
srcs = testsrc,
incs = testincs,
@@ -63,14 +65,13 @@
misc = testmisc,
buildtarget = 'Test.exe',
variant = 'Release')
-"""
+""" % {'HOST_ARCH':host_arch, 'PROJECT_GUID': TestSConsMSVS.PROJECT_GUID}
expected_vcproj_sccinfo = """\
\tSccProjectName="Perforce Project"
\tSccLocalPath="C:\\MyMsVsProjects"
"""
-
test.write('SConstruct', SConscript_contents)
test.run(arguments="Test.vcproj")
@@ -88,7 +89,6 @@
# don't compare the pickled data
assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
-
test.pass_test()
# Local Variables:
diff --git a/test/MSVS/vs-7.0-variant_dir.py b/test/MSVS/vs-7.0-variant_dir.py
index 41c3cdcec2..f83d0abe5e 100644
--- a/test/MSVS/vs-7.0-variant_dir.py
+++ b/test/MSVS/vs-7.0-variant_dir.py
@@ -33,40 +33,33 @@
test = TestSConsMSVS.TestSConsMSVS()
host_arch = test.get_vs_host_arch()
-
+sconscript_dict = {'HOST_ARCH': host_arch, 'PROJECT_GUID': TestSConsMSVS.PROJECT_GUID}
# Make the test infrastructure think we have this version of MSVS installed.
test._msvs_versions = ['7.0']
-
-
expected_slnfile = TestSConsMSVS.expected_slnfile_7_0
expected_vcprojfile = TestSConsMSVS.expected_vcprojfile_7_0
SConscript_contents = TestSConsMSVS.SConscript_contents_7_0
-
-
test.subdir('src')
test.write('SConstruct', """\
SConscript('src/SConscript', variant_dir='build')
""")
-test.write(['src', 'SConscript'], SConscript_contents%{'HOST_ARCH': host_arch})
+test.write(['src', 'SConscript'], SConscript_contents % sconscript_dict)
test.run(arguments=".")
-project_guid = "{CB4637F1-2205-50B7-B115-DCFA0DA68FB1}"
vcproj = test.read(['src', 'Test.vcproj'], 'r')
-expect = test.msvs_substitute(expected_vcprojfile, '7.0', None, 'SConstruct',
- project_guid=project_guid)
+expect = test.msvs_substitute(expected_vcprojfile, '7.0', None, 'SConstruct')
# don't compare the pickled data
assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
test.must_exist(test.workpath('src', 'Test.sln'))
sln = test.read(['src', 'Test.sln'], 'r')
-expect = test.msvs_substitute(expected_slnfile, '7.0', 'src',
- project_guid=project_guid)
+expect = test.msvs_substitute(expected_slnfile, '7.0', 'src')
# don't compare the pickled data
assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
@@ -84,8 +77,6 @@
""" % test.workpath('src', 'Test.sln'),
mode='r')
-
-
test.pass_test()
# Local Variables:
diff --git a/test/MSVS/vs-7.1-clean.py b/test/MSVS/vs-7.1-clean.py
index 8c9cb87894..403463e0bb 100644
--- a/test/MSVS/vs-7.1-clean.py
+++ b/test/MSVS/vs-7.1-clean.py
@@ -34,20 +34,16 @@
test = TestSConsMSVS.TestSConsMSVS()
host_arch = test.get_vs_host_arch()
-
# Make the test infrastructure think we have this version of MSVS installed.
test._msvs_versions = ['7.1']
-
-
expected_slnfile = TestSConsMSVS.expected_slnfile_7_1
expected_vcprojfile = TestSConsMSVS.expected_vcprojfile_7_1
-
-
test.write('SConstruct', """\
-env=Environment(platform='win32', tools=['msvs'],
- MSVS_VERSION='7.1',HOST_ARCH='%(HOST_ARCH)s')
+env=Environment(tools=['msvs'],
+ MSVS_VERSION='7.1',
+ HOST_ARCH='%(HOST_ARCH)s')
testsrc = ['test1.cpp', 'test2.cpp']
testincs = ['sdk.h']
@@ -56,6 +52,7 @@
testmisc = ['readme.txt']
p = env.MSVSProject(target = 'Test.vcproj',
+ MSVS_PROJECT_GUID='%(PROJECT_GUID)s',
srcs = testsrc,
incs = testincs,
localincs = testlocalincs,
@@ -69,7 +66,7 @@
slnguid = '{SLNGUID}',
projects = [p],
variant = 'Release')
-"""%{'HOST_ARCH':host_arch})
+""" % {'HOST_ARCH':host_arch, 'PROJECT_GUID': TestSConsMSVS.PROJECT_GUID})
test.run(arguments=".")
@@ -95,16 +92,20 @@
test.must_exist(test.workpath('Test.vcproj'))
test.must_exist(test.workpath('Test.sln'))
-test.run(arguments='-c Test.sln')
-
-test.must_exist(test.workpath('Test.vcproj'))
-test.must_not_exist(test.workpath('Test.sln'))
-
test.run(arguments='-c Test.vcproj')
test.must_not_exist(test.workpath('Test.vcproj'))
+test.must_exist(test.workpath('Test.sln'))
+
+test.run(arguments='.')
+test.must_exist(test.workpath('Test.vcproj'))
+test.must_exist(test.workpath('Test.sln'))
+test.run(arguments='-c Test.sln')
+
+test.must_not_exist(test.workpath('Test.vcproj'))
+test.must_not_exist(test.workpath('Test.sln'))
test.pass_test()
diff --git a/test/MSVS/vs-7.1-files.py b/test/MSVS/vs-7.1-files.py
index e2a40a813d..9fcea6d5f6 100644
--- a/test/MSVS/vs-7.1-files.py
+++ b/test/MSVS/vs-7.1-files.py
@@ -35,20 +35,16 @@
test = TestSConsMSVS.TestSConsMSVS()
host_arch = test.get_vs_host_arch()
-
+sconscript_dict = {'HOST_ARCH': host_arch, 'PROJECT_GUID': TestSConsMSVS.PROJECT_GUID}
# Make the test infrastructure think we have this version of MSVS installed.
test._msvs_versions = ['7.1']
-
-
expected_slnfile = TestSConsMSVS.expected_slnfile_7_1
expected_vcprojfile = TestSConsMSVS.expected_vcprojfile_7_1
SConscript_contents = TestSConsMSVS.SConscript_contents_7_1
-
-
-test.write('SConstruct', SConscript_contents%{'HOST_ARCH': host_arch})
+test.write('SConstruct', SConscript_contents % sconscript_dict)
test.run(arguments="Test.vcproj")
@@ -79,8 +75,6 @@
test.must_not_exist(test.workpath('Test.vcproj'))
test.must_not_exist(test.workpath('Test.sln'))
-
-
# Test that running SCons with $PYTHON_ROOT in the environment
# changes the .vcproj output as expected.
os.environ['PYTHON_ROOT'] = 'xyzzy'
@@ -95,8 +89,6 @@
# don't compare the pickled data
assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
-
-
test.pass_test()
# Local Variables:
diff --git a/test/MSVS/vs-7.1-scc-files.py b/test/MSVS/vs-7.1-scc-files.py
index 0b42930b51..4f253e7172 100644
--- a/test/MSVS/vs-7.1-scc-files.py
+++ b/test/MSVS/vs-7.1-scc-files.py
@@ -33,22 +33,23 @@
import TestSConsMSVS
test = TestSConsMSVS.TestSConsMSVS()
+host_arch = test.get_vs_host_arch()
# Make the test infrastructure think we have this version of MSVS installed.
test._msvs_versions = ['7.1']
-
-
expected_slnfile = TestSConsMSVS.expected_slnfile_7_1
expected_vcprojfile = TestSConsMSVS.expected_vcprojfile_7_1
SConscript_contents = """\
-env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='7.1',
+env=Environment(tools=['msvs'],
+ MSVS_VERSION='7.1',
CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
CPPPATH=['inc1', 'inc2'],
MSVS_SCC_CONNECTION_ROOT='.',
MSVS_SCC_PROVIDER='MSSCCI:Perforce SCM',
MSVS_SCC_PROJECT_NAME='Perforce Project',
- MSVS_SCC_AUX_PATH='AUX')
+ MSVS_SCC_AUX_PATH='AUX',
+ HOST_ARCH='%(HOST_ARCH)s')
testsrc = ['test1.cpp', 'test2.cpp']
testincs = ['sdk.h']
@@ -57,6 +58,7 @@
testmisc = ['readme.txt']
env.MSVSProject(target = 'Test.vcproj',
+ MSVS_PROJECT_GUID='%(PROJECT_GUID)s',
slnguid = '{SLNGUID}',
srcs = testsrc,
incs = testincs,
@@ -65,7 +67,7 @@
misc = testmisc,
buildtarget = 'Test.exe',
variant = 'Release')
-"""
+""" % {'HOST_ARCH':host_arch, 'PROJECT_GUID': TestSConsMSVS.PROJECT_GUID}
expected_sln_sccinfo = """\
\tGlobalSection(SourceCodeControl) = preSolution
@@ -89,7 +91,6 @@
\tSccProvider="MSSCCI:Perforce SCM"
"""
-
test.write('SConstruct', SConscript_contents)
test.run(arguments="Test.vcproj")
@@ -108,7 +109,6 @@
# don't compare the pickled data
assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
-
test.pass_test()
# Local Variables:
diff --git a/test/MSVS/vs-7.1-scc-legacy-files.py b/test/MSVS/vs-7.1-scc-legacy-files.py
index bb184d6dec..96ec21d67f 100644
--- a/test/MSVS/vs-7.1-scc-legacy-files.py
+++ b/test/MSVS/vs-7.1-scc-legacy-files.py
@@ -33,20 +33,21 @@
import TestSConsMSVS
test = TestSConsMSVS.TestSConsMSVS()
+host_arch = test.get_vs_host_arch()
# Make the test infrastructure think we have this version of MSVS installed.
test._msvs_versions = ['7.1']
-
-
expected_slnfile = TestSConsMSVS.expected_slnfile_7_1
expected_vcprojfile = TestSConsMSVS.expected_vcprojfile_7_1
SConscript_contents = """\
-env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='7.1',
+env=Environment(tools=['msvs'],
+ MSVS_VERSION='7.1',
CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
CPPPATH=['inc1', 'inc2'],
MSVS_SCC_LOCAL_PATH=r'C:\\MyMsVsProjects',
- MSVS_SCC_PROJECT_NAME='Perforce Project')
+ MSVS_SCC_PROJECT_NAME='Perforce Project',
+ HOST_ARCH='%(HOST_ARCH)s')
testsrc = ['test1.cpp', 'test2.cpp']
testincs = ['sdk.h']
@@ -55,6 +56,7 @@
testmisc = ['readme.txt']
env.MSVSProject(target = 'Test.vcproj',
+ MSVS_PROJECT_GUID='%(PROJECT_GUID)s',
slnguid = '{SLNGUID}',
srcs = testsrc,
incs = testincs,
@@ -63,14 +65,13 @@
misc = testmisc,
buildtarget = 'Test.exe',
variant = 'Release')
-"""
+""" % {'HOST_ARCH':host_arch, 'PROJECT_GUID': TestSConsMSVS.PROJECT_GUID}
expected_vcproj_sccinfo = """\
\tSccProjectName="Perforce Project"
\tSccLocalPath="C:\\MyMsVsProjects"
"""
-
test.write('SConstruct', SConscript_contents)
test.run(arguments="Test.vcproj")
@@ -88,7 +89,6 @@
# don't compare the pickled data
assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
-
test.pass_test()
# Local Variables:
diff --git a/test/MSVS/vs-7.1-variant_dir.py b/test/MSVS/vs-7.1-variant_dir.py
index 64467def53..df337ae41e 100644
--- a/test/MSVS/vs-7.1-variant_dir.py
+++ b/test/MSVS/vs-7.1-variant_dir.py
@@ -33,40 +33,33 @@
test = TestSConsMSVS.TestSConsMSVS()
host_arch = test.get_vs_host_arch()
-
+sconscript_dict = {'HOST_ARCH': host_arch, 'PROJECT_GUID': TestSConsMSVS.PROJECT_GUID}
# Make the test infrastructure think we have this version of MSVS installed.
test._msvs_versions = ['7.1']
-
-
expected_slnfile = TestSConsMSVS.expected_slnfile_7_1
expected_vcprojfile = TestSConsMSVS.expected_vcprojfile_7_1
SConscript_contents = TestSConsMSVS.SConscript_contents_7_1
-
-
test.subdir('src')
test.write('SConstruct', """\
SConscript('src/SConscript', variant_dir='build')
""")
-test.write(['src', 'SConscript'], SConscript_contents%{'HOST_ARCH': host_arch})
+test.write(['src', 'SConscript'], SConscript_contents % sconscript_dict)
test.run(arguments=".")
-project_guid = "{CB4637F1-2205-50B7-B115-DCFA0DA68FB1}"
vcproj = test.read(['src', 'Test.vcproj'], 'r')
-expect = test.msvs_substitute(expected_vcprojfile, '7.0', None, 'SConstruct',
- project_guid=project_guid)
+expect = test.msvs_substitute(expected_vcprojfile, '7.0', None, 'SConstruct')
# don't compare the pickled data
assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
test.must_exist(test.workpath('src', 'Test.sln'))
sln = test.read(['src', 'Test.sln'], 'r')
-expect = test.msvs_substitute(expected_slnfile, '7.0', 'src',
- project_guid=project_guid)
+expect = test.msvs_substitute(expected_slnfile, '7.0', 'src')
# don't compare the pickled data
assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
@@ -84,8 +77,6 @@
""" % test.workpath('src', 'Test.sln'),
mode='r')
-
-
test.pass_test()
# Local Variables:
diff --git a/test/MSVS/vs-files.py b/test/MSVS/vs-files.py
index b330ce726f..54933565e4 100644
--- a/test/MSVS/vs-files.py
+++ b/test/MSVS/vs-files.py
@@ -33,6 +33,8 @@
import TestSConsMSVS
+test = None
+
for vc_version in TestSConsMSVS.get_tested_proj_file_vc_versions():
test = TestSConsMSVS.TestSConsMSVS()
host_arch = test.get_vs_host_arch()
@@ -103,6 +105,9 @@
# don't compare the pickled data
assert vcxproj[:len(expect)] == expect, test.diff_substr(expect, vcxproj)
+ del os.environ['PYTHON_ROOT']
+
+if test:
test.pass_test()
# Local Variables:
diff --git a/test/MSVS/vs-mult-auto-guid.py b/test/MSVS/vs-mult-auto-guid.py
new file mode 100644
index 0000000000..412c379ab7
--- /dev/null
+++ b/test/MSVS/vs-mult-auto-guid.py
@@ -0,0 +1,166 @@
+#!/usr/bin/env python
+#
+# MIT License
+#
+# Copyright The SCons Foundation
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+"""
+Test two project files (.vcxproj) and three solution (.sln) file.
+"""
+
+import TestSConsMSVS
+
+test = None
+
+for vc_version in TestSConsMSVS.get_tested_proj_file_vc_versions():
+
+ for autofilter_projects in (None, False, True):
+
+ test = TestSConsMSVS.TestSConsMSVS()
+
+ # Make the test infrastructure think we have this version of MSVS installed.
+ test._msvs_versions = [vc_version]
+
+ dirs = ['inc1', 'inc2']
+ major, minor = test.parse_vc_version(vc_version)
+ project_ext = '.vcproj' if major <= 9 else '.vcxproj'
+
+ project_file_1 = 'Test_1' + project_ext
+ project_file_2 = 'Test_2' + project_ext
+
+ filters_file_1 = project_file_1 + '.filters'
+ filters_file_2 = project_file_2 + '.filters'
+ filters_file_expected = major >= 10
+
+ solution_file = 'Test.sln'
+ solution_file_1 = 'Test_1.sln'
+ solution_file_2 = 'Test_2.sln'
+
+ if major >= 10:
+ project_guid_1 = "{F7D7CE55-37BF-51DE-8942-9377B2BE8387}"
+ project_guid_2 = "{8D17BC73-09FD-5B69-BBBF-1E40E0C63456}"
+ else:
+ project_guid_1 = "{53EE9FA7-6300-55B8-8A0E-A3DC40983390}"
+ project_guid_2 = "{57358E9B-126D-53F6-AD5A-559AB4A8EE62}"
+
+ if major >= 10:
+ solution_guid_1 = "{73ABD7C4-0A64-5192-97C3-252B70C8D1B1}"
+ solution_guid_2 = "{142F0D4F-9896-5808-AAB4-A80F5661B1FE}"
+ else:
+ solution_guid_1 = "{73ABD7C4-0A64-5192-97C3-252B70C8D1B1}"
+ solution_guid_2 = "{142F0D4F-9896-5808-AAB4-A80F5661B1FE}"
+
+ expected_vcprojfile_1 = test.get_expected_projects_proj_file_contents(
+ vc_version, dirs, project_file_1, project_guid_1,
+ )
+
+ expected_vcprojfile_2 = test.get_expected_projects_proj_file_contents(
+ vc_version, dirs, project_file_2, project_guid_2,
+ )
+
+ expected_slnfile = test.get_expected_projects_sln_file_contents(
+ vc_version,
+ project_file_1,
+ project_file_2,
+ have_solution_project_nodes=True,
+ autofilter_solution_project_nodes=autofilter_projects,
+ )
+
+ expected_slnfile_1 = test.get_expected_sln_file_contents(
+ vc_version,
+ project_file_1,
+ )
+
+ expected_slnfile_2 = test.get_expected_sln_file_contents(
+ vc_version,
+ project_file_2,
+ )
+
+ SConstruct_contents = test.get_expected_projects_sconscript_file_contents(
+ vc_version=vc_version,
+ project_file_1=project_file_1,
+ project_file_2=project_file_2,
+ solution_file=solution_file,
+ autobuild_solution=1,
+ autofilter_projects=autofilter_projects,
+ default_guids=True,
+ )
+
+ test.write('SConstruct', SConstruct_contents)
+
+ if autofilter_projects is None:
+ test.run(arguments=".", status=2, stderr=r"^.*scons: [*]{3} An msvs solution file was detected in the MSVSSolution 'projects' argument:.+", match=test.match_re_dotall)
+ continue
+
+ test.run(arguments=".")
+
+ test.must_exist(test.workpath(project_file_1))
+ vcproj = test.read(project_file_1, 'r')
+ expect = test.msvs_substitute(expected_vcprojfile_1, vc_version, None, 'SConstruct', project_guid=project_guid_1)
+ # don't compare the pickled data
+ assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
+
+ test.must_exist(test.workpath(project_file_2))
+ vcproj = test.read(project_file_2, 'r')
+ expect = test.msvs_substitute(expected_vcprojfile_2, vc_version, None, 'SConstruct', project_guid=project_guid_2)
+ # don't compare the pickled data
+ assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
+
+ test.must_exist(test.workpath(solution_file))
+ sln = test.read(solution_file, 'r')
+ expect = test.msvs_substitute_projects(
+ expected_slnfile, subdir='src',
+ project_guid_1=project_guid_1, project_guid_2=project_guid_2,
+ solution_guid_1=solution_guid_1, solution_guid_2=solution_guid_2,
+ )
+ # don't compare the pickled data
+ assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
+
+ test.must_exist(test.workpath(solution_file_1))
+ sln = test.read(solution_file_1, 'r')
+ expect = test.msvs_substitute(expected_slnfile_1, vc_version, subdir='src', project_guid=project_guid_1)
+ # don't compare the pickled data
+ assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
+
+ test.must_exist(test.workpath(solution_file_2))
+ sln = test.read(solution_file_2, 'r')
+ expect = test.msvs_substitute(expected_slnfile_2, vc_version, subdir='src', project_guid=project_guid_2)
+ # don't compare the pickled data
+ assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
+
+ if filters_file_expected:
+ test.must_exist(test.workpath(filters_file_1))
+ test.must_exist(test.workpath(filters_file_2))
+ else:
+ test.must_not_exist(test.workpath(filters_file_1))
+ test.must_not_exist(test.workpath(filters_file_2))
+
+ # TODO: clean tests
+
+if test:
+ test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/MSVS/vs-mult-auto-vardir-guid.py b/test/MSVS/vs-mult-auto-vardir-guid.py
new file mode 100644
index 0000000000..87d233220b
--- /dev/null
+++ b/test/MSVS/vs-mult-auto-vardir-guid.py
@@ -0,0 +1,202 @@
+#!/usr/bin/env python
+#
+# MIT License
+#
+# Copyright The SCons Foundation
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+"""
+Test two project files (.vcxproj) and three solution (.sln) file.
+"""
+
+import TestSConsMSVS
+
+test = None
+
+for vc_version in TestSConsMSVS.get_tested_proj_file_vc_versions():
+
+ for autofilter_projects in (None, False, True):
+
+ test = TestSConsMSVS.TestSConsMSVS()
+
+ # Make the test infrastructure think we have this version of MSVS installed.
+ test._msvs_versions = [vc_version]
+
+ dirs = ['inc1', 'inc2']
+ major, minor = test.parse_vc_version(vc_version)
+ project_ext = '.vcproj' if major <= 9 else '.vcxproj'
+
+ project_file_1 = 'Test_1' + project_ext
+ project_file_2 = 'Test_2' + project_ext
+
+ filters_file_1 = project_file_1 + '.filters'
+ filters_file_2 = project_file_2 + '.filters'
+ filters_file_expected = major >= 10
+
+ solution_file = 'Test.sln'
+ solution_file_1 = 'Test_1.sln'
+ solution_file_2 = 'Test_2.sln'
+
+ if major >= 10:
+ project_guid_1 = "{5A243E49-07F0-54C3-B3FD-1DBDF1BA5C9E}"
+ project_guid_2 = "{E20E17C7-251E-5246-8FD1-5D51978A0A5D}"
+ else:
+ project_guid_1 = "{AB46DD68-8CD8-5832-B784-65B216B94739}"
+ project_guid_2 = "{03EB0BC3-DA68-5825-9EBB-D8713304E739}"
+
+ if major >= 10:
+ solution_guid_1 = "{5E5E4F5D-3E6A-5958-81C6-D4B8B8C633FA}"
+ solution_guid_2 = "{ECBCA12A-191D-54EC-BA78-F14249171130}"
+ else:
+ solution_guid_1 = "{5E5E4F5D-3E6A-5958-81C6-D4B8B8C633FA}"
+ solution_guid_2 = "{ECBCA12A-191D-54EC-BA78-F14249171130}"
+
+ expected_vcprojfile_1 = test.get_expected_projects_proj_file_contents(
+ vc_version, dirs, project_file_1, project_guid_1,
+ )
+
+ expected_vcprojfile_2 = test.get_expected_projects_proj_file_contents(
+ vc_version, dirs, project_file_2, project_guid_2,
+ )
+
+ expected_slnfile = test.get_expected_projects_sln_file_contents(
+ vc_version,
+ project_file_1,
+ project_file_2,
+ have_solution_project_nodes=True,
+ autofilter_solution_project_nodes=autofilter_projects,
+ )
+
+ expected_slnfile_1 = test.get_expected_sln_file_contents(
+ vc_version,
+ project_file_1,
+ )
+
+ expected_slnfile_2 = test.get_expected_sln_file_contents(
+ vc_version,
+ project_file_2,
+ )
+
+ SConscript_contents = test.get_expected_projects_sconscript_file_contents(
+ vc_version=vc_version,
+ project_file_1=project_file_1,
+ project_file_2=project_file_2,
+ solution_file=solution_file,
+ autobuild_solution=1,
+ autofilter_projects=autofilter_projects,
+ default_guids=True,
+ )
+
+ test.subdir('src')
+
+ test.write('SConstruct', """\
+SConscript('src/SConscript', variant_dir='build')
+""")
+
+ test.write(['src', 'SConscript'], SConscript_contents)
+
+ if autofilter_projects is None:
+ test.run(arguments=".", status=2, stderr=r"^.*scons: [*]{3} An msvs solution file was detected in the MSVSSolution 'projects' argument:.+", match=test.match_re_dotall)
+ continue
+
+ test.run(arguments=".")
+
+ test.must_exist(test.workpath('src', project_file_1))
+ vcproj = test.read(['src', project_file_1], 'r')
+ expect = test.msvs_substitute(expected_vcprojfile_1, vc_version, None, 'SConstruct', project_guid=project_guid_1)
+ # don't compare the pickled data
+ assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
+
+ test.must_exist(test.workpath('src', project_file_2))
+ vcproj = test.read(['src', project_file_2], 'r')
+ expect = test.msvs_substitute(expected_vcprojfile_2, vc_version, None, 'SConstruct', project_guid=project_guid_2)
+ # don't compare the pickled data
+ assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
+
+ test.must_exist(test.workpath('src', solution_file))
+ sln = test.read(['src', solution_file], 'r')
+ expect = test.msvs_substitute_projects(
+ expected_slnfile, subdir='src',
+ project_guid_1=project_guid_1, project_guid_2=project_guid_2,
+ solution_guid_1=solution_guid_1, solution_guid_2=solution_guid_2,
+ )
+ # don't compare the pickled data
+ assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
+
+ test.must_exist(test.workpath('src', solution_file_1))
+ sln = test.read(['src', solution_file_1], 'r')
+ expect = test.msvs_substitute(expected_slnfile_1, vc_version, subdir='src', project_guid=project_guid_1)
+ # don't compare the pickled data
+ assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
+
+ test.must_exist(test.workpath('src', solution_file_2))
+ sln = test.read(['src', solution_file_2], 'r')
+ expect = test.msvs_substitute(expected_slnfile_2, vc_version, subdir='src', project_guid=project_guid_2)
+ # don't compare the pickled data
+ assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
+
+ if filters_file_expected:
+ test.must_exist(test.workpath('src', filters_file_1))
+ test.must_exist(test.workpath('src', filters_file_2))
+ else:
+ test.must_not_exist(test.workpath('src', filters_file_1))
+ test.must_not_exist(test.workpath('src', filters_file_2))
+
+ test.must_match(['build', project_file_1], """\
+This is just a placeholder file.
+The real project file is here:
+%s
+""" % test.workpath('src', project_file_1), mode='r')
+
+ test.must_match(['build', project_file_2], """\
+This is just a placeholder file.
+The real project file is here:
+%s
+""" % test.workpath('src', project_file_2), mode='r')
+
+ test.must_match(['build', solution_file], """\
+This is just a placeholder file.
+The real workspace file is here:
+%s
+""" % test.workpath('src', solution_file), mode='r')
+
+ test.must_match(['build', solution_file_1], """\
+This is just a placeholder file.
+The real workspace file is here:
+%s
+""" % test.workpath('src', solution_file_1), mode='r')
+
+ test.must_match(['build', solution_file_2], """\
+This is just a placeholder file.
+The real workspace file is here:
+%s
+""" % test.workpath('src', solution_file_2), mode='r')
+
+ # TODO: clean tests
+
+if test:
+ test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/MSVS/vs-mult-auto-vardir.py b/test/MSVS/vs-mult-auto-vardir.py
new file mode 100644
index 0000000000..b4d2109312
--- /dev/null
+++ b/test/MSVS/vs-mult-auto-vardir.py
@@ -0,0 +1,196 @@
+#!/usr/bin/env python
+#
+# MIT License
+#
+# Copyright The SCons Foundation
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+"""
+Test two project files (.vcxproj) and three solution (.sln) file.
+"""
+
+import TestSConsMSVS
+
+project_guid_1 = TestSConsMSVS.PROJECT_GUID_1
+project_guid_2 = TestSConsMSVS.PROJECT_GUID_2
+
+test = None
+
+for vc_version in TestSConsMSVS.get_tested_proj_file_vc_versions():
+
+ for autofilter_projects in (None, False, True):
+
+ test = TestSConsMSVS.TestSConsMSVS()
+
+ # Make the test infrastructure think we have this version of MSVS installed.
+ test._msvs_versions = [vc_version]
+
+ dirs = ['inc1', 'inc2']
+ major, minor = test.parse_vc_version(vc_version)
+ project_ext = '.vcproj' if major <= 9 else '.vcxproj'
+
+ project_file_1 = 'Test_1' + project_ext
+ project_file_2 = 'Test_2' + project_ext
+
+ filters_file_1 = project_file_1 + '.filters'
+ filters_file_2 = project_file_2 + '.filters'
+ filters_file_expected = major >= 10
+
+ solution_file = 'Test.sln'
+ solution_file_1 = 'Test_1.sln'
+ solution_file_2 = 'Test_2.sln'
+
+ if major >= 10:
+ solution_guid_1 = "{5E5E4F5D-3E6A-5958-81C6-D4B8B8C633FA}"
+ solution_guid_2 = "{ECBCA12A-191D-54EC-BA78-F14249171130}"
+ else:
+ solution_guid_1 = "{5E5E4F5D-3E6A-5958-81C6-D4B8B8C633FA}"
+ solution_guid_2 = "{ECBCA12A-191D-54EC-BA78-F14249171130}"
+
+ expected_vcprojfile_1 = test.get_expected_projects_proj_file_contents(
+ vc_version, dirs, project_file_1, project_guid_1,
+ )
+
+ expected_vcprojfile_2 = test.get_expected_projects_proj_file_contents(
+ vc_version, dirs, project_file_2, project_guid_2,
+ )
+
+ expected_slnfile = test.get_expected_projects_sln_file_contents(
+ vc_version,
+ project_file_1,
+ project_file_2,
+ have_solution_project_nodes=True,
+ autofilter_solution_project_nodes=autofilter_projects,
+ )
+
+ expected_slnfile_1 = test.get_expected_sln_file_contents(
+ vc_version,
+ project_file_1,
+ )
+
+ expected_slnfile_2 = test.get_expected_sln_file_contents(
+ vc_version,
+ project_file_2,
+ )
+
+ SConscript_contents = test.get_expected_projects_sconscript_file_contents(
+ vc_version=vc_version,
+ project_file_1=project_file_1,
+ project_file_2=project_file_2,
+ solution_file=solution_file,
+ autobuild_solution=1,
+ autofilter_projects=autofilter_projects,
+ )
+
+ test.subdir('src')
+
+ test.write('SConstruct', """\
+SConscript('src/SConscript', variant_dir='build')
+""")
+
+ test.write(['src', 'SConscript'], SConscript_contents)
+
+ if autofilter_projects is None:
+ test.run(arguments=".", status=2, stderr=r"^.*scons: [*]{3} An msvs solution file was detected in the MSVSSolution 'projects' argument:.+", match=test.match_re_dotall)
+ continue
+
+ test.run(arguments=".")
+
+ test.must_exist(test.workpath('src', project_file_1))
+ vcproj = test.read(['src', project_file_1], 'r')
+ expect = test.msvs_substitute(expected_vcprojfile_1, vc_version, None, 'SConstruct', project_guid=project_guid_1)
+ # don't compare the pickled data
+ assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
+
+ test.must_exist(test.workpath('src', project_file_2))
+ vcproj = test.read(['src', project_file_2], 'r')
+ expect = test.msvs_substitute(expected_vcprojfile_2, vc_version, None, 'SConstruct', project_guid=project_guid_2)
+ # don't compare the pickled data
+ assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
+
+ test.must_exist(test.workpath('src', solution_file))
+ sln = test.read(['src', solution_file], 'r')
+ expect = test.msvs_substitute_projects(
+ expected_slnfile, subdir='src',
+ solution_guid_1=solution_guid_1, solution_guid_2=solution_guid_2,
+ )
+ # don't compare the pickled data
+ assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
+
+ test.must_exist(test.workpath('src', solution_file_1))
+ sln = test.read(['src', solution_file_1], 'r')
+ expect = test.msvs_substitute(expected_slnfile_1, vc_version, subdir='src', project_guid=project_guid_1)
+ # don't compare the pickled data
+ assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
+
+ test.must_exist(test.workpath('src', solution_file_2))
+ sln = test.read(['src', solution_file_2], 'r')
+ expect = test.msvs_substitute(expected_slnfile_2, vc_version, subdir='src', project_guid=project_guid_2)
+ # don't compare the pickled data
+ assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
+
+ if filters_file_expected:
+ test.must_exist(test.workpath('src', filters_file_1))
+ test.must_exist(test.workpath('src', filters_file_2))
+ else:
+ test.must_not_exist(test.workpath('src', filters_file_1))
+ test.must_not_exist(test.workpath('src', filters_file_2))
+
+ test.must_match(['build', project_file_1], """\
+This is just a placeholder file.
+The real project file is here:
+%s
+""" % test.workpath('src', project_file_1), mode='r')
+
+ test.must_match(['build', project_file_2], """\
+This is just a placeholder file.
+The real project file is here:
+%s
+""" % test.workpath('src', project_file_2), mode='r')
+
+ test.must_match(['build', solution_file], """\
+This is just a placeholder file.
+The real workspace file is here:
+%s
+""" % test.workpath('src', solution_file), mode='r')
+
+ test.must_match(['build', solution_file_1], """\
+This is just a placeholder file.
+The real workspace file is here:
+%s
+""" % test.workpath('src', solution_file_1), mode='r')
+
+ test.must_match(['build', solution_file_2], """\
+This is just a placeholder file.
+The real workspace file is here:
+%s
+""" % test.workpath('src', solution_file_2), mode='r')
+
+ # TODO: clean tests
+
+if test:
+ test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/MSVS/vs-mult-auto.py b/test/MSVS/vs-mult-auto.py
new file mode 100644
index 0000000000..57f1145fd1
--- /dev/null
+++ b/test/MSVS/vs-mult-auto.py
@@ -0,0 +1,160 @@
+#!/usr/bin/env python
+#
+# MIT License
+#
+# Copyright The SCons Foundation
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+"""
+Test two project files (.vcxproj) and three solution (.sln) file.
+"""
+
+import TestSConsMSVS
+
+project_guid_1 = TestSConsMSVS.PROJECT_GUID_1
+project_guid_2 = TestSConsMSVS.PROJECT_GUID_2
+
+test = None
+
+for vc_version in TestSConsMSVS.get_tested_proj_file_vc_versions():
+
+ for autofilter_projects in (None, False, True):
+
+ test = TestSConsMSVS.TestSConsMSVS()
+
+ # Make the test infrastructure think we have this version of MSVS installed.
+ test._msvs_versions = [vc_version]
+
+ dirs = ['inc1', 'inc2']
+ major, minor = test.parse_vc_version(vc_version)
+ project_ext = '.vcproj' if major <= 9 else '.vcxproj'
+
+ project_file_1 = 'Test_1' + project_ext
+ project_file_2 = 'Test_2' + project_ext
+
+ filters_file_1 = project_file_1 + '.filters'
+ filters_file_2 = project_file_2 + '.filters'
+ filters_file_expected = major >= 10
+
+ solution_file = 'Test.sln'
+ solution_file_1 = 'Test_1.sln'
+ solution_file_2 = 'Test_2.sln'
+
+ if major >= 10:
+ solution_guid_1 = "{73ABD7C4-0A64-5192-97C3-252B70C8D1B1}"
+ solution_guid_2 = "{142F0D4F-9896-5808-AAB4-A80F5661B1FE}"
+ else:
+ solution_guid_1 = "{73ABD7C4-0A64-5192-97C3-252B70C8D1B1}"
+ solution_guid_2 = "{142F0D4F-9896-5808-AAB4-A80F5661B1FE}"
+
+ expected_vcprojfile_1 = test.get_expected_projects_proj_file_contents(
+ vc_version, dirs, project_file_1, project_guid_1,
+ )
+
+ expected_vcprojfile_2 = test.get_expected_projects_proj_file_contents(
+ vc_version, dirs, project_file_2, project_guid_2,
+ )
+
+ expected_slnfile = test.get_expected_projects_sln_file_contents(
+ vc_version,
+ project_file_1,
+ project_file_2,
+ have_solution_project_nodes=True,
+ autofilter_solution_project_nodes=autofilter_projects,
+ )
+
+ expected_slnfile_1 = test.get_expected_sln_file_contents(
+ vc_version,
+ project_file_1,
+ )
+
+ expected_slnfile_2 = test.get_expected_sln_file_contents(
+ vc_version,
+ project_file_2,
+ )
+
+ SConstruct_contents = test.get_expected_projects_sconscript_file_contents(
+ vc_version=vc_version,
+ project_file_1=project_file_1,
+ project_file_2=project_file_2,
+ solution_file=solution_file,
+ autobuild_solution=1,
+ autofilter_projects=autofilter_projects,
+ )
+
+ test.write('SConstruct', SConstruct_contents)
+
+ if autofilter_projects is None:
+ test.run(arguments=".", status=2, stderr=r"^.*scons: [*]{3} An msvs solution file was detected in the MSVSSolution 'projects' argument:.+", match=test.match_re_dotall)
+ continue
+
+ test.run(arguments=".")
+
+ test.must_exist(test.workpath(project_file_1))
+ vcproj = test.read(project_file_1, 'r')
+ expect = test.msvs_substitute(expected_vcprojfile_1, vc_version, None, 'SConstruct', project_guid=project_guid_1)
+ # don't compare the pickled data
+ assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
+
+ test.must_exist(test.workpath(project_file_2))
+ vcproj = test.read(project_file_2, 'r')
+ expect = test.msvs_substitute(expected_vcprojfile_2, vc_version, None, 'SConstruct', project_guid=project_guid_2)
+ # don't compare the pickled data
+ assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
+
+ test.must_exist(test.workpath(solution_file))
+ sln = test.read(solution_file, 'r')
+ expect = test.msvs_substitute_projects(
+ expected_slnfile, subdir='src',
+ solution_guid_1=solution_guid_1, solution_guid_2=solution_guid_2,
+ )
+ # don't compare the pickled data
+ assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
+
+ test.must_exist(test.workpath(solution_file_1))
+ sln = test.read(solution_file_1, 'r')
+ expect = test.msvs_substitute(expected_slnfile_1, vc_version, subdir='src', project_guid=project_guid_1)
+ # don't compare the pickled data
+ assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
+
+ test.must_exist(test.workpath(solution_file_2))
+ sln = test.read(solution_file_2, 'r')
+ expect = test.msvs_substitute(expected_slnfile_2, vc_version, subdir='src', project_guid=project_guid_2)
+ # don't compare the pickled data
+ assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
+
+ if filters_file_expected:
+ test.must_exist(test.workpath(filters_file_1))
+ test.must_exist(test.workpath(filters_file_2))
+ else:
+ test.must_not_exist(test.workpath(filters_file_1))
+ test.must_not_exist(test.workpath(filters_file_2))
+
+ # TODO: clean tests
+
+if test:
+ test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/MSVS/vs-mult-noauto-vardir.py b/test/MSVS/vs-mult-noauto-vardir.py
new file mode 100644
index 0000000000..18aacba887
--- /dev/null
+++ b/test/MSVS/vs-mult-noauto-vardir.py
@@ -0,0 +1,140 @@
+#!/usr/bin/env python
+#
+# MIT License
+#
+# Copyright The SCons Foundation
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+"""
+Test two project files (.vcxproj) and a solution (.sln) file.
+"""
+
+import TestSConsMSVS
+
+project_guid_1 = TestSConsMSVS.PROJECT_GUID_1
+project_guid_2 = TestSConsMSVS.PROJECT_GUID_2
+
+test = None
+
+for vc_version in TestSConsMSVS.get_tested_proj_file_vc_versions():
+ test = TestSConsMSVS.TestSConsMSVS()
+
+ # Make the test infrastructure think we have this version of MSVS installed.
+ test._msvs_versions = [vc_version]
+
+ dirs = ['inc1', 'inc2']
+ major, minor = test.parse_vc_version(vc_version)
+ project_ext = '.vcproj' if major <= 9 else '.vcxproj'
+
+ project_file_1 = 'Test_1' + project_ext
+ project_file_2 = 'Test_2' + project_ext
+
+ filters_file_1 = project_file_1 + '.filters'
+ filters_file_2 = project_file_2 + '.filters'
+ filters_file_expected = major >= 10
+
+ solution_file = 'Test.sln'
+
+ expected_vcprojfile_1 = test.get_expected_projects_proj_file_contents(
+ vc_version, dirs, project_file_1, project_guid_1,
+ )
+
+ expected_vcprojfile_2 = test.get_expected_projects_proj_file_contents(
+ vc_version, dirs, project_file_2, project_guid_2,
+ )
+
+ expected_slnfile = test.get_expected_projects_sln_file_contents(
+ vc_version,
+ project_file_1,
+ project_file_2,
+ )
+
+ SConscript_contents = test.get_expected_projects_sconscript_file_contents(
+ vc_version=vc_version,
+ project_file_1=project_file_1,
+ project_file_2=project_file_2,
+ solution_file=solution_file,
+ autobuild_solution=0,
+ )
+
+ test.subdir('src')
+
+ test.write('SConstruct', """\
+SConscript('src/SConscript', variant_dir='build')
+""")
+
+ test.write(['src', 'SConscript'], SConscript_contents)
+
+ test.run(arguments=".")
+
+ test.must_exist(test.workpath('src', project_file_1))
+ vcproj = test.read(['src', project_file_1], 'r')
+ expect = test.msvs_substitute(expected_vcprojfile_1, vc_version, None, 'SConstruct', project_guid=project_guid_1)
+ # don't compare the pickled data
+ assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
+
+ test.must_exist(test.workpath('src', project_file_2))
+ vcproj = test.read(['src', project_file_2], 'r')
+ expect = test.msvs_substitute(expected_vcprojfile_2, vc_version, None, 'SConstruct', project_guid=project_guid_2)
+ # don't compare the pickled data
+ assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
+
+ test.must_exist(test.workpath('src', solution_file))
+ sln = test.read(['src', solution_file], 'r')
+ expect = test.msvs_substitute_projects(expected_slnfile, subdir='src')
+ # don't compare the pickled data
+ assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
+
+ if filters_file_expected:
+ test.must_exist(test.workpath('src', filters_file_1))
+ test.must_exist(test.workpath('src', filters_file_2))
+ else:
+ test.must_not_exist(test.workpath('src', filters_file_1))
+ test.must_not_exist(test.workpath('src', filters_file_2))
+
+ test.must_match(['build', project_file_1], """\
+This is just a placeholder file.
+The real project file is here:
+%s
+""" % test.workpath('src', project_file_1), mode='r')
+
+ test.must_match(['build', project_file_2], """\
+This is just a placeholder file.
+The real project file is here:
+%s
+""" % test.workpath('src', project_file_2), mode='r')
+
+ test.must_match(['build', solution_file], """\
+This is just a placeholder file.
+The real workspace file is here:
+%s
+""" % test.workpath('src', solution_file), mode='r')
+
+ # TODO: clean tests
+
+if test:
+ test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/MSVS/vs-mult-noauto.py b/test/MSVS/vs-mult-noauto.py
new file mode 100644
index 0000000000..ab0bb6dc62
--- /dev/null
+++ b/test/MSVS/vs-mult-noauto.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python
+#
+# MIT License
+#
+# Copyright The SCons Foundation
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+"""
+Test two project files (.vcxproj) and a solution (.sln) file.
+"""
+
+import TestSConsMSVS
+
+project_guid_1 = TestSConsMSVS.PROJECT_GUID_1
+project_guid_2 = TestSConsMSVS.PROJECT_GUID_2
+
+test = None
+
+for vc_version in TestSConsMSVS.get_tested_proj_file_vc_versions():
+ test = TestSConsMSVS.TestSConsMSVS()
+
+ # Make the test infrastructure think we have this version of MSVS installed.
+ test._msvs_versions = [vc_version]
+
+ dirs = ['inc1', 'inc2']
+ major, minor = test.parse_vc_version(vc_version)
+ project_ext = '.vcproj' if major <= 9 else '.vcxproj'
+
+ project_file_1 = 'Test_1' + project_ext
+ project_file_2 = 'Test_2' + project_ext
+
+ filters_file_1 = project_file_1 + '.filters'
+ filters_file_2 = project_file_2 + '.filters'
+ filters_file_expected = major >= 10
+
+ solution_file = 'Test.sln'
+
+ expected_vcprojfile_1 = test.get_expected_projects_proj_file_contents(
+ vc_version, dirs, project_file_1, project_guid_1,
+ )
+
+ expected_vcprojfile_2 = test.get_expected_projects_proj_file_contents(
+ vc_version, dirs, project_file_2, project_guid_2,
+ )
+
+ expected_slnfile = test.get_expected_projects_sln_file_contents(
+ vc_version,
+ project_file_1,
+ project_file_2,
+ )
+
+ SConstruct_contents = test.get_expected_projects_sconscript_file_contents(
+ vc_version=vc_version,
+ project_file_1=project_file_1,
+ project_file_2=project_file_2,
+ solution_file=solution_file,
+ autobuild_solution=0,
+ )
+
+ test.write('SConstruct', SConstruct_contents)
+
+ test.run(arguments=".")
+
+ test.must_exist(test.workpath(project_file_1))
+ vcproj = test.read(project_file_1, 'r')
+ expect = test.msvs_substitute(expected_vcprojfile_1, vc_version, None, 'SConstruct', project_guid=project_guid_1)
+ # don't compare the pickled data
+ assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
+
+ test.must_exist(test.workpath(project_file_2))
+ vcproj = test.read(project_file_2, 'r')
+ expect = test.msvs_substitute(expected_vcprojfile_2, vc_version, None, 'SConstruct', project_guid=project_guid_2)
+ # don't compare the pickled data
+ assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
+
+ test.must_exist(test.workpath(solution_file))
+ sln = test.read(solution_file, 'r')
+ expect = test.msvs_substitute_projects(expected_slnfile, subdir='src')
+ # don't compare the pickled data
+ assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
+
+ if filters_file_expected:
+ test.must_exist(test.workpath(filters_file_1))
+ test.must_exist(test.workpath(filters_file_2))
+ else:
+ test.must_not_exist(test.workpath(filters_file_1))
+ test.must_not_exist(test.workpath(filters_file_2))
+
+ # TODO: clean tests
+
+if test:
+ test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/MSVS/vs-scc-files.py b/test/MSVS/vs-scc-files.py
index 85fa27c392..4e79e274f5 100644
--- a/test/MSVS/vs-scc-files.py
+++ b/test/MSVS/vs-scc-files.py
@@ -31,8 +31,11 @@
import TestSConsMSVS
+test = None
+
for vc_version in TestSConsMSVS.get_tested_proj_file_vc_versions():
test = TestSConsMSVS.TestSConsMSVS()
+ host_arch = test.get_vs_host_arch()
# Make the test infrastructure think we have this version of MSVS installed.
test._msvs_versions = [vc_version]
@@ -45,12 +48,14 @@
expected_slnfile = test.get_expected_sln_file_contents(vc_version, project_file)
expected_vcprojfile = test.get_expected_proj_file_contents(vc_version, dirs, project_file)
SConscript_contents = """\
-env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='{vc_version}',
+env=Environment(tools=['msvs'],
+ MSVS_VERSION='{vc_version}',
CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
CPPPATH=['inc1', 'inc2'],
MSVS_SCC_CONNECTION_ROOT='.',
MSVS_SCC_PROVIDER='MSSCCI:Perforce SCM',
- MSVS_SCC_PROJECT_NAME='Perforce Project')
+ MSVS_SCC_PROJECT_NAME='Perforce Project',
+ HOST_ARCH='{host_arch}')
testsrc = ['test1.cpp', 'test2.cpp']
testincs = [r'sdk_dir\\sdk.h']
@@ -59,6 +64,7 @@
testmisc = ['readme.txt']
env.MSVSProject(target = '{project_file}',
+ MSVS_PROJECT_GUID='{project_guid}',
srcs = testsrc,
incs = testincs,
localincs = testlocalincs,
@@ -66,7 +72,10 @@
misc = testmisc,
buildtarget = 'Test.exe',
variant = 'Release')
-""".format(vc_version=vc_version, project_file=project_file)
+""".format(
+ vc_version=vc_version, project_file=project_file,
+ host_arch=host_arch, project_guid=TestSConsMSVS.PROJECT_GUID,
+)
expected_sln_sccinfo = """\
\tGlobalSection(SourceCodeControl) = preSolution
@@ -97,7 +106,6 @@
\t\tMSSCCI:Perforce SCM
"""
-
test.write('SConstruct', SConscript_contents)
test.run(arguments=project_file)
@@ -116,7 +124,7 @@
# don't compare the pickled data
assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
-
+if test:
test.pass_test()
# Local Variables:
diff --git a/test/MSVS/vs-scc-legacy-files.py b/test/MSVS/vs-scc-legacy-files.py
index 8e2ca15cc7..9943d3d7ce 100644
--- a/test/MSVS/vs-scc-legacy-files.py
+++ b/test/MSVS/vs-scc-legacy-files.py
@@ -31,8 +31,11 @@
import TestSConsMSVS
+test = None
+
for vc_version in TestSConsMSVS.get_tested_proj_file_vc_versions():
test = TestSConsMSVS.TestSConsMSVS()
+ host_arch = test.get_vs_host_arch()
# Make the test infrastructure think we have this version of MSVS installed.
test._msvs_versions = [vc_version]
@@ -46,11 +49,13 @@
expected_vcprojfile = test.get_expected_proj_file_contents(vc_version, dirs, project_file)
SConscript_contents = """\
-env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='{vc_version}',
+env=Environment(tools=['msvs'],
+ MSVS_VERSION='{vc_version}',
CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
CPPPATH=['inc1', 'inc2'],
MSVS_SCC_LOCAL_PATH=r'C:\\MyMsVsProjects',
- MSVS_SCC_PROJECT_NAME='Perforce Project')
+ MSVS_SCC_PROJECT_NAME='Perforce Project',
+ HOST_ARCH='{host_arch}')
testsrc = ['test1.cpp', 'test2.cpp']
testincs = [r'sdk_dir\\sdk.h']
@@ -59,6 +64,7 @@
testmisc = ['readme.txt']
env.MSVSProject(target = '{project_file}',
+ MSVS_PROJECT_GUID='{project_guid}',
srcs = testsrc,
incs = testincs,
localincs = testlocalincs,
@@ -66,7 +72,10 @@
misc = testmisc,
buildtarget = 'Test.exe',
variant = 'Release')
-""".format(vc_version=vc_version, project_file=project_file)
+""".format(
+ vc_version=vc_version, project_file=project_file,
+ host_arch=host_arch, project_guid=TestSConsMSVS.PROJECT_GUID,
+)
if major < 10:
# VC8 and VC9 used key-value pair format.
@@ -98,7 +107,7 @@
# don't compare the pickled data
assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
-
+if test:
test.pass_test()
# Local Variables:
diff --git a/test/MSVS/vs-variant_dir.py b/test/MSVS/vs-variant_dir.py
index 7d4b9cbf3e..880a36edac 100644
--- a/test/MSVS/vs-variant_dir.py
+++ b/test/MSVS/vs-variant_dir.py
@@ -31,6 +31,8 @@
import TestSConsMSVS
+test = None
+
for vc_version in TestSConsMSVS.get_tested_proj_file_vc_versions():
test = TestSConsMSVS.TestSConsMSVS()
host_arch = test.get_vs_host_arch()
@@ -58,21 +60,18 @@
test.run(arguments=".")
- project_guid = "{CB4637F1-2205-50B7-B115-DCFA0DA68FB1}"
vcproj = test.read(['src', project_file], 'r')
- expect = test.msvs_substitute(expected_vcprojfile, vc_version, None, 'SConstruct',
- project_guid=project_guid)
+ expect = test.msvs_substitute(expected_vcprojfile, vc_version, None, 'SConstruct')
# don't compare the pickled data
assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
test.must_exist(test.workpath('src', 'Test.sln'))
sln = test.read(['src', 'Test.sln'], 'r')
- expect = test.msvs_substitute(expected_slnfile, '8.0', 'src',
- project_guid=project_guid)
+ expect = test.msvs_substitute(expected_slnfile, '8.0', 'src')
# don't compare the pickled data
assert sln[:len(expect)] == expect, test.diff_substr(expect, sln)
- test.must_match(['build', 'Test.vcproj'], """\
+ test.must_match(['build', project_file], """\
This is just a placeholder file.
The real project file is here:
%s
@@ -84,6 +83,7 @@
%s
""" % test.workpath('src', 'Test.sln'), mode='r')
+if test:
test.pass_test()
# Local Variables:
diff --git a/testing/framework/TestSConsMSVS.py b/testing/framework/TestSConsMSVS.py
index 91aa329d66..0951b4626a 100644
--- a/testing/framework/TestSConsMSVS.py
+++ b/testing/framework/TestSConsMSVS.py
@@ -50,6 +50,13 @@
from TestSCons import __all__
+PROJECT_GUID = "{00000000-0000-0000-0000-000000000000}"
+PROJECT_GUID_1 = "{11111111-1111-1111-1111-111111111111}"
+PROJECT_GUID_2 = "{22222222-2222-2222-2222-222222222222}"
+
+SOLUTION_GUID_1 = "{88888888-8888-8888-8888-888888888888}"
+SOLUTION_GUID_2 = "{99999999-9999-9999-9999-999999999999}"
+
expected_dspfile_6_0 = '''\
# Microsoft Developer Studio Project File - Name="Test" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
@@ -189,8 +196,9 @@
'''
SConscript_contents_6_0 = """\
-env=Environment(platform='win32', tools=['msvs'],
- MSVS_VERSION='6.0',HOST_ARCH='%(HOST_ARCH)s')
+env=Environment(tools=['msvs'],
+ MSVS_VERSION='6.0',
+ HOST_ARCH='%(HOST_ARCH)s')
testsrc = ['test.c']
testincs = ['sdk.h']
@@ -310,8 +318,9 @@
"""
SConscript_contents_7_0 = """\
-env=Environment(platform='win32', tools=['msvs'],
- MSVS_VERSION='7.0',HOST_ARCH='%(HOST_ARCH)s')
+env=Environment(tools=['msvs'],
+ MSVS_VERSION='7.0',
+ HOST_ARCH='%(HOST_ARCH)s')
testsrc = ['test1.cpp', 'test2.cpp']
testincs = ['sdk.h']
@@ -320,6 +329,7 @@
testmisc = ['readme.txt']
env.MSVSProject(target = 'Test.vcproj',
+ MSVS_PROJECT_GUID = '%(PROJECT_GUID)s',
slnguid = '{SLNGUID}',
srcs = testsrc,
incs = testincs,
@@ -436,8 +446,9 @@
"""
SConscript_contents_7_1 = """\
-env=Environment(platform='win32', tools=['msvs'],
- MSVS_VERSION='7.1',HOST_ARCH='%(HOST_ARCH)s')
+env=Environment(tools=['msvs'],
+ MSVS_VERSION='7.1',
+ HOST_ARCH='%(HOST_ARCH)s')
testsrc = ['test1.cpp', 'test2.cpp']
testincs = ['sdk.h']
@@ -446,6 +457,7 @@
testmisc = ['readme.txt']
env.MSVSProject(target = 'Test.vcproj',
+ MSVS_PROJECT_GUID = '%(PROJECT_GUID)s',
slnguid = '{SLNGUID}',
srcs = testsrc,
incs = testincs,
@@ -482,9 +494,9 @@
"
-\tRootNamespace="Test"
+\tRootNamespace="%(PROJECT_BASENAME)s"
\tKeyword="MakeFileProj">
\t
@@ -502,10 +514,10 @@
\t\t\t>
\t\t\t" -c "" -C "" -f SConstruct "Test.exe""
-\t\t\t\tReBuildCommandLine="echo Starting SCons && "" -c "" -C "" -f SConstruct "Test.exe""
-\t\t\t\tCleanCommandLine="echo Starting SCons && "" -c "" -C "" -f SConstruct -c "Test.exe""
-\t\t\t\tOutput="Test.exe"
+\t\t\t\tBuildCommandLine="echo Starting SCons && "" -c "" -C "" -f SConstruct "%(PROJECT_BASENAME)s.exe""
+\t\t\t\tReBuildCommandLine="echo Starting SCons && "" -c "" -C "" -f SConstruct "%(PROJECT_BASENAME)s.exe""
+\t\t\t\tCleanCommandLine="echo Starting SCons && "" -c "" -C "" -f SConstruct -c "%(PROJECT_BASENAME)s.exe""
+\t\t\t\tOutput="%(PROJECT_BASENAME)s.exe"
\t\t\t\tPreprocessorDefinitions="DEF1;DEF2;DEF3=1234"
\t\t\t\tIncludeSearchPath="%(INCLUDE_DIRS)s"
\t\t\t\tForcedIncludes=""
@@ -575,9 +587,9 @@
\t\t
\t
\t
-\t\t{39A97E1F-1A52-8954-A0B1-A10A8487545E}
+\t\t%(PROJECT_GUID)s
-\t\tTest
+\t\t%(PROJECT_BASENAME)s
\t\tMakeFileProj
\t\tNoUpgrade
\t
@@ -585,7 +597,7 @@
\t
\t\tMakefile
\t\tfalse
-\t\tv100
+\t\t%(PLATFORM_TOOLSET)s
\t
\t
\t
@@ -596,15 +608,16 @@
\t
\t
\t<_ProjectFileVersion>10.0.30319.1
-\t\techo Starting SCons && "" -c "" -C "" -f SConstruct "Test.exe"
-\t\techo Starting SCons && "" -c "" -C "" -f SConstruct "Test.exe"
-\t\techo Starting SCons && "" -c "" -C "" -f SConstruct -c "Test.exe"
-\t\tTest.exe
+\t\techo Starting SCons && "" -c "" -C "" -f SConstruct "%(PROJECT_BASENAME)s.exe"
+\t\techo Starting SCons && "" -c "" -C "" -f SConstruct "%(PROJECT_BASENAME)s.exe"
+\t\techo Starting SCons && "" -c "" -C "" -f SConstruct -c "%(PROJECT_BASENAME)s.exe"
+\t\t%(PROJECT_BASENAME)s.exe
\t\tDEF1;DEF2;DEF3=1234
\t\t%(INCLUDE_DIRS)s
\t\t$(NMakeForcedIncludes)
\t\t$(NMakeAssemblySearchPath)
\t\t$(NMakeForcedUsingAssemblies)
+\t\t
\t
\t
\t\t
@@ -632,7 +645,8 @@
"""
SConscript_contents_fmt = """\
-env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='%(MSVS_VERSION)s',
+env=Environment(tools=['msvs'],
+ MSVS_VERSION='%(MSVS_VERSION)s',
CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
CPPPATH=['inc1', 'inc2'],
HOST_ARCH='%(HOST_ARCH)s')
@@ -644,6 +658,7 @@
testmisc = ['readme.txt']
env.MSVSProject(target = '%(PROJECT_FILE)s',
+ MSVS_PROJECT_GUID = '%(PROJECT_GUID)s',
slnguid = '{SLNGUID}',
srcs = testsrc,
incs = testincs,
@@ -654,6 +669,161 @@
variant = 'Release')
"""
+expected_projects_slnfile_fmt = """\
+Microsoft Visual Studio Solution File, Format Version %(FORMAT_VERSION)s
+# Visual Studio %(VS_NUMBER)s
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "%(PROJECT_NAME_1)s", "%(PROJECT_FILE_1)s", ""
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "%(PROJECT_NAME_2)s", "%(PROJECT_FILE_2)s", ""
+EndProject
+Global
+
+\tGlobalSection(SolutionConfigurationPlatforms) = preSolution
+\t\tRelease|Win32 = Release|Win32
+\tEndGlobalSection
+\tGlobalSection(ProjectConfigurationPlatforms) = postSolution
+\t\t.Release|Win32.ActiveCfg = Release|Win32
+\t\t.Release|Win32.Build.0 = Release|Win32
+\t\t.Release|Win32.ActiveCfg = Release|Win32
+\t\t.Release|Win32.Build.0 = Release|Win32
+\tEndGlobalSection
+\tGlobalSection(SolutionProperties) = preSolution
+\t\tHideSolutionNode = FALSE
+\tEndGlobalSection
+EndGlobal
+"""
+
+expected_projects_slnfile_fmt_slnnodes = """\
+Microsoft Visual Studio Solution File, Format Version %(FORMAT_VERSION)s
+# Visual Studio %(VS_NUMBER)s
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "%(PROJECT_NAME_1)s", "%(PROJECT_FILE_1)s", ""
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "%(SOLUTION_FILE_1)s", "%(SOLUTION_FILE_1)s", ""
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "%(PROJECT_NAME_2)s", "%(PROJECT_FILE_2)s", ""
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "%(SOLUTION_FILE_2)s", "%(SOLUTION_FILE_2)s", ""
+EndProject
+Global
+
+\tGlobalSection(SolutionConfigurationPlatforms) = preSolution
+\t\tRelease|Win32 = Release|Win32
+\tEndGlobalSection
+\tGlobalSection(ProjectConfigurationPlatforms) = postSolution
+\t\t.Release|Win32.ActiveCfg = Release|Win32
+\t\t.Release|Win32.Build.0 = Release|Win32
+\t\t.Release|Win32.ActiveCfg = Release|Win32
+\t\t.Release|Win32.Build.0 = Release|Win32
+\t\t.Release|Win32.ActiveCfg = Release|Win32
+\t\t.Release|Win32.Build.0 = Release|Win32
+\t\t.Release|Win32.ActiveCfg = Release|Win32
+\t\t.Release|Win32.Build.0 = Release|Win32
+\tEndGlobalSection
+\tGlobalSection(SolutionProperties) = preSolution
+\t\tHideSolutionNode = FALSE
+\tEndGlobalSection
+EndGlobal
+"""
+
+SConscript_projects_contents_fmt = """\
+env=Environment(
+ tools=['msvs'],
+ MSVS_VERSION='%(MSVS_VERSION)s',
+ CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
+ CPPPATH=['inc1', 'inc2'],
+ HOST_ARCH='%(HOST_ARCH)s',
+)
+
+testsrc = ['test1.cpp', 'test2.cpp']
+testincs = [r'sdk_dir\\sdk.h']
+testlocalincs = ['test.h']
+testresources = ['test.rc']
+testmisc = ['readme.txt']
+
+p1 = env.MSVSProject(
+ target = '%(PROJECT_FILE_1)s',
+ MSVS_PROJECT_GUID = '%(PROJECT_GUID_1)s',
+ slnguid = '{SLNGUID}',
+ srcs = testsrc,
+ incs = testincs,
+ localincs = testlocalincs,
+ resources = testresources,
+ misc = testmisc,
+ buildtarget = 'Test_1.exe',
+ variant = 'Release',
+ auto_build_solution = %(AUTOBUILD_SOLUTION)s,
+)
+
+p2 = env.MSVSProject(
+ target = '%(PROJECT_FILE_2)s',
+ MSVS_PROJECT_GUID = '%(PROJECT_GUID_2)s',
+ slnguid = '{SLNGUID}',
+ srcs = testsrc,
+ incs = testincs,
+ localincs = testlocalincs,
+ resources = testresources,
+ misc = testmisc,
+ buildtarget = 'Test_2.exe',
+ variant = 'Release',
+ auto_build_solution = %(AUTOBUILD_SOLUTION)s,
+)
+
+env.MSVSSolution(
+ target = '%(SOLUTION_FILE)s',
+ projects = [p1, p2],
+ variant = 'Release',
+ auto_filter_projects = %(AUTOFILTER_PROJECTS)s,
+)
+"""
+
+SConscript_projects_defaultguids_contents_fmt = """\
+env=Environment(
+ tools=['msvs'],
+ MSVS_VERSION='%(MSVS_VERSION)s',
+ CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
+ CPPPATH=['inc1', 'inc2'],
+ HOST_ARCH='%(HOST_ARCH)s',
+)
+
+testsrc = ['test1.cpp', 'test2.cpp']
+testincs = [r'sdk_dir\\sdk.h']
+testlocalincs = ['test.h']
+testresources = ['test.rc']
+testmisc = ['readme.txt']
+
+p1 = env.MSVSProject(
+ target = '%(PROJECT_FILE_1)s',
+ slnguid = '{SLNGUID}',
+ srcs = testsrc,
+ incs = testincs,
+ localincs = testlocalincs,
+ resources = testresources,
+ misc = testmisc,
+ buildtarget = 'Test_1.exe',
+ variant = 'Release',
+ auto_build_solution = %(AUTOBUILD_SOLUTION)s,
+)
+
+p2 = env.MSVSProject(
+ target = '%(PROJECT_FILE_2)s',
+ slnguid = '{SLNGUID}',
+ srcs = testsrc,
+ incs = testincs,
+ localincs = testlocalincs,
+ resources = testresources,
+ misc = testmisc,
+ buildtarget = 'Test_2.exe',
+ variant = 'Release',
+ auto_build_solution = %(AUTOBUILD_SOLUTION)s,
+)
+
+env.MSVSSolution(
+ target = '%(SOLUTION_FILE)s',
+ projects = [p1, p2],
+ variant = 'Release',
+ auto_filter_projects = %(AUTOFILTER_PROJECTS)s,
+)
+"""
def get_tested_proj_file_vc_versions():
"""
@@ -720,7 +890,7 @@ def msvs_substitute(self, input, msvs_ver,
python = sys.executable
if project_guid is None:
- project_guid = "{B0CC4EE9-0174-51CD-A06A-41D0713E928A}"
+ project_guid = PROJECT_GUID
if 'SCONS_LIB_DIR' in os.environ:
exec_script_main = f"from os.path import join; import sys; sys.path = [ r'{os.environ['SCONS_LIB_DIR']}' ] + sys.path; import SCons.Script; SCons.Script.main()"
@@ -868,6 +1038,8 @@ def _get_solution_file_vs_number(self, vc_version) -> str:
return '15'
elif major == 14 and minor == 2:
return '16'
+ elif major == 14 and minor == 3:
+ return '17'
else:
raise SCons.Errors.UserError(f'Received unexpected VC version {vc_version}')
@@ -902,6 +1074,15 @@ def _get_vcxproj_file_tools_version(self, vc_version) -> str:
else:
raise SCons.Errors.UserError(f'Received unexpected VC version {vc_version}')
+ def _get_vcxproj_file_platform_toolset(self, vc_version) -> str:
+ """
+ Returns the version entry expected in the project file.
+ For .vcxproj files, this goes is PlatformToolset.
+ For .vcproj files, not applicable.
+ """
+ major, minor = self.parse_vc_version(vc_version)
+ return f"v{major}{minor}"
+
def _get_vcxproj_file_cpp_path(self, dirs):
"""Returns the include paths expected in the .vcxproj file"""
return ';'.join([self.workpath(dir) for dir in dirs])
@@ -925,18 +1106,154 @@ def get_expected_proj_file_contents(self, vc_version, dirs, project_file):
fmt = expected_vcxprojfile_fmt
else:
fmt = expected_vcprojfile_fmt
+ project_filename = os.path.split(project_file)[-1]
+ project_basename = os.path.splitext(project_filename)[0]
return fmt % {
+ 'PROJECT_BASENAME': project_basename,
+ 'PROJECT_GUID': PROJECT_GUID,
'TOOLS_VERSION': self._get_vcxproj_file_tools_version(vc_version),
'INCLUDE_DIRS': self._get_vcxproj_file_cpp_path(dirs),
+ 'PLATFORM_TOOLSET': self._get_vcxproj_file_platform_toolset(vc_version),
}
def get_expected_sconscript_file_contents(self, vc_version, project_file):
return SConscript_contents_fmt % {
'HOST_ARCH': self.get_vs_host_arch(),
'MSVS_VERSION': vc_version,
+ 'PROJECT_GUID': PROJECT_GUID,
'PROJECT_FILE': project_file,
}
+ def msvs_substitute_projects(
+ self, input, *,
+ subdir=None,
+ sconscript=None,
+ python=None,
+ project_guid_1=None,
+ project_guid_2=None,
+ solution_guid_1=None,
+ solution_guid_2=None,
+ vcproj_sccinfo: str='',
+ sln_sccinfo: str=''
+ ):
+ if not hasattr(self, '_msvs_versions'):
+ self.msvs_versions()
+
+ if subdir:
+ workpath = self.workpath(subdir)
+ else:
+ workpath = self.workpath()
+
+ if sconscript is None:
+ sconscript = self.workpath('SConstruct')
+
+ if python is None:
+ python = sys.executable
+
+ if project_guid_1 is None:
+ project_guid_1 = PROJECT_GUID_1
+
+ if project_guid_2 is None:
+ project_guid_2 = PROJECT_GUID_2
+
+ if solution_guid_1 is None:
+ solution_guid_1 = SOLUTION_GUID_1
+
+ if solution_guid_2 is None:
+ solution_guid_2 = SOLUTION_GUID_2
+
+ if 'SCONS_LIB_DIR' in os.environ:
+ exec_script_main = f"from os.path import join; import sys; sys.path = [ r'{os.environ['SCONS_LIB_DIR']}' ] + sys.path; import SCons.Script; SCons.Script.main()"
+ else:
+ exec_script_main = f"from os.path import join; import sys; sys.path = [ join(sys.prefix, 'Lib', 'site-packages', 'scons-{self.scons_version}'), join(sys.prefix, 'scons-{self.scons_version}'), join(sys.prefix, 'Lib', 'site-packages', 'scons'), join(sys.prefix, 'scons') ] + sys.path; import SCons.Script; SCons.Script.main()"
+ exec_script_main_xml = exec_script_main.replace("'", "'")
+
+ result = input.replace(r'', workpath)
+ result = result.replace(r'', python)
+ result = result.replace(r'', sconscript)
+ result = result.replace(r'', exec_script_main)
+ result = result.replace(r'', exec_script_main_xml)
+ result = result.replace(r'', project_guid_1)
+ result = result.replace(r'', project_guid_2)
+ result = result.replace(r'', solution_guid_1)
+ result = result.replace(r'', solution_guid_2)
+ result = result.replace('\n', vcproj_sccinfo)
+ result = result.replace('\n', sln_sccinfo)
+ return result
+
+ def get_expected_projects_proj_file_contents(self, vc_version, dirs, project_file, project_guid):
+ """Returns the expected .vcxproj file contents"""
+ if project_file.endswith('.vcxproj'):
+ fmt = expected_vcxprojfile_fmt
+ else:
+ fmt = expected_vcprojfile_fmt
+ project_filename = os.path.split(project_file)[-1]
+ project_basename = os.path.splitext(project_filename)[0]
+ return fmt % {
+ 'PROJECT_BASENAME': project_basename,
+ 'PROJECT_GUID': project_guid,
+ 'TOOLS_VERSION': self._get_vcxproj_file_tools_version(vc_version),
+ 'INCLUDE_DIRS': self._get_vcxproj_file_cpp_path(dirs),
+ 'PLATFORM_TOOLSET': self._get_vcxproj_file_platform_toolset(vc_version),
+ }
+
+ def get_expected_projects_sln_file_contents(
+ self, vc_version,
+ project_file_1, project_file_2,
+ have_solution_project_nodes=False,
+ autofilter_solution_project_nodes=None,
+ ):
+ if not have_solution_project_nodes or autofilter_solution_project_nodes:
+ rval = expected_projects_slnfile_fmt % {
+ 'FORMAT_VERSION': self._get_solution_file_format_version(vc_version),
+ 'VS_NUMBER': self._get_solution_file_vs_number(vc_version),
+ 'PROJECT_NAME_1': project_file_1.split('.')[0],
+ 'PROJECT_FILE_1': project_file_1,
+ 'PROJECT_NAME_2': project_file_2.split('.')[0],
+ 'PROJECT_FILE_2': project_file_2,
+ }
+ else:
+ rval = expected_projects_slnfile_fmt_slnnodes % {
+ 'FORMAT_VERSION': self._get_solution_file_format_version(vc_version),
+ 'VS_NUMBER': self._get_solution_file_vs_number(vc_version),
+ 'PROJECT_NAME_1': project_file_1.split('.')[0],
+ 'PROJECT_FILE_1': project_file_1,
+ 'PROJECT_NAME_2': project_file_2.split('.')[0],
+ 'PROJECT_FILE_2': project_file_2,
+ 'SOLUTION_FILE_1': project_file_1.split('.')[0] + ".sln",
+ 'SOLUTION_FILE_2': project_file_2.split('.')[0] + ".sln",
+ }
+ return rval
+
+ def get_expected_projects_sconscript_file_contents(
+ self, vc_version,
+ project_file_1, project_file_2, solution_file,
+ autobuild_solution=0,
+ autofilter_projects=None,
+ default_guids=False,
+ ):
+
+ values = {
+ 'HOST_ARCH': self.get_vs_host_arch(),
+ 'MSVS_VERSION': vc_version,
+ 'PROJECT_FILE_1': project_file_1,
+ 'PROJECT_FILE_2': project_file_2,
+ 'SOLUTION_FILE': solution_file,
+ "AUTOBUILD_SOLUTION": autobuild_solution,
+ "AUTOFILTER_PROJECTS": autofilter_projects,
+ }
+
+ if default_guids:
+ format = SConscript_projects_defaultguids_contents_fmt
+ else:
+ format = SConscript_projects_contents_fmt
+
+ values.update({
+ 'PROJECT_GUID_1': PROJECT_GUID_1,
+ 'PROJECT_GUID_2': PROJECT_GUID_2,
+ })
+ return format % values
+
# Local Variables:
# tab-width:4
# indent-tabs-mode:nil