123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318 |
- {
- This file is part of the Free Pascal Makefile Package
- Implementation of fpmake classes and functions
- Copyright (c) 2007 by the freepascal team
- 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.
- **********************************************************************}
- unit fpmkunit;
- {$Mode objfpc}
- {$H+}
- {$inline on}
- { For target or cpu dependent dependencies add also an overload were you
- can pass only a set of cpus. This is disabled for now because it creates
- an error in the compiler with overload choosing }
- { define cpu_only_overloads}
- Interface
- {$IFDEF OS2}
- {$DEFINE NO_UNIT_PROCESS}
- {$ENDIF OS2}
- {$IFDEF GO32V2}
- {$DEFINE NO_UNIT_PROCESS}
- {$ENDIF GO32V2}
- {$ifndef NO_UNIT_PROCESS}
- {$define HAS_UNIT_PROCESS}
- {$endif NO_UNIT_PROCESS}
- {$ifndef NO_UNIT_ZIPPER}
- {$define HAS_UNIT_ZIPPER}
- {$endif NO_UNIT_ZIPPER}
- uses
- SysUtils, Classes, StrUtils
- {$ifdef HAS_UNIT_PROCESS}
- ,process
- {$endif HAS_UNIT_PROCESS}
- {$ifdef HAS_UNIT_ZIPPER}
- ,zipper
- {$endif HAS_UNIT_ZIPPER}
- ;
- Type
- TFileType = (ftSource,ftUnit,ftObject,ftResource,ftExecutable,ftStaticLibrary,
- ftSharedLibrary);
- TFileTypes = set of TFileType;
- // Please keep this order, see OSCPUSupported below
- TCpu=(cpuNone,
- i386,m68k,powerpc,sparc,x86_64,arm,powerpc64,avr,armeb
- );
- TCPUS = Set of TCPU;
- // Please keep this order, see OSCPUSupported below
- TOS=(osNone,
- linux,go32v2,win32,os2,freebsd,beos,netbsd,
- amiga,atari, solaris, qnx, netware, openbsd,wdosx,
- palmos,macos,darwin,emx,watcom,morphos,netwlibc,
- win64,wince,gba,nds,embedded,symbian,haiku,iphonesim
- );
- TOSes = Set of TOS;
- TCompilerMode = (cmFPC,cmTP,cmObjFPC,cmDelphi,cmMacPas);
- TCompilerModes = Set of TCompilerMode;
- TTargetType = (ttProgram,ttUnit,ttImplicitUnit,ttCleanOnlyUnit,ttExampleUnit,ttExampleProgram,ttFPDoc);
- TTargetTypes = set of TTargetType;
- TFPDocFormat = (ffHtml, ffHtm, ffXHtml, ffLaTex, ffXMLStruct, ffChm);
- TFPDocFormats = set of TFPDocFormat;
- TTargetState = (tsNeutral,tsConsidering,tsNoCompile,tsCompiled,tsInstalled,tsNotFound);
- TTargetStates = Set of TTargetState;
- TSourceType = (stDoc,stSrc,stExample,stTest);
- TSourceTypes = set of TSourceType;
- TVerboseLevel = (vlError,vlWarning,vlInfo,vldebug,vlCommand);
- TVerboseLevels = Set of TVerboseLevel;
- TCommandAt = (caBeforeCompile,caAfterCompile,
- caBeforeInstall,caAfterInstall,
- caBeforeArchive,caAfterArchive,
- caBeforeClean,caAfterClean,
- caBeforeDownload,caAfterDownload);
- TDependencyType = (depPackage,depImplicitPackage,depUnit,depInclude);
- TDependencyTypes = set of TDependencyType;
- TLogEvent = Procedure (Level : TVerboseLevel; Const Msg : String) of Object;
- TNotifyProcEvent = procedure(Sender: TObject);
- TRunMode = (rmCompile,rmBuild,rmInstall,rmArchive,rmClean,rmDistClean,rmManifest);
- TBuildMode = (bmOneByOne, bmBuildUnit{, bmSkipImplicitUnits});
- TBuildModes = set of TBuildMode;
- Const
- // Aliases
- Amd64 = X86_64;
- PPC = PowerPC;
- PPC64 = PowerPC64;
- DOS = Go32v2;
- MacOSX = Darwin;
- AllOSes = [Low(TOS)..High(TOS)];
- AllCPUs = [Low(TCPU)..High(TCPU)];
- AllUnixOSes = [Linux,FreeBSD,NetBSD,OpenBSD,Darwin,QNX,BeOS,Solaris,Haiku,iphonesim];
- AllBSDOSes = [FreeBSD,NetBSD,OpenBSD,Darwin,iphonesim];
- AllWindowsOSes = [Win32,Win64,WinCE];
- AllLimit83fsOses= [go32v2,os2,emx,watcom];
- AllSmartLinkLibraryOSes = [Linux]; // OSes that use .a library files for smart-linking
- { This table is kept OS,Cpu because it is easier to maintain (PFV) }
- OSCPUSupported : array[TOS,TCpu] of boolean = (
- { os none i386 m68k ppc sparc x86_64 arm ppc64 avr armeb}
- { none } ( false, false, false, false, false, false, false, false, false, false),
- { linux } ( false, true, true, true, true, true, true, true, false, true ),
- { go32v2 } ( false, true, false, false, false, false, false, false, false, false),
- { win32 } ( false, true, false, false, false, false, false, false, false, false),
- { os2 } ( false, true, false, false, false, false, false, false, false, false),
- { freebsd } ( false, true, true, false, false, true, false, false, false, false),
- { beos } ( false, true, false, false, false, false, false, false, false, false),
- { netbsd } ( false, true, true, true, true, false, false, false, false, false),
- { amiga } ( false, false, true, true, false, false, false, false, false, false),
- { atari } ( false, false, true, false, false, false, false, false, false, false),
- { solaris } ( false, true, false, false, true, false, false, false, false, false),
- { qnx } ( false, true, false, false, false, false, false, false, false, false),
- { netware } ( false, true, false, false, false, false, false, false, false, false),
- { openbsd } ( false, true, true, false, false, false, false, false, false, false),
- { wdosx } ( false, true, false, false, false, false, false, false, false, false),
- { palmos } ( false, false, true, false, false, false, true, false, false, false),
- { macos } ( false, false, false, true, false, false, false, false, false, false),
- { darwin } ( false, true, false, true, false, true, true, true, false, false),
- { emx } ( false, true, false, false, false, false, false, false, false, false),
- { watcom } ( false, true, false, false, false ,false, false, false, false, false),
- { morphos } ( false, false, false, true, false ,false, false, false, false, false),
- { netwlibc }( false, true, false, false, false, false, false, false, false, false),
- { win64 } ( false, false, false, false, false, true, false, false, false, false),
- { wince }( false, true, false, false, false, false, true, false, false, false),
- { gba } ( false, false, false, false, false, false, true, false, false, false),
- { nds } ( false, false, false, false, false, false, true, false, false, false),
- { embedded }( false, true, true, true, true, true, true, true, true, true ),
- { symbian } ( false, true, false, false, false, false, true, false, false, false),
- { haiku } ( false, true, false, false, false, false, false, false, false, false),
- { iphonesim}( false, true, false, false, false, false, false, false, false, false)
- );
- // Useful
- UnitExt = '.ppu';
- PPUExt = UnitExt;
- PasExt = '.pas';
- PPExt = '.pp';
- IncExt = '.inc';
- ObjExt = '.o';
- RstExt = '.rst';
- LibExt = '.a';
- SharedLibExt = '.so';
- DLLExt = '.dll';
- ExeExt = '.exe';
- ZipExt = '.zip';
- FPMakePPFile = 'fpmake.pp';
- ManifestFile = 'manifest.xml';
- UnitConfigFile = 'fpunits.conf';
- DirNotFound = '<dirnotfound>';
- UnitTargets = [ttUnit,ttImplicitUnit,ttCleanOnlyUnit,ttExampleUnit];
- ProgramTargets = [ttProgram,ttExampleProgram];
- DefaultMessages = [vlError,vlWarning,vlCommand];
- AllMessages = [vlError,vlWarning,vlCommand,vlInfo];
- Type
- { TNamedItem }
- TNamedItem = Class(TCollectionItem)
- private
- FName: String;
- procedure SetName(const AValue: String);virtual;
- Public
- property Name : String Read FName Write SetName;
- end;
- { TNamedCollection }
- TNamedCollection = Class(TCollection)
- private
- FUniqueNames: Boolean;
- Public
- Function IndexOfName(const AName : String) : Integer;
- Function ItemByName(const AName : String) : TNamedItem;
- Property UniqueNames : Boolean Read FUniqueNames;
- end;
- { TNamedItemList }
- TNamedItemList = Class(TFPList)
- private
- function GetNamedItem(Index : Integer): TNamedItem;
- procedure SetNamedItem(Index : Integer; const AValue: TNamedItem);
- public
- Function IndexOfName(const AName : String) : Integer;
- Function ItemByName(const ANAme : String) : TNamedItem;
- Property NamedItems[Index : Integer] : TNamedItem Read GetNamedItem Write SetNamedItem; default;
- end;
- { TCommand }
- TCommand = Class(TNamedItem)
- private
- FAfterCommand: TNotifyEvent;
- FBeforeCommand: TNotifyEvent;
- FCommand: String;
- FCommandAt: TCommandAt;
- FDestFile: String;
- FIgnoreResult: Boolean;
- FOptions: TStrings;
- FSourceFile: String;
- Function GetOptions : TStrings;
- Procedure SetOptions(Const Value : TStrings);
- Public
- Destructor Destroy; override;
- Function HaveOptions : Boolean;
- Function CmdLineOptions : String;
- Procedure ParseOptions(S : String);
- Property SourceFile : String Read FSourceFile Write FSourceFile;
- Property DestFile : String Read FDestFile Write FDestFile;
- Property Command : String Read FCommand Write FCommand;
- Property Options : TStrings Read GetOptions Write SetOptions;
- Property At : TCommandAt Read FCommandAt Write FCommandAt;
- Property IgnoreResult : Boolean Read FIgnoreResult Write FIgnoreResult;
- Property BeforeCommand : TNotifyEvent Read FBeforeCommand Write FBeforeCommand;
- Property AfterCommand : TNotifyEvent Read FAfterCommand Write FAfterCommand;
- end;
- { TCommands }
- TCommands = Class(TNamedCollection)
- private
- FDefaultAt: TCommandAt;
- function GetCommand(const Dest : String): TCommand;
- function GetCommandItem(Index : Integer): TCommand;
- procedure SetCommandItem(Index : Integer; const AValue: TCommand);
- Public
- Function AddCommand(Const Cmd : String) : TCommand;
- Function AddCommand(Const Cmd,Options : String) : TCommand;
- Function AddCommand(Const Cmd,Options,Dest,Source : String) : TCommand;
- Function AddCommand(At : TCommandAt; Const Cmd : String) : TCommand;
- Function AddCommand(At : TCommandAt; Const Cmd,Options : String) : TCommand;
- Function AddCommand(At : TCommandAt; Const Cmd,Options, Dest,Source : String) : TCommand;
- Property CommandItems[Index : Integer] : TCommand Read GetCommandItem Write SetCommandItem;
- Property Commands[Dest : String] : TCommand Read GetCommand; default;
- Property DefaultAt : TCommandAt Read FDefaultAt Write FDefaultAt;
- end;
- { TFPVersion }
- TFPVersion = Class(TPersistent)
- private
- FMajor,
- FMinor,
- FMicro,
- FBuild : Integer;
- function GetAsString: String;
- function GetEmpty: Boolean;
- procedure SetAsString(const AValue: String);
- Public
- Procedure Clear;
- Procedure Assign(Source : TPersistent); override;
- Function CompareVersion(AVersion : TFPVersion) : Integer;
- Function SameVersion(AVersion : TFPVersion) : Boolean;
- Property AsString : String Read GetAsString Write SetAsString;
- Property Empty : Boolean Read GetEmpty;
- Published
- Property Major : Integer Read FMajor Write FMajor;
- Property Minor : Integer Read FMinor Write FMinor;
- Property Micro : Integer Read FMicro Write FMicro;
- Property Build : Integer Read FBuild Write FBuild;
- end;
- { TConditionalString }
- TConditionalString = Class
- private
- FOSes : TOSes;
- FCPUs : TCPUs;
- FValue : String;
- Public
- Constructor Create;virtual;
- Property Value : String Read FValue Write FValue;
- Property OSes : TOSes Read FOSes Write FOSes;
- Property CPUs : TCPUs Read FCPUS Write FCPUs;
- end;
- TConditionalStringClass = class of TConditionalString;
- { TConditionalStrings }
- TConditionalStrings = Class(TFPList)
- private
- FCSClass : TConditionalStringClass;
- function GetConditionalString(Index : Integer): TConditionalString;
- procedure SetConditionalString(Index : Integer; const AValue: TConditionalString);
- Public
- Constructor Create(AClass:TConditionalStringClass);
- Function Add(Const Value : String) : TConditionalString;inline;
- Function Add(Const Value : String;const OSes:TOSes) : TConditionalString;inline;
- {$ifdef cpu_only_overloads}
- Function Add(Const Value : String;const CPUs:TCPUs) : TConditionalString;inline;
- {$endif cpu_only_overloads}
- Function Add(Const Value : String;const CPUs:TCPUs;const OSes:TOSes) : TConditionalString;
- Property ConditionalStrings[Index : Integer] : TConditionalString Read GetConditionalString Write SetConditionalString; default;
- end;
- { TDependency }
- TDependency = Class(TConditionalString)
- private
- FDependencyType : TDependencyType;
- // Package, Unit
- FTarget : TObject;
- FVersion : TFPVersion;
- FRequireChecksum : Cardinal;
- // Filenames, Includes
- FTargetFileName : String;
- Function GetVersion : string;
- Procedure SetVersion(const V : string);
- Public
- Constructor Create;override;
- Destructor Destroy;override;
- Property Target : TObject Read FTarget Write FTarget;
- Property DependencyType : TDependencyType Read FDependencyType;
- Property TargetFileName : String Read FTargetFileName Write FTargetFileName;
- Property Version : String Read GetVersion Write SetVersion;
- Property RequireChecksum : Cardinal Read FRequireChecksum Write FRequireChecksum;
- end;
- TDependencies = Class(TConditionalStrings)
- function GetDependency(Index : Integer): TDependency;
- procedure SetDependency(Index : Integer; const AValue: TDependency);
- Public
- Function Add(Const Value : String) : TDependency;inline;
- Function Add(Const Value : String;const OSes:TOSes) : TDependency;inline;
- {$ifdef cpu_only_overloads}
- Function Add(Const Value : String;const CPUs:TCPUs) : TDependency;inline;
- {$endif cpu_only_overloads}
- Function Add(Const Value : String;const CPUs:TCPUs;const OSes:TOSes) : TDependency;
- Function AddUnit(Const Value : String) : TDependency;inline;
- Function AddUnit(Const Value : String;const OSes:TOSes) : TDependency;inline;
- {$ifdef cpu_only_overloads}
- Function AddUnit(Const Value : String;const CPUs:TCPUs) : TDependency;inline;
- {$endif cpu_only_overloads}
- Function AddUnit(Const Value : String;const CPUs:TCPUs;const OSes:TOSes) : TDependency;
- Function AddInclude(Const Value : String) : TDependency;inline;
- Function AddInclude(Const Value : String;const OSes:TOSes) : TDependency;inline;
- {$ifdef cpu_only_overloads}
- Function AddInclude(Const Value : String;const CPUs:TCPUs) : TDependency;inline;
- {$endif cpu_only_overloads}
- Function AddInclude(Const Value : String;const CPUs:TCPUs;const OSes:TOSes) : TDependency;
- Property Dependencies[Index : Integer] : TDependency Read GetDependency Write SetDependency; default;
- end;
- { TTarget }
- TTarget = Class(TNamedItem)
- private
- FInstall : Boolean;
- FAfterClean: TNotifyEvent;
- FAfterCompile: TNotifyEvent;
- FBeforeClean: TNotifyEvent;
- FBeforeCompile: TNotifyEvent;
- FCPUs: TCPUs;
- FOSes: TOSes;
- FMode: TCompilerMode;
- FResourceStrings: Boolean;
- FObjectPath,
- FUnitPath,
- FIncludePath : TConditionalStrings;
- FDependencies : TDependencies;
- FCommands : TCommands;
- FDirectory: String;
- FExtension: String;
- FTargetSourceFileName : String;
- FFileType: TFileType;
- FOptions: TStrings;
- FFPCTarget: String;
- FTargetState: TTargetState;
- FTargetType: TTargetType;
- FXML: string;
- function GetOptions: TStrings;
- procedure SetOptions(const AValue: TStrings);
- Protected
- Function GetSourceFileName : String; virtual;
- Function GetUnitFileName : String; virtual;
- function GetUnitLibFileName: String; virtual;
- Function GetObjectFileName : String; virtual;
- Function GetRSTFileName : String; Virtual;
- Function GetProgramFileName(AOS : TOS) : String; Virtual;
- Public
- Constructor Create(ACollection : TCollection); override;
- Destructor Destroy; override;
- Function GetOutputFileName (AOs : TOS) : String; Virtual;
- Function HaveOptions : Boolean;
- procedure SetName(const AValue: String);override;
- procedure SetXML(const AValue: string);
- Procedure GetCleanFiles(List : TStrings; const APrefixU, APrefixB : String; ACPU:TCPU; AOS : TOS); virtual;
- Procedure GetInstallFiles(List : TStrings; const APrefixU, APrefixB: String; ACPU:TCPU; AOS : TOS); virtual;
- Procedure GetArchiveFiles(List : TStrings; ACPU:TCPU; AOS : TOS); virtual;
- Property Dependencies : TDependencies Read FDependencies;
- Property Commands : TCommands Read FCommands;
- Property State : TTargetState Read FTargetState;
- Property TargetType : TTargetType Read FTargetType Write FTargetType;
- Property OSes : TOSes Read FOSes Write FOSes;
- Property CPUs : TCPUs Read FCPUs Write FCPUs;
- Property Mode : TCompilerMode Read FMode Write FMode;
- Property Options : TStrings Read GetOptions Write SetOptions;
- Property SourceFileName: String Read GetSourceFileName ;
- Property UnitFileName : String Read GetUnitFileName;
- Property UnitLibFileName : String Read GetUnitLibFileName;
- Property ObjectFileName : String Read GetObjectFileName;
- Property RSTFileName : String Read GetRSTFileName;
- Property FPCTarget : String Read FFPCTarget Write FFPCTarget;
- Property Extension : String Read FExtension Write FExtension;
- Property FileType : TFileType Read FFileType Write FFileType;
- Property Directory : String Read FDirectory Write FDirectory;
- Property ResourceStrings : Boolean Read FResourceStrings Write FResourceStrings;
- Property Install : Boolean Read FInstall Write FInstall;
- Property TargetSourceFileName: String Read FTargetSourceFileName;
- Property ObjectPath : TConditionalStrings Read FObjectPath;
- Property UnitPath : TConditionalStrings Read FUnitPath;
- Property IncludePath : TConditionalStrings Read FIncludePath;
- Property XML: string Read FXML Write SetXML;
- // Events.
- Property BeforeCompile : TNotifyEvent Read FBeforeCompile Write FBeforeCompile;
- Property AfterCompile : TNotifyEvent Read FAfterCompile Write FAfterCompile;
- Property BeforeClean : TNotifyEvent Read FBeforeClean Write FBeforeClean;
- Property AfterClean : TNotifyEvent Read FAfterClean Write FAfterClean;
- end;
- { TTargets }
- TTargets = Class(TNamedCollection)
- private
- function GetTargetItem(Index : Integer): TTarget;
- function GetTarget(const AName : String): TTarget;
- procedure SetTargetItem(Index : Integer; const AValue: TTarget);
- Public
- Function AddFPDoc(Const AUnitName, AXMLName : String) : TTarget;inline;
- Function AddUnit(Const AUnitName : String) : TTarget;inline;
- Function AddUnit(Const AUnitName : String;const OSes:TOSes) : TTarget;inline;
- {$ifdef cpu_only_overloads}
- Function AddUnit(Const AUnitName : String;const CPUs:TCPUs) : TTarget;inline;
- {$endif cpu_only_overloads}
- Function AddUnit(Const AUnitName : String;const CPUs:TCPUs;const OSes:TOSes) : TTarget;
- Function AddImplicitUnit(Const AUnitName : String;InstallUnit:boolean=true) : TTarget;inline;
- Function AddImplicitUnit(Const AUnitName : String;const OSes:TOSes;InstallUnit:boolean=true) : TTarget;inline;
- Function AddImplicitUnit(Const AUnitName : String;const CPUs:TCPUs;InstallUnit:boolean=true) : TTarget;inline;
- Function AddImplicitUnit(Const AUnitName : String;const CPUs:TCPUs;const OSes:TOSes;InstallUnit:boolean=true) : TTarget;
- Function AddProgram(Const AProgramName : String) : TTarget;inline;
- Function AddProgram(Const AProgramName : String;const OSes:TOSes) : TTarget;inline;
- {$ifdef cpu_only_overloads}
- Function AddProgram(Const AProgramName : String;const CPUs:TCPUs) : TTarget;inline;
- {$endif cpu_only_overloads}
- Function AddProgram(Const AProgramName : String;const CPUs:TCPUs;const OSes:TOSes) : TTarget;
- Function AddExampleUnit(Const AUnitName : String) : TTarget;inline;
- Function AddExampleUnit(Const AUnitName : String;const OSes:TOSes) : TTarget;inline;
- {$ifdef cpu_only_overloads}
- Function AddExampleUnit(Const AUnitName : String;const CPUs:TCPUs) : TTarget;inline;
- {$endif cpu_only_overloads}
- Function AddExampleUnit(Const AUnitName : String;const CPUs:TCPUs;const OSes:TOSes) : TTarget;
- Function AddExampleProgram(Const AProgramName : String) : TTarget;inline;
- Function AddExampleProgram(Const AProgramName : String;const OSes:TOSes) : TTarget;inline;
- {$ifdef cpu_only_overloads}
- Function AddExampleProgram(Const AProgramName : String;const CPUs:TCPUs) : TTarget;inline;
- {$endif cpu_only_overloads}
- Function AddExampleProgram(Const AProgramName : String;const CPUs:TCPUs;const OSes:TOSes) : TTarget;
- Property Targets[AName : String] : TTarget Read GetTarget; default;
- Property TargetItems[Index : Integer] : TTarget Read GetTargetItem Write SetTargetItem;
- end;
- { TSource }
- TSource = Class(TNamedItem)
- private
- FSourceType : TSourceType;
- FInstallSourcePath : string;
- function GetInstallSourcePath: string;
- Public
- Constructor Create(ACollection : TCollection); override;
- Destructor Destroy; override;
- Procedure GetInstallFiles(List : TStrings); virtual;
- property SourceType : TSourceType read FSourceType;
- property InstallSourcePath : string read GetInstallSourcePath;
- end;
- { TSources }
- TSources = Class(TNamedCollection)
- private
- function GetSourceItem(Index : Integer): TSource;
- procedure SetSourceItem(Index : Integer; const AValue: TSource);
- public
- Function AddDoc(const AFiles : String) : TSource;
- Function AddDoc(const AFiles : String; AInstallSourcePath : String) : TSource;
- Function AddSrc(const AFiles : String) : TSource;
- Function AddExample(const AFiles : String) : TSource;
- Function AddExample(const AFiles : String; AInstallSourcePath : String) : TSource;
- Function AddTest(const AFiles : String) : TSource;
- procedure AddDocFiles(const AFileMask: string; Recursive: boolean = False; AInstallSourcePath : String = '');
- procedure AddSrcFiles(const AFileMask: string; Recursive: boolean = False);
- procedure AddExampleFiles(const AFileMask: string; Recursive: boolean = False; AInstallSourcePath : String = '');
- procedure AddTestFiles(const AFileMask: string; Recursive: boolean = False);
- Property SourceItems[Index : Integer] : TSource Read GetSourceItem Write SetSourceItem;default;
- end;
- { TPackage }
- TPackage = Class(TNamedItem)
- private
- FAfterArchive: TNotifyEvent;
- FAfterArchiveProc: TNotifyProcEvent;
- FAfterClean: TNotifyEvent;
- FAfterCleanProc: TNotifyProcEvent;
- FAfterCompile: TNotifyEvent;
- FAfterCompileProc: TNotifyProcEvent;
- FAfterInstall: TNotifyEvent;
- FAfterInstallProc: TNotifyProcEvent;
- FAfterManifest: TNotifyEvent;
- FAfterManifestProc: TNotifyProcEvent;
- FBeforeArchive: TNotifyEvent;
- FBeforeArchiveProc: TNotifyProcEvent;
- FBeforeClean: TNotifyEvent;
- FBeforeCleanProc: TNotifyProcEvent;
- FBeforeCompile: TNotifyEvent;
- FBeforeCompileProc: TNotifyProcEvent;
- FBeforeInstall: TNotifyEvent;
- FBeforeInstallProc: TNotifyProcEvent;
- FBeforeManifest: TNotifyEvent;
- FBeforeManifestProc: TNotifyProcEvent;
- FBuildMode: TBuildMode;
- FFPDocFormat: TFPDocFormats;
- FIsFPMakeAddIn: boolean;
- FSupportBuildModes: TBuildModes;
- FUnitPath,
- FObjectPath,
- FIncludePath,
- FSourcePath,
- FExamplePath,
- FTestPath,
- FCleanFiles,
- FInstallFiles : TConditionalStrings;
- FDependencies : TDependencies;
- FCPUs: TCPUs;
- FOSes: TOSes;
- FTargetState: TTargetState;
- FTargets: TTargets;
- FSources: TSources;
- FDirectory: String;
- FOptions: TStrings;
- FFileName: String;
- FAuthor: String;
- FLicense: String;
- FHomepageURL: String;
- FDownloadURL: String;
- FVersion: TFPVersion;
- FEmail : String;
- FNeedLibC : Boolean;
- FCommands : TCommands;
- FDescriptionFile : String;
- FDescription : String;
- FInstalledChecksum : Cardinal;
- // Cached directory of installed packages
- FUnitDir : String;
- FBUTargets: TTargets;
- FBUTarget: TTarget;
- Function GetDescription : string;
- Function GetFileName : string;
- function GetOptions: TStrings;
- Function GetVersion : string;
- procedure SetOptions(const AValue: TStrings);
- Procedure SetVersion(const V : string);
- Protected
- procedure SetName(const AValue: String);override;
- procedure LoadUnitConfigFromFile(Const AFileName: String);
- procedure SaveUnitConfigToStringList(Const AStringList: TStrings;ACPU:TCPU;AOS:TOS); virtual;
- procedure SaveUnitConfigToFile(Const AFileName: String;ACPU:TCPU;AOS:TOS);
- Public
- constructor Create(ACollection: TCollection); override;
- destructor destroy; override;
- Function HaveOptions : Boolean;
- Function GetUnitsOutputDir(ACPU:TCPU; AOS : TOS):String;
- Function GetBinOutputDir(ACPU:TCPU; AOS : TOS) : String;
- Procedure GetCleanFiles(List : TStrings; ACPU:TCPU; AOS : TOS); virtual;
- procedure GetInstallFiles(List: TStrings;Types : TTargetTypes;ACPU:TCPU; AOS : TOS); virtual;
- procedure GetInstallSourceFiles(List: TStrings; SourceTypes : TSourceTypes; TargetTypes : TTargetTypes); virtual;
- Procedure GetArchiveFiles(List : TStrings; ACPU:TCPU; AOS : TOS); virtual;
- Procedure GetArchiveSourceFiles(List : TStrings); virtual;
- Procedure GetManifest(Manifest : TStrings);
- Property Version : String Read GetVersion Write SetVersion;
- Property FileName : String Read GetFileName Write FFileName;
- Property HomepageURL : String Read FHomepageURL Write FHomepageURL;
- Property DownloadURL : String Read FDownloadURL Write FDownloadURL;
- Property Email : String Read FEmail Write FEmail;
- Property Author : String Read FAuthor Write FAuthor;
- Property License : String Read FLicense Write FLicense;
- Property Directory : String Read FDirectory Write FDirectory;
- Property Description : String Read GetDescription Write FDescription;
- Property DescriptionFile : String Read FDescriptionFile Write FDescriptionFile;
- Property InstalledChecksum : Cardinal Read FInstalledChecksum Write FInstalledChecksum;
- Property IsFPMakeAddIn: boolean read FIsFPMakeAddIn write FIsFPMakeAddIn;
- Property SupportBuildModes: TBuildModes read FSupportBuildModes write FSupportBuildModes;
- Property BuildMode: TBuildMode read FBuildMode;
- // Compiler options.
- Property OSes : TOSes Read FOSes Write FOSes;
- Property CPUs : TCPUs Read FCPUs Write FCPUs;
- Property NeedLibC : Boolean Read FNeedLibC Write FNeedLibC;
- Property Options: TStrings Read GetOptions Write SetOptions;
- Property UnitPath : TConditionalStrings Read FUnitPath;
- Property ObjectPath : TConditionalStrings Read FObjectPath;
- Property IncludePath : TConditionalStrings Read FIncludePath;
- Property SourcePath : TConditionalStrings Read FSourcePath;
- Property ExamplePath : TConditionalStrings Read FExamplePath;
- Property TestPath : TConditionalStrings Read FTestPath;
- Property FPDocFormat: TFPDocFormats read FFPDocFormat write FFPDocFormat;
- // Targets and dependencies
- Property InstallFiles : TConditionalStrings Read FInstallFiles;
- Property CleanFiles : TConditionalStrings Read FCleanFiles;
- Property Dependencies : TDependencies Read FDependencies;
- Property Commands : TCommands Read FCommands;
- Property State : TTargetState Read FTargetState;
- Property Targets : TTargets Read FTargets;
- Property Sources : TSources Read FSources;
- Property UnitDir : String Read FUnitDir Write FUnitDir;
- // events
- Property BeforeCompile : TNotifyEvent Read FBeforeCompile Write FBeforeCompile;
- Property BeforeCompileProc : TNotifyProcEvent Read FBeforeCompileProc write FBeforeCompileProc;
- Property AfterCompile : TNotifyEvent Read FAfterCompile Write FAfterCompile;
- Property AfterCompileProc : TNotifyProcEvent Read FAfterCompileProc Write FAfterCompileProc;
- Property BeforeInstall : TNotifyEvent Read FBeforeInstall Write FBeforeInstall;
- Property BeforeInstallProc : TNotifyProcEvent Read FBeforeInstallProc Write FBeforeInstallProc;
- Property AfterInstall : TNotifyEvent Read FAfterInstall Write FAfterInstall;
- Property AfterInstallProc : TNotifyProcEvent Read FAfterInstallProc Write FAfterInstallProc;
- Property BeforeClean : TNotifyEvent Read FBeforeClean Write FBeforeClean;
- Property BeforeCleanProc : TNotifyProcEvent Read FBeforeCleanProc Write FBeforeCleanProc;
- Property AfterClean : TNotifyEvent Read FAfterClean Write FAfterClean;
- Property AfterCleanProc : TNotifyProcEvent Read FAfterCleanProc Write FAfterCleanProc;
- Property BeforeArchive : TNotifyEvent Read FBeforeArchive Write FBeforeArchive;
- Property BeforeArchiveProc : TNotifyProcEvent Read FBeforeArchiveProc Write FBeforeArchiveProc;
- Property AfterArchive : TNotifyEvent Read FAfterArchive Write FAfterArchive;
- Property AfterArchiveProc : TNotifyProcEvent Read FAfterArchiveProc Write FAfterArchiveProc;
- Property BeforeManifest : TNotifyEvent Read FBeforeManifest Write FBeforeManifest;
- Property BeforeManifestProc : TNotifyProcEvent Read FBeforeManifestProc Write FBeforeManifestProc;
- Property AfterManifest : TNotifyEvent Read FAfterManifest Write FAfterManifest;
- Property AfterManifestProc : TNotifyProcEvent Read FAfterManifestProc Write FAfterManifestProc;
- end;
- { TPackages }
- TPackages = Class(TNamedCollection)
- private
- function GetPackage(const AName : String): TPackage;
- function GetPackageItem(AIndex : Integer): TPackage;
- procedure SetPackageItem(AIndex : Integer; const AValue: TPackage);
- Public
- Function AddPackage(Const AName : String) : TPackage;
- Property Packages[AName : String] : TPackage Read GetPackage ; Default;
- Property PackageItems[AIndex : Integer] : TPackage Read GetPackageItem Write SetPackageItem;
- end;
- { TCustomDefaults }
- TCustomDefaults = Class(TPersistent)
- Private
- FArchive: String;
- FBuildMode: TBuildMode;
- FCompiler: String;
- FCopy: String;
- FFPDocOutputDir: String;
- FIgnoreInvalidOptions: Boolean;
- FInstallExamples: Boolean;
- FMkDir: String;
- FMove: String;
- FOptions: TStrings;
- FCPU: TCPU;
- FOS: TOS;
- FMode : TCompilerMode;
- FCompilerVersion : String;
- FPrefix: String;
- FLocalUnitDir,
- FGlobalUnitDir,
- FBaseInstallDir,
- FUnitInstallDir,
- FBinInstallDir,
- FDocInstallDir,
- FExamplesInstallDir : String;
- FRemoveTree: String;
- FRemoveDir: String;
- FRemove: String;
- FTarget: String;
- FUnixPaths: Boolean;
- FNoFPCCfg: Boolean;
- FUseEnvironment: Boolean;
- function GetFPDocOutputDir: String;
- function GetLocalUnitDir: String;
- function GetGlobalUnitDir: String;
- function GetBaseInstallDir: String;
- function GetBinInstallDir: String;
- function GetCompiler: String;
- function GetDocInstallDir: String;
- function GetExamplesInstallDir: String;
- function GetOptions: TStrings;
- function GetUnitInstallDir: String;
- procedure SetLocalUnitDir(const AValue: String);
- procedure SetGlobalUnitDir(const AValue: String);
- procedure SetBaseInstallDir(const AValue: String);
- procedure SetCPU(const AValue: TCPU);
- procedure SetOptions(const AValue: TStrings);
- procedure SetOS(const AValue: TOS);
- procedure SetPrefix(const AValue: String);
- procedure SetTarget(const AValue: String);
- procedure SetUnitInstallDir(const AValue: String);
- Protected
- procedure RecalcTarget;
- Function CmdLineOptions : String;
- Public
- Constructor Create;
- Procedure InitDefaults;
- Function HaveOptions: Boolean;
- procedure CompilerDefaults; virtual;
- Procedure LocalInit(Const AFileName : String);
- Procedure LoadFromFile(Const AFileName : String);
- Procedure SaveToFile(Const AFileName : String);
- procedure SaveToStream(S : TStream);virtual;
- procedure LoadFromStream(S : TStream);virtual;
- // Compile Information
- Property Target : String Read FTarget Write SetTarget;
- Property OS : TOS Read FOS Write SetOS;
- Property CPU : TCPU Read FCPU Write SetCPU;
- Property Mode : TCompilerMode Read FMode Write FMode;
- Property UnixPaths : Boolean Read FUnixPaths Write FUnixPaths;
- Property Options : TStrings Read GetOptions Write SetOptions; // Default compiler options.
- Property NoFPCCfg : Boolean Read FNoFPCCfg Write FNoFPCCfg;
- // paths etc.
- Property LocalUnitDir : String Read GetLocalUnitDir Write SetLocalUnitDir;
- Property GlobalUnitDir : String Read GetGlobalUnitDir Write SetGlobalUnitDir;
- Property Prefix : String Read FPrefix Write SetPrefix;
- Property BaseInstallDir : String Read GetBaseInstallDir Write SetBaseInstallDir;
- Property UnitInstallDir : String Read GetUnitInstallDir Write SetUnitInstallDir;
- Property BinInstallDir : String Read GetBinInstallDir Write FBinInstallDir;
- Property DocInstallDir : String Read GetDocInstallDir Write FDocInstallDir;
- Property ExamplesInstallDir : String Read GetExamplesInstallDir Write FExamplesInstallDir;
- Property FPDocOutputDir : String Read GetFPDocOutputDir Write FFPDocOutputDir;
- // Command tools. If not set, internal commands will be used.
- Property Compiler : String Read GetCompiler Write FCompiler; // Compiler. Defaults to fpc
- Property Copy : String Read FCopy Write FCopy; // copy $(FILES) to $(DEST)
- Property Move : String Read FMove Write FMove; // Move $(FILES) to $(DEST)
- Property Remove : String Read FRemove Write FRemove; // Delete $(FILES)
- Property RemoveDir : String Read FRemoveDir Write FRemoveDir; // Delete $(FILES)
- Property RemoveTree : String Read FRemoveTree Write FRemoveTree; // removes $(DIRECTORY)
- Property MkDir : String Read FMkDir write FMkDir; // Make $(DIRECTORY)
- Property Archive : String Read FArchive Write FArchive; // zip $(ARCHIVE) $(FILESORDIRS)
- // Misc
- Property UseEnvironment : Boolean read FUseEnvironment write FUseEnvironment;
- Property IgnoreInvalidOptions: Boolean read FIgnoreInvalidOptions write FIgnoreInvalidOptions;
- Property BuildMode: TBuildMode read FBuildMode write FBuildMode;
- // Installation optioms
- Property InstallExamples: Boolean read FInstallExamples write FInstallExamples;
- end;
- { TBasicDefaults }
- TBasicDefaults = Class(TCustomDefaults)
- end;
- { TFPCDefaults }
- TFPCDefaults = Class(TCustomDefaults)
- public
- procedure CompilerDefaults; override;
- end;
- { TBuildEngine }
- TBuildEngine = Class(TComponent)
- private
- // general variables
- FCompiler : String;
- FStartDir : String;
- FForceCompile : Boolean;
- FListMode : Boolean;
- FVerbose : boolean;
- {$ifdef HAS_UNIT_ZIPPER}
- FZipFile: TZipper;
- {$endif HAS_UNIT_ZIPPER}
- FExternalPackages : TPackages;
- // Logging
- FLogPrefix : String;
- // Events
- FOnLog: TLogEvent;
- FAfterArchive: TNotifyEvent;
- FAfterClean: TNotifyEvent;
- FAfterCompile: TNotifyEvent;
- FAfterInstall: TNotifyEvent;
- FAfterManifest: TNotifyEvent;
- FBeforeArchive: TNotifyEvent;
- FBeforeClean: TNotifyEvent;
- FBeforeCompile: TNotifyEvent;
- FBeforeInstall: TNotifyEvent;
- FBeforeManifest: TNotifyEvent;
- Protected
- Procedure Error(const Msg : String);
- Procedure Error(const Fmt : String; const Args : Array of const);
- // Internal copy/delete/move/archive/mkdir files
- Function SysDirectoryExists(const ADir:string):Boolean;
- Function SysFileExists(const AFileName:string):Boolean;
- Procedure SysCopyFile(Const Src,Dest : String); virtual;
- Procedure SysMoveFile(Const Src,Dest : String); virtual;
- Procedure SysDeleteFile(Const AFileName : String); virtual;
- Procedure SysDeleteDirectory(Const ADirectoryName : String); virtual;
- Procedure SysDeleteTree(Const ADirectoryName : String); virtual;
- Procedure SysArchiveFiles(List : TStrings; Const AFileName : String); virtual;
- procedure LogIndent;
- procedure LogUnIndent;
- Procedure EnterDir(ADir : String);
- Function GetCompiler : String;
- Function InstallPackageFiles(APAckage : TPackage; tt : TTargetType; Const Dest : String):Boolean;
- Procedure InstallUnitConfigFile(APAckage : TPackage; Const Dest : String);
- Function InstallPackageSourceFiles(APAckage : TPackage; stt : TSourceTypes; ttt : TTargetTypes; Const Dest : String):Boolean;
- Function FileNewer(const Src,Dest : String) : Boolean;
- Procedure LogSearchPath(const ASearchPathName:string;Path:TConditionalStrings; ACPU:TCPU;AOS:TOS);
- Function FindFileInPath(Path:TConditionalStrings; AFileName:String; var FoundPath:String;ACPU:TCPU;AOS:TOS):Boolean;
- procedure GetDirectoriesFromFilelist(const AFileList, ADirectoryList: TStringList);
- //package commands
- function GetUnitDir(APackage:TPackage):String;
- procedure AddDependencyPaths(L: TStrings; DependencyType: TDependencyType; ATarget: TTarget);
- procedure AddDependencyUnitPaths(L:TStrings;APackage: TPackage);
- Public
- Constructor Create(AOwner : TComponent); override;
- destructor Destroy;override;
- property Verbose : boolean read FVerbose write FVerbose;
- Procedure ResolveFileNames(APackage : TPackage; ACPU:TCPU;AOS:TOS;DoChangeDir:boolean=true);
- // Public Copy/delete/Move/Archive/Mkdir Commands.
- Procedure ExecuteCommand(const Cmd,Args : String; const Env: TStrings = nil; IgnoreError : Boolean = False); virtual;
- Procedure CmdCopyFiles(List : TStrings; Const DestDir : String);
- Procedure CmdCreateDir(const DestDir : String);
- Procedure CmdMoveFiles(List : TStrings; Const DestDir : String);
- Procedure CmdDeleteFiles(List : TStrings);
- Procedure CmdArchiveFiles(List : TStrings; Const ArchiveFile : String);
- Procedure CmdRenameFile(SourceName, DestName : String);
- Procedure CmdRemoveDirs(List: TStrings);
- Procedure CmdRemoveTrees(List: TStrings);
- Procedure ExecuteCommands(Commands : TCommands; At : TCommandAt);
- // Dependency commands
- Function DependencyOK(ADependency : TDependency) : Boolean;
- // Target commands
- Function GetCompilerCommand(APackage : TPackage; ATarget : TTarget; Env: TStrings) : String;
- Function TargetOK(ATarget : TTarget) : Boolean;
- Function NeedsCompile(APackage:TPackage; ATarget : TTarget) : Boolean;
- Procedure Compile(APackage:TPackage; ATarget : TTarget); virtual;
- Procedure MaybeCompile(APackage:TPackage; ATarget: TTarget);
- Procedure CompileDependencies(APackage:TPackage; ATarget: TTarget);
- // Package commands
- { Function GetPackageDir(APackage : TPackage; AbsolutePath : Boolean = False) : String;
- Function GetUnitsOutputDir(APackage : TPackage; AbsolutePath : Boolean = False) : String;
- Function GetBinOutputDir(APackage : TPackage; AbsolutePath : Boolean = False) : String; }
- Function PackageOK(APackage : TPackage) : Boolean; virtual;
- Procedure DoBeforeCompile(APackage : TPackage);virtual;
- Procedure DoAfterCompile(APackage : TPackage);virtual;
- Procedure DoBeforeInstall(APackage : TPackage);virtual;
- Procedure DoAfterInstall(APackage : TPackage);virtual;
- Procedure DoBeforeArchive(APackage : TPackage);virtual;
- Procedure DoAfterArchive(APackage : TPackage);virtual;
- Procedure DoBeforeClean(APackage : TPackage);virtual;
- Procedure DoAfterClean(APackage : TPackage);virtual;
- Function NeedsCompile(APackage : TPackage) : Boolean; virtual;
- Procedure Compile(APackage : TPackage);
- Procedure MaybeCompile(APackage:TPackage);
- Procedure Install(APackage : TPackage);
- Procedure Archive(APackage : TPackage);
- Procedure Manifest(APackage : TPackage);
- Procedure Clean(APackage : TPackage; AllTargets: boolean);
- Procedure Clean(APackage : TPackage; ACPU:TCPU; AOS : TOS);
- Procedure CompileDependencies(APackage : TPackage);
- Function CheckExternalPackage(Const APackageName : String):TPackage;
- procedure CreateOutputDir(APackage: TPackage);
- // Packages commands
- Procedure Compile(Packages : TPackages);
- Procedure Install(Packages : TPackages);
- Procedure Archive(Packages : TPackages);
- procedure Manifest(Packages: TPackages);
- Procedure Clean(Packages : TPackages; AllTargets: boolean);
- Procedure Log(Level : TVerboseLevel; Const Msg : String);
- Procedure Log(Level : TVerboseLevel; Const Fmt : String; const Args : Array Of Const);
- Property ListMode : Boolean Read FListMode Write FListMode;
- Property ForceCompile : Boolean Read FForceCompile Write FForceCompile;
- Property ExternalPackages: TPackages Read FExternalPackages;
- Property StartDir: String Read FStartDir;
- // Events
- Property BeforeCompile : TNotifyEvent Read FBeforeCompile Write FBeforeCompile;
- Property AfterCompile : TNotifyEvent Read FAfterCompile Write FAfterCompile;
- Property BeforeInstall : TNotifyEvent Read FBeforeInstall Write FBeforeInstall;
- Property AfterInstall : TNotifyEvent Read FAfterInstall Write FAfterInstall;
- Property BeforeClean : TNotifyEvent Read FBeforeClean Write FBeforeClean;
- Property AfterClean : TNotifyEvent Read FAfterClean Write FAfterClean;
- Property BeforeArchive : TNotifyEvent Read FBeforeArchive Write FBeforeArchive;
- Property AfterArchive : TNotifyEvent Read FAfterArchive Write FAfterArchive;
- Property BeforeManifest : TNotifyEvent Read FBeforeManifest Write FBeforeManifest;
- Property AfterManifest : TNotifyEvent Read FAfterManifest Write FAfterManifest;
- Property OnLog : TLogEvent Read FOnLog Write FOnlog;
- end;
- { TCustomInstaller }
- TCustomInstaller = Class(TComponent)
- private
- FBuildEngine: TBuildEngine;
- FPackages: TPackages;
- FRunMode: TRunMode;
- FListMode : Boolean;
- FLogLevels : TVerboseLevels;
- FFPMakeOptionsString: string;
- Protected
- Procedure Log(Level : TVerboseLevel; Const Msg : String);
- Procedure CreatePackages; virtual;
- Procedure FreePackages; virtual;
- function GetPackages: TPackages; virtual;
- Procedure CheckPackages; virtual;
- Procedure CreateBuildEngine; virtual;
- Procedure Error(const Msg : String);
- Procedure Error(const Fmt : String; Args : Array of const);
- Procedure AnalyzeOptions;
- Procedure Usage(const FMT : String; Args : Array of const);
- Procedure Compile(Force : Boolean); virtual;
- Procedure Clean(AllTargets: boolean); virtual;
- Procedure Install; virtual;
- Procedure Archive; virtual;
- Procedure Manifest; virtual;
- Public
- Constructor Create(AOwner : TComponent); virtual;
- Destructor destroy; override;
- Function AddPackage(Const AName : String) : TPackage;
- Function Run : Boolean;
- Property FPMakeOptionsString: string read FFPMakeOptionsString;
- Property BuildEngine : TBuildEngine Read FBuildEngine;
- //files in package
- Property Packages : TPackages Read GetPackages;
- Property RunMode : TRunMode Read FRunMode;
- Property ListMode : Boolean Read FListMode;
- end;
- { TFPCInstaller }
- TFPCInstaller = class(TCustomInstaller)
- public
- Constructor Create(AOwner : TComponent); override;
- end;
- { TBasicInstaller }
- TBasicInstaller = class(TCustomInstaller)
- Constructor Create(AOwner : TComponent); override;
- end;
- TReplaceFunction = Function (Const AName,Args : String) : String of Object;
- { TValueItem }
- TValueItem = Class(TObject)
- FValue : String;
- Constructor Create(AValue : String);
- end;
- { TFunctionItem }
- TFunctionItem = Class(TObject)
- FFunc : TReplaceFunction;
- Constructor Create(AFunc : TReplaceFunction);
- end;
- { TDictionary }
- TDictionary = Class(TComponent)
- FList : TStringList;
- Public
- Constructor Create(AOwner : TComponent); override;
- Destructor Destroy;override;
- Procedure AddVariable(Const AName,Value : String);
- Procedure AddFunction(Const AName : String; FReplacement : TReplaceFunction);
- Procedure RemoveItem(Const AName : String);
- Function GetValue(Const AName : String) : String;
- Function GetValue(Const AName,Args : String) : String; virtual;
- Function ReplaceStrings(Const ASource : String) : String; virtual;
- end;
- ECollectionError = Class(Exception);
- EDictionaryError = Class(Exception);
- EInstallerError = Class(Exception);
- TInstallerClass = Class of TCustomInstaller;
- TDictionaryClass = Class of TDictionary;
- Type
- TArchiveEvent = Procedure (Const AFileName : String; List : TStrings) of Object;
- TArchiveProc = Procedure (Const AFileName : String; List : TStrings);
- Var
- DictionaryClass : TDictionaryClass = TDictionary;
- OnArchiveFiles : TArchiveEvent = Nil;
- ArchiveFilesProc : TArchiveProc = Nil;
- Defaults : TCustomDefaults; // Set by installer.
- Dictionary : TDictionary;
- Function CurrentOS : String;
- Function CurrentCPU : String;
- Function Installer(InstallerClass: TInstallerClass) : TCustomInstaller; overload;
- Function Installer : TCustomInstaller; overload;
- Function OSToString(OS: TOS) : String;
- Function OSesToString(OSes: TOSes) : String;
- Function CPUToString(CPU: TCPU) : String;
- Function CPUSToString(CPUS: TCPUS) : String;
- Function StringToOS(const S : String) : TOS;
- Function OSesToString(const S : String) : TOSes;
- Function StringToCPU(const S : String) : TCPU;
- Function StringToCPUS(const S : String) : TCPUS;
- Function ModeToString(Mode: TCompilerMode) : String;
- Function StringToMode(const S : String) : TCompilerMode;
- Function MakeTargetString(CPU : TCPU;OS: TOS) : String;
- Procedure StringToCPUOS(const S : String; Var CPU : TCPU; Var OS: TOS);
- Function FixPath (const APath : String) : String;
- Function IsRelativePath(const APath : String) : boolean;
- Procedure ChangeDir(const APath : String);
- Function Substitute(Const Source : String; Macros : Array of string) : String;
- Procedure SplitCommand(Const Cmd : String; Var Exe,Options : String);
- Procedure AddCustomFpmakeCommandlineOption(const ACommandLineOption, HelpMessage : string);
- Function GetCustomFpmakeCommandlineOptionValue(const ACommandLineOption : string) : string;
- procedure SearchFiles(const AFileName: string; Recursive: boolean; var List: TStrings);
- Implementation
- uses typinfo, rtlconsts;
- type
- TUnsortedDuplicatesStringList = class(TStringList)
- public
- function Add(const S: string): Integer; override;
- end;
- var
- CustomFpmakeCommandlineOptions: TStrings;
- CustomFpMakeCommandlineValues: TStrings;
- ResourceString
- SErrInvalidCPU = 'Invalid CPU name "%s"';
- SErrInvalidOS = 'Invalid OS name "%s"';
- SErrInvalidMode = 'Invalid compiler mode "%s"';
- SErrInvalidTarget = 'Invalid compiler target "%s"';
- SErrNameExists = 'Name "%s" already exists in the collection.';
- SErrNoSuchName = 'Could not find item with name "%s" in the collection.';
- SErrInValidArgument = 'Invalid command-line argument at position %d: %s';
- SErrNeedArgument = 'Option at position %d (%s) needs an argument';
- SErrNoPackagesDefined = 'No action possible: No packages were defined.';
- SErrInstaller = 'The installer encountered the following error:';
- SErrDepUnknownTarget = 'Unknown target for unit "%s" in dependencies for %s in package %s';
- SErrExternalCommandFailed = 'External command "%s" failed with exit code %d. Console output:'+LineEnding+'%s';
- SErrCreatingDirectory = 'Failed to create directory "%s"';
- SErrDeletingFile = 'Failed to delete file "%s"';
- SErrRemovingDirectory = 'Failed to remove directory "%s"';
- SErrMovingFile = 'Failed to move file "%s" to "%s"';
- SErrCopyingFile = 'Failed to copy file "%s" to "%s"';
- SErrChangeDirFailed = 'Failed to enter directory "%s"';
- SErrInvalidArgumentToSubstitute = 'Invalid number of arguments to Substitute';
- SErrNoArchiveSupport = 'This binary contains no archive support. Please recompile with archive support';
- SErrNoDictionaryItem = 'No item called "%s" in the dictionary';
- SErrNoDictionaryValue = 'The item "%s" in the dictionary is not a value';
- SErrNoDictionaryFunc = 'The item "%s" in the dictionary is not a function';
- SErrInvalidFPCInfo = 'Compiler returns invalid information, check if fpc -iV works';
- SErrDependencyNotFound = 'Could not find unit directory for dependency package "%s"';
- SErrAlreadyInitialized = 'Installer can only be initialized once';
- SErrInvalidState = 'Invalid state for target %s';
- SErrCouldNotCompile = 'Could not compile target %s from package %s';
- SErrUnsupportedBuildmode = 'Package does not support this buildmode';
- SWarnCircularTargetDependency = 'Warning: Circular dependency detected when compiling target %s with target %s';
- SWarnCircularPackageDependency = 'Warning: Circular dependency detected when compiling package %s with package %s';
- SWarnFailedToSetTime = 'Warning: Failed to set timestamp on file "%s"';
- SWarnFailedToGetTime = 'Warning: Failed to get timestamp from file "%s"';
- SWarnAttemptingToCompileNonNeutralTarget = 'Warning: Attempting to compile non-neutral target %s';
- SWarnSourceFileNotFound = 'Warning: Source file "%s" from package %s not found for %s';
- SWarnIncludeFileNotFound = 'Warning: Include file "%s" from package %s not found for %s';
- SWarnDepUnitNotFound = 'Warning: Dependency on unit %s is not supported for %s';
- SWarnTargetDependsOnPackage = 'Warning: Target %s of package %s depends on another package (%s). These kind of dependencies are not processed';
- SWarnDependOnOtherPlatformPackage = 'Warning: Package %s depends on package %s which is not available for the %s platform';
- SWarnStartBuildingPackage = 'Start building package %s for target %s.';
- SWarnBuildingPackagecomplete = '[%3.0f%%] Built target %s';
- SWarnInstallationPackagecomplete = 'Installation package %s for target %s succeeded';
- SWarnCleanPackagecomplete = 'Clean of package %s completed';
- SInfoCompilingPackage = 'Compiling package %s';
- SInfoPackageAlreadyProcessed = 'Package %s is already processed';
- SInfoCompilingTarget = 'Compiling target %s';
- SInfoExecutingCommand = 'Executing command "%s %s"';
- SInfoCreatingOutputDir = 'Creating output dir "%s"';
- SInfoInstallingPackage = 'Installing package %s';
- SInfoArchivingPackage = 'Archiving package %s in "%s"';
- SInfoCleaningPackage = 'Cleaning package %s';
- SInfoManifestPackage = 'Creating manifest for package %s';
- SInfoCopyingFile = 'Copying file "%s" to "%s"';
- SInfoSourceNewerDest = 'Source file "%s" (%s) is newer than destination "%s" (%s).';
- SInfoFallbackBuildmode = 'Buildmode not spported by package, falling back to one by one unit compilation';
- SDbgComparingFileTimes = 'Comparing file "%s" time "%s" to "%s" time "%s".';
- SDbgCompilingDependenciesOfTarget = 'Compiling dependencies of target %s';
- SDbgResolvingSourcesOfTarget = 'Resolving filenames of target %s for %s';
- SDbgResolvedSourceFile = 'Resolved source file %s to "%s"';
- SDbgResolvedIncludeFile = 'Resolved include file %s to "%s"';
- SDbgOutputNotYetAvailable = 'Output file %s not available';
- SDbgDependencyOnUnit = 'Dependency of %s on unit %s';
- SDbgDependencyUnitRecompiled = 'Dependent unit %s is being recompiled';
- SDbgMustCompile = 'Must compile %s';
- SDbgSkippingTargetWrongCPU = 'Skipping target %s, different CPU (%s)';
- SDbgSkippingTargetWrongOS = 'Skipping target %s, different OS (%s)';
- SDbgTargetIsNotAUnitOrProgram = 'Skipping Target %s, not an unit or program';
- SDbgConsideringTarget = 'Considering target %s';
- SDbgConsideringPackage = 'Considering package %s';
- SDbgExternalDependency = 'External dependency %s found in "%s"';
- SDbgBuildEngineArchiving = 'Build engine archiving';
- SDbgBuildEngineGenerateManifests = 'Build engine generating manifests';
- SDbgBuildEngineCleaning = 'Build engine cleaning';
- SDbgGenerating = 'Generating "%s"';
- SDbgLoading = 'Loading "%s"';
- SDbgFound = 'Found';
- SDbgNotFound = 'Not Found';
- SDbgDirectoryExists = 'Directory "%s" %s';
- SDbgFileExists = 'File "%s" %s';
- SDbgArchivingFile = 'Archiving "%s"';
- SDbgSearchPath = 'Using %s path "%s"';
- SDbgEnterDir = 'Entering directory "%s"';
- SDbgPackageChecksumChanged = 'Dependent package %s is modified';
- SDbgFileDoesNotExist = 'File "%s" does not exist';
- SDbgDirectoryDoesNotExist = 'Directory "%s" does not exist';
- SDbgDirectoryNotEmpty = 'Directory "%s" is not empty. Will not remove';
- SDbgGenerateBuildUnit = 'Generate build-unit %s';
- // Help messages for usage
- SValue = 'Value';
- SHelpUsage = 'Usage: %s command [options]';
- SHelpCommand = 'Where command is one of the following:';
- SHelpCompile = 'Compile all units in the package(s).';
- SHelpBuild = 'Build all units in the package(s).';
- SHelpInstall = 'Install all units in the package(s).';
- SHelpClean = 'Clean (remove) all units in the package(s).';
- SHelpArchive = 'Create archive (zip) with all units in the package(s).';
- SHelpHelp = 'This message.';
- SHelpManifest = 'Create a manifest suitable for import in repository.';
- SHelpCmdOptions = 'Where options is one or more of the following:';
- SHelpCPU = 'Compile for indicated CPU.';
- SHelpOS = 'Compile for indicated OS';
- SHelpTarget = 'Compile for indicated target';
- SHelpList = 'list commands instead of actually executing them.';
- SHelpPrefix = 'Use indicated prefix directory for all commands.';
- SHelpNoFPCCfg = 'Compiler will not use fpc.cfg';
- SHelpBaseInstallDir = 'Use indicated directory as base install dir.';
- SHelpLocalUnitDir = 'Use indicated directory as local (user) unit dir.';
- SHelpGlobalUnitDir = 'Use indicated directory as global unit dir.';
- SHelpUnitInstallDir = 'Use indicated directory to install units into.';
- SHelpCompiler = 'Use indicated binary as compiler';
- SHelpConfig = 'Use indicated config file when compiling.';
- SHelpOptions = 'Pass extra options to the compiler.';
- SHelpVerbose = 'Be verbose when working.';
- SHelpInstExamples = 'Install the example-sources.';
- SHelpIgnoreInvOpt = 'Ignore further invalid options.';
- sHelpFpdocOutputDir = 'Use indicated directory as fpdoc output folder.';
- sHelpUseEnvironment = 'Use environment to pass options to compiler.';
- SHelpUseBuildUnit = 'Compile package in Build-unit mode.';
- Const
- // Keys for Defaults file. Do not localize.
- KeyCompiler = 'Compiler';
- KeyArchive = 'Archive';
- KeyCopy = 'Copy';
- KeyMkDir = 'MkDir';
- KeyMove = 'Move';
- KeyRemove = 'Remove';
- KeyRemoveDir= 'RemoveDir';
- KeyRemoveTree= 'RemoveTree';
- KeyOptions = 'Options';
- KeyCPU = 'CPU';
- KeyOS = 'OS';
- KeyMode = 'Mode';
- KeyPrefix = 'Prefix';
- KeyTarget = 'Target';
- KeyNoFPCCfg = 'NoFPCCfg';
- KeyUseEnv = 'UseEnv';
- KeyLocalUnitDir = 'LocalUnitDir';
- KeyGlobalUnitDir = 'GlobalUnitDir';
- KeyBaseInstallDir = 'BaseInstallDir';
- KeyUnitInstallDir = 'UnitInstallDir';
- KeyBinInstallDir = 'BinInstallDir';
- KeyDocInstallDir = 'DocInstallDir';
- KeyExamplesInstallDir = 'ExamplesInstallDir';
- KeyInstallExamples = 'InstallExamples';
- // Keys for unit config
- KeyName = 'Name';
- KeyVersion = 'Version';
- KeyChecksum = 'Checksum';
- KeyNeedLibC = 'NeedLibC';
- KeyDepends = 'Depends';
- KeyAddIn = 'FPMakeAddIn';
- KeySourcePath = 'SourcePath';
- KeyFPMakeOptions = 'FPMakeOptions';
- {****************************************************************************
- Helpers
- ****************************************************************************}
- {$ifdef HAS_UNIT_PROCESS}
- function ExecuteFPC(Verbose: boolean; const Path: string; const ComLine: string; const Env: TStrings; ConsoleOutput: TMemoryStream): integer;
- var
- P: TProcess;
- BytesRead: longint;
- function ReadFromStream: longint;
- const
- READ_BYTES = 2048;
- type
- TMessages = (mCompiling, mLinking);
- var
- //ifdef the MsgNum so it contains the correct message numbers for each compiler version.
- MsgNum : array [TMessages] of integer = (3104, 9015);
- n: longint;
- BuffPos: longint;
- sLine: string;
- ch: char;
- msg: TMessages;
- ipos: integer;
- snum: string;
- begin
- // make sure we have room
- ConsoleOutput.SetSize(BytesRead + READ_BYTES);
- // try reading it
- n := P.Output.Read((ConsoleOutput.Memory + BytesRead)^, READ_BYTES);
- if n > 0 then
- begin
- Inc(BytesRead, n);
- sLine := '';
- BuffPos := ConsoleOutput.Position;
- //read lines from the stream
- repeat
- ConsoleOutput.Read(ch,1);
- if ch in [#10, #13] then
- begin
- if Verbose then
- writeln(sLine)
- else
- begin
- for msg := Low(TMessages) to High(TMessages) do
- begin
- snum := Format('(%d)', [MsgNum[msg]]);
- ipos := Pos(snum, sLine);
- if ipos = 1 then
- writeln(' ', Copy(sLine, ipos + Length(snum), Length(sLine) - ipos - Length(snum) + 1));
- end;
- end;
- sLine := '';
- BuffPos := ConsoleOutput.Position;
- end
- else
- sLine := sLine + ch;
- until ConsoleOutput.Position >= BytesRead;
- ConsoleOutput.Position := BuffPos;
- end
- else
- begin
- // no data, wait 100 ms
- Sleep(100);
- end;
- Result := n;
- end;
- begin
- result := -1;
- BytesRead := 0;
- P := TProcess.Create(nil);
- try
- P.CommandLine := Path + ' ' + ComLine;
- if assigned(Env) then
- P.Environment.Assign(Env);
- P.Options := [poUsePipes];
- P.Execute;
- while P.Running do
- ReadFromStream;
- // read last part
- repeat
- until ReadFromStream = 0;
- ConsoleOutput.SetSize(BytesRead);
- result := P.ExitStatus;
- finally
- P.Free;
- end;
- end;
- {$endif HAS_UNIT_PROCESS}
- function IsDirectoryEmpty(const directory : string) : boolean;
- var
- searchRec: TSearchRec;
- SearchResult: longint;
- begin
- result := true;
- SearchResult := FindFirst(IncludeTrailingPathDelimiter(directory)+AllFilesMask, faAnyFile+faSymLink, searchRec);
- try
- while SearchResult=0 do
- begin
- if (searchRec.Name<>'.') and (searchRec.Name<>'..') then
- begin
- result := false;
- break;
- end;
- SearchResult := FindNext(searchRec);
- end;
- finally
- FindClose(searchRec);
- end;
- end;
- function ParsecompilerOutput(M: TMemoryStream; Verbose: boolean): string;
- type
- TParseCompilerOutputState = (cosBeginOfLine, cosSearchColon, cosParseNumber, cosOther);
- var
- presult: pchar;
- state: TParseCompilerOutputState;
- ch: char;
- eolchar: char;
- begin
- m.Seek(0, soBeginning);
- setlength(Result,M.Size);
- if verbose then
- begin
- m.Read(Result[1],M.Size);
- Exit;
- end;
- presult := @Result[1];
- eolchar := RightStr(LineEnding,1)[1];
- m.Seek(0,soBeginning);
- state := cosBeginOfLine;
- while m.Position<m.Size do
- begin
- ch := char(m.ReadByte);
- case state of
- cosBeginOfLine:
- begin
- if ch='(' then
- state := cosParseNumber
- else if ch=' ' then
- begin
- presult^ := ch;
- inc(presult);
- end
- else
- begin
- presult^ := ch;
- inc(presult);
- state := cosSearchColon;
- end;
- end;
- cosParseNumber:
- begin
- if ch=')' then
- begin
- state := cosOther;
- // Omit the space behind the number
- ch := char(m.ReadByte);
- assert(ch=' ');
- end;
- end;
- cosOther:
- begin
- presult^ := ch;
- inc(presult);
- if ch=eolchar then
- state := cosBeginOfLine;
- end;
- cosSearchColon:
- begin
- presult^ := ch;
- inc(presult);
- if (ch=':') or (ch=eolchar) then
- state := cosBeginOfLine;
- end;
- end;
- end;
- setlength(Result,presult-@result[1]);
- end;
- Function QuoteXML(S : String) : string;
- Procedure W(Var J : Integer; Var R : String; T : String);
- Var
- I: integer;
- begin
- If J+Length(T)>Length(R) then
- SetLength(R,J+Length(T));
- For I:=1 to Length(t) do
- begin
- R[J]:=T[i];
- If I<Length(T) then
- Inc(J);
- end;
- end;
- const
- QuotStr = '"';
- AmpStr = '&';
- ltStr = '<';
- gtStr = '>';
- Var
- I,J : Integer;
- begin
- SetLength(Result,Length(S));
- J:=0;
- For I:=1 to Length(S) do
- begin
- Inc(J);
- case S[i] of
- '"': W(j,Result,QuotStr);
- '&': W(J,Result,AmpStr);
- '<': W(J,Result,ltStr);
- '>': W(J,Result,gtStr);
- // Escape whitespace using CharRefs to be consistent with W3 spec X 3.3.3
- #9: w(J,Result,'	');
- { #10: wrtStr('
');
- #13: wrtStr('
');}
- else
- Result[J]:=S[i];
- end;
- If (J=Length(Result)) and (I<Length(S)) then
- SetLength(Result,J+Length(S)-I);
- end;
- If J<>Length(Result) then
- SetLength(Result,J);
- end;
- function maybequoted(const s:string):string;
- const
- {$IFDEF MSWINDOWS}
- FORBIDDEN_CHARS = ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
- '{', '}', '''', '`', '~'];
- {$ELSE}
- FORBIDDEN_CHARS = ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
- '{', '}', '''', ':', '\', '`', '~'];
- {$ENDIF}
- var
- s1 : string;
- i : integer;
- quoted : boolean;
- begin
- quoted:=false;
- s1:='"';
- for i:=1 to length(s) do
- begin
- case s[i] of
- '"' :
- begin
- quoted:=true;
- s1:=s1+'\"';
- end;
- ' ',
- #128..#255 :
- begin
- quoted:=true;
- s1:=s1+s[i];
- end;
- else begin
- if s[i] in FORBIDDEN_CHARS then
- quoted:=True;
- s1:=s1+s[i];
- end;
- end;
- end;
- if quoted then
- maybequoted:=s1+'"'
- else
- maybequoted:=s;
- end;
- procedure ReadIniFile(Const AFileName: String;L:TStrings);
- Var
- F : TFileStream;
- Line : String;
- I,P,PC : Integer;
- begin
- F:=TFileStream.Create(AFileName,fmOpenRead);
- Try
- L.LoadFromStream(F);
- // Fix lines.
- For I:=L.Count-1 downto 0 do
- begin
- Line:=L[I];
- P:=Pos('=',Line);
- PC:=Pos(';',Line); // Comment line.
- If (P=0) or ((PC<>0) and (PC<P)) then
- L.Delete(I)
- else
- L[i]:=Trim(System.Copy(Line,1,P-1)+'='+Trim(System.Copy(Line,P+1,Length(Line)-P)));
- end;
- Finally
- F.Free;
- end;
- end;
- // Callback for Sysutils getapplicationname.
- Function GetFPMakeName : String;
- begin
- Result:='fpmake';
- end;
- Function CurrentOS : String;
- begin
- Result:=OSToString(Defaults.OS);
- end;
- Function CurrentCPU : String;
- begin
- Result:=CPUToString(Defaults.CPU);
- end;
- Function OSToString(OS: TOS) : String;
- begin
- Result:=LowerCase(GetenumName(TypeInfo(TOS),Ord(OS)));
- end;
- Function OSesToString(OSes: TOSes) : String;
- begin
- Result:=LowerCase(SetToString(PtypeInfo(TypeInfo(TOSes)),Integer(OSes),False));
- end;
- Function CPUToString(CPU: TCPU) : String;
- begin
- Result:=LowerCase(GetenumName(TypeInfo(TCPU),Ord(CPU)));
- end;
- Function CPUSToString(CPUS: TCPUS) : String;
- begin
- Result:=LowerCase(SetToString(PTypeInfo(TypeInfo(TCPUS)),Integer(CPUS),False));
- end;
- Function StringToOS(const S : String) : TOS;
- Var
- I : Integer;
- begin
- I:=GetEnumValue(TypeInfo(TOS),S);
- if (I=-1) then
- Raise EInstallerError.CreateFmt(SErrInvalidOS,[S]);
- Result:=TOS(I);
- end;
- Function OSesToString(const S : String) : TOSes;
- begin
- Result:=TOSes(StringToSet(PTypeInfo(TypeInfo(TOSes)),S));
- end;
- Function StringToCPU(const S : String) : TCPU;
- Var
- I : Integer;
- begin
- I:=GetEnumValue(TypeInfo(TCPU),S);
- if (I=-1) then
- Raise EInstallerError.CreateFmt(SErrInvalidCPU,[S]);
- Result:=TCPU(I);
- end;
- Function StringToCPUS(const S : String) : TCPUS;
- begin
- Result:=TCPUS(StringToSet(PTypeInfo(TypeInfo(TCPUS)),S));
- end;
- Function ModeToString(Mode: TCompilerMode) : String;
- begin
- Result:=LowerCase(GetenumName(TypeInfo(TCompilerMode),Ord(Mode)));
- Delete(Result,1,2);
- end;
- Function StringToMode(const S : String) : TCompilerMode;
- Var
- I : Integer;
- begin
- I:=GetEnumValue(TypeInfo(TCompilerMode),S);
- if (I=-1) then
- Raise EInstallerError.CreateFmt(SErrInvalidMode,[S]);
- Result:=TCompilerMode(I);
- end;
- Function MakeTargetString(CPU : TCPU;OS: TOS) : String;
- begin
- if OS in AllLimit83fsOses then
- Result := OSToString(OS)
- else
- Result:=CPUToString(CPU)+'-'+OSToString(OS);
- end;
- Procedure StringToCPUOS(const S : String; Var CPU : TCPU; Var OS: TOS);
- Var
- P : integer;
- begin
- P:=Pos('-',S);
- If (P=0) then
- Raise EInstallerError.CreateFmt(SErrInvalidTarget,[S]);
- CPU:=StringToCPU(Copy(S,1,P-1));
- OS:=StringToOs(Copy(S,P+1,Length(S)-P));
- end;
- Procedure ResolveDependencies(L : TDependencies; P : TNamedCollection);
- Var
- I,J : Integer;
- C : TDependency;
- begin
- If Assigned(L) then
- For I:=0 to L.Count-1 do
- begin
- C:=L[i];
- if C.DependencyType in [depPackage,depUnit] then
- begin
- J:=P.IndexOfName(C.Value);
- If J<>-1 then
- C.Target:=P.Items[J];
- end;
- end;
- end;
- function AddConditionalStrings(Dest : TStrings; Src : TConditionalStrings;ACPU:TCPU;AOS:TOS; Const APrefix : String='') : Integer ;
- Var
- I : Integer;
- C : TConditionalString;
- S : String;
- begin
- Result:=0;
- Dictionary.AddVariable('CPU',CPUToString(ACPU));
- Dictionary.AddVariable('OS',OSToString(AOS));
- For I:=0 to Src.Count-1 do
- begin
- C:=Src[I];
- if (ACPU in C.CPUs) and (AOS in C.OSes) then
- begin
- If (APrefix<>'') then
- S:=APrefix+C.Value
- else
- S:=C.Value;
- Dest.Add(Dictionary.ReplaceStrings(S));
- Inc(Result);
- end;
- end;
- end;
- function FileListToString(List : TStrings; const APrefix : String) : String;
- Var
- I : integer;
- S : String;
- begin
- Result:='';
- For I:=0 to List.Count-1 do
- begin
- If (I>0) then
- Result:=Result+' ';
- S:=APrefix+List[i];
- If (Pos(' ',S)<>0) then
- S:='"'+S+'"';
- Result:=Result+S;
- end;
- end;
- function FixPath (const APath : String) : String;
- Var
- P : PChar;
- begin
- Result:=APath;
- If (result<>'') then
- begin
- P:=PChar(Result);
- While (P^<>#0) do
- begin
- If P^ in ['/','\'] then
- P^:=PathDelim;
- Inc(P);
- end;
- end;
- end;
- function IsRelativePath(const APath: String): boolean;
- begin
- if APath='' then
- result := true
- {$ifdef unix}
- else if APath[1] in AllowDirectorySeparators then
- result := false
- {$else}
- else if ExtractFileDrive(APath)<>'' then
- result := false
- {$endif}
- else
- result := true;
- end;
- procedure ChangeDir(const APath : String);
- begin
- if Not SetCurrentDir(APath) then
- Raise EInstallerError.CreateFmt(SErrChangeDirFailed,[APath]);
- end;
- procedure SearchFiles(const AFileName: string; Recursive: boolean; var List: TStrings);
- procedure AddRecursiveFiles(const SearchDir, FileMask: string; Recursive: boolean);
- const
- IgnoreCase = {$ifdef UNIX}False{$else}True{$endif};
- var
- Info : TSearchRec;
- begin
- if FindFirst(SearchDir+'*',faAnyFile and faDirectory,Info)=0 then
- begin
- repeat
- if ((Info.Attr and faDirectory) = faDirectory) and (Info.Name <> '.') and (Info.Name <> '..') and (Recursive) then
- AddRecursiveFiles(SearchDir + Info.Name + PathDelim, FileMask, Recursive);
- if ((Info.Attr and faDirectory) <> faDirectory) and IsWild(Info.Name, FileMask, IgnoreCase) then
- List.Add(SearchDir + Info.Name);
- until FindNext(Info)<>0;
- end;
- FindClose(Info);
- end;
- var
- CurrDir,
- BasePath: string;
- i: integer;
- begin
- BasePath := ExtractFilePath(ExpandFileName(AFileName));
- AddRecursiveFiles(BasePath, ExtractFileName(AFileName), Recursive);
- CurrDir:=GetCurrentDir;
- for i := 0 to Pred(List.Count) do
- List[i] := ExtractRelativepath(IncludeTrailingPathDelimiter(CurrDir), List[i]);
- end;
- Const
- WhiteSpace = [#9,#10,#13,' '];
- QuoteChars = ['''','"'];
- procedure SplitCommand(const Cmd : String; var Exe, Options : String);
- Var
- I : Integer;
- InQuote : Boolean;
- LastQuote : Char;
- S : String;
- begin
- S:=Trim(Cmd);
- InQuote:=False;
- LastQuote:=#0;
- I:=1;
- While (I<=Length(S)) and (Inquote or not (S[I] in whiteSpace)) do
- begin
- If S[i] in QuoteChars then
- begin
- InQuote:=Not (S[i]=LastQuote);
- If InQuote then
- LastQuote:=S[i]
- else
- LastQuote:=#0;
- end;
- Inc(I);
- end;
- Exe:=Copy(S,1,I-1);
- Delete(S,1,I);
- Options:=Trim(S);
- end;
- procedure AddCustomFpmakeCommandlineOption(const ACommandLineOption, HelpMessage : string);
- begin
- if not assigned(CustomFpmakeCommandlineOptions) then
- CustomFpmakeCommandlineOptions := TStringList.Create;
- CustomFpmakeCommandlineOptions.Values[ACommandLineOption]:=HelpMessage;
- end;
- function GetCustomFpmakeCommandlineOptionValue(const ACommandLineOption: string): string;
- begin
- if not assigned(CustomFpMakeCommandlineValues) then
- result := ''
- else
- result := CustomFpMakeCommandlineValues.Values[ACommandLineOption];
- end;
- Function OptionListToString(L : TStrings) : String;
- var
- I : Integer;
- S : String;
- begin
- Result:='';
- For I:=0 to L.Count-1 do
- begin
- If (Result<>'') then
- Result:=Result+' ';
- S:=L[I];
- If (Pos(' ',S)<>0) or (S='') then
- Result:='"'+S+'"';
- end;
- end;
- Function OptionsToStringList(S : String) : TStrings;
- Var
- P : Integer;
- begin
- Result:=Nil;
- If (S='') then
- Exit;
- Result:=TStringList.Create;
- Repeat
- P:=Pos(' ',S);
- If P=0 then
- P:=Length(S)+1;
- Result.Add(Copy(S,1,P-1));
- Delete(S,1,P);
- S:=Trim(S);
- Until Length(S)=0;
- If Result.Count=0 then
- FreeAndNil(Result);
- end;
- {$ifdef HAS_UNIT_PROCESS}
- function GetCompilerInfo(const ACompiler,AOptions:string):string;
- const
- BufSize = 1024;
- var
- S: TProcess;
- Buf: array [0..BufSize - 1] of char;
- Count: longint;
- begin
- S:=TProcess.Create(Nil);
- S.Commandline:=ACompiler+' '+AOptions;
- S.Options:=[poUsePipes];
- S.execute;
- Count:=s.output.read(buf,BufSize);
- S.Free;
- SetLength(Result,Count);
- Move(Buf,Result[1],Count);
- end;
- {$endif HAS_UNIT_PROCESS}
- {****************************************************************************
- TUnsortedDuplicatesStringList
- ****************************************************************************}
- function TUnsortedDuplicatesStringList.Add(const S: string): Integer;
- begin
- result := IndexOf(S);
- If result > -1 then
- Case DUplicates of
- DupIgnore : Exit;
- DupError : Error(SDuplicateString,0)
- end;
- inherited Add(S);
- end;
- {****************************************************************************
- TNamedItem
- ****************************************************************************}
- procedure TNamedItem.SetName(const AValue: String);
- begin
- if FName=AValue then exit;
- With TNamedCollection(Collection) do
- If UniqueNames then
- If (IndexOfName(AVAlue)<>-1) then
- Raise ECollectionError.CreateFmt(SErrNameExists,[AValue]);
- FName:=AValue;
- end;
- {****************************************************************************
- TNamedCollection
- ****************************************************************************}
- function TNamedCollection.IndexOfName(const AName: String): Integer;
- begin
- Result:=Count-1;
- While (Result>=0) and (CompareText(TNamedItem(Items[Result]).FName,AName)<>0) do
- Dec(Result);
- end;
- function TNamedCollection.ItemByName(const AName: String): TNamedItem;
- Var
- I : Integer;
- begin
- I:=IndexOfName(AName);
- If (I=-1) Then
- Raise ECollectionError.CreateFmt(SErrNoSuchName,[AName]);
- Result:=TNamedItem(Items[i]);
- end;
- {****************************************************************************
- TNamedItemList
- ****************************************************************************}
- function TNamedItemList.GetNamedItem(Index : Integer): TNamedItem;
- begin
- Result:=TNamedItem(Items[Index]);
- end;
- procedure TNamedItemList.SetNamedItem(Index : Integer; const AValue: TNamedItem);
- begin
- Items[Index]:=AValue;
- end;
- function TNamedItemList.IndexOfName(const AName: String): Integer;
- begin
- Result:=Count-1;
- While (Result>=0) and (CompareText(GetNamedItem(Result).Name,AName)<>0) do
- Dec(Result);
- end;
- function TNamedItemList.ItemByName(const ANAme: String): TNamedItem;
- Var
- I : Integer;
- begin
- I:=IndexOfName(AName);
- If (I=-1) Then
- Raise ECollectionError.CreateFmt(SErrNoSuchName,[AName]);
- Result:=TNamedItem(Items[i]);
- end;
- {****************************************************************************
- TTargets
- ****************************************************************************}
- function TTargets.GetTargetItem(Index : Integer): TTarget;
- begin
- Result:=TTarget(Items[Index]);
- end;
- function TTargets.GetTarget(const AName : String): TTarget;
- begin
- Result:=TTarget(ItemByName(AName));
- end;
- procedure TTargets.SetTargetItem(Index : Integer; const AValue: TTarget);
- begin
- Items[Index]:=AValue;
- end;
- function TTargets.AddFPDoc(const AUnitName, AXMLName: String): TTarget;
- begin
- Result:=Add as TTarget;
- Result.Name:=AUnitName;
- Result.XML:=AXMLName;
- Result.TargetType:=ttFPDoc;
- end;
- Function TTargets.AddUnit(Const AUnitName : String) : TTarget;
- begin
- Result:=AddUnit(AUnitName,AllCPUs,AllOSes);
- end;
- Function TTargets.AddUnit(Const AUnitName : String;const OSes:TOSes) : TTarget;
- begin
- Result:=AddUnit(AUnitName,AllCPUs,OSes);
- end;
- {$ifdef cpu_only_overloads}
- Function TTargets.AddUnit(Const AUnitName : String;const CPUs:TCPUs) : TTarget;
- begin
- Result:=AddUnit(AUnitName,CPUs,AllOSes);
- end;
- {$endif cpu_only_overloads}
- Function TTargets.AddUnit(Const AUnitName : String;const CPUs:TCPUs;const OSes:TOSes) : TTarget;
- begin
- Result:=Add as TTarget;
- Result.Name:=AUnitName;
- Result.TargetType:=TTUnit;
- Result.CPUs:=CPUs;
- Result.OSes:=OSes;
- end;
- Function TTargets.AddImplicitUnit(Const AUnitName : String;InstallUnit:boolean=true) : TTarget;
- begin
- Result:=AddImplicitUnit(AUnitName,AllCPUs,AllOSes,InstallUnit);
- end;
- Function TTargets.AddImplicitUnit(Const AUnitName : String;const OSes:TOSes;InstallUnit:boolean=true) : TTarget;
- begin
- Result:=AddImplicitUnit(AUnitName,AllCPUs,OSes,InstallUnit);
- end;
- Function TTargets.AddImplicitUnit(Const AUnitName : String;const CPUs:TCPUs;InstallUnit:boolean=true) : TTarget;
- begin
- Result:=AddImplicitUnit(AUnitName,CPUs,AllOSes,InstallUnit);
- end;
- Function TTargets.AddImplicitUnit(Const AUnitName : String;const CPUs:TCPUs;const OSes:TOSes;InstallUnit:boolean=true) : TTarget;
- begin
- Result:=Add as TTarget;
- Result.Name:=AUnitName;
- Result.CPUs:=CPUs;
- Result.OSes:=OSes;
- if InstallUnit then
- Result.TargetType:=TTImplicitUnit
- else
- Result.TargetType:=TTCleanOnlyUnit;
- end;
- Function TTargets.AddProgram(Const AProgramName : String) : TTarget;
- begin
- Result:=AddProgram(AProgramName,AllCPUs,AllOSes);
- end;
- Function TTargets.AddProgram(Const AProgramName : String;const OSes:TOSes) : TTarget;
- begin
- Result:=AddProgram(AProgramName,AllCPUs,OSes);
- end;
- {$ifdef cpu_only_overloads}
- Function TTargets.AddProgram(Const AProgramName : String;const CPUs:TCPUs) : TTarget;
- begin
- Result:=AddProgram(AProgramName,CPUs,AllOSes);
- end;
- {$endif cpu_only_overloads}
- Function TTargets.AddProgram(Const AProgramName : String;const CPUs:TCPUs;const OSes:TOSes) : TTarget;
- begin
- Result:=Add as TTarget;
- Result.Name:=AProgramName;
- Result.CPUs:=CPUs;
- Result.OSes:=OSes;
- Result.TargetType:=ttProgram;
- end;
- Function TTargets.AddExampleUnit(Const AUnitName : String) : TTarget;
- begin
- Result:=AddExampleUnit(AUnitName,AllCPUs,AllOSes);
- end;
- Function TTargets.AddExampleUnit(Const AUnitName : String;const OSes:TOSes) : TTarget;
- begin
- Result:=AddExampleUnit(AUnitName,AllCPUs,OSes);
- end;
- {$ifdef cpu_only_overloads}
- Function TTargets.AddExampleUnit(Const AUnitName : String;const CPUs:TCPUs) : TTarget;
- begin
- Result:=AddExampleUnit(AUnitName,CPUs,AllOSes);
- end;
- {$endif cpu_only_overloads}
- Function TTargets.AddExampleUnit(Const AUnitName : String;const CPUs:TCPUs;const OSes:TOSes) : TTarget;
- begin
- Result:=Add as TTarget;
- Result.Name:=AUnitName;
- Result.CPUs:=CPUs;
- Result.OSes:=OSes;
- Result.TargetType:=ttExampleUnit;
- end;
- Function TTargets.AddExampleProgram(Const AProgramName : String) : TTarget;
- begin
- Result:=AddExampleProgram(AProgramName,AllCPUs,AllOSes);
- end;
- Function TTargets.AddExampleProgram(Const AProgramName : String;const OSes:TOSes) : TTarget;
- begin
- Result:=AddExampleProgram(AProgramName,AllCPUs,OSes);
- end;
- {$ifdef cpu_only_overloads}
- Function TTargets.AddExampleProgram(Const AProgramName : String;const CPUs:TCPUs) : TTarget;
- begin
- Result:=AddExampleProgram(AProgramName,CPUs,AllOSes);
- end;
- {$endif cpu_only_overloads}
- Function TTargets.AddExampleProgram(Const AProgramName : String;const CPUs:TCPUs;const OSes:TOSes) : TTarget;
- begin
- Result:=Add as TTarget;
- Result.Name:=AProgramName;
- Result.CPUs:=CPUs;
- Result.OSes:=OSes;
- Result.TargetType:=ttExampleProgram;
- end;
- {****************************************************************************
- TSources
- ****************************************************************************}
- function TSources.GetSourceItem(Index : Integer): TSource;
- begin
- Result:=TSource(Items[Index]);
- end;
- procedure TSources.SetSourceItem(Index : Integer; const AValue: TSource);
- begin
- Items[Index]:=AValue;
- end;
- function TSources.AddDoc (const AFiles : String) : TSource;
- begin
- Result:=Add as TSource;
- Result.Name:=AFiles;
- Result.FSourceType:=stDoc;
- end;
- function TSources.AddDoc(const AFiles: String; AInstallSourcePath: String): TSource;
- begin
- Result:=Add as TSource;
- Result.Name:=AFiles;
- Result.FInstallSourcePath:=AInstallSourcePath;
- Result.FSourceType:=stDoc;
- end;
- function TSources.AddSrc(const AFiles : String) : TSource;
- begin
- Result:=Add as TSource;
- Result.Name:=AFiles;
- Result.FSourceType:=stSrc;
- end;
- function TSources.AddExample(const AFiles : String) : TSource;
- begin
- Result:=Add as TSource;
- Result.Name:=AFiles;
- Result.FSourceType:=stExample;
- end;
- function TSources.AddExample(const AFiles: String; AInstallSourcePath: String): TSource;
- begin
- Result:=Add as TSource;
- Result.Name:=AFiles;
- Result.FInstallSourcePath:=AInstallSourcePath;
- Result.FSourceType:=stExample;
- end;
- function TSources.AddTest(const AFiles : String) : TSource;
- begin
- Result:=Add as TSource;
- Result.Name:=AFiles;
- Result.FSourceType:=stTest;
- end;
- procedure TSources.AddDocFiles(const AFileMask: string; Recursive: boolean; AInstallSourcePath : String = '');
- var
- List : TStrings;
- i: integer;
- begin
- List := TStringList.Create;
- SearchFiles(AFileMask, Recursive, List);
- for i:= 0 to Pred(List.Count) do
- AddDoc(List[i], AInstallSourcePath);
- List.Free;
- end;
- procedure TSources.AddSrcFiles(const AFileMask: string; Recursive: boolean);
- var
- List : TStrings;
- i: integer;
- begin
- List := TStringList.Create;
- SearchFiles(AFileMask, Recursive, List);
- for i:= 0 to Pred(List.Count) do
- AddSrc(List[i]);
- List.Free;
- end;
- procedure TSources.AddExampleFiles(const AFileMask: string; Recursive: boolean; AInstallSourcePath : String = '');
- var
- List : TStrings;
- i: integer;
- begin
- List := TStringList.Create;
- SearchFiles(AFileMask, Recursive, List);
- for i:= 0 to Pred(List.Count) do
- AddExample(List[i], AInstallSourcePath);
- List.Free;
- end;
- procedure TSources.AddTestFiles(const AFileMask: string; Recursive: boolean);
- var
- List : TStrings;
- i: integer;
- begin
- List := TStringList.Create;
- SearchFiles(AFileMask, Recursive, List);
- for i:= 0 to Pred(List.Count) do
- AddTest(List[i]);
- List.Free;
- end;
- {****************************************************************************
- TPackage
- ****************************************************************************}
- constructor TPackage.Create(ACollection: TCollection);
- begin
- inherited Create(ACollection);
- FVersion:=TFPVersion.Create;
- FTargets:=TTargets.Create(TTarget);
- FSources:=TSources.Create(TSource);
- FDependencies:=TDependencies.Create(TDependency);
- FInstallFiles:=TConditionalStrings.Create(TConditionalString);
- FCleanFiles:=TConditionalStrings.Create(TConditionalString);
- FUnitPath:=TConditionalStrings.Create(TConditionalString);
- FObjectPath:=TConditionalStrings.Create(TConditionalString);
- FIncludePath:=TConditionalStrings.Create(TConditionalString);
- FSourcePath:=TConditionalStrings.Create(TConditionalString);
- FExamplePath:=TConditionalStrings.Create(TConditionalString);
- FTestPath:=TConditionalStrings.Create(TConditionalString);
- FCommands:=TCommands.Create(TCommand);
- FCPUs:=AllCPUs;
- FOSes:=AllOSes;
- FInstalledChecksum:=$ffffffff;
- // Implicit dependency on RTL
- FDependencies.Add('rtl');
- FSupportBuildModes:=[bmBuildUnit, bmOneByOne];
- end;
- destructor TPackage.destroy;
- begin
- FreeAndNil(FDependencies);
- FreeAndNil(FInstallFiles);
- FreeAndNil(FCleanFiles);
- FreeAndNil(FIncludePath);
- FreeAndNil(FSourcePath);
- FreeAndNil(FExamplePath);
- FreeAndNil(FTestPath);
- FreeAndNil(FObjectPath);
- FreeAndNil(FUnitPath);
- FreeAndNil(FSources);
- FreeAndNil(FTargets);
- FreeAndNil(FVersion);
- FreeAndNil(FOptions);
- inherited destroy;
- end;
- function TPackage.HaveOptions: Boolean;
- begin
- Result:=(FOptions<>Nil);
- end;
- procedure TPackage.SetName(const AValue: String);
- begin
- inherited SetName(AValue);
- // RTL should not have any dependencies
- if AValue='rtl' then
- FDependencies.Clear;
- end;
- Function TPackage.GetUnitsOutputDir(ACPU:TCPU; AOS : TOS):String;
- begin
- Result:='units'+PathDelim+MakeTargetString(ACPU,AOS);
- end;
- Function TPackage.GetBinOutputDir(ACPU:TCPU; AOS : TOS) : String;
- begin
- Result:='bin'+PathDelim+MakeTargetString(ACPU,AOS);
- end;
- procedure TPackage.GetCleanFiles(List: TStrings; ACPU:TCPU; AOS : TOS);
- Var
- OB,OU : String;
- I : Integer;
- begin
- OB:=IncludeTrailingPathDelimiter(GetBinOutputDir(ACPU,AOS));
- OU:=IncludeTrailingPathDelimiter(GetUnitsOutputDir(ACPU,AOS));
- AddConditionalStrings(List,CleanFiles,ACPU,AOS);
- For I:=0 to FTargets.Count-1 do
- FTargets.TargetItems[I].GetCleanFiles(List, OU, OB, ACPU, AOS);
- end;
- procedure TPackage.GetInstallFiles(List: TStrings;Types : TTargetTypes;ACPU:TCPU; AOS : TOS);
- Var
- OB,OU : String;
- I : Integer;
- T : TTarget;
- begin
- OB:=IncludeTrailingPathDelimiter(GetBinOutputDir(Defaults.CPU,Defaults.OS));
- OU:=IncludeTrailingPathDelimiter(GetUnitsOutputDir(Defaults.CPU,Defaults.OS));
- AddConditionalStrings(List,InstallFiles,ACPU,AOS);
- For I:=0 to FTargets.Count-1 do
- begin
- T:=FTargets.TargetItems[I];
- if (T.TargetType in Types) and (T.Install) then
- T.GetInstallFiles(List, OU, OB, ACPU, AOS);
- end;
- end;
- procedure TPackage.GetInstallSourceFiles(List: TStrings; SourceTypes : TSourceTypes; TargetTypes : TTargetTypes);
- Var
- I : Integer;
- S : TSource;
- T : TTarget;
- begin
- For I:=0 to FSources.Count-1 do
- begin
- S:=FSources.SourceItems[I];
- if (S.SourceType in SourceTypes) then
- S.GetInstallFiles(List);
- end;
- For I:=0 to FTargets.Count-1 do
- begin
- T:=FTargets.TargetItems[I];
- if (T.TargetType in TargetTypes) then
- T.GetArchiveFiles(List,Defaults.CPU,Defaults.OS);
- end;
- end;
- procedure TPackage.GetArchiveFiles(List: TStrings; ACPU:TCPU; AOS : TOS);
- Var
- I : Integer;
- begin
- // Targets only
- For I:=0 to FTargets.Count-1 do
- FTargets.TargetItems[I].GetArchiveFiles(List,ACPU,AOS);
- end;
- procedure TPackage.GetArchiveSourceFiles(List: TStrings);
- var
- i : integer;
- begin
- for i := 0 to Sources.Count-1 do
- List.Add(Sources[i].Name);
- end;
- Function TPackage.GetDescription : string;
- Var
- FN : String;
- L : TStringList;
- begin
- If (FDescription<>'') then
- Result:=FDescription
- else
- If (FDescriptionFile<>'') then
- begin
- // Always relative to binary name.
- FN:=ExtractFilePath(ParamStr(0));
- FN:=FN+FDescriptionFile;
- If FileExists(FN) then
- begin
- L:=TStringList.Create;
- Try
- L.LoadFromFile(FN);
- Result:=L.Text;
- Finally
- L.Free;
- end;
- end;
- end;
- end;
- Function TPackage.GetVersion : string;
- begin
- result:=FVersion.AsString;
- end;
- procedure TPackage.SetOptions(const AValue: TStrings);
- begin
- If (AValue=Nil) or (AValue.Count=0) then
- FreeAndNil(Foptions)
- else
- Options.Assign(AValue);
- end;
- Procedure TPackage.SetVersion(const V : string);
- begin
- FVersion.AsString:=V;
- end;
- Function TPackage.GetFileName : string;
- begin
- If (FFileName<>'') then
- Result:=FFileName
- else
- if not FVersion.Empty then
- Result := Name + '-' + FVersion.AsString
- else
- Result := Name;
- end;
- function TPackage.GetOptions: TStrings;
- begin
- If (FOptions=Nil) then
- FOptions:=TStringList.Create;
- Result:=FOptions;
- end;
- Procedure TPackage.GetManifest(Manifest : TStrings);
- procedure AddOSes(const AIndent:string;AOSes:TOSes);
- var
- IOS : TOS;
- begin
- if (AOSes=AllOSes) then
- exit;
- Manifest.Add(AIndent+'<oses>');
- for IOS:=low(TOSes) to high(TOSes) do
- if IOS in AOSes then
- Manifest.Add(Format(AIndent+' <os name="%s"/>',[OSToString(IOS)]));
- Manifest.Add(AIndent+'</oses>');
- end;
- procedure AddCPUs(const AIndent:string;ACPUs:TCPUs);
- var
- ICPU : TCPU;
- begin
- if (ACPUs=AllCPUs) then
- exit;
- Manifest.Add(AIndent+'<cpus>');
- for ICPU:=low(TCPUs) to high(TCPUs) do
- if ICPU in ACPUs then
- Manifest.Add(Format(AIndent+' <cpu name="%s"/>',[CPUToString(ICPU)]));
- Manifest.Add(AIndent+'</cpus>');
- end;
- function GetXMLVersionString(sMajor, sMinor, sMicro, sBuild: integer): string;
- begin
- Result := '<version';
- if sMajor <> -1 then
- Result := Result + ' major="' + IntToStr(sMajor) + '"';
- if sMinor <> -1 then
- Result := Result + ' minor="' + IntToStr(sMinor) + '"';
- if sMicro <> -1 then
- Result := Result + ' micro="' + IntToStr(sMicro) + '"';
- if sBuild <> -1 then
- Result := Result + ' build="' + IntToStr(sBuild) + '"';
- Result := Result + '/>';
- end;
- Var
- S : String;
- i : Integer;
- D : TDependency;
- begin
- With Manifest do
- begin
- Add(Format('<package name="%s">',[QuoteXml(Name)]));
- Add(' ' + GetXMLVersionString(FVersion.Major,FVersion.Minor,FVersion.Micro,FVersion.Build));
- AddOSes(' ',OSes);
- AddCPUs(' ',CPUs);
- Add(Format(' <filename>%s</filename>',[QuoteXml(FileName + ZipExt)]));
- Add(Format(' <author>%s</author>',[QuoteXml(Author)]));
- Add(Format(' <license>%s</license>',[QuoteXml(License)]));
- if HomepageURL<>'' then
- Add(Format(' <homepageurl>%s</homepageurl>',[QuoteXml(HomepageURL)]));
- if DownloadURL<>'' then
- Add(Format(' <downloadurl>%s</downloadurl>',[QuoteXml(DownloadURL)]));
- Add(Format(' <email>%s</email>',[QuoteXMl(Email)]));
- S:=Description;
- If (S<>'') then
- Add(Format(' <description>%s</description>',[QuoteXML(S)]));
- If (Dependencies.Count>0) then
- begin
- Add(' <dependencies>');
- for I:=0 to Dependencies.Count-1 do
- begin
- D:=Dependencies[i];
- Add(' <dependency>');
- Add(Format(' <package packagename="%s"/>',[QuoteXML(D.Value)]));
- if not D.FVersion.Empty then
- Add(' ' + GetXMLVersionString(D.FVersion.Major,D.FVersion.Minor,D.FVersion.Micro,D.FVersion.Build));
- AddOSes(' ',D.OSes);
- AddCPUs(' ',D.CPUs);
- Add(' </dependency>');
- end;
- Add(' </dependencies>');
- end;
- Add('</package>');
- end;
- end;
- procedure TPackage.LoadUnitConfigFromFile(Const AFileName: String);
- var
- L,L2 : TStrings;
- VOS : TOS;
- VCPU : TCPU;
- i,k : Integer;
- DepChecksum : Cardinal;
- DepName : String;
- D : TDependency;
- begin
- L:=TStringList.Create;
- Try
- ReadIniFile(AFileName,L);
- With L do
- begin
- Version:=Values[KeyVersion];
- InstalledChecksum:=Cardinal(StrToInt64Def(Values[KeyChecksum],$ffffffff));
- VCPU:=StringToCPU(Values[KeyCPU]);
- VOS:=StringToOS(Values[KeyOS]);
- OSes:=[VOS];
- CPUs:=[VCPU];
- L2:=TStringList.Create;
- L2.CommaText:=Values[KeyDepends];
- for i:=0 to L2.Count-1 do
- begin
- DepName:=L2[i];
- k:=Pos('|',DepName);
- if k>0 then
- begin
- DepChecksum:=StrToInt(Copy(DepName,k+1,Length(DepName)-k));
- DepName:=Copy(DepName,1,k-1);
- end
- else
- DepChecksum:=$ffffffff;
- D:=Dependencies.Add(DepName,CPUs,OSes);
- D.RequireChecksum:=DepChecksum;
- end;
- FreeAndNil(L2);
- NeedLibC:=Upcase(Values[KeyNeedLibC])='Y';
- IsFPMakeAddIn:=Upcase(Values[KeyAddIn])='Y';
- end;
- Finally
- L.Free;
- end;
- end;
- procedure TPackage.SaveUnitConfigToStringList(const AStringList: TStrings; ACPU: TCPU; AOS: TOS);
- Var
- Deps : String;
- i : integer;
- D : TDependency;
- p : TPackage;
- begin
- with AStringList do
- begin
- Values[KeyName]:=Name;
- Values[KeyVersion]:=Version;
- // TODO Generate checksum based on PPUs
- Values[KeyChecksum]:=IntToStr(DateTimeToFileDate(Now));
- Values[KeyCPU]:=CPUToString(ACPU);
- Values[KeyOS]:=OSToString(AOS);
- //Installer;
- Values[KeySourcePath]:=IncludeTrailingPathDelimiter(IncludeTrailingPathDelimiter(Installer.BuildEngine.FStartDir)+Directory);
- Values[KeyFPMakeOptions]:=trim(Installer.FPMakeOptionsString);
- Deps:='';
- for i:=0 to Dependencies.Count-1 do
- begin
- D:=Dependencies[i];
- if (ACPU in D.CPUs) and (AOS in D.OSes) then
- begin
- if Deps<>'' then
- Deps:=Deps+',';
- Deps:=Deps+D.Value;
- P:=TPackage(D.Target);
- if assigned(P) and (P.InstalledChecksum<>$ffffffff) then
- Deps:=Deps+'|'+IntToStr(P.InstalledChecksum);
- end;
- end;
- Values[KeyDepends]:=Deps;
- if NeedLibC then
- Values[KeyNeedLibC]:='Y'
- else
- Values[KeyNeedLibC]:='N';
- if IsFPMakeAddIn then
- Values[KeyAddIn]:='Y'
- else
- Values[KeyAddIn]:='N';
- end;
- end;
- procedure TPackage.SaveUnitConfigToFile(Const AFileName: String;ACPU:TCPU;AOS:TOS);
- Var
- F : TFileStream;
- L : TStringList;
- begin
- F:=TFileStream.Create(AFileName,fmCreate);
- L:=TStringList.Create;
- try
- SaveUnitConfigToStringList(L,ACPU,AOS);
- L.SaveToStream(F);
- Finally
- L.Free;
- F.Free;
- end;
- end;
- {****************************************************************************
- TPackages
- ****************************************************************************}
- function TPackages.GetPackage(const AName : String): TPackage;
- begin
- Result:=TPackage(ItemByName(AName))
- end;
- function TPackages.GetPackageItem(AIndex : Integer): TPackage;
- begin
- Result:=TPackage(Items[AIndex]);
- end;
- procedure TPackages.SetPackageItem(AIndex : Integer; const AValue: TPackage);
- begin
- Items[AIndex]:=AValue;
- end;
- function TPackages.AddPackage(const AName: String): TPackage;
- begin
- Result:=Add as TPackage;
- Result.Name:=AName;
- end;
- {****************************************************************************
- TCustomDefaults
- ****************************************************************************}
- procedure TCustomDefaults.SetCPU(const AValue: TCPU);
- begin
- FCPU:=AValue;
- RecalcTarget;
- end;
- procedure TCustomDefaults.SetOptions(const AValue: TStrings);
- begin
- If (AValue=Nil) or (AValue.Count=0) then
- FreeAndNil(Foptions)
- else
- Options.Assign(AValue)
- end;
- function TCustomDefaults.GetBaseInstallDir: String;
- begin
- If (FBaseInstallDir<>'') then
- Result:=FBaseInstallDir
- else
- if UnixPaths then
- Result:=Prefix +'lib' + PathDelim + 'fpc' + PathDelim + FCompilerVersion + PathDelim
- else
- Result:=Prefix;
- end;
- function TCustomDefaults.GetBinInstallDir: String;
- begin
- If (FBinInstallDir<>'') then
- Result:=FBinInstallDir
- else
- If UnixPaths then
- Result:=Prefix+'bin'
- else
- Result:=BaseInstallDir+'bin';
- end;
- function TCustomDefaults.GetCompiler: String;
- begin
- If (FCompiler<>'') then
- Result:=FCompiler
- else
- Result:='fpc';
- end;
- function TCustomDefaults.GetDocInstallDir: String;
- begin
- If (FDocInstallDir<>'') then
- Result:=FDocInstallDir
- else
- If UnixPaths then
- Result:=Prefix+'share'+PathDelim+'doc'
- else
- Result:=BaseInstallDir+'docs';
- end;
- function TCustomDefaults.GetExamplesInstallDir: String;
- begin
- If (FExamplesInstallDir<>'') then
- Result:=FExamplesInstallDir
- else
- If UnixPaths then
- Result:=Prefix+'share'+PathDelim+'doc'
- else
- Result:=BaseInstallDir+'examples';
- end;
- function TCustomDefaults.GetOptions: TStrings;
- begin
- If (FOptions=Nil) then
- FOptions:=TStringList.Create;
- Result:=FOptions;
- end;
- function TCustomDefaults.GetUnitInstallDir: String;
- begin
- Dictionary.AddVariable('target',Target);
- Dictionary.AddVariable('BaseInstallDir',BaseInstallDir);
- result := FixPath(Dictionary.ReplaceStrings(FUnitInstallDir));
- end;
- function TCustomDefaults.GetLocalUnitDir: String;
- begin
- Result:=FLocalUnitDir;
- end;
- function TCustomDefaults.GetFPDocOutputDir: String;
- begin
- If (FFPDocOutputDir<>'') then
- Result:=IncludeTrailingPathDelimiter(FixPath(FFPDocOutputDir))
- else
- Result:=IncludeTrailingPathDelimiter(FixPath('.'+PathDelim+'docs'));
- end;
- function TCustomDefaults.GetGlobalUnitDir: String;
- begin
- If (FGlobalUnitDir<>'') then
- Result:=FGlobalUnitDir
- else
- Result:=UnitInstallDir;
- end;
- procedure TCustomDefaults.SetLocalUnitDir(const AValue: String);
- begin
- // Use ExpandFileName to support ~/ expansion
- if AValue<>'' then
- FLocalUnitDir:=IncludeTrailingPathDelimiter(ExpandFileName(AValue))
- else
- FLocalUnitDir:='';
- end;
- procedure TCustomDefaults.SetGlobalUnitDir(const AValue: String);
- begin
- // Use ExpandFileName to support ~/ expansion
- if AValue<>'' then
- FGlobalUnitDir:=IncludeTrailingPathDelimiter(ExpandFileName(AValue))
- else
- FGlobalUnitDir:='';
- end;
- procedure TCustomDefaults.SetBaseInstallDir(const AValue: String);
- begin
- // Use ExpandFileName to support ~/ expansion
- if AValue<>'' then
- FBaseInstallDir:=IncludeTrailingPathDelimiter(ExpandFileName(AValue))
- else
- FBaseInstallDir:='';
- BinInstallDir:='';
- ExamplesInstallDir:='';
- end;
- procedure TCustomDefaults.SetOS(const AValue: TOS);
- begin
- FOS:=AValue;
- Recalctarget;
- end;
- procedure TCustomDefaults.SetPrefix(const AValue: String);
- begin
- if FPrefix=AValue then exit;
- FPrefix:=IncludeTrailingPathDelimiter(AValue);
- BaseInstallDir:='';
- end;
- procedure TCustomDefaults.SetTarget(const AValue: String);
- Var
- P : Integer;
- begin
- if FTarget<>AValue then
- begin
- P:=Pos('-',AValue);
- If (P<>0) then
- begin
- FOS:=StringToOS(System.Copy(Avalue,P+1,Length(AValue)-P));
- FCPU:=StringToCPU(System.Copy(Avalue,1,P-1));
- end
- else
- FOS:=StringToOS(AValue);
- FTarget:=AValue;
- end;
- end;
- procedure TCustomDefaults.SetUnitInstallDir(const AValue: String);
- begin
- if AValue<>'' then
- FUnitInstallDir:=IncludeTrailingPathDelimiter(AValue)
- else
- FUnitInstallDir:='';
- end;
- procedure TCustomDefaults.RecalcTarget;
- begin
- Ftarget:=CPUToString(FCPU)+'-'+OStoString(FOS);
- end;
- function TCustomDefaults.CmdLineOptions: String;
- begin
- If Haveoptions then
- Result:=OptionListToString(FOptions);
- end;
- constructor TCustomDefaults.Create;
- begin
- InitDefaults;
- end;
- procedure TCustomDefaults.InitDefaults;
- begin
- {$ifdef unix}
- UnixPaths:=True;
- {$else}
- UnixPaths:=False;
- {$endif}
- FNoFPCCfg:=False;
- FCPU:=cpuNone;
- FOS:=osNone;
- FUnitInstallDir:='$(BaseInstallDir)units/$(target)/$(packagename)';
- FBuildMode:=bmOneByOne;
- end;
- function TCustomDefaults.HaveOptions: Boolean;
- begin
- Result:=Assigned(FOptions);
- end;
- procedure TCustomDefaults.LocalInit(Const AFileName : String);
- Var
- FN : String;
- begin
- FN:=AFileName;
- If (FN='') then
- begin
- // Environment variable.
- FN:=GetEnvironmentVariable('FPMAKECFG');
- If (FN<>'') then
- If not FileExists(FN) then
- FN:='';
- // User config file fpmake.cfg
- If (FN='') then
- begin
- FN:=GetAppConfigFile(False);
- If Not FileExists(FN) then
- FN:='';
- end;
- // Global config file fpmake.cfg
- If (FN='') then
- begin
- FN:=GetAppConfigFile(True);
- If Not FileExists(FN) then
- FN:='';
- end;
- end;
- If (FN<>'') and FileExists(FN) then
- LoadFromFile(FN);
- end;
- procedure TCustomDefaults.CompilerDefaults;
- {$ifdef HAS_UNIT_PROCESS}
- var
- infoSL : TStringList;
- {$endif HAS_UNIT_PROCESS}
- begin
- if (CPU=cpuNone) or (OS=osNone) or (FCompilerVersion='') then
- begin
- {$ifdef HAS_UNIT_PROCESS}
- // Detect compiler version/target from -i option
- infosl:=TStringList.Create;
- infosl.Delimiter:=' ';
- infosl.DelimitedText:=GetCompilerInfo(GetCompiler,'-iVTPTO');
- if infosl.Count<>3 then
- Raise EInstallerError.Create(SErrInvalidFPCInfo);
- if FCompilerVersion='' then
- FCompilerVersion:=infosl[0];
- if CPU=cpuNone then
- CPU:=StringToCPU(infosl[1]);
- if OS=osNone then
- OS:=StringToOS(infosl[2]);
- {$else HAS_UNIT_PROCESS}
- // Defaults taken from compiler used to build fpmake
- if CPU=cpuNone then
- CPU:=StringToCPU({$I %FPCTARGETCPU%});
- if OS=osNone then
- OS:=StringToOS({$I %FPCTARGETOS%});
- if FCompilerVersion='' then
- FCompilerVersion:={$I %FPCVERSION%};
- {$endif HAS_UNIT_PROCESS}
- end;
- end;
- procedure TCustomDefaults.LoadFromFile(Const AFileName: String);
- Var
- F : TFileStream;
- begin
- F:=TFileStream.Create(AFileName,fmOpenRead);
- Try
- LoadFromStream(F);
- Finally
- F.Free;
- end;
- end;
- procedure TCustomDefaults.SaveToFile(Const AFileName: String);
- Var
- F : TFileStream;
- begin
- F:=TFileStream.Create(AFileName,fmCreate);
- Try
- SaveToStream(F);
- Finally
- F.Free;
- end;
- end;
- procedure TCustomDefaults.SaveToStream(S : TStream);
- Var
- L : TStringList;
- begin
- L:=TStringList.Create;
- try
- With L do
- begin
- Values[KeyArchive]:=FArchive;
- Values[KeyCompiler]:=FCompiler;
- Values[KeyCopy]:=FCopy;
- Values[KeyMkDir]:=FMkDir;
- Values[KeyMove]:=FMove;
- Values[KeyOptions]:=CmdLineOptions;
- Values[KeyCPU]:=CPUToString(FCPU);
- Values[KeyOS]:=OSToString(FOS);
- Values[KeyMode]:=ModeToString(FMode);
- Values[KeyLocalUnitDir]:=FLocalUnitDir;
- Values[KeyGlobalUnitDir]:=FGlobalUnitDir;
- Values[KeyPrefix]:=FPrefix;
- Values[KeyBaseInstallDir]:=FBaseInstallDir;
- Values[KeyUnitInstallDir]:=FUnitInstallDir;
- Values[KeyBinInstallDir]:=FBinInstallDir;
- Values[KeyDocInstallDir]:=FDocInstallDir;
- Values[KeyExamplesInstallDir]:=FExamplesInstallDir;
- Values[KeyRemove]:=FRemove;
- Values[KeyRemoveDir]:=FRemoveDir;
- Values[KeyRemoveTree]:=FRemoveTree;
- Values[KeyTarget]:=FTarget;
- if FNoFPCCfg then
- Values[KeyNoFPCCfg]:='Y';
- if FUseEnvironment then
- Values[KeyUseEnv]:='Y';
- if FInstallExamples then
- Values[KeyInstallExamples]:='Y';
- end;
- L.SaveToStream(S);
- Finally
- L.Free;
- end;
- end;
- procedure TCustomDefaults.LoadFromStream(S: TStream);
- Var
- L : TStrings;
- Line : String;
- I,P,PC : Integer;
- begin
- L:=TStringList.Create;
- Try
- L.LoadFromStream(S);
- // Fix lines.
- For I:=L.Count-1 downto 0 do
- begin
- Line:=L[I];
- P:=Pos('=',Line);
- PC:=Pos(';',Line); // Comment line.
- If (P=0) or ((PC<>0) and (PC<P)) then
- L.Delete(I)
- else
- L[i]:=Trim(System.Copy(Line,1,P-1)+'='+Trim(System.Copy(Line,P+1,Length(Line)-P)));
- end;
- With L do
- begin
- FArchive:=Values[KeyArchive];
- FCompiler:=Values[KeyCompiler];
- FCopy:=Values[KeyCopy];
- FMkDir:=Values[KeyMkDir];
- FMove:=Values[KeyMove];
- FRemove:=Values[KeyRemove];
- FRemoveDir:=Values[KeyRemoveDir];
- FRemoveTree:=Values[KeyRemoveTree];
- Options:=OptionsToStringList(Values[KeyOptions]);
- Line:=Values[KeyCPU];
- If (Line<>'') then
- FCPU:=StringToCPU(Line);
- Line:=Values[KeyOS];
- If (Line<>'') then
- FOS:=StringToOS(Line);
- Line:=Values[KeyMode];
- If (Line<>'') then
- FMode:=StringToMode(Line);
- FTarget:=Values[KeyTarget];
- FLocalUnitDir:=Values[KeyLocalUnitDir];
- FGlobalUnitDir:=Values[KeyGlobalUnitDir];
- FPrefix:=Values[KeyPrefix];
- FBaseInstallDir:=Values[KeyBaseInstallDir];
- FUnitInstallDir:=Values[KeyUnitInstallDir];
- FBinInstallDir:=Values[KeyBinInstallDir];
- FDocInstallDir:=Values[KeyDocInstallDir];
- FExamplesInstallDir:=Values[KeyExamplesInstallDir];
- FInstallExamples:=(Upcase(Values[KeyInstallExamples])='Y');
- FNoFPCCfg:=(Upcase(Values[KeyNoFPCCfg])='Y');
- FUseEnvironment:=(Upcase(Values[KeyUseEnv])='Y');
- end;
- Finally
- L.Free;
- end;
- end;
- {****************************************************************************
- TFPCDefaults
- ****************************************************************************}
- procedure TFPCDefaults.CompilerDefaults;
- var
- BD : String;
- begin
- inherited CompilerDefaults;
- // Use the same algorithm as the compiler, see options.pas
- {$ifdef Unix}
- BD:=FixPath(GetEnvironmentVariable('FPCDIR'));
- if BD='' then
- begin
- BD:='/usr/local/lib/fpc/'+FCompilerVersion;
- if not DirectoryExists(BD) and
- DirectoryExists('/usr/lib/fpc/'+FCompilerVersion) then
- BD:='/usr/lib/fpc/'+FCompilerVersion;
- end;
- {$else unix}
- BD:=FixPath(GetEnvironmentVariable('FPCDIR'));
- if BD='' then
- begin
- BD:=ExtractFilePath(FCompiler)+'..';
- if not(DirectoryExists(BD+'/units')) and
- not(DirectoryExists(BD+'/rtl')) then
- BD:=FBaseInstallDir+'..';
- end;
- {$endif unix}
- // Where to install by default
- if (FBaseInstallDir='') and (FPrefix='') then
- BaseInstallDir:=BD;
- // Where to find the units by default
- if (FGlobalUnitDir='') then
- GlobalUnitDir:=IncludeTrailingPathDelimiter(BD)+'units'+PathDelim+Target;
- end;
- {****************************************************************************
- TCustomInstaller
- ****************************************************************************}
- constructor TCustomInstaller.Create(AOwner: TComponent);
- begin
- Dictionary:=DictionaryClass.Create(Nil);
- AnalyzeOptions;
- CreatePackages;
- end;
- destructor TCustomInstaller.Destroy;
- begin
- FreePackages;
- FreeAndNil(Defaults);
- FreeAndNil(Dictionary);
- inherited destroy;
- end;
- function TCustomInstaller.GetPackages: TPackages;
- begin
- result := FPackages;
- end;
- procedure TCustomInstaller.Log(Level: TVerboseLevel; const Msg: String);
- begin
- If Level in FLogLevels then
- Writeln(StdOut,Msg);
- end;
- procedure TCustomInstaller.CreatePackages;
- begin
- FPackages:=TPackages.Create(TPackage);
- end;
- procedure TCustomInstaller.FreePackages;
- begin
- FreeAndNil(FPackages);
- end;
- procedure TCustomInstaller.CreateBuildEngine;
- begin
- FBuildEngine:=TBuildEngine.Create(Self);
- // FBuildEngine.Defaults:=Defaults;
- FBuildEngine.ListMode:=FListMode;
- FBuildEngine.Verbose := (FLogLevels = AllMessages);
- FBuildEngine.OnLog:[email protected];
- end;
- procedure TCustomInstaller.Error(const Msg: String);
- begin
- Raise EInstallerError.Create(Msg);
- end;
- procedure TCustomInstaller.Error(const Fmt: String; Args: array of const);
- begin
- Raise EInstallerError.CreateFmt(Fmt,Args);
- end;
- Function TCustomInstaller.AddPackage(const AName: String) : TPackage;
- begin
- result:=Packages.AddPackage(AName);
- end;
- procedure TCustomInstaller.AnalyzeOptions;
- Function CheckOption(Index : Integer;const Short,Long : String; AddToOptionString: boolean = true): Boolean;
- var
- O : String;
- begin
- O:=Paramstr(Index);
- Result:=(O='-'+short) or (O='--'+long) or (copy(O,1,Length(Long)+3)=('--'+long+'='));
- if AddToOptionString and Result then FFPMakeOptionsString := FFPMakeOptionsString+' '+O;
- end;
- Function CheckCustomOption(Index : Integer; out CustOptName: string): Boolean;
- var
- O : String;
- i : integer;
- begin
- result := false;
- CustOptName:='';
- O:=Paramstr(Index);
- if copy(O,1,2)<>'--' then
- Exit;
- i := pos('=',O);
- if i=0 then
- Exit;
- O:=copy(O,3,i-3);
- CustOptName:=O;
- Result:=CustomFpmakeCommandlineOptions.IndexOfName(O)>-1;
- if Result then FFPMakeOptionsString := FFPMakeOptionsString+' '+Paramstr(Index);
- end;
- Function CheckCommand(Index : Integer;const Short,Long : String): Boolean;
- var
- O : String;
- begin
- O:=Paramstr(Index);
- Result:=(O='-'+short) or (O=long);
- end;
- Function OptionArg(Var Index : Integer) : String;
- Var
- P : Integer;
- begin
- if (Length(ParamStr(Index))>1) and (Paramstr(Index)[2]<>'-') then
- begin
- If Index<ParamCount then
- begin
- Inc(Index);
- Result:=Paramstr(Index);
- end
- else
- Error(SErrNeedArgument,[Index,ParamStr(Index)]);
- end
- else If length(ParamStr(Index))>2 then
- begin
- P:=Pos('=',Paramstr(Index));
- If (P=0) then
- Error(SErrNeedArgument,[Index,ParamStr(Index)])
- else
- begin
- Result:=Paramstr(Index);
- Delete(Result,1,P);
- end;
- end;
- end;
- function SplitSpaces(var SplitString: string) : string;
- var i : integer;
- begin
- i := pos(' ',SplitString);
- if i > 0 then
- begin
- result := copy(SplitString,1,i-1);
- delete(SplitString,1,i);
- end
- else
- begin
- result := SplitString;
- SplitString:='';
- end;
- end;
- Var
- I : Integer;
- DefaultsFileName : string;
- OptString : string;
- CustOptName : string;
- begin
- I:=0;
- FListMode:=False;
- FLogLevels:=DefaultMessages;
- While (I<ParamCount) do
- begin
- Inc(I);
- if CheckOption(I,'v','verbose',false) then
- FLogLevels:=AllMessages
- else if CheckOption(I,'d','debug',false) then
- FLogLevels:=AllMessages+[vlDebug]
- else if CheckCommand(I,'m','compile') then
- FRunMode:=rmCompile
- else if CheckCommand(I,'b','build') then
- FRunMode:=rmBuild
- else if CheckCommand(I,'i','install') then
- FRunMode:=rmInstall
- else if CheckCommand(I,'c','clean') then
- FRunMode:=rmClean
- else if CheckCommand(I,'dc','distclean') then
- FRunMode:=rmDistClean
- else if CheckCommand(I,'a','archive') then
- FRunMode:=rmarchive
- else if CheckCommand(I,'M','manifest') then
- FRunMode:=rmManifest
- else if CheckOption(I,'h','help') then
- Usage('',[])
- else if Checkoption(I,'C','cpu') then
- Defaults.CPU:=StringToCPU(OptionArg(I))
- else if Checkoption(I,'O','os') then
- Defaults.OS:=StringToOS(OptionArg(I))
- else if Checkoption(I,'t','target') then
- Defaults.Target:=OptionArg(I)
- else if CheckOption(I,'l','list-commands') then
- FListMode:=True
- else if Checkoption(I,'P','prefix') then
- Defaults.Prefix:=OptionArg(I)
- else if Checkoption(I,'n','nofpccfg') then
- Defaults.NoFPCCfg:=true
- {$ifdef HAS_UNIT_PROCESS}
- else if Checkoption(I,'e','useenv') then
- Defaults.UseEnvironment:=true
- {$endif}
- else if CheckOption(I,'B','baseinstalldir') then
- Defaults.BaseInstallDir:=OptionArg(I)
- else if CheckOption(I,'U','unitinstalldir') then
- Defaults.UnitInstallDir:=OptionArg(I)
- else if CheckOption(I,'UL','localunitdir') then
- Defaults.LocalUnitDir:=OptionArg(I)
- else if CheckOption(I,'UG','globalunitdir') then
- Defaults.GlobalUnitDir:=OptionArg(I)
- else if CheckOption(I,'o','options') then
- begin
- OptString := OptionArg(I);
- while OptString <> '' do
- Defaults.Options.Add(SplitSpaces(OptString));
- end
- else if CheckOption(I,'r','compiler') then
- Defaults.Compiler:=OptionArg(I)
- else if CheckOption(I,'f','config') then
- DefaultsFileName:=OptionArg(I)
- else if CheckOption(I,'ie','installexamples') then
- Defaults.InstallExamples:=true
- else if CheckOption(I,'bu','buildunit') then
- Defaults.BuildMode:=bmBuildUnit
- else if CheckOption(I,'io','ignoreinvalidoption') then
- Defaults.IgnoreInvalidOptions:=true
- else if CheckOption(I,'d','doc-folder') then
- Defaults.FPDocOutputDir:=OptionArg(I)
- else if assigned(CustomFpmakeCommandlineOptions) and CheckCustomOption(I,CustOptName) then
- begin
- if not assigned(CustomFpMakeCommandlineValues) then
- CustomFpMakeCommandlineValues := TStringList.Create;
- CustomFpMakeCommandlineValues.Values[CustOptName]:=OptionArg(I)
- end
- else if not Defaults.IgnoreInvalidOptions then
- begin
- Usage(SErrInValidArgument,[I,ParamStr(I)]);
- end;
- end;
- If DefaultsFileName<>'' then
- Defaults.LocalInit(DefaultsFileName);
- Defaults.CompilerDefaults;
- end;
- procedure TCustomInstaller.Usage(const FMT: String; Args: array of const);
- Procedure LogCmd(const LC,Msg : String);
- begin
- Log(vlInfo,Format(' %-12s %s',[LC,MSG]));
- end;
- Procedure LogOption(const C,LC,Msg : String);
- begin
- Log(vlInfo,Format(' -%s --%-16s %s',[C,LC,MSG]));
- end;
- Procedure LogArgOption(const C,LC,Msg : String);
- begin
- Log(vlInfo,Format(' -%s --%-20s %s',[C,LC+'='+SValue,MSG]));
- end;
- var
- i: Integer;
- begin
- // Force the Usage to be displayed
- Include(FLogLevels,vlInfo);
- If (FMT<>'') then
- Log(vlInfo,Format(Fmt,Args));
- Log(vlInfo,Format(SHelpUsage,[Paramstr(0)]));
- Log(vlInfo,SHelpCommand);
- LogCmd('compile',SHelpCompile);
- LogCmd('build',SHelpBuild);
- LogCmd('install',SHelpInstall);
- LogCmd('clean',SHelpClean);
- LogCmd('archive',SHelpArchive);
- LogCmd('manifest',SHelpManifest);
- Log(vlInfo,SHelpCmdOptions);
- LogOption('h','help',SHelpHelp);
- LogOption('l','list-commands',SHelpList);
- LogOption('n','nofpccfg',SHelpNoFPCCfg);
- LogOption('v','verbose',SHelpVerbose);
- {$ifdef HAS_UNIT_PROCESS}
- LogOption('e', 'useenv', sHelpUseEnvironment);
- {$endif}
- LogOption('ie','installexamples',SHelpInstExamples);
- LogOption('bu','buildunit',SHelpUseBuildUnit);
- LogArgOption('C','cpu',SHelpCPU);
- LogArgOption('O','os',SHelpOS);
- LogArgOption('t','target',SHelpTarget);
- LogArgOption('P','prefix',SHelpPrefix);
- LogArgOption('B','baseinstalldir',SHelpBaseInstalldir);
- LogArgOption('UL','localunitdir',SHelpLocalUnitdir);
- LogArgOption('UG','globalunitdir',SHelpGlobalUnitdir);
- LogArgOption('U','unitinstalldir',SHelpUnitInstallDir);
- LogArgOption('r','compiler',SHelpCompiler);
- LogArgOption('f','config',SHelpConfig);
- LogArgOption('o','options',SHelpOptions);
- LogArgOption('io','ignoreinvalidoption',SHelpIgnoreInvOpt);
- LogArgOption('d', 'doc-folder', sHelpFpdocOutputDir);
- if assigned(CustomFpmakeCommandlineOptions) then for i := 0 to CustomFpmakeCommandlineOptions.Count-1 do
- LogArgOption(' ',CustomFpmakeCommandlineOptions.Names[i],CustomFpmakeCommandlineOptions.ValueFromIndex[i]);
- Log(vlInfo,'');
- If (FMT<>'') then
- halt(1)
- else
- halt(0);
- end;
- procedure TCustomInstaller.Compile(Force: Boolean);
- begin
- FBuildEngine.ForceCompile:=Force;
- FBuildEngine.Compile(Packages);
- end;
- procedure TCustomInstaller.Clean(AllTargets: boolean);
- begin
- BuildEngine.Clean(Packages, AllTargets);
- end;
- procedure TCustomInstaller.Install;
- begin
- BuildEngine.Install(Packages);
- end;
- procedure TCustomInstaller.Archive;
- begin
- // Force generation of manifest.xml, this is required for the repository
- BuildEngine.Manifest(Packages);
- BuildEngine.Archive(Packages);
- end;
- procedure TCustomInstaller.Manifest;
- begin
- BuildEngine.Manifest(Packages);
- end;
- procedure TCustomInstaller.CheckPackages;
- begin
- If (Packages.Count=0) then
- Error(SErrNoPackagesDefined);
- // Check for other obvious errors ?
- end;
- Function TCustomInstaller.Run : Boolean;
- begin
- Result:=True;
- try
- CheckPackages;
- CreateBuildEngine;
- Case RunMode of
- rmCompile : Compile(False);
- rmBuild : Compile(True);
- rmInstall : Install;
- rmArchive : Archive;
- rmClean : Clean(False);
- rmDistClean: Clean(True);
- rmManifest : Manifest;
- end;
- except
- On E : Exception do
- begin
- Log(vlError,SErrInstaller);
- Log(vlError,E.Message);
- Result:=False;
- end;
- end;
- // Force returning an exitcode to the shell
- if not Result then
- ExitCode:=1;
- end;
- {****************************************************************************
- TFPCInstaller
- ****************************************************************************}
- constructor TFPCInstaller.Create(AOwner: TComponent);
- begin
- if assigned(Defaults) then
- Error(SErrAlreadyInitialized);
- Defaults:=TFPCDefaults.Create;
- inherited Create(AOwner);
- end;
- {****************************************************************************
- TBasicInstaller
- ****************************************************************************}
- constructor TBasicInstaller.Create(AOwner: TComponent);
- begin
- if assigned(Defaults) then
- Error(SErrAlreadyInitialized);
- Defaults:=TBasicDefaults.Create;
- inherited Create(AOwner);
- end;
- {****************************************************************************
- TBuildEngine
- ****************************************************************************}
- constructor TBuildEngine.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- // Maybe this should be the current directory ?
- // Or have it as a command-line option.
- // Would allow to put all 'installers' in one dir and call them
- // With --start-dir=/path/to/sources.
- FStartDir:=includeTrailingPathDelimiter(GetCurrentDir);
- FExternalPackages:=TPackages.Create(TPackage);
- end;
- destructor TBuildEngine.Destroy;
- begin
- FreeAndNil(FExternalPackages);
- inherited Destroy;
- end;
- procedure TBuildEngine.Error(const Msg: String);
- begin
- Raise EInstallerError.Create(Msg);
- end;
- procedure TBuildEngine.Error(const Fmt: String; const Args: array of const);
- begin
- Raise EInstallerError.CreateFmt(Fmt,Args);
- end;
- procedure TBuildEngine.ExecuteCommand(const Cmd,Args : String; const Env: TStrings = nil; IgnoreError : Boolean = False);
- Var
- E : Integer;
- cmdLine: string;
- ConsoleOutput: TMemoryStream;
- s: string;
- begin
- Log(vlInfo,SInfoExecutingCommand,[Cmd,Args]);
- if ListMode then
- Log(vlCommand,'%s %s',[Cmd,Args])
- else
- begin
- // We should check cmd for spaces, and move all after first space to args.
- ConsoleOutput := TMemoryStream.Create;
- try
- {$ifdef HAS_UNIT_PROCESS}
- E:=ExecuteFPC(Verbose, cmd, args, env, ConsoleOutput);
- {$else}
- E:=ExecuteProcess(cmd,args);
- {$endif}
- If (E<>0) and (not IgnoreError) then
- begin
- if trim(Args)<>'' then
- cmdLine := cmd + ' ' + trim(args)
- else
- cmdline := cmd;
- s := ParsecompilerOutput(ConsoleOutput,Verbose);
- Error(SErrExternalCommandFailed,[cmdLine,E,s]);
- end;
- finally
- ConsoleOutput.Free;
- end;
- end;
- end;
- Function TBuildEngine.SysDirectoryExists(const ADir:string):Boolean;
- begin
- result:=SysUtils.DirectoryExists(ADir);
- if result then
- Log(vlDebug,SDbgDirectoryExists,[ADir,SDbgFound])
- else
- Log(vlDebug,SDbgDirectoryExists,[ADir,SDbgNotFound]);
- end;
- Function TBuildEngine.SysFileExists(const AFileName:string):Boolean;
- begin
- result:=SysUtils.FileExists(AFileName);
- if result then
- Log(vlDebug,SDbgFileExists,[AFileName,SDbgFound])
- else
- Log(vlDebug,SDbgFileExists,[AFileName,SDbgNotFound]);
- end;
- procedure TBuildEngine.SysCopyFile(Const Src,Dest : String);
- Var
- D,S : String;
- Fin,FOut : TFileStream;
- Count : Int64;
- A : Integer;
- begin
- Log(vlInfo,SInfoCopyingFile,[Src,Dest]);
- FIn:=TFileStream.Create(Src,fmopenRead);
- Try
- D:=IncludeTrailingPathDelimiter(Dest);
- If DirectoryExists(D) then
- S:=D+ExtractFileName(Src)
- else
- S:=Dest;
- FOut:=TFileStream.Create(S,fmCreate);
- Try
- Count:=Fout.CopyFrom(FIn,0);
- If (Count<>Fin.Size) then
- Error(SErrCopyingFile,[Src,S]);
- Finally
- FreeAndNil(Fout);
- end;
- A:=FileGetDate(FIn.Handle);
- If (A=-1) then
- log(vlWarning,SWarnFailedToGetTime,[Src])
- else
- if FileSetDate(S,A)<>0 then
- Log(vlWarning,SWarnFailedToSetTime,[S]);
- finally
- FreeAndNil(Fin);
- end;
- end;
- procedure TBuildEngine.SysMoveFile(Const Src,Dest : String);
- Var
- S : String;
- begin
- If DirectoryExists(IncludeTrailingPathDelimiter(Dest)) then
- S:=IncludeTrailingPathDelimiter(Dest)+ExtractFileName(Src)
- else
- S:=Dest;
- If Not RenameFile(Src,S) then
- begin
- Try
- SysCopyFile(Src,S);
- SysDeleteFile(Src);
- Except
- On E : Exception Do
- Error(SErrMovingFile,[Src,S]);
- end;
- end;
- end;
- procedure TBuildEngine.SysDeleteFile(Const AFileName : String);
- begin
- if not FileExists(AFileName) then
- Log(vldebug,SDbgFileDoesNotExist,[AFileName])
- else If Not DeleteFile(AFileName) then
- Error(SErrDeletingFile,[AFileName]);
- end;
- procedure TBuildEngine.SysDeleteDirectory(const ADirectoryName: String);
- begin
- if not DirectoryExists(ADirectoryName) then
- Log(vldebug,SDbgDirectoryDoesNotExist,[ADirectoryName])
- else if not IsDirectoryEmpty(ADirectoryName) then
- Log(vldebug,SDbgDirectoryNotEmpty,[ADirectoryName])
- else If Not RemoveDir(ADirectoryName) then
- Error(SErrRemovingDirectory,[ADirectoryName]);
- end;
- procedure TBuildEngine.SysDeleteTree(const ADirectoryName: String);
- function IntRemoveTree(const ADirectoryName: String) : boolean;
- var
- searchRec: TSearchRec;
- SearchResult: longint;
- begin
- result := true;
- SearchResult := FindFirst(IncludeTrailingPathDelimiter(ADirectoryName)+AllFilesMask, faAnyFile+faSymLink, searchRec);
- try
- while SearchResult=0 do
- begin
- if (searchRec.Name<>'.') and (searchRec.Name<>'..') then
- begin
- if (searchRec.Attr and faDirectory)=faDirectory then
- begin
- if not IntRemoveTree(IncludeTrailingPathDelimiter(ADirectoryName)+searchRec.Name) then
- result := false;
- end
- else if not DeleteFile(IncludeTrailingPathDelimiter(ADirectoryName)+searchRec.Name) then
- result := False;
- end;
- SearchResult := FindNext(searchRec);
- end;
- finally
- FindClose(searchRec);
- end;
- if not RemoveDir(ADirectoryName) then
- result := false;
- end;
- begin
- if not DirectoryExists(ADirectoryName) then
- Log(vldebug,SDbgDirectoryDoesNotExist,[ADirectoryName])
- else If Not IntRemoveTree(ADirectoryName) then
- Error(SErrRemovingDirectory,[ADirectoryName]);
- end;
- procedure TBuildEngine.SysArchiveFiles(List: TStrings;Const AFileName: String);
- begin
- If Not (Assigned(OnArchivefiles) or Assigned(ArchiveFilesProc)) then
- Raise EInstallerError.Create(SErrNoArchiveSupport);
- If Assigned(ArchiveFilesProc) then
- ArchiveFilesProc(AFileName,List)
- else
- OnArchiveFiles(AFileName,List);
- end;
- procedure TBuildEngine.LogIndent;
- begin
- FLogPrefix:=FLogPrefix+' ';
- end;
- procedure TBuildEngine.LogUnIndent;
- begin
- Delete(FLogPrefix,1,2);
- end;
- procedure TBuildEngine.Log(Level: TVerboseLevel; const Msg: String);
- begin
- If Assigned(FOnLog) then
- begin
- if Level in [vlInfo,vlDebug] then
- FOnLog(Level,FLogPrefix+Msg)
- else
- FOnLog(Level,Msg);
- end;
- end;
- procedure TBuildEngine.Log(Level: TVerboseLevel; const Fmt: String;const Args: array of const);
- begin
- Log(Level,Format(Fmt,Args));
- end;
- procedure TBuildEngine.EnterDir(ADir: String);
- Var
- D : String;
- begin
- D:=FStartDir;
- D:=D+ADir;
- Log(vlDebug,SDbgEnterDir,[D]);
- If Not SetCurrentDir(D) then
- Error(SErrChangeDirFailed,[D]);
- end;
- procedure TBuildEngine.CmdCopyFiles(List: TStrings; Const DestDir: String);
- Var
- Args : String;
- I : Integer;
- DestFileName : String;
- begin
- CmdCreateDir(DestDir);
- If (Defaults.Copy<>'') then
- begin
- Args:=FileListToString(List,'');
- Args:=Args+' '+DestDir;
- ExecuteCommand(Defaults.Copy,Args);
- end
- else
- For I:=0 to List.Count-1 do
- if List.Names[i]<>'' then
- begin
- if IsRelativePath(list.ValueFromIndex[i]) then
- DestFileName:=DestDir+list.ValueFromIndex[i]
- else
- DestFileName:=list.ValueFromIndex[i];
- CmdCreateDir(ExtractFilePath(DestFileName));
- SysCopyFile(List.names[i],DestFileName)
- end
- else
- SysCopyFile(List[i],DestDir);
- end;
- procedure TBuildEngine.CmdCreateDir(const DestDir: String);
- begin
- If (Defaults.MkDir<>'') then
- ExecuteCommand(Defaults.MkDir,DestDir)
- else
- If not ForceDirectories(DestDir) then
- Error(SErrCreatingDirectory,[DestDir]);
- end;
- procedure TBuildEngine.CmdMoveFiles(List: TStrings; Const DestDir: String);
- Var
- Args : String;
- I : Integer;
- begin
- CmdCreateDir(DestDir);
- If (Defaults.Move<>'') then
- begin
- Args:=FileListToString(List,'');
- Args:=Args+' '+DestDir;
- ExecuteCommand(Defaults.Move,Args);
- end
- else
- For I:=0 to List.Count-1 do
- SysMoveFile(List[i],DestDir);
- end;
- procedure TBuildEngine.CmdDeleteFiles(List: TStrings);
- Var
- Args : String;
- I : Integer;
- begin
- If (Defaults.Remove<>'') then
- begin
- Args:=FileListToString(List,'');
- ExecuteCommand(Defaults.Remove,Args);
- end
- else
- For I:=0 to List.Count-1 do
- SysDeleteFile(List[i]);
- end;
- procedure TBuildEngine.CmdArchiveFiles(List: TStrings; Const ArchiveFile: String);
- Var
- S,C,O : String;
- begin
- If (Defaults.Archive='') then
- SysArchiveFiles(List,ArchiveFile)
- else
- begin
- S:=FileListToString(List,'');
- SplitCommand(Defaults.Archive,C,O);
- If (O='') then
- O:=ArchiveFile+' '+S
- else
- O:=Substitute(O,['ARCHIVE',ArchiveFile,'FILESORDIRS']);
- ExecuteCommand(C,O);
- end;
- end;
- procedure TBuildEngine.CmdRenameFile(SourceName, DestName: String);
- var
- Args: string;
- begin
- If (Defaults.Move<>'') then
- begin
- Args:=SourceName;
- Args:=Args+' '+DestName;
- ExecuteCommand(Defaults.Move,Args);
- end
- else
- SysMoveFile(SourceName,DestName);
- end;
- procedure TBuildEngine.CmdRemoveDirs(List: TStrings);
- Var
- Args : String;
- I : Integer;
- begin
- If (Defaults.RemoveDir<>'') then
- begin
- Args:=FileListToString(List,'');
- ExecuteCommand(Defaults.RemoveDir,Args);
- end
- else
- For I:=0 to List.Count-1 do
- SysDeleteDirectory(List[i]);
- end;
- procedure TBuildEngine.CmdRemoveTrees(List: TStrings);
- Var
- Args : String;
- I : Integer;
- begin
- If (Defaults.RemoveTree<>'') then
- begin
- Args:=FileListToString(List,'');
- ExecuteCommand(Defaults.RemoveTree,Args);
- end
- else
- For I:=0 to List.Count-1 do
- SysDeleteTree(List[i]);
- end;
- Function TBuildEngine.FileNewer(const Src,Dest : String) : Boolean;
- Var
- DS,DD : Longint;
- D1,D2 : TDateTime;
- begin
- DS:=FileAge(Src);
- DD:=FileAge(Dest);
- D1:=FileDateToDateTime(DS);
- D2:=FileDateToDateTime(DD);
- Log(vlDebug,SDbgComparingFileTimes,[Src,DateTimeToStr(D1),Dest,DateTimeToStr(D2)]);
- Result:=D1>=D2;
- If Result then
- Log(vlInfo,SInfoSourceNewerDest,[Src,DateTimeToStr(D1),Dest,DateTimeToStr(D2)]);
- end;
- procedure TBuildEngine.ExecuteCommands(Commands: TCommands; At: TCommandAt);
- Var
- C : TCommand;
- I : Integer;
- Cmd,O : String;
- E : Boolean;
- begin
- For I:=0 to Commands.Count-1 do
- begin
- C:=Commands.CommandItems[i];
- if (C.At=At) then
- begin
- E:=True;
- If (C.SourceFile<>'') and (C.DestFile<>'') then
- E:=FileNewer(C.SourceFile,IncludeTrailingPathDelimiter(Dictionary.GetValue('OUTPUTDIR'))+C.DestFile);
- If E then
- begin
- If Assigned(C.BeforeCommand) then
- C.BeforeCommand(C);
- O:=Substitute(C.CmdLineOptions,['SOURCE',C.SourceFile,'DEST',C.DestFile]);
- Cmd:=C.Command;
- If (ExtractFilePath(Cmd)='') then
- Cmd:=ExeSearch(Cmd,GetEnvironmentvariable('PATH'));
- ExecuteCommand(Cmd,O,nil,C.IgnoreResult);
- If Assigned(C.AfterCommand) then
- C.AfterCommand(C);
- end;
- end;
- end;
- end;
- Procedure TBuildEngine.LogSearchPath(const ASearchPathName:string;Path:TConditionalStrings; ACPU:TCPU;AOS:TOS);
- var
- S : String;
- I : Integer;
- C : TConditionalString;
- begin
- S:='';
- for i:=0 to Path.Count-1 do
- begin
- C:=Path[I];
- if (ACPU in C.CPUs) and (AOS in C.OSes) then
- begin
- if S<>'' then
- S:=S+PathSeparator;
- S:=S+Dictionary.ReplaceStrings(C.Value)
- end;
- end;
- if S<>'' then
- Log(vlDebug,SDbgSearchPath,[ASearchPathName,S]);
- end;
- Function TBuildEngine.FindFileInPath(Path:TConditionalStrings; AFileName:String; var FoundPath:String;ACPU:TCPU;AOS:TOS):Boolean;
- var
- I : Integer;
- C : TConditionalString;
- begin
- Result:=false;
- for i:=0 to Path.Count-1 do
- begin
- C:=Path[I];
- if (ACPU in C.CPUs) and (AOS in C.OSes) then
- begin
- FoundPath:=IncludeTrailingPathDelimiter(Dictionary.ReplaceStrings(C.Value));
- if FileExists(FoundPath+AFileName) then
- begin
- result:=true;
- exit;
- end;
- end;
- end;
- FoundPath:='';
- end;
- procedure TBuildEngine.GetDirectoriesFromFilelist(const AFileList, ADirectoryList: TStringList);
- var
- i: integer;
- begin
- ADirectoryList.Sorted:=true;
- ADirectoryList.Duplicates:=dupIgnore;
- for i := 0 to AFileList.Count-1 do
- ADirectoryList.Add(ExtractFileDir(AFileList.Strings[i]));
- end;
- Procedure TBuildEngine.ResolveFileNames(APackage : TPackage; ACPU:TCPU;AOS:TOS;DoChangeDir:boolean=true);
- procedure FindMainSource(T:TTarget);
- var
- SD,SF : String;
- begin
- LogSearchPath('package source',APackage.SourcePath,ACPU,AOS);
- SD:=Dictionary.ReplaceStrings(T.Directory);
- SF:=Dictionary.ReplaceStrings(T.SourceFileName);
- if SD='' then
- FindFileInPath(APackage.SourcePath,SF,SD,ACPU,AOS);
- if SD<>'' then
- SD:=IncludeTrailingPathDelimiter(SD);
- T.FTargetSourceFileName:=SD+SF;
- if FileExists(T.TargetSourceFileName) then
- Log(vlDebug,SDbgResolvedSourceFile,[T.SourceFileName,T.TargetSourceFileName])
- else
- begin
- Log(vlWarning,SWarnSourceFileNotFound,[T.SourceFileName,APackage.Name,MakeTargetString(ACPU,AOS)]);
- T.FTargetSourceFileName:='';
- end;
- end;
- procedure FindIncludeSources(T:TTarget);
- var
- SD,SF : String;
- D : TDependency;
- j : integer;
- begin
- LogSearchPath('target include',T.IncludePath,ACPU,AOS);
- LogSearchPath('package include',APackage.IncludePath,ACPU,AOS);
- for j:=0 to T.Dependencies.Count-1 do
- begin
- D:=T.Dependencies[j];
- if (D.DependencyType=depInclude) then
- begin
- D.TargetFileName:='';
- if (ACPU in D.CPUs) and (AOS in D.OSes) then
- begin
- if ExtractFilePath(D.Value)='' then
- begin
- SF:=Dictionary.ReplaceStrings(D.Value);
- SD:='';
- // first check the target specific path
- if not FindFileInPath(T.IncludePath,SF,SD,ACPU,AOS) then
- FindFileInPath(APackage.IncludePath,SF,SD,ACPU,AOS);
- if SD<>'' then
- SD:=IncludeTrailingPathDelimiter(SD);
- D.TargetFileName:=SD+SF;
- end
- else
- D.TargetFileName:=D.Value;
- if FileExists(D.TargetFileName) then
- Log(vlDebug,SDbgResolvedIncludeFile,[D.Value,D.TargetFileName])
- else
- begin
- Log(vlWarning,SWarnIncludeFileNotFound,[D.Value, APackage.Name, MakeTargetString(ACPU,AOS)]);
- D.TargetFileName:='';
- end;
- end;
- end;
- end;
- end;
- procedure FindExampleSource(T:TTarget);
- var
- SD,SF : String;
- begin
- LogSearchPath('package example',APackage.ExamplePath,ACPU,AOS);
- SD:=Dictionary.ReplaceStrings(T.Directory);
- SF:=Dictionary.ReplaceStrings(T.SourceFileName);
- if SD='' then
- FindFileInPath(APackage.ExamplePath,SF,SD,ACPU,AOS);
- if SD<>'' then
- SD:=IncludeTrailingPathDelimiter(SD);
- T.FTargetSourceFileName:=SD+SF;
- if FileExists(T.TargetSourceFileName) then
- Log(vlDebug,SDbgResolvedSourceFile,[T.SourceFileName,T.TargetSourceFileName])
- else
- begin
- Log(vlWarning,SWarnSourceFileNotFound,[T.SourceFileName, APackage.Name, MakeTargetString(ACPU,AOS)]);
- T.FTargetSourceFileName:='';
- end;
- end;
- var
- T : TTarget;
- i : Integer;
- begin
- if not((ACPU in APackage.CPUs) and (AOS in APackage.OSes)) then
- exit;
- try
- if DoChangeDir and (APackage.Directory<>'') then
- EnterDir(APackage.Directory);
- Dictionary.AddVariable('CPU',CPUToString(ACPU));
- Dictionary.AddVariable('OS',OSToString(AOS));
- For I:=0 to APackage.Targets.Count-1 do
- begin
- T:=APackage.FTargets.TargetItems[I];
- if (ACPU in T.CPUs) and (AOS in T.OSes) then
- begin
- // Debug information
- Log(vlDebug,SDbgResolvingSourcesOfTarget,[T.Name,MakeTargetString(ACPU,AOS)]);
- LogIndent;
- case T.TargetType of
- ttProgram,
- ttUnit,
- ttImplicitUnit :
- begin
- FindMainSource(T);
- if T.Dependencies.Count>0 then
- FindIncludeSources(T);
- end;
- ttExampleUnit,
- ttExampleProgram :
- begin
- FindExampleSource(T);
- end;
- end;
- LogUnIndent;
- end;
- end;
- finally
- If DoChangeDir and (APackage.Directory<>'') then
- EnterDir('');
- end;
- end;
- function TBuildEngine.GetUnitDir(APackage:TPackage):String;
- begin
- if APackage.UnitDir='' then
- begin
- // Retrieve Full directory name where to find the units.
- // The search order is:
- // - Package in this fpmake.pp
- // - LocalUnitDir
- // - GlobalUnitDir
- if (APackage.State in [tsCompiled, tsNoCompile]) then
- begin
- APackage.UnitDir:=IncludeTrailingPathDelimiter(FStartDir)+IncludeTrailingPathDelimiter(APackage.Directory)+APackage.GetUnitsOutputDir(Defaults.CPU,Defaults.OS);
- end;
- if (APackage.UnitDir='') and
- (Defaults.LocalUnitDir<>'') then
- begin
- APackage.UnitDir:=IncludeTrailingPathDelimiter(Defaults.LocalUnitDir)+APackage.Name;
- if not SysDirectoryExists(APackage.UnitDir) then
- APackage.UnitDir:='';
- end;
- if APackage.UnitDir='' then
- begin
- APackage.UnitDir:=IncludeTrailingPathDelimiter(Defaults.GlobalUnitDir)+APackage.Name;
- if not SysDirectoryExists(APackage.UnitDir) then
- APackage.UnitDir:=DirNotFound;
- end;
- if (APackage.UnitDir<>DirNotFound) then
- begin
- if FileExists(IncludeTrailingPathDelimiter(APackage.UnitDir)+FPMakePPFile) then
- begin
- // The package is not installed, but the source-path is detected.
- // It is an external package so it is impossible to compile it, so
- // assume that it has been compiled earlier.
- APackage.UnitDir := IncludeTrailingPathDelimiter(APackage.UnitDir) + APackage.GetUnitsOutputDir(Defaults.CPU,Defaults.OS);
- // If the unit-directory does not exist, you know for sure that
- // the package is not compiled
- if not SysDirectoryExists(APackage.UnitDir) then
- APackage.UnitDir:=DirNotFound
- else
- APackage.FTargetState:=tsCompiled;
- end
- else if not (APackage.FTargetState in [tsCompiled, tsNoCompile]) then
- begin
- APackage.FTargetState:=tsInstalled;
- end;
- end;
- end;
- // Special error marker to prevent searches in case of error
- if APackage.UnitDir=DirNotFound then
- Result:=''
- else
- Result:=APackage.UnitDir;
- end;
- procedure TBuildEngine.AddDependencyPaths(L: TStrings; DependencyType: TDependencyType; ATarget: TTarget);
- Var
- I : Integer;
- D : TDependency;
- SD : String;
- begin
- For I:=0 to ATarget.Dependencies.Count-1 do
- begin
- D:=ATarget.Dependencies[i];
- if (D.DependencyType=DependencyType) and
- (Defaults.CPU in D.CPUs) and (Defaults.OS in D.OSes) then
- begin
- SD:=ExcludeTrailingPathDelimiter(ExtractFilePath(D.TargetFileName));
- if SD<>'' then
- L.Add(SD);
- end;
- end;
- end;
- procedure TBuildEngine.AddDependencyUnitPaths(L:TStrings;APackage: TPackage);
- Var
- I : Integer;
- P : TPackage;
- D : TDependency;
- S : String;
- begin
- For I:=0 to APackage.Dependencies.Count-1 do
- begin
- D:=APackage.Dependencies[i];
- if (D.DependencyType=depPackage) and
- (Defaults.CPU in D.CPUs) and (Defaults.OS in D.OSes) then
- begin
- P:=TPackage(D.Target);
- If Assigned(P) then
- begin
- // Already processed?
- S:=GetUnitDir(P);
- if L.IndexOf(S)=-1 then
- begin
- // Add this package and then dependencies
- L.Add(S);
- AddDependencyUnitPaths(L,P);
- end;
- end;
- end;
- end;
- end;
- Function TBuildEngine.GetCompilerCommand(APackage : TPackage; ATarget : TTarget; Env: TStrings) : String;
- Var
- L : TUnsortedDuplicatesStringList;
- Args : TStringList;
- s : string;
- i : Integer;
- begin
- if ATarget.TargetSourceFileName = '' then
- Error(SErrCouldNotCompile,[ATarget.Name, APackage.Name]);
- Args:=TStringList.Create;
- Args.Duplicates:=dupIgnore;
- Result := '';
- //compiler configuration
- if Defaults.NoFPCCfg then
- Args.Add('-n');
- // Target OS
- Args.Add('-T'+OSToString(Defaults.OS));
- // Compile mode
- If ATarget.Mode<>cmFPC then
- Args.Add('-M'+ModeToString(ATarget.Mode))
- else If Defaults.Mode<>cmFPC then
- Args.Add('-M'+ModeToString(Defaults.Mode));
- // Output file paths
- If ATarget.TargetType in ProgramTargets then
- Args.Add('-FE'+APackage.GetBinOutputDir(Defaults.CPU,Defaults.OS));
- Args.Add('-FU'+APackage.GetUnitsOutputDir(Defaults.CPU,Defaults.OS));
- // Object Path
- L:=TUnsortedDuplicatesStringList.Create;
- L.Duplicates:=dupIgnore;
- AddConditionalStrings(L,APackage.ObjectPath,Defaults.CPU,Defaults.OS);
- AddConditionalStrings(L,ATarget.ObjectPath,Defaults.CPU,Defaults.OS);
- for i:=0 to L.Count-1 do
- Args.Add('-Fo'+L[i]);
- FreeAndNil(L);
- // Unit Dirs
- L:=TUnsortedDuplicatesStringList.Create;
- L.Duplicates:=dupIgnore;
- AddDependencyUnitPaths(L,APackage);
- AddDependencyPaths(L,depUnit,ATarget);
- AddConditionalStrings(L,APackage.UnitPath,Defaults.CPU,Defaults.OS);
- AddConditionalStrings(L,ATarget.UnitPath,Defaults.CPU,Defaults.OS);
- for i:=0 to L.Count-1 do
- Args.Add('-Fu'+L[i]);
- FreeAndNil(L);
- // Include Path
- L:=TUnsortedDuplicatesStringList.Create;
- L.Duplicates:=dupIgnore;
- AddDependencyPaths(L,depInclude,ATarget);
- AddConditionalStrings(L,APackage.IncludePath,Defaults.CPU,Defaults.OS);
- AddConditionalStrings(L,ATarget.IncludePath,Defaults.CPU,Defaults.OS);
- for i:=0 to L.Count-1 do
- Args.Add('-Fi'+L[i]);
- FreeAndNil(L);
- // Custom Options
- If (Defaults.HaveOptions) then
- Args.AddStrings(Defaults.Options);
- If (APackage.HaveOptions) then
- Args.AddStrings(APackage.Options);
- If (ATarget.HaveOptions) then
- Args.AddStrings(ATarget.Options);
- {$ifdef HAS_UNIT_PROCESS}
- // Force the compiler-output to be easy parseable
- if not Verbose then
- args.Add('-viq');
- {$endif}
- // Add Filename to compile
- Args.Add(ATarget.TargetSourceFileName);
- // Convert to string
- Result:='';
- for i:=0 to Args.Count-1 do
- Result:=Result+' '+maybequoted(Args[i]);
- Delete(result,1,1);
- if Defaults.UseEnvironment and assigned(Env) then
- begin
- env.Values['FPCEXTCMD'] := Result;
- result := '!FPCEXTCMD';
- // Make sure that this process' environment variables are passed to the
- // compiler's environment
- for i := 0 to GetEnvironmentVariableCount-1 do
- env.Add(GetEnvironmentString(i));
- end;
- // Add Filename to compile
- result := result + ' ' + ATarget.TargetSourceFileName;
- Args.Free;
- end;
- Function TBuildEngine.GetCompiler : String;
- Var
- S : String;
- begin
- // Cache in FCompiler for speed.
- If (FCompiler='') then
- begin
- FCompiler:=Defaults.Compiler;
- If (ExtractFilePath(FCompiler)='') then
- begin
- S:=ExeSearch(FCompiler,GetEnvironmentVariable('PATH'));
- If (S<>'') then
- FCompiler:=S;
- end;
- end;
- Result:=FCompiler;
- end;
- procedure TBuildEngine.CreateOutputDir(APackage: TPackage);
- Var
- D : String;
- i: integer;
- begin
- //create a units directory
- D:=APackage.GetUnitsOutputDir(Defaults.CPU,Defaults.OS);
- If not SysDirectoryExists(D) then
- begin
- Log(vlInfo,SInfoCreatingOutputDir,[D]);
- CmdCreateDir(D);
- end;
- //also create a bin directory for programtargets
- For i := 0 to Pred(APackage.Targets.Count) do
- begin
- if APackage.Targets.TargetItems[i].TargetType in ProgramTargets then
- begin
- D:=APackage.GetBinOutputDir(Defaults.CPU,Defaults.OS);
- If not SysDirectoryExists(D) then
- begin
- Log(vlInfo,SInfoCreatingOutputDir,[D]);
- CmdCreateDir(D);
- end;
- //do not continue loop, directory is made anyway
- break;
- end;
- end;
- end;
- Function TBuildEngine.DependencyOK(ADependency : TDependency) : Boolean;
- begin
- Result:=(Defaults.CPU in ADependency.CPUs) and (Defaults.OS in ADependency.OSes);
- end;
- Function TBuildEngine.TargetOK(ATarget : TTarget) : Boolean;
- begin
- Result:=(Defaults.CPU in ATarget.CPUs) and (Defaults.OS in ATarget.OSes);
- end;
- Function TBuildEngine.PackageOK(APackage : TPackage) : Boolean;
- begin
- Result:=(Defaults.CPU in APackage.CPUs) and (Defaults.OS in APackage.OSes);
- end;
- procedure TBuildEngine.DoBeforeCompile(APackage: TPackage);
- begin
- ExecuteCommands(APackage.Commands,caBeforeCompile);
- If Assigned(APackage.BeforeCompile) then
- APackage.BeforeCompile(APackage);
- If Assigned(APackage.BeforeCompileProc) then
- APackage.BeforeCompileProc(APackage);
- end;
- procedure TBuildEngine.DoAfterCompile(APackage: TPackage);
- begin
- If Assigned(APackage.AfterCompile) then
- APackage.AfterCompile(APackage);
- If Assigned(APackage.AfterCompileProc) then
- APackage.AfterCompileProc(APackage);
- ExecuteCommands(APackage.Commands,caAfterCompile);
- end;
- Function TBuildEngine.NeedsCompile(APackage:TPackage;ATarget: TTarget): Boolean;
- Var
- I : Integer;
- D : TDependency;
- T : TTarget;
- OD,OFN : String;
- begin
- Result:=False;
- // Forced recompile?
- if FForceCompile then
- Result:=true;
- // Check output file
- if not result then
- begin
- if ATarget.TargetType in ProgramTargets then
- OD:=APackage.GetBinOutputDir(Defaults.CPU,Defaults.OS)
- else
- OD:=APackage.GetUnitsOutputDir(Defaults.CPU,Defaults.OS);
- If (OD<>'') then
- OD:=IncludeTrailingPathDelimiter(OD);
- OFN:=OD+ATarget.GetOutPutFileName(Defaults.OS);
- Result:=Not FileExists(OFN);
- if Result then
- Log(vlDebug,SDbgOutputNotYetAvailable,[OFN]);
- end;
- // Check main source
- If not Result then
- begin
- if FileExists(ATarget.TargetSourceFileName) then
- Result:=FileNewer(ATarget.TargetSourceFileName,OFN)
- end;
- // Check unit and include dependencies
- If not Result then
- begin
- ResolveDependencies(ATarget.Dependencies,ATarget.Collection as TTargets);
- I:=0;
- for i:=0 to ATarget.Dependencies.Count-1 do
- begin
- D:=ATarget.Dependencies[i];
- if (Defaults.CPU in D.CPUs) and (Defaults.OS in D.OSes) then
- begin
- case D.DependencyType of
- depUnit :
- begin
- T:=TTarget(D.Target);
- If (T=Nil) then
- Error(SErrDepUnknownTarget,[D.Value, ATarget.Name, APackage.Name]);
- // If a dependent package is compiled we always need to recompile
- Log(vldebug, SDbgDependencyOnUnit, [ATarget.Name,T.Name]);
- Result:=(T.State=tsCompiled);
- if Result then
- Log(vldebug, SDbgDependencyUnitRecompiled, [T.Name]);
- end;
- depInclude :
- begin
- if D.TargetFileName<>'' then
- Result:=FileNewer(D.TargetFileName,OFN)
- end;
- depPackage :
- begin
- log(vlWarning,SWarnTargetDependsOnPackage,[ATarget.Name, APackage.Name, d.Value]);
- end;
- end;
- if result then
- break;
- end;
- end;
- end;
- if result then
- Log(vlDebug,SDbgMustCompile,[ATarget.Name]);
- end;
- procedure TBuildEngine.Compile(APackage: TPackage; ATarget: TTarget);
- Var
- S : String;
- Env : TStrings;
- begin
- Log(vlInfo,SInfoCompilingTarget,[ATarget.Name]);
- LogIndent;
- ExecuteCommands(ATarget.Commands,caBeforeCompile);
- If Assigned(ATarget.BeforeCompile) then
- ATarget.BeforeCompile(ATarget);
- if APackage.BuildMode=bmBuildUnit then
- begin
- APackage.FBUTarget.Dependencies.AddUnit(ATarget.Name).FTargetFileName:=ATarget.TargetSourceFileName;
- end
- else
- begin
- if Defaults.UseEnvironment then
- begin
- Env := TStringList.Create;
- try
- S:=GetCompilerCommand(APackage,ATarget,Env);
- ExecuteCommand(GetCompiler,S,Env);
- finally
- Env.Free;
- end;
- end
- else
- begin
- S:=GetCompilerCommand(APackage,ATarget,Env);
- ExecuteCommand(GetCompiler,S,nil);
- end;
- If Assigned(ATarget.AfterCompile) then
- ATarget.AfterCompile(ATarget);
- ExecuteCommands(ATarget.Commands,caAfterCompile);
- end;
- LogUnIndent;
- end;
- procedure TBuildEngine.CompileDependencies(APackage:TPackage; ATarget: TTarget);
- Var
- I : Integer;
- T : TTarget;
- D : TDependency;
- begin
- Log(vlDebug, Format(SDbgCompilingDependenciesOfTarget, [ATarget.Name]));
- LogIndent;
- For I:=0 to ATarget.Dependencies.Count-1 do
- begin
- D:=ATarget.Dependencies[i];
- if (D.DependencyType=depPackage) then
- log(vlWarning,SWarnTargetDependsOnPackage,[ATarget.Name, APackage.Name, d.Value])
- else if (D.DependencyType=depUnit) and
- (Defaults.CPU in D.CPUs) and (Defaults.OS in D.OSes) then
- begin
- T:=TTarget(D.Target);
- if Assigned(T) and (T<>ATarget) then
- begin
- if TargetOK(T) then
- begin
- // We don't need to compile implicit units, they are only
- // used for dependency checking
- if (T.TargetType<>ttImplicitUnit) then
- begin
- case T.State of
- tsNeutral :
- MaybeCompile(APackage,T);
- tsConsidering :
- Log(vlWarning,SWarnCircularTargetDependency,[ATarget.Name,T.Name]);
- end;
- end;
- end
- else
- Log(vlWarning, Format(SWarnDepUnitNotFound, [T.Name, MakeTargetString(Defaults.CPU,Defaults.OS)]));
- end
- else
- Error(SErrDepUnknownTarget,[D.Value, ATarget.Name, APackage.Name]);
- end;
- end;
- LogUnIndent;
- end;
- procedure TBuildEngine.MaybeCompile(APackage: TPackage; ATarget: TTarget);
- begin
- if ATarget.State<>tsNeutral then
- Error(SErrInvalidState,[ATarget.Name]);
- Log(vlDebug, Format(SDbgConsideringTarget, [ATarget.Name]));
- LogIndent;
- ATarget.FTargetState:=tsConsidering;
- ResolveDependencies(ATarget.Dependencies,ATarget.Collection as TTargets);
- CompileDependencies(APackage, ATarget);
- if NeedsCompile(APackage, ATarget) then
- begin
- Compile(APackage,ATarget);
- ATarget.FTargetState:=tsCompiled;
- end
- else
- ATarget.FTargetState:=tsNoCompile;
- LogUnIndent;
- end;
- function TBuildEngine.NeedsCompile(APackage: TPackage): Boolean;
- Var
- I : Integer;
- P : TPackage;
- D : TDependency;
- begin
- Result:=False;
- // Forced recompile?
- if FForceCompile then
- Result:=true;
- // Recompile because of Package Dependencies?
- if not Result then
- begin
- I:=0;
- For I:=0 to APackage.Dependencies.Count-1 do
- begin
- D:=APackage.Dependencies[i];
- if (D.DependencyType=depPackage) and
- (Defaults.CPU in D.CPUs) and (Defaults.OS in D.OSes) then
- begin
- P:=TPackage(D.Target);
- if Assigned(P) then
- begin
- Result:=(P.State=tsCompiled);
- if Result then
- break;
- end;
- end;
- end;
- end;
- // Recompile a Target of this package?
- If Not Result then
- begin
- try
- If (APackage.Directory<>'') then
- EnterDir(APackage.Directory);
- for i:=0 to APackage.Targets.Count-1 do
- begin
- Result:=NeedsCompile(APackage,APackage.Targets.TargetItems[i]);
- if Result then
- break;
- end;
- Finally
- If (APackage.Directory<>'') then
- EnterDir('');
- end;
- end;
- if result then
- Log(vlDebug,SDbgMustCompile,[APackage.Name]);
- end;
- function TBuildEngine.CheckExternalPackage(Const APackageName : String):TPackage;
- var
- S : String;
- F : String;
- I : Integer;
- begin
- // Already checked?
- I:=ExternalPackages.IndexOfName(APackageName);
- if I<>-1 then
- begin
- result:=ExternalPackages.PackageItems[I];
- exit;
- end;
- // Create new external package
- Result:=ExternalPackages.AddPackage(APackageName);
- Result.FTargetState:=tsNotFound;
- // Load unit config
- S:=GetUnitDir(Result);
- if S<>'' then
- begin
- Log(vldebug, SDbgExternalDependency, [APackageName,S]);
- // Load unit config if it exists
- F:=IncludeTrailingPathDelimiter(S)+UnitConfigFile;
- if FileExists(F) then
- begin
- Log(vlDebug, Format(SDbgLoading, [F]));
- Result.LoadUnitConfigFromFile(F);
- end;
- // Check recursive implicit dependencies
- CompileDependencies(Result);
- end
- else
- Error(SErrDependencyNotFound,[APackageName]);
- end;
- procedure TBuildEngine.CompileDependencies(APackage: TPackage);
- Var
- I : Integer;
- P : TPackage;
- D : TDependency;
- begin
- For I:=0 to APackage.Dependencies.Count-1 do
- begin
- D:=APackage.Dependencies[i];
- if (D.DependencyType=depPackage) and
- (Defaults.CPU in D.CPUs) and (Defaults.OS in D.OSes) then
- begin
- P:=TPackage(D.Target);
- If Assigned(P) then
- begin
- if (Defaults.CPU in P.CPUs) and (Defaults.OS in P.OSes) then
- begin
- case P.State of
- tsNeutral :
- MaybeCompile(P);
- tsConsidering :
- Log(vlWarning,SWarnCircularPackageDependency,[APackage.Name,P.Name]);
- end;
- end
- else
- Log(vlWarning,SWarnDependOnOtherPlatformPackage,[APackage.Name, D.Value, MakeTargetString(Defaults.CPU, Defaults.OS)]);
- end
- else
- begin
- D.Target:=CheckExternalPackage(D.Value);
- P:=TPackage(D.Target);
- end;
- if (D.RequireChecksum<>$ffffffff) and
- (P.InstalledChecksum<>$ffffffff) and
- (P.InstalledChecksum<>D.RequireChecksum) then
- Log(vlDebug,SDbgPackageChecksumChanged,[P.Name]);
- end;
- end;
- end;
- procedure TBuildEngine.Compile(APackage: TPackage);
- Var
- T : TTarget;
- I : Integer;
- Cmd: string;
- cmdOpts: string;
- sFPDocFormat: string;
- IFPDocFormat: TFPDocFormat;
- d: integer;
- UC: string;
- dep: TDependency;
- RegenerateUnitconfigFile: boolean;
- BUName: string;
- procedure CompileBuildUnit;
- var
- I: Integer;
- T: TTarget;
- L: TStrings;
- F: Text;
- begin
- if (APackage.FBUTarget.Dependencies.Count>0) then
- begin
- Log(vldebug, Format(SDbgGenerateBuildUnit, [APackage.FBUTarget.Name]));
- system.Assign(F,APackage.FBUTarget.FTargetSourceFileName);
- Rewrite(F);
- writeln(F,'unit ' + APackage.FBUTarget.Name +';');
- writeln(F,'interface');
- writeln(F,'uses');
- for i := 0 to APackage.FBUTarget.Dependencies.Count-1 do
- begin
- if i<>0 then
- write(F,',');
- writeln(F,APackage.FBUTarget.Dependencies.Dependencies[i].Value);
- end;
- writeln(F,';');
- writeln(F,'implementation');
- writeln(F,'end.');
- system.close(F);
- APackage.FBuildMode:=bmOneByOne;
- try
- Compile(APackage,APackage.FBUTarget);
- finally
- // Delete temporary build-unit files
- L := TStringList.Create;
- try
- APackage.FBUTarget.GetCleanFiles(L,IncludeTrailingPathDelimiter(APackage.GetUnitsOutputDir(Defaults.CPU,Defaults.OS)),'',Defaults.CPU,Defaults.OS);
- L.Add(APackage.FBUTarget.SourceFileName);
- CmdDeleteFiles(L);
- finally
- L.Free;
- end;
- end;
- end;
- For I:=0 to APackage.Targets.Count-1 do
- begin
- T:=APackage.Targets.TargetItems[i];
- if (T.TargetType = ttUnit) and (TargetOK(T)) then
- begin
- If Assigned(T.AfterCompile) then
- T.AfterCompile(T);
- ExecuteCommands(T.Commands,caAfterCompile);
- end
- end;
- end;
- procedure ProcessCompileTarget;
- begin
- if TargetOK(T) then
- begin
- if T.State=tsNeutral then
- MaybeCompile(APackage,T);
- // If a target is compiled, re-generate the UnitConfigFile
- if T.FTargetState<>tsNoCompile then
- RegenerateUnitconfigFile:= True;
- end
- else
- begin
- if not(Defaults.CPU in T.CPUs) then
- Log(vldebug, Format(SDbgSkippingTargetWrongCPU, [T.Name, CPUsToString(T.CPUs)]));
- if not(Defaults.OS in T.OSes) then
- Log(vldebug, Format(SDbgSkippingTargetWrongOS, [T.Name, OSesToString(T.OSes)]));
- end;
- end;
- begin
- cmdOpts := '';
- Log(vlInfo,SInfoCompilingPackage,[APackage.Name]);
- case Defaults.BuildMode of
- bmOneByOne: begin
- if bmOneByOne in APackage.SupportBuildModes then
- APackage.FBuildMode:=bmOneByOne
- else
- raise exception.create(SErrUnsupportedBuildmode);
- end;
- bmBuildUnit: begin
- // When bmBuildUnit is supported by the package use a buildunit.
- // Unless there is only one target and bmOneByOne is also supported
- if (bmBuildUnit in APackage.SupportBuildModes) and
- not ((APackage.Targets.Count=1) and (bmOneByOne in APackage.SupportBuildModes)) then
- APackage.FBuildMode:=bmBuildUnit
- else if bmOneByOne in APackage.SupportBuildModes then
- begin
- log(vlInfo,SInfoFallbackBuildmode);
- APackage.FBuildMode:=bmOneByOne
- end
- else
- raise exception.create(SErrUnsupportedBuildmode);
- end;
- end;
- Try
- If (APackage.Directory<>'') then
- EnterDir(APackage.Directory);
- CreateOutputDir(APackage);
- Dictionary.AddVariable('UNITSOUTPUTDIR',APackage.GetUnitsOutputDir(Defaults.CPU,Defaults.OS));
- Dictionary.AddVariable('BINOUTPUTDIR',APackage.GetBinOutputDir(Defaults.CPU,Defaults.OS));
- DoBeforeCompile(APackage);
- RegenerateUnitconfigFile:=False;
- if APackage.BuildMode=bmBuildUnit then
- begin
- APackage.FBUTargets := TTargets.Create(TTarget);
- if Defaults.OS in AllLimit83fsOses then
- BUName := 'BUnit.pp'
- else
- BUName := 'BuildUnit_'+StringReplace(APackage.Name,'-','_',[rfReplaceAll])+'.pp';
- APackage.FBUTarget := APackage.FBUTargets.AddUnit(BUName);
- APackage.FBUTarget.FTargetSourceFileName := APackage.FBUTarget.SourceFileName;
- end;
- For I:=0 to APackage.Targets.Count-1 do
- begin
- T:=APackage.Targets.TargetItems[i];
- case T.TargetType of
- ttUnit:
- begin
- ProcessCompileTarget;
- end;
- ttProgram:
- begin // do nothing, are compiled later
- end;
- ttFPDoc:
- begin
- for d := 0 to T.Dependencies.Count - 1 do
- begin
- dep := TDependency(T.Dependencies[d]);
- //add unit dependencies
- if dep.DependencyType = depUnit then
- cmdOpts := cmdOpts + ' --input=' + dep.Value;
- end;
- //check if a documentation target is given
- cmdOpts := cmdOpts + ' --input=' + T.Directory + T.Name + T.Extension + ' --descr='+ T.XML;
- end
- else
- log(vldebug, SDbgTargetIsNotAUnitOrProgram,[T.Name]);
- end;
- end;
- if APackage.BuildMode=bmBuildUnit then
- CompileBuildUnit;
- FreeAndNil(APackage.FBUTarget);
- For I:=0 to APackage.Targets.Count-1 do
- begin
- T:=APackage.Targets.TargetItems[i];
- if T.TargetType=ttProgram then
- begin
- ProcessCompileTarget;
- end;
- end;
- if RegenerateUnitconfigFile then
- begin
- UC:=IncludeTrailingPathDelimiter(APackage.GetUnitsOutputDir(Defaults.CPU,Defaults.OS))+UnitConfigFile;
- Log(vlInfo, Format(SDbgGenerating, [UC]));
- APackage.SaveUnitConfigToFile(UC,Defaults.CPU,Defaults.OS);
- end;
- //compile documentation, because options were found
- if cmdOpts <> '' then
- begin
- //append package name
- cmdOpts := cmdOpts + ' --package=' + APackage.Name;
- for IFPDocFormat:=Low(TFPDocFormat) to High(TFPDocFormat) do
- begin
- if IFPDocFormat in APackage.FPDocFormat then
- begin
- //prepend output format
- case IFPDocFormat of
- ffHtml: sFPDocFormat := '--format=html --output=' + Defaults.FPDocOutputDir;
- ffHtm: sFPDocFormat := '--format=htm --output=' + Defaults.FPDocOutputDir;
- ffXHtml: sFPDocFormat := '--format=xhtml --output=' + Defaults.FPDocOutputDir;
- ffLaTex: sFPDocFormat := '--format=latex --output=' + Defaults.FPDocOutputDir + APackage.Name + '.tex';
- ffXMLStruct: sFPDocFormat := '--format=xml-struct --output=' + Defaults.FPDocOutputDir;
- ffChm: sFPDocFormat := '--format=chm --output=' + Defaults.FPDocOutputDir + APackage.Name + '.chm';
- end;
- //execute fpdoc
- Cmd:=ExeSearch('fpdoc',GetEnvironmentvariable('PATH'));
- if Cmd = '' then Cmd := 'fpdoc';
- ExecuteProcess(Cmd, sFPDocFormat + cmdOpts);
- end;
- end;
- end;
- DoAfterCompile(APackage);
- Finally
- If (APackage.Directory<>'') then
- EnterDir('');
- end;
- end;
- procedure TBuildEngine.MaybeCompile(APackage: TPackage);
- begin
- if APackage.State in [tsCompiled, tsNoCompile] then
- begin
- Log(vlInfo,SInfoPackageAlreadyProcessed,[APackage.Name]);
- Exit;
- end;
- if APackage.State<>tsNeutral then
- Error(SErrInvalidState,[APackage.Name]);
- Log(vlDebug,SDbgConsideringPackage,[APackage.Name]);
- LogIndent;
- APackage.FTargetState:=tsConsidering;
- ResolveDependencies(APackage.Dependencies,(APackage.Collection as TPackages));
- CompileDependencies(APackage);
- ResolveFileNames(APackage,Defaults.CPU,Defaults.OS);
- If NeedsCompile(APackage) then
- begin
- Compile(APackage);
- APackage.FTargetState:=tsCompiled;
- end
- else
- APackage.FTargetState:=tsNoCompile;
- LogUnIndent;
- end;
- Function TBuildEngine.InstallPackageFiles(APAckage : TPackage; tt : TTargetType; Const Dest : String):Boolean;
- Var
- List : TStringList;
- begin
- Result:=False;
- List:=TStringList.Create;
- Try
- APackage.GetInstallFiles(List,[tt],Defaults.CPU, Defaults.OS);
- if (List.Count>0) then
- begin
- Result:=True;
- CmdCopyFiles(List,Dest);
- end;
- Finally
- List.Free;
- end;
- end;
- procedure TBuildEngine.InstallUnitConfigFile(APAckage: TPackage; const Dest: String);
- Var
- List : TStringList;
- begin
- List:=TStringList.Create;
- Try
- List.add(IncludeTrailingPathDelimiter(APackage.GetUnitsOutputDir(Defaults.CPU,Defaults.OS))+UnitConfigFile);
- CmdCopyFiles(List,Dest);
- Finally
- List.Free;
- end;
- end;
- function TBuildEngine.InstallPackageSourceFiles(APAckage : TPackage; stt : TSourceTypes; ttt : TTargetTypes; Const Dest : String): Boolean;
- Var
- List : TStringList;
- begin
- Result:=False;
- List:=TStringList.Create;
- Try
- APackage.GetInstallSourceFiles(List,stt,ttt);
- if (List.Count>0) then
- begin
- Result:=True;
- CmdCopyFiles(List,Dest);
- end;
- Finally
- List.Free;
- end;
- end;
- procedure TBuildEngine.DoBeforeInstall(APackage: TPackage);
- begin
- ExecuteCommands(APackage.Commands,caBeforeInstall);
- If Assigned(APackage.BeforeInstall) then
- APackage.BeforeInstall(APackage);
- If Assigned(APackage.BeforeInstallProc) then
- APackage.BeforeInstallProc(APackage);
- end;
- procedure TBuildEngine.DoAfterInstall(APackage: TPackage);
- begin
- If Assigned(APackage.AfterInstall) then
- APackage.AfterInstall(APackage);
- If Assigned(APackage.AfterInstallProc) then
- APackage.AfterInstallProc(APackage);
- ExecuteCommands(APackage.Commands,caAfterInstall);
- end;
- procedure TBuildEngine.Install(APackage: TPackage);
- Var
- UC,D : String;
- B : Boolean;
- begin
- If (Apackage.State<>tsCompiled) then
- MaybeCompile(APackage);
- try
- Log(vlInfo,SInfoInstallingPackage,[APackage.Name]);
- If (APackage.Directory<>'') then
- EnterDir(APackage.Directory);
- DoBeforeInstall(APackage);
- // units
- B:=false;
- Dictionary.AddVariable('PackageName',APackage.Name);
- D:=IncludeTrailingPathDelimiter(Defaults.UnitInstallDir);
- if InstallPackageFiles(APAckage,ttUnit,D) then
- B:=true;
- if InstallPackageFiles(APAckage,ttImplicitUnit,D) then
- B:=true;
- // By default do not install the examples. Maybe add an option for this later
- //if InstallPackageFiles(APAckage,ttExampleUnit,D) then
- // B:=true;
- // Unit (dependency) configuration if there were units installed
- if B then
- InstallUnitConfigFile(APackage,D);
- // Programs
- D:=IncludeTrailingPathDelimiter(Defaults.BinInstallDir);
- InstallPackageFiles(APAckage,ttProgram,D);
- //InstallPackageFiles(APAckage,ttExampleProgram,D);
- // Documentation
- D:=IncludeTrailingPathDelimiter(Defaults.DocInstallDir)+'fpc-'+APackage.FileName+PathDelim;
- InstallPackageSourceFiles(APackage,[stDoc],[],D);
- // Examples
- if Defaults.InstallExamples then
- begin
- D:=IncludeTrailingPathDelimiter(Defaults.ExamplesInstallDir)+'fpc-'+APackage.FileName+PathDelim+'examples'+PathDelim;
- InstallPackageSourceFiles(APackage,[stExample],[ttExampleProgram,ttExampleUnit],D);
- end;
- // Done.
- APackage.FTargetState:=tsInstalled;
- DoAfterInstall(APackage);
- Finally
- If (APackage.Directory<>'') then
- EnterDir('');
- end;
- end;
- procedure TBuildEngine.DoBeforeArchive(APackage: TPackage);
- begin
- ExecuteCommands(APackage.Commands,caBeforeArchive);
- If Assigned(APackage.BeforeArchive) then
- APackage.BeforeArchive(APackage);
- If Assigned(APackage.BeforeArchiveProc) then
- APackage.BeforeArchiveProc(APackage);
- end;
- procedure TBuildEngine.DoAfterArchive(APackage: TPackage);
- begin
- If Assigned(APackage.AfterArchive) then
- APackage.AfterArchive(APackage);
- If Assigned(APackage.AfterArchiveProc) then
- APackage.AfterArchiveProc(APackage);
- ExecuteCommands(APackage.Commands,caAfterArchive);
- end;
- procedure TBuildEngine.Archive(APackage: TPackage);
- Var
- L : TStringList;
- A : String;
- i: integer;
- ICPU : TCPU;
- IOS : TOS;
- begin
- A:=FStartDir+ APackage.FileName + ZipExt;
- Log(vlInfo,SInfoArchivingPackage,[APackage.Name,A]);
- try
- If (APackage.Directory<>'') then
- EnterDir(APackage.Directory);
- DoBeforeArchive(Apackage);
- L:=TStringList.Create;
- L.Sorted:=true;
- L.Duplicates:=dupIgnore;
- Try
- // Add fpmake.pp & manifest.xml always
- L.Add(FPMakePPFile);
- L.Add(ManifestFile);
- //get all files from all targets
- for ICPU:=Low(TCPU) to high(TCPU) do
- for IOS:=Low(TOS) to high(TOS) do
- if OSCPUSupported[IOS,ICPU] then
- begin
- ResolveFileNames(APackage,ICPU,IOS,false);
- APackage.GetArchiveFiles(L, ICPU, IOS);
- end;
- //from sources
- APackage.GetArchiveSourceFiles(L);
- //show all files
- for i := 0 to L.Count-1 do
- Log(vlDebug, Format(SDbgArchivingFile, [L[i]]));
- {$ifdef HAS_UNIT_ZIPPER}
- if not Assigned(ArchiveFilesProc) then
- begin
- FZipFile := TZipper.Create;
- FZipFile.ZipFiles(A, L);
- end
- else
- {$endif HAS_UNIT_ZIPPER}
- CmdArchiveFiles(L,A);
- Finally
- L.Free;
- {$ifdef HAS_UNIT_ZIPPER}
- if not Assigned(ArchiveFilesProc) then
- FreeAndNil(FZipFile);
- {$endif HAS_UNIT_ZIPPER}
- end;
- DoAfterArchive(Apackage);
- Finally
- If (APackage.Directory<>'') then
- EnterDir('');
- end;
- end;
- procedure TBuildEngine.DoBeforeClean(APackage: TPackage);
- begin
- ExecuteCommands(APackage.Commands,caBeforeClean);
- If Assigned(APackage.BeforeClean) then
- APackage.BeforeClean(APackage);
- If Assigned(APackage.BeforeCleanProc) then
- APackage.BeforeCleanProc(APackage);
- end;
- procedure TBuildEngine.DoAfterClean(APackage: TPackage);
- begin
- If Assigned(APackage.AfterClean) then
- APackage.AfterClean(APackage);
- If Assigned(APackage.AfterInstallProc) then
- APackage.AfterCleanProc(APackage);
- ExecuteCommands(APackage.Commands,caAfterClean);
- end;
- procedure TBuildEngine.Clean(APackage: TPackage; AllTargets: boolean);
- var
- // ACPU: TCpu;
- // AOS: TOS;
- DirectoryList : TStringList;
- begin
- Log(vlInfo,SInfoCleaningPackage,[APackage.Name]);
- try
- If (APackage.Directory<>'') then
- EnterDir(APackage.Directory);
- DoBeforeClean(Apackage);
- if AllTargets then
- begin
- // Remove the unit-directory completely. This is safer in case of files
- // being renamed and such. See also bug 19655
- DirectoryList := TStringList.Create;
- try
- DirectoryList.Add(ExtractFileDir(APackage.GetUnitsOutputDir(Defaults.CPU,Defaults.OS)));
- CmdRemoveTrees(DirectoryList);
- finally
- DirectoryList.Free;
- end;
- { for ACPU:=low(TCpu) to high(TCpu) do
- for AOS:=low(TOS) to high(TOS) do
- begin
- if FileExists(APackage.GetUnitsOutputDir(ACPU,AOS)) or
- FileExists(APackage.GetBinOutputDir(ACPU,AOS)) then
- Clean(APackage,ACPU,AOS);
- end;}
- end
- else
- Clean(APackage, Defaults.CPU, Defaults.OS);
- DoAfterClean(Apackage);
- Finally
- If (APackage.Directory<>'') then
- EnterDir('');
- end;
- end;
- procedure TBuildEngine.Clean(APackage: TPackage; ACPU: TCPU; AOS: TOS);
- Var
- List : TStringList;
- DirectoryList : TStringList;
- begin
- List:=TStringList.Create;
- try
- List.Add(APackage.GetUnitsOutputDir(ACPU,AOS) + PathDelim + UnitConfigFile);
- APackage.GetCleanFiles(List,ACPU,AOS);
- if (List.Count>0) then
- begin
- CmdDeleteFiles(List);
- DirectoryList := TStringList.Create;
- try
- GetDirectoriesFromFilelist(List,DirectoryList);
- CmdRemoveDirs(DirectoryList);
- DirectoryList.Clear;
- if DirectoryExists(APackage.GetBinOutputDir(ACPU,AOS)) then
- DirectoryList.Add(APackage.GetBinOutputDir(ACPU,AOS));
- if DirectoryExists(APackage.GetUnitsOutputDir(ACPU,AOS)) then
- DirectoryList.Add(APackage.GetUnitsOutputDir(ACPU,AOS));
- CmdRemoveDirs(DirectoryList);
- DirectoryList.Clear;
- if DirectoryExists(ExtractFileDir(APackage.GetBinOutputDir(ACPU,AOS))) then
- DirectoryList.Add(ExtractFileDir(APackage.GetBinOutputDir(ACPU,AOS)));
- if DirectoryExists(ExtractFileDir(APackage.GetUnitsOutputDir(ACPU,AOS))) then
- DirectoryList.Add(ExtractFileDir(APackage.GetUnitsOutputDir(ACPU,AOS)));
- CmdRemoveDirs(DirectoryList);
- finally
- DirectoryList.Free;
- end;
- end;
- Finally
- List.Free;
- end;
- end;
- Procedure TBuildEngine.Manifest(APackage : TPackage);
- Var
- L : TStrings;
- PD,
- MF : String;
- begin
- L:=TStringList.Create;
- Try
- Log(vlInfo, Format(SInfoManifestPackage,[APackage.Name]));
- PD:=APackage.Directory;
- if PD<>'' then
- PD:=IncludeTrailingPathDelimiter(PD);
- MF:=PD+ManifestFile;
- Log(vlDebug, Format(SDbgGenerating, [MF]));
- L.Add('<?xml version="1.0"?>');
- L.Add('<packages>');
- APackage.GetManifest(L);
- L.Add('</packages>');
- L.SaveToFile(MF);
- Finally
- L.Free;
- end;
- end;
- procedure TBuildEngine.Compile(Packages: TPackages);
- Var
- I : Integer;
- P : TPackage;
- begin
- If Assigned(BeforeCompile) then
- BeforeCompile(Self);
- For I:=0 to Packages.Count-1 do
- begin
- P:=Packages.PackageItems[i];
- log(vlWarning,SWarnStartBuildingPackage,[P.Name, Defaults.Target]);
- If PackageOK(P) then
- MaybeCompile(P);
- //show compile progress
- log(vlWarning,SWarnBuildingPackagecomplete,[(I + 1)/Packages.Count * 100, P.Name]);
- end;
- If Assigned(AfterCompile) then
- AfterCompile(Self);
- end;
- procedure TBuildEngine.Install(Packages: TPackages);
- Var
- I : Integer;
- P : TPackage;
- begin
- If Assigned(BeforeInstall) then
- BeforeInstall(Self);
- For I:=0 to Packages.Count-1 do
- begin
- P:=Packages.PackageItems[i];
- If PackageOK(P) then
- Install(P);
- log(vlWarning, SWarnInstallationPackagecomplete, [P.Name, Defaults.Target]);
- end;
- If Assigned(AfterInstall) then
- AfterInstall(Self);
- end;
- procedure TBuildEngine.Archive(Packages: TPackages);
- Var
- I : Integer;
- P : TPackage;
- begin
- If Assigned(BeforeArchive) then
- BeforeArchive(Self);
- Log(vlDebug, SDbgBuildEngineArchiving);
- For I:=0 to Packages.Count-1 do
- begin
- P:=Packages.PackageItems[i];
- Archive(P);
- end;
- If Assigned(AfterArchive) then
- AfterArchive(Self);
- end;
- procedure TBuildEngine.Manifest(Packages: TPackages);
- Var
- I : Integer;
- P : TPackage;
- begin
- If Assigned(BeforeManifest) then
- BeforeManifest(Self);
- Log(vlDebug, SDbgBuildEngineGenerateManifests);
- For I:=0 to Packages.Count-1 do
- begin
- P:=Packages.PackageItems[i];
- Manifest(P);
- end;
- If Assigned(AfterManifest) then
- AfterManifest(Self);
- end;
- procedure TBuildEngine.Clean(Packages: TPackages; AllTargets: boolean);
- Var
- I : Integer;
- P : TPackage;
- begin
- If Assigned(BeforeClean) then
- BeforeClean(Self);
- Log(vldebug, SDbgBuildEngineCleaning);
- For I:=0 to Packages.Count-1 do
- begin
- P:=Packages.PackageItems[i];
- If AllTargets or PackageOK(P) then
- Clean(P, AllTargets);
- log(vlWarning, SWarnCleanPackagecomplete, [P.Name]);
- end;
- If Assigned(AfterClean) then
- AfterClean(Self);
- end;
- {****************************************************************************
- TFPVersion
- ****************************************************************************}
- function TFPVersion.GetAsString: String;
- begin
- if Empty then
- Result:='<none>'
- else
- begin
- Result := '';
- if Major <> -1 then
- Result := Result + IntToStr(Major);
- if Minor <> -1 then
- Result := Result + '.' + IntToStr(Minor);
- if Micro <> -1 then
- Result := Result + '.' + IntToStr(Micro);
- if Build <> -1 then
- Result := Result + '-' + IntToStr(Build);
- end;
- end;
- function TFPVersion.GetEmpty: Boolean;
- begin
- Result:=(Major=0) and (Minor=0) and (Micro=0) and (Build=0);
- end;
- procedure TFPVersion.SetAsString(const AValue: String);
- Function NextDigit(sep : Char; var V : string) : integer;
- Var
- P : Integer;
- begin
- P:=Pos(Sep,V);
- If (P=0) then
- P:=Length(V)+1;
- Result:=StrToIntDef(Copy(V,1,P-1),-1);
- If Result<>-1 then
- Delete(V,1,P);
- end;
- Var
- V : String;
- begin
- Clear;
- // Special support for empty version string
- if (AValue='') or (AValue='<none>') then
- exit;
- V:=AValue;
- Major:=NextDigit('.',V);
- Minor:=NextDigit('.',V);
- Micro:=NextDigit('-',V);
- Build:=NextDigit(#0,V);
- end;
- procedure TFPVersion.Clear;
- begin
- Micro:=-1;
- Major:=-1;
- Minor:=-1;
- Build:=-1;
- end;
- procedure TFPVersion.Assign(Source: TPersistent);
- Var
- V : TFPVersion;
- begin
- if Source is TFPVersion then
- begin
- V:=Source as TFPVersion;
- Major:=V.Major;
- Minor:=V.Minor;
- Micro:=V.Micro;
- Build:=V.Build;
- end
- else
- inherited Assign(Source);
- end;
- function TFPVersion.CompareVersion(AVersion: TFPVersion): Integer;
- begin
- Result:=Major-AVersion.Major;
- If (Result=0) then
- begin
- Result:=Minor-AVersion.Minor;
- if (Result=0) then
- begin
- Result:=Micro-AVersion.Micro;
- If (Result=0) then
- Result:=Build-AVersion.Build;
- end;
- end;
- end;
- function TFPVersion.SameVersion(AVersion: TFPVersion): Boolean;
- begin
- Result:=CompareVersion(AVersion)=0;
- end;
- {****************************************************************************
- TTarget
- ****************************************************************************}
- constructor TTarget.Create(ACollection: TCollection);
- begin
- inherited Create(ACollection);
- FInstall:=True;
- FCPUs:=AllCPUs;
- FOSes:=AllOSes;
- FUnitPath:=TConditionalStrings.Create(TConditionalString);
- FIncludePath:=TConditionalStrings.Create(TConditionalString);
- FObjectPath:=TConditionalStrings.Create(TConditionalString);
- FDependencies:=TDependencies.Create(TDependency);
- FCommands:=TCOmmands.Create(TCommand);
- end;
- destructor TTarget.Destroy;
- begin
- FreeAndNil(FUnitPath);
- FreeAndNil(FObjectPath);
- FreeAndNil(FIncludePath);
- FreeAndNil(FDependencies);
- FreeAndNil(FCommands);
- FreeAndNil(Foptions);
- inherited Destroy;
- end;
- function TTarget.GetOptions: TStrings;
- begin
- If Foptions=Nil then
- FOptions:=TStringList.Create;
- Result:=FOptions;
- end;
- function TTarget.GetUnitLibFileName: String;
- begin
- Result:='libp'+Name+LibExt;
- end;
- procedure TTarget.SetOptions(const AValue: TStrings);
- begin
- If (AValue=Nil) or (AValue.Count=0) then
- FreeAndNil(FOptions)
- else
- Options.Assign(AValue);
- end;
- function TTarget.GetSourceFileName: String;
- begin
- Result:=Name+FExtension;
- end;
- function TTarget.GetUnitFileName: String;
- begin
- Result:=Name+UnitExt;
- end;
- function TTarget.GetObjectFileName: String;
- begin
- Result:=Name+ObjExt;
- end;
- function TTarget.GetRSTFileName: String;
- begin
- Result:=Name+RSText;
- end;
- function TTarget.GetProgramFileName(AOS : TOS): String;
- begin
- if AOS in [Go32v2,Win32,Win64,OS2] then
- Result:=Name+ExeExt
- else
- Result:=Name;
- end;
- function TTarget.GetOutputFileName(AOs: TOS): String;
- begin
- if TargetType in UnitTargets then
- Result:=GetUnitFileName
- else
- Result:=GetProgramFileName(AOs);
- end;
- function TTarget.HaveOptions: Boolean;
- begin
- Result:=(FOptions<>Nil);
- end;
- procedure TTarget.SetName(const AValue: String);
- Var
- D,N,E : String;
- begin
- N:=FixPath(AValue);
- D:=ExtractFilePath(N);
- E:=ExtractFileExt(N);
- N:=ExtractFileName(N);
- inherited SetName(Copy(N,1,Length(N)-Length(E)));
- FExtension:=E;
- FDirectory:=D;
- end;
- procedure TTarget.SetXML(const AValue: string);
- begin
- FXML:=FixPath(AValue);
- end;
- procedure TTarget.GetCleanFiles(List: TStrings; const APrefixU, APrefixB : String; ACPU: TCPU; AOS : TOS);
- begin
- If not(ACPU in CPUs) or not(AOS in OSes) then
- exit;
- List.Add(APrefixU + ObjectFileName);
- If (TargetType in [ttUnit,ttImplicitUnit,ttExampleUnit, ttCleanOnlyUnit]) then
- begin
- List.Add(APrefixU + UnitFileName);
- if (AOS in AllSmartLinkLibraryOSes) and FileExists(APrefixU + UnitLibFileName) then
- List.Add(APrefixU + UnitLibFileName);
- end
- else If (TargetType in [ttProgram,ttExampleProgram]) then
- List.Add(APrefixB + GetProgramFileName(AOS));
- If ResourceStrings then
- List.Add(APrefixU + RSTFileName);
- // Maybe add later ? AddConditionalStrings(List,CleanFiles);
- end;
- procedure TTarget.GetInstallFiles(List: TStrings; const APrefixU, APrefixB: String; ACPU: TCPU; AOS : TOS);
- begin
- If not(ACPU in CPUs) or not(AOS in OSes) then
- exit;
- If Not (TargetType in [ttProgram,ttExampleProgram]) then
- List.Add(APrefixU + ObjectFileName);
- If (TargetType in [ttUnit,ttImplicitUnit,ttExampleUnit]) then
- begin
- List.Add(APrefixU + UnitFileName);
- if (AOS in AllSmartLinkLibraryOSes) and FileExists(APrefixU + UnitLibFileName) then
- List.Add(APrefixU + UnitLibFileName);
- end
- else If (TargetType in [ttProgram,ttExampleProgram]) then
- List.Add(APrefixB + GetProgramFileName(AOS));
- If ResourceStrings then
- List.Add(APrefixU + RSTFileName);
- // Maybe add later ? AddConditionalStrings(List,InstallFiles);
- end;
- procedure TTarget.GetArchiveFiles(List: TStrings; ACPU: TCPU; AOS : TOS);
- var
- i : integer;
- D : TDependency;
- begin
- If not(ACPU in CPUs) or not(AOS in OSes) then
- exit;
- // Main source
- if TargetSourceFileName<>'' then
- List.Add(TargetSourceFileName);
- // Includes
- for i:=0 to Dependencies.Count-1 do
- begin
- D:=Dependencies[i];
- if (D.DependencyType=depInclude) and
- (D.TargetFileName<>'') then
- List.Add(D.TargetFileName);
- end;
- // FPDoc files
- if XML <> '' then
- begin
- List.Add(Directory + Name + Extension);
- List.Add(XML);
- end;
- end;
- {****************************************************************************
- TSource
- ****************************************************************************}
- function TSource.GetInstallSourcePath: string;
- begin
- if FInstallSourcePath<>'' then
- result := FInstallSourcePath
- else if SourceType=stExample then
- result := 'examples'
- else
- result := '';
- end;
- constructor TSource.Create(ACollection: TCollection);
- begin
- inherited Create(ACollection);
- end;
- destructor TSource.Destroy;
- begin
- inherited Destroy;
- end;
- procedure TSource.GetInstallFiles(List: TStrings);
- begin
- if InstallSourcePath<>'' then
- list.Values[name] := (IncludeTrailingPathDelimiter(InstallSourcePath)+ExtractFileName(Name))
- else
- list.add(Name);
- end;
- {****************************************************************************
- TCommands
- ****************************************************************************}
- function TCommands.GetCommand(const Dest : String): TCommand;
- begin
- Result:=TCommand(ItemByName(Dest));
- end;
- function TCommands.GetCommandItem(Index : Integer): TCommand;
- begin
- Result:=TCommand(Items[Index]);
- end;
- procedure TCommands.SetCommandItem(Index : Integer; const AValue: TCommand);
- begin
- Items[Index]:=AValue;
- end;
- Function TCommands.AddCommand(const Cmd: String) : TCommand;
- begin
- Result:=AddCommand(fdefaultAt,Cmd,'','','');
- end;
- function TCommands.AddCommand(const Cmd, Options: String): TCommand;
- begin
- Result:=AddCommand(fdefaultAt,Cmd,Options,'','');
- end;
- function TCommands.AddCommand(const Cmd, Options, Dest, Source: String ): TCommand;
- begin
- Result:=AddCommand(fdefaultAt,Cmd,options,Dest,Source);
- end;
- Function TCommands.AddCommand(At: TCommandAt; const Cmd: String) : TCommand;
- begin
- Result:=AddCommand(At,Cmd,'','','');
- end;
- function TCommands.AddCommand(At: TCommandAt; const Cmd, Options: String ): TCommand;
- begin
- Result:=AddCommand(At,Cmd,Options,'','');
- end;
- function TCommands.AddCommand(At: TCommandAt; const Cmd, Options, Dest, Source: String): TCommand;
- begin
- Result:=Add as TCommand;
- Result.Command:=Cmd;
- If (Options<>'') then
- Result.ParseOptions(Options);
- Result.At:=At;
- Result.SourceFile:=Source;
- Result.DestFile:=Dest;
- end;
- {****************************************************************************
- TConditionalString
- ****************************************************************************}
- Constructor TConditionalString.Create;
- begin
- inherited Create;
- end;
- {****************************************************************************
- TConditionalStrings
- ****************************************************************************}
- Constructor TConditionalStrings.Create(AClass:TConditionalStringClass);
- begin
- inherited Create;
- FCSClass:=AClass;
- end;
- function TConditionalStrings.GetConditionalString(Index : Integer): TConditionalString;
- begin
- Result:=TConditionalString(Items[Index]);
- end;
- procedure TConditionalStrings.SetConditionalString(Index : Integer; const AValue: TConditionalString);
- begin
- Items[Index]:=AValue;
- end;
- Function TConditionalStrings.Add(Const Value : String) : TConditionalString;
- begin
- result:=Add(Value,AllCPUs,AllOSes);
- end;
- {$ifdef cpu_only_overloads}
- Function TConditionalStrings.Add(Const Value : String;const CPUs:TCPUs) : TConditionalString;
- begin
- result:=Add(Value,CPUs,AllOSes);
- end;
- {$endif cpu_only_overloads}
- Function TConditionalStrings.Add(Const Value : String;const OSes:TOSes) : TConditionalString;
- begin
- result:=Add(Value,AllCPUs,OSes);
- end;
- Function TConditionalStrings.Add(Const Value : String;const CPUs:TCPUs;const OSes:TOSes) : TConditionalString;
- begin
- Result:=FCSClass.Create;
- Result.Value:=Value;
- Result.OSes:=OSes;
- Result.CPUs:=CPUs;
- inherited Add(Result);
- end;
- {****************************************************************************
- TDependency
- ****************************************************************************}
- Constructor TDependency.Create;
- begin
- inherited Create;
- FVersion:=TFPVersion.Create;
- end;
- Destructor TDependency.Destroy;
- begin
- FreeAndNil(FVersion);
- end;
- Function TDependency.GetVersion : string;
- begin
- result:=FVersion.AsString;
- end;
- Procedure TDependency.SetVersion(const V : string);
- begin
- FVersion.AsString:=V;
- end;
- {****************************************************************************
- TDependencies
- ****************************************************************************}
- function TDependencies.GetDependency(Index : Integer): TDependency;
- begin
- Result:=TDependency(Items[Index]);
- end;
- procedure TDependencies.SetDependency(Index : Integer; const AValue: TDependency);
- begin
- Items[Index]:=AValue;
- end;
- Function TDependencies.Add(Const Value : String) : TDependency;
- begin
- result:=Add(Value,AllCPUs,AllOSes);
- end;
- {$ifdef cpu_only_overloads}
- Function TDependencies.Add(Const Value : String;const CPUs:TCPUs) : TDependency;
- begin
- result:=Add(Value,CPUs,AllOSes);
- end;
- {$endif cpu_only_overloads}
- Function TDependencies.Add(Const Value : String;const OSes:TOSes) : TDependency;
- begin
- result:=Add(Value,AllCPUs,OSes);
- end;
- Function TDependencies.Add(Const Value : String;const CPUs:TCPUs;const OSes:TOSes) : TDependency;
- begin
- Result:=inherited Add(Value,CPUs,OSes) as TDependency;
- Result.Target:=nil;
- Result.FDependencyType:=depPackage;
- end;
- Function TDependencies.AddUnit(Const Value : String) : TDependency;
- begin
- result:=AddUnit(Value,AllCPUs,AllOSes);
- end;
- {$ifdef cpu_only_overloads}
- Function TDependencies.AddUnit(Const Value : String;const CPUs:TCPUs) : TDependency;
- begin
- result:=AddUnit(Value,CPUs,AllOSes);
- end;
- {$endif cpu_only_overloads}
- Function TDependencies.AddUnit(Const Value : String;const OSes:TOSes) : TDependency;
- begin
- result:=AddUnit(Value,AllCPUs,OSes);
- end;
- Function TDependencies.AddUnit(Const Value : String;const CPUs:TCPUs;const OSes:TOSes) : TDependency;
- begin
- Result:=inherited Add(Value,CPUs,OSes) as TDependency;
- Result.Target:=nil;
- Result.FDependencyType:=depUnit;
- end;
- Function TDependencies.AddInclude(Const Value : String) : TDependency;
- begin
- result:=AddInclude(Value,AllCPUs,AllOSes);
- end;
- {$ifdef cpu_only_overloads}
- Function TDependencies.AddInclude(Const Value : String;const CPUs:TCPUs) : TDependency;
- begin
- result:=AddInclude(Value,CPUs,AllOSes);
- end;
- {$endif cpu_only_overloads}
- Function TDependencies.AddInclude(Const Value : String;const OSes:TOSes) : TDependency;
- begin
- result:=AddInclude(Value,AllCPUs,OSes);
- end;
- Function TDependencies.AddInclude(Const Value : String;const CPUs:TCPUs;const OSes:TOSes) : TDependency;
- Var
- N : String;
- begin
- N:=FixPath(Value);
- if ExtractFileExt(N)='' then
- ChangeFileExt(N,IncExt);
- Result:=inherited Add(N,CPUs,OSes) as TDependency;
- Result.FDependencyType:=depInclude;
- end;
- {****************************************************************************
- TValueItem
- ****************************************************************************}
- constructor TValueItem.Create(AValue: String);
- begin
- FValue:=AValue;
- end;
- {****************************************************************************
- TFunctionItem
- ****************************************************************************}
- constructor TFunctionItem.Create(AFunc: TReplaceFunction);
- begin
- FFunc:=AFunc;
- end;
- {****************************************************************************
- TDictionary
- ****************************************************************************}
- constructor TDictionary.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FList:=TStringList.Create;
- FList.Sorted:=True;
- FList.Duplicates:=dupError;
- end;
- destructor TDictionary.Destroy;
- Var
- I : Integer;
- begin
- For I:=0 to Flist.Count-1 do
- FList.Objects[i].Free;
- FreeAndNil(FList);
- inherited Destroy;
- end;
- procedure TDictionary.AddVariable(const AName, Value: String);
- Var
- I : Integer;
- begin
- I:=Flist.IndexOf(AName);
- If I=-1 then
- I:=FList.Add(Aname)
- else
- Flist.Objects[i].Free;
- Flist.Objects[i]:=TValueItem.Create(Value);
- end;
- procedure TDictionary.AddFunction(const AName: String; FReplacement: TReplaceFunction);
- Var
- I : Integer;
- begin
- I:=Flist.IndexOf(AName);
- If I=-1 then
- I:=Flist.Add(AName)
- else
- Flist.Objects[i].Free;
- Flist.Objects[i]:=TFunctionItem.Create(FReplacement);
- end;
- procedure TDictionary.RemoveItem(const AName: String);
- Var
- I : Integer;
- begin
- I:=Flist.IndexOf(AName);
- If (I<>-1) then
- begin
- FList.Objects[i].Free;
- FList.Delete(I);
- end;
- end;
- function TDictionary.GetValue(const AName: String): String;
- begin
- Result:=GetValue(AName,'');
- end;
- function TDictionary.GetValue(const AName,Args: String): String;
- Var
- O : TObject;
- I : Integer;
- begin
- I:=Flist.IndexOf(AName);
- If (I=-1) then
- Raise EDictionaryError.CreateFmt(SErrNoDictionaryItem,[AName]);
- O:=Flist.Objects[I];
- If O is TValueItem then
- Result:=TValueItem(O).FValue
- else
- Result:=TFunctionItem(O).FFunc(AName,Args);
- end;
- function TDictionary.ReplaceStrings(Const ASource: String): String;
- Var
- S,FN,FV : String;
- P: Integer;
- begin
- Result:='';
- S:=ASource;
- P:=Pos('$(',S);
- While (P<>0) do
- begin
- Result:=Result+Copy(S,1,P-1);
- Delete(S,1,P+1);
- P:=Pos(')',S);
- FN:=Copy(S,1,P-1);
- Delete(S,1,P);
- P:=Pos(' ',FN);
- If (P<>0) then // function arguments ?
- begin
- FV:=FN;
- FN:=Copy(FN,1,P);
- System.Delete(FV,1,P);
- end
- else
- FV:='';
- Result:=Result+GetValue(FN,FV);
- P:=Pos('$(',S);
- end;
- Result:=Result+S;
- end;
- Function Substitute(Const Source : String; Macros : Array of string) : String;
- Var
- I : Integer;
- begin
- I:=0;
- While I<High(Macros) do
- begin
- Dictionary.AddVariable(Macros[i],Macros[I+1]);
- Inc(I,2);
- end;
- Result:=Dictionary.ReplaceStrings(Source);
- While I<High(Macros) do
- begin
- Dictionary.RemoveItem(Macros[i]);
- Inc(I,2);
- end;
- end;
- {****************************************************************************
- Default Instances
- ****************************************************************************}
- var
- DefInstaller : TCustomInstaller;
- Function Installer(InstallerClass: TInstallerClass): TCustomInstaller;
- begin
- If Not Assigned(DefInstaller) then
- DefInstaller:=InstallerClass.Create(Nil);
- Result:=DefInstaller;
- end;
- Function Installer: TCustomInstaller;
- begin
- Result := Installer(TFPCInstaller);
- end;
- { TCommand }
- function TCommand.GetOptions: TStrings;
- begin
- If (FOptions=Nil) then
- FOptions:=TStringList.Create;
- Result:=FOptions;
- end;
- procedure TCommand.SetOptions(const Value: TStrings);
- begin
- If (Value=Nil) or (Value.Count=0) then
- FreeAndNil(FOptions)
- else
- Options.Assign(Value);
- end;
- destructor TCommand.Destroy;
- begin
- FreeAndNil(FOptions);
- inherited Destroy;
- end;
- function TCommand.HaveOptions: Boolean;
- begin
- Result:=(FOptions<>Nil);
- end;
- function TCommand.CmdLineOptions: String;
- begin
- If HaveOptions then
- Result:=OptionListToString(Options);
- end;
- procedure TCommand.ParseOptions(S: String);
- begin
- Options:=OptionsToStringList(S);
- end;
- Initialization
- OnGetApplicationName:=@GetFPMakeName;
- CustomFpmakeCommandlineOptions:=nil;
- CustomFpMakeCommandlineValues:=nil;
- Finalization
- FreeAndNil(CustomFpMakeCommandlineValues);
- FreeAndNil(CustomFpmakeCommandlineOptions);
- FreeAndNil(DefInstaller);
- FreeAndNil(Dictionary);
- FreeAndNil(Defaults);
- end.
|