From c5bdc11cb2264b9ddf237d1c5ef04f2de49bd40e Mon Sep 17 00:00:00 2001 From: svenbarth Date: Thu, 14 Apr 2016 21:35:47 +0000 Subject: [PATCH] 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 - --- compiler/fpkg.pas | 13 +------------ compiler/options.pas | 6 +++--- compiler/pkgutil.pas | 44 +++++++++++++++++++++++++++++++++++++++++-- compiler/pmodules.pas | 26 ++++++++++++++++++------- 4 files changed, 65 insertions(+), 24 deletions(-) diff --git a/compiler/fpkg.pas b/compiler/fpkg.pas index c4377820bb..18a399fef1 100644 --- a/compiler/fpkg.pas +++ b/compiler/fpkg.pas @@ -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); diff --git a/compiler/options.pas b/compiler/options.pas index 87e5ca20bd..28ce4925dd 100644 --- a/compiler/options.pas +++ b/compiler/options.pas @@ -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 diff --git a/compiler/pkgutil.pas b/compiler/pkgutil.pas index c50256a5e8..2ee4de2714 100644 --- a/compiler/pkgutil.pas +++ b/compiler/pkgutil.pas @@ -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; diff --git a/compiler/pmodules.pas b/compiler/pmodules.pas index 38a6897f07..f6353505ec 100644 --- a/compiler/pmodules.pas +++ b/compiler/pmodules.pas @@ -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