123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893 |
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
- <HTML>
- <HEAD>
- <META NAME="generator" CONTENT="http://txt2tags.org">
- </HEAD><BODY BGCOLOR="white" TEXT="black">
- <CENTER>
- </CENTER>
- <H1>Part IV - Package management</H1>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <!-- This user guide is for Qi (version 1.3,
- 10 Sep 2019), which is a simple but well-integrated package manager.
- Copyright (C) 2019 Matias Andres Fonzo, Santiago del Estero,
- Argentina.
- Permission is granted to copy, distribute and/or modify this document
- under the terms of the GNU Free Documentation License, Version 1.3 or
- any later version published by the Free Software Foundation; with no
- Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
- Texts. A copy of the license is included in the section entitled
- "GNU Free Documentation License". -->
- <!-- Created by GNU Texinfo 6.5, http://www.gnu.org/software/texinfo/ -->
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
- <title>Qi user guide</title>
- <meta name="description" content="Qi user guide">
- <meta name="keywords" content="Qi user guide">
- <meta name="resource-type" content="document">
- <meta name="distribution" content="global">
- <meta name="Generator" content="makeinfo">
- <link href="#Top" rel="start" title="Top">
- <link href="#Index" rel="index" title="Index">
- <link href="#SEC_Contents" rel="contents" title="Table of Contents">
- <link href="dir.html#Top" rel="up" title="(dir)">
- <style type="text/css">
- <!--
- a.summary-letter {text-decoration: none}
- blockquote.indentedblock {margin-right: 0em}
- blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
- blockquote.smallquotation {font-size: smaller}
- div.display {margin-left: 3.2em}
- div.example {margin-left: 3.2em}
- div.lisp {margin-left: 3.2em}
- div.smalldisplay {margin-left: 3.2em}
- div.smallexample {margin-left: 3.2em}
- div.smalllisp {margin-left: 3.2em}
- kbd {font-style: oblique}
- pre.display {font-family: inherit}
- pre.format {font-family: inherit}
- pre.menu-comment {font-family: serif}
- pre.menu-preformatted {font-family: serif}
- pre.smalldisplay {font-family: inherit; font-size: smaller}
- pre.smallexample {font-size: smaller}
- pre.smallformat {font-family: inherit; font-size: smaller}
- pre.smalllisp {font-size: smaller}
- span.nolinebreak {white-space: nowrap}
- span.roman {font-family: initial; font-weight: normal}
- span.sansserif {font-family: sans-serif; font-weight: normal}
- ul.no-bullet {list-style: none}
- -->
- </style>
- </head>
- <body lang="en">
- <h1 class="settitle" align="center">Qi user guide</h1>
- <a name="SEC_Contents"></a>
- <h2 class="contents-heading">Table of Contents</h2>
- <div class="contents">
- <ul class="no-bullet">
- <li><a name="toc-Introduction-1" href="#Introduction">1 Introduction</a></li>
- <li><a name="toc-Invoking-qi-1" href="#Invoking-qi">2 Invoking qi</a></li>
- <li><a name="toc-The-qirc-file-1" href="#The-qirc-file">3 The qirc file</a></li>
- <li><a name="toc-Packages-1" href="#Packages">4 Packages</a>
- <ul class="no-bullet">
- <li><a name="toc-Package-conflicts" href="#Package-conflicts">4.1 Package conflicts</a></li>
- <li><a name="toc-Installing-packages" href="#Installing-packages">4.2 Installing packages</a></li>
- <li><a name="toc-Removing-packages" href="#Removing-packages">4.3 Removing packages</a></li>
- <li><a name="toc-Upgrading-packages" href="#Upgrading-packages">4.4 Upgrading packages</a>
- <ul class="no-bullet">
- <li><a name="toc-Package-blacklist" href="#Package-blacklist">4.4.1 Package blacklist</a></li>
- </ul></li>
- </ul></li>
- <li><a name="toc-Recipes-1" href="#Recipes">5 Recipes</a>
- <ul class="no-bullet">
- <li><a name="toc-Variables" href="#Variables">5.1 Variables</a></li>
- <li><a name="toc-Special-variables" href="#Special-variables">5.2 Special variables</a></li>
- <li><a name="toc-Writing-recipes" href="#Writing-recipes">5.3 Writing recipes</a></li>
- <li><a name="toc-Building-packages" href="#Building-packages">5.4 Building packages</a></li>
- <li><a name="toc-Variables-from-the-environment" href="#Variables-from-the-environment">5.5 Variables from the environment</a></li>
- <li><a name="toc-The-meta-file" href="#The-meta-file">5.6 The meta file</a></li>
- </ul></li>
- <li><a name="toc-Order-files-1" href="#Order-files">6 Order files</a></li>
- <li><a name="toc-Creating-packages-1" href="#Creating-packages">7 Creating packages</a></li>
- <li><a name="toc-Examining-packages-1" href="#Examining-packages">8 Examining packages</a></li>
- <li><a name="toc-Exit-status-1" href="#Exit-status">9 Exit status</a></li>
- <li><a name="toc-Index-1" href="#Index">Index</a></li>
- </ul>
- </div>
- <a name="Top"></a>
- <div class="header">
- <p>
- Next: <a href="#Introduction" accesskey="n" rel="next">Introduction</a>, Up: <a href="dir.html#Top" accesskey="u" rel="up">(dir)</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="#Index" title="Index" rel="index">Index</a>]</p>
- </div>
- <a name="SEC_Top"></a>
- <p>This user guide is for Qi (version 1.3,
- 10 Sep 2019).
- </p>
- <table class="menu" border="0" cellspacing="0">
- <tr><td align="left" valign="top">• <a href="#Introduction" accesskey="1">Introduction</a>:</td><td> </td><td align="left" valign="top">Description and features of qi
- </td></tr>
- <tr><td align="left" valign="top">• <a href="#Invoking-qi" accesskey="2">Invoking qi</a>:</td><td> </td><td align="left" valign="top">Command-line options
- </td></tr>
- <tr><td align="left" valign="top">• <a href="#The-qirc-file" accesskey="3">The qirc file</a>:</td><td> </td><td align="left" valign="top">Configuration file
- </td></tr>
- <tr><td align="left" valign="top">• <a href="#Packages" accesskey="4">Packages</a>:</td><td> </td><td align="left" valign="top">Managing packages
- </td></tr>
- <tr><td align="left" valign="top">• <a href="#Recipes" accesskey="5">Recipes</a>:</td><td> </td><td align="left" valign="top">Building packages
- </td></tr>
- <tr><td align="left" valign="top">• <a href="#Order-files" accesskey="6">Order files</a>:</td><td> </td><td align="left" valign="top">Handling build order
- </td></tr>
- <tr><td align="left" valign="top">• <a href="#Creating-packages" accesskey="7">Creating packages</a>:</td><td> </td><td align="left" valign="top">Making Qi packages
- </td></tr>
- <tr><td align="left" valign="top">• <a href="#Examining-packages" accesskey="8">Examining packages</a>:</td><td> </td><td align="left" valign="top">Debugging purposes
- </td></tr>
- <tr><td align="left" valign="top">• <a href="#Exit-status" accesskey="9">Exit status</a>:</td><td> </td><td align="left" valign="top">Exit codes
- </td></tr>
- <tr><td align="left" valign="top">• <a href="#Index">Index</a>:</td><td> </td><td align="left" valign="top">
- </td></tr>
- </table>
- <br>
- <p>Copyright (C) 2019 Matias Fonzo.
- </p>
- <p>Qi’s home page can be found at <a href="http://www.dragora.org">http://www.dragora.org</a>.
- Send bug reports or suggestions to <a href="mailto:dragora-users@nongnu.org"><span class="nolinebreak">dragora-users</span>@nongnu.org</a>.<!-- /@w -->
- </p>
- <hr>
- <a name="Introduction"></a>
- <div class="header">
- <p>
- Next: <a href="#Invoking-qi" accesskey="n" rel="next">Invoking qi</a>, Previous: <a href="#Top" accesskey="p" rel="prev">Top</a>, Up: <a href="#Top" accesskey="u" rel="up">Top</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="#Index" title="Index" rel="index">Index</a>]</p>
- </div>
- <a name="Introduction-1"></a>
- <h2 class="chapter">1 Introduction</h2>
- <a name="index-introduction"></a>
- <p>Qi is a simple but well-integrated package manager. It can create,
- install, remove, and upgrade software packages. Qi produces binary
- packages using recipes, which are files containing specific instructions
- to build each package from source. Qi can manage multiple packages
- under a single directory hierarchy. This method allows to maintain a set
- of packages and multiple versions of them. This means that Qi could be
- used as the main package manager or complement the existing one.
- </p>
- <p>Qi offers a friendly command line interface, a global configuration
- file, a simple recipe layout to deploy software packages; also works
- with binary packages in parallel, speeding up installations and packages
- in production. The format used for packages is a simplified but safe
- POSIX pax archive compressed with lzip.
- </p>
- <p>Qi is a modern (POSIX-compliant) shell script released under the
- terms of the GNU General Public License. There are only two major
- dependencies for the magic: graft(1) and tarlz(1), the rest is expected
- to be found in any Unix-like system.
- </p>
- <hr>
- <a name="Invoking-qi"></a>
- <div class="header">
- <p>
- Next: <a href="#The-qirc-file" accesskey="n" rel="next">The qirc file</a>, Previous: <a href="#Introduction" accesskey="p" rel="prev">Introduction</a>, Up: <a href="#Top" accesskey="u" rel="up">Top</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="#Index" title="Index" rel="index">Index</a>]</p>
- </div>
- <a name="Invoking-qi-1"></a>
- <h2 class="chapter">2 Invoking qi</h2>
- <a name="index-invocation"></a>
- <p>This chapter describes the synopsis and command line options for
- invoke Qi.
- </p>
- <div class="example">
- <pre class="example">Usage: qi [<var>OPTION</var>]... [<var>FILE</var>]...
- </pre></div>
- <p>One mandatory option specifies the operation that ‘<samp>qi</samp>’ should
- perform, other options are meant to detail how this operation should be
- performed.
- </p>
- <p>qi supports the following options to operate:
- </p>
- <dl compact="compact">
- <dt><code>-b</code></dt>
- <dd><p>Build package using recipe names.
- </p>
- </dd>
- <dt><code>-c</code></dt>
- <dd><p>Create .tlz package from directory.
- </p>
- </dd>
- <dt><code>-d</code></dt>
- <dd><p>Delete packages.
- </p>
- </dd>
- <dt><code>-i</code></dt>
- <dd><p>Install packages.
- </p>
- </dd>
- <dt><code>-o</code></dt>
- <dd><p>Resolve build order through .order files.
- </p>
- </dd>
- <dt><code>-u</code></dt>
- <dd><p>Update packages (implies -i, -d and -p options).
- </p>
- </dd>
- <dt><code>-w</code></dt>
- <dd><p>Warn about files that will be linked.
- </p>
- </dd>
- <dt><code>-x</code></dt>
- <dd><p>Extract a package for debugging purposes.
- </p></dd>
- </dl>
- <p>There are common options between modes:
- </p>
- <dl compact="compact">
- <dt><code>-N</code></dt>
- <dd><p>Do not read the configuration file.
- </p>
- <p>This will ignore any value in the qirc file.
- </p>
- </dd>
- <dt><code>-P <DIR></code></dt>
- <dd><p>Package directory for installations.
- </p>
- <p>This option sets ‘<samp>${packagedir}</samp>’.
- </p>
- <p>Only valid for -i, -d, or -u options.
- </p>
- </dd>
- <dt><code>-f</code></dt>
- <dd><p>Force option.
- </p>
- <p>This option can force the build of a recipe, or force the update of a
- pre-existing package.
- </p>
- <p>Only valid for -b, -u options.
- </p>
- </dd>
- <dt><code>-t <DIR></code></dt>
- <dd><p>Target directory for symbolic links.
- </p>
- <p>This option sets ‘<samp>${targetdir}</samp>’.
- </p>
- <p>Only valid for -i, -d, or -u options.
- </p>
- </dd>
- <dt><code>-k</code></dt>
- <dd><p>Keep (don’t delete) ‘<samp>${srcdir}</samp>’ or ‘<samp>${destdir}</samp>’ in build
- mode, keep (don’t delete) package directory in delete mode.
- </p>
- <p>Only valid for -b, -d or -u options.
- </p>
- </dd>
- <dt><code>-p</code></dt>
- <dd><p>Prune conflicts on package installations.
- </p>
- <p>This option may proceed with the package installation if one or more
- conflicts occur.
- </p>
- </dd>
- <dt><code>-r /rootdir</code></dt>
- <dd><p>Use the fully qualified named directory as the root directory for all qi
- operations. The target directory and package directory will be relative
- to the specified directory, including the log file for graft.
- </p>
- </dd>
- <dt><code>-v</code></dt>
- <dd><p>Be verbose (a 2nd -v gives more).
- </p></dd>
- </dl>
- <p>Options for build mode (-b):
- </p>
- <dl compact="compact">
- <dt><code>-O <DIR></code></dt>
- <dd><p>Where the packages produced are written.
- </p>
- <p>This option sets ‘<samp>${outdir}</samp>’.
- </p>
- </dd>
- <dt><code>-W <DIR></code></dt>
- <dd><p>Where archives, patches, and recipes are expected.
- </p>
- <p>This option sets ‘<samp>${worktree}</samp>’.
- </p>
- </dd>
- <dt><code>-Z <DIR></code></dt>
- <dd><p>Where (compressed) sources will be found.
- </p>
- <p>This option sets ‘<samp>${tardir}</samp>’.
- </p>
- </dd>
- <dt><code>-a</code></dt>
- <dd><p>Architecture to use.
- </p>
- <p>Default value is obtained via uname(1) as ‘<samp>uname -m</samp>’.
- </p>
- </dd>
- <dt><code>-j</code></dt>
- <dd><p>Parallel jobs for the compiler.
- </p>
- <p>If not specified, default sets to 1.
- </p>
- </dd>
- <dt><code>-1</code></dt>
- <dd><p>Increment release number (‘<samp>${release}</samp>’ + 1).
- </p>
- <p>It will be omitted if the -n option is being used.
- </p>
- </dd>
- <dt><code>-n</code></dt>
- <dd><p>Don’t create a .tlz package.
- </p>
- </dd>
- <dt><code>-S</code></dt>
- <dd><p>Selects the option to skip completed recipes.
- </p>
- <p>This means, in interactive mode, when the dialog
- to summarize recipes is shown.
- </p></dd>
- </dl>
- <p>Informative options:
- </p>
- <dl compact="compact">
- <dt><code>-L</code></dt>
- <dd><p>Print default directory locations.
- </p>
- <p>This will print the target directory, package directory, working tree,
- the directory for tarballs, and the output directory for the packages
- produced.
- </p>
- </dd>
- <dt><code>-h</code></dt>
- <dd><p>Display the help describing the options and then exit.
- </p>
- </dd>
- <dt><code>-V</code></dt>
- <dd><p>Print the version number and license information.
- The version number should be included in all bug reports.
- </p></dd>
- </dl>
- <p>Expected non-option arguments are package directories and regular files:
- recipes or files ending in .tlz, .order. When FILE is -, qi can read from
- the standard input. See examples in <a href="#Packages">Packages</a>.
- </p>
- <hr>
- <a name="The-qirc-file"></a>
- <div class="header">
- <p>
- Next: <a href="#Packages" accesskey="n" rel="next">Packages</a>, Previous: <a href="#Invoking-qi" accesskey="p" rel="prev">Invoking qi</a>, Up: <a href="#Top" accesskey="u" rel="up">Top</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="#Index" title="Index" rel="index">Index</a>]</p>
- </div>
- <a name="The-qirc-file-1"></a>
- <h2 class="chapter">3 The qirc file</h2>
- <a name="index-configuration-file"></a>
- <p>The global <samp>qirc</samp> file offers a way to define variables and tools
- (such as a download manager) for default use. This file is used by qi
- at runtime, e.g., to build, install, remove or upgrade packages.
- </p>
- <p>It has the following rules:
- </p>
- <ul>
- <li> Variables must be declared as ‘<samp>name=value</samp>’.
- </li><li> Declaration of values should only take one line, no line break.
- </li><li> For security reasons, assignments like ‘<samp>name=$var</samp>’ are only
- interpreted as literal.
- </li></ul>
- <p>The command line options related to the package directory and target
- directory plus some of the options used for the build mode can override
- some values in <samp>qirc</samp>. See <a href="#Invoking-qi">Invoking qi</a>.
- </p>
- <p>The order in which qi looks for this file is:
- </p>
- <ol>
- <li> <code>${HOME}/.qirc</code>
- Effective user.
- </li><li> ‘<samp>${sysconfdir}/qirc</samp>’
- System-wide.
- </li></ol>
- <p>If you intend to run qi as effective user, the file
- ‘<samp>${sysconfdir}/qirc</samp>’ could be copied to <code>${HOME}/.qirc</code>
- setting the paths for ‘<samp>${packagedir}</samp>’ and ‘<samp>${targetdir}</samp>’
- according to the <code>$HOME</code>.
- </p>
- <hr>
- <a name="Packages"></a>
- <div class="header">
- <p>
- Next: <a href="#Recipes" accesskey="n" rel="next">Recipes</a>, Previous: <a href="#The-qirc-file" accesskey="p" rel="prev">The qirc file</a>, Up: <a href="#Top" accesskey="u" rel="up">Top</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="#Index" title="Index" rel="index">Index</a>]</p>
- </div>
- <a name="Packages-1"></a>
- <h2 class="chapter">4 Packages</h2>
- <a name="index-managing-packages"></a>
- <p>A package is a suite of programs usually distributed in binary form
- which may also contain manual pages, documentation, or any other file
- associated to a specific software.
- </p>
- <p>The package format used by qi is a simplified POSIX pax archive
- compressed with lzip. The file extension for packages is ‘<samp>.tlz</samp>’.
- </p>
- <p>Both package installation and package de-installation are managed using
- two important (internal) variables: ‘<samp>${packagedir}</samp>’ and
- ‘<samp>${targetdir}</samp>’, these values can be changed in the
- configuration file or via options.
- </p>
- <p>‘<samp>${packagedir}</samp>’ is a common directory tree where the package
- contents will be decompressed (will reside).
- </p>
- <p>‘<samp>${targetdir}</samp>’ is a target directory where the links will be
- made by graft(1) taking ‘<samp>${packagedir}/package_name</samp>’ into account.
- </p>
- <p>Packages are installed in self-contained directory trees and symbolic
- links from a common area are made to the package files. This allows
- multiple versions of the same package to coexist on the same system.
- </p>
- <a name="Package-conflicts"></a>
- <h3 class="section">4.1 Package conflicts</h3>
- <a name="index-package-conflicts"></a>
- <p>All the links to install or remove a package are handled by graft(1).
- Since multiple packages can be installed or removed at the same time,
- certain conflicts may arise between the packages.
- </p>
- <p>graft<a name="DOCF1" href="#FOOT1"><sup>1</sup></a>
- defines a CONFLICT as one of the following conditions:
- </p>
- <ul>
- <li> If the package object is a directory and the target object exists but is
- not a directory.
- </li><li> If the package object is not a directory and the target object exists
- and is not a symbolic link.
- </li><li> If the package object is not a directory and the target object exists
- and is a symbolic link to something other than the package object.
- </li></ul>
- <p>The default behavior of qi for an incoming package is to ABORT if a
- conflict arises. When a package is going to be deleted, qi tells to
- graft(1) to remove those parts that are not in conflict, leaving the
- links to the belonging package. This behavior can be forced if the
- -p option is given.
- </p>
- <a name="Installing-packages"></a>
- <h3 class="section">4.2 Installing packages</h3>
- <a name="index-package-installation"></a>
- <p>To install a single package, simply type:
- </p>
- <div class="example">
- <pre class="example">qi -i coreutils-8.30-i586+1.tlz
- </pre></div>
- <p>To install multiple packages at once, type:
- </p>
- <div class="example">
- <pre class="example">qi -i gcc-8.3.0-i586+1.tlz rafaela-2.2-i586+1.tlz ...
- </pre></div>
- <p>Warn about the files that will be linked:
- </p>
- <div class="example">
- <pre class="example">qi -w bash-5.0-i586+1.tlz
- </pre></div>
- <p>This is to verify the content of a package before installing it.
- </p>
- <p>See the process of an installation (very verbose):
- </p>
- <div class="example">
- <pre class="example">qi -i -v mariana-3.0-i586+1.tlz
- </pre></div>
- <p>A second -v gives more.
- </p>
- <p>Installing package in a different location:
- </p>
- <div class="example">
- <pre class="example">qi -r /media/floppy -i lzip-1.21-i586+1.tlz
- </pre></div>
- <p>The -r option assumes ‘<samp>${targetdir}</samp>’ and ‘<samp>${packagedir}</samp>’.
- See:
- </p>
- <div class="example">
- <pre class="example">qi -r /home/selk -P /pkgs -t / -i lzip-1.21-i586+1.tlz
- </pre></div>
- <p>In this case the content of "lzip-1.21-i586+1.tlz" will be decompressed
- into ‘<samp>/home/selk/pkgs/lzip-1.21-i586+1</samp>’. Assuming that the main
- binary for lzip is under ‘<samp>/home/selk/pkgs/lzip-1.21-i586+1/usr/bin/</samp>’
- the target for "usr/bin" will be created at ‘<samp>/home/selk</samp>’. Considering
- that you have exported the <code>PATH</code> as ‘<samp>${HOME}/usr/bin</samp>’, now the
- system is able to see the recent lzip.
- </p>
- <p>Installing from a list of packages using standard input:
- </p>
- <div class="example">
- <pre class="example">cat FILELIST.txt | qi -i -
- </pre></div>
- <p>The list of packages must contain full path names to be passed in the
- installation, e.g.:
- /var/cache/qi/packages/x86_64/devel/tcl-8.6.9-x86_64+1.tlz
- /var/cache/qi/packages/x86_64/devel/tk-8.6.9.1-x86_64+1.tlz
- /var/cache/qi/packages/x86_64/devel/vala-0.42.3-x86_64+1.tlz
- </p>
- <a name="Removing-packages"></a>
- <h3 class="section">4.3 Removing packages</h3>
- <a name="index-package-de_002dinstallation"></a>
- <p>To remove a package, simply type:
- </p>
- <div class="example">
- <pre class="example">qi -d xz-5.2.4-i586+1.tlz
- </pre></div>
- <p>Delete mode will match the package name using ‘<samp>${packagedir}</samp>’ as
- prefix. For example, if the value of ‘<samp>${packagedir}</samp>’ is set to
- /usr/local/pkgs, this will be equal to:
- </p>
- <div class="example">
- <pre class="example">qi -d /usr/local/pkgs/xz-5.2.4-i586+1
- </pre></div>
- <p>Detailed output (very verbose):
- </p>
- <div class="example">
- <pre class="example">qi -d -v /usr/local/pkgs/xz-5.2.4-i586+1
- </pre></div>
- <p>A second -v gives more.
- </p>
- <p>By default the delete mode does not preserve a package directory after
- removing its links from ‘<samp>${targetdir}</samp>’, but this behavior can be
- changed if the -k option is passed:
- </p>
- <div class="example">
- <pre class="example">qi -d -k /usr/local/pkgs/lzip-1.21-i586+1
- </pre></div>
- <p>This means that the links to the package can be reactivated, later:
- </p>
- <div class="example">
- <pre class="example">cd /usr/local/pkgs && graft -i lzip-1.21-i586+1
- </pre></div>
- <p>Removing package from a different location:
- </p>
- <div class="example">
- <pre class="example">qi -r /home/cthulhu -P /pkgs -t / -d xz-5.2.4-i586+1
- </pre></div>
- <p>Removing a package using standard input:
- </p>
- <div class="example">
- <pre class="example">echo "vala-0.42.3-x86_64+1" | qi -d -
- </pre></div>
- <p>This will match with the package directory.
- </p>
- <a name="Upgrading-packages"></a>
- <h3 class="section">4.4 Upgrading packages</h3>
- <a name="index-package-upgrade"></a>
- <p>The upgrade mode inherits the properties of the installation and removal
- process. To make sure that a package is updated, the package is installed
- in a temporary directory taking ‘<samp>${packagedir}</samp>’ into account. Once
- the incoming package is pre-installed, qi can proceed to search and delete
- packages that have the same name (considered as previous ones). Finally,
- the package is re-installed at its final location and the temporary
- directory is removed.
- </p>
- <p>To upgrade a package, just type:
- </p>
- <div class="example">
- <pre class="example">qi -u gcc-9.0.1-i586+1.tlz
- </pre></div>
- <p>This will proceed to update "gcc-9.0.1-i586+1" removing other versions
- of "gcc" (if any).
- </p>
- <p>If you want to keep the package directories of versions found during the
- upgrade process, just pass:
- </p>
- <div class="example">
- <pre class="example">qi -u -k gcc-9.0.1-i586+1.tlz
- </pre></div>
- <p>To see the upgrade process (very verbose):
- </p>
- <div class="example">
- <pre class="example">qi -u -v gcc-9.0.1-i586+1.tlz
- </pre></div>
- <p>A second -v gives more.
- </p>
- <p>To force the upgrade of an existing package:
- </p>
- <div class="example">
- <pre class="example">qi -u -f gcc-9.0.1-i586+1.tlz
- </pre></div>
- <a name="Package-blacklist"></a>
- <h4 class="subsection">4.4.1 Package blacklist</h4>
- <a name="index-package-blacklist"></a>
- <p>To implement general package facilities, either to install, remove or
- maintain the hierarchy of packages in a clean manner, qi makes use of the
- pruning operation via graft(1):
- </p>
- <p>There is a risk if those are crucial packages for the proper functioning
- of the system, because it implies the deactivation of symbolic from the
- target directory, <em>especially</em> when transitioning an incoming package
- into its final location during upgrade.
- </p>
- <p>A blacklist of package names has been devised for the case where
- a user decides to upgrade all packages in the system, or
- just the crucial ones, such as the C library.
- </p>
- <p>The blacklist is related to the upgrade mode only, consists in installing
- a package instead of updating it or removing previous versions of it;
- the content of the package will be updated over the existing content at
- ‘<samp>${packagedir}</samp>’, while the existing links from
- ‘<samp>${targetdir}</samp>’ will be preserved. A pruning of links will be
- carried out in order to re-link possible differences with the recent
- content, this helps to avoid leaving dead links in the target directory.
- </p>
- <p>Since the upgrade mode is also used to install a new package, the mechanism
- for blacklist is to install a declared package if it does not already
- exist. If it already exists, it is verified that the binary package is
- newer than the package directory in order to perform an update.
- </p>
- <p>Package names for the blacklist can be set from the configuration file.
- </p>
- <hr>
- <a name="Recipes"></a>
- <div class="header">
- <p>
- Next: <a href="#Order-files" accesskey="n" rel="next">Order files</a>, Previous: <a href="#Packages" accesskey="p" rel="prev">Packages</a>, Up: <a href="#Top" accesskey="u" rel="up">Top</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="#Index" title="Index" rel="index">Index</a>]</p>
- </div>
- <a name="Recipes-1"></a>
- <h2 class="chapter">5 Recipes</h2>
- <a name="index-recipes"></a>
- <p>A recipe is a file telling qi what to do. Most often, the recipe tells
- qi how to build a binary package from a source tarball.
- </p>
- <p>A recipe has two parts: a list of variable definitions and a list of
- sections. By convention, the syntax of a section is:
- </p>
- <div class="example">
- <pre class="example">section_name()
- {
- section lines
- }
- </pre></div>
- <p>The section name is followed by parentheses, one newline and an opening
- brace. The line finishing the section contains just a closing brace.
- The section names or the function names currently recognized are
- ‘<samp>build</samp>’.
- </p>
- <p>The ‘<samp>build</samp>’ section is an augmented shell script. This is the main
- section (or <strong>shell function</strong>) which contains the instructions to
- build and produce a package.
- </p>
- <a name="Variables"></a>
- <h3 class="section">5.1 Variables</h3>
- <a name="index-variables"></a>
- <p>A "variable" is a <strong>shell variable</strong> defined either in <samp>qirc</samp>
- or in a recipe to represent a string of text, called the variable’s
- "value". These values are substituted by explicit request in the
- definitions of other variables or in calls to external commands.
- </p>
- <p>Variables can represent lists of file names, options to pass to
- compilers, programs to run, directories to look in for source files,
- directories to write output to, or anything else you can imagine.
- </p>
- <p>Definitions of variables in qi have four levels of precedence.
- Options which define variables from the command-line override those
- specified in the <samp>qirc</samp> file, while variables defined in the recipe
- override those specified in <samp>qirc</samp>, taking priority over those
- variables set by command-line options. Finally, the variables have
- default values if they are not defined anywhere.
- </p>
- <p>Options that set variables through the command-line can only reference
- variables defined in <samp>qirc</samp> and variables with default values.
- </p>
- <p>Definitions of variables in <samp>qirc</samp> can only reference variables
- previously defined in <samp>qirc</samp> and variables with default values.
- </p>
- <p>Definitions of variables in the recipe can only reference variables
- set by the command-line, variables previously defined in the recipe,
- variables defined in <samp>qirc</samp>, and variables with default values.
- </p>
- <a name="Special-variables"></a>
- <h3 class="section">5.2 Special variables</h3>
- <a name="index-special-variables"></a>
- <p>There are variables which can only be set using the command line options or
- via <samp>qirc</samp>, there are other special variables which can be defined or
- redefined in a recipe. See the following definitions:
- </p>
- <p>‘<samp>outdir</samp>’ is the directory where the packages produced are written.
- This variable can not be redefined in the recipe. Default sets to
- ‘<samp>/var/cache/qi/packages</samp>’.
- </p>
- <p>‘<samp>worktree</samp>’ is the working tree where archives, patches, and recipes
- are expected. This variable can not be redefined in the recipe. Default
- sets to ‘<samp>/usr/src/qi</samp>’.
- </p>
- <p>‘<samp>tardir</samp>’ is defined in the recipe to the directory where the tarball
- containing the source can be found. The full name of the tarball is
- composed as ‘<samp>${tardir}/$tarname</samp>’. Its value is available in the
- recipe as ‘<samp>${tardir}</samp>’; a value of . for ‘<samp>tardir</samp>’ sets it to
- the value of CWD (Current Working Directory), this is where the recipe
- lives.
- </p>
- <p>‘<samp>arch</samp>’ is the architecture to compose the package name. Its value is
- available in the recipe as ‘<samp>${arch}</samp>’. Default value is the output
- of ‘<samp>uname -m</samp>’.
- </p>
- <p>‘<samp>jobs</samp>’ is the number of parallel jobs to pass to the compiler. Its
- value is available in the recipe as ‘<samp>${jobs}</samp>’. The default value
- is 1.
- </p>
- <p>The two variables ‘<samp>${srcdir}</samp>’ and ‘<samp>${destdir}</samp>’ can be
- set in the recipe, as any other variable, but if they are not, qi uses
- default values for them when building a package.
- </p>
- <p>‘<samp>srcdir</samp>’ contains the source code to be compiled, and defaults to
- ‘<samp>${program}-${version}</samp>’. ‘<samp>destdir</samp>’ is the place where the
- built package will be installed, and defaults to
- ‘<samp>${TMPDIR}/package-${program}</samp>’.
- </p>
- <p>If ‘<samp>pkgname</samp>’ is left undefined, the special variable ‘<samp>program</samp>’
- is assigned by default. If ‘<samp>pkgversion</samp>’ is left undefined, the
- special variable ‘<samp>version</samp>’ is assigned by default.
- </p>
- <p>‘<samp>pkgname</samp>’ and ‘<samp>pkgversion</samp>’ along with: ‘<samp>version</samp>’, ‘<samp>arch</samp>’,
- and ‘<samp>release</samp>’ are used to produce the name of the package in the form:
- ‘<samp>${pkgname}-${pkgversion}-${arch}+${release}.tlz</samp>’
- </p>
- <p>A special variable called ‘<samp>replace</samp>’ can be used to declare package
- names that will be replaced at the time of installation.
- </p>
- <p>A typical recipe contains the following variables:
- </p>
- <ul>
- <li> ‘<samp>program</samp>’: software name.
- <p>It matches the source name. It is also used to compose the name of the
- package if ‘<samp>${pkgname}</samp>’ is not specified.
- </p>
- </li><li> ‘<samp>version</samp>’: software version.
- <p>It matches the source name. It is also used to compose the version of the
- package if ‘<samp>${pkgversion}</samp>’ is not specified.
- </p>
- </li><li> ‘<samp>arch</samp>’: software architecture.
- <p>It is used to compose the architecture of the package in which it is
- build.
- </p>
- </li><li> ‘<samp>release</samp>’: release number.
- <p>This is used to reflect the release number of the package. It is
- recommended to increase this number after any significant change in
- the recipe or post-install script.
- </p></li></ul>
- <p>Obtaining sources over the network must be declared in the recipe using
- the ‘<samp>fetch</samp>’ variable. Use double quotes for separated values.
- </p>
- <p>The variables ‘<samp>netget</samp>’ and ‘<samp>rsync</samp>’ can be defined in <samp>qirc</samp>
- to establish a network downloader in order to get the sources. If they
- are not defined, qi uses default values:
- </p>
- <p>‘<samp>netget</samp>’ is the general network downloader tool, defaults sets to
- ‘<samp>wget -c -w1 -t3 --no-check-certificate</samp>’.
- </p>
- <p>‘<samp>rsync</samp>’ is the network tool for sources containing the prefix for
- the RSYNC protocol, default sets to
- ‘<samp>rsync -v -a -L -z -i --progress</samp>’.
- </p>
- <p>The variable ‘<samp>description</samp>’ is used to print the package description
- when a package is installed.
- </p>
- <p>A description has two parts: a brief description, and a long description.
- By convention, the syntax of ‘<samp>description</samp>’ is:
- </p>
- <div class="example">
- <pre class="example">description="
- Brief description.
- Long description.
- "
- </pre></div>
- <p>The first line of the value represented is a brief description of the
- software (called "blurb"). A blank line separates the <em>brief
- description</em> from the <em>long description</em>, which should contain a more
- descriptive description of the software.
- </p>
- <p>An example looks like:
- </p>
- <div class="example">
- <pre class="example">description="
- The GNU core utilities.
- The GNU core utilities are the basic file, shell and text manipulation
- utilities of the GNU operating system. These are the core utilities
- which are expected to exist on every operating system.
- "
- </pre></div>
- <p>Please consider a length limit of 78 characters as maximum, because the same
- one would be used on the meta file creation. See
- <a href="#Recipes">The meta file</a> section.
- </p>
- <p>The ‘<samp>homepage</samp>’ variable is used to declare the main site or home page:
- </p>
- <div class="example">
- <pre class="example">homepage=http://www.gnu.org/software/gcc
- </pre></div>
- <p>The variable ‘<samp>license</samp>’ is used for license information<a name="DOCF2" href="#FOOT2"><sup>2</sup></a>.
- Some code in the program can be covered by license A, license B, or
- license C. For "separate licensing" or "heterogeneous licensing", we
- suggest using <strong>|</strong> for a disjunction, <strong>&</strong> for a conjunction
- (if that ever happens in a significant way), and comma for heterogeneous
- licensing. Comma would have lower precedence, plus added special terms.
- </p>
- <div class="example">
- <pre class="example">license="LGPL, GPL | Artistic + added permission"
- </pre></div>
- <a name="Writing-recipes"></a>
- <h3 class="section">5.3 Writing recipes</h3>
- <a name="index-writing-recipes"></a>
- <p>Originally, qi was designed for the version 3 of Dragora GNU/Linux (this
- does not mean that you can’t use it in another distribution, just that
- if you do you will need to test it for your selves). To aid this here
- are some references to well written recipes:
- </p>
- <p><a href="http://git.savannah.nongnu.org/cgit/dragora.git/tree/recipes">http://git.savannah.nongnu.org/cgit/dragora.git/tree/recipes</a>.
- <a href="http://notabug.org/dragora/dragora/src/master/recipes">http://notabug.org/dragora/dragora/src/master/recipes</a>.
- </p>
- <p>You can also check the "doc" directory in the distribution sources of qi
- for some examples.
- </p>
- <a name="Building-packages"></a>
- <h3 class="section">5.4 Building packages</h3>
- <a name="index-package-build"></a>
- <p>A recipe is any valid regular file. Qi sets priorities for reading a
- recipe, the order in which qi looks for a recipe is:
- </p>
- <ol>
- <li> Current working directory.
- </li><li> If the specified path name does not contain "recipe" as the last
- component. Qi will complete it by adding "recipe" to the path name.
- </li><li> If the recipe is not in the current working directory, it will be
- searched under ‘<samp>${worktree}/recipes</samp>’. The last component will be
- completed adding "recipe" to the specified path name.
- </li></ol>
- <p>To build a single package, type:
- </p>
- <div class="example">
- <pre class="example">qi -b x-apps/xterm
- </pre></div>
- <p>Multiple jobs can be passed to the compiler to speed up the build process:
- </p>
- <div class="example">
- <pre class="example">qi -b -j3 x-apps/xterm
- </pre></div>
- <p>Update or install the package produced (if it is not already installed)
- when finish:
- </p>
- <div class="example">
- <pre class="example">qi -b -j3 -u x-apps/xterm
- </pre></div>
- <p>Only process a recipe but do not create the binary package:
- </p>
- <div class="example">
- <pre class="example">qi -b -n dict/aspell
- </pre></div>
- <p>The options -i or -u have no effect when -n is given.
- </p>
- <p>This can be useful to inspect the build process of recipe:
- </p>
- <p>qi -b -k -n dict/aspell 2>&1 | tee aspell-buildlog.txt
- </p>
- <p>The -k option could preserve the source directory and the destination
- directory for later inspection. A log file of the build process will be
- created redirecting both, standard error and standard output to tee(1).
- </p>
- <a name="Variables-from-the-environment"></a>
- <h3 class="section">5.5 Variables from the environment</h3>
- <a name="index-environment-variables"></a>
- <p>Qi has environment variables which can be used at build time:
- </p>
- <p>The variable <code>TMPDIR</code> sets the temporary directory for sources, which is
- used for package extractions (see <a href="#Examining-packages">Examining packages</a>) and is
- prepended to the value of ‘<samp>${srcdir}</samp>’ and ‘<samp>${destdir}</samp>’ in
- build mode. By convention its default value is equal to
- ‘<samp>/usr/src/qi/build</samp>’.
- </p>
- <p>The variables <code>QICFLAGS</code>, <code>QICXXFLAGS</code>, and <code>QILDFLAGS</code> have
- no effect by default. The environment variables such as <code>CFLAGS</code>,
- <code>CXXFLAGS</code>, and <code>LDFLAGS</code> are unset at compile time:
- </p>
- <p>Recommended practice is to set variables in the command line of
- ‘<samp>configure</samp>’ or <em>make(1)</em> instead of exporting to the
- environment. As follows:
- </p>
- <blockquote>
- <p>Variables not defined in a site shell script can be set in the environment
- passed to configure. However, some packages may run configure again
- during the build, and the customized values of these variables may be
- lost. In order to avoid this problem, you should set them in the
- configure command line, using ‘<samp>VAR=value</samp>’. For example:
- </p>
- <p><code>./configure CC=/usr/local2/bin/gcc</code>
- </p>
- <p><a href="http://gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Defining-Variables.html">http://gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Defining-Variables.html</a>
- </p></blockquote>
- <blockquote>
- <p>Indeed, while configure can notice the definition of CC in
- ‘<samp>./configure CC=bizarre-cc</samp>’, it is impossible to notice it in
- ‘<samp>CC=bizarre-cc ./configure</samp>’, which, unfortunately, is what most
- users do.
- </p>
- <p>[...]
- </p>
- <p>configure: error: changes in the environment can compromise the build.
- </p>
- <p><a href="http://gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Setting-Output-Variables.html">http://gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Setting-Output-Variables.html</a>
- </p></blockquote>
- <blockquote>
- <p>It is not wise for makefiles to depend for their functioning on
- environment variables set up outside their control, since this would cause
- different users to get different results from the same makefile. This is
- against the whole purpose of most makefiles.
- </p>
- <p><a href="http://gnu.org/software/make/manual/make.html#Environment">http://gnu.org/software/make/manual/make.html#Environment</a>
- </p></blockquote>
- <a name="The-meta-file"></a>
- <h3 class="section">5.6 The meta file</h3>
- <a name="index-the-meta-file"></a>
- <p>The "meta file" is a regular file created during the build mode, it
- contains information about the package such as package name, package
- version, architecture, release, fetch address, description, and other
- minor data extracted from processed recipes. The name of the file is
- generated as ‘<samp>${full_pkgname}.tlz.txt</samp>’, and its purpose is to
- reflect essential information to the user without having to look inside
- the package content. The file format is also intended to be imported
- from other scripts.
- </p>
- <p>The content of a meta file looks like:
- </p>
- <div class="example">
- <pre class="example">#
- # The Bourne Again SHell.
- #
- # Bash is an sh-compatible shell that incorporates useful features from
- # the Korn shell (ksh) and C shell (csh). It is intended to conform to
- # the IEEE POSIX P1003.2/ISO 9945.2 shell and tools standard.
- #
- # It offers functional improvements over sh for both programming and
- # interactive use.
- #
- QICFLAGS="-g0 -Os -mtune=generic -pipe"
- QICXXFLAGS="-g0 -Os -mtune=generic -pipe"
- QILDFLAGS="-s"
- pkgname=bash
- pkgversion=5.0
- arch=x86_64
- release=1
- blurb="The Bourne Again SHell."
- homepage="http://www.gnu.org/software/bash"
- license="GPLv3+"
- fetch="ftp://ftp.gnu.org/gnu/bash/bash-5.0.tar.gz"
- replace=""
- </pre></div>
- <p>Package descriptions are extracted from the variable ‘<samp>description</samp>’
- where each line is interpreted literally and pre-formatted to fit in
- (exactly) <strong>80 columns</strong>, plus the character ‘<samp>#</samp>’ and a space
- is prefixed to every line.
- </p>
- <p>In addition to the Special variables, there are implicit variables such as
- ‘<samp>blurb</samp>’:
- </p>
- <p>The ‘<samp>blurb</samp>’ variable is related to the special variable
- ‘<samp>description</samp>’. Its value is composed using the first (substantial)
- line of ‘<samp>description</samp>’, mentioned as the "brief description".
- </p>
- <hr>
- <a name="Order-files"></a>
- <div class="header">
- <p>
- Next: <a href="#Creating-packages" accesskey="n" rel="next">Creating packages</a>, Previous: <a href="#Recipes" accesskey="p" rel="prev">Recipes</a>, Up: <a href="#Top" accesskey="u" rel="up">Top</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="#Index" title="Index" rel="index">Index</a>]</p>
- </div>
- <a name="Order-files-1"></a>
- <h2 class="chapter">6 Order files</h2>
- <a name="index-handling-build-order"></a>
- <p>The order mode has the purpose of resolving the build order through
- .order files. An order file contains a list of recipe names, by default
- does not perform any action other than to print a resolved list in
- descending order. For example, if <strong>a</strong> depends on <strong>b</strong> and
- <strong>c</strong>, and <strong>c</strong> depends on <strong>b</strong> as well, the file might
- look like:
- </p>
- <div class="example">
- <pre class="example">a: c b
- b:
- c: b
- </pre></div>
- <p>Each letter represents a recipe name, complete dependencies for
- the first recipe name are listed in descending order, which is
- printed from right to left, and removed from left to right:
- </p>
- <p><small>OUTPUT</small>
- </p>
- <div class="example">
- <pre class="example">b
- c
- a
- </pre></div>
- <p>Blank lines, colons and parentheses are simply ignored. Comment lines
- beginning with ‘<samp>#</samp>’ are allowed.
- </p>
- <p>An order file could be used to build a series of packages, for example,
- if the content is:
- </p>
- <div class="example">
- <pre class="example"># Image handling libraries
- libs/libjpeg-turbo: devel/nasm
- x-libs/jasper: libs/libjpeg-turbo
- libs/tiff: libs/libjpeg-turbo
- </pre></div>
- <p>To proceed with each recipe, we can type:
- </p>
- <div class="example">
- <pre class="example">qi -o imglibs.order | qi -b -i -
- </pre></div>
- <p>The output of ‘<samp>qi -o imglibs.order</samp>’ tells to qi in which order it
- should build the recipes:
- </p>
- <div class="example">
- <pre class="example">devel/nasm
- libs/libjpeg-turbo
- x-libs/jasper
- libs/tiff
- </pre></div>
- <hr>
- <a name="Creating-packages"></a>
- <div class="header">
- <p>
- Next: <a href="#Examining-packages" accesskey="n" rel="next">Examining packages</a>, Previous: <a href="#Order-files" accesskey="p" rel="prev">Order files</a>, Up: <a href="#Top" accesskey="u" rel="up">Top</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="#Index" title="Index" rel="index">Index</a>]</p>
- </div>
- <a name="Creating-packages-1"></a>
- <h2 class="chapter">7 Creating packages</h2>
- <a name="index-package-creation"></a>
- <p>The "creation mode" is an internal function of qi to make new Qi compatible
- compatible packages, the creation mode is selected by the -c option.
- A package is produced using the contents of the Current Directory, and
- the package file is written out.
- </p>
- <div class="example">
- <pre class="example">Usage: qi -c [<var>OUTPUT/packagename.tlz</var>]...
- </pre></div>
- <p>The argument for the file name to be written must contain a fully
- qualified named directory as the output directory where the package
- produced will be written. The file name should be composed using the
- full name: name-version-architecture+release.tlz
- </p>
- <p><small>EXAMPLE</small>
- </p>
- <div class="example">
- <pre class="example">cd /usr/local/pkgs
- cd claws-mail-3.17.1-x86_64+1
- qi -c /var/cache/qi/packages/x86_64/local/claws-mail-3.17.1-x86_64+1.tlz
- </pre></div>
- <p>In this case, the package "claws-mail-3.17.1-x86_64+1.tlz" will be written
- into ‘<samp>/var/cache/qi/packages/x86_64/local/</samp>’.
- </p>
- <p>All packages produced are complemented by a checksum file (.sha256).
- </p>
- <hr>
- <a name="Examining-packages"></a>
- <div class="header">
- <p>
- Next: <a href="#Exit-status" accesskey="n" rel="next">Exit status</a>, Previous: <a href="#Creating-packages" accesskey="p" rel="prev">Creating packages</a>, Up: <a href="#Top" accesskey="u" rel="up">Top</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="#Index" title="Index" rel="index">Index</a>]</p>
- </div>
- <a name="Examining-packages-1"></a>
- <h2 class="chapter">8 Examining packages</h2>
- <a name="index-package-examination"></a>
- <p>The "extraction mode" serves to examine binary packages for debugging
- purposes. The extraction mode is selected by the -x option. It
- decompresses a package into a single directory, verifying its integrity
- and preserving its properties.
- </p>
- <div class="example">
- <pre class="example">Usage: qi -x [<var>packagename.tlz</var>]...
- </pre></div>
- <p><small>EXAMPLE</small>
- </p>
- <div class="example">
- <pre class="example">qi -x mksh-R56c-x86_64+1.tlz
- </pre></div>
- <p>This action will put the content of "mksh-R56c-x86_64+1.tlz" into a
- single directory, this will be a private directory for the user who
- </p>
- <p>requested the action, creation mode will be equal to <strong>u=rwx,g=,o=
- (0700)</strong>. The package content will reside on this location, default
- mask to deploy the content will be equal to
- <strong>u=rwx,g=rwx,o=rwx (0000)</strong>.
- </p>
- <p>The creation of the custom directory is influenced by the value of the
- <code>TMPDIR</code> variable.
- </p>
- <hr>
- <a name="Exit-status"></a>
- <div class="header">
- <p>
- Next: <a href="#Index" accesskey="n" rel="next">Index</a>, Previous: <a href="#Examining-packages" accesskey="p" rel="prev">Examining packages</a>, Up: <a href="#Top" accesskey="u" rel="up">Top</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="#Index" title="Index" rel="index">Index</a>]</p>
- </div>
- <a name="Exit-status-1"></a>
- <h2 class="chapter">9 Exit status</h2>
- <a name="index-exit-codes"></a>
- <p>All the exit codes are described in this chapter.
- </p>
- <dl compact="compact">
- <dt>‘<samp>0</samp>’</dt>
- <dd><p>Successful completion (no errors).
- </p>
- </dd>
- <dt>‘<samp>1</samp>’</dt>
- <dd><p>Minor common errors:
- </p>
- <ul class="no-bullet">
- <li>- Help usage on illegal options or required arguments.
- </li><li>- Program needed by qi (prerequisite) is not available.
- </li></ul>
- </dd>
- <dt>‘<samp>2</samp>’</dt>
- <dd><p>Command execution error:
- </p>
- <p>This code is used to return the evaluation of external commands and shell
- arguments in case of error.
- </p>
- </dd>
- <dt>‘<samp>3</samp>’</dt>
- <dd><p>Integrity check error for compressed files.
- </p>
- <p>Compressed files means:
- </p>
- <ul class="no-bullet">
- <li>- Tarball files from tar(1).
- Supported extensions: .tar, .tar.gz, .tgz, .tar.Z, .tar.bz2, .tbz2, .tbz,
- .tar.xz, .txz
- </li><li>- Tarball files from tarlz(1).
- Supported extensions: .tar.lz, .tlz
- </li><li>- Zip files from unzip(1).
- Supported extensions: .zip, .ZIP
- </li><li>- Gzip files from gzip(1).
- Supported extensions: .gz, .Z
- </li><li>- Bzip2 files from bzip2(1).
- Supported extensions: .bz2
- </li><li>- Lzip files from lzip(1).
- Supported extensions: .lz
- </li><li>- Xz files from xz(1).
- Supported extensions: .xz
- </li></ul>
- </dd>
- <dt>‘<samp>4</samp>’</dt>
- <dd><p>File empty, not regular, or expected.
- </p>
- <p>Commonly, it is expected:
- </p>
- <ul class="no-bullet">
- <li>- An argument for the mode of operation.
- </li><li>- A readable file or directory.
- </li><li>- A binary package (.tlz).
- </li><li>- A valid recipe.
- </li><li>- An order file (.order).
- </li><li>- A protocol supported by the network downloader tool.
- </li><li>- A checksum file (.sha256).
- </li></ul>
- </dd>
- <dt>‘<samp>5</samp>’</dt>
- <dd><p>Empty or not defined variable:
- </p>
- <p>This code is used to report empty or undefined variables; usually,
- variables coming from a recipe or assigned arrays that are tested.
- </p>
- </dd>
- <dt>‘<samp>6</samp>’</dt>
- <dd><p>Package already installed:
- </p>
- <p>The package directory for an incoming .tlz package already exists.
- </p>
- </dd>
- <dt>‘<samp>10</samp>’</dt>
- <dd><p>Network manager error:
- </p>
- <p>This code is used if the network downloader tool fails for some reason.
- </p></dd>
- </dl>
- <hr>
- <a name="Index"></a>
- <div class="header">
- <p>
- Previous: <a href="#Exit-status" accesskey="p" rel="prev">Exit status</a>, Up: <a href="#Top" accesskey="u" rel="up">Top</a> [<a href="#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="#Index" title="Index" rel="index">Index</a>]</p>
- </div>
- <a name="Index-1"></a>
- <h2 class="unnumbered">Index</h2>
- <table><tr><th valign="top">Jump to: </th><td><a class="summary-letter" href="#Index_cp_letter-C"><b>C</b></a>
-
- <a class="summary-letter" href="#Index_cp_letter-E"><b>E</b></a>
-
- <a class="summary-letter" href="#Index_cp_letter-H"><b>H</b></a>
-
- <a class="summary-letter" href="#Index_cp_letter-I"><b>I</b></a>
-
- <a class="summary-letter" href="#Index_cp_letter-M"><b>M</b></a>
-
- <a class="summary-letter" href="#Index_cp_letter-P"><b>P</b></a>
-
- <a class="summary-letter" href="#Index_cp_letter-R"><b>R</b></a>
-
- <a class="summary-letter" href="#Index_cp_letter-S"><b>S</b></a>
-
- <a class="summary-letter" href="#Index_cp_letter-T"><b>T</b></a>
-
- <a class="summary-letter" href="#Index_cp_letter-V"><b>V</b></a>
-
- <a class="summary-letter" href="#Index_cp_letter-W"><b>W</b></a>
-
- </td></tr></table>
- <table class="index-cp" border="0">
- <tr><td></td><th align="left">Index Entry</th><td> </td><th align="left"> Section</th></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th><a name="Index_cp_letter-C">C</a></th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-configuration-file">configuration file</a>:</td><td> </td><td valign="top"><a href="#The-qirc-file">The qirc file</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th><a name="Index_cp_letter-E">E</a></th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-environment-variables">environment variables</a>:</td><td> </td><td valign="top"><a href="#Recipes">Recipes</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-exit-codes">exit codes</a>:</td><td> </td><td valign="top"><a href="#Exit-status">Exit status</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th><a name="Index_cp_letter-H">H</a></th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-handling-build-order">handling build order</a>:</td><td> </td><td valign="top"><a href="#Order-files">Order files</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th><a name="Index_cp_letter-I">I</a></th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-introduction">introduction</a>:</td><td> </td><td valign="top"><a href="#Introduction">Introduction</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-invocation">invocation</a>:</td><td> </td><td valign="top"><a href="#Invoking-qi">Invoking qi</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th><a name="Index_cp_letter-M">M</a></th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-managing-packages">managing packages</a>:</td><td> </td><td valign="top"><a href="#Packages">Packages</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th><a name="Index_cp_letter-P">P</a></th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-package-blacklist">package blacklist</a>:</td><td> </td><td valign="top"><a href="#Packages">Packages</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-package-build">package build</a>:</td><td> </td><td valign="top"><a href="#Recipes">Recipes</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-package-conflicts">package conflicts</a>:</td><td> </td><td valign="top"><a href="#Packages">Packages</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-package-creation">package creation</a>:</td><td> </td><td valign="top"><a href="#Creating-packages">Creating packages</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-package-de_002dinstallation">package de-installation</a>:</td><td> </td><td valign="top"><a href="#Packages">Packages</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-package-examination">package examination</a>:</td><td> </td><td valign="top"><a href="#Examining-packages">Examining packages</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-package-installation">package installation</a>:</td><td> </td><td valign="top"><a href="#Packages">Packages</a></td></tr>
- <tr><td></td><td valign="top"><a href="#index-package-upgrade">package upgrade</a>:</td><td> </td><td valign="top"><a href="#Packages">Packages</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th><a name="Index_cp_letter-R">R</a></th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-recipes">recipes</a>:</td><td> </td><td valign="top"><a href="#Recipes">Recipes</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th><a name="Index_cp_letter-S">S</a></th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-special-variables">special variables</a>:</td><td> </td><td valign="top"><a href="#Recipes">Recipes</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th><a name="Index_cp_letter-T">T</a></th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-the-meta-file">the meta file</a>:</td><td> </td><td valign="top"><a href="#Recipes">Recipes</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th><a name="Index_cp_letter-V">V</a></th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-variables">variables</a>:</td><td> </td><td valign="top"><a href="#Recipes">Recipes</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- <tr><th><a name="Index_cp_letter-W">W</a></th><td></td><td></td></tr>
- <tr><td></td><td valign="top"><a href="#index-writing-recipes">writing recipes</a>:</td><td> </td><td valign="top"><a href="#Recipes">Recipes</a></td></tr>
- <tr><td colspan="4"> <hr></td></tr>
- </table>
- <table><tr><th valign="top">Jump to: </th><td><a class="summary-letter" href="#Index_cp_letter-C"><b>C</b></a>
-
- <a class="summary-letter" href="#Index_cp_letter-E"><b>E</b></a>
-
- <a class="summary-letter" href="#Index_cp_letter-H"><b>H</b></a>
-
- <a class="summary-letter" href="#Index_cp_letter-I"><b>I</b></a>
-
- <a class="summary-letter" href="#Index_cp_letter-M"><b>M</b></a>
-
- <a class="summary-letter" href="#Index_cp_letter-P"><b>P</b></a>
-
- <a class="summary-letter" href="#Index_cp_letter-R"><b>R</b></a>
-
- <a class="summary-letter" href="#Index_cp_letter-S"><b>S</b></a>
-
- <a class="summary-letter" href="#Index_cp_letter-T"><b>T</b></a>
-
- <a class="summary-letter" href="#Index_cp_letter-V"><b>V</b></a>
-
- <a class="summary-letter" href="#Index_cp_letter-W"><b>W</b></a>
-
- </td></tr></table>
- <div class="footnote">
- <hr>
- <h4 class="footnotes-heading">Footnotes</h4>
- <h3><a name="FOOT1" href="#DOCF1">(1)</a></h3>
- <p>The official guide for Graft can be found at
- <a href="http://peters.gormand.com.au/Home/tools/graft/graft.html">http://peters.gormand.com.au/Home/tools/graft/graft.html</a>.</p>
- <h3><a name="FOOT2" href="#DOCF2">(2)</a></h3>
- <p>The proposal for ‘<samp>license</samp>’ was made by Richard M. Stallman at
- <a href="http://lists.gnu.org/archive/html/gnu-linux-libre/2016-05/msg00003.html">http://lists.gnu.org/archive/html/gnu-linux-libre/2016-05/msg00003.html</a>.</p>
- </div>
- <hr>
- </body>
- </html>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
- <html>
- <head>
- <title>Graft</title>
- </head>
- <body>
- <center>
- <h1><em>Graft</em> - a package management utility</h1>
- </center>
- <h4>Prepared by Peter Samuel
- <a href="mailto:peter.r.samuel@gmail.com"><tt><peter.r.samuel@gmail.com></tt></a></h4>
- <h4>$Revision: 2.16 $</h4>
- <h4>$Date: 2018/04/16 14:54:07 $</h4>
- <blockquote>
- <p> <em><strong>graft:</strong> To insert (a graft) in a branch or stem
- of another tree; to propagate by insertion in another stock; also, to
- insert a graft upon. To implant a portion of (living flesh or skin) in
- a lesion so as to form an organic union. To join (one thing) to another
- as if by grafting, so as to bring about a close union.</em> </p>
- </blockquote>
- <hr>
- <h2><a name="contents">Contents</a></h2>
- <ul>
- <li> <a href="#intro">Introduction</a>
- <li> <a href="#rationale">Rationale</a>
- <li> <a href="#research">Research</a>
- <li> <a href="#design">Design</a>
- <ul>
- <li> <a href="#precedence">Control file precedence & conflict resolution</a>
- </ul>
- <li> <a href="#history">History</a>
- <li> <a href="#installation">Installation</a>
- <ul>
- <li> <a href="#rpm_and_deb">Creating RPM and DEB packages</a>
- <li> <a href="#gotchas">Grafting <em>Graft</em> and
- <em>Perl</em> - the bootstrap problem</a>
- </ul>
- <li> <a href="#using-graft">Using <em>Graft</em></a>
- <ul>
- <li> <a href="#compiling-packages">Compiling
- Packages</a>
- <li><a href="#usage"><em>Graft</em> command line
- options</a>
- <ol>
- <li><a href="#graft-i">Install</a>
- <li><a href="#graft-d">Delete</a>
- <li><a href="#graft-p">Prune</a>
- <li><a href="#graft-L">Information</a>
- </ol>
- <li> <a href="#testing">Testing the <em>Graft</em>
- Installation</a>
- <li> <a href="#installing-packages">Installing
- Packages</a>
- <li> <a href="#bypass">Bypassing package
- directories</a>
- <li> <a href="#include">Including specific files
- and/or directories</a>
- <li> <a href="#exclude">Excluding specific files
- and/or directories</a>
- <li> <a href="#config_dirs">Grafting configuration files</a>
- <li><a href="#partial-graft">Grafting part of a
- package</a>
- <li> <a href="#deleting-packages">Deleting and/or
- Upgrading Packages</a>
- <li><a href="#transitioning">Transitioning a package to
- <em>Graft</em> control</a>
- <li> <a href="#conflicts">Conflict Processing</a>
- <li> <a href="#exitstatus">Exit Status</a>
- </ul>
- <li> <a href="#other-pkg-tools">Using <em>Graft</em> with
- other package management tools</a>
- <li> <a href="#availability">Availability</a>
- <li> <a href="#license">License</a>
- </ul>
- <hr>
- <h2><a name="intro">Introduction</a></h2>
- <p> <em>Graft</em> provides a mechanism for managing multiple packages
- under a single directory hierarchy. It was inspired by both <em>Depot</em>
- (Carnegie Mellon University) and <em>Stow</em> (Bob Glickstein). </p>
- <p> For the purposes of this discussion a <em>package</em> is defined as
- a suite of programs and files that make up an individual product. For
- example, the <em>package</em> known as <em>gcc</em> consists of the compiler
- and preprocessor programs, include files, manual pages and any other
- associated file or program. The concept of a <em>package</em> should not be
- confused with some vendor's definitions that are - by this definition -
- actually collections of <em>packages</em>. </p>
- <p> Special thanks to Gordon Rowell, Charles Butcher, Charlie Brady,
- Robert Maldon and Matias A. Fonzo for design suggestions and contributions.
- </p>
- <hr>
- <h2><a name="rationale">Rationale</a></h2>
- <p> In any reasonably large environment, many software packages will be
- installed. The installation location for these packages usually follows
- one of three rationales - each with its own advantages and drawbacks: </p>
- <ol>
- <li> <p> Each package is isolated from all other packages by
- installing it into a self contained directory tree. All binaries,
- manual pages, library and configuration files are stored under
- a single directory tree. This directory tree contains NO other
- files which are not the exclusive domain of the package in
- question. </p>
- <p> This method makes package demarcation obvious. As each
- package is self contained, identification of any file within a
- package is immediately apparent. </p>
- <p> Multiple versions of packages can be installed fairly easily
- to accommodate acceptance testing of new versions and/or legacy
- systems. </p>
- <p> However, the use of individual package directories can
- lead to VERY long <strong>$PATH</strong> and <strong>$MANPATH</strong> environment
- variables. Some shells may not be able to handle such long
- variables. Whenever a new package is added, each user MUST
- update their <strong>$PATH</strong> and <strong>$MANPATH</strong> to make the package
- available. </p>
- <li> <p> Packages are installed under a common directory tree.
- Binaries for all packages are grouped in a single directory,
- manual pages for all packages in another directory and so on.
- </p>
- <p> This method eliminates the need for continually updating long
- <strong>$PATH</strong> variables for each user. As soon as a package is
- placed into the common '<tt>bin</tt>' directory it is immediately
- available to all users (after a shell rehash if necessary). </p>
- <p> However, when a package is to be updated it is often very
- difficult to isolate all the files related to a particular
- package if they are intermingled with unrelated files. </p>
- <li> <p> A combination of methods (1) and (2). </p>
- </ol>
- <p> In an effort to maximise the advantages and minimise the
- disadvantages, <em>Depot</em>, <em>Stow</em> and <em>Graft</em> adopt a similar
- philosophy: </p>
- <blockquote>
- <p> Packages are installed in self contained directory trees and
- symbolic links from a common area are made to the package files. </p>
- </blockquote>
- <p> This approach allows multiple versions of the same package to co-exist
- on the one system. One version is the commonly available version and
- symbolic links will be made to this version. New versions can be tested
- and once acceptable can replace the current commonly available version.
- Older versions can still be used for legacy systems by using the
- '<em>real</em>' path name to the package instead of the '<em>common</em>'
- path name. </p>
- <p> The size and complexity of environment variables such as <strong>$PATH</strong>
- and <strong>$MANPATH</strong> is minimised because only the common area is
- required. Any special cases can also be accommodated but these will
- usually be in the minority when compared with the number of commonly
- available packages. </p>
- <hr>
- <h2><a name="research">Research</a></h2>
- <p> <strong>Note:</strong> Development of <em>Graft</em> began in late 1996. The
- comments regarding the packages listed below reflect their functionality
- and behaviour at that time and may not necessarily reflect their current
- functionality and behaviour. </p>
- <p> As stated earlier, <em>Graft</em> was inspired by <em>Depot</em> and
- <em>Stow</em>. Both these systems were examined and finally rejected for
- the following reasons: </p>
- <dl>
- <dt> <em>Depot</em>
- <a href="ftp://ftp.andrew.cmu.edu/pub/depot/depot.tar.gz">ftp://ftp.andrew.cmu.edu/pub/depot/depot.tar.gz</a>
- <dd> <p> <em>Depot</em> is very flexible yet cumbersome. </p>
- <p> It requires a database file to be created which
- provides a snapshot of the current state of both the package
- repository and the <em>Depot</em> target. It is possible to
- inadvertently destroy the package repository if the database
- is damaged. </p>
- <p> <em>Depot</em> assumes "<em>ownership</em>" of the
- target area, making it almost impossible to accommodate
- packages that are not under the control of <em>Depot</em>.
- ("<em>Ownership</em>" in this case means that <em>Depot</em>
- assumes ALL files in the target area will be under the
- control of <em>Depot</em>. It does not imply that <em>Depot</em>
- modifies Unix file permissions). </p>
- <p> Because of <em>Depot</em>'s assumed <em>ownership</em> it is
- difficult for other packages not under the control of
- <em>Depot</em> to be placed in the same target area. </p>
- <p> <em>Depot</em> attempts to impose a fixed package repository
- relative to the package target. It assumes that all
- packages will be stored under
- '<tt><em>dir</em>/depot/<em>package</em></tt>' and the target
- will be '<tt><em>dir</em></tt>'. This can be overridden on
- the command line but the internals of <em>Depot</em> make
- this mechanism cumbersome. </p>
- <p> <em>Depot</em> is written in C and there are many source
- files in its distribution. Local modifications would be
- difficult to quickly implement and test. </p>
- <dt> <em>Stow</em>
- <a href="https://www.gnu.org/software/stow/">https://www.gnu.org/software/stow/</a>
- <dd> <p> <em>Stow</em> is a stateless system. It requires no
- database or configuration information. </p>
- <p> Like <em>Depot</em>, it assumes that the package repository
- will be stored under '<tt><em>dir</em>/stow/<em>package</em></tt>'
- and the target will be '<tt><em>dir</em></tt>'. This can be
- overridden on the command line and works well during the
- install phase. </p>
- <p> <em>Stow</em> assumes "<em>ownership</em>"
- of the target area, making it difficult to accommodate
- packages that are not under the control of <em>Stow</em>.
- ("<em>Ownership</em>" in this case means that <em>Stow</em>
- assumes ALL files in the target area will be under the
- control of <em>Stow</em>. It does not imply that <em>Stow</em>
- modifies Unix file permissions). </p>
- <p> Because of <em>Stow</em>'s assumed <em>ownership</em>
- it is difficult for other packages not under the control
- of <em>Stow</em> to be placed in the same target area. When
- deleting packages, <em>Stow</em> examines everything in the
- target directory - whether it is associated with the package
- it is trying to delete or not. This can be time consuming and
- potentially dangerous as empty directories are also removed
- - even empty directories that do not belong to the package
- being removed. </p>
- <p> <em>Stow</em> has a clever feature of <em>folding</em> and
- <em>unfolding</em> directories. It attempts to optimise the
- number of symbolic links by making links to directories if
- the directory is only associated with a single package. If
- at a later date <em>Stow</em> discovers another package that
- needs that directory it will <em>unfold</em> that directory
- into a collection of symbolic links to files rather than
- a single symbolic link to the directory. <em>Stow</em> will
- <em>fold</em> the directory when removing packages if the
- remainder of the directory is only concerned with a single
- package. While clever, this feature is probably a waste of
- time and effort. It means that the entire package target
- must be scanned to determine package ownership of links and
- as packages will usually be replaced by newer versions a
- directory <em>fold</em> will probably be short lived. </p>
- <p> <em>Stow</em> will sometimes miss potential conflicts when
- run in <em>show only</em> mode. The conflicts may occur when a
- directory is unfolded and will not show up in <em>show only</em>
- mode. </p>
- <p> <em>Stow</em>'s author suggests that packages be compiled
- such that they refer to files in the target location rather
- than the actual package installation directory. This approach
- precludes the use of multiple versions of packages with
- different configuration and/or library files. </p>
- <p> <em>Stow</em> is written in <em>Perl</em> and is only a
- few hundred lines of code so local modifications can be
- accommodated. However there are very few comments in the
- code which makes the process of modification difficult. </p>
- </dl>
- <p> Since the release of <em>Graft</em> 1.6, the existence of yet another
- packaging program has been brought to the author's attention. </p>
- <dl>
- <dt> <em>Encap</em>
- <a href="http://www.ks.uiuc.edu/Development/Computers/docs/sysadmin/Build/encap.html">http://www.ks.uiuc.edu/Development/Computers/docs/sysadmin/Build/encap.html</a>
- <dd> <p> <em>Encap</em> grew out of work begun at the University
- of Illinois Champaign-Urbana. It has the same underlying
- philosophy as <em>Depot</em>, <em>Stow</em> and <em>Graft</em> -
- encapsulate packages into self contained directories and use
- symbolic links to make them visible in a common location. </p>
- <p> <em>Encap</em> uses a combination of a <em>csh</em> wrapper
- and a <em>Perl</em> program to accomplish its work. Like both
- <em>Depot</em> and <em>Stow</em>, <em>Encap</em> assumes that all
- compiled packages will live under a single directory hierarchy
- - by default '<tt><em>dir</em>/encap/<em>package</em></tt>'. It
- then attempts to create a symbolic link tree for ALL the
- packages under this area. There doesn't appear to be any
- easy way to support the quick addition or removal of a single
- package. </p>
- <p> A new release of <em>Encap</em> incorporating many new
- features was expected to be available in early 1997, however
- no release greater than version 1.2 has been forthcoming. </p>
- <p> One good feature of <em>Encap</em> is the ability to exclude
- specific files from the package tree. This concept has been
- incorporated into <em>Graft</em> 1.7 and above. </p>
- </dl>
- <p> Since the release of <em>Graft</em> 2.3, the existence of
- several another packaging programs have been brought to the author's
- attention. Rather than outline their features and whether or not the
- author feels they are superior (or inferior) to <em>Graft</em>, a reference
- to each package and a brief description is given and further research
- is left as an exercise for the reader: </p>
- <dl>
- <dt> <em>stowES</em>
- <dd>
- <pre>
- <a href="https://os.inf.tu-dresden.de/~adam/stowES/">https://os.inf.tu-dresden.de/~adam/stowES/</a>
- </pre>
- <p> "<em>stowES (stow Enhancement Script) is
- a Perl script which tries to ease the use of the "stow"
- packaging program and software which can be compiled and
- installed with autoconf. It automates the compilation and
- installation of software packages and provides some useful
- functions to maintain your stow packages (e.g., list packages,
- check packages for integrity, etc.).</em>" </p>
- <dt> <em>opt_depot</em>
- <dd>
- <pre>
- <a href="https://github.com/jonabbey/opt_depot">https://github.com/jonabbey/opt_depot</a>
- </pre>
- <p> "<em>opt_depot is a suite of Perl scripts which makes
- it easy to manage installed software across a wide range
- of client systems. opt_depot makes it possible to keep all
- files associated with a program together in one directory,
- so installation and de-installation is simple. opt_depot is
- easy to manage, and provides a scheme for installing software
- in a truly portable fashion; packages may be installed locally
- on client systems, or kept in a central package archive for
- NFS access. </em>"</p>
- <p> This site also has links to several other package
- management utilities, including <em>Graft</em>. </p>
- <dt> <em>relink</em>
- <dd>
- <pre>
- <a href="http://sourceforge.net/projects/relink/">http://sourceforge.net/projects/relink/</a>
- </pre>
- <p> "<em>relink is a package management tool for
- organization and management of software packages. It should
- run on any UNIX platform that runs PERL. Similar tools
- include: rpm(REDHAT/Mandrake), pkgadd(Slackware/SUN),
- stow(GNU) and depot(CMU)</em>" </p>
- <dt> <em>univSrcPkg</em>
- <dd>
- <pre>
- <a href="http://freecode.com/articles/the-universal-source-package">http://freecode.com/articles/the-universal-source-package</a>
- </pre>
- <p> <a href="mailto:bud@sistema.it">Bud Bruegger</a> has written
- a brief paper outlining his thoughts on a "<em>Universal Source
- Package</em>" solution. </p>
- <p> This site also has links to other package management
- programs and similar items of interest. </p>
- </dl>
- <hr>
- <h2><a name="design">Design</a></h2>
- <p> This brings us to <em>Graft</em>. <em>Graft</em> has been designed to
- use the best features of <em>Depot</em>, <em>Stow</em> and <em>Encap</em>
- while maintaining as simple a mechanism as possible. The principles of
- <em>Graft</em> are: </p>
- <ul>
- <li> <p> <em>Graft</em> will allow packages to be <em>grafted</em>
- from any directory to any other directory. Default
- <tt>installation</tt> and <tt>target</tt> directories will be
- used but can easily be overridden on the command line. </p>
- <li> <p> <em>Graft</em> will log its actions to a log file. The
- log file can be specified on the command line. If not specified
- on the command line a default log file will be used. </p>
- <li> <p> <em>Graft</em> will NOT create symbolic links to
- directories. If a directory does not exist in the target tree
- it will be created (with the same ownership and permissions as
- the original if desired). </p>
- <li> <p> <em>Graft</em> will create symbolic links with full
- pathnames rather than relative pathnames. This allows easy
- identification of true package locations and facilitates block
- movement of a target tree without the need for <em>Graft</em>
- deletion and re-installation. </p>
- <li> <p> <em>Graft</em> will cease installation of a package if a
- conflict arises. A conflict is defined as one of the following
- conditions: </p>
- <ul>
- <li> If the package object is a directory and the
- target object exists but is not a directory.
- <li> If the package object is not a directory and the
- target object exists and is not a symbolic link.
- <li> If the package object is not a directory and the
- target object exists and is a symbolic link to
- something other than the package object.
- <li> If the package directory contains a
- <tt>.graft-config</tt> file and the target object exists
- but does not match the 32-bit CRC of the package object.
- </ul>
- <li> <p> Installation conflicts will always be reported. Conflicts
- will be reported to standard error. </p>
- <li> <p> <em>Graft</em> will attempt to display all possible
- operations when asked, even when asked not to perform the
- operations. </p>
- <li> <p> <em>Graft</em> will not delete directories when
- uninstalling. <em>Graft</em> will print an appropriate message if an
- empty directory results and leave the deletion for the operator
- to perform outside the scope of <em>Graft</em>'s operations. This
- ensures that <em>place holder</em> directories that may be
- used by other packages are not inadvertently removed. This
- feature can be permanently disabled by setting a flag in the
- <tt>Makefile</tt>. It can also be temporarily disabled using a
- command line option. </p>
- <li> <p> <em>Graft</em> will continue to delete the remainder of
- a package after a conflict arises. This maximises the amount of
- deletion that can be performed. </p>
- <li> <p> Deletion conflicts will always be reported. Conflicts
- will be reported to standard error. </p>
- <li> <p> <em>Graft</em> will only concern itself with files
- relating to the package at hand. This will allow other packages
- to be placed in the target area without fear of intervention by
- <em>Graft</em>. </p>
- <li> <p> <em>Graft</em> will only allow the superuser to install
- or delete packages. This feature can be permanently disabled by
- setting a flag in the <tt>Makefile</tt> or it may be overridden
- by a command line option. </p>
- <li> <p> If the file <tt>.nograft</tt> exists in any package
- directory, <em>Graft</em> will bypass that directory and any
- subdirectories during installation. The name of this file is
- specified in the <tt>Makefile</tt>. </p>
- <li> <p> When installing a directory tree, if the file
- <tt>.graft-exclude</tt> exists in any package directory,
- <em>Graft</em> will assume that the file contains a list of
- file and/or directory names - one per line - which correspond
- to files and/or directories in the directory containing the
- <tt>.graft-exclude</tt> file. These files and/or directories
- will NOT be <em>grafted</em>. The name of this file is specified
- in the <tt>Makefile</tt>. </p>
- <p> The <tt>.nograft</tt> file takes priority over the
- <tt>.graft-exclude</tt> file. </p>
- <li> <p> When installing a directory tree, if the file
- <tt>.graft-include</tt> exists in any package directory,
- <em>Graft</em> will assume that the file contains a list of
- file and/or directory names - one per line - which correspond
- to files and/or directories in the directory containing the
- <tt>.graft-include</tt> file. ONLY the files and/or directories
- listed in the <tt>.graft-include</tt> will be <em>grafted</em>. The
- name of this file is specified in the <tt>Makefile</tt>. </p>
- <p> The <tt>.graft-exclude</tt> file takes priority over the
- <tt>.graft-include</tt> file. </p>
- <li> <p> When installing a directory tree, if the file
- <tt>.graft-config</tt> exists in a package directory, the contents
- of the directory will be <strong>copied</strong> to the target
- directory. If the target files exists and is in conflict with the
- package file then the package file will be copied into the target
- directory as <tt>file<em>.new</em></tt>. </p>
- <p> The <tt>.graft-include</tt> file takes priority over the
- <tt>.graft-config</tt> file. </p>
- <li> <p> If the file <tt>.nograft</tt> exists in any package
- directory, it will be ignored and <em>Graft</em> will continue
- processing the directory and any subdirectories during
- deletion. </p>
- <li> <p> If the file <tt>.graft-exclude</tt> exists in any
- package directory, its contents will be ignored and <em>Graft</em>
- will continue processing the directory and any subdirectories
- during deletion. </p>
- <li> <p> If the file <tt>.graft-include</tt> exists in any
- package directory, its contents will be ignored and <em>Graft</em>
- will continue processing the directory and any subdirectories
- during deletion. </p>
- <li> <p> If the file <tt>.graft-config</tt> exists in any
- package directory, during deletion matching files in the target
- directory will not be deleted however any
- <tt>file<em>.new</em></tt> files will be deleted. </p>
- <li> <p> As an aid to transitioning systems to <em>Graft</em>,
- <em>Graft</em> will allow conflicting files to be pruned. This
- pruning can take the form of a file rename or a file removal
- depending on either a <tt>Makefile</tt> flag or a command line
- option. If file removal is selected and the file is a non-empty
- directory, it will be renamed instead. </p>
- <li> <p> If the file <tt>.nograft</tt> exists in any package
- directory, it will be ignored and <em>Graft</em> will continue
- processing the directory and any subdirectories during
- pruning. </p>
- <li> <p> If the file <tt>.graft-exclude</tt> exists in any
- package directory, its contents will be ignored and <em>Graft</em>
- will continue processing the directory and any subdirectories
- during pruning. </p>
- <li> <p> If the file <tt>.graft-include</tt> exists in any
- package directory, its contents will be ignored and <em>Graft</em>
- will continue processing the directory and any subdirectories
- during pruning. </p>
- <li> <p> If the file <tt>.graft-config</tt> exists in any
- package directory, the files in the directory will be ignored
- during pruning. Sub-directories will continue to be processed
- appropriately. </p>
- </ul>
- <h3><a name="precedence">Control file precedence & conflict resolution</a></h3>
- <p> As stated above, the various <em>Graft</em> control files have the
- following precedence, from highest to lowest: </p>
- <pre>
- .nograft > .graft-exclude > .graft-include > .graft-config
- </pre>
- <p> The following table summarises the activities of <em>Graft</em> when
- various control files are present: </p>
- <center>
- <table summary="Control File Precedence" border=2 cellpadding=3>
- <tr>
- <th colspan=5>
- Install
- </th>
- </tr>
- <tr>
- <th>
- <em>Target</em>
- </th>
- <th>
- <em>.nograft</em>
- </th>
- <th>
- <em>.graft-exclude</em>
- </th>
- <th>
- <em>.graft-include</em>
- </th>
- <th>
- <em>.graft-config</em>
- </th>
- </tr>
- <tr>
- <td>
- does not exist
- </td>
- <td>
- IGNORE
- </td>
- <td>
- IGNORE
- </td>
- <td>
- SYMLINK
- </td>
- <td>
- COPY
- </td>
- </tr>
- <tr>
- <td>
- symlink to source
- </td>
- <td>
- IGNORE
- </td>
- <td>
- IGNORE
- </td>
- <td>
- NOP
- </td>
- <td>
- DELETE & COPY
- </td>
- </tr>
- <tr>
- <td>
- symlink to other
- </td>
- <td>
- IGNORE
- </td>
- <td>
- IGNORE
- </td>
- <td>
- CONFLICT
- </td>
- <td>
- N/A
- </td>
- </tr>
- <tr>
- <td>
- symlink to other (crc match)
- </td>
- <td>
- N/A
- </td>
- <td>
- N/A
- </td>
- <td>
- N/A
- </td>
- <td>
- NOP
- </td>
- </tr>
- <tr>
- <td>
- symlink to other (crc diff)
- </td>
- <td>
- N/A
- </td>
- <td>
- N/A
- </td>
- <td>
- N/A
- </td>
- <td>
- COPY.new
- </td>
- </tr>
- <tr>
- <td>
- file
- </td>
- <td>
- IGNORE
- </td>
- <td>
- IGNORE
- </td>
- <td>
- CONFLICT
- </td>
- <td>
- N/A
- </td>
- </tr>
- <tr>
- <td>
- file (crc match)
- </td>
- <td>
- N/A
- </td>
- <td>
- N/A
- </td>
- <td>
- N/A
- </td>
- <td>
- NOP
- </td>
- </tr>
- <tr>
- <td>
- file (crc diff)
- </td>
- <td>
- N/A
- </td>
- <td>
- N/A
- </td>
- <td>
- N/A
- </td>
- <td>
- COPY.new
- </td>
- </tr>
- <tr>
- <td>
- not a file
- </td>
- <td>
- IGNORE
- </td>
- <td>
- IGNORE
- </td>
- <td>
- CONFLICT
- </td>
- <td>
- CONFLICT
- </td>
- </tr>
- <tr>
- <th colspan=5>
- Delete
- </th>
- </tr>
- <tr>
- <th>
- <em>Target</em>
- </th>
- <th>
- <em>.nograft</em>
- </th>
- <th>
- <em>.graft-exclude</em>
- </th>
- <th>
- <em>.graft-include</em>
- </th>
- <th>
- <em>.graft-config</em>
- </th>
- </tr>
- <tr>
- <td>
- does not exist
- </td>
- <td>
- NOP
- </td>
- <td>
- NOP
- </td>
- <td>
- NOP
- </td>
- <td>
- NOP
- </td>
- </tr>
- <tr>
- <td>
- symlink to source
- </td>
- <td>
- DELETE
- </td>
- <td>
- DELETE
- </td>
- <td>
- DELETE
- </td>
- <td>
- DELETE & DELETE.new
- </td>
- </tr>
- <tr>
- <td>
- symlink to other
- </td>
- <td>
- CONFLICT
- </td>
- <td>
- CONFLICT
- </td>
- <td>
- CONFLICT
- </td>
- <td>
- N/A
- </td>
- </tr>
- <tr>
- <td>
- symlink to other (crc match)
- </td>
- <td>
- N/A
- </td>
- <td>
- N/A
- </td>
- <td>
- N/A
- </td>
- <td>
- DELETE.new
- </td>
- </tr>
- <tr>
- <td>
- symlink to other (crc diff)
- </td>
- <td>
- N/A
- </td>
- <td>
- N/A
- </td>
- <td>
- N/A
- </td>
- <td>
- NOP
- </td>
- </tr>
- <tr>
- <td>
- file
- </td>
- <td>
- NOTE
- </td>
- <td>
- NOTE
- </td>
- <td>
- CONFLICT
- </td>
- <td>
- N/A
- </td>
- </tr>
- <tr>
- <td>
- file (crc match)
- </td>
- <td>
- N/A
- </td>
- <td>
- N/A
- </td>
- <td>
- N/A
- </td>
- <td>
- DELETE.new
- </td>
- </tr>
- <tr>
- <td>
- file (crc diff)
- </td>
- <td>
- N/A
- </td>
- <td>
- N/A
- </td>
- <td>
- N/A
- </td>
- <td>
- NOP
- </td>
- </tr>
- <tr>
- <td>
- not a file
- </td>
- <td>
- CONFLICT
- </td>
- <td>
- CONFLICT
- </td>
- <td>
- CONFLICT
- </td>
- <td>
- CONFLICT
- </td>
- </tr>
- <tr>
- <th colspan=5>
- Prune
- </th>
- </tr>
- <tr>
- <th>
- <em>Target</em>
- </th>
- <th>
- <em>.nograft</em>
- </th>
- <th>
- <em>.graft-exclude</em>
- </th>
- <th>
- <em>.graft-include</em>
- </th>
- <th>
- <em>.graft-config</em>
- </th>
- </tr>
- <tr>
- <td>
- does not exist
- </td>
- <td>
- NOP
- </td>
- <td>
- NOP
- </td>
- <td>
- NOP
- </td>
- <td>
- N/A
- </td>
- </tr>
- <tr>
- <td>
- symlink to source
- </td>
- <td>
- NOP
- </td>
- <td>
- NOP
- </td>
- <td>
- NOP
- </td>
- <td>
- N/A
- </td>
- </tr>
- <tr>
- <td>
- symlink to other
- </td>
- <td>
- PRUNE
- </td>
- <td>
- PRUNE
- </td>
- <td>
- PRUNE
- </td>
- <td>
- N/A
- </td>
- </tr>
- <tr>
- <td>
- file
- </td>
- <td>
- PRUNE
- </td>
- <td>
- PRUNE
- </td>
- <td>
- PRUNE
- </td>
- <td>
- N/A
- </td>
- </tr>
- <tr>
- <td>
- not a file
- </td>
- <td>
- PRUNE
- </td>
- <td>
- PRUNE
- </td>
- <td>
- PRUNE
- </td>
- <td>
- N/A
- </td>
- </tr>
- </table>
- </center>
- <hr>
- <h2><a name="history">History</a></h2>
- <p> Development on <em>Graft</em> began in October 1996. The initial design
- used a configuration file to map the installed location of each package to
- its target directory (that is the directory in which the symbolic links
- would be created). Work proceeded at a regular pace and by November 1997
- <em>Graft</em> version <em>2.1</em> was released. In this, and all
- subsequent versions, the configuration file had been removed in favour of
- using default source and target directories. </p>
- <p> No further work was performed until September 2000 when the concept of
- bypassing or including files and directories using <tt>.nograft</tt> or
- <tt>.graft-include</tt> files was introduced in <em>Graft</em> version
- <em>2.3</em>. </p>
- <p> Again nothing changed until February 2002 when Rod Whitby identified a
- bug in the handling of <tt>.graft-include</tt> files. Several other users
- (Peter Bray, Robert Maldon and others) also reported some deprecation
- warnings when using <em>Graft</em> with <em>Perl</em> version
- <em>5.6.0</em>. <em>Graft</em> version <em>2.4</em> was the end of
- <em>Graft</em> development for over a decade. </p>
- <p> In May 2015 Matias A. Fonzo contacted the author wishing to use
- <em>Graft</em> in the
- <a href="http://www.dragora.org/">Dragora GNU/Linux</a>
- distribution. Matias' usage of <em>Graft</em> lead to <em>Graft</em>
- version <em>2.5</em> in June 2015 whereby the <tt>-P</tt> command line
- option was silently ignored if the effective user was not root. </p>
- <p> Since the release of <em>Graft</em> version <em>2.4</em> the author's
- <em>Perl</em> code had improved somewhat so <em>Graft</em> version
- <em>2.6</em> released in July 2015 represented a major clean up of coding
- style and internals. No new behaviours or features were added to the
- <em>2.6</em> release. </p>
- <p> Matias made some more suggestions and improvements up to and including
- <em>Graft</em> version <em>2.16</em> in April 2018. These changes added
- the <tt>.graft-config</tt> control file, the <tt>-r /rootdir</tt> option for
- specifying a new root directory, the <tt>-L</tt> option for displaying
- default locations as well as introducing some tighter controls on the
- messages and exit status of <em>Graft</em> under various conditions. </p>
- <hr>
- <h2><a name="installation">Installation</a></h2>
- <p> Before installing <em>Graft</em> you'll need <em>Perl</em>
- 5.<em>x</em>. <em>Graft</em> version 2.<em>x</em> requires features only
- available with <em>Perl</em> 5.<em>x</em> and will not run with
- <em>Perl</em> 4.<em>x</em>. </p>
- <p> Your operating system and its file system(s) should also support
- symbolic links. If you can't make symbolic links then you can't use
- <em>Graft</em>! <em>Graft</em> will exit gracefully if your version of
- <em>Perl</em> does not support symbolic links. It will also exit gracefully
- if you attempt to <em>graft</em> a package into a file system that does not
- support symbolic links - from a Linux <tt>ext4</tt> file system into an
- <tt>vfat</tt> file system for example. </p>
- <p> <em>Graft</em> has been written to ensure it uses <em>Perl</em> modules
- that are considered part of the core <em>Perl</em> distribution. However it
- may be possible that you're using a home grown installation of
- <em>Perl</em> or some distribution that doesn't have the same <em>Perl</em>
- modules as the author's development environment. </p>
- <p> If this is the case you'll see compile failures for the following modules
- if they are unavailable: </p>
- <pre>
- File::Basename
- Getopt::Long
- </pre>
- <p> You will not be able to install <em>Graft</em> until these modules are
- available. </p>
- <p> You may also see run-time failures when using <em>Graft</em> with
- <tt>.graft-config</tt> files if the following modules are unavailable: </p>
- <pre>
- Compress::Raw::Zlib (<em>used in install and delete modes</em>)
- File::Copy (<em>only used in install mode</em>)
- </pre>
- <p> If you don't have these modules and you do not intend to use
- <tt>.graft-config</tt> files then you can continue to use <em>Graft</em>
- without issue. </p>
- <p> Follow these instructions to install <em>Graft</em>: </p>
- <ol>
- <li> <p> Unpack the gzipped <em>Graft</em> distribution: </p>
- <pre>
- gunzip -c graft-2.16.tar.gz | tar xvf -
- </pre>
- <li> <p> change directories to the <em>Graft</em> distribution
- directory: </p>
- <pre>
- cd graft-2.16
- </pre>
- <li> <p> Create an writable version of the <tt>Makefile</tt> by
- running the command </p>
- <pre>
- make -f Makefile.dist
- </pre>
- <p> You'll see output similar to </p>
- <pre>
- cp Makefile.dist Makefile
- chmod 644 Makefile
- ######################################################
- # #
- # You'll now need to modify the Makefile #
- # variables to suit your local conditions. #
- # #
- ######################################################
- make: *** [Makefile] Error 1
- </pre>
- <p> You can ignore the error message. That is just there to
- prevent the creation of the <em>graft</em> executable before you've
- made your site specific configurations to the <tt>Makefile</tt>.
- </p>
- <li> <p> Edit the <tt>Makefile</tt>. The following variables should be
- modified to suit your local requirements: </p>
- <dl>
- <dt>
- <pre>
- <strong>PACKAGEDIR</strong> = /usr/local/pkgs
- <strong>TARGETDIR</strong> = /usr/local
- </pre>
- <dd> <p> These two variables control your default
- package <tt>installation</tt> and <tt>target</tt>
- directories. Most sites will probably choose to
- install packages under a common <tt>installation</tt>
- directory and then <em>graft</em> them into a common
- <tt>target</tt> directory. </p>
- <p> If no specific <tt>target</tt> directory is
- given on the command line, <em>Graft</em> will use
- the default value specified by <strong>TARGETDIR</strong>. If
- a <tt>target</tt> directory is given on the command
- line but is not fully qualified, the value specified
- by <strong>TARGETDIR</strong> will be prepended to the command
- line argument. </p>
- <p> Package names provided to <em>Graft</em> that are
- not fully qualified will have the value specified
- by <strong>PACKAGEDIR</strong> prepended to the command line
- arguments. </p>
- <dt>
- <pre>
- <strong>TOP</strong> = $(PACKAGEDIR)/graft-$(VERSION)
- <strong>BIN</strong> = $(TOP)/bin
- <strong>MAN</strong> = $(TOP)/man
- <strong>DOC</strong> = $(TOP)/doc
- </pre>
- <dd> <p> There should be no need to modify these
- values unless you wish to install <em>Graft</em> into
- a directory that is different from your default
- package installation directory. If you do modify
- <strong>TOP</strong> you should not change the values of
- <strong>BIN</strong>, <strong>MAN</strong> and <strong>DOC</strong>. If you feel
- you must change these values then perhaps you've
- misunderstood the concept behind <em>Graft</em> so a
- re-read of this document may be in order. </p>
- <dt>
- <pre>
- <strong>PERL</strong> = /usr/bin/perl
- </pre>
- <dd> <p> This variable refers to the location
- of the <em>Perl</em> 5.<em>x</em> that will be used by
- the <em>Graft</em> executable. If you plan on
- <em>grafting</em> <em>Perl</em> then this value should
- be the <em>grafted</em> location of <em>Perl</em>
- rather than the installation location of <em>Perl</em>.
- If you are using an operating system that comes with
- <em>Perl</em> 5.<em>x</em> - such as RedHat or Ubuntu
- Linux - then you don't need to worry about
- <em>grafting</em> <em>Perl</em> so the value of
- <strong>PERL</strong> should reflect its installed
- location. </p>
- <p> Most Unix, Linux and other Unix like operating
- systems ship with <em>Perl</em> these days so
- modifying this value is probably unnecessary. </p>
- <dt>
- <pre>
- <strong>BUILDPERL</strong> = $(PERL)
- </pre>
- <dd> <p> <em>Perl</em> is required during the
- <tt>make</tt>. You'll only need to change this if
- the current installed location of <em>Perl</em> is
- different to the future <em>grafted</em> location of
- <em>Perl</em>. </p>
- <dt>
- <pre>
- <strong>LOGFILE</strong> = /var/log/graft
- </pre>
- <dd> <p> <em>Graft</em> logs all of its actions to a log
- file. Modify the value of <strong>LOGFILE</strong> to suit
- your local needs. An alternative name can be
- specified on the command line. </p>
- <p> If you want logging disabled by default, set the
- value of <strong>LOGFILE</strong> to <tt>/dev/null</tt>. </p>
- <dt>
- <pre>
- <strong>GRAFT-IGNORE</strong> = .nograft
- <strong>GRAFT-EXCLUDE</strong> = .graft-exclude
- <strong>GRAFT-INCLUDE</strong> = .graft-include
- <strong>GRAFT-CONFIG</strong> = .graft-config
- </pre>
- <dd> <p> These variables hold the names of the
- special <em>Graft</em> files that control whether or
- not subdirectories or files are <em>grafted</em>. If
- you change these values, try to choose obvious names.
- If you want the files to appear in a simple directory
- listing, do not use file names that begin with a
- dot "." character. </p>
- <dt>
- <pre>
- <strong>GRAFT-NEVER</strong> =
- </pre>
- <dd> <p> This variable holds the names of the
- files and/or directories that should never be
- <em>grafted</em>. Typically these may be source code
- repositories as used by systems such as
- <em>CVS</em>, or perhaps lockfiles. The default
- value is empty but if you wish to specify values,
- simply add them to the variable using only
- whitespace as a separator. For example: </p>
- <pre>
- GRAFT-NEVER = CVS RCS SCCS .lock
- </pre>
- <dt>
- <pre>
- <strong>NEVERGRAFT</strong> = 0
- </pre>
- <dd> <p> If this variable is set to <strong>1</strong>,
- the files and/or directories specified by
- <strong>GRAFT-NEVER</strong> will be automatically excluded
- from the <em>grafted</em> directory. </p>
- <p> If this variable is set to <strong>0</strong>, the files
- and/or directories specified by <strong>GRAFT-NEVER</strong>
- will be not be excluded from the <em>grafted</em>
- directory. </p>
- <p> The sense of this value is reversed by use of
- the <strong>-C</strong> command line option.
- <p> The automatic exclusion is bypassed completely
- if the <em>grafted</em> directory contains either
- a <tt>.nograft</tt> or <tt>.graft-include</tt>
- file. </p>
- <dt>
- <pre>
- <strong>PRUNED-SUFFIX</strong> = .pruned
- </pre>
- <dd> <p> This variable sets the suffix name of
- <em>pruned</em> files. <em>Pruned</em> files will be
- renamed <em>filename</em><tt>.pruned</tt>. </p>
- <dt>
- <pre>
- <strong>CONFIG-SUFFIX</strong> = .new
- </pre>
- <dd> <p> This variable sets the suffix name of configuration
- files that will be copied to the target directory when
- the target object is in conflict with the package
- object. The files will be copied as
- <em>filename</em><tt>.new</tt>. </p>
- <dt>
- <pre>
- <strong>SUPERUSER</strong> = 1
- </pre>
- <dd> <p> If this variable is set to <strong>1</strong> only
- the superuser can <em>install</em>, <em>delete</em>
- or <em>prune</em> packages. This can be overridden
- by the use of the <strong>-u</strong> command line
- option. If this variable is set to <strong>0</strong>,
- superuser privileges are not required and the
- <strong>-u</strong> override command line option is
- disabled. </p>
- <p> If you are installing a private copy of
- <em>Graft</em> to manage packages in your home
- directory you should set <strong>SUPERUSER</strong> to
- <strong>0</strong>. </p>
- <p> If you're using <em>Graft</em> to manage a global
- set of packages you should set <strong>SUPERUSER</strong>
- to <strong>1</strong>. </p>
- <dt>
- <pre>
- <strong>PRESERVEPERMS</strong> = 0
- </pre>
- <dd> <p> When <em>grafting</em> packages, <em>Graft</em>
- will create new directories as required. By setting
- <strong>PRESERVEPERMS</strong> to <strong>1</strong>,
- the original user id, group id and file modes will be
- carried over to the new directory. This variable is
- used only if <strong>SUPERUSER</strong> is set to
- <strong>1</strong>. The sense of this variable can be
- reversed using the <strong>-P</strong> command line
- option. </p>
- <dt>
- <pre>
- <strong>DELETEOBJECTS</strong> = 0
- </pre>
- <dd> <p> When deleting <em>grafted</em> packages,
- <em>Graft</em> may leave empty directories. Setting
- <strong>DELETEOBJECTS</strong> to <strong>1</strong>
- will allow <em>Graft</em> to delete these directories.
- If <strong>DELETEOBJECTS</strong> is <strong>0</strong>
- then <em>Graft</em> will display an appropriate message
- reminding the user that a directory has been emptied.
- The sense of this variable can be reversed using the
- <strong>-D</strong> command line option. </p>
- <p> It's probably not good practise to set this value
- to <strong>1</strong> as some directories may be used
- as place holders by a number of different packages. If
- the value is set to <strong>0</strong> deletion of
- directories can be forced via the <strong>-D</strong>
- command line option. </p>
- <p> When pruning packages, <em>graft</em> can either
- remove conflicting files or rename them. If
- <strong>DELETEOBJECTS</strong> is set to
- <strong>1</strong> the default prune action will be to
- delete conflicting objects. If
- <strong>DELETEOBJECTS</strong> is set to
- <strong>0</strong> the default prune action will be to
- rename conflicting objects. The sense of this variable
- can be reversed using the <strong>-D</strong> command
- line option. </p>
- </dl>
- <p> Save your changes and exit from the editor. </p>
- <li> <p> Remove any existing executables by running: </p>
- <pre>
- make clean
- </pre>
- <p> You should see output similar to: </p>
- <pre>
- rm -f graft
- </pre>
- <li> <p> Create the <em>Graft</em> executable by running: </p>
- <pre>
- make
- </pre>
- <p> You should see output similar to: </p>
- <pre>
- /usr/bin/perl -wc graft.pl
- graft.pl syntax OK
- sed \
- -e 's#xCONFIG-SUFFIXx#.new#g' \
- -e 's#xDELETEOBJECTSx#0#g' \
- -e 's#xGRAFT-CONFIGx#.graft-config#g' \
- -e 's#xGRAFT-EXCLUDEx#.graft-exclude#g' \
- -e 's#xGRAFT-IGNOREx#.nograft#g' \
- -e 's#xGRAFT-INCLUDEx#.graft-include#g' \
- -e 's#xGRAFT-NEVERx##g' \
- -e 's#xLOGFILEx#/var/log/graft#g' \
- -e 's#xNEVERGRAFTx#0#g' \
- -e 's#xPACKAGEDIRx#/usr/local/pkgs#g' \
- -e 's#xPERLx#/usr/bin/perl#g' \
- -e 's#xPRESERVEPERMSx#0#g' \
- -e 's#xPRUNED-SUFFIXx#.pruned#g' \
- -e 's#xSUPERUSERx#1#g' \
- -e 's#xTARGETDIRx#/usr/local#g' \
- < graft.pl > graft
- chmod +x graft
- /usr/bin/perl -wc graft
- graft syntax OK
- if [ -n "" ]; \
- then \
- AUTOIGNORE=1; \
- else \
- AUTOIGNORE=0; \
- fi; \
- sed \
- -e "s#xAUTOIGNOREx#$AUTOIGNORE#g" \
- -e 's#xCONFIG-SUFFIXx#.new#g' \
- -e 's#xDELETEOBJECTSx#0#g' \
- -e 's#xDOCx#/usr/local/pkgs/graft-2.16/doc#g' \
- -e 's#xGRAFT-CONFIGx#.graft-config#g' \
- -e 's#xGRAFT-EXCLUDEx#.graft-exclude#g' \
- -e 's#xGRAFT-IGNOREx#.nograft#g' \
- -e 's#xGRAFT-INCLUDEx#.graft-include#g' \
- -e 's#xGRAFT-NEVERx##g' \
- -e 's#xLOGFILEx#/var/log/graft#g' \
- -e 's#xNEVERGRAFTx#0#g' \
- -e 's#xPACKAGEDIRx#/usr/local/pkgs#g' \
- -e 's#xPERLx#/usr/bin/perl#g' \
- -e 's#xPRESERVEPERMSx#0#g' \
- -e 's#xPRUNED-SUFFIXx#.pruned#g' \
- -e 's#xSUPERUSERx#1#g' \
- -e 's#xTARGETDIRx#/usr/local#g' \
- -e 's#xVERSIONx#2.16#g' \
- < graft.man > graft.1
- </pre>
- <li> <p> If you're using the <em>automounter</em> under Solaris
- 2.<em>x</em>, the installation process may not be able to directly
- create the directory specified by <strong>TOP</strong>. If this is the case
- then manually create this directory using whatever procedures
- are appropriate for your operating system. </p>
- <p> For example, if the <tt>/usr/local</tt> mount point is under the
- control of the <em>automounter</em> via an entry in the
- <tt>auto_pkgs</tt> map: </p>
- <pre>
- * nfshost:/export/sparc-SunOS-5.5.1/usr/local/&
- </pre>
- <p> you'll need to create the <em>Graft</em> installation directory
- by executing the following command on the machine <em>nfshost</em>:
- </p>
- <pre>
- mkdir /export/sparc-SunOS-5.5.1/usr/local/pkgs/graft-2.16
- </pre>
- <li> <p> Install the <em>Graft</em> executable, manual page and
- documentation by executing: </p>
- <pre>
- make install
- </pre>
- <p> You should see output similar to: </p>
- <pre>
- mkdir -p /usr/local/pkgs/graft-2.16/bin
- cp graft /usr/local/pkgs/graft-2.16/bin
- for i in graft.1; \
- do \
- manpage=`basename $i`; \
- man=`expr $i : '.*\.\(.\)'`; \
- mkdir -p /usr/local/pkgs/graft-2.16/man/man$man; \
- cp $i /usr/local/pkgs/graft-2.16/man/man$man/$manpage; \
- chmod 644 /usr/local/pkgs/graft-2.16/man/man$man/$manpage; \
- done
- for i in graft.html graft.pdf graft.ps graft.txt; \
- do \
- mkdir -p /usr/local/pkgs/graft-2.16/doc; \
- cp doc/$i /usr/local/pkgs/graft-2.16/doc; \
- chmod 644 /usr/local/pkgs/graft-2.16/doc/$i; \
- touch /usr/local/pkgs/graft-2.16/doc/.nograft; \
- done
- </pre>
- </ol>
- <p> <em>Graft</em> is now installed and ready to be used. </p>
- <p> <strong>NOTE:</strong> If you make changes to your <em>Graft</em> installation at a
- later date, please run the following commands: </p>
- <pre>
- make clean
- make install
- </pre>
- <p> Failure to do this may result in a <em>Graft</em> manual page that does
- NOT reflect your current configuration. </p>
- <h3><a name="rpm_and_deb">Creating RPM and DEB packages</a></h3>
- <p> Beginning with <em>Graft</em> 2.11 there is now the ability to create
- RPM and Debian installation packages. Obviously you'll need one or more of
- the <em>rpmbuild</em> and <em>dpkg-deb</em> packages installed on your
- system. </p>
- <p> After editing the <tt>Makefile</tt> to suit your environment simply run
- the appropriate <tt>make</tt> command to create the binary installation
- package in the current directory: </p>
- <pre>
- make rpm
- </pre>
- <p> or </p>
- <pre>
- make deb
- </pre>
- <p> The creation of these packages is somewhat experimental. Please let the
- author know if you have issues. </p>
- <hr>
- <h3><a name="gotchas">Grafting <em>Graft</em> and <em>Perl</em> - the
- bootstrap problem</a></h3>
- <p> <strong>If you are using an operating system that comes with <em>Perl</em>
- 5.<em>x</em> - such as RedHat or Ubuntu Linux - then you don't need to worry
- about <em>grafting</em> <em>Perl</em>, so this section can be ignored.</strong> </p>
- <p> <strong>However if you are a creator of an operating system
- distribution then this section may be relevant.</strong> </p>
- <p> Embedded into the <em>Graft</em> executable is the location of the
- <em>Perl</em> executable. If you've understood the concept behind
- <em>Graft</em> then this location may be the <em>grafted</em> location of
- <em>Perl</em> rather than the true location of <em>Perl</em>. </p>
- <p> This presents a dilemma when you come to <em>graft</em> both <em>Graft</em>
- and <em>Perl</em>. You can't run the <em>grafted</em> location of the
- <em>Graft</em> executable because it doesn't exist yet, and you can't run
- the real location of the <em>Graft</em> executable because <em>Perl</em>
- hasn't been <em>grafted</em> yet. </p>
- <p> Assuming that <em>Graft</em> and <em>Perl</em> are installed in </p>
- <pre>
- /usr/local/pkgs/graft-2.16
- /usr/local/pkgs/perl-5.18.2
- </pre>
- <p> you can resolve this dilemma by executing the following commands:
- </p>
- <pre>
- /usr/local/pkgs/perl-5.18.2/bin/perl /usr/local/pkgs/graft-2.16/bin/graft -i graft-2.16
- /usr/local/pkgs/perl-5.18.2/bin/perl /usr/local/pkgs/graft-2.16/bin/graft -i perl-5.18.2
- </pre>
- <p> This will <em>graft</em> both <em>Graft</em> and <em>Perl</em> from the
- default package installation directory (as specified by
- <strong>PACKAGEDIR</strong> in the <tt>Makefile</tt>) into your default target
- directory (as specified by <strong>TARGETDIR</strong> in the <tt>Makefile</tt>).
- </p>
- <p> If you don't wish to use the default directories you can use the
- following commands to <em>graft</em> the packages into <tt>/pkgs</tt>
- instead of <tt>/usr/local</tt> for example: </p>
- <pre>
- /usr/local/pkgs/perl-5.18.2/bin/perl /usr/local/pkgs/graft-2.16/bin/graft -i -t /pkgs /usr/local/pkgs/graft-2.16
- /usr/local/pkgs/perl-5.18.2/bin/perl /usr/local/pkgs/graft-2.16/bin/graft -i -t /pkgs /usr/local/pkgs/perl-5.18.2
- </pre>
- <p> Now both <em>Graft</em> and <em>Perl</em> have been <em>grafted</em> and any
- other package can be <em>grafted</em> by executing the simpler command:
- </p>
- <pre>
- graft -i <em>package</em>
- </pre>
- <p> The <em>Graft</em> distribution includes a program called
- <tt>graftBootStrap.sh</tt> which allows you to easily <em>graft</em> both
- <em>Graft</em> and <em>Perl</em>. It can be found in the <em>contrib</em>
- directory of the distribution. Thanks to Gordon Rowell for providing it.</p>
- <p> You may also find the <tt>-L</tt> command line option to be useful to
- programmatically determine where <em>Graft</em> expects to find
- <em>Perl</em> along with the default locations of its log file, target and
- package directories. See the <a href="#graft-L">Information</a> section
- below for details. </p>
- <hr>
- <h2><a name="using-graft">Using <em>Graft</em></a></h2>
- <h3><a name="compiling-packages">Compiling Packages</a></h3>
- <p> Any packages you wish to place under the control of <em>Graft</em> should
- be compiled and installed in such a way that any package dependent
- files are referenced with the ACTUAL package installation directory
- rather than the common area in which <em>Graft</em> will be creating
- symbolic links. For example, ensure that <em>Perl</em> version
- <em>5.18.2</em> is looking for its library files in
- <tt>/usr/local/pkgs/perl-5.18.2/lib/perl5</tt> instead of
- <tt>/usr/local/lib/perl5</tt>. This approach will allow you to easily
- separate multiple versions of the same package without any problems. </p>
- <hr width="25%">
- <h3><a name="usage"><em>Graft</em> command line options</a></h3>
- <p> All of the details concerning actions, package locations and target
- directories are passed to <em>Graft</em> on the command line.
- (<em>Graft</em> 1.<em>x</em> used a configuration file. This has now been
- deprecated in favour of a log file). </p>
- <p> <em>Graft</em>'s command line options can be summarised as: </p>
- <pre>
- graft -i [-P|u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
- graft -d [-D] [-u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
- graft -p [-D] [-u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
- graft -L
- </pre>
- <p> <em>Graft</em> has four basic actions: </p>
- <ol>
- <li> <p> <a name="graft-i"><strong>Install</strong></a> </p>
- <pre>
- graft -i [-C] [-P|u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
- </pre>
- <dl>
- <dt> <strong>-i</strong>
- <dd>
- <p> Install symbolic links from the package
- installation directory to the target directory.
- Requires superuser privileges if
- <strong>SUPERUSER</strong> was set to <strong>1</strong> in the
- <tt>Makefile</tt>. </p>
- <dt> <strong>-C</strong>
- <dd>
- <p> If <strong>NEVERGRAFT</strong> was set to <strong>1</strong>
- in the <tt>Makefile</tt>, disable the automatic
- exclusion of files and/or directories whose
- names exactly match the values specified by
- <strong>GRAFT-NEVER</strong> in the <tt>Makefile</tt>. </p>
- <p> If <strong>NEVERGRAFT</strong> was set to <strong>0</strong>
- in the <tt>Makefile</tt>, force the automatic
- exclusion of files and/or directories whose
- names exactly match the values specified by
- <strong>GRAFT-NEVER</strong> in the <tt>Makefile</tt>. </p>
- <p> Can only be used with the -i option. </p>
- <p> This option is ignored for each <em>grafted</em>
- directory, if the directory contains a
- <tt>.nograft</tt> or <tt>.graft-include</tt>
- file. </p>
- <p> The <em>Graft</em> manual page will correctly
- reflect the behaviour of this option based on the
- values specified in the <tt>Makefile</tt>. If there
- are no objects specified for
- <strong>GRAFT-NEVER</strong> then this option will
- be silently ignored and will not appear in the help
- message nor in the manual page. </p>
- <dt> <strong>-P</strong>
- <dd>
- <p> Preserve modes and ownerships when creating new
- directories or copying files if
- <strong>PRESERVEPERMS</strong> was set to
- <strong>0</strong> in the <tt>Makefile</tt>. Do not
- preserve modes and ownerships if the option is not
- provided on the command line. </p>
- <p> Do not preserve modes and ownerships when
- creating new directories or copying files if
- <strong>PRESERVEPERMS</strong> was set to
- <strong>1</strong> in the <tt>Makefile</tt>.
- Preserve modes and ownerships if the option is not
- provided on the command line. </p>
- <p> Cannot be used with the <strong>-u</strong> option. </p>
- <p> This option will be silently ignored if the
- effective user of <em>Graft</em> is not root. </p>
- <p> The <em>Graft</em> manual page will correctly
- reflect the behaviour of this option based on the
- values specified in the <tt>Makefile</tt>. This
- option will be silently ignored and will not appear
- in the help message nor in the manual page if
- <strong>SUPERUSER</strong> was set to
- <strong>0</strong> in the <tt>Makefile</tt>. </p>
- <dt> <strong>-u</strong>
- <dd>
- <p> Superuser privileges are not required when
- installing packages. </p>
- <p> Cannot be used with the <strong>-P</strong> option. </p>
- <p> This option is only available if
- <strong>SUPERUSER</strong> was set to
- <strong>1</strong> in the <tt>Makefile</tt>. </p>
- <p> The <em>Graft</em> manual page will correctly
- reflect the behaviour of this option based on the
- values specified in the <tt>Makefile</tt>. This
- option will be silently ignored and will not appear
- in the help message nor in the manual page if
- <strong>SUPERUSER</strong> was set to
- <strong>0</strong> in the <tt>Makefile</tt>. </p>
- <dt> <strong>-l <em>log</em></strong>
- <dd>
- <p> Specify an alternate log file instead of the
- default specified by <strong>LOGFILE</strong> in the
- <tt>Makefile</tt>. No logging is performed if
- the <strong>-n</strong> option is used. </p>
- <p> Log entries have the form: </p>
- <pre>
- 878790215 1.10+ I /usr/local/pkgs/cpio-2.4.2 /usr/local
- 878888916 2.1 I /usr/local/pkgs/gzip-1.2.4 /usr/local
- 878888916 2.1 IC /usr/local/pkgs/gzip-1.2.4/bin/gzip invalid symlink
- </pre>
- <p> This shows that a development version of
- <em>graft</em> (1.10+) was used to install
- symbolic links from <tt>/usr/local/pkgs/cpio-2.4.2</tt>
- to <tt>/usr/local</tt>. A new version of
- <em>graft</em> (2.1) was used to install symbolic
- links from <tt>/usr/local/pkgs/gzip-1.2.4</tt> to
- <tt>/usr/local</tt>. The <tt>IC</tt> entry indicates
- that a conflict occurred during this
- installation - the file <tt>/usr/local/pkgs/bin/gzip</tt>
- was a symbolic link to something other than
- <tt>/usr/local/pkgs/gzip-1.2.4/bin/gzip</tt>. </p>
- <dt> <strong>-n</strong>
- <dd>
- <p> List actions but do not perform them. Implies
- the very verbose option. Does not require
- superuser privileges regardless of the value of
- <strong>SUPERUSER</strong> in the <tt>Makefile</tt>. </p>
- <dt> <strong>-v</strong>
- <dd>
- <p> Be verbose. </p>
- <dt> <strong>-V</strong>
- <dd>
- <p> Be very verbose. </p>
- <dt> <strong>-r <em>/rootdir</em></strong>
- <dd>
- <p> Use the fully qualified named directory as the
- root directory for all graft operations. The source
- directory, target directory and log file will all
- be relative to this specific directory. </p>
- <p> Can only be used by the superuser. </p>
- <dt> <strong>-s</strong>
- <dd>
- <p> <em>Stow</em>/<em>Depot</em> compatibility mode.
- Infer the <em>Graft</em> target directory from
- each package installation directory in the
- manner of <em>Stow</em> and <em>Depot</em>. </p>
- <p> Target directory is the <tt>dirname</tt> of the
- <tt>dirname</tt> of the package installation
- directory. (Yes that really is two
- <tt>dirname</tt>s). So if the package
- installation directory is </p>
- <pre>
- /usr/local/depot/gzip-1.2.4
- </pre>
- <p> the package will be <em>grafted</em> into
- </p>
- <pre>
- /usr/local
- </pre>
- <p> Cannot be used with the <strong>-t</strong> option. </p>
- <dt> <strong>-t <em>target</em></strong>
- <dd>
- <p> Override the default <em>graft</em> target
- directory with <strong><em>target</em></strong>. The value
- of <strong><em>target</em></strong> must be a fully
- qualified directory and it must exist. </p>
- <p> Cannot be used with the <strong>-s</strong> option. </p>
- <dt> <strong>package</strong>
- <dd>
- <p> Install the named package. If <strong>package</strong> is
- a fully qualified directory, use it as the
- package installation directory. If
- <strong>package</strong> is not a fully qualified
- directory, prepend it with the value of
- <strong>PACKAGEDIR</strong> as specified in the
- <tt>Makefile</tt>. </p>
- </dl>
- <hr width="10%">
- <li> <p> <a name="graft-d"><strong>Delete</strong></a> </p>
- <pre>
- graft -d [-D] [-u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
- </pre>
- <dl>
- <dt> <strong>-d</strong>
- <dd>
- <p> Delete symbolic links from the package target
- directory to the package installation
- directory. Requires superuser privileges if
- <strong>SUPERUSER</strong> was set to <strong>1</strong> in the
- <tt>Makefile</tt>. </p>
- <dt> <strong>-D</strong>
- <dd>
- <p> Delete empty directories if
- <strong>DELETEOBJECTS</strong> was set to <strong>0</strong> in the
- <tt>Makefile</tt>. If the option is not
- provided on the command line, notify the user
- that a directory has been emptied. </p>
- <p> Do not delete empty directories if
- <strong>DELETEOBJECTS</strong> was set to <strong>1</strong> in the
- <tt>Makefile</tt>. Notify the user that a
- directory has been emptied. If the option is
- not provided on the command line, delete empty
- directories. </p>
- <p> The <em>Graft</em> manual page will correctly
- reflect the behaviour of this option based on the
- values specified in the <tt>Makefile</tt>. </p>
- <dt> <strong>-u</strong>
- <dd>
- <p> Superuser privileges are not required when
- deleting packages. </p>
- <p> This option is only available if
- <strong>SUPERUSER</strong> was set to
- <strong>1</strong> in the <tt>Makefile</tt>. </p>
- <p> The <em>Graft</em> manual page will correctly
- reflect the behaviour of this option based on the
- values specified in the <tt>Makefile</tt>. This
- option will be silently ignored and will not appear
- in the help message nor in the manual page if
- <strong>SUPERUSER</strong> was set to
- <strong>0</strong> in the <tt>Makefile</tt>. </p>
- <dt> <strong>-l <em>log</em></strong>
- <dd>
- <p> Specify an alternate log file instead of the
- default specified by <strong>LOGFILE</strong> in the
- <tt>Makefile</tt>. No logging is performed if
- the <strong>-n</strong> option is used. </p>
- <p> Log entries have the form: </p>
- <pre>
- 879126278 1.10+ D /usr/local/pkgs/weblint-1.017 /usr/local
- 879126278 1.10+ DC /usr/local/pkgs/weblint-1.017/bin/weblint file exists
- 879126278 1.10+ DC /usr/local/pkgs/weblint-1.017/man/man1/weblint.1 file exists
- </pre>
- <p> This shows that a development version of
- <em>graft</em> (1.10+) was used to delete
- symbolic links from <tt>/usr/local</tt> to
- <tt>/usr/local/pkgs/weblint-1.017</tt>. The <tt>DC</tt>
- entries indicate that conflicts occurred during
- this action - the files
- <tt>/usr/local/bin/weblint</tt> and
- <tt>/usr/local/man/man1/weblint.1</tt> already
- exist. </p>
- <dt> <strong>-n</strong>
- <dd>
- <p> List actions but do not perform them. Implies
- the very verbose option. Does not require
- superuser privileges regardless of the value of
- <strong>SUPERUSER</strong> in the <tt>Makefile</tt>. </p>
- <dt> <strong>-v</strong>
- <dd>
- <p> Be verbose. </p>
- <dt> <strong>-V</strong>
- <dd>
- <p> Be very verbose. </p>
- <dt> <strong>-r <em>/rootdir</em></strong>
- <dd>
- <p> Use the fully qualified named directory as the
- root directory for all graft operations. The source
- directory, target directory and log file will all
- be relative to this specific directory. </p>
- <p> Can only be used by the superuser. </p>
- <dt> <strong>-s</strong>
- <dd>
- <p> <em>Stow</em>/<em>Depot</em> compatibility mode.
- Infer the <em>Graft</em> target directory from
- each package installation directory in the
- manner of <em>Stow</em> and <em>Depot</em>. </p>
- <p> Target directory is the <tt>dirname</tt> of the
- <tt>dirname</tt> of the package installation
- directory. (Yes that really is two
- <tt>dirname</tt>s). So if the package
- installation directory is </p>
- <pre>
- /usr/local/depot/gzip-1.2.4
- </pre>
- <p> the package will be <em>grafted</em> into
- </p>
- <pre>
- /usr/local
- </pre>
- <p> Cannot be used with the <strong>-t</strong> option. </p>
- <dt> <strong>-t <em>target</em></strong>
- <dd>
- <p> Override the default <em>graft</em> target
- directory with <strong><em>target</em></strong>. The value
- of <strong><em>target</em></strong> must be a fully
- qualified directory and it must exist. </p>
- <p> Cannot be used with the <strong>-s</strong> option. </p>
- <dt> <strong>package</strong>
- <dd>
- <p> Delete the named package. If <strong>package</strong> is
- a fully qualified directory, use it as the
- package installation directory. If
- <strong>package</strong> is not a fully qualified
- directory, prepend it with the value of
- <strong>PACKAGEDIR</strong> as specified in the
- <tt>Makefile</tt>. </p>
- </dl>
- <hr width="10%">
- <li> <p> <a name="graft-p"><strong>Prune</strong></a> </p>
- <pre>
- graft -p [-D] [-u] [-l log] [-n] [-v|V] [-r /rootdir] [-s|-t target] package(s)
- </pre>
- <dl>
- <dt> <strong>-p</strong>
- <dd>
- <p> Prune objects (files, links or directories)
- from the package target directory that are in
- conflict with the package installation
- directory. Requires superuser privileges if
- <strong>SUPERUSER</strong> was set to <strong>1</strong> in the
- <tt>Makefile</tt>. </p>
- <dt> <strong>-D</strong>
- <dd>
- <p> Remove conflicting objects if
- <strong>DELETEOBJECTS</strong> was set to <strong>0</strong> in the
- <tt>Makefile</tt>. Rename conflicting objects
- as <tt><em>object</em>.pruned</tt> if the option
- is not provided on the command line. </p>
- <p> Rename conflicting objects to
- <tt><em>object</em>.pruned</tt> if
- <strong>DELETEOBJECTS</strong> was set to <strong>1</strong> in the
- <tt>Makefile</tt>. Remove conflicting objects
- if the option is not provided in the command
- line. </p>
- <p> If a directory is to be removed and it is not
- empty, it will be renamed as
- <tt><em>dir</em>.pruned</tt> and a suitable
- warning message will be given regardless of the
- sense of this flag. </p>
- <p> The <em>Graft</em> manual page will correctly
- reflect the behaviour of this option based on the
- values specified in the <tt>Makefile</tt>. </p>
- <dt> <strong>-u</strong>
- <dd>
- <p> Superuser privileges are not required when
- pruning packages. </p>
- <p> This option is only available if
- <strong>SUPERUSER</strong> was set to
- <strong>1</strong> in the <tt>Makefile</tt>. </p>
- <p> The <em>Graft</em> manual page will correctly
- reflect the behaviour of this option based on the
- values specified in the <tt>Makefile</tt>. This
- option will be silently ignored and will not appear
- in the help message nor in the manual page if
- <strong>SUPERUSER</strong> was set to
- <strong>0</strong> in the <tt>Makefile</tt>. </p>
- <dt> <strong>-l <em>log</em></strong>
- <dd>
- <p> Specify an alternate log file instead of the
- default specified by <strong>LOGFILE</strong> in the
- <tt>Makefile</tt>. No logging is performed if
- the <strong>-n</strong> option is used. </p>
- <p> Log entries have the form: </p>
- <pre>
- 879126283 1.10+ P /usr/local/pkgs/weblint-1.017 /usr/local
- </pre>
- <p> This shows that a development version of
- <em>graft</em> (1.10+) was used to delete objects
- from <tt>/usr/local</tt> that were in conflict with
- <tt>/usr/local/pkgs/weblint-1.017</tt>. </p>
- <dt> <strong>-n</strong>
- <dd>
- <p> List actions but do not perform them. Implies
- the very verbose option. Does not require
- superuser privileges regardless of the value of
- <strong>SUPERUSER</strong> in the <tt>Makefile</tt>. </p>
- <dt> <strong>-v</strong>
- <dd>
- <p> Be verbose. </p>
- <dt> <strong>-V</strong>
- <dd>
- <p> Be very verbose. </p>
- <dt> <strong>-r <em>/rootdir</em></strong>
- <dd>
- <p> Use the fully qualified named directory as the
- root directory for all graft operations. The source
- directory, target directory and log file will all
- be relative to this specific directory. </p>
- <p> Can only be used by the superuser. </p>
- <dt> <strong>-s</strong>
- <dd>
- <p> <em>Stow</em>/<em>Depot</em> compatibility mode.
- Infer the <em>Graft</em> target directory from
- each package installation directory in the
- manner of <em>Stow</em> and <em>Depot</em>. </p>
- <p> Target directory is the <tt>dirname</tt> of the
- <tt>dirname</tt> of the package installation
- directory. (Yes that really is two
- <tt>dirname</tt>s). So if the package
- installation directory is </p>
- <pre>
- /usr/local/depot/gzip-1.2.4
- </pre>
- <p> the package will be <em>grafted</em> into
- </p>
- <pre>
- /usr/local
- </pre>
- <p> Cannot be used with the <strong>-t</strong> option. </p>
- <dt> <strong>-t <em>target</em></strong>
- <dd>
- <p> Override the default <em>graft</em> target
- directory with <strong><em>target</em></strong>. The value
- of <strong><em>target</em></strong> must be a fully
- qualified directory and it must exist. </p>
- <p> Cannot be used with the <strong>-s</strong> option. </p>
- <dt> <strong>package</strong>
- <dd>
- <p> Prune the named package. If <strong>package</strong> is
- a fully qualified directory, use it as the
- package installation directory. If
- <strong>package</strong> is not a fully qualified
- directory, prepend it with the value of
- <strong>PACKAGEDIR</strong> as specified in the
- <tt>Makefile</tt>. </p>
- </dl>
- <li> <p> <a name="graft-L"><strong>Information</strong></a> </p>
- <pre>
- graft -L
- </pre>
- <dl>
- <dt> <strong>-L</strong>
- <dd>
- <p> This is a special mode and it overrides all
- other command line arguments. When present
- <strong>graft</strong> will display the
- <strong>default</strong> locations for Perl, the
- graft log file, the target directory, and the
- package directory in a form suitable for creating
- environment variables for Bourne like shells. The
- output will appear on <strong>STDOUT</strong> as
- follows: </p>
- <pre>
- GRAFT_PERL=/usr/bin/perl
- GRAFT_LOGFILE=/var/log/graft
- GRAFT_TARGETDIR=/usr/local
- GRAFT_PACKAGEDIR=/usr/local/pkgs
- </pre>
- <p> You can set these environment variables using
- one of the following methods. </p>
- <pre>
- eval "$(graft -L)" # modern shells such as bash, zsh etc
- eval "`graft -L`" # older shells such as sh etc
- </pre>
- </dl>
- </ol>
- <hr width="25%">
- <h3><a name="testing">Testing the <em>Graft</em> Installation</a></h3>
- <p> Before creating the symbolic links from the target directory to
- the package directory, you may wish to see what actions <em>Graft</em>
- will perform. Execute the following command: </p>
- <pre>
- graft -i -n <em>package-name</em>
- </pre>
- <p> The <tt>-i</tt> option tells <em>Graft</em> to install the package and
- the <tt>-n</tt> option tells <em>Graft</em> to report on its actions
- without actually performing them. The default <em>Graft</em> target
- directory will be used and the package installation directory will be
- taken from the fully qualified package argument or the default value
- will be prepended to the package argument if it is not fully qualified.
- </p>
- <p> <em>Graft</em> will report on the following actions: </p>
- <ul>
- <li> <p> Installing links to <em>package-location</em> in
- <em>package-target</em> </p>
- <p> Indicates the real package location and its <em>grafted</em>
- target. </p>
- <li> <p> Processing <em>package-directory</em> </p>
- <p> Indicates which package directory is being processed. </p>
- <li> <p> MKDIR <em>dirname</em> </p>
- <p> This destination directory will be created. </p>
- <li> <p> SYMLINK <em>dest-package-file</em> -> <em>package-file</em>
- </p>
- <p> This symbolic link will be created. </p>
- <li> <p> NOP <em>string</em> </p>
- <p> No action was necessary for this package object. </p>
- <li> <p> BYPASS <em>dirname</em> - .nograft file found</p>
- <p> This directory contains a file called <tt>.nograft</tt> so its
- contents and any subdirectories will be bypassed by
- <em>Graft</em>. </p>
- <li> <p> READING include file
- <em>package-dir</em><tt>/.graft-include</tt> </p>
- <p> The directory currently being processed by <em>Graft</em>
- contains a file called <tt>.graft-include</tt> which contains
- a list of file and/or directory names from the directory that
- should only be <em>grafted</em>. The contents of this file are
- being read by <em>Graft</em>. </p>
- <li> <p> INCLUDE file <em>package-file</em> - listed in
- <em>package-dir</em><tt>/.graft-include</tt> </p>
- <p> The file name mentioned in this message appears in the
- <em>.graft-include</em> file and the file exists in the directory
- currently being processed. It will be <tt>grafted</tt>. </p>
- <li> <p> IGNORE file <em>package-file</em> - not listed in
- <em>package-dir</em><tt>/.graft-include</tt> </p>
- <p> The file name mentioned in this message does not appear in the
- <em>.graft-include</em> file and the file exists in the directory
- currently being processed. It will not be <tt>grafted</tt>. </p>
- <li> <p> INCLUDE directory <em>package-directory</em> - listed in
- <em>package-dir</em><tt>/.graft-include</tt> </p>
- <p> The directory name mentioned in this message appears
- in the <em>.graft-include</em> file and the directory exists
- in the directory currently being processed. It will be
- <tt>grafted</tt>. </p>
- <li> <p> IGNORE directory <em>package-file</em> - not listed in
- <em>package-dir</em><tt>/.graft-include</tt> </p>
- <p> The directory name mentioned in this message does not
- appear in the <em>.graft-include</em> file and the directory
- exists in the directory currently being processed. It will not
- be <tt>grafted</tt>. </p>
- <li> <p> READING exclude file
- <em>package-dir</em><tt>/.graft-exclude</tt> </p>
- <p> The directory currently being processed by <em>Graft</em>
- contains a file called <tt>.graft-exclude</tt> which contains
- a list of file and/or directory names from the directory that
- should not be <em>grafted</em>. The contents of this file are
- being read by <em>Graft</em>. </p>
- <li> <p> IGNORE include file
- <em>package-dir</em><tt>/.graft-include</tt>, overridden by exclude
- file <em>package-dir</em><tt>/.graft-exclude</tt> </p>
- <p> The directory currently being processed by <em>Graft</em>
- contains a file called <tt>.graft-exclude</tt> as well as a file
- called <tt>.graft-include</tt>. The <tt>.graft-exclude</tt>
- file takes precedence over the <tt>.graft-include</tt> file,
- so the latter file will be ignored. </p>
- <li> <p> EXCLUDE file <em>package-file</em> - listed in
- <em>package-dir</em><tt>/.graft-exclude</tt> </p>
- <p> The file name mentioned in this message appears in the
- <em>.graft-exclude</em> file and the file exists in the directory
- currently being processed. It will not be <tt>grafted</tt>. </p>
- <li> <p> EXCLUDE directory <em>package-directory</em> - listed in
- <em>package-dir</em><tt>/.graft-exclude</tt> </p>
- <p> The directory name mentioned in this message appears
- in the <em>.graft-exclude</em> file and the directory exists
- in the directory currently being processed. It will not be
- <tt>grafted</tt>. </p>
- <li> <p> CONFLICT <em>message</em> </p>
- <p> <em>Graft</em> could not successfully process a package object.
- One of the following conditions was encountered: </p>
- <ul>
- <li> The package object is a directory and the
- target object exists but it not a directory.
- <li> The package object is not a directory and the
- target object exists and is not a symbolic
- link.
- <li> The package object is not a directory and the
- target object exists and is a symbolic link to
- something other than the package object.
- </ul>
- <p> Conflicts are ALWAYS reported on standard error. If you wish
- to see if the installation of a package will have any
- conflicts, you can execute: </p>
- <pre>
- graft -i -n <em>package-name</em> > /dev/null
- </pre>
- <p> Only <tt>CONFLICT</tt> messages will be displayed. If nothing
- is displayed then you can safely conclude that this package
- can be installed using <em>Graft</em> without any conflicts.
- </p>
- </ul>
- <p> If you were to test the installation of the <em>kermit-5A190</em>
- package you would execute the command: </p>
- <pre>
- graft -i -n kermit-5A190
- </pre>
- You should see output resembling:
- <pre>
- Installing links to /usr/local/pkgs/kermit-5A190 in /usr/local
- Processing /usr/local/pkgs/kermit-5A190
- SYMLINK /usr/local/README -> /usr/local/pkgs/kermit-5A190/README
- NOP /usr/local/pkgs/kermit-5A190/bin and /usr/local/bin are both directories
- Processing /usr/local/pkgs/kermit-5A190/bin
- SYMLINK /usr/local/bin/kermit -> /usr/local/pkgs/kermit-5A190/bin/kermit
- SYMLINK /usr/local/bin/wart -> /usr/local/pkgs/kermit-5A190/bin/wart
- NOP /usr/local/pkgs/kermit-5A190/man and /usr/local/man are both directories
- Processing /usr/local/pkgs/kermit-5A190/man
- NOP /usr/local/pkgs/kermit-5A190/man/man1 and /usr/local/man/man1 are both directories
- Processing /usr/local/pkgs/kermit-5A190/man/man1
- SYMLINK /usr/local/man/man1/kermit.1 -> /usr/local/pkgs/kermit-5A190/man/man1/kermit.1
- MKDIR /usr/local/doc
- Processing /usr/local/pkgs/kermit-5A190/doc
- SYMLINK /usr/local/doc/ckccfg.doc -> /usr/local/pkgs/kermit-5A190/doc/ckccfg.doc
- SYMLINK /usr/local/doc/ckuins.doc -> /usr/local/pkgs/kermit-5A190/doc/ckuins.doc
- SYMLINK /usr/local/doc/ckc190.upd -> /usr/local/pkgs/kermit-5A190/doc/ckc190.upd
- SYMLINK /usr/local/doc/ckcker.upd -> /usr/local/pkgs/kermit-5A190/doc/ckcker.upd
- SYMLINK /usr/local/doc/ckaaaa.hlp -> /usr/local/pkgs/kermit-5A190/doc/ckaaaa.hlp
- SYMLINK /usr/local/doc/ckuaaa.hlp -> /usr/local/pkgs/kermit-5A190/doc/ckuaaa.hlp
- NOP /usr/local/pkgs/kermit-5A190/lib and /usr/local/lib are both directories
- Processing /usr/local/pkgs/kermit-5A190/lib
- SYMLINK /usr/local/lib/ckedemo.ini -> /usr/local/pkgs/kermit-5A190/lib/ckedemo.ini
- SYMLINK /usr/local/lib/ckeracu.ini -> /usr/local/pkgs/kermit-5A190/lib/ckeracu.ini
- SYMLINK /usr/local/lib/ckermit.ini -> /usr/local/pkgs/kermit-5A190/lib/ckermit.ini
- SYMLINK /usr/local/lib/ckermod.ini -> /usr/local/pkgs/kermit-5A190/lib/ckermod.ini
- SYMLINK /usr/local/lib/cketest.ini -> /usr/local/pkgs/kermit-5A190/lib/cketest.ini
- SYMLINK /usr/local/lib/ckevt.ini -> /usr/local/pkgs/kermit-5A190/lib/ckevt.ini
- SYMLINK /usr/local/lib/ckurzsz.ini -> /usr/local/pkgs/kermit-5A190/lib/ckurzsz.ini
- </pre>
- <p> This output shows you that most of the directories already exist
- (indicated by the <tt>NOP</tt> flags). A symbolic link will be created
- in the relevant target directory to each of the files in the
- <em>kermit-5A190</em> package. One directory exists in the
- <em>kermit-5A190</em> package that does not exist in the target -
- <tt>doc</tt>. This directory will be created by <em>Graft</em>. </p>
- <p> <strong>NOTE</strong>: If you are using the <em>automounter</em> you may not be
- able to create the directory <tt>/usr/local/doc</tt>. You'll have to create
- the directory on the NFS server under the file system in which it
- really lives. You should be familiar with the peculiarities of the
- <em>automounter</em> and your specific site configuration before creating
- any directories directly under mount points used by the
- <em>automounter</em>. </p>
- <hr width="25%">
- <h3><a name="installing-packages">Installing Packages</a></h3>
- <p> Once you have ensured that <em>Graft</em> will perform the correct
- actions, you can execute: </p>
- <pre>
- graft -i <em>package-name</em>
- </pre>
- <p> So to install <em>kermit</em> you would execute: </p>
- <pre>
- graft -i kermit-5A190
- </pre>
- <p> There will be no output from <em>Graft</em> unless it encounters a
- conflict. If you wish to see more information you can specify one of
- the verbose flags. For a minimum of output you can execute: </p>
- <pre>
- graft -i -v kermit-5A190
- </pre>
- <p> You should see the following output: </p>
- <pre>
- Processing /usr/local/pkgs/kermit-5A190
- Processing /usr/local/pkgs/kermit-5A190/bin
- Processing /usr/local/pkgs/kermit-5A190/man
- Processing /usr/local/pkgs/kermit-5A190/man/man1
- Processing /usr/local/pkgs/kermit-5A190/doc
- Processing /usr/local/pkgs/kermit-5A190/lib
- </pre>
- <p> If you choose the very verbose option by executing: </p>
- <pre>
- graft -i -V kermit-5A190
- </pre>
- <p> the output will be the same as that when the <tt>-n</tt> option was
- used, however this time <em>Graft</em> will actually create the symbolic
- links. </p>
- <pre>
- Installing links to /usr/local/pkgs/kermit-5A190 in /usr/local
- Processing /usr/local/pkgs/kermit-5A190
- SYMLINK /usr/local/README -> /usr/local/pkgs/kermit-5A190/README
- NOP /usr/local/pkgs/kermit-5A190/bin and /usr/local/bin are both directories
- Processing /usr/local/pkgs/kermit-5A190/bin
- SYMLINK /usr/local/bin/kermit -> /usr/local/pkgs/kermit-5A190/bin/kermit
- SYMLINK /usr/local/bin/wart -> /usr/local/pkgs/kermit-5A190/bin/wart
- NOP /usr/local/pkgs/kermit-5A190/man and /usr/local/man are both directories
- Processing /usr/local/pkgs/kermit-5A190/man
- NOP /usr/local/pkgs/kermit-5A190/man/man1 and /usr/local/man/man1 are both directories
- Processing /usr/local/pkgs/kermit-5A190/man/man1
- SYMLINK /usr/local/man/man1/kermit.1 -> /usr/local/pkgs/kermit-5A190/man/man1/kermit.1
- NOP /usr/local/pkgs/kermit-5A190/doc and /usr/local/doc are both directories
- Processing /usr/local/pkgs/kermit-5A190/doc
- SYMLINK /usr/local/doc/ckccfg.doc -> /usr/local/pkgs/kermit-5A190/doc/ckccfg.doc
- SYMLINK /usr/local/doc/ckuins.doc -> /usr/local/pkgs/kermit-5A190/doc/ckuins.doc
- SYMLINK /usr/local/doc/ckc190.upd -> /usr/local/pkgs/kermit-5A190/doc/ckc190.upd
- SYMLINK /usr/local/doc/ckcker.upd -> /usr/local/pkgs/kermit-5A190/doc/ckcker.upd
- SYMLINK /usr/local/doc/ckaaaa.hlp -> /usr/local/pkgs/kermit-5A190/doc/ckaaaa.hlp
- SYMLINK /usr/local/doc/ckuaaa.hlp -> /usr/local/pkgs/kermit-5A190/doc/ckuaaa.hlp
- NOP /usr/local/pkgs/kermit-5A190/lib and /usr/local/lib are both directories
- Processing /usr/local/pkgs/kermit-5A190/lib
- SYMLINK /usr/local/lib/ckedemo.ini -> /usr/local/pkgs/kermit-5A190/lib/ckedemo.ini
- SYMLINK /usr/local/lib/ckeracu.ini -> /usr/local/pkgs/kermit-5A190/lib/ckeracu.ini
- SYMLINK /usr/local/lib/ckermit.ini -> /usr/local/pkgs/kermit-5A190/lib/ckermit.ini
- SYMLINK /usr/local/lib/ckermod.ini -> /usr/local/pkgs/kermit-5A190/lib/ckermod.ini
- SYMLINK /usr/local/lib/cketest.ini -> /usr/local/pkgs/kermit-5A190/lib/cketest.ini
- SYMLINK /usr/local/lib/ckevt.ini -> /usr/local/pkgs/kermit-5A190/lib/ckevt.ini
- SYMLINK /usr/local/lib/ckurzsz.ini -> /usr/local/pkgs/kermit-5A190/lib/ckurzsz.ini
- </pre>
- <p> <strong>NOTE</strong>: In this case the <tt>/usr/local/doc</tt> directory was not
- created by <em>Graft</em> because <tt>/usr/local</tt> is a mount point
- controlled by the <em>automounter</em>. The <tt>doc</tt> directory was
- created manually prior to executing <em>Graft</em>. </p>
- <hr width="25%">
- <h3><a name="bypass">Bypassing package directories</a></h3>
- <p> You may have the need to place only part of a package under the control
- of <em>Graft</em>. Examples of such occasions may be: </p>
- <ul>
- <li> <p> The contents of one package conflict with another package.
- For example <tt>/usr/local/pkgs/gcc-2.7.2.1/lib/libiberty.a</tt> and
- <tt>/usr/local/pkgs/gdb-4.16/lib/libiberty.a</tt>. </p>
- <li> <p> A package directory is obviously the exclusive domain of
- the package and no benefit will be gained by creating symbolic
- links to its files. For example
- <tt>/usr/local/pkgs/perl-5.18.2/lib/perl5</tt>. </p>
- <p> <strong>NOTE</strong>: This will ONLY work if you originally compiled and
- installed the package such that it refers to its files by their
- '<em>real</em>' pathnames and NOT by the virtual pathnames
- provided by <em>Graft</em>. </p>
- </ul>
- <p> You can force <em>Graft</em> to bypass a directory by creating the file </p>
- <pre>
- <em>package-name/dir/dir/</em>.nograft
- </pre>
- <p> Using the second example above, if you were to create the file: </p>
- <pre>
- /usr/local/pkgs/perl-5.18.2/lib/perl5/.nograft
- </pre>
- <p> <em>Graft</em> would create directories and symbolic links for every file
- and directory down to <tt>/usr/local/pkgs/perl-5.18.2/lib</tt>. The <tt>perl5</tt>
- directory and anything below it would not be created. </p>
- <hr width="25%">
- <h3><a name="include">Including specific files and/or directories</a></h3>
- <p> There may be the occasional need to include specific files and/or
- directories in a directory, rather than the entire directory tree itself. An
- example of such an occurrence would be the case where a package
- contains a number of subdirectories, only one of which is required to
- be <em>grafted</em>. </p>
- <p> You can force <em>Graft</em> to only include any number of files and/or
- directories in a package directory by creating the file </p>
- <pre>
- .graft-include
- </pre>
- <p> in the same directory. </p>
- <p> <tt>.graft-include</tt> will contain a list of file and/or directory names
- - one per line - of the files and/or directories you wish to include. </p>
- <p> Consider the <em>a2ps</em> package for example. When installed it
- contains the following directories: </p>
- <pre>
- /usr/local/pkgs/a2ps-4.13b/bin
- /usr/local/pkgs/a2ps-4.13b/etc
- /usr/local/pkgs/a2ps-4.13b/include
- /usr/local/pkgs/a2ps-4.13b/info
- /usr/local/pkgs/a2ps-4.13b/lib
- /usr/local/pkgs/a2ps-4.13b/man
- /usr/local/pkgs/a2ps-4.13b/share
- </pre>
- <p> The only directory you wish to <em>graft</em> is the <tt>bin</tt>
- directory. You could place a <tt>.nograft</tt> file in each of the other
- directories, <strong>OR</strong> you could create a single <tt>.graft-include</tt>
- file in <tt>/usr/local/pkgs/a2ps-4.13b/.graft-include</tt>. This file would
- contain </p>
- <pre>
- bin
- </pre>
- <p> Now only the <tt>bin</tt> directory will be <em>grafted</em>. </p>
- <hr width="25%">
- <h3><a name="exclude">Excluding specific files and/or directories</a></h3>
- <p> There may be the occasional need to exclude specific files and/or
- directories from a directory, rather than the entire directory itself. An
- example of such an occurrence would be the case where files from different
- packages have the same name. <em>Emacs</em> and <em>Xemacs</em> use the same
- names for a number of their configuration files for example. </p>
- <p> You can force <em>Graft</em> to exclude any number of files and/or
- directories from a package directory by creating the file </p>
- <pre>
- .graft-exclude
- </pre>
- <p> in the same directory. </p>
- <p> <tt>.graft-exclude</tt> will contain a list of file and/or directory names
- - one per line - of the files and/or directories you wish to exclude. </p>
- <p> For example, if you did not wish the file </p>
- <pre>
- /usr/local/pkgs/sudo-1.5.3/etc/sudoers
- </pre>
- <p> to be <em>grafted</em> as </p>
- <pre>
- /usr/local/etc/sudoers
- </pre>
- <p> but you did want </p>
- <pre>
- /usr/local/pkgs/sudo-1.5.3/etc/visudo
- </pre>
- <p> to be <em>grafted</em> as </p>
- <pre>
- /usr/local/etc/visudo
- </pre>
- <p> you would create the file </p>
- <pre>
- /usr/local/pkgs/sudo-1.5.3/etc/.graft-exclude
- </pre>
- <p> and ensure its contents contained the line: </p>
- <pre>
- sudoers
- </pre>
- <p> <strong>NOTE:</strong> Any entries made in a <tt>.graft-exclude</tt> file will
- override the same entries made in a <tt>.graft-include</tt> file. That is,
- if a file or directory name is listen in both a <tt>.graft-exclude</tt>
- and a <tt>.graft-include</tt> file, it will be <strong>excluded</strong> from the
- <em>graft</em>. </p>
- <hr width="25%">
- <h3><a name="config_dirs">Grafting configuration files</a></h3>
- <p> Beginning with <em>Graft</em> 2.11 there is now the ability to treat a
- package directory as a repository for configuration files. In this case you
- would place a <tt>.graft-config</tt> file in the package directory and any
- files in that directory would be <strong>copied</strong> to the target
- directory. Files in conflict would also be copied but would have a default
- suffix of <em>.new</em> to ensure the existing file is not clobbered.
- Conflict discovery is achieved using a simple 32-bit CRC check. This
- feature has been added to assist operating system distributors manage
- system configuration files, specifically it was added at the request of the
- maintainer of the <a href="http://www.dragora.org/">Dragora GNU/Linux</a>
- distribution. </p>
- <p> Consider the following example. You may wish to upgrade the
- <em>openssh</em> server as part of an upgrade to your distribution. In
- order to preserve any local user modifications to the relevant
- configuration files you would add a <tt>.graft-config</tt> file to the
- package as follows: </p>
- <pre>
- /usr/local/pkgs/openssh-server-6.61/etc/default/.graft-config
- /usr/local/pkgs/openssh-server-6.61/etc/init.d/.graft-config
- /usr/local/pkgs/openssh-server-6.61/etc/init/.graft-config
- /usr/local/pkgs/openssh-server-6.61/etc/network/if-up.d/.graft-config
- /usr/local/pkgs/openssh-server-6.61/etc/pam.d/.graft-config
- /usr/local/pkgs/openssh-server-6.61/etc/ufw/applications.d/.graft-config
- /usr/local/pkgs/openssh-server-6.61/lib/systemd/system/.graft-config
- </pre>
- <p> The other directories in the distribution would not require any control
- files. </p>
- <p> Imagine that the local administrator has made some changes to
- <tt>/etc/pam.d/sshd</tt> such as adding additional authentication methods
- to support two-factor authentication for example. As the distribution
- maintainer you do not want to reverse this local change so when the local
- administrator upgrades the distribution, <em>Graft</em>
- <strong>copies</strong> the new <tt>/etc/pam.d/sshd</tt> file to
- <tt>/etc/pam.d/sshd.new</tt> which allows the local administrator to merge
- their changes with any new features supported by the upgrade. </p>
- <p> To take full advantage of this feature you may need to explicitly set the
- target directory as follows: </p>
- <pre>
- graft -i -t / openssh-server-6.61
- </pre>
- <hr width="25%">
- <h3><a name="partial-graft">Grafting part of a package</a></h3>
- <p> Some packages can be successfully used when only part of their
- installation directory is <em>grafted</em>. Other packages are
- recalcitrant and need some special hand holding which can only be
- solved by <em>grafting</em> each section of the package separately. </p>
- <p> The first scenario can be handled by either <tt>.nograft</tt> files or
- partial <em>grafts</em>. Consider <em>Perl</em> version <em>5.18.2</em>.
- When installed in its own directory </p>
- <pre>
- /usr/local/pkgs/perl-5.18.2
- </pre>
- <p> there are three subdirectories </p>
- <pre>
- drwxr-sr-x 2 psamuel bisg 512 Oct 30 1996 bin
- drwxr-sr-x 3 psamuel bisg 512 Oct 30 1996 lib
- drwxr-sr-x 4 psamuel bisg 512 Oct 30 1996 man
- </pre>
- <p> Everything in the <tt>lib</tt> directory is exclusive to <em>Perl</em>
- and does not require <em>grafting</em>. Therefore, <em>perl-5.18.2</em> can
- be <em>grafted</em> using either of the following two methods: </p>
- <pre>
- touch /usr/local/pkgs/perl-5.18.2/lib/.nograft
- graft -i perl-5.18.2
- </pre>
- or
- <pre>
- graft -it /usr/local/bin perl-5.18.2/bin
- graft -it /usr/local/man perl-5.18.2/man
- </pre>
- <p> Now let's consider a recalcitrant package - <em>ObjectStore</em> version
- 4.0.2.a.0. When installed in </p>
- <pre>
- /usr/local/pkgs/ostore-4.0.2.a.0
- </pre>
- <p> the following files and directories are available: </p>
- <pre>
- -rwxrwxr-x 1 pauln one3 1089 Oct 31 1996 Copyright
- drwxrwxrwx 8 pauln one3 512 Oct 2 1996 common
- drwxrwxrwx 6 pauln one3 512 Oct 31 1996 sunpro
- -rw-r----- 1 root one3 1900544 Apr 29 1997 txn.log
- </pre>
- <p> The executable programs that need to be <em>grafted</em> are in
- <tt>sunpro/bin</tt> and the manual pages that need to be <em>grafted</em>
- are in <tt>common/man</tt>. Everything else in the package does not
- need to be <em>grafted</em>. If the entire package was to be
- <em>grafted</em> the result would be two directories that are not in the
- regular <strong>$PATH</strong> and <strong>$MANPATH</strong> environment variables - namely
- <tt>/usr/local/common/man</tt> and <tt>/usr/local/sunpro/bin</tt>, plus a host of
- other directories that are not relevant for <em>grafting</em>. No amount
- of <tt>.nograft</tt> and <tt>.graft-exclude</tt> juggling will solve
- this problem. </p>
- <p> The solution is to use two partial <em>grafts</em>: </p>
- <pre>
- graft -it /usr/local/bin ostore-4.0.2.a.0/sunpro/bin
- graft -it /usr/local/man ostore-4.0.2.a.0/common/bin
- </pre>
- <p> Using this approach, the correct executables and manual pages are
- available without the need to <em>graft</em> unnecessary files and
- directories. </p>
- <hr width="25%">
- <h3><a name="deleting-packages">Deleting and/or Upgrading
- Packages</a></h3>
- <p> If you wish to upgrade a package - let's assume you wish to upgrade
- <em>kermit</em> from version 5A190 to version 6.0.192 - you'd follow
- these steps. </p>
- <p> Firstly, you'd compile and install <em>kermit-6.0.192</em> in </p>
- <pre>
- /usr/local/pkgs/kermit-6.0.192
- </pre>
- <p> Once you'd tested it to your satisfaction, you'd need to delete the
- symbolic links to the current <em>grafted</em> version. You can check
- which actions <em>Graft</em> will perform by executing: </p>
- <pre>
- graft -d -n kermit-5A190
- </pre>
- <p> You'll see output similar to </p>
- <pre>
- Uninstalling links from /usr/local to /usr/local/pkgs/kermit-5A190
- Processing /usr/local/pkgs/kermit-5A190
- Processing /usr/local/pkgs/kermit-5A190/bin
- UNLINK /usr/local/bin/kermit
- UNLINK /usr/local/bin/wart
- Processing /usr/local/pkgs/kermit-5A190/man
- Processing /usr/local/pkgs/kermit-5A190/man/man1
- UNLINK /usr/local/man/man1/kermit.1
- Processing /usr/local/pkgs/kermit-5A190/doc
- UNLINK /usr/local/doc/ckccfg.doc
- UNLINK /usr/local/doc/ckuins.doc
- UNLINK /usr/local/doc/ckc190.upd
- UNLINK /usr/local/doc/ckcker.upd
- UNLINK /usr/local/doc/ckaaaa.hlp
- UNLINK /usr/local/doc/ckuaaa.hlp
- Processing /usr/local/pkgs/kermit-5A190/lib
- UNLINK /usr/local/lib/ckedemo.ini
- UNLINK /usr/local/lib/ckeracu.ini
- UNLINK /usr/local/lib/ckermit.ini
- UNLINK /usr/local/lib/ckermod.ini
- UNLINK /usr/local/lib/cketest.ini
- UNLINK /usr/local/lib/ckevt.ini
- UNLINK /usr/local/lib/ckurzsz.ini
- UNLINK /usr/local/lib/.testing
- </pre>
- <p> If you're happy with the output from the test deletion you can delete
- the <em>grafted</em> package. Once again, you'll only see output if a
- failure occurs unless you use one of the verbose options. </p>
- <p> If you execute: </p>
- <pre>
- graft -dV kermit-5A190
- </pre>
- <p> you'll see: </p>
- <pre>
- Uninstalling links from /usr/local to /usr/local/pkgs/kermit-5A190
- Processing /usr/local/pkgs/kermit-5A190
- Processing /usr/local/pkgs/kermit-5A190/bin
- UNLINK /usr/local/bin/kermit
- UNLINK /usr/local/bin/wart
- Processing /usr/local/pkgs/kermit-5A190/man
- Processing /usr/local/pkgs/kermit-5A190/man/man1
- UNLINK /usr/local/man/man1/kermit.1
- Processing /usr/local/pkgs/kermit-5A190/doc
- UNLINK /usr/local/doc/ckccfg.doc
- UNLINK /usr/local/doc/ckuins.doc
- UNLINK /usr/local/doc/ckc190.upd
- UNLINK /usr/local/doc/ckcker.upd
- UNLINK /usr/local/doc/ckaaaa.hlp
- UNLINK /usr/local/doc/ckuaaa.hlp
- EMPTY /usr/local/doc is now empty. Delete manually if necessary.
- Processing /usr/local/pkgs/kermit-5A190/lib
- UNLINK /usr/local/lib/ckedemo.ini
- UNLINK /usr/local/lib/ckeracu.ini
- UNLINK /usr/local/lib/ckermit.ini
- UNLINK /usr/local/lib/ckermod.ini
- UNLINK /usr/local/lib/cketest.ini
- UNLINK /usr/local/lib/ckevt.ini
- UNLINK /usr/local/lib/ckurzsz.ini
- </pre>
- <p> <strong>NOTE</strong>: In this case the existence of an empty directory has been
- discovered. If <em>Graft</em> empties a directory during a package
- deletion, it will either notify you or delete the directory depending
- on the combination of variables in the <tt>Makefile</tt> and command
- line options. It's probably better practise not to automatically
- delete empty directories as they may be used by other packages - such
- as lock file directories for example. </p>
- <p> Now you can remove the <em>real</em> package contents. (You may not wish
- to do this immediately as some legacy systems may depend on features
- provided by the older version or you may feel the need for further
- testing before feeling confident that the old version can be removed):
- </p>
- <pre>
- rm -rf /usr/local/pkgs/kermit-5A190
- </pre>
- <p> Now you can <em>graft</em> the new version of <em>kermit</em>. Execute: </p>
- <pre>
- graft -i -n kermit-6.0.192
- </pre>
- <p> to ensure that the <em>grafting</em> will proceed without error. Once
- you are satisfied that this is the case you can <em>graft</em> the new
- package by executing: </p>
- <pre>
- graft -i kermit-6.0.192
- </pre>
- <hr width="25%">
- <h3><a name="transitioning">Transitioning a package to <em>Graft</em>
- control</a></h3>
- <p> <em>Graft</em> can be used to easily transition a package from its
- current installation in your target directory to a <em>grafted</em>
- installation. </p>
- <p> As an example, let's consider the package <em>weblint</em> version 1.017.
- It consists of three files installed in: </p>
- <pre>
- /usr/local/bin/weblint
- /usr/local/lib/global.weblintrc
- /usr/local/man/man1/weblint.1
- </pre>
- <p> The first step is to create a new copy of the package in its own
- directory: </p>
- <pre>
- /usr/local/pkgs/weblint-1.017
- </pre>
- <p> Ensure that any references to library files are now made to
- <tt>/usr/local/pkgs/weblint-1.017/lib</tt> instead of <tt>/usr/local/lib</tt>.
- </p>
- <p> Test the new installation to ensure it behaves as expected. </p>
- <p> Then prune the old files from <tt>/usr/local/*</tt> using: </p>
- <pre>
- graft -pV weblint-1.017
- </pre>
- <p> You'd expect to see output similar to: </p>
- <pre>
- Pruning files in /usr/local which conflict with /usr/local/pkgs/weblint-1.017
- Processing /usr/local/pkgs/weblint-1.017
- Processing /usr/local/pkgs/weblint-1.017/man
- Processing /usr/local/pkgs/weblint-1.017/man/man1
- RENAME /usr/local/man/man1/weblint.1
- Processing /usr/local/pkgs/weblint-1.017/bin
- RENAME /usr/local/bin/weblint
- Processing /usr/local/pkgs/weblint-1.017/lib
- RENAME /usr/local/lib/global.weblintrc
- </pre>
- <p> If you elected to delete conflicting files instead of renaming them
- you'd use: </p>
- <pre>
- graft -pDV weblint-1.017
- </pre>
- <p> and you'd see output similar to: </p>
- <pre>
- Pruning files in /usr/local which conflict with /usr/local/pkgs/weblint-1.017
- Processing /usr/local/pkgs/weblint-1.017
- Processing /usr/local/pkgs/weblint-1.017/man
- Processing /usr/local/pkgs/weblint-1.017/man/man1
- UNLINK /usr/local/man/man1/weblint.1
- Processing /usr/local/pkgs/weblint-1.017/bin
- UNLINK /usr/local/bin/weblint
- Processing /usr/local/pkgs/weblint-1.017/lib
- UNLINK /usr/local/lib/global.weblintrc
- </pre>
- <p> Now the new version of <em>weblint</em> 1.017 can be <em>grafted</em> in
- place: </p>
- <pre>
- graft -i weblint-1.017
- </pre>
- <p> The <em>grafted</em> version of <em>weblint</em> can now be tested. </p>
- <p> If we renamed conflicting files, they can be removed once the
- <em>grafted</em> <em>weblint</em> has been satisfactorily tested: </p>
- <pre>
- rm /usr/local/man/man1/weblint.1.pruned
- rm /usr/local/bin/weblint.pruned
- rm /usr/local/lib/global.weblintrc.pruned
- </pre>
- <hr width="25%">
- <h3><a name="conflicts">Conflict Processing</a></h3>
- <p> Occasionally <em>Graft</em> will fail to completely install a package. This
- occurs because <em>Graft</em> encounters a conflict. A conflict is defined as
- one of the following possibilities: </p>
- <center>
- <table summary="Conflcits" border=2 cellpadding=3>
- <tr>
- <th>
- Package Object
- </th>
- <th>
- Target Object
- </th>
- </tr>
- <tr>
- <td>
- directory
- </td>
- <td>
- not a directory
- </td>
- </tr>
- <tr>
- <td>
- file
- </td>
- <td>
- directory
- </td>
- </tr>
- <tr>
- <td>
- file
- </td>
- <td>
- file
- </td>
- </tr>
- <tr>
- <td>
- file
- </td>
- <td>
- symbolic link to something other than the package object
- </td>
- </tr>
- </table>
- </center>
- <p> If <em>Graft</em> encounters such a conflict during the installation of a
- package it will report the conflict and exit. </p>
- <p> Resolving the conflict depends on the nature of the conflict and is
- beyond the scope of this discussion - however most conflicts will
- either be the result of attempting to <em>graft</em> a package on top of
- the same package actually installed in the target directory or a file
- name clash between two (or more) different packages. </p>
- <p> Conflicts arising from the pre-existence of a package in the target
- directory can be resolved using <em>graft</em>'s prune mechanism
- described above in <a href="#transitioning">"Transitioning a
- package to <em>Graft</em> control"</a>. </p>
- <p> File name clash conflicts can be resolved by the use of either a
- <a href="#bypass"><tt>.nograft</tt></a> or
- <a href="#exclude"><tt>.graft-exclude</tt></a> file or by
- <em>grafting</em> only part of a package as described above in
- <a href="#partial-graft">"Grafting part of a package"</a>.
- </p>
- <p> If <em>Graft</em> encounters a conflict while deleting a package, it will
- report the conflict and continue deleting the remainder of the package.
- In this way <em>Graft</em> will delete as much of the package as
- possible. Conflicts that arise during deletion will probably be the
- result of an incorrectly installed package or the installation of other
- components of the same package without the use of <em>Graft</em>. </p>
- <p> Conflict messages are written to standard error. All other messages
- are written to standard output. To quickly determine if a package will
- have any conflicts when <em>grafted</em>, redirect standard output to
- <tt>/dev/null</tt> </p>
- <pre>
- graft -i -n <em>package</em> > /dev/null
- </pre>
- <p> If you don't see any output then you can safely assume that there will
- be no conflicts when <em>grafting</em> this package. </p>
- <p> See the comprehensive table above describing how
- <a href="#precedence">conflicts are handled</a> for more details. </p>
- <hr width="25%">
- <h3><a name="exitstatus">Exit Status</a></h3>
- <p> <em>Graft</em> will terminate with an exit status of either 0, 1, 2, 3 or 4
- under the following conditions: </p>
- <center>
- <table summary="Exit Status" border=2 cellpadding=3>
- <tr>
- <th>
- Exit Status
- </th>
- <th>
- Condition
- </th>
- </tr>
- <tr>
- <td>
- <center>
- <strong>0</strong>
- </center>
- </td>
- <td>
- All operations succeeded.
- </td>
- </tr>
- <tr>
- <td>
- <center>
- <strong>1</strong>
- </center>
- </td>
- <td>
- A conflict occurred during installation.
- </td>
- </tr>
- <tr>
- <td>
- <center>
- <strong>2</strong>
- </center>
- </td>
- <td>
- Command line syntax was incorrect.
- </td>
- </tr>
- <tr>
- <td>
- <center>
- <strong>3</strong>
- </center>
- </td>
- <td>
- One or more packages listed on the command line does not
- exist. Other valid packages listed on the command line were
- processed correctly.
- </td>
- </tr>
- <tr>
- <td>
- <center>
- <strong>4</strong>
- </center>
- </td>
- <td>
- The log file <tt>/var/log/graft</tt> could not be updated. Usually a
- result of a permission error. Any other error condition will
- override this condition.
- </td>
- </tr>
- </table>
- </center>
- <hr>
- <h2><a name="other-pkg-tools">Using <em>Graft</em> with other package
- management tools</a></h2>
- <p> Most Unix vendors have released their own package management tools with
- their operating systems. Examples of this are Solaris 2.<em>x</em> with its
- <em>SVR4 Package Manager</em> <tt>pkgadd</tt>, RedHat Linux with its
- <em>RedHat Package Manager</em> <tt>rpm</tt>, Ubuntu Linux (and other Debian
- Linux derivatives) with its <tt>dpkg</tt> system and HP-UX 10.<em>x</em> with
- its <tt>swinstall</tt> suite. <em>Graft</em> has been designed as an adjunct
- to these package managers rather than a competitor. The author has used
- <em>Graft</em> successfully with all of the operating systems mentioned here.
- </p>
- <ul>
- <li> <p> Many useful packages available in the public domain and from
- other commercial sources are not shipped with most flavours of
- Unix. <em>Graft</em> can be used to maintain a rich package
- environment beyond the set of packages provided by your vendor.
- Vendor based packages can still be maintained using the vendor's
- tools and <em>Graft</em> can be used to maintain your own packages.
- </p>
- <li> <p> The vendor based management tools are usually used to maintain
- single instances of a package on each machine. It is often
- difficult to have multiple versions of the same package coexisting
- on the same machine. <em>Graft</em> can be used to maintain multiple
- versions of a package to support legacy, production and development
- requirements simultaneously. </p>
- <li> <p> Another common problem with vendor supplied software is
- the speed at which upgrades are available. The large vendors are not
- known for providing quick fixes to many of their packages. (Notable
- exceptions to this are the vendors of operating systems based on
- open source software who can draw on the enormous number of users
- who submit patches because the source code is available). Using
- <em>Graft</em> you can obtain a working public domain version of
- a package (if one exists of course) and install it in a different
- location to the vendor copy. When the vendor releases a new version of
- the package, it can be installed using the vendor's package management
- tool and your <em>grafted</em> copy can be removed (only if the vendor's
- version of the package is better than the public domain version). </p>
- <li> <p> Sometimes, a vendor's package doesn't quite perform in the
- manner you'd like. It may be making assumptions about your file
- system(s) that are incorrect for your environment or it may not
- have all the features you'd like. If an alternative package is
- available - either in the public domain or from other commercial
- sources - it can be installed and <em>grafted</em> accordingly. </p>
- </ul>
- <hr>
- <h2><a name="availability">Availability</a></h2>
- <p> The latest version of <em>Graft</em> should always be available from: </p>
- <pre>
- <a href="http://peters.gormand.com.au/Home/tools/graft">http://peters.gormand.com.au/Home/tools/graft</a>
- </pre>
- <hr>
- <h2><a name="license">License</a></h2>
- <p> <em>Graft</em> is licensed under the terms of the GNU General Public
- License, Version 2, June 1991. </p>
- <p> You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or download
- it from the Free Software Foundation's web site: </p>
- <pre>
- <a href="http://www.gnu.org/copyleft/gpl.html">http://www.gnu.org/copyleft/gpl.html</a>
- <a href="http://www.gnu.org/copyleft/gpl.txt">http://www.gnu.org/copyleft/gpl.txt</a>
- </pre>
- <hr>
- </body>
- </html>
- <!-- html code generated by txt2tags 2.6. (http://txt2tags.org) -->
- <!-- cmdline: txt2tags -t html pkgmanagement.t2t -->
- </BODY></HTML>
|