xref: /aosp_15_r20/external/angle/build/toolchain/whole_archive.py (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1# Copyright 2023 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import re
6
7
8def wrap_with_whole_archive(command, is_apple=False):
9  """Modify and return `command` such that -LinkWrapper,add-whole-archive=X
10  becomes a linking inclusion X (-lX) but wrapped in whole-archive
11  modifiers."""
12
13  # We want to link rlibs as --whole-archive if they are part of a unit test
14  # target. This is determined by switch `-LinkWrapper,add-whole-archive`.
15  #
16  # TODO(danakj): If the linking command line gets too large we could move
17  # {{rlibs}} into the rsp file, but then this script needs to modify the rsp
18  # file instead of the command line.
19  def extract_libname(s):
20    m = re.match(r'-LinkWrapper,add-whole-archive=(.+)', s)
21    return m.group(1)
22
23  # The set of libraries we want to apply `--whole-archive`` to.
24  whole_archive_libs = [
25      extract_libname(x) for x in command
26      if x.startswith("-LinkWrapper,add-whole-archive=")
27  ]
28
29  # Remove the arguments meant for consumption by this LinkWrapper script.
30  command = [x for x in command if not x.startswith("-LinkWrapper,")]
31
32  def has_any_suffix(string, suffixes):
33    for suffix in suffixes:
34      if string.endswith(suffix):
35        return True
36    return False
37
38  def wrap_libs_with(command, libnames, before, after):
39    out = []
40    for arg in command:
41      # The arg is a full path to a library, we look if the the library name (a
42      # suffix of the full arg) is one of `libnames`.
43      if has_any_suffix(arg, libnames):
44        out.extend([before, arg])
45        if after:
46          out.append(after)
47      else:
48        out.append(arg)
49    return out
50
51  if is_apple:
52    # Apply -force_load to the libraries that desire it.
53    return wrap_libs_with(command, whole_archive_libs, "-Wl,-force_load", None)
54  else:
55    # Apply --whole-archive to the libraries that desire it.
56    return wrap_libs_with(command, whole_archive_libs, "-Wl,--whole-archive",
57                          "-Wl,--no-whole-archive")
58