Browse Source

--- Merging r15293 into '.':
U packages/fpmkunit/src/fpmkunit.pp
--- Merging r15542 into '.':
G packages/fpmkunit/src/fpmkunit.pp
--- Merging r15873 into '.':
U utils/fppkg/pkgfpmake.pp
U utils/fppkg/fppkg.pp
U utils/fppkg/pkgoptions.pp
--- Merging r15914 into '.':
G utils/fppkg/fppkg.pp
G utils/fppkg/pkgoptions.pp
--- Merging r15917 into '.':
U utils/fppkg/pkghandler.pp
--- Merging r15919 into '.':
G utils/fppkg/pkgfpmake.pp
U utils/fppkg/pkgmessages.pp
G utils/fppkg/pkgoptions.pp
G packages/fpmkunit/src/fpmkunit.pp
--- Merging r15925 into '.':
G packages/fpmkunit/src/fpmkunit.pp
--- Merging r15937 into '.':
G packages/fpmkunit/src/fpmkunit.pp
--- Merging r16006 into '.':
U utils/fppkg/fppkg.lpi
--- Merging r16007 into '.':
G utils/fppkg/fppkg.pp
U utils/fppkg/pkgglobals.pp
G utils/fppkg/pkgoptions.pp
--- Merging r16015 into '.':
G utils/fppkg/fppkg.pp
--- Merging r16016 into '.':
G utils/fppkg/fppkg.pp
--- Merging r16033 into '.':
G utils/fppkg/fppkg.pp
--- Merging r16038 into '.':
G utils/fppkg/pkgfpmake.pp
U utils/fppkg/fpmkunitsrc.inc
--- Merging r16045 into '.':
G utils/fppkg/fppkg.pp
--- Merging r16346 into '.':
G packages/fpmkunit/src/fpmkunit.pp
--- Merging r16348 into '.':
G packages/fpmkunit/src/fpmkunit.pp
--- Merging r16349 into '.':
G utils/fppkg/pkgfpmake.pp
G utils/fppkg/pkgoptions.pp

# revisions: 15293,15542,15873,15914,15917,15919,15925,15937,16006,16007,16015,16016,16033,16038,16045,16245,16346,16348,16349
------------------------------------------------------------------------
r15293 | joost | 2010-05-18 22:07:32 +0200 (Tue, 18 May 2010) | 1 line
Changed paths:
M /trunk/packages/fpmkunit/src/fpmkunit.pp

* Added -o/--options parameters to pass extra parameters to the compiler
------------------------------------------------------------------------
------------------------------------------------------------------------
r15542 | joost | 2010-07-10 13:19:56 +0200 (Sat, 10 Jul 2010) | 6 lines
Changed paths:
M /trunk/packages/fpmkunit/src/fpmkunit.pp

* Install the doc and example sourcefiles
* Added ability to specify in which subdir a doc/example sourcefile should be
installed
* Replace the at that place unset Prefix fpr baseinstalldir in two locations
* Removed useless if-then construct

------------------------------------------------------------------------
------------------------------------------------------------------------
r15873 | joost | 2010-08-22 14:07:12 +0200 (Sun, 22 Aug 2010) | 1 line
Changed paths:
M /trunk/utils/fppkg/fppkg.pp
M /trunk/utils/fppkg/pkgfpmake.pp
M /trunk/utils/fppkg/pkgoptions.pp

* Added option to pass options to the compiler
------------------------------------------------------------------------
------------------------------------------------------------------------
r15914 | joost | 2010-08-28 13:14:01 +0200 (Sat, 28 Aug 2010) | 1 line
Changed paths:
M /trunk/utils/fppkg/fppkg.pp
M /trunk/utils/fppkg/pkgoptions.pp

* Only save new config-files when the version is updated or the file is newly created
------------------------------------------------------------------------
------------------------------------------------------------------------
r15917 | joost | 2010-08-29 15:08:07 +0200 (Sun, 29 Aug 2010) | 1 line
Changed paths:
M /trunk/utils/fppkg/pkghandler.pp

* Flush text output before calling external programs
------------------------------------------------------------------------
------------------------------------------------------------------------
r15919 | joost | 2010-08-29 21:50:19 +0200 (Sun, 29 Aug 2010) | 4 lines
Changed paths:
M /trunk/packages/fpmkunit/src/fpmkunit.pp
M /trunk/utils/fppkg/pkgfpmake.pp
M /trunk/utils/fppkg/pkgmessages.pp
M /trunk/utils/fppkg/pkgoptions.pp

* Added GlobalPrefix and LocalPrefix settings to compilersettings of fppkg
* By default only use the prefix instead of the InstallDir settings


