GN flag to fail for unused build args.

This flag was requested by ChromeOS so their bot can notice if their build's args gets out of sync with Chrome's build files.

Also removes printing all possible build args on this error because we've gotten so many that's it's several screen-fulls of text and you can't even read the error.

BUG=605199

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

Cr-Original-Commit-Position: refs/heads/master@{#389407}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 12985c01ad47c1366920941f837fc2f323480c0e
diff --git a/tools/gn/args.cc b/tools/gn/args.cc
index 1034ea1..496ba18 100644
--- a/tools/gn/args.cc
+++ b/tools/gn/args.cc
@@ -194,25 +194,12 @@
   if (all_overrides.empty())
     return true;
 
-  // Get a list of all possible overrides for help with error finding.
-  //
-  // It might be nice to do edit distance checks to see if we can find one close
-  // to what you typed.
-  std::string all_declared_str;
-  for (const auto& map_pair : declared_arguments_per_toolchain_) {
-    for (const auto& cur_str : map_pair.second) {
-      if (!all_declared_str.empty())
-        all_declared_str += ", ";
-      all_declared_str += cur_str.first.as_string();
-    }
-  }
-
   *err = Err(
       all_overrides.begin()->second.origin(), "Build argument has no effect.",
       "The variable \"" + all_overrides.begin()->first.as_string() +
           "\" was set as a build argument\nbut never appeared in a " +
-          "declare_args() block in any buildfile.\n\nPossible arguments: " +
-          all_declared_str);
+          "declare_args() block in any buildfile.\n\n"
+          "To view possible args, run \"gn args --list <builddir>\"");
   return false;
 }
 
diff --git a/tools/gn/docs/reference.md b/tools/gn/docs/reference.md
index 600daea..7b345d7 100644
--- a/tools/gn/docs/reference.md
+++ b/tools/gn/docs/reference.md
@@ -70,7 +70,29 @@
 
 
 ```
-## **\--markdown**: write the output in the Markdown format.
+## **\--fail-on-unused-args**: Treat unused build args as fatal errors.
+
+```
+  If you set a value in a build's "gn args" and never use it in the
+  build (in a declare_args() block), GN will normally print an error
+  but not fail the build.
+
+  In many cases engineers would use build args to enable or disable
+  features that would sometimes get removed. It would by annoying to
+  block work for typically benign problems. In Chrome in particular,
+  flags might be configured for build bots in a separate infrastructure
+  repository, or a declare_args block might be changed in a third party
+  repository. Treating these errors as blocking forced complex multi-
+  way patches to land what would otherwise be simple changes.
+
+  In some cases, such concerns are not as important, and a mismatch
+  in build flags between the invoker of the build and the build files
+  represents a critical mismatch that should be immediately fixed. Such
+  users can set this flag to force GN to fail in that case.
+
+
+```
+## **\--markdown**: Write help output in the Markdown format.
 
 ## **\--[no]color**: Forces colored output on or off.
 
@@ -5925,7 +5947,8 @@
 **  \--args**: Specifies build arguments overrides.
 **  \--color**: Force colored output.
 **  \--dotfile**: Override the name of the ".gn" file.
-**  \--markdown**: write the output in the Markdown format.
+**  \--fail-on-unused-args**: Treat unused build args as fatal errors.
+**  \--markdown**: Write help output in the Markdown format.
 **  \--nocolor**: Force non-colored output.
 **  -q**: Quiet mode. Don't print output on success.
 **  \--root**: Explicitly specify source root.
diff --git a/tools/gn/setup.cc b/tools/gn/setup.cc
index 384a2af..7f8e286 100644
--- a/tools/gn/setup.cc
+++ b/tools/gn/setup.cc
@@ -332,9 +332,13 @@
     }
 
     if (!build_settings_.build_args().VerifyAllOverridesUsed(&err)) {
-      // TODO(brettw) implement a system of warnings. Until we have a better
-      // system, print the error but don't return failure.
+      // TODO(brettw) implement a system to have a different marker for
+      // warnings. Until we have a better system, print the error but don't
+      // return failure unless requested on the command line.
       err.PrintToStdout();
+      if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+              switches::kFailOnUnusedArgs))
+        return false;
       return true;
     }
   }
diff --git a/tools/gn/switches.cc b/tools/gn/switches.cc
index df167b3..45b25e6 100644
--- a/tools/gn/switches.cc
+++ b/tools/gn/switches.cc
@@ -69,11 +69,34 @@
     "  Note that this interacts with \"--root\" in a possibly incorrect way.\n"
     "  It would be nice to test the edge cases and document or fix.\n";
 
+const char kFailOnUnusedArgs[] = "fail-on-unused-args";
+const char kFailOnUnusedArgs_HelpShort[] =
+    "--fail-on-unused-args: Treat unused build args as fatal errors.";
+const char kFailOnUnusedArgs_Help[] =
+    "--fail-on-unused-args: Treat unused build args as fatal errors.\n"
+    "\n"
+    "  If you set a value in a build's \"gn args\" and never use it in the\n"
+    "  build (in a declare_args() block), GN will normally print an error\n"
+    "  but not fail the build.\n"
+    "\n"
+    "  In many cases engineers would use build args to enable or disable\n"
+    "  features that would sometimes get removed. It would by annoying to\n"
+    "  block work for typically benign problems. In Chrome in particular,\n"
+    "  flags might be configured for build bots in a separate infrastructure\n"
+    "  repository, or a declare_args block might be changed in a third party\n"
+    "  repository. Treating these errors as blocking forced complex multi-\n"
+    "  way patches to land what would otherwise be simple changes.\n"
+    "\n"
+    "  In some cases, such concerns are not as important, and a mismatch\n"
+    "  in build flags between the invoker of the build and the build files\n"
+    "  represents a critical mismatch that should be immediately fixed. Such\n"
+    "  users can set this flag to force GN to fail in that case.\n";
+
 const char kMarkdown[] = "markdown";
 const char kMarkdown_HelpShort[] =
-    "--markdown: write the output in the Markdown format.";
+    "--markdown: Write help output in the Markdown format.";
 const char kMarkdown_Help[] =
-    "--markdown: write the output in the Markdown format.\n";
+    "--markdown: Write help output in the Markdown format.\n";
 
 const char kNoColor[] = "nocolor";
 const char kNoColor_HelpShort[] =
@@ -223,6 +246,7 @@
     INSERT_VARIABLE(Args)
     INSERT_VARIABLE(Color)
     INSERT_VARIABLE(Dotfile)
+    INSERT_VARIABLE(FailOnUnusedArgs)
     INSERT_VARIABLE(Markdown)
     INSERT_VARIABLE(NoColor)
     INSERT_VARIABLE(Root)
diff --git a/tools/gn/switches.h b/tools/gn/switches.h
index 3dc5b9f..cebb19c 100644
--- a/tools/gn/switches.h
+++ b/tools/gn/switches.h
@@ -40,6 +40,10 @@
 extern const char kDotfile_HelpShort[];
 extern const char kDotfile_Help[];
 
+extern const char kFailOnUnusedArgs[];
+extern const char kFailOnUnusedArgs_HelpShort[];
+extern const char kFailOnUnusedArgs_Help[];
+
 extern const char kMarkdown[];
 extern const char kMarkdown_HelpShort[];
 extern const char kMarkdown_Help[];