From e335fed27bf44f20f1bba1c8cd47754e18ca6ff9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Mon, 18 Sep 2023 16:31:15 +0200
Subject: [PATCH] macOS package: use the Meson build system

By the way, simplify the dependency build system by removing 32-bit
SLICOT (was only used for the Octave package), and the symlinks for MatIO and
GSL (no longer needed with Meson).
---
 .gitlab-ci.yml              |   1 +
 macOS/build.sh              | 140 ++++++++++++------------------------
 macOS/deps/Makefile         |  72 +++----------------
 scripts/homebrew-native.ini |   2 +-
 4 files changed, 57 insertions(+), 158 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 60d4b2bf3b..ae463a5dd9 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -92,6 +92,7 @@ pkg_windows:
 pkg_macOS:
   stage: pkg
   script:
+    - meson rewrite kwargs set project / version "$VERSION"
     - ln -s ~/tarballs macOS/deps/
     - arch -x86_64 make -C macOS
   cache:
diff --git a/macOS/build.sh b/macOS/build.sh
index 38e5cf9172..e9d3aeeebe 100755
--- a/macOS/build.sh
+++ b/macOS/build.sh
@@ -21,91 +21,71 @@ set -ex
 
 ROOTDIR=$(pwd)/..
 
-# Set the GCC version
-GCC_VERSION=13
-
-# Set the compilers
-CC=gcc-$GCC_VERSION
-CXX=g++-$GCC_VERSION
-
-# Set the number of threads
-NTHREADS=$(sysctl -n hw.ncpu)
-
 # Set dependency directory
 LIB64="$ROOTDIR"/macOS/deps/lib64
 
-
-##
-## Find Dynare Version
-##
-DATE=$(date +%Y-%m-%d-%H%M)
-DATELONG=$(date '+%d %B %Y')
-if [[ -d ../.git/ ]]; then
-    SHA=$(git rev-parse HEAD)
-    SHASHORT=$(git rev-parse --short HEAD)
-fi
-
-if [[ -z $VERSION ]]; then
-    VERSION=$(grep '^AC_INIT(' ../configure.ac | sed 's/AC_INIT(\[dynare\], \[\(.*\)\])/\1/')
-    if [[ -d ../.git/ ]]; then
-        VERSION="$VERSION"-"$SHASHORT"
-    fi
-fi
-
-# Install location must not be too long for gcc.
-# Otherwise, the headers of the compiled libraries cannot be modified
-# obliging recompilation on the user's system.
-# If VERSION is not a official release number, then do some magic
-# to get something not too long, still more or less unique.
-if [[ "$VERSION" =~ ^[0-9\.]+$ ]]; then
-    LOCATION=$VERSION
-else
-    # Get the first component, truncate it to 5 characters, and add the date
-    LOCATION=$(echo "$VERSION" | cut -f1 -d"-" | cut -c 1-5)-"$DATE"
-fi
-
 ## Hack for statically linking libquadmath, similar to the one used in
 ## deps/Makefile for several libraries (there is no -static-libquadmath flag,
 ## see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46539).
 ##
-## NB: The hack done for Windows (see m4/ax_mexopts.m4) does not work for two reasons:
+## NB: The hack done for Windows does not work for two reasons:
 ## - the macOS linker is different from GNU ld and does not have the equivalent of -Bstatic/-Bdynamic
 ## - libgfortran.spec does not include --as-needed on macOS, hence it will link the library anyways
 ## Also, it does not seem possible to override libgfortran.spec with the --specs option.
+GCC_VERSION=$(sed -En "/^c[[:space:]]*=/s/c[[:space:]]*=[[:space:]]*'gcc-([0-9]+)'/\1/p" "$ROOTDIR"/scripts/homebrew-native.ini)
 QUADMATH_DIR=$(mktemp -d)
 ln -s /usr/local/opt/gcc/lib/gcc/$GCC_VERSION/libquadmath.a $QUADMATH_DIR
 
 ##
-## Compile Dynare preprocessor, mex for MATLAB < 2018a
+## Compile Dynare
 ##
-## NB: In Homebrew, -static-libgfortran is implied by -static-libgcc (see “gfortran -dumpspecs”)
-## NB2: We use the hack for libquadmath in LDFLAGS
 cd "$ROOTDIR"
-[[ -f configure ]] || autoreconf -si
-./configure \
-  PACKAGE_VERSION="$VERSION" \
-  PACKAGE_STRING="dynare $VERSION" \
-  CC=$CC \
-  CXX=$CXX \
-  CPPFLAGS=-I/usr/local/include \
-  LDFLAGS="-static-libgcc -L$QUADMATH_DIR" \
-  LEX=/usr/local/opt/flex/bin/flex \
-  YACC=/usr/local/opt/bison/bin/bison \
-  --with-gsl="$LIB64"/gsl \
-  --with-matio="$LIB64"/matio \
-  --with-slicot="$LIB64"/Slicot/with-underscore \
-  --disable-octave \
-  --with-matlab=/Applications/MATLAB_R2016b.app
-make -j"$NTHREADS"
 
