123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907 |
- {
- Copyright (c) 2001 by Peter Vreman
- FPCMake - Makefile writer
- 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+}
- unit fpcmwr;
- interface
- uses
- sysutils,classes,
- fpcmmain;
- type
- tsections=(sec_none,
- sec_units,sec_exes,sec_loaders,sec_examples,sec_rsts,
- sec_compile,sec_install,
- sec_distinstall,sec_zipinstall,sec_clean,sec_shared,
- sec_command,sec_exts,sec_dirs,sec_tools,sec_info,sec_makefile,
- sec_fpmake
- );
- trules=(
- r_all,r_debug,r_smart,r_release,r_units,
- r_examples,
- r_shared,
- r_install,r_sourceinstall,r_exampleinstall,r_distinstall,
- r_zipinstall,r_zipsourceinstall,r_zipexampleinstall,r_zipdistinstall,
- r_clean,r_distclean,r_cleanall,
- r_info,r_makefiles
- );
- const
- rule2str : array[trules] of string=(
- 'all','debug','smart','release','units',
- 'examples',
- 'shared',
- 'install','sourceinstall','exampleinstall','distinstall',
- 'zipinstall','zipsourceinstall','zipexampleinstall','zipdistinstall',
- 'clean','distclean','cleanall',
- 'info','makefiles'
- );
- rule2sec : array[trules] of tsections=(
- sec_compile,sec_compile,sec_compile,sec_compile,sec_compile,
- sec_examples,
- sec_shared,
- sec_install,sec_install,sec_install,sec_distinstall,
- sec_zipinstall,sec_zipinstall,sec_zipinstall,sec_zipinstall,
- sec_clean,sec_clean,sec_clean,
- sec_info,sec_makefile
- );
- type
- { TMakefileWriter }
- TMakefileWriter=class
- private
- FFileName : string;
- FIni : TFPCMake;
- FInput : TFPCMake;
- FOutput : TStringList;
- FPhony : string;
- FHasSection : array[tsections] of boolean;
- FSkipPackageInfo: Boolean;
- procedure LoadFPCMakeIni;
- procedure AddIniSection(const s:string);
- procedure AddCustomSection(const s:string);
- procedure AddTargetVariable(const inivar:string);
- procedure AddVariable(const inivar:string);
- function AddTargetDefines(const inivar,prefix:string):string;
- procedure AddMainPackage(const pack:string);
- procedure AddRequiredPackages;
- procedure AddTool(const varname,exename,altexename:string);
- procedure AddTools(const inivar:string);
- procedure AddRules;
- procedure AddPhony(const s:string);
- procedure WritePhony;
- procedure AddTargetDirs(const inivar:string);
- procedure AddDefaultTools;
- procedure AddMakefileTargets;
- procedure OptimizeSections;
- public
- constructor Create(AFPCMake:TFPCMake;const AFileName:string);
- destructor Destroy;override;
- procedure WriteGenericMakefile;
- property SkipPackageInfo : Boolean Read FSkipPackageInfo Write FSkipPackageInfo;
- end;
- implementation
- {$i fpcmake.inc}
- type
- TMyMemoryStream=class(TMemoryStream)
- public
- constructor Create(p:pointer;mysize:integer);
- end;
- {*****************************************************************************
- Helpers
- *****************************************************************************}
- function FixVariable(s:string):string;
- var
- i : integer;
- begin
- Result:=UpperCase(s);
- i:=pos('.',Result);
- if i>0 then
- Result[i]:='_';
- end;
- function VarName(const s:string):string;
- var
- i,j : longint;
- begin
- i:=0;
- result:=s;
- while i<length(result) do
- begin
- inc(i);
- case result[i] of
- '{' :
- begin
- { this are pkgs which are hold the dirs between the accolades }
- j:=PosIdx('}',result,i);
- if j>0 then
- Delete(result,i,j-i+1)
- else
- Delete(result,i,1);
- dec(i);
- end;
- '$','(',')' :
- begin
- Delete(result,i,1);
- dec(i);
- end;
- 'a'..'z' :
- result[i]:=chr(ord(result[i])-32);
- end;
- end;
- end;
- procedure FixTab(sl:TStringList);
- var
- i,j,k : integer;
- s,s2 : string;
- begin
- i:=0;
- while (i<sl.Count) do
- begin
- if (sl[i]<>'') and (sl[i][1] in [' ',#9]) then
- begin
- s:=sl[i];
- k:=0;
- j:=0;
- repeat
- inc(j);
- case s[j] of
- ' ' :
- inc(k);
- #9 :
- k:=(k+7) and not(7);
- else
- break;
- end;
- until (j=length(s));
- if k>7 then
- begin
- s2:='';
- Delete(s,1,j-1);
- while (k>7) do
- begin
- s2:=s2+#9;
- dec(k,8);
- end;
- while (k>0) do
- begin
- s2:=s2+' ';
- dec(k);
- end;
- sl[i]:=s2+s;
- end;
- end;
- inc(i);
- end;
- end;
- {*****************************************************************************
- TMyMemoryStream
- *****************************************************************************}
- constructor TMyMemoryStream.Create(p:pointer;mysize:integer);
- begin
- inherited Create;
- SetPointer(p,mysize);
- end;
- {*****************************************************************************
- TMakefileWriter
- *****************************************************************************}
- constructor TMakefileWriter.Create(AFPCMake:TFPCMake;const AFileName:string);
- begin
- FInput:=AFPCMake;
- FFileName:=AFileName;
- FOutput:=TStringList.Create;
- FPhony:='';
- FillChar(FHasSection,sizeof(FHasSection),1);
- LoadFPCMakeIni;
- end;
- destructor TMakefileWriter.Destroy;
- begin
- FOutput.Free;
- FIni.Free;
- end;
- procedure TMakefileWriter.LoadFPCMakeIni;
- var
- IniStream : TStream;
- begin
- try
- IniStream:=TMyMemoryStream.Create(@fpcmakeini,sizeof(fpcmakeini));
- FIni:=TFPCMake.CreateFromStream(IniStream,'fpcmake.ini');
- { Leave the '#' comments in the output }
- // FIni.CommentChars:=[';'];
- FIni.LoadSections;
- finally
- IniStream.Destroy;
- end;
- end;
- procedure TMakefileWriter.AddIniSection(const s:string);
- var
- Sec : TFPCMakeSection;
- begin
- Sec:=TFPCMakeSection(FIni[s]);
- if assigned(Sec) then
- FOutput.AddStrings(Sec.List)
- else
- Raise Exception.Create(Format('Section "%s" doesn''t exists in fpcmake.ini',[s]));
- end;
- procedure TMakefileWriter.AddCustomSection(const s:string);
- var
- Sec : TFPCMakeSection;
- begin
- Sec:=TFPCMakeSection(FInput[s]);
- if assigned(Sec) then
- begin
- Sec.BuildMakefile;
- FOutput.AddStrings(Sec.List);
- end;
- end;
- procedure TMakefileWriter.AddTargetVariable(const inivar:string);
- var
- s : string;
- T : TOs;
- C : TCpu;
- begin
- for c:=succ(low(TCpu)) to high(TCpu) do
- for t:=succ(low(TOS)) to high(TOS) do
- if FInput.IncludeTargets[c,t] then
- begin
- s:=FInput.GetTargetVariable(c,t,IniVar,false);
- if s<>'' then
- begin
- FOutput.Add('ifeq ($(CPU_OS_TARGET),'+CPUStr[c]+'-'+OSStr[t]+')');
- FOutput.Add('override '+FixVariable(IniVar)+'+='+s);
- FOutput.Add('endif');
- end;
- end;
- end;
- procedure TMakefileWriter.AddVariable(const inivar:string);
- var
- s : string;
- begin
- s:=FInput.GetVariable(IniVar,false);
- if s<>'' then
- FOutput.Add('override '+FixVariable(IniVar)+'='+s)
- end;
- function TMakefileWriter.AddTargetDefines(const inivar,prefix:string):string;
- procedure addtokens(s:string);
- var
- name : string;
- k1,k2 : integer;
- begin
- repeat
- Name:=GetToken(s,' ');
- if Name='' then
- break;
- { Remove (..) }
- k1:=pos('(',name);
- if k1>0 then
- begin
- k2:=PosIdx(')',name,k1);
- if k2=0 then
- k2:=length(name)+1;
- Delete(Name,k1,k2);
- end;
- FOutput.Add(prefix+VarName(name)+'=1');
- { add to the list of dirs without duplicates }
- AddTokenNoDup(result,name,' ');
- until false;
- end;
- var
- s : string;
- T : TOs;
- C : TCpu;
- begin
- result:='';
- for c:=succ(low(TCpu)) to high(TCpu) do
- for t:=succ(low(TOS)) to high(TOS) do
- if FInput.IncludeTargets[c,t] then
- begin
- s:=FInput.GetTargetVariable(c,t,IniVar,false);
- if s<>'' then
- begin
- FOutput.Add('ifeq ($(CPU_OS_TARGET),'+CpuStr[c]+'-'+OSStr[t]+')');
- AddTokens(s);
- FOutput.Add('endif');
- end;
- end;
- end;
- procedure TMakefileWriter.AddTool(const varname,exename,altexename:string);
- begin
- with FOutput do
- begin
- Add('ifndef '+varname);
- Add(varname+':=$(strip $(wildcard $(addsuffix /'+exename+'$(SRCEXEEXT),$(SEARCHPATH))))');
- if altexename<>'' then
- begin
- Add('ifeq ($('+varname+'),)');
- Add(varname+':=$(strip $(wildcard $(addsuffix /'+altexename+'$(SRCEXEEXT),$(SEARCHPATH))))');
- end;
- Add('ifeq ($('+varname+'),)');
- Add(varname+'= __missing_command_'+varname); {This is to be shure make stops,
- if the command is not found. Otherwise if the command was set to the
- empty string, options to the command would be interpreted as command,
- and because options is preceeded by a "-", make will ignore the error
- that the command is not found.}
- Add('else');
- Add(varname+':=$(firstword $('+varname+'))');
- Add('endif');
- if altexename<>'' then
- begin
- Add('else');
- Add(varname+':=$(firstword $('+varname+'))');
- Add('endif');
- end;
- Add('endif');
- Add('export '+varname);
- end;
- end;
- procedure TMakefileWriter.AddTools(const inivar:string);
- var
- hs,tool : string;
- begin
- hs:=FInput.GetVariable(inivar,false);
- repeat
- Tool:=GetToken(hs,' ');
- if Tool='' then
- break;
- AddTool(FixVariable(Tool),Tool,'');
- until false;
- end;
- procedure TMakefileWriter.AddRules;
- procedure AddRule(rule:trules);
- var
- i : integer;
- hs : string;
- Sec : TFPCMakeSection;
- Rules : TStringList;
- begin
- Sec:=TFPCMakeSection(FInput['rules']);
- if assigned(Sec) then
- begin
- Rules:=Sec.List;
- for i:=0 to Rules.Count-1 do
- begin
- if (length(rules[i])>length(rule2str[rule])) and
- (rules[i][1]=rule2str[rule][1]) and
- ((rules[i][length(rule2str[rule])+1]=':') or
- ((length(rules[i])>length(rule2str[rule])+1) and
- (rules[i][length(rule2str[rule])+2]=':'))) and
- (Copy(rules[i],1,length(rule2str[rule]))=rule2str[rule]) then
- exit;
- end;
- end;
- hs:='';
- if FHasSection[Rule2Sec[rule]] then
- hs:=hs+' fpc_'+rule2str[rule];
- { include target dirs, but not for info and targets that
- call other targets with a only extra settings, if the
- section was not included, then still process the targets }
- if FInput.HasTargetVariable('target_dirs') and
- (not(rule in [r_info,r_shared,r_smart,r_debug,r_release,r_zipdistinstall,r_distinstall]) or
- not FHasSection[Rule2Sec[rule]]) then
- begin
- if FInput.HasVariable('default_dir') then
- hs:=hs+' $(addsuffix _'+rule2str[rule]+',$(DEFAULT_DIR))'
- else
- if not(rule in [r_sourceinstall,r_zipinstall,r_zipsourceinstall,
- r_makefiles]) or
- not(FInput.HasVariable('package_name')) then
- hs:=hs+' $(addsuffix _'+rule2str[rule]+',$(TARGET_DIRS))';
- end;
- { include cleaning of example dirs }
- if (rule=r_clean) and
- FInput.HasTargetVariable('target_exampledirs') then
- hs:=hs+' $(addsuffix _'+rule2str[rule]+',$(TARGET_EXAMPLEDIRS))';
- { Add the rule }
- AddPhony(Rule2Str[Rule]);
- FOutput.Add(rule2str[rule]+':'+hs);
- end;
- var
- rule : trules;
- begin
- for rule:=low(trules) to high(trules) do
- AddRule(rule);
- WritePhony;
- end;
- procedure TMakefileWriter.AddPhony(const s:string);
- begin
- FPhony:=FPhony+' '+s;
- end;
- procedure TMakefileWriter.WritePhony;
- begin
- if FPhony<>'' then
- begin
- FOutput.Add('.PHONY:'+FPhony);
- FPhony:='';
- end;
- end;
- procedure TMakefileWriter.AddTargetDirs(const inivar:string);
- procedure AddTargetDir(const s,defpref:string);
- var
- j : trules;
- begin
- FOutput.Add('ifdef '+defpref+VarName(s));
- for j:=low(trules) to high(trules) do
- begin
- FOutput.Add(s+'_'+rule2str[j]+':');
- FOutput.Add(#9+'$(MAKE) -C '+s+' '+rule2str[j]);
- AddPhony(s+'_'+rule2str[j]);
- end;
- FOutput.Add(s+':');
- FOutput.Add(#9+'$(MAKE) -C '+s+' all');
- AddPhony(s);
- WritePhony;
- FOutput.Add('endif');
- end;
- var
- hs,dir : string;
- prefix : string;
- begin
- prefix:=FixVariable(inivar)+'_';
- hs:=AddTargetDefines(inivar,prefix);
- repeat
- Dir:=GetToken(hs,' ');
- if Dir='' then
- break;
- AddTargetDir(Dir,prefix);
- until false;
- end;
- procedure TMakefileWriter.AddMainPackage(const pack:string);
- var
- packdirvar : string;
- begin
- { create needed variables }
- packdirvar:='PACKAGEDIR_MAIN';
- { Search packagedir by looking for Makefile.fpc }
- FOutput.Add(packdirvar+':=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /'+pack+'/Makefile.fpc,$(PACKAGESDIR))))))');
- end;
- procedure TMakefileWriter.AddRequiredPackages;
- procedure AddPackage(const pack,prefix:string);
- var
- packdirvar,unitdirvar,unitfpmakedirvar : string;
- fpcmadedirvar : string;
- begin
- FOutput.Add('ifdef '+Prefix+VarName(pack));
- { create needed variables }
- packdirvar:='PACKAGEDIR_'+VarName(pack);
- unitdirvar:='UNITDIR_'+VarName(pack);
- unitfpmakedirvar:='UNITDIR_FPMAKE_'+VarName(pack);
- { Search packagedir by looking for Makefile.fpc }
- FOutput.Add(packdirvar+':=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /'+pack+'/Makefile.fpc,$(PACKAGESDIR))))))');
- { Packages may no longer have a Makefile.fpc . Check existance of Makefile + fpmake.pp to be sure }
- FOutput.Add('ifeq ($('+packdirvar+'),)');
- FOutput.Add(packdirvar+':=$(firstword $(subst /Makefile,,$(strip $(wildcard $(addsuffix /'+pack+'/Makefile,$(PACKAGESDIR))))))');
- FOutput.Add('ifneq ($('+packdirvar+'),)');
- FOutput.Add(packdirvar+':=$(firstword $(subst /fpmake.pp,,$(strip $(wildcard $(addsuffix /'+pack+'/fpmake.pp,$(PACKAGESDIR))))))');
- FOutput.Add('endif');
- FOutput.Add('endif');
- FOutput.Add('ifneq ($('+packdirvar+'),)');
- { Create unit dir, check if os dependent dir exists }
- FOutput.Add('ifneq ($(wildcard $('+packdirvar+')/units/$(TARGETSUFFIX)),)');
- FOutput.Add(unitdirvar+'=$('+packdirvar+')/units/$(TARGETSUFFIX)');
- FOutput.Add('else');
- FOutput.Add(unitdirvar+'=$('+packdirvar+')');
- FOutput.Add('endif');
- FOutput.Add('ifneq ($(wildcard $('+packdirvar+')/units/$(SOURCESUFFIX)),)');
- FOutput.Add(unitfpmakedirvar+'=$('+packdirvar+')/units/$(SOURCESUFFIX)');
- FOutput.Add('else');
- FOutput.Add('ifneq ($(wildcard $('+packdirvar+')/units_bs/$(SOURCESUFFIX)),)');
- FOutput.Add(unitfpmakedirvar+'=$('+packdirvar+')/units_bs/$(SOURCESUFFIX)');
- FOutput.Add('else');
- FOutput.Add(unitfpmakedirvar+'=$('+packdirvar+')');
- FOutput.Add('endif');
- FOutput.Add('endif');
- FOutput.Add('ifdef CHECKDEPEND');
- { rtl needs special handling for FPCMADE }
- if pack='rtl' then
- fpcmadedirvar:='/$(OS_TARGET)'
- else
- fpcmadedirvar:='';
- FOutput.Add('$('+packdirvar+')'+fpcmadedirvar+'/$(FPCMADE):');
- FOutput.Add(#9'$(MAKE) -C $('+packdirvar+')'+fpcmadedirvar+' $(FPCMADE)');
- FOutput.Add('override ALLDEPENDENCIES+=$('+packdirvar+')'+fpcmadedirvar+'/$(FPCMADE)');
- FOutput.Add('endif');
- { Package dir doesn't exists, check unit dir }
- FOutput.Add('else');
- FOutput.Add(packdirvar+'=');
- FOutput.Add(unitdirvar+':=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /'+pack+'/Package.fpc,$(UNITSDIR)))))');
- FOutput.Add('ifneq ($('+unitdirvar+'),)');
- FOutput.Add(unitdirvar+':=$(firstword $('+unitdirvar+'))');
- FOutput.Add('else');
- FOutput.Add(unitdirvar+'=');
- FOutput.Add('endif');
- FOutput.Add('endif');
- { Add Unit dir to the command line -Fu }
- FOutput.Add('ifdef '+unitdirvar);
- FOutput.Add('override COMPILER_UNITDIR+=$('+unitdirvar+')');
- FOutput.Add('endif');
- FOutput.Add('ifdef '+unitfpmakedirvar);
- FOutput.Add('override COMPILER_FPMAKE_UNITDIR+=$('+unitfpmakedirvar+')');
- FOutput.Add('endif');
- { endif for package }
- FOutput.Add('endif');
- end;
- var
- i : integer;
- reqs,req,prefix : string;
- t : TOS;
- c : TCpu;
- sl : TStringList;
- begin
- prefix:='REQUIRE_PACKAGES_';
- reqs:='';
- { Add target defines }
- for c:=succ(low(tcpu)) to high(tcpu) do
- for t:=succ(low(tos)) to high(tos) do
- if FInput.IncludeTargets[c,t] then
- begin
- sl:=FInput.GetTargetRequires(c,t);
- { show info }
- FInput.Verbose(FPCMakeInfo,CpuStr[c]+'-'+OSStr[t]+' requires: '+sl.CommaText);
- if sl.count>0 then
- begin
- FOutput.Add('ifeq ($(CPU_OS_TARGET),'+CPUStr[c]+'-'+OSStr[t]+')');
- for i:=0 to sl.count-1 do
- begin
- FOutput.Add(prefix+VarName(sl[i])+'=1');
- AddTokenNoDup(reqs,sl[i],' ');
- end;
- FOutput.Add('endif');
- end;
- sl.Free;
- end;
- { Add all require packages }
- repeat
- req:=GetToken(reqs,' ');
- if Req='' then
- break;
- AddPackage(req,prefix);
- until false;
- WritePhony;
- end;
- procedure TMakefileWriter.AddDefaultTools;
- begin
- AddTool('ECHO','gecho','echo');
- AddTool('DATE','gdate','date');
- AddTool('GINSTALL','ginstall','install');
- AddTool('CPPROG','cp','');
- AddTool('RMPROG','rm','');
- AddTool('MVPROG','mv','');
- AddTool('MKDIRPROG','gmkdir','mkdir');
- AddIniSection('shelltools');
- AddTool('PPUMOVE','ppumove','');
- AddTool('FPCMAKE','fpcmake','');
- AddTool('ZIPPROG','zip','');
- AddTool('TARPROG','gtar','tar');
- AddIniSection('defaulttools');
- end;
- procedure TMakefileWriter.AddMakefileTargets;
- var
- s : string;
- c : TCpu;
- t : Tos;
- begin
- s:='';
- for c:=succ(low(tcpu)) to high(tcpu) do
- for t:=succ(low(tos)) to high(tos) do
- if FInput.IncludeTargets[c,t] then
- AddToken(s,CpuStr[c]+'-'+OSStr[t],' ');
- FOutput.Add('MAKEFILETARGETS='+s);
- end;
- procedure TMakefileWriter.OptimizeSections;
- var
- SkippedSecs :integer;
- begin
- { Turn some sections off, depending if files are
- provided }
- if not FInput.IsPackage then
- begin
- FHasSection[sec_zipinstall]:=false;
- FHasSection[sec_distinstall]:=false;
- end;
- { Remove unused sections for targets }
- SkippedSecs:=0;
- if (not FInput.HasTargetVariable('target_units')) and (not FInput.HasTargetVariable('target_implicitunits')) then
- begin
- inc(SkippedSecs);
- FHasSection[sec_units]:=false;
- end;
- if (not FInput.HasTargetVariable('target_programs')) then
- begin
- inc(SkippedSecs);
- FHasSection[sec_exes]:=false;
- end;
- if (not FInput.HasTargetVariable('target_examples')) then
- begin
- inc(SkippedSecs);
- { example dirs also requires the fpc_examples target, because
- it also depends on the all target }
- if (not FInput.HasTargetVariable('target_exampledirs')) then
- FHasSection[sec_examples]:=false;
- end;
- if (not FInput.HasTargetVariable('target_loaders')) then
- begin
- inc(SkippedSecs);
- FHasSection[sec_loaders]:=false;
- end;
- if (not FInput.HasTargetVariable('target_fpmake')) then
- begin
- inc(SkippedSecs);
- FHasSection[sec_fpmake]:=false;
- end;
- { if all 5 sections are not available we can skip also the
- generic compile rules }
- if SkippedSecs=5 then
- begin
- FHasSection[sec_shared]:=false;
- FHasSection[sec_compile]:=false;
- if (not FInput.HasTargetVariable('package_name')) and
- (not FInput.HasTargetVariable('install_units')) and
- (not FInput.HasTargetVariable('install_files')) and
- (not FInput.HasTargetVariable('install_createpackagefpc')) then
- FHasSection[sec_install]:=false;
- { Package.fpc also needs to be cleaned }
- if (not FInput.HasTargetVariable('clean_units')) and
- (not FInput.HasTargetVariable('clean_files')) and
- (not FInput.HasTargetVariable('install_createpackagefpc')) then
- FHasSection[sec_clean]:=false;
- end;
- end;
- procedure TMakefileWriter.WriteGenericMakefile;
- begin
- { Remove unused sections }
- OptimizeSections;
- { Generate Output }
- with FOutput do
- begin
- { Header }
- Add('#');
- Add('# Don''t edit, this file is generated by '+TitleNoDate);
- Add('#');
- if FInput.HasVariable('default_rule') then
- Add('default: '+FInput.GetVariable('default_rule',false))
- else
- Add('default: all');
- { Supported targets by this Makefile }
- AddMakefileTargets;
- { Add misc defines }
- AddIniSection('defines');
- { Add automatic detect sections }
- AddIniSection('osdetect');
- { Forced target }
- if FInput.HasVariable('require_target') then
- Add('override OS_TARGET='+FInput.GetVariable('require_target',false))
- else if FInput.HasVariable('default_target') then
- Add('override OS_TARGET_DEFAULT='+FInput.GetVariable('default_target',false));
- if FInput.HasVariable('require_cpu') then
- Add('override CPU_TARGET='+FInput.GetVariable('require_cpu',false))
- else if FInput.HasVariable('default_cpu') then
- Add('override CPU_TARGET_DEFAULT='+FInput.GetVariable('default_cpu',false));
- { FPC Detection }
- AddVariable('default_fpcdir');
- AddIniSection('fpcdetect');
- AddIniSection('fpcdircheckenv');
- AddIniSection('fpcdirdetect');
- AddIniSection('fpmakefpcdetect');
- { Package info }
- if not SkipPackageInfo then
- AddVariable('package_name');
- AddVariable('package_version');
- AddVariable('package_targets');
- { Directory of main package }
- if FInput.HasVariable('package_main') then
- AddMainPackage(FInput.GetVariable('package_main',false));
- { LCL rules }
- if FInput.UsesLCL then
- begin
- AddVariable('default_lcldir');
- AddVariable('lcl_platform');
- AddIniSection('lclrules');
- end;
- { First add the required packages sections }
- // for i:=0 to FInput.RequireList.Count-1 do
- // AddCustomSection(FInput.Requirelist[i]);
- { prerules section }
- if assigned(FInput['prerules']) then
- AddStrings(TFPCMakeSection(FInput['prerules']).List);
- if FHasSection[sec_fpmake] then
- AddIniSection('fpmakeprerules');
- { Default }
- AddVariable('default_dir');
- { Targets }
- AddTargetVariable('target_dirs');
- AddTargetVariable('target_programs');
- AddTargetVariable('target_units');
- AddTargetVariable('target_implicitunits');
- AddTargetVariable('target_loaders');
- AddTargetVariable('target_rsts');
- AddTargetVariable('target_examples');
- AddTargetVariable('target_exampledirs');
- AddTargetVariable('target_fpmake');
- { Clean }
- AddTargetVariable('clean_units');
- AddTargetVariable('clean_files');
- AddTargetVariable('clean_programs');
- { Install }
- AddTargetVariable('install_units');
- AddTargetVariable('install_files');
- AddVariable('install_buildunit');
- AddVariable('install_prefix');
- AddVariable('install_basedir');
- AddVariable('install_datadir');
- AddVariable('install_fpcpackage');
- AddVariable('install_fpcsubdir');
- AddVariable('install_createpackagefpc');
- { Dist }
- AddVariable('dist_destdir');
- AddVariable('dist_zipname');
- AddVariable('dist_ziptarget');
- { Compiler }
- AddTargetVariable('compiler_options');
- AddTargetVariable('compiler_version');
- AddTargetVariable('compiler_includedir');
- AddTargetVariable('compiler_unitdir');
- AddTargetVariable('compiler_sourcedir');
- AddTargetVariable('compiler_objectdir');
- AddTargetVariable('compiler_librarydir');
- AddTargetVariable('compiler_targetdir');
- AddTargetVariable('compiler_unittargetdir');
- { shared }
- AddVariable('shared_build');
- AddVariable('shared_libname');
- AddVariable('shared_libversion');
- AddVariable('shared_libunits');
- AddVariable('shared_build');
- { default Dirs and extensions }
- AddIniSection('defaultdirs');
- if FInput.CheckLibcRequire then
- AddIniSection('dirlibc');
- AddIniSection('extensions');
- { Add default tools }
- AddDefaultTools;
- { Required packages }
- AddVariable('require_packages');
- AddRequiredPackages;
- { commandline }
- AddIniSection('command_begin');
- if FInput.CheckLibcRequire then
- AddIniSection('command_libc');
- AddIniSection('command_end');
- { compile }
- if FHasSection[sec_fpmake] then
- AddIniSection('fpmakerules');
- if FHasSection[sec_loaders] then
- AddIniSection('loaderrules');
- if FHasSection[sec_units] then
- AddIniSection('unitrules');
- if FHasSection[sec_exes] then
- AddIniSection('exerules');
- if FHasSection[sec_rsts] then
- AddIniSection('rstrules');
- if FHasSection[sec_examples] then
- AddIniSection('examplerules');
- if FHasSection[sec_compile] then
- AddIniSection('compilerules');
- if FHasSection[sec_shared] then
- AddIniSection('sharedrules');
- { install }
- if FHasSection[sec_install] then
- AddIniSection('installrules');
- if FHasSection[sec_distinstall] then
- AddIniSection('distinstallrules');
- if FHasSection[sec_zipinstall] then
- AddIniSection('zipinstallrules');
- { clean }
- AddIniSection('cleanrules');
- { info }
- AddIniSection('baseinforules');
- if FInput.UsesLCL then
- AddIniSection('lclinforules');
- AddIniSection('inforules');
- { info }
- AddIniSection('makefilerules');
- { Subdirs }
- AddTargetDirs('target_dirs');
- AddTargetDirs('target_exampledirs');
- { Tools }
- AddTools('require_tools');
- { Rules }
- AddRules;
- { Users own rules }
- AddIniSection('localmakefile');
- AddIniSection('userrules');
- if assigned(FInput['rules']) then
- AddStrings(TFPCMakeSection(FInput['rules']).List);
- end;
- { write to disk }
- FInput.Verbose(FPCMakeInfo,'Writing '+FFileName);
- Fixtab(FOutput);
- FOutput.SaveToFile(FFileName);
- end;
- end.
|