PackageCore.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. {
  2. $Project$
  3. $Workfile$
  4. $Revision$
  5. $DateUTC$
  6. $Id$
  7. This file is part of the Indy (Internet Direct) project, and is offered
  8. under the dual-licensing agreement described on the Indy website.
  9. (http://www.indyproject.org/)
  10. Copyright:
  11. (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
  12. }
  13. {
  14. $Log$
  15. }
  16. {
  17. { Rev 1.5 3/3/2005 7:46:24 PM JPMugaas
  18. { Backdoors for BDS assembly version information.
  19. }
  20. {
  21. { Rev 1.4 9/7/2004 3:50:46 PM JPMugaas
  22. { Updates.
  23. }
  24. {
  25. { Rev 1.3 04/09/2004 12:45:16 ANeillans
  26. { Moved the databasename and output paths into a globally accessible variable
  27. { -- makes it a lot easier to override if you need to (as I did for my local
  28. { file structure).
  29. }
  30. {
  31. { Rev 1.2 2004.06.13 8:06:12 PM czhower
  32. { Update for D8
  33. }
  34. {
  35. { Rev 1.1 02/06/2004 17:00:46 HHariri
  36. { design-time added
  37. }
  38. {
  39. { Rev 1.0 2004.02.08 2:28:34 PM czhower
  40. { Initial checkin
  41. }
  42. {
  43. { Rev 1.0 2004.01.22 8:18:34 PM czhower
  44. { Initial checkin
  45. }
  46. unit PackageCore;
  47. interface
  48. uses
  49. Package;
  50. type
  51. TPackageCore = class(TPackage)
  52. protected
  53. procedure GenOptions; override;
  54. procedure GenPreRequiresClause; override;
  55. procedure GenRequires; override;
  56. procedure GenFooter; override;
  57. procedure GenResourceScript; override;
  58. function IgnoreContainsFile(const AUnit: string): Boolean; override;
  59. public
  60. constructor Create; override;
  61. procedure Generate(ACompiler: TCompiler; const AFlags: TGenerateFlags); override;
  62. procedure GenerateRC(ACompiler: TCompiler; const AFlags: TGenerateFlags); override;
  63. procedure GenerateDsnCoreResourceStrings;
  64. end;
  65. implementation
  66. uses
  67. Classes, SysUtils, DateUtils, StrUtils, DModule;
  68. { TPackageCore }
  69. constructor TPackageCore.Create;
  70. begin
  71. inherited;
  72. FOutputSubDir := 'Lib\Core';
  73. end;
  74. procedure TPackageCore.Generate(ACompiler: TCompiler; const AFlags: TGenerateFlags);
  75. var
  76. LFlags: TGenerateFlags;
  77. begin
  78. LFlags := AFlags;
  79. if (LFlags * [gfRunTime, gfDesignTime]) = [] then begin
  80. Include(LFlags, gfRunTime);
  81. end;
  82. if gfRunTime in LFlags then begin
  83. FName := 'IndyCore' + GPackageVer[ACompiler];
  84. FDesc := 'Core';
  85. FExt := '.dpk';
  86. inherited Generate(ACompiler, LFlags - [gfDesignTime]);
  87. WriteFile;
  88. end;
  89. if gfDesignTime in LFlags then begin
  90. FName := 'dclIndyCore' + GPackageVer[ACompiler];
  91. FDesc := 'Core Design Time';
  92. FExt := '.dpk';
  93. inherited Generate(ACompiler, LFlags - [gfRunTime]);
  94. WriteFile;
  95. end;
  96. end;
  97. // TODO: make the options configurable...
  98. procedure TPackageCore.GenOptions;
  99. const
  100. Delphi_Native_Align8 = Delphi_Native - [Delphi_Native_Lowest..ctDelphiPre2010NR] + [ctDelphi2005];
  101. Delphi_OmittedOptions = [Delphi_Native_Lowest..ctDelphiPre2010NRNet, ctKylix3] - [ctDelphi8Net] + [ctDelphiXE];
  102. Delphi_Native_Ifdef_ImplicitBuilding = Delphi_Native - [Delphi_Native_Lowest..ctDelphiXE];
  103. Delphi_Native_Force_DebugInfo_Off = Delphi_Native - [Delphi_Native_Lowest..ctDelphiXE7];
  104. Delphi_Native_Force_Optimization_On = Delphi_Native - [ctDelphiXE2..Delphi_Native_Highest] + Delphi_DotNet + [ctKylix3];
  105. Delphi_Native_Force_Optimization_Off = Delphi_Native - [Delphi_Native_Lowest..ctDelphiXE];
  106. Delphi_Native_Force_OverflowChecks_Off = Delphi_Native - [Delphi_Native_Lowest..ctDelphiXE];
  107. Delphi_Native_Force_RangeChecks_Off = Delphi_Native - [Delphi_Native_Lowest..ctDelphiXE];
  108. Delphi_Native_Force_StackFrames_On = Delphi_Native - [Delphi_Native_Lowest..ctDelphiXE];
  109. Delphi_Native_Define_DebugRelease = [ctDelphiXE2..ctDelphiSydney];
  110. Delphi_Native_Define_Ver_DT = [ctDelphiXE4..ctDelphiSydney] - [ctDelphiXE8..ctDelphiSeattle];
  111. Delphi_Native_Define_Ver_RT = [ctDelphiXE4..ctDelphiSydney];
  112. function OnOrOff(const AForceOff, AForceOn: TCompilers; const ADefault: Boolean): string;
  113. begin
  114. if FCompiler in AForceOff then begin
  115. Result := 'OFF';
  116. end
  117. else if FCompiler in AForceOn then begin
  118. Result := 'ON';
  119. end
  120. else begin
  121. Result := iif(ADefault, 'ON', 'OFF');
  122. end;
  123. end;
  124. begin
  125. Code('');
  126. if FCompiler in Delphi_DotNet then begin
  127. Code('{$ALIGN 0}');
  128. end else begin
  129. Code('{$R *.res}');
  130. if FCompiler in Delphi_Native_Ifdef_ImplicitBuilding then begin
  131. Code('{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}');
  132. end;
  133. if FCompiler in Delphi_Native_Align8 then begin
  134. Code('{$ALIGN 8}');
  135. end;
  136. end;
  137. if not (FCompiler in Delphi_OmittedOptions) then begin
  138. Code('{$ASSERTIONS ON}');
  139. end;
  140. Code('{$BOOLEVAL OFF}');
  141. if not (FCompiler in Delphi_OmittedOptions) then begin
  142. Code('{$DEBUGINFO ' + OnOrOff(Delphi_Native_Force_DebugInfo_Off, [], FDebug) + '}');
  143. end;
  144. Code('{$EXTENDEDSYNTAX ON}');
  145. Code('{$IMPORTEDDATA ON}');
  146. if not (FCompiler in Delphi_OmittedOptions) then begin
  147. Code('{$IOCHECKS ON}');
  148. end;
  149. Code('{$LOCALSYMBOLS ON}');
  150. Code('{$LONGSTRINGS ON}');
  151. Code('{$OPENSTRINGS ON}');
  152. if FCompiler in Delphi_Native_Force_Optimization_On then begin
  153. Code('{$OPTIMIZATION ' + OnOrOff([], Delphi_Native_Force_Optimization_On, FDebug) + '}');
  154. end
  155. else if FCompiler in Delphi_Native_Force_Optimization_Off then begin
  156. Code('{$OPTIMIZATION ' + OnOrOff(Delphi_Native_Force_Optimization_Off, [], FDebug) + '}');
  157. end;
  158. if not (FCompiler in Delphi_OmittedOptions) then begin
  159. Code('{$OVERFLOWCHECKS ' + OnOrOff(Delphi_Native_Force_OverflowChecks_Off, [], FDebug) + '}');
  160. Code('{$RANGECHECKS ' + OnOrOff(Delphi_Native_Force_RangeChecks_Off, [], FDebug) + '}');
  161. end;
  162. Code('{$REFERENCEINFO ON}');
  163. Code('{$SAFEDIVIDE OFF}');
  164. Code('{$STACKFRAMES ' + OnOrOff([], Delphi_Native_Force_StackFrames_On, not FDebug) + '}');
  165. Code('{$TYPEDADDRESS OFF}');
  166. Code('{$VARSTRINGCHECKS ON}');
  167. Code('{$WRITEABLECONST OFF}');
  168. Code('{$MINENUMSIZE 1}');
  169. Code('{$IMAGEBASE $400000}');
  170. if FCompiler in Delphi_Native_Define_DebugRelease then begin
  171. Code('{$DEFINE ' + iif(FDebug, 'DEBUG', 'RELEASE') + '}');
  172. end;
  173. if FDesignTime then begin
  174. if FCompiler in Delphi_Native_Define_Ver_DT then begin
  175. Code('{$DEFINE VER' + GCompilerVer[FCompiler] + '}');
  176. end;
  177. end else
  178. begin
  179. if FCompiler in Delphi_Native_Define_Ver_RT then begin
  180. Code('{$DEFINE VER' + GCompilerVer[FCompiler] + '}');
  181. end;
  182. end;
  183. if FCompiler in Delphi_Native_Ifdef_ImplicitBuilding then begin
  184. Code('{$ENDIF IMPLICITBUILDING}');
  185. end;
  186. Code('{$DESCRIPTION ''Indy ' + FVersion + TrimRight(' ' + FDesc) + '''}');
  187. Code(iif(FDesignTime, '{$DESIGNONLY}', '{$RUNONLY}'));
  188. Code('{$IMPLICITBUILD OFF}');
  189. end;
  190. const
  191. DelphiNative_Ifdef_Rtl_2 = Delphi_Native_Ifdef_Rtl - [ctDelphiXE2];
  192. DelphiNative_Ifdef_Rtl_3 = DelphiNative_Ifdef_Rtl_2 - [ctDelphiXE3..ctDelphiXE4];
  193. procedure TPackageCore.GenPreRequiresClause;
  194. begin
  195. if (not FDesignTime) and (FCompiler in DelphiNative_Ifdef_Rtl_3) then begin
  196. Code('');
  197. Code('// RLebeau: cannot use IdCompilerDefines.inc here!');
  198. end;
  199. end;
  200. procedure TPackageCore.GenRequires;
  201. begin
  202. if (not FDesignTime) and (FCompiler in DelphiNative_Ifdef_Rtl_2) then begin
  203. if FCompiler in Delphi_Native_Ifdef_Rtl_CheckIOS then begin
  204. Code('');
  205. Code('{$DEFINE HAS_PKG_RTL}');
  206. code('{$IFDEF NEXTGEN}');
  207. Code(' {$IFDEF IOS}');
  208. Code(' // there is no RTL package available for iOS');
  209. Code(' {$UNDEF HAS_PKG_RTL}');
  210. Code(' {$ENDIF}');
  211. Code('{$ENDIF}');
  212. end;
  213. end;
  214. Code('');
  215. Code('requires');
  216. if FDesignTime then begin
  217. if FCompiler = ctDelphi4 then begin
  218. Code(' Vcl40,');
  219. end
  220. else if FCompiler = ctDelphi5 then begin
  221. Code(' Vcl50,');
  222. end
  223. else if FCompiler in [ctDelphi6, ctDelphi7] then begin
  224. Code(' vcl,');
  225. end;
  226. if FCompiler in Delphi_DotNet then
  227. begin
  228. if FCompiler <> ctDelphi8Net then begin
  229. Code(' System.Windows.Forms,');
  230. end;
  231. Code(' Borland.Studio.Vcl.Design,');
  232. end
  233. else if not (FCompiler in [ctDelphi4..ctDelphi5]) then
  234. begin
  235. Code(' designide,');
  236. end;
  237. if FCompiler <> ctDelphi8Net then begin
  238. Code(' IndySystem' + GPackageVer[FCompiler] + ',');
  239. end;
  240. Code(' IndyCore' + GPackageVer[FCompiler] + ';');
  241. end else
  242. begin
  243. if FCompiler in Delphi_DotNet then begin
  244. Code(' Borland.Delphi,');
  245. Code(' Borland.VclRtl,');
  246. end
  247. else if FCompiler = ctDelphi4 then begin
  248. Code(' Vcl40,');
  249. end
  250. else if FCompiler = ctDelphi5 then begin
  251. Code(' Vcl50,');
  252. end else
  253. begin
  254. if FCompiler in DelphiNative_Ifdef_Rtl_2 then begin
  255. if FCompiler in Delphi_Native_Ifdef_Rtl_CheckIOS then begin
  256. Code(' {$IFDEF HAS_PKG_RTL}');
  257. end else begin
  258. Code(' {$IFNDEF NEXTGEN}');
  259. end;
  260. end;
  261. Code(' rtl,');
  262. if FCompiler in DelphiNative_Ifdef_Rtl_2 then begin
  263. Code(' {$ENDIF}');
  264. end;
  265. end;
  266. Code(' IndySystem' + GPackageVer[FCompiler] + ';');
  267. end;
  268. end;
  269. procedure TPackageCore.GenFooter;
  270. begin
  271. if FCompiler in Delphi_DotNet then begin
  272. //back door for embedding version information into an assembly
  273. //without having to do anything to the package directly.
  274. Code(iif(FDesignTime, '{$I IddclCore90ASM90.inc}', '{$I IdCore90ASM90.inc}'));
  275. end;
  276. inherited GenFooter;
  277. end;
  278. procedure TPackageCore.GenerateRC(ACompiler: TCompiler; const AFlags: TGenerateFlags);
  279. var
  280. LFlags: TGenerateFlags;
  281. begin
  282. LFlags := AFlags;
  283. if (LFlags * [gfRunTime, gfDesignTime]) = [] then begin
  284. Include(LFlags, gfRunTime);
  285. end;
  286. if gfRunTime in LFlags then begin
  287. FName := 'IndyCore' + GPackageVer[ACompiler];
  288. FDesc := 'Core Run-Time';
  289. FExt := '.rc.tmpl';
  290. inherited GenerateRC(ACompiler, LFlags - [gfDesignTime] + [gfTemplate]);
  291. WriteFile;
  292. FExt := '.rc';
  293. inherited GenerateRC(ACompiler, LFlags - [gfDesignTime, gfTemplate]);
  294. WriteFile;
  295. end;
  296. if gfDesignTime in LFlags then begin
  297. FName := 'dclIndyCore' + GPackageVer[ACompiler];
  298. FDesc := 'Core Design-Time';
  299. FExt := '.rc.tmpl';
  300. inherited GenerateRC(ACompiler, LFlags - [gfRunTime] + [gfTemplate]);
  301. WriteFile;
  302. FExt := '.rc';
  303. inherited GenerateRC(ACompiler, LFlags - [gfRunTime, gfTemplate]);
  304. WriteFile;
  305. end;
  306. end;
  307. procedure TPackageCore.GenResourceScript;
  308. begin
  309. inherited GenResourceScript;
  310. WriteFile;
  311. end;
  312. function TPackageCore.IgnoreContainsFile(const AUnit: string): Boolean;
  313. begin
  314. if FDesignTime {and (FCompiler in [ctDelphi4..ctDelphi5])} then begin
  315. // TSelectionEditor was not available until Delphi 6...
  316. Result := SameText(AUnit, 'IdCoreSelectionEditors');
  317. if Result then Exit;
  318. end;
  319. Result := inherited IgnoreContainsFile(AUnit);
  320. end;
  321. procedure TPackageCore.GenerateDsnCoreResourceStrings;
  322. var
  323. LFileName: string;
  324. Data: TStringList;
  325. I: Integer;
  326. begin
  327. FCode.Clear;
  328. LFileName := DM.OutputPath + 'Lib\Core\IdDsnCoreResourceStrings.pas';
  329. // TStreamReader would be preferred, but its broken!
  330. Data := TStringList.Create;
  331. try
  332. Data.LoadFromFile(LFileName);
  333. for I := 0 to Data.Count-1 do begin
  334. if StartsStr(' RSAAboutBoxCopyright =', Data[I]) then
  335. begin
  336. Data[I] := ' RSAAboutBoxCopyright = ''Copyright (c) 1993 - ' + IntToStr(YearOf(Date)) + '''#13#10 + IndyPitCrew;';
  337. Break;
  338. end;
  339. end;
  340. FCode.Assign(Data);
  341. finally
  342. Data.Free;
  343. end;
  344. FName := 'IdDsnCoreResourceStrings';
  345. FExt := '.pas';
  346. WriteFile;
  347. end;
  348. end.