Browse Source

* split config in global config and compiler config

git-svn-id: trunk@6344 -
peter 18 years ago
parent
commit
a4f501852e

+ 1 - 0
.gitattributes

@@ -8243,6 +8243,7 @@ utils/fppkg/lnet/sys/lkqueueeventerh.inc svneol=native#text/plain
 utils/fppkg/lnet/sys/lspawnfcgiunix.inc svneol=native#text/plain
 utils/fppkg/lnet/sys/lspawnfcgiwin.inc svneol=native#text/plain
 utils/fppkg/lnet/sys/osunits.inc svneol=native#text/plain
+utils/fppkg/pkgcommands.pp svneol=native#text/plain
 utils/fppkg/pkgdownload.pp svneol=native#text/plain
 utils/fppkg/pkgfpmake.pp svneol=native#text/plain
 utils/fppkg/pkghandler.pp svneol=native#text/plain

+ 140 - 109
utils/fppkg/fppkg.lpi

@@ -12,7 +12,7 @@
       <MainUnit Value="0"/>
       <IconPath Value=".\"/>
       <TargetFileExt Value=""/>
-      <ActiveEditorIndexAtStart Value="0"/>
+      <ActiveEditorIndexAtStart Value="17"/>
     </General>
     <VersionInfo>
       <ProjectVersion Value=""/>
@@ -32,25 +32,25 @@
         <LaunchingApplication PathPlusParams="\usr\X11R6\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
       </local>
     </RunParams>
-    <Units Count="20">
+    <Units Count="23">
       <Unit0>
         <Filename Value="fppkg.pp"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="fppkg"/>
-        <CursorPos X="32" Y="231"/>
-        <TopLine Value="212"/>
+        <CursorPos X="14" Y="105"/>
+        <TopLine Value="76"/>
         <EditorIndex Value="0"/>
-        <UsageCount Value="33"/>
+        <UsageCount Value="43"/>
         <Loaded Value="True"/>
       </Unit0>
       <Unit1>
         <Filename Value="pkgropts.pp"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="pkgropts"/>
-        <CursorPos X="19" Y="25"/>
-        <TopLine Value="22"/>
-        <EditorIndex Value="6"/>
-        <UsageCount Value="33"/>
+        <CursorPos X="31" Y="201"/>
+        <TopLine Value="184"/>
+        <EditorIndex Value="9"/>
+        <UsageCount Value="43"/>
         <Loaded Value="True"/>
       </Unit1>
       <Unit2>
@@ -58,7 +58,7 @@
         <IsPartOfProject Value="True"/>
         <CursorPos X="64" Y="8"/>
         <TopLine Value="1"/>
-        <UsageCount Value="33"/>
+        <UsageCount Value="43"/>
       </Unit2>
       <Unit3>
         <Filename Value="fpmktype.pp"/>
@@ -66,8 +66,8 @@
         <UnitName Value="fpmktype"/>
         <CursorPos X="3" Y="41"/>
         <TopLine Value="1"/>
-        <EditorIndex Value="9"/>
-        <UsageCount Value="33"/>
+        <EditorIndex Value="13"/>
+        <UsageCount Value="43"/>
         <Loaded Value="True"/>
       </Unit3>
       <Unit4>
@@ -77,43 +77,47 @@
         <CursorPos X="1" Y="1"/>
         <TopLine Value="1"/>
         <EditorIndex Value="1"/>
-        <UsageCount Value="33"/>
+        <UsageCount Value="43"/>
         <Loaded Value="True"/>
       </Unit4>
       <Unit5>
         <Filename Value="fprepos.pp"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="fprepos"/>
-        <CursorPos X="27" Y="28"/>
-        <TopLine Value="2"/>
+        <CursorPos X="5" Y="678"/>
+        <TopLine Value="666"/>
         <EditorIndex Value="5"/>
-        <UsageCount Value="33"/>
+        <UsageCount Value="43"/>
         <Loaded Value="True"/>
       </Unit5>
       <Unit6>
         <Filename Value="fpxmlrep.pp"/>
         <IsPartOfProject Value="True"/>
-        <UsageCount Value="33"/>
-        <SyntaxHighlighter Value="Text"/>
+        <UnitName Value="fpxmlrep"/>
+        <CursorPos X="1" Y="831"/>
+        <TopLine Value="794"/>
+        <EditorIndex Value="8"/>
+        <UsageCount Value="43"/>
+        <Loaded Value="True"/>
       </Unit6>
       <Unit7>
         <Filename Value="pkghandler.pp"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="pkghandler"/>
-        <CursorPos X="52" Y="51"/>
-        <TopLine Value="32"/>
-        <EditorIndex Value="13"/>
-        <UsageCount Value="33"/>
+        <CursorPos X="1" Y="115"/>
+        <TopLine Value="97"/>
+        <EditorIndex Value="17"/>
+        <UsageCount Value="43"/>
         <Loaded Value="True"/>
       </Unit7>
       <Unit8>
         <Filename Value="pkgmkconv.pp"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="pkgmkconv"/>
-        <CursorPos X="1" Y="46"/>
-        <TopLine Value="20"/>
-        <EditorIndex Value="11"/>
-        <UsageCount Value="33"/>
+        <CursorPos X="69" Y="697"/>
+        <TopLine Value="660"/>
+        <EditorIndex Value="15"/>
+        <UsageCount Value="43"/>
         <Loaded Value="True"/>
       </Unit8>
       <Unit9>
@@ -122,18 +126,18 @@
         <UnitName Value="pkgdownload"/>
         <CursorPos X="32" Y="18"/>
         <TopLine Value="5"/>
-        <EditorIndex Value="10"/>
-        <UsageCount Value="33"/>
+        <EditorIndex Value="14"/>
+        <UsageCount Value="43"/>
         <Loaded Value="True"/>
       </Unit9>
       <Unit10>
         <Filename Value="pkgmessages.pp"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="pkgmessages"/>
-        <CursorPos X="69" Y="12"/>
-        <TopLine Value="1"/>
-        <EditorIndex Value="8"/>
-        <UsageCount Value="33"/>
+        <CursorPos X="3" Y="43"/>
+        <TopLine Value="6"/>
+        <EditorIndex Value="12"/>
+        <UsageCount Value="43"/>
         <Loaded Value="True"/>
       </Unit10>
       <Unit11>
@@ -141,29 +145,29 @@
         <UnitName Value="streamcoll"/>
         <CursorPos X="66" Y="88"/>
         <TopLine Value="65"/>
-        <UsageCount Value="9"/>
+        <UsageCount Value="8"/>
       </Unit11>
       <Unit12>
         <Filename Value="streamcoll20.pp"/>
         <UnitName Value="streamcoll"/>
         <CursorPos X="3" Y="15"/>
         <TopLine Value="1"/>
-        <UsageCount Value="9"/>
+        <UsageCount Value="8"/>
       </Unit12>
       <Unit13>
         <Filename Value="..\..\..\fpc20\rtl\objpas\classes\classesh.inc"/>
-        <CursorPos X="17" Y="1345"/>
-        <TopLine Value="1326"/>
+        <CursorPos X="24" Y="518"/>
+        <TopLine Value="486"/>
         <EditorIndex Value="2"/>
