]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - utils/gen_link_script.py
Vendor import of libc++ 4.0.0 release r297347:
[FreeBSD/FreeBSD.git] / utils / gen_link_script.py
1 #!/usr/bin/env python
2 #===----------------------------------------------------------------------===##
3 #
4 #                     The LLVM Compiler Infrastructure
5 #
6 # This file is dual licensed under the MIT and the University of Illinois Open
7 # Source Licenses. See LICENSE.TXT for details.
8 #
9 #===----------------------------------------------------------------------===##
10
11 import os
12 import sys
13
14 def print_and_exit(msg):
15     sys.stderr.write(msg + '\n')
16     sys.exit(1)
17
18 def usage_and_exit():
19     print_and_exit("Usage: ./gen_link_script.py [--help] [--dryrun] <path/to/libcxx.so> <public_libs>...")
20
21 def help_and_exit():
22     help_msg = \
23 """Usage
24
25   gen_link_script.py [--help] [--dryrun] <path/to/libcxx.so> <public_libs>...
26
27   Generate a linker script that links libc++ to the proper ABI library.
28   The script replaces the specified libc++ symlink.
29   An example script for c++abi would look like "INPUT(libc++.so.1 -lc++abi)".
30
31 Arguments
32   <path/to/libcxx.so> - The top level symlink to the versioned libc++ shared
33                         library. This file is replaced with a linker script.
34   <public_libs>       - List of library names to include in linker script.
35
36 Exit Status:
37   0 if OK,
38   1 if the action failed.
39 """
40     print_and_exit(help_msg)
41
42 def parse_args():
43     args = list(sys.argv)
44     del args[0]
45     if len(args) == 0:
46         usage_and_exit()
47     if args[0] == '--help':
48         help_and_exit()
49     dryrun = '--dryrun' == args[0]
50     if dryrun:
51         del args[0]
52     if len(args) < 2:
53         usage_and_exit()
54     symlink_file = args[0]
55     public_libs = args[1:]
56     return dryrun, symlink_file, public_libs
57
58 def main():
59     dryrun, symlink_file, public_libs = parse_args()
60
61     # Check that the given libc++.so file is a valid symlink.
62     if not os.path.islink(symlink_file):
63         print_and_exit("symlink file %s is not a symlink" % symlink_file)
64
65     # Read the symlink so we know what libc++ to link to in the linker script.
66     linked_libcxx = os.readlink(symlink_file)
67
68     # Prepare the list of public libraries to link.
69     public_libs = ['-l%s' % l for l in public_libs]
70
71     # Generate the linker script contents and print the script and destination
72     # information.
73     contents = "INPUT(%s %s)" % (linked_libcxx, ' '.join(public_libs))
74     print("GENERATING SCRIPT: '%s' as file %s" % (contents, symlink_file))
75
76     # Remove the existing libc++ symlink and replace it with the script.
77     if not dryrun:
78         os.unlink(symlink_file)
79         with open(symlink_file, 'w') as f:
80             f.write(contents + "\n")
81
82
83 if __name__ == '__main__':
84     main()