• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3#
4# Copyright (c) 2022 Huawei Device Co., Ltd.
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18from __future__ import print_function
19import errno
20import os
21import subprocess
22import sys
23
24USE_PTY = "linux" in sys.platform
25if USE_PTY:
26    import pty
27
28ARCHES = ["x64", "arm", "arm64"]
29DEFAULT_ARCHES = "x64"
30MODES = ["release", "debug"]
31DEFAULT_MODES = "release"
32TARGETS = ["ets_runtime", "ets_frontend", "default", "all"]
33DEFAULT_TARGETS = "default"
34TARGETS_TEST = ["-test262"]
35
36
37USER_ARGS_TEMPLATE = """\
38is_standard_system = true
39%s
40"""
41
42OUTDIR = "out"
43
44
45Help_message = """
46formot like python ark.py [arch].[mode] [options] [test]
47for example , python ark.py x64.release
48[arch] can be one of ["x64", "arm", "arm64"]
49[mode] can be one of ["release", "debug"]
50[options]
51  target: only support [ets_runtime | ets_frontend | default | all] now
52  clean: clear your data in output dir
53[test]
54  test262: run test262
55"""
56
57def PrintHelp():
58    print(Help_message)
59    sys.exit(0)
60
61
62def _Call(cmd, silent=False):
63    if not silent:
64        print("# %s" % cmd)
65    return subprocess.call(cmd, shell=True)
66
67
68def _Write(filename, content, mode):
69    with open(filename, mode) as f:
70        f.write(content)
71
72
73def get_path(arch, mode):
74    subdir = "%s.%s" % (arch, mode)
75    return os.path.join(OUTDIR, subdir)
76
77
78def call_with_output(cmd, file):
79    host, guest = pty.openpty()
80    h = subprocess.Popen(cmd, shell=True, stdin=guest, stdout=guest, stderr=guest)
81    os.close(guest)
82    output_data = []
83    while True:
84        try:
85            build_data = os.read(host, 512).decode('utf-8')
86        except OSError as error:
87            if error == errno.ENOENT:
88                print("no such file")
89            elif error == errno.EPERM:
90                print("permission denied")
91            break
92        else:
93            if not build_data:
94                break
95            print(build_data)
96            sys.stdout.flush()
97            _Write(file, build_data, "a")
98    os.close(host)
99    h.wait()
100    return h.returncode
101
102
103def get_args(argvs):
104    args_list = argvs
105    args_len = len(args_list)
106    if args_len < 1:
107        print("Wrong usage")
108        PrintHelp()
109    elif args_len == 1:
110        args_out = args_list
111        if "-help" in args_out:
112            PrintHelp()
113    else :
114        args_out = args_list
115    return get_templete(args_out)
116
117
118def get_templete(args_list):
119    global_arche = DEFAULT_ARCHES
120    global_mode = DEFAULT_MODES
121    global_target = DEFAULT_TARGETS
122    global_test = ''
123    global_clean = False
124    for args in args_list:
125        parameter = args.split(".")
126        for part in parameter:
127            if part in ARCHES:
128                global_arche = part
129            elif part in MODES:
130                global_mode = part
131            elif part in TARGETS:
132                global_target = part
133            elif part == "clean":
134                global_clean = True
135            elif part in TARGETS_TEST:
136                global_test = part
137            else:
138                print("\033[34mUnkown word: %s\033[0m" % part)
139                PrintHelp()
140                sys.exit(1)
141# Determine the target CPU
142    if global_arche in ("arm", "arm64"):
143        ark_cpu = global_arche
144    else:
145        ark_cpu = "x64"
146    target_cpu = "target_cpu = \"%s\"" % ark_cpu
147# Determine the target OS,Only ohos for now
148    ark_os = "ohos"
149    target_os = "target_os = \"%s\"" % ark_os
150    if global_mode == "debug":
151        is_debug = "is_debug = true"
152    else:
153        is_debug = "is_debug = false"
154    all_part = (is_debug + "\n" + target_os + "\n" + target_cpu)
155    return [global_arche, global_mode, global_target, global_clean, USER_ARGS_TEMPLATE % (all_part), global_test]
156
157
158def Build(template):
159    arch = template[0]
160    mode = template[1]
161    target = template[2]
162    clean = template[3]
163    template_part = template[4]
164    path = get_path(arch, mode)
165    if not os.path.exists(path):
166        print("# mkdir -p %s" % path)
167        os.makedirs(path)
168    if clean:
169        print("=== start clean ===")
170        code = _Call("./prebuilts/build-tools/linux-x86/bin/gn clean %s" % path)
171        code += _Call("./prebuilts/build-tools/linux-x86/bin/ninja -C %s -t clean" % path)
172        if code != 0:
173            return code
174        print("=== clean success! ===")
175        exit(0)
176    build_log = os.path.join(path, "build.log")
177    if not os.path.exists("args.gn"):
178        args_gn = os.path.join(path, "args.gn")
179        _Write(args_gn, template_part, "w")
180    if not os.path.exists("build.ninja"):
181        build_ninja = os.path.join(path, "build.ninja")
182        code = _Call("./prebuilts/build-tools/linux-x86/bin/gn gen %s" % path)
183        print("=== gn success! ===")
184        if code != 0:
185            return code
186    pass_code = call_with_output("./prebuilts/build-tools/linux-x86/bin/ninja -C %s %s" %
187                                          (path, target), build_log)
188    if pass_code == 0:
189        print("=== ninja success! ===")
190    return pass_code
191
192
193def run_test(template):
194    arch = template[0]
195    mode = template[1]
196    test = template[5]
197    test_dir = arch + "." + mode
198    test262_code = '''cd ets_frontend
199    python3 test262/run_test262.py --es2021 all --timeout 180000 --libs-dir ../out/%s:../prebuilts/clang/ohos/linux-x86_64/llvm/lib --ark-tool=../out/%s/arkcompiler/ets_runtime/ark_js_vm --ark-frontend-binary=../out/%s/clang_x64/arkcompiler/ets_frontend/es2abc --merge-abc-binary=../out/%s/clang_x64/arkcompiler/ets_frontend/merge_abc --ark-frontend=es2panda
200    ''' % (test_dir, test_dir, test_dir, test_dir)
201    if ("-test262" == test):
202        print("=== come to test ===")
203        return _Call(test262_code)
204    else:
205        print("=== nothing to test ===")
206        return 0
207
208
209def Main(argvs):
210    pass_code = 0
211    templete = get_args(argvs)
212    pass_code += Build(templete)
213    if pass_code == 0:
214        pass_code += run_test(templete)
215    if pass_code == 0:
216        print('\033[32mDone!\033[0m', '\033[32mARK_{} compilation finished successfully.\033[0m'.format(argvs[0].split('.')[0]))
217    else:
218        print('\033[31mError!\033[0m', '\033[31mARK_{} compilation finished with errors.\033[0m'.format(argvs[0].split('.')[0]))
219    return pass_code
220
221
222if __name__ == "__main__":
223    sys.exit(Main(sys.argv[1:]))
224