-        <UsageCount Value="16"/>
+        <UsageCount Value="21"/>
         <Loaded Value="True"/>
       </Unit13>
       <Unit14>
         <Filename Value="..\..\..\fpc20\rtl\inc\objpash.inc"/>
         <CursorPos X="38" Y="277"/>
         <TopLine Value="269"/>
-        <EditorIndex Value="12"/>
-        <UsageCount Value="16"/>
+        <EditorIndex Value="16"/>
+        <UsageCount Value="21"/>
         <Loaded Value="True"/>
       </Unit14>
       <Unit15>
@@ -171,33 +175,33 @@
         <UnitName Value="contnrs"/>
         <CursorPos X="1" Y="19"/>
         <TopLine Value="1"/>
-        <UsageCount Value="9"/>
+        <UsageCount Value="8"/>
       </Unit15>
       <Unit16>
         <Filename Value="contnrs20.pp"/>
-        <UnitName Value="contnrs"/>
-        <CursorPos X="43" Y="32"/>
+        <UnitName Value="contnrs20"/>
+        <CursorPos X="1" Y="1"/>
         <TopLine Value="1"/>
         <EditorIndex Value="3"/>
-        <UsageCount Value="10"/>
+        <UsageCount Value="15"/>
         <Loaded Value="True"/>
       </Unit16>
       <Unit17>
-        <Filename Value="pkgfpmake.pp"/>
-        <UnitName Value="pkgfpmake"/>
-        <CursorPos X="45" Y="85"/>
-        <TopLine Value="1"/>
-        <EditorIndex Value="7"/>
-        <UsageCount Value="15"/>
+        <Filename Value="pkgcommands.pp"/>
+        <UnitName Value="pkgcommands"/>
+        <CursorPos X="41" Y="62"/>
+        <TopLine Value="44"/>
+        <EditorIndex Value="11"/>
+        <UsageCount Value="20"/>
         <Loaded Value="True"/>
       </Unit17>
       <Unit18>
         <Filename Value="pkgwget.pp"/>
         <UnitName Value="pkgwget"/>
-        <CursorPos X="23" Y="6"/>
+        <CursorPos X="1" Y="1"/>
         <TopLine Value="1"/>
         <EditorIndex Value="4"/>
-        <UsageCount Value="10"/>
+        <UsageCount Value="15"/>
         <Loaded Value="True"/>
       </Unit18>
       <Unit19>
@@ -205,129 +209,156 @@
         <UnitName Value="pkglnet"/>
         <CursorPos X="5" Y="140"/>
         <TopLine Value="103"/>
-        <UsageCount Value="10"/>
+        <UsageCount Value="9"/>
       </Unit19>
+      <Unit20>
+        <Filename Value="reptest.pp"/>
+        <UnitName Value="reptest"/>
+        <CursorPos X="1" Y="93"/>
+        <TopLine Value="59"/>
+        <EditorIndex Value="6"/>
+        <UsageCount Value="14"/>
+        <Loaded Value="True"/>
+      </Unit20>
+      <Unit21>
+        <Filename Value="rep2xml.lpr"/>
+        <UnitName Value="rep2xml"/>
+        <CursorPos X="26" Y="240"/>
+        <TopLine Value="221"/>
+        <EditorIndex Value="7"/>
+        <UsageCount Value="12"/>
+        <Loaded Value="True"/>
+      </Unit21>
+      <Unit22>
+        <Filename Value="pkgfpmake.pp"/>
+        <UnitName Value="pkgfpmake"/>
+        <CursorPos X="5" Y="48"/>
+        <TopLine Value="34"/>
+        <EditorIndex Value="10"/>
+        <UsageCount Value="11"/>
+        <Loaded Value="True"/>
+      </Unit22>
     </Units>
     <JumpHistory Count="30" HistoryIndex="29">
       <Position1>
-        <Filename Value="fppkg.pp"/>
-        <Caret Line="218" Column="42" TopLine="206"/>
+        <Filename Value="fprepos.pp"/>
+        <Caret Line="823" Column="5" TopLine="786"/>
       </Position1>
       <Position2>
-        <Filename Value="pkgfpmake.pp"/>
-        <Caret Line="70" Column="18" TopLine="56"/>
+        <Filename Value="fprepos.pp"/>
+        <Caret Line="100" Column="35" TopLine="77"/>
       </Position2>
       <Position3>
-        <Filename Value="pkgfpmake.pp"/>
-        <Caret Line="10" Column="5" TopLine="1"/>
+        <Filename Value="pkgropts.pp"/>
+        <Caret Line="94" Column="18" TopLine="75"/>
       </Position3>
       <Position4>
-        <Filename Value="pkgmkconv.pp"/>
-        <Caret Line="679" Column="46" TopLine="666"/>
+        <Filename Value="pkgropts.pp"/>
+        <Caret Line="225" Column="14" TopLine="206"/>
       </Position4>
       <Position5>
-        <Filename Value="pkgfpmake.pp"/>
-        <Caret Line="67" Column="1" TopLine="39"/>
+        <Filename Value="pkgropts.pp"/>
+        <Caret Line="33" Column="19" TopLine="14"/>
       </Position5>
       <Position6>
-        <Filename Value="pkgfpmake.pp"/>
-        <Caret Line="28" Column="1" TopLine="8"/>
+        <Filename Value="pkgropts.pp"/>
+        <Caret Line="152" Column="31" TopLine="133"/>
       </Position6>
       <Position7>
-        <Filename Value="pkgfpmake.pp"/>
-        <Caret Line="43" Column="26" TopLine="24"/>
+        <Filename Value="pkgropts.pp"/>
+        <Caret Line="174" Column="23" TopLine="155"/>
       </Position7>
       <Position8>
-        <Filename Value="pkgmessages.pp"/>
-        <Caret Line="11" Column="20" TopLine="1"/>
+        <Filename Value="fppkg.pp"/>
+        <Caret Line="94" Column="73" TopLine="75"/>
       </Position8>
       <Position9>
-        <Filename Value="pkgfpmake.pp"/>
-        <Caret Line="51" Column="11" TopLine="32"/>
+        <Filename Value="pkgropts.pp"/>
+        <Caret Line="224" Column="10" TopLine="206"/>
       </Position9>
       <Position10>
-        <Filename Value="pkgfpmake.pp"/>
-        <Caret Line="35" Column="3" TopLine="20"/>
+        <Filename Value="pkgropts.pp"/>
+        <Caret Line="1" Column="1" TopLine="1"/>
       </Position10>
       <Position11>
-        <Filename Value="fppkg.pp"/>
-        <Caret Line="99" Column="19" TopLine="76"/>
+        <Filename Value="pkgropts.pp"/>
+        <Caret Line="33" Column="1" TopLine="14"/>
       </Position11>
       <Position12>
-        <Filename Value="pkgfpmake.pp"/>
-        <Caret Line="56" Column="6" TopLine="37"/>
+        <Filename Value="pkgropts.pp"/>
+        <Caret Line="69" Column="1" TopLine="50"/>
       </Position12>
       <Position13>
-        <Filename Value="fppkg.pp"/>
-        <Caret Line="86" Column="26" TopLine="76"/>
+        <Filename Value="pkgropts.pp"/>
+        <Caret Line="102" Column="1" TopLine="83"/>
       </Position13>
       <Position14>
