diff --git a/src/ComputingTasks.cc b/src/ComputingTasks.cc
index e3969e30a4bdb58703a6acc05655a58fb464e154..f9fb98abfc9d91b04f8e81d31578d9f9c2f87ef6 100644
--- a/src/ComputingTasks.cc
+++ b/src/ComputingTasks.cc
@@ -2458,7 +2458,7 @@ PlannerObjectiveStatement::writeOutput(ostream &output, const string &basename,
   for (const auto &temporary_terms_derivative : model_tree.getTemporaryTermsDerivatives())
     output << temporary_terms_derivative.size() << "; ";
   output << "];" << endl;
-  model_tree.writeStaticFile(basename + ".objective", false, "", {}, {}, false);
+  model_tree.writeStaticFile(basename + ".objective", false, "", {}, false);
 }
 
 void
diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc
index c874ef2c2f1125765e35896798351557225a8c61..ba1cebb99cfa4e7223988ea0b13925bca847a1c2 100644
--- a/src/DynamicModel.cc
+++ b/src/DynamicModel.cc
@@ -2412,7 +2412,7 @@ DynamicModel::computeBlockDynJacobianCols()
 }
 
 void
-DynamicModel::writeDynamicFile(const string &basename, bool use_dll, const string &mexext, const filesystem::path &matlabroot, const filesystem::path &dynareroot, bool julia) const
+DynamicModel::writeDynamicFile(const string &basename, bool use_dll, const string &mexext, const filesystem::path &matlabroot, bool julia) const
 {
   filesystem::path model_dir{basename};
   model_dir /= "model";
@@ -2443,7 +2443,7 @@ DynamicModel::writeDynamicFile(const string &basename, bool use_dll, const strin
 
   // Legacy representation
   if (use_dll)
-    writeModelCFile<true>(basename, mexext, matlabroot, dynareroot);
+    writeModelCFile<true>(basename, mexext, matlabroot);
   else if (!julia) // M-files
     writeDynamicMFile(basename);
   // The legacy representation is no longer produced for Julia
@@ -2454,7 +2454,7 @@ DynamicModel::writeDynamicFile(const string &basename, bool use_dll, const strin
 
   // Sparse representation
   if (use_dll)
-    writeSparseModelCFiles<true>(basename, mexext, matlabroot, dynareroot);
+    writeSparseModelCFiles<true>(basename, mexext, matlabroot);
   else if (julia)
     writeSparseModelJuliaFiles<true>(basename);
   else // MATLAB/Octave
diff --git a/src/DynamicModel.hh b/src/DynamicModel.hh
index a1f4b98d3cfeccb339b70960af81a7d687b5753f..eb6c6f14a0a82840301e3b811d32ad24655cbd0c 100644
--- a/src/DynamicModel.hh
+++ b/src/DynamicModel.hh
@@ -367,7 +367,7 @@ public:
   void updateVarAndTrendModel() const;
 
   //! Writes dynamic model file (+ bytecode)
-  void writeDynamicFile(const string &basename, bool use_dll, const string &mexext, const filesystem::path &matlabroot, const filesystem::path &dynareroot, bool julia) const;
+  void writeDynamicFile(const string &basename, bool use_dll, const string &mexext, const filesystem::path &matlabroot, bool julia) const;
 
   //! Writes file containing parameters derivatives
   template<bool julia>
diff --git a/src/DynareMain.cc b/src/DynareMain.cc
index e4bd0efdea658cc820417399b70c89f6c782f568..e16c7697e72699b8ba60ebe97d26b21ac7f79379 100644
--- a/src/DynareMain.cc
+++ b/src/DynareMain.cc
@@ -503,7 +503,8 @@ main(int argc, char **argv)
     }
 
   if (mod_file->use_dll)
-    ModelTree::initializeMEXCompilationWorkers(max(jthread::hardware_concurrency(), 1U));
+    ModelTree::initializeMEXCompilationWorkers(max(jthread::hardware_concurrency(), 1U),
+                                               dynareroot, mexext);
 
   if (json == JsonOutputPointType::parsing)
     mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson);
@@ -533,7 +534,7 @@ main(int argc, char **argv)
   else
     mod_file->writeMOutput(basename, clear_all, clear_global, no_warn, console, nograph,
                            nointeractive, config_file, check_model_changes, minimal_workspace, compute_xrefs,
-                           mexext, matlabroot, dynareroot, onlymodel, gui, notime);
+                           mexext, matlabroot, onlymodel, gui, notime);
 
   /* Ensures that workers are not destroyed before they finish compiling.
      Also ensures that the preprocessor final message is printed after the end of
diff --git a/src/ModFile.cc b/src/ModFile.cc
index 9c34b4702c0f7a48f5107a0536438872e26a19df..17ef006ce20d0df17d24a57c935402f484906628 100644
--- a/src/ModFile.cc
+++ b/src/ModFile.cc
@@ -770,8 +770,7 @@ ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global,
                       bool console, bool nograph, bool nointeractive, const ConfigFile &config_file,
                       bool check_model_changes, bool minimal_workspace, bool compute_xrefs,
                       const string &mexext,
-                      const filesystem::path &matlabroot,
-                      const filesystem::path &dynareroot, bool onlymodel, bool gui, bool notime) const
+                      const filesystem::path &matlabroot, bool onlymodel, bool gui, bool notime) const
 {
   if (basename.empty())
     {
@@ -1043,11 +1042,11 @@ ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global,
         {
           if (!no_static)
             {
-              static_model.writeStaticFile(basename, use_dll, mexext, matlabroot, dynareroot, false);
+              static_model.writeStaticFile(basename, use_dll, mexext, matlabroot, false);
               static_model.writeParamsDerivativesFile<false>(basename);
             }
 
-          dynamic_model.writeDynamicFile(basename, use_dll, mexext, matlabroot, dynareroot, false);
+          dynamic_model.writeDynamicFile(basename, use_dll, mexext, matlabroot, false);
 
           dynamic_model.writeParamsDerivativesFile<false>(basename);
         }
@@ -1069,10 +1068,10 @@ ModFile::writeJuliaOutput(const string &basename) const
     {
       if (!no_static)
         {
-          static_model.writeStaticFile(basename, false, "", {}, {}, true);
+          static_model.writeStaticFile(basename, false, "", {}, true);
           static_model.writeParamsDerivativesFile<true>(basename);
         }
-      dynamic_model.writeDynamicFile(basename, use_dll, "", {}, {}, true);
+      dynamic_model.writeDynamicFile(basename, use_dll, "", {}, true);
       dynamic_model.writeParamsDerivativesFile<true>(basename);
     }
   steady_state_model.writeSteadyStateFile(basename, true);
diff --git a/src/ModFile.hh b/src/ModFile.hh
index a4e69d4d5c521c043f220c8fd033831786d2278d..5e141d5005dbd54e1dceeb096ac992de7b4fa576 100644
--- a/src/ModFile.hh
+++ b/src/ModFile.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2006-2022 Dynare Team
+ * Copyright © 2006-2023 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -173,7 +173,7 @@ public:
                     bool console, bool nograph, bool nointeractive, const ConfigFile &config_file,
                     bool check_model_changes, bool minimal_workspace, bool compute_xrefs,
                     const string &mexext, const filesystem::path &matlabroot,
-                    const filesystem::path &dynareroot, bool onlymodel, bool gui, bool notime) const;
+                    bool onlymodel, bool gui, bool notime) const;
 
   void writeJuliaOutput(const string &basename) const;
 
diff --git a/src/ModelTree.cc b/src/ModelTree.cc
index 9e780a58beb5c82adaeceaa2e1be0437f3e745fc..02147440749cdacd959f834881dd8e0f7f7efe93 100644
--- a/src/ModelTree.cc
+++ b/src/ModelTree.cc
@@ -1616,7 +1616,7 @@ ModelTree::findGccOnMacos(const string &mexext)
 #endif
 
 filesystem::path
-ModelTree::compileMEX(const filesystem::path &output_dir, const string &output_basename, const string &mexext, const vector<filesystem::path> &input_files, const filesystem::path &matlabroot, const filesystem::path &dynareroot, bool link) const
+ModelTree::compileMEX(const filesystem::path &output_dir, const string &output_basename, const string &mexext, const vector<filesystem::path> &input_files, const filesystem::path &matlabroot, bool link) const
 {
   assert(!mex_compilation_workers.empty());
 
@@ -1637,22 +1637,6 @@ ModelTree::compileMEX(const filesystem::path &output_dir, const string &output_b
       // Octave
       compiler = matlabroot / "bin" / "mkoctfile";
       flags << "--mex";
-#ifdef __APPLE__
-      /* On macOS, enforce GCC, otherwise Clang will be used, and it does not
-         accept our custom optimization flags (see dynare#1797) */
-      filesystem::path gcc_path {findGccOnMacos(mexext)};
-      if (setenv("CC", gcc_path.c_str(), 1) != 0)
-        {
-          cerr << "Can't set CC environment variable" << endl;
-          exit(EXIT_FAILURE);
-        }
-      // We also define CXX, because that is used for linking
-      if (setenv("CXX", gcc_path.c_str(), 1) != 0)
-        {
-          cerr << "Can't set CXX environment variable" << endl;
-          exit(EXIT_FAILURE);
-        }
-#endif
     }
   else
     {
@@ -1672,22 +1656,8 @@ ModelTree::compileMEX(const filesystem::path &output_dir, const string &output_b
                 << " -shared -Wl,--no-undefined -Wl,-rpath-link," << bin_dir;
           libs += " -lm";
         }
-      else if (mexext == "mexw64")
-        {
-          // Windows
-          flags << " -static-libgcc -shared";
-          // Put the MinGW environment shipped with Dynare in the path
-          auto mingwpath = dynareroot / "mingw64" / "bin";
-          string newpath = "PATH=" + mingwpath.string() + ';' + getenv("PATH");
-          /* We can’t use setenv() since it is not available on MinGW. Note
-            that putenv() seems to make a copy of the string on MinGW, contrary
-            to what is done on GNU/Linux and macOS. */
-          if (putenv(const_cast<char *>(newpath.c_str())) != 0)
-            {
-              cerr << "Can't set PATH" << endl;
-              exit(EXIT_FAILURE);
-            }
-        }
+      else if (mexext == "mexw64") // Windows
+        flags << " -static-libgcc -shared";
 #ifdef __APPLE__
       else if (mexext == "mexmaci64" || mexext == "mexmaca64")
         {
@@ -1866,7 +1836,8 @@ ModelTree::getRHSFromLHS(expr_t lhs) const
 }
 
 void
-ModelTree::initializeMEXCompilationWorkers(int numworkers)
+ModelTree::initializeMEXCompilationWorkers(int numworkers, const filesystem::path &dynareroot,
+                                           const string &mexext)
 {
   assert(numworkers > 0);
   assert(mex_compilation_workers.empty());
@@ -1917,6 +1888,44 @@ ModelTree::initializeMEXCompilationWorkers(int numworkers)
             mex_compilation_cv.notify_all();
           }
     });
