diff --git a/build-config/mfem/build_policy.hpp.in b/build-config/mfem/build_policy.hpp.in new file mode 100644 index 00000000..0f6d054d --- /dev/null +++ b/build-config/mfem/build_policy.hpp.in @@ -0,0 +1,10 @@ +#pragma once +// Meson MFEM policy: buildtype=@BUILD_TYPE@, optimization=@OPTIMIZATION@, +// debug symbols=@DEBUG_SYMBOLS@, NDEBUG=@NDEBUG@. +// This generated header tracks configuration changes for every MFEM consumer. +#ifdef __cplusplus +#include +#if defined(MFEM_DEBUG) != @MFEM_DEBUG@ +#error "MFEM_DEBUG does not match the Meson build; rebuild the MFEM bundle." +#endif +#endif diff --git a/build-config/mfem/meson.build b/build-config/mfem/meson.build index 044f550e..b4a0df0e 100644 --- a/build-config/mfem/meson.build +++ b/build-config/mfem/meson.build @@ -327,6 +327,12 @@ endif system_mfem = disabler() system_mfem_dependencies = [] mfem_provider = 'source bundle' +# MFEM derives its debug-check macro from CMake's build type, independently +# of debug symbols. Keep NDEBUG under Meson's existing assertion policy. +mfem_debug_checks = get_option('buildtype') == 'debug' +mfem_ndebug = get_option('b_ndebug') == 'true' or ( + get_option('b_ndebug') == 'if-release' and get_option('buildtype') in ['release', 'plain'] +) if effective_allow_preinstalled system_candidate = dependency( @@ -416,6 +422,16 @@ if effective_allow_preinstalled endif if system_compatible + if not mfem_debug_checks and not cpp.compiles( + '#include \n' + + '#ifdef MFEM_DEBUG\n#error MFEM debug checks are enabled\n#endif\n' + + 'int main(){return 0;}', + dependencies: system_candidate_dependencies, + name: 'system MFEM has debug checks disabled for this build type', + ) + error('This build type requires MFEM without MFEM_DEBUG. Reconfigure with ' + + '-Dallow_preinstalled=false to build a matching MFEM, or select a release MFEM installation.') + endif system_mfem = system_candidate system_mfem_dependencies = system_candidate_dependencies mfem_provider = 'system' @@ -552,6 +568,11 @@ else '--cc', cc_executable, '--cxx', cxx_executable, '--buildtype', get_option('buildtype'), + '--optimization', get_option('optimization'), + '--debug', get_option('debug') ? 'true' : 'false', + '--ndebug', mfem_ndebug ? 'true' : 'false', + '--compiler-syntax', cpp.get_argument_syntax(), + '--compiler-id', cpp.get_id(), '--jobs', get_option('jobs').to_string(), '--host-system', host_machine.system(), '--cross-build', meson.is_cross_build() ? 'true' : 'false', @@ -656,6 +677,24 @@ else endif bundle_compile_args = ['-I' + mfem_runtime_prefix / 'include'] + # The bundle directory is an order-only prerequisite. A configure-time header + # also invalidates consumer objects when MFEM's policy changes with otherwise + # identical compiler flags (e.g. debug -O2 -> debugoptimized). + mfem_policy = configuration_data() + mfem_policy.set('BUILD_TYPE', get_option('buildtype')) + mfem_policy.set('OPTIMIZATION', get_option('optimization')) + mfem_policy.set('DEBUG_SYMBOLS', get_option('debug').to_string()) + mfem_policy.set('NDEBUG', mfem_ndebug.to_string()) + mfem_policy.set('MFEM_DEBUG', mfem_debug_checks ? 1 : 0) + mfem_policy_header = configure_file( + input: 'build_policy.hpp.in', output: 'mfem_build_policy.hpp', + configuration: mfem_policy, + ) + if cpp.get_argument_syntax() == 'msvc' + bundle_compile_args += ['/FI' + mfem_policy_header.full_path()] + else + bundle_compile_args += ['-include', mfem_policy_header.full_path()] + endif bundle_link_args = [ '-L' + mfem_runtime_prefix / 'lib', '-L' + mfem_runtime_prefix / 'lib64', @@ -760,4 +799,8 @@ if get_option('build_python') and get_option('python_install_native') and not ge error('A self-contained Python wheel requires -Dinstall_mfem=true so the native bundle is installed.') endif -meson.override_dependency('mfem', mfem_dep) +# A compatible system dependency is already registered by dependency(). +# Meson rejects overriding that resolved entry. Only register the source bundle. +if mfem_provider != 'system' + meson.override_dependency('mfem', mfem_dep) +endif