[third_party/yasm] Add option to ignore errors.

Some asm files use defines from the asm (e.g. CONSTANT equ VALUE) in the
preprocessor %if tests. These cannot be referenced in a pass that only
preprocesses and that creates errors, but the dependencies will print
fine and invocations that also assemble will succeed.

TEST: Used in building ffmpeg and libvpx.
Change-Id: Ia5cb58b4af2580b3904d0966120f0e0b6ad095e3
diff --git a/run_yasm.py b/run_yasm.py
index 59e70dc..a144914 100755
--- a/run_yasm.py
+++ b/run_yasm.py
@@ -10,12 +10,23 @@
 management of .inc files.
 
 Run with:
-  python run_yasm.py <yasm_binary_path> <all other yasm args>
+  python run_yasm.py [options] <yasm_binary_path> <yasm args>
+
+Options:
+  --ignore-preprocess-only-errors: Ignore errors that occur during passes that
+                                   only preprocess the input and do not assemble
+                                   it.
 
 Note that <all other yasm args> must include an explicit output file (-o). This
 script will append a ".d" to this and write the dependencies there. This script
 will add "-M" to cause yasm to write the deps to stdout, so you don't need to
 specify that.
+
+If your preprocessor code references symbols defined in asm a preprocess only
+pass may yield errors. If the stdout for `-M` is the correct makefile deps,
+provide `--ignore-preprocess-only-errors` by adding
+`yasm_ignore_preprocess_only_errors = true` to your `yasm_assemble` target
+options.
 """
 
 import argparse
@@ -26,13 +37,18 @@
 # .d file with the same base name.
 parser = argparse.ArgumentParser()
 parser.add_argument("-o", dest="objfile")
+parser.add_argument("--ignore-preprocess-only-errors", action='store_true', dest="ignore_preprocess_only_errors")
 options, _ = parser.parse_known_args()
 
+invocation_start = 1
+if options.ignore_preprocess_only_errors:
+  invocation_start += 1
+
 objfile = options.objfile
 depfile = objfile + '.d'
 
 # Assemble.
-result_code = subprocess.call(sys.argv[1:])
+result_code = subprocess.call(sys.argv[invocation_start:])
 if result_code != 0:
   sys.exit(result_code)
 
@@ -46,7 +62,13 @@
 # we would have to require people to manually specify the .inc files they
 # depend on in the build file, which will surely be wrong or out-of-date in
 # some cases.
-deps = subprocess.check_output(sys.argv[1:] + ['-M'])
+proc = subprocess.Popen(sys.argv[invocation_start:] + ['-M'],
+                        stdout=subprocess.PIPE,
+                        stderr=subprocess.PIPE)
+deps, err = proc.communicate()
+if proc.returncode != 0 and not options.ignore_preprocess_only_errors:
+  print(err)
+  exit(proc.returncode)
 with open(depfile, "wb") as f:
   f.write(deps)
 
diff --git a/yasm_assemble.gni b/yasm_assemble.gni
index 677ae5a..f0f98d2 100644
--- a/yasm_assemble.gni
+++ b/yasm_assemble.gni
@@ -107,9 +107,15 @@
     args = [
       clang_prefix,
       rebase_path(run_yasm_script, root_build_dir),
-      "./" + rebase_path(yasm_path, root_build_dir),  # Force current dir.
     ]
 
+    if (defined(invoker.yasm_ignore_preprocess_only_errors) &&
+        invoker.yasm_ignore_preprocess_only_errors) {
+      args += [ "--ignore-preprocess-only-errors" ]
+    }
+
+    args += [ "./" + rebase_path(yasm_path, root_build_dir) ]  # Force current dir.
+
     # List the yasm binary as an input so the action is re-run when it changes.
     inputs += [ yasm_path ]
     if (defined(invoker.inputs)) {