+
+  /* Set some environment variables needed for compilation on Windows/MATLAB
+     and macOS/Octave.
+     For Windows/MATLAB, this should be done only once, because otherwise
+     the PATH variable can become too long and GCC will not be found. */
+  if (mexext == "mexw64")
+    {
+      // Put the MinGW environment shipped with Dynare in the path
+      auto mingwpath = dynareroot / "mingw64" / "bin";
+      string newpath = "PATH=" + mingwpath.string() + ';' + getenv("PATH");
+      /* We can’t use setenv() since it is not available on MinGW. Note that
+         putenv() seems to make an internal copy of the string on MinGW,
+         contrary to what is done on GNU/Linux and macOS. */
+      if (putenv(const_cast<char *>(newpath.c_str())) != 0)
+        {
+          cerr << "Can't set PATH" << endl;
+          exit(EXIT_FAILURE);
+        }
+    }
+#ifdef __APPLE__
+  else if (mexext == "mex")
+    {
+      /* On macOS, with Octave, enforce GCC, otherwise Clang will be used, and
+         it does not accept our custom optimization flags (see dynare#1797) */
+      filesystem::path gcc_path {findGccOnMacos(mexext)};
+      if (setenv("CC", gcc_path.c_str(), 1) != 0)
+        {
+          cerr << "Can't set CC environment variable" << endl;
+          exit(EXIT_FAILURE);
+        }
+      // We also define CXX, because that is used for linking
+      if (setenv("CXX", gcc_path.c_str(), 1) != 0)
+        {
+          cerr << "Can't set CXX environment variable" << endl;
+          exit(EXIT_FAILURE);
+        }
+    }
+#endif
 }
 
 void
