1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3# Copyright (c) 2022 Huawei Device Co., Ltd. 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16""" 171. add {{ldflags}} and extend everyone in {{ldflags}} to -Clink-args=%s. 182. replace blank with newline in .rsp file because of rustc. 193. add {{rustenv}} and in order to avoid ninja can't incremental compiling, 20 delete them from .d files. 21""" 22 23import os 24import stat 25import sys 26import re 27import argparse 28import pathlib 29import subprocess 30 31import rust_strip 32sys.path.append( 33 os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 34from scripts.util import build_utils # noqa: E402 35 36 37def exec_formatted_command(args): 38 remaining_args = args.args 39 40 ldflags_index = remaining_args.index("LDFLAGS") 41 rustenv_index = remaining_args.index("RUSTENV", ldflags_index) 42 rustc_args = remaining_args[:ldflags_index] 43 ldflags = remaining_args[ldflags_index + 1:rustenv_index] 44 rustenv = remaining_args[rustenv_index + 1:] 45 46 rustc_args.extend(["-Clink-arg=%s" % arg for arg in ldflags]) 47 rustc_args.insert(0, args.rustc) 48 49 if args.rsp: 50 flags = os.O_WRONLY 51 modes = stat.S_IWUSR | stat.S_IRUSR 52 with open(args.rsp) as rspfile: 53 rsp_content = [l.rstrip() for l in rspfile.read().split(' ') if l.rstrip()] 54 with open(args.rsp, 'w') as rspfile: 55 rspfile.write("\n".join(rsp_content)) 56 rustc_args.append(f'@{args.rsp}') 57 58 env = os.environ.copy() 59 fixed_env_vars = [] 60 for item in rustenv: 61 (key, value) = item.split("=", 1) 62 env[key] = value 63 fixed_env_vars.append(key) 64 65 ret = subprocess.run([args.clippy_driver, *rustc_args], env=env, check=False) 66 if ret.returncode != 0: 67 sys.exit(ret.returncode) 68 69 if args.depfile is not None: 70 env_dep_re = re.compile("# env-dep:(.*)=.*") 71 replacement_lines = [] 72 dirty = False 73 with open(args.depfile, encoding="utf-8") as depfile: 74 for line in depfile: 75 matched = env_dep_re.match(line) 76 if matched and matched.group(1) in fixed_env_vars: 77 dirty = True 78 else: 79 replacement_lines.append(line) 80 if dirty: 81 with build_utils.atomic_output(args.depfile) as output: 82 output.write("\n".join(replacement_lines).encode("utf-8")) 83 return 0 84 85 86def main(): 87 parser = argparse.ArgumentParser() 88 parser.add_argument('--clippy-driver', 89 required=True, 90 type=pathlib.Path) 91 parser.add_argument('--rustc', 92 required=True, 93 type=pathlib.Path) 94 parser.add_argument('--depfile', 95 type=pathlib.Path) 96 parser.add_argument('--rsp', 97 type=pathlib.Path) 98 parser.add_argument('--strip', 99 help='The strip binary to run', 100 metavar='PATH') 101 parser.add_argument('--unstripped-file', 102 help='Executable file produced by linking command', 103 metavar='FILE') 104 parser.add_argument('--output', 105 help='Final output executable file', 106 metavar='FILE') 107 parser.add_argument('--mini-debug', 108 action='store_true', 109 default=False, 110 help='Add .gnu_debugdata section for stripped sofile') 111 112 parser.add_argument('args', metavar='ARG', nargs='+') 113 114 args = parser.parse_args() 115 116 result = exec_formatted_command(args) 117 if result != 0: 118 return result 119 if args.strip: 120 result = rust_strip.do_strip(args.strip, args.output, args.unstripped_file, args.mini_debug) 121 return result 122 123 124if __name__ == '__main__': 125 sys.exit(main()) 126