This is an example of a roll-up of packages into a "Main`" package. Note: some backticks in the text are deleted because it influenced formatting. Worked fine in coding examples.
First the two Packages "P3subP1m" and "P4subP1m" roll up into "P1m". Then "P1m" and "P2m" roll up into te "Main" package. Since I am using global symbols in my packages and I need them to be recognized because I don't want private contexts to be create in all the places they appear I add Needs["Appglobals"] to every package.
All package must be .m or .wl "files". You can not simulate this in a notebook by executing every single command.
Start with Needs["Main'"] in a notebook. When you ask for ff in the global context the following is asked for {qq,pp,zz,hh,GCriskpath,GVdataobject}. qq and pp are create as "Main Private qq" and "Main Private pp" because they in usage statements more than 1 level lower and therefore not recognized. zz and hh are in usage messages 1 level lower and are picked up. The function zz:=pp +qq is now evaluated and picks up the values in the packages 1 level lower.
BeginPackage["Main`"];
ff::usage = "ff does something";
Needs["Appglobals`"];
Needs["P1m`"];
Needs["P2m`"];
Begin["`Private`"];
ff:=(Print["This is the Main func:"];{qq,pp, zz,hh, GCriskpath,GVdataobject} );
End[];
EndPackage[];
BeginPackage["P1m`"];
zz::usage="zz ...";
Needs["Appglobals`"];
Needs["P3subP1m`"];
Needs["P4subP1m`"];
Begin["`Private`"];
zz := pp + qq
End[];
EndPackage[];
BeginPackage["P2m`"];
hh::usage="hh ...";
Needs["Appglobals`"];
Begin["`Private`"];
hh := 13
End[];
EndPackage[];
BeginPackage["P3subP1m`"];
pp::usage="pp ...";
Needs["Appglobals`"];
Begin["`Private`"];
pp := 11
End[];
EndPackage[];
BeginPackage["P4subP1m`"];
qq::usage="qq ...";
Needs["Appglobals`"];
Begin["`Private`"];
qq :=22
End[];
EndPackage[];
BeginPackage["Appglobals`"];
GCriskpath = "the path to a local file folder"
GVdataobject = {{"a","b"},{"c","d"}}
EndPackage[];
After evaluating: Needs["Main`"] only the Main context is on the context path.
{$Context, $ContextPath} shows only Main on the contextpath
{"Global`", {"Main`", "TestPackage`", "TemplatingLoader`", "PacletManager`", "System`", "Global`"}
$Packages shows all sub-packages have been read.
{"P2m`", "P4subP1m`", "P3subP1m`", "P1m`", "Main`", "QuantityUnits`", "GetFEKernelInit`", "TemplatingLoader`", "ResourceLocator`", "PacletManager`", "System`", "Global`"}
Find all symbols present with one of the contexts in it. This is as expected.
Map[Names[# <> "*" <> "`*"] &, {"P1m", "P2m", "Main", "P3subP1m", "P4subP1m"}] // Column
{
{{"P1m`zz"}},
{{"P2m`hh"}},
{{"ff", "Main`Private`pp", "Main`Private`qq"}},
{{"P3subP1m`pp"}},
{{"P4subP1m`qq"}}
}