1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
unit CompileHelpers;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, process, UTF8Process, LCLProc;
type
{ TCompileHelper }
TCompileHelper = class
private
FCommandLine: string;
FLastError: String;
public
function TestCompile(const PrgName, FpcOpts, ExeName, FpcExe: string): String;
function TestCompileUnits(const FpcExe, FpcOpts, SrcDirName, OutLibName: string): Boolean;
property LastError: String read FLastError;
property CommandLine: string read FCommandLine;
end;
var CompileHelper: TCompileHelper;
implementation
function ReadOutput(AProcess:TProcessUTF8): TStringList;
const
TIME_OUT = 300;
READ_BYTES = 1024;
var
BytesRead: Integer;
n: Integer;
EndTime: TDateTime;
OutputStream: TMemoryStream;
begin
OutputStream := TMemoryStream.Create;
BytesRead := 0;
EndTime := Now + TIME_OUT / (24 * 60 * 60);
while AProcess.Running and (Now<EndTime) do
begin
// make sure we have room
OutputStream.SetSize(BytesRead + READ_BYTES);
// try reading it
if AProcess.Output.NumBytesAvailable>0 then begin
n := AProcess.Output.Read((OutputStream.Memory + BytesRead)^, READ_BYTES);
Inc(BytesRead, n)
end
else
// no data, wait 100 ms
Sleep(100);
end;
// read last part
repeat
// make sure we have room
OutputStream.SetSize(BytesRead + READ_BYTES);
// try reading it
if AProcess.Output.NumBytesAvailable>0 then begin
n := AProcess.Output.Read((OutputStream.Memory + BytesRead)^, READ_BYTES);
Inc(BytesRead, n);
end
else
n := 0;
until n <= 0;
OutputStream.SetSize(BytesRead);
OutputStream.Position:=0;
Result := TStringList.Create;
Result.LoadFromStream(OutputStream);
OutputStream.Free;
end;
{ TCompileHelper }
function TCompileHelper.TestCompile(const PrgName, FpcOpts, ExeName, FpcExe: string): String;
var
FpcBuild: TProcessUTF8;
OutputLines: TStrings;
CmdLine: string;
begin
Result := 'Error';
FpcBuild := TProcessUTF8.Create(nil);
OutputLines := nil;
try
{$IFDEF windows}
FpcBuild.Options := [poNewConsole, poUsePipes];
{$ELSE}
FpcBuild.Options := [poNoConsole, poUsePipes];
{$ENDIF}
FpcBuild.ShowWindow := swoHIDE;
CmdLine := FpcExe + ' -B -MObjFPC -FUlib -o'+ ExeName + ' ' + FpcOpts + ' ' + PrgName;
debugln(['**** running compiler: ', CmdLine]);
FpcBuild.CommandLine := CmdLine;
FCommandLine := CmdLine;
FpcBuild.CurrentDirectory := ExtractFileDir(PrgName);
FpcBuild.Execute;
OutputLines := ReadOutput(FpcBuild);
if FpcBuild.Running then begin
FpcBuild.Terminate(99);
end;
if FpcBuild.ExitStatus = 0 then
Result := ''
else
Result := Result + LineEnding + OutputLines.Text;
finally
FpcBuild.Free;
OutputLines.Free;
end;
end;
function TCompileHelper.TestCompileUnits(const FpcExe, FpcOpts, SrcDirName,
OutLibName: string): Boolean;
var
FpcBuild: TProcessUTF8;
OutputLines: TStrings;
CmdLine: string;
begin
Result := False;
FpcBuild := TProcessUTF8.Create(nil);
OutputLines := nil;
try
{$IFDEF windows}
FpcBuild.Options := [poNewConsole, poUsePipes];
{$ELSE}
FpcBuild.Options := [poNoConsole, poUsePipes];
{$ENDIF}
FpcBuild.ShowWindow := swoHIDE;
CmdLine := FpcExe + ' -MObjFPC -FU' + OutLibName + ' ' + FpcOpts + ' ' + SrcDirName;
debugln(['**** running compiler: ', CmdLine]);
FpcBuild.CommandLine := CmdLine;
FCommandLine := CmdLine;
FpcBuild.CurrentDirectory := ExtractFileDir(SrcDirName);
FpcBuild.Execute;
OutputLines := ReadOutput(FpcBuild);
if FpcBuild.Running then begin
FpcBuild.Terminate(99);
end;
FLastError := OutputLines.Text;
if FpcBuild.ExitStatus = 0
then Result := True
else Result := False;
finally
FpcBuild.Free;
OutputLines.Free;
end;
end;
initialization
CompileHelper:= TCompileHelper.Create;
finalization
FreeAndNil(CompileHelper);
end.
|