13af6ab5fSopenharmony_ci#!/usr/bin/env python3
23af6ab5fSopenharmony_ci# -*- coding: utf-8 -*-
33af6ab5fSopenharmony_ci
43af6ab5fSopenharmony_ci"""
53af6ab5fSopenharmony_ciCopyright (c) 2024 Huawei Device Co., Ltd.
63af6ab5fSopenharmony_ciLicensed under the Apache License, Version 2.0 (the "License");
73af6ab5fSopenharmony_ciyou may not use this file except in compliance with the License.
83af6ab5fSopenharmony_ciYou may obtain a copy of the License at
93af6ab5fSopenharmony_ci
103af6ab5fSopenharmony_ci    http://www.apache.org/licenses/LICENSE-2.0
113af6ab5fSopenharmony_ci
123af6ab5fSopenharmony_ciUnless required by applicable law or agreed to in writing, software
133af6ab5fSopenharmony_cidistributed under the License is distributed on an "AS IS" BASIS,
143af6ab5fSopenharmony_ciWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
153af6ab5fSopenharmony_ciSee the License for the specific language governing permissions and
163af6ab5fSopenharmony_cilimitations under the License.
173af6ab5fSopenharmony_ci
183af6ab5fSopenharmony_ciDescription: generate abc with mix compilation
193af6ab5fSopenharmony_ci"""
203af6ab5fSopenharmony_ci
213af6ab5fSopenharmony_ciimport os
223af6ab5fSopenharmony_ciimport stat
233af6ab5fSopenharmony_cifrom utils import *
243af6ab5fSopenharmony_ci
253af6ab5fSopenharmony_ci
263af6ab5fSopenharmony_ciclass MixCompiler:
273af6ab5fSopenharmony_ci    def __init__(self, out_file, files_info_list, opt_level, file_threads,
283af6ab5fSopenharmony_ci                 abc_class_threads, function_threads, frontend_tool) -> None:
293af6ab5fSopenharmony_ci        self.out_file = out_file
303af6ab5fSopenharmony_ci        self.files_info_list = files_info_list
313af6ab5fSopenharmony_ci        self.opt_level = opt_level
323af6ab5fSopenharmony_ci        self.file_threads = file_threads
333af6ab5fSopenharmony_ci        self.abc_class_threads = abc_class_threads
343af6ab5fSopenharmony_ci        self.function_threads = function_threads
353af6ab5fSopenharmony_ci        self.frontend_tool = frontend_tool
363af6ab5fSopenharmony_ci        self.abc_outputs = []
373af6ab5fSopenharmony_ci
383af6ab5fSopenharmony_ci    def mix_compile(self, step=1, size=1):
393af6ab5fSopenharmony_ci        flags = os.O_WRONLY | os.O_CREAT
403af6ab5fSopenharmony_ci        modes = stat.S_IWUSR | stat.S_IRUSR
413af6ab5fSopenharmony_ci        files_info_list = self.files_info_list
423af6ab5fSopenharmony_ci        out_file = self.out_file
433af6ab5fSopenharmony_ci        count = 0
443af6ab5fSopenharmony_ci        return_code = 0
453af6ab5fSopenharmony_ci        # For each testcase, we will firstly select some files to generate a merged abc,
463af6ab5fSopenharmony_ci        # and then mix compile it with the remained files to generate the final abc. Will do this for a cycle.
473af6ab5fSopenharmony_ci        for i in range(0, len(files_info_list), step):
483af6ab5fSopenharmony_ci            count = count + 1
493af6ab5fSopenharmony_ci            right_bound = min(i + size, len(files_info_list))
503af6ab5fSopenharmony_ci            selected_file = files_info_list[i : right_bound]
513af6ab5fSopenharmony_ci            remained_file = files_info_list[0 : i]
523af6ab5fSopenharmony_ci            remained_file.extend(files_info_list[right_bound : len(files_info_list)])
533af6ab5fSopenharmony_ci
543af6ab5fSopenharmony_ci            temp_abc = out_file.replace(ABC_EXT, f'_{count}{TEMP_ABC_EXT}')
553af6ab5fSopenharmony_ci            temp_files_info_path = out_file.replace(ABC_EXT, f'_{count}{TEMP_TXT_EXT}')
563af6ab5fSopenharmony_ci            with os.fdopen(os.open(temp_files_info_path, flags, modes), 'w') as f:
573af6ab5fSopenharmony_ci                f.write("".join(selected_file))
583af6ab5fSopenharmony_ci            cmd = [self.frontend_tool, '--opt-level', str(self.opt_level),
593af6ab5fSopenharmony_ci                   '--file-threads', str(self.file_threads),
603af6ab5fSopenharmony_ci                   '--function-threads', str(self.function_threads),
613af6ab5fSopenharmony_ci                   '--output', temp_abc, '--merge-abc', f'@{temp_files_info_path}']
623af6ab5fSopenharmony_ci            return_code = exec_command(cmd)
633af6ab5fSopenharmony_ci            if return_code:
643af6ab5fSopenharmony_ci                print_command(cmd)
653af6ab5fSopenharmony_ci                return return_code
663af6ab5fSopenharmony_ci
673af6ab5fSopenharmony_ci            remained_file.append(f'{temp_abc}\n')
683af6ab5fSopenharmony_ci            abc = out_file.replace(ABC_EXT, f'_{count}{ABC_EXT}')
693af6ab5fSopenharmony_ci            files_info_path = out_file.replace(ABC_EXT, f'_{count}{TXT_EXT}')
703af6ab5fSopenharmony_ci            with os.fdopen(os.open(files_info_path, flags, modes), 'w') as f:
713af6ab5fSopenharmony_ci                f.write("".join(remained_file))
723af6ab5fSopenharmony_ci            cmd = [self.frontend_tool, '--opt-level', str(self.opt_level),
733af6ab5fSopenharmony_ci                   '--file-threads', str(self.file_threads),
743af6ab5fSopenharmony_ci                   '--abc-class-threads', str(self.abc_class_threads),
753af6ab5fSopenharmony_ci                   '--function-threads', str(self.function_threads),
763af6ab5fSopenharmony_ci                   '--output', abc, '--merge-abc', '--enable-abc-input', f'@{files_info_path}']
773af6ab5fSopenharmony_ci            return_code = exec_command(cmd)
783af6ab5fSopenharmony_ci            if return_code:
793af6ab5fSopenharmony_ci                print_command(cmd)
803af6ab5fSopenharmony_ci                return return_code
813af6ab5fSopenharmony_ci
823af6ab5fSopenharmony_ci            self.abc_outputs.append(abc)
833af6ab5fSopenharmony_ci
843af6ab5fSopenharmony_ci        return return_code
85