pkgoptions.pp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  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;
  15. Const
  16. DefaultManifestFile = 'manifest.xml';
  17. CurrentConfigVersion = '0.1';
  18. Type
  19. { TGlobalOptions }
  20. TGlobalOptions = Class(TPersistent)
  21. private
  22. FDirty : Boolean;
  23. FConfigVersion,
  24. FRemoteMirrorsLocation,
  25. FLocalMirrorsLocation,
  26. FRemoteRepository,
  27. FLocalRepository,
  28. FCompilerConfigDir,
  29. FPackagesDir,
  30. FBuildDir,
  31. FDefaultVerbosity,
  32. FDownloader,
  33. FDefaultCompilerConfig,
  34. FFPMakeCompilerConfig : String;
  35. // Parameter options
  36. FCompilerConfig : String;
  37. FInstallGlobal : Boolean;
  38. function GetOptString(Index: integer): String;
  39. procedure SetOptString(Index: integer; const AValue: String);
  40. Public
  41. Constructor Create;
  42. Procedure InitGlobalDefaults;
  43. Procedure LoadGlobalFromIni(Ini : TCustomIniFile); virtual;
  44. Procedure SaveGlobalToIni(Ini : TCustomIniFile); virtual;
  45. Procedure LoadGlobalFromFile(const AFileName : String);
  46. Procedure SaveGlobalToFile(const AFileName : String);
  47. Property Dirty : Boolean Read FDirty;
  48. Property ConfigVersion : String read FConfigVersion;
  49. function RemotePackagesFile:string;
  50. function LocalPackagesFile:string;
  51. function LocalVersionsFile(const ACompilerConfig:String):string;
  52. Published
  53. Property RemoteMirrorsLocation : String Index 0 Read GetOptString Write SetOptString;
  54. Property LocalMirrorsLocation : String Index 1 Read GetOptString Write SetOptString;
  55. Property RemoteRepository : String Index 2 Read GetOptString Write SetOptString;
  56. Property LocalRepository : String Index 3 Read GetOptString Write SetOptString;
  57. Property BuildDir : String Index 4 Read GetOptString Write SetOptString;
  58. Property PackagesDir : String Index 5 Read GetOptString Write SetOptString;
  59. Property CompilerConfigDir : String Index 6 Read GetOptString Write SetOptString;
  60. Property DefaultVerbosity : String Index 7 Read GetOptString Write SetOptString;
  61. Property DefaultCompilerConfig : String Index 8 Read GetOptString Write SetOptString;
  62. Property FPMakeCompilerConfig : String Index 9 Read GetOptString Write SetOptString;
  63. Property Downloader: String Index 10 Read GetOptString Write SetOptString;
  64. // Parameters
  65. Property CompilerConfig : String Read FCompilerConfig Write FCompilerConfig;
  66. Property InstallGlobal : Boolean Read FInstallGlobal Write FInstallGlobal;
  67. end;
  68. { TCompilerOptions }
  69. TCompilerOptions = Class(TPersistent)
  70. private
  71. FDirty: Boolean;
  72. FConfigVersion,
  73. FCompiler,
  74. FCompilerVersion,
  75. FLocalInstallDir,
  76. FGlobalInstallDir : String;
  77. FCompilerCPU: TCPU;
  78. FCompilerOS: TOS;
  79. function GetOptString(Index: integer): String;
  80. procedure SetOptString(Index: integer; const AValue: String);
  81. procedure SetCompilerCPU(const AValue: TCPU);
  82. procedure SetCompilerOS(const AValue: TOS);
  83. Public
  84. Constructor Create;
  85. Procedure InitCompilerDefaults;
  86. Procedure LoadCompilerFromIni(Ini : TCustomIniFile); virtual;
  87. Procedure SaveCompilerToIni(Ini : TCustomIniFile); virtual;
  88. Procedure LoadCompilerFromFile(const AFileName : String);
  89. Procedure SaveCompilerToFile(const AFileName : String);
  90. Property Dirty : Boolean Read FDirty;
  91. Property ConfigVersion : String read FConfigVersion;
  92. Function LocalUnitDir:string;
  93. Function GlobalUnitDir:string;
  94. Published
  95. Property Compiler : String Index 1 Read GetOptString Write SetOptString;
  96. Property CompilerTarget : String Index 2 Read GetOptString Write SetOptString;
  97. Property CompilerVersion : String Index 3 Read GetOptString Write SetOptString;
  98. Property GlobalInstallDir : String Index 4 Read GetOptString Write SetOptString;
  99. Property LocalInstallDir : String Index 5 Read GetOptString Write SetOptString;
  100. Property CompilerOS : TOS Read FCompilerOS Write SetCompilerOS;
  101. Property CompilerCPU : TCPU Read FCompilerCPU Write SetCompilerCPU;
  102. end;
  103. var
  104. GlobalOptions : TGlobalOptions;
  105. CompilerOptions : TCompilerOptions;
  106. FPMakeCompilerOptions : TCompilerOptions;
  107. Implementation
  108. uses
  109. pkgglobals,
  110. pkgmessages;
  111. Const
  112. DefaultMirrorFile = 'mirrors.xml';
  113. DefaultPackagesFile = 'packages.xml';
  114. DefaultVersionsFile = 'versions-%s.dat';
  115. DefaultMirrorsLocation = 'http://www.freepascal.org/repository/'+DefaultMirrorFile;
  116. {$warning TODO use real repository}
  117. {$ifdef localrepository}
  118. DefaultRemoteRepository = 'file://'+{$I %HOME%}+'/repository/';
  119. {$else}
  120. DefaultRemoteRepository = 'http://www.freepascal.org/~peter/repository/';
  121. {$endif}
  122. // ini file keys
  123. SDefaults = 'Defaults';
  124. // All configs
  125. KeyConfigVersion = 'ConfigVersion';
  126. // Global config
  127. KeyLocalMirrorsLocation = 'LocalMirrors';
  128. KeyRemoteMirrorsLocation = 'RemoteMirrors';
  129. KeyRemoteRepository = 'RemoteRepository';
  130. KeyLocalRepository = 'LocalRepository';
  131. KeyPackagesDir = 'PackagesDir';
  132. KeyBuildDir = 'BuildDir';
  133. KeyCompilerConfigDir = 'CompilerConfigDir';
  134. KeyVerbosity = 'Verbosity';
  135. KeyCompilerConfig = 'CompilerConfig';
  136. KeyFPMakeCompilerConfig = 'FPMakeCompilerConfig';
  137. KeyDownloader = 'Downloader';
  138. // Compiler dependent config
  139. KeyGlobalInstallDir = 'GlobalInstallDir';
  140. KeyLocalInstallDir = 'LocalInstallDir';
  141. KeyCompiler = 'Compiler' ;
  142. KeyCompilerOS = 'OS';
  143. KeyCompilerCPU = 'CPU';
  144. KeyCompilerVersion = 'Version';
  145. {*****************************************************************************
  146. TGlobalOptions
  147. *****************************************************************************}
  148. constructor TGlobalOptions.Create;
  149. begin
  150. InitGlobalDefaults;
  151. end;
  152. function TGlobalOptions.GetOptString(Index: integer): String;
  153. begin
  154. Case Index of
  155. 0 : Result:=FRemoteMirrorsLocation;
  156. 1 : Result:=FLocalMirrorsLocation;
  157. 2 : Result:=FRemoteRepository;
  158. 3 : Result:=FLocalRepository;
  159. 4 : Result:=FBuildDir;
  160. 5 : Result:=FPackagesDir;
  161. 6 : Result:=FCompilerConfigDir;
  162. 7 : Result:=FDefaultVerbosity;
  163. 8 : Result:=FDefaultCompilerConfig;
  164. 9 : Result:=FFPMakeCompilerConfig;
  165. 10 : Result:=FDownloader;
  166. else
  167. Error('Unknown option');
  168. end;
  169. end;
  170. procedure TGlobalOptions.SetOptString(Index: integer; const AValue: String);
  171. begin
  172. If AValue=GetOptString(Index) then
  173. Exit;
  174. Case Index of
  175. 0 : FLocalMirrorsLocation:=AValue;
  176. 1 : FRemoteMirrorsLocation:=AValue;
  177. 2 : FRemoteRepository:=AValue;
  178. 3 : FLocalRepository:=AValue;
  179. 4 : FBuildDir:=FixPath(AValue);
  180. 5 : FPackagesDir:=FixPath(AValue);
  181. 6 : FCompilerConfigDir:=FixPath(AValue);
  182. 7 : FDefaultVerbosity:=AValue;
  183. 8 : FDefaultCompilerConfig:=AValue;
  184. 9 : FFPMakeCompilerConfig:=AValue;
  185. 10 : FDownloader:=AValue;
  186. else
  187. Error('Unknown option');
  188. end;
  189. FDirty:=True;
  190. end;
  191. function TGlobalOptions.RemotePackagesFile:string;
  192. begin
  193. Result:=FRemoteRepository+DefaultPackagesFile;
  194. end;
  195. function TGlobalOptions.LocalPackagesFile:string;
  196. begin
  197. Result:=FLocalRepository+DefaultPackagesFile;
  198. end;
  199. function TGlobalOptions.LocalVersionsFile(const ACompilerConfig:String):string;
  200. begin
  201. Result:=FLocalRepository+Format(DefaultVersionsFile,[ACompilerConfig]);
  202. end;
  203. Procedure TGlobalOptions.InitGlobalDefaults;
  204. var
  205. LocalDir : String;
  206. begin
  207. FConfigVersion:=CurrentConfigVersion;
  208. // Retrieve Local fppkg directory
  209. {$ifdef unix}
  210. if IsSuperUser then
  211. begin
  212. if DirectoryExists('/usr/local/lib/fpc') then
  213. LocalDir:='/usr/local/lib/fpc/fppkg/'
  214. else
  215. LocalDir:='/usr/lib/fpc/fppkg/';
  216. end
  217. else
  218. LocalDir:=IncludeTrailingPathDelimiter(GetEnvironmentVariable('HOME'))+'.fppkg/';
  219. {$else}
  220. // Change as needed on all OS-es...
  221. LocalDir:=ExtractFilePath(Paramstr(0))+'fppkg'+PathDelim;
  222. {$endif}
  223. // Directories
  224. FBuildDir:=LocalDir+'build'+PathDelim;
  225. FPackagesDir:=LocalDir+'packages'+PathDelim;
  226. FCompilerConfigDir:=LocalDir+'config'+PathDelim;
  227. FLocalMirrorsLocation:=LocalDir+DefaultMirrorFile;
  228. FLocalRepository:=LocalDir;
  229. // Remote
  230. FRemoteMirrorsLocation:=DefaultMirrorsLocation;
  231. FRemoteRepository:=DefaultRemoteRepository;
  232. // Other config
  233. FDefaultVerbosity:='error,warning,info,debug,commands';
  234. FDefaultCompilerConfig:='default';
  235. FFPMakeCompilerConfig:='default';
  236. // Downloader
  237. {$if defined(unix) or defined(windows)}
  238. FDownloader:='lnet';
  239. {$else}
  240. FDownloader:='base';
  241. {$endif}
  242. // Parameter defaults
  243. FCompilerConfig:=FDefaultCompilerConfig;
  244. FInstallGlobal:=False;
  245. end;
  246. procedure TGlobalOptions.LoadGlobalFromIni(Ini: TCustomIniFile);
  247. begin
  248. With Ini do
  249. begin
  250. FConfigVersion:=ReadString(SDefaults,KeyConfigVersion,'');
  251. if FConfigVersion<>CurrentConfigVersion then
  252. Error('Old configuration found, please delete manual');
  253. FLocalMirrorsLocation:=ReadString(SDefaults,KeyLocalMirrorsLocation,FLocalMirrorsLocation);
  254. FRemoteMirrorsLocation:=ReadString(SDefaults,KeyRemoteMirrorsLocation,FRemoteMirrorsLocation);
  255. FRemoteRepository:=ReadString(SDefaults,KeyRemoteRepository,FRemoteRepository);
  256. FLocalRepository:=ReadString(SDefaults,KeyLocalRepository,FLocalRepository);
  257. FBuildDir:=FixPath(ReadString(SDefaults,KeyBuildDir,FBuildDir));
  258. FPackagesDir:=FixPath(ReadString(SDefaults,KeyPackagesDir,FPackagesDir));
  259. FCompilerConfigDir:=FixPath(ReadString(SDefaults,KeyCompilerConfigDir,FCompilerConfigDir));
  260. FDefaultVerbosity:=ReadString(SDefaults,KeyVerbosity,FDefaultVerbosity);
  261. FDefaultCompilerConfig:=ReadString(SDefaults,KeyCompilerConfig,FDefaultCompilerConfig);
  262. FFPMakeCompilerConfig:=ReadString(SDefaults,KeyFPMakeCompilerConfig,FFPMakeCompilerConfig);
  263. FDownloader:=ReadString(SDefaults,KeyDownloader,FDownloader);
  264. end;
  265. end;
  266. procedure TGlobalOptions.SaveGlobalToIni(Ini: TCustomIniFile);
  267. begin
  268. With Ini do
  269. begin
  270. WriteString(SDefaults,KeyConfigVersion,FConfigVersion);
  271. WriteString(SDefaults,KeyBuildDir,FBuildDir);
  272. WriteString(SDefaults,KeyPackagesDir,FPackagesDir);
  273. WriteString(SDefaults,KeyCompilerConfigDir,FCompilerConfigDir);
  274. WriteString(SDefaults,KeyLocalRepository,FLocalRepository);
  275. WriteString(SDefaults,KeyLocalMirrorsLocation,FLocalMirrorsLocation);
  276. WriteString(SDefaults,KeyRemoteMirrorsLocation,FRemoteMirrorsLocation);
  277. WriteString(SDefaults,KeyRemoteRepository,FRemoteRepository);
  278. WriteString(SDefaults,KeyVerbosity,FDefaultVerbosity);
  279. WriteString(SDefaults,KeyCompilerConfig,FDefaultCompilerConfig);
  280. WriteString(SDefaults,KeyFPMakeCompilerConfig,FFPMakeCompilerConfig);
  281. WriteString(SDefaults,KeyDownloader,FDownloader);
  282. end;
  283. end;
  284. procedure TGlobalOptions.LoadGlobalFromFile(const AFileName: String);
  285. Var
  286. Ini : TMemIniFile;
  287. begin
  288. Ini:=TMemIniFile.Create(AFileName);
  289. try
  290. LoadGlobalFromIni(Ini);
  291. finally
  292. Ini.Free;
  293. end;
  294. end;
  295. procedure TGlobalOptions.SaveGlobalToFile(const AFileName: String);
  296. Var
  297. Ini : TIniFile;
  298. begin
  299. if FileExists(AFileName) then
  300. BackupFile(AFileName);
  301. Ini:=TIniFile.Create(AFileName);
  302. try
  303. SaveGlobalToIni(Ini);
  304. Ini.UpdateFile;
  305. finally
  306. Ini.Free;
  307. end;
  308. end;
  309. {*****************************************************************************
  310. TCompilerOptions
  311. *****************************************************************************}
  312. constructor TCompilerOptions.Create;
  313. begin
  314. end;
  315. function TCompilerOptions.GetOptString(Index: integer): String;
  316. begin
  317. Case Index of
  318. 1 : Result:=FCompiler;
  319. 2 : Result:=MakeTargetString(CompilerCPU,CompilerOS);
  320. 3 : Result:=FCompilerVersion;
  321. 4 : Result:=FGlobalInstallDir;
  322. 5 : Result:=FLocalInstallDir;
  323. else
  324. Error('Unknown option');
  325. end;
  326. end;
  327. procedure TCompilerOptions.SetOptString(Index: integer; const AValue: String);
  328. begin
  329. If AValue=GetOptString(Index) then
  330. Exit;
  331. Case Index of
  332. 1 : FCompiler:=AValue;
  333. 2 : StringToCPUOS(AValue,FCompilerCPU,FCompilerOS);
  334. 3 : FCompilerVersion:=AValue;
  335. 4 : FGlobalInstallDir:=FixPath(AValue);
  336. 5 : FLocalInstallDir:=FixPath(AValue);
  337. else
  338. Error('Unknown option');
  339. end;
  340. FDirty:=True;
  341. end;
  342. procedure TCompilerOptions.SetCompilerCPU(const AValue: TCPU);
  343. begin
  344. if FCompilerCPU=AValue then
  345. exit;
  346. FCompilerCPU:=AValue;
  347. FDirty:=True;
  348. end;
  349. procedure TCompilerOptions.SetCompilerOS(const AValue: TOS);
  350. begin
  351. if FCompilerOS=AValue then
  352. exit;
  353. FCompilerOS:=AValue;
  354. FDirty:=True;
  355. end;
  356. function TCompilerOptions.LocalUnitDir:string;
  357. begin
  358. if FLocalInstallDir<>'' then
  359. result:=FLocalInstallDir+'units'+PathDelim+CompilerTarget+PathDelim
  360. else
  361. result:='';
  362. end;
  363. function TCompilerOptions.GlobalUnitDir:string;
  364. begin
  365. if FGlobalInstallDir<>'' then
  366. result:=FGlobalInstallDir+'units'+PathDelim+CompilerTarget+PathDelim
  367. else
  368. result:='';
  369. end;
  370. procedure TCompilerOptions.InitCompilerDefaults;
  371. var
  372. infoSL : TStringList;
  373. begin
  374. FConfigVersion:=CurrentConfigVersion;
  375. FCompiler:=FileSearch('fpc'+ExeExt,GetEnvironmentVariable('PATH'));
  376. if FCompiler='' then
  377. Raise EPackagerError.Create(SErrMissingFPC);
  378. // Detect compiler version/target from -i option
  379. infosl:=TStringList.Create;
  380. infosl.Delimiter:=' ';
  381. infosl.DelimitedText:=GetCompilerInfo(FCompiler,'-iVTPTO');
  382. if infosl.Count<>3 then
  383. Raise EPackagerError.Create(SErrInvalidFPCInfo);
  384. FCompilerVersion:=infosl[0];
  385. FCompilerCPU:=StringToCPU(infosl[1]);
  386. FCompilerOS:=StringToOS(infosl[2]);
  387. Log(vDebug,SLogDetectedCompiler,[FCompiler,FCompilerVersion,MakeTargetString(FCompilerCPU,FCompilerOS)]);
  388. // Use the same algorithm as the compiler, see options.pas
  389. {$ifdef Unix}
  390. FGlobalInstallDir:=FixPath(GetEnvironmentVariable('FPCDIR'));
  391. if FGlobalInstallDir='' then
  392. begin
  393. FGlobalInstallDir:='/usr/local/lib/fpc/'+FCompilerVersion+'/';
  394. if not DirectoryExists(FGlobalInstallDir) and
  395. DirectoryExists('/usr/lib/fpc/'+FCompilerVersion) then
  396. FGlobalInstallDir:='/usr/lib/fpc/'+FCompilerVersion+'/';
  397. end;
  398. {$else unix}
  399. FGlobalInstallDir:=FixPath(GetEnvironmentVariable('FPCDIR'));
  400. if FGlobalInstallDir='' then
  401. begin
  402. FGlobalInstallDir:=ExtractFilePath(FCompiler)+'../';
  403. if not(DirectoryExists(FGlobalInstallDir+'/units')) and
  404. not(DirectoryExists(FGlobalInstallDir+'/rtl')) then
  405. FGlobalInstallDir:=FGlobalInstallDir+'../';
  406. end;
  407. FGlobalInstallDir:=ExpandFileName(FGlobalInstallDir);
  408. {$endif unix}
  409. Log(vDebug,SLogDetectedFPCDIR,['global',FGlobalInstallDir]);
  410. // User writable install directory
  411. if not IsSuperUser then
  412. begin
  413. FLocalInstallDir:=GlobalOptions.LocalRepository+'lib'+PathDelim+FCompilerVersion+PathDelim;
  414. Log(vDebug,SLogDetectedFPCDIR,['local',FLocalInstallDir]);
  415. end;
  416. end;
  417. procedure TCompilerOptions.LoadCompilerFromIni(Ini: TCustomIniFile);
  418. begin
  419. With Ini do
  420. begin
  421. FConfigVersion:=ReadString(SDefaults,KeyConfigVersion,'');
  422. if FConfigVersion<>CurrentConfigVersion then
  423. Error('Old configuration found, please delete manual');
  424. FGlobalInstallDir:=FixPath(ReadString(SDefaults,KeyGlobalInstallDir,FGlobalInstallDir));
  425. FLocalInstallDir:=FixPath(ReadString(SDefaults,KeyLocalInstallDir,FLocalInstallDir));
  426. FCompiler:=ReadString(SDefaults,KeyCompiler,FCompiler);
  427. FCompilerOS:=StringToOS(ReadString(SDefaults,KeyCompilerOS,OSToString(CompilerOS)));
  428. FCompilerCPU:=StringToCPU(ReadString(SDefaults,KeyCompilerCPU,CPUtoString(CompilerCPU)));
  429. FCompilerVersion:=ReadString(SDefaults,KeyCompilerVersion,FCompilerVersion);
  430. end;
  431. end;
  432. procedure TCompilerOptions.SaveCompilerToIni(Ini: TCustomIniFile);
  433. begin
  434. With Ini do
  435. begin
  436. WriteString(SDefaults,KeyConfigVersion,FConfigVersion);
  437. WriteString(SDefaults,KeyGlobalInstallDir,FGlobalInstallDir);
  438. WriteString(SDefaults,KeyLocalInstallDir,FLocalInstallDir);
  439. WriteString(SDefaults,KeyCompiler,FCompiler);
  440. WriteString(SDefaults,KeyCompilerOS,OSToString(CompilerOS));
  441. WriteString(SDefaults,KeyCompilerCPU,CPUtoString(CompilerCPU));
  442. WriteString(SDefaults,KeyCompilerVersion,FCompilerVersion);
  443. end;
  444. end;
  445. procedure TCompilerOptions.LoadCompilerFromFile(const AFileName: String);
  446. Var
  447. Ini : TMemIniFile;
  448. begin
  449. Ini:=TMemIniFile.Create(AFileName);
  450. try
  451. LoadCompilerFromIni(Ini);
  452. finally
  453. Ini.Free;
  454. end;
  455. end;
  456. procedure TCompilerOptions.SaveCompilerToFile(const AFileName: String);
  457. Var
  458. Ini : TIniFile;
  459. begin
  460. if FileExists(AFileName) then
  461. BackupFile(AFileName);
  462. Ini:=TIniFile.Create(AFileName);
  463. try
  464. SaveCompilerToIni(Ini);
  465. Ini.UpdateFile;
  466. finally
  467. Ini.Free;
  468. end;
  469. end;
  470. initialization
  471. GlobalOptions:=TGlobalOptions.Create;
  472. CompilerOptions:=TCompilerOptions.Create;
  473. FPMakeCompilerOptions:=TCompilerOptions.Create;
  474. finalization
  475. FreeAndNil(GlobalOptions);
  476. FreeAndNil(CompilerOptions);
  477. FreeAndNil(FPMakeCompilerOptions);
  478. end.