build(meson): much more robust build system

This commit is contained in:
2026-06-10 14:28:55 -04:00
parent 1c975a873d
commit d6fff3cdbe
33 changed files with 571 additions and 360 deletions

View File

@@ -1,13 +1,12 @@
cppad_cmake_options = cmake.subproject_options()
cppad_cmake_options.add_cmake_defines({
'cppad_static_lib': 'true',
'cpp_mas_num_threads': '10',
'cppad_debug_and_release': 'false',
'include_doc': 'false',
'CMAKE_POSITION_INDEPENDENT_CODE': true
})
'cppad_static_lib': 'true',
'cpp_mas_num_threads': '10',
'cppad_debug_and_release': 'false',
'include_doc': 'false',
'CMAKE_POSITION_INDEPENDENT_CODE': true
})
cppad_cmake_options.set_install(false)
cppad_sp = cmake.subproject(
@@ -22,22 +21,28 @@ cppad_incs = cppad_sp.include_directories('cppad_lib')
empty_cppad_file = configure_file(output: 'cppad_dummy_ar.cpp', command: ['echo'], capture: true)
libcppad_static = static_library(
'cppad-static',
empty_cppad_file,
objects: cppad_objs,
include_directories: cppad_incs,
pic: true,
install: false
'cppad-static',
empty_cppad_file,
objects: cppad_objs,
include_directories: cppad_incs,
pic: true,
install: false
)
cppad_dep = declare_dependency(
link_with: libcppad_static,
include_directories: cppad_incs
include_directories: cppad_incs
)
message('Installing CppAD headers to ' + get_option('includedir'))
install_subdir(
'subprojects/CppAD-20250000.2/include',
install_dir: get_option('includedir'),
strip_directory: true
)
message('Staging vendored CppAD headers for ' + gridfire_vendor_includedir)
custom_target(
'vendor_cppad_headers',
command: copytree_cmd + [
meson.project_source_root() / 'subprojects' / 'CppAD-20250000.2' / 'include' / 'cppad',
'@OUTPUT@',
],
output: 'cppad',
depends: libcppad_static,
install: true,
install_dir: gridfire_vendor_includedir,
)

View File

@@ -1,5 +1,13 @@
eigen_dep = dependency(
'eigen3',
version : '>=3.3',
fallback : ['eigen', 'eigen_dep']
).as_system()
eigen_sp = subproject('eigen')
eigen_dep = eigen_sp.get_variable('eigen_dep').as_system()
custom_target(
'vendor_eigen_headers',
command: copytree_cmd + [
meson.project_source_root() / 'subprojects' / 'eigen-3.4.0' / 'Eigen',
'@OUTPUT@',
],
output: 'Eigen',
install: true,
install_dir: gridfire_vendor_includedir,
)

View File

@@ -1,23 +1,25 @@
# bring in all of the fourdst utility repositories
fourdst_build_lib_all = true
if not get_option('plugin_support')
fourdst_build_lib_all=false
message('Disabling fourdst plugin support as per user request.')
endif
fourdst_sp = subproject('fourdst',
default_options:
['build_tests=' + get_option('build_tests').to_string(),
'build_python=' + get_option('build_python').to_string(),
'build_lib_all=' + fourdst_build_lib_all.to_string(),
'build_lib_comp=true',
'build_lib_config=true',
'build_lib_log=true',
'build_lib_const=true',
'pkg_config=' + get_option('pkg_config').to_string(),
]
)
fourdst_default_options = [
'build_tests=' + get_option('build_tests').to_string(),
'build_python=' + get_option('build_python').to_string(),
'build_lib_all=' + fourdst_build_lib_all.to_string(),
'build_lib_comp=true',
'build_lib_config=true',
'build_lib_log=true',
'build_lib_const=true',
'pkg_config=' + get_option('pkg_config').to_string(),
]
if get_option('build_python')
fourdst_default_options += ['default_library=static']
endif
fourdst_sp = subproject('fourdst', default_options: fourdst_default_options)
composition_dep = fourdst_sp.get_variable('composition_dep')
log_dep = fourdst_sp.get_variable('log_dep')
@@ -36,3 +38,45 @@ if get_option('plugin_support')
warning('Including plugin library from fourdst. Note this will bring in minizip-ng and openssl, which can cause build issues with cross compilation due to their complexity.')
libplugin = fourdst_sp.get_variable('libplugin')
endif
if get_option('build_python')
sp_root = meson.project_source_root() / 'subprojects'
fourdst_header_trees = [
['config',
sp_root / 'libconfig' / 'src' / 'config' / 'include' / 'fourdst' / 'config',
gridfire_includedir / 'fourdst'],
['composition',
sp_root / 'libcomposition' / 'src' / 'composition' / 'include' / 'fourdst' / 'composition',
gridfire_includedir / 'fourdst'],
['atomic',
sp_root / 'libcomposition' / 'src' / 'composition' / 'include' / 'fourdst' / 'atomic',
gridfire_includedir / 'fourdst'],
['constants',
sp_root / 'libconstants' / 'src' / 'constants' / 'include' / 'fourdst' / 'constants',
gridfire_includedir / 'fourdst'],
['logging',
sp_root / 'liblogging' / 'src' / 'logging' / 'include' / 'fourdst' / 'logging',
gridfire_includedir / 'fourdst'],
['toml++',
sp_root / 'libconfig' / 'build-config' / 'tomlpp' / 'vendor' / 'include' / 'toml++',
gridfire_fourdst_vendor_includedir],
['quill',
sp_root / 'quill' / 'include' / 'quill',
gridfire_fourdst_vendor_includedir],
['CLI',
sp_root / 'CLI11-2.6.1' / 'include' / 'CLI',
gridfire_fourdst_vendor_includedir],
]
foreach t : fourdst_header_trees
custom_target(
'wheel_headers_' + t[0].underscorify(),
command: copytree_cmd + [t[1], '@OUTPUT@'],
output: t[0],
install: true,
install_dir: t[2],
)
endforeach
endif

View File

@@ -1,3 +1,9 @@
json_dep = declare_dependency(
include_directories: include_directories('include')
)
install_subdir(
'include',
install_dir: gridfire_vendor_includedir,
strip_directory: true,
)

View File

@@ -4,6 +4,41 @@ if get_option('build_python')
subdir('python')
subdir('pybind')
endif
if get_option('build_python')
gridfire_pkg_dir = py_installation.get_install_dir() / 'gridfire'
gridfire_includedir = gridfire_pkg_dir / 'include'
gridfire_libdir = gridfire_pkg_dir / 'lib'
gridfire_pcdir = gridfire_libdir / 'pkgconfig'
else
gridfire_includedir = get_option('includedir')
gridfire_libdir = get_option('libdir')
gridfire_pcdir = get_option('libdir') / 'pkgconfig'
endif
gridfire_vendor_includedir = gridfire_includedir / 'gridfire' / 'vendor'
gridfire_fourdst_vendor_includedir = gridfire_includedir / 'fourdst' / 'vendor'
vendor_py = import('python').find_installation('python3')
copytree_cmd = [
vendor_py, '-c',
'''import sys, os, stat, shutil
src, dst = sys.argv[1], sys.argv[2]
shutil.rmtree(dst, ignore_errors=True)
shutil.copytree(src, dst)
for root, dirs, files in os.walk(dst):
os.chmod(root, 0o755)
for f in files:
p = os.path.join(root, f)
os.chmod(p, os.stat(p).st_mode | 0o644)
''',
]
copyfiles_cmd = [
vendor_py, '-c',
'import sys, shutil; [shutil.copy2(p, sys.argv[-1]) for p in sys.argv[1:-1]]',
]
subdir('fourdst')
subdir('sundials')
@@ -14,7 +49,6 @@ subdir('eigen')
subdir('json')
subdir('CLI11')
subdir('unordered_dense')
if get_option('use_mimalloc')
subdir('mimalloc')

View File

@@ -1,8 +1,7 @@
py_installation = import('python').find_installation('python3', pure: false)
if meson.is_cross_build() and host_machine.system() == 'darwin'
py_ver = get_option('python-target-version')
py_ver = get_option('python_target_version')
message('Cross build on Darwin, using python version ' + py_ver)
py_inc_dir = include_directories('../../cross/python_includes/python-' + py_ver + '/include/python' + py_ver)
py_dep = declare_dependency(include_directories: py_inc_dir)

View File

@@ -1,32 +1,34 @@
cmake = import('cmake')
cvode_cmake_options = cmake.subproject_options()
cvode_cmake_options.add_cmake_defines({
'CMAKE_CXX_FLAGS' : '-Wno-deprecated-declarations',
'CMAKE_C_FLAGS' : '-Wno-deprecated-declarations',
'BUILD_SHARED_LIBS' : 'OFF',
'BUILD_STATIC_LIBS' : 'ON',
'EXAMPLES_ENABLE_C' : 'OFF',
'CMAKE_POSITION_INDEPENDENT_CODE': true,
'CMAKE_PLATFORM_NO_VERSIONED_SONAME': 'ON',
'SUNDIALS_LOGGING_LEVEL': 1
})
sundials_hidden_flags = '-Wno-deprecated-declarations -fvisibility=hidden -fvisibility-inlines-hidden'
cvode_cmake_options.add_cmake_defines({
'CMAKE_INSTALL_LIBDIR': get_option('libdir'),
'CMAKE_INSTALL_INCLUDEDIR': get_option('includedir')
})
'CMAKE_CXX_FLAGS' : sundials_hidden_flags,
'CMAKE_C_FLAGS' : sundials_hidden_flags,
'BUILD_SHARED_LIBS' : 'OFF',
'BUILD_STATIC_LIBS' : 'ON',
'EXAMPLES_ENABLE_C' : 'OFF',
'CMAKE_POSITION_INDEPENDENT_CODE': true,
'CMAKE_PLATFORM_NO_VERSIONED_SONAME': 'ON',
'SUNDIALS_LOGGING_LEVEL': 1
})
cvode_cmake_options.add_cmake_defines({
'CMAKE_INSTALL_LIBDIR': get_option('libdir'),
'CMAKE_INSTALL_INCLUDEDIR': get_option('includedir')
})
cvode_cmake_options.set_install(false)
if meson.is_cross_build() and host_machine.system() == 'emscripten'
cvode_cmake_options.add_cmake_defines({
'CMAKE_C_FLAGS': '-s MEMORY64=1 -s ALLOW_MEMORY_GROWTH=1',
'CMAKE_CXX_FLAGS': '-s MEMORY64=1 -s ALLOW_MEMORY_GROWTH=1',
'CMAKE_SHARED_LINKER_FLAGS': '-s MEMORY64=1 -s ALLOW_MEMORY_GROWTH=1',
'CMAKE_EXE_LINKER_FLAGS': '-s MEMORY64=1 -s ALLOW_MEMORY_GROWTH=1'
})
cvode_cmake_options.add_cmake_defines({
'CMAKE_C_FLAGS': '-s MEMORY64=1 -s ALLOW_MEMORY_GROWTH=1',
'CMAKE_CXX_FLAGS': '-s MEMORY64=1 -s ALLOW_MEMORY_GROWTH=1',
'CMAKE_SHARED_LINKER_FLAGS': '-s MEMORY64=1 -s ALLOW_MEMORY_GROWTH=1',
'CMAKE_EXE_LINKER_FLAGS': '-s MEMORY64=1 -s ALLOW_MEMORY_GROWTH=1'
})
endif
cvode_sp = cmake.subproject(
@@ -41,11 +43,11 @@ sundials_sunmatrixdense_tgt = cvode_sp.target('sundials_sunmatrixdense_static')
sundials_sunlinsoldense_tgt = cvode_sp.target('sundials_sunlinsoldense_static')
cvode_objs = [
sundials_core_tgt.extract_all_objects(recursive: true),
sundials_cvode_tgt.extract_all_objects(recursive: true),
sundials_nvecserial_tgt.extract_all_objects(recursive: true),
sundials_sunmatrixdense_tgt.extract_all_objects(recursive: true),
sundials_sunlinsoldense_tgt.extract_all_objects(recursive: true),
sundials_core_tgt.extract_all_objects(recursive: true),
sundials_cvode_tgt.extract_all_objects(recursive: true),
sundials_nvecserial_tgt.extract_all_objects(recursive: true),
sundials_sunmatrixdense_tgt.extract_all_objects(recursive: true),
sundials_sunlinsoldense_tgt.extract_all_objects(recursive: true),
]
sundials_core_includes = cvode_sp.include_directories('sundials_core_static')
@@ -55,35 +57,29 @@ sundials_sunmatrixdense_includes = cvode_sp.include_directories('sundials_sunmat
sundials_sunlinsoldense_includes = cvode_sp.include_directories('sundials_sunlinsoldense_static')
cvode_includes = [
sundials_core_includes,
sundials_cvode_includes,
sundials_nvecserial_includes,
sundials_sunmatrixdense_includes,
sundials_sunlinsoldense_includes
sundials_core_includes,
sundials_cvode_includes,
sundials_nvecserial_includes,
sundials_sunmatrixdense_includes,
sundials_sunlinsoldense_includes
]
empty_cvode_file = configure_file(
output: 'cvode_dummy_ar.cpp',
command: ['echo'],
capture: true
)
output: 'cvode_dummy_ar.cpp',
command: ['echo'],
capture: true
)
libcvode_static = static_library(
'cvode-static',
empty_cvode_file,
objects: cvode_objs,
include_directories: cvode_includes,
pic: true,
install: false
'cvode-static',
empty_cvode_file,
objects: cvode_objs,
include_directories: cvode_includes,
pic: true,
install: false
)
cvode_dep = declare_dependency(
link_with: libcvode_static,
include_directories: cvode_includes,
include_directories: cvode_includes,
)

View File

@@ -3,20 +3,20 @@ cmake = import('cmake')
kinsol_cmake_options = cmake.subproject_options()
kinsol_cmake_options.add_cmake_defines({
'CMAKE_CXX_FLAGS' : '-Wno-deprecated-declarations',
'CMAKE_C_FLAGS' : '-Wno-deprecated-declarations',
'BUILD_SHARED_LIBS' : 'OFF',
'BUILD_STATIC_LIBS' : 'ON',
'EXAMPLES_ENABLE_C' : 'OFF',
'CMAKE_POSITION_INDEPENDENT_CODE': true,
'CMAKE_PLATFORM_NO_VERSIONED_SONAME': 'ON',
'SUNDIALS_LOGGING_LEVEL': 1
})
'CMAKE_CXX_FLAGS' : '-Wno-deprecated-declarations -fvisibility=hidden -fvisibility-inlines-hidden',
'CMAKE_C_FLAGS' : '-Wno-deprecated-declarations -fvisibility=hidden -fvisibility-inlines-hidden',
'BUILD_SHARED_LIBS' : 'OFF',
'BUILD_STATIC_LIBS' : 'ON',
'EXAMPLES_ENABLE_C' : 'OFF',
'CMAKE_POSITION_INDEPENDENT_CODE': true,
'CMAKE_PLATFORM_NO_VERSIONED_SONAME': 'ON',
'SUNDIALS_LOGGING_LEVEL': 1
})
kinsol_cmake_options.add_cmake_defines({
'CMAKE_INSTALL_LIBDIR': get_option('libdir'),
'CMAKE_INSTALL_INCLUDEDIR': get_option('includedir')
})
'CMAKE_INSTALL_LIBDIR': get_option('libdir'),
'CMAKE_INSTALL_INCLUDEDIR': get_option('includedir')
})
kinsol_cmake_options.set_install(false)
@@ -31,25 +31,22 @@ kinsol_includes = kinsol_sp.include_directories('sundials_kinsol_obj_static')
kinsol_objs = [sundials_kinsol_static_tgt.extract_all_objects(recursive: false)]
empty_kinsol_file = configure_file(
output: 'kinsol_dummy_ar.cpp',
command: ['echo'],
capture: true
)
output: 'kinsol_dummy_ar.cpp',
command: ['echo'],
capture: true
)
libkinsol_static = static_library(
'kinsol_static',
empty_kinsol_file,
objects: kinsol_objs,
include_directories: kinsol_includes,
pic: true,
install: false
'kinsol_static',
empty_kinsol_file,
objects: kinsol_objs,
include_directories: kinsol_includes,
pic: true,
install: false
)
kinsol_dep = declare_dependency(
link_with: libkinsol_static,
include_directories: kinsol_includes
include_directories: kinsol_includes
)