+common_meson_opts=(-Dbuild_for=matlab -Dbuildtype=release -Dprefer_static=true -Dfortran_args="[ '-B', '$LIB64/Slicot/' ]" \
+                   -Dc_link_args="[ '-L$QUADMATH_DIR' ]" -Dcpp_link_args="[ '-L$QUADMATH_DIR' ]" -Dfortran_link_args="[ '-L$QUADMATH_DIR' ]" \
+                   --native-file scripts/homebrew-native.ini)
+
+# Build for MATLAB ⩾ R2018a
+meson setup "${common_meson_opts[@]}" -Dmatlab_path=/Applications/MATLAB_R2022b.app build-matlab
+meson compile -v -C build-matlab
+
+# Build for MATLAB < R2018a
+meson setup "${common_meson_opts[@]}" -Dmatlab_path=/Applications/MATLAB_R2016b.app build-old-matlab
+meson compile -v -C build-old-matlab
+
+# If not in CI, build the docs
 if [[ -z $CI ]]; then
-    echo "Building out of GitLab CI is not supported, documentation support needs to be fixed" 2>&1
-    exit 1
+    meson compile -v -C build-matlab doc
+    ln -s build-matlab build-doc
 fi
 
 ##
 ## Create package
 ##
+
+# Determine Dynare version if not passed by an environment variable as in the CI
+if [[ -z $VERSION ]]; then
+    cd build-matlab
+    VERSION=$(meson introspect --projectinfo | sed -En 's/^.*"version": "([^"]*)".*$/\1/p')
+    cd ..
+fi
+
+# Other useful variables
+DATE=$(date +%Y-%m-%d-%H%M)
+DATELONG=$(date '+%d %B %Y')
+
+# Install location must not be too long for gcc.
+# Otherwise, the headers of the compiled libraries cannot be modified
+# obliging recompilation on the user's system.
+# If VERSION is not a official release number, then do some magic
+# to get something not too long, still more or less unique.
+if [[ "$VERSION" =~ ^[0-9\.]+$ ]]; then
+    LOCATION=$VERSION
+else
+    # Get the first component, truncate it to 5 characters, and add the date
+    LOCATION=$(echo "$VERSION" | cut -f1 -d"-" | cut -c 1-5)-"$DATE"
+fi
+
 NAME=dynare-"$VERSION"
 PKGFILES="$ROOTDIR"/macOS/pkg/"$NAME"
 mkdir -p \
@@ -116,24 +96,21 @@ mkdir -p \
       "$PKGFILES"/scripts \
       "$PKGFILES"/contrib/ms-sbvar/TZcode
 
-if [[ $VERSION == *-unstable* ]]; then
-    echo "$SHA"                                                    > "$PKGFILES"/sha.txt
-fi
 cp -p  "$ROOTDIR"/NEWS.md                                            "$PKGFILES"
 cp -p  "$ROOTDIR"/COPYING                                            "$PKGFILES"
-cp -p  "$ROOTDIR"/VERSION                                            "$PKGFILES"
 cp -p  "$ROOTDIR"/license.txt                                        "$PKGFILES"
 
 cp -pr "$ROOTDIR"/matlab                                             "$PKGFILES"
 cp -pr "$ROOTDIR"/examples                                           "$PKGFILES"
 
-cp -p  "$ROOTDIR"/preprocessor/src/dynare-preprocessor               "$PKGFILES"/preprocessor
+cp -p  "$ROOTDIR"/build-matlab/preprocessor/src/dynare-preprocessor  "$PKGFILES"/preprocessor
 
-# Recreate backward-compatibility symlink
-rm -f "$ROOTDIR"/matlab/preprocessor64/dynare_m
+# Create backward-compatibility symlink
+mkdir -p                                                             "$PKGFILES"/matlab/preprocessor64
 ln -sf ../../preprocessor/dynare-preprocessor                        "$PKGFILES"/matlab/preprocessor64/dynare_m
 
