Compiler.Compile.pas 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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. Data.DebugInfoSize := DebugInfo.Size;
  74. Params.CallbackProc(iscbNotifySuccess, Data, Params.AppData);
  75. end;
  76. procedure NotifyError(const SetupCompiler: TSetupCompiler);
  77. var
  78. Data: TCompilerCallbackData;
  79. S: String;
  80. begin
  81. Data.ErrorMsg := nil;
  82. Data.ErrorFilename := nil;
  83. Data.ErrorLine := 0;
  84. if not(ExceptObject is EAbort) then begin
  85. S := GetExceptMessage;
  86. Data.ErrorMsg := PChar(S);
  87. { use a Pointer cast instead of PChar so that we'll get a null
  88. pointer if the string is empty }
  89. Data.ErrorFilename := Pointer(SetupCompiler.GetLineFilename);
  90. Data.ErrorLine := SetupCompiler.GetLineNumber;
  91. end;
  92. Params.CallbackProc(iscbNotifyError, Data, Params.AppData);
  93. end;
  94. var
  95. SetupCompiler: TSetupCompiler;
  96. P: PChar;
  97. P2: Integer;
  98. begin
  99. if not CheckParams(Params) then begin
  100. Result := isceInvalidParam;
  101. Exit;
  102. end;
  103. SetupCompiler := TSetupCompiler.Create(nil);
  104. try
  105. InitializeSetupCompiler(SetupCompiler, Params);
  106. { Parse Options (only present in TCompileScriptParamsEx) }
  107. if (Params.Size <> SizeOf(TCompileScriptParams)) and Assigned(Params.Options) then begin
  108. P := Params.Options;
  109. while P^ <> #0 do begin
  110. if StrLIComp(P, 'Output=', Length('Output=')) = 0 then begin
  111. Inc(P, Length('Output='));
  112. var Output: Boolean;
  113. if TryStrToBoolean(P, Output) then
  114. SetupCompiler.SetOutput(Output)
  115. else begin
  116. { Bad option }
  117. Result := isceInvalidParam;
  118. Exit;
  119. end;
  120. end else if StrLIComp(P, 'OutputDir=', Length('OutputDir=')) = 0 then begin
  121. Inc(P, Length('OutputDir='));
  122. SetupCompiler.SetOutputDir(P);
  123. end else if StrLIComp(P, 'OutputBaseFilename=', Length('OutputBaseFilename=')) = 0 then begin
  124. Inc(P, Length('OutputBaseFilename='));
  125. SetupCompiler.SetOutputBaseFilename(P);
  126. end else if StrLIComp(P, 'SignTool-', Length('SignTool-')) = 0 then begin
  127. Inc(P, Length('SignTool-'));
  128. P2 := Pos('=', P);
  129. if (P2 <> 0) then
  130. SetupCompiler.AddSignTool(Copy(P, 1, P2-1), Copy(P, P2+1, MaxInt))
  131. else begin
  132. { Bad option }
  133. Result := isceInvalidParam;
  134. Exit;
  135. end;
  136. end else if StrLIComp(P, 'ISPP:', Length('ISPP:')) = 0 then
  137. SetupCompiler.AddPreprocOption(P)
  138. else begin
  139. { Unknown option }
  140. Result := isceInvalidParam;
  141. Exit;
  142. end;
  143. Inc(P, StrLen(P) + 1);
  144. end;
  145. end;
  146. try
  147. try
  148. SetupCompiler.Compile;
  149. finally
  150. NotifyPreproc(SetupCompiler);
  151. end;
  152. Result := isceNoError;
  153. NotifySuccess(SetupCompiler);
  154. except
  155. Result := isceCompileFailure;
  156. NotifyError(SetupCompiler);
  157. if PropagateExceptions then
  158. raise;
  159. end;
  160. finally
  161. SetupCompiler.Free;
  162. end;
  163. end;
  164. function ISGetVersion: PCompilerVersionInfo;
  165. const
  166. Ver: TCompilerVersionInfo =
  167. (Title: SetupTitle; Version: SetupVersion; BinVersion: SetupBinVersion);
  168. begin
  169. Result := @Ver;
  170. end;
  171. end.