[libc++] Execute tests from the Lit execution root instead of the test tree

Instead of executing tests from within the libc++ test suite, we execute
them from the Lit execution directory. However, since some tests have
file dependencies, we must copy those dependencies to the execution
directory where they are executed.

This has the major benefit that if a test modifies a file (whether it
is wanted or not), other tests will not see those modifications. This
is good because current tests assume that input data is never modified,
however this could be an incorrect assumption if some test does not
behave properly.

Cr-Mirrored-From: https://chromium.googlesource.com/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: ff09135fc2b7a9696f87a8a8e89be2ef777895d3
diff --git a/utils/run.py b/utils/run.py
index 6a89a2b..7de82c7 100644
--- a/utils/run.py
+++ b/utils/run.py
@@ -14,14 +14,15 @@
 
 import argparse
 import os
+import shutil
 import subprocess
 import sys
+import tempfile
 
 
 def main():
     parser = argparse.ArgumentParser()
     parser.add_argument('--codesign_identity', type=str, required=False)
-    parser.add_argument('--working_directory', type=str, required=True)
     parser.add_argument('--dependencies', type=str, nargs='*', required=True)
     parser.add_argument('--env', type=str, nargs='*', required=True)
     (args, remaining) = parser.parse_known_args(sys.argv[1:])
@@ -42,14 +43,23 @@
     # Extract environment variables into a dictionary
     env = {k : v  for (k, v) in map(lambda s: s.split('=', 1), args.env)}
 
-    # Ensure the file dependencies exist
-    for file in args.dependencies:
-        if not os.path.exists(file):
-            sys.stderr.write('Missing file {} marked as a dependency of a test'.format(file))
-            exit(1)
+    try:
+        tmpDir = tempfile.mkdtemp()
 
-    # Run the executable with the given environment in the given working directory
-    return subprocess.call(' '.join(remaining), cwd=args.working_directory, env=env, shell=True)
+        # Ensure the file dependencies exist and copy them to a temporary directory.
+        for dep in args.dependencies:
+            if not os.path.exists(dep):
+                sys.stderr.write('Missing file or directory "{}" marked as a dependency of a test'.format(dep))
+                exit(1)
+            if os.path.isdir(dep):
+                shutil.copytree(dep, os.path.join(tmpDir, os.path.basename(dep)), symlinks=True)
+            else:
+                shutil.copy2(dep, tmpDir)
+
+        # Run the executable with the given environment in the temporary directory.
+        return subprocess.call(' '.join(remaining), cwd=tmpDir, env=env, shell=True)
+    finally:
+        shutil.rmtree(tmpDir)
 
 if __name__ == '__main__':
     exit(main())