------------------------------------------------------------------------
------------------------------------------------------------------------
r15925 | joost | 2010-08-31 21:34:06 +0200 (Tue, 31 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fpmkunit/src/fpmkunit.pp

* Use prefix again as base-path for examples and binaries (changed in r15919)
------------------------------------------------------------------------
------------------------------------------------------------------------
r15937 | joost | 2010-09-01 22:41:30 +0200 (Wed, 01 Sep 2010) | 1 line
Changed paths:
M /trunk/packages/fpmkunit/src/fpmkunit.pp

* Added the ability to use sub-dirs for examples and documents
------------------------------------------------------------------------
------------------------------------------------------------------------
r16006 | joost | 2010-09-19 12:39:49 +0200 (Sun, 19 Sep 2010) | 1 line
Changed paths:
M /trunk/utils/fppkg/fppkg.lpi

* Session-info removed from Lazarus project-file
------------------------------------------------------------------------
------------------------------------------------------------------------
r16007 | joost | 2010-09-19 13:05:45 +0200 (Sun, 19 Sep 2010) | 5 lines
Changed paths:
M /trunk/utils/fppkg/fppkg.pp
M /trunk/utils/fppkg/pkgglobals.pp
M /trunk/utils/fppkg/pkgoptions.pp

* Parse command-line options twice, so they can override values from the configuration files
* Added --prefix command-line option
* Added -n command-line option to skip reading of configuration files
* Added --compiler option to set compiler-executable
* When the compiler version, target os or cpu is not given in the configuration files, obtain them from the compiler-executable
------------------------------------------------------------------------
------------------------------------------------------------------------
r16015 | joost | 2010-09-19 20:23:12 +0200 (Sun, 19 Sep 2010) | 1 line
Changed paths:
M /trunk/utils/fppkg/fppkg.pp

* Do not use -c command line parameter for the compiler executable, it is already used for the compiler config file
------------------------------------------------------------------------
------------------------------------------------------------------------
r16016 | joost | 2010-09-19 22:06:37 +0200 (Sun, 19 Sep 2010) | 1 line
Changed paths:
M /trunk/utils/fppkg/fppkg.pp

* Fixed exception while parsing the -o option for the second time
------------------------------------------------------------------------
------------------------------------------------------------------------
r16033 | joost | 2010-09-20 23:33:36 +0200 (Mon, 20 Sep 2010) | 1 line
Changed paths:
M /trunk/utils/fppkg/fppkg.pp

* Hopefully finally fixed the --options option after r16007,r16016
------------------------------------------------------------------------
------------------------------------------------------------------------
r16038 | joost | 2010-09-23 21:14:43 +0200 (Thu, 23 Sep 2010) | 1 line
Changed paths:
M /trunk/utils/fppkg/fpmkunitsrc.inc
M /trunk/utils/fppkg/pkgfpmake.pp

* Regenerated and added comment how to re-generate
------------------------------------------------------------------------
------------------------------------------------------------------------
r16045 | joost | 2010-09-25 22:03:05 +0200 (Sat, 25 Sep 2010) | 1 line
Changed paths:
M /trunk/utils/fppkg/fppkg.pp

* Added --cpu and --os command-line options
------------------------------------------------------------------------
------------------------------------------------------------------------
------------------------------------------------------------------------
r16346 | joost | 2010-11-14 16:16:34 +0100 (Sun, 14 Nov 2010) | 1 line
Changed paths:
M /trunk/packages/fpmkunit/src/fpmkunit.pp

* Added ability to add custom command-line options for fpmake
------------------------------------------------------------------------
------------------------------------------------------------------------
r16348 | joost | 2010-11-14 20:25:13 +0100 (Sun, 14 Nov 2010) | 2 lines
Changed paths:
M /trunk/packages/fpmkunit/src/fpmkunit.pp

* Added option to ignore further invalid options
* Fixed AV when showing command-line options when no custom options are present
------------------------------------------------------------------------
------------------------------------------------------------------------
r16349 | joost | 2010-11-14 20:29:26 +0100 (Sun, 14 Nov 2010) | 1 line
Changed paths:
M /trunk/utils/fppkg/pkgfpmake.pp
M /trunk/utils/fppkg/pkgoptions.pp

* Added FPMakeOptions to the global configuration file, to pass custom options to fpmake
------------------------------------------------------------------------

git-svn-id: branches/fixes_2_4@16398 -

marco 14 years ago
parent
commit
a1ae51e0fa

+ 194 - 17
packages/fpmkunit/src/fpmkunit.pp

@@ -471,10 +471,14 @@ Type
   TSource = Class(TNamedItem)
   private
     FSourceType : TSourceType;
+    FInstallSourcePath : string;
+    function GetInstallSourcePath: string;
   Public
     Constructor Create(ACollection : TCollection); override;
     Destructor Destroy; override;
+    Procedure GetInstallFiles(List : TStrings); virtual;
     property SourceType : TSourceType read FSourceType;
+    property InstallSourcePath : string read GetInstallSourcePath;
   end;
 
   { TSources }
@@ -485,12 +489,14 @@ Type
     procedure SetSourceItem(Index : Integer; const AValue: TSource);
   public
     Function AddDoc(const AFiles : String) : TSource;
+    Function AddDoc(const AFiles : String; AInstallSourcePath : String) : TSource;
     Function AddSrc(const AFiles : String) : TSource;
     Function AddExample(const AFiles : String) : TSource;
+    Function AddExample(const AFiles : String; AInstallSourcePath : String) : TSource;
     Function AddTest(const AFiles : String) : TSource;
-    procedure AddDocFiles(const AFileMask: string; Recursive: boolean = False);
+    procedure AddDocFiles(const AFileMask: string; Recursive: boolean = False; AInstallSourcePath : String = '');
     procedure AddSrcFiles(const AFileMask: string; Recursive: boolean = False);
-    procedure AddExampleFiles(const AFileMask: string; Recursive: boolean = False);
+    procedure AddExampleFiles(const AFileMask: string; Recursive: boolean = False; AInstallSourcePath : String = '');
     procedure AddTestFiles(const AFileMask: string; Recursive: boolean = False);
     Property SourceItems[Index : Integer] : TSource Read GetSourceItem Write SetSourceItem;default;
   end;
@@ -557,6 +563,7 @@ Type
     Function  GetBinOutputDir(ACPU:TCPU; AOS : TOS) : String;
     Procedure GetCleanFiles(List : TStrings; ACPU:TCPU; AOS : TOS); virtual;
     procedure GetInstallFiles(List: TStrings;Types : TTargetTypes;ACPU:TCPU; AOS : TOS);
+    procedure GetInstallSourceFiles(List: TStrings;Types : TSourceTypes);
     Procedure GetArchiveFiles(List : TStrings; ACPU:TCPU; AOS : TOS); virtual;
     Procedure GetManifest(Manifest : TStrings);
     Property Version : String Read GetVersion Write SetVersion;
@@ -623,6 +630,7 @@ Type
     FArchive: String;
     FCompiler: String;
     FCopy: String;
+    FIgnoreInvalidOptions: Boolean;
     FMkDir: String;
     FMove: String;
     FOptions: TStrings;
@@ -696,6 +704,8 @@ Type
     Property Remove : String Read FRemove Write FRemove;       // Delete $(FILES)
     Property MkDir : String Read FMkDir write FMkDir;          // Make $(DIRECTORY)
     Property Archive : String Read FArchive Write FArchive;    // zip $(ARCHIVE) $(FILESORDIRS)
+    // Misc
+    Property IgnoreInvalidOptions: Boolean read FIgnoreInvalidOptions write FIgnoreInvalidOptions;
   end;
 
   { TBasicDefaults }
@@ -754,6 +764,7 @@ Type
     Procedure EnterDir(ADir : String);
     Function GetCompiler : String;
     Function InstallPackageFiles(APAckage : TPackage; tt : TTargetType; Const Dest : String):Boolean;
+    Function InstallPackageSourceFiles(APAckage : TPackage; tt : TSourceType; Const Dest : String):Boolean;
     Function FileNewer(const Src,Dest : String) : Boolean;
     Procedure LogSearchPath(const ASearchPathName:string;Path:TConditionalStrings; ACPU:TCPU;AOS:TOS);
     Function FindFileInPath(Path:TConditionalStrings; AFileName:String; var FoundPath:String;ACPU:TCPU;AOS:TOS):Boolean;
@@ -948,6 +959,8 @@ Function FixPath (const APath : String) : String;
 Procedure ChangeDir(const APath : String);
 Function Substitute(Const Source : String; Macros : Array of string) : String;
 Procedure SplitCommand(Const Cmd : String; Var Exe,Options : String);
+Procedure AddCustomFpmakeCommandlineOption(const ACommandLineOption, HelpMessage : string);
+Function GetCustomFpmakeCommandlineOptionValue(const ACommandLineOption : string) : string;
 
 Implementation
 
@@ -959,6 +972,10 @@ type
     function Add(const S: string): Integer; override;
   end;
 
+var
+  CustomFpmakeCommandlineOptions: TStrings;
+  CustomFpMakeCommandlineValues: TStrings;
+
 ResourceString
   SErrInvalidCPU        = 'Invalid CPU name "%s"';
   SErrInvalidOS         = 'Invalid OS name "%s"';
@@ -1065,7 +1082,9 @@ ResourceString
   SHelpGlobalUnitDir  = 'Use indicated directory as global unit dir.';
   SHelpCompiler       = 'Use indicated binary as compiler';
   SHelpConfig         = 'Use indicated config file when compiling.';
+  SHelpOptions        = 'Pass extra options to the compiler.';
   SHelpVerbose        = 'Be verbose when working.';
+  SHelpIgnoreInvOpt   = 'Ignore further invalid options.';
 
 
 Const
@@ -1496,6 +1515,21 @@ begin
   Options:=Trim(S);
 end;
 
+procedure AddCustomFpmakeCommandlineOption(const ACommandLineOption, HelpMessage : string);
+begin
+  if not assigned(CustomFpmakeCommandlineOptions) then
+    CustomFpmakeCommandlineOptions := TStringList.Create;
+  CustomFpmakeCommandlineOptions.Values[ACommandLineOption]:=HelpMessage;
+end;
+
+function GetCustomFpmakeCommandlineOptionValue(const ACommandLineOption: string): string;
+begin
+  if not assigned(CustomFpMakeCommandlineValues) then
+    result := ''
+  else
+    result := CustomFpMakeCommandlineValues.Values[ACommandLineOption];
+end;
+
 Function OptionListToString(L : TStrings) : String;
 
 var
@@ -1847,6 +1881,15 @@ begin
 end;
 
 
+function TSources.AddDoc(const AFiles: String; AInstallSourcePath: String): TSource;
+begin
+  Result:=Add as TSource;
+  Result.Name:=AFiles;
+  Result.FInstallSourcePath:=AInstallSourcePath;
+  Result.FSourceType:=stDoc;
+end;
+
+
 function TSources.AddSrc(const AFiles : String) : TSource;
 begin
   Result:=Add as TSource;
@@ -1862,6 +1905,14 @@ begin
   Result.FSourceType:=stExample;
 end;
 
+function TSources.AddExample(const AFiles: String; AInstallSourcePath: String): TSource;
+begin
+  Result:=Add as TSource;
+  Result.Name:=AFiles;
+  Result.FInstallSourcePath:=AInstallSourcePath;
+  Result.FSourceType:=stExample;
+end;
+
 
 function TSources.AddTest(const AFiles : String) : TSource;
 begin
@@ -1871,7 +1922,7 @@ begin
 end;
 
 
-procedure TSources.AddDocFiles(const AFileMask: string; Recursive: boolean);
+procedure TSources.AddDocFiles(const AFileMask: string; Recursive: boolean; AInstallSourcePath : String = '');
 var
   List : TStrings;
   i: integer;
@@ -1879,7 +1930,7 @@ begin
   List := TStringList.Create;
   SearchFiles(AFileMask, Recursive, List);
   for i:= 0 to Pred(List.Count) do
-    AddDoc(List[i]);
+    AddDoc(List[i], AInstallSourcePath);
   List.Free;
 end;
 
@@ -1897,7 +1948,7 @@ begin
 end;
 
 
-procedure TSources.AddExampleFiles(const AFileMask: string; Recursive: boolean);
+procedure TSources.AddExampleFiles(const AFileMask: string; Recursive: boolean; AInstallSourcePath : String = '');
 var
   List : TStrings;
   i: integer;
@@ -1905,7 +1956,7 @@ begin
   List := TStringList.Create;
   SearchFiles(AFileMask, Recursive, List);
   for i:= 0 to Pred(List.Count) do
-    AddExample(List[i]);
+    AddExample(List[i], AInstallSourcePath);
   List.Free;
 end;
 
@@ -2027,6 +2078,20 @@ begin
 end;
 
 
+procedure TPackage.GetInstallSourceFiles(List: TStrings; Types: TSourceTypes);
+Var
+  I : Integer;
+  S : TSource;
+begin
+  For I:=0 to FSources.Count-1 do
+    begin
+      S:=FSources.SourceItems[I];
+      if (S.SourceType in Types) then
+        S.GetInstallFiles(List);
+    end;
+end;
+
+
 procedure TPackage.GetArchiveFiles(List: TStrings; ACPU:TCPU; AOS : TOS);
 Var
   I : Integer;
@@ -2322,7 +2387,7 @@ begin
     Result:=FBaseInstallDir
   else
     if UnixPaths then
-      Result:=Prefix +'lib' + PathDelim + 'fpc' + PathDelim
+      Result:=Prefix +'lib' + PathDelim + 'fpc' + PathDelim + FCompilerVersion + PathDelim
     else
       Result:=Prefix;
 end;
@@ -2334,7 +2399,7 @@ begin
     Result:=FBinInstallDir
   else
     If UnixPaths then
-      Result:=BaseInstallDir+'bin'
+      Result:=Prefix+'bin'
     else
       Result:=BaseInstallDir+'bin';
 end;
@@ -2351,8 +2416,8 @@ end;
 
 function TCustomDefaults.GetDocInstallDir: String;
 begin
-  If (FBinInstallDir<>'') then
-    Result:=FBinInstallDir
+  If (FDocInstallDir<>'') then
+    Result:=FDocInstallDir
   else
     If UnixPaths then
       Result:=Prefix+'share'+PathDelim+'doc'
@@ -2367,7 +2432,7 @@ begin
     Result:=FExamplesInstallDir
   else
     If UnixPaths then
-      Result:=Prefix+'share'+PathDelim+'docs'+PathDelim+'examples'
+      Result:=Prefix+'share'+PathDelim+'doc'
     else
       Result:=BaseInstallDir+'examples';
 end;
@@ -2385,10 +2450,7 @@ begin
   If (FUnitInstallDir<>'') then
     Result:=FUnitInstallDir
   else
-    If UnixPaths then
-      Result:=BaseInstallDir+'units'+PathDelim+Target
-    else
-      Result:=BaseInstallDir+'units'+PathDelim+Target;
+    Result:=BaseInstallDir+'units'+PathDelim+Target;
 end;
 
 
@@ -2805,6 +2867,25 @@ procedure TCustomInstaller.AnalyzeOptions;
     Result:=(O='-'+short) or (O='--'+long) or (copy(O,1,Length(Long)+3)=('--'+long+'='));
   end;
 
+  Function CheckCustomOption(Index : Integer; out CustOptName: string): Boolean;
+  var
+    O : String;
+    i : integer;
+  begin
+    result := false;
+    CustOptName:='';
+    O:=Paramstr(Index);
+    if copy(O,1,2)<>'--' then
+      Exit;
+    i := pos('=',O);
+    if i=0 then
+      Exit;
+    O:=copy(O,3,i-3);
+    CustOptName:=O;
+    Result:=CustomFpmakeCommandlineOptions.IndexOfName(O)>-1;
+  end;
+
+
   Function CheckCommand(Index : Integer;const Short,Long : String): Boolean;
   var
     O : String;
@@ -2840,9 +2921,27 @@ procedure TCustomInstaller.AnalyzeOptions;
       end;
   end;
 
+  function SplitSpaces(var SplitString: string) : string;
+  var i : integer;
+  begin
+    i := pos(' ',SplitString);
+    if i > 0 then
+      begin
+        result := copy(SplitString,1,i-1);
+        delete(SplitString,1,i);
+      end
+    else
+      begin
+        result := SplitString;
+        SplitString:='';
+      end;
+  end;
+
 Var
   I : Integer;
   DefaultsFileName : string;
+  OptString : string;
+  CustOptName : string;
 begin
   I:=0;
   FListMode:=False;
@@ -2886,11 +2985,25 @@ begin
       Defaults.LocalUnitDir:=OptionArg(I)
     else if CheckOption(I,'UG','globalunitdir') then
       Defaults.GlobalUnitDir:=OptionArg(I)
+    else if CheckOption(I,'o','options') then
+      begin
+        OptString := OptionArg(I);
+        while OptString <> '' do
+          Defaults.Options.Add(SplitSpaces(OptString));
+      end
     else if CheckOption(I,'r','compiler') then
       Defaults.Compiler:=OptionArg(I)
     else if CheckOption(I,'f','config') then
       DefaultsFileName:=OptionArg(I)
-    else
+    else if CheckOption(I,'io','ignoreinvalidoption') then
+      Defaults.IgnoreInvalidOptions:=true
+    else if assigned(CustomFpmakeCommandlineOptions) and CheckCustomOption(I,CustOptName) then
+      begin
+      if not assigned(CustomFpMakeCommandlineValues) then
+        CustomFpMakeCommandlineValues := TStringList.Create;
+      CustomFpMakeCommandlineValues.Values[CustOptName]:=OptionArg(I)
+      end
+    else if not Defaults.IgnoreInvalidOptions then
       begin
       Usage(SErrInValidArgument,[I,ParamStr(I)]);
       end;
@@ -2918,6 +3031,8 @@ procedure TCustomInstaller.Usage(const FMT: String; Args: array of const);
     Log(vlInfo,Format(' -%s --%-20s %s',[C,LC+'='+SValue,MSG]));
   end;
 
+var
+  i: Integer;
 begin
   // Force the Usage to be displayed
   Include(FLogLevels,vlInfo);
@@ -2945,6 +3060,10 @@ begin
   LogArgOption('UG','globalunitdir',SHelpGlobalUnitdir);
   LogArgOption('r','compiler',SHelpCompiler);
   LogArgOption('f','config',SHelpConfig);
+  LogArgOption('o','options',SHelpOptions);
+  LogArgOption('io','ignoreinvalidoption',SHelpIgnoreInvOpt);
+  if assigned(CustomFpmakeCommandlineOptions) then for i  := 0 to CustomFpmakeCommandlineOptions.Count-1 do
+    LogArgOption(' ',CustomFpmakeCommandlineOptions.Names[i],CustomFpmakeCommandlineOptions.ValueFromIndex[i]);
   Log(vlInfo,'');
   If (FMT<>'') then
     halt(1)
@@ -3244,6 +3363,7 @@ procedure TBuildEngine.CmdCopyFiles(List: TStrings; Const DestDir: String);
 Var
   Args : String;
   I : Integer;
+  DestFileName : String;
 
 begin
   CmdCreateDir(DestDir);
@@ -3255,7 +3375,14 @@ begin
     end
   else
     For I:=0 to List.Count-1 do
-      SysCopyFile(List[i],DestDir);
+      if List.Names[i]<>'' then
+        begin
+          DestFileName:=DestDir+list.ValueFromIndex[i];
+          CmdCreateDir(ExtractFilePath(DestFileName));
+          SysCopyFile(List.names[i],DestFileName)
+        end
+      else
+        SysCopyFile(List[i],DestDir);
 end;
 
 
@@ -4167,6 +4294,24 @@ begin
   end;
 end;
 
+function TBuildEngine.InstallPackageSourceFiles(APAckage: TPackage; tt: TSourceType; const Dest: String): Boolean;
+Var
+  List : TStringList;
+begin
+  Result:=False;
+  List:=TStringList.Create;
+  Try
+    APackage.GetInstallSourceFiles(List,[tt]);
+    if (List.Count>0) then
+      begin
+        Result:=True;
+        CmdCopyFiles(List,Dest);
+      end;
+  Finally
+    List.Free;
+  end;
+end;
+
 
 procedure TBuildEngine.DoBeforeInstall(APackage: TPackage);
 begin
@@ -4203,6 +4348,9 @@ begin
       B:=true;
     if InstallPackageFiles(APAckage,ttImplicitUnit,D) then
       B:=true;
+    // By default do not install the examples. Maybe add an option for this later
+    //if InstallPackageFiles(APAckage,ttExampleUnit,D) then
+    //  B:=true;
     // Unit (dependency) configuration if there were units installed
     if B then
       begin
@@ -4213,6 +4361,13 @@ begin
     // Programs
     D:=IncludeTrailingPathDelimiter(Defaults.BinInstallDir);
     InstallPackageFiles(APAckage,ttProgram,D);
+    //InstallPackageFiles(APAckage,ttExampleProgram,D);
+    // Documentation
+    D:=IncludeTrailingPathDelimiter(Defaults.DocInstallDir)+'fpc-'+APackage.FileName+PathDelim;
+    InstallPackageSourceFiles(APackage,stDoc,D);
+    // Examples
+    D:=IncludeTrailingPathDelimiter(Defaults.ExamplesInstallDir)+'fpc-'+APackage.FileName+PathDelim;
+    InstallPackageSourceFiles(APackage,stExample,D);
     // Done.
     APackage.FTargetState:=tsInstalled;
     DoAfterInstall(APackage);
@@ -4715,6 +4870,16 @@ end;
                                  TSource
 ****************************************************************************}
 
