Use GN to copy crt objects into fusl sysroot

We can avoid using the external script and copy the crt files directly
using GN and Ninja.

BUG=#619
R=kulakowski@chromium.org

Review URL: https://codereview.chromium.org/1628443003 .
diff --git a/fusl/BUILD.gn b/fusl/BUILD.gn
index a03a358..a352bcb 100644
--- a/fusl/BUILD.gn
+++ b/fusl/BUILD.gn
@@ -1472,48 +1472,57 @@
 sysroot_lib_dir = "${sysroot}/usr/lib"
 sysroot_include_dir = "${sysroot}/usr/include"
 
-action("copy_crt_objects") {
-  deps = [
-    ":crt",
-  ]
-  script = "tools/copy_crt.py"
-
-  args = [
-    "--source",
-    rebase_path("${target_out_dir}/crt", root_build_dir),
-
-    "--target",
-    rebase_path("${sysroot_lib_dir}", root_build_dir),
-
-    # GN mangling prefix. It corresponds to e.g. the first few
-    # characters of "crt.Scrt1.o". This is included to catch some of
-    # the brittleness in this script, which depends on where exactly
-    # GN places and names things. If this changes, this and the
-    # following path names must also change.
-    "--gn-prefix",
-    "crt.",
-
-    # Object files.
-    "crt.Scrt1.o",
-    "crt.crt1.o",
-    "crt.rcrt1.o",
-  ]
-
-  # Arch-specific object files.
-  if (current_cpu == "x64") {
-    args += [
-      "x86_64/crt.crti.o",
-      "x86_64/crt.crtn.o",
-    ]
+template("copy_objects") {
+  assert(defined(invoker.input_dir), "input_dir must be defined")
+  assert(defined(invoker.output_dir), "output_dir must be defined")
+  object_prefix = ""
+  if (defined(invoker.object_prefix)) {
+    object_prefix = invoker.object_prefix
   }
+  foreach(file, invoker.sources) {
+    copy("copy_${file}") {
+      sources = [
+        rebase_path("${invoker.input_dir}/${object_prefix}${file}",
+                    "",
+                    target_out_dir),
+      ]
+      outputs = [
+        "${invoker.output_dir}/${file}",
+      ]
+      deps = [
+        ":crt",
+      ]
+    }
+  }
+  group(target_name) {
+    deps = [
+      ":crt",
+    ]
+    foreach(file, invoker.sources) {
+      deps += [ ":copy_$file" ]
+    }
+  }
+}
 
-  outputs = [
-    "${sysroot_lib_dir}/Scrt1.o",
-    "${sysroot_lib_dir}/crt1.o",
-    "${sysroot_lib_dir}/crti.o",
-    "${sysroot_lib_dir}/crtn.o",
-    "${sysroot_lib_dir}/rcrt1.o",
+copy_objects("copy_crt_objects") {
+  sources = [
+    "Scrt1.o",
+    "crt1.o",
+    "rcrt1.o",
   ]
+  object_prefix = "crt."
+  input_dir = "crt"
+  output_dir = "${sysroot_lib_dir}"
+}
+
+copy_objects("copy_crt_x64_objects") {
+  sources = [
+    "crti.o",
+    "crtn.o",
+  ]
+  object_prefix = "crt."
+  input_dir = "crt/x86_64"
+  output_dir = "${sysroot_lib_dir}"
 }
 
 copy("copy_include") {
@@ -1558,6 +1567,9 @@
     ":copy_include_bits",
     ":copy_libc",
   ]
+  if (current_cpu == "x64") {
+    deps += [ ":copy_crt_x64_objects" ]
+  }
 }
 
 group("fusl") {
diff --git a/fusl/tools/copy_crt.py b/fusl/tools/copy_crt.py
deleted file mode 100755
index 5041465..0000000
--- a/fusl/tools/copy_crt.py
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2016 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.
-
-"""A tool to populate the C runtime portions of a fusl sysroot. This
-script primarily exists because it is easier to copy manually than to
-teach GN how to treat .o files as first class outputs."""
-
-import argparse
-import os
-import shutil
-import sys
-
-def copy_sysroot(args, files):
-  try:
-    os.makedirs(args.target)
-  except OSError:
-    # It already exists. Probably.
-    pass
-
-  for file in files:
-    source_file = os.path.join(args.source, file)
-
-  # Some source files will be under a subdirectory, so take the last
-  # path component.
-  _, stripped_file = os.path.split(source_file)
-  # Strip out the prefix gn places for its object files.
-  assert(stripped_file.startswith(args.gn_prefix))
-  stripped_file = stripped_file[len(args.gn_prefix):]
-  target_file = os.path.join(args.target, stripped_file)
-
-  shutil.copyfile(source_file, target_file)
-
-
-def parse():
-  parser = argparse.ArgumentParser()
-
-  parser.add_argument('--source',
-                      required=True,
-                      help='Source directory')
-  parser.add_argument('--target',
-                      required=True,
-                      help='Target directory')
-  parser.add_argument('--gn-prefix',
-                      required=True,
-                      help='File prefix added by GN')
-
-  return parser.parse_known_args()
-
-
-def main():
-  args, files = parse()
-  copy_sysroot(args, files)
-  return 0
-
-
-if __name__ == '__main__':
-  sys.exit(main())