Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
Upgrade GYP to r1477
Browse files Browse the repository at this point in the history
  • Loading branch information
ry committed Aug 22, 2012
1 parent 2e1f2b5 commit f90c9ce
Show file tree
Hide file tree
Showing 24 changed files with 4,065 additions and 159 deletions.
10 changes: 9 additions & 1 deletion tools/gyp/gyptest.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ def main(argv=None):
help="chdir to the specified directory")
parser.add_option("-f", "--format", action="store", default='',
help="run tests with the specified formats")
parser.add_option("-G", '--gyp_option', action="append", default=[],
help="Add -G options to the gyp command line")
parser.add_option("-l", "--list", action="store_true",
help="list available tests and exit")
parser.add_option("-n", "--no-exec", action="store_true",
Expand Down Expand Up @@ -220,8 +222,14 @@ def main(argv=None):
if not opts.quiet:
sys.stdout.write('TESTGYP_FORMAT=%s\n' % format)

gyp_options = []
for option in opts.gyp_option:
gyp_options += ['-G', option]
if gyp_options and not opts.quiet:
sys.stdout.write('Extra Gyp options: %s\n' % gyp_options)

for test in tests:
status = cr.run([sys.executable, test],
status = cr.run([sys.executable, test] + gyp_options,
stdout=sys.stdout,
stderr=sys.stderr)
if status == 2:
Expand Down
28 changes: 21 additions & 7 deletions tools/gyp/pylib/gyp/MSVSSettings.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Copyright (c) 2012 Google Inc. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

Expand All @@ -15,7 +15,7 @@
"""

import sys

import re

# Dictionaries of settings validators. The key is the tool name, the value is
# a dictionary mapping setting names to validation functions.
Expand Down Expand Up @@ -362,6 +362,24 @@ def _Translate(value, msbuild_settings):
_msvs_to_msbuild_converters[tool.msvs_name][msvs_name] = _Translate


fix_vc_macro_slashes_regex_list = ('IntDir', 'OutDir')
fix_vc_macro_slashes_regex = re.compile(
r'(\$\((?:%s)\))(?:[\\/]+)' % "|".join(fix_vc_macro_slashes_regex_list)
)

def FixVCMacroSlashes(s):
"""Replace macros which have excessive following slashes.
These macros are known to have a built-in trailing slash. Furthermore, many
scripts hiccup on processing paths with extra slashes in the middle.
This list is probably not exhaustive. Add as needed.
"""
if '$' in s:
s = fix_vc_macro_slashes_regex.sub(r'\1', s)
return s


def ConvertVCMacrosToMSBuild(s):
"""Convert the the MSVS macros found in the string to the MSBuild equivalent.
Expand All @@ -378,14 +396,10 @@ def ConvertVCMacrosToMSBuild(s):
'$(ParentName)': '$(ProjectFileName)',
'$(PlatformName)': '$(Platform)',
'$(SafeInputName)': '%(Filename)',

'$(IntDir)\\': '$(IntDir)',
'$(OutDir)\\': '$(OutDir)',
'$(IntDir)/': '$(IntDir)',
'$(OutDir)/': '$(OutDir)',
}
for old, new in replace_map.iteritems():
s = s.replace(old, new)
s = FixVCMacroSlashes(s)
return s


Expand Down
34 changes: 31 additions & 3 deletions tools/gyp/pylib/gyp/MSVSVersion.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class VisualStudioVersion(object):

def __init__(self, short_name, description,
solution_version, project_version, flat_sln, uses_vcxproj,
path, sdk_based):
path, sdk_based, default_toolset=None):
self.short_name = short_name
self.description = description
self.solution_version = solution_version
Expand All @@ -25,6 +25,7 @@ def __init__(self, short_name, description,
self.uses_vcxproj = uses_vcxproj
self.path = path
self.sdk_based = sdk_based
self.default_toolset = default_toolset

def ShortName(self):
return self.short_name
Expand Down Expand Up @@ -60,6 +61,11 @@ def ToolPath(self, tool):
"""Returns the path to a given compiler tool. """
return os.path.normpath(os.path.join(self.path, "VC/bin", tool))

def DefaultToolset(self):
"""Returns the msbuild toolset version that will be used in the absence
of a user override."""
return self.default_toolset

def SetupScript(self, target_arch):
"""Returns a command (with arguments) to be used to set up the
environment."""
Expand Down Expand Up @@ -188,6 +194,24 @@ def _CreateVersion(name, path, sdk_based=False):
passed in that doesn't match a value in versions python will throw a error.
"""
versions = {
'2012': VisualStudioVersion('2012',
'Visual Studio 2012',
solution_version='12.00',
project_version='4.0',
flat_sln=False,
uses_vcxproj=True,
path=path,
sdk_based=sdk_based,
default_toolset='v110'),
'2012e': VisualStudioVersion('2012e',
'Visual Studio 2012',
solution_version='12.00',
project_version='4.0',
flat_sln=True,
uses_vcxproj=True,
path=path,
sdk_based=sdk_based,
default_toolset='v110'),
'2010': VisualStudioVersion('2010',
'Visual Studio 2010',
solution_version='11.00',
Expand Down Expand Up @@ -252,9 +276,11 @@ def _DetectVisualStudioVersions(versions_to_check, force_express):
2005(e) - Visual Studio 2005 (8)
2008(e) - Visual Studio 2008 (9)
2010(e) - Visual Studio 2010 (10)
2012(e) - Visual Studio 2012 (11)
Where (e) is e for express editions of MSVS and blank otherwise.
"""
version_to_year = {'8.0': '2005', '9.0': '2008', '10.0': '2010'}
version_to_year = {
'8.0': '2005', '9.0': '2008', '10.0': '2010', '11.0': '2012'}
versions = []
for version in versions_to_check:
# Old method of searching for which VS version is installed
Expand Down Expand Up @@ -306,13 +332,15 @@ def SelectVisualStudioVersion(version='auto'):
if version == 'auto':
version = os.environ.get('GYP_MSVS_VERSION', 'auto')
version_map = {
'auto': ('10.0', '9.0', '8.0'),
'auto': ('10.0', '9.0', '8.0', '11.0'),
'2005': ('8.0',),
'2005e': ('8.0',),
'2008': ('9.0',),
'2008e': ('9.0',),
'2010': ('10.0',),
'2010e': ('10.0',),
'2012': ('11.0',),
'2012e': ('11.0',),
}
version = str(version)
versions = _DetectVisualStudioVersions(version_map[version], 'e' in version)
Expand Down
54 changes: 42 additions & 12 deletions tools/gyp/pylib/gyp/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python

# Copyright (c) 2011 Google Inc. All rights reserved.
# Copyright (c) 2012 Google Inc. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

Expand Down Expand Up @@ -39,11 +39,18 @@ def FindBuildFiles():
files = os.listdir(os.getcwd())
build_files = []
for file in files:
if file[-len(extension):] == extension:
if file.endswith(extension):
build_files.append(file)
return build_files


class GypError(Exception):
"""Error class representing an error, which is to be presented
to the user. The main entry point will catch and display this.
"""
pass


def Load(build_files, format, default_variables={},
includes=[], depth='.', params=None, check=False, circular_check=True):
"""
Expand All @@ -66,7 +73,22 @@ def Load(build_files, format, default_variables={},
# avoiding collisions with user and automatic variables.
default_variables['GENERATOR'] = format

generator_name = 'gyp.generator.' + format
# Format can be a custom python file, or by default the name of a module
# within gyp.generator.
if format.endswith('.py'):
generator_name = os.path.splitext(format)[0]
path, generator_name = os.path.split(generator_name)

# Make sure the path to the custom generator is in sys.path
# Don't worry about removing it once we are done. Keeping the path
# to each generator that is used in sys.path is likely harmless and
# arguably a good idea.
path = os.path.abspath(path)
if path not in sys.path:
sys.path.insert(0, path)
else:
generator_name = 'gyp.generator.' + format

# These parameters are passed in order (as opposed to by key)
# because ActivePython cannot handle key parameters to __import__.
generator = __import__(generator_name, globals(), locals(), generator_name)
Expand Down Expand Up @@ -157,7 +179,10 @@ def RegenerateAppendFlag(flag, values, predicate, env_name, options):
flags = []
if options.use_environment and env_name:
for flag_value in ShlexEnv(env_name):
flags.append(FormatOpt(flag, predicate(flag_value)))
value = FormatOpt(flag, predicate(flag_value))
if value in flags:
flags.remove(value)
flags.append(value)
if values:
for flag_value in values:
flags.append(FormatOpt(flag, predicate(flag_value)))
Expand Down Expand Up @@ -254,7 +279,7 @@ def parse_args(self, *args):
values._regeneration_metadata = self.__regeneratable_options
return values, args

def main(args):
def gyp_main(args):
my_name = os.path.basename(sys.argv[0])

parser = RegeneratableOptionParser()
Expand Down Expand Up @@ -366,9 +391,8 @@ def main(args):
if not build_files:
build_files = FindBuildFiles()
if not build_files:
print >>sys.stderr, (usage + '\n\n%s: error: no build_file') % \
(my_name, my_name)
return 1
raise GypError((usage + '\n\n%s: error: no build_file') %
(my_name, my_name))

# TODO(mark): Chromium-specific hack!
# For Chromium, the gyp "depth" variable should always be a relative path
Expand All @@ -393,10 +417,9 @@ def main(args):
break

if not options.depth:
raise Exception, \
'Could not automatically locate src directory. This is a ' + \
'temporary Chromium feature that will be removed. Use ' + \
'--depth as a workaround.'
raise GypError('Could not automatically locate src directory. This is'
'a temporary Chromium feature that will be removed. Use'
'--depth as a workaround.')

# If toplevel-dir is not set, we assume that depth is the root of our source
# tree.
Expand Down Expand Up @@ -483,5 +506,12 @@ def main(args):
return 0


def main(args):
try:
return gyp_main(args)
except GypError, e:
sys.stderr.write("gyp: %s\n" % e)
return 1

if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))
9 changes: 9 additions & 0 deletions tools/gyp/pylib/gyp/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,15 @@ def BuildFile(fully_qualified_target):
return ParseQualifiedTarget(fully_qualified_target)[0]


def GetEnvironFallback(var_list, default):
"""Look up a key in the environment, with fallback to secondary keys
and finally falling back to a default value."""
for var in var_list:
if var in os.environ:
return os.environ[var]
return default


def QualifiedTarget(build_file, target, toolset):
# "Qualified" means the file that a target was defined in and the target
# name, separated by a colon, suffixed by a # and the toolset name:
Expand Down
17 changes: 13 additions & 4 deletions tools/gyp/pylib/gyp/easy_xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# found in the LICENSE file.

import re
import os


def XmlToString(content, encoding='utf-8', pretty=False):
Expand Down Expand Up @@ -79,7 +80,7 @@ def _ConstructContentList(xml_parts, specification, pretty, level=0):
rest = specification[1:]
if rest and isinstance(rest[0], dict):
for at, val in sorted(rest[0].iteritems()):
xml_parts.append(' %s="%s"' % (at, _XmlEscape(val)))
xml_parts.append(' %s="%s"' % (at, _XmlEscape(val, attr=True)))
rest = rest[1:]
if rest:
xml_parts.append('>')
Expand All @@ -101,7 +102,8 @@ def _ConstructContentList(xml_parts, specification, pretty, level=0):
xml_parts.append('/>%s' % new_line)


def WriteXmlIfChanged(content, path, encoding='utf-8', pretty=False):
def WriteXmlIfChanged(content, path, encoding='utf-8', pretty=False,
win32=False):
""" Writes the XML content to disk, touching the file only if it has changed.
Args:
Expand All @@ -111,6 +113,8 @@ def WriteXmlIfChanged(content, path, encoding='utf-8', pretty=False):
pretty: True if we want pretty printing with indents and new lines.
"""
xml_string = XmlToString(content, encoding, pretty)
if win32 and os.linesep != '\r\n':
xml_string = xml_string.replace('\n', '\r\n')

# Get the old content
try:
Expand Down Expand Up @@ -142,7 +146,12 @@ def WriteXmlIfChanged(content, path, encoding='utf-8', pretty=False):
"(%s)" % "|".join(map(re.escape, _xml_escape_map.keys())))


def _XmlEscape(value):
def _XmlEscape(value, attr=False):
""" Escape a string for inclusion in XML."""
replace = lambda m: _xml_escape_map[m.string[m.start() : m.end()]]
def replace(match):
m = match.string[match.start() : match.end()]
# don't replace single quotes in attrs
if attr and m == "'":
return m
return _xml_escape_map[m]
return _xml_escape_re.sub(replace, value)
9 changes: 5 additions & 4 deletions tools/gyp/pylib/gyp/easy_xml_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ def test_EasyXml_simple_with_attributes(self):

def test_EasyXml_escaping(self):
original = '<test>\'"\r&\nfoo'
converted = '&lt;test&gt;&apos;&quot;&#xD;&amp;&#xA;foo'
converted = '&lt;test&gt;\'&quot;&#xD;&amp;&#xA;foo'
converted_apos = converted.replace("'", '&apos;')
self.assertEqual(
easy_xml.XmlToString(['test3', {'a': original}, original]),
'<?xml version="1.0" encoding="utf-8"?><test3 a="%s">%s</test3>' %
(converted, converted))
(converted, converted_apos))

def test_EasyXml_pretty(self):
self.assertEqual(
Expand Down Expand Up @@ -73,8 +74,8 @@ def test_EasyXml_complex(self):
'</PropertyGroup>'
'<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.props"/>'
'<PropertyGroup '
'Condition="&apos;$(Configuration)|$(Platform)&apos;=='
'&apos;Debug|Win32&apos;" Label="Configuration">'
'Condition="\'$(Configuration)|$(Platform)\'=='
'\'Debug|Win32\'" Label="Configuration">'
'<ConfigurationType>Application</ConfigurationType>'
'<CharacterSet>Unicode</CharacterSet>'
'</PropertyGroup>'
Expand Down
Loading

0 comments on commit f90c9ce

Please sign in to comment.