In principle this can be done using LibraryLink. Just run an action on library unload. The library will be unloaded on kernel exit, if you don't unload it manually before.
Warning: This is a heavyweight solution that just won't be practical in most cases. But it does work and it does not conflict with other packages. If you need to do the cleanup privately, only on your own computer, then it can be useful. If you need to do the cleanup from a package that already uses LibraryLink, then it is useful. Otherwise I wouldn't use it.
For reasons of laziness, here's with LTemplate:
<< LTemplate`
tem = LClass["Cleanup", {}];
SetDirectory[$TemporaryDirectory];
code = "
struct Cleanup {
~Cleanup() {
mma::print(\"C++: Cleaning up\");
// this below calls myCleanupFunction[]
MLINK link = mma::libData->getMathLink(mma::libData);
MLPutFunction(link, \"EvaluatePacket\", 1);
MLPutFunction(link, \"myCleanupFunction\", 0);
mma::libData->processMathLink(link);
MLNextPacket(link);
MLNewPacket(link);
}
};
";
Export["Cleanup.h", code, "String"];
CompileTemplate[tem, "ShellOutputFunction" -> Print]
LoadTemplate[tem]
This will be called on exit:
myCleanupFunction[] := Print["Mathematica: Cleaning up"]
We create a special object. When this object is no longer referenced, or when the library is unloaded, the cleanup code will be run.
globalCleaner = Make["Cleanup"]
(* Cleanup[1] *)
Now we quit:
Quit
Quitting triggers unloading the library and this gets printed:
C++: Cleaning up
Mathematica: Cleaning up
Standard LibraryLink is a bit different than LTemplate. You'll need to put the code form the destructor above into WolframLibrary_uninitialize()
and there's no need a create a special object like Cleanup[1]
. I have not tested it (again: laziness), but I expect it will work the same way.
SetDelayed[$Epilog,f_]
such that you append the calling of yourend.m
to the execution off
? $\endgroup$init.m
. $\endgroup$SetDelayed
inside the upvalue definition (so as not to run into infinite recursion). I'm sure it's possible, but I'm not that familiar with upvalues. $\endgroup$$Epilog
orend.m
. I gave up on this. $\endgroup$