I have been tracing the boot progress of a minimal release (generated with Mix) to understand who and when preloads modules and runs on_load handlers.
The source code of application.erl and application_controller.erl seem to suggest that (-init_debug notation)
basically loads the application resource file and stores stuff in ETS tables, but object code does not seem to be loaded (that coincides with the documentation of application:load/1, but contradicts at least two books).
I have added an on_load callback in a module that prints a trace, and that trace is shown after *all* applications have been loaded, after kernel has been started, and before stdlib is started.
I thought that meant kernel:start_boot preloaded the modules. But I have read some of the initialization of kernel and I believe the callback is *not* called when the module has been loaded into the VM, but with this ad-hoc line in the init/1 of kernel_sup:
which goes before all application loading in a conventional generated boot script.
So, I've come with this tentative workflow:
* primLoad loads all object code into the BEAM. In a normal boot script that means loading all modules of all bundled applications and included applications.
* Loading applications just processes and stores the application resource file.
* On boot, on_load handlers do not actually run when the object code is loaded into the BEAM, but much later, when kernel_sup is initialized as part of starting the kernel application (which I guess makes sense because you want to run that code when the callback is able to execute with enough stuff bootstrapped).
My walkthrough has not been exhaustive, though. Can anyone confirm/refute that?