pkgoptions.pp 23 KB

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