• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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