arkcompiler_runtime_core/cmake/TemplateBasedGen.cmake
huangyu c658ccf319 Update runtime_core code
Issue: https://gitee.com/openharmony/arkcompiler_runtime_core/issues/I5G96F
Test: Test262 suit, ark unittest, rk3568 XTS, ark previewer demo

Signed-off-by: huangyu <huangyu76@huawei.com>
Change-Id: I3f63d129a07deaa27a390f556dcaa5651c098185
2022-07-17 10:20:32 +08:00

254 lines
9.7 KiB
CMake

# Copyright (c) 2021-2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cmake_minimum_required(VERSION 3.5.2 FATAL_ERROR)
# Generate files based on templates and YAML data provided.
# Adds targets for every template. Also adds a target for the whole function invocation
# with name ${data_name}_gen_${PROJECT_NAME} for ease of declaring dependencies on generated files.
#
# Mandatory arguments:
# * DATA -- data source, YAML file
# * TEMPLATES -- a list of templates to generate files
# * REQUIRES -- a list of Ruby scripts that provide data-querying API for templates
#
# Optional arguments:
# * SOURCE -- a directory with templates, default is ${PROJECT_SOURCE_DIR}/templates
# * DESTINATION -- a directory for output files, default is ${PANDA_BINARY_ROOT}
# * EXTRA_DEPENDENCIES -- a list of files that should be considered as dependencies
# * EXTRA_ARGV -- a list of positional arguments that could be accessed in '.erb' files via ARGV[]
function(panda_gen)
set(singlevalues DATA SOURCE DESTINATION TARGET_NAME)
set(multivalues TEMPLATES REQUIRES EXTRA_DEPENDENCIES EXTRA_ARGV)
cmake_parse_arguments(
GEN_ARG
""
"${singlevalues}"
"${multivalues}"
${ARGN}
)
if (NOT DEFINED GEN_ARG_TEMPLATES)
message(FATAL_ERROR "`TEMPLATES` were not passed to `panda_gen` function")
endif()
if (NOT DEFINED GEN_ARG_DATA)
message(FATAL_ERROR "`DATA` was not passed to `panda_gen` function")
endif()
if (NOT DEFINED GEN_ARG_SOURCE)
set(GEN_ARG_SOURCE "${PROJECT_SOURCE_DIR}/templates")
endif()
if (NOT DEFINED GEN_ARG_DESTINATION)
set(GEN_ARG_DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
endif()
if (NOT DEFINED GEN_ARG_TARGET_NAME)
get_filename_component(DATA_NAME ${GEN_ARG_DATA} NAME_WE)
set(GEN_ARG_TARGET_NAME "${DATA_NAME}_gen_${PROJECT_NAME}")
endif()
add_custom_target(${GEN_ARG_TARGET_NAME}) # Umbrella target for all generated files
foreach(t ${GEN_ARG_TEMPLATES})
set(TEMPLATE "${GEN_ARG_SOURCE}/${t}")
string(REGEX REPLACE "\.erb$" "" NAME ${t})
string(REPLACE "\." "_" TARGET ${NAME})
string(REPLACE "/" "_" TARGET ${TARGET})
set(TARGET ${PROJECT_NAME}_${TARGET})
set(OUTPUT_FILE "${GEN_ARG_DESTINATION}/${NAME}")
panda_gen_file(DATAFILE ${GEN_ARG_DATA}
TEMPLATE ${TEMPLATE}
OUTPUTFILE ${OUTPUT_FILE}
REQUIRES ${GEN_ARG_REQUIRES}
EXTRA_DEPENDENCIES ${GEN_ARG_EXTRA_DEPENDENCIES}
EXTRA_ARGV ${GEN_ARG_EXTRA_ARGV}
)
add_custom_target(${TARGET} DEPENDS ${OUTPUT_FILE})
add_dependencies(${GEN_ARG_TARGET_NAME} ${TARGET})
endforeach()
endfunction()
# Calls `panda_gen` for ISA YAML.
# Adds targets for every template. Also adds a target for the whole function invocation
# with name isa_gen_${PROJECT_NAME} for ease of declaring dependencies on generated files.
#
# Mandatory arguments:
# * TEMPLATES -- a list of templates to generate files
#
# Optional arguments:
# * SOURCE -- a directory with templates, default is ${PROJECT_SOURCE_DIR}/templates
# * DESTINATION -- a directory for output files, default is ${PANDA_BINARY_ROOT}
# * REQUIRES -- if defined, will require additional Ruby files for template generation
# * EXTRA_DEPENDENCIES -- a list of files that should be considered as dependencies
function(panda_isa_gen)
set(singlevalues SOURCE DESTINATION)
set(multivalues TEMPLATES REQUIRES EXTRA_DEPENDENCIES)
cmake_parse_arguments(
ISA_GEN_ARG
""
"${singlevalues}"
"${multivalues}"
${ARGN}
)
set(ISA_DATA "${CMAKE_BINARY_DIR}/isa/isa.yaml")
set(ISAPI "${PANDA_ROOT}/isa/isapi.rb")
list(INSERT ISA_GEN_ARG_REQUIRES 0 ${ISAPI})
list(APPEND ISA_GEN_ARG_EXTRA_DEPENDENCIES isa_assert)
panda_gen(DATA ${ISA_DATA}
TEMPLATES ${ISA_GEN_ARG_TEMPLATES}
SOURCE ${ISA_GEN_ARG_SOURCE}
DESTINATION ${ISA_GEN_ARG_DESTINATION}
REQUIRES ${ISA_GEN_ARG_REQUIRES}
EXTRA_DEPENDENCIES ${ISA_GEN_ARG_EXTRA_DEPENDENCIES}
)
endfunction()
# Generate file for a template and YAML data provided.
#
# Mandatory arguments:
# DATAFILE -- YAML data full name
# TEMPLATE -- template full name
# OUTPUTFILE -- output file full name
# REQUIRES -- a list of scripts that provide data-querying API for templates
# EXTRA_DEPENDENCIES -- a list of files that should be considered as dependencies
# EXTRA_ARGV -- a list of positional arguments that could be accessed in '.erb' files via ARGV[]
function(panda_gen_file)
set(singlevalues DATAFILE TEMPLATE OUTPUTFILE)
set(multivalues REQUIRES EXTRA_DEPENDENCIES EXTRA_ARGV)
cmake_parse_arguments(
ARG
""
"${singlevalues}"
"${multivalues}"
${ARGN}
)
set(GENERATOR "${PANDA_ROOT}/isa/gen.rb")
string(REPLACE ";" "," REQUIRE_STR "${ARG_REQUIRES}")
set(DEPENDS_LIST ${GENERATOR} ${ARG_TEMPLATE} ${ARG_DATAFILE})
add_custom_command(OUTPUT ${ARG_OUTPUTFILE}
COMMENT "Generate file for ${ARG_TEMPLATE}"
COMMAND ${GENERATOR} ${ARG_EXTRA_ARGV} --template ${ARG_TEMPLATE} --data ${ARG_DATAFILE} --output ${ARG_OUTPUTFILE} --require ${REQUIRE_STR}
DEPENDS ${DEPENDS_LIST} ${ARG_EXTRA_DEPENDENCIES} ${ARG_REQUIRES}
)
endfunction()
# Create an options header using a YAML file for the target
#
# Mandatory arguments:
# TARGET -- target
# YAML_FILE -- YAML file
# GENERATED_HEADER -- generated header
#
# Use "#include 'generated/GENERATED_HEADER"' to include the generated header
function(panda_gen_options)
# Parsing function arguments
set(singlevalues TARGET YAML_FILE GENERATED_HEADER)
cmake_parse_arguments(GEN_OPTIONS "" "${singlevalues}" "" ${ARGN})
# Generate a options header
get_filename_component(YAML_FILE ${GEN_OPTIONS_YAML_FILE} ABSOLUTE)
set(GENERATED_DIR ${CMAKE_CURRENT_BINARY_DIR}/panda_gen_options/generated)
file(MAKE_DIRECTORY ${GENERATED_DIR})
set(OPTIONS_H ${GENERATED_DIR}/${GEN_OPTIONS_GENERATED_HEADER})
panda_gen_file(
DATAFILE ${YAML_FILE}
TEMPLATE ${PANDA_ROOT}/templates/options/options.h.erb
OUTPUTFILE ${OPTIONS_H}
REQUIRES ${PANDA_ROOT}/templates/common.rb
)
# Add dependencies for a target
target_include_directories(${GEN_OPTIONS_TARGET} PUBLIC ${GENERATED_DIR}/..)
add_custom_target(${GEN_OPTIONS_TARGET}_options DEPENDS ${OPTIONS_H})
add_dependencies(${GEN_OPTIONS_TARGET} ${GEN_OPTIONS_TARGET}_options)
endfunction()
function(panda_gen_messages)
set(singlevalues TARGET YAML_FILE GENERATED_HEADER)
cmake_parse_arguments(ARG "" "${singlevalues}" "" ${ARGN})
if(NOT DEFINED ARG_YAML_FILE)
set(ARG_YAML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/messages.yaml)
endif()
if(NOT DEFINED ARG_GENERATED_HEADER)
set(ARG_GENERATED_HEADER messages.h)
endif()
get_filename_component(YAML_FILE ${ARG_YAML_FILE} ABSOLUTE)
if(IS_ABSOLUTE ${ARG_GENERATED_HEADER})
get_filename_component(GENERATED_DIR ${ARG_GENERATED_HEADER} DIRECTORY)
set(MESSAGES_H ${ARG_GENERATED_HEADER})
else()
set(INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/panda_gen_messages)
set(GENERATED_DIR ${INCLUDE_DIR}/generated)
set(MESSAGES_H ${GENERATED_DIR}/${ARG_GENERATED_HEADER})
endif()
file(MAKE_DIRECTORY ${GENERATED_DIR})
panda_gen_file(
DATAFILE ${YAML_FILE}
TEMPLATE ${PANDA_ROOT}/templates/messages/messages.h.erb
OUTPUTFILE ${MESSAGES_H}
REQUIRES ${PANDA_ROOT}/templates/messages.rb
)
# Add dependencies for a target
if (NOT DEFINED ARG_TARGET)
set(ARG_TARGET messages_gen_${PROJECT_NAME})
add_custom_target(${ARG_TARGET})
endif()
if (DEFINED INCLUDE_DIR)
target_include_directories(${ARG_TARGET} PUBLIC ${INCLUDE_DIR})
endif()
add_custom_target(${ARG_TARGET}_messages DEPENDS ${MESSAGES_H})
add_dependencies(${ARG_TARGET} ${ARG_TARGET}_messages)
endfunction()
add_custom_target(plugin_options_gen)
set_target_properties(plugin_options_gen PROPERTIES PLUGIN_OPTIONS_YAML_FILES "${PANDA_ROOT}/templates/plugin_options.yaml")
add_custom_target(entrypoints_yaml_gen)
set_target_properties(entrypoints_yaml_gen PROPERTIES ENTRYPOINT_YAML_FILES "${PANDA_ROOT}/runtime/entrypoints/entrypoints.yaml")
add_custom_target(runtime_options_gen)
set_target_properties(runtime_options_gen PROPERTIES RUNTIME_OPTIONS_YAML_FILES "${PANDA_ROOT}/runtime/options.yaml")
function(add_plugin_options YAML_FILE_PATH)
get_target_property(YAML_FILES plugin_options_gen PLUGIN_OPTIONS_YAML_FILES)
list(APPEND YAML_FILES ${YAML_FILE_PATH})
set_target_properties(plugin_options_gen PROPERTIES PLUGIN_OPTIONS_YAML_FILES "${YAML_FILES}")
endfunction()
function(add_entrypoints_yaml YAML_FILE_PATH)
get_target_property(YAML_FILES entrypoints_yaml_gen ENTRYPOINT_YAML_FILES)
list(APPEND YAML_FILES ${YAML_FILE_PATH})
set_target_properties(entrypoints_yaml_gen PROPERTIES ENTRYPOINT_YAML_FILES "${YAML_FILES}")
endfunction()
function(add_runtime_options YAML_FILE_PATH)
get_target_property(YAML_FILES runtime_options_gen RUNTIME_OPTIONS_YAML_FILES)
list(APPEND YAML_FILES ${YAML_FILE_PATH})
set_target_properties(runtime_options_gen PROPERTIES RUNTIME_OPTIONS_YAML_FILES "${YAML_FILES}")
endfunction()