From f80bef352450801b26b7be4de79342dcb6a23e1a Mon Sep 17 00:00:00 2001 From: David Rheinsberg Date: Mon, 8 Sep 2025 13:00:53 +0200 Subject: [PATCH] compiler: add 'b_time64' base option Introduce a new base option called `b_time64`. This is a boolean option, which defaults to `false` (in which case it has no effect). If set to true, this will set `_TIME_BITS=64` (or equivalent) for all compilations. This enables a workaround for the Y2038 problem. With `_TIME_BITS=64`, libc will switch `time_t` and other relevant time types to 64-bits, if not already 64-bit (i.e., this usually only affects 32-bit platforms). libc will also transparently switch to 64-bit syscalls. For more background information, there is an LWN article about it (from 10 years ago): https://lwn.net/Articles/664800/ Handling of this option is similar to _FILE_OFFSET_BITS=64, which meson sets by default. Unfortunately, `time_t` is much more often used in public APIs, and thus more likely to lead to ABI mismatches when mixing code compiled with and without the option. --- docs/markdown/Builtin-options.md | 1 + mesonbuild/compilers/compilers.py | 12 ++++++++++++ mesonbuild/compilers/mixins/clike.py | 3 +++ mesonbuild/modules/rust.py | 5 +++++ mesonbuild/options.py | 1 + 5 files changed, 22 insertions(+) diff --git a/docs/markdown/Builtin-options.md b/docs/markdown/Builtin-options.md index e52ba3f5dd88..a95aac2f738b 100644 --- a/docs/markdown/Builtin-options.md +++ b/docs/markdown/Builtin-options.md @@ -232,6 +232,7 @@ available on all platforms or with all compilers: | b_pgo | off | off, generate, use | Use profile guided optimization | | b_sanitize | none | see below | Code sanitizer to use | | b_staticpic | true | true, false | Build static libraries as position independent | +| b_time64 | false | true, false | Enable 64-bit time handling for 32-bit platforms (via `_TIME_BITS=64`) | | b_pie | false | true, false | Build position-independent executables (since 0.49.0) | | b_vscrt | from_buildtype | none, md, mdd, mt, mtd, from_buildtype, static_from_buildtype | VS runtime library to use (since 0.48.0) (static_from_buildtype since 0.56.0) | diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 624226d33c8d..66c874c5de4e 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -330,6 +330,11 @@ def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Env pass except KeyError: pass + try: + if env.coredata.get_option_for_target(target, 'b_time64'): + args += compiler.get_time64_args() + except (KeyError, AttributeError): + pass return args def get_base_link_args(target: 'BuildTarget', @@ -1095,6 +1100,13 @@ def get_assert_args(self, disable: bool, env: 'Environment') -> T.List[str]: """ return [] + def get_time64_args(self) -> T.List[str]: + """Get arguments to enable 64-bit time handling for 32-bit platforms. + + :return: A list of string arguments for this compiler + """ + return [] + def get_crt_val(self, crt_val: str, buildtype: str) -> str: if crt_val in options.MSCRT_VALS: return crt_val diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index d2eb6119bcd0..c1139664fd3a 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -1344,6 +1344,9 @@ def get_assert_args(self, disable: bool, env: 'Environment') -> T.List[str]: return ['-DNDEBUG'] return [] + def get_time64_args(self) -> T.List[str]: + return ['-D_TIME_BITS=64'] + @functools.lru_cache(maxsize=None) def can_compile(self, src: 'mesonlib.FileOrString') -> bool: # Files we preprocess can be anything, e.g. .in diff --git a/mesonbuild/modules/rust.py b/mesonbuild/modules/rust.py index d0e809181005..8af905d6c762 100644 --- a/mesonbuild/modules/rust.py +++ b/mesonbuild/modules/rust.py @@ -344,6 +344,11 @@ def bindgen(self, state: ModuleState, args: T.List, kwargs: FuncBindgen) -> Modu if are_asserts_disabled_for_subproject(state.subproject, state.environment): clang_args.append('-DNDEBUG') + time64 = state.get_option('b_time64', state.subproject) + assert isinstance(time64, bool), 'for mypy' + if time64: + clang_args.append('-D_TIME_BITS=64') + for de in kwargs['dependencies']: for i in de.get_include_dirs(): clang_args.extend([f'-I{x}' for x in i.to_string_list( diff --git a/mesonbuild/options.py b/mesonbuild/options.py index 1b2bfc64e757..301dcfa336eb 100644 --- a/mesonbuild/options.py +++ b/mesonbuild/options.py @@ -789,6 +789,7 @@ def option_to_argparse(option: AnyOptionType, name: OptionKey, parser: argparse. UserComboOption( 'b_ndebug', 'Disable asserts', 'false', choices=['true', 'false', 'if-release']), UserBooleanOption('b_staticpic', 'Build static libraries as position independent', True), + UserBooleanOption('b_time64', 'Set _TIME_BITS=64', False), UserBooleanOption('b_pie', 'Build executables as position independent', False), UserBooleanOption('b_bitcode', 'Generate and embed bitcode (only macOS/iOS/tvOS)', False), UserComboOption(