Home | History | Annotate | Download | only in utils
      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()
     85