| Index: tools/gypi_to_gn.py
|
| diff --git a/tools/gypi_to_gn.py b/tools/gypi_to_gn.py
|
| index 7cb1190c19df72b687599adf7342372a2c84972f..ca62a12b72433f77e56d9c8379bba022a8562564 100755
|
| --- a/tools/gypi_to_gn.py
|
| +++ b/tools/gypi_to_gn.py
|
| @@ -3,9 +3,9 @@
|
| # Use of this source code is governed by a BSD-style license that can be
|
| # found in the LICENSE file.
|
|
|
| -"""Converts given gypi files to a python scope and writes the result to stdout.
|
| +"""Converts a given gypi file to a python scope and writes the result to stdout.
|
|
|
| -It is assumed that the files contain a toplevel dictionary, and this script
|
| +It is assumed that the file contains a toplevel dictionary, and this script
|
| will return that dictionary as a GN "scope" (see example below). This script
|
| does not know anything about GYP and it will not expand variables or execute
|
| conditions.
|
| @@ -22,11 +22,10 @@ Say your_file.gypi looked like this:
|
| }
|
|
|
| You would call it like this:
|
| - gypi_files = [ "your_file.gypi", "your_other_file.gypi" ]
|
| gypi_values = exec_script("//build/gypi_to_gn.py",
|
| - [ rebase_path(gypi_files) ],
|
| + [ rebase_path("your_file.gypi") ],
|
| "scope",
|
| - [ gypi_files ])
|
| + [ "your_file.gypi" ])
|
|
|
| Notes:
|
| - The rebase_path call converts the gypi file from being relative to the
|
| @@ -42,14 +41,14 @@ Notes:
|
|
|
| Read the values into a target like this:
|
| component("mycomponent") {
|
| - sources = gypi_values.your_file_sources
|
| - defines = gypi_values.your_file_defines
|
| + sources = gypi_values.sources
|
| + defines = gypi_values.defines
|
| }
|
|
|
| Sometimes your .gypi file will include paths relative to a different
|
| directory than the current .gn file. In this case, you can rebase them to
|
| be relative to the current directory.
|
| - sources = rebase_path(gypi_values.your_files_sources, ".",
|
| + sources = rebase_path(gypi_values.sources, ".",
|
| "//path/gypi/input/values/are/relative/to")
|
|
|
| This script will tolerate a 'variables' in the toplevel dictionary or not. If
|
| @@ -74,7 +73,6 @@ the input will be replaced with "bar":
|
| import gn_helpers
|
| from optparse import OptionParser
|
| import sys
|
| -import os.path
|
|
|
| def LoadPythonDictionary(path):
|
| file_string = open(path).read()
|
| @@ -107,6 +105,30 @@ def LoadPythonDictionary(path):
|
| return file_data
|
|
|
|
|
| +def ReplaceSubstrings(values, search_for, replace_with):
|
| + """Recursively replaces substrings in a value.
|
| +
|
| + Replaces all substrings of the "search_for" with "repace_with" for all
|
| + strings occurring in "values". This is done by recursively iterating into
|
| + lists as well as the keys and values of dictionaries."""
|
| + if isinstance(values, str):
|
| + return values.replace(search_for, replace_with)
|
| +
|
| + if isinstance(values, list):
|
| + return [ReplaceSubstrings(v, search_for, replace_with) for v in values]
|
| +
|
| + if isinstance(values, dict):
|
| + # For dictionaries, do the search for both the key and values.
|
| + result = {}
|
| + for key, value in values.items():
|
| + new_key = ReplaceSubstrings(key, search_for, replace_with)
|
| + new_value = ReplaceSubstrings(value, search_for, replace_with)
|
| + result[new_key] = new_value
|
| + return result
|
| +
|
| + # Assume everything else is unchanged.
|
| + return values
|
| +
|
| def KeepOnly(values, filters):
|
| """Recursively filters out strings not ending in "f" from "values"""
|
|
|
| @@ -125,41 +147,37 @@ def KeepOnly(values, filters):
|
|
|
| def main():
|
| parser = OptionParser()
|
| + parser.add_option("-r", "--replace", action="append",
|
| + help="Replaces substrings. If passed a=b, replaces all substrs a with b.")
|
| parser.add_option("-k", "--keep_only", default = [], action="append",
|
| help="Keeps only files ending with the listed strings.")
|
| - parser.add_option("--prefix", action="store_true",
|
| - help="Prefix variables with base name")
|
| (options, args) = parser.parse_args()
|
|
|
| - if len(args) < 1:
|
| - raise Exception("Need at least one .gypi file to read.")
|
| -
|
| - data = {}
|
| -
|
| - for gypi in args:
|
| - gypi_data = LoadPythonDictionary(gypi)
|
| -
|
| - if options.keep_only != []:
|
| - gypi_data = KeepOnly(gypi_data, options.keep_only)
|
| -
|
| - # Sometimes .gypi files use the GYP syntax with percents at the end of the
|
| - # variable name (to indicate not to overwrite a previously-defined value):
|
| - # 'foo%': 'bar',
|
| - # Convert these to regular variables.
|
| - for key in gypi_data:
|
| - if len(key) > 1 and key[len(key) - 1] == '%':
|
| - gypi_data[key[:-1]] = gypi_data[key]
|
| - del gypi_data[key]
|
| - gypi_name = os.path.basename(gypi)[:-len(".gypi")]
|
| - for key in gypi_data:
|
| - if options.prefix:
|
| - # Prefix all variables from this gypi file with the name to disambiguate
|
| - data[gypi_name + "_" + key] = gypi_data[key]
|
| - elif key in data:
|
| - for entry in gypi_data[key]:
|
| - data[key].append(entry)
|
| - else:
|
| - data[key] = gypi_data[key]
|
| + if len(args) != 1:
|
| + raise Exception("Need one argument which is the .gypi file to read.")
|
| +
|
| + data = LoadPythonDictionary(args[0])
|
| + if options.replace:
|
| + # Do replacements for all specified patterns.
|
| + for replace in options.replace:
|
| + split = replace.split('=')
|
| + # Allow "foo=" to replace with nothing.
|
| + if len(split) == 1:
|
| + split.append('')
|
| + assert len(split) == 2, "Replacement must be of the form 'key=value'."
|
| + data = ReplaceSubstrings(data, split[0], split[1])
|
| +
|
| + if options.keep_only != []:
|
| + data = KeepOnly(data, options.keep_only)
|
| +
|
| + # Sometimes .gypi files use the GYP syntax with percents at the end of the
|
| + # variable name (to indicate not to overwrite a previously-defined value):
|
| + # 'foo%': 'bar',
|
| + # Convert these to regular variables.
|
| + for key in data:
|
| + if len(key) > 1 and key[len(key) - 1] == '%':
|
| + data[key[:-1]] = data[key]
|
| + del data[key]
|
|
|
| print gn_helpers.ToGNString(data)
|
|
|
|
|