pkgoptions.pp 22 KB

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