diff --git a/compiler/fpcp.pas b/compiler/fpcp.pas index 59dcfb99e5..424736cf85 100644 --- a/compiler/fpcp.pas +++ b/compiler/fpcp.pas @@ -57,6 +57,7 @@ interface function getmodulestream(module:tmodulebase):tcstream; procedure initmoduleinfo(module:tmodulebase); procedure addunit(module:tmodulebase); + procedure add_required_package(pkg:tpackage); end; implementation @@ -551,5 +552,19 @@ implementation containedmodules.add(module.modulename^,containedunit); end; + + procedure tpcppackage.add_required_package(pkg:tpackage); + var + p : tpackage; + begin + p:=tpackage(requiredpackages.find(pkg.packagename^)); + if not assigned(p) then + requiredpackages.Add(pkg.packagename^,pkg) + else + if p<>pkg then + internalerror(2015112302); + end; + + end. diff --git a/compiler/fpkg.pas b/compiler/fpkg.pas index 8638faeff6..44219dc416 100644 --- a/compiler/fpkg.pas +++ b/compiler/fpkg.pas @@ -56,6 +56,7 @@ interface package : tpackage; realpkgname : string; usedunits : longint; + direct : boolean; end; ppackageentry=^tpackageentry; diff --git a/compiler/options.pas b/compiler/options.pas index 052bb3a19a..8752f6ff9e 100644 --- a/compiler/options.pas +++ b/compiler/options.pas @@ -1555,7 +1555,7 @@ begin if ispara then parapackages.add(more,nil) else - add_package(more,true); + add_package(more,true,true); end; 'p' : begin @@ -3637,7 +3637,7 @@ begin FrameworkSearchPath.AddList(option.ParaFrameworkPath,true); packagesearchpath.addlist(option.parapackagepath,true); for j:=0 to option.parapackages.count-1 do - add_package(option.parapackages.NameOfIndex(j),true); + add_package(option.parapackages.NameOfIndex(j),true,true); { add unit environment and exepath to the unit search path } if inputfilepath<>'' then diff --git a/compiler/pkgutil.pas b/compiler/pkgutil.pas index d5d2492e07..670a2a44cf 100644 --- a/compiler/pkgutil.pas +++ b/compiler/pkgutil.pas @@ -33,7 +33,7 @@ interface Function RewritePPU(const PPUFn:String;OutStream:TCStream):Boolean; procedure export_unit(u:tmodule); procedure load_packages; - procedure add_package(const name:string;ignoreduplicates:boolean); + procedure add_package(const name:string;ignoreduplicates:boolean;direct:boolean); procedure add_package_unit_ref(package:tpackage); procedure add_package_libs(l:tlinker); @@ -382,13 +382,17 @@ implementation procedure load_packages; var - i : longint; + i,j : longint; pcp: tpcppackage; - entry : ppackageentry; + entry, + entryreq : ppackageentry; + name, + uname : string; begin if not (tf_supports_packages in target_info.flags) then exit; - for i:=0 to packagelist.count-1 do + i:=0; + while i<packagelist.count do begin entry:=ppackageentry(packagelist[i]); if assigned(entry^.package) then @@ -397,11 +401,46 @@ implementation pcp:=tpcppackage.create(entry^.realpkgname); pcp.loadpcp; entry^.package:=pcp; + + { add all required packages that are not yet part of packagelist } + for j:=0 to pcp.requiredpackages.count-1 do + begin + name:=pcp.requiredpackages.NameOfIndex(j); + uname:=upper(name); + if not assigned(packagelist.Find(uname)) then + begin + New(entryreq); + entryreq^.realpkgname:=name; + entryreq^.package:=nil; + entryreq^.usedunits:=0; + entryreq^.direct:=false; + packagelist.add(uname,entryreq); + end; + end; + + Inc(i); + end; + + { all packages are now loaded, so we can fill in the links of the required packages } + for i:=0 to packagelist.count-1 do + begin + entry:=ppackageentry(packagelist[i]); + if not assigned(entry^.package) then + internalerror(2015111301); + for j:=0 to entry^.package.requiredpackages.count-1 do + begin + if assigned(entry^.package.requiredpackages[j]) then + internalerror(2015111303); + entryreq:=packagelist.find(upper(entry^.package.requiredpackages.NameOfIndex(j))); + if not assigned(entryreq) then + internalerror(2015111302); + entry^.package.requiredpackages[j]:=entryreq^.package; + end; end; end; - procedure add_package(const name:string;ignoreduplicates:boolean); + procedure add_package(const name:string;ignoreduplicates:boolean;direct:boolean); var entry : ppackageentry; i : longint; @@ -419,6 +458,7 @@ implementation entry^.package:=nil; entry^.realpkgname:=name; entry^.usedunits:=0; + entry^.direct:=direct; packagelist.add(upper(name),entry); end; diff --git a/compiler/pmodules.pas b/compiler/pmodules.pas index 2b6b8fab2b..c68d7a30d5 100644 --- a/compiler/pmodules.pas +++ b/compiler/pmodules.pas @@ -1384,6 +1384,7 @@ type force_init_final : boolean; uu : tused_unit; module_name: ansistring; + pentry: ppackageentry; begin Status.IsPackage:=true; Status.IsExe:=true; @@ -1482,7 +1483,7 @@ type module_name:=module_name+'.'+orgpattern; consume(_ID); end; - add_package(module_name,false); + add_package(module_name,false,true); end else consume(_ID); @@ -1721,8 +1722,18 @@ type hp:=tmodule(loaded_units.first); while assigned(hp) do begin - if (hp<>current_module) and not assigned(hp.package) then - pkg.addunit(hp); + if (hp<>current_module) then + begin + if not assigned(hp.package) then + pkg.addunit(hp) + else + begin + pentry:=ppackageentry(packagelist.find(hp.package.packagename^)); + if not assigned(pentry) then + internalerror(2015112301); + pkg.add_required_package(hp.package); + end; + end; hp:=tmodule(hp.next); end;