-        <Filename Value="pkghandler.pp"/>
-        <Caret Line="47" Column="1" TopLine="22"/>
+        <Filename Value="pkgropts.pp"/>
+        <Caret Line="149" Column="1" TopLine="130"/>
       </Position14>
       <Position15>
-        <Filename Value="pkgfpmake.pp"/>
-        <Caret Line="56" Column="23" TopLine="37"/>
+        <Filename Value="pkgropts.pp"/>
+        <Caret Line="170" Column="1" TopLine="151"/>
       </Position15>
       <Position16>
-        <Filename Value="pkgfpmake.pp"/>
-        <Caret Line="58" Column="16" TopLine="39"/>
+        <Filename Value="pkgropts.pp"/>
+        <Caret Line="265" Column="1" TopLine="246"/>
       </Position16>
       <Position17>
-        <Filename Value="pkgfpmake.pp"/>
-        <Caret Line="74" Column="1" TopLine="55"/>
+        <Filename Value="pkgropts.pp"/>
+        <Caret Line="279" Column="1" TopLine="260"/>
       </Position17>
       <Position18>
-        <Filename Value="pkgfpmake.pp"/>
-        <Caret Line="25" Column="1" TopLine="1"/>
+        <Filename Value="pkgropts.pp"/>
+        <Caret Line="49" Column="5" TopLine="37"/>
       </Position18>
       <Position19>
-        <Filename Value="pkgfpmake.pp"/>
-        <Caret Line="105" Column="23" TopLine="75"/>
+        <Filename Value="pkgropts.pp"/>
+        <Caret Line="205" Column="5" TopLine="163"/>
       </Position19>
       <Position20>
-        <Filename Value="pkgfpmake.pp"/>
-        <Caret Line="89" Column="17" TopLine="70"/>
+        <Filename Value="fppkg.pp"/>
+        <Caret Line="94" Column="57" TopLine="75"/>
       </Position20>
       <Position21>
-        <Filename Value="pkgfpmake.pp"/>
-        <Caret Line="100" Column="34" TopLine="71"/>
+        <Filename Value="pkgropts.pp"/>
+        <Caret Line="64" Column="27" TopLine="45"/>
       </Position21>
       <Position22>
-        <Filename Value="pkgfpmake.pp"/>
-        <Caret Line="86" Column="13" TopLine="70"/>
+        <Filename Value="pkgropts.pp"/>
+        <Caret Line="205" Column="28" TopLine="184"/>
       </Position22>
       <Position23>
         <Filename Value="fppkg.pp"/>
-        <Caret Line="29" Column="1" TopLine="20"/>
+        <Caret Line="25" Column="36" TopLine="24"/>
       </Position23>
       <Position24>
-        <Filename Value="pkgfpmake.pp"/>
-        <Caret Line="90" Column="23" TopLine="71"/>
+        <Filename Value="fppkg.pp"/>
+        <Caret Line="84" Column="34" TopLine="59"/>
       </Position24>
       <Position25>
-        <Filename Value="pkgfpmake.pp"/>
-        <Caret Line="88" Column="1" TopLine="72"/>
+        <Filename Value="fppkg.pp"/>
+        <Caret Line="30" Column="35" TopLine="11"/>
       </Position25>
       <Position26>
         <Filename Value="fppkg.pp"/>
-        <Caret Line="42" Column="25" TopLine="17"/>
+        <Caret Line="84" Column="41" TopLine="65"/>
       </Position26>
       <Position27>
-        <Filename Value="pkghandler.pp"/>
-        <Caret Line="51" Column="19" TopLine="42"/>
+        <Filename Value="fppkg.pp"/>
+        <Caret Line="148" Column="36" TopLine="124"/>
       </Position27>
       <Position28>
-        <Filename Value="pkghandler.pp"/>
-        <Caret Line="214" Column="24" TopLine="181"/>
+        <Filename Value="fppkg.pp"/>
+        <Caret Line="134" Column="14" TopLine="117"/>
       </Position28>
       <Position29>
         <Filename Value="fppkg.pp"/>
-        <Caret Line="233" Column="19" TopLine="199"/>
+        <Caret Line="128" Column="1" TopLine="102"/>
       </Position29>
       <Position30>
-        <Filename Value="fppkg.pp"/>
-        <Caret Line="231" Column="39" TopLine="214"/>
+        <Filename Value="pkghandler.pp"/>
+        <Caret Line="119" Column="27" TopLine="95"/>
       </Position30>
     </JumpHistory>
   </ProjectOptions>

+ 70 - 40
utils/fppkg/fppkg.pp

@@ -19,12 +19,15 @@ Type
   TMakeTool = Class(TCustomApplication)
   Private
     FDefaults: TPackagerOptions;
-    FCompiler : String;
-    Function GetCompiler : String;
+    FRepository : TFPRepository;
+    FCompilerConfig : String;
+    procedure LoadRepository;
+    procedure MaybeCreateLocalDirs;
     procedure ShowUsage;
   Public
     Function GetConfigFileName : String;
-    Procedure LoadDefaults;
+    Procedure LoadGlobalDefaults;
+    Procedure LoadCompilerDefaults;
     Procedure ProcessCommandLine;
     Procedure DoRun; Override;
     procedure ExecuteAction(const AAction:string;const Args:TActionArgs);
@@ -35,39 +38,6 @@ Type
 
 { TMakeTool }
 
-function TMakeTool.GetCompiler: String;
-begin
-  If (FCompiler='') then
-    begin
-    {$if defined(cpui386)}
-      FCompiler:='ppc386';
-    {$elseif defined(cpuAlpha)}
-      FCompiler:='ppcaxp';
-    {$elseif defined(cpusparc)}
-      FCompiler:='ppcsparc';
-    {$elseif defined(cpuarm)}
-      FCompiler:='ppcarm';
-    {$elseif defined(cpum68k)}
-      FCompiler:='ppcm68k';
-   {$elseif defined(cpux86_64)}
-      FCompiler:='ppcx64';
-    {$elseif defined(cpupowerpc)}
-      FCompiler:='ppcppc';
-    {$else}
-      {$Fatal Unknown architecture}
-    {$endif}
-    end;
-  If (ExtractFilePath(FCompiler)<>'') then
-    Result:=FCompiler
-  else
-    begin
-    Result:=FileSearch(FCompiler+ExeExt,GetEnvironmentVariable('PATH'));
-    If (Result='') then
-      Result:=FCompiler+ExeExt;
-    end;
-end;
-
-
 function TMakeTool.GetConfigFileName: String;
 var
   G : Boolean;
@@ -86,11 +56,64 @@ begin
 end;
 
 
-procedure TMakeTool.LoadDefaults;
+procedure TMakeTool.LoadGlobalDefaults;
+var
+  SL : TStringList;
+  i : integer;
 begin
-  Verbosity:=[vError,vInfo,vCommands,vDebug];
   FDefaults:=TPackagerOptions.Create;
