diff --git a/components/buildintf/compoptsintf.pas b/components/buildintf/compoptsintf.pas index 1dd5c46c13..9638a7131e 100644 --- a/components/buildintf/compoptsintf.pas +++ b/components/buildintf/compoptsintf.pas @@ -153,7 +153,6 @@ type private FOnModified: TNotifyEvent; fOwner: TObject; - FSubtarget: string; SetEmulatedFloatOpcodes: boolean; function GetDebugInfoTypeStr: String; procedure SetAllowLabel(const AValue: Boolean); @@ -213,6 +212,7 @@ type procedure SetVarsInReg(const AValue: Boolean); procedure SetVerifyObjMethodCall(const AValue: boolean); procedure SetWin32GraphicApp(const AValue: boolean); + procedure SetWriteConfigFile(AValue: Boolean); procedure SetWriteFPCLogo(const AValue: Boolean); protected FChangeStamp: int64; @@ -249,6 +249,7 @@ type fTargetOS: String; fTargetCPU: string; fTargetProc: string; + FSubtarget: string; fOptLevel: Integer; fVarsInReg: Boolean; fUncertainOpt: Boolean; @@ -294,6 +295,8 @@ type fExecuteAfter: TLazCompilationToolOptions; // Other: fDontUseConfigFile: Boolean; + FWriteConfigFile: Boolean; + FWriteConfigFilePath: String; fCustomConfigFile: Boolean; fConfigFilePath: String; fUseCommentsInCustomOptions: Boolean; @@ -310,6 +313,7 @@ type function GetSrcPath: string; virtual; abstract; function GetUnitOutputDir: string; virtual; abstract; function GetUnitPaths: String; virtual; abstract; + function GetWriteConfigFilePath: String; virtual; abstract; procedure SetCompilerPath(const AValue: String); virtual; abstract; procedure SetConditionals(AValue: string); virtual; abstract; procedure SetCustomOptions(const AValue: string); virtual; abstract; @@ -328,6 +332,7 @@ type procedure SetTargetProc(const AValue: string); virtual; abstract; procedure SetUnitOutputDir(const AValue: string); virtual; abstract; procedure SetUnitPaths(const AValue: String); virtual; abstract; + procedure SetWriteConfigFilePath(AValue: String); virtual; abstract; public constructor Create(const TheOwner: TObject); virtual; destructor Destroy; override; @@ -467,6 +472,8 @@ type property ExecuteAfter: TLazCompilationToolOptions read fExecuteAfter; // other property DontUseConfigFile: Boolean read fDontUseConfigFile write SetDontUseConfigFile; + property WriteConfigFile: Boolean read FWriteConfigFile write SetWriteConfigFile; + property WriteConfigFilePath: String read GetWriteConfigFilePath write SetWriteConfigFilePath; property CustomConfigFile: Boolean read fCustomConfigFile write SetCustomConfigFile; property ConfigFilePath: String read fConfigFilePath write SetConfigFilePath; property CustomOptions: string read GetCustomOptions write SetCustomOptions; @@ -968,6 +975,13 @@ begin IncreaseChangeStamp; end; +procedure TLazCompilerOptions.SetWriteConfigFile(AValue: Boolean); +begin + if FWriteConfigFile=AValue then Exit; + FWriteConfigFile:=AValue; + IncreaseChangeStamp; +end; + procedure TLazCompilerOptions.SetWriteFPCLogo(const AValue: Boolean); begin if fWriteFPCLogo=AValue then exit; diff --git a/ide/buildmanager.pas b/ide/buildmanager.pas index 2234b3ee7d..67e961cbcb 100644 --- a/ide/buildmanager.pas +++ b/ide/buildmanager.pas @@ -1388,7 +1388,7 @@ begin //DebugLn([DbgCap,'CompilerFilename="',CompilerFilename,'" CompilerPath="',AProject.CompilerOptions.CompilerPath,'"']); // Note: use absolute paths, because some external tools resolve symlinked directories CompilerParams := - AProject.CompilerOptions.MakeOptionsString([ccloAbsolutePaths]); + AProject.CompilerOptions.MakeCompilerParams([ccloAbsolutePaths]); try CompilerParams.Add(SrcFilename); diff --git a/ide/checkcompileropts.pas b/ide/checkcompileropts.pas index 89ed69db44..cbfbe7692d 100644 --- a/ide/checkcompileropts.pas +++ b/ide/checkcompileropts.pas @@ -332,7 +332,7 @@ begin CmdLineParams:=nil; try // create compiler command line options - CmdLineParams:=Options.MakeOptionsString( + CmdLineParams:=Options.MakeCompilerParams( [ccloAddVerboseAll,ccloDoNotAppendOutFileOption,ccloAbsolutePaths]); CmdLineParams.Add(BogusFilename); CompileTool:=ExternalToolList.Add(dlgCCOTestToolCompilingEmptyFile); diff --git a/ide/compiler.pp b/ide/compiler.pp index 3739c4044c..18e83e6454 100644 --- a/ide/compiler.pp +++ b/ide/compiler.pp @@ -275,7 +275,6 @@ function TCompiler.Compile(AProject: TProject; const WorkingDir, SkipAssembler, CurrentDirectoryIsTestDir: boolean; const aCompileHint: string ): TModalResult; var - Abort : Boolean; Tool: TAbstractExternalTool; FPCParser: TFPCParser; Title: String; diff --git a/ide/compileroptions.pp b/ide/compileroptions.pp index 16e4e79134..0b30aa0b16 100644 --- a/ide/compileroptions.pp +++ b/ide/compileroptions.pp @@ -190,7 +190,8 @@ type pcosOutputDir, // the output directory pcosCompilerPath, // the filename of the compiler pcosDebugPath, // additional debug search path - pcosMsgFile // fpc message file (errore.msg) + pcosMsgFile, // fpc message file (errore.msg) + pcosWriteConfigFilePath // auto generated cfg file ); TParsedCompilerOptStrings = set of TParsedCompilerOptString; @@ -198,15 +199,16 @@ type const ParsedCompilerSearchPaths = [pcosUnitPath,pcosIncludePath,pcosObjectPath, pcosLibraryPath,pcosSrcPath,pcosDebugPath]; - ParsedCompilerFilenames = [pcosCompilerPath,pcosMsgFile]; + ParsedCompilerExecutables = [pcosCompilerPath]; + ParsedCompilerFilenames = ParsedCompilerExecutables+[pcosMsgFile,pcosWriteConfigFilePath]; ParsedCompilerDirectories = [pcosOutputDir]; ParsedCompilerOutDirectories = [pcosOutputDir]; ParsedCompilerFiles = ParsedCompilerSearchPaths+ParsedCompilerFilenames+ParsedCompilerDirectories; ParsedCompilerOptsVars: array[TParsedCompilerOptString] of string = ( - '', - '', + '', // pcosNone + '', // pcosBaseDir 'UnitPath', 'Namespaces', 'IncPath', @@ -218,11 +220,12 @@ const 'OutputDir', 'CompilerPath', 'DebugPath', - 'MsgFile' + 'MsgFile', + 'WriteCfgFile' ); ParsedCompilerOptsUsageVars: array[TParsedCompilerOptString] of string = ( - '', - '', + '', // pcosNone + '', // pcosBaseDir 'UsageUnitPath', 'UsageNamespaces', 'UsageIncPath', @@ -231,10 +234,11 @@ const 'UsageSrcPath', 'UsageLinkerOptions', 'UsageCustomOptions', - '', - '', - 'UsageDebugPath', - '' + '', // pcosOutputDir + '', // pcosCompilerPath + 'UsageDebugPath', // pcosDebugPath + '', // pcosMsgFile + '' // pcosWriteConfigFilePath ); InheritedToParsedCompilerOption: array[TInheritedCompilerOption] of TParsedCompilerOptString = ( @@ -432,6 +436,7 @@ type function GetSrcPath: string; override; function GetUnitOutputDir: string; override; function GetUnitPaths: String; override; + function GetWriteConfigFilePath: String; override; procedure SetBaseDirectory(AValue: string); procedure SetCompilerPath(const AValue: String); override; procedure SetConditionals(AValue: string); override; @@ -450,6 +455,7 @@ type procedure SetTargetOS(const AValue: string); override; procedure SetTargetFileExt(const AValue: String); override; procedure SetTargetFilename(const AValue: String); override; + procedure SetWriteConfigFilePath(AValue: String); override; protected function GetModified: boolean; override; procedure SetModified(const AValue: boolean); override; @@ -476,7 +482,7 @@ type procedure SetAlternativeCompile(const Command: string; ScanFPCMsgs: boolean); override; - function MakeOptionsString(Flags: TCompilerCmdLineOptions): TStringListUTF8Fast; + function MakeCompilerParams(Flags: TCompilerCmdLineOptions): TStringListUTF8Fast; procedure GetSyntaxOptions(Kind: TPascalCompiler; Params: TStrings); virtual; function CreatePPUFilename(const SourceFileName: string): string; override; function CreateTargetFilename: string; override; @@ -490,6 +496,7 @@ type Parsed: TCompilerOptionsParseType = coptParsed ): string; virtual; function GetDefaultMainSourceFileName: string; virtual; + function GetDefaultWriteConfigFilePath: string; virtual; abstract; function CanBeDefaulForProject: boolean; virtual; function NeedsLinkerOpts: boolean; function HasCommands: boolean; // true if there is at least one commad to execute @@ -1309,6 +1316,16 @@ begin IncreaseChangeStamp; end; +procedure TBaseCompilerOptions.SetWriteConfigFilePath(AValue: String); +begin + if WriteConfigFilePath=AValue then exit; + ParsedOpts.SetUnparsedValue(pcosWriteConfigFilePath,AValue); + {$IFDEF VerboseIDEModified} + debugln(['TBaseCompilerOptions.SetWriteConfigFilePath ',AValue]); + {$ENDIF} + IncreaseChangeStamp; +end; + function TBaseCompilerOptions.GetModified: boolean; begin Result:=(inherited GetModified) or MessageFlags.Modified; @@ -1379,6 +1396,11 @@ begin Result:=ParsedOpts.Values[pcosUnitPath].UnparsedValue; end; +function TBaseCompilerOptions.GetWriteConfigFilePath: String; +begin + Result:=ParsedOpts.Values[pcosWriteConfigFilePath].UnparsedValue; +end; + function TBaseCompilerOptions.GetExecuteAfter: TCompilationToolOptions; begin Result:=TCompilationToolOptions(fExecuteAfter); @@ -1716,6 +1738,8 @@ begin { Other } p:=Path+'Other/'; DontUseConfigFile := aXMLConfig.GetValue(p+'ConfigFile/DontUseConfigFile/Value', false); + WriteConfigFile := aXMLConfig.GetValue(p+'ConfigFile/WriteConfigFile/Value', false); + WriteConfigFilePath := f(aXMLConfig.GetValue(p+'ConfigFile/WriteConfigFilePath/Value', GetDefaultWriteConfigFilePath)); if FileVersion<=3 then CustomConfigFile := aXMLConfig.GetValue(p+'ConfigFile/AdditionalConfigFile/Value', false) else @@ -1909,6 +1933,8 @@ begin { Other } p:=Path+'Other/'; aXMLConfig.SetDeleteValue(p+'ConfigFile/DontUseConfigFile/Value', DontUseConfigFile,false); + aXMLConfig.SetDeleteValue(p+'ConfigFile/WriteConfigFile/Value', WriteConfigFile,false); + aXMLConfig.SetDeleteValue(p+'ConfigFile/WriteConfigFilePath/Value', f(WriteConfigFilePath),GetDefaultWriteConfigFilePath); aXMLConfig.SetDeleteValue(p+'ConfigFile/CustomConfigFile/Value', CustomConfigFile,false); aXMLConfig.SetDeleteValue(p+'ConfigFile/ConfigFilePath/Value', f(ConfigFilePath),'extrafpc.cfg'); aXMLConfig.SetDeleteValue(p+'CustomOptions/Value', @@ -2480,7 +2506,7 @@ var Params: TStringListUTF8Fast; h: String; begin - Params:=MakeOptionsString([ccloNoMacroParams]); + Params:=MakeCompilerParams([ccloNoMacroParams]); try Result:=MergeCmdLineParams(Params); h:=GetCustomOptions(coptParsed); @@ -2560,13 +2586,13 @@ begin end; {------------------------------------------------------------------------------ - function TBaseCompilerOptions.MakeOptionsString( + function TBaseCompilerOptions.MakeCompilerParams( const MainSourceFilename: string; Flags: TCompilerCmdLineOptions): String; Get all the options and create a string that can be passed to the compiler ------------------------------------------------------------------------------} -function TBaseCompilerOptions.MakeOptionsString(Flags: TCompilerCmdLineOptions +function TBaseCompilerOptions.MakeCompilerParams(Flags: TCompilerCmdLineOptions ): TStringListUTF8Fast; var tempsw, quietsw, t: String; @@ -3363,6 +3389,7 @@ begin if Done(Tool.AddDiff('TargetOS',fTargetOS,CompOpts.fTargetOS)) then exit; if Done(Tool.AddDiff('TargetCPU',fTargetCPU,CompOpts.fTargetCPU)) then exit; if Done(Tool.AddDiff('TargetProc',fTargetProc,CompOpts.fTargetProc)) then exit; + if Done(Tool.AddDiff('Subtarget',FSubtarget,CompOpts.FSubtarget)) then exit; if Done(Tool.AddDiff('OptLevel',fOptLevel,CompOpts.fOptLevel)) then exit; if Done(Tool.AddDiff('VarsInReg',fVarsInReg,CompOpts.fVarsInReg)) then exit; if Done(Tool.AddDiff('UncertainOpt',fUncertainOpt,CompOpts.fUncertainOpt)) then exit; @@ -3408,6 +3435,8 @@ begin // other if Tool<>nil then Tool.Path:='Other'; if Done(Tool.AddDiff('DontUseConfigFile',fDontUseConfigFile,CompOpts.fDontUseConfigFile)) then exit; + if Done(Tool.AddDiff('WriteConfigFile',FWriteConfigFile,CompOpts.FWriteConfigFile)) then exit; + if Done(Tool.AddDiff('WriteConfigFilePath',FWriteConfigFilePath,CompOpts.FWriteConfigFilePath)) then exit; if Done(Tool.AddDiff('CustomConfigFile',fCustomConfigFile,CompOpts.fCustomConfigFile)) then exit; if Done(Tool.AddDiff('ConfigFilePath',fConfigFilePath,CompOpts.fConfigFilePath)) then exit; if Done(Tool.AddDiff('StopAfterErrCount',fStopAfterErrCount,CompOpts.fStopAfterErrCount)) then exit; @@ -3731,7 +3760,7 @@ begin Result:=MergeCustomOptions(Result,MoreOptions); end; end; - pcosOutputDir,pcosCompilerPath: + pcosOutputDir,pcosCompilerPath,pcosWriteConfigFilePath: if Vars.IsDefined(PChar(VarName)) then Result:=GetForcedPathDelims(Vars[VarName]); end @@ -3862,7 +3891,8 @@ begin begin // make filename absolute //debugln(['TParsedCompilerOptions.DoParseOption ',ParsedCompilerOptsVars[Option],' s="',s,'"']); - if ExtractFilePath(s)='' then begin + if (Option in ParsedCompilerExecutables) and (ExtractFilePath(s)='') then + begin h:=FileUtil.FindDefaultExecutablePath(s,GetBaseDir); if h<>'' then s:=h; end; diff --git a/ide/frames/compiler_config_target.lfm b/ide/frames/compiler_config_target.lfm index b67f19f9a3..249f9605fb 100644 --- a/ide/frames/compiler_config_target.lfm +++ b/ide/frames/compiler_config_target.lfm @@ -6,67 +6,100 @@ object CompilerConfigTargetFrame: TCompilerConfigTargetFrame ClientHeight = 446 ClientWidth = 594 TabOrder = 0 - DesignLeft = 338 - DesignTop = 284 + DesignLeft = 436 + DesignTop = 273 object grbConfigFile: TGroupBox Left = 0 - Height = 101 + Height = 139 Top = 0 Width = 594 Align = alTop AutoSize = True Caption = 'grbConfigFile' - ClientHeight = 74 + ClientHeight = 112 ClientWidth = 584 TabOrder = 0 object chkConfigFile: TCheckBox + AnchorSideLeft.Control = grbConfigFile + AnchorSideTop.Control = grbConfigFile Left = 6 Height = 18 - Top = 6 - Width = 572 - Align = alTop + Top = 3 + Width = 104 BorderSpacing.Left = 6 - BorderSpacing.Top = 6 - BorderSpacing.Right = 6 + BorderSpacing.Top = 3 Caption = 'chkConfigFile' TabOrder = 0 end - object chkCustomConfigFile: TCheckBox + object chkWriteConfigFile: TCheckBox + AnchorSideLeft.Control = chkConfigFile + AnchorSideTop.Control = chkConfigFile + AnchorSideTop.Side = asrBottom + AnchorSideRight.Side = asrBottom Left = 6 Height = 18 - Top = 27 - Width = 572 - Align = alTop - BorderSpacing.Left = 6 + Top = 24 + Width = 134 BorderSpacing.Top = 3 - BorderSpacing.Right = 6 - Caption = 'chkCustomConfigFile' - OnClick = chkCustomConfigFileClick - TabOrder = 1 + Caption = 'chkWriteConfigFile' + OnClick = chkWriteConfigFileClick + TabOrder = 3 end - object edtConfigPath: TEdit - AnchorSideLeft.Control = chkCustomConfigFile - AnchorSideTop.Control = chkCustomConfigFile + object edtWriteConfigFilePath: TEdit + AnchorSideLeft.Control = chkWriteConfigFile + AnchorSideTop.Control = chkWriteConfigFile AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = chkCustomConfigFile + AnchorSideRight.Control = grbConfigFile AnchorSideRight.Side = asrBottom Left = 25 Height = 22 - Top = 46 + Top = 43 Width = 553 Anchors = [akTop, akLeft, akRight] BorderSpacing.Left = 19 BorderSpacing.Top = 1 - BorderSpacing.Bottom = 6 + BorderSpacing.Right = 6 + BorderSpacing.Bottom = 3 + TabOrder = 4 + Text = 'edtWriteConfigFilePath' + end + object chkCustomConfigFile: TCheckBox + AnchorSideLeft.Control = chkConfigFile + AnchorSideTop.Control = edtWriteConfigFilePath + AnchorSideTop.Side = asrBottom + Left = 6 + Height = 18 + Top = 68 + Width = 147 + BorderSpacing.Top = 3 + Caption = 'chkCustomConfigFile' + OnClick = chkCustomConfigFileClick + TabOrder = 1 + end + object edtCustomConfigPath: TEdit + AnchorSideLeft.Control = chkCustomConfigFile + AnchorSideTop.Control = chkCustomConfigFile + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = grbConfigFile + AnchorSideRight.Side = asrBottom + Left = 25 + Height = 22 + Top = 87 + Width = 553 + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Left = 19 + BorderSpacing.Top = 1 + BorderSpacing.Right = 6 + BorderSpacing.Bottom = 3 TabOrder = 2 - Text = 'edtConfigPath' + Text = 'edtCustomConfigPath' end end object grbTargetPlatform: TGroupBox AnchorSideBottom.Side = asrBottom Left = 0 Height = 125 - Top = 109 + Top = 147 Width = 594 Align = alTop AutoSize = True @@ -116,7 +149,7 @@ object CompilerConfigTargetFrame: TCompilerConfigTargetFrame Left = 6 Height = 16 Top = 74 - Width = 75 + Width = 74 Caption = 'lblSubtarget' ParentColor = False end @@ -189,10 +222,10 @@ object CompilerConfigTargetFrame: TCompilerConfigTargetFrame AnchorSideTop.Side = asrBottom AnchorSideRight.Control = grbTargetPlatform AnchorSideRight.Side = asrBottom - Left = 87 + Left = 86 Height = 20 Top = 72 - Width = 491 + Width = 492 Anchors = [akTop, akLeft, akRight] BorderSpacing.Left = 6 BorderSpacing.Top = 3 @@ -206,7 +239,7 @@ object CompilerConfigTargetFrame: TCompilerConfigTargetFrame object grbTargetOptions: TGroupBox Left = 0 Height = 57 - Top = 242 + Top = 280 Width = 594 Align = alTop AutoSize = True @@ -231,7 +264,7 @@ object CompilerConfigTargetFrame: TCompilerConfigTargetFrame AnchorSideTop.Side = asrBottom Left = 16 Height = 16 - Top = 327 + Top = 365 Width = 128 BorderSpacing.Top = 3 Caption = 'LCLWidgetTypeLabel' @@ -247,7 +280,7 @@ object CompilerConfigTargetFrame: TCompilerConfigTargetFrame AnchorSideTop.Side = asrBottom Left = 3 Height = 16 - Top = 308 + Top = 346 Width = 151 BorderSpacing.Top = 9 Caption = 'CurrentWidgetTypeLabel' diff --git a/ide/frames/compiler_config_target.pas b/ide/frames/compiler_config_target.pas index 8cf9d9fcd7..f3d9844b5b 100644 --- a/ide/frames/compiler_config_target.pas +++ b/ide/frames/compiler_config_target.pas @@ -48,8 +48,10 @@ type TCompilerConfigTargetFrame = class(TAbstractIDEOptionsEditor) chkConfigFile: TCheckBox; chkCustomConfigFile: TCheckBox; + chkWriteConfigFile: TCheckBox; chkWin32GraphicApp: TCheckBox; - edtConfigPath: TEdit; + edtCustomConfigPath: TEdit; + edtWriteConfigFilePath: TEdit; grbTargetOptions: TGroupBox; grbConfigFile: TGroupBox; grbTargetPlatform: TGroupBox; @@ -64,6 +66,7 @@ type TargetProcComboBox: TComboBox; SubtargetComboBox: TComboBox; procedure chkCustomConfigFileClick(Sender: TObject); + procedure chkWriteConfigFileClick(Sender: TObject); procedure TargetOSComboBoxSelect(Sender: TObject); procedure TargetCPUComboBoxSelect(Sender: TObject); procedure LCLWidgetTypeLabelClick(Sender: TObject); @@ -158,16 +161,14 @@ end; function TCompilerConfigTargetFrame.Check: Boolean; var - NewDontUseConfigFile: Boolean; - NewCustomConfigFile: Boolean; - NewConfigFilePath: String; - AdditionalConfig: String; + NewDontUseConfigFile, NewCustomConfigFile: Boolean; + NewConfigFilePath, AdditionalConfig: String; begin //debugln(['TCompilerConfigTargetFrame.ReadSettings ',dbgs(Pointer(FCompOptions)),' ',FCompOptions=Project1.CompilerOptions]); NewDontUseConfigFile := not chkConfigFile.Checked; NewCustomConfigFile := chkCustomConfigFile.Checked; - NewConfigFilePath := edtConfigPath.Text; + NewConfigFilePath := edtCustomConfigPath.Text; if ((NewDontUseConfigFile <> FCompOptions.DontUseConfigFile) or (NewCustomConfigFile <> FCompOptions.CustomConfigFile) or @@ -176,9 +177,8 @@ begin begin // config file options changed // and both additional and standard config files are used - AdditionalConfig := ExtractFilename(edtConfigPath.Text); - if (CompareFileNames(AdditionalConfig, 'fpc.cfg') = 0) or - (CompareFileNames(AdditionalConfig, 'ppc386.cfg') = 0) then + AdditionalConfig := ExtractFilename(edtCustomConfigPath.Text); + if (CompareFileNames(AdditionalConfig, 'fpc.cfg') = 0) then begin if IDEMessageDialog(lisCOAmbiguousAdditionalCompilerConfigFile, Format(lisCOClickOKIfAreSureToDoThat, @@ -270,8 +270,10 @@ begin // Config grbConfigFile.Caption := dlgConfigFiles; chkConfigFile.Caption := dlgUseFpcCfg + ' ('+lisIfNotChecked+' -n)'; + chkWriteConfigFile.Caption := lisWriteConfigInsteadOfCommandLineParameters+' (@)'; + edtWriteConfigFilePath.Text := ''; chkCustomConfigFile.Caption := dlgUseCustomConfig + ' (@)'; - edtConfigPath.Text := ''; + edtCustomConfigPath.Text := ''; // Target platform grbTargetPlatform.Caption := dlgTargetPlatform; @@ -329,9 +331,12 @@ begin with FCompOptions do begin chkConfigFile.Checked := not DontUseConfigFile; + chkWriteConfigFile.Checked := WriteConfigFile; + edtWriteConfigFilePath.Enabled:= WriteConfigFile; + edtWriteConfigFilePath.Text := WriteConfigFilePath; chkCustomConfigFile.Checked := CustomConfigFile; - edtConfigPath.Enabled := chkCustomConfigFile.Checked; - edtConfigPath.Text := ConfigFilePath; + edtCustomConfigPath.Enabled := chkCustomConfigFile.Checked; + edtCustomConfigPath.Text := ConfigFilePath; if fIsPackage then begin grbTargetPlatform.Visible:=false; TargetOSComboBox.ItemIndex := 0; @@ -386,8 +391,10 @@ begin with CurOptions do begin DontUseConfigFile := not chkConfigFile.Checked; + WriteConfigFile := chkWriteConfigFile.Checked; + WriteConfigFilePath := edtWriteConfigFilePath.Text; CustomConfigFile := chkCustomConfigFile.Checked; - ConfigFilePath := edtConfigPath.Text; + ConfigFilePath := edtCustomConfigPath.Text; if not fIsPackage then begin NewTargetOS := TargetOSComboBox.Text; @@ -407,7 +414,12 @@ end; procedure TCompilerConfigTargetFrame.chkCustomConfigFileClick(Sender: TObject); begin - edtConfigPath.Enabled := chkCustomConfigFile.Checked; + edtCustomConfigPath.Enabled := chkCustomConfigFile.Checked; +end; + +procedure TCompilerConfigTargetFrame.chkWriteConfigFileClick(Sender: TObject); +begin + edtWriteConfigFilePath.Enabled := chkWriteConfigFile.Checked; end; procedure TCompilerConfigTargetFrame.TargetOSComboBoxSelect(Sender: TObject); diff --git a/ide/lazarusidestrconsts.pas b/ide/lazarusidestrconsts.pas index 16fbb1ff87..b03ec0a250 100644 --- a/ide/lazarusidestrconsts.pas +++ b/ide/lazarusidestrconsts.pas @@ -2425,6 +2425,8 @@ resourcestring dlgConfigFiles = 'Config files'; dlgUseFpcCfg = 'Use standard compiler config file (fpc.cfg)'; lisIfNotChecked = 'If not checked:'; + lisWriteConfigInsteadOfCommandLineParameters = 'Write config instead of ' + +'command line parameters'; dlgUseCustomConfig = 'Use additional compiler config file'; lisAllOptions = 'All Options'; lisFilterTheAvailableOptionsList = 'Filter the available options list'; diff --git a/ide/lazbuild.lpr b/ide/lazbuild.lpr index 5be8ebae08..0b4c8244e0 100644 --- a/ide/lazbuild.lpr +++ b/ide/lazbuild.lpr @@ -769,7 +769,7 @@ var CompilerFilename: String; WorkingDir: String; SrcFilename: String; - CompilerParams: TStrings; + CompilerParams, CmdLineParams: TStrings; ToolBefore: TProjectCompilationToolOptions; ToolAfter: TProjectCompilationToolOptions; UnitOutputDirectory: String; @@ -785,6 +785,8 @@ var CurResult: Boolean; function StartBuilding : boolean; + var + CfgCode: TCodeBuffer; begin Result := false; @@ -805,6 +807,7 @@ var MainBuildBoss.SetBuildTargetProject1(true,smsfsSkip); CompilerParams:=nil; + CmdLineParams:=nil; try if not SkipDependencies then begin @@ -883,16 +886,25 @@ var //DebugLn(['TLazBuildApplication.BuildProject CompilerFilename="',CompilerFilename,'" CompilerPath="',Project1.CompilerOptions.CompilerPath,'"']); // CompileHint: use absolute paths, same as TBuildManager.DoCheckIfProjectNeedsCompilation - CompilerParams:=Project1.CompilerOptions.MakeOptionsString([ccloAbsolutePaths]); + CompilerParams:=Project1.CompilerOptions.MakeCompilerParams([ccloAbsolutePaths]); CompilerParams.Add(SrcFilename); if (CompReason in Project1.CompilerOptions.CompileReasons) then begin // compile + if Project1.CompilerOptions.WriteConfigFile then + begin + CfgCode:=Project1.WriteCompilerCfgFile(Project1,CompilerParams,CmdLineParams); + if CfgCode=nil then + Error(ErrorBuildFailed,'unable to read "'+Project1.GetWriteConfigFilePath+'"'); + if CfgCode.FileOnDiskNeedsUpdate and (not CfgCode.Save) then + Error(ErrorBuildFailed,'unable to write "'+Project1.GetWriteConfigFilePath+'"'); + end; + // write state file to avoid building clean every time if Project1.SaveStateFile(CompilerFilename,CompilerParams,false)<>mrOk then Error(ErrorBuildFailed,'failed saving statefile of project '+AFilename); - if TheCompiler.Compile(Project1,WorkingDir,CompilerFilename,CompilerParams, + if TheCompiler.Compile(Project1,WorkingDir,CompilerFilename,CmdLineParams, BuildAll or NeedBuildAllFlag,false,false,false, CompileHint)<>mrOk then @@ -914,6 +926,8 @@ var // no need to check for mrOk, we are exit if it wasn't Result:=true; finally + if CmdLineParams<>CompilerParams then + CmdLineParams.Free; CompilerParams.Free; if not SkipDependencies then PackageGraph.EndUpdate; diff --git a/ide/main.pp b/ide/main.pp index 9251e634e8..1e940c0e71 100644 --- a/ide/main.pp +++ b/ide/main.pp @@ -6834,7 +6834,8 @@ var PkgFlags: TPkgCompileFlags; CompilerFilename: String; WorkingDir: String; - CompilerParams: TStringListUTF8Fast; + CompilerParams: TStrings; + CmdLineParams: TStrings; NeedBuildAllFlag: Boolean; NoBuildNeeded: Boolean; UnitOutputDirectory: String; @@ -6846,6 +6847,7 @@ var IsComplete: Boolean; StartTime: TDateTime; CompilerKind: TPascalCompiler; + CfgCode: TCodeBuffer; begin if DoAbortBuild(true)<>mrOK then begin debugln(['Error: (lazarus) [TMainIDE.DoBuildProject] DoAbortBuild failed']); @@ -6881,6 +6883,7 @@ begin if Result<>mrOk then exit; CompilerParams:=nil; + CmdLineParams:=nil; try Result:=DoSaveForBuild(AReason); if Result<>mrOk then begin @@ -7098,9 +7101,22 @@ begin // compile CompilerFilename:=Project1.GetCompilerFilename; // Hint: use absolute paths, because some external tools resolve symlinked directories - CompilerParams := - Project1.CompilerOptions.MakeOptionsString([ccloAbsolutePaths]); + CompilerParams := Project1.CompilerOptions.MakeCompilerParams([ccloAbsolutePaths]); CompilerParams.Add(SrcFilename); + CmdLineParams := CompilerParams; + + if Project1.CompilerOptions.WriteConfigFile then + begin + CfgCode:=Project1.WriteCompilerCfgFile(Project1,CompilerParams,CmdLineParams); + if CfgCode=nil then begin + IDEMessageDialog(lisReadError,Format(lisUnableToReadFile2, + [Project1.GetWriteConfigFilePath]),mtError,[mbOk]); + exit(mrCancel); + end; + if CfgCode.FileOnDiskNeedsUpdate and (SaveCodeBuffer(CfgCode)<>mrOk) then + exit(mrCancel); + end; + // write state file, to avoid building clean every time Result:=Project1.SaveStateFile(CompilerFilename, CompilerParams,false); @@ -7113,7 +7129,7 @@ begin StartTime:=Now; Result:=TheCompiler.Compile(Project1, - WorkingDir,CompilerFilename,CompilerParams, + WorkingDir,CompilerFilename,CmdLineParams, (AReason = crBuild) or NeedBuildAllFlag, pbfSkipLinking in Flags, pbfSkipAssembler in Flags,Project1.IsVirtual, @@ -7171,6 +7187,8 @@ begin DoCallBuildingFinishedHandler(lihtProjectBuildingFinished, Self, Result=mrOk); end; finally + if CmdLineParams<>CompilerParams then + CmdLineParams.Free; CompilerParams.Free; // check sources DoCheckFilesOnDisk; diff --git a/ide/project.pp b/ide/project.pp index 405d4c1820..1c9096c96d 100644 --- a/ide/project.pp +++ b/ide/project.pp @@ -553,6 +553,7 @@ type function CanBeDefaulForProject: boolean; override; function GetOwnerName: string; override; function GetDefaultMainSourceFileName: string; override; + function GetDefaultWriteConfigFilePath: string; override; procedure GetInheritedCompilerOptions(var OptionsList: TFPList); override; procedure Assign(Source: TPersistent); override; function CreateDiff(CompOpts: TBaseCompilerOptions; @@ -1068,6 +1069,7 @@ type function GetCompilerFilename: string; function GetStateFilename: string; function GetCompileSourceFilename: string; + function GetWriteConfigFilePath: string; procedure AutoAddOutputDirToIncPath; function ExtendUnitSearchPath(NewUnitPaths: string): boolean; function ExtendIncSearchPath(NewIncPaths: string): boolean; @@ -1076,7 +1078,9 @@ type function LoadStateFile(IgnoreErrors: boolean): TModalResult; function SaveStateFile(const CompilerFilename: string; CompilerParams: TStrings; Complete: boolean): TModalResult; - + function WriteCompilerCfgFile(aProject: TProject; CompilerParams: TStrings; + out CmdLineParams: TStrings): TCodeBuffer; + // source editor procedure UpdateAllCustomHighlighter; procedure UpdateAllSyntaxHighlighter; @@ -5166,6 +5170,11 @@ begin Result:=ExtractFilename(MainUnitInfo.Filename); end; +function TProject.GetWriteConfigFilePath: string; +begin + Result:=CompilerOptions.ParsedOpts.GetParsedValue(pcosWriteConfigFilePath); +end; + procedure TProject.AutoAddOutputDirToIncPath; begin if pfLRSFilesInOutputDirectory in Flags then begin @@ -5312,6 +5321,40 @@ begin Result:=mrOk; end; +function TProject.WriteCompilerCfgFile(aProject: TProject; + CompilerParams: TStrings; out CmdLineParams: TStrings): TCodeBuffer; +var + CfgFile, Src, Param: String; + i: Integer; +begin + Result:=nil; + CmdLineParams:=TStringListUTF8Fast.Create; + CmdLineParams.Add('@'+aProject.GetWriteConfigFilePath); + CfgFile:=AProject.GetWriteConfigFilePath; + Src:='# Auto generated by Lazarus. Do not edit.'+LineEnding; + for i:=CompilerParams.Count-1 downto 0 do + begin + Param:=CompilerParams[i]; + if (Param[1]='@') + or (Param='n') + or (Param[1]<>'-') then + CmdLineParams.Insert(1,Param) + else begin + Src+=Param+LineEnding; + CompilerParams.Delete(i); + end; + end; + + Result:=CodeToolBoss.LoadFile(CfgFile,true,true); + if (Result=nil) and FileExistsCached(CfgFile) then + exit; // failed loading old cfg + if (Result<>nil) and (Result.Source=Src) then + exit; // nothing changed -> skip + if Result=nil then + Result:=CodeToolBoss.CreateFile(CfgFile); + Result.Source:=Src; +end; + procedure TProject.UpdateAllCustomHighlighter; var i: Integer; @@ -6507,6 +6550,11 @@ begin Result:=inherited GetDefaultMainSourceFileName; end; +function TProjectCompilerOptions.GetDefaultWriteConfigFilePath: string; +begin + Result:='$(ProjOutDir)'+PathDelim+'fpclaz.cfg'; +end; + procedure TProjectCompilerOptions.GetInheritedCompilerOptions( var OptionsList: TFPList); var diff --git a/ide/showcompileropts.pas b/ide/showcompileropts.pas index a01dbd7c65..7f6144be95 100644 --- a/ide/showcompileropts.pas +++ b/ide/showcompileropts.pas @@ -302,7 +302,7 @@ begin Flags:=CompilerOpts.DefaultMakeOptionsFlags; if not RelativePathsCheckBox.Checked then Include(Flags,ccloAbsolutePaths); - CompOptions := CompilerOpts.MakeOptionsString(Flags); + CompOptions := CompilerOpts.MakeCompilerParams(Flags); try CompPath:=CompilerOpts.ParsedOpts.GetParsedValue(pcosCompilerPath); if Pos(' ',CompPath)>0 then diff --git a/packager/packagedefs.pas b/packager/packagedefs.pas index f144fcc570..aa309e5cd2 100644 --- a/packager/packagedefs.pas +++ b/packager/packagedefs.pas @@ -353,6 +353,7 @@ type procedure GetInheritedCompilerOptions(var OptionsList: TFPList); override; function GetOwnerName: string; override; function GetDefaultMainSourceFileName: string; override; + function GetDefaultWriteConfigFilePath: string; override; function CreateTargetFilename: string; override; function HasCompilerCommand: boolean; override; @@ -4254,6 +4255,11 @@ begin Result:=inherited GetDefaultMainSourceFileName; end; +function TPkgCompilerOptions.GetDefaultWriteConfigFilePath: string; +begin + Result:='$(PkgOutDir)'+PathDelim+'fpclaz.cfg'; +end; + function TPkgCompilerOptions.CreateTargetFilename: string; begin Result:=''; diff --git a/packager/packagesystem.pas b/packager/packagesystem.pas index 93f076e21f..a329c1bc6c 100644 --- a/packager/packagesystem.pas +++ b/packager/packagesystem.pas @@ -1131,7 +1131,7 @@ end; function TLazPackageGraph.GetPackageCompilerParams(APackage: TLazPackage ): TStrings; begin - Result:=APackage.CompilerOptions.MakeOptionsString( + Result:=APackage.CompilerOptions.MakeCompilerParams( APackage.CompilerOptions.DefaultMakeOptionsFlags+[ccloAbsolutePaths]); Result.Add(CreateRelativePath(APackage.GetSrcFilename,APackage.Directory)); end; @@ -4703,7 +4703,7 @@ begin coptParsedPlatformIndependent); CustomOptions:=APackage.CompilerOptions.GetCustomOptions( coptParsedPlatformIndependent); - List:=APackage.CompilerOptions.MakeOptionsString( + List:=APackage.CompilerOptions.MakeCompilerParams( [ccloDoNotAppendOutFileOption,ccloNoMacroParams]); OtherOptions:=MergeCmdLineParams(List); List.Free; @@ -5025,7 +5025,7 @@ begin coptParsedPlatformIndependent); if ConsoleVerbosity>0 then debugln('Hint: (lazarus) Writing fpmake.pp: CustomOptions (orig): ',CustomOptions); - List:=APackage.CompilerOptions.MakeOptionsString( + List:=APackage.CompilerOptions.MakeCompilerParams( [ccloDoNotAppendOutFileOption,ccloNoMacroParams]); if ConsoleVerbosity>0 then debugln('Hint: (lazarus) Writing fpmake.pp: OtherOptions (orig): ',MergeCmdLineParams(List,TLazCompilerOptions.ConsoleParamsMax));