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 11import os 12import sys 13 14def print_and_exit(msg): 15 sys.stderr.write(msg + '\n') 16 sys.exit(1) 17 18def usage_and_exit(): 19 print_and_exit("Usage: ./gen_link_script.py [--help] [--dryrun] <path/to/libcxx.so> <public_libs>...") 20 21def 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 31Arguments 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 36Exit Status: 37 0 if OK, 38 1 if the action failed. 39""" 40 print_and_exit(help_msg) 41 42def 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 58def 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 83if __name__ == '__main__': 84 main() 85