• 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    parser.add_argument('--clang-base-dir', help='')
112
113    parser.add_argument('args', metavar='ARG', nargs='+')
114
115    args = parser.parse_args()
116
117    result = exec_formatted_command(args)
118    if result != 0:
119        return result
120    if args.strip:
121        result = rust_strip.do_strip(args.strip, args.output, args.unstripped_file, args.mini_debug,
122            args.clang_base_dir)
123    return result
124
125
126if __name__ == '__main__':
127    sys.exit(main())
128