-  FDefaults.LoadFromFile(GetConfigFileName);
+  FDefaults.LoadGlobalFromFile(GetConfigFileName);
+  // Load default verbosity from config
+  SL:=TStringList.Create;
+  SL.CommaText:=FDefaults.DefaultVerbosity;
+  for i:=0 to SL.Count-1 do
+    Include(Verbosity,StringToVerbosity(SL[i]));
+  SL.Free;
+  FCompilerConfig:=FDefaults.DefaultCompilerConfig;
+end;
+
+
+procedure TMakeTool.MaybeCreateLocalDirs;
+begin
+  ForceDirectories(FDefaults.BuildDir);
+  ForceDirectories(FDefaults.PackagesDir);
+  ForceDirectories(FDefaults.CompilerConfigDir);
+end;
+
+
+procedure TMakeTool.LoadCompilerDefaults;
+var
+  S : String;
+begin
+  S:=FDefaults.CompilerConfigDir+FCompilerConfig;
+  if FileExists(S) then
+    begin
+      Log(vDebug,SLogLoadingCompilerConfig,[S]);
+      FDefaults.LoadCompilerFromFile(S)
+    end
+  else
+    begin
+      Log(vDebug,SLogGeneratingCompilerConfig,[S]);
+      FDefaults.InitCompilerDefaults;
+      FDefaults.SaveCompilerToFile(S);
+    end;
+end;
+
+
+procedure TMakeTool.LoadRepository;
+var
+  S : String;
+begin
+  FRepository:=TFPRepository.Create(Nil);
+  // Repository
+  Log(vDebug,SLogLoadingRepository,[FDefaults.LocalRepository]);
+  if FileExists(FDefaults.LocalRepository) then
+    FRepository.LoadFromFile(FDefaults.LocalRepository);
+  // Versions
+  S:=FDefaults.LocalVersions(FCompilerConfig);
+  Log(vDebug,SLogLoadingRepository,[S]);
+  if FileExists(S) then
+    FRepository.LoadStatusFromFile(S);
 end;
 
 
@@ -108,6 +131,7 @@ begin
   Writeln('  install            Install package');
   Writeln('  download           Download package');
   Writeln('  convertmk          Convert Makefile.fpc to fpmake.pp');
+  Halt(0);
 end;
 
 
@@ -191,6 +215,9 @@ begin
               end;
           end;
       end;
+    { Default "package" is current directory }
+    if (ParaPackages.Count=0) then
+      ParaPackages.Add('.');
     if HasAction then
       begin
         if GetPkgHandler(Action)<>nil then
@@ -242,9 +269,12 @@ var
   Action : string;
   Args   : TActionArgs;
 begin
-  LoadDefaults;
+  LoadGlobalDefaults;
   Try
     ProcessCommandLine;
+    MaybeCreateLocalDirs;
+    LoadCompilerDefaults;
+    LoadRepository;
     
     repeat
       if not ActionStack.Pop(Action,Args) then

+ 11 - 11
utils/fppkg/fprepos.pp

@@ -173,10 +173,10 @@ Type
     Procedure SaveToFile(AFileName : String);
     Procedure Save;
     // Loading and Saving version numbers: List of Name=Value pairs.
-    Procedure LoadVersionsFromStream(Stream : TStream); virtual;
-    Procedure SaveVersionsToStream(Stream : TStream; InstalledVersions : Boolean); virtual;
-    Procedure LoadVersionsFromFile(AFileName : String);
-    Procedure SaveVersionsToFile(AFileName : String; InstalledVersions : Boolean);
+    Procedure LoadStatusFromStream(Stream : TStream); virtual;
+    Procedure SaveStatusToStream(Stream : TStream; InstalledStatus : Boolean); virtual;
+    Procedure LoadStatusFromFile(AFileName : String);
+    Procedure SaveStatusToFile(AFileName : String; InstalledStatus : Boolean);
     // Package management
     Function IndexOfPackage(PackageName : String) : Integer;
     Function FindPackage(PackageName : String) : TFPPackage;
@@ -646,7 +646,7 @@ begin
   SaveToFile(FFileName);
 end;
 
-procedure TFPRepository.LoadVersionsFromStream(Stream: TStream);
+procedure TFPRepository.LoadStatusFromStream(Stream: TStream);
 
 Var
   L : TStrings;
@@ -668,7 +668,7 @@ begin
   end;
 end;
 
-procedure TFPRepository.SaveVersionsToStream(Stream: TStream;InstalledVersions : Boolean);
+procedure TFPRepository.SaveStatusToStream(Stream: TStream;InstalledStatus : Boolean);
 
 Var
   L : TStrings;
@@ -677,7 +677,7 @@ Var
 begin
   L:=TStringList.Create;
   Try
-    If InstalledVersions then
+    If InstalledStatus then
       For I:=0 to PackageCount-1 do
         With Packages[i] do
           L.Add(Name+'='+InstalledVersion.AsString)
@@ -691,7 +691,7 @@ begin
   end;
 end;
 
-procedure TFPRepository.LoadVersionsFromFile(AFileName: String);
+procedure TFPRepository.LoadStatusFromFile(AFileName: String);
 
 Var
   F : TFileStream;
@@ -699,13 +699,13 @@ Var
 begin
   F:=TFileStream.Create(AFileName,fmOpenRead);
   Try
-    LoadVersionsFromStream(F);
+    LoadStatusFromStream(F);
   Finally
     F.Free;
   end;
 end;
 
-procedure TFPRepository.SaveVersionsToFile(AFileName: String; InstalledVersions : Boolean);
+procedure TFPRepository.SaveStatusToFile(AFileName: String; InstalledStatus : Boolean);
 
 Var
   F : TFileStream;
@@ -715,7 +715,7 @@ begin
     BackupFile(AFileName);
   F:=TFileStream.Create(AFileName,fmCreate);
   Try
-    SaveVersionsToStream(F,InstalledVersions);
+    SaveStatusToStream(F,InstalledStatus);
   Finally
     F.Free;
   end;

+ 94 - 0
utils/fppkg/pkgcommands.pp

@@ -0,0 +1,94 @@
+unit pkgcommands;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils,pkghandler;
+
+type
+  { TCommandUpdate }
+
+  TCommandBuild = Class(TPackagehandler)
+  Public
+    Function Execute(const Args:TActionArgs):boolean;override;
+  end;
+  
+  { TCommandDownload }
+
+  TCommandDownload = Class(TPackagehandler)
+  Public
+    Function Execute(const Args:TActionArgs):boolean;override;
+  end;
+
+  { TCommandBuild }
+
+  TCommandBuild = Class(TPackagehandler)
+  Public
+    Function Execute(const Args:TActionArgs):boolean;override;
+  end;
+
+
+  { TCommandInstall }
+
+  TCommandInstall = Class(TPackagehandler)
+  Public
+    Function Execute(const Args:TActionArgs):boolean;override;
+  end;
+
+
+implementation
+
+uses
+  pkgmessages;
+  
+function TCommandUpdate.Execute(const Args:TActionArgs):boolean;
+Var
+  X : TFPXMLRepositoryHandler;
+  P : TFPPackage;
+begin
+  P:=Repository.AddPackage('FirstPackage');
+  P.Author:='Michael Van Canneyt';
+  P.URL:='http://www.freepascal.org/packages/firstpackage.zip';
+  P.Email:='[email protected]';
+  P.Version.AsString:='1.2.3';
+  P.Description:='First package in the repository. Provides basic information.';
+  P.OSes:=[Win32,linux];
+  P.CPUs:=[i386,x86_64];
+  X:=TFPXMLRepositoryHandler.Create;
+  With X do
+    try
+      SaveToXml(Repository,'packages.xml');
+    finally
+      Free;
+    end;
+end;
+
+
+function TCommandDownload.Execute(const Args:TActionArgs):boolean;
+begin
+  ActionStack.Push('downloadpackage',Args);
+end;
+
+
+function TCommandBuild.Execute(const Args:TActionArgs):boolean;
+begin
+  ActionStack.Push('fpmakebuild',Args);
+  ActionStack.Push('compilefpmake',Args);
+end;
+
+
+function TCommandInstall.Execute(const Args:TActionArgs):boolean;
+begin
+  ActionStack.Push('fpmakeinstall',Args);
+  ActionStack.Push('build',Args);
+end;
+
+
+initialization
+  RegisterPkgHandler('update',TCommandUpdate);
+  RegisterPkgHandler('download',TCommandDownload);
+  RegisterPkgHandler('build',TCommandBuild);
+  RegisterPkgHandler('install',TCommandInstall);
+end.

