mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-16 01:20:38 +01:00
IDE: fixed checking type of compiler (fpc/pas2js), fixed quoting compiler filename, improved error handling
git-svn-id: trunk@60535 -
This commit is contained in:
parent
acf40b5480
commit
ad2827a4e5
@ -809,11 +809,11 @@ type
|
||||
// values
|
||||
Kind: TPascalCompiler;
|
||||
CompilerDate: longint;
|
||||
RealCompiler: string; // when Compiler is fpc, this is the real compiler (e.g. ppc386)
|
||||
RealCompiler: string; // when Compiler is fpc.exe, this is the real compiler (e.g. ppc386.exe)
|
||||
RealCompilerDate: longint;
|
||||
RealTargetOS: string;
|
||||
RealTargetCPU: string;
|
||||
RealCompilerInPath: string; // the ppc<target> in PATH
|
||||
RealTargetCPUCompiler: string; // the ppc<target>.exe in PATH for TargetCPU
|
||||
FullVersion: string; // Version.Release.Patch
|
||||
ConfigFiles: TPCConfigFileStateList;
|
||||
UnitPaths: TStrings;
|
||||
@ -843,7 +843,7 @@ type
|
||||
function GetFPCInfoCmdLineOptions(ExtraOptions: string): string;
|
||||
function Update(TestFilename: string; ExtraOptions: string = '';
|
||||
const OnProgress: TDefinePoolProgress = nil): boolean;
|
||||
function FindRealCompilerInPath(aTargetCPU: string; ResolveLinks: boolean): string;
|
||||
function FindDefaultTargetCPUCompiler(aTargetCPU: string; ResolveLinks: boolean): string;
|
||||
function GetUnitPaths: string;
|
||||
function GetFPCVerNumbers(out FPCVersion, FPCRelease, FPCPatch: integer): boolean;
|
||||
function GetFPCVer: string; // e.g. 2.7.1
|
||||
@ -1066,11 +1066,14 @@ function GetDefaultCompilerFilename(const TargetCPU: string = ''; Cross: boolean
|
||||
procedure GetTargetProcessors(const TargetCPU: string; aList: TStrings);
|
||||
function GetFPCTargetOS(TargetOS: string): string; // normalize
|
||||
function GetFPCTargetCPU(TargetCPU: string): string; // normalize
|
||||
function GetPascalCompilerFromExeName(Filename: string): TPascalCompiler;
|
||||
|
||||
function IsCTExecutable(AFilename: string; out ErrorMsg: string): boolean; // not thread-safe
|
||||
function IsCompilerExecutable(AFilename: string; out ErrorMsg: string; out Kind: TPascalCompiler): boolean; // not thread-safe
|
||||
function IsFPCExecutable(AFilename: string; out ErrorMsg: string): boolean; // not thread-safe
|
||||
function IsPas2JSExecutable(AFilename: string; out ErrorMsg: string): boolean; // not thread-safe
|
||||
|
||||
function GuessPascalCompilerFromExeName(Filename: string): TPascalCompiler;
|
||||
function IsCompilerExecutable(AFilename: string; out ErrorMsg: string;
|
||||
out Kind: TPascalCompiler; Run: boolean): boolean; // not thread-safe
|
||||
function IsFPCExecutable(AFilename: string; out ErrorMsg: string; Run: boolean): boolean; // not thread-safe
|
||||
function IsPas2JSExecutable(AFilename: string; out ErrorMsg: string; Run: boolean): boolean; // not thread-safe
|
||||
|
||||
// functions to quickly setup some defines
|
||||
function CreateDefinesInDirectories(const SourcePaths, FlagName: string
|
||||
@ -1100,14 +1103,13 @@ type
|
||||
const
|
||||
AllFPCFrontEndParams = [low(TFPCFrontEndParam)..high(TFPCFrontEndParam)];
|
||||
|
||||
function GuessCompilerType(Filename: string): TPascalCompiler;
|
||||
function ParseFPCInfo(FPCInfo: string; InfoTypes: TFPCInfoTypes;
|
||||
out Infos: TFPCInfoStrings): boolean;
|
||||
function RunFPCInfo(const CompilerFilename: string;
|
||||
InfoTypes: TFPCInfoTypes; const Options: string =''): string;
|
||||
function FPCVersionToNumber(const FPCVersionString: string): integer;
|
||||
function FPCVersionToNumber(const FPCVersionString: string): integer; // 2.7.1 -> 20701
|
||||
function SplitFPCVersion(const FPCVersionString: string;
|
||||
out FPCVersion, FPCRelease, FPCPatch: integer): boolean;
|
||||
out FPCVersion, FPCRelease, FPCPatch: integer): boolean; // 2.7.1 -> 2,7,1
|
||||
function ParseFPCVerbose(List: TStrings; // fpc -va output
|
||||
const WorkDir: string;
|
||||
out ConfigFiles: TStrings; // prefix '-' for file not found, '+' for found and read
|
||||
@ -1136,24 +1138,24 @@ procedure GatherUnitsInFPMSources(Units: TStringToStringTree; // unit names to f
|
||||
function GatherUnitSourcesInDirectory(Directory: string;
|
||||
MaxLevel: integer = 1): TStringToStringTree; // unit names to full file name
|
||||
procedure AdjustFPCSrcRulesForPPUPaths(Units: TStringToStringTree;
|
||||
Rules: TFPCSourceRules);
|
||||
Rules: TFPCSourceRules); // not for pas2js
|
||||
function GatherUnitsInFPCSources(Files: TStringList;
|
||||
TargetOS: string = ''; TargetCPU: string = '';
|
||||
Duplicates: TStringToStringTree = nil; // unit to semicolon separated list of files
|
||||
Rules: TFPCSourceRules = nil;
|
||||
const DebugUnitName: string = ''): TStringToStringTree;
|
||||
const DebugUnitName: string = ''): TStringToStringTree; // not for pas2js
|
||||
function CreateFPCTemplate(Config: TPCTargetConfigCache;
|
||||
Owner: TObject): TDefineTemplate; overload;
|
||||
function CreateFPCTemplate(Config: TFPCUnitSetCache;
|
||||
Owner: TObject): TDefineTemplate; overload;
|
||||
function CreateFPCSourceTemplate(Config: TFPCUnitSetCache;
|
||||
Owner: TObject): TDefineTemplate; overload;
|
||||
Owner: TObject): TDefineTemplate; overload; // not for pas2js
|
||||
function CreateFPCSourceTemplate(FPCSrcDir: string;
|
||||
Owner: TObject): TDefineTemplate; overload;
|
||||
Owner: TObject): TDefineTemplate; overload; // not for pas2js
|
||||
procedure CheckPPUSources(PPUFiles, // unitname to filename
|
||||
UnitToSource, // unitname to file name
|
||||
UnitToDuplicates: TStringToStringTree; // unitname to semicolon separated list of files
|
||||
var Duplicates, Missing: TStringToStringTree);
|
||||
var Duplicates, Missing: TStringToStringTree); // not for pas2js
|
||||
procedure LoadFPCCacheFromFile(Filename: string;
|
||||
var Configs: TPCTargetConfigCaches; var Sources: TFPCSourceCaches);
|
||||
procedure SaveFPCCacheToFile(Filename: string;
|
||||
@ -1521,14 +1523,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function GuessCompilerType(Filename: string): TPascalCompiler;
|
||||
begin
|
||||
Filename:=ExtractFileNameOnly(Filename);
|
||||
if Pos('pas2js',lowercase(Filename))>0 then
|
||||
exit(pcPas2js);
|
||||
Result:=pcFPC;
|
||||
end;
|
||||
|
||||
function ParseFPCInfo(FPCInfo: string; InfoTypes: TFPCInfoTypes;
|
||||
out Infos: TFPCInfoStrings): boolean;
|
||||
var
|
||||
@ -1557,29 +1551,32 @@ end;
|
||||
function RunFPCInfo(const CompilerFilename: string;
|
||||
InfoTypes: TFPCInfoTypes; const Options: string): string;
|
||||
var
|
||||
Params: String;
|
||||
Param: String;
|
||||
List: TStringList;
|
||||
Params: TStringListUTF8;
|
||||
begin
|
||||
Result:='';
|
||||
Params:='';
|
||||
if fpciCompilerDate in InfoTypes then Params:=Params+'D';
|
||||
if fpciShortVersion in InfoTypes then Params:=Params+'V';
|
||||
if fpciFullVersion in InfoTypes then Params:=Params+'W';
|
||||
if fpciCompilerOS in InfoTypes then Params:=Params+'SO';
|
||||
if fpciCompilerProcessor in InfoTypes then Params:=Params+'SP';
|
||||
if fpciTargetOS in InfoTypes then Params:=Params+'TO';
|
||||
if fpciTargetProcessor in InfoTypes then Params:=Params+'TP';
|
||||
if Params='' then exit;
|
||||
Params:='-i'+Params;
|
||||
if Options<>'' then
|
||||
Params:=Params+' '+Options;
|
||||
Param:='';
|
||||
if fpciCompilerDate in InfoTypes then Param:=Param+'D';
|
||||
if fpciShortVersion in InfoTypes then Param:=Param+'V';
|
||||
if fpciFullVersion in InfoTypes then Param:=Param+'W';
|
||||
if fpciCompilerOS in InfoTypes then Param:=Param+'SO';
|
||||
if fpciCompilerProcessor in InfoTypes then Param:=Param+'SP';
|
||||
if fpciTargetOS in InfoTypes then Param:=Param+'TO';
|
||||
if fpciTargetProcessor in InfoTypes then Param:=Param+'TP';
|
||||
if Param='' then exit;
|
||||
Param:='-i'+Param;
|
||||
List:=nil;
|
||||
Params:=TStringListUTF8.Create;
|
||||
try
|
||||
Params.Add(Param);
|
||||
SplitCmdLineParams(Options,Params);
|
||||
List:=RunTool(CompilerFilename,Params);
|
||||
if (List=nil) or (List.Count<1) then exit;
|
||||
Result:=List[0];
|
||||
if copy(Result,1,6)='Error:' then Result:='';
|
||||
finally
|
||||
Params.Free;
|
||||
List.free;
|
||||
end;
|
||||
end;
|
||||
@ -1840,7 +1837,7 @@ function RunFPCVerbose(const CompilerFilename, TestFilename: string; out
|
||||
UnitPaths: TStrings; out IncludePaths: TStrings; out UnitScopes: TStrings;
|
||||
out Defines, Undefines: TStringToStringTree; const Options: string): boolean;
|
||||
var
|
||||
Params: String;
|
||||
Params: TStringListUTF8;
|
||||
Filename: String;
|
||||
WorkDir: String;
|
||||
List: TStringList;
|
||||
@ -1855,23 +1852,28 @@ begin
|
||||
Defines:=nil;
|
||||
Undefines:=nil;
|
||||
|
||||
// create empty file
|
||||
try
|
||||
fs:=TFileStreamUTF8.Create(TestFilename,fmCreate);
|
||||
fs.Free;
|
||||
except
|
||||
debugln(['Warning: [RunFPCVerbose] unable to create test file "'+TestFilename+'"']);
|
||||
exit;
|
||||
end;
|
||||
|
||||
Params:='-va';
|
||||
if Options<>'' then
|
||||
Params:=Params+' '+Options;
|
||||
Filename:=ExtractFileName(TestFilename);
|
||||
WorkDir:=ExtractFilePath(TestFilename);
|
||||
Params:=Params+' '+Filename;
|
||||
Params:=TStringListUTF8.Create;
|
||||
List:=nil;
|
||||
try
|
||||
Params.Add('-va');
|
||||
|
||||
if TestFilename<>'' then begin
|
||||
// create empty file
|
||||
try
|
||||
fs:=TFileStreamUTF8.Create(TestFilename,fmCreate);
|
||||
fs.Free;
|
||||
except
|
||||
debugln(['Warning: [RunFPCVerbose] unable to create test file "'+TestFilename+'"']);
|
||||
exit;
|
||||
end;
|
||||
Filename:=ExtractFileName(TestFilename);
|
||||
WorkDir:=ExtractFilePath(TestFilename);
|
||||
Params.Add(Filename);
|
||||
end else
|
||||
WorkDir:='';
|
||||
|
||||
SplitCmdLineParams(Options,Params);
|
||||
|
||||
//DebugLn(['RunFPCVerbose ',CompilerFilename,' ',Params,' ',WorkDir]);
|
||||
List:=RunTool(CompilerFilename,Params,WorkDir);
|
||||
if (List=nil) or (List.Count=0) then begin
|
||||
@ -1881,8 +1883,10 @@ begin
|
||||
Result:=ParseFPCVerbose(List,WorkDir,ConfigFiles,RealCompilerFilename,
|
||||
UnitPaths,IncludePaths,UnitScopes,Defines,Undefines);
|
||||
finally
|
||||
Params.Free;
|
||||
List.Free;
|
||||
DeleteFileUTF8(TestFilename);
|
||||
if TestFilename<>'' then
|
||||
DeleteFileUTF8(TestFilename);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -3844,25 +3848,6 @@ begin
|
||||
Result:=LowerCase(TargetCPU);
|
||||
end;
|
||||
|
||||
function GetPascalCompilerFromExeName(Filename: string): TPascalCompiler;
|
||||
var
|
||||
ShortFilename: String;
|
||||
begin
|
||||
ShortFilename:=ExtractFileNameOnly(Filename);
|
||||
|
||||
// pas2js*
|
||||
if CompareText(LeftStr(ShortFilename,6),'pas2js')=0 then
|
||||
exit(pcPas2js);
|
||||
|
||||
// dcc*.exe
|
||||
if (CompareFilenames(LeftStr(ShortFilename,3),'dcc')=0)
|
||||
and ((ExeExt='') or (CompareFileExt(Filename,ExeExt)=0))
|
||||
then
|
||||
exit(pcDelphi);
|
||||
|
||||
Result:=pcFPC;
|
||||
end;
|
||||
|
||||
function IsCTExecutable(AFilename: string; out ErrorMsg: string): boolean;
|
||||
begin
|
||||
Result:=false;
|
||||
@ -3893,10 +3878,32 @@ begin
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
function IsCompilerExecutable(AFilename: string; out ErrorMsg: string; out
|
||||
Kind: TPascalCompiler): boolean;
|
||||
function GuessPascalCompilerFromExeName(Filename: string): TPascalCompiler;
|
||||
var
|
||||
ShortFilename: String;
|
||||
begin
|
||||
ShortFilename:=ExtractFileNameOnly(Filename);
|
||||
|
||||
// pas2js*
|
||||
if CompareText(LeftStr(ShortFilename,6),'pas2js')=0 then
|
||||
exit(pcPas2js);
|
||||
|
||||
// dcc*.exe
|
||||
if (CompareFilenames(LeftStr(ShortFilename,3),'dcc')=0)
|
||||
and ((ExeExt='') or (CompareFileExt(Filename,ExeExt)=0))
|
||||
then
|
||||
exit(pcDelphi);
|
||||
|
||||
Result:=pcFPC;
|
||||
end;
|
||||
|
||||
function IsCompilerExecutable(AFilename: string; out ErrorMsg: string; out
|
||||
Kind: TPascalCompiler; Run: boolean): boolean;
|
||||
var
|
||||
ShortFilename, Line: String;
|
||||
Params: TStringListUTF8;
|
||||
Lines: TStringList;
|
||||
i: Integer;
|
||||
begin
|
||||
Result:=IsCTExecutable(AFilename,ErrorMsg);
|
||||
if not Result then exit;
|
||||
@ -3905,27 +3912,74 @@ begin
|
||||
// allow scripts like fpc.sh and fpc.bat
|
||||
ShortFilename:=ExtractFileNameOnly(AFilename);
|
||||
//debugln(['IsFPCompiler Short=',ShortFilename]);
|
||||
if CompareFilenames(ShortFilename,'fpc')=0 then
|
||||
exit(true);
|
||||
|
||||
// allow ppcxxx.exe
|
||||
// check ppc*.exe
|
||||
if (CompareFilenames(LeftStr(ShortFilename,3),'ppc')=0)
|
||||
and ((ExeExt='') or (CompareFileExt(AFilename,ExeExt)=0))
|
||||
then
|
||||
exit(true);
|
||||
|
||||
// check pas2js*
|
||||
if CompareText(LeftStr(ShortFilename,6),'pas2js')=0 then begin
|
||||
Kind:=pcPas2js;
|
||||
exit(true);
|
||||
end;
|
||||
|
||||
// dcc*.exe
|
||||
if (CompareFilenames(LeftStr(ShortFilename,3),'dcc')=0)
|
||||
and ((ExeExt='') or (CompareFileExt(ShortFilename,ExeExt)=0))
|
||||
then begin
|
||||
Kind:=pcDelphi;
|
||||
exit(true);
|
||||
end;
|
||||
|
||||
if Run then begin
|
||||
// run it and check for magics
|
||||
Params:=TStringListUTF8.Create;
|
||||
Lines:=nil;
|
||||
try
|
||||
Params.Add('-va');
|
||||
Lines:=RunTool(AFilename,Params);
|
||||
if Lines<>nil then begin
|
||||
for i:=0 to Lines.Count-1 do
|
||||
begin
|
||||
Line:=Lines[i];
|
||||
if Pos('fpc.cfg',Line)>0 then
|
||||
begin
|
||||
Kind:=pcFPC;
|
||||
exit(true);
|
||||
end;
|
||||
if Pos('pas2js.cfg',Line)>0 then
|
||||
begin
|
||||
Kind:=pcPas2js;
|
||||
exit(true);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
Params.Free;
|
||||
Lines.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
// check fpc<something>
|
||||
// Note: fpc.exe is just a wrapper, it can call pas2js
|
||||
if CompareFilenames(ShortFilename,'fpc')=0 then
|
||||
exit(true);
|
||||
|
||||
ErrorMsg:='fpc executable should start with fpc or ppc';
|
||||
end;
|
||||
|
||||
function IsFPCExecutable(AFilename: string; out ErrorMsg: string): boolean;
|
||||
function IsFPCExecutable(AFilename: string; out ErrorMsg: string; Run: boolean
|
||||
): boolean;
|
||||
var
|
||||
ShortFilename: String;
|
||||
Kind: TPascalCompiler;
|
||||
begin
|
||||
if Run then begin
|
||||
Result:=IsCompilerExecutable(AFilename,ErrorMsg,Kind,true) and (Kind=pcFPC);
|
||||
exit;
|
||||
end;
|
||||
|
||||
Result:=IsCTExecutable(AFilename,ErrorMsg);
|
||||
if not Result then exit;
|
||||
|
||||
@ -3944,10 +3998,17 @@ begin
|
||||
ErrorMsg:='fpc executable should start with fpc or ppc';
|
||||
end;
|
||||
|
||||
function IsPas2JSExecutable(AFilename: string; out ErrorMsg: string): boolean;
|
||||
function IsPas2JSExecutable(AFilename: string; out ErrorMsg: string;
|
||||
Run: boolean): boolean;
|
||||
var
|
||||
ShortFilename: String;
|
||||
Kind: TPascalCompiler;
|
||||
begin
|
||||
if Run then begin
|
||||
Result:=IsCompilerExecutable(AFilename,ErrorMsg,Kind,true) and (Kind=pcPas2js);
|
||||
exit;
|
||||
end;
|
||||
|
||||
Result:=IsCTExecutable(AFilename,ErrorMsg);
|
||||
if not Result then exit;
|
||||
|
||||
@ -6200,7 +6261,7 @@ var
|
||||
end;
|
||||
end;
|
||||
|
||||
var CmdLine: string;
|
||||
var
|
||||
i, OutLen, LineStart: integer;
|
||||
TheProcess: TProcessUTF8;
|
||||
OutputLine, Buf: String;
|
||||
@ -6208,6 +6269,7 @@ var CmdLine: string;
|
||||
SrcOS: string;
|
||||
SrcOS2: String;
|
||||
Step: String;
|
||||
Params: TStringListUTF8;
|
||||
begin
|
||||
Result:=nil;
|
||||
//DebugLn('TDefinePool.CreateFPCTemplate PPC386Path="',CompilerPath,'" FPCOptions="',CompilerOptions,'"');
|
||||
@ -6225,21 +6287,22 @@ begin
|
||||
SetLength(Buf,1024);
|
||||
Step:='Init';
|
||||
try
|
||||
CmdLine:=CompilerPath+' -va ';
|
||||
if (Pos('pas2js',lowercase(ExtractFileName(CompilerPath)))<1)
|
||||
and FileExistsCached(EnglishErrorMsgFilename) then
|
||||
CmdLine:=CmdLine+'-Fr'+EnglishErrorMsgFilename+' ';
|
||||
if CompilerOptions<>'' then
|
||||
CmdLine:=CmdLine+CompilerOptions+' ';
|
||||
CmdLine:=CmdLine+TestPascalFile;
|
||||
//DebugLn('TDefinePool.CreateFPCTemplate CmdLine="',CmdLine,'"');
|
||||
|
||||
Params:=TStringListUTF8.Create;
|
||||
TheProcess := TProcessUTF8.Create(nil);
|
||||
TheProcess.ParseCmdLine(CmdLine);
|
||||
TheProcess.Options:= [poUsePipes, poStdErrToOutPut];
|
||||
TheProcess.ShowWindow := swoHide;
|
||||
Step:='Running '+CmdLine;
|
||||
try
|
||||
TheProcess.Executable:=CompilerPath;
|
||||
Params.Add('-va');
|
||||
if (Pos('pas2js',lowercase(ExtractFileName(CompilerPath)))<1)
|
||||
and FileExistsCached(EnglishErrorMsgFilename) then
|
||||
Params.Add('-Fr'+EnglishErrorMsgFilename);
|
||||
if CompilerOptions<>'' then
|
||||
SplitCmdLineParams(CompilerOptions,Params,true);
|
||||
Params.Add(TestPascalFile);
|
||||
//DebugLn('TDefinePool.CreateFPCTemplate Params="',MergeCmdLineParams(Params),'"');
|
||||
TheProcess.Parameters:=Params;
|
||||
TheProcess.Options:= [poUsePipes, poStdErrToOutPut];
|
||||
TheProcess.ShowWindow := swoHide;
|
||||
Step:='Running '+MergeCmdLineParams(Params);
|
||||
TheProcess.Execute;
|
||||
OutputLine:='';
|
||||
repeat
|
||||
@ -6267,23 +6330,24 @@ begin
|
||||
finally
|
||||
//DebugLn('TDefinePool.CreateFPCTemplate Run with -va: OutputLine="',OutputLine,'"');
|
||||
TheProcess.Free;
|
||||
Params.Free;
|
||||
end;
|
||||
DefineSymbol(FPCUnitPathMacroName,UnitSearchPath,'FPC default unit search path');
|
||||
|
||||
//DebugLn('TDefinePool.CreateFPCTemplate First done UnitSearchPath="',UnitSearchPath,'"');
|
||||
|
||||
// ask for target operating system -> ask compiler with switch -iTO
|
||||
CmdLine:=CompilerPath;
|
||||
if CompilerOptions<>'' then
|
||||
CmdLine:=CmdLine+' '+CompilerOptions;
|
||||
CmdLine:=CmdLine+' -iTO';
|
||||
|
||||
Params:=TStringListUTF8.Create;
|
||||
TheProcess := TProcessUTF8.Create(nil);
|
||||
TheProcess.ParseCmdLine(CmdLine);
|
||||
TheProcess.Options:= [poUsePipes, poStdErrToOutPut];
|
||||
TheProcess.ShowWindow := swoHide;
|
||||
Step:='Running '+CmdLine;
|
||||
try
|
||||
TheProcess.Executable:=CompilerPath;
|
||||
if CompilerOptions<>'' then
|
||||
SplitCmdLineParams(CompilerOptions,Params,true);
|
||||
Params.Add('-iTO');
|
||||
TheProcess.Parameters:=Params;
|
||||
TheProcess.Options:= [poUsePipes, poStdErrToOutPut];
|
||||
TheProcess.ShowWindow := swoHide;
|
||||
Step:='Running '+MergeCmdLineParams(Params);
|
||||
TheProcess.Execute;
|
||||
if (TheProcess.Output<>nil) then
|
||||
OutLen:=TheProcess.Output.Read(Buf[1],length(Buf))
|
||||
@ -6321,19 +6385,21 @@ begin
|
||||
finally
|
||||
//DebugLn('TDefinePool.CreateFPCTemplate Run with -iTO: OutputLine="',OutputLine,'"');
|
||||
TheProcess.Free;
|
||||
Params.Free;
|
||||
end;
|
||||
|
||||
// ask for target processor -> ask compiler with switch -iTP
|
||||
Params:=TStringListUTF8.Create;
|
||||
TheProcess := TProcessUTF8.Create(nil);
|
||||
CmdLine:=CompilerPath;
|
||||
if CompilerOptions<>'' then
|
||||
CmdLine:=CmdLine+' '+CompilerOptions;
|
||||
CmdLine:=CmdLine+' -iTP';
|
||||
TheProcess.ParseCmdLine(CmdLine);
|
||||
TheProcess.Options:= [poUsePipes, poStdErrToOutPut];
|
||||
TheProcess.ShowWindow := swoHide;
|
||||
Step:='Running '+CmdLine;
|
||||
try
|
||||
TheProcess.Executable:=CompilerPath;
|
||||
if CompilerOptions<>'' then
|
||||
SplitCmdLineParams(CompilerOptions,Params,true);
|
||||
Params.Add('-iTP');
|
||||
TheProcess.Parameters:=Params;
|
||||
TheProcess.Options:= [poUsePipes, poStdErrToOutPut];
|
||||
TheProcess.ShowWindow := swoHide;
|
||||
Step:='Running '+MergeCmdLineParams(Params);
|
||||
TheProcess.Execute;
|
||||
if TheProcess.Output<>nil then
|
||||
OutLen:=TheProcess.Output.Read(Buf[1],length(Buf))
|
||||
@ -7631,7 +7697,7 @@ begin
|
||||
UnitPath:='';
|
||||
IncPath:='';
|
||||
Namespaces:='';
|
||||
Params:=TStringList.Create;
|
||||
Params:=TStringListUTF8.Create;
|
||||
try
|
||||
SplitCmdLineParams(CmdLine,Params);
|
||||
for i:=0 to Params.Count-1 do begin
|
||||
@ -8039,7 +8105,7 @@ begin
|
||||
RealCompilerDate:=0;
|
||||
RealTargetCPU:='';
|
||||
RealTargetOS:='';
|
||||
RealCompilerInPath:='';
|
||||
RealTargetCPUCompiler:='';
|
||||
FullVersion:='';
|
||||
HasPPUs:=false;
|
||||
ConfigFiles.Clear;
|
||||
@ -8104,7 +8170,7 @@ begin
|
||||
or (RealCompilerDate<>Item.RealCompilerDate)
|
||||
or (RealTargetOS<>Item.RealTargetOS)
|
||||
or (RealTargetCPU<>Item.RealTargetCPU)
|
||||
or (RealCompilerInPath<>Item.RealCompilerInPath)
|
||||
or (RealTargetCPUCompiler<>Item.RealTargetCPUCompiler)
|
||||
or (FullVersion<>Item.FullVersion)
|
||||
or (HasPPUs<>Item.HasPPUs)
|
||||
or (not ConfigFiles.Equals(Item.ConfigFiles,true))
|
||||
@ -8197,7 +8263,7 @@ begin
|
||||
RealCompilerDate:=Item.RealCompilerDate;
|
||||
RealTargetOS:=Item.RealTargetOS;
|
||||
RealTargetCPU:=Item.RealTargetCPU;
|
||||
RealCompilerInPath:=Item.RealCompilerInPath;
|
||||
RealTargetCPUCompiler:=Item.RealTargetCPUCompiler;
|
||||
FullVersion:=Item.FullVersion;
|
||||
HasPPUs:=Item.HasPPUs;
|
||||
ConfigFiles.Assign(Item.ConfigFiles);
|
||||
@ -8346,7 +8412,7 @@ begin
|
||||
RealCompilerDate:=XMLConfig.GetValue(Path+'RealCompiler/Date',0);
|
||||
RealTargetOS:=XMLConfig.GetValue(Path+'RealCompiler/OS','');
|
||||
RealTargetCPU:=XMLConfig.GetValue(Path+'RealCompiler/CPU','');
|
||||
RealCompilerInPath:=XMLConfig.GetValue(Path+'RealCompiler/InPath','');
|
||||
RealTargetCPUCompiler:=XMLConfig.GetValue(Path+'RealCompiler/InPath','');
|
||||
FullVersion:=XMLConfig.GetValue(Path+'RealCompiler/FullVersion','');
|
||||
HasPPUs:=XMLConfig.GetValue(Path+'HasPPUs',true);
|
||||
ConfigFiles.LoadFromXMLConfig(XMLConfig,Path+'Configs/');
|
||||
@ -8531,7 +8597,7 @@ begin
|
||||
XMLConfig.SetDeleteValue(Path+'RealCompiler/Date',RealCompilerDate,0);
|
||||
XMLConfig.SetDeleteValue(Path+'RealCompiler/OS',RealTargetOS,'');
|
||||
XMLConfig.SetDeleteValue(Path+'RealCompiler/CPU',RealTargetCPU,'');
|
||||
XMLConfig.SetDeleteValue(Path+'RealCompiler/InPath',RealCompilerInPath,'');
|
||||
XMLConfig.SetDeleteValue(Path+'RealCompiler/InPath',RealTargetCPUCompiler,'');
|
||||
XMLConfig.SetDeleteValue(Path+'RealCompiler/FullVersion',FullVersion,'');
|
||||
XMLConfig.SetDeleteValue(Path+'HasPPUs',HasPPUs,true);
|
||||
ConfigFiles.SaveToXMLConfig(XMLConfig,Path+'Configs/');
|
||||
@ -8666,10 +8732,10 @@ begin
|
||||
end;
|
||||
// fpc searches via PATH for the real compiler, resolves any symlink
|
||||
// and that is the RealCompiler
|
||||
AFilename:=FindRealCompilerInPath(TargetCPU,true);
|
||||
if RealCompilerInPath<>AFilename then begin
|
||||
AFilename:=FindDefaultTargetCPUCompiler(TargetCPU,true);
|
||||
if RealTargetCPUCompiler<>AFilename then begin
|
||||
if CTConsoleVerbosity>0 then
|
||||
debugln(['Hint: [TPCTargetConfigCache.NeedsUpdate] TargetOS="',TargetOS,'" TargetCPU="',TargetCPU,'" Options="',CompilerOptions,'" real compiler in PATH changed from "',RealCompilerInPath,'" to "',AFilename,'"']);
|
||||
debugln(['Hint: [TPCTargetConfigCache.NeedsUpdate] TargetOS="',TargetOS,'" TargetCPU="',TargetCPU,'" Options="',CompilerOptions,'" real compiler in PATH changed from "',RealTargetCPUCompiler,'" to "',AFilename,'"']);
|
||||
exit;
|
||||
end;
|
||||
for i:=0 to ConfigFiles.Count-1 do begin
|
||||
@ -8732,7 +8798,7 @@ var
|
||||
Infos: TFPCInfoStrings;
|
||||
InfoTypes: TFPCInfoTypes;
|
||||
BaseDir: String;
|
||||
FullFilename: String;
|
||||
FullFilename, KindErrorMsg: String;
|
||||
begin
|
||||
OldOptions:=TPCTargetConfigCache.Create(nil);
|
||||
CfgFiles:=nil;
|
||||
@ -8743,18 +8809,17 @@ begin
|
||||
|
||||
if CTConsoleVerbosity>0 then
|
||||
debugln(['Hint: [TPCTargetConfigCache.NeedsUpdate] ',Compiler,' TargetOS=',TargetOS,' TargetCPU=',TargetCPU,' CompilerOptions=',CompilerOptions,' ExtraOptions=',ExtraOptions,' PATH=',GetEnvironmentVariableUTF8('PATH')]);
|
||||
CompilerDate:=FileAgeCached(Compiler);
|
||||
CompilerDate:=-1;
|
||||
if FileExistsCached(Compiler) then begin
|
||||
ExtraOptions:=GetFPCInfoCmdLineOptions(ExtraOptions);
|
||||
CompilerDate:=FileAgeCached(Compiler);
|
||||
ExtraOptions:=GetFPCInfoCmdLineOptions(ExtraOptions);// contains TargetOS and TargetCPU
|
||||
BaseDir:='';
|
||||
|
||||
// kind
|
||||
Kind:=GuessCompilerType(Compiler);
|
||||
|
||||
// get version and real OS and CPU
|
||||
// get version, OS and CPU
|
||||
InfoTypes:=[fpciTargetOS,fpciTargetProcessor,fpciFullVersion];
|
||||
Info:=RunFPCInfo(Compiler,InfoTypes,ExtraOptions);
|
||||
if ParseFPCInfo(Info,InfoTypes,Infos) then begin
|
||||
// fpc or pas2js
|
||||
RealTargetOS:=Infos[fpciTargetOS];
|
||||
RealTargetCPU:=Infos[fpciTargetProcessor];
|
||||
FullVersion:=Infos[fpciFullVersion];
|
||||
@ -8766,9 +8831,6 @@ begin
|
||||
if RealTargetCPU='' then
|
||||
RealTargetCPU:=GetCompiledTargetCPU;
|
||||
end;
|
||||
if Kind=pcFPC then
|
||||
RealCompilerInPath:=FindRealCompilerInPath(TargetCPU,true);
|
||||
|
||||
// run fpc/pas2js and parse output
|
||||
HasPPUs:=false;
|
||||
RunFPCVerbose(Compiler,TestFilename,CfgFiles,RealCompiler,UnitPaths,
|
||||
@ -8780,8 +8842,15 @@ begin
|
||||
|
||||
if Defines.Contains('PAS2JS') and Defines.Contains('PAS2JS_FULLVERSION') then
|
||||
Kind:=pcPas2js
|
||||
else
|
||||
Kind:=pcFPC;
|
||||
else if Defines.Contains('FPC') and Defines.Contains('FPC_FULLVERSION') then
|
||||
Kind:=pcFPC
|
||||
else begin
|
||||
IsCompilerExecutable(Compiler,KindErrorMsg,Kind,false);
|
||||
if KindErrorMsg<>'' then
|
||||
debugln(['Warning: [TPCTargetConfigCache.Update] cannot determine type of compiler: Compiler="'+Compiler+'" Options="'+ExtraOptions+'"']);
|
||||
end;
|
||||
if Kind=pcFPC then
|
||||
RealTargetCPUCompiler:=FindDefaultTargetCPUCompiler(TargetCPU,true);
|
||||
PreparePaths(UnitPaths);
|
||||
PreparePaths(IncludePaths);
|
||||
// store the real compiler file and date
|
||||
@ -8847,7 +8916,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TPCTargetConfigCache.FindRealCompilerInPath(aTargetCPU: string;
|
||||
function TPCTargetConfigCache.FindDefaultTargetCPUCompiler(aTargetCPU: string;
|
||||
ResolveLinks: boolean): string;
|
||||
|
||||
function Search(const ShortFileName: string): string;
|
||||
@ -9740,7 +9809,7 @@ begin
|
||||
Result:={$I %FPCVersion%}
|
||||
else
|
||||
Result:='';
|
||||
if not IsFPCExecutable(CompilerFilename,ErrorMsg) then
|
||||
if not IsCTExecutable(CompilerFilename,ErrorMsg) then
|
||||
exit;
|
||||
CfgCache:=ConfigCaches.Find(CompilerFilename,ExtraOptions,TargetOS,TargetCPU,true);
|
||||
if CfgCache.NeedsUpdate
|
||||
|
||||
@ -571,7 +571,7 @@ procedure THeapTrcInfo.ParseTraceLine(s: string; var line: TStackLine);
|
||||
var
|
||||
AnId, SrcX, SrcY, SrcTopLine: Integer;
|
||||
AnIsCurrent, Complete: Boolean;
|
||||
AFuncName, AFile, AReminder, TheErrorMsg: String;
|
||||
AFuncName, AReminder, TheErrorMsg: String;
|
||||
AnArgs: TStringList;
|
||||
SrcCode: TCodeBuffer;
|
||||
begin
|
||||
|
||||
@ -191,7 +191,7 @@ type
|
||||
// Methods used by CreateIDEMakeOptions :
|
||||
procedure BackupExe(Flags: TBuildLazarusFlags);
|
||||
function CreateAppleBundle: TModalResult;
|
||||
procedure AppendExtraOption(const aOption: string; EncloseIfSpace: boolean = True);
|
||||
procedure AppendExtraOption(const aOption: string; AutoQuote: boolean = True);
|
||||
// This is used by MakeLazarus and SaveIDEMakeOptions
|
||||
function PrepareTargetDir(Flags: TBuildLazarusFlags): TModalResult;
|
||||
public
|
||||
@ -376,20 +376,22 @@ function TLazarusBuilder.MakeLazarus(Profile: TBuildLazarusProfile;
|
||||
Flags: TBuildLazarusFlags): TModalResult;
|
||||
var
|
||||
Tool: TAbstractExternalTool;
|
||||
Executable, CmdLineParams, Cmd: String;
|
||||
Executable, Cmd: String;
|
||||
CmdLineParams: TStrings;
|
||||
EnvironmentOverrides: TStringList;
|
||||
|
||||
function Run(CurTitle: string): TModalResult;
|
||||
var
|
||||
Params: String;
|
||||
procedure AddCmdLineParam(Param: string; ExecMacros: boolean);
|
||||
begin
|
||||
Params:=UTF8Trim(CmdLineParams,[]);
|
||||
if fMacros<>nil then
|
||||
fMacros.SubstituteStr(Params);
|
||||
if Params<>'' then
|
||||
Params:=Cmd+' '+Params
|
||||
else
|
||||
Params:=Cmd;
|
||||
if Param='' then exit;
|
||||
if ExecMacros and (fMacros<>nil) then
|
||||
fMacros.SubstituteStr(Param);
|
||||
if Param<>'' then
|
||||
CmdLineParams.Add(Param);
|
||||
end;
|
||||
|
||||
function Run(CurTitle: string): TModalResult;
|
||||
begin
|
||||
AddCmdLineParam(Cmd,false);
|
||||
Tool:=ExternalToolList.Add(CurTitle);
|
||||
Tool.Reference(Self,ClassName);
|
||||
try
|
||||
@ -401,7 +403,7 @@ var
|
||||
Tool.AddParsers(SubToolMake);
|
||||
Tool.Process.CurrentDirectory:=fWorkingDir;
|
||||
Tool.EnvironmentOverrides:=EnvironmentOverrides;
|
||||
Tool.CmdLineParams:=Params;
|
||||
Tool.CmdLineParams:=MergeCmdLineParams(CmdLineParams);
|
||||
Tool.Execute;
|
||||
Tool.WaitForExit;
|
||||
if Tool.ErrorMessage='' then
|
||||
@ -428,6 +430,7 @@ begin
|
||||
IdeBuildMode:=Profile.IdeBuildMode;
|
||||
|
||||
EnvironmentOverrides:=TStringList.Create;
|
||||
CmdLineParams:=TStringListUTF8.Create;
|
||||
Tool:=nil;
|
||||
try
|
||||
// setup external tool
|
||||
@ -451,13 +454,17 @@ begin
|
||||
end;
|
||||
|
||||
// add -w option to print leaving/entering messages of "make"
|
||||
CmdLineParams:=' -w';
|
||||
AddCmdLineParam('-w',false);
|
||||
// append target OS
|
||||
if fTargetOS<>fCompilerTargetOS then
|
||||
CmdLineParams+=' OS_TARGET='+fTargetOS+' OS_SOURCE='+fTargetOS;
|
||||
if fTargetOS<>fCompilerTargetOS then begin
|
||||
AddCmdLineParam('OS_TARGET='+fTargetOS,true);
|
||||
AddCmdLineParam('OS_SOURCE='+fTargetOS,true);
|
||||
end;
|
||||
// append target CPU
|
||||
if fTargetCPU<>fCompilerTargetCPU then
|
||||
CmdLineParams+=' CPU_TARGET='+fTargetCPU+' CPU_SOURCE='+fTargetCPU;
|
||||
if fTargetCPU<>fCompilerTargetCPU then begin
|
||||
AddCmdLineParam('CPU_TARGET='+fTargetCPU,true);
|
||||
AddCmdLineParam('CPU_SOURCE='+fTargetCPU,true);
|
||||
end;
|
||||
|
||||
// create target directory and bundle
|
||||
Result:=PrepareTargetDir(Flags);
|
||||
@ -535,6 +542,7 @@ begin
|
||||
end;
|
||||
Result:=mrOk;
|
||||
finally
|
||||
CmdLineParams.Free;
|
||||
EnvironmentOverrides.Free;
|
||||
if LazarusIDE<>nil then
|
||||
LazarusIDE.MainBarSubTitle:='';
|
||||
@ -841,13 +849,13 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLazarusBuilder.AppendExtraOption(const aOption: string; EncloseIfSpace: boolean);
|
||||
procedure TLazarusBuilder.AppendExtraOption(const aOption: string; AutoQuote: boolean);
|
||||
begin
|
||||
if aOption='' then exit;
|
||||
if fExtraOptions<>'' then
|
||||
fExtraOptions:=fExtraOptions+' ';
|
||||
if EncloseIfSpace and (Pos(' ',aOption)>0) then
|
||||
fExtraOptions:=fExtraOptions+'"'+aOption+'"'
|
||||
if AutoQuote then
|
||||
fExtraOptions:=fExtraOptions+AnsiQuotedStr(aOption,'"')
|
||||
else
|
||||
fExtraOptions:=fExtraOptions+aOption;
|
||||
//DebugLn(['AppendExtraOption ',fExtraOptions]);
|
||||
@ -870,7 +878,7 @@ begin
|
||||
|
||||
// create apple bundle if needed
|
||||
//debugln(['CreateIDEMakeOptions NewTargetDirectory=',fTargetDir]);
|
||||
if (compareText(fTargetOS,'darwin')=0)
|
||||
if (CompareText(fTargetOS,'darwin')=0)
|
||||
and fOutputDirRedirected and DirectoryIsWritableCached(fTargetDir) then
|
||||
begin
|
||||
Result:=CreateAppleBundle;
|
||||
|
||||
@ -80,6 +80,9 @@ type
|
||||
fTargetOS: string;
|
||||
fTargetCPU: string;
|
||||
fLCLWidgetType: string;
|
||||
// cache
|
||||
FFPCompilerFilename: string;
|
||||
FFPCompilerFilenameStamp: Integer;
|
||||
procedure DoOnRescanFPCDirectoryCache(Sender: TObject);
|
||||
function GetTargetFilename: String;
|
||||
procedure OnMacroSubstitution(TheMacro: TTransferMacro;
|
||||
@ -335,6 +338,7 @@ begin
|
||||
DefaultCfgVars:=TCTCfgScriptVariables.Create;
|
||||
DefaultCfgVarsBuildMacroStamp:=CTInvalidChangeStamp;
|
||||
FFPCVerChangeStamp:=CTInvalidChangeStamp;
|
||||
FFPCompilerFilenameStamp:=CTInvalidChangeStamp;
|
||||
MainBuildBoss:=Self;
|
||||
inherited Create(AOwner);
|
||||
fTargetOS:=GetCompiledTargetOS;
|
||||
@ -640,9 +644,7 @@ end;
|
||||
|
||||
function TBuildManager.GetCompilerFilename: string;
|
||||
var
|
||||
s: string;
|
||||
Opts: TProjectCompilerOptions;
|
||||
Kind: TPascalCompiler;
|
||||
begin
|
||||
Result:='';
|
||||
//debugln(['TBuildManager.GetCompilerFilename START FBuildTarget=',DbgSName(FBuildTarget)]);
|
||||
@ -658,27 +660,35 @@ begin
|
||||
// the compiler filename is resolved twice, once for getting the default
|
||||
// compiler target OS/CPU and once with the real values.
|
||||
// For easier debugging macros, avoid this double resolve.
|
||||
if Result='$(CompPath)' then
|
||||
if Result='' then
|
||||
// see below
|
||||
else if Result='$(CompPath)' then
|
||||
Result:=''
|
||||
else if (Pos('$',Result)<1) and (FilenameIsAbsolute(Result)) then
|
||||
Result:=TrimFilename(Result)
|
||||
else
|
||||
Result:=FBuildTarget.GetCompilerFilename;
|
||||
//debugln(['TBuildManager.GetFPCompilerFilename project compiler="',Result,'"']);
|
||||
//debugln(['TBuildManager.GetCompilerFilename project compiler="',Result,'"']);
|
||||
end;
|
||||
end;
|
||||
if not IsCompilerExecutable(Result,s,Kind) then begin
|
||||
//debugln(['TBuildManager.GetFPCompilerFilename project compiler IS NOT a pascal compiler: "',Result,'"']);
|
||||
if Result='' then
|
||||
Result:=EnvironmentOptions.GetParsedCompilerFilename;
|
||||
if Kind=pcFPC then ;
|
||||
end;
|
||||
//debugln(['TBuildManager.GetCompilerFilename END Result="',Result,'"']);
|
||||
end;
|
||||
|
||||
function TBuildManager.GetFPCompilerFilename: string;
|
||||
var
|
||||
ErrMsg: string;
|
||||
Kind: TPascalCompiler;
|
||||
begin
|
||||
Result:=GetCompilerFilename;
|
||||
if GuessCompilerType(Result)<>pcFPC then
|
||||
Result:=EnvironmentOptions.GetParsedCompilerFilename;
|
||||
if FFPCompilerFilenameStamp<>CompilerParseStamp then begin
|
||||
FFPCompilerFilename:=GetCompilerFilename;
|
||||
if (not IsCompilerExecutable(FFPCompilerFilename,ErrMsg,Kind,false)) or (ErrMsg<>'')
|
||||
or (Kind<>pcFPC) then
|
||||
FFPCompilerFilename:=EnvironmentOptions.GetParsedCompilerFilename;
|
||||
FFPCompilerFilenameStamp:=CompilerParseStamp;
|
||||
end;
|
||||
Result:=FFPCompilerFilename;
|
||||
end;
|
||||
|
||||
function TBuildManager.GetFPCFrontEndOptions: string;
|
||||
@ -829,7 +839,7 @@ procedure TBuildManager.RescanCompilerDefines(ResetBuildTarget,
|
||||
if Cfg.Kind=pcFPC then begin
|
||||
if Cfg.RealCompiler='' then begin
|
||||
if ConsoleVerbosity>=0 then
|
||||
debugln(['Error: (lazarus) [PPUFilesAndCompilerMatch] Compiler=',Cfg.Compiler,' RealComp=',Cfg.RealCompiler,' InPath=',Cfg.RealCompilerInPath]);
|
||||
debugln(['Error: (lazarus) [PPUFilesAndCompilerMatch] Compiler=',Cfg.Compiler,' RealComp=',Cfg.RealCompiler,' InPath=',Cfg.RealTargetCPUCompiler]);
|
||||
IDEMessageDialog(lisCCOErrorCaption, Format(
|
||||
lisCompilerDoesNotSupportTarget, [Cfg.Compiler, Cfg.TargetCPU, Cfg.TargetOS]),
|
||||
mtError,[mbOk]);
|
||||
@ -858,8 +868,8 @@ var
|
||||
UnitSetChanged: Boolean;
|
||||
HasTemplate: Boolean;
|
||||
CompilerErrorMsg: string;
|
||||
Msg: String;
|
||||
Kind: TPascalCompiler;
|
||||
Msg, DefCompilerFilename: String;
|
||||
CompilerKind: TPascalCompiler;
|
||||
begin
|
||||
if ClearCaches then begin
|
||||
{$IFDEF VerboseFPCSrcScan}
|
||||
@ -881,13 +891,15 @@ begin
|
||||
{$IFDEF VerboseFPCSrcScan}
|
||||
debugln(['TBuildManager.RescanCompilerDefines GetParsedFPCSourceDirectory needs FPCVer...']);
|
||||
{$ENDIF}
|
||||
FPCSrcDir:=EnvironmentOptions.GetParsedFPCSourceDirectory; // needs FPCVer macro
|
||||
CompilerFilename:=GetCompilerFilename;
|
||||
IsCompilerExecutable(CompilerFilename,CompilerErrorMsg,CompilerKind,true);
|
||||
FPCSrcDir:=EnvironmentOptions.GetParsedFPCSourceDirectory; // needs FPCVer macro
|
||||
FPCOptions:=GetFPCFrontEndOptions;
|
||||
|
||||
{$IFDEF VerboseFPCSrcScan}
|
||||
debugln(['TMainIDE.RescanCompilerDefines START ',
|
||||
' CompilerFilename=',CompilerFilename,
|
||||
' Kind=',PascalCompilerNames[CompilerKind],
|
||||
' TargetOS=',TargetOS,
|
||||
' TargetCPU=',TargetCPU,
|
||||
' FPCOptions="',FPCOptions,'"',
|
||||
@ -911,29 +923,31 @@ begin
|
||||
end;
|
||||
|
||||
// then check the project's compiler
|
||||
if not IsCompilerExecutable(CompilerFilename,CompilerErrorMsg,Kind) then begin
|
||||
if (CompilerErrorMsg<>'') then begin
|
||||
Msg:='';
|
||||
if (FBuildTarget<>nil)
|
||||
and ([crCompile,crBuild]*FBuildTarget.CompilerOptions.CompileReasons<>[])
|
||||
and (FBuildTarget.CompilerOptions.CompilerPath<>'')
|
||||
then begin
|
||||
CompilerFilename:=FBuildTarget.GetCompilerFilename;
|
||||
if not IsCompilerExecutable(CompilerFilename,CompilerErrorMsg,Kind) then begin
|
||||
if not IsCompilerExecutable(CompilerFilename,CompilerErrorMsg,CompilerKind,true)
|
||||
then begin
|
||||
Msg+='Project''s compiler: "'+CompilerFilename+'": '+CompilerErrorMsg+#13;
|
||||
end;
|
||||
end;
|
||||
|
||||
CompilerFilename:=EnvironmentOptions.GetParsedCompilerFilename;
|
||||
if not IsFPCExecutable(CompilerFilename,CompilerErrorMsg) then begin
|
||||
Msg+='Environment compiler: "'+CompilerFilename+'": '+CompilerErrorMsg+#13;
|
||||
DefCompilerFilename:=EnvironmentOptions.GetParsedCompilerFilename;
|
||||
if not IsCompilerExecutable(DefCompilerFilename,CompilerErrorMsg,CompilerKind,true)
|
||||
then begin
|
||||
Msg+='Environment compiler: "'+DefCompilerFilename+'": '+CompilerErrorMsg+#13;
|
||||
end;
|
||||
debugln('Warning: (lazarus) [TBuildManager.RescanCompilerDefines]: invalid compiler:');
|
||||
debugln(Msg);
|
||||
if not Quiet then begin
|
||||
IDEMessageDialog('Error','There is no Free Pascal Compiler'
|
||||
+' (e.g. fpc'+ExeExt+' or ppc<cpu>'+ExeExt+') configured in the'
|
||||
+' environment options. Codetools will not work properly.'#13
|
||||
+Msg,mtError,[mbCancel]);
|
||||
+' project options. Codetools will not work properly.'#13
|
||||
+Msg,mtError,[mbOk]);
|
||||
end;
|
||||
UnitSetCache:=nil;
|
||||
exit;
|
||||
@ -2111,14 +2125,17 @@ function TBuildManager.MacroFuncFPCVer(const Param: string; const Data: PtrInt;
|
||||
s: string;
|
||||
begin
|
||||
FFPC_FULLVERSION:=0;
|
||||
if OverrideFPCVer<>'' then
|
||||
if OverrideFPCVer<>'' then begin
|
||||
FFPCVer:=OverrideFPCVer;
|
||||
FFPC_FULLVERSION:=FPCVersionToNumber(FFPCVer);
|
||||
exit;
|
||||
end;
|
||||
FFPCVer:={$I %FPCVERSION%}; // Version.Release.Patch
|
||||
if CodeToolBoss<>nil then begin
|
||||
// fetch the FPC version from the current compiler
|
||||
// Not from the fpc.exe, but from the real compiler
|
||||
CompilerFilename:=GetFPCompilerFilename;
|
||||
if not IsFPCExecutable(CompilerFilename,s) then exit;
|
||||
if not IsCTExecutable(CompilerFilename,s) then exit;
|
||||
TargetOS:=GetTargetOS;
|
||||
TargetCPU:=GetTargetCPU;
|
||||
ConfigCache:=CodeToolBoss.CompilerDefinesCache.ConfigCaches.Find(
|
||||
@ -2133,7 +2150,8 @@ function TBuildManager.MacroFuncFPCVer(const Param: string; const Data: PtrInt;
|
||||
end;
|
||||
FFPCVer:=ConfigCache.GetFPCVer;
|
||||
FFPC_FULLVERSION:=ConfigCache.GetFPC_FULLVERSION;
|
||||
end;
|
||||
end else
|
||||
FFPC_FULLVERSION:=FPCVersionToNumber(FFPCVer);
|
||||
end;
|
||||
|
||||
begin
|
||||
|
||||
@ -301,8 +301,9 @@ function TCheckCompilerOptsDlg.CheckCompileBogusFile(
|
||||
var
|
||||
TestDir: String;
|
||||
BogusFilename: String;
|
||||
CmdLineParams: String;
|
||||
CmdLineParams, ErrMsg: String;
|
||||
CompileTool: TAbstractExternalTool;
|
||||
Kind: TPascalCompiler;
|
||||
begin
|
||||
// compile bogus file
|
||||
FTest:=cotCompileBogusFiles;
|
||||
@ -334,7 +335,7 @@ begin
|
||||
CompileTool:=ExternalToolList.Add(dlgCCOTestToolCompilingEmptyFile);
|
||||
CompileTool.Reference(Self,ClassName);
|
||||
try
|
||||
if GuessCompilerType(CompilerFilename)=pcPas2js then
|
||||
if IsCompilerExecutable(CompilerFilename,ErrMsg,Kind,true) and (Kind=pcPas2js) then
|
||||
CompileTool.AddParsers(SubToolPas2js)
|
||||
else
|
||||
CompileTool.AddParsers(SubToolFPC);
|
||||
|
||||
@ -44,7 +44,7 @@ uses
|
||||
// LCL
|
||||
Forms, Controls,
|
||||
// Codetools
|
||||
DefineTemplates, LinkScanner, TransferMacros,
|
||||
DefineTemplates, LinkScanner, CodeToolManager, TransferMacros,
|
||||
// IdeIntf
|
||||
IDEExternToolIntf, IDEMsgIntf, LazIDEIntf,
|
||||
// IDE
|
||||
@ -282,6 +282,7 @@ var
|
||||
TargetOS: String;
|
||||
TargetCPU: String;
|
||||
TargetFilename, SubTool: String;
|
||||
CompilerKind: TPascalCompiler;
|
||||
begin
|
||||
Result:=mrCancel;
|
||||
if ConsoleVerbosity>=1 then
|
||||
@ -344,7 +345,8 @@ begin
|
||||
Tool.Process.CurrentDirectory:=WorkingDir;
|
||||
Tool.CurrentDirectoryIsTestDir:=CurrentDirectoryIsTestDir;
|
||||
SubTool:=SubToolFPC;
|
||||
if GuessCompilerType(CompilerFilename)=pcPas2js then
|
||||
CompilerKind:=CodeToolBoss.GetPascalCompilerForDirectory(WorkingDir);
|
||||
if CompilerKind=pcPas2js then
|
||||
SubTool:=SubToolPas2js;
|
||||
FPCParser:=TFPCParser(Tool.AddParsers(SubTool));
|
||||
FPCParser.ShowLinesCompiled:=EnvironmentOptions.MsgViewShowFPCMsgLinesCompiled;
|
||||
|
||||
@ -2582,7 +2582,7 @@ var
|
||||
DefaultTargetOS: string;
|
||||
DefaultTargetCPU: string;
|
||||
RealCompilerFilename: String;
|
||||
s, CurNamespaces: string;
|
||||
CurNamespaces: string;
|
||||
CurFPCMsgFile: TFPCMsgFilePoolItem;
|
||||
Quiet: Boolean;
|
||||
Kind: TPascalCompiler;
|
||||
@ -2859,9 +2859,10 @@ begin
|
||||
Quiet:=ConsoleVerbosity<=-3; // lazbuild -q -q, lazarus -q -q -q
|
||||
|
||||
CompilerFilename:=ParsedOpts.GetParsedValue(pcosCompilerPath);
|
||||
if IsCompilerExecutable(CompilerFilename,s,Kind) then
|
||||
if CompilerFilename<>'' then
|
||||
RealCompilerFilename:=CompilerFilename
|
||||
else begin
|
||||
// use default compiler
|
||||
RealCompilerFilename:=EnvironmentOptions.GetParsedCompilerFilename;
|
||||
Kind:=pcFPC;
|
||||
end;
|
||||
@ -4093,6 +4094,7 @@ begin
|
||||
else if Option in ParsedCompilerFilenames then
|
||||
begin
|
||||
// make filename absolute
|
||||
//debugln(['TParsedCompilerOptions.DoParseOption ',ParsedCompilerOptsVars[Option],' s="',s,'"']);
|
||||
if ExtractFilePath(s)='' then begin
|
||||
h:=FileUtil.FindDefaultExecutablePath(s,GetBaseDir);
|
||||
if h<>'' then s:=h;
|
||||
|
||||
@ -1009,7 +1009,6 @@ var
|
||||
FPCVer: String;
|
||||
FPCSrcDir: String;
|
||||
aFilename: String;
|
||||
ErrMsg: string;
|
||||
begin
|
||||
if fMsgFileStamp<>CompilerParseStamp then begin
|
||||
fCurrentEnglishFile:=DefaultEnglishFile;
|
||||
@ -1017,10 +1016,7 @@ begin
|
||||
// English msg file
|
||||
// => use fpcsrcdir/compiler/msg/errore.msg
|
||||
// the fpcsrcdir might depend on the FPC version
|
||||
if IsFPCExecutable(CompilerFilename,ErrMsg) then
|
||||
FPCVer:=CodeToolBoss.CompilerDefinesCache.GetFPCVersion(CompilerFilename,TargetOS,TargetCPU,false)
|
||||
else
|
||||
FPCVer:='';
|
||||
FPCVer:=CodeToolBoss.CompilerDefinesCache.GetFPCVersion(CompilerFilename,TargetOS,TargetCPU,false);
|
||||
FPCSrcDir:=EnvironmentOptions.GetParsedFPCSourceDirectory(FPCVer);
|
||||
if FilenameIsAbsolute(FPCSrcDir) then begin
|
||||
// FPCSrcDir exists => use the errore.msg
|
||||
|
||||
@ -12,7 +12,7 @@ uses
|
||||
// CodeTools
|
||||
FileProcs, DefineTemplates, CodeToolManager, LinkScanner,
|
||||
// LazUtils
|
||||
FileUtil, LazFileUtils,
|
||||
FileUtil, LazFileUtils, LazUTF8,
|
||||
// IDEIntf
|
||||
IDEOptionsIntf, IDEOptEditorIntf, CompOptsIntf, IDEExternToolIntf,
|
||||
IDEDialogs, IDEUtils,
|
||||
@ -126,42 +126,43 @@ begin
|
||||
|
||||
if not OpenDialog.Execute then exit;
|
||||
NewFilename:=TrimAndExpandFilename(OpenDialog.Filename);
|
||||
// check, even if new file is old filename, so the user see the warnings again
|
||||
// check, even if new file is old filename, so the user sees the warnings again
|
||||
ok:=false;
|
||||
if Sender=BrowseCompilerButton then begin
|
||||
// check compiler filename
|
||||
case GetPascalCompilerFromExeName(NewFilename) of
|
||||
pcPas2js:
|
||||
if IsPas2JSExecutable(NewFilename,s) then begin
|
||||
// check pas2js
|
||||
Quality:=CheckPas2jsQuality(NewFilename,Note,
|
||||
CodeToolBoss.CompilerDefinesCache.TestFilename);
|
||||
if not ShowQuality(Quality,NewFilename,Note) then exit;
|
||||
ok:=true;
|
||||
end;
|
||||
else
|
||||
if IsCompilerExecutable(NewFilename,s,Kind) then begin
|
||||
// check compiler
|
||||
if Kind=pcPas2js then
|
||||
Quality:=CheckPas2jsQuality(NewFilename,Note,
|
||||
CodeToolBoss.CompilerDefinesCache.TestFilename)
|
||||
else
|
||||
Quality:=CheckFPCExeQuality(NewFilename,Note,
|
||||
CodeToolBoss.CompilerDefinesCache.TestFilename);
|
||||
if not ShowQuality(Quality,NewFilename,Note) then exit;
|
||||
ok:=true;
|
||||
end;
|
||||
if Pos('pas2js',UTF8LowerCase(ExtractFileNameOnly(NewFilename)))>0 then begin
|
||||
// check pas2js
|
||||
Quality:=CheckPas2jsQuality(NewFilename,Note,
|
||||
CodeToolBoss.CompilerDefinesCache.TestFilename);
|
||||
if not ShowQuality(Quality,NewFilename,Note) then exit;
|
||||
ok:=true;
|
||||
end;
|
||||
// maybe a script
|
||||
if (not ok)
|
||||
and not CheckExecutable(OldFilename,NewFilename,lisInvalidExecutable,lisInvalidExecutableMessageText)
|
||||
then
|
||||
exit;
|
||||
ok:=true;
|
||||
and (SameText('ppc',LeftStr(ExtractFileNameOnly(NewFilename),3))
|
||||
or (Pos('fpc',UTF8LowerCase(ExtractFileNameOnly(NewFilename)))>0)) then begin
|
||||
// check fpc
|
||||
Quality:=CheckFPCExeQuality(NewFilename,Note,
|
||||
CodeToolBoss.CompilerDefinesCache.TestFilename);
|
||||
if not ShowQuality(Quality,NewFilename,Note) then exit;
|
||||
ok:=true;
|
||||
end;
|
||||
if not ok then begin
|
||||
// maybe a wrapper script
|
||||
if IsCompilerExecutable(NewFilename,s,Kind,true) then begin
|
||||
if (s<>'') and not ShowQuality(sddqInvalid,NewFilename,s) then exit;
|
||||
ok:=true;
|
||||
end;
|
||||
// maybe a script
|
||||
if (not ok)
|
||||
and not CheckExecutable('',NewFilename,lisInvalidExecutable,lisInvalidExecutableMessageText)
|
||||
then
|
||||
exit;
|
||||
ok:=true;
|
||||
end;
|
||||
end else if (Sender=ExecBeforeBrowseButton)
|
||||
or (Sender=ExecAfterBrowseButton) then begin
|
||||
// check executable
|
||||
if not CheckExecutable(OldFilename,NewFilename,lisInvalidExecutable,lisInvalidExecutableMessageText)
|
||||
if not CheckExecutable('',NewFilename,lisInvalidExecutable,lisInvalidExecutableMessageText)
|
||||
then
|
||||
exit;
|
||||
ok:=true;
|
||||
|
||||
@ -315,7 +315,7 @@ begin
|
||||
sl.Add('RealCompilerDate='+DateTimeToStr(FileDateToDateTimeDef(CfgCache.RealCompilerDate)));
|
||||
sl.Add('RealTargetOS='+CfgCache.RealTargetOS);
|
||||
sl.Add('RealTargetCPU='+CfgCache.RealTargetCPU);
|
||||
sl.Add('RealCompilerInPath='+CfgCache.RealCompilerInPath);
|
||||
sl.Add('RealCompilerInPath='+CfgCache.RealTargetCPUCompiler);
|
||||
sl.Add('Version='+CfgCache.FullVersion);
|
||||
HasCfgs:=false;
|
||||
if CfgCache.ConfigFiles<>nil then begin
|
||||
|
||||
@ -280,6 +280,7 @@ procedure TIDEInfoDialog.GatherGlobalOptions(sl: TStrings);
|
||||
var
|
||||
CfgCache: TPCTargetConfigCache;
|
||||
Note, aFilename: string;
|
||||
CompilerKind: TPascalCompiler;
|
||||
begin
|
||||
sl.add('Global IDE options:');
|
||||
sl.Add('Primary config directory='+GetPrimaryConfigPath);
|
||||
@ -302,12 +303,13 @@ begin
|
||||
sl.Add('Project CompilerFilename='+Project1.CompilerOptions.CompilerPath);
|
||||
aFilename:=LazarusIDE.GetCompilerFilename;
|
||||
sl.Add('Real Project CompilerFilename='+aFilename);
|
||||
if GuessCompilerType(aFilename)=pcPas2js then begin
|
||||
IsCompilerExecutable(aFilename,Note,CompilerKind,true);
|
||||
if CompilerKind=pcPas2js then begin
|
||||
if CheckPas2jsQuality(aFilename,Note,
|
||||
CodeToolBoss.CompilerDefinesCache.TestFilename)<>sddqCompatible
|
||||
then
|
||||
sl.Add('WARNING: '+Note);
|
||||
end else begin;
|
||||
end else begin
|
||||
if CheckFPCExeQuality(aFilename,Note,
|
||||
CodeToolBoss.CompilerDefinesCache.TestFilename)<>sddqCompatible
|
||||
then
|
||||
|
||||
@ -95,7 +95,7 @@ uses
|
||||
// LCL
|
||||
Forms, Controls, Dialogs,
|
||||
// LazUtils
|
||||
UTF8Process, FileUtil, LazFileUtils, LazUtilities, LazUTF8,
|
||||
UTF8Process, FileUtil, LazFileUtils, LazUtilities, LazUTF8, LazUTF8Classes,
|
||||
// CodeTools
|
||||
FileProcs,
|
||||
// IdeIntf
|
||||
@ -421,12 +421,18 @@ end;
|
||||
|
||||
constructor TLazarusProcess.Create(const LazarusPath: string;
|
||||
const CommandLine: string; EnvOverrides: TStringList);
|
||||
var
|
||||
Params: TStringListUTF8;
|
||||
begin
|
||||
FProcess := TProcessUTF8.Create(nil);
|
||||
FProcess.InheritHandles := false;
|
||||
FProcess.Options := [];
|
||||
FProcess.ShowWindow := swoShow;
|
||||
FProcess.CommandLine := LazarusPath + CommandLine;
|
||||
Params:=TStringListUTF8.Create;
|
||||
Params.Add(LazarusPath);
|
||||
SplitCmdLineParams(CommandLine,Params);
|
||||
FProcess.Parameters:=Params;
|
||||
Params.Free;
|
||||
if (EnvOverrides<>nil) and (EnvOverrides.Count>0) then
|
||||
AssignEnvironmentTo(FProcess.Environment,EnvOverrides);
|
||||
end;
|
||||
|
||||
55
ide/main.pp
55
ide/main.pp
@ -7180,7 +7180,8 @@ end;
|
||||
function TMainIDE.DoRunProjectWithoutDebug: TModalResult;
|
||||
var
|
||||
Process: TProcessUTF8;
|
||||
ExeCmdLine, ExeWorkingDirectory, ExeFile, Params: string;
|
||||
RunCmdLine, RunWorkingDirectory, ExeFile: string;
|
||||
Params: TStringListUTF8;
|
||||
RunAppBundle, Handled: Boolean;
|
||||
ARunMode: TRunParamsOptionsMode;
|
||||
begin
|
||||
@ -7199,29 +7200,39 @@ begin
|
||||
Result:=DoCallRunWithoutDebugInit(Handled);
|
||||
if Handled then exit;
|
||||
|
||||
ExeCmdLine := MainBuildBoss.GetRunCommandLine;
|
||||
debugln(['Hint: (lazarus) [TMainIDE.DoRunProjectWithoutDebug] ExeCmdLine="',ExeCmdLine,'"']);
|
||||
if ExeCmdLine='' then
|
||||
RunCmdLine := MainBuildBoss.GetRunCommandLine;
|
||||
debugln(['Hint: (lazarus) [TMainIDE.DoRunProjectWithoutDebug] ExeCmdLine="',RunCmdLine,'"']);
|
||||
if RunCmdLine='' then
|
||||
begin
|
||||
IDEMessageDialog(lisUnableToRun, lisLaunchingApplicationInvalid,
|
||||
mtError,[mbCancel]);
|
||||
Exit(mrNone);
|
||||
end;
|
||||
|
||||
Params:=TStringListUTF8.Create;
|
||||
Process := TProcessUTF8.Create(nil);
|
||||
try
|
||||
RunAppBundle:={$IFDEF Darwin}true{$ELSE}false{$ENDIF};
|
||||
RunAppBundle:=RunAppBundle and Project1.UseAppBundle;
|
||||
|
||||
SplitCmdLine(ExeCmdLine,ExeFile,Params);
|
||||
SplitCmdLineParams(RunCmdLine,Params);
|
||||
if Params.Count=0 then begin
|
||||
IDEMessageDialog(lisUnableToRun,
|
||||
Format(lisUnableToRun2, ['<project has no target file>']),
|
||||
mtError, [mbOK]);
|
||||
exit(mrCancel);
|
||||
end else begin
|
||||
ExeFile:=Params[0];
|
||||
Params.Delete(0);
|
||||
end;
|
||||
Process.Executable := ExeFile;
|
||||
if Params<>'' then
|
||||
CommandToList(Params, Process.Parameters);
|
||||
ARunMode := Project1.RunParameterOptions.GetActiveMode;
|
||||
|
||||
if RunAppBundle and FileExistsUTF8(Process.Executable)
|
||||
and FileExistsUTF8('/usr/bin/open') then
|
||||
if RunAppBundle
|
||||
and FileExistsUTF8(Process.Executable)
|
||||
and FileExistsUTF8('/usr/bin/open') then
|
||||
begin
|
||||
// run bundle via open
|
||||
Process.Parameters.Insert(0,Process.Executable);
|
||||
Process.Executable := '/usr/bin/open';
|
||||
end else if not FileIsExecutable(Process.Executable) then
|
||||
@ -7235,19 +7246,19 @@ begin
|
||||
IDEMessageDialog(lisUnableToRun,
|
||||
Format(lisUnableToRun2, [Process.Executable]),
|
||||
mtError, [mbOK]);
|
||||
Exit(mrNone);
|
||||
Exit(mrCancel);
|
||||
end;
|
||||
|
||||
if ARunMode<>nil then
|
||||
ExeWorkingDirectory := ARunMode.WorkingDirectory
|
||||
RunWorkingDirectory := ARunMode.WorkingDirectory
|
||||
else
|
||||
ExeWorkingDirectory := '';
|
||||
if not GlobalMacroList.SubstituteStr(ExeWorkingDirectory) then
|
||||
ExeWorkingDirectory := '';
|
||||
RunWorkingDirectory := '';
|
||||
if not GlobalMacroList.SubstituteStr(RunWorkingDirectory) then
|
||||
RunWorkingDirectory := '';
|
||||
|
||||
if ExeWorkingDirectory = '' then
|
||||
ExeWorkingDirectory := ExtractFilePath(Process.Executable);
|
||||
Process.CurrentDirectory := ExeWorkingDirectory;
|
||||
if RunWorkingDirectory = '' then
|
||||
RunWorkingDirectory := ExtractFilePath(Process.Executable);
|
||||
Process.CurrentDirectory := RunWorkingDirectory;
|
||||
|
||||
if not DirectoryExists(Process.CurrentDirectory) then
|
||||
begin
|
||||
@ -7259,9 +7270,15 @@ begin
|
||||
end;
|
||||
|
||||
Project1.RunParameterOptions.AssignEnvironmentTo(Process.Environment);
|
||||
TNotifyProcessEnd.Create(Process, @DoCallRunFinishedHandler);
|
||||
except
|
||||
try
|
||||
TNotifyProcessEnd.Create(Process, @DoCallRunFinishedHandler);
|
||||
except
|
||||
on E: Exception do
|
||||
debugln(['Error: (lazarus) [TMainIDE.DoRunProjectWithoutDebug] ',E.Message]);
|
||||
end;
|
||||
finally
|
||||
Process.Free;
|
||||
Params.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user