1*61c4878aSAndroid Build Coastguard Worker# Copyright 2022 The Pigweed Authors 2*61c4878aSAndroid Build Coastguard Worker# 3*61c4878aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4*61c4878aSAndroid Build Coastguard Worker# use this file except in compliance with the License. You may obtain a copy of 5*61c4878aSAndroid Build Coastguard Worker# the License at 6*61c4878aSAndroid Build Coastguard Worker# 7*61c4878aSAndroid Build Coastguard Worker# https://www.apache.org/licenses/LICENSE-2.0 8*61c4878aSAndroid Build Coastguard Worker# 9*61c4878aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*61c4878aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11*61c4878aSAndroid Build Coastguard Worker# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12*61c4878aSAndroid Build Coastguard Worker# License for the specific language governing permissions and limitations under 13*61c4878aSAndroid Build Coastguard Worker# the License. 14*61c4878aSAndroid Build Coastguard Worker 15*61c4878aSAndroid Build Coastguard Workerinclude_guard(GLOBAL) 16*61c4878aSAndroid Build Coastguard Worker 17*61c4878aSAndroid Build Coastguard Workercmake_minimum_required(VERSION 3.20) # string(JSON) 18*61c4878aSAndroid Build Coastguard Worker 19*61c4878aSAndroid Build Coastguard Workerinclude("$ENV{PW_ROOT}/pw_build/pigweed.cmake") 20*61c4878aSAndroid Build Coastguard Worker 21*61c4878aSAndroid Build Coastguard Worker# Turns binary blobs into a C++ library of hard-coded byte arrays. The byte 22*61c4878aSAndroid Build Coastguard Worker# arrays are constant initialized and are safe to access at any time, including 23*61c4878aSAndroid Build Coastguard Worker# before main(). 24*61c4878aSAndroid Build Coastguard Worker# 25*61c4878aSAndroid Build Coastguard Worker# Args: 26*61c4878aSAndroid Build Coastguard Worker# 27*61c4878aSAndroid Build Coastguard Worker# HEADER 28*61c4878aSAndroid Build Coastguard Worker# 29*61c4878aSAndroid Build Coastguard Worker# The header file to generate. Users will include this file exactly as it is 30*61c4878aSAndroid Build Coastguard Worker# written here to reference the byte arrays. 31*61c4878aSAndroid Build Coastguard Worker# 32*61c4878aSAndroid Build Coastguard Worker# NAMESPACE 33*61c4878aSAndroid Build Coastguard Worker# 34*61c4878aSAndroid Build Coastguard Worker# The C++ namespace in which to place the generated blobs. 35*61c4878aSAndroid Build Coastguard Worker# 36*61c4878aSAndroid Build Coastguard Worker# BLOB 37*61c4878aSAndroid Build Coastguard Worker# 38*61c4878aSAndroid Build Coastguard Worker# A blob to be transformed from file to byte array. Multiple blobs may be 39*61c4878aSAndroid Build Coastguard Worker# specified. 40*61c4878aSAndroid Build Coastguard Worker# 41*61c4878aSAndroid Build Coastguard Worker# Blob args: 42*61c4878aSAndroid Build Coastguard Worker# 43*61c4878aSAndroid Build Coastguard Worker# SYMBOL_NAME 44*61c4878aSAndroid Build Coastguard Worker# 45*61c4878aSAndroid Build Coastguard Worker# The C++ symbol name for the byte array. 46*61c4878aSAndroid Build Coastguard Worker# 47*61c4878aSAndroid Build Coastguard Worker# PATH 48*61c4878aSAndroid Build Coastguard Worker# 49*61c4878aSAndroid Build Coastguard Worker# The file path for the binary blob. 50*61c4878aSAndroid Build Coastguard Worker# 51*61c4878aSAndroid Build Coastguard Worker# LINKER_SECTION [optional] 52*61c4878aSAndroid Build Coastguard Worker# 53*61c4878aSAndroid Build Coastguard Worker# If present, places the byte array in the specified linker section. 54*61c4878aSAndroid Build Coastguard Worker# 55*61c4878aSAndroid Build Coastguard Worker# ALIGNAS [optional] 56*61c4878aSAndroid Build Coastguard Worker# 57*61c4878aSAndroid Build Coastguard Worker# If present, the byte array is aligned as specified. The value of this 58*61c4878aSAndroid Build Coastguard Worker# argument is used verbatim in an alignas() specifier for the blob 59*61c4878aSAndroid Build Coastguard Worker# byte array. 60*61c4878aSAndroid Build Coastguard Worker# 61*61c4878aSAndroid Build Coastguard Workerfunction(pw_cc_blob_library NAME) 62*61c4878aSAndroid Build Coastguard Worker cmake_parse_arguments(PARSE_ARGV 1 arg "" "HEADER;NAMESPACE" "") 63*61c4878aSAndroid Build Coastguard Worker 64*61c4878aSAndroid Build Coastguard Worker set(blobs ${arg_UNPARSED_ARGUMENTS}) 65*61c4878aSAndroid Build Coastguard Worker set(blob_files "") 66*61c4878aSAndroid Build Coastguard Worker set(blob_index 0) 67*61c4878aSAndroid Build Coastguard Worker set(json_blobs "[]") # Create a JSON list of blobs 68*61c4878aSAndroid Build Coastguard Worker 69*61c4878aSAndroid Build Coastguard Worker pw_require_args("" arg_ HEADER NAMESPACE) 70*61c4878aSAndroid Build Coastguard Worker 71*61c4878aSAndroid Build Coastguard Worker while(NOT "${blobs}" STREQUAL "") 72*61c4878aSAndroid Build Coastguard Worker list(POP_FRONT blobs first_arg) 73*61c4878aSAndroid Build Coastguard Worker 74*61c4878aSAndroid Build Coastguard Worker if(NOT "${first_arg}" STREQUAL BLOB) 75*61c4878aSAndroid Build Coastguard Worker message(FATAL_ERROR "Invalid syntax in pw_cc_blob_library: " 76*61c4878aSAndroid Build Coastguard Worker "Expected 'BLOB', found '${first_arg}'.") 77*61c4878aSAndroid Build Coastguard Worker endif() 78*61c4878aSAndroid Build Coastguard Worker 79*61c4878aSAndroid Build Coastguard Worker list(FIND blobs BLOB blob_end) 80*61c4878aSAndroid Build Coastguard Worker list(SUBLIST blobs 0 "${blob_end}" current_blob) 81*61c4878aSAndroid Build Coastguard Worker 82*61c4878aSAndroid Build Coastguard Worker cmake_parse_arguments( 83*61c4878aSAndroid Build Coastguard Worker blob_arg "" "SYMBOL_NAME;PATH;LINKER_SECTION;ALIGNAS" "" "${current_blob}" 84*61c4878aSAndroid Build Coastguard Worker ) 85*61c4878aSAndroid Build Coastguard Worker 86*61c4878aSAndroid Build Coastguard Worker if(NOT "${blob_arg_UNPARSED_ARGUMENTS}" STREQUAL "") 87*61c4878aSAndroid Build Coastguard Worker message(FATAL_ERROR "Unexpected BLOB arguments in pw_cc_blob_library: " 88*61c4878aSAndroid Build Coastguard Worker "${blob_arg_UNPARSED_ARGUMENTS}") 89*61c4878aSAndroid Build Coastguard Worker endif() 90*61c4878aSAndroid Build Coastguard Worker 91*61c4878aSAndroid Build Coastguard Worker pw_require_args("BLOB args for ${CMAKE_CURRENT_FUNCTION}" 92*61c4878aSAndroid Build Coastguard Worker blob_arg_ PATH SYMBOL_NAME) 93*61c4878aSAndroid Build Coastguard Worker 94*61c4878aSAndroid Build Coastguard Worker cmake_path(ABSOLUTE_PATH blob_arg_PATH) 95*61c4878aSAndroid Build Coastguard Worker list(APPEND blob_files "${blob_arg_PATH}") 96*61c4878aSAndroid Build Coastguard Worker 97*61c4878aSAndroid Build Coastguard Worker set(json_blob "{}") 98*61c4878aSAndroid Build Coastguard Worker _pw_json_set_string_key(json_blob file_path "${blob_arg_PATH}") 99*61c4878aSAndroid Build Coastguard Worker _pw_json_set_string_key(json_blob symbol_name "${blob_arg_SYMBOL_NAME}") 100*61c4878aSAndroid Build Coastguard Worker 101*61c4878aSAndroid Build Coastguard Worker if(NOT "${blob_arg_ALIGNAS}" STREQUAL "") 102*61c4878aSAndroid Build Coastguard Worker _pw_json_set_string_key(json_blob alignas "${blob_arg_ALIGNAS}") 103*61c4878aSAndroid Build Coastguard Worker endif() 104*61c4878aSAndroid Build Coastguard Worker 105*61c4878aSAndroid Build Coastguard Worker if(NOT "${blob_arg_LINKER_SECTION}" STREQUAL "") 106*61c4878aSAndroid Build Coastguard Worker _pw_json_set_string_key( 107*61c4878aSAndroid Build Coastguard Worker json_blob linker_section "${blob_arg_LINKER_SECTION}") 108*61c4878aSAndroid Build Coastguard Worker endif() 109*61c4878aSAndroid Build Coastguard Worker 110*61c4878aSAndroid Build Coastguard Worker string(JSON json_blobs SET "${json_blobs}" "${blob_index}" "${json_blob}") 111*61c4878aSAndroid Build Coastguard Worker 112*61c4878aSAndroid Build Coastguard Worker if("${blob_end}" EQUAL -1) 113*61c4878aSAndroid Build Coastguard Worker break() 114*61c4878aSAndroid Build Coastguard Worker endif() 115*61c4878aSAndroid Build Coastguard Worker 116*61c4878aSAndroid Build Coastguard Worker list(SUBLIST blobs "${blob_end}" -1 blobs) 117*61c4878aSAndroid Build Coastguard Worker math(EXPR blob_index "${blob_index}+1") 118*61c4878aSAndroid Build Coastguard Worker endwhile() 119*61c4878aSAndroid Build Coastguard Worker 120*61c4878aSAndroid Build Coastguard Worker set(out_dir "${CMAKE_CURRENT_BINARY_DIR}/${NAME}") 121*61c4878aSAndroid Build Coastguard Worker set(blob_json_file "${out_dir}/blobs.json") 122*61c4878aSAndroid Build Coastguard Worker 123*61c4878aSAndroid Build Coastguard Worker file(WRITE "${blob_json_file}" "${json_blobs}") 124*61c4878aSAndroid Build Coastguard Worker set_property( # Ensure the file is regenerated by CMake if it is deleted. 125*61c4878aSAndroid Build Coastguard Worker DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${blob_json_file}") 126*61c4878aSAndroid Build Coastguard Worker 127*61c4878aSAndroid Build Coastguard Worker set(generated_header "${out_dir}/public/${arg_HEADER}") 128*61c4878aSAndroid Build Coastguard Worker 129*61c4878aSAndroid Build Coastguard Worker cmake_path(GET arg_HEADER STEM filename) 130*61c4878aSAndroid Build Coastguard Worker set(generated_source "${out_dir}/${filename}.cc") 131*61c4878aSAndroid Build Coastguard Worker 132*61c4878aSAndroid Build Coastguard Worker add_custom_command( 133*61c4878aSAndroid Build Coastguard Worker COMMAND 134*61c4878aSAndroid Build Coastguard Worker python3 135*61c4878aSAndroid Build Coastguard Worker "$ENV{PW_ROOT}/pw_build/py/pw_build/generate_cc_blob_library.py" 136*61c4878aSAndroid Build Coastguard Worker --blob-file "${blob_json_file}" 137*61c4878aSAndroid Build Coastguard Worker --header-include "${arg_HEADER}" 138*61c4878aSAndroid Build Coastguard Worker --out-header "${generated_header}" 139*61c4878aSAndroid Build Coastguard Worker --out-source "${generated_source}" 140*61c4878aSAndroid Build Coastguard Worker --namespace "${arg_NAMESPACE}" 141*61c4878aSAndroid Build Coastguard Worker DEPENDS 142*61c4878aSAndroid Build Coastguard Worker "$ENV{PW_ROOT}/pw_build/py/pw_build/generate_cc_blob_library.py" 143*61c4878aSAndroid Build Coastguard Worker "${blob_json_file}" 144*61c4878aSAndroid Build Coastguard Worker ${blob_files} 145*61c4878aSAndroid Build Coastguard Worker OUTPUT 146*61c4878aSAndroid Build Coastguard Worker "${generated_header}" 147*61c4878aSAndroid Build Coastguard Worker "${generated_source}" 148*61c4878aSAndroid Build Coastguard Worker ) 149*61c4878aSAndroid Build Coastguard Worker 150*61c4878aSAndroid Build Coastguard Worker add_custom_target("${NAME}._gen" 151*61c4878aSAndroid Build Coastguard Worker DEPENDS 152*61c4878aSAndroid Build Coastguard Worker "${generated_header}" 153*61c4878aSAndroid Build Coastguard Worker "${generated_source}" 154*61c4878aSAndroid Build Coastguard Worker ) 155*61c4878aSAndroid Build Coastguard Worker 156*61c4878aSAndroid Build Coastguard Worker pw_add_library_generic("${NAME}" OBJECT 157*61c4878aSAndroid Build Coastguard Worker SOURCES 158*61c4878aSAndroid Build Coastguard Worker "${generated_source}" 159*61c4878aSAndroid Build Coastguard Worker PUBLIC_INCLUDES 160*61c4878aSAndroid Build Coastguard Worker "${out_dir}/public" 161*61c4878aSAndroid Build Coastguard Worker PUBLIC_DEPS 162*61c4878aSAndroid Build Coastguard Worker pw_polyfill 163*61c4878aSAndroid Build Coastguard Worker pw_preprocessor 164*61c4878aSAndroid Build Coastguard Worker ) 165*61c4878aSAndroid Build Coastguard Worker add_dependencies("${NAME}" "${NAME}._gen") 166*61c4878aSAndroid Build Coastguard Workerendfunction(pw_cc_blob_library) 167*61c4878aSAndroid Build Coastguard Worker 168*61c4878aSAndroid Build Coastguard Worker# Sets a key with a string value in a JSON object. 169*61c4878aSAndroid Build Coastguard Workermacro(_pw_json_set_string_key json_var key value) 170*61c4878aSAndroid Build Coastguard Worker string(JSON "${json_var}" SET "${${json_var}}" "${key}" "\"${value}\"") 171*61c4878aSAndroid Build Coastguard Workerendmacro() 172