+ 58 - 29
utils/fppkg/pkgfpmake.pp

@@ -12,9 +12,9 @@ type
 
   TFPMakeCompiler = Class(TPackagehandler)
   Private
-    Procedure CompileFPMake;
+    Procedure CompileFPMake(const ADir:string);
   Public
-    Function Execute(const Args:array of string):boolean;override;
+    Function Execute(const Args:TActionArgs):boolean;override;
   end;
 
 
@@ -22,9 +22,17 @@ type
 
   TFPMakeRunner = Class(TPackagehandler)
   Private
-    Function RunFPMake : Integer;
+    Function RunFPMake(const ADir:string) : Integer;
   Public
-    Function Execute(const Args:array of string):boolean;override;
+    Function Execute(const Args:TActionArgs):boolean;override;
+  end;
+
+
+  { TFPMakeRunner }
+
+  TCommandBuild = Class(TPackagehandler)
+  Public
+    Function Execute(const Args:TActionArgs):boolean;override;
   end;
 
 
@@ -35,43 +43,52 @@ uses
   
 { TFPMakeCompiler }
 
-Procedure TFPMakeCompiler.CompileFPMake;
+Procedure TFPMakeCompiler.CompileFPMake(const ADir:string);
 Var
-  O,C : String;
+  D,O,C : String;
+  FPMakeBin,
   FPMakeSrc : string;
   HaveFpmake : boolean;
 begin
+  D:=IncludeTrailingPathDelimiter(ADir);
   { Check for fpmake source }
-  FPMakeSrc:='fpmake.pp';
+  FPMakeBin:=D+'fpmake'+ExeExt;
+  FPMakeSrc:=D+'fpmake.pp';
   HaveFpmake:=FileExists(FPMakeSrc);
   If Not HaveFPMake then
     begin
-      HaveFPMake:=FileExists('fpmake.pas');
+      HaveFPMake:=FileExists(D+'fpmake.pas');
       If HaveFPMake then
-        FPMakeSrc:='fpmake.pas';
+        FPMakeSrc:=D+'fpmake.pas';
     end;
-  if Not HaveFPMake then
-    Error(SErrMissingFPMake);
-  { Call compiler }
-  C:=Defaults.Compiler;
-  O:=FPmakeSrc;
-  Log(vCommands,SLogCompilingFPMake+C+' '+O);
-  If ExecuteProcess(C,O)<>0 then
-    Error(SErrFailedToCompileFPCMake)
+  { Need to compile fpmake executable? }
+  if FileAge(FPMakeBin)<FileAge(FPMakeSrc) then
+    begin
+      if Not HaveFPMake then
+        Error(SErrMissingFPMake);
+      { Call compiler }
+      C:=Defaults.Compiler;
+      O:=FPmakeSrc;
+      Log(vCommands,SLogCompilingFPMake+C+' '+O);
+      If ExecuteProcess(C,O)<>0 then
+        Error(SErrFailedToCompileFPCMake)
+    end
+  else
+    Log(vCommands,SLogNotCompilingFPMake);
 end;
 
 
-function TFPMakeCompiler.Execute(const Args:array of string):boolean;
+function TFPMakeCompiler.Execute(const Args:TActionArgs):boolean;
 begin
 {$warning TODO Check arguments}
-  CompileFPMake;
+  CompileFPMake(Args[0]);
   result:=true;
 end;
 
 
 { TFPMakeRunner }
 
-Function TFPMakeRunner.RunFPMake : Integer;
+Function TFPMakeRunner.RunFPMake(const ADir:string) : Integer;
 
   Function MaybeQuote(Const S : String) : String;
   begin
@@ -86,25 +103,37 @@ Var
   FPMakeBin,
   D,O : String;
 begin
-  FPMakeBin:='fpmake'+ExeExt;
-  D:=IncludeTrailingPathDelimiter(GetCurrentDir);
+  D:=IncludeTrailingPathDelimiter(ADir);
+  FPMakeBin:=D+'fpmake'+ExeExt;
   O:='';
   For I:=1 to ParamCount do
     begin
-    If (O<>'') then
-      O:=O+' ';
-    O:=O+MaybeQuote(ParamStr(I));
+      If (O<>'') then
+        O:=O+' ';
+      O:=O+MaybeQuote(ParamStr(I));
     end;
-  Log(vCommands,SLogRunningFPMake+D+FPMakeBin+' '+O);
-  Result:=ExecuteProcess(D+FPMakeBin,O);
+  Log(vCommands,SLogRunningFPMake+FPMakeBin+' '+O);
+  Result:=ExecuteProcess(FPMakeBin,O);
 end;
 
 
-function TFPMakeRunner.Execute(const Args:array of string):boolean;
+function TFPMakeRunner.Execute(const Args:TActionArgs):boolean;
 begin
 {$warning TODO Check arguments}
-  result:=(RunFPMake=0);
+  result:=(RunFPMake(Args[0])=0);
+end;
+
+
+
+function TCommandBuild.Execute(const Args:TActionArgs):boolean;
+begin
+  ActionStack.Push('fpmakebuild',[]);
+  ActionStack.Push('compilefpmake',[]);
 end;
 
 
+initialization
+  RegisterPkgHandler('compilefpmake',TFPMakeCompiler);
+  RegisterPkgHandler('fpmakebuild',TFPMakeRunner);
+  RegisterPkgHandler('build',TCommandBuild);
 end.

+ 17 - 8
utils/fppkg/pkghandler.pp

@@ -4,7 +4,7 @@ unit pkghandler;
 
 interface
 
-uses Classes,SysUtils, fpmktype, pkgropts;
+uses Classes,SysUtils, fpmktype, pkgropts, fprepos;
 
 Const
 {$ifdef unix}
@@ -45,15 +45,16 @@ Type
   private
     FBackupFile : Boolean;
     FDefaults   : TPackagerOptions;
+    function PackageBuildPath(APackage:TFPPackage):String;
   Protected
     Procedure BackupFile(Const FileName : String);
   Public
     Constructor Create(AOwner: TComponent;ADefaults:TPackagerOptions); virtual;
-    Function Execute(const Args:array of string):boolean; virtual; abstract;
+    Function Execute(const Args:TActionArgs):boolean; virtual; abstract;
     Property BackupFiles : Boolean Read FBackupFile Write FBackupFile;
     Property Defaults:TPackagerOptions Read FDefaults;
   end;
-  TPackageHandlerClass = class(TPackageHandler);
+  TPackageHandlerClass = class of TPackageHandler;
 
   EPackageHandler = Class(EInstallerError);
 
