From 096936be9c50a661dd0282b783487c8b34d63ce1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Mon, 29 Oct 2018 14:41:34 +0100
Subject: [PATCH] The preprocessor now compiles the MEX when use_dll is
 specified

Update documentation accordingly (except on macOS where the solution has not
yet been implemented).

Also include MinGW in the Windows installer.
---
 Makefile.am                        |   2 -
 doc/dynare.texi                    |  42 +++--------
 matlab/dynare.m                    |   9 +++
 matlab/utilities/general/dyn_mex.m | 116 -----------------------------
 preprocessor                       |   2 +-
 windows/dynare.nsi                 |  20 ++++-
 windows/mexopts-win32.bat          |  67 -----------------
 windows/mexopts-win64.bat          |  67 -----------------
 8 files changed, 36 insertions(+), 289 deletions(-)
 delete mode 100644 matlab/utilities/general/dyn_mex.m
 delete mode 100644 windows/mexopts-win32.bat
 delete mode 100644 windows/mexopts-win64.bat

diff --git a/Makefile.am b/Makefile.am
index 14561aaffd..1bb82885a5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -27,8 +27,6 @@ EXTRA_DIST = \
 	COPYING \
 	CONTRIBUTING.md \
 	windows/dynare.nsi \
-	windows/mexopts-win32.bat \
-	windows/mexopts-win64.bat \
 	windows/README.txt \
 	osx \
 	examples \
diff --git a/doc/dynare.texi b/doc/dynare.texi
index 6e1186af04..434fddaaa2 100644
--- a/doc/dynare.texi
+++ b/doc/dynare.texi
@@ -593,36 +593,29 @@ Octave comes with built-in functionality for compiling mex-files.
 @node Prerequisites on Windows
 @subsection Prerequisites on Windows
 
