From e3a33ae8ae87f724f0675379db5c0a74b09de584 Mon Sep 17 00:00:00 2001 From: Tyler Erickson Date: Mon, 20 Oct 2025 12:08:01 -0600 Subject: [PATCH 1/3] make: Adding support for building json-c with meson Adding meson build files for json-c that work similarly to the cmake build files. Where it made sense, I reused existing cmake .h.in files or generated entirely from meson. All tests were done with GCC and Clang in ubuntu 24.04, Windows using MSVC 2022 and Clang-cl from llvm's repo using version 21.1.3 Signed-off-by: Tyler Erickson --- apps/meson.build | 27 ++++ meson.build | 347 ++++++++++++++++++++++++++++++++++++++++++++++ meson_options.txt | 12 ++ tests/meson.build | 65 +++++++++ 4 files changed, 451 insertions(+) create mode 100644 apps/meson.build create mode 100644 meson.build create mode 100644 meson_options.txt create mode 100644 tests/meson.build diff --git a/apps/meson.build b/apps/meson.build new file mode 100644 index 0000000..55e9b4d --- /dev/null +++ b/apps/meson.build @@ -0,0 +1,27 @@ + +appconf_data = configuration_data() +# Check for json_tokener_get_parse_end symbol +appconf_data.set('HAVE_JSON_TOKENER_GET_PARSE_END', + cc.has_function('json_tokener_get_parse_end', prefix: '#include ') ? 1 : 0 +) + +# Check for getrusage if sys/resource.h is available +appconf_data.set('HAVE_SYS_RESOURCE_H', cc.has_header('sys/resource.h') ? 1 : 0, description: 'Define to 1 if you have the header file.') +if appconf_data.get('HAVE_SYS_RESOURCE_H') == 1 + appconf_data.set('HAVE_GETRUSAGE', + cc.has_function('getrusage', prefix: '#include ') ? 1 : 0, description: 'Define if you have the `getrusage` function. ') +else + appconf_data.set('HAVE_GETRUSAGE', 0, description: 'Define if you have the `getrusage` function. ') +endif + +# Generate apps_config.h +configure_file( + output: 'apps_config.h', + configuration: appconf_data +) + +# Build json_parse executable +executable('json_parse', 'json_parse.c', + dependencies: [jsonc_dep], + install: false +) diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..f612037 --- /dev/null +++ b/meson.build @@ -0,0 +1,347 @@ + +project('json-c', 'c', version: '0.18.99', + default_options: ['buildtype=release', 'warning_level=2']) + +cc = meson.get_compiler('c') + +# Configuration header generation +conf_data = configuration_data() +jconf_data = configuration_data() +conf_data.set('VERSION', meson.project_version()) + +has_std_lib = cc.has_header('stdlib.h') +has_std_arg = cc.has_header('stdarg.h') +has_string = cc.has_header('string.h') +has_float = cc.has_header('float.h') + +if has_std_lib and has_std_arg and has_string and has_float + conf_data.set('STDC_HEADERS', 1, description : 'Define to 1 if you have the ANSI C header files.') +endif + +if cc.has_header('dlfcn.h') + conf_data.set('HAVE_DLFCN_H', 1, description : 'Define to 1 if you have the header file.') +endif + +if cc.has_header('endian.h') + conf_data.set('HAVE_ENDIAN_H', 1, description : 'Define to 1 if you have the header file') +endif + +if cc.has_header('fcntl.h') + conf_data.set('HAVE_FCNTL_H', 1, description : 'Define to 1 if you have the header file.') +endif + +if cc.has_header('inttypes.h') + conf_data.set('HAVE_INTTYPES_H', 1, description : 'Define to 1 if you have the header file.') + conf_data.set('JSON_C_HAVE_INTTYPES_H', 1, description : 'Define to 1 if you have the header file.') + jconf_data.set('JSON_C_HAVE_INTTYPES_H', 1, description : 'Define to 1 if you have the header file.') +endif + +if cc.has_header('limits.h') + conf_data.set('HAVE_LIMITS_H', 1, description : 'Define to 1 if you have the header file.') +endif + +if cc.has_header('locale.h') + conf_data.set('HAVE_LOCALE_H', 1, description : 'Define to 1 if you have the header file.') +endif +if cc.has_header('memory.h') + conf_data.set('HAVE_MEMORY_H', 1, description : 'Define to 1 if you have the header file.') +endif +if has_std_arg + conf_data.set('HAVE_STDARG_H', 1, description : 'Define to 1 if you have the header file.') +endif +if cc.has_header('stdint.h') + conf_data.set('HAVE_STDINT_H', 1, description : 'Define to 1 if you have the header file.') + conf_data.set('JSON_C_HAVE_STDINT_H', 1, description : 'Define to 1 if you have the header file.') + jconf_data.set('JSON_C_HAVE_STDINT_H', 1, description : 'Define to 1 if you have the header file.') +endif +if has_std_lib + conf_data.set('HAVE_STDLIB_H', 1, description : 'Define to 1 if you have the header file.') +endif +if cc.has_header('strings.h') + conf_data.set('HAVE_STRINGS_H', 1, description : 'Define to 1 if you have the header file.') + if cc.has_function('strcasecmp', prefix : '#include ') + conf_data.set('HAVE_STRCASECMP', 1, description : 'Define to 1 if you have the `strcasecmp` function.') + endif + if cc.has_function('strncasecmp', prefix : '#include ') + conf_data.set('HAVE_STRNCASECMP', 1, description : 'Define to 1 if you have the `strncasecmp` function.') + endif +endif +if has_string + conf_data.set('HAVE_STRING_H', 1, description : 'Define to 1 if you have the header file.') +endif +if cc.has_header('syslog.h') + conf_data.set('HAVE_SYSLOG_H', 1, description : 'Define to 1 if you have the header file.') +endif +if cc.has_header('sys/cdefs.h') + conf_data.set('HAVE_SYS_CDEFS_H', 1, description : 'Define to 1 if you have the header file.') +endif +if cc.has_header('sys/param.h') + conf_data.set('HAVE_SYS_PARAM_H', 1, description : 'Define to 1 if you have the header file.') +endif +if cc.has_header('sys/random.h') + conf_data.set('HAVE_SYS_RANDOM_H', 1, description : 'Define to 1 if you have the header file.') +endif +if cc.has_header('sys/resource.h') + conf_data.set('HAVE_SYS_RESOURCE_H', 1, description : 'Define to 1 if you have the header file.') +endif +if cc.has_header('sys/stat.h') + conf_data.set('HAVE_SYS_STAT_H', 1, description : 'Define to 1 if you have the header file.') +endif +if cc.has_header('sys/types.h') + conf_data.set('HAVE_SYS_TYPES_H', 1, description : 'Define to 1 if you have the header file.') +endif +if cc.has_header('unistd.h') + conf_data.set('HAVE_UNISTD_H', 1, description : 'Define to 1 if you have the header file.') +endif +if cc.has_header('xlocale.h') + conf_data.set('HAVE_XLOCALE_H', 1, description : 'Define to 1 if you have the header file.') +endif +has_bsd_stdlib = cc.has_header('bsd/stdlib.h') +if has_bsd_stdlib + conf_data.set('HAVE_BSD_STDLIB_H', 1, description : 'Define to 1 if you have the header file.') +endif +if cc.has_function('vprintf', prefix : '#include \n#include ') + conf_data.set('HAVE_VPRINTF', 1, description : 'Define to 1 if you have the `vprintf` function.') +elif cc.has_function('_doprnt') + conf_data.set('HAVE_DOPRNT', 1, description : 'Define to 1 if you have _doprnt but not vprintf.') +endif +if cc.has_define('INFINITY', prefix : '#include \n#include ') + conf_data.set('HAVE_DECL_INFINITY', 1, description : 'Define to 1 if you have the declaration of `INFINITY`') +endif +if cc.has_define('isinf', prefix : '#include \n#include ') or cc.has_function('isinf', prefix : '#include \n#include ') + conf_data.set('HAVE_DECL_ISINF', 1, description : 'Define to 1 if you have the declaration of `isinf`') +endif +if cc.has_define('isnan', prefix : '#include \n#include ') or cc.has_function('isnan', prefix : '#include \n#include ') + conf_data.set('HAVE_DECL_ISNAN', 1, description : 'Define to 1 if you have the declaration of `isnan`') +endif +if cc.has_define('NAN', prefix : '#include \n#include ') + conf_data.set('HAVE_DECL_NAN', 1, description : 'Define to 1 if you have the declaration of `NAN`') +endif +if cc.has_define('_finite', prefix : '#include \n#include ') or cc.has_function('_finite', prefix : '#include \n#include ') + conf_data.set('HAVE_DECL__FINITE', 1, description : 'Define to 1 if you have the declaration of `_finite`') +endif +if cc.has_define('_isnan', prefix : '#include \n#include ') or cc.has_function('_isnan', prefix : '#include \n#include ') + conf_data.set('HAVE_DECL__ISNAN', 1, description : 'Define to 1 if you have the declaration of `_isnan`') +endif + +if cc.has_function('open', prefix : '#include ') + conf_data.set('HAVE_OPEN', 1, description : 'Define to 1 if you have the `open` function.') +endif +if cc.has_function('realloc', prefix : '#include ') + conf_data.set('HAVE_REALLOC', 1, description : 'Define to 1 if you have the `realloc` function.') +endif +if cc.has_function('setlocale', prefix : '#include ') + conf_data.set('HAVE_SETLOCALE', 1, description : 'Define to 1 if you have the `setlocale` function.') +endif +if cc.has_function('snprintf', prefix : '#include ') + conf_data.set('HAVE_SNPRINTF', 1, description : 'Define to 1 if you have the `snprintf` function.') +endif +if cc.has_function('strdup') + conf_data.set('HAVE_STRDUP', 1, description : 'Define to 1 if you have the `strdup` function.') +endif +if cc.has_function('strerror') + conf_data.set('HAVE_STRERROR', 1, description : 'Define to 1 if you have the `strerror` function.') +endif + +if cc.has_function('uselocale', prefix : '#include ') + conf_data.set('HAVE_USELOCALE', 1, description : 'Define to 1 if you have the `uselocale` function.') +endif +if cc.has_function('duplocale', prefix : '#include ') + conf_data.set('HAVE_DUPLOCALE', 1, description : 'Define to 1 if you have the `duplocale` function.') +endif +if cc.has_function('vasprintf', prefix : '#define _GNU_SOURCE\n#include \n#include ') + conf_data.set('HAVE_VASPRINTF', 1, description : 'Define to 1 if you have the `vasprintf` function.') +endif +if cc.has_function('vsnprintf', prefix : '#include \n#include ') + conf_data.set('HAVE_VSNPRINTF', 1, description : 'Define to 1 if you have the `vsnprintf` function.') +endif +if cc.has_function('vsyslog') + conf_data.set('HAVE_VSYSLOG', 1, description : 'Define to 1 if you have the `vsyslog` function.') +endif +if cc.has_function('getrandom') + conf_data.set('HAVE_GETRANDOM', 1, description : 'Define to 1 if you have the `getrandom` function.') +endif +if cc.has_function('getrusage', prefix : '#include ') + conf_data.set('HAVE_GETRUSAGE', 1, description : 'Define to 1 if you have the `getrusage` function.') +endif + +have_strtoll = cc.has_function('strtoll') +have_strtoull = cc.has_function('strtoull') + +if have_strtoll + conf_data.set('HAVE_STRTOLL', 1) + conf_data.set('json_c_strtoll', 'strtoll') +elif cc.has_function('_strtoi64', prefix : '#include ') + conf_data.set('json_c_strtoll', '_strtoi64') +endif + +if have_strtoull + conf_data.set('HAVE_STRTOULL', 1) + conf_data.set('json_c_strtoull', 'strtoull') +elif cc.has_function('_strtoui64', prefix : '#include ') + conf_data.set('json_c_strtoull', '_strtoui64') +endif + +check_thread = cc.compiles(''' + __thread int x = 0; + int main() { return x; } + ''', + name: 'Check for __thread support') + +if check_thread + conf_data.set('HAVE___THREAD', 1) + conf_data.set('SPEC___THREAD', '__thread') +elif cc.get_id().contains('msvc') + conf_data.set('SPEC___THREAD', '__declspec(thread)') +endif + + +gnu_warning_section_support = cc.compiles(''' + extern void json_object_get(); + __asm__(".section .gnu.json_object_get\n\t.ascii \"Please link against libjson-c instead of libjson\"\n\t.text"); + int main(int c, char *v) { return 0; } + ''', name: 'Check for GNU warning section support') +if gnu_warning_section_support + conf_data.set('HAS_GNU_WARNING_LONG', 1, description : 'Define to 1 if the compiler supports .gnu.warning sections.') +endif + +if has_bsd_stdlib + if cc.has_function('arc4random', prefix: '#include ') + conf_data.set('HAVE_ARC4RANDOM', 1) + endif +else + if cc.has_function('arc4random', prefix: '#include ') + conf_data.set('HAVE_ARC4RANDOM', 1) + endif +endif + +atomic_builtin_support = cc.compiles(''' + int main() { + int x = 0; + int i = __sync_add_and_fetch(&x, 1); + return x; + } + ''', + name: 'Check for atomic builtins') +if atomic_builtin_support + conf_data.set('HAVE_ATOMIC_BUILTINS', 1, description : 'Define to 1 if the compiler supports atomic builtins.') +endif + +if get_option('enable_rdrand') + conf_data.set('ENABLE_RDRAND', 1) +endif +if get_option('override_get_random_seed') + conf_data.set('OVERRIDE_GET_RANDOM_SEED', get_option('override_get_random_seed')) +endif +if get_option('enable_threading') + conf_data.set('ENABLE_THREADING', 1) +endif +if get_option('newlocale_needs_freelocale') + conf_data.set('NEWLOCALE_NEEDS_FREELOCALE', 1) +endif + +conf_data.set('SIZEOF_INT', cc.sizeof('int')) +conf_data.set('SIZEOF_INT64_T', cc.sizeof('int64_t', prefix : '#include ')) +conf_data.set('SIZEOF_LONG', cc.sizeof('long')) +conf_data.set('SIZEOF_LONG_LONG', cc.sizeof('long long')) +conf_data.set('SIZEOF_SIZE_T', cc.sizeof('size_t')) +if target_machine.system() == 'windows' + conf_data.set('SIZEOF_SSIZE_T', cc.sizeof('SSIZE_T', prefix : '#include \n#include ')) +else + conf_data.set('SIZEOF_SSIZE_T', cc.sizeof('ssize_t', prefix : '#include ')) +endif + +conf_data.set('PACKAGE_VERSION', meson.project_version()) +conf_data.set('PROJECT_NAME', meson.project_name()) + +configure_header = configure_file( + output: 'config.h', + configuration: conf_data +) + +json_configure_header = configure_file( + output: 'json_config.h', + configuration: jconf_data +) + +jhconf_data = configuration_data() + +jhconf_data.set('JSON_H_JSON_PATCH', + get_option('disable_json_patch') ? '' : '#include "json_patch.h"' +) + +jhconf_data.set('JSON_H_JSON_POINTER', + get_option('disable_json_pointer') ? '' : '#include "json_pointer.h"' +) + +json_header = configure_file( + input: 'json.h.cmakein', + output: 'json.h', + configuration: jhconf_data +) + + +# Platform-specific flags +add_project_arguments('-D_GNU_SOURCE', language: 'c') + +if host_machine.system() == 'windows' + add_project_arguments('-DWIN32', language: 'c') +endif + +# Compiler flags +message('target is ' + target_machine.system()) +if target_machine.system() == 'windows' + # Cover any compiler on Windows attempting to use MSVC's standard library + add_project_arguments(['-D_CRT_NONSTDC_NO_DEPRECATE', '-D_CRT_SECURE_NO_WARNINGS'], language: 'c') +endif + +if cc.get_id().contains('gcc') or cc.get_id().contains('clang') + add_project_arguments(cc.get_supported_arguments(['-Wno-unused-parameter']), language : 'c') +endif + +# Source files +sources = files( + 'arraylist.c', 'debug.c', 'json_c_version.c', 'json_object.c', + 'json_object_iterator.c', 'json_tokener.c', 'json_util.c', + 'json_visit.c', 'linkhash.c', 'printbuf.c', 'random_seed.c', + 'strerror_override.c' +) + +if not get_option('disable_json_pointer') + sources += files('json_pointer.c') + if not get_option('disable_json_patch') + sources += files('json_patch.c') + endif +endif + +# Include directories +inc = include_directories('.') + +# Build library +libjson = library('json-c', + sources, + include_directories: inc, + install: true, + version: '5.4.0', + soversion: '5', +) + +jsonc_dep = declare_dependency(link_with: libjson, include_directories: inc) + +# Install headers +install_headers( + 'arraylist.h', 'debug.h', 'json_c_version.h', 'json_inttypes.h', + 'json_object.h', 'json_object_iterator.h', 'json_tokener.h', + 'json_types.h', 'json_util.h', 'json_visit.h', 'linkhash.h', + 'printbuf.h', json_configure_header, json_header +) + +# Optional apps +if get_option('build_apps') and target_machine.system() != 'windows' + subdir('apps') +endif + +# Optional tests +if get_option('buildtype') == 'debug' + subdir('tests') +endif diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000..fa6272f --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,12 @@ + +option('disable_bsymbolic', type: 'boolean', value: false, description: 'Avoid linking with -Bsymbolic-function') +option('disable_thread_local_storage', type: 'boolean', value: false, description: 'Disable Thread-Local Storage') +option('disable_werror', type: 'boolean', value: false, description: 'Disable treating warnings as errors') +option('enable_rdrand', type: 'boolean', value: false, description: 'Enable RDRAND Hardware RNG') +option('enable_threading', type: 'boolean', value: false, description: 'Enable partial threading support') +option('override_get_random_seed', type: 'boolean', value: false, description: 'Override json_c_get_random_seed()') +option('disable_extra_libs', type: 'boolean', value: false, description: 'Avoid linking extra libraries like libbsd') +option('disable_json_pointer', type: 'boolean', value: false, description: 'Disable JSON pointer support') +option('disable_json_patch', type: 'boolean', value: false, description: 'Disable JSON patch support') +option('newlocale_needs_freelocale', type: 'boolean', value: false, description: 'FreeBSD workaround for newlocale') +option('build_apps', type: 'boolean', value: true, description: 'Build command-line apps') diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 0000000..9580e4b --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,65 @@ +test_includes = include_directories('.') +test_deps = [jsonc_dep] + +# List of test sources and expected output files +test_cases = [ + ['test1', 'test1.expected'], + ['test2', 'test2.expected'], + ['test4', 'test4.expected'], + ['testReplaceExisting', 'testReplaceExisting.expected'], + ['test_cast', 'test_cast.expected'], + ['test_charcase', 'test_charcase.expected'], + ['test_compare', 'test_compare.expected'], + ['test_deep_copy', 'test_deep_copy.expected'], + ['test_double_serializer', 'test_double_serializer.expected'], + ['test_float', 'test_float.expected'], + ['test_int_add', 'test_int_add.expected'], + ['test_int_get', 'test_int_get.expected'], + ['test_locale', 'test_locale.expected'], + ['test_null', 'test_null.expected'], + ['test_parse', 'test_parse.expected'], + ['test_parse_int64', 'test_parse_int64.expected'], + ['test_printbuf', 'test_printbuf.expected'], + ['test_set_serializer', 'test_set_serializer.expected'], + ['test_set_value', 'test_set_value.expected'], + ['test_strerror', 'test_strerror.expected'], + ['test_util_file', 'test_util_file.expected'], + ['test_visit', 'test_visit.expected'], + ['test_object_iterator', 'test_object_iterator.expected'], + ['test_json_pointer', 'test_json_pointer.expected'], + ['test_json_patch', 'test_json_patch.expected'], +] + +# Copy expected files and test data +expected_files = [] +foreach t : test_cases + expected_files += t[1] +endforeach + +foreach f : expected_files + ['valid.json', 'valid_nested.json', 'json_patch_spec_tests.json', 'json_patch_tests.json'] + configure_file(input: f, output: f, copy: true) +endforeach + +# Build and register tests +special_args = { + 'test_json_patch': ['.'], + 'test_util_file': ['.'], +} + +testdir = meson.current_build_dir() +message('Test data directory: ' + testdir) + +foreach t : test_cases + name = t[0] + expected = t[1] + exe = executable(name, name + '.c', + include_directories: test_includes, + dependencies: test_deps + ) + + test(name, exe, + args: special_args.get(name, []), + env: ['EXPECTED_FILE=' + meson.current_build_dir() / expected], + workdir: testdir + ) +endforeach \ No newline at end of file From 3723b182db6f0cf62c5a041ac31f23485433ccac Mon Sep 17 00:00:00 2001 From: Tyler Erickson Date: Mon, 20 Oct 2025 12:10:57 -0600 Subject: [PATCH 2/3] bug: Fixing runtime issue with test_util_file.c in Windows Windows was failing tests due to how the Windows API works with some of the calls used. When opening and reading a file O_BINARY is needed otherwise it fails for size checks. This is due to how Windows handles newlines and counts between text and binary mode file reads. Also fixed is the test for /dev/null. In Windows, this fails, but crashes due to a missing return statement when it cannot open this file. I also tried telling windows to open the special file NUL, however that leads to a CRT crash later in the test that cannot be stopped and will always fail. Rather than fail a test that Windows will always fail, it has been disabled in that specific case. Signed-off-by: Tyler Erickson --- tests/test_util_file.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/tests/test_util_file.c b/tests/test_util_file.c index 2a4ceef..03ba3a4 100644 --- a/tests/test_util_file.c +++ b/tests/test_util_file.c @@ -27,7 +27,9 @@ static void test_read_valid_with_fd(const char *testdir); static void test_read_valid_nested_with_fd(const char *testdir); static void test_read_nonexistant(void); +#ifndef _WIN32 static void test_read_closed(void); +#endif static void test_write_to_file(void); static void stat_and_cat(const char *file); @@ -92,7 +94,12 @@ static void test_write_to_file(void) static void stat_and_cat(const char *file) { struct stat sb; - int d = open(file, O_RDONLY); + int flags = O_RDONLY; +#ifdef O_BINARY + // This fixes Windows which otherwise opens this in text mode and returns different counts + flags |= O_BINARY; +#endif + int d = open(file, flags); if (d < 0) { printf("FAIL: unable to open %s: %s\n", file, strerror(errno)); @@ -159,7 +166,10 @@ int main(int argc, char **argv) test_read_valid_with_fd(testdir); test_read_valid_nested_with_fd(testdir); test_read_nonexistant(); + #ifndef _WIN32 + // Disabled because the Windows CRT causes a crash during this test that cannot be disabled/stopped/worked around test_read_closed(); + #endif test_write_to_file(); test_read_fd_equal(testdir); return EXIT_SUCCESS; @@ -169,8 +179,12 @@ static void test_read_valid_with_fd(const char *testdir) { char filename[PATH_MAX]; (void)snprintf(filename, sizeof(filename), "%s/valid.json", testdir); - - int d = open(filename, O_RDONLY); + int flags = O_RDONLY; +#ifdef O_BINARY + // This fixes Windows which otherwise opens this in text mode and returns different counts + flags |= O_BINARY; +#endif + int d = open(filename, flags); if (d < 0) { fprintf(stderr, "FAIL: unable to open %s: %s\n", filename, strerror(errno)); @@ -194,8 +208,12 @@ static void test_read_valid_nested_with_fd(const char *testdir) { char filename[PATH_MAX]; (void)snprintf(filename, sizeof(filename), "%s/valid_nested.json", testdir); - - int d = open(filename, O_RDONLY); + int flags = O_RDONLY; +#ifdef O_BINARY + // This fixes Windows which otherwise opens this in text mode and returns different counts + flags |= O_BINARY; +#endif + int d = open(filename, flags); if (d < 0) { fprintf(stderr, "FAIL: unable to open %s: %s\n", filename, strerror(errno)); @@ -250,7 +268,7 @@ static void test_read_nonexistant(void) json_util_get_last_err()); } } - +#ifndef _WIN32 static void test_read_closed(void) { // Test reading from a closed fd @@ -258,6 +276,7 @@ static void test_read_closed(void) if (d < 0) { puts("FAIL: unable to open"); + return; } // Copy over to a fixed fd number so test output is consistent. int fixed_d = 10; @@ -281,6 +300,7 @@ static void test_read_closed(void) "expecting NULL, EBADF, got:NULL, %s\n", json_util_get_last_err()); } +#endif static void test_read_fd_equal(const char *testdir) { @@ -288,8 +308,12 @@ static void test_read_fd_equal(const char *testdir) (void)snprintf(filename, sizeof(filename), "%s/valid_nested.json", testdir); json_object *jso = json_object_from_file(filename); - - int d = open(filename, O_RDONLY); + int flags = O_RDONLY; +#ifdef O_BINARY + // This fixes Windows which otherwise opens this in text mode and returns different counts + flags |= O_BINARY; +#endif + int d = open(filename, flags); if (d < 0) { fprintf(stderr, "FAIL: unable to open %s: %s\n", filename, strerror(errno)); From a5bc36de261a4e33f4cdb67e7566f18034f352e5 Mon Sep 17 00:00:00 2001 From: Tyler Erickson Date: Fri, 24 Oct 2025 09:48:56 -0600 Subject: [PATCH 3/3] Removing werror option as meson has a built-in option for this Signed-off-by: Tyler Erickson --- meson_options.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/meson_options.txt b/meson_options.txt index fa6272f..94205b0 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,7 +1,6 @@ option('disable_bsymbolic', type: 'boolean', value: false, description: 'Avoid linking with -Bsymbolic-function') option('disable_thread_local_storage', type: 'boolean', value: false, description: 'Disable Thread-Local Storage') -option('disable_werror', type: 'boolean', value: false, description: 'Disable treating warnings as errors') option('enable_rdrand', type: 'boolean', value: false, description: 'Enable RDRAND Hardware RNG') option('enable_threading', type: 'boolean', value: false, description: 'Enable partial threading support') option('override_get_random_seed', type: 'boolean', value: false, description: 'Override json_c_get_random_seed()')