From 9ed047596112f881ba9a4a18408e6d22cd22acda Mon Sep 17 00:00:00 2001 From: Winfried Dobbe Date: Wed, 16 Dec 2020 13:27:07 +0100 Subject: [PATCH] #168: add cmake helper function to generate flatbuffer code --- CMakeLists.txt | 1 + README.md | 37 +++++++++++++ cmake/FlatccGenerateSources.cmake | 86 +++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 cmake/FlatccGenerateSources.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 40dee3b3c..5bef0fe7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -346,5 +346,6 @@ set_target_properties(${dist_targets} if (FLATCC_INSTALL) install(DIRECTORY include/flatcc DESTINATION include) + install(DIRECTORY cmake DESTINATION ${CMAKE_INSTALL_PREFIX}) endif() diff --git a/README.md b/README.md index 860672e01..df6e6e897 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ executable also handle optional json parsing or printing in less than 2 us for a * [Online Forums](#online-forums) * [Introduction](#introduction) * [Project Details](#project-details) +* [Use in CMake build](#use-in-cmake-build) * [Poll on Meson Build](#poll-on-meson-build) * [Reporting Bugs](#reporting-bugs) * [Status](#status) @@ -186,6 +187,42 @@ their place. **NOTE: Big-endian platforms are only supported as of release 0.4.0.** +## Use in CMake build + +If your project uses the CMake build system, you can include cmake module +`cmake/FlatccGenerateSources.cmake` that provides the following cmake +function: + + flatcc_generate_sources(GENERATED_SOURCE_DIRECTORY + GENERATE_BUILDER + GENERATE_VERIFIER + EXPECTED_OUTPUT_FILES + DEFINITION_FILES +) + +`GENERATE_BUILDER` and `GENERATE_VERIFIER` are boolean options. When specified +they will instruct flatcc to generate builder / verifier source code. + +Optionally you can let cmake know the directory where the flatcc executable +is located in environment variable `FLATCC_BUILD_BIN_PATH`. This is especially +usefull when cross-compiling. In that case you should provide the directory +where the build arch flatcc compiler executable is located. + +The flatcc_generate_sources function will create a cmake custom command to +generate the output files during just before compilation (so in the build +step, not the configure step). + +Example: + + include(FlatccGenerateSources) + flatcc_generate_sources(GENERATED_SOURCE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/datadef + GENERATE_BUILDER + GENERATE_VERIFIER + EXPECTED_OUTPUT_FILES datadef/seclif_protocol_reader.h + datadef/seclif_protocol_builder.h + datadef/seclif_protocol_verifier.h + DEFINITION_FILES ${CMAKE_CURRENT_SOURCE_DIR}/datadef/seclif_protocol.fbs + ) ## Poll on Meson Build diff --git a/cmake/FlatccGenerateSources.cmake b/cmake/FlatccGenerateSources.cmake new file mode 100644 index 000000000..4141dacd4 --- /dev/null +++ b/cmake/FlatccGenerateSources.cmake @@ -0,0 +1,86 @@ + cmake_minimum_required(VERSION 3.5) + +# Use the following function to generate C source files from flatbuffer definition files: +# +# flatcc_generate_sources(GENERATED_SOURCE_DIRECTORY +# GENERATE_BUILDER +# GENERATE_VERIFIER +# EXPECTED_OUTPUT_FILES +# DEFINITION_FILES +# ) +# +# GENERATE_BUILDER and GENERATE_VERIFIER are boolean options. When specified they will instruct +# flatcc to generate builder / verifier source code. +# +# With cross-compiling you should provide the directory where the flatcc compiler executable is located +# in environment variable FLATCC_BUILD_BIN_PATH. If you use Conan and add flatcc as a build requirement +# this will be done automatically. + + +function(flatcc_generate_sources) + + # parse function arguments + set(OUTPREFIX "FLATCC") #variables created by 'cmake_parse_arguments' will be prefixed with this + set(NO_VAL_ARGS GENERATE_BUILDER GENERATE_VERIFIER) + set(SINGLE_VAL_ARGS GENERATED_SOURCE_DIRECTORY) + set(MULTI_VAL_ARGS DEFINITION_FILES EXPECTED_OUTPUT_FILES CC_OPTIONS) + + cmake_parse_arguments(${OUTPREFIX} + "${NO_VAL_ARGS}" + "${SINGLE_VAL_ARGS}" + "${MULTI_VAL_ARGS}" + ${ARGN} + ) + if (GENERATED_SOURCE_DIRECTORY IN_LIST FLATCC_KEYWORDS_MISSING_VALUES) + message(FATAL_ERROR "No directory provided after GENERATED_SOURCE_DIRECTORY keyword") + endif() + if (NOT FLATCC_GENERATED_SOURCE_DIRECTORY) + set(FLATCC_GENERATED_SOURCE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + endif() + message(STATUS "Flatcc sources will be generated in directory ${FLATCC_GENERATED_SOURCE_DIRECTORY}") + + if (FLATCC_GENERATE_BUILDER) + list(APPEND FLATCC_CC_OPTIONS --builder) + endif() + if (FLATCC_GENERATE_VERIFIER) + list(APPEND FLATCC_CC_OPTIONS --verifier) + endif() + + if (FLATCC_DEFINITION_FILES) + if (NOT EXISTS ${FLATCC_GENERATED_SOURCE_DIRECTORY}) + file(MAKE_DIRECTORY ${FLATCC_GENERATED_SOURCE_DIRECTORY}) + endif() + + message(VERBOSE "Executing command ${FLATCC_COMPILER} ${FLATCC_CC_OPTIONS} -o ${FLATCC_GENERATED_SOURCE_DIRECTORY} ${FLATCC_DEFINITION_FILES}") + add_custom_command(OUTPUT ${FLATCC_EXPECTED_OUTPUT_FILES} + COMMAND ${FLATCC_COMPILER} ${FLATCC_CC_OPTIONS} -o ${FLATCC_GENERATED_SOURCE_DIRECTORY} ${FLATCC_DEFINITION_FILES} + WORKING_DIRECTORY ${FLATCC_GENERATED_SOURCE_DIRECTORY}) + else() + message(WARNING "No flatbuffer definition files provided, no sources will be generated") + endif() + +endfunction() + + +#### Main #### + +#When cross-compiling user can provide location of the flatbuffers to C compiler in build arch via +#environment variable FLATCC_BUILD_BIN_PATH +set(FLATCC_BIN_PATH "$ENV{FLATCC_BUILD_BIN_PATH}") +if (FLATCC_BIN_PATH) + #user provided location where asn1c compiler executable is installed + find_program(FLATCC_COMPILER flatcc + PATHS ${FLATCC_BIN_PATH} + NO_DEFAULT_PATH + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH +) +else() + #Find compiler exe + find_program(FLATCC_COMPILER flatcc) +endif() + + +if (NOT FLATCC_COMPILER) + message(FATAL_ERROR "Could not locate the flatcc compiler executable") +endif()