pkgoptions.pp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  1. {
  2. This file is part of the Free Pascal Utilities
  3. Copyright (c) 1999-2000 by the Free Pascal development team
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. {$mode objfpc}
  11. {$h+}
  12. unit pkgoptions;
  13. interface
  14. uses Classes, Sysutils, Inifiles, fprepos, fpTemplate, pkgglobals;
  15. Const
  16. UnitConfigFileName = 'fpunits.conf';
  17. ManifestFileName = 'manifest.xml';
  18. MirrorsFileName = 'mirrors.xml';
  19. PackagesFileName = 'packages.xml';
  20. VersionsFileName = 'versions-%s.dat';
  21. CurrentConfigVersion = 4;
  22. Type
  23. { TGlobalOptions }
  24. TGlobalOptions = Class(TPersistent)
  25. private
  26. FConfigFilename: string;
  27. FSaveInifileChanges : Boolean;
  28. FConfigVersion : Integer;
  29. FRemoteMirrorsURL,
  30. FRemoteRepository,
  31. FLocalRepository,
  32. FCompilerConfigDir,
  33. FArchivesDir,
  34. FBuildDir,
  35. FDownloader,
  36. FDefaultCompilerConfig,
  37. FFPMakeCompilerConfig : String;
  38. // Parameter options
  39. FCompilerConfig : String;
  40. FAllowBroken,
  41. FInstallGlobal,
  42. FRecoveryMode : Boolean;
  43. FOptionParser: TTemplateParser;
  44. FShowLocation: Boolean;
  45. FSkipConfigurationFiles: boolean;
  46. FCustomFPMakeOptions : string;
  47. FSkipFixBrokenAfterInstall: boolean;
  48. function GetOptString(Index: integer): String;
  49. procedure SetOptString(Index: integer; const AValue: String);
  50. procedure UpdateLocalRepositoryOption;
  51. Public
  52. Constructor Create;
  53. destructor Destroy; override;
  54. Procedure InitGlobalDefaults;
  55. Procedure LoadGlobalFromFile(const AFileName : String);
  56. Procedure SaveGlobalToFile(const AFileName : String);
  57. procedure LogValues(ALogLevel: TLogLevel);
  58. // Is set when the inifile has an old version number (which is also the case when a new file is generated)
  59. Property SaveInifileChanges : Boolean Read FSaveInifileChanges;
  60. Property ConfigVersion : Integer read FConfigVersion;
  61. function LocalPackagesFile:string;
  62. function LocalMirrorsFile:string;
  63. function LocalVersionsFile(const ACompilerConfig:String):string;
  64. Published
  65. Property RemoteMirrorsURL : String Index 0 Read GetOptString Write SetOptString;
  66. // 1 is unused
  67. Property RemoteRepository : String Index 2 Read GetOptString Write SetOptString;
  68. Property LocalRepository : String Index 3 Read GetOptString Write SetOptString;
  69. Property BuildDir : String Index 4 Read GetOptString Write SetOptString;
  70. Property ArchivesDir : String Index 5 Read GetOptString Write SetOptString;
  71. Property CompilerConfigDir : String Index 6 Read GetOptString Write SetOptString;
  72. Property DefaultCompilerConfig : String Index 8 Read GetOptString Write SetOptString;
  73. Property FPMakeCompilerConfig : String Index 9 Read GetOptString Write SetOptString;
  74. Property Downloader: String Index 10 Read GetOptString Write SetOptString;
  75. Property CustomFPMakeOptions: String Index 11 Read GetOptString Write SetOptString;
  76. // Parameters
  77. Property CompilerConfig : String Read FCompilerConfig Write FCompilerConfig;
  78. Property InstallGlobal : Boolean Read FInstallGlobal Write FInstallGlobal;
  79. Property RecoveryMode : Boolean Read FRecoveryMode Write FRecoveryMode;
  80. Property AllowBroken : Boolean Read FAllowBroken Write FAllowBroken;
  81. Property ShowLocation : Boolean Read FShowLocation Write FShowLocation;
  82. Property SkipConfigurationFiles: boolean read FSkipConfigurationFiles write FSkipConfigurationFiles;
  83. Property SkipFixBrokenAfterInstall: boolean read FSkipFixBrokenAfterInstall write FSkipFixBrokenAfterInstall;
  84. end;
  85. { TCompilerOptions }
  86. TCompilerOptions = Class(TPersistent)
  87. private
  88. FConfigFilename: string;
  89. FSaveInifileChanges: Boolean;
  90. FConfigVersion : Integer;
  91. FCompiler,
  92. FCompilerVersion,
  93. FLocalInstallDir,
  94. FGlobalInstallDir,
  95. FLocalPrefix,
  96. FGlobalPrefix: String;
  97. FCompilerCPU: TCPU;
  98. FCompilerOS: TOS;
  99. FOptionParser: TTemplateParser;
  100. FOptions: TStrings;
  101. function GetOptions: TStrings;
  102. function GetOptString(Index: integer): String;
  103. procedure SetOptString(Index: integer; const AValue: String);
  104. procedure SetCompilerCPU(const AValue: TCPU);
  105. procedure SetCompilerOS(const AValue: TOS);
  106. Public
  107. Constructor Create;
  108. Destructor Destroy; override;
  109. Procedure InitCompilerDefaults;
  110. Procedure LoadCompilerFromFile(const AFileName : String);
  111. Procedure SaveCompilerToFile(const AFileName : String);
  112. procedure LogValues(ALogLevel: TLogLevel; const ACfgName:string);
  113. procedure UpdateLocalRepositoryOption;
  114. procedure CheckCompilerValues;
  115. Function LocalUnitDir:string;
  116. Function GlobalUnitDir:string;
  117. Function HasOptions: boolean;
  118. // Is set when the inifile has an old version number (which is also the case when a new file is generated)
  119. Property SaveInifileChanges : Boolean Read FSaveInifileChanges;
  120. Property ConfigVersion : Integer read FConfigVersion;
  121. Published
  122. Property Compiler : String Index 1 Read GetOptString Write SetOptString;
  123. Property CompilerTarget : String Index 2 Read GetOptString Write SetOptString;
  124. Property CompilerVersion : String Index 3 Read GetOptString Write SetOptString;
  125. Property GlobalInstallDir : String Index 4 Read GetOptString Write SetOptString;
  126. Property LocalInstallDir : String Index 5 Read GetOptString Write SetOptString;
  127. Property GlobalPrefix : String Index 6 Read GetOptString Write SetOptString;
  128. Property LocalPrefix : String Index 7 Read GetOptString Write SetOptString;
  129. Property Options : TStrings read GetOptions;
  130. Property CompilerOS : TOS Read FCompilerOS Write SetCompilerOS;
  131. Property CompilerCPU : TCPU Read FCompilerCPU Write SetCompilerCPU;
  132. end;
  133. var
  134. GlobalOptions : TGlobalOptions;
  135. CompilerOptions : TCompilerOptions;
  136. FPMakeCompilerOptions : TCompilerOptions;
  137. Implementation
  138. uses
  139. pkgmessages;
  140. Const
  141. DefaultMirrorsURL = 'http://www.freepascal.org/repository/'+MirrorsFileName;
  142. {$ifdef localrepository}
  143. DefaultRemoteRepository = 'file://'+{$I %HOME%}+'/repository/';
  144. {$else}
  145. DefaultRemoteRepository = 'auto';
  146. {$endif}
  147. // ini file keys
  148. SDefaults = 'Defaults';
  149. // All configs
  150. KeyConfigVersion = 'ConfigVersion';
  151. // Global config
  152. KeyRemoteMirrorsURL = 'RemoteMirrors';
  153. KeyRemoteRepository = 'RemoteRepository';
  154. KeyLocalRepository = 'LocalRepository';
  155. KeyArchivesDir = 'ArchivesDir';
  156. KeyBuildDir = 'BuildDir';
  157. KeyCompilerConfigDir = 'CompilerConfigDir';
  158. KeyCompilerConfig = 'CompilerConfig';
  159. KeyFPMakeCompilerConfig = 'FPMakeCompilerConfig';
  160. KeyDownloader = 'Downloader';
  161. KeyCustomFPMakeOptions = 'FPMakeOptions';
  162. // Compiler dependent config
  163. KeyGlobalPrefix = 'GlobalPrefix';
  164. KeyLocalPrefix = 'LocalPrefix';
  165. KeyGlobalInstallDir = 'GlobalInstallDir';
  166. KeyLocalInstallDir = 'LocalInstallDir';
  167. KeyCompiler = 'Compiler' ;
  168. KeyCompilerOS = 'OS';
  169. KeyCompilerCPU = 'CPU';
  170. KeyCompilerVersion = 'Version';
  171. {*****************************************************************************
  172. TGlobalOptions
  173. *****************************************************************************}
  174. constructor TGlobalOptions.Create;
  175. begin
  176. FOptionParser := TTemplateParser.Create;
  177. FOptionParser.Values['AppConfigDir'] := GetAppConfigDir(false);
  178. FOptionParser.Values['UserDir'] := GetUserDir;
  179. InitGlobalDefaults;
  180. end;
  181. destructor TGlobalOptions.Destroy;
  182. begin
  183. FOptionParser.Free;
  184. inherited Destroy;
  185. end;
  186. function TGlobalOptions.GetOptString(Index: integer): String;
  187. begin
  188. Case Index of
  189. 0 : Result:=FRemoteMirrorsURL;
  190. 2 : Result:=FRemoteRepository;
  191. 3 : Result:=FOptionParser.ParseString(FLocalRepository);
  192. 4 : Result:=FOptionParser.ParseString(FBuildDir);
  193. 5 : Result:=FOptionParser.ParseString(FArchivesDir);
  194. 6 : Result:=FOptionParser.ParseString(FCompilerConfigDir);
  195. 8 : Result:=FDefaultCompilerConfig;
  196. 9 : Result:=FFPMakeCompilerConfig;
  197. 10 : Result:=FDownloader;
  198. 11 : Result:=FCustomFPMakeOptions;
  199. else
  200. Error('Unknown option');
  201. end;
  202. end;
  203. procedure TGlobalOptions.SetOptString(Index: integer; const AValue: String);
  204. begin
  205. If AValue=GetOptString(Index) then
  206. Exit;
  207. Case Index of
  208. 1 : FRemoteMirrorsURL:=AValue;
  209. 2 : FRemoteRepository:=AValue;
  210. 3 : begin
  211. FLocalRepository:=AValue;
  212. UpdateLocalRepositoryOption;
  213. end;
  214. 4 : FBuildDir:=FixPath(AValue);
  215. 5 : FArchivesDir:=FixPath(AValue);
  216. 6 : FCompilerConfigDir:=FixPath(AValue);
  217. 8 : FDefaultCompilerConfig:=AValue;
  218. 9 : FFPMakeCompilerConfig:=AValue;
  219. 10 : FDownloader:=AValue;
  220. 11 : FCustomFPMakeOptions:=AValue;
  221. else
  222. Error('Unknown option');
  223. end;
  224. end;
  225. procedure TGlobalOptions.UpdateLocalRepositoryOption;
  226. begin
  227. FOptionParser.Values['LocalRepository'] := LocalRepository;
  228. end;
  229. function TGlobalOptions.LocalPackagesFile:string;
  230. begin
  231. Result:=LocalRepository+PackagesFileName;
  232. end;
  233. function TGlobalOptions.LocalMirrorsFile:string;
  234. begin
  235. Result:=LocalRepository+MirrorsFileName;
  236. end;
  237. function TGlobalOptions.LocalVersionsFile(const ACompilerConfig:String):string;
  238. begin
  239. Result:=LocalRepository+Format(VersionsFileName,[ACompilerConfig]);
  240. end;
  241. Procedure TGlobalOptions.InitGlobalDefaults;
  242. var
  243. i: Integer;
  244. begin
  245. FConfigVersion:=CurrentConfigVersion;
  246. // Retrieve Local fppkg directory
  247. {$ifdef unix}
  248. if IsSuperUser then
  249. begin
  250. if DirectoryExists('/usr/local/lib/fpc') then
  251. FLocalRepository:='/usr/local/lib/fpc/fppkg/'
  252. else
  253. FLocalRepository:='/usr/lib/fpc/fppkg/';
  254. end
  255. else
  256. FLocalRepository:='{UserDir}.fppkg/';
  257. {$else}
  258. if IsSuperUser then
  259. FLocalRepository:=IncludeTrailingPathDelimiter(GetAppConfigDir(true))
  260. else
  261. FLocalRepository:='{AppConfigDir}';
  262. {$endif}
  263. UpdateLocalRepositoryOption;
  264. // Directories
  265. FBuildDir:='{LocalRepository}build'+PathDelim;
  266. FArchivesDir:='{LocalRepository}archives'+PathDelim;
  267. FCompilerConfigDir:='{LocalRepository}config'+PathDelim;
  268. // Remote
  269. FRemoteMirrorsURL:=DefaultMirrorsURL;
  270. FRemoteRepository:=DefaultRemoteRepository;
  271. // Other config
  272. FDefaultCompilerConfig:='default';
  273. FFPMakeCompilerConfig:='default';
  274. // Downloader
  275. {$if defined(unix) or defined(windows)}
  276. FDownloader:='lnet';
  277. {$else}
  278. FDownloader:='base';
  279. {$endif}
  280. // Parameter defaults
  281. FCompilerConfig:=FDefaultCompilerConfig;
  282. FInstallGlobal:=False;
  283. FRecoveryMode:=False;
  284. FAllowBroken:=False;
  285. SetLength(FPMKUnitDeps,FPMKUnitDepDefaultCount);
  286. for i := 0 to FPMKUnitDepDefaultCount-1 do
  287. FPMKUnitDeps[i]:=FPMKUnitDepsDefaults[i];
  288. end;
  289. procedure TGlobalOptions.LoadGlobalFromFile(const AFileName: String);
  290. Var
  291. Ini : TMemIniFile;
  292. begin
  293. try
  294. Ini:=TMemIniFile.Create(AFileName);
  295. FConfigFileName:=AFileName;
  296. With Ini do
  297. begin
  298. FConfigVersion:=ReadInteger(SDefaults,KeyConfigVersion,0);
  299. if (FConfigVersion<>CurrentConfigVersion) then
  300. begin
  301. Log(vlDebug,SLogUpgradingConfig,[AFileName]);
  302. FSaveInifileChanges:=true;
  303. if FConfigVersion<1 then
  304. begin
  305. FRemoteRepository:='auto';
  306. end;
  307. if FConfigVersion<3 then
  308. begin
  309. // Directories
  310. FBuildDir:=FLocalRepository+'build'+PathDelim;
  311. FArchivesDir:=FLocalRepository+'archives'+PathDelim;
  312. FCompilerConfigDir:=FLocalRepository+'config'+PathDelim;
  313. end;
  314. if (FConfigVersion>CurrentConfigVersion) then
  315. Error(SErrUnsupportedConfigVersion,[AFileName]);
  316. end;
  317. FRemoteMirrorsURL:=ReadString(SDefaults,KeyRemoteMirrorsURL,FRemoteMirrorsURL);
  318. FRemoteRepository:=ReadString(SDefaults,KeyRemoteRepository,FRemoteRepository);
  319. FLocalRepository:=ReadString(SDefaults,KeyLocalRepository,FLocalRepository);
  320. UpdateLocalRepositoryOption;
  321. FBuildDir:=FixPath(ReadString(SDefaults,KeyBuildDir,FBuildDir));
  322. FArchivesDir:=FixPath(ReadString(SDefaults,KeyArchivesDir,FArchivesDir));
  323. FCompilerConfigDir:=FixPath(ReadString(SDefaults,KeyCompilerConfigDir,FCompilerConfigDir));
  324. FDefaultCompilerConfig:=ReadString(SDefaults,KeyCompilerConfig,FDefaultCompilerConfig);
  325. FFPMakeCompilerConfig:=ReadString(SDefaults,KeyFPMakeCompilerConfig,FFPMakeCompilerConfig);
  326. FDownloader:=ReadString(SDefaults,KeyDownloader,FDownloader);
  327. FCustomFPMakeOptions:=ReadString(SDefaults,KeyCustomFPMakeOptions,FCustomFPMakeOptions);
  328. end;
  329. finally
  330. Ini.Free;
  331. end;
  332. end;
  333. procedure TGlobalOptions.SaveGlobalToFile(const AFileName: String);
  334. Var
  335. Ini : TIniFile;
  336. begin
  337. if FileExists(AFileName) then
  338. BackupFile(AFileName);
  339. try
  340. Ini:=TIniFile.Create(AFileName);
  341. With Ini do
  342. begin
  343. WriteInteger(SDefaults,KeyConfigVersion,CurrentConfigVersion);
  344. WriteString(SDefaults,KeyLocalRepository,FLocalRepository);
  345. WriteString(SDefaults,KeyBuildDir,FBuildDir);
  346. WriteString(SDefaults,KeyArchivesDir,FArchivesDir);
  347. WriteString(SDefaults,KeyCompilerConfigDir,FCompilerConfigDir);
  348. WriteString(SDefaults,KeyRemoteMirrorsURL,FRemoteMirrorsURL);
  349. WriteString(SDefaults,KeyRemoteRepository,FRemoteRepository);
  350. WriteString(SDefaults,KeyCompilerConfig,FDefaultCompilerConfig);
  351. WriteString(SDefaults,KeyFPMakeCompilerConfig,FFPMakeCompilerConfig);
  352. WriteString(SDefaults,KeyDownloader,FDownloader);
  353. FSaveInifileChanges:=False;
  354. end;
  355. Ini.UpdateFile;
  356. finally
  357. Ini.Free;
  358. end;
  359. end;
  360. procedure TGlobalOptions.LogValues(ALogLevel: TLogLevel);
  361. begin
  362. Log(ALogLevel,SLogGlobalCfgHeader,[FConfigFilename]);
  363. Log(ALogLevel,SLogGlobalCfgRemoteMirrorsURL,[FRemoteMirrorsURL]);
  364. Log(ALogLevel,SLogGlobalCfgRemoteRepository,[FRemoteRepository]);
  365. Log(ALogLevel,SLogGlobalCfgLocalRepository,[FLocalRepository,LocalRepository]);
  366. Log(ALogLevel,SLogGlobalCfgBuildDir,[FBuildDir,BuildDir]);
  367. Log(ALogLevel,SLogGlobalCfgArchivesDir,[FArchivesDir,ArchivesDir]);
  368. Log(ALogLevel,SLogGlobalCfgCompilerConfigDir,[FCompilerConfigDir,CompilerConfigDir]);
  369. Log(ALogLevel,SLogGlobalCfgDefaultCompilerConfig,[FDefaultCompilerConfig]);
  370. Log(ALogLevel,SLogGlobalCfgFPMakeCompilerConfig,[FPMakeCompilerConfig]);
  371. Log(ALogLevel,SLogGlobalCfgDownloader,[FDownloader]);
  372. end;
  373. {*****************************************************************************
  374. TCompilerOptions
  375. *****************************************************************************}
  376. constructor TCompilerOptions.Create;
  377. begin
  378. FOptionParser := TTemplateParser.Create;
  379. FOptionParser.Values['AppConfigDir'] := GetAppConfigDir(false);
  380. FOptionParser.Values['UserDir'] := GetUserDir;
  381. {$ifdef unix}
  382. FLocalInstallDir:='{LocalPrefix}'+'lib'+PathDelim+'fpc'+PathDelim+'{CompilerVersion}'+PathDelim;
  383. FGlobalInstallDir:='{GlobalPrefix}'+'lib'+PathDelim+'fpc'+PathDelim+'{CompilerVersion}'+PathDelim;
  384. {$else unix}
  385. FLocalInstallDir:='{LocalPrefix}';
  386. FGlobalInstallDir:='{GlobalPrefix}';
  387. {$endif}
  388. end;
  389. destructor TCompilerOptions.Destroy;
  390. begin
  391. FOptionParser.Free;
  392. if assigned(FOptions) then
  393. FreeAndNil(FOptions);
  394. inherited Destroy;
  395. end;
  396. function TCompilerOptions.GetOptString(Index: integer): String;
  397. begin
  398. Case Index of
  399. 1 : Result:=FCompiler;
  400. 2 : Result:=MakeTargetString(CompilerCPU,CompilerOS);
  401. 3 : Result:=FCompilerVersion;
  402. 4 : Result:=FOptionParser.ParseString(FGlobalInstallDir);
  403. 5 : Result:=FOptionParser.ParseString(FLocalInstallDir);
  404. 6 : Result:=FixPath(FOptionParser.ParseString(FGlobalPrefix));
  405. 7 : Result:=FixPath(FOptionParser.ParseString(FLocalPrefix));
  406. else
  407. Error('Unknown option');
  408. end;
  409. end;
  410. function TCompilerOptions.GetOptions: TStrings;
  411. begin
  412. if not assigned(FOptions) then
  413. begin
  414. FOptions := TStringList.Create;
  415. FOptions.Delimiter:=' ';
  416. end;
  417. Result := FOptions;
  418. end;
  419. procedure TCompilerOptions.SetOptString(Index: integer; const AValue: String);
  420. begin
  421. If AValue=GetOptString(Index) then
  422. Exit;
  423. Case Index of
  424. 1 : FCompiler:=AValue;
  425. 2 : StringToCPUOS(AValue,FCompilerCPU,FCompilerOS);
  426. 3 : begin
  427. FCompilerVersion:=AValue;
  428. FOptionParser.Values['CompilerVersion'] := FCompilerVersion;
  429. end;
  430. 4 : FGlobalInstallDir:=FixPath(AValue);
  431. 5 : FLocalInstallDir:=FixPath(AValue);
  432. 6 : begin
  433. FGlobalPrefix:=AValue;
  434. FOptionParser.Values['GlobalPrefix'] := GlobalPrefix;
  435. end;
  436. 7 : begin
  437. FLocalPrefix:=AValue;
  438. FOptionParser.Values['LocalPrefix'] := LocalPrefix;
  439. end
  440. else
  441. Error('Unknown option');
  442. end;
  443. end;
  444. procedure TCompilerOptions.SetCompilerCPU(const AValue: TCPU);
  445. begin
  446. if FCompilerCPU=AValue then
  447. exit;
  448. FCompilerCPU:=AValue;
  449. end;
  450. procedure TCompilerOptions.UpdateLocalRepositoryOption;
  451. begin
  452. FOptionParser.Values['LocalRepository'] := GlobalOptions.LocalRepository;
  453. end;
  454. procedure TCompilerOptions.CheckCompilerValues;
  455. var
  456. AVersion : string;
  457. ACpu : TCpu;
  458. AOs : TOS;
  459. begin
  460. if Compiler='' then
  461. Exit;
  462. if (CompilerCPU=cpuNone) or
  463. (CompilerOS=osNone) or
  464. (CompilerVersion='') then
  465. begin
  466. GetCompilerInfo(Compiler,'-iVTPTO',AVersion,ACpu,AOs);
  467. if CompilerCPU=cpuNone then
  468. CompilerCPU := ACpu;
  469. if CompilerOS=osNone then
  470. CompilerOS:=AOs;
  471. if CompilerVersion='' then
  472. CompilerVersion:=AVersion;
  473. end;
  474. end;
  475. procedure TCompilerOptions.SetCompilerOS(const AValue: TOS);
  476. begin
  477. if FCompilerOS=AValue then
  478. exit;
  479. FCompilerOS:=AValue;
  480. end;
  481. function TCompilerOptions.LocalUnitDir:string;
  482. var ALocalInstallDir: string;
  483. begin
  484. ALocalInstallDir:=LocalInstallDir;
  485. if ALocalInstallDir<>'' then
  486. result:=ALocalInstallDir+'units'+PathDelim+CompilerTarget+PathDelim
  487. else
  488. result:='';
  489. end;
  490. function TCompilerOptions.GlobalUnitDir:string;
  491. var AGlobalInstallDir: string;
  492. begin
  493. AGlobalInstallDir:=GlobalInstallDir;
  494. if AGlobalInstallDir<>'' then
  495. result:=AGlobalInstallDir+'units'+PathDelim+CompilerTarget+PathDelim
  496. else
  497. result:='';
  498. end;
  499. function TCompilerOptions.HasOptions: boolean;
  500. begin
  501. result := assigned(FOptions);
  502. end;
  503. procedure TCompilerOptions.InitCompilerDefaults;
  504. var
  505. ACompilerVersion: string;
  506. fpcdir: string;
  507. begin
  508. FConfigVersion:=CurrentConfigVersion;
  509. if fcompiler = '' then
  510. FCompiler:=ExeSearch('fpc'+ExeExt,GetEnvironmentVariable('PATH'));
  511. if FCompiler='' then
  512. Raise EPackagerError.Create(SErrMissingFPC);
  513. // Detect compiler version/target from -i option
  514. GetCompilerInfo(FCompiler,'-iVTPTO',ACompilerVersion,FCompilerCPU,FCompilerOS);
  515. CompilerVersion := ACompilerVersion;
  516. // Temporary hack to workaround bug in fpc.exe that doesn't support spaces
  517. // We retrieve the real binary
  518. if FCompilerVersion='2.2.0' then
  519. FCompiler:=GetCompilerInfo(FCompiler,'-PB');
  520. Log(vlDebug,SLogDetectedCompiler,[FCompiler,FCompilerVersion,MakeTargetString(FCompilerCPU,FCompilerOS)]);
  521. // Use the same algorithm as the compiler, see options.pas
  522. // Except that the prefix is extracted and GlobalInstallDir is set using
  523. // that prefix
  524. {$ifdef Unix}
  525. FGlobalPrefix:='/usr/local/';
  526. if not DirectoryExists(FGlobalPrefix+'lib/fpc/'+FCompilerVersion+'/') and
  527. DirectoryExists('/usr/lib/fpc/'+FCompilerVersion+'/') then
  528. FGlobalPrefix:='/usr/';
  529. {$else unix}
  530. FGlobalPrefix:=ExtractFilePath(FCompiler)+'..'+PathDelim;
  531. if not(DirectoryExists(FGlobalPrefix+PathDelim+'units')) and
  532. not(DirectoryExists(FGlobalPrefix+PathDelim+'rtl')) then
  533. FGlobalPrefix:=FGlobalPrefix+'..'+PathDelim;
  534. FGlobalPrefix:=ExpandFileName(FGlobalPrefix);
  535. {$endif unix}
  536. Log(vlDebug,SLogDetectedPrefix,['global',FGlobalPrefix]);
  537. // User writable install directory
  538. if not IsSuperUser then
  539. begin
  540. FLocalPrefix:= '{LocalRepository}';
  541. Log(vlDebug,SLogDetectedPrefix,['local',FLocalPrefix]);
  542. end;
  543. fpcdir:=FixPath(GetEnvironmentVariable('FPCDIR'));
  544. if fpcdir<>'' then
  545. begin
  546. {$ifndef Unix}
  547. fpcdir:=ExpandFileName(fpcdir);
  548. {$endif unix}
  549. Log(vlDebug,SLogFPCDirEnv,[fpcdir]);
  550. FGlobalInstallDir:=fpcdir;
  551. end;
  552. end;
  553. procedure TCompilerOptions.LoadCompilerFromFile(const AFileName: String);
  554. Var
  555. Ini : TMemIniFile;
  556. begin
  557. try
  558. Ini:=TMemIniFile.Create(AFileName);
  559. FConfigFilename:=AFileName;
  560. With Ini do
  561. begin
  562. FConfigVersion:=ReadInteger(SDefaults,KeyConfigVersion,0);
  563. if (FConfigVersion<>CurrentConfigVersion) then
  564. begin
  565. Log(vlDebug,SLogUpgradingConfig,[AFileName]);
  566. FSaveInifileChanges:=true;
  567. if (FConfigVersion>CurrentConfigVersion) then
  568. Error(SErrUnsupportedConfigVersion,[AFileName]);
  569. end;
  570. GlobalPrefix:=ReadString(SDefaults,KeyGlobalPrefix,FGlobalPrefix);
  571. LocalPrefix:=ReadString(SDefaults,KeyLocalPrefix,FLocalPrefix);
  572. FGlobalInstallDir:=FixPath(ReadString(SDefaults,KeyGlobalInstallDir,FGlobalInstallDir));
  573. FLocalInstallDir:=FixPath(ReadString(SDefaults,KeyLocalInstallDir,FLocalInstallDir));
  574. FCompiler:=ReadString(SDefaults,KeyCompiler,FCompiler);
  575. FCompilerOS:=StringToOS(ReadString(SDefaults,KeyCompilerOS,OSToString(CompilerOS)));
  576. FCompilerCPU:=StringToCPU(ReadString(SDefaults,KeyCompilerCPU,CPUtoString(CompilerCPU)));
  577. CompilerVersion:=ReadString(SDefaults,KeyCompilerVersion,FCompilerVersion);
  578. end;
  579. finally
  580. Ini.Free;
  581. end;
  582. end;
  583. procedure TCompilerOptions.SaveCompilerToFile(const AFileName: String);
  584. Var
  585. Ini : TIniFile;
  586. begin
  587. if FileExists(AFileName) then
  588. BackupFile(AFileName);
  589. try
  590. Ini:=TIniFile.Create(AFileName);
  591. With Ini do
  592. begin
  593. WriteInteger(SDefaults,KeyConfigVersion,CurrentConfigVersion);
  594. WriteString(SDefaults,KeyGlobalPrefix,FGlobalPrefix);
  595. WriteString(SDefaults,KeyLocalPrefix,FLocalPrefix);
  596. WriteString(SDefaults,KeyGlobalInstallDir,FGlobalInstallDir);
  597. WriteString(SDefaults,KeyLocalInstallDir,FLocalInstallDir);
  598. WriteString(SDefaults,KeyCompiler,FCompiler);
  599. WriteString(SDefaults,KeyCompilerOS,OSToString(CompilerOS));
  600. WriteString(SDefaults,KeyCompilerCPU,CPUtoString(CompilerCPU));
  601. WriteString(SDefaults,KeyCompilerVersion,FCompilerVersion);
  602. FSaveInifileChanges:=False;
  603. end;
  604. Ini.UpdateFile;
  605. finally
  606. Ini.Free;
  607. end;
  608. end;
  609. procedure TCompilerOptions.LogValues(ALogLevel: TLogLevel; const ACfgName:string);
  610. begin
  611. Log(ALogLevel,SLogCompilerCfgHeader,[ACfgName,FConfigFilename]);
  612. Log(ALogLevel,SLogCompilerCfgCompiler,[FCompiler]);
  613. Log(ALogLevel,SLogCompilerCfgTarget,[MakeTargetString(CompilerCPU,CompilerOS)]);
  614. Log(ALogLevel,SLogCompilerCfgVersion,[FCompilerVersion]);
  615. Log(ALogLevel,SLogCompilerCfgGlobalPrefix,[FGlobalPrefix,GlobalPrefix]);
  616. Log(ALogLevel,SLogCompilerCfgLocalPrefix,[FLocalPrefix,LocalPrefix]);
  617. Log(ALogLevel,SLogCompilerCfgGlobalInstallDir,[FGlobalInstallDir,GlobalInstallDir]);
  618. Log(ALogLevel,SLogCompilerCfgLocalInstallDir,[FLocalInstallDir,LocalInstallDir]);
  619. Log(ALogLevel,SLogCompilerCfgOptions,[Options.DelimitedText]);
  620. end;
  621. initialization
  622. GlobalOptions:=TGlobalOptions.Create;
  623. CompilerOptions:=TCompilerOptions.Create;
  624. FPMakeCompilerOptions:=TCompilerOptions.Create;
  625. finalization
  626. FreeAndNil(GlobalOptions);
  627. FreeAndNil(CompilerOptions);
  628. FreeAndNil(FPMakeCompilerOptions);
  629. end.