浏览代码

Store the modified PPU files directly inside the PCP and thus get finally rid of the .ppl.ppu files.

entfile.pas:
  + new entry type ibpputable
pkgutil.pas:
  * adjust RewritePPU to work on a stream as output instead of a filename
fpcp.pas, tpcppackage:
  + new method writepputable() which writes the offsets and sizes of all contained units (not part of CRC!)
  + new method writeppudata() which rewrites all contained PPUs directly into the PCP after the ibend entry (Note: the data is written 16 Byte aligned to ease viewing of the PCP and its contained PPUs in a hex editor)
  + new method readpputable() which reads the offsets and sizes of all contained units
  + new method getmodulestream() which returns a substream for a contained module
  * loadpcp: also call readpputable()
  * writepcp: first write an empty pputable, then finish writing all data that requires the put*/write* methods of the pcpfile, then use writeppudata() to write all PPUs and finally write the correct pputable at the original location
fppu.pas, tppumodule:
  * loadfrompackage: don't read the PPU from a file if it is contained in a package, but using the new tpcppackage.getmodulestream() and tppumodule.openppustream() methods
pmodules.pas, proc_package:
  * don't rewrite the PPUs here
pcp.pas:
  * increase CurrentPCPVersion

git-svn-id: branches/svenbarth/packages@32312 -
svenbarth 9 年之前
父节点
当前提交
5aa7e5740b
共有 6 个文件被更改,包括 141 次插入38 次删除
  1. 1 0
      compiler/entfile.pas
  2. 122 4
      compiler/fpcp.pas
  3. 12 5
      compiler/fppu.pas
  4. 1 1
      compiler/pcp.pas
  5. 5 19
      compiler/pkgutil.pas
  6. 0 9
      compiler/pmodules.pas

+ 1 - 0
compiler/entfile.pas

@@ -38,6 +38,7 @@ interface
     subentryid          = 2;
     {special}
     iberror             = 0;
+    ibpputable          = 241;
     ibstartrequireds    = 242;
     ibendrequireds      = 243;
     ibstartcontained    = 244;

+ 122 - 4
compiler/fpcp.pas

@@ -26,7 +26,7 @@ unit fpcp;
 interface
 
   uses
-    cclasses,
+    cclasses,cstreams,
     globtype,
     pcp,finput,fpkg;
 
@@ -43,14 +43,18 @@ interface
       procedure writecontainernames;
       procedure writecontainedunits;
       procedure writerequiredpackages;
+      procedure writepputable;
+      procedure writeppudata;
       procedure readcontainernames;
       procedure readcontainedunits;
       procedure readrequiredpackages;
+      procedure readpputable;
     public
       constructor create(const pn:string);
       destructor destroy; override;
       procedure loadpcp;
       procedure savepcp;
+      function getmodulestream(module:tmodulebase):tcstream;
       procedure initmoduleinfo(module:tmodulebase);
       procedure addunit(module:tmodulebase);
     end;
@@ -62,7 +66,7 @@ implementation
     cfileutl,cutils,
     systems,globals,version,
     verbose,
-    entfile,fppu;
+    entfile,fppu,pkgutil;
 
 { tpcppackage }
 
@@ -265,6 +269,59 @@ implementation
       pcpfile.writeentry(ibendrequireds);
     end;
 
