|
@@ -2718,13 +2718,19 @@ end;
|
|
|
|
|
|
|
|
|
{$ifdef HAS_UNIT_PROCESS}
|
|
|
-function GetCompilerInfo(const ACompiler,AOptions:string; ReadStdErr: boolean):string;
|
|
|
+{ function GetCompilerInfo
|
|
|
+ used both for gcc and Free Pascal compiler
|
|
|
+ returns stdout output of Acompiler with AOptions parameters
|
|
|
+ If ReadStdErr is True, return stderr output if stdout is empty
|
|
|
+ If EmptyIfStdErr, return empty string if stderr output is not empty }
|
|
|
+function GetCompilerInfo(const ACompiler,AOptions:string; ReadStdErr: boolean;EmptyIfStdErr : boolean):string;
|
|
|
const
|
|
|
BufSize = 1024;
|
|
|
var
|
|
|
S: TProcess;
|
|
|
Buf: array [0..BufSize - 1] of char;
|
|
|
- Count: longint;
|
|
|
+ ErrorBuf: array [0..BufSize - 1] of char;
|
|
|
+ Count, ErrorCount: longint;
|
|
|
begin
|
|
|
S:=TProcess.Create(Nil);
|
|
|
S.Commandline:=ACompiler+' '+AOptions;
|
|
@@ -2732,7 +2738,17 @@ begin
|
|
|
S.execute;
|
|
|
Count:=s.output.read(buf,BufSize);
|
|
|
if (count=0) and ReadStdErr then
|
|
|
- Count:=s.Stderr.read(buf,BufSize);
|
|
|
+ Count:=s.Stderr.read(buf,BufSize)
|
|
|
+ else if EmptyIfStdErr then
|
|
|
+ begin
|
|
|
+ ErrorCount:=s.StdErr.read(ErrorBuf,BufSize);
|
|
|
+ if (ErrorCount>0) then
|
|
|
+ begin
|
|
|
+ Result:='';
|
|
|
+ S.Free;
|
|
|
+ exit;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
S.Free;
|
|
|
SetLength(Result,Count);
|
|
|
Move(Buf,Result[1],Count);
|
|
@@ -2781,7 +2797,7 @@ function GetDefaultLibGCCDir(CPU : TCPU;OS: TOS; var ErrorMessage: string): stri
|
|
|
if FileExists(GccExecutable) then
|
|
|
begin
|
|
|
{$ifdef HAS_UNIT_PROCESS}
|
|
|
- ExecResult:=GetCompilerInfo(GccExecutable,'-v '+GCCParams, True);
|
|
|
+ ExecResult:=GetCompilerInfo(GccExecutable,'-v '+GCCParams, True, True);
|
|
|
libgccFilename:=Get4thWord(ExecResult);
|
|
|
// Use IsRelativePath to check if the 4th word is an (absolute) path.
|
|
|
// This depends on the language settings. In English the 4th word is
|
|
@@ -2791,7 +2807,7 @@ function GetDefaultLibGCCDir(CPU : TCPU;OS: TOS; var ErrorMessage: string): stri
|
|
|
if IsRelativePath(libgccFilename) then
|
|
|
libgccFilename:='';
|
|
|
if libgccFilename='' then
|
|
|
- libgccFilename:=GetCompilerInfo(GccExecutable,'--print-libgcc-file-name '+GCCParams, False);
|
|
|
+ libgccFilename:=GetCompilerInfo(GccExecutable,'--print-libgcc-file-name '+GCCParams, False, True);
|
|
|
result := ExtractFileDir(libgccFilename);
|
|
|
{$else HAS_UNIT_PROCESS}
|
|
|
ErrorMessage := SWarnNoFCLProcessSupport;
|
|
@@ -2814,11 +2830,11 @@ begin
|
|
|
x86_64: result := GetGccDirArch('cpux86_64','-m64');
|
|
|
powerpc: result := GetGccDirArch('cpupowerpc','-m32');
|
|
|
powerpc64:result := GetGccDirArch('cpupowerpc64','-m64');
|
|
|
- arm: result := GetGccDirArch('cpuarm','');
|
|
|
- aarch64: result := GetGccDirArch('cpuaarch64','');
|
|
|
+ arm: result := GetGccDirArch('cpuarm','-march=armv2');
|
|
|
+ aarch64: result := GetGccDirArch('cpuaarch64','-march=aarch64 -mcmodel=large');
|
|
|
m68k: result := GetGccDirArch('cpum68k','');
|
|
|
- mips: result := GetGccDirArch('cpumips','');
|
|
|
- mipsel: result := GetGccDirArch('cpumipsel','');
|
|
|
+ mips: result := GetGccDirArch('cpumips','-mips32 -EB -mabi=32');
|
|
|
+ mipsel: result := GetGccDirArch('cpumipsel','-mips32 -EL -mabi=32');
|
|
|
riscv32: result := GetGccDirArch('cpuriscv32','-march=rv32imafdc');
|
|
|
riscv64: result := GetGccDirArch('cpuriscv64','-march=rv64imafdc');
|
|
|
sparc: result := GetGccDirArch('cpusparc','-m32');
|
|
@@ -4735,7 +4751,7 @@ begin
|
|
|
// Detect compiler version/target from -i option
|
|
|
infosl:=TStringList.Create;
|
|
|
infosl.Delimiter:=' ';
|
|
|
- infosl.DelimitedText:=GetCompilerInfo(GetCompiler,'-iVTPTO', False);
|
|
|
+ infosl.DelimitedText:=GetCompilerInfo(GetCompiler,'-iVTPTO', False, True);
|
|
|
if infosl.Count<>3 then
|
|
|
Raise EInstallerError.Create(SErrInvalidFPCInfo);
|
|
|
if FCompilerVersion='' then
|