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_cicmake_minimum_required(VERSION 3.5.2 FATAL_ERROR)
15b1994897Sopenharmony_ci
16b1994897Sopenharmony_ci# Generate files based on templates and YAML data provided.
17b1994897Sopenharmony_ci# Adds targets for every template. Also adds a target for the whole function invocation
18b1994897Sopenharmony_ci# with name ${data_name}_gen_${PROJECT_NAME} for ease of declaring dependencies on generated files.
19b1994897Sopenharmony_ci#
20b1994897Sopenharmony_ci# Mandatory arguments:
21b1994897Sopenharmony_ci# * DATA -- data source, YAML file
22b1994897Sopenharmony_ci# * TEMPLATES -- a list of templates to generate files
23b1994897Sopenharmony_ci# * REQUIRES -- a list of Ruby scripts that provide data-querying API for templates
24b1994897Sopenharmony_ci#
25b1994897Sopenharmony_ci# Optional arguments:
26b1994897Sopenharmony_ci# * SOURCE -- a directory with templates, default is ${PROJECT_SOURCE_DIR}/templates
27b1994897Sopenharmony_ci# * DESTINATION -- a directory for output files, default is ${PANDA_BINARY_ROOT}
28b1994897Sopenharmony_ci# * EXTRA_DEPENDENCIES -- a list of files that should be considered as dependencies
29b1994897Sopenharmony_ci# * EXTRA_ARGV -- a list of positional arguments that could be accessed in '.erb' files via ARGV[]
30b1994897Sopenharmony_ci
31b1994897Sopenharmony_cifunction(panda_gen)
32b1994897Sopenharmony_ci    set(singlevalues DATA SOURCE DESTINATION TARGET_NAME)
33b1994897Sopenharmony_ci    set(multivalues TEMPLATES REQUIRES EXTRA_DEPENDENCIES EXTRA_ARGV)
34b1994897Sopenharmony_ci    cmake_parse_arguments(
35b1994897Sopenharmony_ci        GEN_ARG
36b1994897Sopenharmony_ci        ""
37b1994897Sopenharmony_ci        "${singlevalues}"
38b1994897Sopenharmony_ci        "${multivalues}"
39b1994897Sopenharmony_ci        ${ARGN}
40b1994897Sopenharmony_ci    )
41b1994897Sopenharmony_ci
42b1994897Sopenharmony_ci    if (NOT DEFINED GEN_ARG_TEMPLATES)
43b1994897Sopenharmony_ci        message(FATAL_ERROR "`TEMPLATES` were not passed to `panda_gen` function")
44b1994897Sopenharmony_ci    endif()
45b1994897Sopenharmony_ci
46b1994897Sopenharmony_ci    if (NOT DEFINED GEN_ARG_DATA)
47b1994897Sopenharmony_ci        message(FATAL_ERROR "`DATA` was not passed to `panda_gen` function")
48b1994897Sopenharmony_ci    endif()
49b1994897Sopenharmony_ci
50b1994897Sopenharmony_ci    if (NOT DEFINED GEN_ARG_SOURCE)
51b1994897Sopenharmony_ci        set(GEN_ARG_SOURCE "${PROJECT_SOURCE_DIR}/templates")
52b1994897Sopenharmony_ci    endif()
53b1994897Sopenharmony_ci
54b1994897Sopenharmony_ci    if (NOT DEFINED GEN_ARG_DESTINATION)
55b1994897Sopenharmony_ci        set(GEN_ARG_DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
56b1994897Sopenharmony_ci    endif()
57b1994897Sopenharmony_ci
58b1994897Sopenharmony_ci    if (NOT DEFINED GEN_ARG_TARGET_NAME)
59b1994897Sopenharmony_ci        get_filename_component(DATA_NAME ${GEN_ARG_DATA} NAME_WE)
60b1994897Sopenharmony_ci        set(GEN_ARG_TARGET_NAME "${DATA_NAME}_gen_${PROJECT_NAME}")
61b1994897Sopenharmony_ci    endif()
62b1994897Sopenharmony_ci
63b1994897Sopenharmony_ci    add_custom_target(${GEN_ARG_TARGET_NAME}) # Umbrella target for all generated files
64b1994897Sopenharmony_ci
65b1994897Sopenharmony_ci    foreach(t ${GEN_ARG_TEMPLATES})
66b1994897Sopenharmony_ci        set(TEMPLATE "${GEN_ARG_SOURCE}/${t}")
67b1994897Sopenharmony_ci        string(REGEX REPLACE "\.erb$" "" NAME ${t})
68b1994897Sopenharmony_ci        string(REPLACE "\." "_" TARGET ${NAME})
69b1994897Sopenharmony_ci        string(REPLACE "/" "_" TARGET ${TARGET})
70b1994897Sopenharmony_ci        set(TARGET ${PROJECT_NAME}_${TARGET})
71b1994897Sopenharmony_ci        set(OUTPUT_FILE "${GEN_ARG_DESTINATION}/${NAME}")
72b1994897Sopenharmony_ci
73b1994897Sopenharmony_ci        panda_gen_file(DATAFILE ${GEN_ARG_DATA}
74b1994897Sopenharmony_ci            TEMPLATE ${TEMPLATE}
75b1994897Sopenharmony_ci            OUTPUTFILE ${OUTPUT_FILE}
76b1994897Sopenharmony_ci            REQUIRES ${GEN_ARG_REQUIRES}
77b1994897Sopenharmony_ci            EXTRA_DEPENDENCIES ${GEN_ARG_EXTRA_DEPENDENCIES}
78b1994897Sopenharmony_ci            EXTRA_ARGV ${GEN_ARG_EXTRA_ARGV}
79b1994897Sopenharmony_ci        )
80b1994897Sopenharmony_ci        add_custom_target(${TARGET} DEPENDS ${OUTPUT_FILE})
81b1994897Sopenharmony_ci        add_dependencies(${GEN_ARG_TARGET_NAME} ${TARGET})
82b1994897Sopenharmony_ci    endforeach()
83b1994897Sopenharmony_ciendfunction()
84b1994897Sopenharmony_ci
85b1994897Sopenharmony_ci# Calls `panda_gen` for ISA YAML.
86b1994897Sopenharmony_ci# Adds targets for every template. Also adds a target for the whole function invocation
87b1994897Sopenharmony_ci# with name isa_gen_${PROJECT_NAME} for ease of declaring dependencies on generated files.
88b1994897Sopenharmony_ci#
89b1994897Sopenharmony_ci# Mandatory arguments:
90b1994897Sopenharmony_ci# * TEMPLATES -- a list of templates to generate files
91b1994897Sopenharmony_ci#
92b1994897Sopenharmony_ci# Optional arguments:
93b1994897Sopenharmony_ci# * SOURCE -- a directory with templates, default is ${PROJECT_SOURCE_DIR}/templates
94b1994897Sopenharmony_ci# * DESTINATION -- a directory for output files, default is ${PANDA_BINARY_ROOT}
95b1994897Sopenharmony_ci# * REQUIRES -- if defined, will require additional Ruby files for template generation
96b1994897Sopenharmony_ci# * EXTRA_DEPENDENCIES -- a list of files that should be considered as dependencies
97b1994897Sopenharmony_ci
98b1994897Sopenharmony_cifunction(panda_isa_gen)
99b1994897Sopenharmony_ci    set(singlevalues SOURCE DESTINATION)
100b1994897Sopenharmony_ci    set(multivalues TEMPLATES REQUIRES EXTRA_DEPENDENCIES)
101b1994897Sopenharmony_ci    cmake_parse_arguments(
102b1994897Sopenharmony_ci        ISA_GEN_ARG
103b1994897Sopenharmony_ci        ""
104b1994897Sopenharmony_ci        "${singlevalues}"
105b1994897Sopenharmony_ci        "${multivalues}"
106b1994897Sopenharmony_ci        ${ARGN}
107b1994897Sopenharmony_ci    )
108b1994897Sopenharmony_ci    set(ISA_DATA "${CMAKE_BINARY_DIR}/isa/isa.yaml")
109b1994897Sopenharmony_ci    set(ISAPI "${PANDA_ROOT}/isa/isapi.rb")
110b1994897Sopenharmony_ci    list(INSERT ISA_GEN_ARG_REQUIRES 0 ${ISAPI})
111b1994897Sopenharmony_ci    list(APPEND ISA_GEN_ARG_EXTRA_DEPENDENCIES isa_assert)
112b1994897Sopenharmony_ci    panda_gen(DATA ${ISA_DATA}
113b1994897Sopenharmony_ci        TEMPLATES ${ISA_GEN_ARG_TEMPLATES}
114b1994897Sopenharmony_ci        SOURCE ${ISA_GEN_ARG_SOURCE}
115b1994897Sopenharmony_ci        DESTINATION ${ISA_GEN_ARG_DESTINATION}
116b1994897Sopenharmony_ci        REQUIRES ${ISA_GEN_ARG_REQUIRES}
117b1994897Sopenharmony_ci        EXTRA_DEPENDENCIES ${ISA_GEN_ARG_EXTRA_DEPENDENCIES}
118b1994897Sopenharmony_ci    )
119b1994897Sopenharmony_ciendfunction()
120b1994897Sopenharmony_ci
121b1994897Sopenharmony_ci# Generate file for a template and YAML data provided.
122b1994897Sopenharmony_ci#
123b1994897Sopenharmony_ci# Mandatory arguments:
124b1994897Sopenharmony_ci# DATAFILE -- YAML data full name
125b1994897Sopenharmony_ci# TEMPLATE -- template full name
126b1994897Sopenharmony_ci# OUTPUTFILE -- output file full name
127b1994897Sopenharmony_ci# REQUIRES -- a list of scripts that provide data-querying API for templates
128b1994897Sopenharmony_ci# EXTRA_DEPENDENCIES -- a list of files that should be considered as dependencies
129b1994897Sopenharmony_ci# EXTRA_ARGV -- a list of positional arguments that could be accessed in '.erb' files via ARGV[]
130b1994897Sopenharmony_ci
131b1994897Sopenharmony_cifunction(panda_gen_file)
132b1994897Sopenharmony_ci    set(singlevalues DATAFILE TEMPLATE OUTPUTFILE)
133b1994897Sopenharmony_ci    set(multivalues REQUIRES EXTRA_DEPENDENCIES EXTRA_ARGV)
134b1994897Sopenharmony_ci    cmake_parse_arguments(
135b1994897Sopenharmony_ci        ARG
136b1994897Sopenharmony_ci        ""
137b1994897Sopenharmony_ci        "${singlevalues}"
138b1994897Sopenharmony_ci        "${multivalues}"
139b1994897Sopenharmony_ci        ${ARGN}
140b1994897Sopenharmony_ci    )
141b1994897Sopenharmony_ci    set(GENERATOR "${PANDA_ROOT}/isa/gen.rb")
142b1994897Sopenharmony_ci    string(REPLACE ";" "," REQUIRE_STR "${ARG_REQUIRES}")
143b1994897Sopenharmony_ci    set(DEPENDS_LIST ${GENERATOR} ${ARG_TEMPLATE} ${ARG_DATAFILE})
144b1994897Sopenharmony_ci
145b1994897Sopenharmony_ci    add_custom_command(OUTPUT ${ARG_OUTPUTFILE}
146b1994897Sopenharmony_ci        COMMENT "Generate file for ${ARG_TEMPLATE}"
147b1994897Sopenharmony_ci        COMMAND ${GENERATOR} ${ARG_EXTRA_ARGV} --template ${ARG_TEMPLATE} --data ${ARG_DATAFILE} --output ${ARG_OUTPUTFILE} --require ${REQUIRE_STR}
148b1994897Sopenharmony_ci        DEPENDS ${DEPENDS_LIST} ${ARG_EXTRA_DEPENDENCIES} ${ARG_REQUIRES}
149b1994897Sopenharmony_ci    )
150b1994897Sopenharmony_ciendfunction()
151b1994897Sopenharmony_ci
152b1994897Sopenharmony_ci# Create an options header using a YAML file for the target
153b1994897Sopenharmony_ci#
154b1994897Sopenharmony_ci# Mandatory arguments:
155b1994897Sopenharmony_ci# TARGET -- target
156b1994897Sopenharmony_ci# YAML_FILE -- YAML file
157b1994897Sopenharmony_ci# GENERATED_HEADER -- generated header
158b1994897Sopenharmony_ci#
159b1994897Sopenharmony_ci# Use "#include 'generated/GENERATED_HEADER"' to include the generated header
160b1994897Sopenharmony_ci
161b1994897Sopenharmony_cifunction(panda_gen_options)
162b1994897Sopenharmony_ci    # Parsing function arguments
163b1994897Sopenharmony_ci    set(singlevalues TARGET YAML_FILE GENERATED_HEADER)
164b1994897Sopenharmony_ci    cmake_parse_arguments(GEN_OPTIONS "" "${singlevalues}" "" ${ARGN})
165b1994897Sopenharmony_ci
166b1994897Sopenharmony_ci    # Generate a options header
167b1994897Sopenharmony_ci    get_filename_component(YAML_FILE ${GEN_OPTIONS_YAML_FILE} ABSOLUTE)
168b1994897Sopenharmony_ci    set(GENERATED_DIR ${CMAKE_CURRENT_BINARY_DIR}/panda_gen_options/generated)
169b1994897Sopenharmony_ci    file(MAKE_DIRECTORY ${GENERATED_DIR})
170b1994897Sopenharmony_ci    set(OPTIONS_H ${GENERATED_DIR}/${GEN_OPTIONS_GENERATED_HEADER})
171b1994897Sopenharmony_ci    panda_gen_file(
172b1994897Sopenharmony_ci        DATAFILE ${YAML_FILE}
173b1994897Sopenharmony_ci        TEMPLATE ${PANDA_ROOT}/templates/options/options.h.erb
174b1994897Sopenharmony_ci        OUTPUTFILE ${OPTIONS_H}
175b1994897Sopenharmony_ci        REQUIRES ${PANDA_ROOT}/templates/common.rb
176b1994897Sopenharmony_ci    )
177b1994897Sopenharmony_ci
178b1994897Sopenharmony_ci    # Add dependencies for a target
179b1994897Sopenharmony_ci    target_include_directories(${GEN_OPTIONS_TARGET} PUBLIC ${GENERATED_DIR}/..)
180b1994897Sopenharmony_ci    add_custom_target(${GEN_OPTIONS_TARGET}_options DEPENDS ${OPTIONS_H})
181b1994897Sopenharmony_ci    add_dependencies(${GEN_OPTIONS_TARGET} ${GEN_OPTIONS_TARGET}_options)
182b1994897Sopenharmony_ciendfunction()
183b1994897Sopenharmony_ci
184b1994897Sopenharmony_cifunction(panda_gen_messages)
185b1994897Sopenharmony_ci    set(singlevalues TARGET YAML_FILE GENERATED_HEADER)
186b1994897Sopenharmony_ci    cmake_parse_arguments(ARG "" "${singlevalues}" "" ${ARGN})
187b1994897Sopenharmony_ci
188b1994897Sopenharmony_ci    if(NOT DEFINED ARG_YAML_FILE)
189b1994897Sopenharmony_ci        set(ARG_YAML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/messages.yaml)
190b1994897Sopenharmony_ci    endif()
191b1994897Sopenharmony_ci
192b1994897Sopenharmony_ci    if(NOT DEFINED ARG_GENERATED_HEADER)
193b1994897Sopenharmony_ci        set(ARG_GENERATED_HEADER messages.h)
194b1994897Sopenharmony_ci    endif()
195b1994897Sopenharmony_ci
196b1994897Sopenharmony_ci    get_filename_component(YAML_FILE ${ARG_YAML_FILE} ABSOLUTE)
197b1994897Sopenharmony_ci
198b1994897Sopenharmony_ci    if(IS_ABSOLUTE ${ARG_GENERATED_HEADER})
199b1994897Sopenharmony_ci        get_filename_component(GENERATED_DIR ${ARG_GENERATED_HEADER} DIRECTORY)
200b1994897Sopenharmony_ci        set(MESSAGES_H ${ARG_GENERATED_HEADER})
201b1994897Sopenharmony_ci    else()
202b1994897Sopenharmony_ci        set(INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/panda_gen_messages)
203b1994897Sopenharmony_ci        set(GENERATED_DIR ${INCLUDE_DIR}/generated)
204b1994897Sopenharmony_ci        set(MESSAGES_H ${GENERATED_DIR}/${ARG_GENERATED_HEADER})
205b1994897Sopenharmony_ci    endif()
206b1994897Sopenharmony_ci
207b1994897Sopenharmony_ci    file(MAKE_DIRECTORY ${GENERATED_DIR})
208b1994897Sopenharmony_ci    panda_gen_file(
209b1994897Sopenharmony_ci        DATAFILE ${YAML_FILE}
210b1994897Sopenharmony_ci        TEMPLATE ${PANDA_ROOT}/templates/messages/messages.h.erb
211b1994897Sopenharmony_ci        OUTPUTFILE ${MESSAGES_H}
212b1994897Sopenharmony_ci        REQUIRES ${PANDA_ROOT}/templates/messages.rb
213b1994897Sopenharmony_ci    )
214b1994897Sopenharmony_ci
215b1994897Sopenharmony_ci    # Add dependencies for a target
216b1994897Sopenharmony_ci    if (NOT DEFINED ARG_TARGET)
217b1994897Sopenharmony_ci        set(ARG_TARGET messages_gen_${PROJECT_NAME})
218b1994897Sopenharmony_ci        add_custom_target(${ARG_TARGET})
219b1994897Sopenharmony_ci    endif()
220b1994897Sopenharmony_ci
221b1994897Sopenharmony_ci    if (DEFINED INCLUDE_DIR)
222b1994897Sopenharmony_ci        target_include_directories(${ARG_TARGET} PUBLIC ${INCLUDE_DIR})
223b1994897Sopenharmony_ci    endif()
224b1994897Sopenharmony_ci    add_custom_target(${ARG_TARGET}_messages DEPENDS ${MESSAGES_H})
225b1994897Sopenharmony_ci    add_dependencies(${ARG_TARGET} ${ARG_TARGET}_messages)
226b1994897Sopenharmony_ciendfunction()
227b1994897Sopenharmony_ci
228b1994897Sopenharmony_ciadd_custom_target(plugin_options_gen)
229b1994897Sopenharmony_ciset_target_properties(plugin_options_gen PROPERTIES PLUGIN_OPTIONS_YAML_FILES "${PANDA_ROOT}/templates/plugin_options.yaml")
230b1994897Sopenharmony_ci
231b1994897Sopenharmony_ciadd_custom_target(entrypoints_yaml_gen)
232b1994897Sopenharmony_ciset_target_properties(entrypoints_yaml_gen PROPERTIES ENTRYPOINT_YAML_FILES "${PANDA_ROOT}/runtime/entrypoints/entrypoints.yaml")
233b1994897Sopenharmony_ci
234b1994897Sopenharmony_ciadd_custom_target(runtime_options_gen)
235b1994897Sopenharmony_ciset_target_properties(runtime_options_gen PROPERTIES RUNTIME_OPTIONS_YAML_FILES "${PANDA_ROOT}/runtime/options.yaml")
236b1994897Sopenharmony_ci
237b1994897Sopenharmony_cifunction(add_plugin_options YAML_FILE_PATH)
238b1994897Sopenharmony_ci    get_target_property(YAML_FILES plugin_options_gen PLUGIN_OPTIONS_YAML_FILES)
239b1994897Sopenharmony_ci    list(APPEND YAML_FILES ${YAML_FILE_PATH})
240b1994897Sopenharmony_ci    set_target_properties(plugin_options_gen PROPERTIES PLUGIN_OPTIONS_YAML_FILES "${YAML_FILES}")
241b1994897Sopenharmony_ciendfunction()
242b1994897Sopenharmony_ci
243b1994897Sopenharmony_cifunction(add_entrypoints_yaml YAML_FILE_PATH)
244b1994897Sopenharmony_ci    get_target_property(YAML_FILES entrypoints_yaml_gen ENTRYPOINT_YAML_FILES)
245b1994897Sopenharmony_ci    list(APPEND YAML_FILES ${YAML_FILE_PATH})
246b1994897Sopenharmony_ci    set_target_properties(entrypoints_yaml_gen PROPERTIES ENTRYPOINT_YAML_FILES "${YAML_FILES}")
247b1994897Sopenharmony_ciendfunction()
248b1994897Sopenharmony_ci
249b1994897Sopenharmony_cifunction(add_runtime_options YAML_FILE_PATH)
250b1994897Sopenharmony_ci    get_target_property(YAML_FILES runtime_options_gen RUNTIME_OPTIONS_YAML_FILES)
251b1994897Sopenharmony_ci    list(APPEND YAML_FILES ${YAML_FILE_PATH})
252b1994897Sopenharmony_ci    set_target_properties(runtime_options_gen PROPERTIES RUNTIME_OPTIONS_YAML_FILES "${YAML_FILES}")
253b1994897Sopenharmony_ciendfunction()
254