Merged revision(s) 31924, 31934-31937 from branches/svenbarth/packages:

pmodules.pas, proc_package:
  * generate the dummy entry symbol only on Windows systems (ToDo for other systems that might need it)

........
options.pas:
  * TOption.interpret_option & read_arguments: use add_package() from pkgutils instead of addpackage() from fpkg
fpkg.pas:
  - remove no longer needed addpackage()

........
pkgutil.pas:
  + new procedure add_package_libs() to add all packages as libraries that are also linked against
pmodules.pas:
  * proc_package & proc_program: add all package libraries to the linker before creating the final binary

........
pkgutil.pas, add_package:
  * package names are case insensitive so add them in uppercase to correctly detect duplicates

........
Keep track of how many units are used from each required/requested package and only link those from which any units are used.

fpkg.pas, tpackageentry:
  + new field usedunits to count how many units of the package are used
pkgutil.pas:
  + new procedure add_package_unit_ref() to increase the amount of used units for the given package
pmodules.pas:
  * proc_package & proc_program: check which units of all loaded ones are provided by other packages

........

git-svn-id: trunk@33510 -
This commit is contained in:
svenbarth 2016-04-14 21:35:47 +00:00
parent 814d3c4071
commit c5bdc11cb2
4 changed files with 65 additions and 24 deletions

View File

@ -53,26 +53,15 @@ interface
tpackageentry=record
package : tpackage;
realpkgname : string;
usedunits : longint;
end;
ppackageentry=^tpackageentry;
procedure addpackage(list:tfphashlist;const pn:string);
implementation
uses
cutils,globals;
procedure addpackage(list: tfphashlist;const pn:string);
var
pkgentry : ppackageentry;
begin
new(pkgentry);
pkgentry^.realpkgname:=pn;
pkgentry^.package:=nil;
list.add(upper(pn),pkgentry);
end;
{ tpackage }
constructor tpackage.create(const pn: string);

View File

@ -103,7 +103,7 @@ uses
llvminfo,
{$endif llvm}
dirparse,
fpkg,
pkgutil,
i_bsd;
const
@ -1555,7 +1555,7 @@ begin
if ispara then
parapackages.add(more,nil)
else
addpackage(packagelist,more);
add_package(more,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
addpackage(packagelist,option.parapackages.NameOfIndex(j));
add_package(option.parapackages.NameOfIndex(j),true);
{ add unit environment and exepath to the unit search path }
if inputfilepath<>'' then

View File

@ -27,13 +27,15 @@ unit pkgutil;
interface
uses
fmodule,fpkg;
fmodule,fpkg,link;
procedure createimportlibfromexternals;
Function RewritePPU(const PPUFn,PPLFn:String):Boolean;
procedure export_unit(u:tmodule);
procedure load_packages;
procedure add_package(const name:string;ignoreduplicates:boolean);
procedure add_package_unit_ref(package:tpackage);
procedure add_package_libs(l:tlinker);
implementation
@ -430,7 +432,45 @@ implementation
new(entry);
entry^.package:=nil;
entry^.realpkgname:=name;
packagelist.add(name,entry);
entry^.usedunits:=0;
packagelist.add(upper(name),entry);
end;
procedure add_package_unit_ref(package: tpackage);
var
pkgentry : ppackageentry;
begin
pkgentry:=ppackageentry(packagelist.find(package.packagename^));
if not assigned(pkgentry) then
internalerror(2015100301);
inc(pkgentry^.usedunits);
end;
procedure add_package_libs(l:tlinker);
var
pkgentry : ppackageentry;
i : longint;
pkgname : tpathstr;
begin
for i:=0 to packagelist.count-1 do
begin
pkgentry:=ppackageentry(packagelist[i]);
if pkgentry^.usedunits>0 then
begin
//writeln('package used: ',pkgentry^.realpkgname);
pkgname:=pkgentry^.package.pplfilename;
if copy(pkgname,1,length(target_info.sharedlibprefix))=target_info.sharedlibprefix then
delete(pkgname,1,length(target_info.sharedlibprefix));
if copy(pkgname,length(pkgname)-length(target_info.sharedlibext)+1,length(target_info.sharedlibext))=target_info.sharedlibext then
delete(pkgname,length(pkgname)-length(target_info.sharedlibext)+1,length(target_info.sharedlibext));
//writeln('adding library: ', pkgname);
l.sharedlibfiles.concat(pkgname);
end
else
{writeln('ignoring package: ',pkgentry^.realpkgname)};
end;
end;

View File

@ -1577,14 +1577,17 @@ type
current_module.allunitsused;
end;
new_section(current_asmdata.asmlists[al_globals],sec_data,'_FPCDummy',4);
current_asmdata.asmlists[al_globals].concat(tai_symbol.createname_global('_FPCDummy',AT_DATA,0));
current_asmdata.asmlists[al_globals].concat(tai_const.create_32bit(0));
if target_info.system in systems_windows then
begin
new_section(current_asmdata.asmlists[al_globals],sec_data,'_FPCDummy',4);
current_asmdata.asmlists[al_globals].concat(tai_symbol.createname_global('_FPCDummy',AT_DATA,0));
current_asmdata.asmlists[al_globals].concat(tai_const.create_32bit(0));
new_section(current_asmdata.asmlists[al_procedures],sec_code,'',0);
current_asmdata.asmlists[al_procedures].concat(tai_symbol.createname_global('_DLLMainCRTStartup',AT_FUNCTION,0));
gen_fpc_dummy(current_asmdata.asmlists[al_procedures]);
current_asmdata.asmlists[al_procedures].concat(tai_const.createname('_FPCDummy',0));
new_section(current_asmdata.asmlists[al_procedures],sec_code,'',0);
current_asmdata.asmlists[al_procedures].concat(tai_symbol.createname_global('_DLLMainCRTStartup',AT_FUNCTION,0));
gen_fpc_dummy(current_asmdata.asmlists[al_procedures]);
current_asmdata.asmlists[al_procedures].concat(tai_const.createname('_FPCDummy',0));
end;
{ leave when we got an error }
if (Errorcount>0) and not status.skip_error then
@ -1602,6 +1605,8 @@ type
begin
hp2:=hp;
hp:=tmodule(hp.next);
if assigned(hp2.package) then
add_package_unit_ref(hp2.package);
if hp2.is_unit and
not assigned(hp2.globalsymtable) then
loaded_units.remove(hp2);
@ -1728,6 +1733,9 @@ type
end;
hp:=hp2;
end;
{ add the library of directly used packages }
add_package_libs(linker);
{ and now link the package library }
linker.MakeSharedLibrary
end;
@ -2232,6 +2240,8 @@ type
if (hp<>sysinitmod) and (hp.flags and uf_in_library=0) then
linker.AddModuleFiles(hp);
hp2:=tmodule(hp.next);
if assigned(hp.package) then
add_package_unit_ref(hp.package);
if (hp<>current_module) and
(not needsymbolinfo) then
begin
@ -2243,6 +2253,8 @@ type
{ free also unneeded units we didn't free before }
if not needsymbolinfo then
unloaded_units.Clear;
{ add all directly used packages as libraries }
add_package_libs(linker);
{ finally we can create a executable }
if current_module.islibrary then
linker.MakeSharedLibrary