• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2024-2025 Huawei Device Co., Ltd.
2# Licensed under the Apache License, Version 2.0 (the "License");
3# you may not use this file except in compliance with the License.
4# You may obtain a copy of the License at
5#
6# http://www.apache.org/licenses/LICENSE-2.0
7#
8# Unless required by applicable law or agreed to in writing, software
9# distributed under the License is distributed on an "AS IS" BASIS,
10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11# See the License for the specific language governing permissions and
12# limitations under the License.
13
14if (PANDA_TARGET_ARM32)
15    return()
16endif()
17
18function(compile_arktsconfig_unit TARGET ABC_FILES WORK_DIR ARKTS_CONFIG ETS_SOURCES)
19    set(oneValueArgs OPT_LEVEL)
20    set(multiValueArgs )
21    cmake_parse_arguments(ARG "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
22
23    compile_ets_sources(${WORK_DIR} ${TARGET} RESULT "${ETS_SOURCES}"
24                        ARKTS_CONFIG ${ARKTS_CONFIG}
25                        OPT_LEVEL ${ARG_OPT_LEVEL}
26    )
27    set(${ABC_FILES} ${RESULT} PARENT_SCOPE)
28endfunction()
29
30function(compile_pandasm_source ABC_TARGET ABC_FILES WORK_DIR PA_SOURCES)
31    add_custom_target(${ABC_TARGET})
32    set(RESULT "")
33    foreach(PA_SOURCE ${PA_SOURCES})
34        get_filename_component(SOURCE_FNAME ${PA_SOURCE} NAME_WE)
35        set(SOURCE_ABC ${WORK_DIR}/${ABC_TARGET}-${SOURCE_FNAME}.abc)
36        set(SOURCE_ABC_TARGET ${ABC_TARGET}-${SOURCE_FNAME}-ets-asm)
37        add_custom_command(OUTPUT "${SOURCE_ABC}"
38                COMMAND ${PANDA_RUN_PREFIX} $<TARGET_FILE:ark_asm> ${PA_SOURCE} ${SOURCE_ABC}
39                DEPENDS ${assembler} "${PA_SOURCE}"
40                WORKING_DIRECTORY "${ARG_WORKING_DIR}")
41        set(RESULT ${RESULT} ${SOURCE_ABC})
42        add_custom_target(${SOURCE_ABC_TARGET} DEPENDS ${SOURCE_ABC})
43        add_dependencies(${ABC_TARGET} ${SOURCE_ABC_TARGET})
44    endforeach()
45    set(${ABC_FILES} ${RESULT} PARENT_SCOPE)
46endfunction()
47
48function(build_spawn_native_module TARGET OUTPUT_DIR)
49    panda_add_library(${TARGET} SHARED spawn/spawn.cpp)
50    set_target_properties(${TARGET} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${OUTPUT_DIR})
51    panda_target_link_libraries(${TARGET} arkruntime)
52    panda_target_include_directories(${TARGET} PRIVATE ${PANDA_ETS_PLUGIN_SOURCE}/runtime/ani)
53endfunction()
54
55function(build_spawn_managed_code TARGET ABC_FILES WORK_DIR)
56    set(oneValueArgs OPT_LEVEL)
57    set(multiValueArgs )
58    cmake_parse_arguments(ARG "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
59
60    set(SPAWN_ETS_SOURCES
61        ${CMAKE_CURRENT_SOURCE_DIR}/spawn/spawn.ets;
62        ${CMAKE_CURRENT_SOURCE_DIR}/spawn/ability.ets;
63    )
64    compile_arktsconfig_unit(${TARGET} RESULT ${WORK_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/spawn/arktsconfig.json
65                             "${SPAWN_ETS_SOURCES}"
66                             OPT_LEVEL ${ARG_OPT_LEVEL}
67    )
68    set(${ABC_FILES} "${RESULT}" PARENT_SCOPE)
69endfunction()
70
71function(prepare_spawn TARGET ABC_FILES WORK_DIR)
72    # Build Spawn native module
73    set(TARGET_LIB ${TARGET}-lib)
74    set(ETSNAPI_LIB_DIR "${WORK_DIR}/lib")
75    file(MAKE_DIRECTORY ${ETSNAPI_LIB_DIR})
76    build_spawn_native_module(${TARGET_LIB} ${ETSNAPI_LIB_DIR})
77
78    # Build Spawn managed code. Produced abc files will be loaded into boot context
79    set(TARGET_ABC ${TARGET}-abc)
80    build_spawn_managed_code(${TARGET_ABC} RESULT ${WORK_DIR})
81    set(${ABC_FILES} "${RESULT}" PARENT_SCOPE)
82
83    # Add env variables required for spawn native module
84    set(PANDA_RUN_PREFIX
85        LD_LIBRARY_PATH=${ETSNAPI_LIB_DIR}
86        NATIVE_LIB_NAME=${TARGET_LIB}
87        ${PANDA_RUN_PREFIX}
88        PARENT_SCOPE)
89
90    add_custom_target(${TARGET} DEPENDS ${TARGET_LIB} ${TARGET_ABC})
91endfunction()
92
93function(run_sts_app_mode_with_special_option TARGET WORK_DIR APP_MAIN_ABILITY_CLASS APP_ABC_FILES)
94    set(oneValueArgs STDOUT_FILE SPAWN_ENTRYPOINT_FUNCTION)
95    set(multiValueArgs RUNTIME_EXTRA_OPTIONS)
96    cmake_parse_arguments(ARG "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
97
98    prepare_spawn(${TARGET}-spawn SPAWN_ABC_FILES ${WORK_DIR})
99    list(GET SPAWN_ABC_FILES 0 SPAWN_ENTRY_ABC)
100    list(JOIN SPAWN_ABC_FILES ":" SPAWN_ABC_FILES)
101
102    list(JOIN APP_ABC_FILES ":" APP_ABC_FILES)
103    set(PANDA_RUN_PREFIX
104        APP_ABC_FILES=${APP_ABC_FILES}
105        APP_MAIN_ABILITY_CLASS=${APP_MAIN_ABILITY_CLASS}
106        ${PANDA_RUN_PREFIX})
107
108    if (NOT DEFINED ARG_SPAWN_ENTRYPOINT_FUNCTION)
109        set(ARG_SPAWN_ENTRYPOINT_FUNCTION "main")
110    endif()
111
112    set(BOOT_PANDA_FILES ${PANDA_BINARY_ROOT}/plugins/ets/etsstdlib.abc:${SPAWN_ABC_FILES})
113
114    set(RUNTIME_ARGUMENTS
115        --boot-panda-files=${BOOT_PANDA_FILES}
116        ${ARG_RUNTIME_EXTRA_OPTIONS}
117        ${SPAWN_ENTRY_ABC}
118        "@spawn.spawn.ETSGLOBAL::${ARG_SPAWN_ENTRYPOINT_FUNCTION}"
119    )
120
121    if (DEFINED ARG_STDOUT_FILE)
122        set(RUNTIME_ARGUMENTS ${RUNTIME_ARGUMENTS} 1> ${ARG_STDOUT_FILE})
123    endif()
124
125    add_custom_target(${TARGET}
126        COMMAND ${PANDA_RUN_PREFIX} $<TARGET_FILE:ark> ${RUNTIME_ARGUMENTS}
127        DEPENDS ${TARGET}-spawn
128    )
129endfunction()
130
131
132function(run_sts_app_mode TARGET WORK_DIR APP_MAIN_ABILITY_CLASS APP_ABC_FILES)
133    set(oneValueArgs STDOUT_FILE SPAWN_ENTRYPOINT_FUNCTION)
134    cmake_parse_arguments(ARG "" "${oneValueArgs}" "" ${ARGN})
135    set(RUNTIME_EXTRA_OPTIONS
136        "--load-runtimes=ets"
137        "--verification-mode=on-the-fly"
138        "--gc-type=g1-gc"
139    )
140    run_sts_app_mode_with_special_option(${TARGET} ${WORK_DIR} ${APP_MAIN_ABILITY_CLASS} "${ABC_FILES}"
141                STDOUT_FILE ${ARG_STDOUT_FILE}
142                SPAWN_ENTRYPOINT_FUNCTION ${ARG_SPAWN_ENTRYPOINT_FUNCTION}
143                RUNTIME_EXTRA_OPTIONS ${RUNTIME_EXTRA_OPTIONS})
144endfunction()
145
146function(prepare_app TARGET ABC_FILES WORK_DIR SOURCE_DIR)
147    # All application files
148    set(RESULT "")
149
150    # `app` package
151    set(SOURCES_APP_DIR ${SOURCE_DIR}/app)
152    set(SOURCES_APP
153        ${SOURCES_APP_DIR}/module1.ets
154        ${SOURCES_APP_DIR}/module2.ets
155        ${SOURCES_APP_DIR}/module3.ets
156    )
157    set(TARGET_APP ${TARGET}-app-abc)
158    compile_arktsconfig_unit(${TARGET_APP} ABCS_MODULES ${WORK_DIR} ${SOURCES_APP_DIR}/arktsconfig.json
159                             "${SOURCES_APP}"
160    )
161    set(RESULT ${RESULT} ${ABCS_MODULES})
162
163    # `foo` package
164    set(TARGET_FOO ${TARGET}-foo-abc)
165    set(SOURCES_FOO
166        ${SOURCE_DIR}/foo/base.ets
167        ${SOURCE_DIR}/foo/foo.ets
168    )
169    compile_arktsconfig_unit(${TARGET_FOO} ABCS_FOO ${WORK_DIR} ${SOURCE_DIR}/foo/arktsconfig.json
170                             "${SOURCES_FOO}"
171    )
172    set(RESULT ${RESULT} ${ABCS_FOO})
173
174    # `bar` package
175    set(TARGET_BAR ${TARGET}-bar-abc)
176    compile_arktsconfig_unit(${TARGET_BAR} ABCS_BAR ${WORK_DIR} ${SOURCE_DIR}/bar/arktsconfig.json
177                             ${SOURCE_DIR}/bar/bar.ets
178    )
179    set(RESULT ${RESULT} ${ABCS_BAR})
180    set(${ABC_FILES} "${RESULT}" PARENT_SCOPE)
181    add_custom_target(${TARGET} DEPENDS ${TARGET_APP} ${TARGET_FOO} ${TARGET_BAR})
182endfunction()
183
184# prepare_incompatible_app compile the specific case and replace the original abc files with incompatiable
185# the src dir contains original sts file
186# the incompatible dir contains incompatiable sts file
187# the app dir contains main entry to run the case
188function(prepare_incompatible_app TARGET ABC_FILES WORK_DIR SOURCE_DIR MODULE_NAME)
189    set(RESULT "")
190    set(oneValueArgs ASM_SOURCE)
191    set(multiValueArgs IGNORE_REPLACE_FILES)
192    cmake_parse_arguments(ARG "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
193    # src package
194    set(TARGET_SRC ${TARGET}-${MODULE_NAME}-src-abc)
195    file(GLOB SOURCES_SRC "${SOURCE_DIR}/${MODULE_NAME}/src/*.ets")
196    compile_arktsconfig_unit(${TARGET_SRC} ABCS_SRC ${WORK_DIR} ${SOURCE_DIR}/${MODULE_NAME}/src/arktsconfig.json
197                             "${SOURCES_SRC}"
198    )
199    # incompatible package
200    set(TARGET_INCOMPATIABLE ${TARGET}-${MODULE_NAME}-incompatible-abc)
201    if (ARG_ASM_SOURCE)
202        file(GLOB SOURCES_INCOMPATIABLE "${SOURCE_DIR}/${MODULE_NAME}/incompatible/*.pa")
203        compile_pandasm_source(${TARGET_INCOMPATIABLE} ABCS_INCOMPATIABLE ${WORK_DIR} "${SOURCES_INCOMPATIABLE}")
204    else()
205        file(GLOB SOURCES_INCOMPATIABLE "${SOURCE_DIR}/${MODULE_NAME}/incompatible/*.ets")
206        compile_arktsconfig_unit(${TARGET_INCOMPATIABLE} ABCS_INCOMPATIABLE ${WORK_DIR} ${SOURCE_DIR}/${MODULE_NAME}/incompatible/arktsconfig.json
207                                "${SOURCES_INCOMPATIABLE}"
208        )
209    endif()
210
211    # replace the same name with incompatiable file, but do not replace files set by the IGNORE_REPLACE_FILES parameter
212    foreach(SRC ${ABCS_SRC})
213        get_filename_component(SRC_NAME ${SRC} NAME)
214        string(REPLACE "${TARGET_SRC}-" "" SRC_NAME ${SRC_NAME})
215        set(REPLACEMENT ${SRC})
216        foreach(INCOMPATIABLE ${ABCS_INCOMPATIABLE})
217            get_filename_component(INCOMPATIABLE_NAME ${INCOMPATIABLE} NAME)
218            string(REPLACE "${TARGET_INCOMPATIABLE}-" "" INCOMPATIABLE_NAME ${INCOMPATIABLE_NAME})
219            if(SRC_NAME STREQUAL INCOMPATIABLE_NAME)
220                if (DEFINED ARG_IGNORE_REPLACE_FILES)
221                    list_find_by_regex("${ARG_IGNORE_REPLACE_FILES}" "${SRC_NAME}" BASE_ABC_IDX)
222                    if (BASE_ABC_IDX EQUAL -1)
223                        set(REPLACEMENT ${INCOMPATIABLE})
224                    endif()
225                else()
226                    set(REPLACEMENT ${INCOMPATIABLE})
227                endif()
228                break()
229            endif()
230        endforeach()
231        set(RESULT ${RESULT} ${REPLACEMENT})
232    endforeach()
233
234    # `app` package
235    set(TARGET_APP ${TARGET}-${MODULE_NAME}-app-abc)
236    file(GLOB SOURCES_APP "${SOURCE_DIR}/${MODULE_NAME}/app/*.ets")
237    compile_arktsconfig_unit(${TARGET_APP} ABCS_APP ${WORK_DIR} ${SOURCE_DIR}/${MODULE_NAME}/app/arktsconfig.json
238                             "${SOURCES_APP}"
239    )
240    set(RESULT ${RESULT} ${ABCS_APP})
241    set(${ABC_FILES} "${RESULT}" PARENT_SCOPE)
242
243
244    add_custom_target(${TARGET} DEPENDS ${TARGET_SRC} ${TARGET_APP} ${TARGET_INCOMPATIABLE})
245endfunction()
246
247
248function(create_modules_test TARGET WORK_DIR SOURCE_DIR)
249    prepare_app(${TARGET}-app ABC_FILES ${WORK_DIR} ${SOURCE_DIR})
250
251    run_sts_app_mode(${TARGET} ${WORK_DIR} "@app.module1.MainAbility" "${ABC_FILES}")
252
253    add_dependencies(${TARGET} ${TARGET}-app)
254endfunction()
255
256create_modules_test(ets_modules_app_mode_test ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
257
258function(list_find_by_regex ELEMENTS REGEX FOUND_IDX)
259    set(RESULT -1)
260    set(IDX 0)
261    foreach(ITER ${ELEMENTS})
262        if(ITER MATCHES ${REGEX})
263            set(RESULT ${IDX})
264            break()
265        endif()
266        math(EXPR IDX "${IDX}+1")
267    endforeach()
268    set(${FOUND_IDX} ${RESULT} PARENT_SCOPE)
269endfunction()
270
271function(create_no_class_def_found_test TARGET WORK_DIR SOURCE_DIR)
272    prepare_app(${TARGET}-app ABC_FILES ${WORK_DIR} ${SOURCE_DIR})
273    list_find_by_regex("${ABC_FILES}" "(.*)-base.abc" BASE_ABC_IDX)
274    # As a result, `@foo.foo.Dummy` class from `foo.ets` must be not loaded
275    list(REMOVE_AT ABC_FILES ${BASE_ABC_IDX})
276
277    set(STDOUT_FILE ${WORK_DIR}/${TARGET}-output.txt)
278    run_sts_app_mode(${TARGET}-run-sts-app-mode ${WORK_DIR} "@app.module1.MainAbility" "${ABC_FILES}"
279                     STDOUT_FILE ${STDOUT_FILE}
280                     SPAWN_ENTRYPOINT_FUNCTION "mainCatchLinkerUnresolvedClassError"
281    )
282    add_dependencies(${TARGET}-run-sts-app-mode ${TARGET}-app)
283
284    add_custom_target(${TARGET}
285        COMMENT "Check class not loaded due to LinkerUnresolvedClassError"
286        COMMAND ${CMAKE_COMMAND} -E compare_files ${STDOUT_FILE} ${SOURCE_DIR}/incompatible_foo/not_verified_method.txt
287        DEPENDS ${TARGET}-run-sts-app-mode
288    )
289endfunction()
290
291create_no_class_def_found_test(ets_modules_no_class_def_found_test ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
292
293function(create_incompatible_class_change_test TARGET WORK_DIR SOURCE_DIR)
294    prepare_app(${TARGET}-app ABC_FILES ${WORK_DIR} ${SOURCE_DIR})
295    list_find_by_regex("${ABC_FILES}" "(.*)-base.abc" BASE_ABC_IDX)
296    list(REMOVE_AT ABC_FILES ${BASE_ABC_IDX})
297
298    # Take `Base` class from `incompatible-foo` package's file
299    set(TARGET_INCOMPATIBLE_FOO ${TARGET}-incompatible-foo-abc)
300    compile_arktsconfig_unit(${TARGET_INCOMPATIBLE_FOO} ABCS_FOO ${WORK_DIR} ${SOURCE_DIR}/incompatible_foo/arktsconfig.json
301                             ${SOURCE_DIR}/incompatible_foo/base.ets
302    )
303    set(ABC_FILES ${ABC_FILES} ${ABCS_FOO})
304
305    set(STDOUT_FILE ${WORK_DIR}/${TARGET}-output.txt)
306    run_sts_app_mode(${TARGET}-run-sts-app-mode ${WORK_DIR} "@app.module1.MainAbility" "${ABC_FILES}"
307                     STDOUT_FILE ${STDOUT_FILE}
308                     SPAWN_ENTRYPOINT_FUNCTION "mainCatchLinkerBadSupertypeError")
309    add_dependencies(${TARGET}-run-sts-app-mode ${TARGET}-app ${TARGET_INCOMPATIBLE_FOO})
310
311    add_custom_target(${TARGET}
312        COMMENT "Check class not loaded due to LinkerBadSupertypeError"
313        COMMAND ${CMAKE_COMMAND} -E compare_files ${STDOUT_FILE} ${SOURCE_DIR}/incompatible_foo/not_loaded_class.txt
314        DEPENDS ${TARGET}-run-sts-app-mode
315    )
316endfunction()
317
318create_incompatible_class_change_test(ets_modules_incompatible_class_change_test ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
319
320function(create_mismatched_test TARGET WORK_DIR SOURCE_DIR)
321    prepare_incompatible_app(${TARGET}-app ABC_FILES ${WORK_DIR} ${SOURCE_DIR} "mismatched" )
322
323    # test extends final class
324    run_sts_app_mode(${TARGET}-extends-final-run-sts-app-mode ${WORK_DIR} "@app.module4.MainAbility" "${ABC_FILES}"
325                     SPAWN_ENTRYPOINT_FUNCTION "mainMisatchedExtendsFinal")
326    add_dependencies(${TARGET}-extends-final-run-sts-app-mode ${TARGET}-app)
327    add_custom_target(${TARGET}-extends
328        COMMENT "Check class extends final class mainMisatchedExtendsFinal"
329        DEPENDS ${TARGET}-extends-final-run-sts-app-mode
330    )
331
332    # test override final method
333    run_sts_app_mode(${TARGET}-override-final-run-sts-app-mode ${WORK_DIR} "@app.module5.MainAbility" "${ABC_FILES}"
334                     SPAWN_ENTRYPOINT_FUNCTION "mainMisatchedOverrideFinal")
335    add_dependencies(${TARGET}-override-final-run-sts-app-mode ${TARGET}-app)
336    add_custom_target(${TARGET}-override
337        COMMENT "Check class override final method mainMisatchedOverrideFinal"
338        DEPENDS ${TARGET}-override-final-run-sts-app-mode
339    )
340
341    add_custom_target(${TARGET}
342            DEPENDS ${TARGET}-extends ${TARGET}-override
343    )
344
345endfunction()
346
347create_mismatched_test(ets_modules_mismatched_test ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
348
349function(create_loop_inheritance_class_test TARGET WORK_DIR SOURCE_DIR)
350    prepare_incompatible_app(${TARGET}-app ABC_FILES ${WORK_DIR} ${SOURCE_DIR} "loop_inheritance"
351                             IGNORE_REPLACE_FILES "level_two.abc")
352
353    # test extends final class
354    run_sts_app_mode(${TARGET}-run-sts-app-mode ${WORK_DIR} "@app.module6.MainAbility" "${ABC_FILES}"
355                     SPAWN_ENTRYPOINT_FUNCTION "mainCircularityExtends")
356    add_dependencies(${TARGET}-run-sts-app-mode ${TARGET}-app)
357
358    add_custom_target(${TARGET}
359        COMMENT "Check class loop inheritance class mainCircularityExtends"
360        DEPENDS ${TARGET}-run-sts-app-mode
361    )
362
363endfunction()
364
365create_loop_inheritance_class_test(ets_modules_loop_inheritance_class_test ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
366
367function(create_multiple_override_test TARGET WORK_DIR SOURCE_DIR)
368    prepare_incompatible_app(${TARGET}-app ABC_FILES ${WORK_DIR} ${SOURCE_DIR} "multiple_override")
369
370    # test override_base.ets multiple override method
371    run_sts_app_mode(${TARGET}-multiple_override-run-sts-app-mode ${WORK_DIR} "@app.module.MainAbility" "${ABC_FILES}"
372                     SPAWN_ENTRYPOINT_FUNCTION "mainMultipleOverrideBase")
373    add_dependencies(${TARGET}-multiple_override-run-sts-app-mode ${TARGET}-app)
374    add_custom_target(${TARGET}-multiple_override
375        COMMENT "Check class multiple override method mainMultipleOverrideBase"
376        DEPENDS ${TARGET}-multiple_override-run-sts-app-mode
377    )
378
379    # test override_base1.ets multiple override method
380    run_sts_app_mode(${TARGET}-multiple_override1-run-sts-app-mode ${WORK_DIR} "@app.module1.MainAbility" "${ABC_FILES}"
381                     SPAWN_ENTRYPOINT_FUNCTION "mainMultipleOverrideBase1")
382    add_dependencies(${TARGET}-multiple_override1-run-sts-app-mode ${TARGET}-app)
383    add_custom_target(${TARGET}-multiple_override1
384        COMMENT "Check class multiple override method mainMultipleOverrideBase1"
385        DEPENDS ${TARGET}-multiple_override1-run-sts-app-mode
386    )
387
388    add_custom_target(${TARGET}
389            DEPENDS ${TARGET}-multiple_override ${TARGET}-multiple_override1
390    )
391
392endfunction()
393
394create_multiple_override_test(ets_modules_multiple_override_test ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
395
396function(create_multiple_implement_test TARGET WORK_DIR SOURCE_DIR)
397    prepare_incompatible_app(${TARGET}-app ABC_FILES ${WORK_DIR} ${SOURCE_DIR} "multiple_implement")
398    # test a2_extends_a1_i1.ets multiple implement method
399    run_sts_app_mode(${TARGET}-multiple_implement-run-sts-app-mode ${WORK_DIR} "@app.module.MainAbility" "${ABC_FILES}"
400                     SPAWN_ENTRYPOINT_FUNCTION "mainMultipleImplement")
401    add_dependencies(${TARGET}-multiple_implement-run-sts-app-mode ${TARGET}-app)
402    add_custom_target(${TARGET}-multiple_implement
403        COMMENT "Check class multiple implement method mainMultipleImplement"
404        DEPENDS ${TARGET}-multiple_implement-run-sts-app-mode
405    )
406
407    # test a2_extends_a1_i2.ets multiple implement method
408    run_sts_app_mode(${TARGET}-multiple_implement1-run-sts-app-mode ${WORK_DIR} "@app.module1.MainAbility" "${ABC_FILES}"
409                     SPAWN_ENTRYPOINT_FUNCTION "mainMultipleImplement1")
410    add_dependencies(${TARGET}-multiple_implement1-run-sts-app-mode ${TARGET}-app)
411    add_custom_target(${TARGET}-multiple_implement1
412        COMMENT "Check class multiple implement method mainMultipleImplement1"
413        DEPENDS ${TARGET}-multiple_implement1-run-sts-app-mode
414    )
415
416    add_custom_target(${TARGET}
417            DEPENDS ${TARGET}-multiple_implement ${TARGET}-multiple_implement1
418    )
419
420endfunction()
421
422create_multiple_implement_test(ets_modules_multiple_implement_test ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
423
424function(create_verification_mode_test TARGET WORK_DIR SOURCE_DIR TEST_NAME ASM_SOURCE)
425    prepare_incompatible_app(${TARGET}-app ABC_FILES ${WORK_DIR} ${SOURCE_DIR} ${TEST_NAME} ASM_SOURCE ${ASM_SOURCE})
426    # test --verification-mode on-the-fly mode
427    set(RUNTIME_EXTRA_OPTIONS
428        "--load-runtimes=ets"
429        "--verification-mode=on-the-fly"
430        "--gc-type=g1-gc"
431    )
432    run_sts_app_mode_with_special_option(${TARGET}-on-the-fly-run-sts-app-mode ${WORK_DIR} "@app.module.MainAbility" "${ABC_FILES}"
433                     SPAWN_ENTRYPOINT_FUNCTION "mainVerificationModeOnTheFly" RUNTIME_EXTRA_OPTIONS ${RUNTIME_EXTRA_OPTIONS})
434    add_dependencies(${TARGET}-on-the-fly-run-sts-app-mode ${TARGET}-app)
435    add_custom_target(${TARGET}-on-the-fly
436        COMMENT "Check --verification-mode on-the-fly mode mainVerificationModeOnTheFly"
437        DEPENDS ${TARGET}-on-the-fly-run-sts-app-mode
438    )
439
440    # test --verification-mode ahead-of-time mode
441    set(RUNTIME_EXTRA_OPTIONS
442        "--load-runtimes=ets"
443        "--verification-mode=ahead-of-time"
444        "--gc-type=g1-gc"
445    )
446    run_sts_app_mode_with_special_option(${TARGET}-ahead-of-time-run-sts-app-mode ${WORK_DIR} "@app.module.MainAbility" "${ABC_FILES}"
447                     SPAWN_ENTRYPOINT_FUNCTION "mainVerificationModeAheadOfTime" RUNTIME_EXTRA_OPTIONS ${RUNTIME_EXTRA_OPTIONS})
448    add_dependencies(${TARGET}-ahead-of-time-run-sts-app-mode ${TARGET}-app)
449    add_custom_target(${TARGET}-ahead-of-time
450        COMMENT "Check --verification-mode ahead-of-time mode mainVerificationModeAheadOfTime"
451        DEPENDS ${TARGET}-ahead-of-time-run-sts-app-mode
452    )
453    add_custom_target(${TARGET}
454            DEPENDS ${TARGET}-on-the-fly ${TARGET}-ahead-of-time
455    )
456endfunction()
457
458create_verification_mode_test(ets_modules_verification_mode_test ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} "verification_mode" FALSE)
459create_verification_mode_test(ets_modules_verification_i32f64misuse_test ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} "verification_i32f64misuse" TRUE)
460create_verification_mode_test(ets_modules_verification_wrong_this_test ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} "verification_wrong_this" TRUE)
461
462add_custom_target(ets_modules_tests
463                  DEPENDS
464                    ets_modules_app_mode_test
465                    ets_modules_no_class_def_found_test
466                    ets_modules_incompatible_class_change_test
467                    ets_modules_mismatched_test
468                    ets_modules_loop_inheritance_class_test
469                    ets_modules_multiple_override_test
470                    ets_modules_multiple_implement_test
471                    ets_modules_verification_mode_test)
472add_dependencies(ets_tests ets_modules_tests)
473