-cp -L  "$ROOTDIR"/mex/matlab/*                                       "$PKGFILES"/mex/matlab/maci64-8.3-9.3
+cp -L  "$ROOTDIR"/build-matlab/*.mexmaci64                           "$PKGFILES"/mex/matlab/maci64-9.4-9.14
+cp -L  "$ROOTDIR"/build-old-matlab/*.mexmaci64                       "$PKGFILES"/mex/matlab/maci64-8.3-9.3
 
 cp -p  "$ROOTDIR"/scripts/dynare.el                                  "$PKGFILES"/scripts
 cp -pr "$ROOTDIR"/contrib/ms-sbvar/TZcode/MatlabFiles                "$PKGFILES"/contrib/ms-sbvar/TZcode
@@ -147,29 +124,6 @@ mkdir -p                                                             "$PKGFILES"
 cp -p  "$ROOTDIR"/macOS/deps/lib64/x13as/x13as                       "$PKGFILES"/matlab/modules/dseries/externals/x13/macOS/64
 
 
-##
-## Create mex for MATLAB ≥ 2018a
-##
-cd "$ROOTDIR"/mex/build/matlab
-make clean
-./configure \
-  PACKAGE_VERSION="$VERSION" \
-  PACKAGE_STRING="dynare $VERSION" \
-  CC=$CC \
-  CXX=$CXX \
-  CPPFLAGS=-I/usr/local/include \
-  LDFLAGS="-static-libgcc -L$QUADMATH_DIR" \
-  --with-gsl="$LIB64"/gsl \
-  --with-matio="$LIB64"/matio \
-  --with-slicot="$LIB64"/Slicot/with-underscore \
-  --with-matlab=/Applications/MATLAB_R2022b.app
-make -j"$NTHREADS"
-cp -L  "$ROOTDIR"/mex/matlab/*                                       "$PKGFILES"/mex/matlab/maci64-9.4-9.14
-
-
-##
-## Make package
-##
 cd "$ROOTDIR"/macOS/pkg
 
 # Dynare option
diff --git a/macOS/deps/Makefile b/macOS/deps/Makefile
index 802119fb15..799553c7fe 100644
--- a/macOS/deps/Makefile
+++ b/macOS/deps/Makefile
@@ -17,7 +17,7 @@
 
 include versions.mk
 
-GCC_VERSION = 13
+GCC_VERSION = $(shell sed -En "/^c[[:space:]]*=/s/c[[:space:]]*=[[:space:]]*'gcc-([0-9]+)'/\1/p" ../../scripts/homebrew-native.ini)
 ROOT_PATH = $(realpath .)
 
 WGET_OPTIONS := --no-verbose --no-use-server-timestamps --retry-connrefused --retry-on-host-error
@@ -30,7 +30,7 @@ WGET_OPTIONS := --no-verbose --no-use-server-timestamps --retry-connrefused --re
 
 all: build
 
-build: build-slicot build-x13as ln-matio ln-gsl
+build: build-slicot build-x13as
 
 clean-lib: clean-libslicot clean-x13as-bin
 
@@ -40,49 +40,6 @@ clean-tar: clean-slicot-tar clean-x13as-tar
 
 clean-all: clean-lib clean-src clean-tar
 
-
-#
-# Matio & GSL
-# (done to link only to static Matio and GSL libraries)
-
-# Matio
-lib64/matio/lib/libmatio.a: /usr/local/lib/libmatio.a
-	mkdir -p $(dir $@) && ln -sf $< $@
-
-lib64/matio/lib/libhdf5.a: /usr/local/lib/libhdf5.a
-	mkdir -p $(dir $@) && ln -sf $< $@
-
-lib64/matio/lib/libsz.a: /usr/local/lib/libsz.a
-	mkdir -p $(dir $@) && ln -sf $< $@
-
-lib64/matio/include/matio.h: /usr/local/include/matio.h
-	mkdir -p $(dir $@) && cd $(dir $@).. && rm -rf include && ln -sf $(dir $<) .
-
-ln-matio: lib64/matio/lib/libmatio.a \
-	lib64/matio/lib/libhdf5.a \
-	lib64/matio/lib/libsz.a \
-	lib64/matio/include/matio.h
-
-clean-matio:
-	rm -rf lib64/matio
-
-# GSL
-lib64/gsl/lib/libgsl.a: /usr/local/lib/libgsl.a
-	mkdir -p $(dir $@) && ln -sf $< $@
-
-lib64/gsl/lib/libgslcblas.a: /usr/local/lib/libgslcblas.a
-	mkdir -p $(dir $@) && ln -sf $< $@
-
-lib64/gsl/include/gsl/gsl_blas.h: /usr/local/include/gsl/gsl_blas.h
-	mkdir -p $(dir $@) && cd $(dir $@).. && rm -rf gsl && ln -sf $(dir $<) .
-
-ln-gsl: lib64/gsl/lib/libgsl.a \
-	lib64/gsl/lib/libgslcblas.a \
-	lib64/gsl/include/gsl/gsl_blas.h
-
-clean-gsl:
-	rm -rf lib64/gsl
-
 #
 # Slicot
 #
@@ -90,38 +47,25 @@ tarballs/slicot-$(SLICOT_VERSION).tar.gz:
 	mkdir -p tarballs
 	wget $(WGET_OPTIONS) -O $@ https://deb.debian.org/debian/pool/main/s/slicot/slicot_$(SLICOT_VERSION).orig.tar.gz
 
-sources64/slicot-$(SLICOT_VERSION)-with-32bit-integer-and-underscore: tarballs/slicot-$(SLICOT_VERSION).tar.gz
-	rm -rf sources64/slicot-*-with-32bit-integer-and-underscore
-	mkdir -p $@
-	tar xf $< --directory $@ --strip-components=1
-	touch $@
-
-sources64/slicot-$(SLICOT_VERSION)-with-64bit-integer-and-underscore: tarballs/slicot-$(SLICOT_VERSION).tar.gz
-	rm -rf sources64/slicot-*-with-64bit-integer-and-underscore
+sources64/slicot-$(SLICOT_VERSION): tarballs/slicot-$(SLICOT_VERSION).tar.gz
+	rm -rf sources64/slicot-*
 	mkdir -p $@
 	tar xf $< --directory $@ --strip-components=1
 	touch $@
 
-lib64/Slicot/with-underscore/lib/libslicot_pic.a: sources64/slicot-$(SLICOT_VERSION)-with-32bit-integer-and-underscore
-	make -C $< FORTRAN=gfortran LOADER=gfortran SLICOTLIB=../libslicot_pic.a OPTS="-O2 -g" lib
-	strip -S $</libslicot_pic.a
-	mkdir -p $(dir $@)
-	cp $</libslicot_pic.a $@
-
-lib64/Slicot/with-underscore/lib/libslicot64_pic.a: sources64/slicot-$(SLICOT_VERSION)-with-64bit-integer-and-underscore
+lib64/Slicot/libslicot64_pic.a: sources64/slicot-$(SLICOT_VERSION)
 	make -C $< FORTRAN=gfortran LOADER=gfortran SLICOTLIB=../libslicot64_pic.a OPTS="-O2 -g -fdefault-integer-8" lib
 	strip -S $</libslicot64_pic.a
 	mkdir -p $(dir $@)
 	cp $</libslicot64_pic.a $@
 
-build-slicot: lib64/Slicot/with-underscore/lib/libslicot_pic.a \
-	lib64/Slicot/with-underscore/lib/libslicot64_pic.a
+build-slicot: lib64/Slicot/libslicot64_pic.a
 
 clean-slicot-tar:
 	rm -f tarballs/slicot-$(SLICOT_VERSION).tar.gz
 
 clean-slicot-src:
-	rm -rf sources64/slicot-$(SLICOT_VERSION)-with-64bit-integer-and-underscore
+	rm -rf sources64/slicot-$(SLICOT_VERSION)
 
 clean-libslicot:
 	rm -rf lib64/Slicot
@@ -153,7 +97,7 @@ lib64/x13as/x13as: sources64/x13as-$(X13AS_VERSION)
 	# gfortran as the linker with -static-libgfortran and
 	# -static-libquadmath flags, and drop the GCC_VERSION variable.
 	cd $< && sed -i '' 's/-static//g' makefile.gf
-	make -C $< -f makefile.gf FC=gfortran LINKER=gcc-$(GCC_VERSION) FFLAGS="-O2 -std=legacy" LDFLAGS=-static-libgcc LIBS="/usr/local/lib/gcc/current/libgfortran.a /usr/local/lib/gcc/current/libquadmath.a" PROGRAM=x13as
+	make -C $< -f makefile.gf FC=gfortran LINKER=gcc-$(GCC_VERSION) FFLAGS="-O2 -std=legacy" LDFLAGS=-static-libgcc LIBS="/usr/local/lib/gcc/$(GCC_VERSION)/libgfortran.a /usr/local/lib/gcc/$(GCC_VERSION)/libquadmath.a" PROGRAM=x13as
 	strip $</x13as
 	mkdir -p $(dir $@)
 	cp $</x13as $@
diff --git a/scripts/homebrew-native.ini b/scripts/homebrew-native.ini
index f00b7712ff..e1622b7ffa 100644
--- a/scripts/homebrew-native.ini
+++ b/scripts/homebrew-native.ini
@@ -8,4 +8,4 @@ bison = '/usr/local/opt/bison/bin/bison'
 
 [built-in options]
 cpp_args = [ '-I/usr/local/include', '-B', '/usr/local/lib' ]
-fortran_args = [ '-B', '/Users/sebastien/slicot' ]
+#fortran_args = [ '-B', '/Users/sebastien/slicot' ]
-- 
GitLab