From 3c1c879cf5d0602bf55989633f9fa2803f2aae5c Mon Sep 17 00:00:00 2001 From: Juha Date: Fri, 15 Mar 2024 14:36:28 +0200 Subject: [PATCH] IDE: Separate parsed compiler options code to a new unit ParsedCompilerOpts. --- converter/convertdelphi.pas | 2 +- ide/buildlazdialog.pas | 6 +- ide/buildmanager.pas | 10 +- ide/buildmodesmanager.pas | 2 +- ide/checkcompileropts.pas | 2 +- ide/compileroptions.pp | 882 +------------------- ide/frames/compiler_buildmacro_options.pas | 2 +- ide/frames/compiler_other_options.pas | 4 +- ide/frames/compiler_path_options.pas | 2 +- ide/main.pp | 4 +- ide/parsedcompileropts.pas | 897 +++++++++++++++++++++ ide/project.pp | 2 +- ide/showcompileropts.pas | 6 +- ide/sourcefilemanager.pas | 2 +- packager/interpkgconflictfiles.pas | 2 +- packager/packagedefs.pas | 9 +- packager/packageeditor.pas | 2 +- packager/packagesystem.pas | 2 +- packager/pkgmanager.pas | 2 +- 19 files changed, 932 insertions(+), 908 deletions(-) create mode 100644 ide/parsedcompileropts.pas diff --git a/converter/convertdelphi.pas b/converter/convertdelphi.pas index 071e78da20..425207c034 100644 --- a/converter/convertdelphi.pas +++ b/converter/convertdelphi.pas @@ -48,7 +48,7 @@ uses // IdeConfig IDEProcs, // IDE - DialogProcs, CompilerOptions, ProjPackCommon, Project, + DialogProcs, ParsedCompilerOpts, CompilerOptions, ProjPackCommon, Project, PackageDefs, PackageSystem, PackageEditor, BasePkgManager, LazarusIDEStrConsts, SearchPathProcs, SourceFileManager, // Converter diff --git a/ide/buildlazdialog.pas b/ide/buildlazdialog.pas index e4f139dde5..ee83d52ef2 100644 --- a/ide/buildlazdialog.pas +++ b/ide/buildlazdialog.pas @@ -62,9 +62,9 @@ uses // IdeConfig EnvironmentOpts, LazConf, TransferMacros, // IDE - LazarusIDEStrConsts, DialogProcs, MainBar, - ApplicationBundle, ModeMatrixOpts, CompilerOptions, BuildProfileManager, - GenericListEditor, GenericCheckList, PackageSystem, PackageDefs; + LazarusIDEStrConsts, DialogProcs, MainBar, ApplicationBundle, ModeMatrixOpts, + ParsedCompilerOpts, CompilerOptions, BuildProfileManager, GenericListEditor, + GenericCheckList, PackageSystem, PackageDefs; type diff --git a/ide/buildmanager.pas b/ide/buildmanager.pas index cd8c6a693d..2cc7bc5385 100644 --- a/ide/buildmanager.pas +++ b/ide/buildmanager.pas @@ -55,7 +55,7 @@ uses IDEProcs, // IDE LazarusIDEStrConsts, DialogProcs, - EditDefineTree, ProjectResources, MiscOptions, CompilerOptions, + EditDefineTree, ProjectResources, MiscOptions, ParsedCompilerOpts, CompilerOptions, ExtTools, etMakeMsgParser, etFPCMsgParser, etPas2jsMsgParser, Compiler, FPCSrcScan, PackageDefs, PackageSystem, Project, ProjectIcon, BaseBuildManager, ApplicationBundle, RunParamsOpts, IdeTransferMacros, SearchPathProcs; @@ -190,7 +190,7 @@ type DefaultCfgVarsBuildMacroStamp: integer; procedure Notification(AComponent: TComponent; Operation: TOperation); override; - function GetBuildMacroValuesHandler(Options: TBaseCompilerOptions; + function GetBuildMacroValuesHandler(Options: TLazCompilerOptions; IncludeSelf: boolean): TCTCfgScriptVariables; function GetActiveBuildModeName: string; procedure AppendMatrixCustomOption(Sender: TObject; @@ -437,7 +437,7 @@ begin GlobalMacroList:=TTransferMacroList.Create; GlobalMacroList.OnSubstitution:=@MacroSubstitution; IDEMacros:=TLazIDEMacros.Create; - CompilerOptions.OnParseString:=@SubstituteCompilerOption; + OnParseString:=@SubstituteCompilerOption; TIdeTransferMarcros.InitMacros(GlobalMacroList); @@ -2691,7 +2691,7 @@ begin end; end; -function TBuildManager.GetBuildMacroValuesHandler(Options: TBaseCompilerOptions; +function TBuildManager.GetBuildMacroValuesHandler(Options: TLazCompilerOptions; IncludeSelf: boolean): TCTCfgScriptVariables; {off $DEFINE VerboseBuildMacros} @@ -2842,7 +2842,7 @@ var begin Result:=nil; - ParseOpts:=Options.ParsedOpts; + ParseOpts:=TBaseCompilerOptions(Options).ParsedOpts; if ParseOpts=nil then exit; if IncludeSelf then begin diff --git a/ide/buildmodesmanager.pas b/ide/buildmodesmanager.pas index 261c01f33f..2f408ee856 100644 --- a/ide/buildmodesmanager.pas +++ b/ide/buildmodesmanager.pas @@ -42,7 +42,7 @@ uses // IdeConfig EnvironmentOpts, TransferMacros, SearchPathProcs, // IDE - MainBase, MainBar, BasePkgManager, PackageDefs, Project, CompilerOptions, + MainBase, MainBar, BasePkgManager, PackageDefs, Project, ParsedCompilerOpts, CompilerOptions, BaseBuildManager, Compiler_ModeMatrix, BuildModeDiffDlg, GenericCheckList, LazarusIDEStrConsts; diff --git a/ide/checkcompileropts.pas b/ide/checkcompileropts.pas index e83501a366..4c30e75821 100644 --- a/ide/checkcompileropts.pas +++ b/ide/checkcompileropts.pas @@ -45,7 +45,7 @@ uses // IdeConfig TransferMacros, SearchPathProcs, IDEProcs, // IDE - Project, PackageSystem, LazarusIDEStrConsts, PackageDefs, CompilerOptions; + Project, PackageSystem, LazarusIDEStrConsts, PackageDefs, ParsedCompilerOpts, CompilerOptions; type TCompilerOptionsTest = ( diff --git a/ide/compileroptions.pp b/ide/compileroptions.pp index ebfbaebb2c..dcc4811dbf 100644 --- a/ide/compileroptions.pp +++ b/ide/compileroptions.pp @@ -45,7 +45,7 @@ uses Classes, SysUtils, AVL_Tree, System.UITypes, // LazUtils FileUtil, LazFileUtils, LazUTF8, Laz2_XMLCfg, Laz2_DOM, LazUtilities, LazTracer, - LazStringUtils, FPCAdds, LazVersion, + LazStringUtils, FPCAdds, // CodeTools FileProcs, DefineTemplates, CodeToolsCfgScript, CodeToolManager, KeywordFuncLists, BasicCodeTools, LinkScanner, DirectoryCacher, @@ -57,7 +57,7 @@ uses LazConf, EnvironmentOpts, SearchPathProcs, IdeXmlConfigProcs, TransferMacros, IDEProcs, ModeMatrixOpts, CompOptsModes, // IDE - LazarusIDEStrConsts, etFPCMsgParser; + etFPCMsgParser, ParsedCompilerOpts; const DefaultCompilerPath = '$(CompPath)'; @@ -70,8 +70,6 @@ type ccomlNone ); - TIDEBuildMacros = class; - { TIDEBuildMacro } TIDEBuildMacro = class(TLazBuildMacro) @@ -138,195 +136,17 @@ const +'//end;' ; -type - - { TIDECfgScriptEngine } - - TIDECfgScriptEngine = class(TCTConfigScriptEngine) - private - FProjValuesAvailable: boolean; - protected - function IsCustomFunction(FunctionName: PChar): boolean; override; - procedure RunCustomSimpleFunction(FunctionName: PChar; - Value: PCTCfgScriptVariable); override; - public - property ProjValuesAvailable: boolean read FProjValuesAvailable write FProjValuesAvailable; - end; - -type - TInheritedCompilerOption = ( - icoNone, - icoUnitPath, - icoNamespaces, - icoIncludePath, - icoObjectPath, - icoLibraryPath, - icoSrcPath, - icoLinkerOptions, - icoCustomOptions - ); - TInheritedCompilerOptions = set of TInheritedCompilerOption; - - TInheritedCompOptsStrings = array[TInheritedCompilerOption] of string; - const - icoAllSearchPaths = [icoUnitPath,icoIncludePath,icoObjectPath,icoLibraryPath, - icoSrcPath]; - -type - { TParsedCompilerOptions } - - TParsedCompilerOptString = ( - pcosNone, - pcosBaseDir, // the base directory for the relative paths (only auto created packages can have macros in the BaseDir) - pcosUnitPath, // search path for pascal units - pcosNamespaces, // namespaces - pcosIncludePath, // search path for pascal include files - pcosObjectPath, // search path for .o files - pcosLibraryPath, // search path for libraries - pcosSrcPath, // additional search path for pascal source files - pcosLinkerOptions,// additional linker options - pcosCustomOptions,// additional options - pcosOutputDir, // the output directory - pcosCompilerPath, // the filename of the compiler - pcosDebugPath, // additional debug search path - pcosMsgFile, // fpc message file (errore.msg) - pcosCustomConfigFilePath, // additional custom config file - pcosWriteConfigFilePath // auto generated cfg file - ); - TParsedCompilerOptStrings = set of TParsedCompilerOptString; - - -const - ParsedCompilerSearchPaths = [pcosUnitPath,pcosIncludePath,pcosObjectPath, - pcosLibraryPath,pcosSrcPath,pcosDebugPath]; - ParsedCompilerExecutables = [pcosCompilerPath]; - ParsedCompilerFilenames = ParsedCompilerExecutables+[pcosMsgFile, - pcosCustomConfigFilePath,pcosWriteConfigFilePath]; - ParsedCompilerDirectories = [pcosOutputDir]; - ParsedCompilerOutDirectories = [pcosOutputDir]; - ParsedCompilerFiles = - ParsedCompilerSearchPaths+ParsedCompilerFilenames+ParsedCompilerDirectories; - - ParsedCompilerOptsVars: array[TParsedCompilerOptString] of string = ( - '', // pcosNone - '', // pcosBaseDir - 'UnitPath', - 'Namespaces', - 'IncPath', - 'ObjectPath', - 'LibraryPath', - 'SrcPath', - 'LinkerOptions', - 'CustomOptions', - 'OutputDir', - 'CompilerPath', - 'DebugPath', - 'MsgFile', - 'CustomConfigFile', - 'WriteCfgFile' - ); - ParsedCompilerOptsUsageVars: array[TParsedCompilerOptString] of string = ( - '', // pcosNone - '', // pcosBaseDir - 'UsageUnitPath', - 'UsageNamespaces', - 'UsageIncPath', - 'UsageObjectPath', - 'UsageLibraryPath', - 'UsageSrcPath', - 'UsageLinkerOptions', - 'UsageCustomOptions', - '', // pcosOutputDir - '', // pcosCompilerPath - 'UsageDebugPath', // pcosDebugPath - '', // pcosMsgFile - '', - '' // pcosWriteConfigFilePath - ); - InheritedToParsedCompilerOption: array[TInheritedCompilerOption] of - TParsedCompilerOptString = ( - pcosNone, - pcosUnitPath, // icoUnitPath, - pcosNamespaces, // icoNamespaces, - pcosIncludePath, // icoIncludePath, - pcosObjectPath, // icoObjectPath, - pcosLibraryPath, // icoLibraryPath, - pcosSrcPath, // icoSrcPath, - pcosLinkerOptions, // icoLinkerOptions, - pcosCustomOptions // icoCustomOptions - ); - CompilerOptionMacroNormal = 0; CompilerOptionMacroPlatformIndependent = 1; type - TLocalSubstitutionEvent = function(s: string; - PlatformIndependent: boolean): string of object; + //TLocalSubstitutionEvent = function(s: string; + // PlatformIndependent: boolean): string of object; TInheritedCompOptsParseTypesStrings = array[TCompilerOptionsParseType] of TInheritedCompOptsStrings; - { TParsedCompilerOptions } - - TParsedCompilerOptions = class - private - FInvalidateParseOnChange: boolean; - FOnLocalSubstitute: TLocalSubstitutionEvent; - FOutputDirectoryOverride: string; - FOwner: TObject; - procedure SetOutputDirectoryOverride(const AValue: string); - public - // parsed - Values: array[TParsedCompilerOptString] of TParseString; - ParsedErrorOption: TParsedCompilerOptString; - ParsedErrorMsg: string; - ParsedErrorStamp: integer; // see CompilerParseStamp - // parsed except for platform macros - ParsedPIValues: array[TParsedCompilerOptString] of string; - ParsedPIStamp: array[TParsedCompilerOptString] of integer; // see CompilerParseStamp - ParsingPI: array[TParsedCompilerOptString] of boolean; - // macro values - InheritedMacroValues: TCTCfgScriptVariables; - InheritedMacroValuesStamp: integer; // see BuildMacroChangeStamp - InheritedMacroValuesParsing: boolean; - MacroValues: TIDECfgScriptEngine; - MacroValuesStamp: integer; // see BuildMacroChangeStamp - MacroValuesParsing: boolean; - constructor Create(TheOwner: TObject); - destructor Destroy; override; - function HasParsedError: boolean; - procedure ParsedError(Option: TParsedCompilerOptString; Msg: string); - function GetUnparsedWithConditionals(Option: TParsedCompilerOptString): string; - function GetParsedValue(Option: TParsedCompilerOptString; - WithOverrides: boolean = true): string; - function GetParsedPIValue(Option: TParsedCompilerOptString): string;// platform independent - procedure SetUnparsedValue(Option: TParsedCompilerOptString; - const NewValue: string); - function DoParseOption(OptionText: string; - Option: TParsedCompilerOptString; - PlatformIndependent: boolean): string; - procedure Assign(Src: TParsedCompilerOptions); - procedure Clear; - procedure InvalidateAll; - procedure InvalidateFiles; - procedure RenameMacro(const OldName, NewName: string; - out Changed: TParsedCompilerOptStrings); // rename macro in UnparsedValues - public - property Owner: TObject read FOwner; - property OnLocalSubstitute: TLocalSubstitutionEvent read FOnLocalSubstitute - write FOnLocalSubstitute; - property InvalidateParseOnChange: boolean read FInvalidateParseOnChange - write FInvalidateParseOnChange; - property OutputDirectoryOverride: string read FOutputDirectoryOverride - write SetOutputDirectoryOverride; - end; - - TParseStringEvent = - function(Options: TParsedCompilerOptions; - const UnparsedValue: string; PlatformIndependent: boolean - ): string of object; - { TBaseCompilerOptions } @@ -581,60 +401,6 @@ type TBaseCompilerOptionsClass = class of TBaseCompilerOptions; - { TAdditionalCompilerOptions - - Additional Compiler options are used by packages to define, what a project - or a package or the IDE needs to use the package. - } - TAdditionalCompilerOptions = class - private - fOwner: TObject; - FParsedOpts: TParsedCompilerOptions; - protected - function GetBaseDirectory: string; - function GetCustomOptions: string; virtual; - function GetIncludePath: string; virtual; - function GetLibraryPath: string; virtual; - function GetLinkerOptions: string; virtual; - function GetNamespaces: string; virtual; - function GetObjectPath: string; virtual; - function GetSrcPath: string; virtual; - function GetUnitPath: string; virtual; - procedure SetBaseDirectory(const AValue: string); virtual; - procedure SetCustomOptions(const AValue: string); virtual; - procedure SetIncludePath(const AValue: string); virtual; - procedure SetLibraryPath(const AValue: string); virtual; - procedure SetLinkerOptions(const AValue: string); virtual; - procedure SetNamespaces(const AValue: string); virtual; - procedure SetObjectPath(const AValue: string); virtual; - procedure SetSrcPath(const AValue: string); virtual; - procedure SetUnitPath(const AValue: string); virtual; - public - constructor Create(TheOwner: TObject); - destructor Destroy; override; - procedure Clear; - procedure AssignOptions(Source: TObject); virtual; - procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string; - AdjustPathDelims: boolean); - procedure SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string; - UsePathDelim: TPathDelimSwitch); - function GetOwnerName: string; virtual; - function GetOption(AnOption: TInheritedCompilerOption): string; - function GetBaseCompilerOptions: TBaseCompilerOptions; virtual; - public - property Owner: TObject read fOwner; - property UnitPath: string read GetUnitPath write SetUnitPath; - property Namespaces: string read GetNamespaces write SetNamespaces; - property IncludePath: string read GetIncludePath write SetIncludePath; - property SrcPath: string read GetSrcPath write SetSrcPath; - property ObjectPath: string read GetObjectPath write SetObjectPath; - property LibraryPath: string read GetLibraryPath write SetLibraryPath; - property LinkerOptions: string read GetLinkerOptions write SetLinkerOptions; - property CustomOptions: string read GetCustomOptions write SetCustomOptions; - property BaseDirectory: string read GetBaseDirectory write SetBaseDirectory; - property ParsedOpts: TParsedCompilerOptions read FParsedOpts; - end; - { TCompilerOptions } @@ -647,13 +413,6 @@ const 'Run' ); -var - OnParseString: TParseStringEvent = nil; - -function EnumToStr(opt: TParsedCompilerOptString): string; overload; -function ParseString(Options: TParsedCompilerOptions; - const UnparsedValue: string; - PlatformIndependent: boolean): string; function GetMakefileMacroValue(const MacroName: string): string; function TargetNeedsFPCOptionCG(TargetOS, TargetCPU: string): boolean; @@ -663,23 +422,9 @@ procedure GatherInheritedOptions(AddOptionsList: TFPList; function InheritedOptionsToCompilerParameters( var InheritedOptionStrings: TInheritedCompOptsStrings; Flags: TCompilerCmdLineOptions): string; -function MergeLinkerOptions(const OldOptions, AddOptions: string): string; -function MergeCustomOptions(const OldOptions, AddOptions: string): string; procedure ConvertSearchPathToCmdParams(const Switch, Paths, BasePath: String; Params: TStrings); procedure ConvertOptionsToCmdParams(const Switch, OptionStr: string; Params: TStrings); -type - TGetBuildMacroValues = function(Options: TBaseCompilerOptions; - IncludeSelf: boolean): TCTCfgScriptVariables of object; - TOnAppendCustomOptions = procedure(Sender: TObject; - var CustomOptions: string; Types: TBuildMatrixGroupTypes) of object; - TOnGetOutputDirectoryOverride = procedure(Sender: TObject; - var OutDir: string; Types: TBuildMatrixGroupTypes) of object; -var - GetBuildMacroValues: TGetBuildMacroValues = nil; // set by TPkgManager, do not change or free the variables - OnAppendCustomOption: TOnAppendCustomOptions = nil; // set by MainBuildBoss - OnGetOutputDirectoryOverride: TOnGetOutputDirectoryOverride = nil; // set by MainBuildBoss - function LoadXMLCompileReasons(const AConfig: TXMLConfig; const APath: String; const DefaultReasons: TCompileReasons): TCompileReasons; procedure SaveXMLCompileReasons(const AConfig: TXMLConfig; const APath: String; @@ -699,18 +444,6 @@ const // 7 TargetProcessor/Value // 6 SyntaxMode/Value -function EnumToStr(opt: TParsedCompilerOptString): string; -begin - Result:=''; - WriteStr(Result, opt); -end; - -function ParseString(Options: TParsedCompilerOptions; - const UnparsedValue: string; PlatformIndependent: boolean): string; -begin - Result:=OnParseString(Options,UnparsedValue,PlatformIndependent); -end; - function GetMakefileMacroValue(const MacroName: string): string; begin if SysUtils.CompareText('TargetCPU',MacroName)=0 then @@ -906,21 +639,6 @@ begin end; end; -function MergeLinkerOptions(const OldOptions, AddOptions: string): string; -begin - Result:=MergeCustomOptions(OldOptions,AddOptions); -end; - -function MergeCustomOptions(const OldOptions, AddOptions: string): string; -begin - Result:=OldOptions; - if AddOptions='' then exit; - if (OldOptions<>'') and (OldOptions[length(OldOptions)]<>' ') - and (AddOptions[1]<>' ') then - Result+=' '; - Result+=AddOptions; -end; - procedure ConvertSearchPathToCmdParams(const Switch, Paths, BasePath: String; Params: TStrings); var @@ -1070,64 +788,6 @@ begin Result:=FCurrent<>nil; end; -{ TIDECfgScriptEngine } - -function TIDECfgScriptEngine.IsCustomFunction(FunctionName: PChar): boolean; -begin - case UpChars[FunctionName^] of - 'G': - if (CompareIdentifiers(FunctionName,'GetIDEValue')=0) - or (CompareIdentifiers(FunctionName,'GetEnv')=0) - or (ProjValuesAvailable and (CompareIdentifiers(FunctionName,'GetProjValue')=0)) - then exit(true); - end; - Result:=false; -end; - -procedure TIDECfgScriptEngine.RunCustomSimpleFunction(FunctionName: PChar; - Value: PCTCfgScriptVariable); -var - VarName: String; - s: String; -begin - case UpChars[FunctionName^] of - 'G': - if (CompareIdentifiers(FunctionName,'GetIDEValue')=0) then - begin - VarName:=GetCTCSVariableAsString(Value); - if CompareIdentifiers(PChar(VarName),'OS')=0 then - SetCTCSVariableAsString(Value,FPCAdds.GetCompiledTargetOS) - else if CompareIdentifiers(PChar(VarName),'CPU')=0 then - SetCTCSVariableAsString(Value,FPCAdds.GetCompiledTargetCPU) - else if CompareIdentifiers(PChar(VarName),'SrcOS')=0 then - SetCTCSVariableAsString(Value,GetDefaultSrcOSForTargetOS(FPCAdds.GetCompiledTargetOS)) - else if CompareIdentifiers(PChar(VarName),'SrcOS2')=0 then - SetCTCSVariableAsString(Value,GetDefaultSrcOS2ForTargetOS(FPCAdds.GetCompiledTargetOS)) - else if CompareIdentifiers(PChar(VarName),'LCLWidgetType')=0 then - SetCTCSVariableAsString(Value,GetLCLWidgetTypeName) - else if CompareIdentifiers(PChar(VarName),'LAZ_FULLVERSION')=0 then - SetCTCSVariableAsNumber(Value,laz_fullversion) - else - ClearCTCSVariable(Value); - end else if (CompareIdentifiers(FunctionName,'GetEnv')=0) then - begin - VarName:=GetCTCSVariableAsString(Value); - SetCTCSVariableAsString(Value,GetEnvironmentVariableUTF8(VarName)); - end else if ProjValuesAvailable - and (CompareIdentifiers(FunctionName,'GetProjValue')=0) then - begin - VarName:=GetCTCSVariableAsString(Value); - if CompareIdentifiers(PChar(VarName),'FPC_FULLVERSION')=0 then - begin - s:='$(FPC_FULLVERSION)'; - GlobalMacroList.SubstituteStr(s); - SetCTCSVariableAsNumber(Value,StrToIntDef(s,0)); - end; - end; - end; -end; - - { TBaseCompilerOptions } // inline @@ -3495,540 +3155,6 @@ begin end; -{ TAdditionalCompilerOptions } - -procedure TAdditionalCompilerOptions.SetCustomOptions(const AValue: string); -begin - ParsedOpts.SetUnparsedValue(pcosCustomOptions,AValue); -end; - -procedure TAdditionalCompilerOptions.SetSrcPath(const AValue: string); -begin - ParsedOpts.SetUnparsedValue(pcosSrcPath,AValue); -end; - -function TAdditionalCompilerOptions.GetUnitPath: string; -begin - Result:=FParsedOpts.Values[pcosUnitPath].UnparsedValue; -end; - -function TAdditionalCompilerOptions.GetIncludePath: string; -begin - Result:=FParsedOpts.Values[pcosIncludePath].UnparsedValue; -end; - -function TAdditionalCompilerOptions.GetBaseDirectory: string; -begin - Result:=FParsedOpts.Values[pcosBaseDir].UnparsedValue; -end; - -function TAdditionalCompilerOptions.GetCustomOptions: string; -begin - Result:=FParsedOpts.Values[pcosCustomOptions].UnparsedValue; -end; - -function TAdditionalCompilerOptions.GetLibraryPath: string; -begin - Result:=FParsedOpts.Values[pcosLibraryPath].UnparsedValue; -end; - -function TAdditionalCompilerOptions.GetLinkerOptions: string; -begin - Result:=FParsedOpts.Values[pcosLinkerOptions].UnparsedValue; -end; - -function TAdditionalCompilerOptions.GetNamespaces: string; -begin - Result:=FParsedOpts.Values[pcosNamespaces].UnparsedValue; -end; - -function TAdditionalCompilerOptions.GetObjectPath: string; -begin - Result:=FParsedOpts.Values[pcosObjectPath].UnparsedValue; -end; - -function TAdditionalCompilerOptions.GetSrcPath: string; -begin - Result:=FParsedOpts.Values[pcosSrcPath].UnparsedValue; -end; - -procedure TAdditionalCompilerOptions.SetBaseDirectory(const AValue: string); -begin - ParsedOpts.SetUnparsedValue(pcosBaseDir,AValue); -end; - -procedure TAdditionalCompilerOptions.SetIncludePath(const AValue: string); -begin - ParsedOpts.SetUnparsedValue(pcosIncludePath,AValue); -end; - -procedure TAdditionalCompilerOptions.SetLibraryPath(const AValue: string); -begin - ParsedOpts.SetUnparsedValue(pcosLibraryPath,AValue); -end; - -procedure TAdditionalCompilerOptions.SetLinkerOptions(const AValue: string); -begin - ParsedOpts.SetUnparsedValue(pcosLinkerOptions,AValue); -end; - -procedure TAdditionalCompilerOptions.SetNamespaces(const AValue: string); -begin - ParsedOpts.SetUnparsedValue(pcosNamespaces,AValue); -end; - -procedure TAdditionalCompilerOptions.SetObjectPath(const AValue: string); -begin - ParsedOpts.SetUnparsedValue(pcosObjectPath,AValue); -end; - -procedure TAdditionalCompilerOptions.SetUnitPath(const AValue: string); -begin - ParsedOpts.SetUnparsedValue(pcosUnitPath,AValue); -end; - -constructor TAdditionalCompilerOptions.Create(TheOwner: TObject); -begin - fOwner:=TheOwner; - FParsedOpts:=TParsedCompilerOptions.Create(Self); - Clear; -end; - -destructor TAdditionalCompilerOptions.Destroy; -begin - FreeThenNil(FParsedOpts); - inherited Destroy; -end; - -procedure TAdditionalCompilerOptions.Clear; -begin - UnitPath:=''; - Namespaces:=''; - SrcPath:=''; - IncludePath:=''; - CustomOptions:=''; - LibraryPath:=''; - LinkerOptions:=''; - ObjectPath:=''; -end; - -procedure TAdditionalCompilerOptions.AssignOptions(Source: TObject); -var - Src: TAdditionalCompilerOptions; -begin - if not (Source is TAdditionalCompilerOptions) then - raise Exception.Create('TAdditionalCompilerOptions.AssignOptions: Can not copy from '+DbgSName(Source)); - Src:=TAdditionalCompilerOptions(Source); - UnitPath:=Src.UnitPath; - Namespaces:=Src.Namespaces; - IncludePath:=Src.IncludePath; - SrcPath:=Src.SrcPath; - ObjectPath:=Src.ObjectPath; - LibraryPath:=Src.LibraryPath; - LinkerOptions:=Src.LinkerOptions; - CustomOptions:=Src.CustomOptions; - BaseDirectory:=Src.BaseDirectory; -end; - -procedure TAdditionalCompilerOptions.LoadFromXMLConfig(XMLConfig: TXMLConfig; - const Path: string; AdjustPathDelims: boolean); - - function f(const Filename: string): string; - begin - Result:=SwitchPathDelims(Filename,AdjustPathDelims); - end; - -begin - Clear; - CustomOptions:=f(XMLConfig.GetValue(Path+'CustomOptions/Value','')); - IncludePath:=f(XMLConfig.GetValue(Path+'IncludePath/Value','')); - LibraryPath:=f(XMLConfig.GetValue(Path+'LibraryPath/Value','')); - LinkerOptions:=f(XMLConfig.GetValue(Path+'LinkerOptions/Value','')); - Namespaces:=f(XMLConfig.GetValue(Path+'Namespaces/Value','')); - ObjectPath:=f(XMLConfig.GetValue(Path+'ObjectPath/Value','')); - UnitPath:=f(XMLConfig.GetValue(Path+'UnitPath/Value','')); - SrcPath:=f(XMLConfig.GetValue(Path+'SrcPath/Value','')); -end; - -procedure TAdditionalCompilerOptions.SaveToXMLConfig(XMLConfig: TXMLConfig; - const Path: string; UsePathDelim: TPathDelimSwitch); - - function f(const AFilename: string): string; - begin - Result:=SwitchPathDelims(AFilename,UsePathDelim); - end; - -begin - XMLConfig.SetDeleteValue(Path+'CustomOptions/Value',f(CustomOptions),''); - XMLConfig.SetDeleteValue(Path+'IncludePath/Value',f(IncludePath),''); - XMLConfig.SetDeleteValue(Path+'LibraryPath/Value',f(LibraryPath),''); - XMLConfig.SetDeleteValue(Path+'LinkerOptions/Value',f(LinkerOptions),''); - XMLConfig.SetDeleteValue(Path+'Namespaces/Value',Namespaces,''); - XMLConfig.SetDeleteValue(Path+'ObjectPath/Value',f(ObjectPath),''); - XMLConfig.SetDeleteValue(Path+'UnitPath/Value',f(UnitPath),''); - XMLConfig.SetDeleteValue(Path+'SrcPath/Value',f(SrcPath),''); -end; - -function TAdditionalCompilerOptions.GetOwnerName: string; -begin - if fOwner<>nil then - Result:=fOwner.Classname - else - Result:='Has no owner'; -end; - -function TAdditionalCompilerOptions.GetOption(AnOption: TInheritedCompilerOption - ): string; -begin - Result:=''; - case AnOption of - icoNone: Result:=''; - icoUnitPath: Result:=UnitPath; - icoNamespaces: Result:=Namespaces; - icoIncludePath: Result:=IncludePath; - icoObjectPath: Result:=ObjectPath; - icoLibraryPath: Result:=LibraryPath; - icoSrcPath: Result:=SrcPath; - icoLinkerOptions: Result:=LinkerOptions; - icoCustomOptions: Result:=CustomOptions; - else - RaiseGDBException(''){%H-}; // inconsistency detected - end; -end; - -function TAdditionalCompilerOptions.GetBaseCompilerOptions: TBaseCompilerOptions; -begin - Result:=nil; -end; - -{ TParsedCompilerOptions } - -procedure TParsedCompilerOptions.SetOutputDirectoryOverride(const AValue: string); -begin - if FOutputDirectoryOverride=AValue then exit; - FOutputDirectoryOverride:=AValue; - if InvalidateParseOnChange then - IncreaseCompilerParseStamp;// the output dir is used by other packages - //if FOutputDirectoryOverride<>'' then - // DebugLn(['TParsedCompilerOptions.SetOutputDirectoryOverride New=',FOutputDirectoryOverride]) - //else - // DebugLn(['TParsedCompilerOptions.SetOutputDirectoryOverride using default']); -end; - -constructor TParsedCompilerOptions.Create(TheOwner: TObject); -begin - FOwner:=TheOwner; - InheritedMacroValues:=TCTCfgScriptVariables.Create; - MacroValues:=TIDECfgScriptEngine.Create; - Clear; -end; - -destructor TParsedCompilerOptions.Destroy; -begin - FreeAndNil(InheritedMacroValues); - FreeAndNil(MacroValues); - inherited Destroy; -end; - -function TParsedCompilerOptions.HasParsedError: boolean; -begin - Result:=(ParsedErrorStamp<>CTInvalidChangeStamp) - and (ParsedErrorStamp=CompilerParseStamp); -end; - -procedure TParsedCompilerOptions.ParsedError(Option: TParsedCompilerOptString; - Msg: string); -begin - if HasParsedError then exit; - ParsedErrorMsg:=Msg; - ParsedErrorOption:=Option; - ParsedErrorStamp:=CompilerParseStamp; -end; - -function TParsedCompilerOptions.GetUnparsedWithConditionals( - Option: TParsedCompilerOptString): string; -var - Opts: TBaseCompilerOptions; - VarName: String; - Vars: TCTCfgScriptVariables; - MoreOptions: String; -begin - Result:=Values[Option].UnparsedValue; - Opts:=nil; - VarName:=''; - if (Owner is TBaseCompilerOptions) then - begin - Opts:=TBaseCompilerOptions(Owner); - VarName:=ParsedCompilerOptsVars[Option]; - end else if (Owner is TAdditionalCompilerOptions) then - begin - Opts:=TAdditionalCompilerOptions(Owner).GetBaseCompilerOptions; - VarName:=ParsedCompilerOptsUsageVars[Option]; - end; - if (VarName='') or (Opts=nil) then exit; - Vars:=GetBuildMacroValues(Opts,true); - if Vars=nil then exit; - case Option of - pcosUnitPath,pcosIncludePath,pcosObjectPath,pcosLibraryPath,pcosSrcPath, - pcosDebugPath: - Result:=MergeSearchPaths(Result,GetForcedPathDelims(Vars[VarName])); - pcosLinkerOptions: - Result:=MergeLinkerOptions(Result,Vars[VarName]); - pcosNamespaces: - Result:=MergeWithDelimiter(Result,Vars[VarName],';'); - pcosCustomOptions: - begin - Result:=MergeCustomOptions(Result,Vars[VarName]); - // add project/global overrides - if (Owner is TBaseCompilerOptions) and Assigned(OnAppendCustomOption) then - begin - MoreOptions:=''; - OnAppendCustomOption(Opts,MoreOptions,bmgtAll); - if Assigned(OnLocalSubstitute) then - MoreOptions:=OnLocalSubstitute(MoreOptions,false); - MoreOptions:=SpecialCharsToSpaces(MoreOptions,true); - Result:=MergeCustomOptions(Result,MoreOptions); - end; - end; - pcosOutputDir,pcosCompilerPath,pcosWriteConfigFilePath: - if Vars.IsDefined(PChar(VarName)) then - Result:=GetForcedPathDelims(Vars[VarName]); - end -end; - -function TParsedCompilerOptions.GetParsedValue(Option: TParsedCompilerOptString; - WithOverrides: boolean): string; -var - s: String; -begin - if WithOverrides then begin - if (Option=pcosOutputDir) and (OutputDirectoryOverride<>'') then begin - Result:=OutputDirectoryOverride; - exit; - end; - end; - if Values[Option].ParseStamp<>CompilerParseStamp then begin - if Values[Option].Parsing then begin - DebugLn('TParsedCompilerOptions.GetParsedValue Circle in Options: ',EnumToStr(Option),' Unparsed="',Values[Option].UnparsedValue,'"'); - ParsedError(Option, lisEndlessLoopInMacros); - exit(''); - end; - Values[Option].Parsing:=true; - try - s:=DoParseOption(GetUnparsedWithConditionals(Option),Option,false); - Values[Option].ParsedValue:=s; - Values[Option].ParseStamp:=CompilerParseStamp; - finally - Values[Option].Parsing:=false; - end; - end; - Result:=Values[Option].ParsedValue; -end; - -function TParsedCompilerOptions.GetParsedPIValue( - Option: TParsedCompilerOptString): string; -var - s: String; -begin - if ParsedPIStamp[Option]<>CompilerParseStamp then begin - if ParsingPI[Option] then begin - DebugLn('TParsedCompilerOptions.GetParsedPIValue Circle in Options: ',EnumToStr(Option)); - exit(''); - end; - ParsingPI[Option]:=true; - try - s:=DoParseOption(GetUnparsedWithConditionals(Option),Option,true); - ParsedPIValues[Option]:=s; - ParsedPIStamp[Option]:=CompilerParseStamp; - //if Option=pcosCustomOptions then begin - // DebugLn('TParsedCompilerOptions.GetParsedValue PARSED ',dbgs(ParsedStamp[Option]),' ',dbgs(CompilerParseStamp),' new="',ParsedValues[Option],'"'); - //end; - finally - ParsingPI[Option]:=false; - end; - end; - Result:=ParsedPIValues[Option]; -end; - -procedure TParsedCompilerOptions.SetUnparsedValue( - Option: TParsedCompilerOptString; const NewValue: string); -begin - if NewValue=Values[Option].UnparsedValue then exit; - if InvalidateParseOnChange then IncreaseCompilerParseStamp; - if Option=pcosBaseDir then - InvalidateFiles - else begin - Values[Option].ParseStamp:=CTInvalidChangeStamp; - ParsedPIStamp[Option]:=CTInvalidChangeStamp; - end; - Values[Option].UnparsedValue:=NewValue; -end; - -function TParsedCompilerOptions.DoParseOption(OptionText: string; - Option: TParsedCompilerOptString; PlatformIndependent: boolean): string; -// Don't use "const" for OptionText parameter. - - function GetBaseDir: string; - begin - if PlatformIndependent then - Result:=GetParsedPIValue(pcosBaseDir) - else - Result:=GetParsedValue(pcosBaseDir); - if Result='' then - Result:=EnvironmentOptions.GetParsedTestBuildDirectory; - end; - - procedure MakeFilenameAbsolute(var aFilename: string); - var - BaseDirectory: String; - begin - aFilename:=TrimFilename(aFilename); - if (aFilename<>'') and (not FilenameIsAbsolute(aFilename)) then begin - BaseDirectory:=GetBaseDir; - if (BaseDirectory<>'') then - aFilename:=TrimFilename(BaseDirectory+aFilename); - end; - end; - -var - BaseDirectory, h: String; -begin - Result:=OptionText; - - // apply overrides - if not PlatformIndependent then begin - if Option=pcosOutputDir then begin - if Assigned(OnGetOutputDirectoryOverride) then - OnGetOutputDirectoryOverride(Self,Result,bmgtAll); - end; - end; - - // parse locally (macros depending on owner, like pkgdir and build macros) - if Assigned(OnLocalSubstitute) then - begin - //DebugLn(['TParsedCompilerOptions.DoParseOption local "',Result,'" ...']); - Result:=OnLocalSubstitute(Result,PlatformIndependent) - end else - begin - //DebugLn(['TParsedCompilerOptions.DoParseOption global "',Result,'" ...']); - Result:=ParseString(Self,Result,PlatformIndependent); - end; - //DebugLn(['TParsedCompilerOptions.DoParseOption complete "',Result,'" ...']); - // improve - if Option=pcosBaseDir then - // base directory - Result:=AppendPathDelim(TrimFilename(Result)) - else if Option in ParsedCompilerFilenames then - begin - // make filename absolute - //debugln(['TParsedCompilerOptions.DoParseOption ',ParsedCompilerOptsVars[Option],' Result="',Result,'"']); - if (Option in ParsedCompilerExecutables) and (ExtractFilePath(Result)='') then - begin - h:=FileUtil.FindDefaultExecutablePath(Result,GetBaseDir); - if h<>'' then - Result:=h; - end; - MakeFilenameAbsolute(Result); - end - else if Option in ParsedCompilerDirectories then - begin - // make directory absolute - Result:=TrimFilename(Result); - if Option<>pcosBaseDir then - MakeFilenameAbsolute(Result); - Result:=AppendPathDelim(Result); - end - else if Option in ParsedCompilerSearchPaths then - begin - // make search paths absolute - BaseDirectory:=GetBaseDir; - Result:=TrimSearchPath(Result,BaseDirectory); - end else if Option=pcosCustomOptions then begin - Result:=SpecialCharsToSpaces(Result,true); - end; -end; - -procedure TParsedCompilerOptions.Assign(Src: TParsedCompilerOptions); -begin - FInvalidateParseOnChange := Src.FInvalidateParseOnChange; -// FOnLocalSubstitute := Src.FOnLocalSubstitute; - FOutputDirectoryOverride := Src.FOutputDirectoryOverride; - Values := Src.Values; - ParsedErrorOption := Src.ParsedErrorOption; - ParsedErrorMsg := Src.ParsedErrorMsg; - ParsedErrorStamp := Src.ParsedErrorStamp; - // parsed except for platform macros - ParsedPIValues := Src.ParsedPIValues; - ParsedPIStamp := Src.ParsedPIStamp; - ParsingPI := Src.ParsingPI; - // macro values -// InheritedMacroValues.Assign(Src.InheritedMacroValues); - InheritedMacroValuesStamp := Src.InheritedMacroValuesStamp; - InheritedMacroValuesParsing := Src.InheritedMacroValuesParsing; -// MacroValues: TIDECfgScriptEngine; - MacroValuesStamp := Src.MacroValuesStamp; - MacroValuesParsing := Src.MacroValuesParsing; -end; - -procedure TParsedCompilerOptions.Clear; -var - Option: TParsedCompilerOptString; -begin - InvalidateAll; - for Option:=Low(TParsedCompilerOptString) to High(TParsedCompilerOptString) do - begin - Values[Option].ParsedValue:=''; - ParsedPIValues[Option]:=''; - Values[Option].UnparsedValue:=''; - end; - InheritedMacroValues.Clear; - MacroValues.Variables.Clear; - MacroValues.ClearErrors; -end; - -procedure TParsedCompilerOptions.InvalidateAll; -var - Option: TParsedCompilerOptString; -begin - for Option:=Low(TParsedCompilerOptString) to High(TParsedCompilerOptString) do - begin - Values[Option].ParseStamp:=CTInvalidChangeStamp; - ParsedPIStamp[Option]:=CTInvalidChangeStamp; - end; - InheritedMacroValuesStamp:=CTInvalidChangeStamp; - MacroValuesStamp:=CTInvalidChangeStamp; - ParsedErrorStamp:=CTInvalidChangeStamp; -end; - -procedure TParsedCompilerOptions.InvalidateFiles; -var - Option: TParsedCompilerOptString; -begin - for Option:=Low(TParsedCompilerOptString) to High(TParsedCompilerOptString) do - if (Option in ParsedCompilerFiles) then begin - Values[Option].ParseStamp:=CTInvalidChangeStamp; - ParsedPIStamp[Option]:=CTInvalidChangeStamp; - end; -end; - -procedure TParsedCompilerOptions.RenameMacro(const OldName, NewName: string; - out Changed: TParsedCompilerOptStrings); -var - o: TParsedCompilerOptString; - s: String; -begin - Changed:=[]; - for o:=Low(Values) to High(Values) do - begin - s:=Values[o].UnparsedValue; - RenameIDEMacroInString(s,OldName,NewName); - if s<>Values[o].UnparsedValue then begin - SetUnparsedValue(o,s); - Include(Changed,o) - end; - end; -end; - { TCompilationToolOptions } procedure TCompilationToolOptions.SetCommand(AValue: string); diff --git a/ide/frames/compiler_buildmacro_options.pas b/ide/frames/compiler_buildmacro_options.pas index afb1e41a21..5987aba979 100644 --- a/ide/frames/compiler_buildmacro_options.pas +++ b/ide/frames/compiler_buildmacro_options.pas @@ -35,7 +35,7 @@ uses // IdeIntf IDEOptionsIntf, IDEOptEditorIntf, CompOptsIntf, MacroIntf, IDEImagesIntf, IDEDialogs, // IDE - CompilerOptions, LazarusIDEStrConsts, PackageDefs; + ParsedCompilerOpts, CompilerOptions, LazarusIDEStrConsts, PackageDefs; type TCBMNodeType = ( diff --git a/ide/frames/compiler_other_options.pas b/ide/frames/compiler_other_options.pas index b627984cae..b577681465 100644 --- a/ide/frames/compiler_other_options.pas +++ b/ide/frames/compiler_other_options.pas @@ -40,8 +40,8 @@ uses // SynEdit SynEdit, SynEditKeyCmds, SynCompletion, // IDE - LazarusIDEStrConsts, CompilerOptions, Compiler, AllCompilerOptions, DefinesGui, - EditorOptions, PackageDefs, SourceSynEditor; + LazarusIDEStrConsts, ParsedCompilerOpts, CompilerOptions, Compiler, + AllCompilerOptions, DefinesGui, EditorOptions, PackageDefs, SourceSynEditor; type diff --git a/ide/frames/compiler_path_options.pas b/ide/frames/compiler_path_options.pas index 662984efac..4d77960b6e 100644 --- a/ide/frames/compiler_path_options.pas +++ b/ide/frames/compiler_path_options.pas @@ -15,7 +15,7 @@ uses // IdeConfig SearchPathProcs, // IDE - Project, CompilerOptions, LazarusIDEStrConsts, PathEditorDlg, + Project, ParsedCompilerOpts, CompilerOptions, LazarusIDEStrConsts, PathEditorDlg, CheckCompilerOpts, ShowCompilerOpts, ImExportCompilerOpts; type diff --git a/ide/main.pp b/ide/main.pp index 24cf4077d6..91c935b7ff 100644 --- a/ide/main.pp +++ b/ide/main.pp @@ -86,8 +86,8 @@ uses // protocol IDEProtocol, // compile - CompilerOptions, CheckCompilerOpts, BuildProjectDlg, BuildModesManager, - ApplicationBundle, ExtTools, ExtToolsIDE, + ParsedCompilerOpts, CompilerOptions, CheckCompilerOpts, BuildProjectDlg, + BuildModesManager, ApplicationBundle, ExtTools, ExtToolsIDE, // projects ProjectResources, Project, ProjectDefs, NewProjectDlg, PublishModuleDlg, ProjectInspector, PackageDefs, ProjectDescriptorTypes, diff --git a/ide/parsedcompileropts.pas b/ide/parsedcompileropts.pas new file mode 100644 index 0000000000..a853ff577c --- /dev/null +++ b/ide/parsedcompileropts.pas @@ -0,0 +1,897 @@ +unit ParsedCompilerOpts; + +{$mode ObjFPC}{$H+} + +interface + +uses + Classes, SysUtils, + // CodeTools + FileProcs, DefineTemplates, CodeToolsCfgScript, + KeywordFuncLists, BasicCodeTools, LinkScanner, DirectoryCacher, + // LazUtils + FPCAdds, LazVersion, LazUTF8, LazStringUtils, LazFileUtils, FileUtil, + LazUtilities, LazTracer, Laz2_XMLCfg, + // BuildIntf + CompOptsIntf, MacroIntf, + // IdeConfig + EnvironmentOpts, TransferMacros, SearchPathProcs, ModeMatrixOpts, + // IDE + LazarusIDEStrConsts; + +type + + { TIDECfgScriptEngine } + + TIDECfgScriptEngine = class(TCTConfigScriptEngine) + private + FProjValuesAvailable: boolean; + protected + function IsCustomFunction(FunctionName: PChar): boolean; override; + procedure RunCustomSimpleFunction(FunctionName: PChar; + Value: PCTCfgScriptVariable); override; + public + property ProjValuesAvailable: boolean read FProjValuesAvailable write FProjValuesAvailable; + end; + + TInheritedCompilerOption = ( + icoNone, + icoUnitPath, + icoNamespaces, + icoIncludePath, + icoObjectPath, + icoLibraryPath, + icoSrcPath, + icoLinkerOptions, + icoCustomOptions + ); + TInheritedCompilerOptions = set of TInheritedCompilerOption; + + TInheritedCompOptsStrings = array[TInheritedCompilerOption] of string; + +const + icoAllSearchPaths = [icoUnitPath,icoIncludePath,icoObjectPath,icoLibraryPath, + icoSrcPath]; + +type + TParsedCompilerOptString = ( + pcosNone, + pcosBaseDir, // the base directory for the relative paths (only auto created packages can have macros in the BaseDir) + pcosUnitPath, // search path for pascal units + pcosNamespaces, // namespaces + pcosIncludePath, // search path for pascal include files + pcosObjectPath, // search path for .o files + pcosLibraryPath, // search path for libraries + pcosSrcPath, // additional search path for pascal source files + pcosLinkerOptions,// additional linker options + pcosCustomOptions,// additional options + pcosOutputDir, // the output directory + pcosCompilerPath, // the filename of the compiler + pcosDebugPath, // additional debug search path + pcosMsgFile, // fpc message file (errore.msg) + pcosCustomConfigFilePath, // additional custom config file + pcosWriteConfigFilePath // auto generated cfg file + ); + TParsedCompilerOptStrings = set of TParsedCompilerOptString; + +const + InheritedToParsedCompilerOption: array[TInheritedCompilerOption] of + TParsedCompilerOptString = ( + pcosNone, + pcosUnitPath, // icoUnitPath, + pcosNamespaces, // icoNamespaces, + pcosIncludePath, // icoIncludePath, + pcosObjectPath, // icoObjectPath, + pcosLibraryPath, // icoLibraryPath, + pcosSrcPath, // icoSrcPath, + pcosLinkerOptions, // icoLinkerOptions, + pcosCustomOptions // icoCustomOptions + ); + + ParsedCompilerSearchPaths = [pcosUnitPath,pcosIncludePath,pcosObjectPath, + pcosLibraryPath,pcosSrcPath,pcosDebugPath]; + ParsedCompilerExecutables = [pcosCompilerPath]; + ParsedCompilerFilenames = ParsedCompilerExecutables+[pcosMsgFile, + pcosCustomConfigFilePath,pcosWriteConfigFilePath]; + ParsedCompilerDirectories = [pcosOutputDir]; + ParsedCompilerOutDirectories = [pcosOutputDir]; + ParsedCompilerFiles = + ParsedCompilerSearchPaths+ParsedCompilerFilenames+ParsedCompilerDirectories; + + ParsedCompilerOptsVars: array[TParsedCompilerOptString] of string = ( + '', // pcosNone + '', // pcosBaseDir + 'UnitPath', + 'Namespaces', + 'IncPath', + 'ObjectPath', + 'LibraryPath', + 'SrcPath', + 'LinkerOptions', + 'CustomOptions', + 'OutputDir', + 'CompilerPath', + 'DebugPath', + 'MsgFile', + 'CustomConfigFile', + 'WriteCfgFile' + ); + ParsedCompilerOptsUsageVars: array[TParsedCompilerOptString] of string = ( + '', // pcosNone + '', // pcosBaseDir + 'UsageUnitPath', + 'UsageNamespaces', + 'UsageIncPath', + 'UsageObjectPath', + 'UsageLibraryPath', + 'UsageSrcPath', + 'UsageLinkerOptions', + 'UsageCustomOptions', + '', // pcosOutputDir + '', // pcosCompilerPath + 'UsageDebugPath', // pcosDebugPath + '', // pcosMsgFile + '', + '' // pcosWriteConfigFilePath + ); + +type + TLocalSubstitutionEvent = function(s: string; + PlatformIndependent: boolean): string of object; + + { TParsedCompilerOptions } + + TParsedCompilerOptions = class + private + FInvalidateParseOnChange: boolean; + FOnLocalSubstitute: TLocalSubstitutionEvent; + FOutputDirectoryOverride: string; + FOwner: TObject; + procedure SetOutputDirectoryOverride(const AValue: string); + public + // parsed + Values: array[TParsedCompilerOptString] of TParseString; + ParsedErrorOption: TParsedCompilerOptString; + ParsedErrorMsg: string; + ParsedErrorStamp: integer; // see CompilerParseStamp + // parsed except for platform macros + ParsedPIValues: array[TParsedCompilerOptString] of string; + ParsedPIStamp: array[TParsedCompilerOptString] of integer; // see CompilerParseStamp + ParsingPI: array[TParsedCompilerOptString] of boolean; + // macro values + InheritedMacroValues: TCTCfgScriptVariables; + InheritedMacroValuesStamp: integer; // see BuildMacroChangeStamp + InheritedMacroValuesParsing: boolean; + MacroValues: TIDECfgScriptEngine; + MacroValuesStamp: integer; // see BuildMacroChangeStamp + MacroValuesParsing: boolean; + constructor Create(TheOwner: TObject); + destructor Destroy; override; + function HasParsedError: boolean; + procedure ParsedError(Option: TParsedCompilerOptString; Msg: string); + function GetUnparsedWithConditionals(Option: TParsedCompilerOptString): string; + function GetParsedValue(Option: TParsedCompilerOptString; + WithOverrides: boolean = true): string; + function GetParsedPIValue(Option: TParsedCompilerOptString): string;// platform independent + procedure SetUnparsedValue(Option: TParsedCompilerOptString; + const NewValue: string); + function DoParseOption(OptionText: string; + Option: TParsedCompilerOptString; + PlatformIndependent: boolean): string; + procedure Assign(Src: TParsedCompilerOptions); + procedure Clear; + procedure InvalidateAll; + procedure InvalidateFiles; + procedure RenameMacro(const OldName, NewName: string; + out Changed: TParsedCompilerOptStrings); // rename macro in UnparsedValues + public + property Owner: TObject read FOwner; + property OnLocalSubstitute: TLocalSubstitutionEvent read FOnLocalSubstitute + write FOnLocalSubstitute; + property InvalidateParseOnChange: boolean read FInvalidateParseOnChange + write FInvalidateParseOnChange; + property OutputDirectoryOverride: string read FOutputDirectoryOverride + write SetOutputDirectoryOverride; + end; + + { TAdditionalCompilerOptions + + Additional Compiler options are used by packages to define, what a project + or a package or the IDE needs to use the package. + } + TAdditionalCompilerOptions = class + private + fOwner: TObject; + FParsedOpts: TParsedCompilerOptions; + protected + function GetBaseDirectory: string; + function GetCustomOptions: string; virtual; + function GetIncludePath: string; virtual; + function GetLibraryPath: string; virtual; + function GetLinkerOptions: string; virtual; + function GetNamespaces: string; virtual; + function GetObjectPath: string; virtual; + function GetSrcPath: string; virtual; + function GetUnitPath: string; virtual; + procedure SetBaseDirectory(const AValue: string); virtual; + procedure SetCustomOptions(const AValue: string); virtual; + procedure SetIncludePath(const AValue: string); virtual; + procedure SetLibraryPath(const AValue: string); virtual; + procedure SetLinkerOptions(const AValue: string); virtual; + procedure SetNamespaces(const AValue: string); virtual; + procedure SetObjectPath(const AValue: string); virtual; + procedure SetSrcPath(const AValue: string); virtual; + procedure SetUnitPath(const AValue: string); virtual; + public + constructor Create(TheOwner: TObject); + destructor Destroy; override; + procedure Clear; + procedure AssignOptions(Source: TObject); virtual; + procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string; + AdjustPathDelims: boolean); + procedure SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string; + UsePathDelim: TPathDelimSwitch); + function GetOwnerName: string; virtual; + function GetOption(AnOption: TInheritedCompilerOption): string; + function GetLazCompilerOptions: TLazCompilerOptions; virtual; + public + property Owner: TObject read fOwner; + property UnitPath: string read GetUnitPath write SetUnitPath; + property Namespaces: string read GetNamespaces write SetNamespaces; + property IncludePath: string read GetIncludePath write SetIncludePath; + property SrcPath: string read GetSrcPath write SetSrcPath; + property ObjectPath: string read GetObjectPath write SetObjectPath; + property LibraryPath: string read GetLibraryPath write SetLibraryPath; + property LinkerOptions: string read GetLinkerOptions write SetLinkerOptions; + property CustomOptions: string read GetCustomOptions write SetCustomOptions; + property BaseDirectory: string read GetBaseDirectory write SetBaseDirectory; + property ParsedOpts: TParsedCompilerOptions read FParsedOpts; + end; + + + TGetBuildMacroValues = function(Options: TLazCompilerOptions; + IncludeSelf: boolean): TCTCfgScriptVariables of object; + TParseStringEvent = function(Options: TParsedCompilerOptions; + const UnparsedValue: string; PlatformIndependent: boolean): string of object; + TOnAppendCustomOptions = procedure(Sender: TObject; + var CustomOptions: string; Types: TBuildMatrixGroupTypes) of object; + TOnGetOutputDirectoryOverride = procedure(Sender: TObject; + var OutDir: string; Types: TBuildMatrixGroupTypes) of object; + +var + OnAppendCustomOption: TOnAppendCustomOptions = nil; // set by MainBuildBoss + OnGetOutputDirectoryOverride: TOnGetOutputDirectoryOverride = nil; // set by MainBuildBoss + OnParseString: TParseStringEvent = nil; + GetBuildMacroValues: TGetBuildMacroValues = nil; // set by TPkgManager, do not change or free the variables + +function EnumToStr(opt: TParsedCompilerOptString): string; overload; +function MergeCustomOptions(const OldOptions, AddOptions: string): string; +function MergeLinkerOptions(const OldOptions, AddOptions: string): string; +function ParseString(Options: TParsedCompilerOptions; + const UnparsedValue: string; PlatformIndependent: boolean): string; + + +implementation + +function EnumToStr(opt: TParsedCompilerOptString): string; +begin + Result:=''; + WriteStr(Result, opt); +end; + +function MergeCustomOptions(const OldOptions, AddOptions: string): string; +begin + Result:=OldOptions; + if AddOptions='' then exit; + if (OldOptions<>'') and (OldOptions[length(OldOptions)]<>' ') + and (AddOptions[1]<>' ') then + Result+=' '; + Result+=AddOptions; +end; + +function MergeLinkerOptions(const OldOptions, AddOptions: string): string; +begin + Result:=MergeCustomOptions(OldOptions,AddOptions); +end; + +function ParseString(Options: TParsedCompilerOptions; + const UnparsedValue: string; PlatformIndependent: boolean): string; +begin + Result:=OnParseString(Options,UnparsedValue,PlatformIndependent); +end; + +{ TIDECfgScriptEngine } + +function TIDECfgScriptEngine.IsCustomFunction(FunctionName: PChar): boolean; +begin + case UpChars[FunctionName^] of + 'G': + if (CompareIdentifiers(FunctionName,'GetIDEValue')=0) + or (CompareIdentifiers(FunctionName,'GetEnv')=0) + or (ProjValuesAvailable and (CompareIdentifiers(FunctionName,'GetProjValue')=0)) + then exit(true); + end; + Result:=false; +end; + +procedure TIDECfgScriptEngine.RunCustomSimpleFunction(FunctionName: PChar; + Value: PCTCfgScriptVariable); +var + VarName: String; + s: String; +begin + case UpChars[FunctionName^] of + 'G': + if (CompareIdentifiers(FunctionName,'GetIDEValue')=0) then + begin + VarName:=GetCTCSVariableAsString(Value); + if CompareIdentifiers(PChar(VarName),'OS')=0 then + SetCTCSVariableAsString(Value,FPCAdds.GetCompiledTargetOS) + else if CompareIdentifiers(PChar(VarName),'CPU')=0 then + SetCTCSVariableAsString(Value,FPCAdds.GetCompiledTargetCPU) + else if CompareIdentifiers(PChar(VarName),'SrcOS')=0 then + SetCTCSVariableAsString(Value,GetDefaultSrcOSForTargetOS(FPCAdds.GetCompiledTargetOS)) + else if CompareIdentifiers(PChar(VarName),'SrcOS2')=0 then + SetCTCSVariableAsString(Value,GetDefaultSrcOS2ForTargetOS(FPCAdds.GetCompiledTargetOS)) + else if CompareIdentifiers(PChar(VarName),'LCLWidgetType')=0 then + SetCTCSVariableAsString(Value,GetLCLWidgetTypeName) + else if CompareIdentifiers(PChar(VarName),'LAZ_FULLVERSION')=0 then + SetCTCSVariableAsNumber(Value,laz_fullversion) + else + ClearCTCSVariable(Value); + end else if (CompareIdentifiers(FunctionName,'GetEnv')=0) then + begin + VarName:=GetCTCSVariableAsString(Value); + SetCTCSVariableAsString(Value,GetEnvironmentVariableUTF8(VarName)); + end else if ProjValuesAvailable + and (CompareIdentifiers(FunctionName,'GetProjValue')=0) then + begin + VarName:=GetCTCSVariableAsString(Value); + if CompareIdentifiers(PChar(VarName),'FPC_FULLVERSION')=0 then + begin + s:='$(FPC_FULLVERSION)'; + GlobalMacroList.SubstituteStr(s); + SetCTCSVariableAsNumber(Value,StrToIntDef(s,0)); + end; + end; + end; +end; + + +{ TParsedCompilerOptions } + +procedure TParsedCompilerOptions.SetOutputDirectoryOverride(const AValue: string); +begin + if FOutputDirectoryOverride=AValue then exit; + FOutputDirectoryOverride:=AValue; + if InvalidateParseOnChange then + IncreaseCompilerParseStamp;// the output dir is used by other packages + //if FOutputDirectoryOverride<>'' then + // DebugLn(['TParsedCompilerOptions.SetOutputDirectoryOverride New=',FOutputDirectoryOverride]) + //else + // DebugLn(['TParsedCompilerOptions.SetOutputDirectoryOverride using default']); +end; + +constructor TParsedCompilerOptions.Create(TheOwner: TObject); +begin + FOwner:=TheOwner; + InheritedMacroValues:=TCTCfgScriptVariables.Create; + MacroValues:=TIDECfgScriptEngine.Create; + Clear; +end; + +destructor TParsedCompilerOptions.Destroy; +begin + FreeAndNil(InheritedMacroValues); + FreeAndNil(MacroValues); + inherited Destroy; +end; + +function TParsedCompilerOptions.HasParsedError: boolean; +begin + Result:=(ParsedErrorStamp<>CTInvalidChangeStamp) + and (ParsedErrorStamp=CompilerParseStamp); +end; + +procedure TParsedCompilerOptions.ParsedError(Option: TParsedCompilerOptString; + Msg: string); +begin + if HasParsedError then exit; + ParsedErrorMsg:=Msg; + ParsedErrorOption:=Option; + ParsedErrorStamp:=CompilerParseStamp; +end; + +function TParsedCompilerOptions.GetUnparsedWithConditionals( + Option: TParsedCompilerOptString): string; +var + Opts: TLazCompilerOptions; + VarName: String; + Vars: TCTCfgScriptVariables; + MoreOptions: String; +begin + Result:=Values[Option].UnparsedValue; + Opts:=nil; + VarName:=''; + if (Owner is TLazCompilerOptions) then + begin + Opts:=TLazCompilerOptions(Owner); + VarName:=ParsedCompilerOptsVars[Option]; + end else if (Owner is TAdditionalCompilerOptions) then + begin + Opts:=TAdditionalCompilerOptions(Owner).GetLazCompilerOptions; + VarName:=ParsedCompilerOptsUsageVars[Option]; + end; + if (VarName='') or (Opts=nil) then exit; + Vars:=GetBuildMacroValues(Opts,true); + if Vars=nil then exit; + case Option of + pcosUnitPath,pcosIncludePath,pcosObjectPath,pcosLibraryPath,pcosSrcPath, + pcosDebugPath: + Result:=MergeSearchPaths(Result,GetForcedPathDelims(Vars[VarName])); + pcosLinkerOptions: + Result:=MergeLinkerOptions(Result,Vars[VarName]); + pcosNamespaces: + Result:=MergeWithDelimiter(Result,Vars[VarName],';'); + pcosCustomOptions: + begin + Result:=MergeCustomOptions(Result,Vars[VarName]); + // add project/global overrides + if (Owner is TLazCompilerOptions) and Assigned(OnAppendCustomOption) then + begin + MoreOptions:=''; + OnAppendCustomOption(Opts,MoreOptions,bmgtAll); + if Assigned(OnLocalSubstitute) then + MoreOptions:=OnLocalSubstitute(MoreOptions,false); + MoreOptions:=SpecialCharsToSpaces(MoreOptions,true); + Result:=MergeCustomOptions(Result,MoreOptions); + end; + end; + pcosOutputDir,pcosCompilerPath,pcosWriteConfigFilePath: + if Vars.IsDefined(PChar(VarName)) then + Result:=GetForcedPathDelims(Vars[VarName]); + end +end; + +function TParsedCompilerOptions.GetParsedValue(Option: TParsedCompilerOptString; + WithOverrides: boolean): string; +var + s: String; +begin + if WithOverrides then begin + if (Option=pcosOutputDir) and (OutputDirectoryOverride<>'') then begin + Result:=OutputDirectoryOverride; + exit; + end; + end; + if Values[Option].ParseStamp<>CompilerParseStamp then begin + if Values[Option].Parsing then begin + DebugLn('TParsedCompilerOptions.GetParsedValue Circle in Options: ',EnumToStr(Option),' Unparsed="',Values[Option].UnparsedValue,'"'); + ParsedError(Option, lisEndlessLoopInMacros); + exit(''); + end; + Values[Option].Parsing:=true; + try + s:=DoParseOption(GetUnparsedWithConditionals(Option),Option,false); + Values[Option].ParsedValue:=s; + Values[Option].ParseStamp:=CompilerParseStamp; + finally + Values[Option].Parsing:=false; + end; + end; + Result:=Values[Option].ParsedValue; +end; + +function TParsedCompilerOptions.GetParsedPIValue( + Option: TParsedCompilerOptString): string; +var + s: String; +begin + if ParsedPIStamp[Option]<>CompilerParseStamp then begin + if ParsingPI[Option] then begin + DebugLn('TParsedCompilerOptions.GetParsedPIValue Circle in Options: ',EnumToStr(Option)); + exit(''); + end; + ParsingPI[Option]:=true; + try + s:=DoParseOption(GetUnparsedWithConditionals(Option),Option,true); + ParsedPIValues[Option]:=s; + ParsedPIStamp[Option]:=CompilerParseStamp; + //if Option=pcosCustomOptions then begin + // DebugLn('TParsedCompilerOptions.GetParsedValue PARSED ',dbgs(ParsedStamp[Option]),' ',dbgs(CompilerParseStamp),' new="',ParsedValues[Option],'"'); + //end; + finally + ParsingPI[Option]:=false; + end; + end; + Result:=ParsedPIValues[Option]; +end; + +procedure TParsedCompilerOptions.SetUnparsedValue( + Option: TParsedCompilerOptString; const NewValue: string); +begin + if NewValue=Values[Option].UnparsedValue then exit; + if InvalidateParseOnChange then IncreaseCompilerParseStamp; + if Option=pcosBaseDir then + InvalidateFiles + else begin + Values[Option].ParseStamp:=CTInvalidChangeStamp; + ParsedPIStamp[Option]:=CTInvalidChangeStamp; + end; + Values[Option].UnparsedValue:=NewValue; +end; + +function TParsedCompilerOptions.DoParseOption(OptionText: string; + Option: TParsedCompilerOptString; PlatformIndependent: boolean): string; +// Don't use "const" for OptionText parameter. + + function GetBaseDir: string; + begin + if PlatformIndependent then + Result:=GetParsedPIValue(pcosBaseDir) + else + Result:=GetParsedValue(pcosBaseDir); + if Result='' then + Result:=EnvironmentOptions.GetParsedTestBuildDirectory; + end; + + procedure MakeFilenameAbsolute(var aFilename: string); + var + BaseDirectory: String; + begin + aFilename:=TrimFilename(aFilename); + if (aFilename<>'') and (not FilenameIsAbsolute(aFilename)) then begin + BaseDirectory:=GetBaseDir; + if (BaseDirectory<>'') then + aFilename:=TrimFilename(BaseDirectory+aFilename); + end; + end; + +var + BaseDirectory, h: String; +begin + Result:=OptionText; + + // apply overrides + if not PlatformIndependent then begin + if Option=pcosOutputDir then begin + if Assigned(OnGetOutputDirectoryOverride) then + OnGetOutputDirectoryOverride(Self,Result,bmgtAll); + end; + end; + + // parse locally (macros depending on owner, like pkgdir and build macros) + if Assigned(OnLocalSubstitute) then + begin + //DebugLn(['TParsedCompilerOptions.DoParseOption local "',Result,'" ...']); + Result:=OnLocalSubstitute(Result,PlatformIndependent) + end else + begin + //DebugLn(['TParsedCompilerOptions.DoParseOption global "',Result,'" ...']); + Result:=ParseString(Self,Result,PlatformIndependent); + end; + //DebugLn(['TParsedCompilerOptions.DoParseOption complete "',Result,'" ...']); + // improve + if Option=pcosBaseDir then + // base directory + Result:=AppendPathDelim(TrimFilename(Result)) + else if Option in ParsedCompilerFilenames then + begin + // make filename absolute + //debugln(['TParsedCompilerOptions.DoParseOption ',ParsedCompilerOptsVars[Option],' Result="',Result,'"']); + if (Option in ParsedCompilerExecutables) and (ExtractFilePath(Result)='') then + begin + h:=FileUtil.FindDefaultExecutablePath(Result,GetBaseDir); + if h<>'' then + Result:=h; + end; + MakeFilenameAbsolute(Result); + end + else if Option in ParsedCompilerDirectories then + begin + // make directory absolute + Result:=TrimFilename(Result); + if Option<>pcosBaseDir then + MakeFilenameAbsolute(Result); + Result:=AppendPathDelim(Result); + end + else if Option in ParsedCompilerSearchPaths then + begin + // make search paths absolute + BaseDirectory:=GetBaseDir; + Result:=TrimSearchPath(Result,BaseDirectory); + end else if Option=pcosCustomOptions then begin + Result:=SpecialCharsToSpaces(Result,true); + end; +end; + +procedure TParsedCompilerOptions.Assign(Src: TParsedCompilerOptions); +begin + FInvalidateParseOnChange := Src.FInvalidateParseOnChange; +// FOnLocalSubstitute := Src.FOnLocalSubstitute; + FOutputDirectoryOverride := Src.FOutputDirectoryOverride; + Values := Src.Values; + ParsedErrorOption := Src.ParsedErrorOption; + ParsedErrorMsg := Src.ParsedErrorMsg; + ParsedErrorStamp := Src.ParsedErrorStamp; + // parsed except for platform macros + ParsedPIValues := Src.ParsedPIValues; + ParsedPIStamp := Src.ParsedPIStamp; + ParsingPI := Src.ParsingPI; + // macro values +// InheritedMacroValues.Assign(Src.InheritedMacroValues); + InheritedMacroValuesStamp := Src.InheritedMacroValuesStamp; + InheritedMacroValuesParsing := Src.InheritedMacroValuesParsing; +// MacroValues: TIDECfgScriptEngine; + MacroValuesStamp := Src.MacroValuesStamp; + MacroValuesParsing := Src.MacroValuesParsing; +end; + +procedure TParsedCompilerOptions.Clear; +var + Option: TParsedCompilerOptString; +begin + InvalidateAll; + for Option:=Low(TParsedCompilerOptString) to High(TParsedCompilerOptString) do + begin + Values[Option].ParsedValue:=''; + ParsedPIValues[Option]:=''; + Values[Option].UnparsedValue:=''; + end; + InheritedMacroValues.Clear; + MacroValues.Variables.Clear; + MacroValues.ClearErrors; +end; + +procedure TParsedCompilerOptions.InvalidateAll; +var + Option: TParsedCompilerOptString; +begin + for Option:=Low(TParsedCompilerOptString) to High(TParsedCompilerOptString) do + begin + Values[Option].ParseStamp:=CTInvalidChangeStamp; + ParsedPIStamp[Option]:=CTInvalidChangeStamp; + end; + InheritedMacroValuesStamp:=CTInvalidChangeStamp; + MacroValuesStamp:=CTInvalidChangeStamp; + ParsedErrorStamp:=CTInvalidChangeStamp; +end; + +procedure TParsedCompilerOptions.InvalidateFiles; +var + Option: TParsedCompilerOptString; +begin + for Option:=Low(TParsedCompilerOptString) to High(TParsedCompilerOptString) do + if (Option in ParsedCompilerFiles) then begin + Values[Option].ParseStamp:=CTInvalidChangeStamp; + ParsedPIStamp[Option]:=CTInvalidChangeStamp; + end; +end; + +procedure TParsedCompilerOptions.RenameMacro(const OldName, NewName: string; + out Changed: TParsedCompilerOptStrings); +var + o: TParsedCompilerOptString; + s: String; +begin + Changed:=[]; + for o:=Low(Values) to High(Values) do + begin + s:=Values[o].UnparsedValue; + RenameIDEMacroInString(s,OldName,NewName); + if s<>Values[o].UnparsedValue then begin + SetUnparsedValue(o,s); + Include(Changed,o) + end; + end; +end; + +{ TAdditionalCompilerOptions } + +procedure TAdditionalCompilerOptions.SetCustomOptions(const AValue: string); +begin + ParsedOpts.SetUnparsedValue(pcosCustomOptions,AValue); +end; + +procedure TAdditionalCompilerOptions.SetSrcPath(const AValue: string); +begin + ParsedOpts.SetUnparsedValue(pcosSrcPath,AValue); +end; + +function TAdditionalCompilerOptions.GetUnitPath: string; +begin + Result:=FParsedOpts.Values[pcosUnitPath].UnparsedValue; +end; + +function TAdditionalCompilerOptions.GetIncludePath: string; +begin + Result:=FParsedOpts.Values[pcosIncludePath].UnparsedValue; +end; + +function TAdditionalCompilerOptions.GetBaseDirectory: string; +begin + Result:=FParsedOpts.Values[pcosBaseDir].UnparsedValue; +end; + +function TAdditionalCompilerOptions.GetCustomOptions: string; +begin + Result:=FParsedOpts.Values[pcosCustomOptions].UnparsedValue; +end; + +function TAdditionalCompilerOptions.GetLibraryPath: string; +begin + Result:=FParsedOpts.Values[pcosLibraryPath].UnparsedValue; +end; + +function TAdditionalCompilerOptions.GetLinkerOptions: string; +begin + Result:=FParsedOpts.Values[pcosLinkerOptions].UnparsedValue; +end; + +function TAdditionalCompilerOptions.GetNamespaces: string; +begin + Result:=FParsedOpts.Values[pcosNamespaces].UnparsedValue; +end; + +function TAdditionalCompilerOptions.GetObjectPath: string; +begin + Result:=FParsedOpts.Values[pcosObjectPath].UnparsedValue; +end; + +function TAdditionalCompilerOptions.GetSrcPath: string; +begin + Result:=FParsedOpts.Values[pcosSrcPath].UnparsedValue; +end; + +procedure TAdditionalCompilerOptions.SetBaseDirectory(const AValue: string); +begin + ParsedOpts.SetUnparsedValue(pcosBaseDir,AValue); +end; + +procedure TAdditionalCompilerOptions.SetIncludePath(const AValue: string); +begin + ParsedOpts.SetUnparsedValue(pcosIncludePath,AValue); +end; + +procedure TAdditionalCompilerOptions.SetLibraryPath(const AValue: string); +begin + ParsedOpts.SetUnparsedValue(pcosLibraryPath,AValue); +end; + +procedure TAdditionalCompilerOptions.SetLinkerOptions(const AValue: string); +begin + ParsedOpts.SetUnparsedValue(pcosLinkerOptions,AValue); +end; + +procedure TAdditionalCompilerOptions.SetNamespaces(const AValue: string); +begin + ParsedOpts.SetUnparsedValue(pcosNamespaces,AValue); +end; + +procedure TAdditionalCompilerOptions.SetObjectPath(const AValue: string); +begin + ParsedOpts.SetUnparsedValue(pcosObjectPath,AValue); +end; + +procedure TAdditionalCompilerOptions.SetUnitPath(const AValue: string); +begin + ParsedOpts.SetUnparsedValue(pcosUnitPath,AValue); +end; + +constructor TAdditionalCompilerOptions.Create(TheOwner: TObject); +begin + fOwner:=TheOwner; + FParsedOpts:=TParsedCompilerOptions.Create(Self); + Clear; +end; + +destructor TAdditionalCompilerOptions.Destroy; +begin + FreeThenNil(FParsedOpts); + inherited Destroy; +end; + +procedure TAdditionalCompilerOptions.Clear; +begin + UnitPath:=''; + Namespaces:=''; + SrcPath:=''; + IncludePath:=''; + CustomOptions:=''; + LibraryPath:=''; + LinkerOptions:=''; + ObjectPath:=''; +end; + +procedure TAdditionalCompilerOptions.AssignOptions(Source: TObject); +var + Src: TAdditionalCompilerOptions; +begin + if not (Source is TAdditionalCompilerOptions) then + raise Exception.Create('TAdditionalCompilerOptions.AssignOptions: Can not copy from '+DbgSName(Source)); + Src:=TAdditionalCompilerOptions(Source); + UnitPath:=Src.UnitPath; + Namespaces:=Src.Namespaces; + IncludePath:=Src.IncludePath; + SrcPath:=Src.SrcPath; + ObjectPath:=Src.ObjectPath; + LibraryPath:=Src.LibraryPath; + LinkerOptions:=Src.LinkerOptions; + CustomOptions:=Src.CustomOptions; + BaseDirectory:=Src.BaseDirectory; +end; + +procedure TAdditionalCompilerOptions.LoadFromXMLConfig(XMLConfig: TXMLConfig; + const Path: string; AdjustPathDelims: boolean); + + function f(const Filename: string): string; + begin + Result:=SwitchPathDelims(Filename,AdjustPathDelims); + end; + +begin + Clear; + CustomOptions:=f(XMLConfig.GetValue(Path+'CustomOptions/Value','')); + IncludePath:=f(XMLConfig.GetValue(Path+'IncludePath/Value','')); + LibraryPath:=f(XMLConfig.GetValue(Path+'LibraryPath/Value','')); + LinkerOptions:=f(XMLConfig.GetValue(Path+'LinkerOptions/Value','')); + Namespaces:=f(XMLConfig.GetValue(Path+'Namespaces/Value','')); + ObjectPath:=f(XMLConfig.GetValue(Path+'ObjectPath/Value','')); + UnitPath:=f(XMLConfig.GetValue(Path+'UnitPath/Value','')); + SrcPath:=f(XMLConfig.GetValue(Path+'SrcPath/Value','')); +end; + +procedure TAdditionalCompilerOptions.SaveToXMLConfig(XMLConfig: TXMLConfig; + const Path: string; UsePathDelim: TPathDelimSwitch); + + function f(const AFilename: string): string; + begin + Result:=SwitchPathDelims(AFilename,UsePathDelim); + end; + +begin + XMLConfig.SetDeleteValue(Path+'CustomOptions/Value',f(CustomOptions),''); + XMLConfig.SetDeleteValue(Path+'IncludePath/Value',f(IncludePath),''); + XMLConfig.SetDeleteValue(Path+'LibraryPath/Value',f(LibraryPath),''); + XMLConfig.SetDeleteValue(Path+'LinkerOptions/Value',f(LinkerOptions),''); + XMLConfig.SetDeleteValue(Path+'Namespaces/Value',Namespaces,''); + XMLConfig.SetDeleteValue(Path+'ObjectPath/Value',f(ObjectPath),''); + XMLConfig.SetDeleteValue(Path+'UnitPath/Value',f(UnitPath),''); + XMLConfig.SetDeleteValue(Path+'SrcPath/Value',f(SrcPath),''); +end; + +function TAdditionalCompilerOptions.GetOwnerName: string; +begin + if fOwner<>nil then + Result:=fOwner.Classname + else + Result:='Has no owner'; +end; + +function TAdditionalCompilerOptions.GetOption(AnOption: TInheritedCompilerOption + ): string; +begin + Result:=''; + case AnOption of + icoNone: Result:=''; + icoUnitPath: Result:=UnitPath; + icoNamespaces: Result:=Namespaces; + icoIncludePath: Result:=IncludePath; + icoObjectPath: Result:=ObjectPath; + icoLibraryPath: Result:=LibraryPath; + icoSrcPath: Result:=SrcPath; + icoLinkerOptions: Result:=LinkerOptions; + icoCustomOptions: Result:=CustomOptions; + else + RaiseGDBException(''){%H-}; // inconsistency detected + end; +end; + +function TAdditionalCompilerOptions.GetLazCompilerOptions: TLazCompilerOptions; +begin + Result:=nil; +end; + + +end. + diff --git a/ide/project.pp b/ide/project.pp index c33b3a056f..09429335d0 100644 --- a/ide/project.pp +++ b/ide/project.pp @@ -66,7 +66,7 @@ uses EnvironmentOpts, LazConf, TransferMacros, SearchPathProcs, IdeXmlConfigProcs, IDECmdLine, IDEProcs, CompOptsModes, ModeMatrixOpts, // IDE - ProjectResources, ProjectIcon, CompilerOptions, RunParamsOpts, + ProjectResources, ProjectIcon, ParsedCompilerOpts, CompilerOptions, RunParamsOpts, ProjectDefs, EditDefineTree, LazarusIDEStrConsts, ProjPackCommon, PackageDefs, PackageSystem; diff --git a/ide/showcompileropts.pas b/ide/showcompileropts.pas index 7f6144be95..8f8fe377a8 100644 --- a/ide/showcompileropts.pas +++ b/ide/showcompileropts.pas @@ -47,7 +47,7 @@ uses PackageIntf, MacroIntf, // IDE LazarusIDEStrConsts, Project, PackageDefs, - CompilerOptions, ModeMatrixOpts, MiscOptions; + ParsedCompilerOpts, CompilerOptions, ModeMatrixOpts, MiscOptions; type TShowCompToolOpts = class @@ -320,7 +320,7 @@ var i: integer; AncestorOptions: TAdditionalCompilerOptions; AncestorNode: TTreeNode; - AncestorBaseOpts: TBaseCompilerOptions; + AncestorBaseOpts: TLazCompilerOptions; Vars: TCTCfgScriptVariables; Macro: TLazBuildMacro; j: Integer; @@ -444,7 +444,7 @@ begin AncestorNode.Text := AncestorOptions.GetOwnerName; AncestorNode.ImageIndex := ImageIndexPackage; AncestorNode.SelectedIndex := AncestorNode.ImageIndex; - AncestorBaseOpts:=AncestorOptions.GetBaseCompilerOptions; + AncestorBaseOpts:=AncestorOptions.GetLazCompilerOptions; with AncestorOptions.ParsedOpts do begin AddChildNode(lisunitPath, diff --git a/ide/sourcefilemanager.pas b/ide/sourcefilemanager.pas index 34abca2059..95cd044fbe 100644 --- a/ide/sourcefilemanager.pas +++ b/ide/sourcefilemanager.pas @@ -57,7 +57,7 @@ uses // IDE DialogProcs, IDEProtocol, LazarusIDEStrConsts, NewDialog, NewProjectDlg, MainBase, MainBar, MainIntf, Project, ProjectDefs, - ProjectInspector, CompilerOptions, SourceSynEditor, SourceEditor, + ProjectInspector, ParsedCompilerOpts, CompilerOptions, SourceSynEditor, SourceEditor, EditorOptions, CustomFormEditor, ControlSelection, FormEditor, EmptyMethodsDlg, BaseDebugManager, BuildManager, EditorMacroListViewer, FindRenameIdentifier, BuildModesManager, ViewUnit_Dlg, diff --git a/packager/interpkgconflictfiles.pas b/packager/interpkgconflictfiles.pas index 644b3f8169..f260a42632 100644 --- a/packager/interpkgconflictfiles.pas +++ b/packager/interpkgconflictfiles.pas @@ -66,7 +66,7 @@ uses // IdeConfig EnvironmentOpts, TransferMacros, IDEProcs, SearchPathProcs, // IDE - CompilerOptions, DialogProcs, LazarusIDEStrConsts, PackageDefs, PackageSystem; + ParsedCompilerOpts, CompilerOptions, DialogProcs, LazarusIDEStrConsts, PackageDefs, PackageSystem; type TPGInterPkgOwnerInfo = class diff --git a/packager/packagedefs.pas b/packager/packagedefs.pas index 391efac28d..2c9ef5a13b 100644 --- a/packager/packagedefs.pas +++ b/packager/packagedefs.pas @@ -48,12 +48,13 @@ uses FileUtil, LazFileUtils, LazUtilities, LazFileCache, LazUTF8, FileReferenceList, LazTracer, LazLoggerBase, Laz2_XMLCfg, AvgLvlTree, // BuildIntf - MacroIntf, MacroDefIntf, IDEOptionsIntf, PublishModuleIntf, ComponentReg, + MacroIntf, MacroDefIntf, CompOptsIntf, IDEOptionsIntf, PublishModuleIntf, ComponentReg, PackageDependencyIntf, PackageIntf, FppkgIntf, LazMsgWorker, BaseIDEIntf, // IdeConfig TransferMacros, IDEProcs, IDEOptionDefs, CompOptsModes, SearchPathProcs, IdeXmlConfigProcs, // IDE - EditDefineTree, CompilerOptions, ProjPackCommon, LazarusIDEStrConsts, FppkgHelper; + EditDefineTree, ParsedCompilerOpts, CompilerOptions, ProjPackCommon, + LazarusIDEStrConsts, FppkgHelper; type TLazPackage = class; @@ -394,7 +395,7 @@ type constructor Create(ThePackage: TLazPackage); procedure AssignOptions(Source: TObject); override; function GetOwnerName: string; override; - function GetBaseCompilerOptions: TBaseCompilerOptions; override; + function GetLazCompilerOptions: TLazCompilerOptions; override; public property LazPackage: TLazPackage read FLazPackage write SetLazPackage; end; @@ -4377,7 +4378,7 @@ begin Result:=LazPackage.IDAsString; end; -function TPkgAdditionalCompilerOptions.GetBaseCompilerOptions: TBaseCompilerOptions; +function TPkgAdditionalCompilerOptions.GetLazCompilerOptions: TLazCompilerOptions; begin Result:=LazPackage.CompilerOptions; end; diff --git a/packager/packageeditor.pas b/packager/packageeditor.pas index 41bc41cd3e..9769aee997 100644 --- a/packager/packageeditor.pas +++ b/packager/packageeditor.pas @@ -52,7 +52,7 @@ uses // IdeConfig EnvironmentOpts, SearchPathProcs, // IDE - MainBase, DialogProcs, LazarusIDEStrConsts, IDEDefs, CompilerOptions, + MainBase, DialogProcs, LazarusIDEStrConsts, IDEDefs, ParsedCompilerOpts, CompilerOptions, PackageSystem, PackageDefs, AddToPackageDlg, AddPkgDependencyDlg, ComponentPalette, AddFPMakeDependencyDlg, ProjPackChecks, PkgVirtualUnitEditor, CleanPkgDeps, MissingPkgFilesDlg, ProjPackFilePropGui, ProjPackEditing, BasePkgManager; diff --git a/packager/packagesystem.pas b/packager/packagesystem.pas index 89990af4b2..4565ce7312 100644 --- a/packager/packagesystem.pas +++ b/packager/packagesystem.pas @@ -63,7 +63,7 @@ uses // IdeConfig EnvironmentOpts, LazConf, TransferMacros, IDEProcs, SearchPathProcs, // IDE - LazarusIDEStrConsts, DialogProcs, IDETranslations, CompilerOptions, + LazarusIDEStrConsts, DialogProcs, IDETranslations, ParsedCompilerOpts, CompilerOptions, PackageLinks, PackageDefs, FppkgHelper, PkgSysBasePkgs; const diff --git a/packager/pkgmanager.pas b/packager/pkgmanager.pas index 614cc6d812..1497c8a5c7 100644 --- a/packager/pkgmanager.pas +++ b/packager/pkgmanager.pas @@ -71,7 +71,7 @@ uses // IDE LazarusIDEStrConsts, DialogProcs, MiscOptions, Project, ProjPackEditing, AddToPackageDlg, PackageDefs, PackageLinks, PackageSystem, - OpenInstalledPkgDlg, PkgGraphExplorer, BrokenDependenciesDlg, CompilerOptions, + OpenInstalledPkgDlg, PkgGraphExplorer, BrokenDependenciesDlg, ParsedCompilerOpts, CompilerOptions, IDETranslations, BuildLazDialog, NewDialog, FindInFilesDlg, ProjectInspector, PackageEditor, SourceEditor, ProjPackChecks, AddFileToAPackageDlg, PublishModuleDlg, PkgLinksDlg, InterPkgConflictFiles, InstallPkgSetDlg,