192 lines
5.8 KiB
ObjectPascal
192 lines
5.8 KiB
ObjectPascal
unit Compiler.Compile;
|
|
|
|
{
|
|
Inno Setup
|
|
Copyright (C) 1997-2024 Jordan Russell
|
|
Portions by Martijn Laan
|
|
For conditions of distribution and use, see LICENSE.TXT.
|
|
|
|
Compiler DLL interface functions which wrap TSetupCompiler
|
|
}
|
|
|
|
interface
|
|
|
|
uses
|
|
Shared.CompilerInt.Struct;
|
|
|
|
function ISCompileScript(const Params: TCompileScriptParamsEx;
|
|
const PropagateExceptions: Boolean): Integer;
|
|
function ISGetVersion: PCompilerVersionInfo;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Windows, SysUtils, Classes, PathFunc,
|
|
Shared.Struct, Shared.CommonFunc, Compiler.SetupCompiler;
|
|
|
|
function GetSelfFilename: String;
|
|
{ Returns Filename of the calling DLL or application. (ParamStr(0) can only
|
|
return the filename of the calling application.) }
|
|
var
|
|
Buf: array[0..MAX_PATH-1] of Char;
|
|
begin
|
|
SetString(Result, Buf, GetModuleFileName(HInstance, Buf, SizeOf(Buf)))
|
|
end;
|
|
|
|
function ISCompileScript(const Params: TCompileScriptParamsEx;
|
|
const PropagateExceptions: Boolean): Integer;
|
|
|
|
function CheckParams(const Params: TCompileScriptParamsEx): Boolean;
|
|
begin
|
|
Result := ((Params.Size = SizeOf(Params)) or
|
|
(Params.Size = SizeOf(TCompileScriptParams))) and
|
|
Assigned(Params.CallbackProc);
|
|
end;
|
|
|
|
procedure InitializeSetupCompiler(const SetupCompiler: TSetupCompiler;
|
|
const Params: TCompileScriptParamsEx);
|
|
begin
|
|
SetupCompiler.AppData := Params.AppData;
|
|
SetupCompiler.CallbackProc := Params.CallbackProc;
|
|
if Assigned(Params.CompilerPath) then
|
|
SetupCompiler.CompilerDir := Params.CompilerPath
|
|
else
|
|
SetupCompiler.CompilerDir := PathExtractPath(GetSelfFilename);
|
|
SetupCompiler.SourceDir := Params.SourcePath;
|
|
end;
|
|
|
|
function EncodeIncludedFilenames(const IncludedFilenames: TStringList): String;
|
|
var
|
|
S: String;
|
|
I: Integer;
|
|
begin
|
|
S := '';
|
|
for I := 0 to IncludedFilenames.Count-1 do
|
|
S := S + IncludedFilenames[I] + #0;
|
|
Result := S;
|
|
end;
|
|
|
|
procedure NotifyPreproc(const SetupCompiler: TSetupCompiler);
|
|
var
|
|
Data: TCompilerCallbackData;
|
|
S: String;
|
|
begin
|
|
Data.PreprocessedScript := PChar(SetupCompiler.GetPreprocOutput);
|
|
S := EncodeIncludedFilenames(SetupCompiler.GetPreprocIncludedFilenames);
|
|
Data.IncludedFilenames := PChar(S);
|
|
Params.CallbackProc(iscbNotifyPreproc, Data, Params.AppData);
|
|
end;
|
|
|
|
procedure NotifySuccess(const SetupCompiler: TSetupCompiler);
|
|
var
|
|
Data: TCompilerCallbackData;
|
|
begin
|
|
Data.OutputExeFilename := PChar(SetupCompiler.GetExeFilename);
|
|
var DebugInfo := SetupCompiler.GetDebugInfo;
|
|
Data.DebugInfo := DebugInfo.Memory;
|
|
Data.DebugInfoSize := DebugInfo.Size;
|
|
Params.CallbackProc(iscbNotifySuccess, Data, Params.AppData);
|
|
end;
|
|
|
|
procedure NotifyError(const SetupCompiler: TSetupCompiler);
|
|
var
|
|
Data: TCompilerCallbackData;
|
|
S: String;
|
|
begin
|
|
Data.ErrorMsg := nil;
|
|
Data.ErrorFilename := nil;
|
|
Data.ErrorLine := 0;
|
|
if not(ExceptObject is EAbort) then begin
|
|
S := GetExceptMessage;
|
|
Data.ErrorMsg := PChar(S);
|
|
{ use a Pointer cast instead of PChar so that we'll get a null
|
|
pointer if the string is empty }
|
|
Data.ErrorFilename := Pointer(SetupCompiler.GetLineFilename);
|
|
Data.ErrorLine := SetupCompiler.GetLineNumber;
|
|
end;
|
|
Params.CallbackProc(iscbNotifyError, Data, Params.AppData);
|
|
end;
|
|
|
|
var
|
|
SetupCompiler: TSetupCompiler;
|
|
P: PChar;
|
|
P2: Integer;
|
|
begin
|
|
if not CheckParams(Params) then begin
|
|
Result := isceInvalidParam;
|
|
Exit;
|
|
end;
|
|
SetupCompiler := TSetupCompiler.Create(nil);
|
|
try
|
|
InitializeSetupCompiler(SetupCompiler, Params);
|
|
|
|
{ Parse Options (only present in TCompileScriptParamsEx) }
|
|
if (Params.Size <> SizeOf(TCompileScriptParams)) and Assigned(Params.Options) then begin
|
|
P := Params.Options;
|
|
while P^ <> #0 do begin
|
|
if StrLIComp(P, 'Output=', Length('Output=')) = 0 then begin
|
|
Inc(P, Length('Output='));
|
|
var Output: Boolean;
|
|
if TryStrToBoolean(P, Output) then
|
|
SetupCompiler.SetOutput(Output)
|
|
else begin
|
|
{ Bad option }
|
|
Result := isceInvalidParam;
|
|
Exit;
|
|
end;
|
|
end else if StrLIComp(P, 'OutputDir=', Length('OutputDir=')) = 0 then begin
|
|
Inc(P, Length('OutputDir='));
|
|
SetupCompiler.SetOutputDir(P);
|
|
end else if StrLIComp(P, 'OutputBaseFilename=', Length('OutputBaseFilename=')) = 0 then begin
|
|
Inc(P, Length('OutputBaseFilename='));
|
|
SetupCompiler.SetOutputBaseFilename(P);
|
|
end else if StrLIComp(P, 'SignTool-', Length('SignTool-')) = 0 then begin
|
|
Inc(P, Length('SignTool-'));
|
|
P2 := Pos('=', P);
|
|
if (P2 <> 0) then
|
|
SetupCompiler.AddSignTool(Copy(P, 1, P2-1), Copy(P, P2+1, MaxInt))
|
|
else begin
|
|
{ Bad option }
|
|
Result := isceInvalidParam;
|
|
Exit;
|
|
end;
|
|
end else if StrLIComp(P, 'ISPP:', Length('ISPP:')) = 0 then
|
|
SetupCompiler.AddPreprocOption(P)
|
|
else begin
|
|
{ Unknown option }
|
|
Result := isceInvalidParam;
|
|
Exit;
|
|
end;
|
|
Inc(P, StrLen(P) + 1);
|
|
end;
|
|
end;
|
|
|
|
try
|
|
try
|
|
SetupCompiler.Compile;
|
|
finally
|
|
NotifyPreproc(SetupCompiler);
|
|
end;
|
|
Result := isceNoError;
|
|
NotifySuccess(SetupCompiler);
|
|
except
|
|
Result := isceCompileFailure;
|
|
NotifyError(SetupCompiler);
|
|
if PropagateExceptions then
|
|
raise;
|
|
end;
|
|
finally
|
|
SetupCompiler.Free;
|
|
end;
|
|
end;
|
|
|
|
function ISGetVersion: PCompilerVersionInfo;
|
|
const
|
|
Ver: TCompilerVersionInfo =
|
|
(Title: SetupTitle; Version: SetupVersion; BinVersion: SetupBinVersion);
|
|
begin
|
|
Result := @Ver;
|
|
end;
|
|
|
|
end.
|