Chromium Code Reviews| Index: test/lib/TestGyp.py |
| =================================================================== |
| --- test/lib/TestGyp.py (revision 1925) |
| +++ test/lib/TestGyp.py (working copy) |
| @@ -78,6 +78,7 @@ |
| configuration and to run executables generated by those builds. |
| """ |
| + formats = [] |
| build_tool = None |
| build_tool_list = [] |
| @@ -113,6 +114,8 @@ |
| self.gyp = os.path.abspath(gyp) |
| self.no_parallel = False |
| + self.formats = [self.format] |
| + |
| self.initialize_build_tool() |
| kw.setdefault('match', TestCommon.match_exact) |
| @@ -130,10 +133,11 @@ |
| super(TestGypBase, self).__init__(*args, **kw) |
| + real_format = self.format.split('-')[-1] |
| excluded_formats = set([f for f in formats if f[0] == '!']) |
| included_formats = set(formats) - excluded_formats |
| - if ('!'+self.format in excluded_formats or |
| - included_formats and self.format not in included_formats): |
| + if ('!'+real_format in excluded_formats or |
| + included_formats and real_format not in included_formats): |
| msg = 'Invalid test for %r format; skipping test.\n' |
| self.skip_test(msg % self.format) |
| @@ -272,9 +276,13 @@ |
| # TODO: --depth=. works around Chromium-specific tree climbing. |
| depth = kw.pop('depth', '.') |
| - run_args = ['--depth='+depth, '--format='+self.format, gyp_file] |
| + run_args = ['--depth='+depth] |
| + run_args.extend(['--format='+f for f in self.formats]); |
| + run_args.append(gyp_file) |
| if self.no_parallel: |
| run_args += ['--no-parallel'] |
| + # TODO: if extra_args contains a '--build' flag |
| + # we really want that to only apply to the last format (self.format). |
| run_args.extend(self.extra_args) |
| run_args.extend(args) |
| return self.run(program=self.gyp, arguments=run_args, **kw) |
| @@ -747,6 +755,63 @@ |
| return path |
| +def FindMSBuildInstallation(msvs_version = 'auto'): |
| + """Returns path to MSBuild for msvs_version or latest available. |
| + |
| + Looks in the registry to find install location of MSBuild. |
| + MSBuild before v4.0 will not build c++ projects, so only use newer versions. |
| + """ |
| + import _winreg |
|
scottmg
2014/06/02 16:04:49
I don't think this module is available on cygwin p
bungeman-chromium
2014/06/02 17:35:31
I was not aware of that. Done.
|
| + def get_reg_key(base, key): |
| + try: |
| + result = _winreg.OpenKey(base, key, 0, |
| + _winreg.KEY_READ | _winreg.KEY_WOW64_32KEY) |
| + except WindowsError: |
| + result = None |
| + return result |
| + |
| + def get_reg_key_value(key, value): |
| + try: |
| + result, _ = _winreg.QueryValueEx(key, value) |
| + except WindowsError: |
| + result = None |
| + return result |
| + |
| + msbuild_basekey = get_reg_key(_winreg.HKEY_LOCAL_MACHINE, |
| + 'SOFTWARE\Microsoft\MSBuild\ToolsVersions') |
| + if not msbuild_basekey: |
| + print 'Error: could not find MSBuild base registry entry' |
| + return None |
| + |
| + msvs_to_msbuild = { |
| + '2013': r'12.0', |
| + '2012': r'4.0', #really v4.0.30319 which comes with .NET 4.5 |
|
scottmg
2014/06/02 16:04:49
nit; two spaces before #, one after, capital R, en
bungeman-chromium
2014/06/02 17:35:31
Done.
|
| + '2010': r'4.0'} |
| + |
| + msbuild_key = None |
| + if msvs_version in msvs_to_msbuild: |
| + msbuild_version = msvs_to_msbuild[msvs_version] |
| + msbuild_key = get_reg_key(msbuild_basekey, msbuild_version) |
| + if not msbuild_key: |
| + print ('Warning: Environment variable GYP_MSVS_VERSION specifies "%s" ' |
| + 'but corresponding MSBuild "%s" was not found.' % |
| + (msvs_version, msbuild_version)) |
| + if not msbuild_key: |
| + for msvs_version in sorted(msvs_to_msbuild, reverse=True): |
| + msbuild_version = msvs_to_msbuild[msvs_version] |
| + msbuild_key = get_reg_key(msbuild_basekey, msbuild_version) |
| + if not msbuild_key: |
| + print 'Error: could not find MSBuild registry entry' |
| + return None |
| + |
| + msbuild_path = get_reg_key_value(msbuild_key, 'MSBuildToolsPath') |
| + if not msbuild_path: |
| + print 'Error: could not get MSBuild registry entry value' |
| + return None |
| + |
| + return os.path.join(msbuild_path, 'MSBuild.exe') |
| + |
| + |
| def FindVisualStudioInstallation(): |
| """Returns appropriate values for .build_tool and .uses_msbuild fields |
| of TestGypBase for Visual Studio. |
| @@ -772,39 +837,28 @@ |
| msvs_version = flag.split('=')[-1] |
| msvs_version = os.environ.get('GYP_MSVS_VERSION', msvs_version) |
| - build_tool = None |
| if msvs_version in possible_paths: |
| # Check that the path to the specified GYP_MSVS_VERSION exists. |
| path = possible_paths[msvs_version] |
| for r in possible_roots: |
| - bt = os.path.join(r, path) |
| - if os.path.exists(bt): |
| - build_tool = bt |
| + build_tool = os.path.join(r, path) |
| + if os.path.exists(build_tool): |
| uses_msbuild = msvs_version >= '2010' |
| - return build_tool, uses_msbuild |
| + msbuild_path = FindMSBuildInstallation(msvs_version) |
| + return build_tool, uses_msbuild, msbuild_path |
| else: |
| print ('Warning: Environment variable GYP_MSVS_VERSION specifies "%s" ' |
| 'but corresponding "%s" was not found.' % (msvs_version, path)) |
| - if build_tool: |
| - # We found 'devenv' on the path, use that and try to guess the version. |
| - for version, path in possible_paths.iteritems(): |
| - if build_tool.find(path) >= 0: |
| - uses_msbuild = version >= '2010' |
| - return build_tool, uses_msbuild |
| - else: |
| - # If not, assume not MSBuild. |
| - uses_msbuild = False |
| - return build_tool, uses_msbuild |
| # Neither GYP_MSVS_VERSION nor the path help us out. Iterate through |
| # the choices looking for a match. |
| for version in sorted(possible_paths, reverse=True): |
| path = possible_paths[version] |
| for r in possible_roots: |
| - bt = os.path.join(r, path) |
| - if os.path.exists(bt): |
| - build_tool = bt |
| + build_tool = os.path.join(r, path) |
| + if os.path.exists(build_tool): |
| uses_msbuild = msvs_version >= '2010' |
| - return build_tool, uses_msbuild |
| + msbuild_path = FindMSBuildInstallation(msvs_version) |
| + return build_tool, uses_msbuild, msbuild_path |
| print 'Error: could not find devenv' |
| sys.exit(1) |
| @@ -822,7 +876,8 @@ |
| def initialize_build_tool(self): |
| super(TestGypOnMSToolchain, self).initialize_build_tool() |
| if sys.platform in ('win32', 'cygwin'): |
| - self.devenv_path, self.uses_msbuild = FindVisualStudioInstallation() |
| + build_tools = FindVisualStudioInstallation() |
| + self.devenv_path, self.uses_msbuild, self.msbuild_path = build_tools |
| self.vsvars_path = TestGypOnMSToolchain._ComputeVsvarsPath( |
| self.devenv_path) |
| @@ -1002,6 +1057,56 @@ |
| return self.workpath(*result) |
| +class TestGypMSVSNinja(TestGypNinja): |
| + """ |
| + Subclass for testing the GYP Visual Studio Ninja generator. |
| + """ |
| + format = 'msvs-ninja' |
| + |
| + def initialize_build_tool(self): |
| + super(TestGypMSVSNinja, self).initialize_build_tool() |
| + # When using '--build', make sure ninja is first in the format list. |
| + self.formats.insert(0, 'ninja') |
| + |
| + def build(self, gyp_file, target=None, rebuild=False, clean=False, **kw): |
| + """ |
| + Runs a Visual Studio build using the configuration generated |
| + from the specified gyp_file. |
| + """ |
| + arguments = kw.get('arguments', [])[:] |
| + if target in (None, self.ALL, self.DEFAULT): |
| + # Note: the Visual Studio generator doesn't add an explicit 'all' target. |
| + # This will build each project. This will work if projects are hermetic, |
| + # but may fail if they are not (a project may run more than once). |
| + # It would be nice to supply an all.metaproj for MSBuild. |
| + arguments.extend([gyp_file.replace('.gyp', '.sln')]) |
| + else: |
| + # MSBuild documentation claims that one can specify a sln but then build a |
| + # project target like 'msbuild a.sln /t:proj:target' but this format only |
| + # supports 'Clean', 'Rebuild', and 'Publish' (with none meaning Default). |
| + # This limitation is due to the .sln -> .sln.metaproj conversion. |
| + # The ':' is not special, 'proj:target' is a target in the metaproj. |
| + arguments.extend([target+'.vcxproj']) |
| + |
| + if clean: |
| + build = 'Clean' |
| + elif rebuild: |
| + build = 'Rebuild' |
| + else: |
| + build = 'Build' |
| + arguments.extend(['/target:'+build]) |
| + configuration = self.configuration_buildname() |
| + config = configuration.split('|') |
| + arguments.extend(['/property:Configuration='+config[0]]) |
| + if len(config) > 1: |
| + arguments.extend(['/property:Platform='+config[1]]) |
| + arguments.extend(['/property:BuildInParallel=false']) |
| + arguments.extend(['/verbosity:minimal']) |
| + |
| + kw['arguments'] = arguments |
| + return self.run(program=self.msbuild_path, **kw) |
| + |
| + |
| class TestGypXcode(TestGypBase): |
| """ |
| Subclass for testing the GYP Xcode generator. |
| @@ -1118,6 +1223,7 @@ |
| TestGypCMake, |
| TestGypMake, |
| TestGypMSVS, |
| + TestGypMSVSNinja, |
| TestGypNinja, |
| TestGypXcode, |
| ] |