New build flag system, convert Google Now flag

This generates headers with build flags rather than forcing them all to be global. It includes an accessor wrapper so that references to the flags will fail if the proper header is not included.

Converts Google Now to use this and remove the global google now define and grit define.

Adds support for grit define values of "true" and "false" for ease of integration with GN (they are mapped to the corresponding Python "True" and "False").

Adds dependencies from the main gyp targets to the new generated feature define target. Since GYP only does hard dependencies one level, this should reduce the chance that somebody adds more of these cases and forces to add a dependency.

Reland of https://codereview.chromium.org/1475513006/
Reland of https://codereview.chromium.org/1458653002/
TBR=mark@chromium.org

Review URL: https://codereview.chromium.org/1469383005

Cr-Commit-Position: refs/heads/master@{#361854}


CrOS-Libchrome-Original-Commit: 06c2ba3165d8b02364bf818d5028a7cb4fe48ac0
diff --git a/build/write_buildflag_header.py b/build/write_buildflag_header.py
new file mode 100755
index 0000000..d46cfc8
--- /dev/null
+++ b/build/write_buildflag_header.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+# Copyright 2015 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.
+
+# This writes headers for build flags. See buildflag_header.gni for usage of
+# this system as a whole.
+#
+# The parameters are passed in a response file so we don't have to worry
+# about command line lengths. The name of the response file is passed on the
+# command line.
+#
+# The format of the response file is:
+#    [--flags <list of one or more flag values>]
+
+import optparse
+import os
+import shlex
+import sys
+
+
+class Options:
+  def __init__(self, output, rulename, header_guard, flags):
+    self.output = output
+    self.rulename = rulename
+    self.header_guard = header_guard
+    self.flags = flags
+
+
+def GetOptions():
+  parser = optparse.OptionParser()
+  parser.add_option('--output', help="Output header name inside --gen-dir.")
+  parser.add_option('--rulename',
+                    help="Helpful name of build rule for including in the " +
+                         "comment at the top of the file.")
+  parser.add_option('--gen-dir',
+                    help="Path to root of generated file directory tree.")
+  parser.add_option('--definitions',
+                    help="Name of the response file containing the flags.")
+  cmdline_options, cmdline_flags = parser.parse_args()
+
+  # Compute header guard by replacing some chars with _ and upper-casing.
+  header_guard = cmdline_options.output.upper()
+  header_guard = \
+      header_guard.replace('/', '_').replace('\\', '_').replace('.', '_')
+  header_guard += '_'
+
+  # The actual output file is inside the gen dir.
+  output = os.path.join(cmdline_options.gen_dir, cmdline_options.output)
+
+  # Definition file in GYP is newline separated, in GN they are shell formatted.
+  # shlex can parse both of these.
+  with open(cmdline_options.definitions, 'r') as def_file:
+    defs = shlex.split(def_file.read())
+  flags_index = defs.index('--flags')
+
+  # Everything after --flags are flags. true/false are remapped to 1/0,
+  # everything else is passed through.
+  flags = []
+  for flag in defs[flags_index + 1 :]:
+    equals_index = flag.index('=')
+    key = flag[:equals_index]
+    value = flag[equals_index + 1:]
+
+    # Canonicalize and validate the value.
+    if value == 'true':
+      value = '1'
+    elif value == 'false':
+      value = '0'
+    flags.append((key, str(value)))
+
+  return Options(output=output,
+                 rulename=cmdline_options.rulename,
+                 header_guard=header_guard,
+                 flags=flags)
+
+
+def WriteHeader(options):
+  with open(options.output, 'w') as output_file:
+    output_file.write("// Generated by build/write_buildflag_header.py\n")
+    if options.rulename:
+      output_file.write('// From "' + options.rulename + '"\n')
+
+    output_file.write('\n#ifndef %s\n' % options.header_guard)
+    output_file.write('#define %s\n\n' % options.header_guard)
+    output_file.write('#include "build/buildflag.h"\n\n')
+
+    for pair in options.flags:
+      output_file.write('#define BUILDFLAG_INTERNAL_%s() (%s)\n' % pair)
+
+    output_file.write('\n#endif  // %s\n' % options.header_guard)
+
+
+options = GetOptions()
+WriteHeader(options)