@@ -89,7 +90,7 @@ uses
   pkgmessages;
 
 var
-  PkgHandlerList : TFPHashObjectList;
+  PkgHandlerList : TFPHashList;
 
 procedure RegisterPkgHandler(const AAction:string;pkghandlerclass:TPackageHandlerClass);
 begin
@@ -199,6 +200,12 @@ end;
 
 { TPackageHandler }
 
+constructor TPackageHandler.Create(AOwner : TComponent; ADefaults:TPackagerOptions);
+begin
+  inherited Create(AOwner);
+  FDefaults:=ADefaults;
+end;
+
 procedure TPackageHandler.BackupFile(const FileName: String);
 Var
   BFN : String;
@@ -208,10 +215,12 @@ begin
     Error(SErrBackupFailed,[FileName,BFN]);
 end;
 
-constructor TPackageHandler.Create(AOwner : TComponent; ADefaults:TPackagerOptions);
+function TPackageHandler.PackageBuildPath(APackage:TFPPackage):String;
 begin
-  inherited Create(AOwner);
-  FDefaults:=ADefaults;
+  if APackage=nil then
+    Result:='.'
+  else
+    Result:=Defaults.BuildDir+APackage.Name;
 end;
 
 
@@ -275,7 +284,7 @@ end;
 
 
 initialization
-  PkgHandlerList:=TFPHashObjectList.Create(true);
+  PkgHandlerList:=TFPHashList.Create;
   ActionStack:=TActionStack.Create;
 finalization
   FreeAndNil(PkgHandlerList);

+ 7 - 0
utils/fppkg/pkgmessages.pp

@@ -8,6 +8,7 @@ interface
 Resourcestring
   SErrInValidArgument        = 'Invalid command-line argument at position %d : %s';
   SErrNeedArgument           = 'Option at position %d (%s) needs an argument';
+  SErrMissingFPC             = 'Could not find a fpc executable in the PATH';
   SErrMissingFPMake          = 'Missing configuration fpmake.pp';
   SErrMissingMakefilefpc     = 'Missing configuration Makefile.fpc';
   SErrRunning                = 'The FPC make tool encountered the following error: %s';
@@ -31,8 +32,14 @@ Resourcestring
   
   SLogGeneratingFPMake       = 'Generating fpmake.pp';
   SLogCompilingFPMake        = 'Compiling fpmake.pp: ';
+  SLogNotCompilingFPMake     = 'Skipping compiling of fpmake.pp, fpmake executable already exists';
   SLogRunningFPMake          = 'Running fpmake';
   SLogRunAction              = 'Action: %s %s';
+  SLogLoadingCompilerConfig  = 'Loading compiler configuration from "%s"';
+  SLogGeneratingCompilerConfig  = 'Generating default compiler configuration in "%s"';
+  SLogLoadingRepository      = 'Loading repository data from "%s"';
+  SLogLoadingVersions        = 'Loading versions data from "%s"';
+
 
 implementation
 

+ 2 - 2
utils/fppkg/pkgmkconv.pp

@@ -42,7 +42,7 @@ Type
     procedure ConvertFile(const AFileName: String; Src: TStrings; Dir,OS : String);
     Procedure ConvertFile(Const Source,Dest: String);
   Public
-    Function Execute(const Args:array of string):boolean;override;
+    Function Execute(const Args:TActionArgs):boolean;override;
   end;
 
 
@@ -694,7 +694,7 @@ begin
   end;
 end;
 
-function TMakeFileConverter.Execute(const Args:array of string):boolean;
+function TMakeFileConverter.Execute(const Args:TActionArgs):boolean;
 begin
 {$warning TODO Check arguments}
   ConvertFile(Args[1],Args[2]);

+ 196 - 70
utils/fppkg/pkgropts.pp

@@ -24,42 +24,60 @@ Type
 
   TPackagerOptions = Class(TPersistent)
   private
+    FDirty: Boolean;
+    // Global options
     FRemoteMirrorsLocation : String;
     FLocalMirrorsLocation : String;
     FRemoteRepository : String;
     FLocalRepository : String;
-    FInstallDir : String;
-    FBuildDir : String;
-    FCompiler : String;
-    FCPU: TCPU;
-    FDirty: Boolean;
-    FOS: TOS;
+    FCompilerConfigDir,
+    FPackagesDir,
+    FBuildDir,
     FLocalDir : String;
+    FDefaultVerbosity,
+    FDefaultCompilerConfig : String;
+    // Compiler specific options
+    FCompiler : String;
+    FCompilerCPU: TCPU;
+    FCompilerOS: TOS;
+    FCompilerVersion : String;
+    FInstallDir : String;
     function GetOptString(Index: integer): String;
-    procedure SetCPU(const AValue: TCPU);
     procedure SetOptString(Index: integer; const AValue: String);
-    procedure SetOS(const AValue: TOS);
+    procedure SetCompilerCPU(const AValue: TCPU);
+    procedure SetCompilerOS(const AValue: TOS);
   protected
     Property LocalDir : String Read FLocalDir;
   Public
     Constructor Create;
-    Procedure InitDefaults;
-    Procedure LoadFromIni(Ini : TCustomIniFile); virtual;
-    Procedure SaveToIni(Ini : TCustomIniFile); virtual;
-    Procedure LoadFromFile(FileName : String);
-    Procedure SaveToFile(FileName : String);
+    Procedure InitGlobalDefaults;
+    Procedure LoadGlobalFromIni(Ini : TCustomIniFile); virtual;
+    Procedure SaveGlobalToIni(Ini : TCustomIniFile); virtual;
+    Procedure LoadGlobalFromFile(FileName : String);
+    Procedure SaveGlobalToFile(FileName : String);
+    Procedure InitCompilerDefaults;
+    Procedure LoadCompilerFromIni(Ini : TCustomIniFile); virtual;
+    Procedure SaveCompilerToIni(Ini : TCustomIniFile); virtual;
+    Procedure LoadCompilerFromFile(FileName : String);
+    Procedure SaveCompilerToFile(FileName : String);
     Property Dirty : Boolean Read FDirty;
+    function LocalVersions(CompilerConfig:String):string;
   Published
     Property RemoteMirrorsLocation : String Index 0 Read GetOptString Write SetOptString;
     Property LocalMirrorsLocation : String Index 1 Read GetOptString Write SetOptString;
     Property RemoteRepository : String Index 2 Read GetOptString Write SetOptString;
     Property LocalRepository : String Index 3 Read GetOptString Write SetOptString;
-    Property InstallDir : String Index 4 Read GetOptString Write SetOptString;
     Property BuildDir : String Index 5 Read GetOptString Write SetOptString;
     Property Compiler : String Index 6 Read GetOptString Write SetOptString;
-    Property Target : String Index 7 Read GetOptString Write SetOptString;
-    Property OS : TOS Read FOS Write SetOS;
-    Property CPU : TCPU Read FCPU Write SetCPU;
+    Property CompilerTarget : String Index 7 Read GetOptString Write SetOptString;
+    Property DefaultCompilerConfig : String Index 8 Read GetOptString Write SetOptString;
+    Property CompilerVersion : String Index 9 Read GetOptString Write SetOptString;
+    Property InstallDir : String Index 10 Read GetOptString Write SetOptString;
+    Property DefaultVerbosity : String Index 11 Read GetOptString Write SetOptString;
+    Property PackagesDir : String Index 12 Read GetOptString Write SetOptString;
+    Property CompilerConfigDir : String Index 13 Read GetOptString Write SetOptString;
+    Property CompilerOS : TOS Read FCompilerOS Write SetCompilerOS;
+    Property CompilerCPU : TCPU Read FCompilerCPU Write SetCompilerCPU;
   end;
 
 Const
