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`"]].
Compilestuff achieves it though. – Szabolcs Jan 19 '16 at 10:55$Epilogincorrectly. 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 ... – Szabolcs Jan 19 '16 at 11:12WolframLibrary_uninitialize. Could you post a sample code that cleans up a few known files? – QuantumDot Jul 08 '17 at 05:09