mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-07 20:38:11 +02:00
451 lines
14 KiB
ObjectPascal
451 lines
14 KiB
ObjectPascal
{
|
|
***************************************************************************
|
|
* *
|
|
* This source is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This code is distributed in the hope that it will be useful, but *
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
|
* General Public License for more details. *
|
|
* *
|
|
* A copy of the GNU General Public License is available on the World *
|
|
* Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
|
|
* obtain it by writing to the Free Software Foundation, *
|
|
* Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. *
|
|
* *
|
|
***************************************************************************
|
|
|
|
Author: Mattias Gaertner
|
|
|
|
Abstract:
|
|
This unit helps to setup and configure the codetools.
|
|
|
|
Example:
|
|
Create an empty unit empty.pas and do
|
|
|
|
Options:=TCodeToolsOptions.Create;
|
|
Options.LoadFromFile('config.xml');
|
|
Options.FPCPath:='/usr/bin/ppc386';
|
|
Options.FPCSrcDir:='/home/username/freepascal/fpc';
|
|
Options.LazarusSrcDir:='/home/username/pascal/lazarus';
|
|
Options.ProjectDir:='/home/username/pascal/project1/';
|
|
Options.TestPascalFile:=Options.ProjectDir+'empty.pas';
|
|
CodeToolBoss.Init(Options);
|
|
Options.SaveToFile('config.xml');
|
|
Options.Free;
|
|
|
|
.. use CodeToolBoss ..
|
|
|
|
}
|
|
unit CodeToolsConfig;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
{$I codetools.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Laz2_XMLCfg, Laz2_XMLRead, Laz2_XMLWrite, Laz2_DOM,
|
|
FileProcs, LazFileUtils, LazFileCache, LazUTF8, CodeCache, DefineTemplates;
|
|
|
|
type
|
|
|
|
{ TCodeBufXMLConfig }
|
|
|
|
TCodeBufXMLConfig = class(TRttiXMLConfig)
|
|
private
|
|
FCodeCache: TCodeCache;
|
|
protected
|
|
fKeepFileAttributes: boolean;
|
|
procedure ReadXMLFile(out ADoc: TXMLDocument; const AFilename: String); override;
|
|
procedure WriteXMLFile(ADoc: TXMLDocument; const AFileName: String); override;
|
|
function GetCache: TCodeCache;
|
|
public
|
|
constructor CreateWithCache(AFilename: string;
|
|
LoadContent: boolean = true; // init/load from disk
|
|
LoadFileAttributes: boolean = true; // load lineending and encoding
|
|
ASource: string = ''; // init with this source
|
|
ACache: TCodeCache = nil);
|
|
property CodeCache: TCodeCache read FCodeCache write FCodeCache;
|
|
property KeepFileAttributes: boolean read fKeepFileAttributes write fKeepFileAttributes;
|
|
end;
|
|
|
|
var
|
|
DefaultConfigCodeCache: TCodeCache = nil; // set by CodeToolBoss
|
|
|
|
type
|
|
|
|
{ TCodeToolsOptions }
|
|
|
|
TCodeToolsOptions = class
|
|
private
|
|
FConfigCaches: TPCTargetConfigCaches;
|
|
FFPCOptions: string;
|
|
FFPCPath: string;
|
|
FFPCSrcDir: string;
|
|
FLazarusSrcDir: string;
|
|
FLazarusSrcOptions: string;
|
|
FLCLWidgetType: string;
|
|
FModified: boolean;
|
|
FPPUExt: string;
|
|
FProjectDir: string;
|
|
FSourceCaches: TFPCSourceCaches;
|
|
FSubtarget: string;
|
|
FTargetOS: string;
|
|
FTargetProcessor: string;
|
|
FTestPascalFile: string;
|
|
procedure SetFPCOptions(const AValue: string);
|
|
procedure SetFPCPath(const AValue: string);
|
|
procedure SetFPCSrcDir(const AValue: string);
|
|
procedure SetLazarusSrcDir(const AValue: string);
|
|
procedure SetLCLWidgetType(const AValue: string);
|
|
procedure SetLazarusSrcOptions(const AValue: string);
|
|
procedure SetModified(const AValue: boolean);
|
|
procedure SetPPUExt(const AValue: string);
|
|
procedure SetProjectDir(const AValue: string);
|
|
procedure SetSubtarget(AValue: string);
|
|
procedure SetTargetOS(const AValue: string);
|
|
procedure SetTargetProcessor(const AValue: string);
|
|
procedure SetTestPascalFile(const AValue: string);
|
|
public
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
procedure InitWithEnvironmentVariables;
|
|
function FindDefaultCompilerFilename: string;
|
|
|
|
procedure SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string);
|
|
procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string);
|
|
procedure SaveToFile(const Filename: string);
|
|
procedure LoadFromFile(const Filename: string);
|
|
|
|
property Modified: boolean read FModified write SetModified;
|
|
|
|
// FPC
|
|
property FPCSrcDir: string read FFPCSrcDir write SetFPCSrcDir; // e.g. /usr/share/fpcsrc
|
|
property FPCPath: string read FFPCPath write SetFPCPath; // e.g. /usr/bin/fpc or /usr/bin/ppc386
|
|
property FPCOptions: string read FFPCOptions write SetFPCOptions; // extra options for fpc
|
|
property TargetOS: string read FTargetOS write SetTargetOS;
|
|
property TargetProcessor: string read FTargetProcessor write SetTargetProcessor;
|
|
property Subtarget: string read FSubtarget write SetSubtarget;
|
|
property TestPascalFile: string read FTestPascalFile write SetTestPascalFile; // points to an empty unit
|
|
property PPUExt: string read FPPUExt write SetPPUExt;
|
|
property SourceCaches: TFPCSourceCaches read FSourceCaches;
|
|
property ConfigCaches: TPCTargetConfigCaches read FConfigCaches;
|
|
|
|
// Project
|
|
property ProjectDir: string read FProjectDir write SetProjectDir;
|
|
|
|
// Lazarus
|
|
property LazarusSrcDir: string read FLazarusSrcDir write SetLazarusSrcDir;
|
|
property LCLWidgetType: string read FLCLWidgetType write SetLCLWidgetType;
|
|
property LazarusSrcOptions: string read FLazarusSrcOptions write SetLazarusSrcOptions;
|
|
end;
|
|
|
|
implementation
|
|
|
|
{ TCodeToolsOptions }
|
|
|
|
procedure TCodeToolsOptions.SetFPCOptions(const AValue: string);
|
|
begin
|
|
if FFPCOptions=AValue then exit;
|
|
FFPCOptions:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TCodeToolsOptions.SetFPCPath(const AValue: string);
|
|
var
|
|
NewValue: String;
|
|
begin
|
|
NewValue:=TrimAndExpandFilename(AValue);
|
|
if FFPCPath=NewValue then exit;
|
|
FFPCPath:=NewValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TCodeToolsOptions.SetFPCSrcDir(const AValue: string);
|
|
var
|
|
NewValue: String;
|
|
begin
|
|
NewValue:=TrimAndExpandFilename(AValue);
|
|
if FFPCSrcDir=NewValue then exit;
|
|
FFPCSrcDir:=NewValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TCodeToolsOptions.SetLazarusSrcDir(const AValue: string);
|
|
var
|
|
NewValue: String;
|
|
begin
|
|
NewValue:=TrimAndExpandFilename(AValue);
|
|
if FLazarusSrcDir=NewValue then exit;
|
|
FLazarusSrcDir:=NewValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TCodeToolsOptions.SetLCLWidgetType(const AValue: string);
|
|
begin
|
|
if FLCLWidgetType=AValue then exit;
|
|
FLCLWidgetType:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TCodeToolsOptions.SetLazarusSrcOptions(const AValue: string);
|
|
begin
|
|
if FLazarusSrcOptions=AValue then exit;
|
|
FLazarusSrcOptions:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TCodeToolsOptions.SetModified(const AValue: boolean);
|
|
begin
|
|
if FModified=AValue then exit;
|
|
FModified:=AValue;
|
|
end;
|
|
|
|
procedure TCodeToolsOptions.SetPPUExt(const AValue: string);
|
|
begin
|
|
if FPPUExt=AValue then exit;
|
|
FPPUExt:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TCodeToolsOptions.SetProjectDir(const AValue: string);
|
|
begin
|
|
if FProjectDir=AValue then exit;
|
|
FProjectDir:=AppendPathDelim(AValue);
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TCodeToolsOptions.SetSubtarget(AValue: string);
|
|
begin
|
|
if FSubtarget=AValue then Exit;
|
|
FSubtarget:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TCodeToolsOptions.SetTargetOS(const AValue: string);
|
|
begin
|
|
if FTargetOS=AValue then exit;
|
|
FTargetOS:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TCodeToolsOptions.SetTargetProcessor(const AValue: string);
|
|
begin
|
|
if FTargetProcessor=AValue then exit;
|
|
FTargetProcessor:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TCodeToolsOptions.SetTestPascalFile(const AValue: string);
|
|
begin
|
|
if FTestPascalFile=AValue then exit;
|
|
FTestPascalFile:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
constructor TCodeToolsOptions.Create;
|
|
begin
|
|
FPPUExt:='.ppu';
|
|
FLCLWidgetType:='gtk2';
|
|
FConfigCaches:=TPCTargetConfigCaches.Create(nil);
|
|
FSourceCaches:=TFPCSourceCaches.Create(nil);
|
|
end;
|
|
|
|
destructor TCodeToolsOptions.Destroy;
|
|
begin
|
|
FreeAndNil(FConfigCaches);
|
|
FreeAndNil(FSourceCaches);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TCodeToolsOptions.InitWithEnvironmentVariables;
|
|
|
|
{ procedure WriteEnv;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
for i:=0 to GetEnvironmentVariableCount-1 do
|
|
debugln(['TCodeToolsOptions.InitWithEnvironmentVariables ',i,' ',GetEnvironmentStringUTF8(i)]);
|
|
end;
|
|
}
|
|
begin
|
|
if GetEnvironmentVariableUTF8('PP')<>'' then
|
|
FPCPath:=GetEnvironmentVariableUTF8('PP')
|
|
else if (FPCPath='') or not FileExistsCached(FPCPath) then
|
|
FPCPath:=FindDefaultCompilerFilename;
|
|
if GetEnvironmentVariableUTF8('FPCDIR')<>'' then
|
|
FPCSrcDir:=GetEnvironmentVariableUTF8('FPCDIR');
|
|
if GetEnvironmentVariableUTF8('LAZARUSDIR')<>'' then
|
|
LazarusSrcDir:=GetEnvironmentVariableUTF8('LAZARUSDIR');
|
|
if GetEnvironmentVariableUTF8('FPCTARGET')<>'' then
|
|
TargetOS:=GetEnvironmentVariableUTF8('FPCTARGET');
|
|
if GetEnvironmentVariableUTF8('FPCTARGETCPU')<>'' then
|
|
TargetProcessor:=GetEnvironmentVariableUTF8('FPCTARGETCPU');
|
|
if GetEnvironmentVariableUTF8('FPCSUBTARGET')<>'' then
|
|
Subtarget:=GetEnvironmentVariableUTF8('FPCSUBTARGET');
|
|
end;
|
|
|
|
function TCodeToolsOptions.FindDefaultCompilerFilename: string;
|
|
begin
|
|
Result:=SearchFileInPath(GetDefaultCompilerFilename,'',
|
|
GetEnvironmentVariableUTF8('PATH'),PathSeparator,ctsfcDefault);
|
|
end;
|
|
|
|
procedure TCodeToolsOptions.SaveToXMLConfig(XMLConfig: TXMLConfig;
|
|
const Path: string);
|
|
begin
|
|
XMLConfig.SetDeleteValue(Path+'FPC/Options/Value',FPCOptions,'');
|
|
XMLConfig.SetDeleteValue(Path+'FPC/CompilerPath/Value',FPCPath,'');
|
|
XMLConfig.SetDeleteValue(Path+'FPC/SrcDir/Value',FPCSrcDir,'');
|
|
XMLConfig.SetDeleteValue(Path+'FPC/TargetOS/Value',TargetOS,'');
|
|
XMLConfig.SetDeleteValue(Path+'FPC/TargetProcessor/Value',TargetProcessor,'');
|
|
XMLConfig.SetDeleteValue(Path+'FPC/Subtarget/Value',Subtarget,'');
|
|
XMLConfig.SetDeleteValue(Path+'FPC/PPUExt/Value',PPUExt,'.ppu');
|
|
XMLConfig.SetDeleteValue(Path+'FPC/TestPascalFile/Value',TestPascalFile,'');
|
|
XMLConfig.SetDeleteValue(Path+'Lazarus/SrcDir/Value',LazarusSrcDir,'');
|
|
XMLConfig.SetDeleteValue(Path+'Lazarus/SrcDirOptions/Value',LazarusSrcOptions,'');
|
|
XMLConfig.SetDeleteValue(Path+'Lazarus/LCLWidgetType/Value',LCLWidgetType,'');
|
|
XMLConfig.SetDeleteValue(Path+'Project/Dir/Value',ProjectDir,'');
|
|
FConfigCaches.SaveToXMLConfig(XMLConfig,Path+'FPCConfigCaches/');
|
|
FSourceCaches.SaveToXMLConfig(XMLConfig,Path+'FPCSrcDirCaches/');
|
|
Modified:=false;
|
|
end;
|
|
|
|
procedure TCodeToolsOptions.LoadFromXMLConfig(XMLConfig: TXMLConfig;
|
|
const Path: string);
|
|
begin
|
|
FPCOptions:=XMLConfig.GetValue(Path+'FPC/Options/Value','');
|
|
FPCPath:=XMLConfig.GetValue(Path+'FPC/CompilerPath/Value','');
|
|
FPCSrcDir:=XMLConfig.GetValue(Path+'FPC/SrcDir/Value','');
|
|
TargetOS:=XMLConfig.GetValue(Path+'FPC/TargetOS/Value','');
|
|
TargetProcessor:=XMLConfig.GetValue(Path+'FPC/TargetProcessor/Value','');
|
|
Subtarget:=XMLConfig.GetValue(Path+'FPC/Subtarget/Value','');
|
|
PPUExt:=XMLConfig.GetValue(Path+'FPC/PPUExt/Value','.ppu');
|
|
TestPascalFile:=XMLConfig.GetValue(Path+'FPC/TestPascalFile/Value','');
|
|
FConfigCaches.LoadFromXMLConfig(XMLConfig,Path+'FPCConfigCaches/');
|
|
FSourceCaches.LoadFromXMLConfig(XMLConfig,Path+'FPCSrcDirCaches/');
|
|
|
|
LazarusSrcDir:=XMLConfig.GetValue(Path+'Lazarus/SrcDir/Value','');
|
|
LazarusSrcOptions:=XMLConfig.GetValue(Path+'Lazarus/SrcDirOptions/Value','');
|
|
LCLWidgetType:=XMLConfig.GetValue(Path+'Lazarus/LCLWidgetType/Value','');
|
|
ProjectDir:=XMLConfig.GetValue(Path+'Project/Dir/Value','');
|
|
Modified:=false;
|
|
end;
|
|
|
|
procedure TCodeToolsOptions.SaveToFile(const Filename: string);
|
|
var
|
|
XMLConfig: TXMLConfig;
|
|
begin
|
|
XMLConfig:=TXMLConfig.CreateClean(Filename);
|
|
try
|
|
SaveToXMLConfig(XMLConfig,'CodeToolsOptions/');
|
|
XMLConfig.Flush;
|
|
finally
|
|
XMLConfig.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TCodeToolsOptions.LoadFromFile(const Filename: string);
|
|
var
|
|
XMLConfig: TXMLConfig;
|
|
begin
|
|
XMLConfig:=TXMLConfig.Create(Filename);
|
|
try
|
|
LoadFromXMLConfig(XMLConfig,'CodeToolsOptions/');
|
|
XMLConfig.Flush;
|
|
finally
|
|
XMLConfig.Free;
|
|
end;
|
|
end;
|
|
|
|
{ TCodeBufXMLConfig }
|
|
|
|
procedure TCodeBufXMLConfig.ReadXMLFile(out ADoc: TXMLDocument;
|
|
const AFilename: String);
|
|
var
|
|
Buf: TCodeBuffer;
|
|
ms: TMemoryStream;
|
|
Cache: TCodeCache;
|
|
begin
|
|
Cache:=GetCache;
|
|
if Cache<>nil then begin
|
|
Buf:=Cache.LoadFile(AFilename);
|
|
if Buf<>nil then begin
|
|
fKeepFileAttributes:=true;
|
|
ms:=TMemoryStream.Create;
|
|
try
|
|
Buf.SaveToStream(ms);
|
|
ms.Position:=0;
|
|
Laz2_XMLRead.ReadXMLFile(ADoc, ms, ReadFlags);
|
|
exit; // success
|
|
finally
|
|
ms.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
// try default (this will create the normal exceptions)
|
|
inherited ReadXMLFile(ADoc, AFilename);
|
|
end;
|
|
|
|
procedure TCodeBufXMLConfig.WriteXMLFile(ADoc: TXMLDocument;
|
|
const AFileName: String);
|
|
var
|
|
Buf: TCodeBuffer;
|
|
ms: TMemoryStream;
|
|
Cache: TCodeCache;
|
|
begin
|
|
Cache:=GetCache;
|
|
if Cache<>nil then begin
|
|
Buf:=nil;
|
|
if (not fKeepFileAttributes) or (not FileExistsCached(AFileName)) then
|
|
Buf:=Cache.CreateFile(AFilename)
|
|
else
|
|
Buf:=Cache.LoadFile(AFilename);
|
|
if Buf<>nil then begin
|
|
fKeepFileAttributes:=true;
|
|
ms:=TMemoryStream.Create;
|
|
try
|
|
Laz2_XMLWrite.WriteXMLFile(ADoc, ms, WriteFlags);
|
|
ms.Position:=0;
|
|
Buf.LoadFromStream(ms);
|
|
if Buf.FileOnDiskIsEqual then exit;
|
|
//debugln(['TCodeBufXMLConfig.WriteXMLFile writing ',AFileName,' ...']);
|
|
if Buf.Save then exit; // success
|
|
finally
|
|
ms.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
// try default (this will create the normal exceptions)
|
|
inherited WriteXMLFile(ADoc, AFileName);
|
|
end;
|
|
|
|
function TCodeBufXMLConfig.GetCache: TCodeCache;
|
|
begin
|
|
Result:=CodeCache;
|
|
if Result=nil then
|
|
Result:=DefaultConfigCodeCache;
|
|
end;
|
|
|
|
constructor TCodeBufXMLConfig.CreateWithCache(AFilename: string;
|
|
LoadContent: boolean; LoadFileAttributes: boolean; ASource: string;
|
|
ACache: TCodeCache);
|
|
begin
|
|
CodeCache:=ACache;
|
|
fKeepFileAttributes:=LoadFileAttributes;
|
|
if (ASource<>'') then
|
|
inherited CreateWithSource(AFilename,ASource)
|
|
else if LoadContent then
|
|
inherited Create(AFilename)
|
|
else
|
|
inherited CreateClean(AFilename);
|
|
end;
|
|
|
|
end.
|
|
|