1# Copyright 2015 Google Inc. All rights reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15# General function to create FlatBuffer build rules for the given list of 16# schemas. 17# 18# flatbuffers_schemas: A list of flatbuffer schema files to process. 19# 20# schema_include_dirs: A list of schema file include directories, which will be 21# passed to flatc via the -I parameter. 22# 23# custom_target_name: The generated files will be added as dependencies for a 24# new custom target with this name. You should add that target as a dependency 25# for your main target to ensure these files are built. You can also retrieve 26# various properties from this target, such as GENERATED_INCLUDES_DIR, 27# BINARY_SCHEMAS_DIR, and COPY_TEXT_SCHEMAS_DIR. 28# 29# additional_dependencies: A list of additional dependencies that you'd like 30# all generated files to depend on. Pass in a blank string if you have none. 31# 32# generated_includes_dir: Where to generate the C++ header files for these 33# schemas. The generated includes directory will automatically be added to 34# CMake's include directories, and will be where generated header files are 35# placed. This parameter is optional; pass in empty string if you don't want to 36# generate include files for these schemas. 37# 38# binary_schemas_dir: If you specify an optional binary schema directory, binary 39# schemas will be generated for these schemas as well, and placed into the given 40# directory. 41# 42# copy_text_schemas_dir: If you want all text schemas (including schemas from 43# all schema include directories) copied into a directory (for example, if you 44# need them within your project to build JSON files), you can specify that 45# folder here. All text schemas will be copied to that folder. 46# 47# IMPORTANT: Make sure you quote all list arguments you pass to this function! 48# Otherwise CMake will only pass in the first element. 49# Example: build_flatbuffers("${fb_files}" "${include_dirs}" target_name ...) 50function(build_flatbuffers flatbuffers_schemas 51 schema_include_dirs 52 custom_target_name 53 additional_dependencies 54 generated_includes_dir 55 binary_schemas_dir 56 copy_text_schemas_dir) 57 58 # Test if including from FindFlatBuffers 59 if(FLATBUFFERS_FLATC_EXECUTABLE) 60 set(FLATC_TARGET "") 61 set(FLATC ${FLATBUFFERS_FLATC_EXECUTABLE}) 62 else() 63 set(FLATC_TARGET flatc) 64 set(FLATC flatc) 65 endif() 66 set(FLATC_SCHEMA_ARGS --gen-mutable) 67 if(FLATBUFFERS_FLATC_SCHEMA_EXTRA_ARGS) 68 set(FLATC_SCHEMA_ARGS 69 ${FLATBUFFERS_FLATC_SCHEMA_EXTRA_ARGS} 70 ${FLATC_SCHEMA_ARGS} 71 ) 72 endif() 73 74 set(working_dir "${CMAKE_CURRENT_SOURCE_DIR}") 75 76 set(schema_glob "*.fbs") 77 # Generate the include files parameters. 78 set(include_params "") 79 set(all_generated_files "") 80 foreach (include_dir ${schema_include_dirs}) 81 set(include_params -I ${include_dir} ${include_params}) 82 if (NOT ${copy_text_schemas_dir} STREQUAL "") 83 # Copy text schemas from dependent folders. 84 file(GLOB_RECURSE dependent_schemas ${include_dir}/${schema_glob}) 85 foreach (dependent_schema ${dependent_schemas}) 86 file(COPY ${dependent_schema} DESTINATION ${copy_text_schemas_dir}) 87 endforeach() 88 endif() 89 endforeach() 90 91 foreach(schema ${flatbuffers_schemas}) 92 get_filename_component(filename ${schema} NAME_WE) 93 # For each schema, do the things we requested. 94 if (NOT ${generated_includes_dir} STREQUAL "") 95 set(generated_include ${generated_includes_dir}/${filename}_generated.h) 96 add_custom_command( 97 OUTPUT ${generated_include} 98 COMMAND ${FLATC} ${FLATC_ARGS} 99 -o ${generated_includes_dir} 100 ${include_params} 101 -c ${schema} 102 DEPENDS ${FLATC_TARGET} ${schema} ${additional_dependencies} 103 WORKING_DIRECTORY "${working_dir}") 104 list(APPEND all_generated_files ${generated_include}) 105 endif() 106 107 if (NOT ${binary_schemas_dir} STREQUAL "") 108 set(binary_schema ${binary_schemas_dir}/${filename}.bfbs) 109 add_custom_command( 110 OUTPUT ${binary_schema} 111 COMMAND ${FLATC} -b --schema 112 -o ${binary_schemas_dir} 113 ${include_params} 114 ${schema} 115 DEPENDS ${FLATC_TARGET} ${schema} ${additional_dependencies} 116 WORKING_DIRECTORY "${working_dir}") 117 list(APPEND all_generated_files ${binary_schema}) 118 endif() 119 120 if (NOT ${copy_text_schemas_dir} STREQUAL "") 121 file(COPY ${schema} DESTINATION ${copy_text_schemas_dir}) 122 endif() 123 endforeach() 124 125 # Create a custom target that depends on all the generated files. 126 # This is the target that you can depend on to trigger all these 127 # to be built. 128 add_custom_target(${custom_target_name} 129 DEPENDS ${all_generated_files} ${additional_dependencies}) 130 131 # Register the include directory we are using. 132 if (NOT ${generated_includes_dir} STREQUAL "") 133 include_directories(${generated_includes_dir}) 134 set_property(TARGET ${custom_target_name} 135 PROPERTY GENERATED_INCLUDES_DIR 136 ${generated_includes_dir}) 137 endif() 138 139 # Register the binary schemas dir we are using. 140 if (NOT ${binary_schemas_dir} STREQUAL "") 141 set_property(TARGET ${custom_target_name} 142 PROPERTY BINARY_SCHEMAS_DIR 143 ${binary_schemas_dir}) 144 endif() 145 146 # Register the text schema copy dir we are using. 147 if (NOT ${copy_text_schemas_dir} STREQUAL "") 148 set_property(TARGET ${custom_target_name} 149 PROPERTY COPY_TEXT_SCHEMAS_DIR 150 ${copy_text_schemas_dir}) 151 endif() 152endfunction() 153 154# Creates a target that can be linked against that generates flatbuffer headers. 155# 156# This function takes a target name and a list of schemas. You can also specify 157# other flagc flags using the FLAGS option to change the behavior of the flatc 158# tool. 159# 160# Arguments: 161# TARGET: The name of the target to generate. 162# SCHEMAS: The list of schema files to generate code for. 163# BINARY_SCHEMAS_DIR: Optional. The directory in which to generate binary 164# schemas. Binary schemas will only be generated if a path is provided. 165# INCLUDE: Optional. Search for includes in the specified paths. (Use this 166# instead of "-I <path>" and the FLAGS option so that CMake is aware of 167# the directories that need to be searched). 168# INCLUDE_PREFIX: Optional. The directory in which to place the generated 169# files. Use this instead of the --include-prefix option. 170# FLAGS: Optional. A list of any additional flags that you would like to pass 171# to flatc. 172# 173# Example: 174# 175# flatbuffers_generate_headers( 176# TARGET my_generated_headers_target 177# INCLUDE_PREFIX ${MY_INCLUDE_PREFIX}" 178# SCHEMAS ${MY_SCHEMA_FILES} 179# BINARY_SCHEMAS_DIR "${MY_BINARY_SCHEMA_DIRECTORY}" 180# FLAGS --gen-object-api) 181# 182# target_link_libraries(MyExecutableTarget 183# PRIVATE my_generated_headers_target 184# ) 185function(flatbuffers_generate_headers) 186 # Parse function arguments. 187 set(options) 188 set(one_value_args 189 "TARGET" 190 "INCLUDE_PREFIX" 191 "BINARY_SCHEMAS_DIR") 192 set(multi_value_args 193 "SCHEMAS" 194 "INCLUDE" 195 "FLAGS") 196 cmake_parse_arguments( 197 PARSE_ARGV 0 198 FLATBUFFERS_GENERATE_HEADERS 199 "${options}" 200 "${one_value_args}" 201 "${multi_value_args}") 202 203 # Test if including from FindFlatBuffers 204 if(FLATBUFFERS_FLATC_EXECUTABLE) 205 set(FLATC_TARGET "") 206 set(FLATC ${FLATBUFFERS_FLATC_EXECUTABLE}) 207 else() 208 set(FLATC_TARGET flatc) 209 set(FLATC flatc) 210 endif() 211 212 set(working_dir "${CMAKE_CURRENT_SOURCE_DIR}") 213 214 # Generate the include files parameters. 215 set(include_params "") 216 foreach (include_dir ${FLATBUFFERS_GENERATE_HEADERS_INCLUDE}) 217 set(include_params -I ${include_dir} ${include_params}) 218 endforeach() 219 220 # Create a directory to place the generated code. 221 set(generated_target_dir "${CMAKE_CURRENT_BINARY_DIR}/${FLATBUFFERS_GENERATE_HEADERS_TARGET}") 222 set(generated_include_dir "${generated_target_dir}") 223 if (NOT ${FLATBUFFERS_GENERATE_HEADERS_INCLUDE_PREFIX} STREQUAL "") 224 set(generated_include_dir "${generated_include_dir}/${FLATBUFFERS_GENERATE_HEADERS_INCLUDE_PREFIX}") 225 list(APPEND FLATBUFFERS_GENERATE_HEADERS_FLAGS 226 "--include-prefix" ${FLATBUFFERS_GENERATE_HEADERS_INCLUDE_PREFIX}) 227 endif() 228 229 # Create rules to generate the code for each schema. 230 foreach(schema ${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS}) 231 get_filename_component(filename ${schema} NAME_WE) 232 set(generated_include "${generated_include_dir}/${filename}_generated.h") 233 add_custom_command( 234 OUTPUT ${generated_include} 235 COMMAND ${FLATC} ${FLATC_ARGS} 236 -o ${generated_include_dir} 237 ${include_params} 238 -c ${schema} 239 ${FLATBUFFERS_GENERATE_HEADERS_FLAGS} 240 DEPENDS ${FLATC_TARGET} ${schema} 241 WORKING_DIRECTORY "${working_dir}") 242 list(APPEND all_generated_header_files ${generated_include}) 243 244 # Geneate the binary flatbuffers schemas if instructed to. 245 if (NOT ${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR} STREQUAL "") 246 set(binary_schema 247 "${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR}/${filename}.bfbs") 248 add_custom_command( 249 OUTPUT ${binary_schema} 250 COMMAND ${FLATC} -b --schema 251 -o ${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR} 252 ${include_params} 253 ${schema} 254 DEPENDS ${FLATC_TARGET} ${schema} 255 WORKING_DIRECTORY "${working_dir}") 256 list(APPEND all_generated_binary_files ${binary_schema}) 257 endif() 258 endforeach() 259 260 # Set up interface library 261 add_library(${FLATBUFFERS_GENERATE_HEADERS_TARGET} INTERFACE) 262 target_sources( 263 ${FLATBUFFERS_GENERATE_HEADERS_TARGET} 264 INTERFACE 265 ${all_generated_header_files} 266 ${all_generated_binary_files} 267 ${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS}) 268 add_dependencies( 269 ${FLATBUFFERS_GENERATE_HEADERS_TARGET} 270 ${FLATC} 271 ${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS}) 272 target_include_directories( 273 ${FLATBUFFERS_GENERATE_HEADERS_TARGET} 274 INTERFACE ${generated_target_dir}) 275 276 # Organize file layout for IDEs. 277 source_group( 278 TREE "${generated_target_dir}" 279 PREFIX "Flatbuffers/Generated/Headers Files" 280 FILES ${all_generated_header_files}) 281 source_group( 282 TREE ${working_dir} 283 PREFIX "Flatbuffers/Schemas" 284 FILES ${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS}) 285 if (NOT ${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR} STREQUAL "") 286 source_group( 287 TREE "${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR}" 288 PREFIX "Flatbuffers/Generated/Binary Schemas" 289 FILES ${all_generated_binary_files}) 290 endif() 291endfunction() 292 293# Creates a target that can be linked against that generates flatbuffer binaries 294# from json files. 295# 296# This function takes a target name and a list of schemas and Json files. You 297# can also specify other flagc flags and options to change the behavior of the 298# flatc compiler. 299# 300# Adding this target to your executable ensurses that the flatbuffer binaries 301# are compiled before your executable is run. 302# 303# Arguments: 304# TARGET: The name of the target to generate. 305# JSON_FILES: The list of json files to compile to flatbuffers binaries. 306# SCHEMA: The flatbuffers schema of the Json files to be compiled. 307# INCLUDE: Optional. Search for includes in the specified paths. (Use this 308# instead of "-I <path>" and the FLAGS option so that CMake is aware of 309# the directories that need to be searched). 310# OUTPUT_DIR: The directly where the generated flatbuffers binaries should be 311# placed. 312# FLAGS: Optional. A list of any additional flags that you would like to pass 313# to flatc. 314# 315# Example: 316# 317# flatbuffers_generate_binary_files( 318# TARGET my_binary_data 319# SCHEMA "${MY_SCHEMA_DIR}/my_example_schema.fbs" 320# JSON_FILES ${MY_JSON_FILES} 321# OUTPUT_DIR "${MY_BINARY_DATA_DIRECTORY}" 322# FLAGS --strict-json) 323# 324# target_link_libraries(MyExecutableTarget 325# PRIVATE my_binary_data 326# ) 327function(flatbuffers_generate_binary_files) 328 # Parse function arguments. 329 set(options) 330 set(one_value_args 331 "TARGET" 332 "SCHEMA" 333 "OUTPUT_DIR") 334 set(multi_value_args 335 "JSON_FILES" 336 "INCLUDE" 337 "FLAGS") 338 cmake_parse_arguments( 339 PARSE_ARGV 0 340 FLATBUFFERS_GENERATE_BINARY_FILES 341 "${options}" 342 "${one_value_args}" 343 "${multi_value_args}") 344 345 # Test if including from FindFlatBuffers 346 if(FLATBUFFERS_FLATC_EXECUTABLE) 347 set(FLATC_TARGET "") 348 set(FLATC ${FLATBUFFERS_FLATC_EXECUTABLE}) 349 else() 350 set(FLATC_TARGET flatc) 351 set(FLATC flatc) 352 endif() 353 354 set(working_dir "${CMAKE_CURRENT_SOURCE_DIR}") 355 356 # Generate the include files parameters. 357 set(include_params "") 358 foreach (include_dir ${FLATBUFFERS_GENERATE_BINARY_FILES_INCLUDE}) 359 set(include_params -I ${include_dir} ${include_params}) 360 endforeach() 361 362 # Create rules to generate the flatbuffers binary for each json file. 363 foreach(json_file ${FLATBUFFERS_GENERATE_BINARY_FILES_JSON_FILES}) 364 get_filename_component(filename ${json_file} NAME_WE) 365 set(generated_binary_file "${FLATBUFFERS_GENERATE_BINARY_FILES_OUTPUT_DIR}/${filename}.bin") 366 add_custom_command( 367 OUTPUT ${generated_binary_file} 368 COMMAND ${FLATC} ${FLATC_ARGS} 369 -o ${FLATBUFFERS_GENERATE_BINARY_FILES_OUTPUT_DIR} 370 ${include_params} 371 -b ${FLATBUFFERS_GENERATE_BINARY_FILES_SCHEMA} ${json_file} 372 ${FLATBUFFERS_GENERATE_BINARY_FILES_FLAGS} 373 DEPENDS ${FLATC_TARGET} ${json_file} 374 WORKING_DIRECTORY "${working_dir}") 375 list(APPEND all_generated_binary_files ${generated_binary_file}) 376 endforeach() 377 378 # Set up interface library 379 add_library(${FLATBUFFERS_GENERATE_BINARY_FILES_TARGET} INTERFACE) 380 target_sources( 381 ${FLATBUFFERS_GENERATE_BINARY_FILES_TARGET} 382 INTERFACE 383 ${all_generated_binary_files} 384 ${FLATBUFFERS_GENERATE_BINARY_FILES_JSON_FILES} 385 ${FLATBUFFERS_GENERATE_BINARY_FILES_SCHEMA}) 386 add_dependencies( 387 ${FLATBUFFERS_GENERATE_BINARY_FILES_TARGET} 388 ${FLATC}) 389 390 # Organize file layout for IDEs. 391 source_group( 392 TREE ${working_dir} 393 PREFIX "Flatbuffers/JSON Files" 394 FILES ${FLATBUFFERS_GENERATE_BINARY_FILES_JSON_FILES}) 395 source_group( 396 TREE ${working_dir} 397 PREFIX "Flatbuffers/Schemas" 398 FILES ${FLATBUFFERS_GENERATE_BINARY_FILES_SCHEMA}) 399 source_group( 400 TREE ${FLATBUFFERS_GENERATE_BINARY_FILES_OUTPUT_DIR} 401 PREFIX "Flatbuffers/Generated/Binary Files" 402 FILES ${all_generated_binary_files}) 403endfunction() 404