@@ -72,26 +90,38 @@ Const
   DefaultUnixBuildDir = '/tmp/fppkg/';
   DefaultMirrors = 'mirrors.xml';
   DefaultRepository = 'repository.dat';
+  DefaultVersions   = 'versions.dat';
 
   // ini file keys
   SDefaults = 'Defaults';
 
+  // Global config
   KeyLocalMirrorsLocation  = 'LocalMirrors';
   KeyRemoteMirrorsLocation = 'RemoteMirrors';
   KeyRemoteRepository      = 'RemoteRepository';
   KeyLocalRepository       = 'LocalRepository';
-  KeyInstallDir            = 'InstallDir';
+  KeyDefaultConfig         = 'DefaultCompilerConfig';
+  KeyCompilerConfigDir     = 'CompilerConfigDir';
+  KeyPackagesDir           = 'PackagesDir';
   KeyBuildDir              = 'BuildDir';
+  KeyVerbosity             = 'Verbosity';
+  // Compiler dependent config
+  KeyInstallDir            = 'InstallDir';
   KeyCompiler              = 'Compiler' ;
-  KeyOS                    = 'OS';
-  KeyCPU                   = 'CPU';
+  KeyCompilerOS            = 'OS';
+  KeyCompilerCPU           = 'CPU';
+  KeyCompilerVersion       = 'Version';
 
 
 Implementation
 
+uses
 {$ifdef unix}
-uses baseunix;
+  baseunix
 {$endif}
+  pkghandler,
+  pkgmessages;
+  
 Function FixPath(S : String) : string;
 
 begin
@@ -104,6 +134,12 @@ end;
 
 { TPackagerOptions }
 
+constructor TPackagerOptions.Create;
+begin
+  InitGlobalDefaults;
+end;
+
+
 function TPackagerOptions.GetOptString(Index: integer): String;
 begin
   Case Index of
@@ -111,20 +147,18 @@ begin
     1 : Result:=FLocalMirrorsLocation;
     2 : Result:=FRemoteRepository;
     3 : Result:=FLocalRepository;
-    4 : Result:=FInstallDir;
     5 : Result:=FBuildDir;
     6 : Result:=FCompiler;
-    7 : Result:=MakeTargetString(CPU,OS);
+    7 : Result:=MakeTargetString(CompilerCPU,CompilerOS);
+    8 : Result:=FDefaultCompilerConfig;
+    9 : Result:=FCompilerVersion;
+   10 : Result:=FInstallDir;
+   11 : Result:=FDefaultVerbosity;
+   12 : Result:=FPackagesDir;
+   13 : Result:=FCompilerConfigDir;
   end;
 end;
 
-procedure TPackagerOptions.SetCPU(const AValue: TCPU);
-begin
-  if FCPU=AValue then exit;
-  FCPU:=AValue;
-  FDirty:=True;
-end;
-
 procedure TPackagerOptions.SetOptString(Index: integer; const AValue: String);
 begin
   If AValue=GetOptString(Index) then
@@ -134,32 +168,46 @@ begin
     1 : FRemoteMirrorsLocation:=AValue;
     2 : FRemoteRepository:=AValue;
     3 : FLocalRepository:=AValue;
-    4 : FInstallDir:=FixPath(AValue);
     5 : FBuildDir:=FixPath(AValue);
     6 : FCompiler:=AValue;
-    7 : StringToCPUOS(AValue,FCPU,FOS);
+    7 : StringToCPUOS(AValue,FCompilerCPU,FCompilerOS);
+    8 : FDefaultCompilerConfig:=AValue;
+    9 : FCompilerVersion:=AValue;
+   10 : FInstallDir:=FixPath(AValue);
+   11 : FDefaultVerbosity:=AValue;
+   12 : FPackagesDir:=FixPath(AValue);
+   13 : FCompilerConfigDir:=FixPath(AValue);
   end;
   FDirty:=True;
 end;
 
-procedure TPackagerOptions.SetOS(const AValue: TOS);
+
+procedure TPackagerOptions.SetCompilerCPU(const AValue: TCPU);
 begin
-  if FOS=AValue then exit;
-  FOS:=AValue;
+  if FCompilerCPU=AValue then
+    exit;
+  FCompilerCPU:=AValue;
   FDirty:=True;
 end;
 
-constructor TPackagerOptions.Create;
+
+procedure TPackagerOptions.SetCompilerOS(const AValue: TOS);
 begin
-  InitDefaults;
+  if FCompilerOS=AValue then
+    exit;
+  FCompilerOS:=AValue;
+  FDirty:=True;
 end;
 
-Procedure TPackagerOptions.InitDefaults;
 
+function TPackagerOptions.LocalVersions(CompilerConfig:String):string;
+begin
+  Result:=ExtractFilePath(FLocalRepository)+'versions-'+CompilerConfig+'.dat';
+end;
+
+
+Procedure TPackagerOptions.InitGlobalDefaults;
 begin
-  FCPU:=StringToCPU(DefaultCPU);
-  FOS:=StringToOS(DefaultOS);
-  FCompiler:=DefaultCompiler;
   FRemoteMirrorsLocation:=DefaultMirrorsLocation;
   FRemoteRepository:=DefaultRemoteRepository;
 {$ifdef unix}
@@ -167,75 +215,153 @@ begin
     FLocalDir:=DefaultUnixPrefix
   else
     FLocalDir:=IncludeTrailingPathDelimiter(GetEnvironmentVariable('HOME'))+'.fppkg/';
-  FBuildDir:=DefaultUnixBuildDir;
 {$else}
   // Change as needed on all OS-es...
-  FLocalDir:=ExtractFilePath(Paramstr(0));
-  FBuildDir:=FLocalDir+'build'+PathDelim;
+  FLocalDir:=ExtractFilePath(Paramstr(0))+'fppkg'+PathDelim;
 {$endif}
+  FBuildDir:=FLocalDir+'build'+PathDelim;
+  FPackagesDir:=FLocalDir+'packages'+PathDelim;
+  FCompilerConfigDir:=FLocalDir+'config'+PathDelim;
   FLocalMirrorsLocation:=FLocalDir+DefaultMirrors;
   FLocalRepository:=FLocalDir+DefaultRepository;
+  FDefaultCompilerConfig:='default';
+  FDefaultVerbosity:='error,info,debug,commands';
 end;
 
-procedure TPackagerOptions.LoadFromIni(Ini: TCustomIniFile);
 
