File: whole_archive.py

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (57 lines) | stat: -rw-r--r-- 2,053 bytes parent folder | download | duplicates (11)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# Copyright 2023 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import re


def wrap_with_whole_archive(command, is_apple=False):
  """Modify and return `command` such that -LinkWrapper,add-whole-archive=X
  becomes a linking inclusion X (-lX) but wrapped in whole-archive
  modifiers."""

  # We want to link rlibs as --whole-archive if they are part of a unit test
  # target. This is determined by switch `-LinkWrapper,add-whole-archive`.
  #
  # TODO(danakj): If the linking command line gets too large we could move
  # {{rlibs}} into the rsp file, but then this script needs to modify the rsp
  # file instead of the command line.
  def extract_libname(s):
    m = re.match(r'-LinkWrapper,add-whole-archive=(.+)', s)
    return m.group(1)

  # The set of libraries we want to apply `--whole-archive`` to.
  whole_archive_libs = [
      extract_libname(x) for x in command
      if x.startswith("-LinkWrapper,add-whole-archive=")
  ]

  # Remove the arguments meant for consumption by this LinkWrapper script.
  command = [x for x in command if not x.startswith("-LinkWrapper,")]

  def has_any_suffix(string, suffixes):
    for suffix in suffixes:
      if string.endswith(suffix):
        return True
    return False

  def wrap_libs_with(command, libnames, before, after):
    out = []
    for arg in command:
      # The arg is a full path to a library, we look if the the library name (a
      # suffix of the full arg) is one of `libnames`.
      if has_any_suffix(arg, libnames):
        out.extend([before, arg])
        if after:
          out.append(after)
      else:
        out.append(arg)
    return out

  if is_apple:
    # Apply -force_load to the libraries that desire it.
    return wrap_libs_with(command, whole_archive_libs, "-Wl,-force_load", None)
  else:
    # Apply --whole-archive to the libraries that desire it.
    return wrap_libs_with(command, whole_archive_libs, "-Wl,--whole-archive",
                          "-Wl,--no-whole-archive")