roll ANGLE w/ GN update

ANGLE switched their .gypi files to .gni files this commit,
so we need to make a small tweak to update our ANGLE build.

This removes the last use of gypi_to_gn.py, and in turn gn_helpers.py.

CQ_INCLUDE_TRYBOTS=skia.primary:Build-Debian9-Clang-x86_64-Release-ANGLE;skia.primary:Perf-Win10-Clang-AlphaR2-GPU-RadeonR9M470X-x86_64-Debug-All-ANGLE;skia.primary:Perf-Win10-Clang-NUC5i7RYH-GPU-IntelIris6100-x86_64-Debug-All-ANGLE;skia.primary:Perf-Win10-Clang-NUC6i5SYK-GPU-IntelIris540-x86_64-Debug-All-ANGLE;skia.primary:Perf-Win10-Clang-NUCD34010WYKH-GPU-IntelHD4400-x86_64-Debug-All-ANGLE;skia.primary:Perf-Win10-Clang-ShuttleC-GPU-GTX960-x86_64-Debug-All-ANGLE;skia.primary:Test-Win10-Clang-AlphaR2-GPU-RadeonR9M470X-x86_64-Debug-All-ANGLE;skia.primary:Test-Win10-Clang-NUC6i5SYK-GPU-IntelIris540-x86_64-Debug-All-ANGLE;skia.primary:Test-Win10-Clang-NUCD34010WYKH-GPU-IntelHD4400-x86_64-Debug-All-ANGLE;skia.primary:Test-Win10-Clang-ShuttleC-GPU-GTX960-x86_64-Debug-All-ANGLE