+function TSource.GetInstallSourcePath: string;
+begin
+  if FInstallSourcePath<>'' then
+    result := FInstallSourcePath
+  else if SourceType=stExample then
+    result := 'examples'
+  else
+    result := '';
+end;
+
 constructor TSource.Create(ACollection: TCollection);
 begin
   inherited Create(ACollection);
@@ -4726,6 +4891,14 @@ begin
   inherited Destroy;
 end;
 
+procedure TSource.GetInstallFiles(List: TStrings);
+begin
+  if InstallSourcePath<>'' then
+    list.Values[name] := (IncludeTrailingPathDelimiter(InstallSourcePath)+ExtractFileName(Name))
+  else
+    list.add(Name);
+end;
+
 
 {****************************************************************************
                                  TCommands
@@ -5205,8 +5378,12 @@ end;
 
 Initialization
   OnGetApplicationName:=@GetFPMakeName;
+  CustomFpmakeCommandlineOptions:=nil;
+  CustomFpMakeCommandlineValues:=nil;
 
 Finalization
+  FreeAndNil(CustomFpMakeCommandlineValues);
+  FreeAndNil(CustomFpmakeCommandlineOptions);
   FreeAndNil(DefInstaller);
   FreeAndNil(Dictionary);
   FreeAndNil(Defaults);

File diff suppressed because it is too large
+ 304 - 275
utils/fppkg/fpmkunitsrc.inc


+ 27 - 461
utils/fppkg/fppkg.lpi

@@ -1,7 +1,7 @@
 <?xml version="1.0"?>
 <CONFIG>
   <ProjectOptions>
-    <Version Value="7"/>
+    <Version Value="9"/>
     <General>
       <Flags>
         <MainUnitHasUsesSectionForAllUnits Value="False"/>
@@ -9,14 +9,13 @@
         <MainUnitHasTitleStatement Value="False"/>
         <LRSInOutputDirectory Value="False"/>
       </Flags>
+      <SessionStorage Value="InProjectDir"/>
       <MainUnit Value="0"/>
-      <TargetFileExt Value=""/>
-      <ActiveWindowIndexAtStart Value="0"/>
     </General>
     <VersionInfo>
       <Language Value=""/>
       <CharSet Value=""/>
-      <StringTable Comments="" CompanyName="" FileDescription="" FileVersion="0.0.0.0" InternalName="" LegalCopyright="" LegalTrademarks="" OriginalFilename="" ProductName="" ProductVersion=""/>
+      <StringTable ProductVersion=""/>
     </VersionInfo>
     <PublishOptions>
       <Version Value="2"/>
@@ -31,490 +30,60 @@
         <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
       </local>
     </RunParams>
-    <Units Count="38">
+    <Units Count="8">
       <Unit0>
         <Filename Value="fppkg.pp"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="fppkg"/>
-        <IsVisibleTab Value="True"/>
-        <EditorIndex Value="10"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="99"/>
-        <CursorPos X="61" Y="104"/>
-        <UsageCount Value="223"/>
-        <Loaded Value="True"/>
       </Unit0>
       <Unit1>
         <Filename Value="pkgropts.pp"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="pkgoptions"/>
-        <TopLine Value="1"/>
-        <CursorPos X="41" Y="18"/>
-        <UsageCount Value="223"/>
       </Unit1>
       <Unit2>
-        <Filename Value="fpmkcnst.inc"/>
-        <TopLine Value="1"/>
-        <CursorPos X="64" Y="8"/>
-        <UsageCount Value="59"/>
-      </Unit2>
-      <Unit3>
-        <Filename Value="fpmktype.pp"/>
-        <UnitName Value="fpmktype"/>
-        <TopLine Value="1"/>
-        <CursorPos X="3" Y="41"/>
-        <UsageCount Value="59"/>
-      </Unit3>
-      <Unit4>
-        <Filename Value="fpmkunit.pp"/>
-        <UnitName Value="fpmkunit"/>
-        <TopLine Value="1"/>
-        <CursorPos X="1" Y="1"/>
-        <UsageCount Value="59"/>
-      </Unit4>
-      <Unit5>
         <Filename Value="fprepos.pp"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="fprepos"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="245"/>
-        <CursorPos X="3" Y="245"/>
-        <UsageCount Value="223"/>
-      </Unit5>
-      <Unit6>
+      </Unit2>
+      <Unit3>
         <Filename Value="fpxmlrep.pp"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="fpxmlrep"/>
-        <TopLine Value="43"/>
-        <CursorPos X="1" Y="43"/>
-        <UsageCount Value="223"/>
-      </Unit6>
-      <Unit7>
+      </Unit3>
+      <Unit4>
         <Filename Value="pkghandler.pp"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="pkghandler"/>
-        <EditorIndex Value="9"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="182"/>
-        <CursorPos X="46" Y="212"/>
-        <UsageCount Value="223"/>
-        <Loaded Value="True"/>
-      </Unit7>
-      <Unit8>
+      </Unit4>
+      <Unit5>
         <Filename Value="pkgmkconv.pp"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="pkgmkconv"/>
-        <TopLine Value="29"/>
-        <CursorPos X="14" Y="53"/>
-        <UsageCount Value="223"/>
-      </Unit8>
-      <Unit9>
+      </Unit5>
+      <Unit6>
         <Filename Value="pkgdownload.pp"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="pkgDownload"/>
-        <EditorIndex Value="11"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="113"/>
-        <CursorPos X="24" Y="125"/>
-        <UsageCount Value="223"/>
-        <Loaded Value="True"/>
-      </Unit9>
-      <Unit10>
+      </Unit6>
+      <Unit7>
         <Filename Value="pkgmessages.pp"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="pkgmessages"/>
-        <EditorIndex Value="2"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="36"/>
-        <CursorPos X="3" Y="54"/>
-        <UsageCount Value="223"/>
-        <Loaded Value="True"/>
-      </Unit10>
-      <Unit11>
-        <Filename Value="../../../fpc20/rtl/objpas/classes/classesh.inc"/>
-        <TopLine Value="580"/>
-        <CursorPos X="14" Y="599"/>
-        <UsageCount Value="19"/>
-      </Unit11>
-      <Unit12>
-        <Filename Value="../../../fpc20/rtl/inc/objpash.inc"/>
-        <TopLine Value="269"/>
-        <CursorPos X="38" Y="277"/>
-        <UsageCount Value="17"/>
-      </Unit12>
-      <Unit13>
-        <Filename Value="contnrs20.pp"/>
-        <UnitName Value="contnrs20"/>
-        <TopLine Value="1"/>
-        <CursorPos X="1" Y="1"/>
-        <UsageCount Value="11"/>
-      </Unit13>
-      <Unit14>
-        <Filename Value="pkgcommands.pp"/>
-        <UnitName Value="pkgcommands"/>
-        <EditorIndex Value="1"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="119"/>
-        <CursorPos X="70" Y="134"/>
-        <UsageCount Value="110"/>
-        <Loaded Value="True"/>
-      </Unit14>
-      <Unit15>
-        <Filename Value="pkgwget.pp"/>
-        <UnitName Value="pkgwget"/>
-        <TopLine Value="15"/>
-        <CursorPos X="18" Y="25"/>
-        <UsageCount Value="15"/>
-      </Unit15>
-      <Unit16>
-        <Filename Value="reptest.pp"/>
-        <UnitName Value="reptest"/>
-        <TopLine Value="1"/>
-        <CursorPos X="1" Y="1"/>
-        <UsageCount Value="8"/>
-      </Unit16>
-      <Unit17>
-        <Filename Value="rep2xml.lpr"/>
-        <UnitName Value="rep2xml"/>
-        <TopLine Value="217"/>
-        <CursorPos X="40" Y="228"/>
-        <UsageCount Value="8"/>
-      </Unit17>
-      <Unit18>
-        <Filename Value="pkgrepos.pp"/>
-        <UnitName Value="pkgrepos"/>
-        <EditorIndex Value="7"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="47"/>
-        <CursorPos X="1" Y="62"/>
-        <UsageCount Value="101"/>
-        <Loaded Value="True"/>
-      </Unit18>
-      <Unit19>
-        <Filename Value="zipper.pp"/>
-        <UnitName Value="zipper"/>
-        <TopLine Value="1303"/>
-        <CursorPos X="21" Y="1324"/>
-        <UsageCount Value="1"/>
-      </Unit19>
-      <Unit20>
-        <Filename Value="pkgfpmake.pp"/>
-        <UnitName Value="pkgfpmake"/>
-        <EditorIndex Value="0"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="264"/>
-        <CursorPos X="38" Y="280"/>
-        <UsageCount Value="91"/>
-        <Loaded Value="True"/>
-      </Unit20>
-      <Unit21>
-        <Filename Value="pkglnet.pp"/>
-        <UnitName Value="pkglnet"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="1"/>
-        <CursorPos X="71" Y="10"/>
-        <UsageCount Value="70"/>
-      </Unit21>
-      <Unit22>
-        <Filename Value="pkgoptions.pp"/>
-        <UnitName Value="pkgoptions"/>
-        <EditorIndex Value="3"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="356"/>
-        <CursorPos X="1" Y="371"/>
-        <UsageCount Value="90"/>
-        <Bookmarks Count="2">
-          <Item0 X="1" Y="272" ID="2"/>
-          <Item1 X="1" Y="391" ID="1"/>
-        </Bookmarks>
-        <Loaded Value="True"/>
-      </Unit22>
-      <Unit23>
-        <Filename Value="pkgglobals.pp"/>
-        <UnitName Value="pkgglobals"/>
-        <EditorIndex Value="8"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="344"/>
-        <CursorPos X="37" Y="372"/>
-        <UsageCount Value="88"/>
-        <Loaded Value="True"/>
-      </Unit23>
-      <Unit24>
-        <Filename Value="../../rtl/objpas/sysutils/osutilsh.inc"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="23"/>
-        <CursorPos X="10" Y="41"/>
-        <SyntaxHighlighter Value="FreePascal"/>
-        <UsageCount Value="62"/>
-        <DefaultSyntaxHighlighter Value="Text"/>
-      </Unit24>
-      <Unit25>
-        <Filename Value="../../rtl/unix/sysutils.pp"/>
-        <UnitName Value="sysutils"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="1349"/>
-        <CursorPos X="3" Y="1353"/>
-        <SyntaxHighlighter Value="FreePascal"/>
-        <UsageCount Value="62"/>
-        <DefaultSyntaxHighlighter Value="Text"/>
-      </Unit25>
-      <Unit26>
-        <Filename Value="../../../lazarus/packager/packagesystem.pas"/>
-        <UnitName Value="PackageSystem"/>
-        <EditorIndex Value="5"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="1296"/>
-        <CursorPos X="10" Y="1314"/>
-        <SyntaxHighlighter Value="FreePascal"/>
-        <UsageCount Value="29"/>
-        <Loaded Value="True"/>
-        <DefaultSyntaxHighlighter Value="Text"/>
-      </Unit26>
-      <Unit27>
-        <Filename Value="../../rtl/objpas/sysutils/finah.inc"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="7"/>
-        <CursorPos X="10" Y="39"/>
-        <SyntaxHighlighter Value="FreePascal"/>
-        <UsageCount Value="7"/>
-        <DefaultSyntaxHighlighter Value="Text"/>
-      </Unit27>
-      <Unit28>
-        <Filename Value="../../../lazarus/packager/basepkgmanager.pas"/>
-        <UnitName Value="BasePkgManager"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="229"/>
-        <CursorPos X="37" Y="247"/>
-        <SyntaxHighlighter Value="FreePascal"/>
-        <UsageCount Value="27"/>
-        <DefaultSyntaxHighlighter Value="Text"/>
-      </Unit28>
-      <Unit29>
-        <Filename Value="../../../lazarus/ide/frames/files_options.pas"/>
-        <ComponentName Value="FilesOptionsFrame"/>
-        <HasResources Value="True"/>
-        <ResourceBaseClass Value="Frame"/>
-        <UnitName Value="files_options"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="297"/>
-        <CursorPos X="27" Y="319"/>
-        <SyntaxHighlighter Value="FreePascal"/>
-        <UsageCount Value="7"/>
-        <DefaultSyntaxHighlighter Value="Text"/>
-      </Unit29>
-      <Unit30>
-        <Filename Value="../../../lazarus/ide/environmentopts.pp"/>
-        <UnitName Value="EnvironmentOpts"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="1460"/>
-        <CursorPos X="66" Y="1478"/>
-        <SyntaxHighlighter Value="FreePascal"/>
-        <UsageCount Value="7"/>
-        <DefaultSyntaxHighlighter Value="Text"/>
-      </Unit30>
-      <Unit31>
-        <Filename Value="../../../lazarus/components/codetools/fileprocs.pas"/>
-        <UnitName Value="FileProcs"/>
-        <EditorIndex Value="6"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="966"/>
-        <CursorPos X="26" Y="969"/>
-        <SyntaxHighlighter Value="FreePascal"/>
-        <UsageCount Value="29"/>
-        <Loaded Value="True"/>
-        <DefaultSyntaxHighlighter Value="Text"/>
-      </Unit31>
-      <Unit32>
-        <Filename Value="../../../lazarus/components/chmhelp/packages/idehelp/lazchmhelp.pas"/>
-        <UnitName Value="LazChmHelp"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="176"/>
-        <CursorPos X="31" Y="194"/>
-        <SyntaxHighlighter Value="FreePascal"/>
-        <UsageCount Value="7"/>
-        <DefaultSyntaxHighlighter Value="Text"/>
-      </Unit32>
-      <Unit33>
-        <Filename Value="../../../lazarus/test/bugs/testfileproc.pas"/>
-        <UnitName Value="testfileproc"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="19"/>
-        <CursorPos X="14" Y="45"/>
-        <SyntaxHighlighter Value="FreePascal"/>
-        <UsageCount Value="7"/>
-        <DefaultSyntaxHighlighter Value="Text"/>
-      </Unit33>
-      <Unit34>
-        <Filename Value="../../../lazarus/ide/transfermacros.pp"/>
-        <UnitName Value="TransferMacros"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="1"/>
-        <CursorPos X="40" Y="19"/>
-        <SyntaxHighlighter Value="FreePascal"/>
-        <UsageCount Value="27"/>
-        <DefaultSyntaxHighlighter Value="Text"/>
-      </Unit34>
-      <Unit35>
-        <Filename Value="../../packages/fcl-web/src/fptemplate.pp"/>
-        <UnitName Value="fpTemplate"/>
-        <EditorIndex Value="4"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="56"/>
-        <CursorPos X="1" Y="69"/>
-        <SyntaxHighlighter Value="FreePascal"/>
-        <UsageCount Value="29"/>
-        <Loaded Value="True"/>
-        <DefaultSyntaxHighlighter Value="Text"/>
-      </Unit35>
-      <Unit36>
-        <Filename Value="../../packages/fcl-base/src/inifiles.pp"/>
-        <UnitName Value="IniFiles"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="163"/>
-        <CursorPos X="14" Y="178"/>
-        <SyntaxHighlighter Value="FreePascal"/>
-        <UsageCount Value="7"/>
-        <DefaultSyntaxHighlighter Value="Text"/>
-      </Unit36>
-      <Unit37>
-        <Filename Value="../../rtl/objpas/sysutils/osutil.inc"/>
-        <WindowIndex Value="0"/>
-        <TopLine Value="66"/>
-        <CursorPos X="40" Y="75"/>
-        <SyntaxHighlighter Value="FreePascal"/>
-        <UsageCount Value="7"/>
-        <DefaultSyntaxHighlighter Value="Text"/>
-      </Unit37>
+      </Unit7>
     </Units>
-    <JumpHistory Count="30" HistoryIndex="29">
-      <Position1>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="177" Column="16" TopLine="161"/>
-      </Position1>
-      <Position2>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="178" Column="16" TopLine="161"/>
-      </Position2>
-      <Position3>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="184" Column="16" TopLine="161"/>
-      </Position3>
-      <Position4>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="194" Column="30" TopLine="179"/>
-      </Position4>
-      <Position5>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="195" Column="30" TopLine="179"/>
-      </Position5>
-      <Position6>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="196" Column="30" TopLine="179"/>
-      </Position6>
-      <Position7>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="197" Column="30" TopLine="179"/>
-      </Position7>
-      <Position8>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="232" Column="16" TopLine="217"/>
-      </Position8>
-      <Position9>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="271" Column="1" TopLine="256"/>
-      </Position9>
-      <Position10>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="326" Column="1" TopLine="311"/>
-      </Position10>
-      <Position11>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="390" Column="16" TopLine="375"/>
-      </Position11>
-      <Position12>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="391" Column="16" TopLine="375"/>
-      </Position12>
-      <Position13>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="392" Column="16" TopLine="375"/>
-      </Position13>
-      <Position14>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="393" Column="16" TopLine="375"/>
-      </Position14>
-      <Position15>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="398" Column="16" TopLine="375"/>
-      </Position15>
-      <Position16>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="409" Column="30" TopLine="394"/>
-      </Position16>
-      <Position17>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="62" Column="1" TopLine="39"/>
-      </Position17>
-      <Position18>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="94" Column="15" TopLine="79"/>
-      </Position18>
-      <Position19>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="119" Column="23" TopLine="104"/>
-      </Position19>
-      <Position20>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="163" Column="40" TopLine="148"/>
-      </Position20>
-      <Position21>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="410" Column="53" TopLine="395"/>
-      </Position21>
-      <Position22>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="425" Column="19" TopLine="410"/>
-      </Position22>
-      <Position23>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="453" Column="16" TopLine="438"/>
-      </Position23>
-      <Position24>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="454" Column="23" TopLine="438"/>
-      </Position24>
-      <Position25>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="453" Column="23" TopLine="438"/>
-      </Position25>
-      <Position26>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="454" Column="23" TopLine="438"/>
-      </Position26>
-      <Position27>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="516" Column="75" TopLine="494"/>
-      </Position27>
-      <Position28>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="393" Column="1" TopLine="378"/>
-      </Position28>
-      <Position29>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="325" Column="1" TopLine="310"/>
-      </Position29>
-      <Position30>
-        <Filename Value="pkgoptions.pp"/>
-        <Caret Line="371" Column="1" TopLine="356"/>
-      </Position30>
-    </JumpHistory>
   </ProjectOptions>
   <CompilerOptions>
-    <Version Value="8"/>
+    <Version Value="9"/>
     <SearchPaths>
-      <IncludeFiles Value="lnet/sys/"/>
-      <OtherUnitFiles Value="lnet/"/>
+      <IncludeFiles Value="lnet/sys"/>
+      <OtherUnitFiles Value="lnet"/>
     </SearchPaths>
+    <Parsing>
+      <SyntaxOptions>
+        <UseAnsiStrings Value="False"/>
+      </SyntaxOptions>
+    </Parsing>
     <CodeGeneration>
       <Checks>
         <IOChecks Value="True"/>
@@ -535,17 +104,14 @@
       <Verbosity>
         <ShowHints Value="False"/>
       </Verbosity>
-      <CustomOptions Value="-FE.
-"/>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CustomOptions Value="-FE."/>
       <CompilerPath Value="$(CompPath)"/>
     </Other>
   </CompilerOptions>
   <Debugging>
-    <Watches Count="1">
-      <Item1>
-        <Expression Value="builddir"/>
-      </Item1>
-    </Watches>
     <Exceptions Count="2">
       <Item1>
         <Name Value="ECodetoolError"/>

+ 83 - 17
utils/fppkg/fppkg.pp

@@ -39,7 +39,7 @@ Type
     Destructor Destroy;override;
     Procedure LoadGlobalDefaults;
     Procedure LoadCompilerDefaults;
-    Procedure ProcessCommandLine;
+    Procedure ProcessCommandLine(FirstPass: boolean);
     Procedure DoRun; Override;
   end;
 
@@ -97,7 +97,7 @@ begin
   if not GeneratedConfig then
     begin
       GlobalOptions.LoadGlobalFromFile(cfgfile);
-      if GlobalOptions.Dirty and (not UseGlobalConfig or IsSuperUser) then
+      if GlobalOptions.SaveInifileChanges and (not UseGlobalConfig or IsSuperUser) then
         GlobalOptions.SaveGlobalToFile(cfgfile);
     end;
   GlobalOptions.CompilerConfig:=GlobalOptions.DefaultCompilerConfig;
@@ -139,7 +139,7 @@ begin
           pkgglobals.Log(vlDebug,SLogGeneratingCompilerConfig,[S]);
           CompilerOptions.InitCompilerDefaults;
           CompilerOptions.SaveCompilerToFile(S);
-          if CompilerOptions.Dirty then
+          if CompilerOptions.SaveInifileChanges then
             CompilerOptions.SaveCompilerToFile(S);
         end
       else
@@ -154,7 +154,7 @@ begin
     begin
       pkgglobals.Log(vlDebug,SLogLoadingFPMakeCompilerConfig,[S]);
       FPMakeCompilerOptions.LoadCompilerFromFile(S);
-      if FPMakeCompilerOptions.Dirty then
+      if FPMakeCompilerOptions.SaveInifileChanges then
         FPMakeCompilerOptions.SaveCompilerToFile(S);
     end
   else
@@ -168,15 +168,21 @@ procedure TMakeTool.ShowUsage;
 begin
   Writeln('Usage: ',Paramstr(0),' [options] <action> <package>');
   Writeln('Options:');
-  Writeln('  -c --config       Set compiler configuration to use');
-  Writeln('  -h --help         This help');
-  Writeln('  -v --verbose      Show more information');
-  Writeln('  -d --debug        Show debugging information');
-  Writeln('  -g --global       Force installation to global (system-wide) directory');
-  Writeln('  -f --force        Force installation also if the package is already installed');
-  Writeln('  -r --recovery     Recovery mode, use always internal fpmkunit');
-  Writeln('  -b --broken       Do not stop on broken packages');
-  Writeln('  -l --showlocation Show if the packages are installed globally or locally');
+  Writeln('  -c --config        Set compiler configuration to use');
+  Writeln('  -h --help          This help');
+  Writeln('  -v --verbose       Show more information');
+  Writeln('  -d --debug         Show debugging information');
+  Writeln('  -g --global        Force installation to global (system-wide) directory');
+  Writeln('  -f --force         Force installation also if the package is already installed');
+  Writeln('  -r --recovery      Recovery mode, use always internal fpmkunit');
+  Writeln('  -b --broken        Do not stop on broken packages');
+  Writeln('  -l --showlocation  Show if the packages are installed globally or locally');
+  Writeln('  -o --options=value Pass extra options to the compiler');
+  Writeln('  -n                 Do not read the default configuration files');
+  Writeln('  -p --prefix=value  Specify the prefix');
+  Writeln('  --compiler=value   Specify the compiler-executable');
+  Writeln('  --cpu=value        Specify the target cpu to compile for');
+  Writeln('  --os=value         Specify the target operating system to compile for');
   Writeln('Actions:');
   Writeln('  update            Update packages list');
   Writeln('  list              List available and installed packages');
@@ -206,7 +212,7 @@ begin
 end;
 
 
-procedure TMakeTool.ProcessCommandLine;
+procedure TMakeTool.ProcessCommandLine(FirstPass: boolean);
 
   Function CheckOption(Index : Integer;Short,Long : String): Boolean;
   var
@@ -243,9 +249,26 @@ procedure TMakeTool.ProcessCommandLine;
       end;
   end;
 
+  function SplitSpaces(var SplitString: string) : string;
+  var i : integer;
+  begin
+    i := pos(' ',SplitString);
+    if i > 0 then
+      begin
+        result := copy(SplitString,1,i-1);
+        delete(SplitString,1,i);
+      end
+    else
+      begin
+        result := SplitString;
+        SplitString:='';
+      end;
+  end;
+
 Var
   I : Integer;
   HasAction : Boolean;
+  OptString : String;
 begin
   I:=0;
   HasAction:=false;
@@ -265,17 +288,44 @@ begin
         GlobalOptions.InstallGlobal:=true
       else if CheckOption(I,'r','recovery') then
         GlobalOptions.RecoveryMode:=true
+      else if CheckOption(I,'n','') then
+        GlobalOptions.SkipConfigurationFiles:=true
       else if CheckOption(I,'b','broken') then
         GlobalOptions.AllowBroken:=true
       else if CheckOption(I,'l','showlocation') then
         GlobalOptions.ShowLocation:=true
+      else if CheckOption(I,'o','options') and FirstPass then
+        begin
+          OptString := OptionArg(I);
+          while OptString <> '' do
+            CompilerOptions.Options.Add(SplitSpaces(OptString));
+        end
+      else if CheckOption(I,'p','prefix') then
+        begin
+          CompilerOptions.GlobalPrefix := OptionArg(I);
+          CompilerOptions.LocalPrefix := OptionArg(I);
+          FPMakeCompilerOptions.GlobalPrefix := OptionArg(I);
+          FPMakeCompilerOptions.LocalPrefix := OptionArg(I);
+        end
+      else if CheckOption(I,'','compiler') then
+        begin
+          CompilerOptions.Compiler := OptionArg(I);
+          FPMakeCompilerOptions.Compiler := OptionArg(I);
+        end
+      else if CheckOption(I,'','os') then
+        CompilerOptions.CompilerOS := StringToOS(OptionArg(I))
+      else if CheckOption(I,'','cpu') then
+        CompilerOptions.CompilerCPU := StringToCPU(OptionArg(I))
       else if CheckOption(I,'h','help') then
         begin
           ShowUsage;
           halt(0);
         end
       else if (Length(Paramstr(i))>0) and (Paramstr(I)[1]='-') then
-        Raise EMakeToolError.CreateFmt(SErrInvalidArgument,[I,ParamStr(i)])
+        begin
+          if FirstPass then
+            Raise EMakeToolError.CreateFmt(SErrInvalidArgument,[I,ParamStr(i)])
+        end
       else
       // It's a command or target.
         begin
@@ -303,7 +353,7 @@ begin
   OldCurrDir:=GetCurrentDir;
   Try
     LoadGlobalDefaults;
-    ProcessCommandLine;
+    ProcessCommandLine(true);
 
     // Scan is special, it doesn't need a valid local setup
     if (ParaAction='scan') then
@@ -315,7 +365,23 @@ begin
       end;
 
     MaybeCreateLocalDirs;
-    LoadCompilerDefaults;
+    if not GlobalOptions.SkipConfigurationFiles then
+      LoadCompilerDefaults
+    else
+      begin
+        FPMakeCompilerOptions.InitCompilerDefaults;
+        CompilerOptions.InitCompilerDefaults;
+      end;
+
+    // The command-line is parsed for the second time, to make it possible
+    // to override the values in the compiler-configuration file. (like prefix)
+    ProcessCommandLine(false);
+
+    // If CompilerVersion, CompilerOS or CompilerCPU is still empty, use the
+    // compiler-executable to get them
+    FPMakeCompilerOptions.CheckCompilerValues;
+    CompilerOptions.CheckCompilerValues;
+
     LoadLocalAvailableMirrors;
 
     // Load local repository, update first if this is a new installation

+ 27 - 5
utils/fppkg/pkgfpmake.pp

@@ -84,6 +84,10 @@ type
      constructor Create(p:pointer;mysize:integer);
    end;
 
+{
+  Generated from fpmkunit.pp, using data2inc:
+  data2inc -b -s fpmkunit.pp fpmkunitsrc.inc fpmkunitsrc
+}
 {$i fpmkunitsrc.inc}
 
 procedure CreateFPMKUnitSource(const AFileName:string);
@@ -256,6 +260,12 @@ Var
     OOptions:=OOptions+maybequoted(s);
   end;
 
+  procedure CondAddOption(const Name,Value:string);
+  begin
+    if Value<>'' then
+      AddOption(Name+'='+Value);
+  end;
+
 begin
   OOptions:='';
   // Does the current package support this CPU-OS?
@@ -290,13 +300,25 @@ begin
   AddOption('--compiler='+CompilerOptions.Compiler);
   AddOption('--cpu='+CPUToString(CompilerOptions.CompilerCPU));
   AddOption('--os='+OSToString(CompilerOptions.CompilerOS));
+  if CompilerOptions.HasOptions then
+    AddOption('--options='+CompilerOptions.Options.DelimitedText);
   if IsSuperUser or GlobalOptions.InstallGlobal then
-    AddOption('--baseinstalldir='+CompilerOptions.GlobalInstallDir)
+    begin
+      CondAddOption('--prefix',CompilerOptions.GlobalPrefix);
+      CondAddOption('--baseinstalldir',CompilerOptions.GlobalInstallDir);
+    end
   else
-    AddOption('--baseinstalldir='+CompilerOptions.LocalInstallDir);
-  if CompilerOptions.LocalInstallDir<>'' then
-    AddOption('--localunitdir='+CompilerOptions.LocalUnitDir);
-  AddOption('--globalunitdir='+CompilerOptions.GlobalUnitDir);
+    begin
+      CondAddOption('--prefix',CompilerOptions.LocalPrefix);
+      CondAddOption('--baseinstalldir',CompilerOptions.LocalInstallDir);
+    end;
+  CondAddOption('--localunitdir',CompilerOptions.LocalUnitDir);
+  CondAddOption('--globalunitdir',CompilerOptions.GlobalUnitDir);
+  if GlobalOptions.CustomFPMakeOptions<>'' then
+    begin
+    AddOption('--ignoreinvalidoption');
+    AddOption(GlobalOptions.CustomFPMakeOptions);
+    end;
   { Run FPMake }
   FPMakeBin:='fpmake'+ExeExt;
   SetCurrentDir(PackageBuildPath(P));

+ 18 - 2
utils/fppkg/pkgglobals.pp

@@ -9,7 +9,8 @@ uses
   baseunix,
 {$endif}
   SysUtils,
-  Classes;
+  Classes,
+  fprepos;
 
 Const
 {$ifdef unix}
@@ -75,7 +76,8 @@ Function FileExistsLog(const AFileName:string):Boolean;
 procedure BackupFile(const AFileName: String);
 Procedure DeleteDir(const ADir:string);
 Procedure SearchFiles(SL:TStringList;const APattern:string);
-Function GetCompilerInfo(const ACompiler,AOptions:string):string;
+Function GetCompilerInfo(const ACompiler,AOptions:string):string; overload;
+Procedure GetCompilerInfo(const ACompiler, AOptions: string; out AVersion: string; out ACPU: TCpu; out aOS:TOS); overload;
 function IsSuperUser:boolean;
 
 var
@@ -357,6 +359,20 @@ begin
 end;
 
 
+Procedure GetCompilerInfo(const ACompiler, AOptions: string; out AVersion: string; out ACPU: TCpu; out aOS:TOS); overload;
+var
+  infosl: TStringList;
+begin
+  infosl:=TStringList.Create;
+  infosl.Delimiter:=' ';
+  infosl.DelimitedText:=GetCompilerInfo(ACompiler,AOptions);
+  if infosl.Count<>3 then
+    Raise EPackagerError.Create(SErrInvalidFPCInfo);
+  AVersion:=infosl[0];
+  ACPU:=StringToCPU(infosl[1]);
+  AOS:=StringToOS(infosl[2]);
+end;
+
 function IsSuperUser:boolean;
 begin
 {$ifdef unix}

+ 1 - 0
utils/fppkg/pkghandler.pp

@@ -156,6 +156,7 @@ end;
 Function TPackageHandler.ExecuteProcess(Const Prog,Args:String):Integer;
 begin
   Log(vlCommands,SLogExecute,[Prog,Args]);
+  Flush(StdOut);
   Result:=SysUtils.ExecuteProcess(Prog,Args);
 end;
 

+ 4 - 1
utils/fppkg/pkgmessages.pp

@@ -65,7 +65,8 @@ Resourcestring
   SLogLoadingFPMakeCompilerConfig = 'Loading compiler configuration for fpmake building from "%s"';
   SLogGeneratingGlobalConfig = 'Generating default global configuration in "%s"';
   SLogDetectedCompiler       = 'Detected compiler "%s" (version %s for %s)';
-  SLogDetectedFPCDIR         = 'Detected %s FPCDIR "%s"';
+  SLogDetectedPrefix         = 'Detected %s prefix "%s"';
+  SLogFPCDirEnv              = 'FPCDIR from environment setting "%s"';
   SLogGeneratingCompilerConfig  = 'Generating default compiler configuration in "%s"';
   SLogLoadingPackagesFile    = 'Loading available packages from "%s"';
   SLogLoadingMirrorsFile     = 'Loading available mirrors from "%s"';
@@ -95,6 +96,8 @@ Resourcestring
   SLogCompilerCfgVersion     = ' Version: "%s"';
   SLogCompilerCfgGlobalInstallDir = ' GlobalInstallDir: "%s"';
   SLogCompilerCfgLocalInstallDir = ' LocalInstallDir: "%s"';
+  SLogCompilerCfgGlobalPrefix = ' GlobalPrefix: "%s"';
+  SLogCompilerCfgLocalPrefix = ' LocalPrefix: "%s"';
 
   SDbgFound                  = 'Found';
   SDbgNotFound               = 'Not Found';

+ 136 - 47
utils/fppkg/pkgoptions.pp

@@ -32,7 +32,7 @@ Type
 
   TGlobalOptions = Class(TPersistent)
   private
-    FDirty : Boolean;
+    FSaveInifileChanges : Boolean;
     FConfigVersion : Integer;
     FRemoteMirrorsURL,
     FRemoteRepository,
@@ -50,6 +50,8 @@ Type
     FRecoveryMode   : Boolean;
     FOptionParser: TTemplateParser;
     FShowLocation: Boolean;
+    FSkipConfigurationFiles: boolean;
+    FCustomFPMakeOptions : string;
     function  GetOptString(Index: integer): String;
     procedure SetOptString(Index: integer; const AValue: String);
     procedure UpdateLocalRepositoryOption;
@@ -60,7 +62,8 @@ Type
     Procedure LoadGlobalFromFile(const AFileName : String);
     Procedure SaveGlobalToFile(const AFileName : String);
     procedure LogValues;
-    Property Dirty : Boolean Read FDirty;
+    // Is set when the inifile has an old version number (which is also the case when a new file is generated)
+    Property SaveInifileChanges : Boolean Read FSaveInifileChanges;
     Property ConfigVersion : Integer read FConfigVersion;
     function LocalPackagesFile:string;
     function LocalMirrorsFile:string;
@@ -76,12 +79,14 @@ Type
     Property DefaultCompilerConfig : String Index 8 Read GetOptString Write SetOptString;
     Property FPMakeCompilerConfig : String Index 9 Read GetOptString Write SetOptString;
     Property Downloader: String Index 10 Read GetOptString Write SetOptString;
+    Property CustomFPMakeOptions: String Index 11 Read GetOptString Write SetOptString;
     // Parameters
     Property CompilerConfig : String Read FCompilerConfig Write FCompilerConfig;
     Property InstallGlobal : Boolean Read FInstallGlobal Write FInstallGlobal;
     Property RecoveryMode : Boolean Read FRecoveryMode Write FRecoveryMode;
     Property AllowBroken : Boolean Read FAllowBroken Write FAllowBroken;
     Property ShowLocation : Boolean Read FShowLocation Write FShowLocation;
+    Property SkipConfigurationFiles: boolean read FSkipConfigurationFiles write FSkipConfigurationFiles;
   end;
 
 
@@ -89,15 +94,19 @@ Type
 
   TCompilerOptions = Class(TPersistent)
   private
-    FDirty: Boolean;
+    FSaveInifileChanges: Boolean;
     FConfigVersion : Integer;
     FCompiler,
     FCompilerVersion,
     FLocalInstallDir,
-    FGlobalInstallDir : String;
+    FGlobalInstallDir,
+    FLocalPrefix,
+    FGlobalPrefix: String;
     FCompilerCPU: TCPU;
     FCompilerOS: TOS;
     FOptionParser: TTemplateParser;
+    FOptions: TStrings;
+    function GetOptions: TStrings;
     function GetOptString(Index: integer): String;
     procedure SetOptString(Index: integer; const AValue: String);
     procedure SetCompilerCPU(const AValue: TCPU);
@@ -110,9 +119,12 @@ Type
     Procedure SaveCompilerToFile(const AFileName : String);
     procedure LogValues(const ACfgName:string);
     procedure UpdateLocalRepositoryOption;
+    procedure CheckCompilerValues;
     Function LocalUnitDir:string;
     Function GlobalUnitDir:string;
-    Property Dirty : Boolean Read FDirty;
+    Function HasOptions: boolean;
+    // Is set when the inifile has an old version number (which is also the case when a new file is generated)
+    Property SaveInifileChanges : Boolean Read FSaveInifileChanges;
     Property ConfigVersion : Integer read FConfigVersion;
   Published
     Property Compiler : String Index 1 Read GetOptString Write SetOptString;
@@ -120,6 +132,9 @@ Type
     Property CompilerVersion : String Index 3 Read GetOptString Write SetOptString;
     Property GlobalInstallDir : String Index 4 Read GetOptString Write SetOptString;
     Property LocalInstallDir : String Index 5 Read GetOptString Write SetOptString;
+    Property GlobalPrefix : String Index 6 Read GetOptString Write SetOptString;
+    Property LocalPrefix : String Index 7 Read GetOptString Write SetOptString;
+    Property Options : TStrings read GetOptions;
     Property CompilerOS : TOS Read FCompilerOS Write SetCompilerOS;
     Property CompilerCPU : TCPU Read FCompilerCPU Write SetCompilerCPU;
   end;
@@ -160,8 +175,11 @@ Const
   KeyCompilerConfig        = 'CompilerConfig';
   KeyFPMakeCompilerConfig  = 'FPMakeCompilerConfig';
   KeyDownloader            = 'Downloader';
+  KeyCustomFPMakeOptions   = 'FPMakeOptions';
 
   // Compiler dependent config
+  KeyGlobalPrefix          = 'GlobalPrefix';
+  KeyLocalPrefix           = 'LocalPrefix';
   KeyGlobalInstallDir      = 'GlobalInstallDir';
   KeyLocalInstallDir       = 'LocalInstallDir';
   KeyCompiler              = 'Compiler' ;
@@ -201,6 +219,7 @@ begin
     8 : Result:=FDefaultCompilerConfig;
     9 : Result:=FFPMakeCompilerConfig;
    10 : Result:=FDownloader;
+   11 : Result:=FCustomFPMakeOptions;
     else
       Error('Unknown option');
   end;
@@ -222,11 +241,11 @@ begin
     6 : FCompilerConfigDir:=FixPath(AValue);
     8 : FDefaultCompilerConfig:=AValue;
     9 : FFPMakeCompilerConfig:=AValue;
-   10 : FDownloader:=AValue;
+    10 : FDownloader:=AValue;
+    11 : FCustomFPMakeOptions:=AValue;
     else
       Error('Unknown option');
   end;
-  FDirty:=True;
 end;
 
 
@@ -308,7 +327,7 @@ begin
         if (FConfigVersion<>CurrentConfigVersion) then
           begin
             Log(vlDebug,SLogUpgradingConfig,[AFileName]);
-            FDirty:=true;
+            FSaveInifileChanges:=true;
             if FConfigVersion<1 then
               begin
                 FRemoteRepository:='auto';
@@ -333,6 +352,7 @@ begin
         FDefaultCompilerConfig:=ReadString(SDefaults,KeyCompilerConfig,FDefaultCompilerConfig);
         FFPMakeCompilerConfig:=ReadString(SDefaults,KeyFPMakeCompilerConfig,FFPMakeCompilerConfig);
         FDownloader:=ReadString(SDefaults,KeyDownloader,FDownloader);
+        FCustomFPMakeOptions:=ReadString(SDefaults,KeyCustomFPMakeOptions,FCustomFPMakeOptions);
       end;
   finally
     Ini.Free;
@@ -360,7 +380,7 @@ begin
         WriteString(SDefaults,KeyCompilerConfig,FDefaultCompilerConfig);
         WriteString(SDefaults,KeyFPMakeCompilerConfig,FFPMakeCompilerConfig);
         WriteString(SDefaults,KeyDownloader,FDownloader);
-        FDirty:=False;
+        FSaveInifileChanges:=False;
       end;
     Ini.UpdateFile;
   finally
@@ -398,6 +418,8 @@ end;
 destructor TCompilerOptions.Destroy;
 begin
   FOptionParser.Free;
+  if assigned(FOptions) then
+    FreeAndNil(FOptions);
   inherited Destroy;
 end;
 
@@ -410,11 +432,24 @@ begin
     3 : Result:=FCompilerVersion;
     4 : Result:=FOptionParser.ParseString(FGlobalInstallDir);
     5 : Result:=FOptionParser.ParseString(FLocalInstallDir);
+    6 : Result:=FixPath(FOptionParser.ParseString(FGlobalPrefix));
+    7 : Result:=FixPath(FOptionParser.ParseString(FLocalPrefix));
     else
       Error('Unknown option');
   end;
 end;
 
+function TCompilerOptions.GetOptions: TStrings;
+begin
+  if not assigned(FOptions) then
+    begin
+      FOptions := TStringList.Create;
+      FOptions.Delimiter:=' ';
+    end;
+  Result := FOptions;
+end;
+
+
 procedure TCompilerOptions.SetOptString(Index: integer; const AValue: String);
 begin
   If AValue=GetOptString(Index) then
@@ -425,10 +460,17 @@ begin
     3 : FCompilerVersion:=AValue;
     4 : FGlobalInstallDir:=FixPath(AValue);
     5 : FLocalInstallDir:=FixPath(AValue);
+    6 : begin
+          FGlobalPrefix:=AValue;
+          FOptionParser.Values['GlobalPrefix'] := GlobalPrefix;
+        end;
+    7 : begin
+          FLocalPrefix:=AValue;
+          FOptionParser.Values['LocalPrefix'] := LocalPrefix;
+        end
     else
       Error('Unknown option');
   end;
-  FDirty:=True;
 end;
 
 
@@ -437,7 +479,6 @@ begin
   if FCompilerCPU=AValue then
     exit;
   FCompilerCPU:=AValue;
-  FDirty:=True;
 end;
 
 
@@ -446,85 +487,127 @@ begin
   FOptionParser.Values['LocalRepository'] := GlobalOptions.LocalRepository;
 end;
 
+procedure TCompilerOptions.CheckCompilerValues;
+var
+  AVersion : string;
+  ACpu     : TCpu;
+  AOs      : TOS;
+begin
+  if Compiler='' then
+    Exit;
+  if (CompilerCPU=cpuNone) or
+   (CompilerOS=osNone) or
+   (CompilerVersion='') then
+  begin
+    GetCompilerInfo(Compiler,'-iVTPTO',AVersion,ACpu,AOs);
+    if CompilerCPU=cpuNone then
+      CompilerCPU := ACpu;
+    if CompilerOS=osNone then
+      CompilerOS:=AOs;
+    if CompilerVersion='' then
+      CompilerVersion:=AVersion;
+  end;
+end;
+
 
 procedure TCompilerOptions.SetCompilerOS(const AValue: TOS);
 begin
   if FCompilerOS=AValue then
     exit;
   FCompilerOS:=AValue;
-  FDirty:=True;
 end;
 
 
 function TCompilerOptions.LocalUnitDir:string;
+var ALocalInstallDir: string;
 begin
   if LocalInstallDir<>'' then
-    result:=LocalInstallDir+'units'+PathDelim+CompilerTarget+PathDelim
+    ALocalInstallDir:=LocalInstallDir
+  else if LocalPrefix<>'' then
+{$ifdef unix}
+    ALocalInstallDir:=LocalPrefix+'lib'+PathDelim+'fpc'+PathDelim+FCompilerVersion+PathDelim;
+{$else unix}
+    ALocalInstallDir:=LocalPrefix;
+{$endif}
+
+  if ALocalInstallDir<>'' then
+    result:=ALocalInstallDir+'units'+PathDelim+CompilerTarget+PathDelim
   else
     result:='';
 end;
 
 
 function TCompilerOptions.GlobalUnitDir:string;
+var AGlobalInstallDir: string;
 begin
   if GlobalInstallDir<>'' then
-    result:=GlobalInstallDir+'units'+PathDelim+CompilerTarget+PathDelim
+    AGlobalInstallDir:=GlobalInstallDir
+  else if GlobalPrefix<>'' then
+{$ifdef unix}
+    AGlobalInstallDir:=GlobalPrefix+'lib'+PathDelim+'fpc'+PathDelim+FCompilerVersion+PathDelim;
+{$else unix}
+    AGlobalInstallDir:=GlobalPrefix;
+{$endif}
+
+  if AGlobalInstallDir<>'' then
+    result:=AGlobalInstallDir+'units'+PathDelim+CompilerTarget+PathDelim
   else
     result:='';
 end;
 
 
+function TCompilerOptions.HasOptions: boolean;
+begin
+  result := assigned(FOptions);
+end;
+
+
 procedure TCompilerOptions.InitCompilerDefaults;
 
-var
-  infoSL : TStringList;
 begin
   FConfigVersion:=CurrentConfigVersion;
-  FCompiler:=ExeSearch('fpc'+ExeExt,GetEnvironmentVariable('PATH'));
+  if fcompiler = '' then
+    FCompiler:=ExeSearch('fpc'+ExeExt,GetEnvironmentVariable('PATH'));
   if FCompiler='' then
     Raise EPackagerError.Create(SErrMissingFPC);
   // Detect compiler version/target from -i option
-  infosl:=TStringList.Create;
-  infosl.Delimiter:=' ';
-  infosl.DelimitedText:=GetCompilerInfo(FCompiler,'-iVTPTO');
-  if infosl.Count<>3 then
-    Raise EPackagerError.Create(SErrInvalidFPCInfo);
-  FCompilerVersion:=infosl[0];
-  FCompilerCPU:=StringToCPU(infosl[1]);
-  FCompilerOS:=StringToOS(infosl[2]);
+  GetCompilerInfo(FCompiler,'-iVTPTO',FCompilerVersion,FCompilerCPU,FCompilerOS);
   // Temporary hack to workaround bug in fpc.exe that doesn't support spaces
   // We retrieve the real binary
   if FCompilerVersion='2.2.0' then
     FCompiler:=GetCompilerInfo(FCompiler,'-PB');
   Log(vlDebug,SLogDetectedCompiler,[FCompiler,FCompilerVersion,MakeTargetString(FCompilerCPU,FCompilerOS)]);
+
   // Use the same algorithm as the compiler, see options.pas
+  // Except that the prefix is extracted and GlobalInstallDir is set using
+  // that prefix
 {$ifdef Unix}
-  FGlobalInstallDir:=FixPath(GetEnvironmentVariable('FPCDIR'));
-  if FGlobalInstallDir='' then
-    begin
-      FGlobalInstallDir:='/usr/local/lib/fpc/'+FCompilerVersion+'/';
-      if not DirectoryExists(FGlobalInstallDir) and
-         DirectoryExists('/usr/lib/fpc/'+FCompilerVersion) then
-        FGlobalInstallDir:='/usr/lib/fpc/'+FCompilerVersion+'/';
-    end;
+  FGlobalPrefix:='/usr/local/';
+  if not DirectoryExists(FGlobalPrefix+'lib/fpc/'+FCompilerVersion+'/') and
+     DirectoryExists('/usr/lib/fpc/'+FCompilerVersion+'/') then
+    FGlobalPrefix:='/usr/';
 {$else unix}
-  FGlobalInstallDir:=FixPath(GetEnvironmentVariable('FPCDIR'));
-  if FGlobalInstallDir='' then
-    begin
-      FGlobalInstallDir:=ExtractFilePath(FCompiler)+'../';
-      if not(DirectoryExists(FGlobalInstallDir+'/units')) and
-         not(DirectoryExists(FGlobalInstallDir+'/rtl')) then
-        FGlobalInstallDir:=FGlobalInstallDir+'../';
-    end;
-  FGlobalInstallDir:=ExpandFileName(FGlobalInstallDir);
+  FGlobalPrefix:=ExtractFilePath(FCompiler)+'..'+PathDelim;
+  if not(DirectoryExists(FGlobalPrefix+PathDelim+'units')) and
+     not(DirectoryExists(FGlobalPrefix+PathDelim+'rtl')) then
+    FGlobalPrefix:=FGlobalPrefix+'..'+PathDelim;
+  FGlobalPrefix:=ExpandFileName(FGlobalInstallDir);
 {$endif unix}
-  Log(vlDebug,SLogDetectedFPCDIR,['global',FGlobalInstallDir]);
+
+  Log(vlDebug,SLogDetectedPrefix,['global',FGlobalPrefix]);
   // User writable install directory
   if not IsSuperUser then
     begin
-      FLocalInstallDir:= '{LocalRepository}lib'+ PathDelim + FCompilerVersion+PathDelim;
-      Log(vlDebug,SLogDetectedFPCDIR,['local',FLocalInstallDir]);
+      FLocalPrefix:= '{LocalRepository}';
+      Log(vlDebug,SLogDetectedPrefix,['local',FLocalPrefix]);
     end;
+
+  FGlobalInstallDir:=FixPath(GetEnvironmentVariable('FPCDIR'));
+{$ifndef Unix}
+  FGlobalInstallDir:=ExpandFileName(FGlobalInstallDir);
+{$endif unix}
+  if FGlobalInstallDir<>'' then
+    Log(vlDebug,SLogFPCDirEnv,[FGlobalInstallDir]);
 end;
 
 
@@ -540,10 +623,12 @@ begin
         if (FConfigVersion<>CurrentConfigVersion) then
           begin
             Log(vlDebug,SLogUpgradingConfig,[AFileName]);
-            FDirty:=true;
+            FSaveInifileChanges:=true;
             if (FConfigVersion>CurrentConfigVersion) then
               Error(SErrUnsupportedConfigVersion,[AFileName]);
           end;
+        GlobalPrefix:=ReadString(SDefaults,KeyGlobalPrefix,FGlobalPrefix);
+        LocalPrefix:=ReadString(SDefaults,KeyLocalPrefix,FLocalPrefix);
         FGlobalInstallDir:=FixPath(ReadString(SDefaults,KeyGlobalInstallDir,FGlobalInstallDir));
         FLocalInstallDir:=FixPath(ReadString(SDefaults,KeyLocalInstallDir,FLocalInstallDir));
         FCompiler:=ReadString(SDefaults,KeyCompiler,FCompiler);
@@ -568,13 +653,15 @@ begin
     With Ini do
       begin
         WriteInteger(SDefaults,KeyConfigVersion,CurrentConfigVersion);
+        WriteString(SDefaults,KeyGlobalPrefix,FGlobalPrefix);
+        WriteString(SDefaults,KeyLocalPrefix,FLocalPrefix);
         WriteString(SDefaults,KeyGlobalInstallDir,FGlobalInstallDir);
         WriteString(SDefaults,KeyLocalInstallDir,FLocalInstallDir);
         WriteString(SDefaults,KeyCompiler,FCompiler);
         WriteString(SDefaults,KeyCompilerOS,OSToString(CompilerOS));
         WriteString(SDefaults,KeyCompilerCPU,CPUtoString(CompilerCPU));
         WriteString(SDefaults,KeyCompilerVersion,FCompilerVersion);
-        FDirty:=False;
+        FSaveInifileChanges:=False;
       end;
     Ini.UpdateFile;
   finally
@@ -591,6 +678,8 @@ begin
   Log(vlDebug,SLogCompilerCfgVersion,[FCompilerVersion]);
   Log(vlDebug,SLogCompilerCfgGlobalInstallDir,[GlobalInstallDir]);
   Log(vlDebug,SLogCompilerCfgLocalInstallDir,[LocalInstallDir]);
+  Log(vlDebug,SLogCompilerCfgGlobalPrefix,[GlobalPrefix]);
+  Log(vlDebug,SLogCompilerCfgLocalPrefix,[LocalPrefix]);
 end;
 
 

Some files were not shown because too many files changed in this diff