1# This is an example script for use with CMake projects for locating and configuring 2# the nanopb library. 3# 4# The following variables can be set and are optional: 5# 6# 7# PROTOBUF_SRC_ROOT_FOLDER - When compiling with MSVC, if this cache variable is set 8# the protobuf-default VS project build locations 9# (vsprojects/Debug & vsprojects/Release) will be searched 10# for libraries and binaries. 11# 12# NANOPB_IMPORT_DIRS - List of additional directories to be searched for 13# imported .proto files. 14# 15# NANOPB_GENERATE_CPP_APPEND_PATH - By default -I will be passed to protoc 16# for each directory where a proto file is referenced. 17# Set to FALSE if you want to disable this behaviour. 18# 19# Defines the following variables: 20# 21# NANOPB_FOUND - Found the nanopb library (source&header files, generator tool, protoc compiler tool) 22# NANOPB_INCLUDE_DIRS - Include directories for Google Protocol Buffers 23# 24# The following cache variables are also available to set or use: 25# PROTOBUF_PROTOC_EXECUTABLE - The protoc compiler 26# NANOPB_GENERATOR_SOURCE_DIR - The nanopb generator source 27# 28# ==================================================================== 29# 30# NANOPB_GENERATE_CPP (public function) 31# SRCS = Variable to define with autogenerated 32# source files 33# HDRS = Variable to define with autogenerated 34# header files 35# ARGN = proto files 36# 37# ==================================================================== 38# Example: 39# 40# set(NANOPB_SRC_ROOT_FOLDER "/path/to/nanopb") 41# set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${NANOPB_SRC_ROOT_FOLDER}/cmake) 42# find_package( Nanopb REQUIRED ) 43# include_directories(${NANOPB_INCLUDE_DIRS}) 44# 45# NANOPB_GENERATE_CPP(PROTO_SRCS PROTO_HDRS foo.proto) 46# 47# include_directories(${CMAKE_CURRENT_BINARY_DIR}) 48# add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS}) 49# 50# ==================================================================== 51 52#============================================================================= 53# Copyright 2009 Kitware, Inc. 54# Copyright 2009-2011 Philip Lowman <philip@yhbt.com> 55# Copyright 2008 Esben Mose Hansen, Ange Optimization ApS 56# 57# Redistribution and use in source and binary forms, with or without 58# modification, are permitted provided that the following conditions 59# are met: 60# 61# * Redistributions of source code must retain the above copyright 62# notice, this list of conditions and the following disclaimer. 63# 64# * Redistributions in binary form must reproduce the above copyright 65# notice, this list of conditions and the following disclaimer in the 66# documentation and/or other materials provided with the distribution. 67# 68# * Neither the names of Kitware, Inc., the Insight Software Consortium, 69# nor the names of their contributors may be used to endorse or promote 70# products derived from this software without specific prior written 71# permission. 72# 73# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 74# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 75# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 76# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 77# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 78# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 79# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 80# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 81# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 82# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 83# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 84# 85#============================================================================= 86# 87# Changes 88# 2013.01.31 - Pavlo Ilin - used Modules/FindProtobuf.cmake from cmake 2.8.10 to 89# write FindNanopb.cmake 90# 91#============================================================================= 92 93 94function(NANOPB_GENERATE_CPP SRCS HDRS) 95 if(NOT ARGN) 96 return() 97 endif() 98 99 if(NANOPB_GENERATE_CPP_APPEND_PATH) 100 # Create an include path for each file specified 101 foreach(FIL ${ARGN}) 102 get_filename_component(ABS_FIL ${FIL} ABSOLUTE) 103 get_filename_component(ABS_PATH ${ABS_FIL} PATH) 104 105 list(FIND _nanobp_include_path ${ABS_PATH} _contains_already) 106 if(${_contains_already} EQUAL -1) 107 list(APPEND _nanobp_include_path -I ${ABS_PATH}) 108 endif() 109 endforeach() 110 else() 111 set(_nanobp_include_path -I ${CMAKE_CURRENT_SOURCE_DIR}) 112 endif() 113 114 if(DEFINED NANOPB_IMPORT_DIRS) 115 foreach(DIR ${NANOPB_IMPORT_DIRS}) 116 get_filename_component(ABS_PATH ${DIR} ABSOLUTE) 117 list(FIND _nanobp_include_path ${ABS_PATH} _contains_already) 118 if(${_contains_already} EQUAL -1) 119 list(APPEND _nanobp_include_path -I ${ABS_PATH}) 120 endif() 121 endforeach() 122 endif() 123 124 set(${SRCS}) 125 set(${HDRS}) 126 127 set(GENERATOR_PATH ${CMAKE_BINARY_DIR}/nanopb/generator) 128 129 set(NANOPB_GENERATOR_EXECUTABLE ${GENERATOR_PATH}/nanopb_generator.py) 130 131 set(GENERATOR_CORE_DIR ${GENERATOR_PATH}/proto) 132 set(GENERATOR_CORE_SRC 133 ${GENERATOR_CORE_DIR}/nanopb.proto 134 ${GENERATOR_CORE_DIR}/plugin.proto) 135 136 # Treat the source diretory as immutable. 137 # 138 # Copy the generator directory to the build directory before 139 # compiling python and proto files. Fixes issues when using the 140 # same build directory with different python/protobuf versions 141 # as the binary build directory is discarded across builds. 142 # 143 add_custom_command( 144 OUTPUT ${NANOPB_GENERATOR_EXECUTABLE} ${GENERATOR_CORE_SRC} 145 COMMAND ${CMAKE_COMMAND} -E copy_directory 146 ARGS ${NANOPB_GENERATOR_SOURCE_DIR} ${GENERATOR_PATH} 147 VERBATIM) 148 149 set(GENERATOR_CORE_PYTHON_SRC) 150 foreach(FIL ${GENERATOR_CORE_SRC}) 151 get_filename_component(ABS_FIL ${FIL} ABSOLUTE) 152 get_filename_component(FIL_WE ${FIL} NAME_WE) 153 154 set(output "${GENERATOR_CORE_DIR}/${FIL_WE}_pb2.py") 155 set(GENERATOR_CORE_PYTHON_SRC ${GENERATOR_CORE_PYTHON_SRC} ${output}) 156 add_custom_command( 157 OUTPUT ${output} 158 COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} 159 ARGS -I${GENERATOR_PATH}/proto 160 --python_out=${GENERATOR_CORE_DIR} ${ABS_FIL} 161 DEPENDS ${ABS_FIL} 162 VERBATIM) 163 endforeach() 164 165 foreach(FIL ${ARGN}) 166 get_filename_component(ABS_FIL ${FIL} ABSOLUTE) 167 get_filename_component(FIL_WE ${FIL} NAME_WE) 168 get_filename_component(FIL_DIR ${FIL} PATH) 169 set(NANOPB_OPTIONS_FILE ${FIL_DIR}/${FIL_WE}.options) 170 set(NANOPB_OPTIONS) 171 if(EXISTS ${NANOPB_OPTIONS_FILE}) 172 set(NANOPB_OPTIONS -f ${NANOPB_OPTIONS_FILE}) 173 endif() 174 175 list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.c") 176 list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h") 177 178 add_custom_command( 179 OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb" 180 COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} 181 ARGS -I${GENERATOR_PATH} -I${GENERATOR_CORE_DIR} 182 -I${CMAKE_CURRENT_BINARY_DIR} ${_nanobp_include_path} 183 -o${FIL_WE}.pb ${ABS_FIL} 184 DEPENDS ${ABS_FIL} ${GENERATOR_CORE_PYTHON_SRC} 185 COMMENT "Running C++ protocol buffer compiler on ${FIL}" 186 VERBATIM ) 187 188 add_custom_command( 189 OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.c" 190 "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h" 191 COMMAND ${PYTHON_EXECUTABLE} 192 ARGS ${NANOPB_GENERATOR_EXECUTABLE} ${FIL_WE}.pb ${NANOPB_OPTIONS} 193 DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb" 194 COMMENT "Running nanopb generator on ${FIL_WE}.pb" 195 VERBATIM ) 196 endforeach() 197 198 set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE) 199 set(${SRCS} ${${SRCS}} ${NANOPB_SRCS} PARENT_SCOPE) 200 set(${HDRS} ${${HDRS}} ${NANOPB_HDRS} PARENT_SCOPE) 201 202endfunction() 203 204 205 206# 207# Main. 208# 209 210# By default have NANOPB_GENERATE_CPP macro pass -I to protoc 211# for each directory where a proto file is referenced. 212if(NOT DEFINED NANOPB_GENERATE_CPP_APPEND_PATH) 213 set(NANOPB_GENERATE_CPP_APPEND_PATH TRUE) 214endif() 215 216# Make a really good guess regarding location of NANOPB_SRC_ROOT_FOLDER 217if(NOT DEFINED NANOPB_SRC_ROOT_FOLDER) 218 get_filename_component(NANOPB_SRC_ROOT_FOLDER 219 ${CMAKE_CURRENT_LIST_DIR}/.. ABSOLUTE) 220endif() 221 222# Find the include directory 223find_path(NANOPB_INCLUDE_DIRS 224 pb.h 225 PATHS ${NANOPB_SRC_ROOT_FOLDER} 226) 227mark_as_advanced(NANOPB_INCLUDE_DIRS) 228 229# Find nanopb source files 230set(NANOPB_SRCS) 231set(NANOPB_HDRS) 232list(APPEND _nanopb_srcs pb_decode.c pb_encode.c pb_common.c) 233list(APPEND _nanopb_hdrs pb_decode.h pb_encode.h pb_common.h pb.h) 234 235foreach(FIL ${_nanopb_srcs}) 236 find_file(${FIL}__nano_pb_file NAMES ${FIL} PATHS ${NANOPB_SRC_ROOT_FOLDER} ${NANOPB_INCLUDE_DIRS}) 237 list(APPEND NANOPB_SRCS "${${FIL}__nano_pb_file}") 238 mark_as_advanced(${FIL}__nano_pb_file) 239endforeach() 240 241foreach(FIL ${_nanopb_hdrs}) 242 find_file(${FIL}__nano_pb_file NAMES ${FIL} PATHS ${NANOPB_INCLUDE_DIRS}) 243 mark_as_advanced(${FIL}__nano_pb_file) 244 list(APPEND NANOPB_HDRS "${${FIL}__nano_pb_file}") 245endforeach() 246 247# Find the protoc Executable 248find_program(PROTOBUF_PROTOC_EXECUTABLE 249 NAMES protoc 250 DOC "The Google Protocol Buffers Compiler" 251 PATHS 252 ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/Release 253 ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/Debug 254) 255mark_as_advanced(PROTOBUF_PROTOC_EXECUTABLE) 256 257# Find nanopb generator source dir 258find_path(NANOPB_GENERATOR_SOURCE_DIR 259 NAMES nanopb_generator.py 260 DOC "nanopb generator source" 261 PATHS 262 ${NANOPB_SRC_ROOT_FOLDER}/generator 263) 264mark_as_advanced(NANOPB_GENERATOR_SOURCE_DIR) 265 266find_package(PythonInterp REQUIRED) 267 268include(FindPackageHandleStandardArgs) 269FIND_PACKAGE_HANDLE_STANDARD_ARGS(NANOPB DEFAULT_MSG 270 NANOPB_INCLUDE_DIRS 271 NANOPB_SRCS NANOPB_HDRS 272 NANOPB_GENERATOR_SOURCE_DIR 273 PROTOBUF_PROTOC_EXECUTABLE 274 ) 275