Change-Id: I76c8a667e7c5c27dc4cd18ba0d932bfc2de38cf9
Reviewed-on: https://skia-review.googlesource.com/150541
Reviewed-by: Stephan Altmueller <stephana@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
diff --git a/DEPS b/DEPS
index 4d25609..e296b00 100644
--- a/DEPS
+++ b/DEPS
@@ -7,7 +7,7 @@
 deps = {
   "buildtools"                            : "https://chromium.googlesource.com/chromium/buildtools.git@505de88083136eefd056e5ee4ca0f01fe9b33de8",
   "common"                                : "https://skia.googlesource.com/common.git@9737551d7a52c3db3262db5856e6bcd62c462b92",
-  "third_party/externals/angle2"          : "https://chromium.googlesource.com/angle/angle.git@1e1b731a98955fb4fe9cd5a17887e2abcdb283d5",
+  "third_party/externals/angle2"          : "https://chromium.googlesource.com/angle/angle.git@ddc41208c15ffd9aae99e3ac6c9d59a09df914d9",
   "third_party/externals/dng_sdk"         : "https://android.googlesource.com/platform/external/dng_sdk.git@96443b262250c390b0caefbf3eed8463ba35ecae",
   "third_party/externals/egl-registry"    : "https://skia.googlesource.com/external/github.com/KhronosGroup/EGL-Registry@a0bca08de07c7d7651047bedc0b653cfaaa4f2ae",
   "third_party/externals/expat"           : "https://android.googlesource.com/platform/external/expat.git@android-6.0.1_r55",
diff --git a/gn/gn_helpers.py b/gn/gn_helpers.py
deleted file mode 100644
index fb94d54..0000000
--- a/gn/gn_helpers.py
+++ /dev/null
@@ -1,351 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Helper functions useful when writing scripts that integrate with GN.
-
-The main functions are ToGNString and FromGNString which convert between
-serialized GN veriables and Python variables.
-
-To use in a random python file in the build:
-
-  import os
-  import sys
-
-  sys.path.append(os.path.join(os.path.dirname(__file__),
-                               os.pardir, os.pardir, "build"))
-  import gn_helpers
-
-Where the sequence of parameters to join is the relative path from your source
-file to the build directory."""
-
-class GNException(Exception):
-  pass
-
-
-def ToGNString(value, allow_dicts = True):
-  """Returns a stringified GN equivalent of the Python value.
-
-  allow_dicts indicates if this function will allow converting dictionaries
-  to GN scopes. This is only possible at the top level, you can't nest a
-  GN scope in a list, so this should be set to False for recursive calls."""
-  if isinstance(value, basestring):
-    if value.find('\n') >= 0:
-      raise GNException("Trying to print a string with a newline in it.")
-    return '"' + \
-        value.replace('\\', '\\\\').replace('"', '\\"').replace('$', '\\$') + \
-        '"'
-
-  if isinstance(value, unicode):
-    return ToGNString(value.encode('utf-8'))
-
-  if isinstance(value, bool):
-    if value:
-      return "true"
-    return "false"
-
-  if isinstance(value, list):
-    return '[ %s ]' % ', '.join(ToGNString(v) for v in value)
-
-  if isinstance(value, dict):
-    if not allow_dicts:
-      raise GNException("Attempting to recursively print a dictionary.")
-    result = ""
-    for key in sorted(value):
-      if not isinstance(key, basestring):
-        raise GNException("Dictionary key is not a string.")
-      result += "%s = %s\n" % (key, ToGNString(value[key], False))
-    return result
-
-  if isinstance(value, int):
-    return str(value)
-
-  raise GNException("Unsupported type when printing to GN.")
-
-
-def FromGNString(input_):
-  """Converts the input string from a GN serialized value to Python values.
-
-  For details on supported types see GNValueParser.Parse() below.
-
-  If your GN script did:
-    something = [ "file1", "file2" ]
-    args = [ "--values=$something" ]
-  The command line would look something like:
-    --values="[ \"file1\", \"file2\" ]"
-  Which when interpreted as a command line gives the value:
-    [ "file1", "file2" ]
-
-  You can parse this into a Python list using GN rules with:
-    input_values = FromGNValues(options.values)
-  Although the Python 'ast' module will parse many forms of such input, it
-  will not handle GN escaping properly, nor GN booleans. You should use this
-  function instead.
-
-
-  A NOTE ON STRING HANDLING:
-
-  If you just pass a string on the command line to your Python script, or use
-  string interpolation on a string variable, the strings will not be quoted:
-    str = "asdf"
-    args = [ str, "--value=$str" ]
-  Will yield the command line:
-    asdf --value=asdf
-  The unquoted asdf string will not be valid input to this function, which
-  accepts only quoted strings like GN scripts. In such cases, you can just use
-  the Python string literal directly.
-
-  The main use cases for this is for other types, in particular lists. When
-  using string interpolation on a list (as in the top example) the embedded
-  strings will be quoted and escaped according to GN rules so the list can be
-  re-parsed to get the same result."""
-  parser = GNValueParser(input_)
-  return parser.Parse()
-
-
-def FromGNArgs(input_):
-  """Converts a string with a bunch of gn arg assignments into a Python dict.
-
-  Given a whitespace-separated list of
-
-    <ident> = (integer | string | boolean | <list of the former>)
-
-  gn assignments, this returns a Python dict, i.e.:
-
-    FromGNArgs("foo=true\nbar=1\n") -> { 'foo': True, 'bar': 1 }.
-
-  Only simple types and lists supported; variables, structs, calls
-  and other, more complicated things are not.
-
-  This routine is meant to handle only the simple sorts of values that
-  arise in parsing --args.
-  """
-  parser = GNValueParser(input_)
-  return parser.ParseArgs()
-
-
-def UnescapeGNString(value):
-  """Given a string with GN escaping, returns the unescaped string.
-
-  Be careful not to feed with input from a Python parsing function like
-  'ast' because it will do Python unescaping, which will be incorrect when
-  fed into the GN unescaper."""
-  result = ''
-  i = 0
-  while i < len(value):
-    if value[i] == '\\':
-      if i < len(value) - 1:
-        next_char = value[i + 1]
-        if next_char in ('$', '"', '\\'):
-          # These are the escaped characters GN supports.
-          result += next_char
-          i += 1
-        else:
-          # Any other backslash is a literal.
-          result += '\\'
-    else:
-      result += value[i]
-    i += 1
-  return result
-
-
-def _IsDigitOrMinus(char):
-  return char in "-0123456789"
-
-
-class GNValueParser(object):
-  """Duplicates GN parsing of values and converts to Python types.
-
-  Normally you would use the wrapper function FromGNValue() below.
-
-  If you expect input as a specific type, you can also call one of the Parse*
-  functions directly. All functions throw GNException on invalid input. """
-  def __init__(self, string):
-    self.input = string
-    self.cur = 0
-
-  def IsDone(self):
-    return self.cur == len(self.input)
-
-  def ConsumeWhitespace(self):
-    while not self.IsDone() and self.input[self.cur] in ' \t\n':
-      self.cur += 1
-
-  def Parse(self):
-    """Converts a string representing a printed GN value to the Python type.
-
-    See additional usage notes on FromGNString above.
-
-    - GN booleans ('true', 'false') will be converted to Python booleans.
-
-    - GN numbers ('123') will be converted to Python numbers.
-
-    - GN strings (double-quoted as in '"asdf"') will be converted to Python
-      strings with GN escaping rules. GN string interpolation (embedded
-      variables preceeded by $) are not supported and will be returned as
-      literals.
-
-    - GN lists ('[1, "asdf", 3]') will be converted to Python lists.
-
-    - GN scopes ('{ ... }') are not supported."""
-    result = self._ParseAllowTrailing()
-    self.ConsumeWhitespace()
-    if not self.IsDone():
-      raise GNException("Trailing input after parsing:\n  " +
-                        self.input[self.cur:])
-    return result
-
-  def ParseArgs(self):
-    """Converts a whitespace-separated list of ident=literals to a dict.
-
-    See additional usage notes on FromGNArgs, above.
-    """
-    d = {}
-
-    self.ConsumeWhitespace()
-    while not self.IsDone():
-      ident = self._ParseIdent()
-      self.ConsumeWhitespace()
-      if self.input[self.cur] != '=':
-        raise GNException("Unexpected token: " + self.input[self.cur:])
-      self.cur += 1
-      self.ConsumeWhitespace()
-      val = self._ParseAllowTrailing()
-      self.ConsumeWhitespace()
-      d[ident] = val
-
-    return d
-
-  def _ParseAllowTrailing(self):
-    """Internal version of Parse that doesn't check for trailing stuff."""
-    self.ConsumeWhitespace()
-    if self.IsDone():
-      raise GNException("Expected input to parse.")
-
-    next_char = self.input[self.cur]
-    if next_char == '[':
-      return self.ParseList()
-    elif _IsDigitOrMinus(next_char):
-      return self.ParseNumber()
-    elif next_char == '"':
-      return self.ParseString()
-    elif self._ConstantFollows('true'):
-      return True
-    elif self._ConstantFollows('false'):
-      return False
-    else:
-      raise GNException("Unexpected token: " + self.input[self.cur:])
-
-  def _ParseIdent(self):
-    id_ = ''
-
-    next_char = self.input[self.cur]
-    if not next_char.isalpha() and not next_char=='_':
-      raise GNException("Expected an identifier: " + self.input[self.cur:])
-
-    id_ += next_char
-    self.cur += 1
-
-    next_char = self.input[self.cur]
-    while next_char.isalpha() or next_char.isdigit() or next_char=='_':
-      id_ += next_char
-      self.cur += 1
-      next_char = self.input[self.cur]
-
-    return id_
-
-  def ParseNumber(self):
-    self.ConsumeWhitespace()
-    if self.IsDone():
-      raise GNException('Expected number but got nothing.')
-
-    begin = self.cur
-
-    # The first character can include a negative sign.
-    if not self.IsDone() and _IsDigitOrMinus(self.input[self.cur]):
-      self.cur += 1
-    while not self.IsDone() and self.input[self.cur].isdigit():
-      self.cur += 1
-
-    number_string = self.input[begin:self.cur]
-    if not len(number_string) or number_string == '-':
-      raise GNException("Not a valid number.")
-    return int(number_string)
-
-  def ParseString(self):
-    self.ConsumeWhitespace()
-    if self.IsDone():
-      raise GNException('Expected string but got nothing.')
-
-    if self.input[self.cur] != '"':
-      raise GNException('Expected string beginning in a " but got:\n  ' +
-                        self.input[self.cur:])
-    self.cur += 1  # Skip over quote.
-
-    begin = self.cur
-    while not self.IsDone() and self.input[self.cur] != '"':
-      if self.input[self.cur] == '\\':
-        self.cur += 1  # Skip over the backslash.
-        if self.IsDone():
-          raise GNException("String ends in a backslash in:\n  " +
-                            self.input)
-      self.cur += 1
-
-    if self.IsDone():
-      raise GNException('Unterminated string:\n  ' + self.input[begin:])
-
-    end = self.cur
-    self.cur += 1  # Consume trailing ".
-
-    return UnescapeGNString(self.input[begin:end])
-
-  def ParseList(self):
-    self.ConsumeWhitespace()
-    if self.IsDone():
-      raise GNException('Expected list but got nothing.')
-
-    # Skip over opening '['.
-    if self.input[self.cur] != '[':
-      raise GNException("Expected [ for list but got:\n  " +
-                        self.input[self.cur:])
-    self.cur += 1
-    self.ConsumeWhitespace()
-    if self.IsDone():
-      raise GNException("Unterminated list:\n  " + self.input)
-
-    list_result = []
-    previous_had_trailing_comma = True
-    while not self.IsDone():
-      if self.input[self.cur] == ']':
-        self.cur += 1  # Skip over ']'.
-        return list_result
-
-      if not previous_had_trailing_comma:
-        raise GNException("List items not separated by comma.")
-
-      list_result += [ self._ParseAllowTrailing() ]
-      self.ConsumeWhitespace()
-      if self.IsDone():
-        break
-
-      # Consume comma if there is one.
-      previous_had_trailing_comma = self.input[self.cur] == ','
-      if previous_had_trailing_comma:
-        # Consume comma.
-        self.cur += 1
-        self.ConsumeWhitespace()
-
-    raise GNException("Unterminated list:\n  " + self.input)
-
-  def _ConstantFollows(self, constant):
-    """Returns true if the given constant follows immediately at the current
-    location in the input. If it does, the text is consumed and the function
-    returns true. Otherwise, returns false and the current position is
-    unchanged."""
-    end = self.cur + len(constant)
-    if end > len(self.input):
-      return False  # Not enough room.
-    if self.input[self.cur:end] == constant:
-      self.cur = end
-      return True
-    return False
diff --git a/gn/gypi_to_gn.py b/gn/gypi_to_gn.py
deleted file mode 100755
index c4f31ae..0000000
--- a/gn/gypi_to_gn.py
+++ /dev/null
@@ -1,193 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Converts a given gypi file to a python scope and writes the result to stdout.
-
-USING THIS SCRIPT IN CHROMIUM
-
-Forking Python to run this script in the middle of GN is slow, especially on
-Windows, and it makes both the GYP and GN files harder to follow. You can't
-use "git grep" to find files in the GN build any more, and tracking everything
-in GYP down requires a level of indirection. Any calls will have to be removed
-and cleaned up once the GYP-to-GN transition is complete.
-
-As a result, we only use this script when the list of files is large and
-frequently-changing. In these cases, having one canonical list outweights the
-downsides.
-
-As of this writing, the GN build is basically complete. It's likely that all
-large and frequently changing targets where this is appropriate use this
-mechanism already. And since we hope to turn down the GYP build soon, the time
-horizon is also relatively short. As a result, it is likely that no additional
-uses of this script should every be added to the build. During this later part
-of the transition period, we should be focusing more and more on the absolute
-readability of the GN build.
-
-
-HOW TO USE
-
-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.
-
-It will strip conditions blocks.
-
-A variables block at the top level will be flattened so that the variables
-appear in the root dictionary. This way they can be returned to the GN code.
-
-Say your_file.gypi looked like this:
-  {
-     'sources': [ 'a.cc', 'b.cc' ],
-     'defines': [ 'ENABLE_DOOM_MELON' ],
-  }
-
-You would call it like this:
-  gypi_values = exec_script("//build/gypi_to_gn.py",
-                            [ rebase_path("your_file.gypi") ],
-                            "scope",
-                            [ "your_file.gypi" ])
-
-Notes:
- - The rebase_path call converts the gypi file from being relative to the
-   current build file to being system absolute for calling the script, which
-   will have a different current directory than this file.
-
- - The "scope" parameter tells GN to interpret the result as a series of GN
-   variable assignments.
-
- - The last file argument to exec_script tells GN that the given file is a
-   dependency of the build so Ninja can automatically re-run GN if the file
-   changes.
-
-Read the values into a target like this:
-  component("mycomponent") {
-    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.sources, ".",
-                        "//path/gypi/input/values/are/relative/to")
-
-This script will tolerate a 'variables' in the toplevel dictionary or not. If
-the toplevel dictionary just contains one item called 'variables', it will be
-collapsed away and the result will be the contents of that dictinoary. Some
-.gypi files are written with or without this, depending on how they expect to
-be embedded into a .gyp file.
-
-This script also has the ability to replace certain substrings in the input.
-Generally this is used to emulate GYP variable expansion. If you passed the
-argument "--replace=<(foo)=bar" then all instances of "<(foo)" in strings in
-the input will be replaced with "bar":
-
-  gypi_values = exec_script("//build/gypi_to_gn.py",
-                            [ rebase_path("your_file.gypi"),
-                              "--replace=<(foo)=bar"],
-                            "scope",
-                            [ "your_file.gypi" ])
-
-"""
-
-import gn_helpers
-from optparse import OptionParser
-import sys
-
-def LoadPythonDictionary(path):
-  file_string = open(path).read()
-  try:
-    file_data = eval(file_string, {'__builtins__': None}, None)
-  except SyntaxError, e:
-    e.filename = path
-    raise
-  except Exception, e:
-    raise Exception("Unexpected error while reading %s: %s" % (path, str(e)))
-
-  assert isinstance(file_data, dict), "%s does not eval to a dictionary" % path
-
-  # Flatten any variables to the top level.
-  if 'variables' in file_data:
-    file_data.update(file_data['variables'])
-    del file_data['variables']
-
-  # Strip all elements that this script can't process.
-  elements_to_strip = [
-    'conditions',
-    'target_conditions',
-    'targets',
-    'includes',
-    'actions',
-  ]
-  for element in elements_to_strip:
-    if element in file_data:
-      del file_data[element]
-
-  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 main():
-  parser = OptionParser()
-  parser.add_option("-r", "--replace", action="append",
-    help="Replaces substrings. If passed a=b, replaces all substrs a with b.")
-  (options, args) = parser.parse_args()
-
-  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])
-
-  # 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)
-
-if __name__ == '__main__':
-  try:
-    main()
-  except Exception, e:
-    print str(e)
-    sys.exit(1)
diff --git a/third_party/angle2/BUILD.gn b/third_party/angle2/BUILD.gn
index d36626d..752cf0b 100644
--- a/third_party/angle2/BUILD.gn
+++ b/third_party/angle2/BUILD.gn
@@ -9,6 +9,8 @@
 angle_root = "../externals/angle2"
 
 import("../third_party.gni")
+import("$angle_root/src/compiler.gni")
+import("$angle_root/src/libGLESv2.gni")
 
 third_party("angle2") {
   public_include_dirs = [ "$angle_root/include" ]
@@ -18,16 +20,6 @@
   ]
 }
 
-compiler_gypi = exec_script("//gn/gypi_to_gn.py",
-                            [ rebase_path("$angle_root/src/compiler.gypi") ],
-                            "scope",
-                            [])
-
-gles_gypi = exec_script("//gn/gypi_to_gn.py",
-                        [ rebase_path("$angle_root/src/libGLESv2.gypi") ],
-                        "scope",
-                        [])
-
 config("common") {
   defines = [
     "ANGLE_ENABLE_ESSL",
@@ -93,14 +85,11 @@
   ]
   libs = []
   sources = rebase_path(
-          compiler_gypi.angle_preprocessor_sources +
-              compiler_gypi.angle_translator_sources +
-              compiler_gypi.angle_translator_essl_sources +
-              compiler_gypi.angle_translator_glsl_sources +
-              compiler_gypi.angle_translator_hlsl_sources +
-              gles_gypi.libangle_sources + gles_gypi.libangle_common_sources +
-              gles_gypi.libangle_image_util_sources +
-              gles_gypi.libglesv2_sources + gles_gypi.libangle_gl_sources,
+          angle_preprocessor_sources + angle_translator_sources +
+              angle_translator_essl_sources + angle_translator_glsl_sources +
+              angle_translator_hlsl_sources + libangle_sources +
+              libangle_common_sources + libangle_image_util_sources +
+              libglesv2_sources + libangle_gl_sources,
           ".",
           "$angle_root/src")
   if (is_win) {
@@ -112,23 +101,21 @@
       "Xi",
       "Xext",
     ]
-    sources += rebase_path(gles_gypi.libangle_gl_glx_sources +
-                               gles_gypi.libangle_common_linux_sources,
-                           ".",
-                           "$angle_root/src") +
-               [ "$angle_root/src/third_party/libXNVCtrl/NVCtrl.c" ]
+    sources +=
+        rebase_path(libangle_gl_glx_sources + libangle_common_linux_sources,
+                    ".",
+                    "$angle_root/src") +
+        [ "$angle_root/src/third_party/libXNVCtrl/NVCtrl.c" ]
   } else if (is_win) {
     defines += [
       # TODO: ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES
     ]
-    sources += rebase_path(gles_gypi.libangle_gl_wgl_sources +
-                               gles_gypi.libangle_d3d_shared_sources +
-                               gles_gypi.libangle_d3d9_sources +
-                               gles_gypi.libangle_d3d11_sources +
-                               gles_gypi.libangle_d3d11_win32_sources +
-                               gles_gypi.libangle_common_win_sources,
-                           ".",
-                           "$angle_root/src")
+    sources += rebase_path(
+            libangle_gl_wgl_sources + libangle_d3d_shared_sources +
+                libangle_d3d9_sources + libangle_d3d11_sources +
+                libangle_d3d11_win32_sources + libangle_common_win_sources,
+            ".",
+            "$angle_root/src")
     libs += [
       "d3d9.lib",
       "dxguid.lib",
@@ -148,7 +135,7 @@
   deps = [
     ":libGLESv2",
   ]
-  sources = rebase_path(gles_gypi.libegl_sources, ".", "$angle_root/src")
+  sources = rebase_path(libegl_sources, ".", "$angle_root/src")
   if (is_win) {
     sources += [ "$angle_root/src/libEGL/libEGL.def" ]
   }