mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 11:24:16 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			652 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			652 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
{
 | 
						|
    Copyright (c) 1999-2002 by the FPC Development Team
 | 
						|
 | 
						|
    Add multiple FPC units into a static/shared library
 | 
						|
 | 
						|
    This program is free software; you can redistribute it and/or modify
 | 
						|
    it under the terms of the GNU General Public License as published by
 | 
						|
    the Free Software Foundation; either version 2 of the License, or
 | 
						|
    (at your option) any later version.
 | 
						|
 | 
						|
    This program is distributed in the hope that it will be useful,
 | 
						|
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
    GNU General Public License for more details.
 | 
						|
 | 
						|
    You should have received a copy of the GNU General Public License
 | 
						|
    along with this program; if not, write to the Free Software
 | 
						|
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
						|
 | 
						|
 ****************************************************************************}
 | 
						|
{$ifndef TP}
 | 
						|
  {$H+}
 | 
						|
{$endif}
 | 
						|
Program ppumove;
 | 
						|
uses
 | 
						|
 | 
						|
{$IFDEF MACOS}
 | 
						|
{$DEFINE USE_FAKE_SYSUTILS}
 | 
						|
{$ENDIF MACOS}
 | 
						|
 | 
						|
{$IFNDEF USE_FAKE_SYSUTILS}
 | 
						|
  sysutils,
 | 
						|
{$ELSE}
 | 
						|
  fksysutl,
 | 
						|
{$ENDIF}
 | 
						|
 | 
						|
{$ifdef unix}
 | 
						|
  Baseunix,Unix, UnixUtil,
 | 
						|
{$else unix}
 | 
						|
  dos,
 | 
						|
{$endif unix}
 | 
						|
  cutils,ppu,systems,
 | 
						|
  getopts;
 | 
						|
 | 
						|
const
 | 
						|
  Version   = 'Version 2.1.1';
 | 
						|
  Title     = 'PPU-Mover';
 | 
						|
  Copyright = 'Copyright (c) 1998-2007 by the Free Pascal Development Team';
 | 
						|
 | 
						|
  ShortOpts = 'o:e:d:i:qhsvb';
 | 
						|
  BufSize = 4096;
 | 
						|
  PPUExt = 'ppu';
 | 
						|
  ObjExt = 'o';
 | 
						|
  StaticLibExt ='a';
 | 
						|
{$ifdef unix}
 | 
						|
  SharedLibExt ='so';
 | 
						|
  BatchExt     ='.sh';
 | 
						|
{$else}
 | 
						|
  SharedLibExt ='dll';
 | 
						|
  BatchExt     ='.bat';
 | 
						|
{$endif unix}
 | 
						|
 | 
						|
  { link options }
 | 
						|
  link_none    = $0;
 | 
						|
  link_always  = $1;
 | 
						|
  link_static  = $2;
 | 
						|
  link_smart   = $4;
 | 
						|
  link_shared  = $8;
 | 
						|
 | 
						|
Type
 | 
						|
  PLinkOEnt = ^TLinkOEnt;
 | 
						|
  TLinkOEnt = record
 | 
						|
    Name : string;
 | 
						|
    Next : PLinkOEnt;
 | 
						|
  end;
 | 
						|
 | 
						|
Var
 | 
						|
  ArBin,LDBin,StripBin,
 | 
						|
  OutputFileForPPU,
 | 
						|
  OutputFile,
 | 
						|
  OutputFileForLink,  { the name of the output file needed when linking }
 | 
						|
  InputPath,
 | 
						|
  DestPath,
 | 
						|
  PPLExt,
 | 
						|
  LibExt      : string;
 | 
						|
  DoStrip,
 | 
						|
  Batch,
 | 
						|
  Quiet,
 | 
						|
  MakeStatic  : boolean;
 | 
						|
  Buffer      : Pointer;
 | 
						|
  ObjFiles    : PLinkOEnt;
 | 
						|
  BatchFile   : Text;
 | 
						|
  Libs        : ansistring;
 | 
						|
 | 
						|
{*****************************************************************************
 | 
						|
                                 Helpers
 | 
						|
*****************************************************************************}
 | 
						|
 | 
						|
