📄 compile.pas
字号:
{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is: Compile.pas, released on 2004-03-29.
The Initial Developer of the Original Code is Andreas Hausladen
(Andreas dott Hausladen att gmx dott de)
Portions created by Andreas Hausladen are Copyright (C) 2004 Andreas Hausladen.
All Rights Reserved.
Contributor(s): -
You may retrieve the latest version of this file at the Project JEDI's JVCL
home page, located at http://jvcl.sourceforge.net
Known Issues:
-----------------------------------------------------------------------------}
// $Id: Compile.pas,v 1.48 2005/02/04 21:35:26 ahuser Exp $
unit Compile;
{$I jvcl.inc}
{$I windowsonly.inc}
interface
uses
Windows, SysUtils, Classes, CapExec, JVCLData, DelphiData,
GenerateUtils, PackageUtils, Intf, PackageInformation, ConditionParser;
type
TProgressKind = (
pkTarget, // progress of all targets
pkProject, // |- progress of the parts of one target compilation
pkResource, // |- progress of the resource compilation
pkPackage, // |- progress of the package compilation
pkOther // |- progress for copy/delete and other things
);
TTargetProgressEvent = procedure(Sender: TObject; Current: TTargetConfig;
Position, Max: Integer) of object;
TPackageProgressEvent = procedure(Sender: TObject; Current: TPackageTarget;
const Text: string; Position, Max: Integer) of object;
TResourceProgressEvent = procedure(Sender: TObject; const Text: string;
Position, Max: Integer) of object;
TProjectProgressEvent = TResourceProgressEvent;
TProgressEvent = procedure(Sender: TObject; const Text: string;
Position, Max: Integer; Kind: TProgressKind) of object;
TJVCLCompiler = class(TObject)
private
FData: TJVCLData;
FCurrentProjectGroup: TProjectGroup;
FAborted: Boolean;
FOutput: TStrings;
FCount: Integer;
FPkgCount: Integer; // number of packages to compile
FPkgIndex: Integer;
FResCount: Integer;
FResIndex: Integer;
FOnCaptureLine: TCaptureLine;
FOnTargetProgress: TTargetProgressEvent;
FOnPackageProgress: TPackageProgressEvent;
FOnResourceProgress: TResourceProgressEvent;
FOnProjectProgress: TProjectProgressEvent;
FOnProgress: TProgressEvent;
FOnIdle: TNotifyEvent;
FAbortReason: string;
FQuiet: string;
function IsPackageUsed(ProjectGroup: TProjectGroup;
RequiredPackage: TRequiredPackage): Boolean;
function IsFileUsed(ProjectGroup: TProjectGroup;
ContainedFile: TContainedFile): Boolean;
protected
function Make(TargetConfig: ITargetConfig; Args: string;
CaptureLine: TCaptureLine; StartDir: string = ''): Integer;
procedure DoIdle(Sender: TObject);
procedure CaptureLine(const Line: string; var Aborted: Boolean); virtual;
procedure CaptureLineClean(const Line: string; var Aborted: Boolean); virtual;
procedure CaptureLineGetCompileCount(const Line: string; var Aborted: Boolean);
procedure CaptureLinePackageCompilation(const Line: string; var Aborted: Boolean);
procedure CaptureLineResourceCompilation(const Line: string; var Aborted: Boolean);
procedure DoTargetProgress(Current: TTargetConfig; Position, Max: Integer); virtual;
procedure DoProjectProgress(const Text: string; Position, Max: Integer); virtual;
procedure DoResourceProgress(const Text: string; Position, Max: Integer); virtual;
procedure DoPackageProgress(Current: TPackageTarget; const Text: string;
Position, Max: Integer); virtual;
procedure DoProgress(const Text: string; Position, Max: Integer;
Kind: TProgressKind); virtual;
// DoProgress is called by every DoXxxProgress method
function CompileProjectGroup(ProjectGroup: TProjectGroup;
DebugUnits, ForceJclDcp: Boolean): Boolean;
procedure CreateProjectGroupMakefile(ProjectGroup: TProjectGroup; AutoDepend: Boolean);
function GenerateResources(TargetConfig: ITargetConfig): Boolean;
function DeleteFormDataFiles(ProjectGroup: TProjectGroup): Boolean;
function CopyFormDataFiles(ProjectGroup: TProjectGroup; DebugUnits: Boolean): Boolean;
function PrepareJCL(TargetConfig: ITargetConfig; Force: Boolean): Boolean;
function IsCondition(const Condition: string; TargetConfig: ITargetConfig): Boolean;
public
constructor Create(AData: TJVCLData);
destructor Destroy; override;
function GeneratePackages(const Group, Targets, PackagesPath: string): Boolean; overload;
function GenerateAllPackages: Boolean; overload;
function Compile(Force: Boolean = False): Boolean;
function CompileTarget(TargetConfig: TTargetConfig;
ForceJclDcp: Boolean; DoClx: Boolean): Boolean;
procedure Abort; // abort compile process
property AbortReason: string read FAbortReason write FAbortReason;
property Data: TJVCLData read FData;
property Output: TStrings read FOutput;
property OnCaptureLine: TCaptureLine read FOnCaptureLine write FOnCaptureLine;
property OnTargetProgress: TTargetProgressEvent read FOnTargetProgress write FOnTargetProgress;
property OnPackageProgress: TPackageProgressEvent read FOnPackageProgress write FOnPackageProgress;
property OnResourceProgress: TResourceProgressEvent read FOnResourceProgress write FOnResourceProgress;
property OnProjectProgress: TProjectProgressEvent read FOnProjectProgress write FOnProjectProgress;
property OnProgress: TProgressEvent read FOnProgress write FOnProgress;
property OnIdle: TNotifyEvent read FOnIdle write FOnIdle;
end;
const
ProjectMax = 7;
var
Compiler: TJVCLCompiler = nil;
StartupEnvVarPath: string;
resourcestring
RsPackagesAreUpToDate = 'Packages are up to date';
implementation
uses
CmdLineUtils, JvConsts, Utils, Core;
resourcestring
RsCompilingJCL = 'Compiling JCL dcp files...';
RsErrorCompilingJclDcpFiles = 'Error while compiling .dcp files for JCL.';
RsGeneratingTemplates = 'Generating templates...';
RsGeneratingPackages = 'Generating packages...';
RsGeneratingResources = 'Generating resources...';
RsCompilingPackages = 'Compiling packages...';
RsCopyingFiles = 'Copying files...';
RsCopyingFile = 'Copying %s';
RsFinished = 'Finished.';
RsAbortedByUser = 'Aborted by User';
RsErrorLoadingPackageGeneratorConfigFile = 'Error loading devtools\bin\pgEdit.xml';
RsErrorGeneratingPackages = 'Error while generating packages for %s';
RsErrorGeneratingTemplates = 'Error while generating templates.';
RsErrorCompilingResources = 'Error while compiling resources.';
RsErrorGeneratingTemplatesForDir = 'Error generating templates for the %s directory.';
RsErrorCompilingPackages = 'An error occured while compiling the packages.'; // this must not be the doubt of the installer
RsCommandNotFound = 'Command could not be executed.'#10#10#10'Cmdline: %s'#10#0'Start directory: %s';
const
RsGeneratePackages = '[Generating: Packages]'; // do not localize
const
CommonDependencyFiles: array[0..5] of string = (
'jvcl.inc', 'jvclbase.inc', 'jvcl%t.inc', 'jedi.inc', 'linuxonly.inc', 'windowsonly.inc'
);
{ TJVCLCompiler }
constructor TJVCLCompiler.Create(AData: TJVCLData);
begin
inherited Create;
FData := AData;
FOutput := TStringList.Create;
end;
destructor TJVCLCompiler.Destroy;
begin
FOutput.Free;
inherited Destroy;
end;
procedure TJVCLCompiler.DoTargetProgress(Current: TTargetConfig; Position,
Max: Integer);
begin
if Assigned(FOnTargetProgress) then
FOnTargetProgress(Self, Current, Position, Max);
DoProgress(Current.Target.DisplayName, Position, Max, pkTarget);
end;
procedure TJVCLCompiler.DoProjectProgress(const Text: string; Position, Max: Integer);
begin
if Assigned(FOnProjectProgress) then
FOnProjectProgress(Self, Text, Position, Max);
DoProgress(Text, Position, Max, pkProject);
end;
procedure TJVCLCompiler.DoResourceProgress(const Text: string; Position, Max: Integer);
begin
if Assigned(FOnResourceProgress) then
FOnResourceProgress(Self, Text, Position, Max);
DoProgress(Text, Position, Max, pkResource);
end;
procedure TJVCLCompiler.DoPackageProgress(Current: TPackageTarget;
const Text: string; Position, Max: Integer);
begin
if Assigned(FOnPackageProgress) then
FOnPackageProgress(Self, Current, Text, Position, Max);
DoProgress(Text, Position, Max, pkPackage);
end;
procedure TJVCLCompiler.DoProgress(const Text: string; Position, Max: Integer;
Kind: TProgressKind);
begin
if Assigned(FOnProgress) then
FOnProgress(Self, Text, Position, Max, Kind);
end;
procedure TJVCLCompiler.CaptureLine(const Line: string; var Aborted: Boolean);
begin
FOutput.Add(Line);
if Assigned(FOnCaptureLine) then
FOnCaptureLine(Line, FAborted);
Aborted := FAborted;
end;
procedure TJVCLCompiler.CaptureLineClean(const Line: string; var Aborted: Boolean);
begin
if StartsWith('[', Line) then
CaptureLine(Line, Aborted);
end;
procedure TJVCLCompiler.CaptureLineGetCompileCount(const Line: string; var Aborted: Boolean);
begin
if StartsWith(Trim(Line), 'echo [Compiling: ', True) then
Inc(FCount)
else if (Line <> '') and (Line[1] <> #9) then
CaptureLine(Line, FAborted);
Aborted := FAborted;
end;
procedure TJVCLCompiler.CaptureLinePackageCompilation(const Line: string; var Aborted: Boolean);
var
S: string;
i: Integer;
begin
CaptureLine(Line, Aborted);
if (Line <> '') and (Line[1] = '[') then
begin
if StartsWith(Line, '[Compiling: ', True) then
begin
Inc(FPkgIndex);
S := Trim(Copy(Line, 13, Length(Line) - 13));
for i := 0 to FCurrentProjectGroup.Count - 1 do
if CompareText(FCurrentProjectGroup.Packages[i].TargetName, S) = 0 then
begin
S := S + ' (' + FCurrentProjectGroup.Packages[i].Info.Description + ')';
DoPackageProgress(FCurrentProjectGroup.Packages[i], S, FPkgIndex - 1, FPkgCount);
Exit;
end;
DoPackageProgress(nil, S, FPkgIndex, FPkgCount);
end;
end;
end;
procedure TJVCLCompiler.CaptureLineResourceCompilation(const Line: string;
var Aborted: Boolean);
var
S: string;
begin
CaptureLine(Line, Aborted);
if (Line <> '') and (Line[1] = '[') then
begin
if StartsWith(Line, '[Compiling: ', True) then
begin
Inc(FResIndex);
S := Trim(Copy(Line, 15, Length(Line) - 15));
DoResourceProgress(S, FResIndex, FResCount);
end;
end;
end;
procedure TJVCLCompiler.Abort;
begin
FAborted := True;
end;
procedure WriteMsg(const Text: string); // used by TJVCLCompiler.GeneratePackages
begin
Compiler.CaptureLine(Text, Compiler.FAborted);
end;
/// <summary>
/// Make calls the make.exe of the given TargetConfig. If the StartDir is empty
/// the JVCLPackageDir\bin directory is used. If the command could not be
/// executed a message dialog is shown with the complete command line.
/// </summary>
function TJVCLCompiler.Make(TargetConfig: ITargetConfig; Args: string;
CaptureLine: TCaptureLine; StartDir: string): Integer;
begin
if StartDir = '' then
StartDir := Data.JVCLPackagesDir + '\bin';
if Data.IgnoreMakeErrors then
Args := Trim('-i ' + Args);
if Data.Verbose then
begin
// output command line
if Assigned(CaptureLine) then
CaptureLine(#1 + '"' + TargetConfig.Target.Make + '" ' + Args, FAborted);
end;
Result := CaptureExecute('"' + TargetConfig.Target.Make + '"', Args,
StartDir, CaptureLine, DoIdle);
if Result < 0 then // command not found
MessageBox(0, PChar(Format(RsCommandNotFound,
['"' + TargetConfig.Target.Make + '"' + Args, StartDir])),
'JVCL Installer', MB_OK or MB_ICONERROR);
end;
procedure TJVCLCompiler.DoIdle(Sender: TObject);
begin
if Assigned(FOnIdle) then
FOnIdle(Self);
end;
/// <summary>
/// GeneratePackages generates the packages in
/// PackagesPath for the Group (JVCL, JCL) for the Targets (comma separated
/// pg.exe target list).
/// </summary>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -