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