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