+Procedure TPackagerOptions.InitCompilerDefaults;
+begin
+  FCompiler:=FileSearch(DefaultCompiler+ExeExt,GetEnvironmentVariable('PATH'));
+  if FCompiler='' then
+    Error(SErrMissingFPC);
+{$warning TODO detect compiler version/target from -i options }
+  FCompilerVersion:='2.0.4';
+  FCompilerCPU:=StringToCPU(DefaultCPU);
+  FCompilerOS:=StringToOS(DefaultOS);
+  // Use the same algorithm as the compiler, see options.pas
+{$ifdef Unix}
+  FInstallDir:=FixPath(GetEnvironmentVariable('FPCDIR'));
+  if FInstallDir='' then
+    begin
+      if DirectoryExists('/usr/local/lib/fpc/'+FCompilerVersion) then
+        FInstallDir:='/usr/local/lib/fpc/'+FCompilerVersion+'/'
+      else
+        FInstallDir:='/usr/lib/fpc/'+FCompilerVersion+'/';
+    end;
+{$else unix}
+  FInstallDir:=FixPath(GetEnvironmentVariable('FPCDIR'));
+  if FInstallDir='' then
+    begin
+      FInstallDir:=ExtractFilePath(FCompiler)+'../';
+      if not(DirectoryExists(FInstallDir+'/units')) and
+         not(DirectoryExists(FInstallDir+'/rtl')) then
+        FInstallDir:=FInstallDir+'../';
+    end;
+{$endif unix}
+end;
 
 
+procedure TPackagerOptions.LoadGlobalFromIni(Ini: TCustomIniFile);
 begin
  With Ini do
    begin
-   FLocalMirrorsLocation:=ReadString(SDefaults,KeyLocalMirrorsLocation,FLocalMirrorsLocation);
-   FRemoteMirrorsLocation:=ReadString(SDefaults,KeyRemoteMirrorsLocation,FRemoteMirrorsLocation);
-   FRemoteRepository:=ReadString(SDefaults,KeyRemoteRepository,FRemoteRepository);
-   FLocalRepository:=ReadString(SDefaults,KeyLocalRepository,FLocalRepository);
-   FInstallDir:=FixPath(ReadString(SDefaults,KeyInstallDir,FInstallDir));
-   FBuildDir:=FixPath(ReadString(SDefaults,KeyBuildDir,FBuildDir));
-   FCompiler:=ReadString(SDefaults,KeyCompiler,FCompiler);
-   FOS:=StringToOS(ReadString(SDefaults,KeyOS,OSToString(OS)));
-   FCPU:=StringToCPU(ReadString(SDefaults,KeyCPU,CPUtoString(CPU)));
+     FLocalMirrorsLocation:=ReadString(SDefaults,KeyLocalMirrorsLocation,FLocalMirrorsLocation);
+     FRemoteMirrorsLocation:=ReadString(SDefaults,KeyRemoteMirrorsLocation,FRemoteMirrorsLocation);
+     FRemoteRepository:=ReadString(SDefaults,KeyRemoteRepository,FRemoteRepository);
+     FLocalRepository:=ReadString(SDefaults,KeyLocalRepository,FLocalRepository);
+     FBuildDir:=FixPath(ReadString(SDefaults,KeyBuildDir,FBuildDir));
+     FDefaultCompilerConfig:=ReadString(SDefaults,KeyDefaultConfig,FDefaultCompilerConfig);
    end;
-
 end;
 
-procedure TPackagerOptions.SaveToIni(Ini: TCustomIniFile);
+
+procedure TPackagerOptions.SaveGlobalToIni(Ini: TCustomIniFile);
 begin
  With Ini do
    begin
-   WriteString(SDefaults,KeyLocalMirrorsLocation,FLocalMirrorsLocation);
-   WriteString(SDefaults,KeyRemoteMirrorsLocation,FRemoteMirrorsLocation);
-   WriteString(SDefaults,KeyRemoteRepository,FRemoteRepository);
-   WriteString(SDefaults,KeyLocalRepository,FLocalRepository);
-   WriteString(SDefaults,KeyInstallDir,FInstallDir);
-   WriteString(SDefaults,KeyBuildDir,FBuildDir);
-   WriteString(SDefaults,KeyCompiler,FCompiler);
-   WriteString(SDefaults,KeyOS,OSToString(OS));
-   WriteString(SDefaults,KeyCPU,CPUtoString(CPU));
+     WriteString(SDefaults,KeyLocalMirrorsLocation,FLocalMirrorsLocation);
+     WriteString(SDefaults,KeyRemoteMirrorsLocation,FRemoteMirrorsLocation);
+     WriteString(SDefaults,KeyRemoteRepository,FRemoteRepository);
+     WriteString(SDefaults,KeyLocalRepository,FLocalRepository);
+     WriteString(SDefaults,KeyBuildDir,FBuildDir);
+     WriteString(SDefaults,KeyDefaultConfig,FDefaultCompilerConfig);
    end;
 end;
 
-procedure TPackagerOptions.LoadFromFile(FileName: String);
 
+procedure TPackagerOptions.LoadGlobalFromFile(FileName: String);
 Var
   Ini : TMemIniFile;
-
 begin
   Ini:=TMemIniFile.Create(FileName);
   try
-    LoadFromIni(Ini);
+    LoadGlobalFromIni(Ini);
   finally
     Ini.Free;
   end;
 end;
 
-procedure TPackagerOptions.SaveToFile(FileName: String);
 
+procedure TPackagerOptions.SaveGlobalToFile(FileName: String);
 Var
   Ini : TIniFile;
+begin
+  Ini:=TIniFile.Create(FileName);
+  try
+    SaveGlobalToIni(Ini);
+    Ini.UpdateFile;
+  finally
+    Ini.Free;
+  end;
+end;
+
+
+procedure TPackagerOptions.LoadCompilerFromIni(Ini: TCustomIniFile);
+begin
+ With Ini do
+   begin
+     FInstallDir:=FixPath(ReadString(SDefaults,KeyInstallDir,FInstallDir));
+     FCompiler:=ReadString(SDefaults,KeyCompiler,FCompiler);
+     FCompilerOS:=StringToOS(ReadString(SDefaults,KeyCompilerOS,OSToString(CompilerOS)));
+     FCompilerCPU:=StringToCPU(ReadString(SDefaults,KeyCompilerCPU,CPUtoString(CompilerCPU)));
+     FCompilerVersion:=ReadString(SDefaults,KeyCompilerVersion,FCompilerVersion);
+   end;
+end;
+
+
+procedure TPackagerOptions.SaveCompilerToIni(Ini: TCustomIniFile);
+begin
+ With Ini do
+   begin
+     WriteString(SDefaults,KeyInstallDir,FInstallDir);
+     WriteString(SDefaults,KeyCompiler,FCompiler);
+     WriteString(SDefaults,KeyCompilerOS,OSToString(CompilerOS));
+     WriteString(SDefaults,KeyCompilerCPU,CPUtoString(CompilerCPU));
+     WriteString(SDefaults,KeyCompilerVersion,FCompilerVersion);
+   end;
+end;
 
+
+procedure TPackagerOptions.LoadCompilerFromFile(FileName: String);
+Var
+  Ini : TMemIniFile;
+begin
+  Ini:=TMemIniFile.Create(FileName);
+  try
+    LoadCompilerFromIni(Ini);
+  finally
+    Ini.Free;
+  end;
+end;
+
+
+procedure TPackagerOptions.SaveCompilerToFile(FileName: String);
+Var
+  Ini : TIniFile;
 begin
   Ini:=TIniFile.Create(FileName);
   try
-    SaveToIni(Ini);
+    SaveCompilerToIni(Ini);
     Ini.UpdateFile;
   finally
     Ini.Free;