From 83e1b307d29c09e4c386973c8f77795859f71b8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Wed, 20 Sep 2023 15:13:55 +0200 Subject: [PATCH] Update build instructions for Meson --- CONTRIBUTING.md | 6 +- README.md | 223 ++++++++++++++++++------------------------------ 2 files changed, 88 insertions(+), 141 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9b0a2c788..4042cbde7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -92,9 +92,9 @@ The output from the latest run of the test suite can be found in the `test_matla It’s useful to contribute `.mod` files that test some aspect of Dynare that is not currently tested. A `.mod` file that runs into a bug is perfect. As the test suite currently takes several hours to run, we prefer you modify a current test to also create the bug you’ve found. If you can’t do that, please add a new test that runs as quickly as possible. It will contain only those commands necessary to create the bug, nothing more. To contribute a test, after having made an issue and cloned and forked the repository as described above, do the following: -1. Modify the `MODFILES` variable in `tests/Makefile.am` with a line containing your test file name -1. If any ancillary files are needed to run your test, please include them in the `EXTRA_DIST` variable in `tests/Makefile.am` -1. Add and commit your test file and `tests/Makefile.am` as described above +1. Modify the `mod_and_m_tests` variable in `meson.build` with a entry containing your test file name +1. If any ancillary files are needed to run your test, please include them in the `'extra'` field +1. Add and commit your test file and `meson.build` as described above 1. Push and create a pull request as described above ### Unit tests diff --git a/README.md b/README.md index 74668565e..4bd79bf59 100644 --- a/README.md +++ b/README.md @@ -33,8 +33,6 @@ This source can be retrieved in three forms: - using the stable source archive of the latest Dynare version from - using a source snapshot of the unstable version, also from -Note that if you obtain the source code via git, you will need to install more tools (see below). - The first section of this page gives general instructions, which apply to all platforms. Then some specific platforms are discussed. **Note:** Here, when we refer to 32-bit or 64-bit, we refer to the type of @@ -66,28 +64,27 @@ a 32-bit Octave. A number of tools and libraries are needed in order to recompile everything. You don't necessarily need to install everything, depending on what you want to compile. -- A POSIX compliant shell and an implementation of Make (mandatory) - The [GNU Compiler Collection](https://gcc.gnu.org/), version 10 or later, with - gcc, g++ and gfortran (mandatory) + gcc, g++ and gfortran - [MATLAB](https://mathworks.com) (if you want to compile the MEX for MATLAB) - [GNU Octave](https://www.octave.org) with - the development headers (if you want to compile the MEX for Octave) - - the development libraries corresponding to the [UMFPACK](https://people.engr.tamu.edu/davis/suitesparse.html) packaged with Octave + - the development libraries corresponding to the [UMFPACK](https://people.engr.tamu.edu/davis/suitesparse.html) packaged with Octave (if you want to compile the MEX for Octave) - Optionally, the [Control](https://octave.sourceforge.io/control/), [IO](https://octave.sourceforge.io/io/), [Optimization](https://octave.sourceforge.io/optim/) and [Statistics](https://octave.sourceforge.io/statistics/) package either installed via your package manager or through [Octave Forge](https://octave.sourceforge.io/). +- [Meson](https://mesonbuild.com), version 0.64.0 or later +- [Pkgconf](http://pkgconf.org/), or another pkg-config implementation +- [Bash](https://www.gnu.org/software/bash/) - [Boost libraries](https://www.boost.org), version 1.36 or later -- [Bison](https://www.gnu.org/software/bison/), version 3.2 or later (only if you get the source through Git) -- [Flex](https://github.com/westes/flex), version 2.5.4 or later (only if you get the source through Git) -- [Autoconf](https://www.gnu.org/software/autoconf/), version 2.62 or later (only if you get the source through Git) -- [Automake](https://www.gnu.org/software/automake/), version 1.11.2 or later (only if you get the source through Git) -- [MAT File I/O library](https://sourceforge.net/projects/matio/), version 1.5 or later (if you want to compile Markov-Switching SBVAR code) -- [SLICOT](http://www.slicot.org) (if you want to compile the Kalman steady state DLL) -- [GSL library](https://www.gnu.org/software/gsl/) (if you want to compile Markov-Switching SBVAR code) +- [Bison](https://www.gnu.org/software/bison/), version 3.2 or later +- [Flex](https://github.com/westes/flex), version 2.5.4 or later +- [MAT File I/O library](https://sourceforge.net/projects/matio/), version 1.5 or later (only when compiling for Octave) +- [SLICOT](http://www.slicot.org) +- [GSL library](https://www.gnu.org/software/gsl/) - A decent LaTeX distribution (if you want to compile PDF documentation), ideally with Beamer - For building the reference manual: - [Sphinx](https://www.sphinx-doc.org/) - [MathJax](https://www.mathjax.org/) -- [Doxygen](https://www.doxygen.nl) (if you want to build Dynare preprocessor source documentation) - [X-13ARIMA-SEATS Seasonal Adjustment Program](https://www.census.gov/data/software/x13as.html) ### Preparing the sources @@ -99,99 +96,68 @@ have the [Git LFS](https://git-lfs.github.com/) extension installed): ```sh git clone --recurse-submodules https://git.dynare.org/Dynare/dynare.git cd dynare -autoreconf -si ``` -The last line runs Autoconf and Automake in order to prepare the build environment (this is not necessary if you got the sources from an official source archive or the source snapshot). If you want a certain version (e.g. 5.x) , then add `--single-branch --branch 5.x` to the git clone command. +If you want a certain version (e.g. 5.x) , then add `--single-branch --branch 5.x` to the git clone command. -### Configuring the build tree +### Configuring the build directory -Simply launch the configure script from a terminal: +If you want to compile for MATLAB, please run the following (after adapting the path to MATLAB): ```sh -./configure --with-matlab=<…> +meson setup -Dmatlab_path=/usr/local/MATLAB/R2023a -Dbuildtype=debugoptimized build-matlab ``` -where the path to MATLAB is specified. +The build directory will thus be `build-matlab`. -Some important options: - -- `--disable-matlab`: skip the compilation of MEX files for MATLAB -- `--disable-octave`: skip the compilation of MEX files for Octave -- `--disable-doc`: skip the compilation of the documentation (PDF and HTML) - -You may need to specify additional options to the configure script, see the output of the `--help` option, and also the platform specific instructions below. If the configuration goes well, the script will tell you which components are correctly configured and will be built. - -Note that it is possible that some MEX files cannot be compiled, due to missing -build dependencies. If you find no way of installing the missing dependencies, -a workaround can be to give up on compiling these MEX files and rather use -slower implementations (in the MATLAB/Octave language) that are available under -the `matlab/missing/mex/` subdirectories. For example, if you fail to compile -the gensylv MEX, you can type the following at the MATLAB/Octave prompt before -running Dynare: -```matlab -addpath /matlab/missing/mex/gensylv +Or for Octave: +```sh +meson setup -Dbuild_for=octave -Dbuildtype=debugoptimized build-octave ``` -(where you need to replace `` with the full path to your Dynare copy). +The build directory will thus be `build-octave`. + +Note that if you do not chose `build-matlab` (under MATLAB) or `build-octave` +(under Octave) as the build directory, you will need to set the environment +variable `DYNARE_BUILD_DIR` to the full path of your build tree, before running +MATLAB or Octave, if you want Dynare to be able to find the preprocessor and +the MEX files. + +It is possible to specify various Meson options, see the Meson documentation +for more details. Modifying options of an existing build directory can be +done using the `meson configure` command. ### Building -Binaries are built with: +For compiling the preprocessor and the MEX files: ```sh -make +meson compile -C ``` -PDF and HTML documentation are respectively built with: +where `` is the build directory, typically either `build-matlab` or `build-octave`. + +PDF and HTML documentation can be built with: ```sh -make pdf -make html +meson compile -C doc ``` ### Check -The Git source comes with unit tests (in the MATLAB functions) and integration tests (under the `tests` subfolder). All the tests can be run with: +Dynare comes with unit tests (in the MATLAB functions) and integration tests (under the `tests` subfolder). All the tests can be run with: ```sh -make check -``` -in the `tests` subfolder. If Dynare has been compiled against MATLAB and Octave, the tests will be run with both MATLAB and Octave. Depending on the performance of your machine, this can take several hours. It is possible to run the tests only with MATLAB: -```sh -make check-matlab -``` -or only with Octave: -```sh -make check-octave +meson test -C ``` + +Depending on the performance of your machine, this can take several hours. + Note that running the testsuite with Octave requires the additional packages `pstoedit`, `epstool`, `xfig`, and `gnuplot`. -A summary of the results is available in `tests/run_test_matlab_output.txt` or `tests/run_test_octave_output.txt`. Often, it does not make sense to run the complete testsuite. For instance, if you modify codes only related to the perfect foresight model solver, you can decide to run only a subset of the integration tests, with: +Often, it does not make sense to run the complete testsuite. For instance, if you modify codes only related to the perfect foresight model solver, you can decide to run only a subset of the integration tests, with: ```sh -make deterministic_simulations +meson test -C deterministic_simulations ``` -This will run all the integration tests in `tests/deterministic_simulations` with MATLAB and Octave. Again, it is possible to do this only with MATLAB: +This will run all the integration tests in `tests/deterministic_simulations`. + +Finally if you want to run a single integration test, e.g. `deterministic_simulations/lbj/rbc.mod`: ```sh -make m/deterministic_simulations +meson test -C deterministic_simulations/lbj/rbc.mod ``` -or with Octave: -```sh -make o/deterministic_simulations -``` -Finally if you want to run a single integration test, e.g. `deterministic_simulations/lbj/rbc.mod` with MATLAB: -```sh -make deterministic_simulations/lbj/rbc.m.trs -``` -or with Octave: -```sh -make deterministic_simulations/lbj/rbc.o.trs -``` -The result of the test (`PASSED` or `FAILED`) will be printed in the terminal, the produced log can be displayed with: -```sh -make deterministic_simulations/lbj/rbc.m.drs -``` -or -```sh -make deterministic_simulations/lbj/rbc.o.drs -``` -Note that only tests will be executed where the `m.trs/o.trs` does not yet exist. You can run -```sh -make clean -``` -in the `tests` folder to delete files that were created by the run of the testsuite. You can also manually delete the desired `m.trs/o.trs` file(s). +NB: Some individual tests cannot be run using that syntax, if they are a dependency in a chain of tests (see the `mod_and_m_tests` variable `meson.build`); in that case, you should use the name of the last `.mod` file in the chain as the test name to be passed to `meson test`. ## Debian or Ubuntu @@ -200,7 +166,6 @@ All the prerequisites are packaged: - `gcc` - `g++` - `gfortran` -- `make` - `octave-dev` (or `liboctave-dev` on older Debian/Ubuntu releases) - `libboost-graph-dev` - `libgsl-dev` @@ -209,39 +174,31 @@ All the prerequisites are packaged: - `libsuitesparse-dev` - `flex` and `libfl-dev` - `bison` -- `autoconf` -- `automake` +- `meson` +- `pkgconf` - `texlive` - `texlive-publishers` (for Econometrica bibliographic style) - `texlive-latex-extra` (for fullpage.sty) - `texlive-fonts-extra` (for ccicons) - `texlive-science` (for amstex) -- `texlive-plain-generic` - `lmodern` (for macroprocessor PDF) - `python3-sphinx` - `tex-gyre` - `latexmk` - `libjs-mathjax` -- `doxygen` - `x13as` You can install them all at once with: ```sh -apt install gcc g++ gfortran make octave-dev libboost-graph-dev libgsl-dev libmatio-dev libslicot-dev libslicot-pic libsuitesparse-dev flex libfl-dev bison autoconf automake texlive texlive-publishers texlive-latex-extra texlive-fonts-extra texlive-science texlive-plain-generic lmodern python3-sphinx tex-gyre latexmk libjs-mathjax doxygen x13as +apt install gcc g++ gfortran octave-dev libboost-graph-dev libgsl-dev libmatio-dev libslicot-dev libslicot-pic libsuitesparse-dev flex libfl-dev bison meson pkgconf texlive texlive-publishers texlive-latex-extra texlive-fonts-extra texlive-science lmodern python3-sphinx make tex-gyre latexmk libjs-mathjax x13as ``` If you use MATLAB, we strongly advise to also `apt install matlab-support` and confirm to rename the GCC libraries shipped with MATLAB to avoid possible conflicts with GCC libraries shipped by your distribution. -Tested on -- Debian “Buster” 10 -- Debian “Bullseye” 11 -- Ubuntu 20.04 -- Ubuntu 20.10 - ## Fedora, CentOS or RHEL Almost all prerequisites are packaged: -- `gcc`, `gcc-c++`, `make` +- `gcc`, `gcc-c++` - `gcc-gfortran` - `boost-devel` - `gsl-devel` @@ -249,24 +206,23 @@ Almost all prerequisites are packaged: - `suitesparse-devel` - `flex` - `bison` -- `autoconf` -- `automake` +- `meson` - `redhat-rpm-config` - `octave`, `octave-devel`, `octave-statistics`, `octave-io`, `octave-optim`, `octave-control` - `texlive-scheme-minimal`, `texlive-collection-publishers`, `texlive-collection-latexextra`, `texlive-collection-fontsextra`, `texlive-collection-latexrecommended`, `texlive-collection-science`, `texlive-collection-plaingeneric`, `texlive-lm` - `python3-sphinx` - `latexmk` - `mathjax` -- `doxygen` +- `make` (for building Slicot) You can install them all at once with: ```sh -# Minimal packages (use --disable-doc and --disable-octave flags) -dnf install -y gcc gcc-c++ make gcc-gfortran boost-devel gsl-devel matio-devel suitesparse-devel flex bison autoconf automake redhat-rpm-config -# Octave packages (use --disable-doc flag) +# Minimal packages +dnf install -y gcc gcc-c++ make gcc-gfortran boost-devel gsl-devel matio-devel suitesparse-devel flex bison meson redhat-rpm-config +# Octave packages dnf install octave octave-devel octave-statistics octave-io octave-optim octave-control -# Documentation packages -dnf install texlive-scheme-minimal texlive-collection-publishers texlive-collection-latexextra texlive-collection-fontsextra texlive-collection-latexrecommended texlive-collection-science texlive-collection-plaingeneric texlive-lm python3-sphinx latexmk mathjax doxygen +# Documentation packages (only needed if you build documentation) +dnf install texlive-scheme-minimal texlive-collection-publishers texlive-collection-latexextra texlive-collection-fontsextra texlive-collection-latexrecommended texlive-collection-science texlive-collection-plaingeneric texlive-lm python3-sphinx latexmk mathjax ``` In Fedora these are available from the default repositories; whereas for CentOS and RHEL you need to enable the [Extra Packages for Enterprise Linux (EPEL)](https://fedoraproject.org/wiki/EPEL) repository and either the PowerTools repository for CentOS or the CodeReady Linux Builder repository for RHEL: ```sh @@ -277,7 +233,7 @@ dnf config-manager --set-enabled PowerTools ARCH=$( /bin/arch ) subscription-manager repos --enable "codeready-builder-for-rhel-8-${ARCH}-rpms" ``` -The documentation packages have slightly different names in CentOS and RHEL, you can also choose to pass the `--disable-doc` flag to your configure script to skip these dependencies. +The documentation packages have slightly different names in CentOS and RHEL, but this should only impact you if you build the documentation. `Slicot` and `x13as` need to be compiled from source: @@ -288,10 +244,13 @@ cd /home/$USER/dynare/slicot wget https://deb.debian.org/debian/pool/main/s/slicot/slicot_5.0+20101122.orig.tar.gz tar xf slicot_5.0+20101122.orig.tar.gz cd slicot-5.0+20101122 -make FORTRAN=gfortran OPTS="-O2 -fPIC -fdefault-integer-8" LOADER=gfortran lib mkdir -p /home/$USER/dynare/slicot/lib -cp slicot.a /home/$USER/dynare/slicot/lib/libslicot64_pic.a #for matlab -cp slicot.a /home/$USER/dynare/slicot/lib/libslicot_pic.a #for octave +# The following two lines are only for MATLAB +make FORTRAN=gfortran OPTS="-O2 -fPIC -fdefault-integer-8" LOADER=gfortran lib +cp slicot.a /home/$USER/dynare/slicot/lib/libslicot64_pic.a +# The following two lines are only for Octave +make FORTRAN=gfortran OPTS="-O2 -fPIC" LOADER=gfortran lib +cp slicot.a /home/$USER/dynare/slicot/lib/libslicot_pic.a # compile x13as from source and put it into /usr/bin/ mkdir -p /home/$USER/dynare/x13as @@ -305,17 +264,16 @@ sudo cp x13as /usr/bin/ If you use MATLAB, we strongly advise to also rename or exclude the GCC libraries shipped with MATLAB to avoid possible conflicts with GCC libraries shipped by Fedora, see e.g. [Matlab on Fedora 33](https://mutschler.eu/linux/install-guides/fedora-post-install/#matlab) or [MATLAB-ArchWiki](https://wiki.archlinux.org/index.php/MATLAB) for instructions. -Keep in mind to use the `--with-slicot` option to the configure command, e.g.: +Now use the following commands if using MATLAB (adapt them for Octave, see above): ```sh cd /home/$USER/dynare git clone --recurse-submodules https://git.dynare.org/dynare/dynare.git unstable cd unstable -autoreconf -si -./configure --with-slicot=/home/$USER/dynare/slicot --with-matlab=/usr/local/MATLAB/R2020b -make -j$(($(nproc)+1)) #rule of thumb: one more than CPUs as shown by e.g. lscpu +meson setup -Dmatlab_path=/usr/local/MATLAB/R2020b -Dfortran_args="[ '-B', '/home/$USER/dynare/slicot']" -Dbuildtype=debugoptimized build-matlab +meson compile -C build-matlab ``` -If your distribution ships an older version of `bison`, compile it from source and append it *temporarily* to your path before calling the configure script: +If your distribution ships an older version of `bison`, compile it from source and append it *temporarily* to your path before running meson: ```sh bison --version # bison (GNU Bison) 3.0.4 mkdir -p /home/$USER/dynare/bison @@ -331,12 +289,6 @@ bison --version # bison (GNU Bison) 3.6.4 ``` Now configure dynare as above. -Tested on -- CentOS 8 -- Fedora Workstation 32 -- Fedora Workstation 33 -- Red Hat Enterprise Linux 8 - ## Windows - Install [MSYS2](http://www.msys2.org) @@ -350,9 +302,9 @@ pacman -Syu window to complete the upgrade. - Install all needed dependencies: ```sh -pacman -S git autoconf automake-wrapper bison flex make tar texinfo mingw-w64-x86_64-gcc mingw-w64-x86_64-gcc-fortran mingw-w64-x86_64-boost mingw-w64-x86_64-gsl mingw-w64-x86_64-matio +pacman -S git meson bison flex make tar mingw-w64-x86_64-gcc mingw-w64-x86_64-gcc-fortran mingw-w64-x86_64-boost mingw-w64-x86_64-gsl mingw-w64-x86_64-matio ``` -- Compile and install SLICOT, needed for the `kalman_steady_state` MEX file +- Compile and install SLICOT ```sh wget https://deb.debian.org/debian/pool/main/s/slicot/slicot_5.0+20101122.orig.tar.gz tar xf slicot_5.0+20101122.orig.tar.gz @@ -366,11 +318,10 @@ cd .. ```sh git clone --recurse-submodules https://git.dynare.org/Dynare/dynare.git cd dynare -autoreconf -si ``` - Configure Dynare from the source directory: ```sh -./configure --with-slicot=/usr/local --with-matlab=<…> --disable-octave --disable-doc +meson setup -Dmatlab_path=<…> -Dbuildtype=debugoptimized -Dprefer_static=true -Dfortran_args="['-B','/usr/local/lib']" build-matlab ``` where the path of MATLAB is specified. Note that you should use the MSYS2 notation and not put spaces in the MATLAB path, so you probably want @@ -380,11 +331,11 @@ does not have short filenames (8dot3), then you can run `mkdir -p then pass `/usr/local/MATLAB/…` as MATLAB path to the configure script. - Compile: ```sh -make +meson compile -C build-matlab ``` - Run the testsuite: ```sh -make -C tests check-matlab +meson test -C build-matlab ``` **Note:** The above assumes that you have a 64-bit version of MATLAB. It can be @@ -456,21 +407,18 @@ export PATH="$BREWDIR/bin:$PATH" - Install required Homebrew packages and link sphinx-doc: ```sh -arch -$ARCH $BREWDIR/bin/brew install automake bison flex boost gcc gsl libmatio veclibfort octave sphinx-doc docutils wget +arch -$ARCH $BREWDIR/bin/brew install meson bison flex boost gcc gsl libmatio veclibfort octave sphinx-doc docutils wget ``` -If you want to compile the documentation, you need to link sphinx-doc: +If you want to build the documentation, you need to link sphinx-doc: ```sh arch -$ARCH $BREWDIR/bin/brew link --force sphinx-doc ``` -Otherwise add `--disable-doc` flag to the `configure` command below, if you want to skip this. -- Install [MacTeX](http://www.tug.org/mactex/index.html) using the universal installer. MacTeX runs natively on both ARM and Intel machines. On Apple Silicon, it is advised to symlink `pdflatex` and `bibtex` into `/usr/local/bin`: +- Install [MacTeX](http://www.tug.org/mactex/index.html) using the universal installer, if you want to build the documentation. MacTeX runs natively on both ARM and Intel machines. On Apple Silicon, it is advised to symlink `pdflatex` and `bibtex` into `/usr/local/bin`: ```sh sudo ln -s /Library/TeX/texbin/pdflatex /usr/local/bin/pdflatex sudo ln -s /Library/TeX/texbin/bibtex /usr/local/bin/bibtex ``` -Alternatively, if you don’t want to install MacTeX, you should pass the `--disable-doc` flag to the `configure` command below. - - Install MATLAB and additional toolboxes. We recommend, but don't require, the following: Optimization, Global Optimization, Statistics and Machine Learning, Econometrics, and Control System. For Apple Silicon: MATLAB offers a native Apple silicon version of R2022b as an open beta. You can sign up and install it (including a suitable Java 8 JRE, e.g. Amazon Corretto 8) using @@ -484,7 +432,7 @@ Don't forget to run MATLAB at least once to make sure you have a valid license. export DYNAREDIR=$HOME/dynare ``` -- Compile and install SLICOT, needed for e.g. the `kalman_steady_state` MEX file. +- Compile and install SLICOT ```sh mkdir -p $DYNAREDIR/slicot/lib cd $DYNAREDIR/slicot @@ -523,27 +471,26 @@ folder where you want Dynare installed. mkdir -p $DYNAREDIR/unstable git clone --recurse-submodules https://git.dynare.org/Dynare/dynare.git $DYNAREDIR/unstable cd $DYNAREDIR/unstable -arch -$ARCH autoreconf -si ``` You can also choose a specific version of Dynare by checking out the corresponding branch or a specific tag with git. - Configure Dynare from the source directory: ```sh -arch -$ARCH ./configure --prefix=$BREWDIR CC=gcc-13 CXX=g++-13 CPPFLAGS=-I$BREWDIR/include LDFLAGS=-L$BREWDIR/lib LEX=$BREWDIR/opt/flex/bin/flex YACC=$BREWDIR/opt/bison/bin/bison --with-slicot=$DYNAREDIR/slicot --with-matlab=/Applications/MATLAB_R2022b_Beta.app +arch -$ARCH meson setup --native-file scripts/homebrew-native.ini -Dmatlab_path=/Applications/MATLAB_R2022b_Beta.app -Dbuildtype=debugoptimized -Dfortran_args="['-B','$DYNAREDIR/slicot/lib']" build-matlab ``` -where you need to adapt the path to MATLAB. If you don’t have MATLAB, simply replace `--with-matlab=<…>` by `--disable-matlab`. -Similarly, if you don't want to compile for Octave add a `--disable-octave` flag. -Check the output of the command whether Dynare is configured for building everything except the internal docs of Dynare and M2HTML. +where you need to adapt the path to MATLAB. +Similarly, if you don't want to compile for Octave, replace the `-Dmatlab_path` option by `-Dbuild_for=octave`, and change the build directory to `build-octave`. - Compile: ```sh -arch -$ARCH make -j$(sysctl -n hw.ncpu) +arch -$ARCH meson compile -C ``` +where `` is either `build-matlab` or `build-octave`. + If no errors occured, you are done. Dynare is now ready to use. If you additionally want to compile the documentation run: ```sh -arch -$ARCH make pdf -arch -$ARCH make html +arch -$ARCH meson compile -C doc ``` ### Optional: pass the full PATH to MATLAB to run system commands