-If you are using MATLAB under Windows, install a C++ compiler on your machine and configure it with
-MATLAB. There are at least two free compilers you can use. First, there is Microsoft's Visual Studio 
-Community (@uref{https://www.visualstudio.com/}), which has the largest history of MATLAB support, but 
-requires much space on the hard-disk. Second, since MATLAB R2015b, MATLAB supports the MinGW-w64 C/C++ 
-Compiler from TDM-GCC. To install this compiler, use the Add-Ons menu of MATLAB. Search for MinGW or 
-select it from Features. 
-
-For older version of MATLAB, in particular before R2014a, it may sometimes make sense to use the gcc compiler 
-provided by Cygwin. However, integrating it in MATLAB can be quite cumbersome and should be considered as a
-legacy option. For details, see
-@uref{http://www.dynare.org/DynareWiki/ConfigureMatlabWindowsForMexCompilation,instructions
-on the Dynare wiki}. 
+There is no prerequisite on Windows. Dynare now ships a compilation environment
+that can be used with the @code{use_dll} option.
 
 @node Prerequisites on Debian GNU/Linux and Ubuntu
 @subsection Prerequisites on Debian GNU/Linux and Ubuntu
 
-Users of MATLAB under Linux need to have a working compilation environment installed. If not already present,
-it can be installed via @code{apt-get install build-essential}.
+Users of MATLAB under GNU/Linux need a working compilation environment
+installed. If not already present, it can be installed via @code{apt install
+build-essential}.
 
-Users of Octave under Linux should install the package for MEX file compilation 
+Users of Octave under GNU/Linux should install the package for MEX file compilation
 (under Debian or Ubuntu, it is called @file{liboctave-dev}).
 
 @node Prerequisites on macOS
 @subsection Prerequisites on macOS
+
+[TO BE UPDATED]
+
 If you are using MATLAB under macOS, you should install the latest
 version of XCode: see
 @uref{http://www.dynare.org/DynareWiki/InstallOnMacOSX,instructions on
 the Dynare wiki}.
 
-
 @node Configuration
 @section Configuration
 
@@ -917,23 +910,6 @@ command).
 Prevent Dynare from printing the output of the steps leading up to the
 preprocessor as well as the preprocessor output itself.
 
-@item mingw
-Tells Dynare that your MATLAB is configured for compiling MEX files with the
-MinGW-compiler from TDM-GCC (@pxref{Compiler installation}). This option is
-only available under Windows, and is used in conjunction with
-@code{use_dll}.
-
-@item msvc
-Tells Dynare that your MATLAB is configured for compiling MEX files with
-Microsoft Visual C++ (@pxref{Compiler installation}). This option is
-only available under Windows, and is used in conjunction with
-@code{use_dll}.
-
-@item cygwin
-Tells Dynare that your MATLAB is configured for compiling MEX files with
-Cygwin (@pxref{Compiler installation}). This option is only available
-under Windows, and is used in conjunction with @code{use_dll}.
-
 @item parallel[=@var{CLUSTER_NAME}]
 Tells Dynare to perform computations in parallel. If @var{CLUSTER_NAME}
 is passed, Dynare will use the specified cluster to perform parallel
diff --git a/matlab/dynare.m b/matlab/dynare.m
index 369c43b9c1..4e347f1a0b 100644
--- a/matlab/dynare.m
+++ b/matlab/dynare.m
@@ -226,6 +226,7 @@ if regexp(firstline, '\s*\/\/', 'once') == 1
 end
 
 command = ['"' dynareroot 'preprocessor' arch_ext filesep 'dynare_m" ' fname] ;
+command = [ command ' mexext=' mexext ' "matlabroot=' matlabroot '"'];
 for i=1:length(varargin)
     command = [command ' ' varargin{i}];
 end
@@ -240,6 +241,14 @@ if preprocessoroutput
     end
 end
 
+% Under Windows, make sure the MEX file is unloaded (in the use_dll case),
+% otherwise the preprocessor can't recompile it
+if isoctave
+  clear([fname(1:end-4) '.static'], [fname(1:end-4) '.dynamic'])
+else
+  clear(['+' fname(1:end-4) '/static'], ['+' fname(1:end-4) '/dynamic'])
+end
+
 [status, result] = system(command);
 if status ~= 0 || preprocessoroutput
     disp(result)
diff --git a/matlab/utilities/general/dyn_mex.m b/matlab/utilities/general/dyn_mex.m
deleted file mode 100644
index 185e061f5e..0000000000
--- a/matlab/utilities/general/dyn_mex.m
+++ /dev/null
@@ -1,116 +0,0 @@
-function dyn_mex(win_compiler,basename,force)
-
-% Compile Dynare model dlls when model option use_dll is used
-% if C file is fresher than mex file
-%
-% INPUTS
-%  o win_compiler  str  compiler used under Windows (unused under Linux or OSX):
-%                       'msvc' (MS Visual C)
-%                        'cygwin'
-%  o basename      str  filenames base
-%  o force         bool recompile if 1
-%
-% OUTPUTS
-%  none
-%
-
-
-% Copyright (C) 2015-2017 Dynare Team
-%
-% This file is part of Dynare.
-%
-% Dynare is free software: you can redistribute it and/or modify
-% it under the terms of the GNU General Public License as published by
-% the Free Software Foundation, either version 3 of the License, or
-% (at your option) any later version.
-%
-% Dynare is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
-
-Dc = dir([basename '/mode/src/dynamic.c']);
-Dmex = dir(['+' basename '/model/dynamic.' mexext]);
-
-% compile only if date of C file is greater than date of mex file
-% and force is not True
-if ~isempty(Dmex)
-    if (Dmex.datenum > Dc.datenum) && ~force
-        disp('Mex files are newer than the source: not recompiled')
-        return
-    end
-end
-
-if ~isoctave
-    % Some mex commands are enclosed in an eval(), because otherwise it will make Octave fail
-    if ispc
-        if strcmp(win_compiler,'msvc')
-            % MATLAB/Windows + Microsoft Visual C++
-            % Add /TP flag as fix for #1227
-            eval(['mex -O LINKFLAGS="$LINKFLAGS /export:Dynamic" COMPFLAGS="/TP" ' basename '/model/src/dynamic.c ' basename '/model/src/dynamic_mex.c -output +' basename '/dynamic'])
-            eval(['mex -O LINKFLAGS="$LINKFLAGS /export:Static" COMPFLAGS="/TP" ' basename '/model/src/static.c ' basename '/model/src/static_mex.c -output +' basename '/static'])
-        elseif strcmp(win_compiler,'mingw')
-            eval(['mex -O LINKFLAGS="$LINKFLAGS /export:Dynamic" ' basename '/model/src/dynamic.c ' basename '/model/src/dynamic_mex.c -output +' basename '/dynamic'])
-            eval(['mex -O LINKFLAGS="$LINKFLAGS /export:Static"  ' basename '/model/src/static.c ' basename '/model/src/static_mex.c -output +' basename '/static'])
-        elseif strcmp(win_compiler,'cygwin') %legacy support for Cygwin with mexopts.bat
-                                             % MATLAB/Windows + Cygwin g++
-            eval(['mex -O PRELINK_CMDS1="echo EXPORTS > mex.def & echo ' ...
-                  'mexFunction >> mex.def & echo Dynamic >> mex.def" ' ...
-                  basename '/model/src/dynamic.c ' basename '/model/src/dynamic_mex.c -output +' basename '/dynamic'])
-            eval(['mex -O PRELINK_CMDS1="echo EXPORTS > mex.def & echo ' ...
-                  'mexFunction >> mex.def & echo Dynamic >> mex.def" ' ...
-                  basename '/model/src/static.c ' basename '/model/src/static_mex.c -output +' basename '/static'])
-        else
-            error(['When using the USE_DLL option, you must give either ' ...
-                   '''cygwin'', ''mingw'' or ''msvc'' option to the ''dynare'' command'])
-        end
-    elseif isunix && ~ismac
-        % MATLAB/Linux
-        if matlab_ver_less_than('8.3')
-            eval(['mex -O LDFLAGS=''-pthread -shared -Wl,--no-undefined'' ' ...
-                  basename '/model/src/dynamic.c ' basename '/model/src/dynamic_mex.c -output +' basename '/dynamic'])
-            eval(['mex -O LDFLAGS=''-pthread -shared -Wl,--no-undefined'' ' ...
-                  basename '/model/src/static.c ' basename '/model/src/static_mex.c -output +' basename '/static'])
-        elseif matlab_ver_less_than('9.1')
-            eval(['mex -O LINKEXPORT='''' ' basename '/model/src/dynamic.c ' basename '/model/src/dynamic_mex.c -output +' basename '/dynamic'])
-            eval(['mex -O LINKEXPORT='''' ' basename '/model/src/static.c ' basename '/model/src/static_mex.c -output +' basename '/static'])
-        else
-            eval(['mex -O LINKEXPORTVER='''' ' basename '/model/src/dynamic.c ' basename '/model/src/dynamic_mex.c -output +' basename '/dynamic'])
-            eval(['mex -O LINKEXPORTVER='''' ' basename '/model/src/static.c ' basename '/model/src/static_mex.c -output +' basename '/static'])
-        end
-    elseif ismac
-        % MATLAB/MacOS
-        if matlab_ver_less_than('8.1')
-            eval(['mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined ' ...
-                  'error -arch $ARCHS -Wl,-syslibroot,$SDKROOT ' ...
-                  '-mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET -bundle'' ' ...
-                  basename '/model/src/dynamic.c ' basename '/model/src/dynamic_mex.c -output +' basename '/dynamic'])
-            eval(['mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined ' ...
-                  'error -arch $ARCHS -Wl,-syslibroot,$SDKROOT ' ...
-                  '-mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET -bundle'' ' ...
-                  basename '/model/src/static.c ' basename '/model/src/static_mex.c -output +' basename '/static'])
-        elseif matlab_ver_less_than('8.3')
-            eval(['mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined ' ...
-                  'error -arch $ARCHS -Wl,-syslibroot,$MW_SDKROOT ' ...
-                  '-mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET -bundle'' ' ...
-                  basename '/model/src/dynamic.c ' basename '/model/src/dynamic_mex.c -output +' basename '/dynamic'])
-            eval(['mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined ' ...
-                  'error -arch $ARCHS -Wl,-syslibroot,$MW_SDKROOT ' ...
-                  '-mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET -bundle'' ' ...
-                  basename '/model/src/static.c ' basename '/model/src/static_mex.c -output +' basename '/static'])
-        elseif matlab_ver_less_than('9.1')
-            eval(['mex -O LINKEXPORT='''' ' basename '/model/src/dynamic.c ' basename '/model/src/dynamic_mex.c -output +' basename '/dynamic'])
-            eval(['mex -O LINKEXPORT='''' ' basename '/model/src/static.c ' basename '/model/src/static_mex.c -output +' basename '/static'])
-        else
-            eval(['mex -O LINKEXPORT='''' LINKEXPORTVER='''' ' basename '/model/src/dynamic.c ' basename '/model/src/dynamic_mex.c -output +' basename '/dynamic'])
-            eval(['mex -O LINKEXPORT='''' LINKEXPORTVER='''' ' basename '/model/src/static.c ' basename '/model/src/static_mex.c -output +' basename '/static'])
-        end
-    end
-else
-    % Octave
-    eval(['mex ' basename '/model/src/dynamic.c ' basename '/model/src/dynamic_mex.c -o +' basename '/dynamic'])
-    eval(['mex ' basename '/model/src/static.c ' basename '/model/src/static_mex.c -o +' basename '/static'])
-end
diff --git a/preprocessor b/preprocessor
index 1c33af4844..4a974bb428 160000
--- a/preprocessor
+++ b/preprocessor
@@ -1 +1 @@
-Subproject commit 1c33af4844557f9a5ce95a1ab6f3e293006c0811
+Subproject commit 4a974bb428d3960aface3e1760b33e169c7c733a
diff --git a/windows/dynare.nsi b/windows/dynare.nsi
index 1a77815d52..1ccf779290 100644
--- a/windows/dynare.nsi
+++ b/windows/dynare.nsi
@@ -54,7 +54,7 @@ Section "Dynare core (preprocessor and M-files)"
  SectionIn RO
 !insertmacro DETERMINE_CONTEXT
  SetOutPath $INSTDIR
- File README.txt ..\NEWS mexopts-win32.bat mexopts-win64.bat ..\license.txt ..\VERSION
+ File README.txt ..\NEWS ..\license.txt ..\VERSION
 
  SetOutPath $INSTDIR\matlab
  File /r ..\matlab\*.m
@@ -124,6 +124,20 @@ SectionEnd
 
 SectionGroupEnd
 
+SectionGroup "MinGW compiler (needed for use_dll option under MATLAB)"
+
+Section "MinGW for 32-bit MATLAB"
+ SetOutPath $INSTDIR\mingw32
+ File /r mingw32\*
+SectionEnd
+
+Section "MinGW for 64-bit MATLAB"
+ SetOutPath $INSTDIR\mingw64
+ File /r mingw64\*
+SectionEnd
+
+SectionGroupEnd
+
 Section "Dynare++ (standalone executable)"
  SetOutPath $INSTDIR\dynare++
  File ..\dynare++\src\dynare++.exe ..\dynare++\extern\matlab\dynare_simul.m ..\dynare++\*.dll
@@ -159,8 +173,6 @@ Section "Uninstall"
  Delete $INSTDIR\README.txt
  Delete $INSTDIR\NEWS
  Delete $INSTDIR\license.txt
- Delete $INSTDIR\mexopts-win32.bat
- Delete $INSTDIR\mexopts-win64.bat
  Delete $INSTDIR\VERSION
  Rmdir /r $INSTDIR\matlab
  Rmdir /r $INSTDIR\contrib
@@ -169,6 +181,8 @@ Section "Uninstall"
  Rmdir /r $INSTDIR\doc
  Rmdir /r $INSTDIR\examples
  Rmdir /r $INSTDIR\scripts
+ Rmdir /r $INSTDIR\mingw32
+ Rmdir /r $INSTDIR\mingw64
  # We don't force deletion of installation directory (with /r), to avoid deleting important files
  Rmdir $INSTDIR
 
diff --git a/windows/mexopts-win32.bat b/windows/mexopts-win32.bat
deleted file mode 100644
index bb154ecf83..0000000000
--- a/windows/mexopts-win32.bat
+++ /dev/null
@@ -1,67 +0,0 @@
-@echo off
-
-rem Compile and link options used for building MEX-files using Cygwin,
-rem for the 32-bit version of MATLAB.
-rem
-rem It makes the assumption that you installed Cygwin in C:\CYGWIN,
-rem and that you installed either the "mingw64-i686-gcc" package.
-rem
-rem This file should be renamed to "mexopts.bat" and copied to:
-rem C:\Documents and Settings\<Username>\Application Data\MathWorks\MATLAB\<MATLAB version>\
-rem
-rem This file only supports C code. It can easily be changed to compile C++
-rem code by replacing "gcc" by "g++" in COMPILER and LINKER, and by adding
-rem "-static-libstdc++" to LINKFLAGS.
-rem You will also need the "mingw64-i686-gcc-g++" package.
-rem
-rem Initial version by Michel Juillard, revised by Sebastien Villemot.
-
-rem Copyright (C) 2009-2013 Dynare Team
-rem
-rem This file is part of Dynare.
-rem
-rem Dynare is free software: you can redistribute it and/or modify
-rem it under the terms of the GNU General Public License as published by
-rem the Free Software Foundation, either version 3 of the License, or
-rem (at your option) any later version.
-rem
-rem Dynare is distributed in the hope that it will be useful,
-rem but WITHOUT ANY WARRANTY; without even the implied warranty of
-rem MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-rem GNU General Public License for more details.
-rem
-rem You should have received a copy of the GNU General Public License
-rem along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
-
-rem ********************************************************************
-rem General parameters
-rem ********************************************************************
-
-set MATLAB=%MATLAB%
-set PATH=%PATH%;c:\cygwin\bin
-set MW_TARGET_ARCH=win32
-
-rem ********************************************************************
-rem Compiler parameters
-rem ********************************************************************
-set COMPILER=i686-w64-mingw32-gcc
-set COMPFLAGS=-c -fexceptions
-set OPTIMFLAGS=-O3
-set DEBUGFLAGS=-g -Wall
-set NAME_OBJECT=-o 
-
-rem ********************************************************************
-rem Linker parameters
-rem ********************************************************************
-set PRELINK_CMDS1=echo EXPORTS > mex.def & echo mexFunction >> mex.def
-set LIBLOC=%MATLAB%\bin\win32\
-set LINKER=i686-w64-mingw32-gcc
-set LINKFLAGS= -static-libgcc -shared mex.def "-L%LIBLOC%"
-set LINKFLAGSPOST= -lmex -lmx -lmwlapack -lmwblas
-set LINKOPTIMFLAGS=-O3
-set LINKDEBUGFLAGS= -g -Wall
-set LINK_FILE=
-set LINK_LIB=
-set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
-set RSP_FILE_INDICATOR=@
-set POSTLINK_CMDS1=del mex.def
diff --git a/windows/mexopts-win64.bat b/windows/mexopts-win64.bat
deleted file mode 100644
index 806bbd839b..0000000000
--- a/windows/mexopts-win64.bat
+++ /dev/null
@@ -1,67 +0,0 @@
-@echo off
-
-rem Compile and link options used for building MEX-files using Cygwin,
-rem for the 64-bit version of MATLAB.
-rem
-rem It makes the assumption that you installed Cygwin in C:\CYGWIN,
-rem and that you installed either the "mingw64-x86_64-gcc" package.
-rem
-rem This file should be renamed to "mexopts.bat" and copied to:
-rem C:\Documents and Settings\<Username>\Application Data\MathWorks\MATLAB\<MATLAB version>\
-rem
-rem This file only supports C code. It can easily be changed to compile C++
-rem code by replacing "gcc" by "g++" in COMPILER and LINKER, and by adding
-rem "-static-libstdc++" to LINKFLAGS.
-rem You will also need the "mingw64-x86_64-gcc-g++" package.
-rem
-rem Initial version by Michel Juillard, revised by Sebastien Villemot.
-
-rem Copyright (C) 2009-2013 Dynare Team
-rem
-rem This file is part of Dynare.
-rem
-rem Dynare is free software: you can redistribute it and/or modify
-rem it under the terms of the GNU General Public License as published by
-rem the Free Software Foundation, either version 3 of the License, or
-rem (at your option) any later version.
-rem
-rem Dynare is distributed in the hope that it will be useful,
-rem but WITHOUT ANY WARRANTY; without even the implied warranty of
-rem MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-rem GNU General Public License for more details.
-rem
-rem You should have received a copy of the GNU General Public License
-rem along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
-
-rem ********************************************************************
-rem General parameters
-rem ********************************************************************
-
-set MATLAB=%MATLAB%
-set PATH=%PATH%;c:\cygwin\bin
-set MW_TARGET_ARCH=win64
-
-rem ********************************************************************
-rem Compiler parameters
-rem ********************************************************************
-set COMPILER=x86_64-w64-mingw32-gcc
-set COMPFLAGS=-c -fexceptions
-set OPTIMFLAGS=-O3
-set DEBUGFLAGS=-g -Wall
-set NAME_OBJECT=-o 
-
-rem ********************************************************************
-rem Linker parameters
-rem ********************************************************************
-set PRELINK_CMDS1=echo EXPORTS > mex.def & echo mexFunction >> mex.def
-set LIBLOC=%MATLAB%\bin\win64\
-set LINKER=x86_64-w64-mingw32-gcc
-set LINKFLAGS= -static-libgcc -shared mex.def "-L%LIBLOC%"
-set LINKFLAGSPOST= -lmex -lmx -lmwlapack -lmwblas
-set LINKOPTIMFLAGS=-O3
-set LINKDEBUGFLAGS= -g -Wall
-set LINK_FILE=
-set LINK_LIB=
-set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
-set RSP_FILE_INDICATOR=@
-set POSTLINK_CMDS1=del mex.def
-- 
GitLab