• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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