# -----------------------------------------------------------------------------------------------------------
# Copyright (c) 2026 Huawei Technologies Co., Ltd.
# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
# CANN Open Software License Agreement Version 2.0 (the "License").
# Please refer to the License for details. You may not use this file except in compliance with the License.
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
# See LICENSE in the root of the software repository for the full text of the License.
# -----------------------------------------------------------------------------------------------------------
# This helper is only for standalone device-side libruntime.so builds whose
# unsupported APIs must override weak real providers. Currently only tiny and
# arch5162 use this model. Host runtime, cmodel, and other product forms must
# keep their existing source selection and strong API providers. Product UTs
# may reuse stub generation to verify the same capability definition.
set(RUNTIME_API_STUB_CATALOG
${RUNTIME_DIR}/src/runtime/api/runtime_api_stub_catalog.def
)
set(RUNTIME_API_STUB_GENERATOR
${RUNTIME_DIR}/src/runtime/cmake/generate_runtime_api_stubs.py
)
function(check_runtime_api_stub_product product)
if(NOT "${product}" STREQUAL "tiny" AND NOT "${product}" STREQUAL "arch5162")
message(FATAL_ERROR
"Runtime API generated stubs are restricted to standalone device-side tiny/arch5162 libruntime.so")
endif()
endfunction()
function(configure_runtime_api_weak_real_sources product)
check_runtime_api_stub_product(${product})
if("${ARGN}" STREQUAL "")
message(FATAL_ERROR "Runtime API weak real source list must not be empty")
endif()
if(NOT "${TARGET_SYSTEM_NAME}" STREQUAL "Windows")
set_property(SOURCE ${ARGN} APPEND PROPERTY
COMPILE_OPTIONS -ffunction-sections -fdata-sections
)
set_property(SOURCE ${ARGN} APPEND PROPERTY
COMPILE_DEFINITIONS
$<$<BOOL:$<TARGET_PROPERTY:RUNTIME_API_WEAK_PROVIDER>>:RUNTIME_API_WEAK_PROVIDER>
)
endif()
endfunction()
function(generate_runtime_api_stubs product product_def output_var)
check_runtime_api_stub_product(${product})
set(output_dir ${CMAKE_CURRENT_BINARY_DIR}/generated/runtime_api_stubs/${product})
set(output_source ${output_dir}/api_c_generated_stub.cc)
set(output_report ${output_dir}/api_provider_report.csv)
set(generated_outputs ${output_source})
set(generator_test_args)
if(ARGC GREATER 3)
set(output_test_source ${output_dir}/api_c_generated_stub_test.cc)
list(APPEND generated_outputs ${output_test_source})
list(APPEND generator_test_args --test-output ${output_test_source})
endif()
add_custom_command(
OUTPUT ${generated_outputs}
BYPRODUCTS ${output_report}
COMMAND ${CMAKE_COMMAND} -E make_directory ${output_dir}
COMMAND python3 ${RUNTIME_API_STUB_GENERATOR}
--catalog ${RUNTIME_API_STUB_CATALOG}
--product-def ${product_def}
--product ${product}
--output ${output_source}
--report ${output_report}
${generator_test_args}
COMMAND ${CMAKE_COMMAND} -E touch ${generated_outputs}
DEPENDS
${RUNTIME_API_STUB_GENERATOR}
${RUNTIME_API_STUB_CATALOG}
${product_def}
VERBATIM
)
set_source_files_properties(${generated_outputs} PROPERTIES GENERATED TRUE)
if(NOT "${TARGET_SYSTEM_NAME}" STREQUAL "Windows")
set_property(SOURCE ${output_source} APPEND PROPERTY
COMPILE_OPTIONS -ffunction-sections -fdata-sections
)
endif()
set(${output_var} ${output_source} PARENT_SCOPE)
if(ARGC GREATER 3)
set(${ARGV3} ${output_test_source} PARENT_SCOPE)
endif()
endfunction()
# UT source lists are consumed from child directories, so generate their stub
# source while configuring the parent directory.
function(generate_runtime_api_stubs_at_configure product product_def output_var)
check_runtime_api_stub_product(${product})
set(output_dir ${CMAKE_CURRENT_BINARY_DIR}/generated/runtime_api_stubs/${product})
set(output_source ${output_dir}/api_c_generated_stub.cc)
set(output_report ${output_dir}/api_provider_report.csv)
file(MAKE_DIRECTORY ${output_dir})
execute_process(
COMMAND python3 ${RUNTIME_API_STUB_GENERATOR}
--catalog ${RUNTIME_API_STUB_CATALOG}
--product-def ${product_def}
--product ${product}
--output ${output_source}
--report ${output_report}
RESULT_VARIABLE generator_result
ERROR_VARIABLE generator_error
)
if(NOT generator_result EQUAL 0)
message(FATAL_ERROR "Failed to generate ${product} Runtime API stubs: ${generator_error}")
endif()
set_source_files_properties(${output_source} PROPERTIES GENERATED TRUE)
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
${RUNTIME_API_STUB_GENERATOR}
${RUNTIME_API_STUB_CATALOG}
${product_def}
)
set(${output_var} ${output_source} PARENT_SCOPE)
endfunction()
function(enable_runtime_api_weak_override target_name)
get_target_property(runtime_api_target_type ${target_name} TYPE)
if(NOT "${runtime_api_target_type}" STREQUAL "SHARED_LIBRARY")
message(FATAL_ERROR "Runtime API weak override requires a standalone shared libruntime target")
endif()
if(NOT "${TARGET_SYSTEM_NAME}" STREQUAL "Windows")
set_property(TARGET ${target_name} PROPERTY RUNTIME_API_WEAK_PROVIDER TRUE)
target_link_options(${target_name} PRIVATE
-Wl,--gc-sections
)
endif()
endfunction()