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