1# 2# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3# 4# SPDX-License-Identifier: BSD-2-Clause 5# 6 7include_guard(GLOBAL) 8 9# set up some paths 10set(GENERATOR_PATH ${CMAKE_BINARY_DIR}/nanopb/generator) 11set(NANOPB_GENERATOR_EXECUTABLE ${GENERATOR_PATH}/nanopb_generator.py) 12set(GENERATOR_CORE_DIR ${GENERATOR_PATH}/proto) 13set(GENERATOR_CORE_SRC ${GENERATOR_CORE_DIR}/nanopb.proto) 14 15# figure out where nanopb is 16if(NOT DEFINED NANOPB_SRC_ROOT_FOLDER) 17 find_file(NANOPB_SRC_ROOT_FOLDER nanopb PATHS ${CMAKE_SOURCE_DIR} NO_CMAKE_FIND_ROOT_PATH) 18endif() 19mark_as_advanced(FORCE NANOPB_SRC_ROOT_FOLDER) 20if("${NANOPB_SRC_ROOT_FOLDER}" STREQUAL "NANOPB_SRC_ROOT_FOLDER-NOTFOUND") 21 message( 22 FATAL_ERROR "Failed to find nanopb. Consider cmake -DNANOPB_SRC_ROOT_FOLDER=/path/to/nanopb" 23 ) 24endif() 25 26# include the nanopb cmake stuff - portions of it have been forked to this file, 27# but much of it is still useful. 28list(APPEND CMAKE_MODULE_PATH "${NANOPB_SRC_ROOT_FOLDER}/extra/") 29find_package(Nanopb REQUIRED) 30 31# generate nanopb runtime library 32file(GLOB nanopb_src ${NANOPB_SRC_ROOT_FOLDER}/*.h ${NANOPB_SRC_ROOT_FOLDER}/*.c) 33 34add_library(nanopb STATIC EXCLUDE_FROM_ALL ${nanopb_src}) 35target_include_directories(nanopb PUBLIC ${NANOPB_SRC_ROOT_FOLDER}) 36target_link_libraries(nanopb muslc) 37 38# Treat the source diretory as immutable. 39# 40# Copy the generator directory to the build directory before 41# compiling python and proto files. 42add_custom_command( 43 TARGET nanopb 44 COMMAND 45 ${CMAKE_COMMAND} -E copy_directory 46 ARGS 47 ${NANOPB_GENERATOR_SOURCE_DIR} 48 ${GENERATOR_PATH} 49 BYPRODUCTS 50 ${NANOPB_GENERATOR_EXECUTABLE} 51 ${GENERATOR_CORE_SRC} 52 VERBATIM 53) 54 55# This is a fork of nanopb's NANOPB_GENERATE_CPP function 56# for seL4 57function(SEL4_GENERATE_PROTOBUF SRCS HDRS) 58 cmake_parse_arguments(NANOPB_GENERATE_CPP "" "RELPATH" "" ${ARGN}) 59 if(NOT NANOPB_GENERATE_CPP_UNPARSED_ARGUMENTS) 60 return() 61 endif() 62 63 set(GENERATOR_PATH ${CMAKE_BINARY_DIR}/nanopb/generator) 64 set(NANOPB_GENERATOR_EXECUTABLE ${GENERATOR_PATH}/nanopb_generator.py) 65 66 set(GENERATOR_CORE_DIR ${GENERATOR_PATH}/proto) 67 set(GENERATOR_CORE_SRC ${GENERATOR_CORE_DIR}/nanopb.proto) 68 69 set(_nanopb_include_path "-I${NANOPB_SRC_ROOT_FOLDER}/src") 70 if(DEFINED NANOPB_IMPORT_DIRS) 71 foreach(DIR ${NANOPB_IMPORT_DIRS}) 72 get_filename_component(ABS_PATH ${DIR} ABSOLUTE) 73 list(APPEND _nanopb_include_path "-I${ABS_PATH}") 74 endforeach() 75 endif() 76 list(REMOVE_DUPLICATES _nanopb_include_path) 77 78 if(NANOPB_GENERATE_CPP_APPEND_PATH) 79 # Create an include path for each file specified 80 foreach(FIL ${NANOPB_GENERATE_CPP_UNPARSED_ARGUMENTS}) 81 get_filename_component(ABS_FIL ${FIL} ABSOLUTE) 82 get_filename_component(ABS_PATH ${ABS_FIL} PATH) 83 list(APPEND _nanopb_include_path "-I${ABS_PATH}") 84 endforeach() 85 else() 86 set(_nanopb_include_path "-I${CMAKE_CURRENT_SOURCE_DIR}") 87 endif() 88 89 if(NANOPB_GENERATE_CPP_RELPATH) 90 list(APPEND _nanopb_include_path "-I${NANOPB_GENERATE_CPP_RELPATH}") 91 endif() 92 93 if(DEFINED NANOPB_IMPORT_DIRS) 94 foreach(DIR ${NANOPB_IMPORT_DIRS}) 95 get_filename_component(ABS_PATH ${DIR} ABSOLUTE) 96 list(APPEND _nanopb_include_path "-I${ABS_PATH}") 97 endforeach() 98 endif() 99 100 list(REMOVE_DUPLICATES _nanopb_include_path) 101 102 set(NANOPB_GENERATOR_PLUGIN ${GENERATOR_PATH}/protoc-gen-nanopb) 103 104 if(NANOPB_GENERATE_CPP_RELPATH) 105 get_filename_component(ABS_ROOT ${NANOPB_GENERATE_CPP_RELPATH} ABSOLUTE) 106 endif() 107 foreach(FIL ${NANOPB_GENERATE_CPP_UNPARSED_ARGUMENTS}) 108 get_filename_component(ABS_FIL ${FIL} ABSOLUTE) 109 get_filename_component(FIL_WE ${FIL} NAME_WE) 110 get_filename_component(FIL_DIR ${FIL} PATH) 111 set(FIL_PATH_REL) 112 if(ABS_ROOT) 113 # Check that the file is under the given "RELPATH" 114 string(FIND ${ABS_FIL} ${ABS_ROOT} LOC) 115 if(${LOC} EQUAL 0) 116 string( 117 REPLACE 118 "${ABS_ROOT}/" 119 "" 120 FIL_REL 121 ${ABS_FIL} 122 ) 123 get_filename_component(FIL_PATH_REL ${FIL_REL} PATH) 124 file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}) 125 endif() 126 endif() 127 if(NOT FIL_PATH_REL) 128 set(FIL_PATH_REL ".") 129 endif() 130 131 list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}/${FIL_WE}.pb.c") 132 list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}/${FIL_WE}.pb.h") 133 134 set(NANOPB_PLUGIN_OPTIONS) 135 set(NANOPB_OPTIONS_DIRS) 136 137 # If there an options file in the same working directory, set it as a dependency 138 set(NANOPB_OPTIONS_FILE ${FIL_DIR}/${FIL_WE}.options) 139 if(EXISTS ${NANOPB_OPTIONS_FILE}) 140 # Get directory as lookups for dependency options fail if an options 141 # file is used. The options is still set as a dependency of the 142 # generated source and header. 143 get_filename_component(options_dir ${NANOPB_OPTIONS_FILE} DIRECTORY) 144 list(APPEND NANOPB_OPTIONS_DIRS ${options_dir}) 145 else() 146 set(NANOPB_OPTIONS_FILE) 147 endif() 148 149 # If the dependencies are options files, we need to pass the directories 150 # as arguments to nanopb 151 foreach(depends_file ${NANOPB_DEPENDS}) 152 get_filename_component(ext ${depends_file} EXT) 153 if(ext STREQUAL ".options") 154 get_filename_component(depends_dir ${depends_file} DIRECTORY) 155 list(APPEND NANOPB_OPTIONS_DIRS ${depends_dir}) 156 endif() 157 endforeach() 158 159 if(NANOPB_OPTIONS_DIRS) 160 list(REMOVE_DUPLICATES NANOPB_OPTIONS_DIRS) 161 endif() 162 163 foreach(options_path ${NANOPB_OPTIONS_DIRS}) 164 set(NANOPB_PLUGIN_OPTIONS "${NANOPB_PLUGIN_OPTIONS} -I${options_path}") 165 endforeach() 166 167 if(NANOPB_OPTIONS) 168 set(NANOPB_PLUGIN_OPTIONS "${NANOPB_PLUGIN_OPTIONS} ${NANOPB_OPTIONS}") 169 endif() 170 171 add_custom_command( 172 OUTPUT 173 "${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}/${FIL_WE}.pb.c" 174 "${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}/${FIL_WE}.pb.h" 175 COMMAND 176 ${PROTOBUF_PROTOC_EXECUTABLE} 177 ARGS 178 -I${GENERATOR_PATH} 179 -I${GENERATOR_CORE_DIR} 180 -I${CMAKE_CURRENT_BINARY_DIR} 181 ${_nanopb_include_path} 182 --plugin=protoc-gen-nanopb=${NANOPB_GENERATOR_PLUGIN} 183 "--nanopb_out=${NANOPB_PLUGIN_OPTIONS}:${CMAKE_CURRENT_BINARY_DIR}" ${ABS_FIL} 184 DEPENDS 185 ${ABS_FIL} 186 ${GENERATOR_CORE_SRC} 187 ${GENERATOR_CORE_PYTHON_SRC} 188 ${NANOPB_OPTIONS_FILE} 189 ${NANOPB_DEPENDS} 190 COMMENT "Running C++ protocol buffer compiler using nanopb plugin on ${FIL}" 191 VERBATIM 192 ) 193 194 endforeach() 195 196 set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE) 197 set(${SRCS} ${${SRCS}} ${NANOPB_SRCS} PARENT_SCOPE) 198 set(${HDRS} ${${HDRS}} ${NANOPB_HDRS} PARENT_SCOPE) 199endfunction() 200