diff --git a/src/ModelTree.hh b/src/ModelTree.hh
index 551ab744749f949606735d29761c20a8ab382336..5682cf08ade2fd9fb6c813f5142878963417df72 100644
--- a/src/ModelTree.hh
+++ b/src/ModelTree.hh
@@ -309,7 +309,7 @@ protected:
 
   // Writes and compiles dynamic/static file (C version, legacy representation)
   template<bool dynamic>
-  void writeModelCFile(const string &basename, const string &mexext, const filesystem::path &matlabroot, const filesystem::path &dynareroot) const;
+  void writeModelCFile(const string &basename, const string &mexext, const filesystem::path &matlabroot) const;
 
   // Writes per-block residuals and temporary terms (incl. for derivatives)
   template<ExprNodeOutputType output_type>
@@ -377,7 +377,7 @@ protected:
 
   // Writes and compiles the sparse representation of the model in C
   template<bool dynamic>
-  void writeSparseModelCFiles(const string &basename, const string &mexext, const filesystem::path &matlabroot, const filesystem::path &dynareroot) const;
+  void writeSparseModelCFiles(const string &basename, const string &mexext, const filesystem::path &matlabroot) const;
 
   // Writes the sparse representation of the model in Julia
   // Assumes that the directory <MODFILE>/model/julia/ already exists
