| # Copyright 2022 The Pigweed Authors |
| # |
| # 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 |
| # |
| # https://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. |
| |
| include_guard(GLOBAL) |
| |
| cmake_minimum_required(VERSION 3.20) # string(JSON) |
| |
| include("$ENV{PW_ROOT}/pw_build/pigweed.cmake") |
| |
| # Turns binary blobs into a C++ library of hard-coded byte arrays. The byte |
| # arrays are constant initialized and are safe to access at any time, including |
| # before main(). |
| # |
| # Args: |
| # |
| # HEADER |
| # |
| # The header file to generate. Users will include this file exactly as it is |
| # written here to reference the byte arrays. |
| # |
| # NAMESPACE |
| # |
| # The C++ namespace in which to place the generated blobs. |
| # |
| # BLOB |
| # |
| # A blob to be transformed from file to byte array. Multiple blobs may be |
| # specified. |
| # |
| # Blob args: |
| # |
| # SYMBOL_NAME |
| # |
| # The C++ symbol name for the byte array. |
| # |
| # PATH |
| # |
| # The file path for the binary blob. |
| # |
| # LINKER_SECTION [optional] |
| # |
| # If present, places the byte array in the specified linker section. |
| # |
| # ALIGNAS [optional] |
| # |
| # If present, the byte array is aligned as specified. The value of this |
| # argument is used verbatim in an alignas() specifier for the blob |
| # byte array. |
| # |
| function(pw_cc_blob_library NAME) |
| cmake_parse_arguments(PARSE_ARGV 1 arg "" "HEADER;NAMESPACE" "") |
| |
| set(blobs ${arg_UNPARSED_ARGUMENTS}) |
| set(blob_files "") |
| set(blob_index 0) |
| set(json_blobs "[]") # Create a JSON list of blobs |
| |
| pw_require_args("" arg_ HEADER NAMESPACE) |
| |
| while(NOT "${blobs}" STREQUAL "") |
| list(POP_FRONT blobs first_arg) |
| |
| if(NOT "${first_arg}" STREQUAL BLOB) |
| message(FATAL_ERROR "Invalid syntax in pw_cc_blob_library: " |
| "Expected 'BLOB', found '${first_arg}'.") |
| endif() |
| |
| list(FIND blobs BLOB blob_end) |
| list(SUBLIST blobs 0 "${blob_end}" current_blob) |
| |
| cmake_parse_arguments( |
| blob_arg "" "SYMBOL_NAME;PATH;LINKER_SECTION;ALIGNAS" "" "${current_blob}" |
| ) |
| |
| if(NOT "${blob_arg_UNPARSED_ARGUMENTS}" STREQUAL "") |
| message(FATAL_ERROR "Unexpected BLOB arguments in pw_cc_blob_library: " |
| "${blob_arg_UNPARSED_ARGUMENTS}") |
| endif() |
| |
| pw_require_args("BLOB args for ${CMAKE_CURRENT_FUNCTION}" |
| blob_arg_ PATH SYMBOL_NAME) |
| |
| cmake_path(ABSOLUTE_PATH blob_arg_PATH) |
| list(APPEND blob_files "${blob_arg_PATH}") |
| |
| set(json_blob "{}") |
| _pw_json_set_string_key(json_blob file_path "${blob_arg_PATH}") |
| _pw_json_set_string_key(json_blob symbol_name "${blob_arg_SYMBOL_NAME}") |
| |
| if(NOT "${blob_arg_ALIGNAS}" STREQUAL "") |
| _pw_json_set_string_key(json_blob alignas "${blob_arg_ALIGNAS}") |
| endif() |
| |
| if(NOT "${blob_arg_LINKER_SECTION}" STREQUAL "") |
| _pw_json_set_string_key( |
| json_blob linker_section "${blob_arg_LINKER_SECTION}") |
| endif() |
| |
| string(JSON json_blobs SET "${json_blobs}" "${blob_index}" "${json_blob}") |
| |
| if("${blob_end}" EQUAL -1) |
| break() |
| endif() |
| |
| list(SUBLIST blobs "${blob_end}" -1 blobs) |
| math(EXPR blob_index "${blob_index}+1") |
| endwhile() |
| |
| set(out_dir "${CMAKE_CURRENT_BINARY_DIR}/${NAME}") |
| set(blob_json_file "${out_dir}/blobs.json") |
| |
| file(WRITE "${blob_json_file}" "${json_blobs}") |
| set_property( # Ensure the file is regenerated by CMake if it is deleted. |
| DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${blob_json_file}") |
| |
| set(generated_header "${out_dir}/public/${arg_HEADER}") |
| |
| cmake_path(GET arg_HEADER STEM filename) |
| set(generated_source "${out_dir}/${filename}.cc") |
| |
| add_custom_command( |
| COMMAND |
| python3 |
| "$ENV{PW_ROOT}/pw_build/py/pw_build/generate_cc_blob_library.py" |
| --blob-file "${blob_json_file}" |
| --header-include "${arg_HEADER}" |
| --out-header "${generated_header}" |
| --out-source "${generated_source}" |
| --namespace "${arg_NAMESPACE}" |
| DEPENDS |
| "$ENV{PW_ROOT}/pw_build/py/pw_build/generate_cc_blob_library.py" |
| "${blob_json_file}" |
| ${blob_files} |
| OUTPUT |
| "${generated_header}" |
| "${generated_source}" |
| ) |
| |
| add_custom_target("${NAME}._gen" |
| DEPENDS |
| "${generated_header}" |
| "${generated_source}" |
| ) |
| |
| pw_add_library_generic("${NAME}" OBJECT |
| SOURCES |
| "${generated_source}" |
| PUBLIC_INCLUDES |
| "${out_dir}/public" |
| PUBLIC_DEPS |
| pw_polyfill |
| pw_preprocessor |
| ) |
| add_dependencies("${NAME}" "${NAME}._gen") |
| endfunction(pw_cc_blob_library) |
| |
| # Sets a key with a string value in a JSON object. |
| macro(_pw_json_set_string_key json_var key value) |
| string(JSON "${json_var}" SET "${${json_var}}" "${key}" "\"${value}\"") |
| endmacro() |