xref: /llvm-project/llvm/utils/gn/build/symlink_or_copy.py (revision f4d5b14dcc65578db1688580a71db0783bfc82f9)
1#!/usr/bin/env python3
2
3"""Symlinks, or on Windows copies, an existing file to a second location.
4
5Overwrites the target location if it exists.
6Updates the mtime on a stamp file when done."""
7
8import argparse
9import errno
10import os
11import sys
12
13
14def main():
15    parser = argparse.ArgumentParser(
16        description=__doc__,
17        formatter_class=argparse.RawDescriptionHelpFormatter)
18    parser.add_argument(
19        "--stamp", required=True, help="name of a file whose mtime is updated on run"
20    )
21    parser.add_argument("source")
22    parser.add_argument("output")
23    args = parser.parse_args()
24
25    # FIXME: This should not check the host platform but the target platform
26    # (which needs to be passed in as an arg), for cross builds.
27    if sys.platform != "win32":
28        try:
29            os.makedirs(os.path.dirname(args.output))
30        except OSError as e:
31            if e.errno != errno.EEXIST:
32                raise
33        try:
34            os.symlink(args.source, args.output)
35        except OSError as e:
36            if e.errno == errno.EEXIST:
37                os.remove(args.output)
38                os.symlink(args.source, args.output)
39            else:
40                raise
41    else:
42        import shutil
43
44        output = args.output + ".exe"
45        source = args.source + ".exe"
46        shutil.copyfile(os.path.join(os.path.dirname(output), source), output)
47
48    open(args.stamp, "w")  # Update mtime on stamp file.
49
50
51if __name__ == "__main__":
52    sys.exit(main())
53