@@ -583,7 +583,7 @@ private:
      blocking. The dependency of a linked MEX file upon intermediary objects is
      nicely handled. Returns the name of the output file (to be reused later as
      input file if link=false). */
-  filesystem::path compileMEX(const filesystem::path &output_dir, const string &output_basename, const string &mexext, const vector<filesystem::path> &input_files, const filesystem::path &matlabroot, const filesystem::path &dynareroot, bool link = true) const;
+  filesystem::path compileMEX(const filesystem::path &output_dir, const string &output_basename, const string &mexext, const vector<filesystem::path> &input_files, const filesystem::path &matlabroot, bool link = true) const;
 
 public:
   ModelTree(SymbolTable &symbol_table_arg,
@@ -625,8 +625,10 @@ public:
      If no such equation can be found, throws an ExprNode::MatchFailureExpression */
   expr_t getRHSFromLHS(expr_t lhs) const;
 
-  // Initialize the MEX compilation workers
-  static void initializeMEXCompilationWorkers(int numworkers);
+  /* Initialize the MEX compilation workers (and some environment variables
+     needed for finding GCC) */
+  static void initializeMEXCompilationWorkers(int numworkers, const filesystem::path &dynareroot,
+                                              const string &mexext);
 
   // Waits until the MEX compilation queue is empty
   static void waitForMEXCompilationWorkers();
@@ -922,8 +924,7 @@ ModelTree::writeModelFileHelper() const
 template<bool dynamic>
 void
 ModelTree::writeModelCFile(const string &basename, const string &mexext,
-                           const filesystem::path &matlabroot,
-                           const filesystem::path &dynareroot) const
+                           const filesystem::path &matlabroot) const
 {
   ofstream output;
   auto open_file = [&output](const filesystem::path &p)
@@ -974,7 +975,7 @@ ModelTree::writeModelCFile(const string &basename, const string &mexext,
              << endl;
       output.close();
       object_files.push_back(compileMEX(model_src_dir, funcname + "_tt" , mexext, { source_tt },
-                                        matlabroot, dynareroot, false));
+                                        matlabroot, false));
 
       const string prototype_main
         {
@@ -1013,7 +1014,7 @@ ModelTree::writeModelCFile(const string &basename, const string &mexext,
              << endl;
       output.close();
       object_files.push_back(compileMEX(model_src_dir, funcname, mexext, { source_main },
-                                        matlabroot, dynareroot, false));
+                                        matlabroot, false));
     }
 
   const filesystem::path filename { model_src_dir / (dynamic ? "dynamic.c" : "static.c") };
@@ -1123,8 +1124,7 @@ ModelTree::writeModelCFile(const string &basename, const string &mexext,
   output.close();
 
   object_files.push_back(filename);
-  compileMEX(packageDir(basename), dynamic ? "dynamic" : "static", mexext, object_files, matlabroot,
-             dynareroot);
+  compileMEX(packageDir(basename), dynamic ? "dynamic" : "static", mexext, object_files, matlabroot);
 }
 
 template<ExprNodeOutputType output_type>
@@ -2611,8 +2611,7 @@ ModelTree::writeSparseModelMFiles(const string &basename) const
 template<bool dynamic>
 void
 ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext,
-                                  const filesystem::path &matlabroot,
-                                  const filesystem::path &dynareroot) const
+                                  const filesystem::path &matlabroot) const
 {
   constexpr ExprNodeOutputType output_type {dynamic ? ExprNodeOutputType::CSparseDynamicModel : ExprNodeOutputType::CSparseStaticModel};
   auto [d_sparse_output, tt_sparse_output] = writeModelFileHelper<output_type>();
@@ -2654,7 +2653,7 @@ ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext,
   output.close();
   auto power_deriv_object {compileMEX(model_src_dir, (prefix + "power_deriv"),
                                       mexext, { power_deriv_src },
-                                      matlabroot, dynareroot, false)};
+                                      matlabroot, false)};
 
   size_t ttlen {0};
 
