浏览代码

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 -

svenbarth 9 年之前
父节点
当前提交
c5bdc11cb2
共有 4 个文件被更改,包括 66 次插入25 次删除
  1. 1 12
      compiler/fpkg.pas
  2. 3 3
      compiler/options.pas
  3. 42 2
      compiler/pkgutil.pas
  4. 20 8
      compiler/pmodules.pas

+ 1 - 12
compiler/fpkg.pas

@@ -53,26 +53,15 @@ interface
     tpackageentry=record
     tpackageentry=record
       package : tpackage;
       package : tpackage;
       realpkgname : string;
       realpkgname : string;
+      usedunits : longint;
     end;
     end;
     ppackageentry=^tpackageentry;
     ppackageentry=^tpackageentry;
 
 
-    procedure addpackage(list:tfphashlist;const pn:string);
-
 implementation
 implementation
 
 
   uses
   uses
     cutils,globals;
     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 }
   { tpackage }
 
 
   constructor tpackage.create(const pn: string);
   constructor tpackage.create(const pn: string);

+ 3 - 3
compiler/options.pas

@@ -103,7 +103,7 @@ uses
   llvminfo,
   llvminfo,
 {$endif llvm}
 {$endif llvm}
   dirparse,
   dirparse,
-  fpkg,
+  pkgutil,
   i_bsd;
   i_bsd;
 
 
 const
 const
@@ -1555,7 +1555,7 @@ begin
                      if ispara then
                      if ispara then
                        parapackages.add(more,nil)
                        parapackages.add(more,nil)
                      else
                      else
-                       addpackage(packagelist,more);
+                       add_package(more,true);
                    end;
                    end;
                  'p' :
                  'p' :
                    begin
                    begin
@@ -3637,7 +3637,7 @@ begin
   FrameworkSearchPath.AddList(option.ParaFrameworkPath,true);
   FrameworkSearchPath.AddList(option.ParaFrameworkPath,true);
   packagesearchpath.addlist(option.parapackagepath,true);
   packagesearchpath.addlist(option.parapackagepath,true);
   for j:=0 to option.parapackages.count-1 do
   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 }
   { add unit environment and exepath to the unit search path }
   if inputfilepath<>'' then
   if inputfilepath<>'' then

+ 42 - 2
compiler/pkgutil.pas

@@ -27,13 +27,15 @@ unit pkgutil;
 interface
 interface
 
 
   uses
   uses
-    fmodule,fpkg;
+    fmodule,fpkg,link;
 
 
   procedure createimportlibfromexternals;
   procedure createimportlibfromexternals;
   Function RewritePPU(const PPUFn,PPLFn:String):Boolean;
   Function RewritePPU(const PPUFn,PPLFn:String):Boolean;
   procedure export_unit(u:tmodule);
   procedure export_unit(u:tmodule);
   procedure load_packages;
   procedure load_packages;
   procedure add_package(const name:string;ignoreduplicates:boolean);
   procedure add_package(const name:string;ignoreduplicates:boolean);
+  procedure add_package_unit_ref(package:tpackage);
+  procedure add_package_libs(l:tlinker);
 
 
 implementation
 implementation
 
 
@@ -430,7 +432,45 @@ implementation
       new(entry);
       new(entry);
       entry^.package:=nil;
       entry^.package:=nil;
       entry^.realpkgname:=name;
       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;
     end;
 
 
 
 

+ 20 - 8
compiler/pmodules.pas

@@ -1577,14 +1577,17 @@ type
              current_module.allunitsused;
              current_module.allunitsused;
            end;
            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));
-
-         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));
+         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));
+           end;
 
 
          { leave when we got an error }
          { leave when we got an error }
          if (Errorcount>0) and not status.skip_error then
          if (Errorcount>0) and not status.skip_error then
@@ -1602,6 +1605,8 @@ type
           begin
           begin
             hp2:=hp;
             hp2:=hp;
             hp:=tmodule(hp.next);
             hp:=tmodule(hp.next);
+            if assigned(hp2.package) then
+              add_package_unit_ref(hp2.package);
             if hp2.is_unit and
             if hp2.is_unit and
                not assigned(hp2.globalsymtable) then
                not assigned(hp2.globalsymtable) then
               loaded_units.remove(hp2);
               loaded_units.remove(hp2);
@@ -1728,6 +1733,9 @@ type
                       end;
                       end;
                     hp:=hp2;
                     hp:=hp2;
                   end;
                   end;
+                 { add the library of directly used packages }
+                 add_package_libs(linker);
+                 { and now link the package library }
                  linker.MakeSharedLibrary
                  linker.MakeSharedLibrary
                end;
                end;
 
 
@@ -2232,6 +2240,8 @@ type
                     if (hp<>sysinitmod) and (hp.flags and uf_in_library=0) then
                     if (hp<>sysinitmod) and (hp.flags and uf_in_library=0) then
                       linker.AddModuleFiles(hp);
                       linker.AddModuleFiles(hp);
                     hp2:=tmodule(hp.next);
                     hp2:=tmodule(hp.next);
+                    if assigned(hp.package) then
+                      add_package_unit_ref(hp.package);
                     if (hp<>current_module) and
                     if (hp<>current_module) and
                        (not needsymbolinfo) then
                        (not needsymbolinfo) then
                       begin
                       begin
@@ -2243,6 +2253,8 @@ type
                  { free also unneeded units we didn't free before }
                  { free also unneeded units we didn't free before }
                  if not needsymbolinfo then
                  if not needsymbolinfo then
                    unloaded_units.Clear;
                    unloaded_units.Clear;
+                 { add all directly used packages as libraries }
+                 add_package_libs(linker);
                  { finally we can create a executable }
                  { finally we can create a executable }
                  if current_module.islibrary then
                  if current_module.islibrary then
                    linker.MakeSharedLibrary
                    linker.MakeSharedLibrary