Even though there is a rigorous way in which the compiler determines initialisation, it's very difficult for a human to accurately figure out and control when there are many units with many dependencies.
E.g. Your DPR may use UnitA, UnitB, UnitC;
but if UnitA
has dependencies on UnitB
then UnitB has to be initialised first.
Admittedly, the feature of units having initialization and finalization sections can make adding functionality as simple as "add the unit". Although this seems great, in reality, on really large projects it tends to get in the way. Personally I consider the "feature" to be quite horrible.
The best and most reliable way to control the inialisation sequence of your units is to do so explicitly. E.g.
program X;
uses
Vcl.Forms,
uMain in 'uMain.pas' {MainForm},
uFooA in 'uFooA.pas',
uFooB in 'uFooB.pas';
{$R *.res}
begin
Init_uMain;
Init_uFooA;
Init_uFooB;
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
Finalise_uFooB;
Finalise_uFooA;
Finalise_uMain;
end.
Obviously the above code lacks appropriate try..finallys and would get messy with many units needing initialisation. However, there are other techniques that can be applied to keep things manageable.