@@ -2731,7 +2730,7 @@ ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext,
              << endl;
       output.close();
       tt_object_files.push_back(compileMEX(model_src_dir, funcname + "_tt", mexext, { source_tt },
-                                           matlabroot, dynareroot, false));
+                                           matlabroot, false));
 
       const string prototype_main {"void " + funcname + "(const double *restrict y, const double *restrict x, const double *restrict params" + ss_argin + ", const double *restrict T, double *restrict " + (i == 0 ? "residual" : "g" + to_string(i) + "_v") + ")"};
 
@@ -2754,7 +2753,7 @@ ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext,
              << endl;
       output.close();
       auto main_object_file {compileMEX(model_src_dir, funcname, mexext, { source_main },
-                                        matlabroot, dynareroot, false)};
+                                        matlabroot, false)};
 
       const filesystem::path source_mex { model_src_dir / (funcname + "_mex.c")};
       int nargin {5+static_cast<int>(dynamic)+3*static_cast<int>(i == 1)};
@@ -2837,7 +2836,7 @@ ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext,
       vector<filesystem::path> mex_input_files { power_deriv_object, main_object_file, source_mex };
       for (int j {0}; j <= i; j++)
         mex_input_files.push_back(tt_object_files[j]);
-      compileMEX(mex_dir, funcname, mexext, mex_input_files, matlabroot, dynareroot);
+      compileMEX(mex_dir, funcname, mexext, mex_input_files, matlabroot);
     }
 
   if (block_decomposed)
@@ -2926,7 +2925,7 @@ ModelTree::writeSparseModelCFiles(const string &basename, const string &mexext,
             }
           output << "}" << endl;
           output.close();
-          compileMEX(block_dir, funcname, mexext, { source_mex, power_deriv_object }, matlabroot, dynareroot);
+          compileMEX(block_dir, funcname, mexext, { source_mex, power_deriv_object }, matlabroot);
         }
     }
 }
diff --git a/src/StaticModel.cc b/src/StaticModel.cc
index 92e5f2606942840a5e6b95820580625c1e2b132c..a6d87a9f7e036202c1b829ea30158f8c37c53b03 100644
--- a/src/StaticModel.cc
+++ b/src/StaticModel.cc
@@ -456,7 +456,7 @@ StaticModel::writeStaticMCompatFile(const string &basename) const
 }
 
 void
-StaticModel::writeStaticFile(const string &basename, bool use_dll, const string &mexext, const filesystem::path &matlabroot, const filesystem::path &dynareroot, bool julia) const
+StaticModel::writeStaticFile(const string &basename, bool use_dll, const string &mexext, const filesystem::path &matlabroot, bool julia) const
 {
   filesystem::path model_dir{basename};
   model_dir /= "model";
@@ -487,7 +487,7 @@ StaticModel::writeStaticFile(const string &basename, bool use_dll, const string
 
   // Legacy representation
   if (use_dll)
-    writeModelCFile<false>(basename, mexext, matlabroot, dynareroot);
+    writeModelCFile<false>(basename, mexext, matlabroot);
   else if (!julia) // M-files
     writeStaticMFile(basename);
   // The legacy representation is no longer produced for Julia
@@ -498,7 +498,7 @@ StaticModel::writeStaticFile(const string &basename, bool use_dll, const string
 
   // Sparse representation
   if (use_dll)
-    writeSparseModelCFiles<false>(basename, mexext, matlabroot, dynareroot);
+    writeSparseModelCFiles<false>(basename, mexext, matlabroot);
   else if (julia)
     writeSparseModelJuliaFiles<false>(basename);
   else // MATLAB/Octave
diff --git a/src/StaticModel.hh b/src/StaticModel.hh
index 8f02c0047373fb20b521ec4a7c392d45009ddda8..6971f12ae8e6d293037b506666c6ab57552aa030 100644
--- a/src/StaticModel.hh
+++ b/src/StaticModel.hh
@@ -125,7 +125,7 @@ public:
   void computingPass(int derivsOrder, int paramsDerivsOrder, const eval_context_t &eval_context, bool no_tmp_terms, bool block);
 
   //! Writes static model file (+ bytecode)
-  void writeStaticFile(const string &basename, bool use_dll, const string &mexext, const filesystem::path &matlabroot, const filesystem::path &dynareroot, bool julia) const;
+  void writeStaticFile(const string &basename, bool use_dll, const string &mexext, const filesystem::path &matlabroot, bool julia) const;
 
   //! Write JSON Output (used by PlannerObjectiveStatement)
   void writeJsonOutput(ostream &output) const;