View File

@@ -7,3 +7,11 @@ sundials_dep = declare_dependency(
kinsol_dep,
],
)
# Vendor the SUNDIALS public headers (see vendor/meson.build). GridFire's
# installed public headers #include <sundials/...> etc., so consumers of
# gridfire.pc must compile against exactly the headers this build used --
# never whatever SUNDIALS happens to be in /usr/local/include (which may be
# a different version or configuration, e.g. an MPI-enabled build whose
# sundials_config.h pulls in <mpi.h>).
subdir('vendor')

View File

@@ -0,0 +1,46 @@
sundials_src_include = meson.project_source_root() / 'subprojects' / 'cvode-7.5.0' / 'include'
kinsol_src_include = meson.project_source_root() / 'subprojects' / 'kinsol-7.5.0' / 'include'
sundials_vendor_dirs = [
'sundials', # core (includes sundials/priv/)
'cvode',
'nvector',
'sunmatrix',
'sunlinsol',
'sunnonlinsol',
'sunmemory',
'sunadaptcontroller',
]
foreach d : sundials_vendor_dirs
custom_target(
'vendor_sundials_' + d,
command: copytree_cmd + [sundials_src_include / d, '@OUTPUT@'],
output: d,
install: true,
install_dir: gridfire_vendor_includedir,
)
endforeach
custom_target(
'vendor_sundials_kinsol',
command: copytree_cmd + [kinsol_src_include / 'kinsol', '@OUTPUT@'],
output: 'kinsol',
install: true,
install_dir: gridfire_vendor_includedir,
)
sundials_cmake_include = meson.global_build_root() / 'subprojects' / 'cvode-7.5.0' / '__CMake_build' / 'include' / 'sundials'
custom_target(
'vendor_sundials_generated',
command: copyfiles_cmd + [
sundials_cmake_include / 'sundials_config.h',
sundials_cmake_include / 'sundials_export.h',
'@OUTDIR@',
],
output: ['sundials_config.h', 'sundials_export.h'],
depends: libcvode_static,
install: true,
install_dir: gridfire_vendor_includedir / 'sundials',
)

View File

@@ -1,4 +1,9 @@
xxhash_dep = declare_dependency(
include_directories: include_directories('include')
)
install_subdir(
'include',
install_dir: gridfire_vendor_includedir,
strip_directory: true,
)