1b1994897Sopenharmony_ci# Copyright (c) 2021-2022 Huawei Device Co., Ltd.
2b1994897Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
3b1994897Sopenharmony_ci# you may not use this file except in compliance with the License.
4b1994897Sopenharmony_ci# You may obtain a copy of the License at
5b1994897Sopenharmony_ci#
6b1994897Sopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0
7b1994897Sopenharmony_ci#
8b1994897Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software
9b1994897Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
10b1994897Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11b1994897Sopenharmony_ci# See the License for the specific language governing permissions and
12b1994897Sopenharmony_ci# limitations under the License.
13b1994897Sopenharmony_ci
14b1994897Sopenharmony_ci# Add a panda assembly to the project using the specified source file
15b1994897Sopenharmony_ci#
16b1994897Sopenharmony_ci# Example usage:
17b1994897Sopenharmony_ci#
18b1994897Sopenharmony_ci#   add_panda_assembly(TARGET <name> SOURCE <source> INDIR <input directory> OUTDIR <output directory> TARGETNAME <target file name>)
19b1994897Sopenharmony_ci#
20b1994897Sopenharmony_ci# Adds a panda assembly target called <name> to be build from <source> file
21b1994897Sopenharmony_ci# listed in the command invocation.
22b1994897Sopenharmony_cifunction(add_panda_assembly)
23b1994897Sopenharmony_ci    set(prefix ARG)
24b1994897Sopenharmony_ci    set(noValues)
25b1994897Sopenharmony_ci    set(singleValues TARGET SOURCE INDIR OUTDIR TARGETNAME)
26b1994897Sopenharmony_ci    set(multiValues)
27b1994897Sopenharmony_ci    cmake_parse_arguments(${prefix}
28b1994897Sopenharmony_ci                          "${noValues}"
29b1994897Sopenharmony_ci                          "${singleValues}"
30b1994897Sopenharmony_ci                          "${multiValues}"
31b1994897Sopenharmony_ci                          ${ARGN})
32b1994897Sopenharmony_ci    if (NOT DEFINED ARG_TARGET)
33b1994897Sopenharmony_ci        message(FATAL_ERROR "Mandatory TARGET argument is not defined.")
34b1994897Sopenharmony_ci    endif()
35b1994897Sopenharmony_ci
36b1994897Sopenharmony_ci    if (NOT DEFINED ARG_SOURCE)
37b1994897Sopenharmony_ci        message(FATAL_ERROR "Mandatory SOURCE argument is not defined.")
38b1994897Sopenharmony_ci    endif()
39b1994897Sopenharmony_ci
40b1994897Sopenharmony_ci    set(source_file_dir "${CMAKE_CURRENT_SOURCE_DIR}")
41b1994897Sopenharmony_ci
42b1994897Sopenharmony_ci    if (DEFINED ARG_INDIR)
43b1994897Sopenharmony_ci        set(source_file_dir "${ARG_INDIR}")
44b1994897Sopenharmony_ci    endif()
45b1994897Sopenharmony_ci
46b1994897Sopenharmony_ci    set(binary_file_dir "${CMAKE_CURRENT_BINARY_DIR}")
47b1994897Sopenharmony_ci
48b1994897Sopenharmony_ci    if (DEFINED ARG_OUTDIR)
49b1994897Sopenharmony_ci        set(binary_file_dir "${ARG_OUTDIR}")
50b1994897Sopenharmony_ci    endif()
51b1994897Sopenharmony_ci
52b1994897Sopenharmony_ci    set(target_file_name "${ARG_TARGET}")
53b1994897Sopenharmony_ci
54b1994897Sopenharmony_ci    if (DEFINED ARG_TARGETNAME)
55b1994897Sopenharmony_ci        set(target_file_name "${ARG_TARGETNAME}")
56b1994897Sopenharmony_ci    endif()
57b1994897Sopenharmony_ci
58b1994897Sopenharmony_ci    if (TARGET ARG_TARGET)
59b1994897Sopenharmony_ci        message(FATAL_ERROR "Target ${ARG_TARGET} is already defined.")
60b1994897Sopenharmony_ci    endif()
61b1994897Sopenharmony_ci
62b1994897Sopenharmony_ci    set(source_file "${source_file_dir}/${ARG_SOURCE}")
63b1994897Sopenharmony_ci    set(binary_file "${binary_file_dir}/${target_file_name}.abc")
64b1994897Sopenharmony_ci
65b1994897Sopenharmony_ci    if(CMAKE_CROSSCOMPILING)
66b1994897Sopenharmony_ci        ExternalProject_Get_Property(panda_host_tools binary_dir)
67b1994897Sopenharmony_ci        set(assembler_target panda_host_tools)
68b1994897Sopenharmony_ci        set(assembler_bin    "${binary_dir}/assembler/ark_asm")
69b1994897Sopenharmony_ci    else()
70b1994897Sopenharmony_ci        set(assembler_target ark_asm)
71b1994897Sopenharmony_ci        set(assembler_bin    $<TARGET_FILE:${assembler_target}>)
72b1994897Sopenharmony_ci    endif()
73b1994897Sopenharmony_ci
74b1994897Sopenharmony_ci    add_custom_command(OUTPUT "${binary_file}"
75b1994897Sopenharmony_ci                       COMMENT "Building ${ARG_TARGET}"
76b1994897Sopenharmony_ci                       COMMAND "${assembler_bin}" "${source_file}" "${binary_file}"
77b1994897Sopenharmony_ci                       DEPENDS ${assembler_target} "${source_file}")
78b1994897Sopenharmony_ci
79b1994897Sopenharmony_ci    add_custom_target(${ARG_TARGET} DEPENDS "${binary_file}")
80b1994897Sopenharmony_ciendfunction()
81b1994897Sopenharmony_ci
82b1994897Sopenharmony_ci# Use `mkdir` instead of `file(MAKE_DIRECTORY)` to create dependency on the directory existence:
83b1994897Sopenharmony_ciset(COMPILER_STATS_DIR "${CMAKE_BINARY_DIR}/compiler/stats/csv")
84b1994897Sopenharmony_ciadd_custom_target(compiler_stats_dir
85b1994897Sopenharmony_ci                  COMMAND mkdir -p "${COMPILER_STATS_DIR}")
86b1994897Sopenharmony_ci
87b1994897Sopenharmony_ci# Add a single buildable and runnable Panda Assembly file to the build tree.
88b1994897Sopenharmony_ci#
89b1994897Sopenharmony_ci# Usage:
90b1994897Sopenharmony_ci#
91b1994897Sopenharmony_ci#   panda_add_asm_file(
92b1994897Sopenharmony_ci#        FILE <source>
93b1994897Sopenharmony_ci#        TARGET <target>
94b1994897Sopenharmony_ci#        [ENTRY <entry_point>]
95b1994897Sopenharmony_ci#        [SUBDIR <subdir>]
96b1994897Sopenharmony_ci#        [OUTPUT_FILE_VARIABLE <variable>]
97b1994897Sopenharmony_ci#        [ERROR_FILE_VARIABLE <variable>]
98b1994897Sopenharmony_ci#        [SKIP_BUILD TRUE|FALSE]
99b1994897Sopenharmony_ci#        [AOT_MODE TRUE|FALSE]
100b1994897Sopenharmony_ci#        [AOT_STATS TRUE|FALSE]
101b1994897Sopenharmony_ci#        [DEPENDS <dependency>...]
102b1994897Sopenharmony_ci#        [RUNTIME_OPTIONS <option>...]
103b1994897Sopenharmony_ci#        [COMPILER_OPTIONS <option>...]
104b1994897Sopenharmony_ci#        [AOT_GC_OPTION <option>]
105b1994897Sopenharmony_ci#        [ENTRY_ARGUMENTS <argument>...]
106b1994897Sopenharmony_ci#        [TIMEOUT <timeout>]
107b1994897Sopenharmony_ci#        [LANGUAGE_CONTEXT <language>]
108b1994897Sopenharmony_ci#    )
109b1994897Sopenharmony_ci#
110b1994897Sopenharmony_ci# Adds a target <target> which assembles the assembly file <source>
111b1994897Sopenharmony_ci# with Panda assembler and runs it with Panda interpreter.
112b1994897Sopenharmony_ci#
113b1994897Sopenharmony_ci# Options:
114b1994897Sopenharmony_ci#
115b1994897Sopenharmony_ci# ENTRY
116b1994897Sopenharmony_ci#   Entry point to execute in format <Class>::<method>. By default _GLOBAL::main is used
117b1994897Sopenharmony_ci#
118b1994897Sopenharmony_ci# SUBDIR
119b1994897Sopenharmony_ci#   Subdirectory in the current binary directory that is used to store build artifacts.
120b1994897Sopenharmony_ci#   Full path to directory with artifacts: ${CMAKE_CURRENT_BINARY_DIR}/<subdir>/<target>
121b1994897Sopenharmony_ci#
122b1994897Sopenharmony_ci# OUTPUT_FILE_VARIABLE, ERROR_FILE_VARIABLE
123b1994897Sopenharmony_ci#   The variable named will be set with the paths to files with contents of the stdout and
124b1994897Sopenharmony_ci#   stderr of the program respectively
125b1994897Sopenharmony_ci#
126b1994897Sopenharmony_ci# SKIP_BUILD
127b1994897Sopenharmony_ci#   Do not run assembly
128b1994897Sopenharmony_ci#
129b1994897Sopenharmony_ci# AOT_MODE
130b1994897Sopenharmony_ci#   Run test in AOT mode
131b1994897Sopenharmony_ci#
132b1994897Sopenharmony_ci# AOT_STATS
133b1994897Sopenharmony_ci#   Creates additional independent target `${TARGET}-stats`.
134b1994897Sopenharmony_ci#   `stats`-target dumps AOT compiler statistics in `${COMPILER_STATS_DIR}/${TARGET}.csv`
135b1994897Sopenharmony_ci#
136b1994897Sopenharmony_ci# DEPENDS
137b1994897Sopenharmony_ci#   List of additional dependences (exclude assembler and interpreter)
138b1994897Sopenharmony_ci#
139b1994897Sopenharmony_ci# RUNTIME_OPTIONS
140b1994897Sopenharmony_ci#   Runtime options
141b1994897Sopenharmony_ci#
142b1994897Sopenharmony_ci# COMPILER_OPTIONS
143b1994897Sopenharmony_ci#   Options for compiler, given both to panda and paoc
144b1994897Sopenharmony_ci#
145b1994897Sopenharmony_ci# AOT_GC_OPTION
146b1994897Sopenharmony_ci#  Type of a gc
147b1994897Sopenharmony_ci#
148b1994897Sopenharmony_ci# ENTRY_ARGUMENTS
149b1994897Sopenharmony_ci#   List of arguments that will be passed to program's entry point
150b1994897Sopenharmony_ci#
151b1994897Sopenharmony_ci# TIMEOUT
152b1994897Sopenharmony_ci#   If specified, the program will be run and terminated with the signal 10 (corresponds
153b1994897Sopenharmony_ci#   to SIGUSR1 on most platforms) after the given timeout. The format of the value
154b1994897Sopenharmony_ci#   must match the `timeout` command. The run will be considered successful if the program
155b1994897Sopenharmony_ci#   exits before the timeout with the successful exit code or if it is terminated
156b1994897Sopenharmony_ci#   after the timeout with the signal 10.
157b1994897Sopenharmony_ci#
158b1994897Sopenharmony_ci# LANGUAGE_CONTEXT
159b1994897Sopenharmony_ci#   Set the language-dependent semantics for the code. Possible values: core, java.
160b1994897Sopenharmony_ci#
161b1994897Sopenharmony_cifunction(panda_add_asm_file)
162b1994897Sopenharmony_ci    set(prefix ARG)
163b1994897Sopenharmony_ci    set(noValues)
164b1994897Sopenharmony_ci    set(singleValues FILE ENTRY TARGET SUBDIR OUTPUT_FILE_VARIABLE ERROR_FILE_VARIABLE SKIP_BUILD AOT_MODE AOT_STATS TIMEOUT LANGUAGE_CONTEXT AOT_GC_OPTION)
165b1994897Sopenharmony_ci    set(multiValues DEPENDS RUNTIME_OPTIONS COMPILER_OPTIONS ENTRY_ARGUMENTS PRLIMIT_OPTIONS ADDITIONAL_STDLIBS)
166b1994897Sopenharmony_ci    cmake_parse_arguments(${prefix}
167b1994897Sopenharmony_ci                          "${noValues}"
168b1994897Sopenharmony_ci                          "${singleValues}"
169b1994897Sopenharmony_ci                          "${multiValues}"
170b1994897Sopenharmony_ci                          ${ARGN})
171b1994897Sopenharmony_ci
172b1994897Sopenharmony_ci    if (NOT DEFINED ARG_FILE)
173b1994897Sopenharmony_ci        message(FATAL_ERROR "Mandatory FILE argument is not defined.")
174b1994897Sopenharmony_ci    endif()
175b1994897Sopenharmony_ci
176b1994897Sopenharmony_ci    if (NOT DEFINED ARG_TARGET)
177b1994897Sopenharmony_ci        message(FATAL_ERROR "Mandatory TARGET argument is not defined.")
178b1994897Sopenharmony_ci    endif()
179b1994897Sopenharmony_ci
180b1994897Sopenharmony_ci    if (TARGET ARG_TARGET)
181b1994897Sopenharmony_ci        message(FATAL_ERROR "Target ${ARG_TARGET} is already defined.")
182b1994897Sopenharmony_ci    endif()
183b1994897Sopenharmony_ci
184b1994897Sopenharmony_ci    set(build_dir   "${CMAKE_CURRENT_BINARY_DIR}/${ARG_SUBDIR}/${ARG_TARGET}")
185b1994897Sopenharmony_ci    set(build_log   "${build_dir}/build.log")
186b1994897Sopenharmony_ci    set(build_out   "${build_dir}/build.out")
187b1994897Sopenharmony_ci    set(build_err   "${build_dir}/build.err")
188b1994897Sopenharmony_ci    set(binary_file "${build_dir}/test.abc")
189b1994897Sopenharmony_ci    set(launch_file "${build_dir}/launch.sh")
190b1994897Sopenharmony_ci    set(output_file "${build_dir}/run.out")
191b1994897Sopenharmony_ci    set(error_file  "${build_dir}/run.err")
192b1994897Sopenharmony_ci
193b1994897Sopenharmony_ci    file(MAKE_DIRECTORY "${build_dir}")
194b1994897Sopenharmony_ci
195b1994897Sopenharmony_ci    if (DEFINED ARG_OUTPUT_FILE_VARIABLE)
196b1994897Sopenharmony_ci        set(${ARG_OUTPUT_FILE_VARIABLE} "${output_file}" PARENT_SCOPE)
197b1994897Sopenharmony_ci    endif()
198b1994897Sopenharmony_ci
199b1994897Sopenharmony_ci    if (DEFINED ARG_ERROR_FILE_VARIABLE)
200b1994897Sopenharmony_ci        set(${ARG_ERROR_FILE_VARIABLE} "${error_file}" PARENT_SCOPE)
201b1994897Sopenharmony_ci    endif()
202b1994897Sopenharmony_ci
203b1994897Sopenharmony_ci    if (ARG_SKIP_BUILD)
204b1994897Sopenharmony_ci        set(binary_file "${ARG_FILE}")
205b1994897Sopenharmony_ci    else()
206b1994897Sopenharmony_ci        set(assembler ark_asm)
207b1994897Sopenharmony_ci        add_custom_command(OUTPUT "${binary_file}"
208b1994897Sopenharmony_ci                          COMMENT "Building ${ARG_TARGET}"
209b1994897Sopenharmony_ci                          COMMAND ${PANDA_RUN_PREFIX} $<TARGET_FILE:${assembler}> --verbose --log-file "${build_log}" "${ARG_FILE}" "${binary_file}" 1>"${build_out}" 2>"${build_err}"
210b1994897Sopenharmony_ci                          DEPENDS ${assembler} "${ARG_FILE}")
211b1994897Sopenharmony_ci    endif()
212b1994897Sopenharmony_ci
213b1994897Sopenharmony_ci    if (DEFINED ARG_TIMEOUT AND NOT "${ARG_TIMEOUT}" STREQUAL "")
214b1994897Sopenharmony_ci        set(timeout_signal 10)
215b1994897Sopenharmony_ci        set(timeout_prefix "timeout --preserve-status --signal=${timeout_signal} --kill-after=10s ${ARG_TIMEOUT}")
216b1994897Sopenharmony_ci        set(timeout_suffix "|| [ `expr \$? % 128` -eq ${timeout_signal} ]")
217b1994897Sopenharmony_ci    else()
218b1994897Sopenharmony_ci        set(timeout_prefix "")
219b1994897Sopenharmony_ci        set(timeout_suffix "")
220b1994897Sopenharmony_ci    endif()
221b1994897Sopenharmony_ci
222b1994897Sopenharmony_ci    if (NOT DEFINED ARG_ENTRY)
223b1994897Sopenharmony_ci        set(ARG_ENTRY "_GLOBAL::main")
224b1994897Sopenharmony_ci    endif()
225b1994897Sopenharmony_ci
226b1994897Sopenharmony_ci    set(panda_stdlib   arkstdlib)
227b1994897Sopenharmony_ci    set(panda_cli      ark)
228b1994897Sopenharmony_ci    set(panda_verifier verifier)
229b1994897Sopenharmony_ci
230b1994897Sopenharmony_ci    set(stdlibs "${${panda_stdlib}_BINARY_DIR}/${panda_stdlib}.abc")
231b1994897Sopenharmony_ci    if (DEFINED ARG_ADDITIONAL_STDLIBS)
232b1994897Sopenharmony_ci        list(APPEND stdlibs ${ARG_ADDITIONAL_STDLIBS})
233b1994897Sopenharmony_ci    endif()
234b1994897Sopenharmony_ci
235b1994897Sopenharmony_ci    set(spaces "core")
236b1994897Sopenharmony_ci    if (NOT "core" STREQUAL "${ARG_LANGUAGE_CONTEXT}")
237b1994897Sopenharmony_ci        set(spaces "${ARG_LANGUAGE_CONTEXT}")
238b1994897Sopenharmony_ci    endif()
239b1994897Sopenharmony_ci
240b1994897Sopenharmony_ci    string(REPLACE ";" ":" boot_stdlibs "${stdlibs}")
241b1994897Sopenharmony_ci    string(REPLACE ";" ":" boot_spaces  "${spaces}")
242b1994897Sopenharmony_ci
243b1994897Sopenharmony_ci    if (ARG_AOT_MODE)
244b1994897Sopenharmony_ci        set(aot_compiler ark_aot)
245b1994897Sopenharmony_ci        set(launch_aot_file "${build_dir}/launch_aot.sh")
246b1994897Sopenharmony_ci        set(aot_file        "${build_dir}/test.an")
247b1994897Sopenharmony_ci        set(aot_file_stats  "${build_dir}/test_stats.an")
248b1994897Sopenharmony_ci        set(launcher_aot
249b1994897Sopenharmony_ci            "${PANDA_RUN_PREFIX}"
250b1994897Sopenharmony_ci            "$<TARGET_FILE:${aot_compiler}>"
251b1994897Sopenharmony_ci            "--boot-panda-files \"${boot_stdlibs}\""
252b1994897Sopenharmony_ci            "--load-runtimes=${boot_spaces}"
253b1994897Sopenharmony_ci            "--paoc-panda-files \"${binary_file}\""
254b1994897Sopenharmony_ci            "--paoc-output \"${aot_file}\""
255b1994897Sopenharmony_ci            "--compiler-ignore-failures=false"
256b1994897Sopenharmony_ci            "${ARG_COMPILER_OPTIONS}"
257b1994897Sopenharmony_ci            "${ARG_AOT_GC_OPTION}"
258b1994897Sopenharmony_ci            "1>>\"${build_out}\""
259b1994897Sopenharmony_ci            "2>>\"${build_err}\""
260b1994897Sopenharmony_ci        )
261b1994897Sopenharmony_ci        string(REPLACE ";" " " launcher_aot "${launcher_aot}")
262b1994897Sopenharmony_ci        file(GENERATE OUTPUT ${launch_aot_file} CONTENT "${launcher_aot}")
263b1994897Sopenharmony_ci
264b1994897Sopenharmony_ci        # TODO(msherstennikov): enable for arm64
265b1994897Sopenharmony_ci        # Problem in arm64 is that ark_aotdump cannot open aot elf file with error: "undefined symbol: aot"
266b1994897Sopenharmony_ci        if (NOT PANDA_MINIMAL_VIXL AND PANDA_TARGET_AMD64)
267b1994897Sopenharmony_ci            set(aotdump_command
268b1994897Sopenharmony_ci                    "${PANDA_RUN_PREFIX}"
269b1994897Sopenharmony_ci                    "$<TARGET_FILE:ark_aotdump>"
270b1994897Sopenharmony_ci                    "--output-file=/dev/null"
271b1994897Sopenharmony_ci                    "--show-code" "disasm"
272b1994897Sopenharmony_ci                    "${aot_file}")
273b1994897Sopenharmony_ci        endif()
274b1994897Sopenharmony_ci
275b1994897Sopenharmony_ci        set(aot_compile_depends "${aot_compiler}" "${binary_file}")
276b1994897Sopenharmony_ci        if (NOT PANDA_MINIMAL_VIXL)
277b1994897Sopenharmony_ci            list(APPEND aot_compile_depends "ark_aotdump")
278b1994897Sopenharmony_ci        endif()
279b1994897Sopenharmony_ci        
280b1994897Sopenharmony_ci        add_custom_command(OUTPUT "${aot_file}"
281b1994897Sopenharmony_ci                COMMENT "Running aot compiler for ${ARG_TARGET}"
282b1994897Sopenharmony_ci                COMMAND . ${launch_aot_file} || (cat ${build_err} && false)
283b1994897Sopenharmony_ci                COMMAND ${aotdump_command}
284b1994897Sopenharmony_ci                DEPENDS ${aot_compile_depends})
285b1994897Sopenharmony_ci        list(APPEND ARG_RUNTIME_OPTIONS "--aot-file=${aot_file}")
286b1994897Sopenharmony_ci
287b1994897Sopenharmony_ci        if (ARG_AOT_STATS)
288b1994897Sopenharmony_ci            set(launch_aot_stats_file "${build_dir}/launch_aot_stats.sh")
289b1994897Sopenharmony_ci            set(launcher_aot_stats
290b1994897Sopenharmony_ci                "${PANDA_RUN_PREFIX}"
291b1994897Sopenharmony_ci                "$<TARGET_FILE:${aot_compiler}>"
292b1994897Sopenharmony_ci                "--boot-panda-files \"${boot_stdlibs}\""
293b1994897Sopenharmony_ci                "--load-runtimes=${boot_spaces}"
294b1994897Sopenharmony_ci                "--paoc-panda-files \"${binary_file}\""
295b1994897Sopenharmony_ci                "--paoc-output \"${aot_file_stats}\""
296b1994897Sopenharmony_ci                "--compiler-ignore-failures=false"
297b1994897Sopenharmony_ci                "--compiler-dump-stats-csv=\"${COMPILER_STATS_DIR}/${ARG_TARGET}.csv\""
298b1994897Sopenharmony_ci                "${ARG_COMPILER_OPTIONS}"
299b1994897Sopenharmony_ci                "${ARG_AOT_GC_OPTION}"
300b1994897Sopenharmony_ci                "1>>\"${build_out}\""
301b1994897Sopenharmony_ci                "2>>\"${build_err}\""
302b1994897Sopenharmony_ci            )
303b1994897Sopenharmony_ci            string(REPLACE ";" " " launcher_aot_stats "${launcher_aot_stats}")
304b1994897Sopenharmony_ci            file(GENERATE OUTPUT ${launch_aot_stats_file} CONTENT "${launcher_aot_stats}")
305b1994897Sopenharmony_ci            add_custom_target(${ARG_TARGET}-stats
306b1994897Sopenharmony_ci                              COMMENT "Gathering AOT-statistics for ${ARG_TARGET}"
307b1994897Sopenharmony_ci                              COMMAND . ${launch_aot_stats_file}
308b1994897Sopenharmony_ci                              DEPENDS ${aot_compiler} "${binary_file}" compiler_stats_dir)
309b1994897Sopenharmony_ci        endif()
310b1994897Sopenharmony_ci    endif()
311b1994897Sopenharmony_ci
312b1994897Sopenharmony_ci    # NB! The lines below imply that we cannot handle ";" properly
313b1994897Sopenharmony_ci    # in both Panda's own options and the runned program's options.
314b1994897Sopenharmony_ci    # TODO: Fix this once this becomes an issue.
315b1994897Sopenharmony_ci    string(REPLACE ";" " " runtime_options "${ARG_COMPILER_OPTIONS} ${ARG_RUNTIME_OPTIONS}")
316b1994897Sopenharmony_ci    string(REPLACE ";" " " entry_arguments "${ARG_ENTRY_ARGUMENTS}")
317b1994897Sopenharmony_ci
318b1994897Sopenharmony_ci    set(prlimit_cmd "")
319b1994897Sopenharmony_ci    if (DEFINED ARG_PRLIMIT_OPTIONS)
320b1994897Sopenharmony_ci        set(prlimit_cmd "prlimit ${ARG_PRLIMIT_OPTIONS}")
321b1994897Sopenharmony_ci        string(REPLACE ";" " " prlimit_cmd "${prlimit_cmd}")
322b1994897Sopenharmony_ci    endif()
323b1994897Sopenharmony_ci
324b1994897Sopenharmony_ci    if (${runtime_options} MATCHES ".*events-output=csv.*")
325b1994897Sopenharmony_ci        set(runtime_options "${runtime_options} --events-file=${build_dir}/events.csv")
326b1994897Sopenharmony_ci    endif()
327b1994897Sopenharmony_ci
328b1994897Sopenharmony_ci    set(launcher
329b1994897Sopenharmony_ci        "${timeout_prefix}"
330b1994897Sopenharmony_ci        "${prlimit_cmd}"
331b1994897Sopenharmony_ci        "${PANDA_RUN_PREFIX}"
332b1994897Sopenharmony_ci        $<TARGET_FILE:${panda_cli}>
333b1994897Sopenharmony_ci        "--boot-panda-files \"${boot_stdlibs}\""
334b1994897Sopenharmony_ci        "--load-runtimes=${boot_spaces}"
335b1994897Sopenharmony_ci        "--compiler-ignore-failures=false"
336b1994897Sopenharmony_ci        "${runtime_options}"
337b1994897Sopenharmony_ci        "\"${binary_file}\""
338b1994897Sopenharmony_ci        "\"${ARG_ENTRY}\""
339b1994897Sopenharmony_ci        "${entry_arguments}"
340b1994897Sopenharmony_ci        "1>\"${output_file}\""
341b1994897Sopenharmony_ci        "2>\"${error_file}\""
342b1994897Sopenharmony_ci        "${timeout_suffix}"
343b1994897Sopenharmony_ci    )
344b1994897Sopenharmony_ci    string(REPLACE ";" " " launcher "${launcher}")
345b1994897Sopenharmony_ci    file(GENERATE OUTPUT ${launch_file} CONTENT "${launcher}")
346b1994897Sopenharmony_ci
347b1994897Sopenharmony_ci    add_custom_target(${ARG_TARGET}
348b1994897Sopenharmony_ci                      COMMENT "Running ${ARG_TARGET}"
349b1994897Sopenharmony_ci                      COMMAND . ${launch_file} || (cat ${error_file} && false)
350b1994897Sopenharmony_ci                      DEPENDS ${panda_cli} ${panda_stdlib} "${binary_file}" ${aot_file})
351b1994897Sopenharmony_ci
352b1994897Sopenharmony_ci    if (DEFINED ARG_DEPENDS)
353b1994897Sopenharmony_ci        add_dependencies(${ARG_TARGET} ${ARG_DEPENDS})
354b1994897Sopenharmony_ci    endif()
355b1994897Sopenharmony_ci
356b1994897Sopenharmony_ci
357b1994897Sopenharmony_ciendfunction()
358b1994897Sopenharmony_ci
359b1994897Sopenharmony_ci# Add a single buildable and verifiable Panda Assembly file to the build tree.
360b1994897Sopenharmony_ci#
361b1994897Sopenharmony_ci# Usage:
362b1994897Sopenharmony_ci#
363b1994897Sopenharmony_ci#   verifier_add_asm_file(
364b1994897Sopenharmony_ci#        FILE <source>
365b1994897Sopenharmony_ci#        TARGET <target>
366b1994897Sopenharmony_ci#        [RUNTIME_OPTIONS <runtime options>]
367b1994897Sopenharmony_ci#        [VERIFIER_OPTIONS <verifier options>]
368b1994897Sopenharmony_ci#        [SUBDIR <subdir>]
369b1994897Sopenharmony_ci#        [OUTPUT_FILE_VARIABLE <variable>]
370b1994897Sopenharmony_ci#        [ERROR_FILE_VARIABLE <variable>]
371b1994897Sopenharmony_ci#        [DEPENDS <dependency>...]
372b1994897Sopenharmony_ci#        [TIMEOUT <timeout>]
373b1994897Sopenharmony_ci#        [LANGUAGE_CONTEXT <language>]
374b1994897Sopenharmony_ci#    )
375b1994897Sopenharmony_ci#
376b1994897Sopenharmony_ci# Adds a target <target> which assembles the assembly file <source>
377b1994897Sopenharmony_ci# with Panda assembler and verifies it with verifier.
378b1994897Sopenharmony_ci#
379b1994897Sopenharmony_ci# Options:
380b1994897Sopenharmony_ci#
381b1994897Sopenharmony_ci# SUBDIR
382b1994897Sopenharmony_ci#   Subdirectory in the current binary directory that is used to store build artifacts.
383b1994897Sopenharmony_ci#   Full path to directory with artifacts: ${CMAKE_CURRENT_BINARY_DIR}/<subdir>/<target>
384b1994897Sopenharmony_ci#
385b1994897Sopenharmony_ci# OUTPUT_FILE_VARIABLE, ERROR_FILE_VARIABLE
386b1994897Sopenharmony_ci#   The variable named will be set with the paths to files with contents of the stdout and
387b1994897Sopenharmony_ci#   stderr of the program respectively
388b1994897Sopenharmony_ci#
389b1994897Sopenharmony_ci# DEPENDS
390b1994897Sopenharmony_ci#   List of additional dependences (exclude assembler and interpreter)
391b1994897Sopenharmony_ci#
392b1994897Sopenharmony_ci# RUNTIME_OPTIONS
393b1994897Sopenharmony_ci#   Runtime initialization options
394b1994897Sopenharmony_ci#
395b1994897Sopenharmony_ci# VERIFIER_OPTIONS
396b1994897Sopenharmony_ci#   Verifier CLI options
397b1994897Sopenharmony_ci#
398b1994897Sopenharmony_ci# VERIFIER_FAIL_TEST
399b1994897Sopenharmony_ci#   If true, verifier is allowed to exit with non-0 exit code
400b1994897Sopenharmony_ci#
401b1994897Sopenharmony_ci# TIMEOUT
402b1994897Sopenharmony_ci#   If specified, the program will be run and terminated with the signal 10 (corresponds
403b1994897Sopenharmony_ci#   to SIGUSR1 on most platforms) after the given timeout. The format of the value
404b1994897Sopenharmony_ci#   must match the `timeout` command. The run will be considered successful if the program
405b1994897Sopenharmony_ci#   exits before the timeout with the successful exit code or if it is terminated
406b1994897Sopenharmony_ci#   after the timeout with the signal 10.
407b1994897Sopenharmony_ci#
408b1994897Sopenharmony_ci# LANGUAGE_CONTEXT
409b1994897Sopenharmony_ci#   Set the language-dependent semantics for the code. Possible values: core, java.
410b1994897Sopenharmony_ci#
411b1994897Sopenharmony_cifunction(verifier_add_asm_file)
412b1994897Sopenharmony_ci    set(prefix ARG)
413b1994897Sopenharmony_ci    set(noValues VERIFIER_FAIL_TEST)
414b1994897Sopenharmony_ci    set(singleValues
415b1994897Sopenharmony_ci        FILE
416b1994897Sopenharmony_ci        TARGET
417b1994897Sopenharmony_ci        SUBDIR
418b1994897Sopenharmony_ci        OUTPUT_FILE_VARIABLE
419b1994897Sopenharmony_ci        ERROR_FILE_VARIABLE
420b1994897Sopenharmony_ci        TIMEOUT
421b1994897Sopenharmony_ci        LANGUAGE_CONTEXT)
422b1994897Sopenharmony_ci    set(multiValues DEPENDS RUNTIME_OPTIONS VERIFIER_OPTIONS STDLIBS)
423b1994897Sopenharmony_ci    cmake_parse_arguments(${prefix}
424b1994897Sopenharmony_ci                          "${noValues}"
425b1994897Sopenharmony_ci                          "${singleValues}"
426b1994897Sopenharmony_ci                          "${multiValues}"
427b1994897Sopenharmony_ci                          ${ARGN})
428b1994897Sopenharmony_ci
429b1994897Sopenharmony_ci    if (NOT DEFINED ARG_FILE)
430b1994897Sopenharmony_ci        message(FATAL_ERROR "Mandatory FILE argument is not defined.")
431b1994897Sopenharmony_ci    endif()
432b1994897Sopenharmony_ci
433b1994897Sopenharmony_ci    if (NOT DEFINED ARG_TARGET)
434b1994897Sopenharmony_ci        message(FATAL_ERROR "Mandatory TARGET argument is not defined.")
435b1994897Sopenharmony_ci    endif()
436b1994897Sopenharmony_ci
437b1994897Sopenharmony_ci    if (TARGET ARG_TARGET)
438b1994897Sopenharmony_ci        message(FATAL_ERROR "Target ${ARG_TARGET} is already defined.")
439b1994897Sopenharmony_ci    endif()
440b1994897Sopenharmony_ci
441b1994897Sopenharmony_ci    set(build_dir   "${CMAKE_CURRENT_BINARY_DIR}/${ARG_SUBDIR}/${ARG_TARGET}")
442b1994897Sopenharmony_ci    set(build_out   "${build_dir}/build.out")
443b1994897Sopenharmony_ci    set(build_err   "${build_dir}/build.err")
444b1994897Sopenharmony_ci    set(binary_file "${build_dir}/test.abc")
445b1994897Sopenharmony_ci    set(launch_file "${build_dir}/verifier_launch.sh")
446b1994897Sopenharmony_ci    set(output_file "${build_dir}/verify.out")
447b1994897Sopenharmony_ci    set(error_file  "${build_dir}/verify.err")
448b1994897Sopenharmony_ci
449b1994897Sopenharmony_ci    file(MAKE_DIRECTORY "${build_dir}")
450b1994897Sopenharmony_ci
451b1994897Sopenharmony_ci    if (DEFINED ARG_OUTPUT_FILE_VARIABLE)
452b1994897Sopenharmony_ci        set(${ARG_OUTPUT_FILE_VARIABLE} "${output_file}" PARENT_SCOPE)
453b1994897Sopenharmony_ci    endif()
454b1994897Sopenharmony_ci
455b1994897Sopenharmony_ci    if (DEFINED ARG_ERROR_FILE_VARIABLE)
456b1994897Sopenharmony_ci        set(${ARG_ERROR_FILE_VARIABLE} "${error_file}" PARENT_SCOPE)
457b1994897Sopenharmony_ci    endif()
458b1994897Sopenharmony_ci
459b1994897Sopenharmony_ci    set(assembler ark_asm)
460b1994897Sopenharmony_ci    add_custom_command(OUTPUT "${binary_file}"
461b1994897Sopenharmony_ci                      COMMENT "Building ${ARG_TARGET}"
462b1994897Sopenharmony_ci                      COMMAND ${PANDA_RUN_PREFIX} $<TARGET_FILE:${assembler}> "${ARG_FILE}" "${binary_file}" 1>"${build_out}" 2>"${build_err}"
463b1994897Sopenharmony_ci                      DEPENDS ${assembler} "${ARG_FILE}")
464b1994897Sopenharmony_ci
465b1994897Sopenharmony_ci    if (DEFINED ARG_TIMEOUT AND NOT "${ARG_TIMEOUT}" STREQUAL "")
466b1994897Sopenharmony_ci        set(timeout_signal 10)
467b1994897Sopenharmony_ci        set(timeout_prefix "timeout --preserve-status --signal=${timeout_signal} --kill-after=10s ${ARG_TIMEOUT}")
468b1994897Sopenharmony_ci        set(timeout_suffix "|| [ `expr \$? % 128` -eq ${timeout_signal} ]")
469b1994897Sopenharmony_ci    else()
470b1994897Sopenharmony_ci        set(timeout_prefix "")
471b1994897Sopenharmony_ci        set(timeout_suffix "")
472b1994897Sopenharmony_ci    endif()
473b1994897Sopenharmony_ci
474b1994897Sopenharmony_ci    set(panda_stdlib arkstdlib)
475b1994897Sopenharmony_ci    set(verifier_cli verifier)
476b1994897Sopenharmony_ci
477b1994897Sopenharmony_ci    set(spaces "core")
478b1994897Sopenharmony_ci    if (NOT "core" STREQUAL "${ARG_LANGUAGE_CONTEXT}")
479b1994897Sopenharmony_ci        set(spaces "${ARG_LANGUAGE_CONTEXT}")
480b1994897Sopenharmony_ci    else()
481b1994897Sopenharmony_ci        set(stdlibs "${${panda_stdlib}_BINARY_DIR}/${panda_stdlib}.abc")
482b1994897Sopenharmony_ci    endif()
483b1994897Sopenharmony_ci
484b1994897Sopenharmony_ci    list(APPEND stdlibs ${ARG_STDLIBS})
485b1994897Sopenharmony_ci
486b1994897Sopenharmony_ci    string(REPLACE ";" ":" boot_stdlibs "${stdlibs}")
487b1994897Sopenharmony_ci    string(REPLACE ";" ":" boot_spaces  "${spaces}")
488b1994897Sopenharmony_ci
489b1994897Sopenharmony_ci    set(launcher_verifier
490b1994897Sopenharmony_ci        "${PANDA_RUN_PREFIX}"
491b1994897Sopenharmony_ci        $<TARGET_FILE:${verifier_cli}>
492b1994897Sopenharmony_ci        "${ARG_VERIFIER_OPTIONS}"
493b1994897Sopenharmony_ci        "${ARG_RUNTIME_OPTIONS}"
494b1994897Sopenharmony_ci        "--boot-panda-files=\"${boot_stdlibs}\""
495b1994897Sopenharmony_ci        "--load-runtimes=${boot_spaces}"
496b1994897Sopenharmony_ci        "\"${binary_file}\""
497b1994897Sopenharmony_ci        "1>\"${output_file}\""
498b1994897Sopenharmony_ci        "2>\"${error_file}\""
499b1994897Sopenharmony_ci    )
500b1994897Sopenharmony_ci    string(REPLACE ";" " " launcher_verifier "${launcher_verifier}")
501b1994897Sopenharmony_ci    if (ARG_VERIFIER_FAIL_TEST)
502b1994897Sopenharmony_ci        string(APPEND launcher_verifier " || (exit 0)")
503b1994897Sopenharmony_ci    endif()
504b1994897Sopenharmony_ci
505b1994897Sopenharmony_ci    file(GENERATE OUTPUT ${launch_file} CONTENT "${launcher_verifier}")
506b1994897Sopenharmony_ci
507b1994897Sopenharmony_ci    add_custom_target(${ARG_TARGET}
508b1994897Sopenharmony_ci                      COMMENT "Verifying ${ARG_TARGET}"
509b1994897Sopenharmony_ci                      COMMAND . ${launch_file}
510b1994897Sopenharmony_ci                      DEPENDS ${verifier_cli} "${binary_file}")
511b1994897Sopenharmony_ci
512b1994897Sopenharmony_ci    if (DEFINED ARG_DEPENDS)
513b1994897Sopenharmony_ci        add_dependencies(${ARG_TARGET} ${ARG_DEPENDS})
514b1994897Sopenharmony_ci    endif()
515b1994897Sopenharmony_ci
516b1994897Sopenharmony_ciendfunction()
517