dynare/meson.build

501 lines
29 KiB
Meson
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# TODO:
# - move to fortran_std=f2018; this requires changes in libkordersim, and also replacing isnan() by ieee_is_nan() in various MEX (or use -fall-intrinsics)
# - use buildtype=debugoptimized by default? (and in the preprocessor too)
# - with -Dprefer_static=true, under Octave/Windows, we are now linking the compiler libs (libgcc, libstdc++, libgfortran, libquadmath, libssp, libgomp) statically (contrary to what we were doing with autotools). In theory this is better, because the compiler used for creating the Octave binary may be different from the one used for creating our MEX. Check that this is ok
# - configuration option to disable documentation
# - configuration option to disable preprocessor build
# - add -Wold-style-cast C++ flag except when building flex-generated files
# - determine minimal meson version required, and declare it in the project() function (here and the preprocessor); if possible at low cost, diminish the requirement. NB: Ubuntu “jammy” 22.04 has 0.61, Debian “bullseye” 11 has 0.56 (but bullseye-backports has 1.0), Ubuntu ”focal” 20.04 has 0.53
project('dynare',
'cpp', 'fortran', 'c',
version : '6-unstable',
default_options : [ 'cpp_std=gnu++20', 'fortran_std=none', 'c_std=gnu17', 'warning_level=2' ])
add_global_arguments('-Wimplicit-interface', '-Wno-compare-reals', language : 'fortran')
add_global_arguments('-DPACKAGE_VERSION="' + meson.project_version() + '"', language : 'cpp')
cpp_compiler = meson.get_compiler('cpp')
fortran_compiler = meson.get_compiler('fortran')
c_compiler = meson.get_compiler('c')
### Preprocessor
subdir('preprocessor/src')
subdir('preprocessor/doc')
### Generated M-file
sed_exe = find_program('sed')
custom_target(output : 'dynare_version.m', input : 'matlab/dynare_version.m.in',
command : [ sed_exe, 's/@PACKAGE_VERSION@/' + meson.project_version() + '/', '@INPUT@' ],
capture : true,
build_by_default : true) # FIXME: This option can be removed when “install” is set to true
### MEX files
mex_incdir = include_directories('mex/sources')
## Various dependencies
if host_machine.system() != 'windows'
dl_dep = dependency('dl')
else
# Under Windows, we dont use dlopen but rely on LoadLibrary
dl_dep = []
endif
openmp_dep = dependency('openmp')
gsl_dep = dependency('gsl')
if get_option('build_for') == 'octave'
matio_dep = dependency('matio')
else
# We dont use MatIO under MATLAB
matio_dep = []
endif
pthread_t_sizeof = c_compiler.sizeof('pthread_t', prefix : '#include <pthread.h>')
# TODO: when requiring meson ⩾ 1.2, incorporate pthread.F08 into the dependency object with “extra_files” option
# (and thus remove the pthread_fortran_iface variable)
pthread_fortran_dep = declare_dependency(compile_args : '-DSIZEOF_PTHREAD_T=' + pthread_t_sizeof.to_string())
## Determine MEX compilation options
if get_option('build_for') == 'matlab'
matlab_path = get_option('matlab_path')
if matlab_path == ''
error('The “matlab_path” option must be provided when doing a MATLAB build')
endif
matlab_version = run_command('scripts/get-matlab-version', matlab_path, check : true).stdout().strip()
matlab_minimal_version = [ '8.3', 'R2014a' ]
if matlab_version.version_compare('<' + matlab_minimal_version[0])
error('MATLAB is too old (version ' + matlab_version + '), please upgrade to version ' + matlab_minimal_version[0] + ' (' + matlab_minimal_version[1] + ') at least.')
endif
matlab_version_hex = run_command('scripts/get-matlab-version', '--hex', matlab_path, check : true).stdout().strip()
matlab_exe = find_program(matlab_path / 'bin' / 'matlab', required : not meson.is_cross_build())
if host_machine.system() == 'linux' and host_machine.cpu_family() == 'x86_64'
mexext = 'mexa64'
matlab_arch = 'glnxa64'
export_file = matlab_path / 'extern/lib/glnxa64/mexFunction.map'
export_link_arg = '-Wl,--version-script,' + export_file
elif host_machine.system() == 'windows' and host_machine.cpu_family() == 'x86_64'
mexext = 'mexw64'
matlab_arch = 'win64'
export_file = meson.current_source_dir() / 'mex/build/matlab/mex.def'
export_link_arg = export_file
if get_option('build_for') == 'matlab'
arch_fortran_args = [ '-fno-underscoring' ]
endif
elif host_machine.system() == 'darwin'
if host_machine.cpu_family() == 'x86_64'
mexext = 'mexmaci64'
matlab_arch = 'maci64'
elif host_machine.cpu_family() == 'aarch64'
mexext = 'mexmaca64'
matlab_arch = 'maca64'
else
error('Unsupported platform')
endif
export_file = meson.current_source_dir() / 'mex/build/matlab/mexFunction-MacOSX.map'
export_link_arg = '-Wl,-exported_symbols_list,' + export_file
else
error('Unsupported platform')
endif
matlab_defs = [ '-DMATLAB_MEX_FILE', '-DMATLAB_VERSION=' + matlab_version_hex, '-DMEXEXT="' + mexext + '"' ]
matlab_incdir = include_directories(matlab_path / 'extern/include')
mex_kwargs = { 'name_prefix' : '',
'name_suffix' : mexext,
'include_directories' : [ mex_incdir, matlab_incdir ],
'cpp_args' : matlab_defs,
'fortran_args' : matlab_defs + [ '-fexceptions' ] + get_variable('arch_fortran_args', []),
'c_args' : matlab_defs + [ '-fexceptions' ],
'link_args' : [ export_link_arg, '-L' + (matlab_path / 'bin' / matlab_arch), '-lmx', '-lmex', '-lmat' ],
'link_depends' : export_file }
# For unit tests
exe_rpath = matlab_path / 'bin' / matlab_arch
exe_link_args = [ '-L' + exe_rpath, '-lmx', '-lmex', '-lmat' ]
# No need to use find_library() for the following libraries, since they are always shipped with MATLAB
blas_dep = declare_dependency(link_args : '-lmwblas')
lapack_dep = declare_dependency(link_args : '-lmwlapack', dependencies : blas_dep)
umfpack_dep = declare_dependency(link_args : '-lmwumfpack', dependencies : blas_dep)
ut_dep = declare_dependency(link_args : '-lut')
slicot_dep = declare_dependency(dependencies : [ fortran_compiler.find_library('slicot64_pic'), blas_dep, lapack_dep ])
else # Octave build
octave_exe = find_program('octave', required : not meson.is_cross_build())
mkoctfile_exe = find_program('mkoctfile')
octave_minimal_version = '6.2.0'
octave_version = run_command(mkoctfile_exe, '-v', check : true).stdout().replace('mkoctfile, version ', '')
if octave_version.version_compare('<' + octave_minimal_version)
error('Octave is too old (version ' + octave_version + '), please upgrade to version ' + octave_minimal_version + ' at least.')
endif
octave_incflags = run_command(mkoctfile_exe, '-p', 'INCFLAGS', check : true).stdout().split()
octlibdir = run_command(mkoctfile_exe, '-p', 'OCTLIBDIR', check : true).stdout().strip()
# Determine whether to link MEX files against the Octave libraries. mkoctfile
# no longer does this by default but in practice it is needed for Windows and
# macOS.
octave_libs = run_command(mkoctfile_exe, '-p', 'OCTAVE_LIBS', check : true).stdout().split()
if host_machine.system() == 'windows' or host_machine.system() == 'darwin'
# Under Windows, --enable-link-all-dependencies is hardcoded in src/mkoctfile.cc.in.
# Under macOS, the Homebrew formula passes --enable-link-all-dependencies
# to the configure script.
octave_link_args = [ '-L' + octlibdir ] + octave_libs
else
octave_link_args = []
endif
# For unit tests
exe_rpath = octlibdir
exe_link_args = [ '-L' + octlibdir ] + octave_libs
octave_defs = [ '-DOCTAVE_MEX_FILE', '-DMEXEXT="mex"' ]
mex_kwargs = { 'name_prefix' : '',
'name_suffix' : 'mex',
'include_directories' : [ mex_incdir ],
'cpp_args' : octave_incflags + octave_defs,
'fortran_args' : octave_incflags + octave_defs,
'c_args' : octave_incflags + octave_defs,
'link_args' : octave_link_args}
# The -L argument is useful when cross-compiling.
blas_dep = declare_dependency(link_args : [ '-L' + (octlibdir / '../..') ] + run_command(mkoctfile_exe, '-p', 'BLAS_LIBS', check : true).stdout().split())
lapack_dep = declare_dependency(link_args : run_command(mkoctfile_exe, '-p', 'LAPACK_LIBS', check : true).stdout().split(),
dependencies : blas_dep)
# Create a dependency object for UMFPACK.
# The dependency returned by find_library('umfpack') is not enough, because we also want the define
# that indicates the location of umfpack.h, so we construct a new dependency object.
if cpp_compiler.has_header('suitesparse/umfpack.h', args : octave_incflags)
umfpack_def = '-DHAVE_SUITESPARSE_UMFPACK_H'
elif cpp_compiler.has_header('umfpack.h', args : octave_incflags)
umfpack_def = '-DHAVE_UMFPACK_H'
else
error('Cant find umfpack.h')
endif
# Do not enforce static linking even if prefer_static is true, since that library is shipped
# with Octave.
# The “dirs” argument is useful when cross-compiling.
umfpack_dep_tmp = cpp_compiler.find_library('umfpack', dirs : octlibdir / '../..', static : false)
umfpack_dep = declare_dependency(compile_args : umfpack_def, dependencies : [ umfpack_dep_tmp, blas_dep ])
# This library does not exist under Octave
ut_dep = []
# First look for libslicot, then if needed fallback on libslicot_pic
slicot_dep_tmp = fortran_compiler.find_library('slicot', required : false)
if not slicot_dep_tmp.found()
slicot_dep_tmp = fortran_compiler.find_library('slicot_pic')
endif
slicot_dep = declare_dependency(dependencies : [ slicot_dep_tmp, blas_dep, lapack_dep ])
endif
# When static linking is preferred, try to statically link the compiler libraries
if get_option('prefer_static')
static_flags_pre = [ '-static-libgcc', '-static-libstdc++' ]
static_flags_post = []
if host_machine.system() == 'windows'
# Under Debian 12, libgfortran.a and libquadmath.a are not compiled with -fPIC, so cant be linked in a MEX.
# Under macOS, -static-libgcc implies -static-libgfortran (see gfortran -dumpspecs), and for libquadmath
# we use a hack with a local copy of libquadmath.a.
# -static-libquadmath was introduced in GCC 13. Until we require the latter, use a hack.
static_flags_pre += [ '-static-libgfortran', '-Wl,-Bstatic,--whole-archive', '-lquadmath', '-Wl,-Bdynamic,--no-whole-archive' ]
# Hack to avoid dynamically linking against libwinpthread DLL (which is
# pulled in by libstdc++, even without using threads, since we are using
# the POSIX threads version of MinGW).
static_flags_pre += [ '-Wl,-Bstatic,--whole-archive', '-lwinpthread', '-Wl,-Bdynamic,--no-whole-archive' ]
# Hack for libssp, which is pulled in by -fstack-protector (curiously only
# on some MEX files), see windows/build.sh. Note that the link against
# libssp should not happen with compilers from MSYS2, see:
# https://www.msys2.org/news/#2022-10-10-libssp-is-no-longer-required
# But it happens with Debians cross compilers (as of Debian “bookworm”
# 12). Also note that the -lssp must come by the end of the link command
# (otherwise it will have to be enclosed within --whole-archive).
static_flags_post = [ '-Wl,-Bstatic', '-lssp', '-Wl,-Bdynamic' ]
endif
mex_kwargs += { 'link_args' : static_flags_pre + mex_kwargs.get('link_args', []) + static_flags_post }
# NB: constructing a dependency object with link_args : ['-Wl,-Bstatic', '-lgomp', '-Wl,-Bdynamic'] does not work,
# because it reorders the three arguments and puts -lgomp at the end
openmp_dep_tmp = cpp_compiler.find_library('gomp', static : true)
openmp_dep = declare_dependency(dependencies : [ openmp_dep, openmp_dep_tmp ])
endif
# For use when creating intermediate static libraries to be incorporated in MEX files
static_library_kwargs = mex_kwargs + { 'name_prefix' : [], 'name_suffix' : [], 'link_args' : [], 'pic' : true }
mex_blas_fortran_iface = [ 'mex/sources/matlab_mex.F08', 'mex/sources/blas_lapack.F08' ]
pthread_fortran_iface = [ 'mex/sources/pthread.F08' ]
## Various core MEX
shared_module('mjdgges', [ 'mex/sources/mjdgges/mjdgges.F08' ] + mex_blas_fortran_iface, kwargs : mex_kwargs, dependencies : lapack_dep)
shared_module('num_procs', 'mex/sources/num_procs/num_procs.cc', kwargs : mex_kwargs)
perfect_foresight_problem_src = [ 'mex/sources/perfect_foresight_problem/perfect_foresight_problem.cc',
'mex/sources/perfect_foresight_problem/DynamicModelCaller.cc' ]
shared_module('perfect_foresight_problem', perfect_foresight_problem_src, kwargs : mex_kwargs, dependencies : openmp_dep)
block_trust_region_src = [ 'mex/sources/block_trust_region/dulmage_mendelsohn.f08',
'mex/sources/block_trust_region/matlab_fcn_closure.F08',
'mex/sources/block_trust_region/trust_region.f08',
'mex/sources/block_trust_region/mexFunction.f08' ] + mex_blas_fortran_iface
shared_module('block_trust_region', block_trust_region_src, kwargs : mex_kwargs, dependencies : lapack_dep)
bytecode_src = [ 'mex/sources/bytecode/bytecode.cc',
'mex/sources/bytecode/Interpreter.cc',
'mex/sources/bytecode/Mem_Mngr.cc',
'mex/sources/bytecode/SparseMatrix.cc',
'mex/sources/bytecode/Evaluate.cc',
'mex/sources/bytecode/BasicSymbolTable.cc' ]
preprocessor_headers_dep = declare_dependency(include_directories : include_directories('preprocessor/src'))
shared_module('bytecode', bytecode_src, kwargs : mex_kwargs, dependencies : [ umfpack_dep, ut_dep, preprocessor_headers_dep ])
shared_module('sparse_hessian_times_B_kronecker_C', 'mex/sources/kronecker/sparse_hessian_times_B_kronecker_C.cc',
kwargs : mex_kwargs, dependencies : openmp_dep)
# TODO: A_times_B_kronecker_C does not depend on LAPACK, but since the
# interfaces to both BLAS and LAPACK are in the same source file, the
# dependency must be added. Think about splitting into two files.
# NB: The problem does not appear with libkordersim because since it is a library,
# the LAPACK stuff is never pulled in.
shared_module('A_times_B_kronecker_C', [ 'mex/sources/kronecker/A_times_B_kronecker_C.f08' ] + mex_blas_fortran_iface,
kwargs : mex_kwargs, dependencies : [ blas_dep, lapack_dep ])
shared_module('cycle_reduction', [ 'mex/sources/cycle_reduction/mexFunction.f08' ] + mex_blas_fortran_iface,
kwargs : mex_kwargs, dependencies : [ blas_dep, lapack_dep ])
shared_module('logarithmic_reduction', [ 'mex/sources/logarithmic_reduction/mexFunction.f08' ] + mex_blas_fortran_iface,
kwargs : mex_kwargs, dependencies : [ blas_dep, lapack_dep ])
shared_module('disclyap_fast', [ 'mex/sources/disclyap_fast/disclyap_fast.f08' ] + mex_blas_fortran_iface,
kwargs : mex_kwargs, dependencies : [ blas_dep, lapack_dep ])
# TODO: Same remark as A_times_B_kronecker_C
shared_module('riccati_update', [ 'mex/sources/riccati_update/mexFunction.f08' ] + mex_blas_fortran_iface,
kwargs : mex_kwargs, dependencies : [ blas_dep, lapack_dep ])
qmc_sequence_src = [ 'mex/sources/sobol/qmc_sequence.cc',
'mex/sources/sobol/sobol.f08' ]
# Hack for statically linking libgfortran
# Since qmc_sequence is a mix of C++ and Fortran, the linker invoked is the C++ one.
# Meson then rightly adds -lgfortran, but the -static-libgfortran flag does not work.
qmc_sequence_mex_kwargs = mex_kwargs
if get_option('prefer_static') and host_machine.system() == 'windows'
qmc_sequence_mex_kwargs += { 'link_args' : qmc_sequence_mex_kwargs.get('link_args') + [ '-Wl,-Bstatic', '-lgfortran', '-Wl,-Bdynamic' ] }
endif
shared_module('qmc_sequence', qmc_sequence_src, kwargs : qmc_sequence_mex_kwargs, dependencies : [ blas_dep, openmp_dep ])
shared_module('kalman_steady_state', 'mex/sources/kalman_steady_state/kalman_steady_state.cc', kwargs : mex_kwargs, dependencies : slicot_dep)
## k-order simulation stuff
kordersim_src = [ 'mex/sources/libkordersim/pascal.f08',
'mex/sources/libkordersim/sort.f08',
'mex/sources/libkordersim/partitions.f08',
'mex/sources/libkordersim/tensors.f08',
'mex/sources/libkordersim/simulation.f08',
'mex/sources/libkordersim/struct.f08' ] + mex_blas_fortran_iface + pthread_fortran_iface
kordersim_lib = static_library('kordersim', kordersim_src, kwargs : static_library_kwargs, dependencies : [ blas_dep, pthread_fortran_dep ])
shared_module('folded_to_unfolded_dr', 'mex/sources/folded_to_unfolded_dr/mexFunction.f08', kwargs : mex_kwargs, link_with : kordersim_lib)
shared_module('k_order_mean', 'mex/sources/k_order_mean/mexFunction.f08', kwargs : mex_kwargs, link_with : kordersim_lib)
shared_module('k_order_simul', 'mex/sources/k_order_simul/mexFunction.f08', kwargs : mex_kwargs, link_with : kordersim_lib)
shared_module('local_state_space_iteration_2', 'mex/sources/local_state_space_iterations/local_state_space_iteration_2.cc', kwargs : mex_kwargs, dependencies : openmp_dep)
shared_module('local_state_space_iteration_3', 'mex/sources/local_state_space_iterations/local_state_space_iteration_3.f08', kwargs : mex_kwargs, link_with : kordersim_lib)
shared_module('local_state_space_iteration_k', 'mex/sources/local_state_space_iterations/local_state_space_iteration_k.f08', kwargs : mex_kwargs, link_with : kordersim_lib)
## k-order resolution stuff
korder_src = [ 'mex/sources/libkorder/kord/approximation.cc',
'mex/sources/libkorder/kord/decision_rule.cc',
'mex/sources/libkorder/kord/dynamic_model.cc',
'mex/sources/libkorder/kord/faa_di_bruno.cc',
'mex/sources/libkorder/kord/first_order.cc',
'mex/sources/libkorder/kord/korder.cc',
'mex/sources/libkorder/kord/korder_stoch.cc',
'mex/sources/libkorder/kord/journal.cc',
'mex/sources/libkorder/sylv/BlockDiagonal.cc',
'mex/sources/libkorder/sylv/GeneralMatrix.cc',
'mex/sources/libkorder/sylv/GeneralSylvester.cc',
'mex/sources/libkorder/sylv/IterativeSylvester.cc',
'mex/sources/libkorder/sylv/KronUtils.cc',
'mex/sources/libkorder/sylv/KronVector.cc',
'mex/sources/libkorder/sylv/QuasiTriangular.cc',
'mex/sources/libkorder/sylv/QuasiTriangularZero.cc',
'mex/sources/libkorder/sylv/SchurDecomp.cc',
'mex/sources/libkorder/sylv/SchurDecompEig.cc',
'mex/sources/libkorder/sylv/SimilarityDecomp.cc',
'mex/sources/libkorder/sylv/SylvException.cc',
'mex/sources/libkorder/sylv/SylvMatrix.cc',
'mex/sources/libkorder/sylv/SylvParams.cc',
'mex/sources/libkorder/sylv/SymSchurDecomp.cc',
'mex/sources/libkorder/sylv/TriangularSylvester.cc',
'mex/sources/libkorder/sylv/Vector.cc',
'mex/sources/libkorder/tl/equivalence.cc',
'mex/sources/libkorder/tl/fine_container.cc',
'mex/sources/libkorder/tl/fs_tensor.cc',
'mex/sources/libkorder/tl/gs_tensor.cc',
'mex/sources/libkorder/tl/int_sequence.cc',
'mex/sources/libkorder/tl/kron_prod.cc',
'mex/sources/libkorder/tl/normal_moments.cc',
'mex/sources/libkorder/tl/permutation.cc',
'mex/sources/libkorder/tl/ps_tensor.cc',
'mex/sources/libkorder/tl/pyramid_prod.cc',
'mex/sources/libkorder/tl/pyramid_prod2.cc',
'mex/sources/libkorder/tl/rfs_tensor.cc',
'mex/sources/libkorder/tl/sparse_tensor.cc',
'mex/sources/libkorder/tl/stack_container.cc',
'mex/sources/libkorder/tl/symmetry.cc',
'mex/sources/libkorder/tl/t_container.cc',
'mex/sources/libkorder/tl/t_polynomial.cc',
'mex/sources/libkorder/tl/tensor.cc',
'mex/sources/libkorder/tl/tl_static.cc',
'mex/sources/libkorder/tl/twod_matrix.cc',
'mex/sources/libkorder/utils/pascal_triangle.cc',
'mex/sources/libkorder/utils/int_power.cc',
'mex/sources/libkorder/utils/sthread.cc',
'mex/sources/libkorder/k_ord_dynare.cc',
'mex/sources/libkorder/dynamic_dll.cc',
'mex/sources/libkorder/dynamic_m.cc' ]
korder_incdir = include_directories('mex/sources/libkorder', 'mex/sources/libkorder/tl', 'mex/sources/libkorder/sylv',
'mex/sources/libkorder/kord', 'mex/sources/libkorder/utils')
korder_lib = static_library('korder', korder_src,
kwargs : static_library_kwargs + { 'include_directories' : static_library_kwargs.get('include_directories') + korder_incdir},
dependencies : [ blas_dep, lapack_dep, dl_dep ])
korder_mex_kwargs = mex_kwargs + { 'include_directories' : mex_kwargs.get('include_directories') + korder_incdir}
shared_module('gensylv', 'mex/sources/gensylv/gensylv.cc', kwargs : korder_mex_kwargs, link_with : korder_lib)
shared_module('k_order_perturbation', 'mex/sources/gensylv/gensylv.cc', kwargs : korder_mex_kwargs, link_with : korder_lib)
k_order_welfare_src = [ 'mex/sources/k_order_welfare/k_order_welfare.cc',
'mex/sources/k_order_welfare/approximation_welfare.cc',
'mex/sources/k_order_welfare/k_ord_objective.cc',
'mex/sources/k_order_welfare/objective_m.cc' ]
shared_module('k_order_welfare', k_order_welfare_src, kwargs : korder_mex_kwargs, link_with : korder_lib)
# Unit tests
korder_test_kwargs = { 'include_directories' : [ mex_incdir, korder_incdir ],
'link_args' : exe_link_args,
'build_rpath' : exe_rpath,
'link_with' : korder_lib }
korder_sylv_test_exe = executable('korder_sylv_test', [ 'mex/sources/libkorder/sylv/tests/MMMatrix.cc',
'mex/sources/libkorder/sylv/tests/tests.cc'],
kwargs : korder_test_kwargs)
test('korder_sylv', korder_sylv_test_exe, workdir : meson.current_source_dir() / 'mex/sources/libkorder/sylv/tests', timeout : 300)
korder_tl_test_exe = executable('korder_tl_test', [ 'mex/sources/libkorder/tl/tests/factory.cc',
'mex/sources/libkorder/tl/tests/monoms.cc',
'mex/sources/libkorder/tl/tests/tests.cc'],
kwargs : korder_test_kwargs)
test('korder_tl', korder_tl_test_exe, timeout : 300)
korder_kord_test_exe = executable('korder_kord_test', 'mex/sources/libkorder/kord/tests/tests.cc', kwargs : korder_test_kwargs)
test('korder_kord', korder_kord_test_exe, timeout : 1500)
## MS-SBVAR stuff
ms_sbvar_src = [ 'contrib/ms-sbvar/utilities_dw/arrays/dw_array.c',
'contrib/ms-sbvar/utilities_dw/arrays/dw_matrix_array.c',
'contrib/ms-sbvar/utilities_dw/ascii/dw_ascii.c',
'contrib/ms-sbvar/utilities_dw/ascii/dw_parse_cmd.c',
'contrib/ms-sbvar/utilities_dw/elliptical/dw_elliptical.c',
'contrib/ms-sbvar/utilities_dw/error/dw_error.c',
'contrib/ms-sbvar/utilities_dw/histogram/dw_histogram.c',
'contrib/ms-sbvar/utilities_dw/math/dw_math.c',
'contrib/ms-sbvar/utilities_dw/matrix/dw_matrix.c',
'contrib/ms-sbvar/utilities_dw/matrix/bmatrix.c',
'contrib/ms-sbvar/utilities_dw/sort/dw_matrix_sort.c',
'contrib/ms-sbvar/utilities_dw/stat/dw_rand_gsl.c',
'contrib/ms-sbvar/utilities_dw/stat/dw_matrix_rand.c',
'contrib/ms-sbvar/switch_dw/switching/dw_switch.c',
'contrib/ms-sbvar/switch_dw/switching/dw_switchio.c',
'contrib/ms-sbvar/switch_dw/switching/dw_dirichlet_restrictions.c',
'contrib/ms-sbvar/switch_dw/switching/dw_metropolis_theta.c',
'contrib/ms-sbvar/switch_dw/state_space/sbvar/VARbase.c',
'contrib/ms-sbvar/switch_dw/state_space/sbvar/VARio.c',
'mex/sources/ms-sbvar/mex_top_level.cc',
'mex/sources/ms-sbvar/modify_for_mex.cc' ]
ms_sbvar_defs = [ '-DSTRUCTURED_COLUMN_MAJOR' ]
ms_sbvar_incdir = include_directories('contrib/ms-sbvar/utilities_dw/include', 'contrib/ms-sbvar/switch_dw/switching', 'mex/sources/ms-sbvar')
ms_sbvar_lib = static_library('ms_sbvar', ms_sbvar_src,
kwargs : static_library_kwargs + { 'c_args' : static_library_kwargs.get('c_args') + ms_sbvar_defs,
'cpp_args' : static_library_kwargs.get('cpp_args') + ms_sbvar_defs,
'include_directories' : static_library_kwargs.get('include_directories') + ms_sbvar_incdir },
dependencies : [ blas_dep, lapack_dep, gsl_dep, matio_dep, ut_dep ])
mex_ms_sbvar_kwargs = mex_kwargs + { 'c_args' : mex_kwargs.get('c_args') + ms_sbvar_defs,
'cpp_args' : mex_kwargs.get('cpp_args') + ms_sbvar_defs,
'include_directories' : mex_kwargs.get('include_directories') + ms_sbvar_incdir }
ms_sbvar_create_init_file_src = [ 'contrib/ms-sbvar/switch_dw/state_space/sbvar/create_init_file.c',
'contrib/ms-sbvar/switch_dw/state_space/sbvar/VARio_matlab.c' ]
shared_module('ms_sbvar_create_init_file', ms_sbvar_create_init_file_src, kwargs : mex_ms_sbvar_kwargs, link_with : ms_sbvar_lib, dependencies : matio_dep)
ms_sbvar_command_line_src = [ 'contrib/ms-sbvar/switch_dw/switching/dw_switch_opt.c',
'contrib/ms-sbvar/switch_dw/switching/dw_mdd_switch.c',
'contrib/ms-sbvar/switch_dw/state_space/sbvar/dw_sbvar_command_line.c',
'contrib/ms-sbvar/switch_dw/state_space/sbvar/sbvar_estimate.c',
'contrib/ms-sbvar/switch_dw/state_space/sbvar/sbvar_simulate.c',
'contrib/ms-sbvar/switch_dw/state_space/sbvar/sbvar_probabilities.c',
'contrib/ms-sbvar/switch_dw/state_space/sbvar/sbvar_mdd.c',
'contrib/ms-sbvar/switch_dw/state_space/sbvar/sbvar_forecast.c',
'contrib/ms-sbvar/switch_dw/state_space/sbvar/sbvar_variance_decomposition.c',
'contrib/ms-sbvar/switch_dw/state_space/sbvar/sbvar_impulse_responses.c',
'contrib/ms-sbvar/switch_dw/state_space/sbvar/dw_csminwel.c' ]
shared_module('ms_sbvar_command_line', ms_sbvar_command_line_src, kwargs : mex_ms_sbvar_kwargs, link_with : ms_sbvar_lib, dependencies : [ gsl_dep, matio_dep ])
### Integration tests
# Create a test driver (in bash) that takes as arguments:
# - unique name of the test
# - get_option('build_for')
# - the path to the MATLAB/Octave executable: get_option('build_for') == 'matlab' ? matlab_exe.full_path() : octave_exe.full_path()
# - the version of MATLAB/Octave (needed under MATLAB for determining the batch options)
# - a list of .mod files that must be executed sequentially (i.e. a flattened dependency tree)
# - a separator (e.g. "--")
# - a list of extra files on which the .mod files depend (.inc, .mat, …)
#
# The test driver would do the following:
# - create a temporary directory (with mktemp -d or its equivalent on Windows/macOS), of the form dynare-$(testname).XXXXXX
# - copy the .mod files and the extra files into that temporary directory, keeping the original directory structure (a test dependency may be in another directory)
# - set the environment variable DYNARE_BUILD_DIR
# - run MATLAB/Octave on the .mod files sequentially (using a thin .m wrapper for printing the stack trace in case of error)
# - return the correct exitcode
#
# In the present file, the tests list could be organized in a array of arrays. Each inner array would correspond to a test, and contain:
# - the unique name of the test
# - an array containing the list of .mod files
# - an array containing the list of extra files
# - an array indicating the suite(s) to which this test belongs
# - an optional timeout value?
#
# This tests list would be used in a foreach loop around the test() command.
#
# Other items:
# - Decide whether to automatically delete the temporary directories created by the test driver. Cons: removes test data useful for debugging. Pro: avoid excessive disk filling.
# - See what to do with xvfb-run (see #1892). Maybe try to detect it from meson.build, and pass it optionally to the test driver script
# - Include the k-order unit tests in some suite(s)
# - See if the tests can be automatically disabled if the MATLAB/Octave executable is not found (using the disabler option of find_program?)
# - Deal with other types of tests (integration tests implemented as pure .m scripts, unit tests for .m files)