15f9996aaSopenharmony_ci#!/usr/bin/env python3
25f9996aaSopenharmony_ci# -*- coding: utf-8 -*-
35f9996aaSopenharmony_ci# Copyright (c) 2022 Huawei Device Co., Ltd.
45f9996aaSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
55f9996aaSopenharmony_ci# you may not use this file except in compliance with the License.
65f9996aaSopenharmony_ci# You may obtain a copy of the License at
75f9996aaSopenharmony_ci#
85f9996aaSopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
95f9996aaSopenharmony_ci#
105f9996aaSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
115f9996aaSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
125f9996aaSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135f9996aaSopenharmony_ci# See the License for the specific language governing permissions and
145f9996aaSopenharmony_ci# limitations under the License.
155f9996aaSopenharmony_ci
165f9996aaSopenharmony_ci"""
175f9996aaSopenharmony_ci1. add {{ldflags}} and extend everyone in {{ldflags}} to -Clink-args=%s.
185f9996aaSopenharmony_ci2. replace blank with newline in .rsp file because of rustc.
195f9996aaSopenharmony_ci3. add {{rustenv}} and in order to avoid ninja can't incremental compiling,
205f9996aaSopenharmony_ci   delete them from .d files.
215f9996aaSopenharmony_ci"""
225f9996aaSopenharmony_ci
235f9996aaSopenharmony_ciimport os
245f9996aaSopenharmony_ciimport stat
255f9996aaSopenharmony_ciimport sys
265f9996aaSopenharmony_ciimport re
275f9996aaSopenharmony_ciimport argparse
285f9996aaSopenharmony_ciimport pathlib
295f9996aaSopenharmony_ciimport subprocess
305f9996aaSopenharmony_ci
315f9996aaSopenharmony_ciimport rust_strip
325f9996aaSopenharmony_cisys.path.append(
335f9996aaSopenharmony_ci    os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
345f9996aaSopenharmony_cifrom scripts.util import build_utils  # noqa: E402
355f9996aaSopenharmony_ci
365f9996aaSopenharmony_ci
375f9996aaSopenharmony_cidef exec_formatted_command(args):
385f9996aaSopenharmony_ci    remaining_args = args.args
395f9996aaSopenharmony_ci
405f9996aaSopenharmony_ci    ldflags_index = remaining_args.index("LDFLAGS")
415f9996aaSopenharmony_ci    rustenv_index = remaining_args.index("RUSTENV", ldflags_index)
425f9996aaSopenharmony_ci    rustc_args = remaining_args[:ldflags_index]
435f9996aaSopenharmony_ci    ldflags = remaining_args[ldflags_index + 1:rustenv_index]
445f9996aaSopenharmony_ci    rustenv = remaining_args[rustenv_index + 1:]
455f9996aaSopenharmony_ci    for arg in ldflags:
465f9996aaSopenharmony_ci        if "cfi.versionscript" not in arg:
475f9996aaSopenharmony_ci            rustc_args.append("-Clink-arg=%s" % arg)
485f9996aaSopenharmony_ci    rustc_args.insert(0, args.rustc)
495f9996aaSopenharmony_ci
505f9996aaSopenharmony_ci    if args.rsp:
515f9996aaSopenharmony_ci        flags = os.O_WRONLY
525f9996aaSopenharmony_ci        modes = stat.S_IWUSR | stat.S_IRUSR
535f9996aaSopenharmony_ci        with open(args.rsp) as rspfile:
545f9996aaSopenharmony_ci            rsp_content = [l.rstrip() for l in rspfile.read().split(' ') if l.rstrip()]
555f9996aaSopenharmony_ci        with open(args.rsp, 'w') as rspfile:
565f9996aaSopenharmony_ci            rspfile.write("\n".join(rsp_content))
575f9996aaSopenharmony_ci        rustc_args.append(f'@{args.rsp}')
585f9996aaSopenharmony_ci
595f9996aaSopenharmony_ci    env = os.environ.copy()
605f9996aaSopenharmony_ci    fixed_env_vars = []
615f9996aaSopenharmony_ci    for item in rustenv:
625f9996aaSopenharmony_ci        (key, value) = item.split("=", 1)
635f9996aaSopenharmony_ci        env[key] = value
645f9996aaSopenharmony_ci        fixed_env_vars.append(key)
655f9996aaSopenharmony_ci
665f9996aaSopenharmony_ci    ret = subprocess.run([args.clippy_driver, *rustc_args], env=env, check=False)
675f9996aaSopenharmony_ci    if ret.returncode != 0:
685f9996aaSopenharmony_ci        sys.exit(ret.returncode)
695f9996aaSopenharmony_ci
705f9996aaSopenharmony_ci    if args.depfile is not None:
715f9996aaSopenharmony_ci        env_dep_re = re.compile("# env-dep:(.*)=.*")
725f9996aaSopenharmony_ci        replacement_lines = []
735f9996aaSopenharmony_ci        dirty = False
745f9996aaSopenharmony_ci        with open(args.depfile, encoding="utf-8") as depfile:
755f9996aaSopenharmony_ci            for line in depfile:
765f9996aaSopenharmony_ci                matched = env_dep_re.match(line)
775f9996aaSopenharmony_ci                if matched and matched.group(1) in fixed_env_vars:
785f9996aaSopenharmony_ci                    dirty = True
795f9996aaSopenharmony_ci                else:
805f9996aaSopenharmony_ci                    replacement_lines.append(line)
815f9996aaSopenharmony_ci        if dirty:
825f9996aaSopenharmony_ci            with build_utils.atomic_output(args.depfile) as output:
835f9996aaSopenharmony_ci                output.write("\n".join(replacement_lines).encode("utf-8"))
845f9996aaSopenharmony_ci    return 0
855f9996aaSopenharmony_ci
865f9996aaSopenharmony_ci
875f9996aaSopenharmony_cidef main():
885f9996aaSopenharmony_ci    parser = argparse.ArgumentParser()
895f9996aaSopenharmony_ci    parser.add_argument('--clippy-driver',
905f9996aaSopenharmony_ci                        required=True,
915f9996aaSopenharmony_ci                        type=pathlib.Path)
925f9996aaSopenharmony_ci    parser.add_argument('--rustc',
935f9996aaSopenharmony_ci                        required=True,
945f9996aaSopenharmony_ci                        type=pathlib.Path)
955f9996aaSopenharmony_ci    parser.add_argument('--depfile',
965f9996aaSopenharmony_ci                        type=pathlib.Path)
975f9996aaSopenharmony_ci    parser.add_argument('--rsp',
985f9996aaSopenharmony_ci                        type=pathlib.Path)
995f9996aaSopenharmony_ci    parser.add_argument('--strip',
1005f9996aaSopenharmony_ci                        help='The strip binary to run',
1015f9996aaSopenharmony_ci                        metavar='PATH')
1025f9996aaSopenharmony_ci    parser.add_argument('--unstripped-file',
1035f9996aaSopenharmony_ci                        help='Executable file produced by linking command',
1045f9996aaSopenharmony_ci                        metavar='FILE')
1055f9996aaSopenharmony_ci    parser.add_argument('--output',
1065f9996aaSopenharmony_ci                        help='Final output executable file',
1075f9996aaSopenharmony_ci                        metavar='FILE')
1085f9996aaSopenharmony_ci    parser.add_argument('--mini-debug',
1095f9996aaSopenharmony_ci                        action='store_true',
1105f9996aaSopenharmony_ci                        default=False,
1115f9996aaSopenharmony_ci                        help='Add .gnu_debugdata section for stripped sofile')
1125f9996aaSopenharmony_ci    parser.add_argument('--clang-base-dir', help='')
1135f9996aaSopenharmony_ci
1145f9996aaSopenharmony_ci    parser.add_argument('args', metavar='ARG', nargs='+')
1155f9996aaSopenharmony_ci
1165f9996aaSopenharmony_ci    args = parser.parse_args()
1175f9996aaSopenharmony_ci
1185f9996aaSopenharmony_ci    result = exec_formatted_command(args)
1195f9996aaSopenharmony_ci    if result != 0:
1205f9996aaSopenharmony_ci        return result
1215f9996aaSopenharmony_ci    if args.strip:
1225f9996aaSopenharmony_ci        result = rust_strip.do_strip(args.strip, args.output, args.unstripped_file, args.mini_debug,
1235f9996aaSopenharmony_ci            args.clang_base_dir)
1245f9996aaSopenharmony_ci    return result
1255f9996aaSopenharmony_ci
1265f9996aaSopenharmony_ci
1275f9996aaSopenharmony_ciif __name__ == '__main__':
1285f9996aaSopenharmony_ci    sys.exit(main())
129