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