From d5e09c1ed750e4a684b2f95718e6e05b98f20a21 Mon Sep 17 00:00:00 2001 From: Andrew McNulty Date: Mon, 17 Apr 2023 16:29:51 +0200 Subject: [PATCH 1/5] Update meson build system. This commit brings the meson build system branch up-to-date with the current CMake build system. It should be possible now to build and test flatcc using the Meson build system, like so: $ meson setup build $ meson compile -C build $ meson test -C build This is not yet integrated with the shell scripts in the scipts directory. --- meson.build | 228 ++++++++++++++++++ meson_options.txt | 78 ++++++ rules/meson.build | 105 ++++++++ samples/meson.build | 11 + samples/monster/meson.build | 39 +++ samples/reflection/meson.build | 19 ++ scripts/build.cfg.meson | 2 + test/benchmark/benchflatc/benchflatc.cpp | 2 + test/benchmark/benchflatc/meson.build | 11 + test/benchmark/benchflatcc/benchflatcc.c | 1 + test/benchmark/benchflatcc/meson.build | 9 + test/benchmark/benchflatccjson/meson.build | 9 + test/benchmark/benchmain/benchmain.h | 4 + test/benchmark/benchraw/benchraw.c | 1 + test/benchmark/benchraw/meson.build | 6 + test/cgen_test/meson.build | 8 + test/emit_test/meson.build | 7 + test/flatc_compat/meson.build | 8 + test/json_test/meson.build | 32 +++ test/load_test/meson.build | 8 + test/meson.build | 72 ++++++ test/monster_test/meson.build | 10 + test/monster_test_concat/meson.build | 52 ++++ .../monster_test_concat_explicit.c | 24 ++ test/monster_test_cpp/meson.build | 10 + test/monster_test_prefix/meson.build | 18 ++ test/monster_test_solo/meson.build | 26 ++ test/reflection_test/meson.build | 28 +++ 28 files changed, 828 insertions(+) create mode 100644 meson.build create mode 100644 meson_options.txt create mode 100644 rules/meson.build create mode 100644 samples/meson.build create mode 100644 samples/monster/meson.build create mode 100644 samples/reflection/meson.build create mode 100644 scripts/build.cfg.meson create mode 100644 test/benchmark/benchflatc/meson.build create mode 100644 test/benchmark/benchflatcc/meson.build create mode 100644 test/benchmark/benchflatccjson/meson.build create mode 100644 test/benchmark/benchraw/meson.build create mode 100644 test/cgen_test/meson.build create mode 100644 test/emit_test/meson.build create mode 100644 test/flatc_compat/meson.build create mode 100644 test/json_test/meson.build create mode 100644 test/load_test/meson.build create mode 100644 test/meson.build create mode 100644 test/monster_test/meson.build create mode 100644 test/monster_test_concat/meson.build create mode 100644 test/monster_test_concat/monster_test_concat_explicit.c create mode 100644 test/monster_test_cpp/meson.build create mode 100644 test/monster_test_prefix/meson.build create mode 100644 test/monster_test_solo/meson.build create mode 100644 test/reflection_test/meson.build diff --git a/meson.build b/meson.build new file mode 100644 index 000000000..cc3a09596 --- /dev/null +++ b/meson.build @@ -0,0 +1,228 @@ +# NOTE: This build system is maintained by the community. +project('flatcc', + 'c', 'cpp', + version : '0.6.1', + license : 'Apache-2.0', + default_options : ['c_std=c11', 'cpp_std=c++11', 'default_library=static'], + meson_version : '>=0.56.0' +) + +buildtype = get_option('buildtype') +ignore_const_cond = get_option('ignore_const_cond') +allow_werror = get_option('allow_werror') +gnu_posix_memalign = get_option('gnu_posix_memalign') +has_c99_var_decl = get_option('c_std') != 'c89' + +cc = meson.get_compiler('c') +cc_id = cc.get_id() +cc_version = cc.version() + +cxx = meson.get_compiler('cpp') + +c_args = [] + +if get_option('flatcc_portable') or cc_id == 'msvc' + c_args += '-DFLATCC_PORTABLE' +endif + +if get_option('flatcc_debug_verify') + c_args += '-DFLATCC_DEBUG_VERIFY=1' +endif + +if get_option('flatcc_fast_double') + c_args += '-DGRISU3_PARSE_ALLOW_ERROR' + c_args += '-DFLATCC_USE_GRISU3=1' +endif + +if buildtype == 'release' or buildtype == 'minsize' + c_args += '-DNDEBUG' +endif + +if cc_id == 'mvsc' + + has_c99_var_decl = cc_version.version_compare('>=18') + +elif cc_id == 'clang' + + c_args += [ + '-Wstrict-prototypes', + '-Wsign-conversion', + '-Wconversion', + '-pedantic', + '-Wextra' + ] + + if ignore_const_cond + c_args += '-Wno-tautological-constant-out-of-range-compare' + endif + + if cc_version.version_compare('< 6') + c_args += '-Wno-missing-field-initializers' + endif + +elif cc_id == 'gcc' + + c_args += [ + '-Wall', + '-Wextra', + ] + + if ignore_const_cond + c_args += '-Wno-type-limits' + endif + + if cc_version.version_compare('>4.8') + c_args += '-Wsign-compare' + endif + + if cc_version.version_compare('>8') + c_args += [ '-Wno-stringop-truncation', '-Wno-format-overflow' ] + endif + + if cc_version.version_compare('>=11') + c_args += '-Wno-misleading-indentation' + endif + + if gnu_posix_memalign + c_args += '-DPORTABLE_POSIX_MEMALIGN=1' + endif + +endif + +if allow_werror + c_args += '-Werror' +endif + +# Reflection must be disabled temporarily when making breaking changes. +if get_option('flatcc_reflection') + c_args += '-DFLATCC_REFLECTION=1' +else + c_args += '-DFLATCC_REFLECTION=0' +endif + +add_project_arguments(cc.get_supported_arguments(c_args), language: 'c') +add_project_arguments(cxx.get_supported_arguments(c_args), language: 'cpp') + +if get_option('xflatcc_gen_version') + revisition_tag = vcs_tag( + input: 'config/version.in', + output: 'revision', + command: ['git', 'rev-parse', 'HEAD'], + fallback: 'n/a' + ) + + version_tag = vcs_tag( + input: 'config/version.in', + output: 'version', + command: ['git', 'describe', '--abbrev=0', '--tags'], + fallback: 'n/a' + ) +endif + +inc_dir = include_directories('include', 'config', 'external') + +if not meson.is_subproject() + install_subdir('include/flatcc', install_dir: 'include') +endif + +flatccrt_src = [ + 'src/runtime/builder.c', + 'src/runtime/emitter.c', + 'src/runtime/refmap.c', + 'src/runtime/json_parser.c', + 'src/runtime/json_printer.c', + 'src/runtime/verifier.c' +] + +flatcc_src = [ + 'src/compiler/codegen_c.c', + 'src/compiler/codegen_c_builder.c', + 'src/compiler/codegen_c_json_parser.c', + 'src/compiler/codegen_c_json_printer.c', + 'src/compiler/codegen_c_reader.c', + 'src/compiler/codegen_c_sort.c', + 'src/compiler/codegen_c_sorter.c', + 'src/compiler/codegen_c_verifier.c', + 'src/compiler/codegen_schema.c', + 'src/compiler/coerce.c', + 'src/compiler/fileio.c', + 'src/compiler/flatcc.c', + 'src/compiler/parser.c', + 'src/compiler/semantics.c', + 'src/compiler/hash_tables/name_table.c', + 'src/compiler/hash_tables/schema_table.c', + 'src/compiler/hash_tables/scope_table.c', + 'src/compiler/hash_tables/symbol_table.c', + 'src/compiler/hash_tables/value_set.c', + 'external/hash/cmetrohash64.c', + 'external/hash/ptr_set.c', + 'external/hash/str_set.c', + flatccrt_src +] + +flatccrt_name = 'flatccrt' +flatcc_name = 'flatcc' + +if buildtype == 'debug' + flatccrt_name = 'flatccrt_d' + flatcc_name = 'flatcc_d' +endif + + +libflatccrt = library(flatccrt_name, + sources: flatccrt_src, + include_directories: inc_dir, + install: not meson.is_subproject() +) + +libflatcc = library(flatcc_name, + sources: flatcc_src, + include_directories: inc_dir, + install: not meson.is_subproject() +) + +flatcc = executable(flatcc_name, + sources: ['src/cli/flatcc_cli.c'], + link_with: libflatcc, + include_directories: inc_dir, + install: not meson.is_subproject() +) + +if not meson.is_subproject() + + mkdir_command = find_program('mkdir') + cp_command = find_program('cp') + + copy_targets = { + 'flatcc-copy' : [flatcc, meson.project_source_root() / 'bin'], + 'libflatccrt-copy' : [libflatccrt, meson.project_source_root() / 'lib'], + 'libflatcc-copy' : [libflatcc, meson.project_source_root() / 'lib'] + } + + foreach target_name, target_details : copy_targets + target = target_details[0] + destination = target_details[1] + custom_target(target_name, + command: [ mkdir_command, '-p', destination, '&&', cp_command, target, destination ], + output: 'fake-@0@'.format(target_name), + build_by_default: true, + build_always_stale: false + ) + endforeach +endif + +meson.override_find_program('flatcc', flatcc) + +subdir('rules') + +if not get_option('flatcc_disable_tests') and not meson.is_subproject() + # For end user programs, samples, and test. + subdir('samples') + subdir('test') +endif + +flatcc_dep = declare_dependency( + link_with: libflatcc, + include_directories: inc_dir +) + diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 000000000..a87d4277b --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,78 @@ +# Use this for some compilers that doesn't C11 standard. +# It is not needed for some non-compliant compilers such as +# recent gcc and clang. + +option('flatcc_portable', type : 'boolean', value : false) + +# Use this option to trigger assertions on flatcc errors. Useful to +# learn more about why api is used incorrectly or where a binary +# flatbuffer fails a verify test. + +option('flatcc_debug_verify', type : 'boolean', value : false) + +# Controls the flatcc compilers ability to handle binary schema (bfbs). +# Can be used to trim down flatcc and libflatcc size, but is primarily +# for internal development because flatcc won't otherwise compile while +# there are breaking changes in generated code. + +option('flatcc_reflection', type : 'boolean', value : true) + +# This option controls a special case in grisu3 but does not enable or +# disable grisu3 floating point parsing, which is enabled without +# special configuration elsewhere: +# +# Fast grisu3 string/floating point conversion still depends on strtod +# for about 1-2% of the conversions in order to produce an exact result. +# By allowing a minor difference in the least significant bits, this +# dependeny can be avoided, and speed improved. Some strtod +# implementations call strlen which is really slow on large JSON +# buffers, and catastrophic on buffers that are not zero-terminated - +# regardless of size. Most platforms have a decent strtod these days. + +option('flatcc_fast_double', type : 'boolean', value : false) + +# Only build libraries, not samples, tests, or benchmarks. +# This option is implied true when building as a subproject +# regardless of this setting. + +option('flatcc_disable_tests', type : 'boolean', value : false) + +option('ignore_const_cond', type: 'boolean', value: false) +option('allow_werror', type: 'boolean', value: true) +option('gnu_posix_memalign', type: 'boolean', value: true) + +# -- +# -- For more detailed control, see also config/config.h compiler flags. +# -- + + +##################################################################### +# +# EXPERIMENTAL SETTINGS +# +# Subject to change without notice. +# +##################################################################### + + +# dealing with missing support for proper multi output dependencies in +# both ninja build and in flatcc. For now the myschema_reader.h is used +# to drive the depencies. + +option('xflatcc_multi_dep_targets', type : 'boolean', value : false) + +# Removes all tests, except the important `monster_test`. +# Useful for smaller test suite on new build targets +# and for testing dependency rules without noise. + +option('xflatcc_monster_test_only', type : 'boolean', value : false) + +# Currently (meson 0.34) it is not possible to generate .bfbs. files +# because there must be a registered compiler that handles .bfbs +# extension, but it is possible to use a custom target that does. + +option('xflatcc_reflection_test_custom', type : 'boolean', value : true) + +# Experimental support for automatically generating latest tag +# and revision from source control. +option('xflatcc_gen_version', type : 'boolean', value : false) diff --git a/rules/meson.build b/rules/meson.build new file mode 100644 index 000000000..141d31a20 --- /dev/null +++ b/rules/meson.build @@ -0,0 +1,105 @@ +# Must be a relative path for parent projects to work +flatcc_include = include_directories('../include') + +# The flatcc compiler can generate common header files and +# schema specific files in one operation, but meson isn't +# allowing us to list them because @BASENAME@ must be in the path. +# It could still work though, but messy. It is better to generate +# the files once. Unforunately we must explicitly add these +# as a dependency to very executable becuase the schema specific +# generator (in meson 0.34) doesn't have a depends: argument. +# +# -c generates header and -w generates builder since we +# don't supply any input .fbs argument -w here means build +# flatbuffers_common_builder.h otherwise we only get the +# common reader. +# +# Common files are generated because it allows for future +# variations in the namespaces and file format, such as +# large offset buffers. +# +flatcc_common = custom_target('flatbuffer_common', + output : [ + 'flatbuffers_common_reader.h', + 'flatbuffers_common_builder.h'], + command : [ flatcc, '-cw', '-o', meson.current_build_dir()]) + +# flatcc -r generates included schema recursively, and -d lists included +# schema files in a dependency file. Ninja 1.7.1 (via meson 0.34) +# currently has a bug so either multiple outputs or deps file can be +# chosen, but not both. The best option is to use single output because +# even if the file is not used, the other outputs will be in sync. +# Alternatively the inlcuded files can be listed as inputs explicitly, but +# this is error prone. Regardless, recursive output files cannot be listed +# because Ninja cannot deal with them - this is only important for clean, +# meaning the build dir mus be removed manually or via a helper script. +# +# https://groups.google.com/forum/#!searchin/ninja-build/depslog%7Csort:relevance/ninja-build/4RK3vACeHG0/T3iEPSoLEAAJ +# https://github.com/ninja-build/ninja/issues/1184 +# +# However, with single output, single deps file, the build fails this +# step with no detailed explanation (meson 0.34), so we drop the depfile +# for now. This means dependencies must be added manually which we can't +# do in a generator. For our test purposes this is ok, but as an example +# for other users with active schema development, it is not ok. +# +# NOTE: make sure to add flatcc_common as input to C executables as a +# dependency when using the flatcc_gen generator. This is needed because +# meson does not allow the generator to depend on a custom target as is. +# (We could also just generate the custom headers here with flatcc -c +# option, but they are shared across schema and it is messy to +# update same file repeatedly). + +if get_option('xflatcc_multi_dep_targets') + flatcc_gen_output = [ + '@BASENAME@_reader.h', + '@BASENAME@_builder.h', + '@BASENAME@_verifier.h'] + + flatcc_json_gen_output = flatcc_gen_output + [ + '@BASENAME@_json_parser.h', + '@BASENAME@_json_printer.h'] +else + flatcc_gen_output = [ '@BASENAME@_reader.h' ] + flatcc_json_gen_output = [ '@BASENAME@_reader.h' ] +endif + +# Debugging depfile rules: +# +# Ninja immediately consumes (reads and deletes) depfiles. +# For debugging, rename the file so it does not match, e.g: +# '--depfile=@DEPFILE@,x' +# then `ag -g ,x` in the build dir to find generated depfiles, +# or `find . -type f -name '*,x'` if find is preferable. +# +# With the normal build rules (no rename hack), enable only +# monster_test, the build, then cd build +# ninja +# ninja +# Second time, nothing to build. +# touch ../test/monster_test/include_test2.fbs +# ninja +# should rebuild, next time it shouldn't, try also with touch .../monster.fbs + +flatcc_gen = generator(flatcc, + output : flatcc_gen_output, + depfile: '@BASENAME@' + '.fbs.d', + # with explicit --depfile relative to cwd, i.e. build root, + # depfile: name can be chosen relatively freely. + arguments : [ '-vwr', '-o', '@BUILD_DIR@', '--depfile=@DEPFILE@', '@INPUT@' ]) + # With flatcc -d option, depfile: must be exactly as listed + #arguments : ['-vwrd', '-o', '@BUILD_DIR@', '@INPUT@']) + +flatcc_json_gen = generator(flatcc, + output : flatcc_json_gen_output, + depfile: '@BASENAME@' + '.fbs.d', + arguments : [ '-vwrd', '--json','-o', '@BUILD_DIR@', '@INPUT@' ]) + +# Note: we cannot currently (mesono 0.34) define a genrator the produces +# and output file with a .bfbs extension. Only things like .c, .h, .cpp +# files can be generated. We leave the rule for future reference. +flatcc_bfbs_gen = generator(flatcc, + output : [ '@BASENAME@' + '.bfbs' ], + depfile: '@BASENAME@' + '.fbs.d', + arguments : [ '-rd', '--schema', '-o', '@BUILD_DIR@', '@INPUT@' ]) + diff --git a/samples/meson.build b/samples/meson.build new file mode 100644 index 000000000..6d98492a5 --- /dev/null +++ b/samples/meson.build @@ -0,0 +1,11 @@ + + +monster_dir = join_paths(meson.current_source_dir(), 'monster') +monster_fbs = join_paths(monster_dir, 'monster.fbs') +monster_src = join_paths(monster_dir, 'monster.c') + +subdir('monster') + +if get_option('flatcc_reflection') + subdir('reflection') +endif diff --git a/samples/monster/meson.build b/samples/monster/meson.build new file mode 100644 index 000000000..68c9a6077 --- /dev/null +++ b/samples/monster/meson.build @@ -0,0 +1,39 @@ +# Here we build everything manually. +# Because the schema does not include other +# schema we do not have to deal with additiaonl +# dependencies here. +# +# See also `monster_build_rules` where predefined +# build rules are being used. + +if has_c99_var_decl + + my_schema_dir = meson.current_source_dir() + my_gen_dir = meson.current_build_dir() + + monster_builder_outfiles = [ + 'monster_builder.h', + 'monster_reader.h', + 'flatbuffers_common_reader.h', + 'flatbuffers_common_builder.h' + ] + + my_monster_gen = custom_target('my_monster_builder', + output: monster_builder_outfiles, + input: my_schema_dir + '/monster.fbs', + command: [ + flatcc, '-cw', '-o', my_gen_dir, '@INPUT@' + ] + ) + + monster_sample = executable('monster', + sources: ['monster.c', my_monster_gen ], + link_with: libflatccrt, + include_directories: flatcc_include + ) + + test('monster_sample', monster_sample) + +else + message('Skipping monster sample because C compiler does not support late variable declarations') +endif diff --git a/samples/reflection/meson.build b/samples/reflection/meson.build new file mode 100644 index 000000000..b33ca1681 --- /dev/null +++ b/samples/reflection/meson.build @@ -0,0 +1,19 @@ +name = 'bfbs2json' + +out_dir = meson.current_build_dir() + +# Generate binary schema +bfbs_monster = custom_target('monster.bfbs', + output: 'monster.bfbs', + input: monster_fbs, + command: [flatcc, '--schema', '-o', out_dir, '@INPUT@'] +) + +test(name, + executable(name, + name + '.c', bfbs_monster, + link_with: libflatcc, + include_directories: flatcc_include + ), + args: bfbs_monster.full_path() +) diff --git a/scripts/build.cfg.meson b/scripts/build.cfg.meson new file mode 100644 index 000000000..83ce379f4 --- /dev/null +++ b/scripts/build.cfg.meson @@ -0,0 +1,2 @@ +FLATCC_BUILD_CMD=ninja + diff --git a/test/benchmark/benchflatc/benchflatc.cpp b/test/benchmark/benchflatc/benchflatc.cpp index ae24abdb2..d5d329606 100644 --- a/test/benchmark/benchflatc/benchflatc.cpp +++ b/test/benchmark/benchflatc/benchflatc.cpp @@ -46,6 +46,8 @@ int64_t decode(void *bench, void *buffer, size_t size, int64_t sum) auto foobarcontainer = GetFooBarContainer(buffer); (void)bench; + (void)size; + sum += foobarcontainer->initialized(); sum += foobarcontainer->location()->Length(); sum += foobarcontainer->fruit(); diff --git a/test/benchmark/benchflatc/meson.build b/test/benchmark/benchflatc/meson.build new file mode 100644 index 000000000..2157ce493 --- /dev/null +++ b/test/benchmark/benchflatc/meson.build @@ -0,0 +1,11 @@ +name = 'benchflatc' + +# Testing Googles flatc implementation +benchflatc = executable(name, name + '.cpp', + # Sort of like default_options: ['cpp_std=c++11'] in main + # project def, but we don't want the main project to be + # to enable cpp just for this one test. + cpp_args: ['-std=c++11'], # get NDEBUG flag + include_directories : testinc_dir) + +benchmark(name, benchflatc) diff --git a/test/benchmark/benchflatcc/benchflatcc.c b/test/benchmark/benchflatcc/benchflatcc.c index 682418a98..1d7208389 100644 --- a/test/benchmark/benchflatcc/benchflatcc.c +++ b/test/benchmark/benchflatcc/benchflatcc.c @@ -70,6 +70,7 @@ int64_t decode(flatcc_builder_t *B, void *buffer, size_t size, int64_t sum) Foo(struct_t) foo; (void)B; + (void)size; foobarcontainer = C(as_root(buffer)); sum += C(initialized(foobarcontainer)); diff --git a/test/benchmark/benchflatcc/meson.build b/test/benchmark/benchflatcc/meson.build new file mode 100644 index 000000000..b4d32205b --- /dev/null +++ b/test/benchmark/benchflatcc/meson.build @@ -0,0 +1,9 @@ +name = 'benchflatcc' + +fb_flatbench = flatcc_json_gen.process(flatbench_fbs) + +benchflatcc = executable(name, name + '.c', + fb_flatbench, flatcc_common, link_with : libflatccrt, + include_directories : testinc_dir) + +benchmark(name, benchflatcc) diff --git a/test/benchmark/benchflatccjson/meson.build b/test/benchmark/benchflatccjson/meson.build new file mode 100644 index 000000000..88727c0e2 --- /dev/null +++ b/test/benchmark/benchflatccjson/meson.build @@ -0,0 +1,9 @@ +name = 'benchflatccjson' + +fb_flatbench = flatcc_json_gen.process(flatbench_fbs) + +benchflatccjson = executable(name, name + '.c', + fb_flatbench, flatcc_common, link_with : libflatccrt, + include_directories : testinc_dir) + +benchmark(name, benchflatccjson) diff --git a/test/benchmark/benchmain/benchmain.h b/test/benchmark/benchmain/benchmain.h index f29c54824..8241ca483 100644 --- a/test/benchmark/benchmain/benchmain.h +++ b/test/benchmark/benchmain/benchmain.h @@ -23,6 +23,10 @@ int main(int argc, char *argv[]) /* Use volatie to prevent over optimization. */ volatile int64_t total = 0; int i, ret = 0; + + (void)(argc); + (void)(argv); + DECLARE_BENCHMARK(BM); buf = malloc(bufsize); diff --git a/test/benchmark/benchraw/benchraw.c b/test/benchmark/benchraw/benchraw.c index fd6a9ea4e..7a50c9719 100644 --- a/test/benchmark/benchraw/benchraw.c +++ b/test/benchmark/benchraw/benchraw.c @@ -91,6 +91,7 @@ int64_t decode(void *bench, void *buffer, size_t size, int64_t sum) struct Bar *bar; (void)bench; + (void)size; foobarcontainer = buffer; sum += foobarcontainer->initialized; diff --git a/test/benchmark/benchraw/meson.build b/test/benchmark/benchraw/meson.build new file mode 100644 index 000000000..7658dcae8 --- /dev/null +++ b/test/benchmark/benchraw/meson.build @@ -0,0 +1,6 @@ +name = 'benchraw' + +benchraw = executable(name, name + '.c', + include_directories : testinc_dir) + +benchmark(name, benchraw) diff --git a/test/cgen_test/meson.build b/test/cgen_test/meson.build new file mode 100644 index 000000000..c3ca1901c --- /dev/null +++ b/test/cgen_test/meson.build @@ -0,0 +1,8 @@ +name = 'cgen_test' + +test(name, + executable(name, name + '.c', + link_with: libflatcc, + include_directories: testinc_dir + ) +) diff --git a/test/emit_test/meson.build b/test/emit_test/meson.build new file mode 100644 index 000000000..ace0d5ee1 --- /dev/null +++ b/test/emit_test/meson.build @@ -0,0 +1,7 @@ +name = 'emit_test' + +test(name, + executable(name, name + '.c', + flatcc_gen.process(name + '.fbs'), flatcc_common, + link_with : libflatccrt, + include_directories : testinc_dir)) diff --git a/test/flatc_compat/meson.build b/test/flatc_compat/meson.build new file mode 100644 index 000000000..3120e7029 --- /dev/null +++ b/test/flatc_compat/meson.build @@ -0,0 +1,8 @@ +name = 'flatc_compat' + +test(name, + executable(name, name + '.c', + flatcc_gen.process(monster_test_fbs), + flatcc_common, link_with : libflatccrt, + include_directories : testinc_dir), + args: [monster_data_test_bin_src]) diff --git a/test/json_test/meson.build b/test/json_test/meson.build new file mode 100644 index 000000000..c779df315 --- /dev/null +++ b/test/json_test/meson.build @@ -0,0 +1,32 @@ +out_dir = meson.current_build_dir() + +fb_monster_json = flatcc_json_gen.process(monster_test_fbs) + +test('test_basic_parse', + executable('test_basic_parse', 'test_basic_parse.c', + fb_monster_json, flatcc_common, link_with : libflatccrt, + include_directories : testinc_dir)) + +# Parse a Google flatc printed json file. +test('test_json_parser', + executable('test_json_parser', 'test_json_parser.c', + fb_monster_json, flatcc_common, link_with : libflatccrt, + include_directories : testinc_dir), + args: [ monster_data_test_json_ref ]) + +# Print a json file from a Google flatc generated buffer +# and compare the output to a Google flatc printed json file. +test('test_json_printer', + executable('test_json_printer', 'test_json_printer.c', + fb_monster_json, flatcc_common, link_with : libflatccrt, + include_directories : testinc_dir), + args: [ + monster_data_test_bin_src, + monster_data_test_json_ref, + join_paths(out_dir, 'monsterdata_test.json.txt')]) + +test('test_json', + executable('test_json', 'test_json.c', + fb_monster_json, flatcc_common, link_with : libflatccrt, + include_directories : testinc_dir)) + diff --git a/test/load_test/meson.build b/test/load_test/meson.build new file mode 100644 index 000000000..a32ad9486 --- /dev/null +++ b/test/load_test/meson.build @@ -0,0 +1,8 @@ +name = 'load_test' + +test(name, + executable(name, name + '.c', + flatcc_common, + flatcc_gen.process(monster_test_fbs), + link_with : libflatccrt, + include_directories : testinc_dir)) diff --git a/test/meson.build b/test/meson.build new file mode 100644 index 000000000..e5ca4dde7 --- /dev/null +++ b/test/meson.build @@ -0,0 +1,72 @@ +test_dir = meson.current_source_dir() +bench_dir = join_paths(test_dir, 'benchmark') + +testinc_dir = [ inc_dir, include_directories('benchmark/benchmain')] + +monster_test_dir = join_paths(test_dir, 'monster_test') + +# This schema is widely reused in various tests and has +# include statements unlike the samples/monster/monster.fbs schema. +monster_test_fbs = join_paths(monster_test_dir, 'monster_test.fbs') + +# For compatibility tests: +# Google flatc generated binary FlatBuffer from C++ code generator. +monster_data_test_bin_src = join_paths(test_dir, 'flatc_compat/monsterdata_test.mon') + +# Google flatc printed json from the binary FlatBuffer. +monster_data_test_json_ref = join_paths(test_dir, 'flatc_compat/monsterdata_test.golden') + +flatbench_fbs = join_paths(bench_dir, 'schema/flatbench.fbs') + +subdir('monster_test') + +# Simply testing for debugging build rules and for smoke testing new platforms. +if get_option('xflatcc_monster_test_only') + subdir_done() +endif + +testdirs = [ + 'cgen_test', + 'monster_test_cpp', + 'monster_test_solo', + 'monster_test_prefix', + 'monster_test_concat', + 'emit_test', + 'load_test', + 'json_test', + 'flatc_compat' +] + +if get_option('flatcc_reflection') + testdirs += 'reflection_test' +else + warning('reflection disabled') +endif + +testdirs += [ + 'benchmark/benchflatcc', + 'benchmark/benchflatc', + 'benchmark/benchraw', + 'benchmark/benchflatccjson' +] + +foreach testdir : testdirs + subdir(testdir) +endforeach + +# As of meson 0.34 the benchmark loops over the test program incl. warmup +# and dumps output in a condensed json file - so we add a run_target to +# drive the test instead. +if meson.backend() == 'ninja' + message('Note: run benchmark with `ninja flatbench`, not `ninja benchmark`') +endif + +run_target('flatbench', + depends: [benchflatcc, benchflatc, benchraw, benchflatccjson], + command: [ + benchflatcc, '&&', + benchflatc, '&&', + benchraw, '&&', + benchflatccjson + ] +) diff --git a/test/monster_test/meson.build b/test/monster_test/meson.build new file mode 100644 index 000000000..8a4d6ddb7 --- /dev/null +++ b/test/monster_test/meson.build @@ -0,0 +1,10 @@ +name = 'monster_test' + +test(name, + executable(name, name + '.c', + flatcc_common, + flatcc_gen.process(monster_test_fbs), + link_with: libflatccrt, + include_directories: testinc_dir + ) +) diff --git a/test/monster_test_concat/meson.build b/test/monster_test_concat/meson.build new file mode 100644 index 000000000..c34ebfb78 --- /dev/null +++ b/test/monster_test_concat/meson.build @@ -0,0 +1,52 @@ +name = 'monster_test_concat' + +build_root = meson.project_build_root() + +# merges all output to stdout and into a capture file +# test that files are produced as given on the command line. +# Note that -cwv does not recurse the monster_test so dependencies are managed +# manually, unlike -cwvr aka -a on just the main monster_test file +# that latter is tested in the monster_test_prefix test. + +# Here we avoid capture by directing the concatenated output +# to a known file and use it as a dependency target +# without automatic dependency file generation. +# +# NOTE: the build sysem cannot (by design) handle generated output +# files, which cause clean to mess up, but when we send the output to a +# single file, we avoid this problem. The entire set of test cases still +# doesn't clean properly because we need to test various scenarios. +concat_gen = custom_target(name, + output : 'monster_test.h', + input : [ monster_test_dir + '/monster_test.fbs' ], + depfile: '@BASENAME@.depends-custom-extension', + # we don't actually need -o with --outfile. + command : [flatcc, '-cwvr', '-o', build_root, + '--depfile', '@DEPFILE@', + '--outfile', '@OUTPUT@', '@INPUT@']) + +test(name, + executable(name, name + '.c', + concat_gen, + link_with : libflatccrt, + include_directories : testinc_dir)) + +# Test manual build of dependent files without recursion. +name2 = name + '_explicit' + +concat_gen_explicit = custom_target(name + '_explicit', + output : 'monster_test_explicit.h', + input : [ + monster_test_dir + '/attributes.fbs', + monster_test_dir + '/include_test2.fbs', + monster_test_dir + '/include_test1.fbs', + monster_test_dir + '/monster_test.fbs', + ], + command : [ flatcc, '-cwv', '@INPUT@', '--outfile', '@OUTPUT@' ]) + + +test(name2, + executable(name2, name2 + '.c', + concat_gen_explicit, + link_with : libflatccrt, + include_directories : testinc_dir)) diff --git a/test/monster_test_concat/monster_test_concat_explicit.c b/test/monster_test_concat/monster_test_concat_explicit.c new file mode 100644 index 000000000..ff389e8d3 --- /dev/null +++ b/test/monster_test_concat/monster_test_concat_explicit.c @@ -0,0 +1,24 @@ +/* Minimal test with all headers generated into a single file. */ +#include "monster_test_explicit.h" + +int main(int argc, char *argv[]) +{ + int ret; + void *buf; + size_t size; + flatcc_builder_t builder, *B; + + (void)argc; + (void)argv; + + B = &builder; + flatcc_builder_init(B); + + MyGame_Example_Monster_start_as_root(B); + MyGame_Example_Monster_name_create_str(B, "MyMonster"); + MyGame_Example_Monster_end_as_root(B); + buf = flatcc_builder_get_direct_buffer(B, &size); + ret = MyGame_Example_Monster_verify_as_root(buf, size); + flatcc_builder_clear(B); + return ret; +} diff --git a/test/monster_test_cpp/meson.build b/test/monster_test_cpp/meson.build new file mode 100644 index 000000000..0db31da3a --- /dev/null +++ b/test/monster_test_cpp/meson.build @@ -0,0 +1,10 @@ +name = 'monster_test_cpp' + +test(name, + executable(name, 'monster_test.cpp', + flatcc_common, + flatcc_gen.process(monster_fbs), + link_with: libflatccrt, + include_directories: testinc_dir + ) +) diff --git a/test/monster_test_prefix/meson.build b/test/monster_test_prefix/meson.build new file mode 100644 index 000000000..f32115eb3 --- /dev/null +++ b/test/monster_test_prefix/meson.build @@ -0,0 +1,18 @@ +name = 'monster_test_prefix' + +prefix_name = 'zzz_monster_test' + +# merges all output to stdout with a custom namespace prefix, +# meson captures this in the output file (meson 0.34+). + +prefix_gen = custom_target(prefix_name, + output : prefix_name + '.h', + input : monster_test_fbs, + capture : true, + command : [flatcc, '-a', '--prefix=zzz_', '--stdout', '@INPUT@']) + +test(name, + executable(name, name + '.c', + prefix_gen, + link_with : libflatccrt, + include_directories : testinc_dir)) diff --git a/test/monster_test_solo/meson.build b/test/monster_test_solo/meson.build new file mode 100644 index 000000000..09130495d --- /dev/null +++ b/test/monster_test_solo/meson.build @@ -0,0 +1,26 @@ +name = 'monster_test_solo' + +# merges all output to stdout and into a capture file +# test that files are produced as given on the command line. +# Note that -cwv does not recurse the monster_test so dependencies are managed +# manually, unlike -cwvr aka -a on just the main monster_test file +# that latter is tested in the monster_test_prefix test. +prefix_gen = custom_target(name, + output : 'monster_test.h', + input : [ + join_paths(monster_test_dir, 'attributes.fbs'), + join_paths(monster_test_dir, 'include_test2.fbs'), + join_paths(monster_test_dir, 'include_test1.fbs'), + join_paths(monster_test_dir, 'monster_test.fbs'), + ], + capture : true, + command : [flatcc, '-cwv', '--stdout', '@INPUT@'] +) + +test(name, + executable(name, name + '.c', + prefix_gen, + link_with: libflatccrt, + include_directories: testinc_dir + ) +) diff --git a/test/reflection_test/meson.build b/test/reflection_test/meson.build new file mode 100644 index 000000000..a71024b34 --- /dev/null +++ b/test/reflection_test/meson.build @@ -0,0 +1,28 @@ +name = 'reflection_test' + +out_dir = meson.current_build_dir() + +if get_option('xflatcc_reflection_test_custom') + +bfbs_monster_test = custom_target('monster_test.bfbs', + output : 'monster_test.bfbs', + input : monster_test_fbs, + depfile : 'monster_test.fbs.d', + command : [ flatcc, '--schema', '-d', '-o', out_dir, '--depfile', '@DEPFILE@', '@INPUT@' ]) + +else + +# Currently (meson 0.34) it is not possible to generate .bfbs. files +# because there must be a registered compiler that handles .bfbs +# extension. +bfbs_monster_test = flatcc_bfbs_gen.process(monster_test_fbs) + +endif + +test(name, + executable(name, name + '.c', + bfbs_monster_test, + link_with : libflatcc, + include_directories : testinc_dir), + args: out_dir + '/monster_test.bfbs') + From bcc1c3eb41cd1b91c47c1b974a65ecfbe69ef904 Mon Sep 17 00:00:00 2001 From: Andrew McNulty Date: Mon, 17 Apr 2023 16:32:43 +0200 Subject: [PATCH 2/5] Passing NULL to memcpy is UB. UBSan warns when passing a NULL as the src argument to memcpy. Avoid doing that. --- src/compiler/codegen_c.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/compiler/codegen_c.c b/src/compiler/codegen_c.c index 5e5fe0e6b..f9d5bc89a 100644 --- a/src/compiler/codegen_c.c +++ b/src/compiler/codegen_c.c @@ -164,8 +164,13 @@ int fb_copy_scope(fb_scope_t *scope, char *buf) buf[0] = '\0'; return -1; } + len = (size_t)scope->prefix.len; - memcpy(buf, scope->prefix.s, len); + if (scope->prefix.s != NULL) { + /* Passing NULL as the 2nd argument to memcpy yields undefined behaviour. */ + memcpy(buf, scope->prefix.s, len); + } + for (name = scope->name; name; name = name->link) { n = (size_t)name->ident->len; memcpy(buf + len, name->ident->text, n); From fd691533a03e50a27fbcb6c674138a2923f6f2d8 Mon Sep 17 00:00:00 2001 From: Andrew McNulty Date: Mon, 17 Apr 2023 17:19:18 +0200 Subject: [PATCH 3/5] Rework build scripts to integrate Meson This commit reorganizes the build scripts while also integrating Meson into the system. --- README.md | 17 +++++++++-------- scripts/build.cfg.cmake | 11 +++++++++++ scripts/build.cfg.make | 9 ++++++++- scripts/build.cfg.make-32bit | 9 ++++++++- scripts/build.cfg.make-concurrent | 9 ++++++++- scripts/build.cfg.meson | 11 ++++++++++- scripts/build.cfg.ninja | 3 --- scripts/build.sh | 10 ++++++---- scripts/initbuild.sh | 14 +++++++------- scripts/test.sh | 19 +++++++++++++++---- 10 files changed, 82 insertions(+), 30 deletions(-) create mode 100644 scripts/build.cfg.cmake delete mode 100644 scripts/build.cfg.ninja diff --git a/README.md b/README.md index 95fe80866..1cc8048a7 100644 --- a/README.md +++ b/README.md @@ -101,8 +101,8 @@ C given a FlatBuffer schema file. This introduction also creates a separate test project with the traditional monster example, here in a C version. For now assume a Unix like system although that is not a general requirement - -see also [Building](#building). You will need git, cmake, bash, a C compiler, -and either the ninja build system, or make. +see also [Building](#building). You will need git, either cmake or meson, bash, +a C compiler, and either the ninja build system, or make. git clone https://github.com/dvidelabs/flatcc.git cd flatcc @@ -117,7 +117,7 @@ and either the ninja build system, or make. ls generated `scripts/initbuild.sh` is optional and chooses the build backend, which defaults -to ninja. +to ninja via CMake. The setup script builds flatcc using CMake, then creates a test project directory with the monster example, and a build script which is just a small @@ -2218,16 +2218,17 @@ To initialize and run the build (see required build tools below): The `bin` and `lib` folders will be created with debug and release build products. -The build depends on `CMake`. By default the `Ninja` build tool is also required, -but alternatively `make` can be used. +The build depends on either `CMake` or `Meson`. By default the `Ninja` build tool +is also required, but alternatively `make` can be used. Optionally switch to a different build tool by choosing one of: + scripts/initbuild.sh cmake + scripts/initbuild.sh meson scripts/initbuild.sh make scripts/initbuild.sh make-concurrent - scripts/initbuild.sh ninja -where `ninja` is the default and `make-concurrent` is `make` with the `-j` flag. +where `cmake` is the default and `make-concurrent` is `make` with the `-j` flag. To enforce a 32-bit build on a 64-bit machine the following configuration can be used: @@ -2367,7 +2368,7 @@ a different assert behaviour is desirable, it is possible to override the default behaviour in runtime part of flatcc library via logic defined in [flatcc_assert.h](include/flatcc/flatcc_assert.h). -By default Posix `assert` is beeing used. It can be changed by preprocessor definition: +By default Posix `assert` is being used. It can be changed by preprocessor definition: -DFLATCC_ASSERT=own_assert diff --git a/scripts/build.cfg.cmake b/scripts/build.cfg.cmake new file mode 100644 index 000000000..3a337ddb4 --- /dev/null +++ b/scripts/build.cfg.cmake @@ -0,0 +1,11 @@ +FLATCC_BUILD_CONFIG=cmake + +FLATCC_BUILD_SYSTEM=cmake +FLATCC_BUILD_GEN="-G Ninja" +FLATCC_BUILD_CMD=ninja + +FLATCC_TARGET_RELEASE="-DCMAKE_BUILD_TYPE=Release" +FLATCC_TARGET_DEBUG="-DCMAKE_BUILD_TYPE=Debug" +FLATCC_BUILD_FLAGS="" + +FLATCC_TEST_CMD=ctest diff --git a/scripts/build.cfg.make b/scripts/build.cfg.make index ae9c33258..2becfffc3 100644 --- a/scripts/build.cfg.make +++ b/scripts/build.cfg.make @@ -1,3 +1,10 @@ -FLATCC_BUILD_GEN="Unix Makefiles" +FLATCC_BUILD_CONFIG=make +FLATCC_BUILD_GEN="-G Unix Makefiles" + +FLATCC_BUILD_SYSTEM=cmake FLATCC_BUILD_CMD=make +FLATCC_TEST_CMD=ctest + FLATCC_BUILD_FLAGS="" +FLATCC_TARGET_RELEASE="-DCMAKE_BUILD_TYPE=Release" +FLATCC_TARGET_DEBUG="-DCMAKE_BUILD_TYPE=Debug" diff --git a/scripts/build.cfg.make-32bit b/scripts/build.cfg.make-32bit index 2299d679e..3b76db3ef 100644 --- a/scripts/build.cfg.make-32bit +++ b/scripts/build.cfg.make-32bit @@ -1,3 +1,10 @@ -FLATCC_BUILD_GEN="Unix Makefiles" +FLATCC_BUILD_CONFIG=make-32bit +FLATCC_BUILD_GEN="-G Unix Makefiles" + +FLATCC_BUILD_SYSTEM=cmake FLATCC_BUILD_CMD=make +FLATCC_TEST_CMD=ctest + FLATCC_BUILD_FLAGS="-DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32" +FLATCC_TARGET_RELEASE="-DCMAKE_BUILD_TYPE=Release" +FLATCC_TARGET_DEBUG="-DCMAKE_BUILD_TYPE=Debug" diff --git a/scripts/build.cfg.make-concurrent b/scripts/build.cfg.make-concurrent index 76846426b..c15229fea 100644 --- a/scripts/build.cfg.make-concurrent +++ b/scripts/build.cfg.make-concurrent @@ -1,3 +1,10 @@ -FLATCC_BUILD_GEN="Unix Makefiles" +FLATCC_BUILD_CONFIG=make-concurrent +FLATCC_BUILD_GEN="-G Unix Makefiles" + +FLATCC_BUILD_SYSTEM=cmake FLATCC_BUILD_CMD="make -j" +FLATCC_TEST_CMD=ctest + FLATCC_BUILD_FLAGS="" +FLATCC_TARGET_RELEASE="-DCMAKE_BUILD_TYPE=Release" +FLATCC_TARGET_RELEASE="-DCMAKE_BUILD_TYPE=Debug" diff --git a/scripts/build.cfg.meson b/scripts/build.cfg.meson index 83ce379f4..abbd47ccd 100644 --- a/scripts/build.cfg.meson +++ b/scripts/build.cfg.meson @@ -1,2 +1,11 @@ -FLATCC_BUILD_CMD=ninja +FLATCC_BUILD_CONFIG=meson +FLATCC_BUILD_GEN= + +FLATCC_BUILD_SYSTEM=meson +FLATCC_BUILD_CMD=ninja +FLATCC_TEST_CMD="meson test" + +FLATCC_BUILD_FLAGS= +FLATCC_TARGET_RELEASE="--buildtype release" +FLATCC_TARGET_DEBUG="--buildtype debug" diff --git a/scripts/build.cfg.ninja b/scripts/build.cfg.ninja deleted file mode 100644 index 07ead7000..000000000 --- a/scripts/build.cfg.ninja +++ /dev/null @@ -1,3 +0,0 @@ -FLATCC_BUILD_GEN=Ninja -FLATCC_BUILD_CMD=ninja -FLATCC_BUILD_FLAGS="" diff --git a/scripts/build.sh b/scripts/build.sh index 98cd41cc3..3667f8e9f 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -10,10 +10,12 @@ CFGFILE=${ROOT}/scripts/build.cfg if [ -e $CFGFILE ]; then . $CFGFILE +else + # Default build system is cmake/ninja + ${ROOT}/scripts/initbuild.sh cmake + . $CFGFILE fi -FLATCC_BUILD_CMD=${FLATCC_BUILD_CMD:-ninja} - mkdir -p ${ROOT}/bin mkdir -p ${ROOT}/lib @@ -24,8 +26,8 @@ rm -f ${ROOT}/libflatcc_d.a rm -f ${ROOT}/libflatccrt.a rm -f ${ROOT}/libflatccrt_d.a -if [ ! -d ${ROOT}/build/Debug ] || [ ! -d ${ROOT}/build/Release ]; then - ${ROOT}/scripts/initbuild.sh +if [ ! -d ${ROOT}/build/Debug ] || [ ! -d ${ROOT}/build/Release ]; then + ${ROOT}/scripts/initbuild.sh $FLATCC_BUILD_CONFIG fi echo "building Debug" 1>&2 diff --git a/scripts/initbuild.sh b/scripts/initbuild.sh index 2b18cd257..770e92231 100755 --- a/scripts/initbuild.sh +++ b/scripts/initbuild.sh @@ -5,15 +5,17 @@ # # call build/cleanall.sh before changing -set -e +set -x HERE=`dirname $0` cd $HERE/.. ROOT=`pwd` +cd $HERE CFGFILE=${ROOT}/scripts/build.cfg if [ x"$1" != x ]; then + if [ -e ${CFGFILE}.$1 ]; then ln -sf ${CFGFILE}.$1 $CFGFILE else @@ -27,14 +29,12 @@ if [ -e $CFGFILE ]; then . $CFGFILE fi -FLATCC_BUILD_GEN=${FLATCC_BUILD_GEN:-Ninja} - -echo "initializing build for CMake $FLATCC_BUILD_GEN" - mkdir -p ${ROOT}/build/Debug mkdir -p ${ROOT}/build/Release rm -rf ${ROOT}/build/Debug/* rm -rf ${ROOT}/build/Release/* -cd ${ROOT}/build/Debug && cmake -G "$FLATCC_BUILD_GEN" $FLATCC_BUILD_FLAGS ../.. -DCMAKE_BUILD_TYPE=Debug -cd ${ROOT}/build/Release && cmake -G "$FLATCC_BUILD_GEN" $FLATCC_BUILD_FLAGS ../.. -DCMAKE_BUILD_TYPE=Release +echo "initializing build for $FLATCC_BUILD_SYSTEM $FLATCC_BUILD_GEN" + +cd ${ROOT}/build/Debug && $FLATCC_BUILD_SYSTEM "$FLATCC_BUILD_GEN" $FLATCC_BUILD_FLAGS ../.. $FLATCC_TARGET_DEBUG +cd ${ROOT}/build/Release && $FLATCC_BUILD_SYSTEM "$FLATCC_BUILD_GEN" $FLATCC_BUILD_FLAGS ../.. $FLATCC_TARGET_RELEASE diff --git a/scripts/test.sh b/scripts/test.sh index d87924b9e..309081036 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -6,6 +6,16 @@ HERE=`dirname $0` cd $HERE/.. ROOT=`pwd` +CFGFILE=${ROOT}/scripts/build.cfg + +if [ -e $CFGFILE ]; then + . $CFGFILE +else + # Default build system is cmake/ninja + ${ROOT}/scripts/initbuild.sh cmake + . $CFGFILE +fi + DBGDIR=$ROOT/build/Debug RELDIR=$ROOT/build/Release @@ -26,12 +36,13 @@ echo "building before tests ..." $ROOT/scripts/build.sh $DEBUG echo "running test in debug build ..." -cd $DBGDIR && ctest $ROOT +cd $DBGDIR && $FLATCC_TEST_CMD if [ "$DEBUG" != "--debug" ]; then -echo "running test in release build ..." -cd $RELDIR && ctest $ROOT -echo "TEST PASSED" + + echo "running test in release build ..." + cd $RELDIR && $FLATCC_TEST_CMD + echo "TEST PASSED" else echo "DEBUG TEST PASSED" fi From b4bd4ede2d863a45000523cca08b7abffd922385 Mon Sep 17 00:00:00 2001 From: Andrew McNulty Date: Thu, 20 Apr 2023 17:04:43 +0200 Subject: [PATCH 4/5] Make Windows build under Meson --- meson.build | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/meson.build b/meson.build index cc3a09596..86f503ecf 100644 --- a/meson.build +++ b/meson.build @@ -41,6 +41,7 @@ endif if cc_id == 'mvsc' has_c99_var_decl = cc_version.version_compare('>=18') + c_args += '-W3' elif cc_id == 'clang' @@ -89,6 +90,10 @@ elif cc_id == 'gcc' endif +if build_machine.system() == 'windows' + c_args += '-D_CRT_SECURE_NO_WARNINGS' +endif + if allow_werror c_args += '-Werror' endif @@ -103,22 +108,6 @@ endif add_project_arguments(cc.get_supported_arguments(c_args), language: 'c') add_project_arguments(cxx.get_supported_arguments(c_args), language: 'cpp') -if get_option('xflatcc_gen_version') - revisition_tag = vcs_tag( - input: 'config/version.in', - output: 'revision', - command: ['git', 'rev-parse', 'HEAD'], - fallback: 'n/a' - ) - - version_tag = vcs_tag( - input: 'config/version.in', - output: 'version', - command: ['git', 'describe', '--abbrev=0', '--tags'], - fallback: 'n/a' - ) -endif - inc_dir = include_directories('include', 'config', 'external') if not meson.is_subproject() @@ -163,12 +152,11 @@ flatcc_src = [ flatccrt_name = 'flatccrt' flatcc_name = 'flatcc' -if buildtype == 'debug' +if buildtype == 'debug' and build_machine.system() != 'windows' flatccrt_name = 'flatccrt_d' flatcc_name = 'flatcc_d' endif - libflatccrt = library(flatccrt_name, sources: flatccrt_src, include_directories: inc_dir, @@ -188,7 +176,7 @@ flatcc = executable(flatcc_name, install: not meson.is_subproject() ) -if not meson.is_subproject() +if not meson.is_subproject() and build_machine.system() != 'windows' mkdir_command = find_program('mkdir') cp_command = find_program('cp') From a32fc9f59a1dc8914f3dc0cca444229f7d7b2117 Mon Sep 17 00:00:00 2001 From: Andrew McNulty Date: Thu, 20 Apr 2023 17:43:00 +0200 Subject: [PATCH 5/5] Add Meson build job to CI workflow. This commit adds a new job to the CI workflow which builds, runs the tests, and the benchmarks under meson on Linux, Windows and macos. The benchmark code up until now was not compiled with the same flags as the library and runtime and so had avoided some scrutiny from these warnings. Under Meson this is no longer the case, and so this code has been fixed up to clean up some warnings --- .github/workflows/ci.yml | 42 +++++++++++++++++++ test/benchmark/benchflatc/benchflatc.cpp | 13 ++++-- .../benchflatc/flatbuffers/flatbuffers.h | 2 +- test/benchmark/benchflatcc/benchflatcc.c | 11 +++-- .../benchflatccjson/benchflatccjson.c | 11 +++-- test/benchmark/benchmain/benchmain.h | 6 +++ test/benchmark/benchraw/benchraw.c | 16 +++---- 7 files changed, 83 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 42e227d67..7de458d8d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,3 +58,45 @@ jobs: cmake . msbuild FlatCC.sln /m /property:Configuration=Release ctest -VV + + meson-build: + name: Meson (${{matrix.os}}) + runs-on: ${{matrix.os}} + continue-on-error: true + strategy: + matrix: + os: [ ubuntu-22.04, macos-12, windows-2022 ] + steps: + - uses: actions/checkout@v3 + + - uses: microsoft/setup-msbuild@v1.1 + if: runner.os == 'windows' + - uses: actions/setup-python@v2 + if: runner.os == 'windows' + - name: Prepare MSVC + uses: bus1/cabuild/action/msdevshell@v1 + with: + architecture: x64 + if: runner.os == 'windows' + - name: Install dependencies (windows) + if: runner.os == 'windows' + run: | + pip install meson + + - name: Install dependencies (ubuntu) + if: runner.os == 'linux' + run: | + sudo apt update -y + sudo apt install ninja-build meson + + - name: Install dependencies (macos) + if: runner.os == 'macos' + run: | + brew install meson ninja + + - name: Build and run tests + run: | + meson setup build --buildtype release + meson compile -C build + meson test -C build --verbose + meson test -C build --benchmark --verbose diff --git a/test/benchmark/benchflatc/benchflatc.cpp b/test/benchmark/benchflatc/benchflatc.cpp index d5d329606..d1e7c7a87 100644 --- a/test/benchmark/benchflatc/benchflatc.cpp +++ b/test/benchmark/benchflatc/benchflatc.cpp @@ -23,10 +23,17 @@ int encode(void *bench, void *buffer, size_t *size) for (int i = 0; i < veclen; i++) { // We add + i to not make these identical copies for a more realistic // compression test. - auto const &foo = Foo(0xABADCAFEABADCAFE + i, 10000 + i, '@' + i, 1000000 + i); - auto const &bar = Bar(foo, 123456 + i, 3.14159f + i, 10000 + i); + auto const &foo = Foo(0xABADCAFEABADCAFE + static_cast(i), + 10000 + static_cast(i), + '@' + static_cast(i), + 1000000 + static_cast(i) + ); + auto const &bar = Bar(foo, 123456 + i, + 3.14159f + static_cast(i), + 10000 + static_cast(i) + ); auto name = fbb.CreateString("Hello, World!"); - auto foobar = CreateFooBar(fbb, &bar, name, 3.1415432432445543543 + i, '!' + i); + auto foobar = CreateFooBar(fbb, &bar, name, 3.1415432432445543543 + i, '!' + static_cast(i)); vec[i] = foobar; } auto location = fbb.CreateString("https://www.example.com/myurl/"); diff --git a/test/benchmark/benchflatc/flatbuffers/flatbuffers.h b/test/benchmark/benchflatc/flatbuffers/flatbuffers.h index 3482cbee3..2311d54a9 100644 --- a/test/benchmark/benchflatc/flatbuffers/flatbuffers.h +++ b/test/benchmark/benchflatc/flatbuffers/flatbuffers.h @@ -464,7 +464,7 @@ class vector_downward { uoffset_t size() const { assert(cur_ != nullptr && buf_ != nullptr); - return static_cast(reserved_ - (cur_ - buf_)); + return static_cast(reserved_ - static_cast(cur_ - buf_)); } uint8_t *data() const { diff --git a/test/benchmark/benchflatcc/benchflatcc.c b/test/benchmark/benchflatcc/benchflatcc.c index 1d7208389..a45d7cc4f 100644 --- a/test/benchmark/benchflatcc/benchflatcc.c +++ b/test/benchmark/benchflatcc/benchflatcc.c @@ -37,11 +37,16 @@ int encode(flatcc_builder_t *B, void *buffer, size_t *size) */ C(list_push_start(B)); FooBar(sibling_create(B, - 0xABADCAFEABADCAFE + i, 10000 + i, '@' + i, 1000000 + i, - 123456 + i, 3.14159f + i, 10000 + i)); + 0xABADCAFEABADCAFE + (unsigned long)i, + 10000 + (short)i, + '@' + (char)i, + 1000000 + (unsigned int)i, + 123456 + i, + 3.14159f + (float)i, + 10000 + (unsigned short)i)); FooBar(name_create_str(B, "Hello, World!")); FooBar(rating_add(B, 3.1415432432445543543 + i)); - FooBar(postfix_add(B, '!' + i)); + FooBar(postfix_add(B, '!' + (unsigned char)i)); C(list_push_end(B)); } C(list_end(B)); diff --git a/test/benchmark/benchflatccjson/benchflatccjson.c b/test/benchmark/benchflatccjson/benchflatccjson.c index 26ee2915d..a10b4af38 100644 --- a/test/benchmark/benchflatccjson/benchflatccjson.c +++ b/test/benchmark/benchflatccjson/benchflatccjson.c @@ -63,11 +63,16 @@ int flatcc_jsonbench_init(flatcc_jsonbench_t *bench) */ C(list_push_start(B)); FooBar(sibling_create(B, - 0xABADCAFEABADCAFE + i, 10000 + i, '@' + i, 1000000 + i, - 123456 + i, 3.14159f + i, 10000 + i)); + 0xABADCAFEABADCAFE + (unsigned long)i, + 10000 + (short)i, + '@' + (char)i, + 1000000 + (unsigned int)i, + 123456 + i, + 3.14159f + (float)i, + 10000 + (unsigned short)i)); FooBar(name_create_str(B, "Hello, World!")); FooBar(rating_add(B, 3.1415432432445543543 + i)); - FooBar(postfix_add(B, '!' + i)); + FooBar(postfix_add(B, '!' + (unsigned char)i)); C(list_push_end(B)); } C(list_end(B)); diff --git a/test/benchmark/benchmain/benchmain.h b/test/benchmark/benchmain/benchmain.h index 8241ca483..b6bbefe91 100644 --- a/test/benchmark/benchmain/benchmain.h +++ b/test/benchmark/benchmain/benchmain.h @@ -61,6 +61,12 @@ int main(int argc, char *argv[]) show_benchmark(BENCH_TITLE " decode/traverse " COMPILE_TYPE, t2, t3, size, rep, "1M"); printf("----\n"); ret = 0; + +#ifdef NDEBUG + // Silence warnings in optimised builds. + (void)ret; +#endif + done: if (buf) { free(buf); diff --git a/test/benchmark/benchraw/benchraw.c b/test/benchmark/benchraw/benchraw.c index 7a50c9719..d3cba2973 100644 --- a/test/benchmark/benchraw/benchraw.c +++ b/test/benchmark/benchraw/benchraw.c @@ -55,24 +55,24 @@ int encode(void *bench, void *buffer, size_t *size) (void)bench; strcpy(fbc.location, "https://www.example.com/myurl/"); - fbc.location_len = strlen(fbc.location); + fbc.location_len = (int)strlen(fbc.location); fbc.fruit = Bananas; fbc.initialized = 1; for (i = 0; i < VEC_LEN; ++i) { foobar = &fbc.list[i]; foobar->rating = 3.1415432432445543543 + i; - foobar->postfix = '!' + i; + foobar->postfix = '!' + (unsigned char)i; strcpy(foobar->name, "Hello, World!"); - foobar->name_len = strlen(foobar->name); + foobar->name_len = (int)strlen(foobar->name); bar = &foobar->sibling; - bar->ratio = 3.14159f + i; - bar->size = 10000 + i; + bar->ratio = 3.14159f + (float)i; + bar->size = 10000 + (unsigned short)i; bar->time = 123456 + i; foo = &bar->parent; - foo->id = 0xABADCAFEABADCAFE + i; - foo->count = 10000 + i; + foo->id = (int64_t)0xABADCAFEABADCAFE + i; + foo->count = 10000 + (short)i; foo->length = 1000000 + i; - foo->prefix = '@' + i; + foo->prefix = '@' + (char)i; } if (*size < sizeof(struct FooBarContainer)) { return -1;