@@ -338,4 +338,191 @@ function(fuzztest_proto_library)
338338
339339 add_library (fuzztest::${FUZZTEST_PROTO_LIB_NAME} ALIAS ${_NAME} )
340340
341- endfunction ()
341+ endfunction ()
342+
343+ # fuzztest_flatbuffers_generate_headers()
344+ #
345+ # Modified version of `flatbuffers_generate_headers`
346+ # from https://github.com/google/flatbuffers/blob/master/CMake/BuildFlatBuffers.cmake
347+ # Supports having the embedded schema header in the output set.
348+ #
349+ # Creates a target that can be linked against that generates flatbuffer headers.
350+ #
351+ # This function takes a target name and a list of schemas. You can also specify
352+ # other flagc flags using the FLAGS option to change the behavior of the flatc
353+ # tool.
354+ #
355+ # When the target_link_libraries is done within a different directory than
356+ # flatbuffers_generate_headers is called, then the target should also be dependent
357+ # the custom generation target called fuzztest_GENERATE_<TARGET>.
358+ #
359+ # Arguments:
360+ # TARGET: The name of the target to generate.
361+ # SCHEMAS: The list of schema files to generate code for.
362+ # BINARY_SCHEMAS_DIR: Optional. The directory in which to generate binary
363+ # schemas. Binary schemas will only be generated if a path is provided.
364+ # INCLUDE: Optional. Search for includes in the specified paths. (Use this
365+ # instead of "-I <path>" and the FLAGS option so that CMake is aware of
366+ # the directories that need to be searched).
367+ # INCLUDE_PREFIX: Optional. The directory in which to place the generated
368+ # files. Use this instead of the --include-prefix option.
369+ # FLAGS: Optional. A list of any additional flags that you would like to pass
370+ # to flatc.
371+ # TESTONLY: When added, this target will only be built if both
372+ # BUILD_TESTING=ON and FUZZTEST_BUILD_TESTING=ON.
373+ #
374+ # Example:
375+ #
376+ # fuzztest_flatbuffers_library(
377+ # TARGET my_generated_headers_target
378+ # INCLUDE_PREFIX ${MY_INCLUDE_PREFIX}"
379+ # SCHEMAS ${MY_SCHEMA_FILES}
380+ # BINARY_SCHEMAS_DIR "${MY_BINARY_SCHEMA_DIRECTORY}"
381+ # FLAGS --gen-object-api)
382+ #
383+ # target_link_libraries(MyExecutableTarget
384+ # PRIVATE fuzztest_my_generated_headers_target
385+ # )
386+ #
387+ # Optional (only needed within different directory):
388+ # add_dependencies(app fuzztest_GENERATE_my_generated_headers_target)
389+ function (fuzztest_flatbuffers_generate_headers)
390+ # Parse function arguments.
391+ set (options TESTONLY)
392+ set (one_value_args
393+ "TARGET"
394+ "INCLUDE_PREFIX"
395+ "BINARY_SCHEMAS_DIR" )
396+ set (multi_value_args
397+ "SCHEMAS"
398+ "INCLUDE"
399+ "FLAGS" )
400+ cmake_parse_arguments (
401+ PARSE_ARGV 0
402+ FLATBUFFERS_GENERATE_HEADERS
403+ "${options} "
404+ "${one_value_args} "
405+ "${multi_value_args} " )
406+
407+ if (FLATBUFFERS_GENERATE_HEADERS_TESTONLY AND NOT (BUILD_TESTING AND FUZZTEST_BUILD_TESTING))
408+ return ()
409+ endif ()
410+
411+ # Test if including from FindFlatBuffers
412+ if (FLATBUFFERS_FLATC_EXECUTABLE)
413+ set (FLATC_TARGET "" )
414+ set (FLATC ${FLATBUFFERS_FLATC_EXECUTABLE} )
415+ elseif (TARGET flatbuffers::flatc)
416+ set (FLATC_TARGET flatbuffers::flatc)
417+ set (FLATC flatbuffers::flatc)
418+ else ()
419+ set (FLATC_TARGET flatc)
420+ set (FLATC flatc)
421+ endif ()
422+
423+ set (working_dir "${CMAKE_CURRENT_SOURCE_DIR} " )
424+
425+ # Generate the include files parameters.
426+ set (include_params "" )
427+ foreach (include_dir ${FLATBUFFERS_GENERATE_HEADERS_INCLUDE} )
428+ set (include_params -I ${include_dir} ${include_params} )
429+ endforeach ()
430+
431+ # Create a directory to place the generated code.
432+ set (generated_target_dir "${CMAKE_CURRENT_BINARY_DIR} " )
433+ set (generated_include_dir "${generated_target_dir} " )
434+ if (NOT ${FLATBUFFERS_GENERATE_HEADERS_INCLUDE_PREFIX} STREQUAL "" )
435+ set (generated_include_dir "${generated_include_dir} /${FLATBUFFERS_GENERATE_HEADERS_INCLUDE_PREFIX} " )
436+ list (APPEND FLATBUFFERS_GENERATE_HEADERS_FLAGS
437+ "--include-prefix" ${FLATBUFFERS_GENERATE_HEADERS_INCLUDE_PREFIX} )
438+ endif ()
439+
440+ set (generated_custom_commands)
441+
442+ # Create rules to generate the code for each schema.
443+ foreach (schema ${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS} )
444+ get_filename_component (filename ${schema} NAME_WE )
445+ set (generated_include "${generated_include_dir} /${filename} _generated.h" )
446+ # Add the embedded schema header in the output set if requested.
447+ if ("${FLATBUFFERS_GENERATE_HEADERS_FLAGS} " MATCHES "--bfbs-gen-embed" )
448+ list (APPEND generated_include "${generated_include_dir} /${filename} _bfbs_generated.h" )
449+ endif ()
450+
451+ # Generate files for grpc if needed
452+ set (generated_source_file)
453+ if ("${FLATBUFFERS_GENERATE_HEADERS_FLAGS} " MATCHES "--grpc" )
454+ # Check if schema file contain a rpc_service definition
455+ file (STRINGS ${schema} has_grpc REGEX "rpc_service" )
456+ if (has_grpc)
457+ list (APPEND generated_include "${generated_include_dir} /${filename} .grpc.fb.h" )
458+ set (generated_source_file "${generated_include_dir} /${filename} .grpc.fb.cc" )
459+ endif ()
460+ endif ()
461+
462+ add_custom_command (
463+ OUTPUT ${generated_include} ${generated_source_file}
464+ COMMAND ${FLATC} ${FLATC_ARGS}
465+ -o ${generated_include_dir}
466+ ${include_params}
467+ -c ${schema}
468+ ${FLATBUFFERS_GENERATE_HEADERS_FLAGS}
469+ DEPENDS ${FLATC_TARGET} ${schema}
470+ WORKING_DIRECTORY "${working_dir} "
471+ COMMENT "Building ${schema} flatbuffers..." )
472+ list (APPEND all_generated_header_files ${generated_include} )
473+ list (APPEND all_generated_source_files ${generated_source_file} )
474+ list (APPEND generated_custom_commands "${generated_include} " "${generated_source_file} " )
475+
476+ # Generate the binary flatbuffers schemas if instructed to.
477+ if (NOT ${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR} STREQUAL "" )
478+ set (binary_schema
479+ "${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR} /${filename} .bfbs" )
480+ add_custom_command (
481+ OUTPUT ${binary_schema}
482+ COMMAND ${FLATC} -b --schema
483+ -o ${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR}
484+ ${include_params}
485+ ${schema}
486+ DEPENDS ${FLATC_TARGET} ${schema}
487+ WORKING_DIRECTORY "${working_dir} " )
488+ list (APPEND generated_custom_commands "${binary_schema} " )
489+ list (APPEND all_generated_binary_files ${binary_schema} )
490+ endif ()
491+ endforeach ()
492+
493+ # Create an additional target as add_custom_command scope is only within same directory (CMakeFile.txt)
494+ set (generate_target fuzztest_GENERATE_${FLATBUFFERS_GENERATE_HEADERS_TARGET} )
495+ add_custom_target (${generate_target} ALL
496+ DEPENDS ${generated_custom_commands}
497+ COMMENT "Generating flatbuffer target fuzztest_${FLATBUFFERS_GENERATE_HEADERS_TARGET} " )
498+
499+ # Set up interface library
500+ add_library (fuzztest_${FLATBUFFERS_GENERATE_HEADERS_TARGET} INTERFACE )
501+ add_dependencies (
502+ fuzztest_${FLATBUFFERS_GENERATE_HEADERS_TARGET}
503+ ${FLATC}
504+ ${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS} )
505+ target_include_directories (
506+ fuzztest_${FLATBUFFERS_GENERATE_HEADERS_TARGET}
507+ INTERFACE ${generated_target_dir} )
508+
509+ # Organize file layout for IDEs.
510+ source_group (
511+ TREE "${generated_target_dir} "
512+ PREFIX "Flatbuffers/Generated/Headers Files"
513+ FILES ${all_generated_header_files} )
514+ source_group (
515+ TREE "${generated_target_dir} "
516+ PREFIX "Flatbuffers/Generated/Source Files"
517+ FILES ${all_generated_source_files} )
518+ source_group (
519+ TREE ${working_dir}
520+ PREFIX "Flatbuffers/Schemas"
521+ FILES ${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS} )
522+ if (NOT ${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR} STREQUAL "" )
523+ source_group (
524+ TREE "${FLATBUFFERS_GENERATE_HEADERS_BINARY_SCHEMAS_DIR} "
525+ PREFIX "Flatbuffers/Generated/Binary Schemas"
526+ FILES ${all_generated_binary_files} )
527+ endif ()
528+ endfunction ()
0 commit comments