+  procedure tpcppackage.writepputable;
+    var
+      module : pcontainedunit;
+      i : longint;
+    begin
+      { no need to write the count again; it's the same as for the contained units }
+      for i:=0 to containedmodules.count-1 do
+        begin
+          module:=pcontainedunit(containedmodules[i]);
+          pcpfile.putlongint(module^.offset);
+          pcpfile.putlongint(module^.size);
+        end;
+      pcpfile.writeentry(ibpputable);
+    end;
+
+  procedure tpcppackage.writeppudata;
+    const
+      align: array[0..15] of byte = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+    var
+      i,j,
+      pos,
+      rem : longint;
+      module : pcontainedunit;
+      stream : TCStream;
+    begin
+      pcpfile.flush;
+
+      for i:=0 to containedmodules.count-1 do
+        begin
+          module:=pcontainedunit(containedmodules[i]);
+
+          pos:=pcpfile.position;
+          { align to 16 byte so that it can be nicely viewed in hex editors;
+            maybe we could also use 512 byte alignment instead }
+          rem:=$f-(pos and $f);
+          pcpfile.stream.write(align[0],rem+1);
+          pcpfile.flush;
+          module^.offset:=pcpfile.position;
+
+          { retrieve substream for the current position }
+          stream:=pcpfile.substream(module^.offset,-1);
+          rewriteppu(module^.module.ppufilename,stream);
+          module^.size:=stream.position;
+          stream.free;
+        end;
+
+      pos:=pcpfile.position;
+      { align to 16 byte so that it can be nicely viewed in hex editors;
+        maybe we could also use 512 byte alignment instead }
+      rem:=$f-(pos and $f);
+      pcpfile.stream.write(align[0],rem+1);
+    end;
+
   procedure tpcppackage.readcontainernames;
     begin
       if pcpfile.readentry<>ibpackagefiles then
@@ -297,7 +354,7 @@ implementation
       for i:=0 to cnt-1 do
         begin
           name:=pcpfile.getstring;
-          path:=ChangeFileExt(pcpfile.getstring,'.ppl.ppu');
+          path:=pcpfile.getstring;
           new(p);
           p^.module:=nil;
           p^.ppufile:=path;
@@ -332,6 +389,24 @@ implementation
         end;
     end;
 
+  procedure tpcppackage.readpputable;
+    var
+      module : pcontainedunit;
+      i : longint;
+    begin
+      if pcpfile.readentry<>ibpputable then
+        begin
+          message(package_f_pcp_read_error);
+          internalerror(2015103001);
+        end;
+      for i:=0 to containedmodules.count-1 do
+        begin
+          module:=pcontainedunit(containedmodules[i]);
+          module^.offset:=pcpfile.getlongint;
+          module^.size:=pcpfile.getlongint;
+        end;
+    end;
+
     constructor tpcppackage.create(const pn: string);
     begin
       inherited create(pn);
@@ -373,9 +448,14 @@ implementation
       readrequiredpackages;
 
       readcontainedunits;
+
+      readpputable;
     end;
 
   procedure tpcppackage.savepcp;
+    var
+      tablepos,
+      oldpos : longint;
     begin
       { create new ppufile }
       pcpfile:=tpcpfile.create(pcpfilename);
@@ -391,7 +471,16 @@ implementation
 
       writecontainedunits;
 
-      //writeppus;
+      { the offsets and the contents of the ppus are not crc'd }
+      pcpfile.do_crc:=false;
+
+      pcpfile.flush;
+      tablepos:=pcpfile.position;
+
+      { this will write a table with empty entries }
+      writepputable;
+
+      pcpfile.do_crc:=true;
 
       { the last entry ibend is written automatically }
 
@@ -408,6 +497,18 @@ implementation
       pcpfile.header.requiredlistsize:=requiredpackages.count;
       pcpfile.writeheader;
 
+      { write the ppu table which will also fill the offsets/sizes }
+      writeppudata;
+
+      pcpfile.flush;
+      oldpos:=pcpfile.position;
+
+      { now write the filled PPU table at the previously stored position }
+      pcpfile.position:=tablepos;
+      writepputable;
+
+      pcpfile.position:=oldpos;
+
       { save crc in current module also }
       //crc:=pcpfile.crc;
 
@@ -416,6 +517,23 @@ implementation
       pcpfile:=nil;
     end;
 
+  function tpcppackage.getmodulestream(module:tmodulebase):tcstream;
+    var
+      i : longint;
+      contained : pcontainedunit;
+    begin
+      for i:=0 to containedmodules.count-1 do
+        begin
+          contained:=pcontainedunit(containedmodules[i]);
+          if contained^.module=module then
+            begin
+              result:=pcpfile.substream(contained^.offset,contained^.size);
+              exit;
+            end;
+        end;
+      result:=nil;
+    end;
+
   procedure tpcppackage.initmoduleinfo(module: tmodulebase);
     begin
       pplfilename:=extractfilename(module.sharedlibfilename);

+ 12 - 5
compiler/fppu.pas

@@ -127,7 +127,7 @@ uses
   aasmbase,ogbase,
   parser,
   comphook,
-  entfile,fpkg;
+  entfile,fpkg,fpcp;
 
 
 var
@@ -517,7 +517,7 @@ var
       end;
 
     function tppumodule.loadfrompackage: boolean;
-      var
+      {var
         singlepathstring,
         filename : TCmdStr;
 
@@ -540,7 +540,7 @@ var
             if Found then
              Begin
                SetFileName(hs,false);
-               Found:=openppufile;
+               //Found:=OpenPPU;
              End;
             PPUSearchPath:=Found;
           end;
@@ -560,12 +560,13 @@ var
                hp:=TCmdStrListItem(hp.next);
              end;
             SearchPathList:=found;
-          end;
+          end;}
 
       var
         pkg : ppackageentry;
         pkgunit : pcontainedunit;
         i,idx : longint;
+        strm : TCStream;
       begin
         result:=false;
         for i:=0 to packagelist.count-1 do
@@ -580,8 +581,14 @@ var
                 pkgunit:=pcontainedunit(pkg^.package.containedmodules[idx]);
                 if not assigned(pkgunit^.module) then
                   pkgunit^.module:=self;
-                filename:=pkgunit^.ppufile;
+                { ToDo: check whether we really don't need this anymore }
+                {filename:=pkgunit^.ppufile;
                 if not SearchPathList(unitsearchpath) then
+                  exit};
+                strm:=tpcppackage(pkg^.package).getmodulestream(self);
+                if not assigned(strm) then
+                  internalerror(2015103002);
+                if not openppustream(strm) then
                   exit;
                 package:=pkg^.package;
                 Message2(unit_u_loading_from_package,modulename^,pkg^.package.packagename^);

+ 1 - 1
compiler/pcp.pas

@@ -29,7 +29,7 @@ interface
     cstreams,entfile;
 
   const
-    CurrentPCPVersion=2;
+    CurrentPCPVersion=3;
 
   { unit flags }
     //uf_init                = $000001; { unit has initialization section }

+ 5 - 19
compiler/pkgutil.pas

@@ -27,10 +27,10 @@ unit pkgutil;
 interface
 
   uses
-    fmodule,fpkg,link;
+    fmodule,fpkg,link,cstreams;
 
   procedure createimportlibfromexternals;
-  Function RewritePPU(const PPUFn,PPLFn:String):Boolean;
+  Function RewritePPU(const PPUFn:String;OutStream:TCStream):Boolean;
   procedure export_unit(u:tmodule);
   procedure load_packages;
   procedure add_package(const name:string;ignoreduplicates:boolean);
@@ -205,7 +205,7 @@ implementation
             end;
     end;
 
-  Function RewritePPU(const PPUFn,PPLFn:String):Boolean;
+  Function RewritePPU(const PPUFn:String;OutStream:TCStream):Boolean;
     Var
       MakeStatic : Boolean;
     Var
@@ -271,11 +271,8 @@ implementation
          MakeStatic:=true;
        end;
     { Create the new ppu }
-      if PPUFn=PPLFn then
-       outppu:=tppufile.create('ppumove.$$$')
-      else
-       outppu:=tppufile.create(PPLFn);
-      outppu.createfile;
+      outppu:=tppufile.create(PPUFn);
+      outppu.createstream(OutStream);
     { Create new header, with the new flags }
       outppu.header:=inppu.header;
       outppu.header.common.flags:=outppu.header.common.flags or uf_in_library;
@@ -389,17 +386,6 @@ implementation
       outppu.writeheader;
       outppu.free;
       inppu.free;
-    { rename }
-      if PPUFn=PPLFn then
-       begin
-         {$push}{$I-}
-          assign(f,PPUFn);
-          erase(f);
-          assign(f,'ppumove.$$$');
-          rename(f,PPUFn);
-         {$pop}
-         if ioresult<>0 then;
-       end;
       Result:=True;
     end;
 

+ 0 - 9
compiler/pmodules.pas

@@ -1656,15 +1656,6 @@ type
 
              pkg.initmoduleinfo(current_module);
 
-             { finally rewrite all units included into the package }
-             uu:=tused_unit(usedunits.first);
-             while assigned(uu) do
-               begin
-                 if not assigned(uu.u.package) then
-                   RewritePPU(uu.u.ppufilename,changefileext(uu.u.ppufilename,'.ppl.ppu'));
-                 uu:=tused_unit(uu.next);
-               end;
-
              { create the executable when we are at level 1 }
              if (compile_level=1) then
                begin