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 @@ \tKeyword="MakeFileProj"> \t @@ -502,10 +514,10 @@ \t\t\t> \t\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