pkgoptions.pp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  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. var
  242. i: Integer;
  243. begin
  244. FConfigVersion:=CurrentConfigVersion;
  245. // Retrieve Local fppkg directory
  246. {$ifdef unix}
  247. if IsSuperUser then
  248. begin
  249. if DirectoryExists('/usr/local/lib/fpc') then
  250. FLocalRepository:='/usr/local/lib/fpc/fppkg/'
  251. else
  252. FLocalRepository:='/usr/lib/fpc/fppkg/';
  253. end
  254. else
  255. FLocalRepository:='{UserDir}.fppkg/';
  256. {$else}
  257. FLocalRepository:=IncludeTrailingPathDelimiter(GetAppConfigDir(IsSuperUser));
  258. {$endif}
  259. UpdateLocalRepositoryOption;
  260. // Directories
  261. FBuildDir:='{LocalRepository}build'+PathDelim;
  262. FArchivesDir:='{LocalRepository}archives'+PathDelim;
  263. FCompilerConfigDir:='{LocalRepository}config'+PathDelim;
  264. // Remote
  265. FRemoteMirrorsURL:=DefaultMirrorsURL;
  266. FRemoteRepository:=DefaultRemoteRepository;
  267. // Other config
  268. FDefaultCompilerConfig:='default';
  269. FFPMakeCompilerConfig:='default';
  270. // Downloader
  271. {$if defined(unix) or defined(windows)}
  272. FDownloader:='lnet';
  273. {$else}
  274. FDownloader:='base';
  275. {$endif}
  276. // Parameter defaults
  277. FCompilerConfig:=FDefaultCompilerConfig;
  278. FInstallGlobal:=False;
  279. FRecoveryMode:=False;
  280. FAllowBroken:=False;
  281. SetLength(FPMKUnitDeps,FPMKUnitDepDefaultCount);
  282. for i := 0 to FPMKUnitDepDefaultCount-1 do
  283. FPMKUnitDeps[i]:=FPMKUnitDepsDefaults[i];
  284. end;
  285. procedure TGlobalOptions.LoadGlobalFromFile(const AFileName: String);
  286. Var
  287. Ini : TMemIniFile;
  288. begin
  289. try
  290. Ini:=TMemIniFile.Create(AFileName);
  291. With Ini do
  292. begin
  293. FConfigVersion:=ReadInteger(SDefaults,KeyConfigVersion,0);
  294. if (FConfigVersion<>CurrentConfigVersion) then
  295. begin
  296. Log(vlDebug,SLogUpgradingConfig,[AFileName]);
  297. FSaveInifileChanges:=true;
  298. if FConfigVersion<1 then
  299. begin
  300. FRemoteRepository:='auto';
  301. end;
  302. if FConfigVersion<3 then
  303. begin
  304. // Directories
  305. FBuildDir:=FLocalRepository+'build'+PathDelim;
  306. FArchivesDir:=FLocalRepository+'archives'+PathDelim;
  307. FCompilerConfigDir:=FLocalRepository+'config'+PathDelim;
  308. end;
  309. if (FConfigVersion>CurrentConfigVersion) then
  310. Error(SErrUnsupportedConfigVersion,[AFileName]);
  311. end;
  312. FRemoteMirrorsURL:=ReadString(SDefaults,KeyRemoteMirrorsURL,FRemoteMirrorsURL);
  313. FRemoteRepository:=ReadString(SDefaults,KeyRemoteRepository,FRemoteRepository);
  314. FLocalRepository:=ReadString(SDefaults,KeyLocalRepository,FLocalRepository);
  315. UpdateLocalRepositoryOption;
  316. FBuildDir:=FixPath(ReadString(SDefaults,KeyBuildDir,FBuildDir));
  317. FArchivesDir:=FixPath(ReadString(SDefaults,KeyArchivesDir,FArchivesDir));
  318. FCompilerConfigDir:=FixPath(ReadString(SDefaults,KeyCompilerConfigDir,FCompilerConfigDir));
  319. FDefaultCompilerConfig:=ReadString(SDefaults,KeyCompilerConfig,FDefaultCompilerConfig);
  320. FFPMakeCompilerConfig:=ReadString(SDefaults,KeyFPMakeCompilerConfig,FFPMakeCompilerConfig);
  321. FDownloader:=ReadString(SDefaults,KeyDownloader,FDownloader);
  322. FCustomFPMakeOptions:=ReadString(SDefaults,KeyCustomFPMakeOptions,FCustomFPMakeOptions);
  323. end;
  324. finally
  325. Ini.Free;
  326. end;
  327. end;
  328. procedure TGlobalOptions.SaveGlobalToFile(const AFileName: String);
  329. Var
  330. Ini : TIniFile;
  331. begin
  332. if FileExists(AFileName) then
  333. BackupFile(AFileName);
  334. try
  335. Ini:=TIniFile.Create(AFileName);
  336. With Ini do
  337. begin
  338. WriteInteger(SDefaults,KeyConfigVersion,CurrentConfigVersion);
  339. WriteString(SDefaults,KeyLocalRepository,FLocalRepository);
  340. WriteString(SDefaults,KeyBuildDir,FBuildDir);
  341. WriteString(SDefaults,KeyArchivesDir,FArchivesDir);
  342. WriteString(SDefaults,KeyCompilerConfigDir,FCompilerConfigDir);
  343. WriteString(SDefaults,KeyRemoteMirrorsURL,FRemoteMirrorsURL);
  344. WriteString(SDefaults,KeyRemoteRepository,FRemoteRepository);
  345. WriteString(SDefaults,KeyCompilerConfig,FDefaultCompilerConfig);
  346. WriteString(SDefaults,KeyFPMakeCompilerConfig,FFPMakeCompilerConfig);
  347. WriteString(SDefaults,KeyDownloader,FDownloader);
  348. FSaveInifileChanges:=False;
  349. end;
  350. Ini.UpdateFile;
  351. finally
  352. Ini.Free;
  353. end;
  354. end;
  355. procedure TGlobalOptions.LogValues;
  356. begin
  357. Log(vlDebug,SLogGlobalCfgHeader);
  358. Log(vlDebug,SLogGlobalCfgRemoteMirrorsURL,[FRemoteMirrorsURL]);
  359. Log(vlDebug,SLogGlobalCfgRemoteRepository,[FRemoteRepository]);
  360. Log(vlDebug,SLogGlobalCfgLocalRepository,[LocalRepository]);
  361. Log(vlDebug,SLogGlobalCfgBuildDir,[BuildDir]);
  362. Log(vlDebug,SLogGlobalCfgArchivesDir,[ArchivesDir]);
  363. Log(vlDebug,SLogGlobalCfgCompilerConfigDir,[CompilerConfigDir]);
  364. Log(vlDebug,SLogGlobalCfgDefaultCompilerConfig,[FDefaultCompilerConfig]);
  365. Log(vlDebug,SLogGlobalCfgFPMakeCompilerConfig,[FFPMakeCompilerConfig]);
  366. Log(vlDebug,SLogGlobalCfgDownloader,[FDownloader]);
  367. end;
  368. {*****************************************************************************
  369. TCompilerOptions
  370. *****************************************************************************}
  371. constructor TCompilerOptions.Create;
  372. begin
  373. FOptionParser := TTemplateParser.Create;
  374. FOptionParser.Values['AppConfigDir'] := GetAppConfigDir(false);
  375. FOptionParser.Values['UserDir'] := GetUserDir;
  376. end;
  377. destructor TCompilerOptions.Destroy;
  378. begin
  379. FOptionParser.Free;
  380. if assigned(FOptions) then
  381. FreeAndNil(FOptions);
  382. inherited Destroy;
  383. end;
  384. function TCompilerOptions.GetOptString(Index: integer): String;
  385. begin
  386. Case Index of
  387. 1 : Result:=FCompiler;
  388. 2 : Result:=MakeTargetString(CompilerCPU,CompilerOS);
  389. 3 : Result:=FCompilerVersion;
  390. 4 : Result:=FOptionParser.ParseString(FGlobalInstallDir);
  391. 5 : Result:=FOptionParser.ParseString(FLocalInstallDir);
  392. 6 : Result:=FixPath(FOptionParser.ParseString(FGlobalPrefix));
  393. 7 : Result:=FixPath(FOptionParser.ParseString(FLocalPrefix));
  394. else
  395. Error('Unknown option');
  396. end;
  397. end;
  398. function TCompilerOptions.GetOptions: TStrings;
  399. begin
  400. if not assigned(FOptions) then
  401. begin
  402. FOptions := TStringList.Create;
  403. FOptions.Delimiter:=' ';
  404. end;
  405. Result := FOptions;
  406. end;
  407. procedure TCompilerOptions.SetOptString(Index: integer; const AValue: String);
  408. begin
  409. If AValue=GetOptString(Index) then
  410. Exit;
  411. Case Index of
  412. 1 : FCompiler:=AValue;
  413. 2 : StringToCPUOS(AValue,FCompilerCPU,FCompilerOS);
  414. 3 : FCompilerVersion:=AValue;
  415. 4 : FGlobalInstallDir:=FixPath(AValue);
  416. 5 : FLocalInstallDir:=FixPath(AValue);
  417. 6 : begin
  418. FGlobalPrefix:=AValue;
  419. FOptionParser.Values['GlobalPrefix'] := GlobalPrefix;
  420. end;
  421. 7 : begin
  422. FLocalPrefix:=AValue;
  423. FOptionParser.Values['LocalPrefix'] := LocalPrefix;
  424. end
  425. else
  426. Error('Unknown option');
  427. end;
  428. end;
  429. procedure TCompilerOptions.SetCompilerCPU(const AValue: TCPU);
  430. begin
  431. if FCompilerCPU=AValue then
  432. exit;
  433. FCompilerCPU:=AValue;
  434. end;
  435. procedure TCompilerOptions.UpdateLocalRepositoryOption;
  436. begin
  437. FOptionParser.Values['LocalRepository'] := GlobalOptions.LocalRepository;
  438. end;
  439. procedure TCompilerOptions.CheckCompilerValues;
  440. var
  441. AVersion : string;
  442. ACpu : TCpu;
  443. AOs : TOS;
  444. begin
  445. if Compiler='' then
  446. Exit;
  447. if (CompilerCPU=cpuNone) or
  448. (CompilerOS=osNone) or
  449. (CompilerVersion='') then
  450. begin
  451. GetCompilerInfo(Compiler,'-iVTPTO',AVersion,ACpu,AOs);
  452. if CompilerCPU=cpuNone then
  453. CompilerCPU := ACpu;
  454. if CompilerOS=osNone then
  455. CompilerOS:=AOs;
  456. if CompilerVersion='' then
  457. CompilerVersion:=AVersion;
  458. end;
  459. end;
  460. procedure TCompilerOptions.SetCompilerOS(const AValue: TOS);
  461. begin
  462. if FCompilerOS=AValue then
  463. exit;
  464. FCompilerOS:=AValue;
  465. end;
  466. function TCompilerOptions.LocalUnitDir:string;
  467. var ALocalInstallDir: string;
  468. begin
  469. if LocalInstallDir<>'' then
  470. ALocalInstallDir:=LocalInstallDir
  471. else if LocalPrefix<>'' then
  472. {$ifdef unix}
  473. ALocalInstallDir:=LocalPrefix+'lib'+PathDelim+'fpc'+PathDelim+FCompilerVersion+PathDelim;
  474. {$else unix}
  475. ALocalInstallDir:=LocalPrefix;
  476. {$endif}
  477. if ALocalInstallDir<>'' then
  478. result:=ALocalInstallDir+'units'+PathDelim+CompilerTarget+PathDelim
  479. else
  480. result:='';
  481. end;
  482. function TCompilerOptions.GlobalUnitDir:string;
  483. var AGlobalInstallDir: string;
  484. begin
  485. if GlobalInstallDir<>'' then
  486. AGlobalInstallDir:=GlobalInstallDir
  487. else if GlobalPrefix<>'' then
  488. {$ifdef unix}
  489. AGlobalInstallDir:=GlobalPrefix+'lib'+PathDelim+'fpc'+PathDelim+FCompilerVersion+PathDelim;
  490. {$else unix}
  491. AGlobalInstallDir:=GlobalPrefix;
  492. {$endif}
  493. if AGlobalInstallDir<>'' then
  494. result:=AGlobalInstallDir+'units'+PathDelim+CompilerTarget+PathDelim
  495. else
  496. result:='';
  497. end;
  498. function TCompilerOptions.HasOptions: boolean;
  499. begin
  500. result := assigned(FOptions);
  501. end;
  502. procedure TCompilerOptions.InitCompilerDefaults;
  503. begin
  504. FConfigVersion:=CurrentConfigVersion;
  505. if fcompiler = '' then
  506. FCompiler:=ExeSearch('fpc'+ExeExt,GetEnvironmentVariable('PATH'));
  507. if FCompiler='' then
  508. Raise EPackagerError.Create(SErrMissingFPC);
  509. // Detect compiler version/target from -i option
  510. GetCompilerInfo(FCompiler,'-iVTPTO',FCompilerVersion,FCompilerCPU,FCompilerOS);
  511. // Temporary hack to workaround bug in fpc.exe that doesn't support spaces
  512. // We retrieve the real binary
  513. if FCompilerVersion='2.2.0' then
  514. FCompiler:=GetCompilerInfo(FCompiler,'-PB');
  515. Log(vlDebug,SLogDetectedCompiler,[FCompiler,FCompilerVersion,MakeTargetString(FCompilerCPU,FCompilerOS)]);
  516. // Use the same algorithm as the compiler, see options.pas
  517. // Except that the prefix is extracted and GlobalInstallDir is set using
  518. // that prefix
  519. {$ifdef Unix}
  520. FGlobalPrefix:='/usr/local/';
  521. if not DirectoryExists(FGlobalPrefix+'lib/fpc/'+FCompilerVersion+'/') and
  522. DirectoryExists('/usr/lib/fpc/'+FCompilerVersion+'/') then
  523. FGlobalPrefix:='/usr/';
  524. {$else unix}
  525. FGlobalPrefix:=ExtractFilePath(FCompiler)+'..'+PathDelim;
  526. if not(DirectoryExists(FGlobalPrefix+PathDelim+'units')) and
  527. not(DirectoryExists(FGlobalPrefix+PathDelim+'rtl')) then
  528. FGlobalPrefix:=FGlobalPrefix+'..'+PathDelim;
  529. FGlobalPrefix:=ExpandFileName(FGlobalInstallDir);
  530. {$endif unix}
  531. Log(vlDebug,SLogDetectedPrefix,['global',FGlobalPrefix]);
  532. // User writable install directory
  533. if not IsSuperUser then
  534. begin
  535. FLocalPrefix:= '{LocalRepository}';
  536. Log(vlDebug,SLogDetectedPrefix,['local',FLocalPrefix]);
  537. end;
  538. FGlobalInstallDir:=FixPath(GetEnvironmentVariable('FPCDIR'));
  539. {$ifndef Unix}
  540. FGlobalInstallDir:=ExpandFileName(FGlobalInstallDir);
  541. {$endif unix}
  542. if FGlobalInstallDir<>'' then
  543. Log(vlDebug,SLogFPCDirEnv,[FGlobalInstallDir]);
  544. end;
  545. procedure TCompilerOptions.LoadCompilerFromFile(const AFileName: String);
  546. Var
  547. Ini : TMemIniFile;
  548. begin
  549. try
  550. Ini:=TMemIniFile.Create(AFileName);
  551. With Ini do
  552. begin
  553. FConfigVersion:=ReadInteger(SDefaults,KeyConfigVersion,0);
  554. if (FConfigVersion<>CurrentConfigVersion) then
  555. begin
  556. Log(vlDebug,SLogUpgradingConfig,[AFileName]);
  557. FSaveInifileChanges:=true;
  558. if (FConfigVersion>CurrentConfigVersion) then
  559. Error(SErrUnsupportedConfigVersion,[AFileName]);
  560. end;
  561. GlobalPrefix:=ReadString(SDefaults,KeyGlobalPrefix,FGlobalPrefix);
  562. LocalPrefix:=ReadString(SDefaults,KeyLocalPrefix,FLocalPrefix);
  563. FGlobalInstallDir:=FixPath(ReadString(SDefaults,KeyGlobalInstallDir,FGlobalInstallDir));
  564. FLocalInstallDir:=FixPath(ReadString(SDefaults,KeyLocalInstallDir,FLocalInstallDir));
  565. FCompiler:=ReadString(SDefaults,KeyCompiler,FCompiler);
  566. FCompilerOS:=StringToOS(ReadString(SDefaults,KeyCompilerOS,OSToString(CompilerOS)));
  567. FCompilerCPU:=StringToCPU(ReadString(SDefaults,KeyCompilerCPU,CPUtoString(CompilerCPU)));
  568. FCompilerVersion:=ReadString(SDefaults,KeyCompilerVersion,FCompilerVersion);
  569. end;
  570. finally
  571. Ini.Free;
  572. end;
  573. end;
  574. procedure TCompilerOptions.SaveCompilerToFile(const AFileName: String);
  575. Var
  576. Ini : TIniFile;
  577. begin
  578. if FileExists(AFileName) then
  579. BackupFile(AFileName);
  580. try
  581. Ini:=TIniFile.Create(AFileName);
  582. With Ini do
  583. begin
  584. WriteInteger(SDefaults,KeyConfigVersion,CurrentConfigVersion);
  585. WriteString(SDefaults,KeyGlobalPrefix,FGlobalPrefix);
  586. WriteString(SDefaults,KeyLocalPrefix,FLocalPrefix);
  587. WriteString(SDefaults,KeyGlobalInstallDir,FGlobalInstallDir);
  588. WriteString(SDefaults,KeyLocalInstallDir,FLocalInstallDir);
  589. WriteString(SDefaults,KeyCompiler,FCompiler);
  590. WriteString(SDefaults,KeyCompilerOS,OSToString(CompilerOS));
  591. WriteString(SDefaults,KeyCompilerCPU,CPUtoString(CompilerCPU));
  592. WriteString(SDefaults,KeyCompilerVersion,FCompilerVersion);
  593. FSaveInifileChanges:=False;
  594. end;
  595. Ini.UpdateFile;
  596. finally
  597. Ini.Free;
  598. end;
  599. end;
  600. procedure TCompilerOptions.LogValues(const ACfgName:string);
  601. begin
  602. Log(vlDebug,SLogCompilerCfgHeader,[ACfgName]);
  603. Log(vlDebug,SLogCompilerCfgCompiler,[FCompiler]);
  604. Log(vlDebug,SLogCompilerCfgTarget,[MakeTargetString(CompilerCPU,CompilerOS)]);
  605. Log(vlDebug,SLogCompilerCfgVersion,[FCompilerVersion]);
  606. Log(vlDebug,SLogCompilerCfgGlobalInstallDir,[GlobalInstallDir]);
  607. Log(vlDebug,SLogCompilerCfgLocalInstallDir,[LocalInstallDir]);
  608. Log(vlDebug,SLogCompilerCfgGlobalPrefix,[GlobalPrefix]);
  609. Log(vlDebug,SLogCompilerCfgLocalPrefix,[LocalPrefix]);
  610. end;
  611. initialization
  612. GlobalOptions:=TGlobalOptions.Create;
  613. CompilerOptions:=TCompilerOptions.Create;
  614. FPMakeCompilerOptions:=TCompilerOptions.Create;
  615. finalization
  616. FreeAndNil(GlobalOptions);
  617. FreeAndNil(CompilerOptions);
  618. FreeAndNil(FPMakeCompilerOptions);
  619. end.