...

Text file src/github.com/google/flatbuffers/CMake/BuildFlatBuffers.cmake

Documentation: github.com/google/flatbuffers/CMake

     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  elseif(TARGET flatbuffers::flatc)
    63    set(FLATC_TARGET flatbuffers::flatc)
    64    set(FLATC flatbuffers::flatc)
    65  else()
    66    set(FLATC_TARGET flatc)
    67    set(FLATC flatc)
    68  endif()
    69  set(FLATC_SCHEMA_ARGS --gen-mutable)
    70  if(FLATBUFFERS_FLATC_SCHEMA_EXTRA_ARGS)
    71    set(FLATC_SCHEMA_ARGS
    72      ${FLATBUFFERS_FLATC_SCHEMA_EXTRA_ARGS}
    73      ${FLATC_SCHEMA_ARGS}
    74      )
    75  endif()
    76
    77  set(working_dir "${CMAKE_CURRENT_SOURCE_DIR}")
    78
    79  set(schema_glob "*.fbs")
    80  # Generate the include files parameters.
    81  set(include_params "")
    82  set(all_generated_files "")
    83  foreach (include_dir ${schema_include_dirs})
    84    set(include_params -I ${include_dir} ${include_params})
    85    if (NOT ${copy_text_schemas_dir} STREQUAL "")
    86      # Copy text schemas from dependent folders.
    87      file(GLOB_RECURSE dependent_schemas ${include_dir}/${schema_glob})
    88      foreach (dependent_schema ${dependent_schemas})
    89        file(COPY ${dependent_schema} DESTINATION ${copy_text_schemas_dir})
    90      endforeach()
    91    endif()
    92  endforeach()
    93
    94  foreach(schema ${flatbuffers_schemas})
    95    get_filename_component(filename ${schema} NAME_WE)
    96    # For each schema, do the things we requested.
    97    if (NOT ${generated_includes_dir} STREQUAL "")
    98      set(generated_include ${generated_includes_dir}/${filename}_generated.h)
    99      add_custom_command(
   100        OUTPUT ${generated_include}
   101        COMMAND ${FLATC} ${FLATC_SCHEMA_ARGS}
   102        -o ${generated_includes_dir}
   103        ${include_params}
   104        -c ${schema}
   105        DEPENDS ${FLATC_TARGET} ${schema} ${additional_dependencies}
   106        WORKING_DIRECTORY "${working_dir}")
   107      list(APPEND all_generated_files ${generated_include})
   108    endif()
   109
   110    if (NOT ${binary_schemas_dir} STREQUAL "")
   111      set(binary_schema ${binary_schemas_dir}/${filename}.bfbs)
   112      add_custom_command(
   113        OUTPUT ${binary_schema}
   114        COMMAND ${FLATC} -b --schema
   115        -o ${binary_schemas_dir}
   116        ${include_params}
   117        ${schema}
   118        DEPENDS ${FLATC_TARGET} ${schema} ${additional_dependencies}
   119        WORKING_DIRECTORY "${working_dir}")
   120      list(APPEND all_generated_files ${binary_schema})
   121    endif()
   122
   123    if (NOT ${copy_text_schemas_dir} STREQUAL "")
   124      file(COPY ${schema} DESTINATION ${copy_text_schemas_dir})
   125    endif()
   126  endforeach()
   127
   128  # Create a custom target that depends on all the generated files.
   129  # This is the target that you can depend on to trigger all these
   130  # to be built.
   131  add_custom_target(${custom_target_name}
   132                    DEPENDS ${all_generated_files} ${additional_dependencies})
   133
   134  # Register the include directory we are using.
   135  if (NOT ${generated_includes_dir} STREQUAL "")
   136    include_directories(${generated_includes_dir})
   137    set_property(TARGET ${custom_target_name}
   138      PROPERTY GENERATED_INCLUDES_DIR
   139      ${generated_includes_dir})
   140  endif()
   141
   142  # Register the binary schemas dir we are using.
   143  if (NOT ${binary_schemas_dir} STREQUAL "")
   144    set_property(TARGET ${custom_target_name}
   145      PROPERTY BINARY_SCHEMAS_DIR
   146      ${binary_schemas_dir})
   147  endif()
   148
   149  # Register the text schema copy dir we are using.
   150  if (NOT ${copy_text_schemas_dir} STREQUAL "")
   151    set_property(TARGET ${custom_target_name}
   152      PROPERTY COPY_TEXT_SCHEMAS_DIR
   153      ${copy_text_schemas_dir})
   154  endif()
   155endfunction()
   156
   157# Creates a target that can be linked against that generates flatbuffer headers.
   158#
   159# This function takes a target name and a list of schemas. You can also specify
   160# other flagc flags using the FLAGS option to change the behavior of the flatc
   161# tool.
   162#
   163# When the target_link_libraries is done within a different directory than
   164# flatbuffers_generate_headers is called, then the target should also be dependent
   165# the custom generation target called GENERATE_<TARGET>.
   166#
   167# Arguments:
   168#   TARGET: The name of the target to generate.
   169#   SCHEMAS: The list of schema files to generate code for.
   170#   BINARY_SCHEMAS_DIR: Optional. The directory in which to generate binary
   171#       schemas. Binary schemas will only be generated if a path is provided.
   172#   INCLUDE: Optional. Search for includes in the specified paths. (Use this
   173#       instead of "-I <path>" and the FLAGS option so that CMake is aware of
   174#       the directories that need to be searched).
   175#   INCLUDE_PREFIX: Optional. The directory in which to place the generated
   176#       files. Use this instead of the --include-prefix option.
   177#   FLAGS: Optional. A list of any additional flags that you would like to pass
   178#       to flatc.
   179#
   180# Example:
   181#
   182#     flatbuffers_generate_headers(
   183#         TARGET my_generated_headers_target
   184#         INCLUDE_PREFIX ${MY_INCLUDE_PREFIX}"
   185#         SCHEMAS ${MY_SCHEMA_FILES}
   186#         BINARY_SCHEMAS_DIR "${MY_BINARY_SCHEMA_DIRECTORY}"
   187#         FLAGS --gen-object-api)
   188#
   189#     target_link_libraries(MyExecutableTarget
   190#         PRIVATE my_generated_headers_target
   191#     )
   192#
   193# Optional (only needed within different directory):
   194#     add_dependencies(app GENERATE_my_generated_headers_target)
   195function(flatbuffers_generate_headers)
   196  # Parse function arguments.
   197  set(options)
   198  set(one_value_args
   199    "TARGET"
   200    "INCLUDE_PREFIX"
   201    "BINARY_SCHEMAS_DIR")
   202  set(multi_value_args
   203    "SCHEMAS"
   204    "INCLUDE"
   205    "FLAGS")
   206  cmake_parse_arguments(
   207    PARSE_ARGV 0
   208    FLATBUFFERS_GENERATE_HEADERS
   209    "${options}"
   210    "${one_value_args}"
   211    "${multi_value_args}")
   212
   213  # Test if including from FindFlatBuffers
   214  if(FLATBUFFERS_FLATC_EXECUTABLE)
   215    set(FLATC_TARGET "")
   216    set(FLATC ${FLATBUFFERS_FLATC_EXECUTABLE})
   217  elseif(TARGET flatbuffers::flatc)
   218    set(FLATC_TARGET flatbuffers::flatc)
   219    set(FLATC flatbuffers::flatc)
   220  else()
   221    set(FLATC_TARGET flatc)
   222    set(FLATC flatc)
   223  endif()
   224
   225  set(working_dir "${CMAKE_CURRENT_SOURCE_DIR}")
   226
   227  # Generate the include files parameters.
   228  set(include_params "")
   229  foreach (include_dir ${FLATBUFFERS_GENERATE_HEADERS_INCLUDE})
   230    set(include_params -I ${include_dir} ${include_params})
   231  endforeach()
   232
   233  # Create a directory to place the generated code.
   234  set(generated_target_dir "${CMAKE_CURRENT_BINARY_DIR}/${FLATBUFFERS_GENERATE_HEADERS_TARGET}")
   235  set(generated_include_dir "${generated_target_dir}")
   236  if (NOT ${FLATBUFFERS_GENERATE_HEADERS_INCLUDE_PREFIX} STREQUAL "")
   237    set(generated_include_dir "${generated_include_dir}/${FLATBUFFERS_GENERATE_HEADERS_INCLUDE_PREFIX}")
   238    list(APPEND FLATBUFFERS_GENERATE_HEADERS_FLAGS 
   239         "--include-prefix" ${FLATBUFFERS_GENERATE_HEADERS_INCLUDE_PREFIX})
   240  endif()
   241
   242  set(generated_custom_commands)
   243
   244  # Create rules to generate the code for each schema.
   245  foreach(schema ${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS})
   246    get_filename_component(filename ${schema} NAME_WE)
   247    set(generated_include "${generated_include_dir}/${filename}_generated.h")
   248
   249    # Generate files for grpc if needed
   250    set(generated_source_file)
   251    if("${FLATBUFFERS_GENERATE_HEADERS_FLAGS}" MATCHES "--grpc")
   252      # Check if schema file contain a rpc_service definition
   253      file(STRINGS ${schema} has_grpc REGEX "rpc_service")
   254      if(has_grpc)
   255        list(APPEND generated_include "${generated_include_dir}/${filename}.grpc.fb.h")
   256        set(generated_source_file "${generated_include_dir}/${filename}.grpc.fb.cc")
   257      endif()
   258    endif()
   259
   260    add_custom_command(
   261      OUTPUT ${generated_include} ${generated_source_file}
   262      COMMAND ${FLATC} ${FLATC_ARGS}
   263      -o ${generated_include_dir}
   264      ${include_params}
   265      -c ${schema}
   266      ${FLATBUFFERS_GENERATE_HEADERS_FLAGS}
   267      DEPENDS ${FLATC_TARGET} ${schema}
   268      WORKING_DIRECTORY "${working_dir}"
   269      COMMENT "Building ${schema} flatbuffers...")
   270    list(APPEND all_generated_header_files ${generated_include})
   271    list(APPEND all_generated_source_files ${generated_source_file})
   272    list(APPEND generated_custom_commands "${generated_include}" "${generated_source_file}")
   273
   274    # Geneate the binary flatbuffers schemas if instructed to.
   275    if (NOT ${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR} STREQUAL "")
   276      set(binary_schema
   277          "${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR}/${filename}.bfbs")
   278      add_custom_command(
   279        OUTPUT ${binary_schema}
   280        COMMAND ${FLATC} -b --schema
   281        -o ${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR}
   282        ${include_params}
   283        ${schema}
   284        DEPENDS ${FLATC_TARGET} ${schema}
   285        WORKING_DIRECTORY "${working_dir}")
   286      list(APPEND generated_custom_commands "${binary_schema}")
   287      list(APPEND all_generated_binary_files ${binary_schema})
   288    endif()
   289  endforeach()
   290
   291  # Create an additional target as add_custom_command scope is only within same directory (CMakeFile.txt)
   292  set(generate_target GENERATE_${FLATBUFFERS_GENERATE_HEADERS_TARGET})
   293  add_custom_target(${generate_target} ALL
   294                    DEPENDS ${generated_custom_commands}
   295                    COMMENT "Generating flatbuffer target ${FLATBUFFERS_GENERATE_HEADERS_TARGET}")
   296
   297  # Set up interface library
   298  add_library(${FLATBUFFERS_GENERATE_HEADERS_TARGET} INTERFACE)
   299  target_sources(
   300    ${FLATBUFFERS_GENERATE_HEADERS_TARGET}
   301    INTERFACE
   302      ${all_generated_header_files}
   303      ${all_generated_binary_files}
   304      ${all_generated_source_files}
   305      ${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS})
   306  add_dependencies(
   307    ${FLATBUFFERS_GENERATE_HEADERS_TARGET}
   308    ${FLATC}
   309    ${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS})
   310  target_include_directories(
   311    ${FLATBUFFERS_GENERATE_HEADERS_TARGET}
   312    INTERFACE ${generated_target_dir})
   313
   314  # Organize file layout for IDEs.
   315  source_group(
   316    TREE "${generated_target_dir}"
   317    PREFIX "Flatbuffers/Generated/Headers Files"
   318    FILES ${all_generated_header_files})
   319  source_group(
   320    TREE "${generated_target_dir}"
   321    PREFIX "Flatbuffers/Generated/Source Files"
   322    FILES ${all_generated_source_files})
   323  source_group(
   324    TREE ${working_dir}
   325    PREFIX "Flatbuffers/Schemas"
   326    FILES ${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS})
   327  if (NOT ${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR} STREQUAL "")
   328    source_group(
   329      TREE "${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR}"
   330      PREFIX "Flatbuffers/Generated/Binary Schemas"
   331      FILES ${all_generated_binary_files})
   332  endif()
   333endfunction()
   334
   335# Creates a target that can be linked against that generates flatbuffer binaries
   336# from json files.
   337#
   338# This function takes a target name and a list of schemas and Json files. You
   339# can also specify other flagc flags and options to change the behavior of the
   340# flatc compiler.
   341#
   342# Adding this target to your executable ensurses that the flatbuffer binaries
   343# are compiled before your executable is run.
   344#
   345# Arguments:
   346#   TARGET: The name of the target to generate.
   347#   JSON_FILES: The list of json files to compile to flatbuffers binaries.
   348#   SCHEMA: The flatbuffers schema of the Json files to be compiled.
   349#   INCLUDE: Optional. Search for includes in the specified paths. (Use this 
   350#       instead of "-I <path>" and the FLAGS option so that CMake is aware of 
   351#       the directories that need to be searched).
   352#   OUTPUT_DIR: The directly where the generated flatbuffers binaries should be
   353#       placed.
   354#   FLAGS: Optional. A list of any additional flags that you would like to pass
   355#       to flatc.
   356#
   357# Example:
   358#
   359#     flatbuffers_generate_binary_files(
   360#         TARGET my_binary_data
   361#         SCHEMA "${MY_SCHEMA_DIR}/my_example_schema.fbs"
   362#         JSON_FILES ${MY_JSON_FILES}
   363#         OUTPUT_DIR "${MY_BINARY_DATA_DIRECTORY}"
   364#         FLAGS --strict-json)
   365#
   366#     target_link_libraries(MyExecutableTarget
   367#         PRIVATE my_binary_data
   368#     )
   369function(flatbuffers_generate_binary_files)
   370  # Parse function arguments.
   371  set(options)
   372  set(one_value_args
   373    "TARGET"
   374    "SCHEMA"
   375    "OUTPUT_DIR")
   376  set(multi_value_args
   377    "JSON_FILES"
   378    "INCLUDE"
   379    "FLAGS")
   380  cmake_parse_arguments(
   381    PARSE_ARGV 0
   382    FLATBUFFERS_GENERATE_BINARY_FILES
   383    "${options}"
   384    "${one_value_args}"
   385    "${multi_value_args}")
   386
   387  # Test if including from FindFlatBuffers
   388  if(FLATBUFFERS_FLATC_EXECUTABLE)
   389    set(FLATC_TARGET "")
   390    set(FLATC ${FLATBUFFERS_FLATC_EXECUTABLE})
   391  elseif(TARGET flatbuffers::flatc)
   392    set(FLATC_TARGET flatbuffers::flatc)
   393    set(FLATC flatbuffers::flatc)
   394  else()
   395    set(FLATC_TARGET flatc)
   396    set(FLATC flatc)
   397  endif()
   398
   399  set(working_dir "${CMAKE_CURRENT_SOURCE_DIR}")
   400
   401  # Generate the include files parameters.
   402  set(include_params "")
   403  foreach (include_dir ${FLATBUFFERS_GENERATE_BINARY_FILES_INCLUDE})
   404    set(include_params -I ${include_dir} ${include_params})
   405  endforeach()
   406
   407  # Create rules to generate the flatbuffers binary for each json file.
   408  foreach(json_file ${FLATBUFFERS_GENERATE_BINARY_FILES_JSON_FILES})
   409    get_filename_component(filename ${json_file} NAME_WE)
   410    set(generated_binary_file "${FLATBUFFERS_GENERATE_BINARY_FILES_OUTPUT_DIR}/${filename}.bin")
   411    add_custom_command(
   412      OUTPUT ${generated_binary_file}
   413      COMMAND ${FLATC} ${FLATC_ARGS}
   414      -o ${FLATBUFFERS_GENERATE_BINARY_FILES_OUTPUT_DIR}
   415      ${include_params}
   416      -b ${FLATBUFFERS_GENERATE_BINARY_FILES_SCHEMA} ${json_file}
   417      ${FLATBUFFERS_GENERATE_BINARY_FILES_FLAGS}
   418      DEPENDS ${FLATC_TARGET} ${json_file}
   419      WORKING_DIRECTORY "${working_dir}"
   420      COMMENT "Building ${json_file} binary flatbuffers...")
   421      list(APPEND all_generated_binary_files ${generated_binary_file})
   422  endforeach()
   423
   424  # Set up interface library
   425  add_library(${FLATBUFFERS_GENERATE_BINARY_FILES_TARGET} INTERFACE)
   426  target_sources(
   427    ${FLATBUFFERS_GENERATE_BINARY_FILES_TARGET}
   428    INTERFACE
   429      ${all_generated_binary_files}
   430      ${FLATBUFFERS_GENERATE_BINARY_FILES_JSON_FILES}
   431      ${FLATBUFFERS_GENERATE_BINARY_FILES_SCHEMA})
   432  add_dependencies(
   433    ${FLATBUFFERS_GENERATE_BINARY_FILES_TARGET}
   434    ${FLATC})
   435
   436  # Organize file layout for IDEs.
   437  source_group(
   438    TREE ${working_dir}
   439    PREFIX "Flatbuffers/JSON Files"
   440    FILES ${FLATBUFFERS_GENERATE_BINARY_FILES_JSON_FILES})
   441  source_group(
   442    TREE ${working_dir}
   443    PREFIX "Flatbuffers/Schemas"
   444    FILES ${FLATBUFFERS_GENERATE_BINARY_FILES_SCHEMA})
   445  source_group(
   446    TREE ${FLATBUFFERS_GENERATE_BINARY_FILES_OUTPUT_DIR}
   447    PREFIX "Flatbuffers/Generated/Binary Files"
   448    FILES ${all_generated_binary_files})
   449endfunction()

View as plain text