Procedure Error(const s:string;stop:boolean);
 | 
						|
{
 | 
						|
  Write an error message to stderr
 | 
						|
}
 | 
						|
begin
 | 
						|
  writeln(stderr,s);
 | 
						|
  if stop then
 | 
						|
   halt(1);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function Shell(const s:string):longint;
 | 
						|
{
 | 
						|
  Run a shell commnad and return the exitcode
 | 
						|
}
 | 
						|
begin
 | 
						|
  if Batch then
 | 
						|
   begin
 | 
						|
     Writeln(BatchFile,s);
 | 
						|
     Shell:=0;
 | 
						|
     exit;
 | 
						|
   end;
 | 
						|
{$ifdef unix}
 | 
						|
  Shell:=unix.fpsystem(s);
 | 
						|
{$else}
 | 
						|
  exec(getenv('COMSPEC'),'/C '+s);
 | 
						|
  Shell:=DosExitCode;
 | 
						|
{$endif}
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Function FileExists (Const F : String) : Boolean;
 | 
						|
{
 | 
						|
  Returns True if the file exists, False if not.
 | 
						|
}
 | 
						|
Var
 | 
						|
{$ifdef unix}
 | 
						|
  info : Stat;
 | 
						|
{$else}
 | 
						|
  info : searchrec;
 | 
						|
{$endif}
 | 
						|
begin
 | 
						|
{$ifdef unix}
 | 
						|
  FileExists:=FpStat(F,Info)=0;
 | 
						|
{$else}
 | 
						|
  FindFirst (F,anyfile,Info);
 | 
						|
  FileExists:=DosError=0;
 | 
						|
{$endif}
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Function ChangeFileExt(Const HStr,ext:String):String;
 | 
						|
{
 | 
						|
  Return a filename which will have extension ext added if no
 | 
						|
  extension is found
 | 
						|
}
 | 
						|
var
 | 
						|
  j : longint;
 | 
						|
begin
 | 
						|
  j:=length(Hstr);
 | 
						|
  while (j>0) and (Hstr[j]<>'.') do
 | 
						|
   dec(j);
 | 
						|
  if j=0 then
 | 
						|
   ChangeFileExt:=Hstr+'.'+Ext
 | 
						|
  else
 | 
						|
   ChangeFileExt:=HStr;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Function ForceExtension(Const HStr,ext:String):String;
 | 
						|
{
 | 
						|
  Return a filename which certainly has the extension ext
 | 
						|
}
 | 
						|
var
 | 
						|
  j : longint;
 | 
						|
begin
 | 
						|
  j:=length(Hstr);
 | 
						|
  while (j>0) and (Hstr[j]<>'.') do
 | 
						|
   dec(j);
 | 
						|
  if j=0 then
 | 
						|
   j:=255;
 | 
						|
  ForceExtension:=Copy(Hstr,1,j-1)+'.'+Ext;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Procedure AddToLinkFiles(const S : String);
 | 
						|
{
 | 
						|
  Adds a filename to a list of object files to link to.
 | 
						|
  No duplicates allowed.
 | 
						|
}
 | 
						|
Var
 | 
						|
  P : PLinKOEnt;
 | 
						|
