2
0

Compiler.Compile.pas 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. unit Compiler.Compile;
  2. {
  3. Inno Setup
  4. Copyright (C) 1997-2024 Jordan Russell
  5. Portions by Martijn Laan
  6. For conditions of distribution and use, see LICENSE.TXT.
  7. Compiler DLL interface functions which wrap TSetupCompiler
  8. }
  9. interface
  10. uses
  11. Shared.CompilerInt.Struct;
  12. function ISCompileScript(const Params: TCompileScriptParamsEx;
  13. const PropagateExceptions: Boolean): Integer;
  14. function ISGetVersion: PCompilerVersionInfo;
  15. implementation
  16. uses
  17. Windows, SysUtils, Classes, PathFunc,
  18. Shared.Struct, Shared.CommonFunc, Compiler.SetupCompiler;
  19. function GetSelfFilename: String;
  20. { Returns Filename of the calling DLL or application. (ParamStr(0) can only
  21. return the filename of the calling application.) }
  22. var
  23. Buf: array[0..MAX_PATH-1] of Char;
  24. begin
  25. SetString(Result, Buf, GetModuleFileName(HInstance, Buf, SizeOf(Buf)))
  26. end;
  27. function ISCompileScript(const Params: TCompileScriptParamsEx;
  28. const PropagateExceptions: Boolean): Integer;
  29. function CheckParams(const Params: TCompileScriptParamsEx): Boolean;
  30. begin
  31. Result := ((Params.Size = SizeOf(Params)) or
  32. (Params.Size = SizeOf(TCompileScriptParams))) and
  33. Assigned(Params.CallbackProc);
  34. end;
  35. procedure InitializeSetupCompiler(const SetupCompiler: TSetupCompiler;
  36. const Params: TCompileScriptParamsEx);
  37. begin
  38. SetupCompiler.AppData := Params.AppData;
  39. SetupCompiler.CallbackProc := Params.CallbackProc;
  40. if Assigned(Params.CompilerPath) then
  41. SetupCompiler.CompilerDir := Params.CompilerPath
  42. else
  43. SetupCompiler.CompilerDir := PathExtractPath(GetSelfFilename);
  44. SetupCompiler.SourceDir := Params.SourcePath;
  45. end;
  46. function EncodeIncludedFilenames(const IncludedFilenames: TStringList): String;
  47. var
  48. S: String;
  49. I: Integer;
  50. begin
  51. S := '';
  52. for I := 0 to IncludedFilenames.Count-1 do
  53. S := S + IncludedFilenames[I] + #0;
  54. Result := S;
  55. end;
  56. procedure NotifyPreproc(const SetupCompiler: TSetupCompiler);
  57. var
  58. Data: TCompilerCallbackData;
  59. S: String;
  60. begin
  61. Data.PreprocessedScript := PChar(SetupCompiler.GetPreprocOutput);
  62. S := EncodeIncludedFilenames(SetupCompiler.GetPreprocIncludedFilenames);
  63. Data.IncludedFilenames := PChar(S);
  64. Params.CallbackProc(iscbNotifyPreproc, Data, Params.AppData);
  65. end;
  66. procedure NotifySuccess(const SetupCompiler: TSetupCompiler);
  67. var
  68. Data: TCompilerCallbackData;
  69. begin
  70. Data.OutputExeFilename := PChar(SetupCompiler.GetExeFilename);
  71. var DebugInfo := SetupCompiler.GetDebugInfo;
  72. Data.DebugInfo := DebugInfo.Memory;
  73. if DebugInfo.Size > High(Cardinal) then
  74. raise Exception.Create('Unexpected DebugInfo.Size value');
  75. Data.DebugInfoSize := Cardinal(DebugInfo.Size);
  76. Params.CallbackProc(iscbNotifySuccess, Data, Params.AppData);
  77. end;
  78. procedure NotifyError(const SetupCompiler: TSetupCompiler);
  79. var
  80. Data: TCompilerCallbackData;
  81. S: String;
  82. begin
  83. Data.ErrorMsg := nil;
  84. Data.ErrorFilename := nil;
  85. Data.ErrorLine := 0;
  86. if not(ExceptObject is EAbort) then begin
  87. S := GetExceptMessage;
  88. Data.ErrorMsg := PChar(S);
  89. { use a Pointer cast instead of PChar so that we'll get a null
  90. pointer if the string is empty }
  91. Data.ErrorFilename := Pointer(SetupCompiler.GetLineFilename);
  92. Data.ErrorLine := SetupCompiler.GetLineNumber;
  93. end;
  94. Params.CallbackProc(iscbNotifyError, Data, Params.AppData);
  95. end;
  96. var
  97. SetupCompiler: TSetupCompiler;
  98. P: PChar;
  99. P2: Integer;
  100. begin
  101. if not CheckParams(Params) then begin
  102. Result := isceInvalidParam;
  103. Exit;
  104. end;
  105. SetupCompiler := TSetupCompiler.Create(nil);
  106. try
  107. InitializeSetupCompiler(SetupCompiler, Params);
  108. { Parse Options (only present in TCompileScriptParamsEx) }
  109. if (Params.Size <> SizeOf(TCompileScriptParams)) and Assigned(Params.Options) then begin
  110. P := Params.Options;
  111. while P^ <> #0 do begin
  112. if StrLIComp(P, 'Output=', Length('Output=')) = 0 then begin
  113. Inc(P, Length('Output='));
  114. var Output: Boolean;
  115. if TryStrToBoolean(P, Output) then
  116. SetupCompiler.SetOutput(Output)
  117. else begin
  118. { Bad option }
  119. Result := isceInvalidParam;
  120. Exit;
  121. end;
  122. end else if StrLIComp(P, 'OutputDir=', Length('OutputDir=')) = 0 then begin
  123. Inc(P, Length('OutputDir='));
  124. SetupCompiler.SetOutputDir(P);
  125. end else if StrLIComp(P, 'OutputBaseFilename=', Length('OutputBaseFilename=')) = 0 then begin
  126. Inc(P, Length('OutputBaseFilename='));
  127. SetupCompiler.SetOutputBaseFilename(P);
  128. end else if StrLIComp(P, 'SignTool-', Length('SignTool-')) = 0 then begin
  129. Inc(P, Length('SignTool-'));
  130. P2 := Pos('=', P);
  131. if (P2 <> 0) then
  132. SetupCompiler.AddSignTool(Copy(P, 1, P2-1), Copy(P, P2+1, MaxInt))
  133. else begin
  134. { Bad option }
  135. Result := isceInvalidParam;
  136. Exit;
  137. end;
  138. end else if StrLIComp(P, 'ISPP:', Length('ISPP:')) = 0 then
  139. SetupCompiler.AddPreprocOption(P)
  140. else begin
  141. { Unknown option }
  142. Result := isceInvalidParam;
  143. Exit;
  144. end;
  145. Inc(P, StrLen(P) + 1);
  146. end;
  147. end;
  148. try
  149. try
  150. SetupCompiler.Compile;
  151. finally
  152. NotifyPreproc(SetupCompiler);
  153. end;
  154. Result := isceNoError;
  155. NotifySuccess(SetupCompiler);
  156. except
  157. Result := isceCompileFailure;
  158. NotifyError(SetupCompiler);
  159. if PropagateExceptions then
  160. raise;
  161. end;
  162. finally
  163. SetupCompiler.Free;
  164. end;
  165. end;
  166. function ISGetVersion: PCompilerVersionInfo;
  167. const
  168. Ver: TCompilerVersionInfo =
  169. (Title: SetupTitle; Version: SetupVersion; BinVersion: SetupBinVersion);
  170. begin
  171. Result := @Ver;
  172. end;
  173. end.