1# Copyright (c) 2021-2024 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 14macro(LISTPLUGINS result plugin_dir) 15 file(GLOB children RELATIVE ${plugin_dir} ${plugin_dir}/*) 16 set(plugin_list "") 17 foreach(child ${children}) 18 if (IS_DIRECTORY ${plugin_dir}/${child}) 19 set(plugin_list ${plugin_list} ${child}) 20 endif() 21 endforeach() 22 set(${result} ${plugin_list}) 23endmacro() 24 25function(register_plugin plugin_name) 26 string(TOUPPER ${plugin_name} plugin_name_upper) 27 28 string(CONCAT PANDA_WITH_PLUGIN "PANDA_WITH_" ${plugin_name_upper}) 29 string(CONCAT PANDA_WITH_PLUGIN "PANDA_WITH_" ${plugin_name_upper}) 30 31 set(PLUGIN_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/plugins/${plugin_name}") 32 33 if (DEFINED ${PANDA_WITH_PLUGIN} AND NOT ${PANDA_WITH_PLUGIN}) 34 message(STATUS "${PANDA_WITH_PLUGIN} = ${${PANDA_WITH_PLUGIN}}") 35 return() 36 else() 37 include("${PLUGIN_SOURCE_DIR}/RegisterPlugin.cmake") 38 if ((PANDA_PRODUCT_BUILD AND NOT PLUGIN_IN_PRODUCT_BUILD) AND NOT ${PANDA_WITH_PLUGIN}) 39 option(${PANDA_WITH_PLUGIN} "Enable ${plugin_name} plugin" OFF) 40 else() 41 option(${PANDA_WITH_PLUGIN} "Enable ${plugin_name} plugin" ON) 42 endif() 43 endif() 44 45 message(STATUS "${PANDA_WITH_PLUGIN} = ${${PANDA_WITH_PLUGIN}}") 46 47 string(CONCAT PLUGIN_SOURCE "PANDA_" ${plugin_name_upper} "_PLUGIN_SOURCE") 48 string(CONCAT PLUGIN_BINARY "PANDA_" ${plugin_name_upper} "_PLUGIN_BINARY") 49 set(${PLUGIN_SOURCE} "${PLUGIN_SOURCE_DIR}" PARENT_SCOPE) 50 set(${PLUGIN_BINARY} "${CMAKE_CURRENT_BINARY_DIR}/plugins/${plugin_name}" PARENT_SCOPE) 51 52 panda_promote_to_definitions(${PANDA_WITH_PLUGIN}) 53endfunction() 54 55LISTPLUGINS(PLUGINS ${CMAKE_CURRENT_SOURCE_DIR}/plugins) 56 57foreach(plugin ${PLUGINS}) 58 register_plugin(${plugin}) 59endforeach() 60 61# Merge Plugins machinery. Example below. 62# 63# ===== Code in core part ===== 64# [some_component/CMakeLists.txt] 65# declare_plugin_file("get_word_size.h") 66# 67# [some_core_file.cpp] 68# void GetWordSize(Language lang) { 69# switch (lang) { 70# #include "some_component/generated/get_word_size.h" 71# } 72# } 73# 74# ===== Code in some plugin ===== 75# [CMakeLists.txt] 76# add_merge_plugin(PLUGIN_NAME "get_word_size.h" INPUT_FILE "plugin_get_word_size.h") 77# 78# [plugin_get_word_size.h] 79# case (Language::PLUGIN_LANGUAGE) 80# return 4; 81# break; 82# 83# After that, content of `some_component/generated/get_word_size.h` file will be filled by all files passed via `add_merge_plugin`. 84# In our case it will be just one file `plugin_get_word_size.h`. 85 86add_custom_target(merge_plugins) 87set_target_properties(merge_plugins PROPERTIES PLUGINS "") 88 89# Declare plugin file for merge_plugins machinery. 90function(declare_plugin_file NAME) 91 string(REGEX REPLACE "[/\\.]" "_" plugin_files_target "${NAME}__files") 92 add_custom_target(${plugin_files_target}) 93 set_target_properties(${plugin_files_target} PROPERTIES 94 PLUGIN_FILES "" 95 GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated") 96 97 get_target_property(PLUGINS merge_plugins PLUGINS) 98 list(APPEND PLUGINS ${NAME}) 99 set_target_properties(merge_plugins PROPERTIES PLUGINS "${PLUGINS}") 100 101 add_dependencies(merge_plugins ${plugin_files_target}) 102endfunction() 103 104# Add file to embedded plugin 105# Arguments: 106# [in] PLUGIN_NAME - name of the plugin, where file should be added 107# [in] INPUT_FILE - path to file to be added to the plugin 108function(add_merge_plugin) 109 set(prefix ARG) 110 set(singleValues PLUGIN_NAME INPUT_FILE) 111 cmake_parse_arguments(${prefix} "" "${singleValues}" "${multiValues}" ${ARGN}) 112 113 string(REGEX REPLACE "[/\\.]" "_" plugin_files_target "${ARG_PLUGIN_NAME}__files") 114 if (NOT TARGET ${plugin_files_target}) 115 message(FATAL_ERROR "Plugin file '${ARG_PLUGIN_NAME}' was not declared!") 116 endif() 117 118 get_target_property(FILES ${plugin_files_target} PLUGIN_FILES) 119 list(APPEND FILES ${ARG_INPUT_FILE}) 120 set_target_properties(${plugin_files_target} PROPERTIES PLUGIN_FILES "${FILES}") 121endfunction() 122