begin
 | 
						|
  P:=ObjFiles;
 | 
						|
  { Don't add files twice }
 | 
						|
  While (P<>nil) and (p^.name<>s) do
 | 
						|
    p:=p^.next;
 | 
						|
  if p=nil then
 | 
						|
   begin
 | 
						|
     new(p);
 | 
						|
     p^.next:=ObjFiles;
 | 
						|
     p^.name:=s;
 | 
						|
     ObjFiles:=P;
 | 
						|
   end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Function ExtractLib(const libfn:string):string;
 | 
						|
{
 | 
						|
  Extract a static library libfn and return the files with a
 | 
						|
  wildcard
 | 
						|
}
 | 
						|
var
 | 
						|
  n : namestr;
 | 
						|
  d : dirstr;
 | 
						|
  e : extstr;
 | 
						|
begin
 | 
						|
{ create the temp dir first }
 | 
						|
  fsplit(libfn,d,n,e);
 | 
						|
  {$I-}
 | 
						|
   mkdir(n+'.sl');
 | 
						|
  {$I+}
 | 
						|
  if ioresult<>0 then;
 | 
						|
{ Extract }
 | 
						|
  if Shell(arbin+' x '+libfn)<>0 then
 | 
						|
   Error('Fatal: Error running '+arbin,true);
 | 
						|
{ Remove the lib file, it's extracted so it can be created with ease }
 | 
						|
  if PPLExt=PPUExt then
 | 
						|
   Shell('rm '+libfn);
 | 
						|
{$ifdef unix}
 | 
						|
  ExtractLib:=n+'.sl/*';
 | 
						|
{$else}
 | 
						|
  ExtractLib:=n+'.sl\*';
 | 
						|
{$endif}
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Function DoPPU(const PPUFn,PPLFn:String):Boolean;
 | 
						|
{
 | 
						|
  Convert one file (in Filename) to library format.
 | 
						|
  Return true if successful, false otherwise.
 | 
						|
}
 | 
						|
Var
 | 
						|
  inppu,
 | 
						|
  outppu : tppufile;
 | 
						|
  b,
 | 
						|
  untilb : byte;
 | 
						|
  l,m    : longint;
 | 
						|
  f      : file;
 | 
						|
  ext,
 | 
						|
  s      : string;
 | 
						|
  ppuversion : dword;
 | 
						|
begin
 | 
						|
  DoPPU:=false;
 | 
						|
  If Not Quiet then
 | 
						|
   Write ('Processing ',PPUFn,'...');
 | 
						|
  inppu:=tppufile.create(PPUFn);
 | 
						|
  if not inppu.openfile then
 | 
						|
   begin
 | 
						|
     inppu.free;
 | 
						|
     Error('Error: Could not open : '+PPUFn,false);
 | 
						|
     Exit;
 | 
						|
   end;
 | 
						|
{ Check the ppufile }
 | 
						|
  if not inppu.CheckPPUId then
 | 
						|
   begin
 | 
						|
     inppu.free;
 | 
						|
     Error('Error: Not a PPU File : '+PPUFn,false);
 | 
						|
     Exit;
 | 
						|
   end;
 | 
						|
  ppuversion:=inppu.GetPPUVersion;
 | 
						|
  if ppuversion<CurrentPPUVersion then
 | 
						|
   begin
 | 
						|
     inppu.free;
 | 
						|
     Error('Error: Wrong PPU Version '+tostr(ppuversion)+' in '+PPUFn,false);
 | 
						|
     Exit;
 | 
						|
   end;
 | 
						|
{ No .o file generated for this ppu, just skip }
 | 
						|
  if (inppu.header.flags and uf_no_link)<>0 then
 | 
						|
   begin
 | 
						|
     inppu.free;
 | 
						|
     If Not Quiet then
 | 
						|
      Writeln (' No files.');
 | 
						|
     DoPPU:=true;
 | 
						|
     Exit;
 | 
						|
   end;
 | 
						|
{ Already a lib? }
 | 
						|
  if (inppu.header.flags and uf_in_library)<>0 then
 | 
						|
   begin
 | 
						|
     inppu.free;
 | 
						|
     Error('Error: PPU is already in a library : '+PPUFn,false);
 | 
						|
     Exit;
 | 
						|
   end;
 | 
						|
{ We need a static linked unit }
 | 
						|
  if (inppu.header.flags and uf_static_linked)=0 then
 | 
						|
   begin
 | 
						|
     inppu.free;
 | 
						|
     Error('Error: PPU is not static linked : '+PPUFn,false);
 | 
						|
     Exit;
 | 
						|
   end;
 | 
						|
{ Check if shared is allowed }
 | 
						|
  if tsystem(inppu.header.target) in [system_i386_go32v2] then
 | 
						|
   begin
 | 
						|
     Writeln('Warning: shared library not supported for ppu target, switching to static library');
 | 
						|
     MakeStatic:=true;
 | 
						|
   end;
 | 
						|
{ Create the new ppu }
 | 
						|
  if PPUFn=PPLFn then
 | 
						|
   outppu:=tppufile.create('ppumove.$$$')
 | 
						|
  else
 | 
						|
   outppu:=tppufile.create(PPLFn);
 | 
						|
  outppu.createfile;
 | 
						|
{ Create new header, with the new flags }
 | 
						|
  outppu.header:=inppu.header;
 | 
						|
  outppu.header.flags:=outppu.header.flags or uf_in_library;
 | 
						|
  if MakeStatic then
 | 
						|
   outppu.header.flags:=outppu.header.flags or uf_static_linked
 | 
						|
  else
 | 
						|
   outppu.header.flags:=outppu.header.flags or uf_shared_linked;
 | 
						|
{ read until the object files are found }
 | 
						|
  untilb:=iblinkunitofiles;
 | 
						|
  repeat
 | 
						|
    b:=inppu.readentry;
 | 
						|
    if b in [ibendinterface,ibend] then
 | 
						|
     begin
 | 
						|
       inppu.free;
 | 
						|
       outppu.free;
 | 
						|
       Error('Error: No files to be linked found : '+PPUFn,false);
 | 
						|
       Exit;
 | 
						|
     end;
 | 
						|
    if b<>untilb then
 | 
						|
     begin
 | 
						|
       repeat
 | 
						|
         inppu.getdatabuf(buffer^,bufsize,l);
 | 
						|
         outppu.putdata(buffer^,l);
 | 
						|
       until l<bufsize;
 | 
						|
       outppu.writeentry(b);
 | 
						|
     end;
 | 
						|
  until (b=untilb);
 | 
						|
{ we have now reached the section for the files which need to be added,
 | 
						|
  now add them to the list }
 | 
						|
  case b of
 | 
						|
    iblinkunitofiles :
 | 
						|
      begin
 | 
						|
        { add all o files, and save the entry when not creating a static
 | 
						|
          library to keep staticlinking possible }
 | 
						|
        while not inppu.endofentry do
 | 
						|
         begin
 | 
						|
           s:=inppu.getstring;
 | 
						|
           m:=inppu.getlongint;
 | 
						|
           if not MakeStatic then
 | 
						|
            begin
 | 
						|
              outppu.putstring(s);
 | 
						|
              outppu.putlongint(m);
 | 
						|
            end;
 | 
						|
           AddToLinkFiles(s);
 | 
						|
         end;
 | 
						|
        if not MakeStatic then
 | 
						|
         outppu.writeentry(b);
 | 
						|
      end;
 | 
						|
{    iblinkunitstaticlibs :
 | 
						|
      begin
 | 
						|
        AddToLinkFiles(ExtractLib(inppu.getstring));
 | 
						|
        if not inppu.endofentry then
 | 
						|
         begin
 | 
						|
           repeat
 | 
						|
             inppu.getdatabuf(buffer^,bufsize,l);
 | 
						|
             outppu.putdata(buffer^,l);
 | 
						|
           until l<bufsize;
 | 
						|
           outppu.writeentry(b);
 | 
						|
         end;
 | 
						|
       end; }
 | 
						|
  end;
 | 
						|
{ just add a new entry with the new lib }
 | 
						|
  if MakeStatic then
 | 
						|
   begin
 | 
						|
     outppu.putstring(OutputfileForPPU);
 | 
						|
     outppu.putlongint(link_static);
 | 
						|
     outppu.writeentry(iblinkunitstaticlibs)
 | 
						|
   end
 | 
						|
  else
 | 
						|
   begin
 | 
						|
     outppu.putstring(OutputfileForPPU);
 | 
						|
     outppu.putlongint(link_shared);
 | 
						|
     outppu.writeentry(iblinkunitsharedlibs);
 | 
						|
   end;
 | 
						|
{ read all entries until the end and write them also to the new ppu }
 | 
						|
  repeat
 | 
						|
    b:=inppu.readentry;
 | 
						|
  { don't write ibend, that's written automaticly }
 | 
						|
    if b<>ibend then
 | 
						|
     begin
 | 
						|
       if b=iblinkothersharedlibs then
 | 
						|
         begin
 | 
						|
           while not inppu.endofentry do
 | 
						|
             begin
 | 
						|
               s:=inppu.getstring;
 | 
						|
               m:=inppu.getlongint;
 | 
						|
 | 
						|
               outppu.putstring(s);
 | 
						|
 | 
						|
               { strip lib prefix }
 | 
						|
               if copy(s,1,3)='lib' then
 | 
						|
                 delete(s,1,3);
 | 
						|
 | 
						|
               { strip lib prefix }
 | 
						|
               if copy(s,1,3)='lib' then
 | 
						|
                 delete(s,1,3);
 | 
						|
               ext:=ExtractFileExt(s);
 | 
						|
               if ext<>'' then
 | 
						|
                 delete(s,length(s)-length(ext)+1,length(ext));
 | 
						|
 | 
						|
               libs:=libs+' -l'+s;
 | 
						|
 | 
						|
               outppu.putlongint(m);
 | 
						|
             end;
 | 
						|
         end
 | 
						|
       else
 | 
						|
         repeat
 | 
						|
           inppu.getdatabuf(buffer^,bufsize,l);
 | 
						|
           outppu.putdata(buffer^,l);
 | 
						|
         until l<bufsize;
 | 
						|
       outppu.writeentry(b);
 | 
						|
     end;
 | 
						|
  until b=ibend;
 | 
						|
{ write the last stuff and close }
 | 
						|
  outppu.flush;
 | 
						|
  outppu.writeheader;
 | 
						|
  outppu.free;
 | 
						|
  inppu.free;
 | 
						|
{ rename }
 | 
						|
  if PPUFn=PPLFn then
 | 
						|
   begin
 | 
						|
     {$I-}
 | 
						|
      assign(f,PPUFn);
 | 
						|
      erase(f);
 | 
						|
      assign(f,'ppumove.$$$');
 | 
						|
      rename(f,PPUFn);
 | 
						|
     {$I+}
 | 
						|
     if ioresult<>0 then;
 | 
						|
   end;
 | 
						|
{ the end }
 | 
						|
  If Not Quiet then
 | 
						|
   Writeln (' Done.');
 | 
						|
  DoPPU:=True;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Function DoFile(const FileName:String):Boolean;
 | 
						|
{
 | 
						|
  Process a file, mainly here for wildcard support under Dos
 | 
						|
}
 | 
						|
{$ifndef unix}
 | 
						|
var
 | 
						|
  dir : searchrec;
 | 
						|
{$endif}
 | 
						|
begin
 | 
						|
{$ifdef unix}
 | 
						|
  DoFile:=DoPPU(InputPath+FileName,InputPath+ForceExtension(FileName,PPLExt));
 | 
						|
{$else}
 | 
						|
  DoFile:=false;
 | 
						|
  findfirst(filename,$20,dir);
 | 
						|
  while doserror=0 do
 | 
						|
   begin
 | 
						|
     if not DoPPU(InputPath+Dir.Name,InputPath+ForceExtension(Dir.Name,PPLExt)) then
 | 
						|
      exit;
 | 
						|
     findnext(dir);
 | 
						|
   end;
 | 
						|
  findclose(dir);
 | 
						|
  DoFile:=true;
 | 
						|
{$endif}
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Procedure DoLink;
 | 
						|
{
 | 
						|
  Link the object files together to form a (shared) library
 | 
						|
}
 | 
						|
Var
 | 
						|
  Names : ansistring;
 | 
						|
  f     : file;
 | 
						|
  Err   : boolean;
 | 
						|
  P     : PLinkOEnt;
 | 
						|
begin
 | 
						|
  if not Quiet then
 | 
						|
   Write ('Linking ');
 | 
						|
  P:=ObjFiles;
 | 
						|
  names:='';
 | 
						|
  While p<>nil do
 | 
						|
   begin
 | 
						|
     if Names<>'' then
 | 
						|
      Names:=Names+' '+InputPath+P^.name
 | 
						|
     else
 | 
						|
      Names:=InputPath+p^.Name;
 | 
						|
     p:=p^.next;
 | 
						|
   end;
 | 
						|
  if Names='' then
 | 
						|
   begin
 | 
						|
     If not Quiet then
 | 
						|
      Writeln('Error: no files found to be linked');
 | 
						|
     exit;
 | 
						|
   end;
 | 
						|
  If not Quiet then
 | 
						|
    WriteLn(names+Libs);
 | 
						|
{ Run ar or ld to create the lib }
 | 
						|
  If MakeStatic then
 | 
						|
   Err:=Shell(arbin+' rs '+outputfile+' '+names)<>0
 | 
						|
  else
 | 
						|
   begin
 | 
						|
     Err:=Shell(ldbin+' -shared -E -o '+OutputFile+' '+names+' '+libs)<>0;
 | 
						|
     if (not Err) and dostrip then
 | 
						|
      Shell(stripbin+' --strip-unneeded '+OutputFile);
 | 
						|
   end;
 | 
						|
  If Err then
 | 
						|
   Error('Fatal: Library building stage failed.',true);
 | 
						|
{ fix permission to 644, so it's not 755 }
 | 
						|
{$ifdef unix}
 | 
						|
  FPChmod(OutputFile,420);
 | 
						|
{$endif}
 | 
						|
{ Rename to the destpath }
 | 
						|
  if DestPath<>'' then
 | 
						|
   begin
 | 
						|
     Assign(F, OutputFile);
 | 
						|
     Rename(F,DestPath+DirectorySeparator+OutputFile);
 | 
						|
   end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Procedure usage;
 | 
						|
{
 | 
						|
  Print usage and exit.
 | 
						|
}
 | 
						|
begin
 | 
						|
  Writeln(paramstr(0),': [-qhvbsS] [-e ext] [-o name] [-d path] file [file ...]');
 | 
						|
  Halt(0);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
 | 
						|
Procedure processopts;
 | 
						|
{
 | 
						|
  Process command line opions, and checks if command line options OK.
 | 
						|
}
 | 
						|
var
 | 
						|
  C : char;
 | 
						|
begin
 | 
						|
  if paramcount=0 then
 | 
						|
   usage;
 | 
						|
{ Reset }
 | 
						|
  ObjFiles:=Nil;
 | 
						|
  Quiet:=False;
 | 
						|
  Batch:=False;
 | 
						|
  DoStrip:=False;
 | 
						|
  OutputFile:='';
 | 
						|
  PPLExt:='ppu';
 | 
						|
  ArBin:='ar';
 | 
						|
  LdBin:='ld';
 | 
						|
  StripBin:='strip';
 | 
						|
  repeat
 | 
						|
    c:=Getopt (ShortOpts);
 | 
						|
    Case C of
 | 
						|
      EndOfOptions : break;
 | 
						|
      'S' : MakeStatic:=True;
 | 
						|
      'o' : OutputFile:=OptArg;
 | 
						|
      'd' : DestPath:=OptArg;
 | 
						|
      'i' : begin
 | 
						|
              InputPath:=OptArg;
 | 
						|
              if InputPath[length(InputPath)]<>DirectorySeparator then
 | 
						|
                InputPath:=InputPath+DirectorySeparator;
 | 
						|
            end;
 | 
						|
      'e' : PPLext:=OptArg;
 | 
						|
      'q' : Quiet:=True;
 | 
						|
      'b' : Batch:=true;
 | 
						|
      's' : DoStrip:=true;
 | 
						|
      '?' : Usage;
 | 
						|
      'h' : Usage;
 | 
						|
    end;
 | 
						|
  until false;
 | 
						|
{ Test filenames on the commandline }
 | 
						|
  if (OptInd>Paramcount) then
 | 
						|
   Error('Error: no input files',true);
 | 
						|
  if (OptInd<ParamCount) and (OutputFile='') then
 | 
						|
   Error('Error: when moving multiple units, specify an output name.',true);
 | 
						|
{ alloc a buffer }
 | 
						|
  GetMem (Buffer,Bufsize);
 | 
						|
  If Buffer=Nil then
 | 
						|
   Error('Error: could not allocate memory for buffer.',true);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
var
 | 
						|
  i : longint;
 | 
						|
begin
 | 
						|
  Libs:='';
 | 
						|
  ProcessOpts;
 | 
						|
{ Write Header }
 | 
						|
  if not Quiet then
 | 
						|
   begin
 | 
						|
     Writeln(Title+' '+Version);
 | 
						|
     Writeln(Copyright);
 | 
						|
     Writeln;
 | 
						|
   end;
 | 
						|
{ fix the libext and outputfilename }
 | 
						|
  if Makestatic then
 | 
						|
   LibExt:=StaticLibExt
 | 
						|
  else
 | 
						|
   LibExt:=SharedLibExt;
 | 
						|
  if OutputFile='' then
 | 
						|
   OutputFile:=Paramstr(OptInd);
 | 
						|
  OutputFileForPPU:=OutputFile;
 | 
						|
{ fix filename }
 | 
						|
{$ifdef unix}
 | 
						|
  if Copy(OutputFile,1,3)<>'lib' then
 | 
						|
   OutputFile:='lib'+OutputFile;
 | 
						|
  { For unix skip replacing the extension if a full .so.X.X if specified }
 | 
						|
  i:=pos('.so.',Outputfile);
 | 
						|
  if i<>0 then
 | 
						|
   OutputFileForLink:=Copy(Outputfile,4,i-4)
 | 
						|
  else
 | 
						|
   begin
 | 
						|
     OutputFile:=ForceExtension(OutputFile,LibExt);
 | 
						|
     OutputFileForLink:=Copy(Outputfile,4,length(Outputfile)-length(LibExt)-4);
 | 
						|
   end;
 | 
						|
{$else}
 | 
						|
  OutputFile:=ForceExtension(OutputFile,LibExt);
 | 
						|
  OutputFileForLink:=OutputFile;
 | 
						|
{$endif}
 | 
						|
{ Open BatchFile }
 | 
						|
  if Batch then
 | 
						|
   begin
 | 
						|
     Assign(BatchFile,'pmove'+BatchExt);
 | 
						|
     Rewrite(BatchFile);
 | 
						|
   end;
 | 
						|
{ Process Files }
 | 
						|
  i:=OptInd;
 | 
						|
  While (i<=ParamCount) and Dofile(ChangeFileExt(Paramstr(i),PPUExt)) do
 | 
						|
   Inc(i);
 | 
						|
{ Do Linking stage }
 | 
						|
  DoLink;
 | 
						|
{ Close BatchFile }
 | 
						|
  if Batch then
 | 
						|
   begin
 | 
						|
     if Not Quiet then
 | 
						|
      Writeln('Writing pmove'+BatchExt);
 | 
						|
     Close(BatchFile);
 | 
						|
{$ifdef unix}
 | 
						|
  FPChmod('pmove'+BatchExt,493);
 | 
						|
{$endif}
 | 
						|
   end;
 | 
						|
{ The End }
 | 
						|
  if Not Quiet then
 | 
						|
   Writeln('Done.');
 | 
						|
end.
 |