blob: 6ef01ebcc4094d877785d2c155e0ffb5d3986f54 [file] [log] [blame]
Peter Collingbournee7c71c32023-03-31 20:21:19 -07001#!/usr/bin/env python3
2#
3# Copyright (C) 2023 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18"""
19This script is used as a replacement for the Rust linker. It converts a linker
20command line into a rspfile that can be used during the link phase.
21"""
22
23import os
24import shutil
25import subprocess
26import sys
27
28def create_archive(out, objects, archives):
29 mricmd = f'create {out}\n'
30 for o in objects:
31 mricmd += f'addmod {o}\n'
32 for a in archives:
33 mricmd += f'addlib {a}\n'
34 mricmd += 'save\nend\n'
35 subprocess.run([os.getenv('AR'), '-M'], encoding='utf-8', input=mricmd, check=True)
36
37objects = []
38archives = []
39linkdirs = []
40libs = []
41temp_archives = []
42version_script = None
43
44for i, arg in enumerate(sys.argv):
45 if arg == '-o':
46 out = sys.argv[i+1]
47 if arg == '-L':
48 linkdirs.append(sys.argv[i+1])
49 if arg.startswith('-l') or arg == '-shared':
50 libs.append(arg)
A. Cody Schuffelenf29ca582023-07-13 19:03:39 -070051 if os.getenv('ANDROID_RUST_DARWIN') and (arg == '-dylib' or arg == '-dynamiclib'):
52 libs.append(arg)
Peter Collingbournee7c71c32023-03-31 20:21:19 -070053 if arg.startswith('-Wl,--version-script='):
54 version_script = arg[21:]
55 if arg[0] == '-':
56 continue
57 if arg.endswith('.o') or arg.endswith('.rmeta'):
58 objects.append(arg)
59 if arg.endswith('.rlib'):
60 if arg.startswith(os.getenv('TMPDIR')):
61 temp_archives.append(arg)
62 else:
63 archives.append(arg)
64
65create_archive(f'{out}.whole.a', objects, [])
66create_archive(f'{out}.a', [], temp_archives)
67
68with open(out, 'w') as f:
A. Cody Schuffelenf29ca582023-07-13 19:03:39 -070069 if os.getenv("ANDROID_RUST_DARWIN"):
70 print(f'-force_load', file=f)
71 print(f'{out}.whole.a', file=f)
72 else:
73 print(f'-Wl,--whole-archive', file=f)
74 print(f'{out}.whole.a', file=f)
75 print(f'-Wl,--no-whole-archive', file=f)
Peter Collingbournee7c71c32023-03-31 20:21:19 -070076 print(f'{out}.a', file=f)
77 for a in archives:
78 print(a, file=f)
79 for linkdir in linkdirs:
80 print(f'-L{linkdir}', file=f)
81 for l in libs:
82 print(l, file=f)
83 if version_script:
84 shutil.copyfile(version_script, f'{out}.version_script')
85 print(f'-Wl,--version-script={out}.version_script', file=f)