mkcratersp.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #!/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. This script is used as a replacement for the Rust linker. It converts a linker
  19. command line into a rspfile that can be used during the link phase.
  20. """
  21. import os
  22. import shutil
  23. import subprocess
  24. import sys
  25. def create_archive(out, objects, archives):
  26. mricmd = f'create {out}\n'
  27. for o in objects:
  28. mricmd += f'addmod {o}\n'
  29. for a in archives:
  30. mricmd += f'addlib {a}\n'
  31. mricmd += 'save\nend\n'
  32. subprocess.run([os.getenv('AR'), '-M'], encoding='utf-8', input=mricmd, check=True)
  33. objects = []
  34. archives = []
  35. linkdirs = []
  36. libs = []
  37. temp_archives = []
  38. version_script = None
  39. for i, arg in enumerate(sys.argv):
  40. if arg == '-o':
  41. out = sys.argv[i+1]
  42. if arg == '-L':
  43. linkdirs.append(sys.argv[i+1])
  44. if arg.startswith('-l') or arg == '-shared':
  45. libs.append(arg)
  46. if arg.startswith('-Wl,--version-script='):
  47. version_script = arg[21:]
  48. if arg[0] == '-':
  49. continue
  50. if arg.endswith('.o') or arg.endswith('.rmeta'):
  51. objects.append(arg)
  52. if arg.endswith('.rlib'):
  53. if arg.startswith(os.getenv('TMPDIR')):
  54. temp_archives.append(arg)
  55. else:
  56. archives.append(arg)
  57. create_archive(f'{out}.whole.a', objects, [])
  58. create_archive(f'{out}.a', [], temp_archives)
  59. with open(out, 'w') as f:
  60. print(f'-Wl,--whole-archive', file=f)
  61. print(f'{out}.whole.a', file=f)
  62. print(f'-Wl,--no-whole-archive', file=f)
  63. print(f'{out}.a', file=f)
  64. for a in archives:
  65. print(a, file=f)
  66. for linkdir in linkdirs:
  67. print(f'-L{linkdir}', file=f)
  68. for l in libs:
  69. print(l, file=f)
  70. if version_script:
  71. shutil.copyfile(version_script, f'{out}.version_script')
  72. print(f'-Wl,--version-script={out}.version_script', file=f)