There are Mathematica packages that must create temporary files to function. If we are implementing such a package ourselves, how can we ensure that the temporary files will get cleaned up when the kernel exits?
Is this really a practical problem? Yes, both MATLink and MaTeX need to do it. Neither are able to do a full cleanup at the moment. Standard packages do it too, e.g. CCompilerDriver`
.
Is it really possible to do it? Yes. Compile
creates shared libraries when compiling to C code. These do get cleaned up on exit. How is this implemented?
In[1]:= cf = Compile[{{x}}, 2 x, CompilationTarget -> "C"];
In[2]:= FileNames[
FileNameJoin[{$UserBaseDirectory, "ApplicationData",
"CCompilerDriver", "BuildFolder", "*", "*"}]]
Out[2]= {"/Users/szhorvat/Library/Mathematica/ApplicationData/\
CCompilerDriver/BuildFolder/hawkeye-8727/compiledFunction0.dylib"}
In[3]:= Quit
In[1]:= FileNames[
FileNameJoin[{$UserBaseDirectory, "ApplicationData",
"CCompilerDriver", "BuildFolder", "*", "*"}]]
Out[1]= {}
We can use $Epilog
for this! $Epilog
is by default defined to evaluate << end`
. This file does not exist by default (it is not found by FindFile
). One possible solution is to create this file and add the cleanup code to it at the time when the package loads. But it is not clear how to this in a robust way, without conflicting with other packages that might also modify the same file.
The cleanup mechanism for shared libraries created by Compile
does not seem to use this. Thus I am still hoping to find a better and more robust solution. What does Compile
use?
One way to try to find out what happens when existing the kernel is to evaluate On[]
, followed by Quit[]
. This is best done in a terminal session, which does not need to deal with front-end interaction. This trick does not reveal any other evaluations that the one triggered by $Epilog
. The default value of $Epilog
in Mathematica 10 is If[FindFile["end`"] =!= $Failed, Get["end`"]]
.
Compile
stuff achieves it though. $\endgroup$$Epilog
incorrectly. It does have a value, it will do<<end`
if such a file exists. It is not what cleans it up though. What I tried now was to evaluateOn[]
before exit (in a terminal, no front end!) to see what gets evaluated. I'm trying to sort through that ... $\endgroup$WolframLibrary_uninitialize
. Could you post a sample code that cleans up a few known files? $\endgroup$