summaryrefslogtreecommitdiff
path: root/tools/gyp/pylib/gyp/input.py
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2013-03-24 14:29:17 +0100
committerBen Noordhuis <info@bnoordhuis.nl>2013-03-24 15:03:09 +0100
commit8632af381e7086823db764f815cbee53681d450b (patch)
tree84c752dbe7c2adb53a567087ac995383fb3e3935 /tools/gyp/pylib/gyp/input.py
parent329b5388ba5a74aa3c4a7e142ba33510e4282cc1 (diff)
downloadandroid-node-v8-8632af381e7086823db764f815cbee53681d450b.tar.gz
android-node-v8-8632af381e7086823db764f815cbee53681d450b.tar.bz2
android-node-v8-8632af381e7086823db764f815cbee53681d450b.zip
tools: update gyp to r1601
Among other things, this should make it easier for people to build node.js on openbsd.
Diffstat (limited to 'tools/gyp/pylib/gyp/input.py')
-rw-r--r--tools/gyp/pylib/gyp/input.py140
1 files changed, 78 insertions, 62 deletions
diff --git a/tools/gyp/pylib/gyp/input.py b/tools/gyp/pylib/gyp/input.py
index 65236671f9..eca0eb93aa 100644
--- a/tools/gyp/pylib/gyp/input.py
+++ b/tools/gyp/pylib/gyp/input.py
@@ -46,21 +46,16 @@ base_path_sections = [
]
path_sections = []
+is_path_section_charset = set('=+?!')
+is_path_section_match_re = re.compile('_(dir|file|path)s?$')
def IsPathSection(section):
# If section ends in one of these characters, it's applied to a section
# without the trailing characters. '/' is notably absent from this list,
# because there's no way for a regular expression to be treated as a path.
- while section[-1:] in ('=', '+', '?', '!'):
- section = section[0:-1]
-
- if section in path_sections or \
- section.endswith('_dir') or section.endswith('_dirs') or \
- section.endswith('_file') or section.endswith('_files') or \
- section.endswith('_path') or section.endswith('_paths'):
- return True
- return False
-
+ while section[-1:] in is_path_section_charset:
+ section = section[:-1]
+ return section in path_sections or is_path_section_match_re.search(section)
# base_non_configuraiton_keys is a list of key names that belong in the target
# itself and should not be propagated into its configurations. It is merged
@@ -269,7 +264,7 @@ def LoadBuildFileIncludesIntoDict(subdict, subdict_path, data, aux_data,
aux_data[subdict_path]['included'] = []
aux_data[subdict_path]['included'].append(include)
- gyp.DebugOutput(gyp.DEBUG_INCLUDES, "Loading Included File: '%s'" % include)
+ gyp.DebugOutput(gyp.DEBUG_INCLUDES, "Loading Included File: '%s'", include)
MergeDicts(subdict,
LoadOneBuildFile(include, data, aux_data, variables, None,
@@ -359,7 +354,7 @@ def LoadTargetBuildFile(build_file_path, data, aux_data, variables, includes,
data['target_build_files'].add(build_file_path)
gyp.DebugOutput(gyp.DEBUG_INCLUDES,
- "Loading Target Build File '%s'" % build_file_path)
+ "Loading Target Build File '%s'", build_file_path)
build_file_data = LoadOneBuildFile(build_file_path, data, aux_data, variables,
includes, True, check)
@@ -494,7 +489,7 @@ def CallLoadTargetBuildFile(global_flags,
aux_data_out,
dependencies)
except Exception, e:
- print "Exception: ", e
+ print >>sys.stderr, 'Exception: ', e
return None
@@ -569,6 +564,12 @@ def LoadTargetBuildFileParallel(build_file_path, data, aux_data,
parallel_state.condition.acquire()
while parallel_state.dependencies or parallel_state.pending:
if parallel_state.error:
+ print >>sys.stderr, (
+ '\n'
+ 'Note: an error occurred while running gyp using multiprocessing.\n'
+ 'For more verbose output, set GYP_PARALLEL=0 in your environment.\n'
+ 'If the error only occurs when GYP_PARALLEL=1, '
+ 'please report a bug!')
break
if not parallel_state.dependencies:
parallel_state.condition.wait()
@@ -608,32 +609,27 @@ def LoadTargetBuildFileParallel(build_file_path, data, aux_data,
# the input is something like "<(foo <(bar)) blah", then it would
# return (1, 13), indicating the entire string except for the leading
# "<" and trailing " blah".
-def FindEnclosingBracketGroup(input):
- brackets = { '}': '{',
- ']': '[',
- ')': '(', }
+LBRACKETS= set('{[(')
+BRACKETS = {'}': '{', ']': '[', ')': '('}
+def FindEnclosingBracketGroup(input_str):
stack = []
- count = 0
start = -1
- for char in input:
- if char in brackets.values():
+ for index, char in enumerate(input_str):
+ if char in LBRACKETS:
stack.append(char)
if start == -1:
- start = count
- if char in brackets.keys():
- try:
- last_bracket = stack.pop()
- except IndexError:
+ start = index
+ elif char in BRACKETS:
+ if not stack:
return (-1, -1)
- if last_bracket != brackets[char]:
+ if stack.pop() != BRACKETS[char]:
return (-1, -1)
- if len(stack) == 0:
- return (start, count + 1)
- count = count + 1
+ if not stack:
+ return (start, index + 1)
return (-1, -1)
-canonical_int_re = re.compile('^(0|-?[1-9][0-9]*)$')
+canonical_int_re = re.compile('(0|-?[1-9][0-9]*)$')
def IsStrCanonicalInt(string):
@@ -641,10 +637,7 @@ def IsStrCanonicalInt(string):
The canonical form is such that str(int(string)) == string.
"""
- if not isinstance(string, str) or not canonical_int_re.match(string):
- return False
-
- return True
+ return isinstance(string, str) and canonical_int_re.match(string)
# This matches things like "<(asdf)", "<!(cmd)", "<!@(cmd)", "<|(list)",
@@ -713,7 +706,7 @@ def ExpandVariables(input, phase, variables, build_file):
# Get the entire list of matches as a list of MatchObject instances.
# (using findall here would return strings instead of MatchObjects).
- matches = [match for match in variable_re.finditer(input_str)]
+ matches = list(variable_re.finditer(input_str))
if not matches:
return input_str
@@ -725,8 +718,7 @@ def ExpandVariables(input, phase, variables, build_file):
matches.reverse()
for match_group in matches:
match = match_group.groupdict()
- gyp.DebugOutput(gyp.DEBUG_VARIABLES,
- "Matches: %s" % repr(match))
+ gyp.DebugOutput(gyp.DEBUG_VARIABLES, "Matches: %r", match)
# match['replace'] is the substring to look for, match['type']
# is the character code for the replacement type (< > <! >! <| >| <@
# >@ <!@ >!@), match['is_array'] contains a '[' for command
@@ -839,8 +831,8 @@ def ExpandVariables(input, phase, variables, build_file):
cached_value = cached_command_results.get(cache_key, None)
if cached_value is None:
gyp.DebugOutput(gyp.DEBUG_VARIABLES,
- "Executing command '%s' in directory '%s'" %
- (contents,build_file_dir))
+ "Executing command '%s' in directory '%s'",
+ contents, build_file_dir)
replacement = ''
@@ -852,12 +844,17 @@ def ExpandVariables(input, phase, variables, build_file):
# <!(python modulename param eters). Do this in |build_file_dir|.
oldwd = os.getcwd() # Python doesn't like os.open('.'): no fchdir.
os.chdir(build_file_dir)
-
- parsed_contents = shlex.split(contents)
- py_module = __import__(parsed_contents[0])
- replacement = str(py_module.DoMain(parsed_contents[1:])).rstrip()
-
- os.chdir(oldwd)
+ try:
+
+ parsed_contents = shlex.split(contents)
+ try:
+ py_module = __import__(parsed_contents[0])
+ except ImportError as e:
+ raise GypError("Error importing pymod_do_main"
+ "module (%s): %s" % (parsed_contents[0], e))
+ replacement = str(py_module.DoMain(parsed_contents[1:])).rstrip()
+ finally:
+ os.chdir(oldwd)
assert replacement != None
elif command_string:
raise GypError("Unknown command string '%s' in '%s'." %
@@ -884,8 +881,8 @@ def ExpandVariables(input, phase, variables, build_file):
cached_command_results[cache_key] = replacement
else:
gyp.DebugOutput(gyp.DEBUG_VARIABLES,
- "Had cache value for command '%s' in directory '%s'" %
- (contents,build_file_dir))
+ "Had cache value for command '%s' in directory '%s'",
+ contents,build_file_dir)
replacement = cached_value
else:
@@ -960,8 +957,7 @@ def ExpandVariables(input, phase, variables, build_file):
# Look for more matches now that we've replaced some, to deal with
# expanding local variables (variables defined in the same
# variables block as this one).
- gyp.DebugOutput(gyp.DEBUG_VARIABLES,
- "Found output %s, recursing." % repr(output))
+ gyp.DebugOutput(gyp.DEBUG_VARIABLES, "Found output %r, recursing.", output)
if isinstance(output, list):
if output and isinstance(output[0], list):
# Leave output alone if it's a list of lists.
@@ -1062,7 +1058,7 @@ def ProcessConditionsInDict(the_dict, phase, variables, build_file):
except NameError, e:
gyp.common.ExceptionAppend(e, 'while evaluating condition \'%s\' in %s' %
(cond_expr_expanded, build_file))
- raise
+ raise GypError(e)
if merge_dict != None:
# Expand variables and nested conditinals in the merge_dict before
@@ -1407,6 +1403,25 @@ def RemoveDuplicateDependencies(targets):
target_dict[dependency_key] = Unify(dependencies)
+def Filter(l, item):
+ """Removes item from l."""
+ res = {}
+ return [res.setdefault(e, e) for e in l if e != item]
+
+
+def RemoveSelfDependencies(targets):
+ """Remove self dependencies from targets that have the prune_self_dependency
+ variable set."""
+ for target_name, target_dict in targets.iteritems():
+ for dependency_key in dependency_sections:
+ dependencies = target_dict.get(dependency_key, [])
+ if dependencies:
+ for t in dependencies:
+ if t == target_name:
+ if targets[t].get('variables', {}).get('prune_self_dependency', 0):
+ target_dict[dependency_key] = Filter(dependencies, target_name)
+
+
class DependencyGraphNode(object):
"""
@@ -1845,12 +1860,10 @@ def MakePathRelative(to_file, fro_file, item):
return ret
def MergeLists(to, fro, to_file, fro_file, is_paths=False, append=True):
- def is_hashable(x):
- try:
- hash(x)
- except TypeError:
- return False
- return True
+ # Python documentation recommends objects which do not support hash
+ # set this value to None. Python library objects follow this rule.
+ is_hashable = lambda val: val.__hash__
+
# If x is hashable, returns whether x is in s. Else returns whether x is in l.
def is_in_set_or_list(x, s, l):
if is_hashable(x):
@@ -1861,8 +1874,7 @@ def MergeLists(to, fro, to_file, fro_file, is_paths=False, append=True):
# Make membership testing of hashables in |to| (in particular, strings)
# faster.
- hashable_to_set = set([x for x in to if is_hashable(x)])
-
+ hashable_to_set = set(x for x in to if is_hashable(x))
for item in fro:
singleton = False
if isinstance(item, str) or isinstance(item, int):
@@ -2056,7 +2068,7 @@ def SetUpConfigurations(target, target_dict):
if not 'configurations' in target_dict:
target_dict['configurations'] = {'Default': {}}
if not 'default_configuration' in target_dict:
- concrete = [i for i in target_dict['configurations'].keys()
+ concrete = [i for i in target_dict['configurations'].iterkeys()
if not target_dict['configurations'][i].get('abstract')]
target_dict['default_configuration'] = sorted(concrete)[0]
@@ -2315,8 +2327,8 @@ def ValidateTargetType(target, target_dict):
def ValidateSourcesInTarget(target, target_dict, build_file):
- # TODO: Check if MSVC allows this for non-static_library targets.
- if target_dict.get('type', None) != 'static_library':
+ # TODO: Check if MSVC allows this for loadable_module targets.
+ if target_dict.get('type', None) not in ('static_library', 'shared_library'):
return
sources = target_dict.get('sources', [])
basenames = {}
@@ -2548,7 +2560,7 @@ def Load(build_files, variables, includes, depth, generator_input_info, check,
build_file = os.path.normpath(build_file)
try:
if parallel:
- print >>sys.stderr, 'Using parallel processing (experimental).'
+ print >>sys.stderr, 'Using parallel processing.'
LoadTargetBuildFileParallel(build_file, data, aux_data,
variables, includes, depth, check)
else:
@@ -2564,6 +2576,10 @@ def Load(build_files, variables, includes, depth, generator_input_info, check,
# Fully qualify all dependency links.
QualifyDependencies(targets)
+ # Remove self-dependencies from targets that have 'prune_self_dependencies'
+ # set to 1.
+ RemoveSelfDependencies(targets)
+
# Expand dependencies specified as build_file:*.
ExpandWildcardDependencies(targets, data)