mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-05 08:58:31 +02:00
330 lines
8.9 KiB
ObjectPascal
330 lines
8.9 KiB
ObjectPascal
{
|
|
Copyright (c) 2001 by Peter Vreman
|
|
|
|
Convert Makefile.fpc to Makefile
|
|
|
|
See the file COPYING.FPC, included in this distribution,
|
|
for details about the copyright.
|
|
|
|
This program 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.
|
|
|
|
**********************************************************************}
|
|
{$ifdef fpc}{$mode objfpc}{$endif}
|
|
{$H+}
|
|
program fpcmake;
|
|
|
|
{ Define to not catch exceptions and output backtraces }
|
|
{ define NOEXCEPT}
|
|
|
|
uses
|
|
getopts,
|
|
sysutils,
|
|
fpcmmain,fpcmwr,fpcmpkg, fpcmdic;
|
|
|
|
type
|
|
{ Verbosity Level }
|
|
TVerboseLevel = (v_Quiet,v_Default,v_Verbose);
|
|
|
|
{ Operation mode }
|
|
TMode = (m_None,m_PackageFpc,m_Makefile);
|
|
|
|
TFPCMakeConsole=class(TFPCMake)
|
|
procedure Verbose(lvl:TFPCMakeVerbose;const s:string);override;
|
|
end;
|
|
|
|
var
|
|
ParaMode : TMode;
|
|
ParaVerboseLevel : TVerboseLevel;
|
|
paraExtra : string;
|
|
ParaTargets : string;
|
|
ParaOutputFileName : string;
|
|
ParaRecursive : boolean;
|
|
ParaSkipPackageInfo : Boolean;
|
|
|
|
|
|
{*****************************************************************************
|
|
Helpers
|
|
*****************************************************************************}
|
|
|
|
procedure Show(lvl:TVerboseLevel;const s:string);
|
|
begin
|
|
if ParaVerboseLevel>=lvl then
|
|
Writeln(s);
|
|
end;
|
|
|
|
|
|
procedure Error(const s:string);
|
|
begin
|
|
Writeln('Error: ',s);
|
|
Halt(1);
|
|
end;
|
|
|
|
|
|
{*****************************************************************************
|
|
TFPCMakeConsole
|
|
*****************************************************************************}
|
|
|
|
procedure TFPCMakeConsole.Verbose(lvl:TFPCMakeVerbose;const s:string);
|
|
begin
|
|
case lvl of
|
|
FPCMakeInfo :
|
|
Show(V_Default,' '+VerboseIdent+s);
|
|
FPCMakeDebug :
|
|
Show(V_Verbose,' '+VerboseIdent+s);
|
|
FPCMakeError :
|
|
Error(s);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
{*****************************************************************************
|
|
Makefile output
|
|
*****************************************************************************}
|
|
|
|
procedure ProcessFile_Makefile(const fn:string; const aOutputfile : string; aextra: string);
|
|
var
|
|
CurrFPCMake : TFPCMakeConsole;
|
|
CurrMakefile : TMakefileWriter;
|
|
s,s2,Subdirs : string;
|
|
c : tcpu;
|
|
t : tos;
|
|
begin
|
|
Show(V_Default,'Processing '+fn);
|
|
CurrFPCMake:=nil;
|
|
{$ifndef NOEXCEPT}
|
|
try
|
|
{$endif NOEXCEPT}
|
|
{ Load Makefile.fpc }
|
|
CurrFPCMake:=TFPCMakeConsole.Create(fn);
|
|
CurrFPCMake.ExtraTargetsFile:=aExtra;
|
|
if ParaTargets<>'' then
|
|
CurrFPCMake.SetTargets(ParaTargets);
|
|
CurrFPCMake.LoadMakefileFPC;
|
|
// CurrFPCMake.Print;
|
|
|
|
{ Add the subdirs }
|
|
subdirs:='';
|
|
for c:=succ(low(tcpu)) to high(tcpu) do
|
|
for t:=succ(low(tos)) to high(tos) do
|
|
if CurrFPCMake.IncludeTargets[c,t] then
|
|
begin
|
|
s2:=CurrFPCMake.GetTargetVariable(c,t,'target_dirs',true);
|
|
repeat
|
|
s:=GetToken(s2,' ');
|
|
if s='' then
|
|
break;
|
|
AddTokenNoDup(subdirs,s,' ');
|
|
until false;
|
|
end;
|
|
for c:=succ(low(tcpu)) to high(tcpu) do
|
|
for t:=succ(low(tos)) to high(tos) do
|
|
if CurrFPCMake.IncludeTargets[c,t] then
|
|
begin
|
|
s2:=CurrFPCMake.GetTargetVariable(c,t,'target_exampledirs',true);
|
|
repeat
|
|
s:=GetToken(s2,' ');
|
|
if s='' then
|
|
break;
|
|
AddTokenNoDup(subdirs,s,' ');
|
|
until false;
|
|
end;
|
|
|
|
{ Write Makefile }
|
|
CurrMakefile:=TMakefileWriter.Create(CurrFPCMake,ExtractFilePath(fn)+aOutputFile);
|
|
CurrMakefile.SkipPackageInfo:=ParaSkipPackageInfo;
|
|
CurrMakefile.WriteGenericMakefile;
|
|
CurrMakefile.Free;
|
|
|
|
{$ifndef NOEXCEPT}
|
|
except
|
|
on e : exception do
|
|
begin
|
|
Error(e.message);
|
|
Subdirs:='';
|
|
end;
|
|
end;
|
|
{$endif NOEXCEPT}
|
|
CurrFPCMake.Free;
|
|
|
|
{ Process subdirs }
|
|
if (Subdirs<>'') and
|
|
ParaRecursive then
|
|
begin
|
|
Show(v_Verbose,'Subdirs found: '+subdirs);
|
|
repeat
|
|
s:=GetToken(subdirs,' ');
|
|
if s='' then
|
|
break;
|
|
ProcessFile_Makefile(ExtractFilePath(fn)+s+'/Makefile.fpc',aOutputFile, paraExtra);
|
|
until false;
|
|
end;
|
|
|
|
end;
|
|
|
|
{*****************************************************************************
|
|
Package.fpc output
|
|
*****************************************************************************}
|
|
|
|
procedure ProcessFile_PackageFpc(const fn:string; const aOutputFile : string; aExtra : String);
|
|
var
|
|
CurrFPCMake : TFPCMakeConsole;
|
|
CurrPackageFpc : TPackageFpcWriter;
|
|
begin
|
|
Show(V_Default,'Processing '+fn);
|
|
CurrFPCMake:=nil;
|
|
{$ifndef NOEXCEPT}
|
|
try
|
|
{$endif NOEXCEPT}
|
|
{ Load Makefile.fpc }
|
|
CurrFPCMake:=TFPCMakeConsole.Create(fn);
|
|
if ParaTargets<>'' then
|
|
CurrFPCMake.SetTargets(ParaTargets);
|
|
CurrFPCMake.ExtraTargetsFile:=aExtra;
|
|
CurrFPCMake.LoadMakefileFPC;
|
|
// CurrFPCMake.Print;
|
|
|
|
{ Write Package.fpc }
|
|
CurrPackageFpc:=TPackageFpcWriter.Create(CurrFPCMake,ExtractFilePath(fn)+aOutputFile);
|
|
CurrPackageFpc.WritePackageFpc;
|
|
CurrPackageFpc.Free;
|
|
|
|
{$ifndef NOEXCEPT}
|
|
except
|
|
on e : exception do
|
|
begin
|
|
Error(e.message);
|
|
end;
|
|
end;
|
|
{$endif NOEXCEPT}
|
|
CurrFPCMake.Free;
|
|
end;
|
|
|
|
|
|
procedure ProcessFile(const fn:string; const aOutputFile : string; const aExtra : string);
|
|
|
|
var
|
|
ofn : String;
|
|
|
|
begin
|
|
Show(V_Verbose,TitleDate);
|
|
case ParaMode of
|
|
m_None :
|
|
Error('No operation specified, see -h for help');
|
|
m_Makefile :
|
|
begin
|
|
ofn:=aOutputFile;
|
|
if ofn='' then
|
|
ofn:='Makefile';
|
|
ProcessFile_Makefile(fn,ofn,aExtra);
|
|
end;
|
|
m_PackageFpc :
|
|
begin
|
|
ofn:=aOutputFile;
|
|
if ofn='' then
|
|
ofn:='Package.fpc';
|
|
ProcessFile_PackageFpc(fn,ofn,aextra);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure UseMakefilefpc;
|
|
var
|
|
fn : string;
|
|
begin
|
|
if FileExists('Makefile.fpc') then
|
|
fn:='Makefile.fpc'
|
|
else
|
|
fn:='makefile.fpc';
|
|
ProcessFile(fn,ParaOutputFilename, paraExtra);
|
|
end;
|
|
|
|
|
|
procedure UseParameters;
|
|
var
|
|
i : integer;
|
|
begin
|
|
for i:=OptInd to ParamCount do
|
|
ProcessFile(ParamStr(i),ParaOutputFilename,ParaExtra);
|
|
end;
|
|
|
|
|
|
Procedure Usage;
|
|
{
|
|
Print usage and exit.
|
|
}
|
|
begin
|
|
writeln(paramstr(0),': <-pw> [-vqh] [file] [file ...]');
|
|
writeln('Operations:');
|
|
writeln(' -p Generate Package.fpc');
|
|
writeln(' -w Write Makefile');
|
|
writeln(' -V Print fpcmake version and exit');
|
|
writeln('');
|
|
writeln('Options:');
|
|
writeln(' -T<target>[,target] Support only specified targets. If "-Tall", all targets are');
|
|
writeln(' supported. If omitted only default target is supported');
|
|
writeln(' -r Recursively process target directories from Makefile.fpc');
|
|
writeln(' -v Be more verbose');
|
|
writeln(' -ooutputfile Use outputfile as filename instead of the default Makefile or Package.fpc');
|
|
writeln(' -s Skip writing package name');
|
|
writeln(' -q Be quiet');
|
|
writeln(' -h This help screen');
|
|
writeln(' -x file Read extra target definitions from file.');
|
|
Halt(0);
|
|
end;
|
|
|
|
|
|
procedure printVersion;
|
|
begin
|
|
writeln (TitleDate);
|
|
halt(0);
|
|
end;
|
|
|
|
|
|
Procedure ProcessOpts;
|
|
{
|
|
Process command line opions, and checks if command line options OK.
|
|
}
|
|
const
|
|
ShortOpts = 'pwqrvh?VsT:o:x:';
|
|
var
|
|
C : char;
|
|
begin
|
|
{ Reset }
|
|
ParaSkipPackageInfo:=False;
|
|
ParaMode:=m_Makefile;
|
|
ParaVerboseLevel:=v_default;
|
|
ParaTargets:=LowerCase({$I %FPCTARGETCPU})+'-'+LowerCase({$I %FPCTARGETOS});
|
|
{ Parse options }
|
|
repeat
|
|
c:=Getopt (ShortOpts);
|
|
Case C of
|
|
EndOfOptions : break;
|
|
'p' : ParaMode:=m_PackageFpc;
|
|
'w' : ParaMode:=m_Makefile;
|
|
'o' : ParaOutputFileName:=OptArg;
|
|
'q' : ParaVerboseLevel:=v_quiet;
|
|
'r' : ParaRecursive:=true;
|
|
's' : ParaSkipPackageInfo:=True;
|
|
'v' : ParaVerboseLevel:=v_verbose;
|
|
'T' : ParaTargets:=OptArg;
|
|
'x' : ParaExtra:=OptArg;
|
|
'?' : Usage;
|
|
'h' : Usage;
|
|
'V' : printVersion;
|
|
end;
|
|
until false;
|
|
end;
|
|
|
|
|
|
begin
|
|
ProcessOpts;
|
|
if (OptInd>Paramcount) then
|
|
UseMakefilefpc
|
|
else
|
|
UseParameters;
|
|
end.
|