Make the hack for MATLAB+Windows directory lock work with any recursive directory structure

This simplifes the treatment of the new sparse representation, which creates
several subdirectories in the “+” package folder.
master
Sébastien Villemot 2022-10-11 17:25:19 +02:00
parent 93054cf692
commit 39051aeb30
No known key found for this signature in database
GPG Key ID: 2CECE9350ECEBE4A
2 changed files with 26 additions and 17 deletions

View File

@ -774,6 +774,22 @@ ModFile::computingPass(bool no_tmp_terms, OutputType output, int params_derivs_o
cout.rdbuf(oldcout);
}
void
ModFile::remove_directory_with_matlab_lock(const filesystem::path &dir)
{
if (!exists(dir))
return;
if (is_directory(dir))
for (const auto &e : filesystem::directory_iterator{dir})
if (is_directory(e))
remove_directory_with_matlab_lock(e);
auto tmp {unique_path()};
rename(dir, tmp);
remove_all(tmp);
}
void
ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global, bool no_warn,
bool console, bool nograph, bool nointeractive, const ConfigFile &config_file,
@ -794,27 +810,13 @@ ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global,
if (hasModelChanged)
{
// Erase possible remnants of previous runs
/* Under MATLAB+Windows (but not under Octave nor under GNU/Linux or
macOS), if we directly remove the "+" subdirectory, then the
preprocessor is not able to recreate it afterwards (presumably because
MATLAB maintains some sort of lock on it). The workaround is to rename
it before deleting it (the renaming must occur in the same directory,
otherwise it may file if the destination is not on the same
filesystem). */
if (exists(plusfolder))
{
if (exists(plusfolder / "+objective"))
{
// Do it recursively for the +objective folder, created by ramsey_policy
auto tmp2 = unique_path();
rename(plusfolder / "+objective", tmp2);
remove_all(tmp2);
}
MATLAB maintains some sort of lock on it). So we use a hack. */
remove_directory_with_matlab_lock(plusfolder);
auto tmp = unique_path();
rename(plusfolder, tmp);
remove_all(tmp);
}
filesystem::remove_all(basename + "/model/src");
filesystem::remove_all(basename + "/model/bytecode");
}

View File

@ -130,6 +130,13 @@ private:
boost::filesystem::unique_path(). Both are insecure, but currently there
is no better portable solution. Maybe in a later C++ standard? */
static filesystem::path unique_path();
/* Hack for removing a directory that is locked by MATLAB/Windows. The
directory is renamed before being deleted. The renaming must occur in the
same directory, otherwise it may file if the destination is not on the
same filesystem. This technique is applied recursively to subdirectories.
Works even if the argument does not exist or is not a directory. */
static void remove_directory_with_matlab_lock(const filesystem::path &dir);
public:
//! Add a statement
void addStatement(unique_ptr<Statement> st);