#! /usr/bin/env python # Copyright (c) 2020 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # Linker wrapper that performs distributed ThinLTO on Goma. # # Usage: Pass the original link command as parameters to this script. # E.g. original: clang++ -o foo foo.o # Becomes: goma-ld clang++ -o foo foo.o from __future__ import absolute_import from __future__ import division from __future__ import print_function from __future__ import unicode_literals import goma_link import os import re import sys class GomaLinkUnix(goma_link.GomaLinkBase): # Target-platform-specific constants. WL = '-Wl,' TLTO = '-plugin-opt=thinlto' SEP = '=' DATA_SECTIONS = '-fdata-sections' FUNCTION_SECTIONS = '-ffunction-sections' GROUP_RE = re.compile(WL + '--(?:end|start)-group') MACHINE_RE = re.compile('-m([0-9]+)') OBJ_PATH = '-plugin-opt=obj-path' + SEP OBJ_SUFFIX = '.o' PREFIX_REPLACE = TLTO + '-prefix-replace' + SEP XIR = '-x ir ' ALLOWLIST = { 'chrome', } def analyze_args(self, args, *posargs, **kwargs): # TODO(crbug.com/1040196): Builds are unreliable when all targets use # distributed ThinLTO, so we only enable it for some targets. # For other targets, we fall back to local ThinLTO. We must use ThinLTO # because we build with -fsplit-lto-unit, which requires code generation # be done for each object and target. # Returning None from this function causes the original, non-distributed # linker command to be invoked. if args.output is None: return None if not (args.allowlist or os.path.basename(args.output) in self.ALLOWLIST): return None return super(GomaLinkUnix, self).analyze_args(args, *posargs, **kwargs) def process_output_param(self, args, i): """ If args[i] is a parameter that specifies the output file, returns (output_name, new_i). Else, returns (None, new_i). """ if args[i] == '-o': return (os.path.normpath(args[i + 1]), i + 2) else: return (None, i + 1) if __name__ == '__main__': sys.exit(GomaLinkUnix().main(sys.argv))