diff --git a/DynareMain.cc b/DynareMain.cc index c5c23657..f2f9bf57 100644 --- a/DynareMain.cc +++ b/DynareMain.cc @@ -34,12 +34,20 @@ using namespace std; Splitting main() in two parts was necessary because ParsingDriver.h and MacroDriver.h can't be included simultaneously (because of Bison limitations). */ -void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tmp_terms, bool warn_uninit); +void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tmp_terms, bool warn_uninit +#if defined(_WIN32) || defined(__CYGWIN32__) + , bool cygwin, bool msvc +#endif + ); void usage() { - cerr << "Dynare usage: dynare mod_file [debug] [noclearall] [savemacro[=macro_file]] [onlymacro] [nolinemacro] [notmpterms] [warn_uninit]" << endl; + cerr << "Dynare usage: dynare mod_file [debug] [noclearall] [savemacro[=macro_file]] [onlymacro] [nolinemacro] [notmpterms] [warn_uninit]" +#if defined(_WIN32) || defined(__CYGWIN32__) + << " [cygwin] [msvc]" +#endif + << endl; exit(EXIT_FAILURE); } @@ -60,6 +68,10 @@ main(int argc, char** argv) bool only_macro = false; bool no_line_macro = false; bool warn_uninit = false; +#if defined(_WIN32) || defined(__CYGWIN32__) + bool cygwin = false; + bool msvc = false; +#endif // Parse options for (int arg = 2; arg < argc; arg++) @@ -89,6 +101,12 @@ main(int argc, char** argv) no_tmp_terms = true; else if (!strcmp(argv[arg], "warn_uninit")) warn_uninit = true; +#if defined(_WIN32) || defined(__CYGWIN32__) + else if (!strcmp(argv[arg], "cygwin")) + cygwin = true; + else if (!strcmp(argv[arg], "msvc")) + msvc = true; +#endif else { cerr << "Unknown option: " << argv[arg] << endl; @@ -128,7 +146,11 @@ main(int argc, char** argv) return EXIT_SUCCESS; // Do the rest - main2(macro_output, basename, debug, clear_all, no_tmp_terms, warn_uninit); + main2(macro_output, basename, debug, clear_all, no_tmp_terms, warn_uninit, +#if defined(_WIN32) || defined(__CYGWIN32__) + cygwin, msvc +#endif + ); return EXIT_SUCCESS; } diff --git a/DynareMain2.cc b/DynareMain2.cc index b6dc438d..fed8ed98 100644 --- a/DynareMain2.cc +++ b/DynareMain2.cc @@ -25,8 +25,11 @@ using namespace std; #include "ModFile.hh" void -main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tmp_terms, - bool warn_uninit) +main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tmp_terms, bool warn_uninit +#if defined(_WIN32) || defined(__CYGWIN32__) + , bool cygwin, bool msvc +#endif + ) { ParsingDriver p; @@ -46,10 +49,14 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tm mod_file->computingPass(no_tmp_terms); // Write outputs - mod_file->writeOutputFiles(basename, clear_all); + mod_file->writeOutputFiles(basename, clear_all +#if defined(_WIN32) || defined(__CYGWIN32__) + , cygwin, msvc +#endif + ); delete mod_file; cout << "Preprocessing completed." << endl - << "Starting Matlab computing ..." << endl; + << "Starting MATLAB/Octave computing." << endl; } diff --git a/ModFile.cc b/ModFile.cc index e3349675..eca9e5ae 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -225,7 +225,11 @@ ModFile::computingPass(bool no_tmp_terms) } void -ModFile::writeOutputFiles(const string &basename, bool clear_all) const +ModFile::writeOutputFiles(const string &basename, bool clear_all +#if defined(_WIN32) || defined(__CYGWIN32__) + , bool cygwin, bool msvc +#endif +) const { ofstream mOutputFile; bool dynamic_model_needed = mod_file_struct.simul_present || mod_file_struct.check_present || mod_file_struct.stoch_simul_present @@ -302,15 +306,26 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all) const // Compile the dynamic MEX file for use_dll option if (use_dll) - mOutputFile << "if ~exist('OCTAVE_VERSION')" << endl - << " if ispc" << endl - << " eval('mex -O LINKER=''echo EXPORTS > mex.def & echo mexFunction >> mex.def & echo Dynamic >> mex.def & gcc-3'' LDFLAGS=''-pthread -shared -Wl,--no-undefined'' " << basename << "_dynamic.c')" << endl // This command is enclosed in an eval(), because otherwise it will make Octave fail - << " else" << endl - << " eval('mex -O LDFLAGS=''-pthread -shared -Wl,--no-undefined'' " << basename << "_dynamic.c')" << endl // This command is enclosed in an eval(), because otherwise it will make Octave fail - << " end" << endl - << "else" << endl - << " mex " << basename << "_dynamic.c" << endl - << "end" << endl; + { + mOutputFile << "if ~exist('OCTAVE_VERSION')" << endl; + // Some mex commands are enclosed in an eval(), because otherwise it will make Octave fail +#if defined(_WIN32) || defined(__CYGWIN32__) + if (msvc) + mOutputFile << " eval('mex -O LINKFLAGS=\"$LINKFLAGS /export:Dynamic\" " << basename << "_dynamic.c')" << endl; // MATLAB/Windows + Microsoft Visual C++ + else if (cygwin) + mOutputFile << " eval('mex -O PRELINK_CMDS1=\"echo EXPORTS > mex.def & echo mexFunction >> mex.def & echo Dynamic >> mex.def\" " << basename << "_dynamic.c')" << endl; // MATLAB/Windows + Cygwin g++ + else + { + cerr << "ERROR: When using the USE_DLL option, you must give either 'cygwin' or 'msvc' option to the 'dynare' command" << endl; + exit(EXIT_FAILURE); + } +#else + mOutputFile << " eval('mex -O LDFLAGS=\"-pthread -shared -Wl,--no-undefined\" " << basename << "_dynamic.c')" << endl; // MATLAB/Linux|Mac +#endif + mOutputFile << "else" << endl + << " mex " << basename << "_dynamic.c" << endl // Octave + << "end" << endl; + } // Add path for block option with M-files if (block && !byte_code) diff --git a/ModFile.hh b/ModFile.hh index 118b8504..e7ba4e8d 100644 --- a/ModFile.hh +++ b/ModFile.hh @@ -91,8 +91,13 @@ public: /*! \param basename The base name used for writing output files. Should be the name of the mod file without its extension \param clear_all Should a "clear all" instruction be written to output ? + \param msvc Should the MEX command of use_dll be adapted for MSVC? */ - void writeOutputFiles(const string &basename, bool clear_all) const; + void writeOutputFiles(const string &basename, bool clear_all +#if defined(_WIN32) || defined(__CYGWIN32__) + , bool cygwin, bool msvc +#endif + ) const; }; #endif // ! MOD_FILE_HH