blob: b0c5c8fbcffdd2a427f6c4a6e013985a3eebd9f6 [file] [log] [blame]
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001# 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}
James Kuszmaul8e62b022022-03-22 09:33:25 -070098 COMMAND ${FLATC} ${FLATC_SCHEMA_ARGS}
Austin Schuhe89fa2d2019-08-14 20:24:23 -070099 -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()
Austin Schuh272c6132020-11-14 16:37:52 -0800153
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")
James Kuszmaul8e62b022022-03-22 09:33:25 -0700233
234 # Generate files for grpc if needed
235 set(generated_source_file)
236 if("${FLATBUFFERS_GENERATE_HEADERS_FLAGS}" MATCHES "--grpc")
237 # Check if schema file contain a rpc_service definition
238 file(STRINGS ${schema} has_grpc REGEX "rpc_service")
239 if(has_grpc)
240 list(APPEND generated_include "${generated_include_dir}/${filename}.grpc.fb.h")
241 set(generated_source_file "${generated_include_dir}/${filename}.grpc.fb.cc")
242 endif()
243 endif()
244
Austin Schuh272c6132020-11-14 16:37:52 -0800245 add_custom_command(
James Kuszmaul8e62b022022-03-22 09:33:25 -0700246 OUTPUT ${generated_include} ${generated_source_file}
Austin Schuh272c6132020-11-14 16:37:52 -0800247 COMMAND ${FLATC} ${FLATC_ARGS}
248 -o ${generated_include_dir}
249 ${include_params}
250 -c ${schema}
251 ${FLATBUFFERS_GENERATE_HEADERS_FLAGS}
252 DEPENDS ${FLATC_TARGET} ${schema}
James Kuszmaul8e62b022022-03-22 09:33:25 -0700253 WORKING_DIRECTORY "${working_dir}"
254 COMMENT "Building ${schema} flatbuffers...")
Austin Schuh272c6132020-11-14 16:37:52 -0800255 list(APPEND all_generated_header_files ${generated_include})
James Kuszmaul8e62b022022-03-22 09:33:25 -0700256 list(APPEND all_generated_source_files ${generated_source_file})
Austin Schuh272c6132020-11-14 16:37:52 -0800257
258 # Geneate the binary flatbuffers schemas if instructed to.
259 if (NOT ${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR} STREQUAL "")
260 set(binary_schema
261 "${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR}/${filename}.bfbs")
262 add_custom_command(
263 OUTPUT ${binary_schema}
264 COMMAND ${FLATC} -b --schema
265 -o ${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR}
266 ${include_params}
267 ${schema}
268 DEPENDS ${FLATC_TARGET} ${schema}
269 WORKING_DIRECTORY "${working_dir}")
270 list(APPEND all_generated_binary_files ${binary_schema})
271 endif()
272 endforeach()
273
274 # Set up interface library
275 add_library(${FLATBUFFERS_GENERATE_HEADERS_TARGET} INTERFACE)
276 target_sources(
277 ${FLATBUFFERS_GENERATE_HEADERS_TARGET}
278 INTERFACE
279 ${all_generated_header_files}
280 ${all_generated_binary_files}
James Kuszmaul8e62b022022-03-22 09:33:25 -0700281 ${all_generated_source_files}
Austin Schuh272c6132020-11-14 16:37:52 -0800282 ${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS})
283 add_dependencies(
284 ${FLATBUFFERS_GENERATE_HEADERS_TARGET}
285 ${FLATC}
286 ${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS})
287 target_include_directories(
288 ${FLATBUFFERS_GENERATE_HEADERS_TARGET}
289 INTERFACE ${generated_target_dir})
290
291 # Organize file layout for IDEs.
292 source_group(
293 TREE "${generated_target_dir}"
294 PREFIX "Flatbuffers/Generated/Headers Files"
295 FILES ${all_generated_header_files})
296 source_group(
James Kuszmaul8e62b022022-03-22 09:33:25 -0700297 TREE "${generated_target_dir}"
298 PREFIX "Flatbuffers/Generated/Source Files"
299 FILES ${all_generated_source_files})
300 source_group(
Austin Schuh272c6132020-11-14 16:37:52 -0800301 TREE ${working_dir}
302 PREFIX "Flatbuffers/Schemas"
303 FILES ${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS})
304 if (NOT ${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR} STREQUAL "")
305 source_group(
306 TREE "${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR}"
307 PREFIX "Flatbuffers/Generated/Binary Schemas"
308 FILES ${all_generated_binary_files})
309 endif()
310endfunction()
311
312# Creates a target that can be linked against that generates flatbuffer binaries
313# from json files.
314#
315# This function takes a target name and a list of schemas and Json files. You
316# can also specify other flagc flags and options to change the behavior of the
317# flatc compiler.
318#
319# Adding this target to your executable ensurses that the flatbuffer binaries
320# are compiled before your executable is run.
321#
322# Arguments:
323# TARGET: The name of the target to generate.
324# JSON_FILES: The list of json files to compile to flatbuffers binaries.
325# SCHEMA: The flatbuffers schema of the Json files to be compiled.
326# INCLUDE: Optional. Search for includes in the specified paths. (Use this
327# instead of "-I <path>" and the FLAGS option so that CMake is aware of
328# the directories that need to be searched).
329# OUTPUT_DIR: The directly where the generated flatbuffers binaries should be
330# placed.
331# FLAGS: Optional. A list of any additional flags that you would like to pass
332# to flatc.
333#
334# Example:
335#
336# flatbuffers_generate_binary_files(
337# TARGET my_binary_data
338# SCHEMA "${MY_SCHEMA_DIR}/my_example_schema.fbs"
339# JSON_FILES ${MY_JSON_FILES}
340# OUTPUT_DIR "${MY_BINARY_DATA_DIRECTORY}"
341# FLAGS --strict-json)
342#
343# target_link_libraries(MyExecutableTarget
344# PRIVATE my_binary_data
345# )
346function(flatbuffers_generate_binary_files)
347 # Parse function arguments.
348 set(options)
349 set(one_value_args
350 "TARGET"
351 "SCHEMA"
352 "OUTPUT_DIR")
353 set(multi_value_args
354 "JSON_FILES"
355 "INCLUDE"
356 "FLAGS")
357 cmake_parse_arguments(
358 PARSE_ARGV 0
359 FLATBUFFERS_GENERATE_BINARY_FILES
360 "${options}"
361 "${one_value_args}"
362 "${multi_value_args}")
363
364 # Test if including from FindFlatBuffers
365 if(FLATBUFFERS_FLATC_EXECUTABLE)
366 set(FLATC_TARGET "")
367 set(FLATC ${FLATBUFFERS_FLATC_EXECUTABLE})
368 else()
369 set(FLATC_TARGET flatc)
370 set(FLATC flatc)
371 endif()
372
373 set(working_dir "${CMAKE_CURRENT_SOURCE_DIR}")
374
375 # Generate the include files parameters.
376 set(include_params "")
377 foreach (include_dir ${FLATBUFFERS_GENERATE_BINARY_FILES_INCLUDE})
378 set(include_params -I ${include_dir} ${include_params})
379 endforeach()
380
381 # Create rules to generate the flatbuffers binary for each json file.
382 foreach(json_file ${FLATBUFFERS_GENERATE_BINARY_FILES_JSON_FILES})
383 get_filename_component(filename ${json_file} NAME_WE)
384 set(generated_binary_file "${FLATBUFFERS_GENERATE_BINARY_FILES_OUTPUT_DIR}/${filename}.bin")
385 add_custom_command(
386 OUTPUT ${generated_binary_file}
387 COMMAND ${FLATC} ${FLATC_ARGS}
388 -o ${FLATBUFFERS_GENERATE_BINARY_FILES_OUTPUT_DIR}
389 ${include_params}
390 -b ${FLATBUFFERS_GENERATE_BINARY_FILES_SCHEMA} ${json_file}
391 ${FLATBUFFERS_GENERATE_BINARY_FILES_FLAGS}
392 DEPENDS ${FLATC_TARGET} ${json_file}
James Kuszmaul8e62b022022-03-22 09:33:25 -0700393 WORKING_DIRECTORY "${working_dir}"
394 COMMENT "Building ${json_file} binary flatbuffers...")
Austin Schuh272c6132020-11-14 16:37:52 -0800395 list(APPEND all_generated_binary_files ${generated_binary_file})
396 endforeach()
397
398 # Set up interface library
399 add_library(${FLATBUFFERS_GENERATE_BINARY_FILES_TARGET} INTERFACE)
400 target_sources(
401 ${FLATBUFFERS_GENERATE_BINARY_FILES_TARGET}
402 INTERFACE
403 ${all_generated_binary_files}
404 ${FLATBUFFERS_GENERATE_BINARY_FILES_JSON_FILES}
405 ${FLATBUFFERS_GENERATE_BINARY_FILES_SCHEMA})
406 add_dependencies(
407 ${FLATBUFFERS_GENERATE_BINARY_FILES_TARGET}
408 ${FLATC})
409
410 # Organize file layout for IDEs.
411 source_group(
412 TREE ${working_dir}
413 PREFIX "Flatbuffers/JSON Files"
414 FILES ${FLATBUFFERS_GENERATE_BINARY_FILES_JSON_FILES})
415 source_group(
416 TREE ${working_dir}
417 PREFIX "Flatbuffers/Schemas"
418 FILES ${FLATBUFFERS_GENERATE_BINARY_FILES_SCHEMA})
419 source_group(
420 TREE ${FLATBUFFERS_GENERATE_BINARY_FILES_OUTPUT_DIR}
421 PREFIX "Flatbuffers/Generated/Binary Files"
422 FILES ${all_generated_binary_files})
423endfunction()