IDE: Separate parsed compiler options code to a new unit ParsedCompilerOpts.

This commit is contained in:
Juha 2024-03-15 14:36:28 +02:00
parent 1580d1778e
commit 3c1c879cf5
19 changed files with 932 additions and 908 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -45,7 +45,7 @@ uses
// IdeConfig
TransferMacros, SearchPathProcs, IDEProcs,
// IDE
Project, PackageSystem, LazarusIDEStrConsts, PackageDefs, CompilerOptions;
Project, PackageSystem, LazarusIDEStrConsts, PackageDefs, ParsedCompilerOpts, CompilerOptions;
type
TCompilerOptionsTest = (

View File

@ -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);

View File

@ -35,7 +35,7 @@ uses
// IdeIntf
IDEOptionsIntf, IDEOptEditorIntf, CompOptsIntf, MacroIntf, IDEImagesIntf, IDEDialogs,
// IDE
CompilerOptions, LazarusIDEStrConsts, PackageDefs;
ParsedCompilerOpts, CompilerOptions, LazarusIDEStrConsts, PackageDefs;
type
TCBMNodeType = (

View File

@ -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

View File

@ -15,7 +15,7 @@ uses
// IdeConfig
SearchPathProcs,
// IDE
Project, CompilerOptions, LazarusIDEStrConsts, PathEditorDlg,
Project, ParsedCompilerOpts, CompilerOptions, LazarusIDEStrConsts, PathEditorDlg,
CheckCompilerOpts, ShowCompilerOpts, ImExportCompilerOpts;
type

View File

@ -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,

897
ide/parsedcompileropts.pas Normal file
View File

@ -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.

View File

@ -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;

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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,