feat(initial): added portable mfem build system
This commit is contained in:
2
build-config/meson.build
Normal file
2
build-config/meson.build
Normal file
@@ -0,0 +1,2 @@
|
||||
subdir('mfem')
|
||||
|
||||
651
build-config/mfem/meson.build
Normal file
651
build-config/mfem/meson.build
Normal file
@@ -0,0 +1,651 @@
|
||||
profile = get_option('feature_profile')
|
||||
allow_preinstalled = get_option('allow_preinstalled')
|
||||
dependency_prefix = get_option('dependency_prefix')
|
||||
wheel_carries_native_bundle = get_option('build_python') and get_option('python_install_native')
|
||||
|
||||
|
||||
effective_allow_preinstalled = allow_preinstalled and not wheel_carries_native_bundle
|
||||
is_wasm = host_machine.system() == 'emscripten'
|
||||
is_windows = host_machine.system() == 'windows'
|
||||
can_build_posix_mpi = not meson.is_cross_build() and not is_windows and not is_wasm
|
||||
|
||||
nvcc_program = find_program('nvcc', required: false)
|
||||
hipcc_program = find_program('hipcc', required: false)
|
||||
dependency_has_nvcc = dependency_prefix != '' and fs.exists(dependency_prefix / 'bin' / 'nvcc')
|
||||
dependency_has_hipcc = dependency_prefix != '' and fs.exists(dependency_prefix / 'bin' / 'hipcc')
|
||||
cuda_toolkit_available = nvcc_program.found() or dependency_has_nvcc
|
||||
hip_toolkit_available = hipcc_program.found() or dependency_has_hipcc
|
||||
openmp_dep = dependency('openmp', required: false)
|
||||
|
||||
bundled_compiler_openmp = cpp.get_id() == 'gcc' and openmp_dep.found()
|
||||
usable_openmp = openmp_dep.found() and (
|
||||
effective_allow_preinstalled or dependency_prefix != '' or bundled_compiler_openmp
|
||||
)
|
||||
simd_arch_supported = host_machine.cpu_family() in ['x86', 'x86_64']
|
||||
if host_machine.cpu_family() in ['aarch64', 'arm']
|
||||
simd_arch_supported = cpp.compiles('''
|
||||
#ifndef __ARM_FEATURE_SVE
|
||||
#error SVE is required by MFEM's ARM SIMD specialization
|
||||
#endif
|
||||
int main() { return 0; }
|
||||
''', name: 'MFEM ARM SVE SIMD support')
|
||||
elif host_machine.cpu_family() in ['ppc', 'ppc64']
|
||||
simd_arch_supported = cpp.compiles('''
|
||||
#ifndef __VSX__
|
||||
#error VSX is required by MFEM's Power SIMD specialization
|
||||
#endif
|
||||
int main() { return 0; }
|
||||
''', name: 'MFEM Power VSX SIMD support')
|
||||
endif
|
||||
|
||||
mfem_feature_names = [
|
||||
'mpi', 'metis', 'exceptions', 'zlib', 'libunwind', 'lapack',
|
||||
'thread_safe', 'openmp', 'legacy_openmp', 'memalloc', 'sundials',
|
||||
'suitesparse', 'superlu', 'superlu5', 'mumps', 'strumpack', 'cudss',
|
||||
'ginkgo', 'amgx', 'magma', 'gnutls', 'gslib', 'hdf5', 'netcdf',
|
||||
'petsc', 'slepc', 'mpfr', 'sidre', 'fms', 'conduit', 'pumi', 'hiop',
|
||||
'cuda', 'hip', 'occa', 'raja', 'ceed', 'umpire', 'simd', 'adios2',
|
||||
'caliper', 'algoim', 'mkl_cpardiso', 'mkl_pardiso', 'adforward',
|
||||
'codipack', 'benchmark', 'parelag', 'tribol', 'enzyme', 'moonolith',
|
||||
'simmetrix',
|
||||
]
|
||||
|
||||
mfem_cmake_names = [
|
||||
'MFEM_USE_MPI', 'MFEM_USE_METIS', 'MFEM_USE_EXCEPTIONS', 'MFEM_USE_ZLIB',
|
||||
'MFEM_USE_LIBUNWIND', 'MFEM_USE_LAPACK', 'MFEM_THREAD_SAFE',
|
||||
'MFEM_USE_OPENMP', 'MFEM_USE_LEGACY_OPENMP', 'MFEM_USE_MEMALLOC',
|
||||
'MFEM_USE_SUNDIALS', 'MFEM_USE_SUITESPARSE', 'MFEM_USE_SUPERLU',
|
||||
'MFEM_USE_SUPERLU5', 'MFEM_USE_MUMPS', 'MFEM_USE_STRUMPACK',
|
||||
'MFEM_USE_CUDSS', 'MFEM_USE_GINKGO', 'MFEM_USE_AMGX', 'MFEM_USE_MAGMA',
|
||||
'MFEM_USE_GNUTLS', 'MFEM_USE_GSLIB', 'MFEM_USE_HDF5', 'MFEM_USE_NETCDF',
|
||||
'MFEM_USE_PETSC', 'MFEM_USE_SLEPC', 'MFEM_USE_MPFR', 'MFEM_USE_SIDRE',
|
||||
'MFEM_USE_FMS', 'MFEM_USE_CONDUIT', 'MFEM_USE_PUMI', 'MFEM_USE_HIOP',
|
||||
'MFEM_USE_CUDA', 'MFEM_USE_HIP', 'MFEM_USE_OCCA', 'MFEM_USE_RAJA',
|
||||
'MFEM_USE_CEED', 'MFEM_USE_UMPIRE', 'MFEM_USE_SIMD', 'MFEM_USE_ADIOS2',
|
||||
'MFEM_USE_CALIPER', 'MFEM_USE_ALGOIM', 'MFEM_USE_MKL_CPARDISO',
|
||||
'MFEM_USE_MKL_PARDISO', 'MFEM_USE_ADFORWARD', 'MFEM_USE_CODIPACK',
|
||||
'MFEM_USE_BENCHMARK', 'MFEM_USE_PARELAG', 'MFEM_USE_TRIBOL',
|
||||
'MFEM_USE_ENZYME', 'MFEM_USE_MOONOLITH', 'MFEM_USE_SIMMETRIX',
|
||||
]
|
||||
|
||||
source_capable = {
|
||||
'mpi': can_build_posix_mpi,
|
||||
'metis': not is_windows and not is_wasm,
|
||||
'exceptions': true,
|
||||
'zlib': true,
|
||||
'thread_safe': true,
|
||||
'openmp': bundled_compiler_openmp,
|
||||
'legacy_openmp': bundled_compiler_openmp,
|
||||
'memalloc': true,
|
||||
'sundials': not is_windows and not is_wasm,
|
||||
'gslib': not is_windows and not is_wasm,
|
||||
'fms': not is_windows,
|
||||
'ceed': not is_windows,
|
||||
'algoim': not meson.is_cross_build() and not is_windows and not is_wasm,
|
||||
'cuda': cuda_toolkit_available and not is_wasm and not host_machine.system() == 'darwin',
|
||||
'hip': hip_toolkit_available and not is_wasm and not host_machine.system() == 'darwin',
|
||||
'simd': simd_arch_supported and not is_wasm,
|
||||
}
|
||||
|
||||
single_precision_conflicts = [
|
||||
'sundials', 'suitesparse', 'superlu', 'strumpack', 'ginkgo', 'amgx',
|
||||
'slepc', 'pumi', 'simmetrix', 'gslib', 'algoim', 'ceed', 'tribol', 'moonolith',
|
||||
]
|
||||
|
||||
cuda_option = get_option('mfem_cuda')
|
||||
hip_option = get_option('mfem_hip')
|
||||
profile_cuda = false
|
||||
profile_hip = false
|
||||
if cuda_option.enabled() and hip_option.enabled()
|
||||
profile_cuda = true
|
||||
profile_hip = true
|
||||
elif cuda_option.enabled()
|
||||
profile_cuda = true
|
||||
elif hip_option.enabled()
|
||||
profile_hip = true
|
||||
else
|
||||
profile_cuda = cuda_option.auto() and source_capable.get('cuda')
|
||||
profile_hip = hip_option.auto() and not profile_cuda and source_capable.get('hip')
|
||||
endif
|
||||
|
||||
portable_defaults = {
|
||||
'mpi': can_build_posix_mpi,
|
||||
'metis': can_build_posix_mpi,
|
||||
'exceptions': true,
|
||||
'zlib': true,
|
||||
'thread_safe': true,
|
||||
'openmp': usable_openmp,
|
||||
'memalloc': true,
|
||||
'sundials': not is_windows and not is_wasm,
|
||||
'gslib': not is_windows and not is_wasm,
|
||||
'fms': not is_windows,
|
||||
'ceed': not is_windows,
|
||||
'algoim': source_capable.get('algoim'),
|
||||
'cuda': profile_cuda,
|
||||
'hip': profile_hip,
|
||||
'simd': simd_arch_supported and not is_wasm,
|
||||
}
|
||||
|
||||
full_cuda = false
|
||||
full_hip = false
|
||||
if profile == 'full'
|
||||
full_cuda = profile_cuda
|
||||
full_hip = profile_hip
|
||||
endif
|
||||
|
||||
mfem_features = {}
|
||||
mfem_feature_states = []
|
||||
foreach feature_name : mfem_feature_names
|
||||
feature_opt = get_option('mfem_' + feature_name)
|
||||
feature_on = feature_opt.enabled()
|
||||
if feature_opt.auto()
|
||||
if profile == 'portable'
|
||||
feature_on = portable_defaults.get(feature_name, false)
|
||||
elif profile == 'full'
|
||||
feature_on = true
|
||||
if feature_name == 'legacy_openmp' or feature_name == 'superlu5'
|
||||
feature_on = false
|
||||
elif feature_name == 'openmp'
|
||||
feature_on = usable_openmp
|
||||
elif feature_name == 'cuda'
|
||||
feature_on = full_cuda
|
||||
elif feature_name == 'hip'
|
||||
feature_on = full_hip
|
||||
elif feature_name == 'cudss' or feature_name == 'amgx'
|
||||
feature_on = full_cuda
|
||||
elif feature_name == 'magma'
|
||||
feature_on = full_cuda or full_hip
|
||||
elif feature_name == 'simd'
|
||||
feature_on = simd_arch_supported and not is_wasm
|
||||
elif feature_name == 'enzyme'
|
||||
feature_on = cpp.get_id() == 'clang' and not full_cuda
|
||||
elif feature_name in ['benchmark', 'parelag', 'tribol']
|
||||
feature_on = false
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
if (
|
||||
feature_opt.auto() and get_option('mfem_precision') == 'single' and
|
||||
feature_name in single_precision_conflicts
|
||||
)
|
||||
feature_on = false
|
||||
endif
|
||||
|
||||
if (
|
||||
feature_on and
|
||||
feature_name not in ['cuda', 'hip', 'openmp', 'simd'] and
|
||||
not effective_allow_preinstalled and dependency_prefix == '' and
|
||||
not source_capable.get(feature_name, false)
|
||||
)
|
||||
error(
|
||||
'Selected feature mfem_' + feature_name + ' has no bundled source provider. ' +
|
||||
'Supply -Ddependency_prefix=/path/to/a/hermetic/prefix or enable preinstalled dependencies.'
|
||||
)
|
||||
endif
|
||||
mfem_features += {feature_name: feature_on}
|
||||
mfem_feature_states += [feature_on]
|
||||
endforeach
|
||||
|
||||
foreach build_only_feature : ['benchmark', 'parelag', 'tribol']
|
||||
if get_option('mfem_' + build_only_feature).enabled()
|
||||
error(
|
||||
'mfem_' + build_only_feature + ' is an upstream non-installed ' +
|
||||
'benchmark/miniapp build switch, not an MFEM library capability. ' +
|
||||
'Build that program in a separate consumer project against this SDK.'
|
||||
)
|
||||
endif
|
||||
endforeach
|
||||
|
||||
mfem_has_mpi = mfem_features.get('mpi')
|
||||
mfem_has_metis = mfem_features.get('metis')
|
||||
mfem_has_cuda = mfem_features.get('cuda')
|
||||
mfem_has_hip = mfem_features.get('hip')
|
||||
mfem_has_openmp = mfem_features.get('openmp')
|
||||
mfem_has_gslib = mfem_features.get('gslib')
|
||||
mfem_has_zlib = mfem_features.get('zlib')
|
||||
mfem_has_sundials = mfem_features.get('sundials')
|
||||
|
||||
if get_option('mfem_mpi').enabled() and not can_build_posix_mpi and not allow_preinstalled and dependency_prefix == ''
|
||||
error('The bundled MPI provider needs a native POSIX build. For cross/Windows builds, provide an MPI prefix or use -Dmfem_mpi=disabled.')
|
||||
endif
|
||||
if get_option('mfem_cuda').enabled() and not source_capable.get('cuda')
|
||||
error('CUDA was forced on, but nvcc and a supported non-macOS CUDA host were not found.')
|
||||
endif
|
||||
if get_option('mfem_hip').enabled() and not source_capable.get('hip')
|
||||
error('HIP was forced on, but hipcc was not found.')
|
||||
endif
|
||||
if get_option('mfem_openmp').enabled() and not usable_openmp
|
||||
error('OpenMP was forced on, but no permitted OpenMP runtime was found for the selected compiler.')
|
||||
endif
|
||||
if get_option('mfem_simd').enabled() and not simd_arch_supported
|
||||
error('SIMD was forced on, but MFEM has no intrinsic specialization for this target/compiler.')
|
||||
endif
|
||||
if get_option('mfem_enzyme').enabled() and cpp.get_id() != 'clang'
|
||||
error('Enzyme was forced on, but Enzyme requires a matching Clang/LLVM compiler toolchain.')
|
||||
endif
|
||||
if mfem_has_cuda and mfem_has_hip
|
||||
error('MFEM CUDA and HIP backends are mutually exclusive.')
|
||||
endif
|
||||
if mfem_features.get('enzyme') and mfem_has_cuda
|
||||
error('The bundled CUDA route uses nvcc and cannot be combined with Enzyme; use a dedicated clang-CUDA toolchain or disable one feature.')
|
||||
endif
|
||||
if mfem_features.get('cudss') and not mfem_has_cuda
|
||||
error('cuDSS requires -Dmfem_cuda=enabled (or an auto-detected CUDA toolkit).')
|
||||
endif
|
||||
if mfem_features.get('amgx') and not mfem_has_cuda
|
||||
error('AmgX requires the CUDA backend.')
|
||||
endif
|
||||
if mfem_features.get('magma') and not (mfem_has_cuda or mfem_has_hip)
|
||||
error('MAGMA requires either the CUDA or HIP backend.')
|
||||
endif
|
||||
if mfem_features.get('slepc') and not mfem_features.get('petsc')
|
||||
error('SLEPc requires PETSc.')
|
||||
endif
|
||||
if mfem_features.get('adforward') and not mfem_features.get('codipack')
|
||||
error('Forward-mode automatic differentiation requires CoDiPack.')
|
||||
endif
|
||||
if mfem_features.get('superlu5') and not mfem_features.get('superlu')
|
||||
error('The SuperLU 5 compatibility option requires SuperLU_DIST.')
|
||||
endif
|
||||
if mfem_features.get('simmetrix') and not mfem_features.get('pumi')
|
||||
error('Simmetrix integration requires PUMI.')
|
||||
endif
|
||||
foreach mpi_feature : ['superlu', 'mumps', 'strumpack', 'petsc', 'slepc', 'pumi', 'mkl_cpardiso', 'tribol']
|
||||
if mfem_features.get(mpi_feature) and not mfem_has_mpi
|
||||
error('MFEM feature ' + mpi_feature + ' requires MPI/Hypre.')
|
||||
endif
|
||||
endforeach
|
||||
if mfem_features.get('legacy_openmp') and (
|
||||
mfem_has_openmp or mfem_has_cuda or mfem_features.get('raja') or mfem_features.get('occa'))
|
||||
error('Legacy OpenMP cannot be combined with OpenMP, CUDA, RAJA, or OCCA.')
|
||||
endif
|
||||
if mfem_features.get('legacy_openmp') and not mfem_features.get('thread_safe')
|
||||
error('Legacy OpenMP requires MFEM thread-safe mode.')
|
||||
endif
|
||||
|
||||
if get_option('mfem_precision') == 'single'
|
||||
foreach single_conflict : single_precision_conflicts
|
||||
if mfem_features.get(single_conflict)
|
||||
error('Single precision is incompatible with MFEM feature ' + single_conflict + '.')
|
||||
endif
|
||||
endforeach
|
||||
endif
|
||||
mfem_consumer_cpp_std = (
|
||||
mfem_features.get('raja') or mfem_features.get('umpire')
|
||||
) ? 'c++20' : 'c++17'
|
||||
system_mfem = disabler()
|
||||
mfem_provider = 'source bundle'
|
||||
if effective_allow_preinstalled
|
||||
system_candidate = dependency('mfem', version: '>=4.10', required: false, allow_fallback: false)
|
||||
if system_candidate.found()
|
||||
system_compatible = true
|
||||
foreach i : range(mfem_feature_names.length())
|
||||
if mfem_feature_states[i]
|
||||
feature_macro = mfem_cmake_names[i]
|
||||
macro_ok = cpp.compiles(
|
||||
'#include <mfem/config/config.hpp>\n#ifndef ' + feature_macro + '\n#error missing\n#endif\nint main(){return 0;}',
|
||||
dependencies: system_candidate,
|
||||
name: 'system MFEM provides ' + feature_macro,
|
||||
)
|
||||
system_compatible = system_compatible and macro_ok
|
||||
endif
|
||||
endforeach
|
||||
precision_macro = get_option('mfem_precision') == 'single' ? 'MFEM_USE_SINGLE' : 'MFEM_USE_DOUBLE'
|
||||
system_compatible = system_compatible and cpp.compiles(
|
||||
'#include <mfem/config/config.hpp>\n#ifndef ' + precision_macro + '\n#error precision mismatch\n#endif\nint main(){return 0;}',
|
||||
dependencies: system_candidate,
|
||||
name: 'system MFEM uses requested precision',
|
||||
)
|
||||
foreach i : range(mfem_feature_names.length())
|
||||
feature_opt = get_option('mfem_' + mfem_feature_names[i])
|
||||
feature_macro = mfem_cmake_names[i]
|
||||
if feature_opt.disabled()
|
||||
macro_absent = cpp.compiles(
|
||||
'#include <mfem/config/config.hpp>\n#ifdef ' + feature_macro + '\n#error explicitly disabled\n#endif\nint main(){return 0;}',
|
||||
dependencies: system_candidate,
|
||||
name: 'system MFEM omits disabled ' + feature_macro,
|
||||
)
|
||||
system_compatible = system_compatible and macro_absent
|
||||
endif
|
||||
endforeach
|
||||
if system_compatible
|
||||
system_mfem = system_candidate
|
||||
mfem_provider = 'system'
|
||||
else
|
||||
message('The system MFEM does not satisfy the selected feature set; using the pinned source bundle.')
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
uses_unmodelled_system_tpl = false
|
||||
foreach feature_name : mfem_feature_names
|
||||
if (
|
||||
mfem_features.get(feature_name) and feature_name != 'openmp' and
|
||||
not source_capable.get(feature_name, false)
|
||||
)
|
||||
uses_unmodelled_system_tpl = true
|
||||
endif
|
||||
endforeach
|
||||
if (
|
||||
not system_mfem.found() and effective_allow_preinstalled and
|
||||
dependency_prefix == '' and uses_unmodelled_system_tpl
|
||||
)
|
||||
error(
|
||||
'The selected features need external TPLs, but no complete compatible system MFEM was found. ' +
|
||||
'Provide one coherent -Ddependency_prefix=/path/to/tpls so the source MFEM usage interface remains reproducible.'
|
||||
)
|
||||
endif
|
||||
|
||||
if not system_mfem.found() and is_windows
|
||||
error(
|
||||
'The source fallback currently targets POSIX and Emscripten toolchains. ' +
|
||||
'On Windows, provide a complete compatible MFEM installation and use -Dallow_preinstalled=true.'
|
||||
)
|
||||
endif
|
||||
|
||||
mfem_runtime_prefix = ''
|
||||
mfem_build_target = []
|
||||
mpi_launcher_from_dependency = false
|
||||
|
||||
if system_mfem.found()
|
||||
mfem_dep = system_mfem
|
||||
else
|
||||
mfem_source = subproject('mfem').get_variable('mfem_source_dir')
|
||||
|
||||
mpich_source = ''
|
||||
hypre_source = ''
|
||||
metis_source = ''
|
||||
gslib_source = ''
|
||||
zlib_source = ''
|
||||
sundials_source = ''
|
||||
libceed_source = ''
|
||||
fms_source = ''
|
||||
algoim_source = ''
|
||||
blitz_source = ''
|
||||
|
||||
dependency_has_mpi = dependency_prefix != '' and (
|
||||
fs.exists(dependency_prefix / 'bin' / 'mpicc') and
|
||||
fs.exists(dependency_prefix / 'bin' / 'mpicxx')
|
||||
)
|
||||
dependency_has_hypre = dependency_prefix != '' and fs.exists(
|
||||
dependency_prefix / 'include' / 'HYPRE_config.h'
|
||||
)
|
||||
dependency_has_metis = dependency_prefix != '' and fs.exists(
|
||||
dependency_prefix / 'include' / 'metis.h'
|
||||
)
|
||||
dependency_has_gslib = dependency_prefix != '' and fs.exists(
|
||||
dependency_prefix / 'include' / 'gslib' / 'gslib.h'
|
||||
)
|
||||
dependency_has_zlib = dependency_prefix != '' and fs.exists(
|
||||
dependency_prefix / 'include' / 'zlib.h'
|
||||
)
|
||||
dependency_has_sundials = dependency_prefix != '' and fs.exists(
|
||||
dependency_prefix / 'include' / 'sundials' / 'sundials_config.h'
|
||||
)
|
||||
dependency_has_ceed = dependency_prefix != '' and fs.exists(
|
||||
dependency_prefix / 'include' / 'ceed.h'
|
||||
)
|
||||
dependency_has_fms = dependency_prefix != '' and fs.exists(
|
||||
dependency_prefix / 'include' / 'fms.h'
|
||||
)
|
||||
dependency_has_algoim = dependency_prefix != '' and fs.exists(
|
||||
dependency_prefix / 'include' / 'algoim_quad.hpp'
|
||||
) and fs.exists(dependency_prefix / 'include' / 'blitz' / 'array.h')
|
||||
|
||||
build_mpi_from_source = mfem_has_mpi and can_build_posix_mpi and not dependency_has_mpi
|
||||
mpi_launcher_from_dependency = mfem_has_mpi and dependency_has_mpi
|
||||
if build_mpi_from_source
|
||||
mpich_source = subproject('mpich').get_variable('mpich_source_dir')
|
||||
endif
|
||||
if mfem_has_mpi and (build_mpi_from_source or not dependency_has_hypre)
|
||||
hypre_source = subproject('hypre').get_variable('hypre_source_dir')
|
||||
endif
|
||||
if mfem_has_metis and not dependency_has_metis
|
||||
metis_source = subproject('metis').get_variable('metis_source_dir')
|
||||
endif
|
||||
if mfem_has_gslib and (build_mpi_from_source or not dependency_has_gslib)
|
||||
gslib_source = subproject('gslib').get_variable('gslib_source_dir')
|
||||
endif
|
||||
if mfem_has_zlib and not dependency_has_zlib
|
||||
zlib_source = subproject('zlib').get_variable('zlib_source_dir')
|
||||
endif
|
||||
if mfem_has_sundials and (build_mpi_from_source or not dependency_has_sundials)
|
||||
sundials_source = subproject('sundials').get_variable('sundials_source_dir')
|
||||
endif
|
||||
if mfem_features.get('ceed') and not dependency_has_ceed
|
||||
libceed_source = subproject('libceed').get_variable('libceed_source_dir')
|
||||
endif
|
||||
if mfem_features.get('fms') and not dependency_has_fms
|
||||
fms_source = subproject('fms').get_variable('fms_source_dir')
|
||||
endif
|
||||
if mfem_features.get('algoim') and not dependency_has_algoim
|
||||
algoim_source = subproject('algoim').get_variable('algoim_source_dir')
|
||||
blitz_source = subproject('blitz').get_variable('blitz_source_dir')
|
||||
endif
|
||||
|
||||
bundle_is_python_package = get_option('build_python') and get_option('python_install_native')
|
||||
bundle_output_name = bundle_is_python_package ? 'meson_mfem_template' : 'mfem-prefix'
|
||||
mfem_runtime_prefix = meson.current_build_dir() / bundle_output_name
|
||||
bundle_work_dir = meson.current_build_dir() / '_bundle' / 'work'
|
||||
bundle_builder = files('../../tools/build_mfem_bundle.py')
|
||||
bundle_auxiliary_files = files('../../tools/ceed_jit_source_root_relocatable.c')
|
||||
cc_command = cc.cmd_array()
|
||||
cxx_command = cpp.cmd_array()
|
||||
known_compiler_launchers = ['ccache', 'sccache', 'distcc']
|
||||
cc_executable = ''
|
||||
cc_launchers = []
|
||||
cc_fixed_args = []
|
||||
foreach command_part : cc_command
|
||||
if cc_executable == '' and fs.name(command_part) in known_compiler_launchers
|
||||
cc_launchers += [command_part]
|
||||
elif cc_executable == ''
|
||||
cc_executable = command_part
|
||||
else
|
||||
cc_fixed_args += [command_part]
|
||||
endif
|
||||
endforeach
|
||||
cxx_executable = ''
|
||||
cxx_launchers = []
|
||||
cxx_fixed_args = []
|
||||
foreach command_part : cxx_command
|
||||
if cxx_executable == '' and fs.name(command_part) in known_compiler_launchers
|
||||
cxx_launchers += [command_part]
|
||||
elif cxx_executable == ''
|
||||
cxx_executable = command_part
|
||||
else
|
||||
cxx_fixed_args += [command_part]
|
||||
endif
|
||||
endforeach
|
||||
if cc_executable == '' or cxx_executable == ''
|
||||
error('Could not identify the C/C++ compiler executables in Meson compiler commands.')
|
||||
endif
|
||||
bundle_command = [
|
||||
python_build,
|
||||
bundle_builder,
|
||||
'--source', mfem_source,
|
||||
'--work-dir', bundle_work_dir,
|
||||
'--prefix', '@OUTPUT@',
|
||||
'--cmake', cmake_program,
|
||||
'--cc', cc_executable,
|
||||
'--cxx', cxx_executable,
|
||||
'--buildtype', get_option('buildtype'),
|
||||
'--jobs', get_option('jobs').to_string(),
|
||||
'--host-system', host_machine.system(),
|
||||
'--cross-build', meson.is_cross_build() ? 'true' : 'false',
|
||||
'--library-kind', is_wasm ? 'static' : 'shared',
|
||||
'--cuda-arch', get_option('mfem_cuda_arch'),
|
||||
'--hip-arch', get_option('mfem_hip_arch'),
|
||||
'--precision', get_option('mfem_precision'),
|
||||
'--dependency-prefix', dependency_prefix,
|
||||
'--allow-system', effective_allow_preinstalled ? 'true' : 'false',
|
||||
'--vendor-dependency-prefix', wheel_carries_native_bundle ? 'true' : 'false',
|
||||
]
|
||||
foreach compiler_launcher : cc_launchers
|
||||
bundle_command += ['--cc-launcher=' + compiler_launcher]
|
||||
endforeach
|
||||
foreach compiler_launcher : cxx_launchers
|
||||
bundle_command += ['--cxx-launcher=' + compiler_launcher]
|
||||
endforeach
|
||||
foreach c_arg : cc_fixed_args
|
||||
bundle_command += ['--c-arg=' + c_arg]
|
||||
endforeach
|
||||
foreach c_arg : get_option('c_args')
|
||||
bundle_command += ['--c-arg=' + c_arg]
|
||||
endforeach
|
||||
foreach c_arg : platform_c_args
|
||||
bundle_command += ['--c-arg=' + c_arg]
|
||||
endforeach
|
||||
foreach cpp_arg : get_option('cpp_args')
|
||||
bundle_command += ['--cxx-arg=' + cpp_arg]
|
||||
endforeach
|
||||
foreach cpp_arg : cxx_fixed_args
|
||||
bundle_command += ['--cxx-arg=' + cpp_arg]
|
||||
endforeach
|
||||
foreach cpp_arg : platform_cpp_args
|
||||
bundle_command += ['--cxx-arg=' + cpp_arg]
|
||||
endforeach
|
||||
foreach c_link_arg : get_option('c_link_args')
|
||||
bundle_command += ['--c-link-arg=' + c_link_arg]
|
||||
endforeach
|
||||
foreach cpp_link_arg : get_option('cpp_link_args')
|
||||
bundle_command += ['--cxx-link-arg=' + cpp_link_arg]
|
||||
endforeach
|
||||
foreach platform_link_arg : platform_link_args
|
||||
bundle_command += ['--c-link-arg=' + platform_link_arg]
|
||||
bundle_command += ['--cxx-link-arg=' + platform_link_arg]
|
||||
endforeach
|
||||
foreach i : range(mfem_feature_names.length())
|
||||
bundle_command += [
|
||||
'--feature',
|
||||
mfem_feature_names[i] + '=' + (mfem_feature_states[i] ? 'ON' : 'OFF'),
|
||||
]
|
||||
endforeach
|
||||
foreach source_pair : [
|
||||
['mpich', mpich_source],
|
||||
['hypre', hypre_source],
|
||||
['metis', metis_source],
|
||||
['gslib', gslib_source],
|
||||
['zlib', zlib_source],
|
||||
['sundials', sundials_source],
|
||||
['libceed', libceed_source],
|
||||
['fms', fms_source],
|
||||
['algoim', algoim_source],
|
||||
['blitz', blitz_source],
|
||||
]
|
||||
if source_pair[1] != ''
|
||||
bundle_command += ['--' + source_pair[0] + '-source', source_pair[1]]
|
||||
endif
|
||||
endforeach
|
||||
|
||||
if bundle_is_python_package and get_option('install_mfem')
|
||||
mfem_build_target = custom_target(
|
||||
'mfem-source-bundle',
|
||||
output: bundle_output_name,
|
||||
command: bundle_command,
|
||||
depend_files: bundle_auxiliary_files,
|
||||
build_by_default: true,
|
||||
build_always_stale: dependency_prefix != '',
|
||||
console: true,
|
||||
install: true,
|
||||
install_dir: python_build.get_install_dir(),
|
||||
install_tag: 'python-native',
|
||||
)
|
||||
else
|
||||
mfem_build_target = custom_target(
|
||||
'mfem-source-bundle',
|
||||
output: bundle_output_name,
|
||||
command: bundle_command,
|
||||
depend_files: bundle_auxiliary_files,
|
||||
build_by_default: true,
|
||||
build_always_stale: dependency_prefix != '',
|
||||
console: true,
|
||||
)
|
||||
endif
|
||||
|
||||
bundle_compile_args = ['-I' + mfem_runtime_prefix / 'include']
|
||||
bundle_link_args = [
|
||||
'-L' + mfem_runtime_prefix / 'lib',
|
||||
'-L' + mfem_runtime_prefix / 'lib64',
|
||||
]
|
||||
if dependency_prefix != '' and not wheel_carries_native_bundle
|
||||
bundle_compile_args += ['-I' + dependency_prefix / 'include']
|
||||
bundle_link_args += [
|
||||
'-L' + dependency_prefix / 'lib',
|
||||
'-L' + dependency_prefix / 'lib64',
|
||||
]
|
||||
endif
|
||||
bundle_link_args += ['-lmfem']
|
||||
if mfem_has_mpi
|
||||
bundle_link_args += ['-lHYPRE', '-lmpi']
|
||||
endif
|
||||
if mfem_has_metis
|
||||
bundle_link_args += ['-lmetis']
|
||||
endif
|
||||
if mfem_has_gslib
|
||||
bundle_link_args += ['-lgs']
|
||||
endif
|
||||
if mfem_has_zlib
|
||||
bundle_link_args += ['-lz']
|
||||
endif
|
||||
if mfem_has_sundials
|
||||
bundle_link_args += [
|
||||
'-lsundials_nvecserial',
|
||||
'-lsundials_cvodes',
|
||||
'-lsundials_arkode',
|
||||
'-lsundials_kinsol',
|
||||
'-lsundials_core',
|
||||
]
|
||||
if mfem_has_mpi
|
||||
bundle_link_args += [
|
||||
'-lsundials_nvecparallel',
|
||||
'-lsundials_nvecmpiplusx',
|
||||
]
|
||||
endif
|
||||
endif
|
||||
if mfem_features.get('ceed')
|
||||
bundle_link_args += ['-lceed']
|
||||
endif
|
||||
if mfem_features.get('fms')
|
||||
bundle_link_args += ['-lfms']
|
||||
endif
|
||||
if mfem_features.get('algoim')
|
||||
bundle_link_args += ['-lblitz']
|
||||
endif
|
||||
|
||||
mfem_dep_parts = []
|
||||
if mfem_has_openmp or mfem_features.get('legacy_openmp')
|
||||
mfem_dep_parts += [openmp_dep]
|
||||
endif
|
||||
mfem_dep = declare_dependency(
|
||||
compile_args: bundle_compile_args,
|
||||
link_args: bundle_link_args,
|
||||
dependencies: mfem_dep_parts,
|
||||
sources: mfem_build_target,
|
||||
version: '4.10',
|
||||
variables: {
|
||||
'prefix': mfem_runtime_prefix,
|
||||
'includedir': mfem_runtime_prefix / 'include',
|
||||
'libdir': mfem_runtime_prefix / 'lib',
|
||||
},
|
||||
)
|
||||
|
||||
if get_option('install_mfem') and not bundle_is_python_package
|
||||
install_bundle = files('../../tools/install_bundle.py')
|
||||
meson.add_install_script(
|
||||
python_build,
|
||||
install_bundle,
|
||||
'--source', mfem_runtime_prefix,
|
||||
'--destination', get_option('prefix'),
|
||||
install_tag: 'runtime',
|
||||
)
|
||||
endif
|
||||
endif
|
||||
|
||||
if get_option('build_python') and not get_option('python_install_native') and not system_mfem.found()
|
||||
error('A source-built Python extension requires -Dpython_install_native=true so its runtime libraries are included in the wheel.')
|
||||
endif
|
||||
if get_option('build_python') and get_option('python_install_native') and not get_option('install_mfem')
|
||||
error('A self-contained Python wheel requires -Dinstall_mfem=true so the native bundle is installed.')
|
||||
endif
|
||||
|
||||
meson.override_dependency('mfem', mfem_dep)
|
||||
Reference in New Issue
Block a user