Codebase list guitarix / ddd2223
New upstream version 0.39.0+dfsg1 Víctor Cuadrado Juan 4 years ago
81 changed file(s) with 14199 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
166166 from waflib import Scripting
167167 Scripting.waf_entry_point(cwd, VERSION, wafdir)
168168
169 #==>
170 #BZh91AY&SY9 ½´\¥ÿÿÿ³DPÿÿÿÿÿÿÿÿÿÿÿm (¬#%00e€(b÷/mЀ#%#%#%#%#%#%#%#%#%#%#%#%#%#%#%#%#%#%#%#%öÞúzómmkîÖZžÞ旲U#.´[iÚ¾îõ¹±µ–ú:¥'kd‹î7{ÛïoºµÛ¶ÖµK“¹]Øvµ'ÛßO¾ö¸gv÷s½÷¶N)#.Q+Ù½íp·µÞ]/{mš»<{guҋ@Ýó{§«vo;¾ø;ŸvÎiîáÉî44lºï{ß|ûëËßÚU9íõݟݚy½÷½x#%#%@(}ìh#%` ﲀ=âwfí˜:4§[aÓ¹½ y©³A¦€‡¸ê»´ö4=¦öìd+Ö¨ª)ífš0#6 *”¢”{ƒ’Q$#%#6#%YJzÚV½ƒ%çÍíîæ}»j½êºa’ïjÚØá3TTf˦Iv×]s}6óu7¾÷z:#.ÎxûÝW_=³ÛzÖ­åZ;Û»ÍÝÛ}Þsy¾¯³»ß{¸ûížÖîiÉÔ÷Ëzõ¶§rç>^æû}ñ¾íóÛa zúz{x¹-ìz̀ݳ­Ö²4÷³¼ÛÞ÷fÞÏs¬ô`u¡ÒãF°Û"’EE7w¼#%(J*’OCÀ#%lîè•=÷n{Ywº¹½»ÐdÜ öï>}Ü[vÇGÐ`>†ÛEmk®¥ÑMãW`×LæyÛãÚ^u½#%}÷aŽît;o¶û}|{mçO—vpòǼ΀Šo·*WµíƘܶ2>öí®®òϟwÖõ»]´î;ºjîí9QÚt×·Zt“ž>÷»Ü®¨ÜÙu÷‡ß|}í­«×ܬ‰&ÞíN«îq\îû½:¾Ã.ñŽ^ÙéyaC§¶Ó¶Û›—³®÷Ð¥&nCzî¤|öilöͶíÝîвë[¸˜÷»³Ûºû5ÖkoX«èqؗnöÐl­îõÞÞ/`{´žó½wÌ>ï†Ðê¥PJªPTT´jB¹7uÐv&i¶v­Üèº]vú‰Ý›:kÛkÔØëUUܘ{x÷š)º¼»HЃºÚɯfw€#%7ZI#%#%;Ü^êåÉÎó²û3ÊF-Ÿm½ÜözÔíݙÜì_U.us[›¶ õv]]ó¸|˜Hû†,ÍqÑ»ÝÁæñ{c;úŒçvåJº{+¹éÔ²õ§l÷+ªWg¡»`úùÛÙ;{n#î²Ç]÷}çww»{»»xîvÛ#.¾Øú½mÝEfù‡"sž¼ï¯¼ùÚÀ°ËlÐú$/g¬íєx<ïÜë°VØ6EǑµÞ®ÚGxO{×>öø½ïwÞ´#%À*×Û;Fªµíí7¶;g<ÂÀëu´oSk´Ý­ëÓ­mï 9.ó’®Ú×ݬ» ݾçwÅówwtåvë¥Þç:#.[.ëwc ӂàéÕhÁ”gu“½Þ^ïŸnØu¼ÓÐŒ…/=ÝÚ4#%•c¹éî½Mö{ÜàìJ…U )½{xW»´×`ï{®ñÝÊäÅÖÃV¶•U[}÷IzovƒuÇH*Ší·u­$ëIÒÖªîúãÞncÚ[ÓµŽÛ× &Æ»»}öøø‡½óí·³acÜ| ìÁ“G»îñÌͼÜ&:·»}½í6µîÐíç;ï¹ßvÛRÀîï·Ÿw}-âòó[ãnh€ &€#%&€ £CBa0š#.#%‰ä™PÏTz†Ðš#%õ§’{SÔõA) B @†@©©á$zzI☠é4#%#%#%#%#%#%#%‚D!  M5TÿMŠoU<ÔôzTý(òÔõ)é¨mG¨#%#%Ñ£@#%#%'ªRD!4dÐODõ$ÙOFž¡£õM#.€ò@#.Sj#%#%#%#%#%#%$!#%&@bh&M#%M#.4SÓiˆŒ4 ¢ #%h#%#%#%I¨ˆ L˜#Až€&Œ¦=&”õmêˆ{SIé” h#%d4#%È#%—ÿÓ?£Uirê\ÕQWwk¹úµZvhʃ>5Zu!LA³ ,L•Q*"€)æ°Pcõ§óü Zü“•5OùÓ¦¸ üæJt¦î£đ8•WoT"¢]^SÌÆ´_3ý†os2ì ÀlDs‚4;m»qE6­›®ñ‘ÎÊ­´ÚMí˜ÖØ`Vd…â]jí◘•5o‚# åñ÷UŒI7wD¼áÌKUå¦/žÝ~«oÔBäE"ªSº»U¦ÖÖ5k3khȋ €7#%H*-E Õ:¥”$HŠ& ˆ" HåP° !ß#%hŠ–‚¡#%ª$@d PÉ@mªfL…’ŒÍCLÓd@M$Rj6Ñ35–25)F”Sm&‰š$ÐJ2ZšQ°h[Fi,ši¢Z!#.F)iM€F¥ #.1eM£DRl–¨Š–ZSMhˆYi#.š ƒ(ÌÌcRF£Qµ&ƒJl†BjcI@˜hÒËHÆR›F¦›"[M¶³U´i˜’ÆfLÈM& ²m¦ÛM65%)-5±–¦Û3fZL“1‘f´ÄÑd¢‚™l‰B!Qf‘´R`4TH!`ؤ©„f•Jb0lB ‘XhdFIR&B4±ClÍ ’&)BFRÊËf$@ÒYŠY5“ccE#6‘d†K) -)¦ ±%&EDš2hhɉIF‘($@VAMEˆ¢fRÒ¦`›É ؉1M ͂ab6¤Ø–V‹$”›‚$´”PRD•’%¤Q0EaÆIL# ”&RJME™±£XHÒjH’b iM$"H²[bË2ŠF̒‰²™3bdE(͑˜&U4Ћ)A³Q`,i¦†Æ"5+%’6(”R"šIˆ&¤a³LcI¡ &¤–Q”Ôi3HÚ("šh¢kP,&YA¤²2‹%&DÐM2‘*4f6”)1¨6ÄÊA! "“1F4,Ë ŠÙ&TÌ՘£l¥±(‰™#.H¦!HŒØСYM$QF¤É&ÉØÆJšF¦h±b2’™˜²2³i„¬D`ˆ¢JM52i™!Œ¢)#.š1Sb‹5*R’š)#.‘“2)´…HÅ(ÊHR"‹E$˜’M)´i5DŠFÀ˜Œh&Ti¦DÚ#.ƒ,„Òe‹DÈY‘¦ÉJb”D!f™ k6lmd°$4–Ld5EPZ XR$Ècc1 Â2ƒRXÔY¤J&ŒE©M(Z˜hI™IŠ$2ɲ#)‚E,Ñ¥1„5„²e"$4M¶¦¶´`™BjfŒ¦F&”RLȈ­¥6À¥š,Å&‘”%–TÙ¢-L¬-”bC؈RˆšD#HJm~Ãk¢¦©aˆÍ¢ŒlVƶ*6L¥4ÔR¤š44´…¨ØFÉ5Y†¡¦c(ÉS*H¶D‰™¦[%´Q‰IKQµ…£&˜D±5˜±acR#6e¥™2eI´*Ò4TÙB+dË"©TÒT›63š¶,Y­“L¬‰S,¦ÖJ²ÙJSLl’‘µ)¬±%¤2RÔZ ªŒ!¨Õ£%AEVMd£jŠÅEH”kDÑ$m‹hŊÔl2ѵ€´™0°U@i€”R £F2™&•¦±ƍ¦&±‹d‹i Õª–µ–* ”ÍKY4IR1!M¤lY"¶¥Y¶1Jm*–R¦YaZšDF¶•K"e5MM¶„”Êk,Xl²k+,…lÓ  ¨ÒD…bÃ4˜‰!´…-£T%¢†KQY&š6LšJ,ˆ&ËŠl¤#."+,‚E1”ÌJ”lÓ4 AE¢Ó$&Fm6“F6ÆÈS¦™cE%bHÌÔ#!4LÔQ¢JdR–P5BTÀ4˜Ó J™²Bj-#636£)F̤’Œ£!HbÊkÃi4F5&Éa $YP…-4) Ě4Y”©””²•˜d¬aš,‘± jE¨Õ5£4ECF¥)6b¥fQj4  2ÆA¦&ĕ%I”1Ršcd¤Ía)ME`Û0Ù¤²lf“E˜‰CJ2Zfµ‘hTÍ2–H’l£0D2hªih¬Òl”Ä,LDÒRBAh´[ Q¨ÔQŠÆ-–ÃI†’M#6LŒRˆ#b-f›C2ˆ6*2%,¤©‘Ñ´k£TI¢„Ë5EŠ$Ԛ£PdðŒj”¡kA¥4Ë!E$Š¦Ih‚5Eˆ±JÛ"¥F±¤ÁdÑÌ¡jQHfJ$©±(‰•j#V#.2,Y*6Œ)‹4¢Ù2V-­&)+)¶D¶M¡¢T’™R¢Âƒccd£dÑ&#¶HÔRLÁ¬ÉƒA#6)³6&"šÆ¨©•“Y‘¤)¤šŠ¢Š&›RV-”’ÆɈ£F‚4˜2JԈÑie£he¨’ÑjŠ±”£i5² …Q¶5%)ЙÈ̌ƚ‘LÙ&kDlU%‹hԕ,«&´Lڐ1lj £cc$UE2©¥XÚ6¶1mI˜ÊQ f²±-F+iQµ´©QJV”f*šB (4X"J&ØÖ,ʒ+I[M²“+FbbÑIE[l¶¬R&T*&$¢1PÀ"CFŠi&ÔÃ%XÛØ´Í[F5¬´•42ÖÊY6ÔÔÛ!mI¦¬ME26’QA°ÖjMI™²Êˆ B¢LI&RLˆÈÄd"Ù-¢Ñ‚±“þn··ýÔ¥C)þB51jÄÿTqôe+(a(Æh”‡÷!þ§ ûbåÕ LÿL$hÒlùNzí¿Îó±½9¿‹øºô·¦SUIPª?ë[ŒlȟÎÿ·ÖYLâsÈ †ßùë;L(0\:8À¥‰pÁI äˆd˜*ƒ‰Ãß±¢rý*¤çÿœ3ÿ³ôZÑÿÊI(R×+ˆ½”g™,$b/­Í0ÿ-‹npz%ZM‡¼íõâ8ßwB¹ÁŒ¨d~Ë ՋN؜“ÆZþ,3cRR(l“ŠrrXˆþúݳf¤áV…cÈÌ`I¥Û"lÆLhƒcôz瓓G]“¼î˜Þ¹w§¥^¥ã\³Ë/âuçåu™Í\‚LŠëP¦"W‹4LªvcK™@¥JAF&ēM‚ê×bÈ‹Ò3ˆ(êñç]¨eñnY½74h6 m `ٗ(c2@sªªzoþÝ(‘ 7p‡ Êc#6Gv…)†ì,`¼rÂü®R[ŒR}ßÒëdzçgsÅéšÐN×VÄQL0¦Ð¤Y;ùd«Ïô8$ÚÍÏ£˜ØÐ؞j¤Ï(%?·râƒþ°Ãµ “ºÀ¡…†JÅxžß÷k¶Œ¶cÂx-›2KËw%€•¬C°UyáyܖíÞw^QŽr車esn–CQW6éçqllO²ëå5¼Z4EA¯»ºŸ?_ÆW‹ò-ȦWÅȶÆåÈIºÕø¼u‘¨Û?Go*„Èyùæ|m<™b#4L9cuPEX°ž«©#.¹t@#6A!´ä#ñÆ#.¯)ÎãÂHˆÃz”^+›Ý\Ѩ8šë•ÞwcrŽ•Ë™(Ë®é$s™5öø‘ZA„ÿhÿŒJrÈ.YÚlCÙ’,0!M ðÛtÉÈe«#6ýR­‹ÁÃ79ô,ýפ¾ìÉþ˜FtÃÏxV¬@Gô¡€dž%lþ «p’—<kìÄ9 c£ðÐÃ|¶Ç™“#tE]H P0îT[æÈ؃Ù_#¨½—zírH È¦wâԊŽÍW†7mxþVYê? )Ärvj³oQžwE¦m„e#.¿ÂdԂ™ç™×¶b²àþN!ïe §&¢”øuû/ÑÏKà`ö§nínœšùT)"*¤#6d9 #c*w&靃bۆÉðfR6zš®:'ï.àûì¥k,YL#6N*}±ÆyÞ>Ç㊝UË"õ֍“UO«pi)8ª—â”+ñ §Ó¬,‰±Èj[þv¼‹lQôÇôa™1Kèë¯Ç×FÌ÷¿SªÄ7Ím‰Z½&#6”*‰£NŒ¼Pâ-#6¬AË@‰*•{iX<ÙZøW÷»(Éðâ»EEE¼nY5ÆÕ͵þ—ìw’>ÇS6½•ß‹«¦öøÿM‡fhŠF¨%2+zmýW!†ŒbSQIðîÜ®÷uVé(i%"÷@Xš'+¬¥&D§)J²‹šå¢¶/]öï^¯"R¬•k¹bÑ_·-×»±öõÆ*Š|ý{ü=o÷îèë˜ØÔl›|ÏÀÞ1¨4–üŽ‹> õ݌>¬žýóL—ÖȲ"4£~"Uä¨ræPaŒLÖ¶jϹ$Â![ÙùzÛ²†F²lWßî«âøùÑÊW=ì¼4D‰Áa«l—AHÒPŤ'Ò'mBµ§…C×Gƒ¶éE2„R]U¥"»wÕ¬ü*ÔðХ߲œœ²ôî²Á‹¨ÀSE#6lÃQ MZH"JuœëJ» *”Ó#6I¢L²íãe—¥Â„S²ŠŸ$+ b¨¬N¬<ÙkH](©É#6<*žoЗçAJõ ü/•;q°óap×^Ro^X„jÅÄ"_gñ‡Ë<TC—ª¼s×y›¬Xq&ýqK\:05a–áeF1PXäiMö÷3g{O4Ýur™gúkßÙóô€oÄï3à )#åªiÔö¢'”־ʣôwr³éº8;+¹+Ÿ†oìÑ®Há m^L¯q#.1¼öÊIr%ÉnCMÏ}‡×–ìƒ6q¸v~„ØÆ5.›|båÙåA„Å#ƒ™S—<*Jtªð¡áô\äáDäÑö%*Éú9ß<}/²Á"#.“L3¦ÙúÀýv½ëåŽ+’ù§T-±·,»í¶g)õïDš!;SñŐµaÊà=±3œÏDKA´](´ ¸åHvÈÍR߁#v/6P½E#Dž‡8qêΰâKè(q<åÅð¹’ý>¼ê÷Œ:+#%ñ²(\HÎpÊ6疴zmï*'Ü©×1Ù»á?_kŒ#.êV£„ÊFyûeo–Ðæ”$Áª?•ßjfA›­v߾ڜNü£ƒz…$…!¨.fä³Ü¡Ï\ˆiÌ©Ê#.#¥ŠÉE0F:E&©¯}ٞ…µAîg]°éˆÃp?X7d1€á\NB=}ÙILÆ˜#6P#6íç;¢gä˜ý=«»†"ž<ú¹áïïRî:I2Éðˆ\õ­q.Vž)gɅ,Õ8`¬=jPŽûí‰ÞèqëZ®#.þø¯,nM´B8÷8»è¸×µÛº†ä1ž‡i‹l÷õ m±Ï׺|š5Ì=Zí鵦üLuÙ $‘(w0©WX uÒ‘Bd˜N>ù¢Ü¸I¸ì¾½i“íE•éËÒêwë+Õ^{å5ÁZU{Š)ŠãÉÂé¨c¼T˜ì˜í§ @^†Ç¡=4´îç ʉZۍoý4^Û1¶Ã‰±öíªÆË ˜ò-—îûâû™§õoÉÜn¬æU>õéºiúK|e˨†J/±ßåÇ}m}w*IeQ92e@êÛ íhQAA9¼CrºõÝO¡¸Ëðuu5¤&÷JÃF}w/Å¡j©jŠÿ}…(© Ÿ+þ«¯½û¿éºÚ|~þëÇT•öµö°ù¥±G‘R{¨«EŠ ¢€úªS>,õ‰÷öæß»åj»çíj܇±†¿•™Yõ¿¯œõâ‚ú·+$‰þ.hÚ>n·‚ªôj£]–P‚ꩨÆ ׶{âÝûïg˜œå mk4µ“O§k{єÇÛEË£õ;n”dm¥AyÑQŸ#6ÚäúÓ«f‰Í²­ãX—8T¾NL\ð—ôPè‹˜1 øˆ63œYî y²úUM3¦ùÝ#.X˜|è¤TWù“7ìÍÇΊD^jÀEŒR,Œ)9Õß¹ÊÈ·)óÜьûúuO³~™¾$_¶ÏŠ ÊsãÆ4?ŒZu>žì]1yÅøÚüžkÓEµÛX)>óOÖâm8s´Ì‚ëéÞO–z\àÚÄÚ¸;â¦R¸Á1ŠŠ~FS_tí“Rn(‘ØPñ¼b˜¤Rf“WYüÊ¡êô„cì×ùúù«ÜËÎP¼B´ ú’Yׅé¤DQQe0¨x~‚Û{*©nf £ªwiX‡T¯)œ’6-Ï;Ë£êw³$3Ê¡¶Ö}•TÛÉ|-ºz²8ï5›`BüéÝââêÖh¢’…ƒÒ¡¸É~¦™J‘‹Î€¤Z+¯¦9r¬èœlÿV´xð¨#6h6ÀêD¶x0¥Ë)AX›³£*0²¹ë¯_#.Ç·†È÷zìe¥HÙÓ,›¿µñïñ²5AòõÁޟŠ{žeÔË7Sú­þ¡&yÖYñ¯¥³LÅSœ¹¾Ù?•”¾ŽÙƒÊ-„y¯69^èŽ}ž¦pà†BI‘iK‡&±nÎǨŸþ³…éÝs»Î¹ßŽe²‚ð,¼&2:LäßÏå[‹«¸óxHÇ®*–Ø×ÒU9„åé1䌟 DL5;þ²ÏiîÐ傄QT nUّ`ҟ#ÍoJò4†1Sºëïv馫ÚÕéa離Mô4O|®­–I$ {U½órà¼0‡;0©*ÃzG/½7ƒ+– #%Qb ]’öÙK\.ª¸­ÌÖ‡÷) I9q×ëa¾¡—¼òó#.ÑýýïÞ5К¾ä¬×w*8ÙA—'<ß:¥˜bÊï¬2×ÂxÕQn:ú,öTl8:<ôáyï9ëCÛ¢M\¡"#.JvX¢=Êóðw¹Ô%g±œC͕P´GhaÑû£™ªºÅH…”ö)¬¾U.ÎõۙÂî‰A=†”s È«Ôs›H]#.¤ú$¢8.‹\Ó³Mìòõò³ޛ TÑTaÓMš}ª P‚ «½È¥>?‚¿½¨èØkÕborR#Rñ/ŸÌç*3ÔÆѦø–Ú4u©ð±o‰c‡ÈÞéñÇ#.vnV»pÁáã)r‹³Z”,ª£Ž.O€êÀ’·}zwîÝlnª¥Ÿ.LQøy×@EHiwýÐçç=Q›q§"%V2&0+VŒq¬¨w=Pë¦uÁ7ºV^-Eu©QQ'çU0D}ÏéޙNi×ôñ$¤úÊ'1ΝK¯U=_­“lS­#6´íŠ0ã×D­1zßÆǾ+âdpڈô±æZ?wéžx½\`<+½—f—Jøã×~WKËÕ¸îáݝ8n©$z«G»à<c½Ì/Y€á÷ˆÓ vfˆz3ó¹L´cz7k­ù%ûÚEΛY¥ñ¹-J`]ÞBvP\ÃÚïŸHm2LˆMßwðrÈ÷4›:ðŒµ¼`¡‚¯\Ô½u}˜<(ñf`¨Åˆ³÷ôͽ‰UQ9c:ªO+%‰ŽöPiP/º°<H¬§`±È6,I<Y–e"4ECØ@f‹zÝ«šÉbFŽõ™G¡B>q¡z<À®÷±¢—Ù è‘ì#Œá?Ÿ—™}ûI”¡ÓL»_KÃ'ë—B¶Øÿ#É+ù¢ËÖò„|ÑúåµömŽ±‹ת©ü°Œá˜Ç’7û"ònþ½bôŠ#sh¡›¶¢~¥?~´›V]6k)0úô£ ¦ÙUBÕñ °Uˆ¢,õ'«@ž5ûÜ+ÏÕlŸ±X6µÉ nŒ.ö{pùèü}´:ÑÚð†y¥ªŸbsf19%¢ØñZ³æ#Ô#6 ‚ ­ê,&ў3|#6y€"ú.$#. #.æuµÅ.÷ éÙד»*{gd¾Š­evKfûQοí¶ÒÌð7N ›hÄe hP"1b±êL`ÅMm¬"ã-ÅX]#6=™©Õ)˜«Î#.äÓ2¿+]øºtÉg“:Ô00Y½UDà’ÆŠÛHœIå#LÇ͒6\j¾}›Þ#.‚Û»Æ6Ñ=U S¿ÑÏޚtÌ4så Ùº"ïg³.¾‰t(ÄÉ:qþ²c1û¦³^¹ÙÈÕýÉn*fb’¢fƒÛŠãš;èXhêöÛ÷Ç1•£a¼s>¬=N#.ä÷Áý(ûqÃنfT`ÒalÚÞœ~2å8ŒÀr¥‘Ÿ¦!:Y@àe ¨Öj¡Á¥N¬Íec±;8`i‰j%ÉÓcW?äDM¶@0L‚¸¤\Þ'k‘KŽ«®NºËϧcV*±F֘Òßãñð³Ô9O—äÇ»éìåôÁõ*5,<:ؒ|EI$¹$G4¡Õ{âS§#%bŸeÙ‚‡TöŽ¯äìÚÈQ·Ø!û€PveòóêÞ6‚^—ø\F´÷fX= ”*´nïú>Q/ãnNQŠž#64…¯¦E¼×^Æ~ú“’`GÈ'0’õÍ\P”DØLÍÕ7؃Ku„ÑohsyÛÝQ¼ã*Sšçsƒ;5XvPÍf8uŒÁ®[˜ÝÒS¬Ýϒ³•ÔÍ4”¹²†s?…'ÚÝ­i Î;¾n)tYG.å¯K|íMÆ×6AâÖuü×8'¶¿UÊҍ»*se¦ܙL)e‹8«|Šãý×W#%}O`×|AÊ>ƒbm€fò†\sIÑO##y3£Bé#.⊠}ÏÕ¡n«r£CDb+ÂÛ` 왭úÛn¨>O½Õqòh‹¼’×59·b¢ fŒ~~˜V#+bç±^Ug•:^óŽ×ÿxºTq(Ū¿1™y{T‘áâzÒÔ²?[좧s ˆÔ5YÿÆgk’ —qjûWXvã_WmMÆñuÍZ3¥Q_{=’žì㳗¦(5#<IÛD9Ü÷3Ï^—’y%0I†jÂÉ[J3NMíT ¦nPÿG†4„–_oñï=BÚÓK¤JÍ¿‹˜ï¹¹oŒÕa^ݶxe@eˆëªã8GHºê½ÙGÄƊÀú"ûÞ° £‘’wñ†ýž~Sa¢œv®4L§Uz°ÎÞÛß²+f”y´Þ¿#./wWdË«^úPÄ´¤áYKAq:;åG2jT wÌCˆ{¿‡ÚœC¥™k5PuÝrª0àÒs¢l+«3Û¬#Û8]ŋ‘Tœˆò»Ó:—úûâ$KÈr™‰0ʏâ(\ñ>ˆ‡„æ©CÞØ ¥Î]«m9¹ÙãHˆ X1ºÈ½7¸ÙŸdÉ-”K†OèÜû¿—ŽqÛDˋâíÜ×s²žó#%$̐Ø@²š%"£ÏiñÁGn¦· —›šÿ¦åg­sáºÖÉÑosã¢Ñ+-¯m%b”"¹mofŽŠÁfm{pYpÐØoÆ­Z”̸ Â4¸b³Øúxì^S™ÎuÜÛzVþîlbݵ Ï°POæÀŠ:›»ˆ¾Zn(Ô#{›7)×¹L ùσãÕñÁ”€÷YÓ¡á‡õ"6zXø£°ébc™G“ë-þ7J-YSՖ#.™[òw_#6}P$RF/þª:üó²§HèCþCo:“Të–=49yz¿ÃÆÊræĕ{´R4IÖÌom¨3 ]•F“m;Àuc£tÇloz‰Á`(]ô¿5Œ¨å¥÷!œ.º¿»ZUǤe(®™¯ù‚Ê<V+Ύ3¾Òÿ™Ó²uèæ:»bà-¯°F–|¦W“ìºS·§Œµ‚]ëÑöá« Ø·M(ŒW–ù¯:ŒýuÊ:jÝڏÌ£H¹EÑ£8`ñÅتá¨à³ýk £Ã7c¤ü¶<ΒW‚=ëS¼qé4§5#.-ڃ߾›öÝE3ÂcÈär¨Äžù§L¢^3ýލ®§r"ßM¼}1(gËD­ôÑ%¯PÄIƒ¶ôÄ`ƒ³”CȲ-G%nG5—lV°‰À(#6QEc—ærÚéͬ١C8’z³‡`Cß½uˆ.7ªY`ÞD,U GÊRÌÑvp«œOøg[\þ–]EŚ@Bcvß8èˆÕñ]Ñ·7ˆŒBov?Uëì”?ë†oŒ;2ëðÿ…¾>^ŽR÷ F““Ö\«ÈÞ¬Ãô²†Ct½FŽ«X 8Ž,Ò;hŸ˜Xj¾$8ÍûYùüxpå»È6püà ·Ý¤$ÀA7ýc€%#%%"A/üÕê¢c–å9Xãßá]5GóÚY"E5É#ÁÛ/*9/„QÉ?Bu˜jÑm-Ã&é;ýz|ž¯‚££Õ¨l@'ñ(¢¹*öúi|GÀS«êÓ©ÝœKð!7ÕmVÐÒ×>ƒø³9€&u ŽÈ„ƒ#% ’ûÿÕ»Ñþ-¢îÕáø­ÇîäévÞ»¥ #.cc¢¼¢ ÎD×Ì@?Ç4#6†¡o轶j0–ê**Ž¸ÙsóîÅÇ#.„¾º"MŒ\îª"ˆ¤‘ò©¹#%gíޜá4yR™b(Ñ>@€òtÆ¡R¿šÒ]eÑ·äsvÓ Én(+VpäÿE®‘+ü'6¹†ðN°¢3¤Ä[(ZŠaÉ»I{–Þa½x=™Ž9"1ˆ[ëJ¯l ê1­H#.ªñŒŠ%OÙŒ#%”ì#%ÄcÏm¾ÿ¶ç•aùã¤þÑI‡ç³ñåú#.5™ðׯ_ó~µ?èÌO“HÅGTUÙÀM¿ƒðý¶y´»õ¨5ц6¥—Ãcj™b²ø§¹ƒƒ$|_Cºuž0€^~c_ñd° "wƒ#%°>בj>ðõ—ER=Sþñ¶s|º5ŸÛå€Ãm¶fÕ¿.Õ4|œåÝj]“³‘¨:;£únŠ>’Ÿñ:ÿn@ é )ª×fËw#.·l¾¡ßþ0}÷îâ£(WÏÎüoNßÛès’ {G4ÆÞ|ö0t9×bbÎ?GÝ÷k_ÁÉfª ž"@îkò•X/E÷;¥fL¡¦¿qößÕ5¼8±“d¢*¡â{/Ìë¿D4áÅtɚûàûoötgS³wÓ>¬XB§<ÈIÁM•mGý—ùu…9£Š>¿zsáþ¸'^Í¡c®¶7B ªƒ+ÅÀ3ïr˜\«poª_P–ÜâÛô=‚TÁ֓æõ§º»¶4ZMI:îäٜ³[Ê+Yòȍ{Q”Óho³…`#67]±áÄRd1ÌU…²[d"ˆ—”b$#6Jk!¬gÛªLk Š$,¸ûÌ£Ö[ËúžP&¶Ï•¢U´’†ð¼U1#ÅË;§¿&b±A…1dy%*üüóŒî€¨ "/Z7—cûÿuËBˆsrœ™§¿-‘œ$ýþ~…mLÀ:z®X»U ÄDq#6“Ïß©s <=Uƒ¨~L …¯R›5¸}Š ÛVIé­³íLg¦aóÓáåvº˜ÿ_E—F–– -™áG8˜Ÿ“?ûmRGÒ=bSfqÖ7¶ÆAi+sèü"Ê|;O¦$÷#I±aiñÓíÁº×®[Hå[#.º“œu€ÆƎ²X[ȗ¡J×<óÙT¢ Þº™ÆÕQjª@J’ßü.Å#%…W&û9œo…èîD@¾Àß#.âë…cû§˜A,BCG:l¡úkLuÐ#6”‘Õž ?; éõæk¬‡©÷‘ž#.qÌvʐÐ3:^LŸUÈk4Ž#6`#.~•H‰5ðÏٝž>Ãõ›÷þ}¾Ó¯‘[ŠhyѺBJ2\¡~¬dâe#/¯ÿa7·§4ãYUáCÇMs÷þ{¿ÍcB'$Å;Ç©·8¦ø¦#.{,µj€weß#.røâ^˾<0fxþîÍÎ5&Ī¦š6P·cQǘ"5Uô†÷êŸE7¥ã˜y–l)p™Ú7úµ!$—Ó8>ž{K2®rãyòUçD#¯lüw¯åz€ã=wʋÝ#6Dn…¸}^æ¡}ªé«)D¥ÐŠ”‚]âuq·à¿çÛ³2±³…®\ÚS{ûìSXãÅY% qßÀn©ÇA#°óÑUá]=@tÔ³žÅj&†Â»Æ5&fîŒðpK‰ ¶˜Sd&vEÚ}´zGÝ*B#6 ìÃQ>Gêp¬vþ—Û…m}M‚ææ‰ï¤É *Ý0ƒÞþÓpì÷Æûè|A²vB0;½–k[Èé#6¦h˜"# _ ßzéòøÍ3ã 2&ˆBžÑ…5Â6‡…ܦ2,,»¹Ç|زØR¢"ÈQˆæY¼° Æ҃ •ÇLkG>'ôjŽ1* Èéô‹uüi‚S1ëŒu\SdIiÆTˆ°Š²O¨6ƘڱÔᝑ¢»µázl_gêÿ8hx”MöX0-ôî ê#ôéŠsüKˆòÿ5ö¨»?#%Ýyx®)–˜À’7 y#%í2òw‰ ÐPc±   Æ#%tÀ`=!#.fîÁN¯%Ò[^v…'k³Q÷Þ´R“̧`ÆzÆ) û¼nuí¶#ÎÃí?.ÒIpJ[¥iB¡×*,ÂÒÅ š=ÕÕ`„ìQ×pgc¼Iâèez«ôC,Á†f{Ê2ѪRuš„Æú 빈7©Óyå_æ>£vöt…µÆ|ú9´VKœâR˜;#6(<äwãC)ª((F‚Ïv0ñ2hÊЭŒ–ˆDÊ#0+C“9°z“˜¼•]>ÄlÑJYb¦„ÒTœ-¨¦Å¾bàèÁFrÐpõŽ*(~¨Ñäû£sÐÌꆄÊ4 u»y!jŽÐ#8±sy#.bƒn=>tzËÌh†Á¡ÈÌ\åê¦å­…bPõYÄËþ:¹Â—nT ÝÐ`¨é“Õñ턱ֽnz1»DR‘Å+‡GèobŽÊØÛÑ£ŒU$2ÖåŸ#tóëñØó^¸émÖ½¹ªO8«,›}YEω{^ÜIfxOÐpLÂÅG•#.pßú¿‡¸ÊYE³>vKUÓç¼çûˆ} šgا©Ú§^Ï­ÜøÌÍ+#%®[Ÿaœ:9ޚœ9ÉÃd×+àB~e.wµ†¼qalñwE#%{j›,dº*1—®íwyæ]®îëO‘˜ÀFŽn‘snZ*4x’m1|F¢ ˆªÝ4s¡ÊŒý֞{Ζ¹,äl D {#%ÓDhM´ÔD)$CTÅVƨʍ£}íÁ14LT.%"¸ã #%l@'D188Ö÷#.A³èòñ®$Õ^¾0Ʊ³\´h$‡{Þ®#.NUzJ);I?×$è±ØíJö»‹? v#.ê‹Ùö‰T«T¾î°¦‡ãaÆ»EÀø5vÈbãlyA}·É¹»Ròš¢C÷)K.Ç(…ösN\0p¨¨S"Ðoœ*ñ“!WTðCyp2b2„ˆè/mû¬kÙÓY¢Kn9‚†¦µJ:¸Ü­³\ü{oM—h]¥ÂŠfŒXn#6àÛ¯d ә/Qƒè؅E®‘KNÀá®WöÙ=þ= ^u¶Ã?כíÆʓ5çãœ+8~я…ZF0oћ48Ã@òð_¾*Çc0Z4ÛþþJ˜°q …áF‹Ã=’tÌÐÔ%Îln¶b–Š†æ˜¦Àé˜JÞ(BwyÉ.ÅBjܘx†HÃQ•TÊ8¦4c#6Å|mñd@ñ˜#%†ŠÒ奉c‹6PºËÈaFĈ`Ÿ]ÿw&ÅççqÕ2ü2GµÐQˆ¯ŠÛš1R^+¦¯LZ¾•yïÛn@m2(ʼn£-eFK`²(euDÕ 8IwN`;ª–4,œ:$VbV66ÄPEBD 2ÙN—ßYö;üó6é}rÛ=ùk²#6_³S0¢³*¸‰B¬¥yÔy¥,ôS°X¾.‡9€¶¤Ëuª‘ë@+ë#%)|ðÆÔÔ@zæX"% F #%Às´õ‹&Á;Æzüiûç|ú¶&í•Ÿïö툝0t 6‚5à1”L Þ=Ùôãõ¹H 9ív ¥RÜð¿4‡Þ{m›ÇnpíÔ+ãÍ=ŒSº!tî#6oÅgcì—tn€…™©t,–Ülu„VFƔ±#.Ù%Æ·©ƒ_NÃÕsËÏù*\¶µ8r&Aö„²ÕÚ¨N6˜‘÷KY¾#¥ö’ZԟŽÌì:‚w¬9§ƒUf ‰Þj  Íñ0“ÀF•‡+IŽuœ,—<H¿ý…ÍF;ù]õ½ =ci?kÓ]w›©XNړÃC$#."oáo”+wÖÓý6Ì<ärÿ‡gŽ·²ln{²ïé£ú/ä#%Ưۡ¬Ï‰”ªÜåŒô¥ázY].Lè®k¥èÐkš#.Ï·…g/!­¡5ªJ ±R%KA¾Ç³8Ávœk#.î#ƒßxÄEûÈ¿•÷þÎȕÚìv`‡‡ÁÕåEjÜ¡ˆøØ¢Öˆö%ˆ#d¶{äs1܁“‚QãËðÓø—É­Ïe·­’&¸r¦¶Äj¡ýÓ;• ¤5wÙ1#.Ä)r­Á·÷ íÌiò/:'D\ÿl–Ì€m#.¦2!Š1Mäñ&¬ˆ¬ƒF)š˜èdXUK¤@md”2,ÈtëE„4'ÖFÁ°5’‘F:Ep[̐ÙRMÔ0õoïº5"H­J)#.’í¤#6)$Õ¤o.؅)ڊ"0Ñ¥bÈèQ„Ѹ&bÄÌ´‰cˆu·^†ØŒj5 ÔF=3#. M‰ C˜]˜o/Õïâ÷~ÞaƄDbšÃ'™¢Y鱂‡˜ÍCB&g×LF[o×QLi ‚†•Â4ŽòìÏ˃GdÛ78¬Hý]Ñãˆg(q5ÆL¯;•ÆÎEêRiü\©Dyb9iȦaš<µL£Õö½w±Í£ÅBM"1¸È¥—Yi]Ã\†¶…‚Ýb»/•Ì]Nç†úsé Ç p#f①›Œz܈òëÑFß‰Ä å .¡‚IÛµË#.oQævyيxq=L”°¤XÁMÀ7E+_î9x:ãOƒF#äøT`¡’œÜ³µq›„ùCåÊjm·}#6±;¤½d‘JHµ!MSxžLÍÁÁ­ˆàé#6\³•*"ÿ©©eã‡;ߎÏxý#.–q#Ö§i¸>NcUGEæÿÏ^ۤɎà˜4ó$„Á;>)͙n$"˃ýȵ7æ͖Ѡ÷šÈÙf1¡ýê(v Ž h«éC5ל`ò ã{Ô R#ƒ7(HTZ'ÖcJ­:7 Zf6NGÌQä8@ª‘sIÊۤ܎jì’Ú#%;qŒÂnwj٘Q±¡3¿Áaªê©i·Š(Vj¡Š(bõëVðÖ\ÓâM´0kD>§¶U‰„zpNzb#.ý:ë8á“âJï}ŸC•ñ•Ov(ÀäOË ¦Ãÿ¡˜6ˆ8H^&ì×¥±Ó³?òtÇy™ë°#%#ûý¶¼·6é³]Vâ¡3‰ée›Á×GY`IÁ´Ú·%®Š ¼ï| HsϺš˜ÛE“H:u™Å) ²,Fj0ËsVºY#W6é­щ(4ÐÅ"´4Yˆ„aŒdtªÙ#6‚#}´‹Ü¶`Ø5ŒMõøf¤ëÀºfmj Î(#.árµ¯ VŸ¢¿í;'\ãS—´)=ǸöòÒ#%'܀”#%›½ƒzÜ\‹n@|Ê¼îmÛ¿6ôÙ ²êö¶¾7Ç¿ eÊçó)vaÒ¡ÃHF‚Á‰ XÏÛwêÖ?!¿òџŸ©›Ââýj—̞x‹OuƒÖwð4r }ðÛãæáŸ7>ñ§Æ(8Ñ_Ì]`#÷˜úv#%ƒHÑ=©“UŠ°Q0…þrm¾H%x‘; Öõ‹™ý¹….?½VI|gxûœˆq¨[$›î}PT=]‘#6 Lk+ƒì ™•Ïãý¯²K»d9r_ Ÿ¹bD³åAˆÍÝðü(òìù· #6#føåðÝÿ¯c»ì²BŒÜÖÝÕÏtê~jðêêçßlúü3~i»Ónˆn>ûy¾{çñ~ùë]—‹ Þn¨`"1€Ø{ô°õ¯ƒ©Y.HGs$‘å<šÆë½\GŸ<ŸDºáëߧ=~ÏÕþÓCrqy!áã^H³U$ÅÕ2Änà cèúÔb3AÙîù½ùa.ÁGc@õ¼#6\Q\RÒ9¼ôUäÎ)u”Û¯ëqV RVÜ°¶·úûJ#%Gh¡ïÿÒ#%f—÷,ÛQ¾ß·èøvKx#% œè¡”#6€”»—wE·B¸cÖáÄîâ§Ï—¹øj<}Åz¤4:C폝Öï÷7¥d€B‹b3Ôíh"™µ%“D˜€Í•,J/Îã14i±Wö ÑÛv¢e»véRŒIKûR…IXñ¥·õ‹jý_È^Ö„ÒVÅ&.Ìýü²Ü2SQui¶ø]ˆ!C†û^~7²^4snë«u*䔩󫺱5øuåw?çÔÕû%`¢åÑ©ÉãüjRD>=>ÿòu>œi>ÊÊ:##69dc|›ŒVþé­nmü/®ž~çú•´J:3#Þ'$!éþÝPY]oR®ˆm½$­òZ¯&Ö¯SQUQF@ö#Ûá aøè}ΑÙCui±œb)f¢y&¨ƒŠ•D éƒ*þn&NSìÓ°%ö$¨áTò¹^%\…™ýÖwbIlI{VTe—ùä§îjŋçƒÞ•¥Ô:±…Ø1†’µ&óWR÷ñþÑùùÜ>2…ÿ#.#ú6q4¿~¿•ù·X30~>êí{P?œëF(¢,Ö>_#6à3~ž‘­Úˆ#6 0\îr›fžÁ«#6C õÃü j1T,jƒ¥q¾#6Û6Od'@h'Á¤¢$„K“ð²åª¯1¶ œ ½šô† ±ùː=rÿˆ2·æðWÕPŌùw©1P°æ(óډùPŸ™´†îΔVåRh!0ÁV“ñJ@-I[ú¤\T(–#6N=>$oŠ¿ƒïŸ-#ëüþoÌ}÷~?©¿SÄ>áŸçú}+ãä™SÖyà-[O¯?8Ñ[úF©î»ÏDÐÏcÒÿ½tz/Œƒº~˜ùÓïá7|çé6`¶œ¹‚ð‡ÍVúö«Ãñ˹G8©ç°híýqpä"#.ó$`{z—EÂêVsãbÆG˜¹ÄL¯“<„OeпõIGá=}}›’ô,k±Þá<öv}²#.¹—iÒå•ýº{ã¶+¦p±ß³0éý¹@ÒÍîÎÃ{¶uÁ#uwDa n'ª@ÆpTÏÝc#æP”OR˜1ß@y÷^¥ïPÊí8jßeÖÑnvµåô¸aËA¸cüU&dã#6V]#ÛêG²S "‡ Í÷ÙKÎw-ÃÑ4¾Pdé9ïÏåp.Q¯„Ÿ~9r—a#.xR^ö s›eH»q(â>ƒýºë9ÕÜ{Ϭý°±øï½áäÞQEV§ì±p2”/Xu|¶]æ¢c=!U%äi?Cù… CØcX¦ËìÆýýøPRv²Ä…¥24q`Þam;“ÿƒ ŸÕÛ¾×Î_\P Wë¾ëÝ2ÒÓÄ«>îþ ë¤îº~š¤>¶–=TM@òjj*©¢³ÒB''%=-–uûûHkû8ܪpÿXŽËؼ‡¡&>]°CÒp}!é8‘BvþZ>Ö-øÛ꘶*äĄǸ„$M®pƒ9@øI‡Hg­2q#.SýuFfŸÑýÿ›3ñyXx{Pî-ô2Ñ°oõIöO¶ž–$˜¬'ѿƊâ4ÊјŠÂCcíÔÓ×å óí5±y¿oœü|zÚ1QÈøÎóK,,$o_»Cd œÌˆbWά¯Ÿ–¥éŠÕ áZ¿V3XÀŸÓÐôüŠ¹CŠE.}•<åÔt֚žv¹W‹:ìN#K»aÝÙ<ïíáËXÿZ0þ:4°4n'ô)¿©cç£*(ÑZ1F © ûÍIpŒ[Å ]E}¹ýæ™æz½Ô‰ˆÈ‡@x#Muaͧøô÷{»þyú¾ošÓé6låÕTÏG7°èôÓ6”Õò}Y]ûü¤~zú›)ùí`¯]š$Ƃ–×=ù\¹µYÖïS"Ëàîý­ßê#õoÛ}¶?=º;~Îícvφ\·X!kÊôCÍ~8ED´Õí«ù¿]mRáã>^Õçá&÷_#68êpboח›;ëvدµZSqŽ§iûöÇ÷oöjíôgËÈm‡ysrËG÷t{œvǃƒh²à¢á`×æÒúôÏG7…m óSžÜpa»£:H~ êþRöÄj9\RAï·î~^ÌîéçÇ]%=†"Ëù™é»‡íxâ¦É hæ^†LG’ëe#.·s-”ëÝя3Ú÷ٍ̝êÏæ|Û%”n³¬|ðjãWuzµ}F×pé̜°çþS¶1†š¶¯‘ãLSèyµìÑ­}˜í{ù`-¼-§z9Ðó%[¶5¡v»º½2Î;§'D‹?/Ã?À؃}öÛfª]wT¸(9=E)#.]ÙYY‰xôpaòÆÁ¿E3Æ£Ü0¹ÏѼF%Ì.lAÀ>2.sºUÍ?¯Öç½FŽ6e2w?.ì·Å¿–=ÛüÇn¢n–;å"^¯Nù]¦ëûi=Ü[ºó´<Js‘CÆÉÝác!»…-9ý6GŸ£M\RD‡8½;ä¬Dèà¨Xhÿk¬1ÛÝîöj|G#àef®zu?|{?ˆb죩]÷<qáó„Ø2óyúW»î4öùüãØì˜sfö_IÄdaÀíÔ2²#푷Ù#.ˆªú«¾û+ôçñé¾ÎïÒ-«alÙÞ¿(Œô/£#.lŸ<tìß+{t¤3.—üÂó/°Ú 2´@ÎôcL|>y8bºwc|{a²rÜÞÁÐ#šŸgŽwùv[…qýª$R¿S›ú>]ÚwæÿÔtf¶³×֞Oåð{£<î¾ßÇKjØtcú ®ê]·yïìDZ¡¯Ú’ÿ°Ëà” F«àËÕ¤pøzŽì¡Aó:Ð}Ù"¼p+ˆQՇ“ß_«ÐÃ^‰/±m&­îù<‡7;›(|]o”ÎÇO%~Wû™ß2lSœ–7µ|r¯ýæ†ï»,èá†vENJÞá^[#=6{}ŸÂ¶uýŽm™`žóùÌ~ÃýîÑ۟]nåÌ)ÖÿîËÕè¯m¶ÿ£Ïª£ò©#6ù¿GFqŸÂ^FÌÒìò7ðü4µ?w·ö¡(?1œ½è„ŒŒ®ßçõ`¶úO·¯¯Ûï)ÍÓ["†ï ƎH#%õ"ÕËÆÐ2Æ P~kZ#%RE¦)#%éŒ:³»“ÿ£O2ƒŸìô„ý½£•<Ý~¯ÏüsŸ?·åõuåÚ%÷‹›WwPì»4ô¿IÛø×~÷%IôiӝtêüÚoæòšº³¢qüµiAŸ£ªÇçÃ@ïîøgÕÓùj¸aõv{À>ÑÀu.Þ?üB…Í´t¶¿®gºç*¯õhÛDAþ óSö䓈yGÇbeÎ>Í_ÝøþÌ)Ón¢¹8h¾>#.[¿g®øÔjý ¿º;¾œœ0v½=†áÑ›Éñ¯Ÿìá¡>1û4Šðx÷ gP#÷h÷óñÙÀpý_Yõ¥©Ü;ü|PåVˆQó•ñ=€ê?~‡u±ßåmAì#6`¿Ç™«–+¿÷¶ÔºÇ%ð#.ý‰Ã“ ¬óS³÷wt÷/vÎná#Ͷ?!b¿ƒpv ùlîâ¹ù;òžê̙/Ð|S¶ž9¢ ãþ?» "(H;G¾÷*Œt<&/»éֆûçë’GK÷Dj`’à–õç9K#%#61ÜT'&D¯žñª¤½Œ[-2è+˜`†IBfH&ùڒ~;†A΋wù´Åð8,†È¿{#Y^‰ýÙátÁôM ώý®7Ü}·»,°§EÜÜpà…#.±J‘ÔÁ€ÐúìŽR#ÕÃîá4¶LÜhâ+µw».©™À’Xê%äqh– !ô¦ÏÇ~žIèù}A7Œ®«wèüº!À²h;ÐÁà· -˜>ðÐB)Ø ¼³»¥J҈®ǁ“>;ÚëZÁZ;ž|%9µdC–PSx½óƒsZËËgDås£wr×+)°±¶1/1B+SéÏkÍÞ<k«ïQ}=:ÕѧBxóÃ&ýÇï"÷´¹8KÎ.óÉÞiYÉê¤kÍÍê” BI×eŸWRÍ “÷zž4åµ%fˆjŽ|x¥¹‚ê΃0Ϩ]¸RÃbo£<±Ã<âñrgóa^獣Ǽ;y-¾çYð‰&aÈI$¤í"…:¶¾ 8w”Ôu—™²æ\ËÆv³i¯ožM°Õ¥ž„|Yïæ1xÑÀ{]°‚2Çã×^—þa»›Pëø-zםã¾4-‘]»l¥_3T¿˜*|õ„)8óÌõ:„aΓÉ>·_!†(£«F€+~›4sgì¶W×M«°ìÆç/Ïö´©ݎ߶£Ní3¡hžl‰“3û‹Ý-ÌØm=O‹£Ûóp>Ø#&þQ¬½0â/Sß3 þ>mM©‡ñw“÷ì\•ý\} ÿ“—$Ùwü÷y¡ÔR‰$ìØú|¡ô_ÓIØÈDí'¶1ulu³LׄãÏú[=8á'x¿ƒôúè3ú†A¼#%Éé/SØC¡I%yb1ÖFÉ¥Góü™*”å˜bG‹ÑºüCª öIO4|žÿHï½c ÀøòŽ»ÚcY|uŠ·‹>Sþÿ—æ#`ó²{ÑÊÌáþBÔfe̍©cv²Á¨9G…?G¥F5¨4iTlTŽ Ô¢¥n؀Ðæ7#6ªÒƒÀ¢¢,tþÍڛHÁ¶¸}=3†´Ö¤On `˜a´ŽÅ-ŽÀ¦°Aȱ¬a¦ILA«"hhn„)"–4±[VWŒc€ì'Ë#.Ss¬6ÐÚ]&6)":ýº[ÅÖ¡É \’6ö‹B{qZ8dÚu‰ýÿ¶ø[Ñã"?›9ÌgBPP}‡¨üÖÊS<¦³ =a‹5þrÐÍAÉ]E··cˆXw\Š1´™ac0]WëøoýOSø\ýV恜#¯#±E4DCÄHèé@ŒÖbï¡i7¨1lXT¥Q&FÈCV ±6ƛf’J¤ƒÿj*P´Y¶Oà9þ¬éšq·ß›åñãrÌӛܙïëûpì—A¾öFþތi|œ-'Ôl³D±€œçj·UuwåËu¾_…ãŸÉfºòöWV¯Ùãõlò:­ŸŸëôeñÖ1ýèæÕ»ê(¦áLS·ñþ>ܬù±ý9Hþÿ<ƒ·ˆjÄU±Ýmù}Z bçvù–U²«&¸ê²·ü³×†íú¡[GmC……fŸj#6#Ò$pçwÔ]uGÜ<Ý~ßÓø¯Ó§Ù£O«¸¢Z„xûþ#%8g#65U6ü;ܶ>®aL~ØY¿w?VPèÁwÙu~Uwö¹\ç3Ü®“šÀÂÐÃÉÑkøÿ.¬&5)n—|?±½¿>¯&¿án®nàM>äM¹¬ý“ûôwL[% û"ûBßæ<ëά#6)_@è¸à\S¼|8¿ÁéÎØÄћ^F+rEµh‘[J%c§l”õX*5¢gtõu¼^´yçœÛÆ9ÍfRÉ¢((Œ©[\0°Ä£#6’ œÙiéÈ¢ Ôch¥b…€È£°µÂÂ44W VR²ÙÿÒ£FÁ÷R­\æŒmFAKT­Q eBÑlB†#.°Q’ ƒtêMæîy3‘wä%r(*`¥2ƒshفÀXœ;Ýg6®¶JhÇTChÆ%™ 8Ì+:ª-!ñiÜtu,¥µÌà’‡#.óÅ!ÚÐ@AFšþ§YÙ¬†žuD³Žmé¾#.äQ¡±‰‹$I•8‰ì ~UÒI‘#ü,D¢Ö–%\ȪrF‚(3š*ˆÂ®Ôʌp#®²R1Œlž°b¹ÓòJ®x3¸ø!U†$‚’IsJCÙõC‹ID&é½’ôAŒô;/ôôÆNô˜}€Ë ´íäë-ûLH ¬^Þ@ u3ÇD>Õ÷z“´ö#.QùUôhÉz°÷ý”OT=¾÷góxáˆ$g±S—óPü-ΊÃáÉj»#6ý£×£ŸLPL*ø–ý§f¶£Ô§ü!½ëÉ3§F9–û§ùj~¸îîh¨xÊìƒÍcÔºåøËãïÏ›""'NõOU87«6« üVûú„ÖY´¹ÄÞÏÇñ}NO#ûjÒõ@Tõ¹€â9Øs ‘•ûÊvA#%_œï†${Ó«”ÔŽVì6TÖÙõ¯’=óø~ç–{àäm·l’_/ÊÙµÇÒBÐ’č–'Ÿp€âqCó9ˋè‡æ÷¯!üyI£×<³ì©«.V|¾ŸÇÕ!‰æª£#6u¬êyÄC¸î'·>Åþ¹õüܯ±­öÝAe;6LèǨ4«9ÎCH¡QH2t2˜wT9"+1r_uLUv¹ä“h—ì¯F¬ÿÂÅꑀwf\„F±>ž™[î÷QâZ%T»…#6ÏÕ¬ªŠÿM[hÅe”£$#ˆÜ‚±#.D¿ºÅlÅ˦ómòØʊŠB‚YQYCFF¶Ï7®_ËäÇÝã³áê_{HUuí;wùüÿ§OɓA󭬺!BAT‹‚1ž­sa虑sÊ,¿] WÚh&6p¦41-6—·n›ÑHÚ)¬1=j ±o\ËA„y©Y¦=Zﶊ°Ì#6Ô«ÉgAèpE30ËBƒH¨Á‰”V¢À*ø¹¢hâÒñ/mˆŒM}RdCÝ7ˆÌy#6Ú´s¶jdßå$ – 8ÛAmb{€„&‚ãì͆¬o*ž ©H¥›·86AUƒ„Œ‹³àrYb‘ÍZ¨¬ÛÕ§hCZ­¸Æۅ‘2SS­DÍ#.H#6J lXdL1aˆ4KDã#.­‹G‚í3³u#.Ðá1¶“­¡×l°lôÝX Ê-“m(Uz§ûÿñhɐäŽø1†µ—š(UX¬0âؔ©DƒlópÈ#.Ìi@¢OlƒÂÕ·åtS¼'Þ30<sÁ„l˜Pt⢲oŸ»ø¿“Õæ#6” !B#6‚-ê»o.O‹„6öÚº<AÿlqgºŠØÏwìèõfñf4ÙËÆbýÖ}æSuƒT0Ÿ‰’‡44V\áÿwáîÞ:ŸÙìÛé{yзc•(ž~Qïɨ<Þ O û‡Š¹ñÓͫчJt‚zAíÜ'ku#%ùšÇ"#,,‚6űaiUSõÒªˆ4ã÷]áv,ÄDjGH¸¸ÂðâҌi§O®|´°Ud—N¤G#"DÔÂfýV5[ÒDê*#.m4&’Wç§(¡ßÅÆ_ˆt5³…‡¥ˆ3MéСÅA!ðy½ÀÐ’ÑK¥¢#.Tˆ£¡·ÆóÌU:¼]*«EPˆT巗ôùdì×k»¤kmó0¦T¨J 5Ël$2~ßØ?sÏêê¿g¯Ì:?.\`<<øâ@»6žñ™>\G¯øøJ½µ`CT<ʤ2+r‚i÷MŸ„š -+A‘¸·Tc£´øìz^Ƕò—ÅG=Úæ4R뫏Ùî65ÚaŽtHNjµ0 óF‡ÞG[q·º¨ÊN𮋳 þü¥Å Ÿ™ˆ¶<ª¢‘¨6ӈ®Ç!#6^¹"XÞ<(²ÀМk]o3ÆÌÀãH›5KœK¸´pLÊ,°¡+&°,”ʁp#.#Za¿*V>#%ÐÎýhÂ8p™˜Í†K§9æe¼‹õ².l‘m¬8ÁV6>d4#±C§›à­¶——ÔAܺÉ&Fèé ᦠ¦€¬ÒKbíV4˜Î Ø=ÕÝ ¸Døn$DN÷»A£Pӌ+gb†X̑Œ®çFPá2-îc¶+Pƒ¥ò)2ÉÂ2™+ç*³v»ö—w?Ãzwò_Ûü9ô[ߙ£oƒ×ûiþnþAý— èyÔÆÓýb'j¼ç3Xtß1ám¦,¼3êtäzÉù~îìa#.6uqöMۉó¦q9°gì,ªÄÊ;÷ Á͝S¹(v-ª ­ù`kb—ô»­6ßV۾ϱ£)‹`åÈf=NÜRäòAUHtF¨ÚE’ëž1’œÕOSxWxe¶ãjh¨ˆô©Siyiºf6äܑR®©n1v6«D˜E¼ Œqì’T'wÜπ.›gÊh#i™£^ÞM¼h½óé¶3`ìQ±q’&Úri3haԔ9†ÙÆbX±AO}`PwÍUí«3Û¡~ÕoÒ_ÇúFŚ°¤<N=¦,Ü9}Ð'pø”F_smŒÕA—#6#.¬:M³±¸Œ-µÉ°àzÌ! 1IË(Dâ8ìMpî@Î¤2ìl+ñ"V½†Üq·ž*t;$î§iœŽ¨Åo›;n3†Ù†-όu#.põQ…boyN×?u°ƒL…#.¹}#.IŽƒM¤$Á„ x¶ï‹)—Ï®v¼îю±­nú¼…Ë@:kï¯#.K¨iccndë‹ÔªÞAåj«[ɕP]ÃK©)pU7ŽUØ"wW;´Ç ƒˆÁ’ß’ÛÄ!ÜÔr7 •JQoùŲmÛZé\¨ÂIA­Æ†àˆQÞ#6:26#.Š]î;ñ´ïC®â¶£¨ë³º ¬›ÌK%c¸Tnq°QÍ峺mñÙºâã!X ÷Ðk¶Ö·ÚåÇF=ˤV¬v„NŒSuÕÑÆs'&vl©”4µrÍb< vj—N›19ÆbÉÃ"°Ë0NrcZ6ŒßW$œãdŠB\Ü֊ëwl #6Ó¨cÇ.Ûldå¤É6µ&†Dm<͎c/³Ür±±5ߠՁoÓ:ٛD$âoµ}䫂ÅÇy溽<¸üþY·íhՊ@óμžKaNâÒW•GiÝ/_³ym§,­qGr0÷GÂܜFŒDdªõç›V׆¾†’¿òÜdIÄäF6$ˆ«,Ÿ©…5·\m4üŠb-ßöÐTM^í¶"R§".f哽ÿ¾ºáwu…œ¹RM|an‰¸ê!Ô¥•“ÄAl©·KÆ<F–°´‘¼)ÁF§P6ø¤,½¬-®eß4ð¡“RàoNYyÉ\#6wæïÆ·¶¨Å€ÎînŠ,ÿ…ÒÛ§Gt•ïŸJ“L˜L™ kÞ8!ÉLº÷m?oõxtîåöÅa^øñ×4@üÃe¥ŠnÓ8¹búÇUÖµÕim;'Âyƒhz7,íÎ+¿‘öÉ«þÇyDCá÷˜šT–ToƒÁ89I°šY¾ç´<„ß\±`%dn½;,ù²BÂå68ãu6«7“Ž'}ÆôÛ^÷–YtNÃWdÓ;=ä/fRͲºòc p®FiùUóískˆ[áü3¦†¯²ŠŸ77И{¬1F.™LÍÔ4éç¤<³§n#%·SœáGFӃ9“fài©CÓzÒ¯,6õbi#6‹aÝì®îÊómàò7ù¾ÅÚOf#.5Í`ùfz×¥q„aôËÊǵ¦ô»u× [AŒ(g×zÿ”dÅGߨrt‡5:Ú'à®üc´vP¢¨$‹ÞìÛ³­Fáàtx‚‘Ãù]L@¢Ùù›¨öVA¬^–yw†17sŽGqì€Aك™ÉdfÒÒ_—Ä£¯Ãó7n·hÓ'²8u,Ü.¤ñyƒ¿0t¾óO`šD…Tò#6 3 ɤ@ºÃjúP3‚<#.þ”‹‘FRØ/(?€7óGŠá:ix¤ú{¹D€ç#%²yþ¼#âôØž¢€8‹=lè{ý}å¥r¸¸éñ¾Šáç\́ï>’ï ø2Ý䀹ÐiߥþCÒKíWnר>áüpbx_9³å¬×WΎ@žTÛBðъZ·¼B얔b>ß_§çcOVz|ymx#6fǼYJ˜…²-™Ê  0#6@ŸŠwßwvOóÓ®ËÒëÎ!‘Þöƒ‚xnpŒF€°Q¨#%Š²ÝjŠ«ÀÎÇ·e#1T˜´ËRV¡Ö1(3‡È40° cpç¯T‡ô沪ÎA›œÏ¨9zâ"3áłNÇíí<·¹“ycМr—v>óZªQà:¹ý탂%ÖД~ND|²EÊÉ´à÷Ô%¸< &فÚq4öÁ …)UyøèÌùÿ_ó–Æu«޼?ßàzg nõ¼;qËô;剚ރ†Ò„&LÅSå1ºúeÃyg²)IVì–\—.B„m0J°þ’[qƒkdÅ°ó#´-©`®Rb]­8ð3ŠÏcÝÇÊûO¥Ÿ]ÝB“$ÄKÁÇ|\Àț|jÌÅg}'ò$j­•a±áêȵ¿<4Æ=6=&¹|§‹ð»®6…]ºÔOvé¸pX»Ü=ôTŸÖV*yumžì…+¾â1e¼#µöÚgDtž,DãFQiwqlޟäÀþµ#.س^O¢ƒàô.­é¤îÝϪ’‡-ÇIÐ÷]ÔAõõ…îÆQ72„I8€ïxL’joLk.ˎˆ¢MDz=ýtï&½ó:oŸ$48;!Cªpóa}j‹ bݛ94gÖ|«¯3­ß½›µ4#.ÒOè%èÛԍءñ­–ÓÞ:Î<4ÅôE#.54òì3R‘¬úTW-Çðk¥³øyçÈcUéN-<#.'çik“é;!:-DŒ¤§ 7)%#.M;î·$®ƒÂ÷h.ؖCpíJi“˜5Ðéï¬Zñ™9þ®ß#%ÿ‡7±CðÉêpC ‚Ï#ò‰Á´ð ü¹“ßrÞÓ¬Grɧ嶖“9¶šE„“J¥™Í•aՅë¶ú`xf¤-0è´%ùk‚ö2#Ž¼üx#.|^š:+Њ „ÒÉù­Ì۝S9lVŠo•azâ3!m ²<…¦y©CÞo{vþ|eŽûüÿdQ茌¶F÷T½Ä½Ïá~;¬wÚjl .r<0XîÍ1`àžœ1ß¹iê1æйºKj„¶Ó§\ž¾¯‡å;åd“ý|†:ó»OeÑ¡ÌìÉâcs§ãò²Íc↛Zøô<«LÁ“QÖE-¿”Æa H •àòµ0·Nõ3\JܘrSs t UýÒ>\}[ˆìäåúžŽÞc‡ríàXZ.ê,¥¯Ô#Ώfi?ú'î¤è—DÁµÊŠ©æÔ÷½`£Ñ@ˆ¨úã´#6ˆoÍÇ~ÏhÊ0*Ü×ã:Ö hïÿKC¼i´Î|½_ðÍÓÃ_.¼71¼§½Âu"˜¹r—Fxô⠘Šç#LþÒ¹Æky™—óé“>Q†9¬€Àȳ÷›#%hÍÊÈ(²…Ÿ¨ˆž+fLmìßãh”}ƒãÄuڎŽBN[ëR fJé{ 2ñªA·Pjפ/ñt那YÚÚ$ùyPñŽÖ–øêú뢕‹@…)Õ§)O”~U$BO3âud¾‰Û1/5¿<’k«æ‡U«xd›í¬½ìu¶ø¦ta>y6œ­¡™û5œÍNîQáp­NHèºeò¸è>–·D.•÷*EdÌn2,Y—(迃f—ñ/¥sµÒ› ñ˜D‰µÒ‹Óô’Ìؗ›Ð¦wN—¯®ÖIóíîç#.¤PBbÛV¦u]í‡Un=Eœl㋷ï¿>JªE·":ǔ̝[~ÊڋÄ&ÂOš¨ÁÄ­)ƒ%&UrfIJNgq¾aCF¦p—zP‡™†vß·SC…:l#ƒ:=ɪ/¢6<ç0DU­¼F9‘Š¦îÅR3–}m¡ð6‚£y)¤8Õáà7Õ¿QúÜñeìî#$†ã\¦Æ§ò^q1®J=f3£ÕÍkÆÝ$·LùÎã{ˆ–¦Ö=Jì‹mŸ&@׆vµÑ|^m÷"Xî<ºãcèšQՐ¨ŠR„­HyrÕòá#6̪\hlæτ„#6Qɺ*h9·¹Œ52g(eG=¦!ƒB-½FäÈ= *\¨½[=Ù4³ʅܧIm¯ƒÐŠã¹Fo%ë*œ¡açgþsé7s”¾›ð¤ß>­üç:¶è$qCñntl ûÜŒ=³D”OåùÅ@à}Äýó;Â_+'ç» EFžÍǐD_½@Ê´Î/HÌ(¹%“üñãÖۏ~!ÞʨÁõsÉMžªG4E8ŸˆyKåÒØڄ¾ôc6Ãä´ÜàÎû6vâv¥l½Ë#.‡g“t>";¢ïm¼Ùu¼,ÉvõutÁ=;2hä!0ßH¿(âލ}´s^G ap%N=¬c¥çµQ»<dZf˜ÛêïÞWˆå—=¾ïy±[g|̉¥“ÿi¼å¤2ÖÉüLøÅ7Š¯#.¿n˜ßF0‰r ðI8T­Ý̌­·6µD$‰M/#6oñ@üÑ ˜HÜ¡—ÈYe—V×ÛrÁ‘D¨ïDÔ_‰MºpàütC¯‹y°ý:Ç1_G’ ¦h.:üzÑÓ«‚“&~Ðbª ÒqëM—N6kՐmcí99º×ļkg‡X3s­S§¶‡–„ûtc˜¼/+ÍìF!ä÷øŸ†2xìåX?]¤BM#%èìùRÔöÁ3. s®)©³ù3F~~!­Ä i9þ×8ÁIütgHC©B³Ê @é›Fº×E¸éÆɁÔt ÎxêýbT{ÈIZkŽšÎŸér­Î[J(7ÕZÇפґ–é½¥“°ô4%ngW³U¡pÂ‰zÜƚ. D…c·Fó\Ïå¢ê ÑsT»f«ø†W#6­/á9=jÑ´S¹e‹EØàö¹ÑãÈB#%ÈX±u­ÏÊ֊¬N,&6#6B‹õ=p]ٝ#6fˆ§|:×D¹a­êF/þ¿©+6Í|Շ,2Ø'7;5mÌ©ÙÂû]Ü`x¿2°²kŒ\U_v‹¬X)æûêëò°,àµ{wï…ñYžÞ%åq\jµ|ßxèªÌÕ,`œRWn²Æ°øÙÍËM0º‰ <X5…U’Ûo6<-¨Ç)d^÷Ýb#%ûðçÚ°Šò”®[£±õ¾·>Iz]¸lð«°S·#6eŽh´³$'°´¬çíHf#6^Uî…Ѓt.‡.k„“¤ö#.п4âî6 zÛXÛPÅ¥½“\9šÛ1mðR´t­}yUQ¯}[;î¨Æûáožs„˜-÷À•<¤¦TvZ§•H¤sĕéïã寻Ë&?ÁߙÆf}ôèÁ>WÞ³ÅøÕO‡Ùwbe'½øëåÆqžçŒtÕÑ_I&5q¶–"æ¹Öçgõj2àE°™©£•½"*[WÕn¬2¾ëAá¦ÐM*’aFkmö0*áe"ë²°I@.µq|ž%hy±gt>›ûõGÌ0ÍxQ“¨ZQ]~¹„…LfÏ9ÖÑhjÀ’®“'»YžtX?PØçÜôTðQäj?¬½Èo]YQµfÐ[DÔ³áGçtP?ÒóèþØÎeϤ;ûmð÷\ã4•§á˜‘x§5¨íÍKèÒ@¥ÛY ü– —°¡•³([¥uã`£„"ñ%K ¢%b5j!®#TRé,Ы©’ªö`A¬5w,åu1ž…¶K#6¯uÌÍ+;¼òzÜÇEºâko¡.¦ùÕÏVÍ߇Ç>ëä(úXòV÷9Cg–­Œ ôuª<²w]ÇÞ7ÆðÛþë+™Þ#6–~J¢ÖÞož8Ð#!žõþ³PJ†#%)W&8Ø9¢/Îo7v°Ðv¸- õ 6âm¾Žæ¤C+«WA’z)zÄêéVµ{„Ñuå|NÉK›¦ҏ ¥tßËòܹÆ"‘½E¦/séÑWa›Æº\T:Ü©ÝÆðñ#%̹ÖovJ±$o¨e›@„¦ëtLE#.õ Há­Ð­’æxizÎ @pžßyƒŠ¦M>úgŒV0P´¡ã/ïÚWFŒê ªÆê°ÊgR0y¹ö\÷› Ü+nS×GJÊՖ^I¸ºY©}ªëÜ轄BÎYC™;-|ŽCÄDfVšsÖ#%Û5·\a?Æ ÖÖv•s>×_Òë5Fó¨÷ypfÝuÓʝ#-/Í\¿Tz>#»¸dq ÄËÍKÎ{e¿"ϽFòæŒÁ³Áµ@œ}#6#6pÂi†1šIc¯1Ž¡òª¯ ÇÃ|èŽIm'T\&IËlgµp/jº~?†5óÎvÝ ææܲÓ5‘bŒ7fÓnº™N3[al@}sم_ XƒFɝÆۄß'mÂ6)k4ïÞ',Ö #6֕KdÒUÅCÞ£¬ô#6F6¡H‰Dp¢JÊ÷ÖÚWS€“ä²R²sýÙí~ ¥axÆ«aázß5Ä7¾m.mí*E¨$ CAlæ¦BIm*øÒ¡ò˳5®Ø45ÖJ·jºï9}捞ÖÏxôHü5Z¸QŒ<Wž÷¾»N³VDÕhU¡|ãf+ÏÆ<é¹v „€^-~]ðBäA`Äæ‡n˜ð¬W…éÒô>·W«¯ê‚ñ‘B¢(PŽ%¶ÃD7K#..mØÎLjئ+Ô,#e3m{­wlˆ4º/}úî}¼ÎYðsEÞC9H2ƒ¶±ƒtflkA²´ÕM1‹C,áî…`âl„™Ø±„ëkù´OIiN•}¥áù#6nÆ#%ààÍA^†³(ÆÀl˜!Ê.±o7Bù[8fX»HíڀWzò2ÔÕså@ç¬É“¯ËjÎc¯oN=,qkóPxÙ¡ÀË·qÊX8~ =Þ¡O½íϒ‹Ó¯tÌqÁ8=þø´¼Âžûx–’ÔE†@é#%Åmp‰•‘ÀO˜NА’³Ïaj¬ ôe“³ÊÈT†I*ƒxzÊÔ¢ˆŽ4äãlûGüGþޏtОq͇¯5K¯ìëâì·VžÉxdÔÊ*Wž6—XËSm³¾‘$ðH/᦯°FŽì¤øS‰Ùà‚<?z̈GP-’;yZæOµD5Ë·gºë«iT ÖêœÏéÄ2 Á¿ryº~NKûôøÌGˆâkgÑêv|¿W痿êþÆú~xøL珲1«¨\8û}Ñ Ó®ŠÌW¯Î6—¼jS…;TǯOmæÜuW<ߍ±©38z†%~çrý·–›ÙÄ¢3̦ۤïàåq^˜—úðN¥gÑ'u±k//u65—>Q²{Æh‰e!wº(¦±Ïš]ºÈ—c!‡ïƒÂëOZÏ_…ÍÓy©1L6ðéšP¾·«>ºÃezÑa¦ö_j¸ï©~Z^¢iJ­áÝtQaè[›9ò-QÍïäzí$o“‰±ýL— ÷æsaÕHR1€ÒTÕ ×¡Áâè*aæu®|b¶ž‡µïææȳ…Ä“{Sê-p5cÞ§wsÕ_L›ÜÂG‚›ËÖôöû©åŽ¿¦àc}±Œ —«ûû5I³©jJ#fع¾”ÎM$rÂKLîg¡sß9a--Jɖ,°ã¾›õ½`¤Ç|ír]xä+n/ÑÖ՜ELm¹‡˜‰‰›Èb3ÍO]a­Ó(£ì!^\C᛽¦Õ-(r"„ÇFgRÒ¸nXم꣥ü1½„+/!“ÆšÃ6d#6P ÕdØIá‚ÇT”ÁHS{ÚÔbÿ3Ÿ1棆…N¬ù \¤ë€`- xŠf<Ž3·¡Ù#6  g î®Þ|Ûc$âSâ¹@ág"Ä ÀÝ:9Òà»Ý.mچ—¾|×[6âjžg5sÍ¢ðºàÙ½KÚ=WæˆÐ#%U)Aµý³MU7/”Îà³E³V¶û³õb>|ÔÔsDD°#6T2À¦y Áq¢Ð²#6èü¥ŸÒk1~6ñ,ŸÑå%Øâèûgû—K°¶ˆ"hÔi2KúŸ;e#6é f¼¬T¡ ÅX]Ó¦h”vÍÖ°NZPqîWP¦õáÐä²I¼|Æ ág¬í÷ži ㍢\ÒªÊaîa·Øé8ºibP» ”Jr¬ÑÑkLØ0óöÖë¢vÝ\ê£q!ö•ytŸØ :÷Ôܵo‚û<£gŒÏ=Éo6¼Iޏbì·låHÜCZýn±ù¯Ö7Fn²“žd»Ê¿_¦Ö„VM‚ü£cîƒ:v¹+F;³Ü¬)&#.M—'ÁÂ#.›Ë‚¯£¶Œb»ÀYÊw:$ƒ†±å½À=ë Z×û°' &hhmZžñX\Ë,€ÊŠÙ9CÆçò¤!9¹­0rÊÜ =ÞµmŒ©3¾¶[…ƒ¿ è‰ZÁW©TƒŒ·ÈÞÝ+(a 19ł‘Ìáë<¥Ñé搡ÜvÅF³Ôè©xñ‚è~ÅGÁB UU(;}ný½º¯œà•Þ¹™Áµzoô]4Œ‰B:ž­Ð=.®atÏ$³ôÒeJûœä™í` r=q`ÉiC J¿ç¼ø”D¡ùâÓÁ#.BY`œ‘åfYB¢òó¿Ay ±U /v¶ /—C—3¯¿±òÔ$¬sék:!ßr=®.ê«Y8=}«œ[SdІ*„¼¡÷M¹õ(œö´¯RԐ˜xÁ5&œ¾GԆ¢¨)´èÉÄp¼Ió{ ã™.xGtÆ¡žÿ',©iAxdÙt½×ôY»7ÓFšs<dçWÙÕÈߣlõúÅ`)N}Êè͙fK¸H™}öC¡ó"qÝQ†™/Džq×hÞ%Y“NuðùËûaØÓüf6¦­œ‘O}_+Ës$õÞ;œöçzìm$$L·LÑáz¯bòþø˞š*'%$i:tٙcŒ£yªâs‚–Qi':-'‰™·(Þ`„b6†<-‹ã8ž¨ó.£uÐé¶ïËmòÚ]{¿ÜÞg·j9 ¨ š^æJª'­ÎæÀo}҇¬ÑÐñD-‘‹W8g{Èm´“ˆqná†êkÏZ9æË9ò›ïŒù֍, CŒü`ÅNŒ`[£½Â™y#6Z=Ôs'´WïÏ'dë¤\¬ù¦¯ÇUÖ|MÛµÃъé{ùËzürE÷õn­tœwšæi­0²J:Ìñímã¢û åO äz㍉-¹|o)#XÔW·—>ÅÓÐs=o¼[DØЂ unÄ2¨æƒû‹`Ü1˜ÛNAö;ñoó$³¶‹›¸x‹<¡³EüqÊíêK‘­/–¬ÙߐbÐK¬„/aÑt÷h$&c„%n×çl#«'¬s¹â™(é­T¿·iاۤªËò¡^v*ø1Ö.)òFÅ<eZÝØxA)³NTÿ(ÃöAБ?”>?NŠá_§X#6ãûbo1QìÐb¼DzÞÒ¸Û¾nB¬htRߌM~Þ¹Ÿ¼çhæ>(â= 6º†6Mº1@ì|]½fÏ.×ös۞(õ::l¬züø³jîOÁk)¾pVzקk÷û±jÔ3pV×>IÎf¥$™Jý€?LV2e*¤Xpå¹³‹nžÈ(#2òY¸zk0Ö9êŸ<õ-w¨õ°u¡Íˆ¶lÂnIv(˜"`‘îTaŠÙߦ:b×däB®zí†GmÚå»#6õÈyh3儌³#.¡™Œæó‡vÏ=ýB´Ùîïj¸+8;å>N¼Ù8›dÃøݺÌu]:D£~·/Ò®*©z½pIs>•Ó¾Ä¶7¢ð¾ìæ|¡Ð.ÝC×o“ü<©Oz¬Û5*ôÚЌ}&E§xãъ»ó!½SbGeœžFI-ÉU#%¦$Ô³I Ù™lM,–01Œ*Fe`÷ S~S G>»2@×ã¾~ï3¬ ZÂË/ÒsÛ¤¸zµkÓÆ.xï|~ñÍ‘•D¤#%¼Û鮈u™¯ÍÐ*±§Z#.ßËn¾‹€P>¡…uxi¬ëÍÔ¨&„'a¼ S9—2)igkHÏíð|·¯`çÛÜ¡à‚iÖÉÛS{Æ`'Œ+æU<:êI,öæÙ7¿_ǍƒVñ5î‡O/Iú~!®ìàœZ§ºÜÁáÈR¸÷pùqyàì^Km›ž$?«ÿr¢­‡u“à;46CR;,VÒ¤èøu'Ž/•0Î?­í5¯{íÀ™iÎÚÞÜsü"Vîu¾ jOð3ˆýKÉOäýN“w™³ª¯ÂÛ¦/½6¨ .¡#6×X”rpÑoHì~!ÑRKz¹£%dn(è)!ëߞnȀr†lšÔˆ£§‹G’ÜŸ#D’ÎŽ¸N5›çþwP$È~žåtԟNBeåkµîM„ ‚ÏÙèn æ²1Â7_êÝóÞ¹¾?5õü;{Óº'àãÕøό¥¡{ùq(#%`@)ïõ(õ§áôáԊç°Ö9MvŽ#Õ(JL+G;I@À€ðèz¼xÔ¾(H)­æ„gëxTWÆ®òØ] —÷ào»ýEkù©\ë¹lIi?K¶Wò¨Ø”‹Rm“cÚ-«®¯ñþ5ù³Lˆ–ˆ…>­(2͛ÊþbFmp–ß‹gË~:×ô@ß4>$Ë_#p¼$’ ŠÅ"‘AƒY ä&©×‡™z½:œžÛ¬-&OŸÈÌySµgÎ]–ÜžlÈþÔÃfÁõ¤™^¥«Û¾÷ʓAo¼?“ñxüGŠ5‘ý7B÷ØH‡Ó\™ü¯íN9†1‚¤IY‘[Gtþ#%²©‚¨qHTi*7+¡þÜõÿ—‰Ëò?¯YC‹‰xþöaÏ(¾zÿ~[Ûá_Ú Ï]>Nt©"rNK(ö·ËçzÔöKíˆd¿»æïžðù´!ڇEá¹tî›V}ëªÚÃÞíèÝnCiü˜]÷ùY??ÎýŽ…ªz¯nÇN¶:*F`6$´t%5®Ææ󳃊\ª#%±|´ãÓ¹ƒþ1“ì?£¾í/ÒÊY¡°ê8KË,H|ñ“‰"~¯Ð©¡ýj!Š#.K©wk|Y ž™²äèYû=v&‚Sú7åí}f“›¥h¯P#6ªÌ·Š Ϩ:ý_Býš>¼•s<­7E‰a§VNKÎõú]›(ú¶ÅÆQØ/ð~¶w+E@âõL›0½Æ\üƒª"XÉBÌÜ!œ?_þG7‹L˜z߄çmßÂÇ>¯+e§m¿—Á÷¡Øf c(QƊ#6‹"šýu9¡Ñ#.P?KóO¹ êL¥09]#%n‡?Ÿøí®@¡/T¨#%ž½t xÎè†"RµœKš Tg¹‘L°ÇJæhZ‡\j ¨µ+r¼ Lt#Èæ"#%oŽŠ®¡òËÒ(~†—ª#%¾± ´é§ëãcßÁmÃfÿU#%èõ@ÝEôÿR ðºØŒÄŸxi¯Ðþ•ëôBañŠ¾`Ù8ú&ØH¨Ù6óòP¿Ÿˆ€XøcÚi®à†í´ ÇK™÷$qý4¹a‹ß-)Á>ÏN99¨“Õ‰5v8ñ:je`a"ÅeOXï2€ƒ~ƒZhCq‹ yžÏWiƺ(T¾¦Û¿ol|ïøH,ézþë–(`L$¼{ †9gÕWR|1€¿{՟¹Ýø™@Äyi<×ހÿ$ï è LJòS(ò‚ýäOgÏIëŽÕ¥OSIïô–õ#Ñzüco*(B¢Êvæý?Ít,¡xë©TÏ[]3«X(~Š¤ž©R”#6¥`UMKõ·;ã6Á¢(ܣ؊y·½?=Æ Ýа섀>Š©˜ aI\öñ}V$øÁ4º­2qÇ m¿Êe#.fqpÚi”ÌkZÔ·ü(b§RfÌ%ݵEÔR1#µ¤Ûp2„‚\4SywE9gŸ+ìôŸÐmÒü!Œô¯#À耠(&ë]Ì#%¹Öië…uQºâý:vêÙ®¨ÙJË5Iší4ôýn½2‘×m’pŒ­è«¡ön³DAñ|],ʈ‰[#6Øy`ïÄ#6€ŒPIµoßÕwÊîŽ,ßlN¹¬ç·Ü"‡c;þú†Y³:=Ÿ±Z&W¨å#6‚Çf½Y¦ÈÈ`¢ÃÏÅ3×8Ȋ7K±´-•T"EÃvÉFQ`¹Š\ÏP.Dp1C¯f¶Öoe¹_}g¶âúà«âc'‰ŸKš³’T¢©Ö¨`¢XD$¡›\æ#6P8ÌüøÀ·Ì£€¾ý—tb•ÓÎOIan0aÓ֐€LŠ bBç#.°‚ ¶ö]\ñ²òBET dØÇ(°so¾)g®Ñ à#.4FÌ·e¦`1ÜL`òyJœIÅG§³Â¥ô ï#?øYÖzKéÄ2 ÷#.ÍÔþ:·Ü7ÃߍüÕaÖNQżÿi˃2}}Jo£Èú¯.þ³ÊÍýÇÐïL_fs@ˆvô#6€Ä¥Í7–;Î_{ɞ‘Fy"]yXºmý~,@yÆNr+(kîØ®™ñ3zL;,Ÿ" 썼BN3$ü÷>åq6׿yðö]|'<@¶HZ°¦ „Ýè[ï*¹süÚÍæðX¤ßï”@¤U-0žàeœ‹{¶Ú3ÀÂӓƒíTÆií’7q¢‘I¼y»Î…—'íýVç?rÕëHƒŒõ!d=1#3tÿe–®ÎÝ~AN{º4N ¡úÓ‡× ‚I5Ù(åtD# øŒ uՙÜ`ÔQP+&֗á`KH³ZŒhð!É î¾ÉA ê(‘e<ýd’¼þ½eý÷ímÊ5^äÞ¢)?̸Úþñ皖6`éØÂàäâ{î£Æák¼dVԝ™2S„Ä;¬7ÊN¤@‘`wdÃ@à¢`s¤˜á59—_E·OR« _ªzŽq…›Ks^GlÞ<ЈŠ¹\¡±BÖ³žBdF&!Úë\[S®~zÞd'¼ˆ’¢$6›ÒÙ¢½ɟ6NX |¼¡AÀ(噘øïÃrã;XËq-î¨ùöˆÎrI{@Î{"{íLÕźÞœ“5y\ˆJ‹E㛏%9×!}ÞCøI(ès=>§X.~Xp^‰éó{ì¨k±âøa§Ë%–&⒒Ñþ„Ww,/òmì¥z¹€Nãõ‡5ǎ/mKŸ¦$jìá +ÓK6L²8ª~í1‚o'š\8¸`À-€ #!C<×® lˆá2ô×8ëṍÙXÃN¾eÌü®R«•b/!ö¥E7Â5ƒˆpdp«¬BÜqÖ;»8]c5 Ù½= L=«ô7#%í¾XžïÃ%3#6‰¥,4«ã¤"»¹¼±¦ÿò€uoŠ8‘KÔ<׬(¸§E¤;UZ ÙÃoXÍ:I¬‚ßMejyyBþBœT¥îú#6=‘q¨<ô,;¢ qÌ·¡Lá-á¨rjß~Ă=%³Š¿uû:RcŒ’x+#.ÃVe(Jź•¨ C°×¦m"¯ƒ‘1IÃÉ2*˜Ü¼ùÎÔ‡FÆ2­…?Ù0¨k˳ߔïÚ?Éðý\ðßCc£{ ž±¥õ‚>Ô儯p/UM†óè<g;e#6,Û¡¬…(àÆz¶bâJ ü¼¢‰®:…Öò7㠜lG1џát¸ù|±<ŸXÛ'M1çIñà /T½]‘)œÏo9ìð_Urb,ˆÝOèL{Sá_mTܶ§ã³ZY:Tú9°Ïo¿¥Áƚ‚³(u™l;g}šm@óߑ¿²YµCfMjdÕó<#.x³:O)ºm‘÷/·ú4@[Zô’; Š÷hÙ‹hhP ¯;wœìÁ҂Vñ¸¥_F”m¥?ºø2_P|M9Ü©|r]¼­½–ko {†<x–rÎdLf¡œ,z7±¿ßg>îPxÝ,lû5 =¹‡™ËJÔé{CTj‚Çh÷ñ•bìãšc°«¾DƒiÊî:L™$eR‹I¦ÆÚtî×ãÄtç)†¬ëÈߙ·žÜŽÑ~“tÔÆã‚Ãœç£#.p²†}wÍ)@))ë 2d¨…t‘`!. 3ØYbô(%œD®‡#%ûtdb#ŠÐ7B™Ê©—Ÿ'Ø«ÁYúcþõCµg›ï‰îé¬ÔMRaÿ2[þ4¤ ]g†bҕ»woÕNÝ«Ï,.1D¦•XËûØö¾ÛTÓ<’€5ÿ'ƒË.¸¿¢ª×?Øä*£b¯iöÅW-«cµ@UTÙ #%AýJÌ#%î? øó>ÝÚô¯á[íê{}¾¤aªô·ï«éE „aûÄEÃû(ÈõÍüώðÝøÉöý–Áä?²ÔðNšxè` ß·¥"lÆP Þ·G?`lû=Úø ®j¹Ë—\ॣ4ʤˆAàP(AÍ&…à¾Ê0Ax2E¼«¸Móˆr“¹Ù2I#6Q0’D%9èÀ÷¯0(^Cg~‚ÁەRT:F¯gŽw÷Ù}}v®‰ÄT$/d*>Q¾•4C´ãÝÞ¨¦ÙˆÇVÍT«Å„Kv#.ï­ÙÊ[Tú_‘üúl6q™½„ Ì:ÑAéé-‘¾ìE.ôñ x4‚à‘†ŽÎ2²#.±ñދ|Â¥ÀÿóääqÚ¡K¥Èj#Åìðý3˜© 2r·2¢ «êȚ#6Óù¬<7ÐêžY’Ö1֑$“â‚Íh>GÛTÌx~2‹ããéŸÊô@‰î*%Ô39h­þZš[ÃÏù`tgø·Ø’j«Úcü© Àïð÷Ãz¾ô! °,¹f°Ç­ٔèd"Ô@„2 v¨0é³k(!ïh[YÙR |"€h/ #.( ³(00Ýú¸ …˜Mm”°¶>˜+dʈ¦²’ÆDTKƒ¥ÊGE´@ˆÅ2†. ¨&c¯u…ù8 #a j¥6MIF›EÜ.–3+ˆ;bÁ–$K*˜Ù’”³T”HBn|4D3Š¿Á#6Ù½3¡ç$ú{•OôÙ«ÂÿHô³ €i"Q`UK‹È–…s;$>ª¾5ñÌP({èlpùÈ?)ã¨,ý¾r˜b"Zô§KA±Æ’;5Wژ øO´~‹Ë~ËýOî„Nâ¡{Zc#1¼¦Ìň…P'OäŠ)Ï­·ž±ŠÎ£¼M!+½E>÷TöƒÃßô9¶s¨ÎšÞ?— ä#%“`cnh?½öÝ+ŸBGG%om_}Žþ ¤M¼Q' ÀwG«ÏwE&h¢æÝnï%óªpmœÜ"&ñõëw&©$·)¢rÛu©í³Ùí«ûÉíööñp)\uÆUüdá{‘KãqÚÛ ãE¦é]RÎ*8#.ñ6lTxÌ2Œi†˜§DéÃL©Ýåj22JˑïuPݹš3Tj²‡©ÿ :§Å¦%tCAç0Û³ô=f[ŽªŠ®Û/0Mk­svLoTõw e1ð C¹{…ÉR‰â_qý“Zk‹ác>Õaü¬ûìfоáÜlJéæBBé€r'·;<[ŒKå€îñÛuïºä±f’È«%3J„a1b‘{Ûì=G\‹ULj#ERX城ncsÁÜr†sVÓmš;ÃX;MÆV Š]±#.Z²·›mÔ2$ †g-$F„ÄÆñ žLŠ%ð.ª_–L©§Ç6íßQSÔxݚ#.I»!¨œM#.”F×Ϫ‡MC€êvB¶ð#%æ! qŽI*™Øt‘§m­Œå´Æ¡t:CÖ\$×@0!ª†#6%ÀB‰eV‰7vd”‚À°ò®cÀAÖ©Fvt×FýeÐm6Û¨ëô_^qöÀ©3_éävjᙎ:¤ö7T%â#.aû ŸŽÈ3ÅÀã#’Dõ<d!'š=Ws=Ñ á"ƒ{Üð±ür3‚»xXããÑèL“#Ì{ë€FÅ0ñœ“¹<ït²'ö(v²¢Uº¥\±ªÞËs[%k·ÁÖU’ÖÅZåµsl›UÊ®’@ÁK¢¼›ªÆ!E T$UhÁ^³¢“eeÍq0Q›j„¹»6x©$ëÛAICt“×M4iÁ‚šŽ‘@ƒš\!£Ž{í!Êxtš®á™,ØècÄߓ³¡x ltH±h<û“yî̯wy£¥|®3¼¥ðìp§Õ+4 ðŸ‚)ÒIÍ ŒHŒ‚ÂE‘@;Ð4['H!³¡ljÁQÎ^58uä9^çSi|£E_¬ŠPE‹Üš4æÃixj’–Rd’F[ÏI)-|݇E#.ÉBœ–ÿJÖ¢}•÷Ø ˆ“ÊS0Ž+Ÿ–Zc8VêrØQ­„5†TQ¨[u-¶*£gu­ï«^2÷4¯yt£K»kvË_\h¼•G}þ÷{ÇÎNÍߨV I ’tU¯Ìb*ÂäÚ§’Œ‡VKðfá,#†œl ìÇ Žs·©¿®üwB1‹óQ”"¬ÝØ ÊN¿]S}|x×­?¿ç=,%xo:!ÀI*såÑoɋ1¬J:ò¤´¡eÒB Û#.#%,þ$÷ü9g»ŸnòyϨ7#%&êuÆ$3â6;ˆ7ØR71)™¥‡Tð$Ž¸¤¶§#6ø¹!ÅHTZaH $´"%;úQҬ߃(Z„©"²(M­PB0Ûˎw@NÕeóñÙ{]=Üd[»ÁrÈnÀÇVoÔR@<†‹$„D DÉG׶·-"+joaÖà eSUXò'Ò‚ˆòB‚«ÐÆ,ÚºK•Ô¸g¯/7vj»ºRK]#.Ìeâ+µžÿ‡|½xzª”p®ބERǓPiƒg>á,üPCª†Ä{Ɩò½˜½«XÜ©¦_=Þq¤¡A g6ОO¢¦‰_*’P!6E†3Ë87Xd]ä#6­æmóŽ±2M#%áF³™k#U@T¢yÂý3Ø›÷o#ÖÉÐÁfÞî,Ü ›;èΗm0T&â&4÷5I$ÂpŽº~¶4Æ1ržÍ/€‡ë›#6íÙj¼wüšXëËh:nx–fø|ñLJgXC§ÒPt/yҟ¿áìÍørŠ#6°\ÈÆØÍ(‰< UTȵ\[#%^™H#.}qš¨ÛVFX+1á÷D¨ûºÕÓ­Bà„#..”rªü‚˜m¾È½Í—¡—½Y]ŽZ† I„¸8ÓLÓA5À×ÏN·Ó0$ю–mÅ#6æ#.€Xõæa÷îÙâ.êôå“\ºH܎9T¥w_–¥v¢E”F`0HƒÊ¡E%xÜÂ+º¸öî2<õç<Œ-“#.áê}›ϤÛy£¶™ÙÜT[§Ï%)Ý7°40¶ãòâæÙO:§dXoY£t¢«º{{»õÆU;ªR %£D P–ÈÌ0ì¼Y3#%€Û*V ÃØq@iãAF®L`àîë´'©!ç#´ ÏAVì#º(®RÐBVcÙ3±EÊí’ a „›¶)ÙXª`_€žôɝ ­X¸h£Dì;£Ûe¼ô‰ŒŽ'¡Ž4QÁJ#6 Q`¹”(T"’@ çK¨ ®¬`²ÇînÆ´Ý ïZ:uY¹í©ŸÆtFýð›ìÂ-¢˜RTˆÐfµs™K>÷Bo¾Hç¼~YÅuúý­sPÓÊÑ¿±ï ˜9:ô–Y†&ۘ:ö cU:çٛëBûrÎ0º>È^i…[d6p;÷Š6¡ ’O‹ðƒ#.¿c>ëU o*&L:ÜÁÀŒ–.$ó³ôLx㤴»§Õ~àÂïÉ9Àë'tldæ…!¤1#.—@Ìäu*n&H÷QT*ÖËCî.졉=9"E‹.Ԝ+u˜e×̪¤HÈA$}á{;~æJ²\¨MâÔDF`aÝGnJB†PÁŒ=­Ù#.“ݱâcL¸¡Bž"Yáî¢ýYÏÒj@=½Ï<èq¾í!ɋùÆÞf—l¹c\ƒü1GVø¦l.o6ÈêûlinDµÄ ®ÌCÆD ¬ïÁKøµˆÃÖ)Uf[(8?ìBª± §^fÀ] tJëM/œBóC]™éƒ¯…è×»i¡^|ÇE7u[d¥g¥ÊZ;KÚ`¤ ÆóÈ3;†óæï`n… 節qi‹8šö׏“OB!2ÌØCP;Èä{Ž]¡Gʂ¢¼È0†QvDÝ9¼‘¥ºËY=†s³¤íEÃBî4¶:˜vAèC2.û\•|ÓioÝv®ZFQ4ZOí²i2e67­î1kÓkð/™#.§]Ž6@‘³4xÊ3töÕÑøželG•Í†²Íђ@R† ]ˆ)˜NýþüueVL5š‡Ú)·é.´É©ü sà7§@4/:UÛ‘Ë]u‹C<äR\€w'UWÞ:çQ“vbª§F†H RÉS©Ð,wÀ×ß=uÃYƒV\<wWa‘"ä¢wÕ÷€Èߤ #ö ˜’®qœ”¿£å„.›#8%€vÏÏíωIúu-?µ÷ðž·8>ë2‡“Rª™MÄ£8{ôíåŽíxÍ]z¨Bì<bc«öz:yÿfáÃçG•ŸËhäŸbV…©÷b‰ ÒÖéZ‰Ù‹ÙUð%ž¯óè™Q>V'׿_ÝSÈ2È6½–_g¸ñ¢Öåä#%˜Æð§:¬É©£_ÑÆxÖyßÔ#%ŒÒéDه¯Š~ªJ†ó$ƒ?Ù~~é†8f>†îÑ=G/‰…Þe%A7Üüq,[Y§â­¿o¹€b΢oªd¡ÝŠãà¶4€CęÀ?Æaûý?˝ÉoôÝÝã‰è”Ÿßþ$Ý6aH*2AHe,-3ôWðþ>—|ðoÃpûgŠrñßã‹jËntKç;Óø߭%ÂòJŸMY¨TßzÊüúQ÷óÌ<u`ÔáXXCWKqŠ_æA?žÛÇoMWœŒ*ôˤ,«éýŸ£õÿ/7ö0oöÿ­‹Ûöþ±/Ý8üq¤¬”I&Éêe…UšÕωk›ôR2ˆXIlW+YsÎC?Û äÚ¡Gþ€€ŠeݞYg ÜÕ|ÆÚ#%$Ç¡µ¨Ãhý››“[<cOgöNÚk¼Mbf"\ 0íÝ{PÖõÏ?oÈGðª¡)©>p?îüy÷?=BVüsɼcýNG8(´5Y‰yPYú¾ÎÞξ½¢jö«vÚÙÜ1¸ýË}+sk…6édص2½yÛù¯$Ü¡i)_?ï_Œ3÷ÓÇíüûàüéC6ª?·LG÷³û_Àȯ«ï5‹Mu¹=!£~*+LOú¤k2¨‘bÄ2ðÏVÞ 7üDÏDa{ª';âûƒ (#jº£ª€%3t»¬i×¥¦•A‰Qǎ®¬2ÕYhqߞ´w/ù‡øƒã¦Z7¤Åö#6uÑiM«ZÎ0—XL¡ëŒ!…9¼zóü€ª ²zYÏ¿hnÎHr`§fá5©¯N$fá"ßæßV Þ±Æeî>¥?ë.3/«ð>KÔ6½ŸM(Ÿ9ž—Ož‰ ÊK#6=mcÒï¾´'ª¬€§J¦1EæwŸ³g¶ËO… õR—¿Õó °"ûå m"À„Œ@¦D¡È_ßØ_éú«ÕÈqè4é|Ÿ`òßR쎉+´j`ŠQ‰(‰âL”&‡ПK#.FM=‡3–ÿ§úñ3£I¢Sø¦Ø¥cҚ ÈȹÄþƒ~î>ÜþËq•U×-Ã^Ë­uèàH19ôêaY?¸NN·Ñ¯¨]ó#.—y·Ûßù `2É/ÈDϐà‰ê>Ÿ #6m*€ÕHç<\2ê=|.mcÅwž~÷‡w§`PòMêÆ9^Þj¼=ÐXŽfulDRžÀç,±þBp­ˆRH‚ú‡Ð݉™îµ˜)_Å®ðߦ.üîÏÏôúýà|Iõü¸“ò» ãšMJîë áEŸO×ñ"aÚO‰A$ÉF‚ï5ýéúxqçÐû¦„Fwd;zçСËÓ².'œgòêç©äâ|9Êlrå€ó×ê¯l¢:vGÐi2] ™³ @ñ¦ Š ®3×#M»½‹.À;Gâ¿9BG8ý¯ý\žŽý»D=®h¯^þòÖØøÉýò=k‹â<RÂÐäõ†©‹€DD` _êåî‚"xKyy‘+·75¼â]*ߏ:Îp#%"t-8¹j°ä €®Ä»ÓëRiö4úi÷>áú¿ÀØñ<ÎzüãËçò%LÑQû>\ÿ3pÓ°êvÇ1gío ¡¨Ócj‹ÛÚï^ÿø½\¯:³Hr!i ~ZT×°-î(ÿL½þ›rø†'›™@Ù·Uì:k¶+cJ ©Òò]ô8<Ãr¾ɹÐ#6ȄԘ²¤ƒìüØõ^ˆc՝gqÁ”oTÔL#6$8ˆ=Ìò<Ë1c„‹Š4+?G£âòó¿x#.âÎ\ÝZs ܟ™ÀàF’)¡EŽhsŽ•ƒ.²`.z´ñò„Ù0öªÞÒʹQR~m+í»0†Ç._¯Û˗ÑåÇC«nè5 ÏutßWv#60蔪Z.0òë𷵍¬žËðSŠF§NOƒµN®#.ÐûEÁ¤Ÿe˜ûøÑ3¦2J¦|;ìïMmQ³ ïºvj†x¼rïJœ¹¾Ý‘~“Ð€pr)‡c§~¢;wo«j£ï‹ïÎö1žsÑõñTh#0Ò!ãóR³UW•×}Úh¥bÍ exƒËá "æ|PH[ǧ:àJžäô/°qŒDC“×I¦™u„ÃGµ_z§ó8Xzgü‰Ï—N×È:ÎÝÓ¿¿x£aF÷›Ó¤ïÅø̺€["·½ò½ejøM†§Û™AéA&¶²¶®6)BЁ‰ˆ;XG꧕('ꢵ¬IB¬×(~ a{ŸÕpß5×.êµ 55‡½.>#b·—´Þç=ÿ©]oðÃG§Tmü#%AÁP1@zsÍnál?]ÞªzxkÝ@ˆ2 eó*+h۝:¬¿w›ìݩΆÜ~‚ TJ–^9¿ ͑4hB&¨ï¿#.xbðPýÀ;Ô¢Ÿ^Æýú}¡‡›¥Ø€K“Ú}´!IŸ+ê@=ªçŸÏ@- êá)"„-±ñ³êa”å7&#.J+Ç¢ñå™ÏL½pæ#.uڅýŸÏó,fƒò¼5à‡(ÌTMB³î9ál¡0á5ŠÕ’:¦s‡V6z=oÝür¼úÙ,åƯ÷~\Ý¿£Œm½ñW#úLv‘ÅÙÏ#.‚{£PP·6Ú).zEËÏ{ï»ý›Üan!Ì@ï\Nø¯*}Wÿ†±›þÉ3ÄÒS+ÏPhÅu·¯cãßm’Ù ӇÚ]’<ÑÒõyÅÕ'ëïztW{ÛÚ³—êøÞ`Ì«í- XLm#¸ ‡F—u¢ÓZ±ä¾µïŒÿ9S9œí¶}È8ß+äªnæÓ^ßn$ÊdE[Ó'}ìt”¯íøѵK¥Q´Ûm﷓mˆs³‡ñVhïU¹á _@6½o‡ÞíöO¢êCU˜sª†V“Ãú«:ÇJM,²tnOƒäÛ伎r'Jh±Ï“ªŒÁ¬ˆW•è*˜• IJŽTy`¸­ñ´,xÂÆPèL*3(#.ÛàsÇÍ(Ç5Ã.wà~>>j; ›A^ZՊÂ0MÆÇ¿š*vˆaFš¸7Ï#%÷Ðgˆ}lÌÒÌÁì-a”Ôƒz3urî#.œ‚÷?̶›#6!î8P¹òˆ-ã¡lÕ]EïÇ®ÎZØð™[¥•ðRӇºÝâ“H‘53û5qµ‘ÓÝ¥ƒ¡ƒ(¨*‚—Sv†Akë«Ü´iXE¦ë%qaÅn_–#%ÑEò¸ÙeÑ.’g}‚H#lkÓ>§.¿ÙÔ¯-º(ž2}T|pðÔ=ˆæ ÊÓm.C:)]úݐ«ËÛyï§ÌåÝÖÇð …0«¥7§aÝçYјóÉî® úÁž™ÛEg'>±Ež®LNïˆzûë1Åè§âßÒ(íÓ\x¬ëµÎ©ê wƒõÆiYئóãÊe0wóԇ%<Gœz¦÷Z¿­ ±a”úÝÊéFK^Ԝ%zd¿M½5:îRª®cw×{Wô©hØOú“¨—o¯œ¾½löyšâÍ$®¨¯zÀ 0§mCÓgÀpP®¥h îÒöUA| ÊÀÝ!=yy©DzäsÎ9UI#ºêI¹#6ÉWeý¯gÍóz8V“)tÇáFöƒ®úBÜXöãfñÎþG|Âøoí.lì&)ÄpæôëøMSӟô5#.2ŠsQ"„—Þw"×ju÷5ªNþº7Îåí}uKfs=}é؊zÚ_CŽ¿dlO¶¹²ªrú%Ÿ§Øçß#¤¿|*¦›góßsg~®ÉD\͈zw”¼Ö~h˜é¬»{ˆxHgPî„6ßÂ÷¬8¹ãŠß³Þt[iÖ(N…ÒIÝô—‰Ð‘Œ¿ÅÜSm©Áw—tî‹sÄ:·'³?‘¬g6ムÉÄz)÷=n™çЯ[J DqD QJhµŸ<Â^·gPáñ%mÝäú»·n·=3¼ítd2ïäËÉAíTdýúÌù^sŸÙo–R×j=µì\å,c¾-#%¯Ã³Žx©©; WÍxÙzë†X\µÜéó™3Õ] ΰ»«—K^ûÕGª1Õª÷ć¡–k{¦1Bϧñ êœY±£]é~·<ëí¬‹«%HºîmƔ2¡™ ´¸U\ E\¨¥D#6Ö©ýè¥=ÿE̒㶉ÛËrëïǑYòûáã%»¾f=ÞéMŸÞ³žKÚtZÓÈ'l8•¿8{žß6TF=Eò|"#.ßßUGÙVmϑiûY'.þ÷Æ ´n¤(¦Ôh³ä\ŠjdäW¹MØ£Ç×G¦XÒ|^–uS‚&Æ ú]^Ñ]s}§GPW齑ɵùÛ]¹>íîæ˜~çÚã¯+}ß  Ùî"•6ÃõµÁU =c¥Ú8j~>Ï?sÓ×Òs…Å"Cqv…?·å N=3 ύDü™ƒÆs\ùÿ‚¤­õ¤=§¤y-&*ŽJý†öãÃ[ÔÛw ™bÄØñéûDfNÖHZZÛóJQù«¿¯bÑÔ|¥¨Áv¼êšŠ±¤z(ó±V‹ÖÁtAµêq¶#.èÄ‘ø6ÔÔrÑþú#¸\ØÇÖgÞü},#6ÛNjBÅp®~ÇBYÅ7ŸàÅË;æ­ßO¶ï‡Ãß«…Ä* Â=µ³\F’˜v©ểÁRÚMܯ©”øeàE\G)×ÈLÅ­<ýŸ™];8iÉú‘Æ££í –]Ä ËĺÏYŽ\6Çg#%U¤{’Ø[†»¦.Iœ<:Øg‹#6¨Q.AQÁƒ´7æ¼¯#üá#.¬h;û!ƒ]žX–0ÇÏçò¸m‡gݚ1Ž9ÍÿžèmúH¾_H‡–GYÓ¼Ï?N××wíQ:)þ$ø/KyÎi6¡+žvŽJŠ¢ÕE‰B¹@¸ÊƉðˆP¢úz…¢,Š¡–ªÙm–¿¢„ÛiKˆ»eïAxý1_®ùS4`Š÷³…¿wٍ“»N¶{PÔôÖ÷ÅTXPD]Î*çDïCEžüYc¤ô¤ãð^FO¸Žëz]ÕÏéæ’cpÈÚUʏUÐ@œ,#%ŒÂpHmUWùa±ƒµ®*|ÛH¦Îˆ}Úu÷'Ø2›Ô¤æŸŒ¼…ìGC9BSu&3æÖ5ñh÷=3m"±|Ø\!€XPŠ‘.{ØyÝH¸›¹[¹BJ+ÅGPÍS#.O2,,<Ó¿f;r‘÷ú½M`ª)…®¢Ñ@9b\m@ü @@]¶ÐئD #_K®cR(ä?µ‰#QQÄpFñ#%¨ªêªÄÄ:UÙ#%œ¨"ñÓm݄²#.ž·4맯É(¾Î^¬(üEJB녋2 3º ¬W¾\îp®4«ÎJê#.¬ËqÂ&zÐB/ò‰!<Ë9#.ølc´“Àw£ôMzME‚×®#.CÁEEÁEà#%‚<så£ñhõyp³R¸„øðá#6ÌÞO}Ž¢„åE§=•ï½ï–8Å»—ðàÙø{q!† ‘¯ÑÅ=ܝƢÛ©ˆ)êCöà?Ës_îì‡]#6„ŒêT?ˆ€–@-!öðó÷ÎÌ/™¾¥™Mþ¢Jk覱{Z-@?÷U§œÕ빙üGê-›ÇŸ·Õ@{ª¼cnÎL‡§Q-ðÿúöòÎÿ”ÛeÐFçÛAùk9ý3xÇx/‡À4¾ÔPÅH DÀÒ¯ §¼z@ìÓüUÿ‰¼x´#%žo2‡2ií鏅¶z—® kÒ$~ÇÙcÒ5õ«ŸoÕöü}œù°RH1蹈çè Ú4£}çKêçÎ L¥Ÿ­vJjþ©J%ÿñ ìøÐ}ÝAbAr€ðQ1«˜o£Ú·X„#66ÅH.>qÈ|ñ$T½‘Š"~ßÀ$ééí#.YqrA@f#%ûW°@Cë:ÑЊi&s7Ïôì¾&BOCüf+uÙòj” Ù$ߜº×Ïíz³¾EêOæÚ$>ùhÕn¡á™t÷HŒ†ú§¸!#*1"Ú.Nç¸Û;]\xVÙöùú¤šd^ ƒwÏ|gO6ÃϺí;ŒJæ0&é5Ó#%}¡8Ur/$€ß…3‘ì„>Ü­x¿,CŠq¨;™†•@v/#%å@]¹C9P¤grÏþ¸(9Á Èv kš$§9T¬Æ4˜h ÷~ÿm*ñ8꘻ˆÈ` #%X} ¹lJ‚‡^¾ü. #.JCVgˆ‚5t^‚ˆ7!߆÷ eøÆe#%~zT)AY`ʼNµÂù íUö)>Sæ׋rYXP\¨¢!Å&‚NŽ0#6±ƒzY*¥MtÛ ìt‰šÊl,tgÎçg2ˆj—bOåN@–Âq7´ñ&¿FŠ)¶¦=((œ{;›‚P'+ª×Ãw”V_ðÀëá?tf“¸Ÿ@¢ÛnóX.Ž3Q%x]]Ïv[ÒÉk¥סTÔ4¢¦ª%…e^ROkl(FX8g&øw†å!£?géâÊ#.#íYÍïj‡~†âi›e•Ä×u'³Ý˜e;g•ÂTüLìq1Ý ¯#¨(òáá#ŒÉ,p†“çt‡Aè•5+ÙldèwäÕÒ{øÞv‡åÆ;Úõm”P•'@î}ˆço=pÊ2H#6O G™ê_™0P&Ú‰J#%íËTO¦\ýæÀ¢j›hDp¿É“ꡧКy©9Sr³xêÚ-ÇhvÔdŠ#.Y|ÓãÃPmSÀˆ_¶V?L_"'(PvÖR«6ã$¾Z'Žxõ×=÷#.A='áTP‘)þ%¦}ýjW¿Íþ\èô´Ò¨õÑ3Ê¡â̸|ÅZ~c¡ÞFÊ0‡V‡(·ÙÛiúÿ+Þíôüt|~!s#.Ë@Å¥ÑZÃñxä·˜aƒ……%»©±ªþ½GŠK1à*ÒpÁþ'Â=6ŸqK½•¶±/öþ ®x ©®óÒ½±dRl/U¬ôdÂAÆr³#6+óÁ…G‹Ì&IŸòê“nçôBs\g"ìé _žKâéœ?ŠŸ§èMað­{4•„ÝCɸü¤ý³þ~ö܅ÚázNö}˝ê˜9„)˜Jë³ÒïIƀf¸<Êw²Á»¤‹Æ=,µ¶&M•!.üpVí±ðNtÞe°Ø²”Ó¦p„1•Иàƒøôžzrŝ¼ùX—wÇ+8So£°y1Ï,ð#.›0#йò½ÇÈB9:ƒ-{~Ã1[rµã[öÁå/{Ã"“ V«Ñ*&dÛëqì¶Y-Ï.õâÒÝpœO5Æw‹;-¹’¸ò ¦JÅff Ç»¼Á¤à°Õç–H‰|WÉ¡œ!I¥Æý1eEÖ¿Ö9†AŸtP_ªÈåÐêk‹WHV#6%±¥ì嬭1^ˆ´#0Ó)åªùº°E­óg*ímŲÜë èûßÁV–Bo^Eæñ4ûy­Ö°‡. éÄFŸ±¾z4÷ö`€¡(Ù§¢œW'¨f鶹Jb•‚®òÑ;¥:ZÑ;n‘»Íçe¤°,5÷¿_„¡==:©8¼á*è›çñŽ–_ozâ|qä“5v]QsÚö.2ß#6ïӜ‡Ó~ýá*ÜEÛ‘"cƒ¬|T=ù<³#€‚ˆ#6àœÆ`—Ñ-¶™ŠP¦#.…ÀLï6– ÏÜѺ Gà¨ëÔTt6k®^m¾×¡Îu¾íˆr%ÄD>ڇòQŠMŸã~p݌, ¬&»œ_Ag¨šŸ²„Naæ{¼'##6ØÊ°àY•€È‡#søýø²\¿ú-´Ø~mÞÂɱ*ƒ6i¨I@­¡¯PUG¶/G$YYzÑÎR0úgÏüŸ—î–å¯Cæ“ô~6·ÌS™PÔŸ^ÎÓ¤é#.Ózý¯kHmiÛm.•3Ìx‡K¦ÜÈÿ~®%Ä"Þ+G;L¡ïncï–53áõ>¬pxq¸dê}ƒŽ †¬=ÓÓ·Uý öA¶Ÿ—vr„v¤’9’“4‹>ü‘L¸½p¯´°©gL{Ùþµt6É{<]^Òޝœ‚™Ó X ÈÁ\€‚ ¸­ALäo¢—Ïóü¢’Ôð8ºÜP6;Ak…Ù#.†›njú«xõm©ÁäXµEÕ-— ">/Ñ£§5ô¦`åä[R÷6qì./Ó#%®Prö9¤¡ÏTXŒù8H^ôѬPòÖ~•Zª¨‚S~§!¡™<פýUîO'›Uú¤–0°*û¡Â!5Éåúõ…`ØY—³¿ÂÁà$µD£#%¡<珟˜ A8¤y¦ç½â±F*$‚P’IåeÉ#%úZ;dž>žý{/ó n\ö»A8*Ž#vw3…*ü5`,rØ5¦#./¾ºË܎ 4W‘i•Z¢‰œG˜é­Ÿ!uá&(ÒÇ_q”Då®gˆ·3$g²a:¬ï,ÕMˆ{ÂkÌû!†ÚR [€#.Mßâ–i a½6`3­š"»—½§ïØÈNÐ+Ùbv™‡§ˆêëd뗊ZO9ª$-]»°Û–ü"üfÕÃõ¸p‚ELÂçìîiUHšE¹é±e.™ÂC¼â‡gA¬6y¢gÏë]±éwÁ÷U îåã½}¿)¯#.A²ÌëðÀ`lAºÁ×dí9Èãjá*Ù݆ 渻²§°ñ,‘ƒ«hï Ü£dwÌ.°‚»d€åšy „r ‹%(sãeäFzeÚ­Xí¼#.Kó¿i†CÜÚ'~Z6´–# ±sY‘”JÉaL”Jƒ ˜¦#%39F¸¨™Q" ^Då6{PSS3yÝL†Ý'n˜'´sûõ*ãšz‚¶ƒ«cT¸ˆ#. 2!r(PhPÚë37nPᙌF;E6‹ƒ#%ò-®}“˜]…âRkß ×ø°Œ‘ç>Ðt©Ž[â¾Ú²Ù¯kYëõÉ×,oŝѲZf°Øâ'̆ü¼üFæ"_ê•ßv8í<[8›¢Xæ˫ɝ;ýˆÚru06fåÚ¹$£”ìH½_¿ÅÌÖ_ÈB'ÑsÁ¾Wì$Š“³m#6E]}Ñ#.~j4aÙ£ Mfù‡ ‘À\ö=‚°¶²„„ÔJqå΂{ŠôÅO ª÷Üþ§Òj›AéTPº¦Êƒæ}Ëã1¨ò%¦ÿ£Ì÷"‡ÛÍ¢1#6HsMžÇ¡±Q¯5óßâ¬Ì½9ÆÂ>uRÂ#}ì3va¤gìvŽ‘m¹€ZUÀ#ª³qÆîëƒVØX®H2 ÚÏßÙ#.Á֛@¨$7›°­íc<ƒŠ!"†·ô2¯È.îöö !҇5‰ÐÀ„¡LŒ÷³á±Ú¶æ…™Ÿ`ÆVØäºÑb#6#6õϧë(¢Ý‹a'9ú#6«`Ž‰„4Z†¢ >P4i á~q\KAÔ!nȂ)™ÁÑYÅɼLèÈÉ6Þ¼44mŠ§3r !±é郓Z-*5Þ/!*kâÔ €VäD­—K¸ù°;"Ön[z€2bŒˆèé}ˆÚÖ½ÖJ"ÃX¢žÌvh{X£è¹Øf¬b¡Z–ëó‰Šè¾´ò+AŽ­u~üâOÚ°Éqm©ބ:¤Œ·C®aïÄ,«&q\șA̶¿n<l4(ÉÙÛÄW†ŸΔ"oí?wŠ©zg\.Äf¾]%k€Ù’¢t<æÐ#.c–Êá tgߛr#%s-¤  ÷çmhÅ»]§ˆN4(ãZs´cÎ.ßx*sŸgi5‘ÃÌJI@íod/(&_ÊX·éåøC¥¿ZO¹V?0Ìd<—‰Ö‘¼ÌĉË0斕;bù¶ëðzàUö‡Kd3‹³ ʗ áh@ـQm´c`‰ñíYÀíÌ ÀNò‰1ª8ؔ´œ+n5µ#˜ðF¼]²"†RO]WQ5#.ê/Ùªß~”aêÔàí#%遉£µ âÓ˜ê(-ˆ”+ƒGcÒÐÝ`|^D]ÿ¤¿³ÄœÁ#6El\q´`!z I¡¼<)MG~©oÖxEß¿øÍF'­Qn#%xTL9ó¸- 4‚€ÜÜÜÝOÂxp8Yx¶@Ø‘o\D÷Níuœ§WL7COÀ»îZ¨#6iY|ŸÊäVú—AÓ]&[óêæ¥À_5·i>sE/#6¸¹€%5ÿ/ÃN¿ÃÝìï(öþlâò9Ðs7Îåú§óˆh£ógTH‚€ŸðYg}ç_Aò0¢VÅSNĂHQ–'Äá×õÀ£U GJ­ÙB3qØ÷dZšÞ gÅÒЇq÷q¥¢×‹_aÜ8#%Iü~Jڞ79ÀëÒ6ò`á|û6¯/ YÚr´hÄú §]Ù3óþKÕ⻳«—Ä|3ü|cÈužyb3f‡ïíÃø‡Ý Cx-®–X3ÐPX‰ú†t?Qà œˆL#6Ô28~±s;{þ|%UVvþ,¿Æp‚gºÿ…ÀY²Tì*”Br)SŽ0e–Çûï¯Éþp>VÇù¸îü¡ü_ášbÖ?©BÈrøð½C9%_ý¹$TÅIÿUP©þ·÷êYE»üZÕôAêa#°^ˆØ”Xá©8Š1#%hÿ]¡ 0;5 gûYý¼³Ö÷vØà|ávçv…†ßë›ûîšÖáþÐ¹ÞŽc€Ë«±_wNóx©©A3Caڗ ï:Æ]Û¸…xn4©‰ã×Ìê{3 ®íH¸éÍßYTBºâüT£Ca²lÀ–ºª<ƒý¼ƒ;ª§`xµÍG°{‘ڝ€ÀÞõ{ƒ¯œaô{ý.Aô¯³í4A#.PÈû=¨íŠÚ+þ˜ªYÄ; ]ÃäNÁ5%–‘Ñ…î\þK¿ÞÍ5”9€Í=¶Ïâ}™ F²†¡®B Ötüû™§ }ËÔ:Џ$A7ýß¾ºÏîû]MéÎÉ㈠D|_÷*ØUÙý./Žœó,Õ!nÿP=`dÄ_¼çœâÜ&\’B7dªõ{ ²Aåý—ˆŽ qÈP#%)X†u„¬¯# #\>Ïæþ¯G¿å+÷[q7¡ˆç˜b<œ*„™Ïw÷ý=OŸâG­ÔûôŸH|ï=áãøN®A ÊL’ª´RÅßzáóHò?yˆCԔ“àVøþí¼…ò>!”0нÈ^‡ûÆÁ„.4ñ6×å#.ý?ipvóÙ7ìj¢Ñ X…˜%.S–7pÂM”ÞbÀò6£ƒ4¡ÖyÂCaΚ#.Ì·¨¬Qv ´†&ËPÿ—<#6ÃvT‡«±}ž‚ ûXðÒ¥W–‡Ò`_Ýä }ÝâÄì9Åwœû[wmZ?¼“C`ðã tÌ{àsõ›Û?OqÂöžVÆȨ7RÁ°Æ.¸È’(H0µ˜p½#%o{‹‚íx-)F,=žÂÙ²"œÃÌ„ä—°íÀÚæ9Níw.i…c’vL0ìòÆ‚Ð*ÚÃz}pAZ€sŸmy^®šROÅö…îNÿïòðY GÔT%X›|ËBáá5¦ý4 ¨TÎ(ÔXÐ# ýeµeþô=]Hê#%ºwZÁÀH“_ž6£áúl¯ïwç£èÃ0%ï»=¡iìÁ'åƒÇ`w‚Ž%#{†ì;r6,#.øÖ,ć¤zdx`¿‡ý9p©CYÐÒTe*ÞiD¢-&¶Ö H<>Rg#65Y$îŸ?.ÔäxRR°Áîú=T²U}ø@ú1ME~ kmmÙG“åô¨óƒ&FØèÃefæj²’~G³M¬2ëôê‚YAÁwYÃâÖ÷ ™#%y M©o®#̉ôlBÉÕ@"Ð$eæ ˆÄ|³5:IF~Œ—¸"Ì-¨É>¤÷x›¸ºŽ"#.?â#6ª[pÆñ”·æ4ï* *˜D¨ uåsØmos¬!ÖÃfM€ð*fÀo5йdãÆ¿­ç=1…”V·ñÚÀÓömçÊkû8…6ú„l£\ðgŒbݒK!UU;¤’I#6ðïlJüý¸f¶­˜Çí86#îu︔öoz©žàÖó×„É „à<è:YhÜðyfÊ–çñΙSlK6ÉÆd–.Õåè‡SøÌöü½Aô–~Ã!#6ü§ù‘|N3ôÿ›»òï;§ÔO‘Úy K~ô¡…×Ä°´—SêœúfÄ=ºÔ#.óévdÖõò?IÆÉõáUê6ü‰“ƒôû”[~@ðˆ@X#6‚Ä`ÈÃ/õ{ü>Ÿ¨ #6èQÚ@Äöl„²Φ§\Ã)%±·P7À`«³¹ðׅ÷C.ŽÐup È`gü­ŠûV}¹Î•|¥F1°bcC„2æ²Ëœæ‡0ž}"£‡A°o‚#. '#%ØÐhü÷‚ìÚ¹&F÷7yGÃÌ2M†Š:Œ„ÖúD(3ü_‹ý}Hlû·§qƒE#.2+Ï­M¦äûøæƒÖ039!×ÚFå—9-Eö V#6„ ‡`d’€êxïk #%ÔOÁ-=fŒŠq/¾Êƒõ¥*`k|X}yÅ^Eí“!l<—FDYºÓA ±¨TD â)#–¢š3S :€™™š‘i°q`wr$îï+à™±›">,Œòq$D©L#6„3ÎÏõk’NðÍÔk‡Ä^!rÈÌC¹éi Ñ93C<µ™½Ø2.¦„#.Y$ˆà ¸ûŸÙÓñŸoXÿËw^º#%r€ÿ™úõˆUv­Aýù+ŽRWáóÆVoë¸q®ž½v¤ÞŒ”™zíÛ$cÁú»e’XjÿÇý1ž-.õ„XÊf‰]dmffžµ¨Tä!Ô }™§§Å´5N*näl³+”¤CEš‘×’I$™ª5ŠLTË­MIikm§™«š²Öjãzef׌º†:õ„ '«^kA«ÐÖ·¢šféu†G¼ÇV:ŒÒÄeA)2¬gøY(Î:ü¾Ù#6ŒX#6ª4YH¹„ŸŽ²¨é™ô0 ˜A‘P~_bÑjTmå»2sxqnaÑX„î;ڟ%³ïöÞÙýµ£ƒ˜t€Gí^^ȞÂÆÛýÁ éŒó˼ÉI~}~ÝÕ¼QRü¾ÔúÑ÷}‚q§‡#%è!À´>Ò^„¶Cwl9¨; Œ„‚6ð›IÝ·;¶¯¬ó·Þd]¶d>a؈ZjH M)ßQl‰ÐªïVY¬$ˆ €r¶PRm82d?ðۍc;ŽÆxézZªÎÀ«àU¶#AIE5º&W¾f^%àù§Sš«-5Rkӄ¾]ZÍÌ¿ŸÂ19l=1IAJ~ËöêuEð4+Õ.^‡¿%6‰è ßرfÆó£æŽg §-Ô¦ÝɽŠI"H±’~Å÷WN3v¥7(Š)sp‚ƒ*ˆKûû;®Î϶þÒÀû“´ÛïŸ3Ž£ßødc_dDôvö´€’»~¢µQ‹ý![~Æ1m—ؾñ!túíÈÿ©©¿)èlHÅ3ê+ì:ŸöK<¾¢ªQRR”Š"›äÙL„Ù°LÔËsMw¶`¡º îÍieBñ@0bRòK:R¢d|~“n|šâšWnƒGô „ݽ}‘8_¨à<'¯aòV¼Qîó5¯·o\W‹÷Û^0'h7 2u%‘¸Fmîò f±0/ÍÊÀ·ió¸ò@£P.£ùbúÈ+‹?NÎTáõPäDs#%>!ø½Þ@Y68þçxÉ\ż.Ü?€ú-¸QÙþ*°™D­jIôßç½a-êzÄRÏ¢ˆ*%ö›Q<ìr0}y,ýÂz ú>Ç[„žäv€ãòƒ`õ#.€²Â½ú&Ì2(Abã:’6ƒ¿ô9œv¾ðû`ç¾É±9ßÙú_¨ì>†Ê§8»ÀþÉù€ö»6x'ã7ˆu'€{Å;H©A5twµñíPI”É(Ö?xyX"DNþ}+»ÅÞy‡sF±èæÆÀY—€3m;0#6ŒJŸÊÌ#%âaAŒö÷D<…‚É„Y(‡Ìò ¯À.pW÷Îapõ÷lòÕs½8¾?~†ç3 PGÌpC© :¨3yC³ŠÐÕ?P«¯™»/id+ä?ÇGÞÙúÉõ­õɬ÷V7LUQX•®4=áù2»Ý–£¯ë‚ø|áçð*ú­Ä ‚êkCÔ¦j˜„‡£’I'±â©æ>·Ò »ø5UŠÈA°4d€>Ÿ/ЯãH¤ŸWb)فZ]CÝZ{Ž_\£ßö¨0G±Lùru‹pÖÖÆZžÿG}6\ҍšT…É᠞åõú÷£°20®Uöʒ°8MAÕñ#.7û;³ ƒ¬{Š¯Ïàtc$Ÿ:F†Þ,!î:€ìÎ:`âÁbq e¨s꾸äædQÒPÁ“NêƒËJCì2U‘ ÕZˆ*>RQÀÑИ†©üèeLæHãc;väáÁbNˆTm÷T†Í&†t”K£Pññø©†tóUŒ‚Hª%HYÇW¯>nÛC-Žmu‹r6ÑêE±½„¹Þô+šn}|=i³Ÿ'2)˜E^úÏS<a‘$Ed@¡$´ZЫFþÎ)Ìí76,BĤJ(~¾'QvVôb•JÁ­øN|À=ɯ»ß<OZ'ˆIâh<Þ°ö#%`íßÂs#.dòUî6šûcÁ-£È3#%§Mª¥¹ãïù¼_Øû«óåïè/˜_Çk/qcu¨²{¤·´?×?ž#%#49'öJŠ<ªJÿ¡Ä†Ã”5m᥈8`«:m _ \‘¸Í©R•JJ­Q¸kúºu÷OIÝ'lòµ°~3áGb˜â=hòäÒøŸj=ußËã$½!­°ÔÃïLý®äwšžò!³Ý(TöC’ÇٝDåÄã÷~C—Ï¡\Èৠ‹T £T¦!S䧊r>Ð2üY"æC}Àí•iòJ;)œ.Ù¹ž½ð˜ h_Ÿ™é籄¾üåw¼!,Œ#6|õ»ùN}Cƒà=åË)BB¡háô"þã3애kEµ,ã‚e”'?`vðßù\à£öíç¶>ã‰(}M|)kì`éþ¹­áaª]˕àa½E½h#ãòF%LæV #%ÚI0%‰¾ Z\Baнìh%R­À2` øÐlHvE6Œ˜‚(¤\D½€d󈸂HÅH"8‰ERG5Ö ™½Áù²AC€ DÖ55-~£¿Àú}ý#.>(#.ØÈðòÅÓ<³1™Z*¦°°'Qb¨r#%*ãIé}¨kOH~)Û´ÑLAG§QbY()9gb4 ÁˆGô~×ôs­¢×3ܓ×fH„z3J³íü`‘œV߶PÁý+_>q°Ù#64X”Ì¢3|»Í¯’r«Ò¸n‘[]0ÙP˜‚²ÙmÝyæ]­<(©h–‘ïô›“Wóúý?f’þÐ3MãÊ ³ìóžAì};`%õñºéîf ú‰#%–½'¼ŠYÍõù½HÃ[±#hqŽÃkóÔ6CôƒH&·j ˜ªY1#€(#.D†B2`ëJhL€é·E(ˆҎ*XZÌO/'œ ;+Ó³xBJ<ò9œ/;3§¨^-ûi^Cµ#6@Õ£wëܟ¢}”RN5 7ö†n9ÐõD#%ØpHo(ë u}›J6öÄ+pòi:ºØç¡<½s¶Üíö[c˜Û’.Ó à49°¶¨ <ïªÊ<Ïgã³Ùۃ; Âä=Åa¨]lùŒ‰úÇ#.ÒÒá)Š#6(£ß½d©ý`~¯YíˆIæIRJìóî9\§ÃÞúîŸ8ÿ‰#6Ù6zC¬÷|ý“>4Ò~Á1؊ŸÂ¡ð&Il™LatɆ¼,#ZÅò4|˜kf_Ñ‚½š ´¸¹K†\ UÔ0½—¼$…´UO°ßÈùq¢úHhG®Ž¬’:Š#žY9!|úÿróŒ=H͊@p2¡ «B#؉ë·×îüèt*KHÍÁÙ·Z<ƒ°ïC$"4˜ëêëç–?}z¢3Œԟx'îM'oÝé#%ø÷ÿ´‹;)âB0®ƒôo%dLƒ›,6f(·—Öߤ¯J”¼u.î¯[ž<r±!‚J‘™´Sâ_í#6Ïíªãø ùßïÅ#%¯P–C2?¢?½öýfYÌ1?I#6¯Úz³:ÃÀÉå”Öh¢ˆ"ƒ’•VŠ£ÌwŒg#6 „þ¬)ʏ²üöTÜ0¯Á=iڠώ‰™…Bi0‡Ö“%ö§ gpõ c%ÌU!ˆ1¤1*D\?S:PzΟ ®þçæ–Ë—ÉHJMŠ´ŠRÁd¸¸1?;‚ÁcÀÌÝ°.<Îb§ ‡Ö;nçÎN[»›Ñê ݞõ{Cízƒ!RسãõÙ. S#6 žŠê=‡,”è>½¾zDZN°ëÀàô·•NV’2KÀ.*Ð~› àGX5ºž!¶Å/K›¬ۅةӀyâzK¨Š*üÌ`…–êAn߉lä¦ï/g«”*|[•B‰³‰¿âUBP„ Ÿ£âÍù·4„¸Å„á8'Pf,͊¥d‹Ä1éÿk‰üš;Ô¾Ö#ՄžQÒRƒQŠñ{ùmzIIJ…0êÄ‰´Ã–Å…ãd…å1 *ç0%v_η?nTÖtÎ#lš1绸UgP=`Š‡*•IùI²8¢º'ʨ´§F¥‰ëPØ A¶_NáAJŽ`µ}ÿ¨|ýÅÓÚ/O€>9X<ü|z`î7Éíö¤Š»ÍýVèŸt¹ úd¨HÁ^mQÔЯ€ŒÒkK™ÖH¾‚ƒºëÓ.pâìDéGb\3>:ZA*à¡=^Wû< eÀ|ä 9 âp]û-³•¦hêØyƒš¡¥̊šÁÐðN£{q¤bB:8jð´AK F#6#}띸ŸO`y½JÝü‰Ñ <÷ à]ÈȐJ¬Êª%¤[9‡_Ôöì;#.HÂ.҂PŽó÷áùOžÜ¶Õܒ“ÌúˆQœóμ8*eåàx _Xú(ÉA=ÐIÓ퇌É\½èÖÈ,Råí <nÝÔn3Ûò'ÙÙéóøö–_gùUJè â¯Wô‹(X¨7>àý<ž?ÔÕ =>Âcp`¾Æø™ÏðAv}Ï°¦òO"¾€<ªŠƒR†{Ë€¦8r?ŠOësðo¶S·à~4Îj·¹£0gþðˆ¢¢™+dã(€Z‹@·˜A}î­lí…rÔåŸØޟ̤]אݮ¥éÎ#%5I#%M$—ee5hPmØ؇5o¢àLÝpxûÂoJ#.0I Ò,6©‚BÈXõZªPýÑ÷w˜*÷o6`>Ϲ#.¨,~謙ðˆ!"Æ "?»  Þ`]Q{“jòNo.ä˾‡0,bd% ¯pA°kó:Î.îz³h*;¾ŸÏ»kõê'©uÑÔ9V/N|Ž¢½%œbªdÏ¡‘?*=…ym+Pw!Ýd#.Œ[*›p… ½ÈÁa°ln7â^€öÂ9„íLÀйp´4#6ú}>¿|{Vuï-¯MŠ«¼ô©)mï¥Ývó·n°­EÿQõ½Ä3t6ËnáññõÙºÈÀ®Þn]¯C9Q›pë’]q¾#.ãvË´[ÒQ¦ßô‡ßõ‡…̚D÷Fˆ§œ-hja°»^¹B†‡VͶl؁ˆÅ#%PX°V0PPÓ®¹ø:ä nî¡zgžxDeñŠÝÚb‡Ÿ³ÇÐ>ˆyÊék¦ô>z{h}Ás1óAˆdÑä–H>Ôéf X}„Ô¾î͞Ì#¼ð8&`ÛwÐ6pŸÑF¾ý…BBM¬#6I#6çá~­È랠H7V%íü/Äÿxên=@çE¶¡ï‚=jÛQQEV$[jUUD:ü‹•z⤊^*eV“ؔ!ªú¿¨Ì&&r¶l|ô—‡D\Üç´X†€Öi¡š?«Xiê%x¯<íæ ®ézîÒfSo—[Ö¨ ¬’ s4üåú¿ä'÷åcyÜÕÕáP”Ðv‚SÓú0Ñ"#ò Èð͑~éº{ç´×Dª_*9äÕ¸S^t œ§(MÉg#ärö=“§ßÆò}²„)NVú¿A>?Òe ³èÎýPã/#.Yl{d+×V=µpø£µ0têÔ¹2ý0‘‡â{Qnw™vï÷ê8KÎÛ¨àzÊk0Ó2¡#%óØéüú»#.qÉTÕK£ë‡±+WU‚шù÷ÜxÉ°ý *(D¾Ý!Q4ãH“À¢¤çæT,P@X$àY´5eHr€ëþ;lýÐèllWTKw{ºŹ¬û?‘ü£øN=‰ªg±‹\ļ3à1ê¢Il“¸ù݃ã'0´`Œ°+Ãm÷@#.ÉY†Çî½Éc÷µóy§#êú’éàãœ/ê#%B§ôëé._0þjà%Æ/ò9Q»ür#6Wúÿ=…rý™¥ˆ“âÀ¡(‰#6`1—M3-“ÊS¼ómÛÛËÄï)s ª[!÷Œ™D–TL­¡Y¬ß¨è™Žhq9"ºT"Õ#6+èAᩅ¤©˜¥q„¬©æŸøڟàúY¡š…ûfgñ ²¤(kf:ñ£ðå،ÅCù¬”#. çXÑa¤Å¨klmYçqÎ3Ö~73™®Ô.¦Æ%½Q²’: v-°—r· ê0#6ÄlÖ¯H`³}gÏ¡‘t¼¨Lýïä|~Gôÿ‡ìÛnîv<ÁÌ!ìÊù #.‹ÓÕwʟ†,ý†Ã°õ*ŒUŠ0BA_Üá÷KÒ¡‰(æI:§*•‚þM?µ™Í®ßÅÁ5›ä=½ÖN}¼NÍ\ë׳ž&‡í?z Ð¤´Y-…„¤*¨õÃ~‘#%·žöµ¦ÚSŸõ’ Qk„#%Z…z³#%åÝÈW;Àτ§m`ŽðŒÝ%#%&„âUêï1ó~{Žýq×ÙúùT{,eÃMÙ"bª!œÖŸÍÌ"qùz„Nº|úw¿1ˆÔe”É»D@’ å€Ày#6#°2;×₾÷%þ÷2zTXAÄ#%2€8Æð*5@åï'»ˆn„Êl„’V#6~Ž\bHQ^ÿ½èž¿,[>G;H=iêPÈJޝ§b¨$ ¦ð¯ñ”LÒú˜.½ÕÎ`ð4ƒÑm°É(4^?b——S*èdðpéÿ7f§Mó ÜÖñ?A‰£7DË$˗tÆûë̛dÞ>o#%dˆ„*6<¾Þ<Î= Í¸_èyËa°aú ðLfë9›ßm‚ÚíŸãÆxjt3û±]]î~N.5¿U4†K.w¤Í…ÒG…QëæìøŠæ°ÞŠi}‚kCeúÉî.§ZÆ8=6t™¸Yr#6„%Ý7"—sPDÖL1ܱ þ’‡^'y·=Ÿë;â*Slb¬lˆ{¼*þR{ „\2ˆî@¯çk·¨˜ªØPîᬅâðDçG½#6@<0Gzò£|~Hø¤þ‡zN† ˜ØûcGÿÍý]ŽbïÓcy×÷҅Ø!éÅ!ù‰Æ?ƒí·oÙÜÙ?ÉåTQŽÜ)ލQñ6ÓÒáÞú_7ۃàò‹à#.èðüª½ÚŠpÉê7?v¿~óAÞJî„îç'bœ—û,íÜz@®‘”^í@q(M¶9T*²õ†Ã.Évm‡¶Âºˆ9ψY t Æ"ñÌ&÷Ä;:„×ì<݇Lò0âÃñ{ü×R¬þ/$œúý3Ò#6?¿>þ_Óu,š6捚sl»sÄl˩Ň0â•Õ躨ƒsŸæG#ä.ñuÁgg¹mPÿk¼§l$XóüE‘æv˜Q ?™â[òÏÞßÆIGG”HNåwÒSƒîý çâ-‚¹³\Áx„µ”9ù¯ˆs£†{©¤`öù¤J÷ªÕ:^¶‰B4žœË?ÕzfêÞÿ•§„¥¢®¿)#.!£“†a’€û1¬KÚëõÌó€ê†2_‘ã[¬{™lAnµLL#6#.µ› qÍ¡S'[o”½ÂÓGf¬(`ƒ{JÂñw–óç¦$ÛÇRuœŽ:g<®ÏðÛ] 3êød¼çŒCpê֓4¦8óe2övÏw]Lâ0W½k³8h[¡åÁ,¶ †”{ö}/l\_G–H½£¤á¦#6ù^'…òlŸ­æ¢å®#6—Ê Ù.rƒ‚w ë0Þáü~-¼ï>]¸ã›ÉÀswsÜ&…ÑÜÝÛe‰ìü§]È]2ý3„Ë4ٗ–£UtÏ[žmjpªž¤9-ÐÁ@AbŒ#6™£AkãÕÓlԕùúøoTqŽ˜4°—gÒ3,Θw<vâ‘/£Ã±ü—3#6¤39ߊ \ëa 7gÖâ¸< Ž«I…º×$ #%‚!¼|_á1w痣6ôtŠ‹3kì'6¥Œe¶>É1~¯&#Ùî+ïUÜ¿îÌ×}.µŒŠðÆ³Ó¦³K7wMïTD_UŒÒr{RniÐU!Üñȸ>mòi?]“Ðúsyü®ç:áéõ#6Œõ›3Pÿ[~´ì—ù¯§¹OšÏ.pìà?h‹^UÚfÞ|ð‰ 7䆨 DN&¥6iQ-9z-¶bêwþ{£K–Ý4d@òuL:؀ÝrŽËç}ÖÓ¶æ8\à4›Ýœ&dOË‹x”tð£ÕŠ1ÕoêïSßþþt¾þßã}¿FZ÷|iwïòÃ\EÂ^ÃÑq¼.Îúy­µŒß³Ì#Fכšcró°Ê 1J?„yŸU`< zŒôê­ 9Ÿ=(ÇV#%Û»#%øÓY]¦˜ÆÉNIör+Í0‰Õ‡”#%)aN^/X#÷$ 2ÂOaA~eœoa#%†aӁȁÅNÍ¿GõŽ‡ðãηÁ8•†ÝóÎ$÷ÍKs{üœtJä^ôeìQú¤ê(L̐#.!Ž~ž=.gm “iijÞ]¨¦b¸MÐ6Eî@ýŒ´‡Þv`­w‡aY<<ëà›;% ‚Ó3!.áé»IÕ35Ç3å·®N†úÇÓ (¯§ëƒù6‰c9vòD[µ4;ȘQT 4¢Æ’R.²aV&¤BœÓÕ¯Nh¬Fz *åQH¼Õj´$fU"Â67U’<y„b ןžb® »T†#.‹Zd˜‹K©ƒ¨å9̑‘?¼’TRëøq©û߯:ÌÑÜYE‚zh€À‘O¥òúÑ'Â}ߏϯú¶´ã´!hRéÿgÉ8_‡ú+ƒvá4¼þxÓËDçèûý]g#.ZŠgùPô˜}šý;ñšlÈ°†± IôKû«ôlpýŸHN#öþ?bpà€~á¹#%—$!!ûß#%ܕUl?Úz˜Søól]¸~·a¶Ä­Ûɘkä öjk#6vè¼]ý#.çˆÓHIH‘Šÿ{µ?¢ËÀ;uM·YMQÃÈÓ[q“Ƀ[N¹´ƒ€&ÚôunµÝW€x¾0óÉ籈×p4-œçPÖ\IÁ¸7\¶Öò¨ªñô¦Ü‚ Béǽÿ9Á¸t<#%<‡3§ê#. 2¿ÛÐs½k•!(Ú*]𒪨°©A+hX™˜’Æ?“Úvÿ)Èi0h~~ë[v[‘¹a,î͐ìw ÚÌÖM€N0Ï|¼Ùª<ÝД'Qä{jWÛö[¾¿‰ 9`±Mà®P ³(yÝ9qõEX‡—ós!GWQ®Ú-ñg4'™io/R„ á—«®Pï¡ØùØk„•¬ÈŽBé;"kƒ£s_¤‡}5fŠcfS.ê²ëƒ€Ã2 `D  §ÂSIˆ0&„b1"áJ5ih¤˜>fRàH¢Í«‡N¶s8„ˆ¬ Fe…qWžäz’§d¾5àօ!;xÀÞ>ï†ç†eÕeB-!؝œïm§0M.Î"Éô¤à7ñ¡NõbÈ>}¾X3ýä…:²íäÖNÅÍ÷ü7º[Sò„aéߦ#HáòÇéwo¦¢Ì³ÙÛ´!€;Z-"¡ø‰è’zbS Á#6ª…°ÐՒ–²A±¨ÛAp¥i²e¢TA Ð@h=Bµˌº¿ f?´5û†»›q&­}Ûrd^Wð?üßk{K5™ Ú,_Öï{¬/+Yüt1Q!%¥*‰d`ü¿­ÚŸ@R¾Ä9AžäF"ÕÝ·f۞Pàw†£|}¯ôh„ {·g =×·½¬HER!AÓË´Ößè,?»ßØ=†ËȪŠÄDy_7xÿ<íî,ö‡+ɲ­.eñÖàÈÔhX؉‚+VBG=«ÝŠÛV =¼R7–Áý.ÎùrõT'(f¡Úh»V7ʑ¤–sW´Ð’Ž¦À&’áõQN!ëMpqZ%·d岘—nƒ¶;±'Ú%1†LhˆUQú#6l}i Ã ó"™e¿¦<BˆÈ|½†3®Ü<<t¹Rð`6¸Ç&ÀvîÛv ŸyÂ8Û`«pBº¶DÆd“kOVR\:¤+‰;ï#¡s°îÝÈãLºÅ€xó rÇúÝkå.̇xžÔ©¸ë„4Úgu“"0úË!we*ñt5æ—:ÝÎ&e%•ßãD‹¬sì·.¬é5Ĭ^r)Ãg[Äb.;a“3¤ðžœX8:^Ó·¿Ÿ¡Û&Éë“Ïs^½ÛÃõwG•$fž>šWâw}wλw̸á‘Ŷò՚˜Y$6ÎÖa7Åç4E#v8œ–¹omæf¸À¯C'am²H|MÜ4!vkÿ!VBÞ†ðÙ:Æ Å]å&@Éî[ÝÈù1àô#.sžµ3/MC4XÅ#6ÅE)ë‹n؝áã´'a‚Ú[–\†£Àº½ŽfÖ@ƒ¬næ¨|?¢©£_w³Ý¨Ï¦ÐàY”ÎÀlô2K™‡?*#%a8xIéç×¾=¾øs¿AÜrø€‡‡fA#6¤–±á ·GÃM§o#.F¾™Üϵš*wQ¥íè¥T—ˆ”ñ˜›`Ñö7€õF4kÈAËð#.2ìª0hXøT¬ZÔß´åb µØ=H<àXoA#.!rqíg#%[:yléTËs©ÓT#q¿`Z×͓^!|´Bl¶Ç¸ò´©Ê=1Ž#ÖÑ8šÆέ$'`äQ.º%ì+¶&†À÷{¡èzy…‰5 °ÔmyÁ,Tí6¾$pd‡—ø(Q13(%&ŤÂBß²°Ôla¥²HrÏ#.æcΝ<BÙɤôÏÔÞ»«[°ËZPX·wouMÁÈ̪÷LÎi‚]©C£0=ƒ°X¨îuà]ˆñ»$8dï;ˆu!‚ÉÒ@0äPT®a¬xoà„fv‡fåWl׀Œ G–¿àªˆQp@©Öö›¡’”MÇ“qG{tØ&ðºSlƒ* z½39Ã=NùÌÌÈðØy"¥ˆw'ÐUÒq5¶Æé¹v/¡’Ëà24@·øl'âlȳ§w@'©gyÂvk–Ìùµ‹œÒ¢¬ d¤Í„4ôÎ¥ë|í#6£Ðà«5t¶õMÚ]î‘<#6 i5À{WÓêB<ᤜ‡”16;€¤ ²D`ª#6†ÍɈšN^D­YuQX’¥ŽÚhgLm¤»2îxNKaÊ£R+q õ(Xø8œLÎÎoE”¤hÂ.JhÚBHN_C]àYÑÉ.ƒžÅuáŽ-,\à@ Ø+ǯ53¢,UæeǙ™2æffXÛ1¬«2ÌÉ%Xì<õcˆûªjñl$0n˜Æ&z¸í ü'qÚÌQ¶*WÕÜFÞz>7³wœ&–¥éÖû½C›9Û#%!zˆlžP?V[¸·=¾Û»ÊÄsÍÑ֙Ò„&w·áÁ"TK¯=k9çÓäôzp¼m™)ðiè֚ÜæÄÙ3=êFC¾hYCS8G+}9•­ÇÏ5®ÍGÞ˜sÔÁÐi“·d%(ô#6×nÜÉBiÄhŸáIw°P¨¡%Õ,±h¨¢ ^4˜{ûw+Ñ#6Æ]Án™³ÍÊԍJ,!25.!bÌΒ[úsHƶg6|kë‡P奕èŽÐÐɪ×e‚ìëÁéë#.dӒC¸ÌG)¢”AkotcC~[^²Ù#%D¹ÞìÎBI(×¼®Ò´U6U;â´øÀ¸}=‡ »Ï|#%Ö«Õ¬´”ÑÂ7:ðäUC#6ŠS¥Áµ;’Ȑ‰èáÎ\6Fj«U*F7Û`žr¹á˜t¯äXȂë@¾v…^µš­G1)ã^ï4¡N)LvàYÎò`']ÑL„ª5m²Ý3ã}´Y¼5ÞB@-º· ¦ü¦ÏFµ&¶€á®) l‚ÐÑÛµŽm,¹r,±aòãH }3V%O2‘(ö›–„Ðà£J(‹ÐâHk2fdçqªºDôòÚy"èN‰5«Û¹ˆ]Æ#.¡¬Ï7Á£0¡ :þÿç‡06î쪻BÌÙµRÉÊ$Ç‘‡cHÃáŠÂûJ$ètU&WD9æςš*Ë!çÈÜåÞb<BÑ#.#.¤E¡Fy ha½¶E· ­38aú-á'/JZ*šV¨i4œ`hRq!]#6ÐΡ«0Q¢e.‘ÿ_B†"ûÉ¥#:+R*‰F䨎ãºq=r@õœ¾_ 9Û!ß/¦MHYˆLÓӑgq.Ôt=vü7]Xu&I¯Ù„(Cy¨¼°jÏ4±K ¨d;Ä¢¥Ú…©#.üJ”$E1ΦÚ1‘d‚€k±€×´†³[&ᨡÁÄrGÌXÐ!™"|&“4уIŒƒr`ô<4˜ÒËMkW€gÅ7&»Ó6ínS./ÌçÇÚÖÞ°‡F2õN;@ÕDf¹â“»ãUëÐûŽÀ%NÐn_~L•À ‚DH²Óf©˜¤ß |oŒšR½oªó æ85IF+:ƒ5_`d{ÎuȦ¾¿\–·\g#_-7‘èõ–ì{Œèìî"æ³#YCi#.‹×ØÊW¬¹7R¹ÉØÎ!‡‹±E¹—*.I¦›#6’‚Éw×¢½³áp$Nj$‹#.Îxy|FÀPL’Z#.š°’(̗‡nÛm&C¶#.F´"뼡%Ï·z9¼Òjě6¦„™Þ0ð¾oHCøŒÇǚ‰Š¥7L!3 „0q‚Ä#%Æ;{‚[‚þ@o $ÜÙVI6“-Ãp%A<劂O××'ŸP£ÿ¯¹Mu#%†I|E>½Êõž…8q¼D¨-ê½0ÒƘ»²ô:¢äåê=¦‘™&-O醥éÏÛgÆ úîí²]+<GHk%Ù¢˜*>ñ¬K‡¿·M>i#.$×ûwã_ܟóÐь‰¸$ëÌg­ñ\W«§Ñ3nWVGM§OUªy#.ñ”ÜY7#.ï·»·=h=BÐR´”‡gÌß»´_t=V[(@²2N. c ›!áHôØ>((Q6ÿÅ7Ý*Š…=Š°eHÐÿoµéÅr.#6ë\HîÚæzyŸðCÿ?²e˜³ý“€‡BÔVKÓÝò<`PA>B¢*£!>Ÿy5©÷Tõ.¥(¶fÉ(ε<U”vöú|G¼z¨lô!á×gï"ûN`´é~aõúCäD#6F ‰[Ûº‰7÷«nÓ6R[êž ‚P!½ÊPE.xùš®5 †#.+i}˜ 2AA‚ˆûw­ R@ŠH¡A)Ò¢+­4Õ#6˜ÚÊ fkك:·oNqï$$$¥¯b¸Îô”yØöpÕ$µ@© ‚Ò(øì¡ Þ§’pm`<lr°#.ú¯±òÁY±W,ï$ˆÍø àž ””ôŠ]CP÷À;?8¤D™v#6#bBÙ-’hÐ I÷ì{ĐB"@ˆæ|§®\¦€ú¢Æ*X4GZ‘A#.ʛِx‚{i#.¤Pd ‚##%=ÀA`|x_ä CR³¥éó4èÔ£`$‰kB1KºíÁ#6Xƨ1tI‡Åʝ»{m|®Õé¶#%¬Pº5ƒ80.˜HÜÌö¶D[¡·¯¸ê’{-ύþ0~ðî6#.ÐÀۜuHKÓÁȬ;‡Æè+ù(ª‡—°0ˆ#6AÍ£3¬%„_²Ÿ\$͕>‚&@!åÌh!7#%Ü#.[Ó]쁸F/ˆ5û"•µöi^øUÍÔdwéÖn­\¶qüŠ/  ‚êÌpá<` bˆé·¤Éê5e6Û}åcj墩i,ÚAE`d;ˆá;`‚þèˆ ˆè«UÛ4ÖÖéW¼ªÙ¬”àc‹ò z9$ž»u[}’ÌnS(î—ÁG¦" uÆäMö#%²¶×/lM²`Î 3 ˆ™ €Iˆ‡BŅ‘ÆêÜ£ÉPbî 0*z*RI‹z»·M·7©½MÍv%»´^uå»ùÞy·‹›¦;¹ÕÍË%ewh䉽#.„ºEhÒÐ% Ô¦¯>6õ|,µ•ŸÁ}lƒ@›$~×Ú#%Üà=Ó$.4¡°†eÏE‡Y $$gñ¸|o'¯Øÿ&_xr¤¹ße{ڃŒ²qõøç#Øéêô/Í9xóÏsLXËü‚ðDo™Ã7 æzF%€A\Gv‚íg–}¡õ¨ÄhKmBˆx#6I!yb°hÚùëí*×O–é¦Ïî§{h“Vø­¶¹[sU>þ³Ö2šf00$Y§Ó‘Ä·+?߈ó÷㐖ì#%OPÐ?ÂUHïjÍgy诨·«f#.¼ç• ™r£k¸,“‹CǕsŒ(lÈd×XT ‘˜„¡…#.-¡¦êTÞè`¦–—`0¹þf( äC.¸hïâÜ_ <rµXzèý¦.[÷ƒ9WlÑþDÝÇ~++yK”ÜD„Ýèó5Û­=ÇÝåó†Ý氇_uZ¬ÎûÛItï ½Œìßi!,òîh~a­ÑCåð#.ïvœ±ß“!@»‡#.W8Gµä´®M[q‘³ó'ôÿ5çc‰yΉ˜èóó\s‚ÚU’Á´ü³1,;næ)šÈ£D£lè¢{Â#6üýE„ª•RŠNÞϤ:oN‹EŽµbz©5RöóžnJ¯\E  k}ð„Gp0³5+"¾•N¤zŒ¥|JNq±z©$MÅkÔÃâÁ/H…çƒx8˜ˆSø{Qy´¶"Ø؛}¹ú+<·‹1™#k²*âªh–ü·ÖÐñÓãïí„()de1*#úå¢#ј{<¤©#6B~´0„úÑPPa­¶ÉV‹d¢6jƒl¢JŒV++-«M²ZI[Ò[YQ¦ÌÐ Š@ŒAdDõ”ü8üú—ÒZ§U¾¹G]WHsÞ"zådHª2#%È õúÐú „˜à×ùuÜßÄgõ¯"ÝV7Ձ6‡?e¹¡€ðÐØ늣šˆ5 ŒhXdi½ú#.ˆ«,Š_Â*†ƒ›”é’i›â{ÒWÍí ï—BI*@<&k(}¼Hšt¯•MÍ#.%€hkI”‚/¤Ò²fIš¯©ÓrÝw‚§º*(»w*R Z(íxÇ՘N{Òup£&šÝ¨$[j]8l JÄ*ʽ‘mî°uA}žC˕¬ ê•##%©QM¢:öï¦ ¤*$g¸À½3ÂtBE ÁP‰'H¤!‰-EjæÜÙ+šÜ¦l)S(ªf#.EI­¤)¨ˆ‚€¢“ç™÷O°h!ØÜÓ&²Ð8@#% HAdA•NÔUÔ£Êúø>|Çí½÷z»Õ‹r¦š7ËHdaÅÂ&fA=/Q…yžwßv) ß#%ÖHˆ}0!ÂÓã!ì?çîÿ—ðûoçôŸü6*‡œ9Ã}ŸâHß $Áßég‹/ƒŠb¬5B^!Õ i >ЌüÝhFŠD"°¢#誨d|M×½÷ÇNV2]Q5J…:4¡x¡²¢(.QÒHMŸnš]E>¶,xC6tŒ‰h/לá†ɏ»²Ô{hÍDhËþ8_£÷ùóÄ“õÒ+µ˜A#.¬Zb ‚¡žÿiÞ0"$œqÝ»1ñ;“£n²èÓxIx5S²ù2ûõ#.Ou‚ *}–À©9,Ê1üKûE垭è')®Á²#% ÈB £H싶0›º=IÐøõœþÚ;B ³q@lŠi8"d3¿!û±Üx#.ARúì:ýØp´xԁ…ˆ$‘¶¯SÓÖû·¿„'ˆCµ¥ß£sƒì¡ßlQñ»aúpð:r‰S²^uÍz놳ÃéÊdT$֏`ý²À ”Œ>·†D=‡ÕNž3%c£xIîÝøµÏʼiă=ÏI#.-3}ûüÉr¯ÏõÉÀÃÄ#%ÿ4vvu„#%ÍN‘‘vº÷n¼Bq †ˆYƒ¼ê…(›lÊSiLúÚ¥Äcí&b‰3ãOx±“»#.k#6P2C+Ž´ãLjAçXô9¢”pªq¯ïf÷³®zçíblS¡-§œÚá&+šíXRka\¹Ùrnj`„X#%ˆŒ žâ’¢¡ë ò£À;Ÿx‹¦h}§œ6uò:«1[w~ÿòÑ ³?Ä7¯(iHPjÊj¨¨4£QPuQöt?_‡ïbɱù*îíw(Qa–DçéýM ™ªEbyf:öõ¯ŒìôeÕË8C8èPX‰{il[ÍI~#6!OLc욾––@#9OÓçVvÐøX79° #¡Ž@úA¢•V/5MP4€0#.»Bgð¸k7ŸÃ¿ß^×ο}Ò‡¯Êùñ‹(=–côôþÁ~‡'‹¢!ÈD£v^ÿŽ#6îóÊ@²²ZÐXzñÍ}fT°Þ.Rá>çæޙ¤SÚ¶8‘ècs(Ÿ:óž‹Á¿>z œ,>cº¸½¾1Þt*U¶¼G¡ÔL c3úZo¥î«ÂÁÞµÑáè㥷;WeÓÇc¶¹åpçqF;jÌt,½ÇÙ¤mÖÙ*a\£·¶|kžµÐ/ç¦ÅоÍhŒ¯›ËDP$S ¡x7ãmš£"äŠ[lmp`¯h8x–ÁÁ}7:ÙדlíA¦ÕÐÃ|v#6õw;60ný1ljmß>øµ;Q‰šcµnÊ$[ž9µœÚŒ5)܋QžaH$ì£h8ŠâæfÏ{xÅlÔÝ.£Á°_+À£ÐÑðøbsaצóëÇ#%YbdSÎdƁ#.pûŸs{¼Il0ÜûÙR&ÌêAÇ#6ñÿBHjëP‘¹A골)œHTøL3 #%!+R¨Ï¢VAH©JÙêÄcv­>8}¥hà÷·2Ö|ÊöçÛ!ˆ¿#%ù˜ì÷;vÀ+…Ã"x%õéÑ×Ûc@­¤«x@¥Ñ ºï¡Ÿ8`Ŷoê¡ùÁS’'+ä9Ùýâ6*êvòñ‘­š¹lØ6‹Ÿ×ÆÛywPõ˜¤/ÊfïWÇ Œ„¬ï¡ëµ#.W#žÃòú¾ ædôn;vêÝFl[Ú ÷†w6%‰9‘ªM–ÛpZód½™òK[?i`ë¿WúX†šAžԄ†Ó}{–n#.˹ÏeA–Ç=ÎB:£‰ îÎhá#¯$ïR¥ˆ"Ã!ÙÙã>|÷É8Žf#.(¤SôܾöÒcC|¸á6RGdõLÅõý}Œô=H )G¯†÷&r ‚ 0Á˜ô€z•s:ñ—•wdêßË-㡧"Ö$3!~ I$ß¿Ð4!•#(í¿‹ Ó]àôö klÑü™1v.ŽsϺ&®]Cj¤„Jöm7†ÊöÚ´õŠšúAôöh†)(r¡ÊV‡T’u©£Ý55#hý~=Yäk©"N(Dï·Ká%OԎœLzJ“"À^q\øëѕX0¸°&ÃaŐ?Õ³h„FE5|øeëëܼó¨_ ë'_·&µîP5' ;ûè`õVSªS¼Ž– ªˆ­*·Us²43d¶º\ÙIÝ]Mœ‹’Æښ[]¾TŒR5 ‚²0ƒ¹`¨ÈX¬%JBŒ¡i)¹d¥ÖpìnæDp¹”f²áݳ ²XÒŠÄé½Vù—µôh´55Šf¬Ê‘E$M¯ê ï!åÄ£c#6låÑ1¥gkÏ~ÓcíÝèginÿu[ÇPüúᆤ„ ×#6Ê´—é+¥dÖm¿JâÐÂO}Žˆgº„#%¨‚#%ÆÙCÜ#6„tü¥È|lûžäðv+ªÁÂ"®Ý ÙS)D¨­ìr«– 4óI£#gm‡±°æ´Sà¨P©Í×p„ã²µma·Ø¢žÏÎu„mwñž`W¹ ¤vëC0‚Ù_·«#%b ž˜n*F¢[föUŽŽÃÛ¦š¸í<¶‰ÞNHO–Nù'ùîHÙ¥#6¬…#.¬meQ€Fˆªd°QB$J”Œ`ÈÓD©*X²R’ A¡iP‰bB‹>&í'5mÌSÀ‡aõP#.ž3¼ù­«¯Uõ_\ÊƃnëµXڀIét÷ÄAÓ¹jr‰ir%§Ã^[šõpÉ!1ßй×ÑXZÚ§TÙóYüÕfǦ³¶Kò`^üBþ“™:â"€^%GPß­:D×-nóD¿\“iKÛ6ªª§£Ú!ÚE$H#%;±Ä+†¦ûãÛþ:Á‰Ù(gœëw'`v2›OA¸ºÚ¡bˆb$(cÕ¨‡Bô6H Ðçªõ&™:å„Á[ýBðn‘6šLÙY¢’&oáoÃa gZæ4ÅS$.vøü}^Gwxù?LD(:íÔl†Ú£Ø|û»^ys*½ oèo’­è¡ýþ{o´Ò)”4±"ˆ‚EƒÖŠ"Îg™ÑŒf¯:ºJåM.8ˆgÕô8è$€ÍI¬´­e¨Ùòˆ”7Ú!ôäþF›­9Îòué¬ ÌV°WT…vgˆ÷ÙîNž^»Þׁ·t) Õc=#j7®çkÏgÔKm&ðŠßÌåܹÁ5.”SêÔÆɸŸk4 JApN:lŠ§eÏÛÆ­‡m2LÆ?¯]°ËYØ¡¶“¯Áª¤úCÝÂûªC<sLTšCvê‚­ÃA ´»†Ê/>!!hl5ç©\¬Ð™J\ ¯×¥ dHÂdê43d=BÂÁH#¢‘¸pK5Qz 5ÑZt%Î^E†A‚@–@Ȝ_àæ÷e{>ñ¢ ³<Ô ‰²Æw+¸s, "õ€5#%B «Piuô+55ƒÁ‚Ú4ÍÖo.Æ#*H) ŒBˆFõ‘ˆ®¦`Ș`¡âÏY¥­Âz¢ØÃɘj8MË!KI} ‹A#.``(3ŠU€Àõ¶­Ô&¢M•·ÊêëlU”j0À%Ô¥†-Ù_›œá烞;^Q=õ\¿)ŸI#6w¬©”H¹`Íöò€¨Åïå‘|ÙF×mÐA;8ck³èÚ{Î “{44‡ ”JàÉܙÕπ}LPCæyBM±dY¾‡«²›ábyOĒý䵒ý™ˆƒ~šÉ¹úšØà›Õ#.¼C"¶‡I<Û;úÏՋ{FÊinlü~}|ßáñBûÅÉ{øºF¾ dìàÉ#6çîà±!!1134ã¹c÷t³Ê'HœC…˜-&Å#6°ªhvÏWqþD€ÈAˆèªt@‹QÙÃÇD¹Ö ‚[!ä åRÉÒs'tÃ-‚T#%g£è雕*ª“ÒY“Kt¥ÅF"(«UV#6Ñ0&(÷&T¼Ç0}zšƒŸO­‡²‰Qj#Æ%…ŒN¼ƒ±€¤nˆ²Ÿ™(VMBòÑsýà ¬¬ãb¨LcC@! ƒ.¤ð¥t˜1'?]‡ˆŠ& Õã¶ØÀÀ¨‘i‹®(DŽ÷¨æçÌâŽõy¤Z¬Ý*BèÀ½ej·–Mdø¨Fí¢FtHFØÑ}ÃZ0À"'•¦?ÑâÊõŠhØÒ;ðdYC*Ï;C¿ ­P…Ct_ À#%2Nÿµª©°¢dÔÔH<ü%ÝqHMÝI\uª´’ß ßЌäLĦæêpÚMÒ<ëç#.­†ÚÊ8ôã%˜fL‰QÇ&јÅ\‰*…å‹01ñxaj€ ;‰”ž‹ùžª{è™<(…pю® =¬¢ÿHy!ŽwD0íµÞǕ˜ÔAc&™´²–b‚˜£Š¤Ø.5sSIý›1ôj2¶ŠEH¢ƒ¥·ÆÏ,k¬Õ=­ÍñÚÍÍ2äÁEœ ¸¨(ʽˆ„ :¡9ˆZkµ‘©´öO<שMFØÚË!Lc`0Ò3s@ï}Y÷N#6late<˜pÖ0÷J"DzØØÓˆßyCr6±Ë#%=l+§j¹0 jÒOþ¯|×f>-=q¦ûÊß:Û¿ƒ×¢ó1Èø¹¨õ’’ ^¼P“\aa£Oö¶³r@^õéu4¨’ãº} ˜xÚc4uÆÙàâ×Xgds°•;îæ"ÆÖ,_ãMþºl„áÇtÛKV¬7LÅ¡8ƒ 9ŒÀ„²T(5T‰H†„™ ‘¨Œp­_;KŠ¦ùeÉYJ9-Uà AˆìXÛIò–.#.áï#bì’ lÃIm£€õ˜U±­ØdáA´”Ã)jѹ ÒMF…Ý4m¦¤’j!6I&̓³¦&1>ì!áÞ¦°ãm.[¼R>Ø]™Ã]+ÙÒí.ì]¥ñ•éx·´®jñašJ¥-#.ÐÑÇ#6†ƒ%±dA‹af“ÂÈ­[&fVãøIå.Û¹ð‡Ç9ÝML™Í5#›Ô’#|¼™[A‹Úæèu˜‰_kØAÆ:œQB3³eÀÔ/ð°ÎÊF ws+¡-+¬œpä.Q­‚S&h%mK‡ƒOÖ¨fö¬¾ Ҋ‡·šñßÝä:yGÈ`ÓÂ$F…½"šˆ„ˆ»|hÙàP;#.aHê‰Å4¦”K_kà@Çip[6‰6y3÷ˆóxpBÿFýfÔLâ[6ãknk׫‰™®TãÝ¥¹„ÊʗÎúNº¬Ó 2I+FÂmá‚ØÙkå>)4+.b‹$馬ú‰¨Ë¶?m…ÃS>^O¹ð㍳*0üÉÍhæŸ'£~;j–0æÕº5-Ne¶F¯Á³9HßGIÚÉr,=ä°4!{nî8nØýÐë’Ùë œ~Æí:gg¿˜Ðƒ`È-@Tùÿ/¯Þ?D/«¹ÕíاÁB °!D±¡DÐE‰Ï% #.&3í÷R’ŽÖâƒ6æ¦÷0Ü Éu*:hë$‘ÌM4h@I&…M/WX(,¹§fh#6l°#%„ÌSÎ`°£X n¦yÓzÚ¹‹©i¥RJùkïVr2L”7käÜr˜E¤¼Ö¦EÇRJðÉ·ÂwXU :½–c7ãweû‰ÚŠ(AÓ×Lo®ÜXçû¡¸×-•=®1&òXËÙL9Éž‰! ’Ù}Á¹IǾä\y$þÉW¦G†~ÃE4ªm©•ëS_ÉþßÌ G®#%ˆ£sºvYBog•?’­~ËA%*j×Ú¹âۈ,#6ѵ¨¶¼TjæÕ¶5­¨ÖÕÍmͶ-V6«¥¥ÖévCÙç.'Q ÷¸ÁE5bõG9;#.¶ïY4¥•(ö±Ô÷u;ƒk®ŽÛœ+¦¤ùï4šÖ¿™D’4$‚S&e3JÓ,É)I¦)5E¤ÍAúΤÂZÒ1Q4Ô¡’š"P¢´±¯~Ü¡“ZLY%™[4)“4̑˜hEQC”M½ÝDFÒY)˜¤”–PÃT%¢Ò£EL¦FhÆL•¦)¬T„Ê&ƒ%!MA”¨ÌA¦ƒLÚcH` ‹4ÑÜS¹&óg¶§äe/è#6b|[|X&Aï~l­U_SBݘ×Çøf̈þ¢˜;708ëY!,”Ìm¯Òfvòús†Á©Ù9`ÄÞ ¬ü8Î#.©‹4czKÖãj\ ‚0Ž¬Î]iÙ¼ ¼Ú(’5÷Ðz—àmÚn.֛¨—,mDñs0³Ž¥xÂxâN;Z-_ßK¡­# ý‰}úYJÒ»0teŒ^ÎÝfw†’~âÅçãîùA{*ÂïÃñŒŽƒbm°Ç Œªd© ­…ïúûZø^Ûo³_‘bc5 £#f²V*(“i–`!Faå³><9ôí0ݽò¬X ›#6"ƒtXaÛô3³ÙŸyèNUMæçaëÔY„b’™Â†+ÏNbC 4®}û0_ê®[ç/c´y‡OÀôW¿—¼‡}#êk#6xn4ëO–åûÒ3Ï=GQá’íPœê‹+™|ÎàÉ ÒV_£ãfåÄw&}z^Ë –p{"r>Mõ£ÓG]‡eUY´#.q¨ E)¢AT‘$/rdÇ¥oKý}eÂGÝ2û¶ÛùåßXÇÆiKôôˆ£¬Ê%x4ûmÁ÷cǗ$I*#1â8-¹¬-ߣ¼8ó#+ígǏö£‡dÎ Cì֓÷µ« ªIm¦úõöÃ{N¹”`g"â–PR¨EΨ¸)µ›xãcB?+ç#6cguVÖˬ!çE®Pӊ#6Ú+G0Âè'­#66[ïG8 ápI5ö,nm_&·É‚Ôè2…ò˜í¶£·ŽWÂc.[õ"^7L³§<1YCŒu-Í4î'¼Ñ¯$º41² Úîg’Œ ®„Ä©OSååšä‡½ðæ^R°öœA虚O?M"… CòqôÂdìNIÈDBª‹´ÊxŒK'²Ùª յގ¢gd6Eõ)×FÛÀ¹m¹™—¼2ÙIb=OiÑ·,(ŸŸÕ5X@ý\µêž{w÷7g FÊHC–ï‰:ڷשÔ'®½]Æðëì±õz¼†— Ãíúëïúv“¢B¤†xà÷Ç}IÁ\³Âw¢â‡vÏ·§Ó–æÖ_¯¥ø? 畧ЪX‰@w Üóߜž5Ìíí†á#6áí)~¿.wðzŒàDà ¢Ÿn”GkBkjl8ògâm»]š•%}; àf.äIG^fP–så­3 jÓ5'B;Cq¬  ™™#6;뀛<rÝ &\?#€E„C8(p+x#.jÝ_âN®ú9pÜh>?/æåüÛ>é5ú³0ù²Yþ–¥7Q6È£Šö0¦Ä¦a i™ªF—˜»ÔÎELš¢ƒÖ¡•ÂŒœ‘u§÷5˜Ú30ÞW>ØًšÓ©œê<Ô4̵¶Í<¼ØÍ3‘©t,Å†q4hÔQSRJbã5¬D‹(E…Æð¶ÒçVL›WUޜŵ¬ æß´¥(%©ñ?”ÕKľ$–.›¥âÃ1^{¶S{ÛeóL:Ø"ža‚ *cŠ“óuo\ a\MLËhz²IÆ´lÆV#6¶Â'¿S³Œ;ٌï¬îç;WGÚv Òá8ƒ acgµ9t!éî^ Ñ´åd»Ìê5+6É 5#.ÂÉ,0&àbÛNJÒ:¤é°~­g–]øì`ɐ½/Ü,7#6ÁŒR[Ì&*_¨€ÊÐõ¡‰êìí§ž4ÍTo#.ª?02!ðnÐ6#.ÂΩª²æсóĐï4Á&:ÏJFìÀ9]Ѥ]Ò¬ua®y:†š0jæó2w67¶ŒLªL¹‚$ôgç}õ‹´n£ð@ußpBƒŒí…´ñց=,æYí?9Š@í´ÓRP±áɬ@ºZßlAsø;oˆ‚Nñ©¦™«¬•qbÐ×gÉÙã6ô¯fl-&¢<ºF!ÏOB|VvÌïDDÆÇr¯/“,¸Ú‹z"VnöÍfrg£ÑñS­ëqH·:Óº¶6´=V_è-³eßÇ®ÚƱã‚æ·mˆO¸Œè¢õ¸t“¤÷)0–ešÔj§=1åŠÎØÐà’F§1žÜWVÕ£i–7îæ)¬Rãžw¾_<ã0Ý®È^ÏP•Üd>ÃÜllg:Žûà5Úã%¬GQÄî²a…3™§¦è:Ó;1¢dÆ9Ž°„LJ¡n5´š£͚']ºß—ÊßQt×\PÄ##.'yJX5Ñ\F™Ö¸2L‘/Fò.ZX]ÔG¡‚Œ(¸jS }5#6jåVͶã]*—ïXTäÊ•Š°­óqdßûªÚöFSB™cÕ\llÏ^sÇ9*N띡Ü,ߞ]̕öO,ºK+çThu¿(vÎ[‚=e´Æ™™¹CAib u†S"“q0V^£ Zk¿kO+gX›]Ž°ÎNe6¼™_y#”n˜uÁÕÎkƒ¦©Éct9)¯Y6ª9àZ€nl8\e¢­‘±¿#ƒ¿˜A#M|fS®±*CP7ð˜vB¦šEVöU;"á֓€X.\†[DY\('¹Ä>›;Öï8‚óghh:yYz™ä×&YNڋ0,¶iQ!³é¥ØXlhÍÍÌpÑÓNVŸNځ]#. ºÑH.q¼†Å:¦ÌR‚IFÈ¡“bÓ<P¹ƒ‰Ô™ÂÀµ)>Û4=¸ÍÃ#6Y¬ŽÛëEÎ&)Ä+æaõ—Æ0[3A”@¡®bXßQÝëí*1‚¤X‚1qI—N~.2ߩݨÛháÛá£Ô7á‰)” ¬neïpOVêÑÙRQ9B&PÆ7Ês‹iõnc­ºÍ7ۃu³U·6vu†blâÂçìw‡Ûsðüa½evâæfcyž5Ù9ݬe|[Èu`z§ ۙ L>8¦²‡·¹O/ ¦ÅR=:„%›)ǒ:Ó{¸ÜÖZÍQëF72Ìf2û"t[¸—LLLb|¾ZÏÔáFc™êEæðó8™—‡S7G”´ÖQ²´ƒÓgórâ’Êܨ;ç¿©Ç1™£Wœ•· i©#\Z%±pƒˆð²ÌÝUX6嵡s2úBº9‰“†H4qÆ:jn¬21É O)&PmV†Ìâë\—[™lÖfõŽ™5,yU–LbÇ0vBŒ ¢&¨©ÒªC¤‰r# šSH‹^éi!°Ó×ÆÊ»I>ívÃ8YÙªüµW›a²EZN©Øχ–+aì'gj0šŽ²ÕUÎ☁™ìrӊÖ*L¾#6$§Ê 3vðä{Á¨·É"aNû+â(0àe#6Bu öó›Rô`h©µÀŠp PI©š,#. f˜F’èã#6ëÚ°äÚ¸c¸M­™©_{RÆ£eé\½1åf2åR;ÎZ©a®šf%‡Ã±Âb"âzÿºïÍ·9V¶ßé2#.¾¦¡#º@DE»ÎuBI‘@aàÞÔs‰¯#]Öhè P h“}”’‚•èuz1‘Uõç €tÍ®NŒzzOQ(‹¶Twqh÷Ä঴üšÄõRù` »pZPLÒ;Ì7CN]ƒ"̎̀äü#6.s׫Z҉4ý½Ø'»õâΠшä^î‹le,Tm®t• ‘쉌SR™ 3› @±0îÃt¬y\)&Œ#.:b8ô“!ËK@õ´]NÍc4܂Ó@rÖàš²e53Al2ȈbiA-’™µR‘rîšvÖºS%#6#¥ÍÜ ¶ói"2ÐÀ…°œõ­3Sd”ÂÅtvNI-"ÚS#.ó['£‘2ä`éRqf à˜d5eëRªŒ#.XsL%q®i¶L§¤n2éÍc*±<.Gâ (N¶çc²ž¥i¶m£¦ TéÂ&pL*ˆ[#%ŒXŒ*tv™‰‚mœÀåŽÈB $I”3¥/ObYÚD³»w\ñ#.»dÃ펋xå/ºï#.Ӊ\lÜêÎ#6eÊ47Uç3}Ç/™ÒÙlpNZÖ)£¢Ájx#u±¡öMXNRÎÒ¬˜³ˆÎ ÔÁ|`5Œ`pËè²3Pò†à‚f—8¬&„7PÐÖÆn°Öj–›;Ã'žCSž…™_¿&™ÓŒPiIÛ+]#%ODö®÷Â,zÜÎùèe̲¤9i 7R#6tÈðS0@e°usǁùM׉#6KÕ5B˜E ¥!UAI HX.Ëb004’ڐÏêÀóbŒ;àG±.NâˆÑÔGI–F1T*©ÒNï_»;QwW‹˜m3ŠoüòÊA8ÐTX$GaJt®Þ†Á˜`g£é®á™ N Ž¡}[aY¢¹I‡°êˆÒB5RÙÂ[#%†—l8Øqˆ+CŽûÈ¡¢#.F+2fisÄØÜ l³3Y†ÅÖ¸©Hˆu#.Íî‘„ÌI‘awmwš#6nò“aæqÁʌWÃ;‘ÂeU ô88JD61C#%CGfú1Ãg­Æ$˜±ÆNØÃɆµ#.fŠšåî äi ’q¥º£ Ã0é#. (à›™œ hLÉåJII4ƒdpjŠì•ËrÁ·i3fÕ̺ÇEÐِ™9—Fm0²jJG8ÒgtÓ^Rg~V@.·uXiØl4I˜%ÝlK9Ã00¡Ü[Xn&uA#%Š0ŒIF ÄúÈ%#6¯qCÿ$R5Á@w³;ÀiSh¦²…Ê#┈1Aÿ6¾*?g€|zœ(† íW¹ *I"Hƒ#$d‚#%‚|jÇØ?´È3$䈌@q:áÔ:7H¤ýhuF¤ˆ@„&È4€¨±TC8Ì  •î#%ƒ»-=Ùk<Œ÷˜º›~¸X$Ÿ*vʪL>ô ÷ó¼JÓhiÁ×/‰Ô'‰Ø³‡—7®R™­ÆM߬·YEr,;Bó®_}®P«4ó¸ëá›&A±´Æ\©s'M•.áiR¸k5†…ÜÖBh7„nÂ20+aÀ7èu%¶ eŽxn„X!ÑՍöõ#%c=¤×Àæ^çõµ’§4pu\0R ÈpBÿev#6h•"J¨”ÔËkñ¦[m&òRjµ*ÕᚈPÙŒR€² q¶˜X¡1H_§‡D‰˜#.o=#6“JAµµ‚ÍBp5㊡Œš\¡íö÷¬C$;×á8·SoWÇ4íUú‚*ˆ#%nùnR 6._¡S—WwUٍn»³.nºn¨-sd¯å¯5<¿Fîȵ¾*ä}î³ÓÁAáÖ<‰`P¡ý÷©¬ŽÙLv*Žôr†ð8«#6#%„†|ž(u/¼ˆqœz0g-ZŠ"½ (àŠ{̸°'ìò@7>™GÔ»ìo?6©2.œþ“0Vè<œŸ­²¾Ü?Ø|~ rÚ=¹—ÈFÙÙwE¹µÈM 44¨ÈÀ,ˆœ;Si#67‹ –P¼o„Æn F¿½µ°bhÐ1D)¦ ‹õªS@£¦n0—.֔™Ò.eÆùA2Ac¿´z¸äf$YÞЂQ#.cG÷±3þ!¬:?+xø…Ë–%êá¹A.‡¦9FòKPí?Vþ?_¶×äUi´&RkF±£Q[FÔIDL“`Í3-‚‹lXÅ|ÿZ0Pˆì´O€ïö¸ñÒ´TîRºÔ᳧zä™K¼º:ŽØk5vˆz€4DŸ+ZÂ"kÂÑ’ÄDŒFÓI0Ž#%¬D‘¨í #”E¶V-Äރ‡ âêxÝïf§PD`@Ë[΋Iß3_Ùk̹<æÑÛ ÕŠ~«Qb*H²j}šJ²a_x;wÙ$”œŽ›l[^•ÖAõ4ÑLÔdÂËp‘çbˆ7úN(ŠÒcKi"ÈF'¸„Üf5jå]*¾M½KÓoB5L­âÕÙ1‹fR–@l@ÓE`›Œ+K†³D#0ŽQÆR&lcƒ8®åB+ Ö×ËHŸyÂ˱žJEƒ†ˆ­HÐq ²@Q¶“Uú©oƒ#.ê;˜‚eK¾ü'Ÿô(ï‰éz–”#.s’ddÞí¨»‹¼è‘%Ï$¡ˆïϏë&ðÙ»#.†PԅHåïT¥Èõ¢®î°]Æc(i“°·Ej#.^&Ž²Ð†åZHšp0…“8‹ˆW‹‹ª.¢cc#%mÆ LN¨–L…uÈÍY^sŲñüÞaÅ#%ò=§w‘Kbm´’lc+A)aLDHÀ Æ-Ÿ°5Iq0]i>â k…@ /_¢Àmˆ!š*  I,Ëñ  ‡Ý›¼;âdç¬D©™_&,ŠúMŽ“õʊ6Á­ ý{ˆ8QÌ`o¨¹U¹¾NJÚ## ‘qöe]²gÞRšrE0;>Ç/¼Ú#Ú:í¦Æ>µîÅÇmcz"4ˆŠïU#.è§ 2†]õÈl0ÒjøáiiZµ}†køw 3†FC“®•zª‰¶i!KábÇgØÌ:„'5˜’bCèVmÓc{”^ZÖH8 “‡ ÉË¿+#%­Ó¾æÖZ ­øA”ËIÃ4Áùz¶^ym£Á¬ÂÉ'Gi±†êØá9E$åPš«%*‰ ÀUŒeYNÜBº1B)#6×6¦Ô9sypYµ.ݘUfylM‘¥ç—x¸‡kÈDÔëi¦lïʋ]ôŽ†ÁúÑ ¡C‡|ÐÁÅF–1#6hÊ7n®ÆbC#%ktE.J ԘDbTJ¨š Q$Ø£J#.L„@Àc¤œ#%-P$PRÄ[¼ t`luqlg¨LÍ #6Ð?Æ@  ®åB<5í Ÿ¨;+Æ>ER+ýÜɟz¹M8¤Qb{(=Gø+t Ãï ~L>±ÿWTŸª/‚¢ÒkºÓÏ ó<1G¦A¢|A]fsÕ10#!ëGšú™"‰‚d„’FHŐ"½†«bƨÚɶ¬ZÚM«Š„ "BCÒ÷©š5 Ï?=x•T\½KŸJåÈûŸ ó[ʾ§ôÀikE/³Šâk|t¶u+W…þ n.¬­…¨ê¬ÞÔrØr­$®E#.“{:iÃYÞ%lšeäʵS0:2¥KŠYk8ißjÓm&ìÙ&èd­ñv5-zÔbŠºSc³AÎ##6pšHÒ.™KÄӃƶ𤁶Ê>-ÌÞI†SŒ1d¼­ÔèËÍ<»SâKÛ¦3‡Û’$•Šiȉ3̸jMÙsy†ô@#DmãŽü¼Õ‹Á(ьíju¾N&H†mŠr¦=fÎþW˜ÑÇàËNÔ띇5ÀÈ凍˭µÝÀÆi>ŠSæ)1jnÀI™Ž‘®$ÌÜC#:¨y>ÖÞ*¨i½ðyXÛz›Mp“\ÎJùš}e)œãï3Ã&=¾¢¸É&B°‚âðÇ"íž–7•5¬´ÝÎ+c¤ØàdÌrpQ© »M=íW0ƒ arr1Æ@Æõ«t¥XE€D‹LXÄ%‚ѵeÌôö²ÒBÌ´¼›˕ôÖkUã\§›©­ê^y^¦¶¼¼âƺÜÛiÖíª ,ŠÜÔsK¡B4ªä!_ÁšhR‡M¢†:—«#ÿRDõì͔¤Dkm^| œ•ÝÅUÚì›"hƒI°’1Ž<¥jÆY*dÂK è퍃0š]#6»jí&°n•ÝuÝÅ&ñ\µëµÉ–§›®ó*òlLi[©­Ãc]¦£hÒT¼e?äÐÉH‘Ã…(¦Ñ³R¤me-¦U$…”™f±¶5¦¤S5ÔµÒ´²–™5¥™SUFŸ6¾^xMEª *f‹VЕl҄T„7–öy™¼túccQ”Õ©£â™`IPÀ€¡Q6››@‚—bQ‘Q‘P´X!º+çÚD='qí°z³ÄõŒ.‡kÓWéaKÞ9S@Ð×î6ýy‡†´Oƒ;‘Øngq  ¾ Oz³,§E™ÀËÂqhöëÏKS-Àº#%DŒFßÝOXÅ¥*jXÃɪÓm'ÓO#»;ÎLÀMÉÞ¦l1JœSí "[ÕKŒR¥U(ѐJ01!¤Uý¨¦ÐŠa•#%¨Çj#%¨)"ìØn¢¶Í¸—eµsÆòèéf´Í:ð²ÿfÂs©÷ pÝ#%H…5¦µ.Gf` #6 ò®µ2™ñÞ‰ eRD£T5ïÓ×ûûyk#.Žæñ#.ãÀÇ=AõÕê4\¸Twíé©Øm?2s¦O^ßn’õU „\ˆ«#%rãÑâuJÿo‘¢Æéˆ%òŀ´ AS¶(†L!¯$yB—`w?6Èl„¨íx3ݟb…ÍÁ‡L8o\šårEœÎD¹S¤,`&Q¶7ühÄ´t{Î+Áoœn/1~»bµxÙ#%à.jßÞ¡ö ~Ɉ0Tˆ„ªþ—¯æƹ¾óíèlodð8YGçÙ|fQ¯ãûô0*mùʂ¨<„ h%µj6¢ùýÕ²Eâì(–’eQ‰’MÍmr,¡–‰¬“Þûµk“M¥c)m&Ê6-")¦Y,¦JUÅ,µ”gå]aM«)˜lڍ1&ÑFÚ¦µMӊ+"µ+ºéµ }í®Öí^Ý»*b(2#6em¥­)­IkjhÆ¥Wµó¹Ư~í’lŠ-cd¶¶ÙH›e­n]ihÒeRMKmçáM‰´Úl¡3#6š°ÛilÚMìê­KlcãnŠÍ–ó«¯;’R­2hk–êÍRW‚ë5x®Ø”ĪÂFÛÂk±ŠË[L7ô®ßõLUšq¼ó¾T•ÔǎîRÈ´­,£›^›?/Ëá>Ïw>Bmôs'`˜ÆèOeÅ3$˜SF¯<XqIƒFÎzŸTX@÷Äñ˜…ª’×æmãœ÷_NñW{<{1’MEœC=”#%.b¤3ª#‚E À‰$T B 6Ø£Ç^–S² ¤"-³JÙ¦Ú÷mªé¶±oƒ²³KÍÚå5so›º×”ª¢#6²QdFA­ôR*fSJl)«iJ)’‘Ô,¢…E’Ö–ÍFÌRÓ3ÚE E¥&©Kmi¶i›Y5°Òš)R›|Vå (“-EeQ-%£(ÓJHQ¡´Û)M"jLÑ°Ó1”b‚Äa£+eØÙ2IdhXԚ±j”ª#6Š”ÙR”ÉT•¢’© Y#jQ#.¨µ›M !BJLX)2“ ¦I¦J–j¦ØƨŠ²$mE,Lړ$‹6Ö¥šÉ“F”’Ò›l²¶¤­Z÷Õk»VÒ²ÛM¤²Ô†’ÞòÚ×M›6µ)ª²V­¯f¯6{*¹­zÍV-¶R–ÁmFÕ¤J­*mm£ZúáÖÞcí³€^ù6g]!‡ n5Æx§“{á·ç5ª÷è`fþÆpb‚›Ézì7ùWkN-ÝðÞW ¸ˆˆîmE<³¤•!‘à#%¤yFäoDz¥ª$„>Xqå×⢵žåE÷Äô^éè†øì\$1gÁÚaž>Ž®ìk£g]7bÙ 3meÌz4º:¶š.L@ݤ¡áÈ"¥+´Ä»/šö7ñ_‡K3ü½©=Úßn9=½™C­#6?q°Å‘@P \cha!¼†„ )Ìæ]28ÐƘ‘›à¡ª ƒ(ÁW_@pÄ$•ûŽ -΄¸>õÒlÕsuæ°ÙåÈ)P;+ôø ž:ó‚lŽPù À‚.3ôу¿ŽI÷¾×‰ÅLFz%;8ã»m§f¸ñ¼õЫ´Ô¬ovÄÅ.šy‡Ëg ØPÝM±"Ê~¤}þ…b\åö2eÏà؁¥WCó|såÇéл\Lu#6“8TóT>µK‘ƒîªtJZ~ÙVêøPŸvÙÂíͳ ÏHdÖ°éè#ÅÄØÚ =õ øs«~O†Øõl£qGFù¬Öû#6¤Èƺj–µ¤7Ò6Wi0½«#._Èé}/[onӀ‹ @òî#%#%‹lj¨Ê²N"Q@R+¥rÔ'8#6Èo(Õàž ‚"2! ÖDëê¥Ñxšíb¹Õu^¬U˜°‰=³¾_vó҅‘Xdé[ž&ya–&\T•CA¸œ!Š$Œ*¨c#.ª “SLÖ`O¼I.!&*x³VÏz§@â]7ù=ý«¨á×èv#.çWµ±ç]{|)LcܚÃPó €fÛÊÖs²šD\OúÙÀ«–‚Îx…#6((S)øbî#úÛËR’dA] %Ù@ÿgìºùaZÞåe±F6ÐÊÊH‘F–Œæª&cD2LŒ#l#6Ðh{ÄC5U.mÈÁ¶“ ÄH)fáu'6ÑÆ¡‰†±ÅXƒVFA4^Z®¨ÆÎj v–©g6&  b S´·»RÅF[¢ÃK#6ª‘@Q®—I&#6–­ŠL*cð¨R⑿J“T#.t#%6:^ôtqs•èÕ(ñQ €jÔÎQ§×hXÔz´A;Pƒl|߶¨4"Ñ JÔL©ª‰‹hJ¸XÌîÁò€›`‘8ŤMýàž5çñæk±—°÷§ŒÁÜæ" k;CXx†j/zø/#£Pì|…4ÉL`ZhÚ-AXAKëí­ÚÛ­[EìÔ×9b$>#%ý0¸ Ìèª=V.ná·kmÿ>sê ý¹gźÆS®i{HÔ·t0Jcˆ*ßÁ$çL¼•·ŸZ«ùß$!›Ã¾$ë”ÚwËIƒ;àtn”l øÇ-i¥!I¡#.njßRY²’VTʁÁ[õðð™l…c0¶õ«ìXlA‘4„(Fë¹ËÈ/n•÷Odçèʃô½teú‹&YùA16ºa2‚e8 ÔÁõQv!h+åËbêÅó¿r@Å/¥)Ɓ®)iQÒÆâO±¹9&íBø>ÿ|­€É­p©*ÚYKmj”i!´ƒ:I$š””žm­DVCCpš€P±Èc&P1èó€´âÚs½s¯gٙ² .Û!›H #6áPªR3ÂxQȵßxǙŠ¥ƒcQ¢Á:÷Ts‹ hiß5¶JÆKF¤„ÉÃ'3ÔGÜyÍãsKMûé:Ÿ]û`‚ª‡§ ÃÂ2‰UKՕJâòÌ«ŒÏZ§N7~R±î(: @"¡ÌȡⶶQfíf´Ä‘ÒiDÓ´ThAŒ´~Œù~ÿNè>‡—èëTšPå›úÇQpº¢ˆóG‚Çšp󠥀CaFE<Q#%,ˆ2ªœä°®Gíâ&±û¼á9Ťð;õ1A¾¼uŒÈŒhœ)¹¢`Ûk­„NÑD’ =ó§#.Á¹üq ¹ Ž[tcv¦¢â#.iÉÆLjÆD.Ã1ì˜ÆVí¡¶&q±"J5†Òë`̆/¸:ž”¯l’F#6¾”R¯OQz‹#%ñ=;NÝÖo+fy*wÐ™¹çF|û Å"TX¥BSM4…DB —¥×*¯rïšJZÀeE–¤É@òrÎf§„PÜ\/èÆQø#%»¶’(tWx.ǨÚP QՂ¤BÉUN#("»ðX¨2#%›LâF›M`”'°fT(#.à2–pâ§.=ZpË×v3œ{×raY &&´Ú²4î¤G] :\„clç¹¾,u/Ëß xµî¹anGÇå¬$46×PŠÁDùkŠ‰’It¼îÂ2žv¹ÍÄÀŽ+­¹,Òçžu ñ<xϹ½eäŒmŽ "#%$lŒá­`Ü1R Œü{n×z¨¢3D¦ë2ә#.䪝†êí¤¯dò“ê߆¹nŒh/‘!Ý­]ñžåîî¶ØnéŸ-ü:»+~A8uˆëÈN3‹5åŠP«Ã p¼Cmí$/R«4²¦ÆîÁ,í1=;ÓPp¥'#.¾>Œú UGLc0õâu{2=AÑ+½ëÜ('_¹HCX=˜DàmÆq–zEn€ÆÅ$ONÃ-Ž’¥¯Ë¡e¤šÈ#6¤ÍSY}Ÿ—ƒ“¹‚YîêúÑ#6I£åíª† ¸%Ý£HÐÍ?]‰$E­/]jôåå˼n¤Ûìnș”HNõæ½Z½jé%»mj©RC¤Š@…àmQcš°^:wn) «—1KÙ)yš#6†­QŠÒ€4šlß·ºw7¥´D9Š;¢¾âênïÕ¢ìÑꙏ§ëÛÄtN(Àºü5šîIåÖïãrBÌ©[æq‚_S¾®¦Rg¿s%_Ɨ¥àM~%Db+)'æhwJM¬0…«ö5¯YFqtªÁÏé‚ "懲‚:Ê­•½Õ4Ñ´L¢‹Z®Q•M4šjW]6èrbK$ج[FߝVäbÄVkãJ*¯KÒõ-kÆ嬳oßýþñ¶Éki¶[V½*ÝrttÊ7ĸeÀ ®h 'kåŠг)ôãK —]¬Îe´"„¶JJˆPÉB7&®r°„2ý(-„Øo)’€<(˜ û7 Îu¡¬²h%,3al!™â ¦±hv>¹3Ù]´l4‚„}»ÒX(¸ÐÞì½qOt”T5(¿åiÀ’¤(‰º#8+!iH@ÛaSòÕ*ŒµVzPT*éd“W˜fTp9°ÌPð5 ëÖàtïôQìêª…¨…E#5ÝvÆÓ"£I´Ul­#%&°ÝíÝ+Èt00p‘²Fù`Åì&á—,܏}C…pÀ×t,Våp¨CšA2 ¬ ÛÑo¢|¸¾ÀÞï'´Pg=b,‹q¤  B€=cik=A’~x#6gLüqöÿˀ.×HšÂà\‹h]IÕíø1…Œ‘#%¨%扨&?¿dÒI¡ÏÊçÕ~¶ÔØ;Îáâ¨Ë#.ÃÀa a‘Qúùh€ŸFÍpA24‘» Mšjÿ-ŸF?=+áÿ‡ûRâl~C~˜œƒ$4Kç‚^ˆn«&߃Byï‹(íê`=4ñ…x(«C’~¿´ŽA@TTвÏa81#6êå{œ êÒB|<Luß»¤/6ìÙýžðéÙÔ;ÂŒûî„€pt6žøSTSbGz¿Cé¿Êw.;=#%žd#%RIí #6J¥*#6¡DYX@¨©PPfŽôlY‚!x¥EdBD “b[’Š3\0ù_a»Ìˏ÷¡ƒôq¸Á™+£b‚ÓIbÁNQ²Õ~ƒ«0ŽGqÍ9Ÿe±ìSQù~ý£Ëj± DŸPõ$›SҞԣC N/P¼läV_Òþ íUAd‚:ƒ C—â[!Üak%ªE IH®^E¿Wcâ|s ¼R¨ÄÅgßêóåńàX!`≫r'ÈàPë;OyÜbPWGçÄ>'¯—¯ï`Ãæy~6×Üߝ=a§,»rÞtï£ÔŸHÄT̉I9¨™¦¤¯V–¾T­ª‹SRÙÍTþ ËÁ˜I¦ƒúËúPцjˆ,TU#6©3û®ÜSE,#6@¼•I#6e,%Žì†€Ze¡Cð@ÃQ>9yñþ_›¼ï€Õ-’­6#ÆD“ca]‚ªñË<>ÙZcm¦É\ïg:F0¶ 0#BÌ £&D®¤ÍeµÄ±¡Gf–4'ÔF4Æ҄qI‰Žlb-ªÍå†LQ”X(‰‹J¶™*™Ef°‹-œH#.Ԓ™a4J@fµ@¤ ±I2ÈPµ›„´Ù’œbƒb$]’ÌÐLïR`MS$’•‹ µZLibm-äB1ŒŒŒç+–=B`HVZM¨“F`L%¥ª¤mV>Lä±¼xa¶EXVÆ¢ÄÞª²¬ ÕÖAÉF¶áÃ4gJ’Z¢‹,j¨j¥0¤…'6Ñ´®è±\·6Årܾ#.ãc^»½.4<ºí¾-“¹1Šç4\3•¨lêApÌjÓ´KŒ&D`:3±ók0Ó,$i¾K†µbc‡,P¸yA®5&Ψ hÕQ.šHº5@€ák[R²°ðÕ5O<­#.ŽC:Q¨€6%Üe{îË]ƒúÓN×Ò!£ Ñ uP2Ëñ»h|€úim²O:“4MiãÁÖÆïØøÈxÕ,#>¸Òc!I¬ÆñÛmwºòeºÍ7YºÐ «áùqüô”Â1Ó ÍÍÓ+p8ñö¼þ#.áߣ .H(ô MT؏Ø?9ø Ñ 0€À«¢¯`1 «þ8÷‘A%Q#FååljT²j,ªê£TI’ñn’ª0±¬QrÕ]JƬQ¶ÜÝm’ÓDbd”@b -eAÔn*¬Z•$A$TɸúÓøC )È°íDÔ@QHXÄHE¤Ǽð?ÙÔX#.Gꂤ@ƒÆYÁáõ×g¿Â¬{S(±ƒk—Ùæf¹!¡çò«W²®]¦Ûnºë[ÎerZOºÂ¡.TP¤IËúìÀ&#ƒŒé¹‰ÍuÕñVã1 Ng°þ["ALàlBƒêŽPoÕTBD‘WáU‚š¼ZƒPø¯4²mdÛÎÝJT²«šæ·¯¥Vò̈¢Ù+Xl…TzšÅŠê»ª-zjö»×‘/]nË\Õ|š×šZƯ7uY‰…$¶¤Õ©3J’ö÷í¶ØšA¦@¨¢G¶2<㥩Xý|º!ÔÑò‘kk™E{”\±È5¨p¯Ê‘•E.I#%}3@¡„ ‘„Ë Á±“,€e rIcÇQ4×´Õ0NK2#.É#%½ Žçì”è¤0#q ÒòœMŽ›ÇnXq[‘l'µ}Ò@aš%Ç¿¯3Ëš‡74Â&iGÊ<Ø!DW‚bUTŠUð˛Â[åHŒ=TvU Äh¸¨Z7aq“P׈ñ0»¹aÌ°oˎuÍ>¨½ ¥ECOˆbȀ(¿ˆ|³”Mî®d=` T6qÓr.À;Q$!îa^ Ò¥#.-T””iKJTÕcj´×¼®ØÓUšk)êWQ´ŒE%D/å‰Ðñ9™‘çÙê°Ä@º5]°;c{nÑ÷µJ*ÎdBdñaöü’6µñ³'¤.ÿ¤ˆý¾v™íFqp£FC²êNº–3ìBKŸQé£4Ó]®“#6¤Ó‹‡ý#.ËÌg8¨¼±†bCÖ°¡ :ëŒÃPó¨êÎÉ&&42i•´PËZÇ0Û#%G{ª" M18=ɉÝGÜ`‡+hƒ}ñ¡È*M bð]þáñOC×ÝXd’I"BMçQýQ¹“‘ì<ÏÖônå¦F^Ϻú¹!}zæ±Ë`™ÉûdšWß#"‡ %54I7L0µš…°3'øþ|ˆ@å¹ÉY¶çA#6?KämɃ:Ž’®MœÓûlp(¡©Ð̓Ò¸×V¹ "ÄëˆÔ§VlÃ@,×j°nÅF•@ˆ$+û™RMŠ6SHDÀ˜B0 D¢¥Ø#P³N5X©Õ4O4D1ö͗á=ü'§1ÀÁ5š5Ò¤”{Û:ðeQÃýi`êñ×K”ã;4Ï×ú´1$ÐÑеÊc£çF^Ó#Ž¼ô=¥ØΤú¡©“§A>iéTSíMZʸk2Pù|Tà€‘¨ðÛ‡’„‰Â5ˆ¶PajJL–i˜¶¦¶–¤Ø֌Œe5ù¥tA&‰•2ÒÏØjܶ¦e©²-,Í`•³LKlÛl­6³Lµ™m–$µ‹J"©µ3f«4M5M±UQli$’1H³$#.GäiGåL"±£æÙ8î¸l–Ɖš¸Èéáü)D M´VµÔåV¢ÚÅ®¦µ®kvo^aQƒoѴצÕû»ËA'"vC¿¯†€œ#%#%ÛFȍD*TK[›R]Kí´·µUøˆm~B ²#ùKÐ=Q_fÚÈH†EQ ÆGúZ#>Õ†–aõ­óØø„á¼ådzApQÙ¸»h¥âB9¨!áOGŠk§!€' %JŠ¾ØÞ!¡ìNHlá`G´>ÒB ‰zAm¨#%û¢Ü‚%íKtŠD©ìByìçx‹Æqä;ÏÓ×8Ï<Iµ#% CÁÕPÌŌ¼Ð“yzÔ´àµ!¶7$¹=ˆÉ6Ý*a x—2š^³30xã—è—pþ#6XXPµÈ…p>W·ÑëU8;€¡¤g‘ê&L‘x‹Ñ;ˆQÄ7V«Z֐‹œKš“è6˜x#6ÅéØ¡›¼ƒ¸€p[1v›*®š@âƒ7̨‡·Ý£Bò8#. Ò\Ð;Ÿ¤:háŸÜz°žp!¬a#.DV„††‰#„mbL¿ê¯(Ó4tì!#6°I£±…Oú;N¦Ï”Rbå.¡÷Ã-+?£VF0¥VªêãìŠ~}мáö™mFÂiîAÁÆQ:ïĕƒ#%>°Ñ#&’!ƒ¦-ŒcöðtL”‚‰!/Ù¯9ãvþWà¼è¥æԐö€ršÍù[ë 9+ÁS:~“r˜âúýt&ø-tœõw–¼¤¦åÆåÒñL ,˜SÝðð4Ç]«Pø¦äº‘C#6(,H„QX€ŒPí‹‚ÇéÓ9À“óx§諒#%2O‡ùæ&ѬH›€ø8ՖY!D1ž4P)#.h¤4–ÉÓL*vƒ#6HÛLMûþ¯ŸéIJB#.™žüX11¾"lN9anTG§d#6숒6«Æ%Œ­  `–6‰ØÄ´wc&µi︷l¼C#.@6dÏZ«Hfh…ãëU)%E`҉„c JO´'ñTŠ¨â*cm¬hæF‰&(}q#%çDBŸ ;s­R; SÎTyzg?~—<s/T– œ#.\/lëã:Þo\™qŠFˆ•(P¹¨µî€„âð8' ¬J‰Œô*ƛ‹›%S ×õ-ªl;w£DÑ@äàPƒ@4ÆB ˆ‚¤PEÐBȔÅPe'‚Î#6zx¨†vi=>~¼® ­QÐu€}Þ&`†]|Ñ÷N^@ÃÕUBÅf€ÔUÐª`EZó}MI¢#ðGðGù$=è‘ŽÞ;}%¡&Zi‚Á]ä4¸¸fÇfÙ«EC–n¢ÉBvP§`¾Cqh—„Š\5&+&ÉWsLŠjFà|Ûùfwâ{àrTPœÙ#6`R#.Õ!æÊ%•‰r)(#6a<,<Ï[މKž:MåÊd¤.óÏ!Y;0•UQT»¸Y“™¡õñ²‹"‡½®$D0øBR0Š!ÔÜD½.Øbo’ìÀ#Š]œÌš T`Áѱ†É"žˆ.)¢†èÉd­rf5Âó"^¬ ž¿îi‰hˆžòœŠÝÝ%|Á#6‡ÓeOuB¥´àÈ©PÚW.T²¹[#.½i?†îÍL#%Ez¤#6©36¶~ôâüÞ*Ž”(›Âý4Ƕ¿Í»CVnÙ=è¾»VâHfmÚ¨·aYe֔ je 5VWE·[Ñ$F¥”¤ŽÂB°ƒNÄy3ó, /¼ŒXŸ¼™½p †8¬§gdpŒ¨:©´>j"ìO=H£EëeäÎh ïˋ“§ÊgؤHޒ–%?^uÝF§·ÙéV§mTS±ÄºÕ+nj„ÜBðôÕ#6´×9Íâ„BröÓ,à¾81rÂsÚU:âæìbúékÿgÖË:¼µÜ‹|ÖƲ:Š#6K%$—,è`˜#%*¨#%A DP€ÐȊҥh€#ͨ¨I n1€l+p<;ŠTÈ)í ˜©Ù¿Ó:þ°UyónêïæÔe³#6ÔeëÇ·VÜÞQöº1ÈßÌÕ×ë2Q#%dd!C‹ÇBŽbuðE!¤G³v#6Ð($«U‰`ѽ­„ÀsƒqKòƒÙï Ñ£šÄv\5Ê ÎÐHÒž%A#%‚‰Î|É:LòOB§¯ÆŜN¦#64 / LdM´¼íÍr¼ó¦ëÏ5wŽÚëm¦ÖJ­I¶ÒËǒ›BHTˆƒ*‰F2ÀD#6 üÿ_¸÷J(-ƒ!þÚnê֐wÁrPl ´ W1¢Šª`Gñúnî¿«Âb£ Œb´Fϸ•­:Ä6Ö4kR&'Ó&{‹_¿´)·w¶õÚV7t\-2á˜Ö5bB<* ˆ\K‰lH2Ym@¡&©€ª"Ó-PÒËf{½•nçˆØé¦{ÚG.®ÊÅz¢ç±¦&#.œ¼zPšÕ1`W¨¬PÙ²‡2¸ÛO!-Ý0éà›È”fÙF¢D$ #fKÀ0‡#.`—ömZhmmèؕáͳŒX"bͲ9Pí( ¼X†m–ÌG0Õ.à£MË쀿˜â§iÅLüI!1²Éb;EP DüÀSqS¿•c²vwñÄä'Ñ祥ÎUñ<þÞzªßòNu ؈›'úû¤ÓIŒáÂfÊbWGq'NÄöP”!×#%ĐI¾åmøÛ^ef’ʍd­‰–’ÒjØÕ)­}ʾÖÚL®»U?OǗŒkÆەÊæ°µ0}½Ãސ^“xÇëaÎ6<îXJ.mèÚ¦Òv¨"«Om¬Õ¨}Pr)N=\w†žü²Ëˆ«Ÿ(ײ|J+±±òT-ªä`Uí èvÙïIðƒ{¨óÎ!WžâÛoUx$˜§áUýÇêYÐYy¾áa©<–·ØÍn6˜I6=Î q.ê`˜Â÷ývǁ]tú¦øo¹ƒ +œM`sZõQ4$n@âtÂpÅ&/m…ÇãîHF1מwë߸Æ,bÅè¬ÞBðì&Ù3‘°kŒÕ&˜†72^A#% •·4ß¹çLÌÑL´K3Jj í>E/Œ»ÛêÛçÌÚA!~ï,v7ÞÛ¯é#sµzø%ªì2t‹·‘ƶ€BÃŠµŽ -úð*¨ð ¹FÇò,¬ðç" sž^ÓÅC^´GÌñUG݂!p6m=ßmÃÝŒ#6NÓ0¨^b!”d%]±‚-Ê.ÛJZʝ0O ¾^!‰¡ÖÂ0ןbí‹-s¦µy䃉Õe‹´SZ·°òüX›K¾fsMÖï%ç8Tb»üè\²?}{Þ>%ËÂça‹8ð‰øqgêd;1Cð™ )æÁ… €ªT'çd%íBnpŸêá·>Ž¡˜¼»f>¥ó‰èÄyKp#ÃææG³´ÕsmGyç…cQ®»·¦Ûš%¶Ì\U#.¡$‰HH0‘Q·™KAŠCo·UïУç»Rˆƒ*·µsà$.?çû‹õà¶Kª bÓ\µ…‚ň„aÇY2J2ÄTX’ (·VyÛ¹ÖîuÞªZÛ¦Û#.1A¼A(ˆ‰ð ¬ ^3@¤dâÑnÀÕÁ£ò—ðt£àyžˆ“Åù¿r=‚÷‹·EI&þŸö01ü›„$Õ¥³º[›Ðö"û·'Ã4Š|·låËMÓGÎòçQÝOg”C_˜ù´4èÓwA0Cf±eÂEÃpÑIå¨GGè ö’à$끪U˜èt§ÝÅÈòZ­ˆ¿0óhäk>1"°Õ—,”W%ëFþä;ùq56z{þÎ@ @qôÙ(”yCScpô_{J!0£:tª4‘“™QZ$†¸ê×\×v庺ͩ¦¬¦ÛNݵu&ÄÚÛ4¶«ªØÑ\¦^.^]ÚVòµ¾l²„@ Å#%C@US_B„Ä«Ëڔ­5ê)ALjºr·S9¬¹† 5öTX“lzï€ÀÊM‡†u>#.3ïk¤ÁÖøûí#ÂÈÉ j÷â ¿«G„í#. Ã0¾Ãn”º·JYUiKí€:ÍËažÛp¶<h6Ú`g5!‘5‘È0°Øzùp՝ŒH¥²”!ÍíÀuþÁë¾pS-VÞM¹”dmÐL¯Ü†á¸6uð|#.ÊäÊÉÜ @à{&ÿ}v›uˆˆÄE'™sj>¦þZ2nǁË׬-å®Wߢæ #%ß`+Âގɬí'm'­·õ#.|¹_úuØÑTF#6Ì5å*oµµX~ÍóÂ\èÄgi[á4Gëk®“]ä9*éitQ™0#6ñ'êwÉúgúÿ§îoÛ`§ñ!(RÄæY} _’bû.“»áÁ5Å(,D‡ÙéPºRð¹ßSX§%DAÀµ¶&Œ‚¤?3Y{ÀZ$*Áöm™˜k_ªèzÔ.¹#mäÐl¨AAì[œv,€aÈ$ºvÀ¥‚+ã'C‡-®H4(an~#.ÐÅ¡´ÁëX> 7¼Pˆ“Å£Ÿ›ã“Fs¼ðE’Ó£pè&¦‘—K¨€ü~iÿKn<£ª{6±€g™TSE_çõð¾ÌϞRI'EÔ,Ìï‰#.™–ümQºC^[ò†#6Èì<¶’èÝPi¥ÀûqL…ñ =Lo³#%{BhÙë Ò¬Ü¿¶lÁs-†…¯¢jgÎ0‰‡€xAËÓ¥¶ßgLeXd¬b‘…û`Y)0(ϐQ3‡I!…áô®ÔùašÃŒý¡ø̽™:ТIÅÔeÁÙ)ýՂÔ<=±®’áÐÁá†c),·[I _òÀ3r^”B8iý5³V-êWBÆCGµ÷cHgM‰ardæ7ÝÍO1U;žæf,Ý1!„Èk q.‚ìaì£P0ëO¯võѤÈg õá§NJ±ÐèO5Ĩw¿€y ‡ˆr²þÊçõm|µåê#%ĨƒÂ#%p+ÓUC'‘ÕG Ìñä¦j&¨ª™ß˖ ¡!ÞÀ[©#%¦B‡½‘OE«¨¶Ö+Q´Z5mdÆ©5£Y,mb¶ @¢²*TEMŒ2…Èì5W‡Ùn—¹\ê4—"Ԗ* AR‡æÀá¹Uz,.ã`!i ÅòìÚp:6ßvýøg7nYÁÞúËÝ;«Üd(]Š)5«=:™šC÷«‚Œ7ã„-\õûn}ªcâÀuÓWCÈ2ùmFm’ CEli î°2d–S ~Õê(‡åíOyÖ!¤ØwF¿?´"„Œ5jùíÌ<ÁCi²”R‘ÚPl.@ä#6ê%ºéçÓ5„ÊU¨ü=¹Ñ®%O™×?#6\¢p`v㋜NJɆ@;$™Ðs]‹_2B‘ªPôÐöV⢁ßÌ0`Cm¶¬×7¶Ú9FD‡·7|Y´&©ªVÍ,[þ}¯]tÁ(L:’"W. {Ž§¶@,ϬGüÛo­ÖÍ ½”(TÐJÀÕs’ª¤ ó £äI/#6½y³ªîfx²&qK¨*.‘qß<¡ˆ¥¥LÒ®%–Å#6eq}Kw4(#ÔæH€ Ÿò*EZ#66°Ö‰Ÿ-5¸éW¾`[É@DêƒFq#.በ†ÌªMZ¡Pwgåõ{ö²Ÿ7>Gcúìcšò0Ä5™µÕÔ⻝×võo1“kpÄ&Á|ÙôO«Y…ñ–¦ãQè‡î>Ž#.zޓ®ùŇ'èkj—©a¨‰„²ÐÈTʥȔläÏ$Í íB…mÊ=·e×àšY bø¿]Ø¹`±#%˜ ª£‹.êLãžÅÓ?ɧtÐnòu#%žNÐê„Ø€L8»1²üÁð¢zÏpÝ#.ž½…Ôêôn•‘êÌÇʪKq·t/Bª+5֍˜kYfŒ…2ÉUBÆÐÀù¾Cˆ®YIô ÙMIÀǵ܄$“Á¨˜Ø:¤Â*š›ËuÖηL«w]¥#jff±PÑh×]uôÕ<®óõ§½æèQfðÀÆÀnBhT¬ci0xÈ`hpTZÔJÄ0`Ä28Ü«hãÕJ!ÁÑ­S£‘ ÉLkLD²üaÐ6™Þ(Ú߃pHìÃW֙û%°Dûo!H¤HI¬j¬¦ºUÍôM̋6J´¥\é23Í×Y2¤ …r»ˆàd­¨Å ¢‹Š#6&†Û¤ 3PE Ðî÷ZH ¨ÌÝZ@Œë ²Ä0ÂíV›52‘ ¥l¥f†Sµ$‘e6›,Û3$ÈÛe-/]Û˵riݲrAfë®[sNݽåÍy¼ï"h¡RÔ3–ùýw³Ù› šf¡å輸÷íï¼öÕæ"¢FJ°ë¦2†–šÙˆ¬ˆËAÁ\µh@Ò4EÙcÄôõf1ºÔ6#.j*Ócq¡¨ÑÈ0À×ÙUkH°[yÐ÷´IòãÁ¤óßQÆM¦Òp&äbÓ\3 PÍֆúÀ4Õ½1ΙóEåêÞnՊ ­zÚéEF¾ÊËIµð[¤ö#6<qêšTU¶ÓuÛ5!(£ƒdb吴 ±#k7 ‘+®6½ª\®¦øµ]ï™\†÷¾’¥Y•â²"°£i1 yŒ ic$I˜Ùi%ehCÑV‚Žc"sz(ˆ¤ˆÝT‚&0ÝÜD1§~/êˆÔaáˆenÃ)±²á™i©Ä3aCwc®<¥j[J\Mb0s.#.ç¶ÖÆÖ¤2Eõ5Ÿß`i’l(A£§‡£‰G½„MÙ·¥2AžTÍn¦©ܞ­]ÏDO•µ3JiAÓ«Ê_¬­Ý»8Ÿ+ɳskhÁÇ gjF— V4Ò.#%ÖcKlÆöõT•MžX…,A(SæX‘ôšçzGí ºó2Ìÿ#FœÜ4ĺf#.„ndÇÕ|PÇí÷k#zLö1Âf˜Ý—֏d6róo?v:WGƎ.Š5Fcmäå…tÈWӐǰ…š1¯‰ÝqƒÆŒM!j´•M¶Vo‰¥Øz¦øã5 ¤§d†„˜vÎUjhÙµ†•#.\"ª9lT¡µ=³C#-‹ÃqÓéîó}&°Æ0#.7B¬¡û÷ Bì¤]”¬‹ˆ&Áê$åÜ,eeU»cõ ¹¸GãO8a¤)¡ ä¥P4/—–ººët֛{¯5E]5fTŠƒ@Â& Â6: é `"0lŒU,P]§DÂQ %Ħÿ¸ „tàtë=A×n¸Ø nìÁìüô³,8¤è×æ¤EþÕiqu#%­T#.Pæûqb¾e4~¹(ÄHægÞ·›fŽ='³¦ÓO¾ï×q6ø¿yÃ&ÒVý?²ç‹ª+lMHŸÜúõCÔÞ±\öÍ#.hÅ#3ÚÚmáîÝÔÉK#{{ºNÅˏÖåyºjð=šy½\ÖM\l¹Ù‘K*̵ðòJpð÷uÐôÐïÛjØÍ-¿kÙ»£qFb!$‡-ÌÌۓ¨Ù¼è®¹ãÌۄ˜F6qÇ8hPhÂ,CöºÂ7ÌÕふCdÌqÎám#±•M¥„ÙBº¯¹yÐà½ëš|÷3¿y‚!È7稺(4Q®ÛX0“wù¾ƒ,h#6?äè‰!“‰¸\£Êo/£÷õgg^i¹ã‚íÓj#.M,=6ͪ뚷곐xFpSÑ4¦ì¨‰–€FÛ,„š~¦JôÖ±ÝrðÓ+°iá³Ýdý_>÷Ž„ÖéM¨#6kf©l#6Ì놡Å)”êýáˆ{Á„=óùœû£‚{ vÜé „R $T@›‡Ð# *Ì…°´%Ôl–#%ú H‚š›*GåB XtL„,³:jU(älŠFÒªŽ‚® Õ`]›[†ÖéµIµwŽ‹bםr髵·6îÜÈrêñµðË%‹H´ŒT©«œwUÝÚ±Z•¦¾+Uã[É[Iº@•%rØ¡#6BKI€`‡šW(0ú6nün°££a‘I}ø«Jì¹X½9*–Šae(¡Q#P­1EŠZÀôÉŒ.p»Rշӛ͗Æ×ZïrÐÕâ¢%&±’X‚Ñ %¨OsË}2†±P”BTBˆe„EªR–¤_ÂëQM”ZÅf&i¥E±¶5™ŠE¨¶6³+Ó5I²Y”LɉTÑDmLɲlklÕçjº7ैŠ9Ÿ? ÉïÐÐ>ߺDE‰OŸjÚóÔMª+ RRËð9ì¿âŸ‹ÆýÝ^lx­êþe˟ÝåEÓ¸°zÃÅ8ӝÕÝóa‡T9—ùhìž !¥ŠÖüíM6´”ÊѾ‡7ѽ]Bͨûf·äV·#6µâ×OÜêê F™æî¢6Ó»³®µÝ¤¥­¹ŠŠ«Knk—5]¥+ZV²½vìÖj(ÄJE¦®ÏøHf;ÙYȌI–b2_l(†‚Ñ$˜‚D@ Ä:o',À’ÕPBMˆÈ4p#6¡a#.§gW¶¤¡Pm+œÄ4ÚÁ €™—Nκk‘fñÖ¶!4ž€õ…>ûµ>ÖùñkÑ6wЇ– äÁí0Ϻ¼è¨…Ì]hÊˆ°Ÿ,Ó`ûO]Œ‰ÿ3]¸™·7µLÌf7?,lc]̓MBbAŒ1H¬µ4Ýi†d8w&ßNÓ)Ĕv»Æ#.Áàu?²æñçãµì! 5éá1°<¦ˆt2b²tÙðVþ²ðæ8ÀU;¬"Ǒ¶C’}åtȎÏë“|w½µ^]™3aÌ8fùã—=ù6´ì§Í„%µ ~¹åšÑ¶»zÊW\=ÙXÛÔZh¸Ïa†°Ó(±Æ™må÷<H°UýÒvЬbE“ȝ#6NÁÛ±=ôL~+"‡õ†È„eÛ)·‚È~ÏðV<0T‡&*ž“2ÊuJÚ©X¡à†÷BxQGš`…×Øhœ Ÿ-“T–­ŠÑªKo•/©ZºˆB2$"cü„\¯IÛ\â£rh¶·’{:²Ulm¨Ú¹Uˆ#Ÿ”U#%Ÿiy?Ò3vµÇ‡$eù»#%ˆb Zü¬ßàTy„/o\½Õ.@Úº[%´×]§·-lfmBÑl@Eá1Á¢#DBùRÈ8$j©À\0z¦Fü¡€¸ á[oZµ¾‚[[fIŒl•m\ÓX¾>Ù*¼î«ˆžË¼UÚDFÒæ»É×>µž¹éw“W–Ù’€“€œãKÁhã*7j*”™A#6´¶³V¥(1Ä*ÛAÍXU¬!R#. aS#6$D•Q#6#6ŠÆ,ÊŽXI˜…vU‡ï€DdА„Â%¢¤€äÄã0õ‡ázâhÌ RƒLcAA‡¬–T#.9?³¿Ïïç*®·€(øhyÒ]aöàŸsÖÐa`ªsêpÄ%X¬gՙ3nš#.Ç#.³ÈÂêH9F1˜ÖKQ·nžíùîÑ™ÛÌ mµ¶¾©kU­~[Â` #.Ä;@¸ˆâ@HŠnüÝ¡ã¦Qð!¼*‰ï'æ£[£Cõmþè¡/C ;¡ø&©“òƽq‡j¯ù#%AD^G9ŸÐÀÓz*‘J#.Š¬¤,XcÍ#6ŽÇ+Ìf¡„zœ#%fθåC8>yóvoÖ¢ŽJ¹ÛïFØØ鍔8ꦈbCDÐ#%ÅEœ7áÃGÐ*‰¨á%ÎÞÇ ¢tºÄ÷Å4Èn#6½¡1*ÃM63âqMí€!œý!ȵ¥ð¨W¬|TaøµX#»# hLCZ¢«xbi(6³‚Š±tŠ\°èYl…ˆEX#%$™—p‰4b9&K“`È°y~5D¼_¼ #%¡ôˆ^3Äê;HÓ× XïYU[ï"zGEM“pùC›ݑ¶Íêц|J§NqÂIß.k6#.éï?XC߶ óð&‚©UMÛWJ(Õ]Ûeº»±š¿ºÄB¬€%Ÿò\;é(B¢ÔÈîLgÇõÙüÞ­ôÛWÎôNÝWu\v¶Âegd!Q‹ò –Bt?g> YA h7vgyÝ\º2嫆”uÝâòœÜËÍÅfË"i$l&ʖ£ÆÛ´Û&‹S60xÜMæÜ®U͍Üw^vo.Üu×l£ •ÝÛ¤W/ñäª9¦Ëy<Ëurîk2Ƈnój•hÈó¶Úæ宛VKhÔ¥ŠÎ·)³,›'ŠÝÝݧ5wft×$RќáÊ»eγQhÑÊÔX¥"µDh‚´m› ¹¸#6XTbzà„vA؉CH#%ömõoÊ´;TÄ< 8#%îGû;ƒ¾Š #P„ ¡A;X‰alExýª*ŠoN™¨xþÉÂ{S´pAÀúJA¸!áE ±#%ã›êwŒ'¬+Ó}†Ïu¯‰¥hÂ%öz3…#6Ëïܟ›´æm:Ïr#%r"1Œ’ ”ÌÒùíêæÛVükZæ+kº¬ÿ¤¹gú£ #6Æ#%™Îžî6S!5²jÅjÐ¥¡–·½5{Ì|‹1À P÷€A!µ%AbÄB’VçjœuÝÔ²±c#.ݵêZðc^úªli¤#. ÷„5w!,8‘*àN߉D l&’PƒtI¨ÅiéÓ&Iš#.ˆ½Ö­|ý·\­{úµ¯UÑæÝÛ½(ÒDH"^‚b#6#.)k‹`‰E•Tb¤"M(0'ñn\ÄÈ)OŠŠVuç#6'÷ð=•øØ 1†„HA„cŠQ Aû†j=•€Ôáa­3‹¼D#%;" T€Ò͖ÖiµJ¢¶•fËMô¡ˆ!·/¤¸Ž‡Y@sÑV2#Í©ZdÍQ¶Ú…­DüÏ&1‰½#.@ §Ë†HH"Zf0šÚÿmFkB¦km…ˆ7€ÉLÍv¦vÓÆk‹±_T,£T ÂÊ$6#%þDûOPp%*¼CrW¿ªúÖó6óô÷}w~›¢|—ïd`ŸB2¿˜¦gËñꟙ´Cå#%a‚aÌHôÿ¹Xˆ4)RkU‘»M¶ ÈfÈOÆÑv`iñΌlD‘HI'2's¤ђõ¡²yˆ?Àáýb€@cÈoSÑ5·câX¢^ü-ëpqû˜ZÇ#%‰ÄÄ#.IÇY%¢ˆiQ8ð$MÊ$4ªB£ŠQ!.pK#.dÔþÕâòºmsWI*å^ï&Å­Ä*6VjBTBW@#6Ö#.c0LK½àŒ1†åËBá-$‹ok#%´Â "JM!hKEÌ©#~N͊ªð»/8Áo:¶f¾$öû^à쪰pÐք 331(Ä`m¥ÁØx]âO,’½).àdË0L\Ò² u"Áb…0«‹ÔÁh BX’T°€²+"¢7*© H4u͒it52LòêUÖRnݸ6 hüt#ùÓw2¢H×`ôò*ù{Ntp~m£fE…DAى`=aPP¬&i»PE±*Ð#6E#KT-ѺZƞ^Šv0ù lûa£ï€ƒÄ‘Œ$µb ÉS¯t·\ªvݪ–Ê­š[§.ê¾»mµõR¶¿’¶×ºØ+ìŠf‘MĔ± f#.‘¨-RHE9À³­‰ŠÐÂѹÑxOd#.Ášyþg2Å>?åDÚñç—ì[Ýa3FÖAÊR±1m6¥ÒqŸÏ#.¾r¯©†×PäqŸPì†4`!‘ÄF˜ÁDm6›¬‰¶òɒc‚„$‘¦ÖcÁ¨ñ©˜ÛvHEJèGŒ+ú2ĹRØ&Ç.-S9;7¶£´3P–—´¹”-2µ‹–š}¦Ó’òxPëצè!àDûšOË[ˆm4;CìAÓA?{@~¨ìFêøʈ;gèª#. #°êÞ#6&àÍdT#%¤‚‚O]#.0UXû%H€ð+Qè¨÷#6'dÑg"æ”Ø;¾#%âßh§#%–6‡Õáüӆ#.š¶ö!þ]ßzLÉ¿¿¯¥$уHX*fO‚'Æ"°›[>PAÍ#%GÉQMAû={”}á§ƒvY¬¯ÑõÖ)Ñu©A_°d FÛϲ½¿†Šc[Ü%•—oEÓ,y† ÷¢ˆJ2&óo†tÜÖ‚;¤¼6^o´uç‚A›(77ü“)– µ¶÷Y…ÄLx‹l+ۚ¨SÃù5ä4wòò$;8SV›âT:—<­‘t(ñH˜Èª†',ð³™RڀÒâRgpo¤ˆŒÂɍ2"ZBÇË0/‚x†ã~æŸÇTCîûÖþIõ‚h&"´#6bƒéC;¾¯3Ž¯«ÚÉÖْ>úWš‰ûc~Ó ÊqÖ'lcØÆöœ·0´U>’L#»²8US›3H—¸¨wâ® B?‹ï‡kzþˆú&)¸E–m[p•´!oqÎJЗYÅ{™ÙL7£L€ÁA€Œ¸¦ÓŽ V0>²BG.­#ÄDDJª® )æŒM+I’¦Ík¥¦=i4b¦—sìž ‹'4ƒ³>é}2ksá²HÎó|DaXéw‡kÎú}e°&f´R‹˜ƒÚyiÚΔóKÛù=iæÙ° y/âu+‰`Çxö$ÝÀû0}]‚ÐJ3ñdáË-^Ýø϶Û9@Ѽ#.3]7üºÊê@óÀ¶ñXT՝˜¬Fôõ{¹Œë²›Q…2fqLd–¦ñ!»o³!‡ ÄtÞ8<µ†çÂôÈ6c8Cg¥B~óQMãøÙKºŒËù®ÇC‰mª¹"9n¨¢ H´<J•#Öر–#%׋1Mn ¥ÊéÝÔxaöŸOڟÖNÿuQá´ÿb¨Ìñz` œ74*¨9‡N¾›tÌ Sõ–z¡օË8 zJãì;EøxW´‘±3Cd¦””6JöˆHŒ å¼Òa¯`&C! íŸó<µ,]I˜ZðÇá€Òß:}P#6f27¢– T‘Í6Eún§m¯FØؙᝎOu—m­×êoٜºSV#6ÌÔýìÞ×éÀԒ¶I&³#ø}3 lýCÖå¿YãšµÏ]Ú6·©d·‹j ­s݅M)gV\ÕÛÒÕÞ,¯ßë'õ‰r8ÃÒPòC5…U4v!yc:Îpôk¼¶••ÿd^קÃD~„ »÷??[TôšðŽE¶»š’wª•;ÀkŽ½WÆÎÊ]!A†ùp£Îrm°d+Û #L`„Œ± ´| P Hšƹ†ç—_®gXo,›¹iž¹ªË\ XyËú)ò¦á4·†§`ž8ÏkÆïgBŽC¹HÎçÕåNw3‰Uv0/ÏnñÑ8ª¡3'»=·„1Mw™É™1‚Ù}ûÒ2xÃER…¦§‘±PL¿@ã×¢LQRI5=û¼x_ZC‡#.eÒG§ï‘üØke(¤Þà҄ F@½Ù¹€ŸuôWn qÈËÙþ/£ò色§Ù(oÒ`ĂH¿I/#% $;ÁðH|‘ë ü!ô€ÿ8¬¾$DYDˆ‡vâõtŠŸFþX*G²»ÏÅ^“Ò™ ÌÝ@E8*mì81P}°‡f>Ãޝ²âôž“s#.Anã"Ý3-½GCÔtä.9#¿å¼:öŸ´Ô>‰ÄÇpwÇÉÄP +m&™#%f¶FÖ´ÑÛd92hş$ÑEy#6,:@ä¡í’(:xÔw‡u#6Š©6Ï쯟T®Î®£Æ>ÞHˆ{:¨óÚrz¨öY5zº¹[­(úù³¨å•gõ 8Àu¢ÚO…±Ú¨¦ ¢0ôV#% FB$š‡¯°Þå<jØÀOfçDšŽ¡Ð+ö8ÍƏ#%àA)hBÀÆ+ Ä®qk_g?ë?¯à̬¤‹ÝOÞS/P@JFÒQ?µ•ªù±À2:‡ß·gˆdªH5R#£Ê‡ˆ;ãM羄Á#%óë‚x N_¼n1¬ÙlX+¤Ž g¹·ù_•4k3>÷Vgl6éÎ×Ó©ñCqš×ÐEúW9³‘v@Óя¨a´Nø¥7 ì⇲ñvVù¦…é ì€?ÔTÆ'»Ÿe¿Ü»Ù;}`£9úì=§„¦ò•…A+©/þnw‹®B’v>û¶çU;QUÎ†¤”RtÐ:`#A‹'BÑ1Œ«¾ùa+Ð1 MpAH!ŸþO«mmCPç¢6îÐ*Á#ñÈr=ñ?£?ùûKÑTHØ?ÚáUŠ¦7ÊIȗۗX”ÇrxiÞ7•Îåƚ˜:tà€^³Í£Á!žKòó©,8AüÏzßóÄw(I ìäh·ÑQúöùw,ù.™1øµZw®íb!&t4!Ç.ü–ú2EŽ”)OkR¶Ä4³¬?eBF1³öeÑ$í8xnÕnùx-ˆPúɌé^û,ÇãXFKP­Í<œÇ+•wOÞ×j¤Ñ¬E¶Ëf³MRÍbZRµMR(gfí–sʵ$‘Èu.kOU;ÏïHÝEUõÔ«@È¥~Ïíýש?£ú~dm”eI£0h šm‰¨ŠLBLh”b#M*FJ&…!&͓a#6ˆ±Šü$åÅögŒxɳ'€«:û“7ܛo'6úÝyŸ”R’M›vÌ ÜÆ0Øh4MÌÝ4¢¤aKæÞ7t¶zh%*éMð·åÆ^&y}Gå1ÑÔ¦׃M6`¥·m—8™@¨…{*E#R«5sQƒ틓øø˜ÞŽ¨Ã&D ¡+fCÐÄÆÛxÎ&cz\/ӆÀ[]4šªœ„>n¨¤ôܟh#.ØL“ ïÖ9obkMNËÒuÕ.Âjõ!2̺ju^ëØÖ8ì3ŸÛë¨fèÎ[ŽG —ç_¸3ýO8†ž°Õ Úm𦶰9ãT’/è„ ™á­ž3°ûç™#6ƒRi¾m#%F÷"¢Ö[©Œ”¥m¦œiG#%0NPÈ©-D‚„#61u2H€âˆë—QUË;®JnVÝ®ésuu®ÈïkÎòYšÛ‰×·‰7®«— +lÆ4›hÆ@î’1ˆAš *ˆ‚•º%*»@’Žë&M’æ˘ª#%¦_å¬2H¢ÈAB,$֙WŠ¸rérÎësk$¢3—*çFד2 ËLEø:UÊA-H¡K29ÇXar„—ŽR×eFÉ‘?6¢teÌeÄÑs4Ñø©…~÷ð/c…ž ò—hâÓX!˜Ë#6Tr!žS“Ñ©/Þ:ãk‚Ãz)\Q„Ñ!TÁ`U«Š¢7*â͈Òll«/c\(­›Ž!¡6BÒˆ’¼«³5A”«¥¨Šž;Í·rÊ.»xÖúÇ®î×uQ”õíQ°i…¢I¥Âħ%4Ъ!h¨&MŽ9Q%Œ²ÛSM©·LÆ<D†”ÓÄÜ$‰AƒVeCbz’Ū‰×*­:R\£³Û+­µ‚(m„UÅ¡:‰WTŠ7"B¡\+-£u´6›­6R†Ê–ó Uj…¦<«•5C`À5·—&Á¼éåŽnãÀnUŠ.à»*.ÔÝTZ%ÚÔ&#.*A±Ñ©§¼Å¶e™ÕތøÁŒÆ1š'3²9Daƒ[#.iH­H7SlYe «UÆ«A–@¬’; )ucÔN }fÍ=,$‚î|ùWoŽÃAŽR<®Ó&ÂQAg–Û#©Â‹\\CÑz!¦©¦GK1dR0q­¨²yܦ8B Ù¼1’EâMjJ#.ÁŽB•mÌKH'…p¬ƒJ¼—šŒŽá*8À­pìŒ#0o”àŁ-ZN5F†A4¨·B戠2+±Ðj!B ›SR1F/4Ì⁆0Ê#.býßR ÷Øsȱ˜Tnͯ›7†nnø÷Xµä¢ÉʾNLâ­!ILs­C#&D™VE ¶Fi›„‚¨(a S#6Hƺ-¡2@aZM'"1A‚ƍî<j¨í˧¥ÁlUòÃÃÛæM8K‰˜¤A³¡ˆØ¡)‘"ÞZ9fñJ6ޘ º‡Ðќê äd'̓4Ǹj¨ºN0ü˜fâÆiûi—©²™°°(0ÓbÉQ”ÑHD5qîe‘éån#.nèÀ™O\m Õà*%oŸC#.«ÊŒM’ìu¦÷…wÀjïˆT™•¯¿&Cr—@Þ±¨Š¨„ÄpŸ•6Êäøz$×&p²±@‹V[i¡YDæË(F )96pÒ¡& 4©J¸(©0Ö\±‚’…0¸ †(ƒæ!B†ÐQ!bJŠ£"¤Á€4‰Š ­Õƒ´‰ÈÂÓGâMI)Ǹ9pd!U!Ì[¼;†îíâ+Îòé‹Q’×b‚„ŸžŠQÁHµCTˆE­ÍIÀ;¤’‚Ú‹mŠ¦Í¦l²Œ"µj …”Cñ`§ë.ÿ3#6ä4êJðüû¯Ì("Å#6ˆˆH°=ùÀ=Rc·.£÷e‹}·ªŠ>üR˜ÕDôÑF¿œ•Y—Ú>REB#%!‰ŒT£AܑBåµé{T}µ*Àì=UíŒ&„æë§ÎÎ00Ò °W!P‹'Û:D¯µg<¼ÕF r†™„O#.4P÷¨ì¬p£þÛ2FÄÙÝۍn®®›[{k®”;¸[ºU0Ir… Y…ƒvÊk^(¦µR˜¡LdÁ’ RËuB¦æ»³qP Ù(f3Т#‰omB‹7û¾¥°·°ø\¼ÌÚÒ㌊L6-Öýš"ò»-ëÛ¹Vçt$YÐI€ÛâóÝkXäœ$Y¬Ùæj±ˆtª/œvA»ˆ>#.¬—½HíÓÒ1ø¶GÛ«ÃD¯P‚VÑõ(þ¯àˆ© N½¤€L¯ÈÏa‚“‰‰r×(‰œ$ìÝÉВ³àw ïRb4w‡^×»C¾/…ìX,^¨bK”\«Ù½-!®ÓlßMvª|ºõö!üȦ7@Ï_]ß̏ØuåÜ(7Ñúþ©ØÁ#%Ë·I#ú;}+¾?}œ­n‡*œ>—Û±ÏÒ[ì×{oѤvÒBÅÛ ³É~¹¼È?ÈùŒc(šñG‘© ÔU#6„+¿æ‚d礇¼ì½¦ÐðÉßz†R‰Ê'j[br¬#.v#%ôηUŠšûʸT71wV­fºËmŽEßÒX J§^v×# ï EC°yƱ,• ìA2±A„ETù°’á™òNÊR¨QeTÎމrá˜\ö9Ú5‘jªË#.&t0ßá‰cZb8z¤0À—mE„þf³ÈßçHœŽ°Mq4› ¤Š9 #.þš ÃUHr¢’\ªévÜV^ßÈò¼QkÚr¶Kh·²ÖìKrîêÛôK\6¼UƎnVéµ·MY#.cnm&Úæ²k—-µÍÞír,m“j Qª+—‹;«î-Ã#.âw²Ë»$çžv÷07Šü<¢ŒÍ}Zk¾˜•˜zÓo´=H^Êî"Ø΁º’!7@A"ä#6´Þ”=¯íÂäD ´‘ƒ»¿vú®_†o™ªƒ‹¾ªýQy>ð)Gä#6çøÑá"É4ÖÂ=$±òSè2w@d#%“ Gßè—q¢1¤(š‰IBHå%ŠJ*¨Nîòá^T#6Z\# x Ù b¡†*©""(¤›[u­#.mt›¦µø~{oF®Ü¨Rd%ÛÝäT]Ñ *½Q@–Q¤ÖHѶÛ%[¿™~k÷!D,#6 éB?õ@Ô#%šÿ$CÏ¥'¾ûHjÆMöFÒ¶FñÇÙ{ZPuðP甼P#%;²f_Œî@O÷A$‘;ý&Ô¬›¡Ôu`¯ª¤ª£Ù¨3`Ð: H#"&Q)òT(uqe-L͒IJ1idŒ´i66hmIEbÆÊRRJdÚ4)µ´Eª*ØÖÔkjZV™jZ52¥b֋ci5³[Ϻϝn·$cu¬È²#.Ǎ"6W"Dûne6˜ÛaPÊAÇ$r®tëÓ£Ò®Ï=tªò®<ìiq¨ò¤©¥’D£O c!&$Ü*+hlŒc ¬H˜É-a"#6@£`èÁi†“#.‰H… 4ECJ¤P*( B*Zë0$(¾B¡ Ô#6Y2?Íü5°Á#%™ô© DØ% %¦îéݘÜ:ÓõÚô·W®ìÛVÀ(@d‘‚$–f­2Óȸ@M°%Ä^û³„B3ã`ûÇNÙ"vÔôôm÷wc¾²³Ù”„…QRN {ABH,O½¸VÆȌÜÐö5OÈ¡äØf2vp®§W_—[—,1Z%ê/-l@Ò¨ˆŠ±±Ü¨Mâ xFߗ¤jœ¯§1p‰V!TÌH!PáJu”0UR8Gõa£ÜœµõN¦’„µFénãɼ•ÖòË©R™”/Ú]êµsQµ±hÕZŽê®Á¥±ìóp–9‡ávº?®HEÊoz¤ÑïpÛ2#6e_ìÓjÎ`»8C®+dßX{Ap–Â!ê>ÿï(ü±YD©Ë³eJ[LTz÷F"Ë`ç`΃Ձš‚RúÕ ÿ™ùiÏJ—Šê%áMY¢ªS|š²|‰š®#6‘u¡‘àÖ½usFpÙ"}rC¼"Él³Êª<ÂoבøÏM™Ïr§ý–æØè„#Æ X}¨vµºt¡;?;#'•ËRùi@Ü¡ÍM¸Ôã|]?ÙÒί^¡ÔB}¨#.#%ù`ø€¨ÖîAå—Íã°Ï/ўÿ|hÒl\1º**;­»3Ú*¥â‘TþÈñÅ4¢ØìçÓ~ö3aƒ¦)¸÷GZ³*¥›z—ÁÑÇUƶÜ` ÂpÞ]ÎÚ£]u\Ê­Jã‰Q¢ë‡òUÓ3÷˜‘ðÁÆ&Òe¥”ÌI#‰ÆåÛJ{ií'[lüÇ¿Üo5ÕÛÄîÙ¥º'Q#%ä3!O¨"e¨BG½V×ÒH#´'53×ÕîZ×#.ÃP„˜ñçRn tÈCñžxm÷¦‰¾Ù¶Uúûïy/‘ãV°A„<(}ZÒÙ81K²‰$=·E4œ¢Bl‚:E’æÊSlµÉÆW_û­×¹/#.ÑۇQuÔîí®:väì³G¸\§”µí{KXî{îV¾¬#%¤LÒ#6Bk¬¨7â¶(/%ÀèÞà÷Ô¦Çb-¬Ä¢õÂÕÄÀÂFÅÆixå$Z³™F®;ûó–©vÂqÙÔ!Äg ÷7tVBZÇS¼•/ yÀo#ß«½Þ%™&‡s©X½*77/²cMž±Ár˜øW^3Ý$"“Q?:yÛ„6"£ŠéÅƺ–{åøÉÐ#.ôŠ¡¡”ÌVË~ügƒÉg‰smm9)¸®jWMöÓÃm‹f±“ 虘·â®8kÃÓ[é‘þ]»±6årXöN”VRTâÌYÍZª¥;¢øùžgrª³s BÄyo…,pѾa& q<£“jf)‰ÐÙnÆۛÐÓE¥Å—•›f5Šw©± ŠÑÄâV\º)2›Æƒl`œqÑáDë¾x¶ŒÅf^–a›TûåkƊWnëh6“³m<pæyßý_ZÝ>ؗ[ÑÆçhNI/$“ËÆfš7Ž)¤ÖŸô•öÍGŒb$C¥×ÌêC–C:ÚÒsŠ/}Ñw§Ê€ò¶DÉJŒnÛTóQíjP÷xÍ÷‡“bëZ:>춖Êü¹Ÿ9õÌW_J×°¦ŠéyƒiÄÆx’»uƒw}²™×:üç´ç”¼Žî'÷u{õõŒa*Ž½^W‹W0ïoèÌÐâò¹˜ô³8ÎÜVx˜«­¶®œ§|ʼntªCVo…Ž†#6åUvga*Fñêòª‹­éïlg¢/Ç=˜’Ã5ÅéüÔÂln÷.úþöb¢</Deìó՝«ô<¥sïŸ>NΠlr²¶AÅ׬Æ<EúûcÛÔÑìôþÝ!˜ ‚"D^æy¾8Ü£ŽËB6KÛ­8£,g ‘:d©D÷˜ÓìLíoY°¼0Pڌ/iÈÚyÔs dÛ)Ž…7°²›žTîÃ÷ä&ªhdrå#6%#.-í/Š×Cð&d«©.]ê™'O8çmÃ7£žUãŒIð,¦`œW£2êçµ8ÏNÀÅî$`.èXÌ@ð=Z¢Ã„ì÷m„R†˜m³³£f3ƒg#„RcÀÞQä¼b3x0óš˜ð½0„_”$gB†È›0íÚº‰9¥#6¨ÜÑ)¯± Ò'¬Ï•Ç– keØ yŒc0À)Հt™±…(ßÛíÖ Ù­dJݧÍ-®¯®ŽAåÖǓ¯0É<¼–^ G¨&ê @1[õ c®UNÃcAÈn>Рo#.°†(ÐÈ#×LC÷ªó#%€@:ó š#6`FãaÀP™˜‡a»ô:£L6 ñÕýxõ»Æ`vŒž¥›¤•`qG=æ26ð•9è•ÖkSAC«#%6ª„sÊ^æz±¿v‰•‘ Z3Kˆ—3.ªÞ&˘sxÃ\ã#6?#6«_Dd\¨¡PʸG`{»u½§D¯OÆ.þîO'6÷ûÞ [ž‡“°ìkÅÖÈ,½ÓÀý* “„GÄÂg ¾T©œ"VsïÎ ´##ËlºNÁƹÓkFÒéaùC·”úÏòghæz¢:§ç™ŽŠ–”žç—>ýcšŠETÚQSSNFüb((±SöۜM—Ä e²Ú{Að]‘Ák]zVÔ4o““Œ{#.”Uû»ð*#%Å9ÇG֓ôÚÏ6(¯Û#.oÏ϶;3\4‘Š¡³G>FÎD(Öѽò‹çÇÑp²9–žfª7 ­Zæ0ÙºÞÝCë¡ã’šÖ‹NÚ21D‘ª!ƒŸ.e-lZ'ÚUbÕõQÃØ¡™ç~%‰@½vÝiVkQ-29¾ysæ83DñÅì^[)X×ÕÚɚ" Dv:e£;F#6Ç~›•Ù¸°ëíÓÓwÌãWoÕqÜ̋²¿';¢Cs:ö#.a º:ë¶Y¹Tû›èœ ¯[–ãÔÇ4v4n s©»x÷ÑÏ;èÝ 2÷~öç‰sw~/´j¦<“£\W‰t·Œåóm‚åG‘^5&ŽÉoä wªŸ7 AÍÄ%å#¾Þ0Må8pqäñ<³~7SÛ»å߃Ló‘Î¥mZ¡\dõQ†Ð{x09hRÄ¥ˆµ¥«#%}¥ë„ô—‰”D4·–bͅèŒ3¨ç’š®E’=¸¼ó‡ ;Hœðà>.Ãx[CUZØ=íô7,Èh¨·tz=<7~†O›œ í†fBñEo7ê9q À°ï‹ˆLBõ«•³üñ6°§«Y܉±Y…„;W¸Žœ –Îå›\¹Þq.ï6… )sf\=®Ë#ՃV4(êvµÐ<³Ê@ǔ,,¸Œg ¢(Ôy zw-•HÕ]B¡¡¯E´öq3¤:f,öÒ­'!Ñð ì@â†1HóFÔó vM\;€© É3@Úõì.Úg$$VtIm-äSLÛ0w0ÈÁ'‰#%ÕY"aÃßôèU×]õûC#.˜`fá˜+u¸mæò?‰N®°Cw"³0ñ²)qO‘n"xXŽ ‚í¸NÛ&Äy~‘å(ä·°ÇèpÅ`\r ‡Pž <߂ð(;ïÍVßáL{U#.>¿ãxKf °ÂwÀõüƒå'™y;`kàýpÃhST«CÙç2°gÏ¥_V«GªG±8v'$ODMáÀÖN}®;O‘[Tb,ŠÈÃäÒ¡E€~ ¯Á°e…D–aì»Ímlš…s˜Ô¸ª’“#I#6±Kº’Ì0ªm&@•<ƅ(Ó`YF91!²²"¨DÈ¢–‚“EXB!$JÆÕ½+F·5¨­nZÊèZ©”‹"(ØÁci¬¢ÅFPTҊˆ¢aQFR¥‚0ø!\Þg¬âþ&x؅µ± Î@LñÜî#…# ¹vЅá¤é$c9ÍbŠž”Õé¼mãnEɱ­*µ¯¹m¶‹V®UQUUé¹UײóÇÐ܌ÍýÐçP:þ~–µÑøC5÷]cÇ-–§AKxæ*Æ1ƒK+udˆ×/¨ÒÁí¸i¶í®o Ü#.hÇHiþc£f-+°£W ¾ù¥SáîÀkN4bJ³ÄòÖ:¸`@¥,זcÉ –(2ƒtHqbePDiòãOR;Æ]ÓxÖa%‚dH°!V“7V˜Á·Ù (š&ÓicRE,%ÝEcbi¦4C®Z*=Ê[ÌgA§Âu‹wL¤t’d½>ùlÀö›L!P9l›ª#6@Y0 šÂfœ‘L7zUàÅ3R·X›€QŽÆ6ëØËÖ¥4ÊÑێv²ÍîFjh£MÔU¬zmkZ¦A¸Lk.<“µ†µcÔèç9«eo†LÑ$D”MqP\`SZ¨X³LÐ*±c‚ñcix1”2ëB‚ÕC$Î¥¯Õ¾5©Ï9;·hÓaY ÎS¼JÎ!ª#6A,ØTP”2„ÇcLhÇ»*ëµs½µPAôãn²‡U"^Ck*œêæVú†•“%+XIw­Ü&]J&0ghnÀot‚Çßh­siH“°N'a§ïšiÏ]P \‰ªR8ÙFö0TjŒ?ªãÞºÓ֓cSˆ‚ò£œµ.¨CZF“Làèd¬q¨Ô"Ú7*ª#6”*à Ѹ”Ðá¤0m0m15+‹‹FÞn-¼™,²»zça›[ ¹tùÐC 2´CdT¨£]ž&09ÜEZÙ*å#.hFe¡›±—mÝF?Sã5@‚ŠLãRùg%¥¶È|4k ¸Ô €ˆÚhŽ¦ª~¬¶ÆŠä$¼*7Ä®é@ì€zi¤„<˜D¨°]8&è .ï®r#.V†FÚqÉ#——B–¡ZYm r˜m†2L䭄ÊlbWfJÌæÚ¢&n\c§ˆF±V=¼§^1Q¼ÁèÞi•®›m·Xˆ9¢Vßãޟßފ= ­GÕy˜úe”}#611(÷"фŽ·e0Qsâš z±ƒXr8c™MAø¹¢@‚œ=6ñalÊSŽ!vH#.0ÕŒÏ ¶–‹€û0­\d#3ÉÜ$d9ö¥›:é¨WbTF¡£†MP1#BÌðCV#6æe´Î-ͳZ"Û­hDF ¤¨b0fµ8҆¸Â±¶FxØ7‘¨Ôƒ{ÔË ¦A¡6Á&'"ː9#.+µU°ÍNß!UíÏ*ª™Û2‡s—£Û1ó•M`ÁC!0çr‡c$’Ûã½n‹ç€¿¦Ì+¾îÝiL™5–MÓõ6¯ÚÙH•$䔴•¤$ˆz—O™®;ÅÝóèºbCóHwÀ©ÚªwUŒØÖ­À4†*SmÙüçƒ U+ {}E*ûXSÔÓ^#.“ñqº²±eÓ¦3™~sÈ+?2CÁûàÿ›Ð9¯¥Ag*Î*JAFä#.o³·Ä³Bx«ÇzQ€#ț»û<*±¿®væA§ ­öœšÁ›Kˆ?~Cóyßì¨×\Ubƒeª•Áå˜ó>\f÷={p1¼$a¦î“»¹0ˆ¿{w@y9;šbƪ¦[ƒ'º0’ÇotÜòä<×Ñ(õÈø¦k´à­µÕ÷ ¤qÁΑHû®øŽ›ü!‘¬í£Q:ǧ å@Hµð†ç© !Í’5iŠ Wj™KV——\Ջm]7‹hlPPH¯Ð†¬»öÐÖiä#ÔD~èì9ߥ}~•Œvý"°R(±H#%V ZÛ#61´Œ˜Æ&1¤ D©(Z¦UŠil[%¤¶¬RQ¶$¬š4(¦Ê£Í¡M5#JM’Q³JHIQÓhD¤KFHS4T¦È¥SF’a¶lÂ%(I1«X!#%øÞ:úx—ôÌÔžg´ê9šÉSÛŒº¬[Ç4UyÜÐ~ðWæòs5þW‘$$g1$8)×ÃÂÚµâW#o®å$î—VÐElO"¨>œ€#.¶ƒ˜4~‘ ¼Hga¡„’hf6ؽØLKn£’R& ¾~§Ûzk³pCõ%߁Ú(2ÆH\Àù9q]‡=½haѹS(ÂBY‰èâ°ª¦$ã…ß´ùû½šÂùïâsþŒCJ‘FÃÅqy§üÚµù¯×ÑÖNj{!Ãë: ûo?“WÝjߍµ¨’Û&ÑXªKXÑ÷Ö­si±©B“Q£±õÝ«™C!b”R©bXK2ïÈ0'uàEŠ$fPÉ#6>ÿ£"ٛ‹)ƒí¬÷ó.#.ƒ>+„¡Q…¡¦b0ÜürèÕcD>n.ž5ª(àÉX¦¤ŽRb"©¢˜ªŠD.éÊf’¡”+@6lxœËRXÐV,Iˆ.¾Þ1Ó{¯.íГ³šöó«Ìь¦»6ö•å&ñsD¬ÊÜ·/×–³PQÀº. a#%­ÅÝÞ!”`ŠÐ¡GLŒŠÄˆÄ½G¾ôÓIà{è5O‹†EÉŸ'& u1p6e¤J'LHQb`àËVAd¦¢ ŒbŒ¤…(Œó©#.LáGô`6  kgì›μÞ6ór1J¤NŽ2,=¤4,°pˆœ¦˜„| d<ÀÂÛ«6ìjHÚÛElmŠ#6­#%ÚÔ(ƒ"3@pBh_²*ÁUY‘U¦#6!ìßÕºLŽ@ ¦‰@¥+†Å-= #%½]­”ô¿~7c¿#´…`>ϾÈ÷÷ò3Œþ¨ž‰Cft½B$#!¿ö?‹"dꅄ|êÙ¾~h%¡Ð{Ñæ#.‚’ Ÿ,(`šä塤|Èؔn2¦‰”­­LÓÈ3ÏÐ@„>€ã7ïØV†Æ’iy¼Â°÷ýÞ=ßµöR|ª2Zûf‹5ïðñÆUo¿[52UQJ–m¯ZÔÆÊJýKï*G;ó&¦¥„u Êqµm¢ò êg™*ñ4-o^…°n2nF-tiªD§7C5Æ6Ó&TS`Ò &Œ!*Q›±A÷Ä rê]uâ+NA–«B/¯Ô{,¢tòOئÊúӒrµÉF¯Aï J+«)è(° Éë;øNsê>«íó]ÊMË°#.ŠšL†|ÊÛéRæ!Á)’Bª9£^¤ÿjfÅ<Ì;¬#6Aî0xw;Þõ†HA)4g˜fzúœqŽòF­õcÏ á„ØE¡kõ|¦!»°uªMG&~逸²#%Q;úŒ¿ÜtŠ@d‰"Ȉˆ*¦#.>¸ô/}RŽâb_cóÖìT#D¥:Ζ£Ê±rÖîõý“'5>‹ç|â²âè}.šàý_Tl×=ÎÜÔ²]4X`C$0ÇVêã9'HØv'F³ñIÚj &¥g™õ@>3¹“ŽÐí€#%pàJrê`{ä7s@òq{ÊA/˜”UÒ\zge)^±²=sDþXÜÆ1×ƣԌ吰nd[wof²XŒ‘²¾çg)P’6B·Þ\+ÉÚEµÜ,3â̈́JS»uUtDÀý19Wž53ÂpTlÐÈÓ#.¤c€h‚` ñ‘0pP#.@ŸÐnªÁ`È%ÿV TU*2ìÈ/&YÛr-Þ¨»5!€PÔÊ0E#Q¤H›a¸’6P";^-ˆš@â–YÇ1Ìnì5͗™¡#%1” ,½!‡sˆYڌñ¾¤flzÙ¹Ôé¥ÁciDã&‘Ho?/3²Ð½X2Ž(uÇÌ°´ÃdÝ­zYg$äÝ&Á5åD ˆEPÚ¥HŒA±è~“3#%‚ˆ Lˆ™ªÀC}ŠYf‚-"¼¤}q¥£ÌàIQ%¼†Ø^FZTz³µšHÅKÅ"@Sp¤u^<o.ÈB3@Dmï½àâ…×j”ta¦lrÞX@z‡QfkQ ‚Á¨‚À½Aƒ(Ö÷Šóò¯n7۞W üï¬"ù:ÈÏÓ7Ò`ÀR7{ƒ¦BdXg&ðS¨f%¤Š‰” É0ð»,í‹ý¶ÜD¶uS2ºcre38ºt#%™aÁ%ç­»#6Lp²O§pߒX9 ¤à»WD¢ƒvkb”Ô+LÄ#.–܈#.»³BñC7<è‰D©#6H2#%ë¸ïšµ ‹!£!PÅ X#6ɊH žºÄyŽ-•_F¨é<´­ŒöÝaš•˜ñ¿n«ÍÛµ±S†o1ï[ÍœVWÁ¦e 2äptc¯,ã2®i²‹혎s¤°ð­Ž4F!ÇöR¨±AV,ñ³á‡‰$Eïæm;ÖcHo!Ó@3k9LJ_™'LÁ›YÓB¯iè1@'*kMž.³ˆÆ£6™‰6“ A»m¶ÒÁL\RE΢ŒFe¥%o˜Ý“*—,už›`Á´¾Ñ‘9¥É1260ìo)¯i#.&”÷Í@V«¦Ä$l‚tšÊvÛck¦—r˜F)œÀKE ÙM‰,vLí.\º{՗[>!m´Áiå¬Þc#4Î!­äkû}av˜ÚߤœljW¸ä'7qÖ$[¬vŠÚÜßLU»ÆD<´ÑjlìïôH=fU̜L3™a萒'£>4‹O¬ÈЌ!Zõ‰S5{ÓX¦¹‡—CÎ&—;±8k¦îŸ\@r¯2n&‘='I©Zã¤êBÅ F՗„,¹\¬*ÍV׳p™`—\ñ©HfJ•Y#%êë㚨‡"ߑkkÌ›%ñO+vv&º?grà{Þºç(äUÐä×I¤  X¬E#65³6ɛ!ÅdhmÌóÀé­^]04©qs:ÙÁÇ0@ëæE}h·¨nœLeÁÃ}8 Üƒ^-1³ñ|2£Ãµ÷@¸p´Vכ;"'›‚å¡„±•X%ôŒ–ºí#%í5`+IB27©t§#.NZÐÅ©º†B¸–°Aø±b+m:+¤‚BN\¯…mgY¬ñ[6L†ÎÀVælåŒa²DgÑ@iµDбP<ŽýÿB㌱§4ü lÔ?nŠMÖÎð„àM$ÕY'¯BÐòtoi´\Ûñ¥Ø+~8ᥢ]-YÃ[Ôtͤp‰?UÿÂQm—2áLØqEÍ#.q™ƒíñØåÓ<<4x¨1 (3Hr›ŽÞ<9²óëktò ¦Æ ‡r³òëz]YÒ1Íñ,̊sÕ¦)³åÈFµ.ÉzˆÂ—y|²ÂÒ +d׳„ÛFó~BÀ™aud¤Ö †l”ŇÇ-Ņµ¾ù‚3XSC´=‹‰±ùq«óëth:j&#61iu]†Šp3B„Àtž§¯_ m}i¢2HÛ bvvÏxâ«$3@ä½Ì·gnªÕ ³ ŠP—JPÍ HÆÜq!¦YÛ%j®`ށˆ"–#I¢#P/¿=¹fgØMœÁC´;,LMµM4Yp'Ò*Úúµ˜·”ÉSìÎxÔEë¹Y¦§vM€Y@ôðSä̎œ™è‰åå#6ݹpf#%ÊÏÚ;tíyA&w©b¥‡OLìO#.&Âé?8L89ÞݓM7ã%†8Ž9Ê¡Ø-u#. ³/L]Ÿ¯\Õ¿%‚Ú.­cxŽ¨b‰4&µ!Ò`,fÄlLM‚á#6­˜‰Ó£p:5ÒHÄÄÌü¤Žd‘A¶¢„Hø0̑Áö 4EqT¡ªk&§xÝÛ3ÅÖè)ïe£(Ã1YÚ`¢ÇŽ6! Ý]ÛÑ.$#.  €àT–0%DH!¹±Z¸å9Ç´ÒQ PP4 ˆwŒšÈi8,ÑHŠê%Fl!6aeÈ0à\*hÛiD5Üè8h陖*¢P ƒK#6¦æÃ@ÀÀALCÄD‘6D“áS*¸è†wB]èÊ4,¨6"ŠwA³½ò3bà‡"¨)Ø٘Òi½‘ƒ†ûøU‘’« Hªå¶ÎMlEÜ 1 ˆÃØ#6š6v4#60gSP#.F†¸H¶WU%0MEó& 83ÐíĄ3œmÂt대ÉHrºâÄ¢ œBB¢ê™• ¯3[Ò^6¼¯_#.óˆ±c%%¾²yyôŸCk£U@Ê(¨ˆ°צŽ½Èš“n‡£¤ž±°f÷ò C°5#6,"B@MbªPê ‡á¿öôl½€Èë:½u‹yÑ\ƒ²íšeX§—ëïk—°Õy+'J#.?Ö>£MÃ܇)üŽøx¨âÙàm&-£™×B¸kMµ7ⓃIf ŒsQ‡fE°Šë»ºf$‘$#6DXÍf¿šY¯§·š#%ó×W%U®ÔEüðMѐÎ^hÂò¨I#%ê¯JS°x|k0ÂJh(¨Gf‚uaÐÆzífˆ?“nôÓ'àÒ«„¨“¹*3#¼¹R'W((q#HªÕÝe’iŽè3³%<ªÙ 쪌JÅrØãz#ÈÄ6¹–7oSñkJêF9ÌTÍ@Z¿0TV(NAqKìÍËVè+ÈämÎÜa·4}o{ž«;Ù¬å¦66”˜µ²¶[[:ÁÖ®¿¢>¡DHª{hˇà}*s9e¾Dʳ:¯«d{÷ÅT°3ñD#.¶CvN]GÃL—@SÞ¡#%4„Ž©C»¶Çá^Wf“·DîΗZ²º÷áâÔRñ7p#6ªVŒˆÚX"kÕáË»[Í$2%ñ5;Îéo7v†È®òï^vÉåÒ¹Å×RÉ#6A‘Ü0@4Ћ5*ˆF ´8iQ¡øé3 iŽöGZK(4‡]-ÌUDÖ7v)<´MF¢¡ÇgVƒ#34u*ÌÙbQ „GFùèë읯·»È!ð†<ýZ÷ H|ÁpDäA#%¦Ï¡¦3ƒõ†j‘¬¼•dú.ÖÚ1<#P„$xîamˆ…ÁV†ŠÄ®ÉÉL+ÃàÀؚÁ$p ¶”(“Ÿ(7'§¨&µ9w²#6nc±ì³êžlæ!ÜúìçÙ#.:ª&Œª§­LYUå™ ùû¦ƒ÷×!ŸG´šÈ(|#%ÉÂmr,A-Ùa…NKÎMN8ÓR0;»n[5'Ã)Lª×³¨^b>%¹C3é8]6±uLDÔ`X€ B!:©O¬i悘ç³n%ڒ"öa\ÐØq¥ÑÃK×董ñLôQ#.i‹1Ç¿†0Ú É 0µö~tm6V,ŒV"$ú‰¬á†sÈkÐҌ˜Ê¸ öò…0'º)HH2DO¢"öµ”ZÍ­iHJÔߪXDVBEGE„ìE—„0cUƄe5@Àm©n\0P‰`„M`¯8#%ì#%IîËѕ…*Bé—øahš<2­½Æ¦Z\ÜìŠÈ¤°ƒ² H’€:¯ƒäßbš•X1¿ 8Íõ #6 #%HŠ’*¾ß–[·|4ÅO4oÕå}#›9†Ñth¼g#.`±Þ»Ž´Å¸3©Õñ*\žY9)h„¢‡#65½P4a£ePM£2X’l+%Ê«EE¨íD‰‘·LNA‰GUÕÂë×yåmÊ^¶²VÌÝv¬V`•%šQV@IÅN†ýWPË3:È$#.EG^2S4#%Ü¥…¤M—2,Às4µ§âPNÞ0:=G§‹Í,0!&*Ç·§ä=ÔÌÃaÂօз;sHc²iÞfÍ ŸŽtê1ëa°SàßÚ½&ñØÒ 7!,HÈ#%—5ëÃ@ä%é© ¾EsRÏr¢Íýï_kWÏ:ó¶¶*'õÍn¥‰†šHƒ[ïh4×·¢`wAu­uÚá#.,‡q89 ‰JþÏáÃ;«¯³‡3€¯ÅO8~kÔ1 Ü$9Ê%¯«y£6ŠZhI¥EG!‘+Ž]£fvßæoí՘8”™`±Òùn¸¿¾¶^Óötš†Y[ÕôãBa»֛iAà~_X>ÈH‚&³ì‚‰ÔXb„#.4Ñ©î„5ë%ïë!rKïl}9úÓì='p>ýÉ­Ô(Ž^7/$‰ˆ¤´š’jYiŒVIJ#6«bÖa´&Ċ*kLmµ&ߺÑZ¸Îk¡£Y³k‡s¼ßÛ<“ÕXªå‘˜ûµ£aÞ¢þs”Ôæ: ÇÅ#.#.¾®¾Š+Ÿ˜±;öòÀMI@\Ùô‘²z°/‡aÙ°nâ#%žÕNÑ=ǾꉑäKÁŸFzùÂFC?6ëñ(ŽukµÃ Ž…XE{šJ•ƒ9&ärÔP|üi¶ŠöÔä4Ø-J[hyªôƒmše;“;ð´#.MÓIÓqA’q«)\»’ÄùÑe®qÄAäÒå˜CDƒ­ 8:ß 7$™l·}uf¶™ÛŽ6c„6ZAI¡%!pj[´-ÑÅ[åÍü ¬+cTdë‹ÔçL¨Í¶§fˆÜ€¤#%PYl±’Ú!VYCrhM ­#.Ñ­ÞîôÅN‚¡êÐ0LoäÅ£JÔ1”ÊȲnÅF´ýJֆ bÕk#.¥ø?{5²b]%OZZl}Æ0 ¸äE!òó÷΀Ù,"÷•Ég4 )@w}* uAÔ ²$ALpIF wIϞ/ƒ©‰tÊð¨A°O€!##Æ Žj‚ U6¼ãÕt±ð<4O‡ ¢+ÙÚt÷ a‚­ŠÛ ‹L;ÏX#6ɨF §ßæý#%oٔ1d”@Ç!”ƒ Tñ {õŸWnÿWòmî'y‰üµ͌ó6@gö8A°ÄZ‘´³0?yüä<vuøl¼ôªÄfPx"%7³0 Ü'´ws7uÿê"ç𒎚¾ÞöݗfÇÓ500.=Ԗl×Àþê:;X澐·ÞQPñã@?LSa#%G1×#6Ü ÕAf˧f¡€Xùè£C&3#ÅÔlDhÒKºº #.‘¦WÑÞaû]Û\«›œõæóÏ]ų„†É”Sd5Q‰y7s]¼‹&ÆѶñs\·Æ+»·‹yåv•¤å[y“oÑ[¶Ís!ÅSõ$S`6™mÙó÷þŠ#6*¾%|}¶<L³=AÞIYªa<Í>›é#%Å<Ô®Êû>Ê,U!¬Ûf,ÚÍ´õµ¿5÷­øµj÷û"Ñ-62)E’4²’©³jü¿tj7ßÕ~îú#. £D1SQ¶*¥)JÚüz§h’—µ¼'̋x„"#%Z"göBRÖÃÖ1ȸ0ćÐ0–HrHNTŠ$è>ä#.D1¦î¹²)±¬-f¬Q¬lÈÅc+™E²Á‰ëÎò*ˆ„(@Š'](Š]ê4{qM_îòýé©çÜOsèùfaב$ðWÀ šõ‡#%£'¸}—ËeL|ó*j¹ #6ý{.³ƒæɃxv÷’,!Ú°3œ…ó˜ÈIÀôªyæ8öÑUãoË{Ø,E˜E'F™ñßt €ž&ny¤À˜ÞB Q¶Äb‘püÈt‡î"€Û@ÖôTÖ¡ódH˜E9§¹Z€¡ ½B!JŠS˜Újh(‘"jKNíÒkTÛRiIª[R’T šl‘‘@njm¯a0¨ ÿNR‚(”+Ô\/*SÞR¬‹e¬Ë/n£.žÃgUPû£ãÓ dtÎ=v£9é.k ¯Ni`MÄljh™ú([;³RÑÖ*È5õXV²Oµ8Ð"Ņk°ÞÚ4ì#.y@^K?ÞÑïW-ï%ë¼lcúé#nìˆzK™š!ö¦ ¸X÷¢Ї§øþàêüûo–—çãvMÅ)¦%I²5¶1R`ÔFÕ&Û#6Z7æm¿+W‰°ÑZ(F AUdQ$ïî9ú»,ì–i!`¡P*…ˆû¤6+°0rBF"EHÒ(ÄɅŠ)¢hlÚQ¬,#%”†ýh—Æ}qÏzíÙ/uÝJQþÀ!"kWš±mF- Ú”5F„«6X‹X«QšZÊßÓ[¯3†:zº›üYݽ´ªË%$ÜkìÇègÍ#6сü5–#êŒ1KŠL5VÊå˜F·ÓLðкùÀƗàIô÷$È«miGlý/$²ÙÛ3"‹ *hc<jֆӃý90Š(„8A K"…Ð2Ú·Én³I©¢•-ë6ÛNìµÝÙ^5æòµÕ6‹&·¥\•ówY›³2«®nڊ¹Ú‚KdYµywcMk»«»­¤ÙRTȔØÖ󺷚kΨ¬$IS‚•a!ƒHˆ6Ôb£cÞMi„^›×—j”ÒÙMI–UéZêÞuuçj¼lm(Êe¬¶Rםܷk»tYc)&A¢ aˆ£ÑN™¡àΓ#%É#6ÛÐqV„m —3ø{䚂è5H±dÜ>²øQ¶EF*‚d‚ÈÇ#%ª@ S㒡¬þ¤Ê[Fh¥ȓ(1P¹{äÁ5×\É&§4)Dڛ7Õ¥GôØ46àYêÓ’äö¢ìþ3OêÁ `>¸ˆ¯pÏ?~ðøfŒEº#6ݧ¾÷#R÷fìˆfKËÇXZ¦#.Yë9¾îã~07"ß^GÏõ–™“¤M#.UJœmG/¤lír$a®îB™1 ßèSJë@ë#³o(ƒ$QGÊ)ļ.#.õêLo.Eä`%Áæ1‰¢GP5¦Õñóç/ml·p†B#%|²$Ÿxk‘(#6™(iÎ ¹8>J¦ç¸iߎ„>ÔÒ9åÈt(a…-Q¢ޖ3oÐÕùUbٛõ`|¢‡B hÚ)I¨i¦×£|#.âöA¯qØÔùKŒ˜5Ó"÷gëtód›±BKûòVµw¬¢ö|jë‚P¤Ot~ÃìJ'`O8)¹A°.F´­'RK`¨¤,n#¨f4äÈlƽQÁ€ÑÔÂ!³n¶`¢úC#’ØÇwšƽ!ȱ|*é €ŠDŘaM ‚¶”FŠ›Õ՚WáœuzC<óËû²œkGG ŽÄêîéՂ]Üãjþ?70ÚEy£ÉZ$£Y¨Ï¨ÑЁǽÁäuMmÐ/÷ЅÄZè8@¾?jã‚8“ù‹ç¯fƒYÁêF4dýŒ—-DEC=µvNÅ|ªÖÞm¨:ƒ´Pi\Xì"ð#.%t¢#‹Ì¸ÝѨU׎1Qߪ…@ãƒ[8AÀÓ Êö;÷—çKŽ¤B4Dbžƒ:[nXŠ#.édRS(´@Ír:†‘ä|Xr×c'pždl€A±ï47mà¶Ô~¤…f1ޓ‚BG¸Ô_h½GCˆô"W¾s;/~†D#.îfYÚÛÊÚ{aµÝ×oÊ÷}þëiäk×í¸*‰>ÜD-(?„LþdÓ* z©Q£fÜ@ ݨþQD¢¸ß³Ñ2Tm`ô=åWì#%ÇßwïØÁ²>u­L䑙› ™˜ÿl#%#%b#%?›Ùÿs¿ñõÿ¿ü¿éýŸôÿ¹íÿóÿûýíÿóîÿ/óÿëþ_òÿHþ]º>_¿ýÙ|¾ß÷Oþÿëëÿ‡þ?ðøÿãáÿ~#ü¿ãÿ/óþïü?ùÙÿ‡ú|åÿ/ôÿ=¸G£üúÿÓËæùGô_ôêüß_Õ¥P÷SÿLBÄ?iþ,ϳüêÈDÊy;"™e\?·ûäE7¨;ˆ‹‡©sÁþ±L@­ZüÄm4 þË#%öªŠÂ)40)*ÿšþþǹÝÔI I™ŸF·ÊÙVôh #%âQ³ßÌôjB »M¢ρ¡E˜SYˆ8ˆÛ,×g Ø+,€ƒþûö¦C¦Ò‚æ¨x¶æñ#.Öâ×ýÀä÷² ƒ¢îǑ^A‰:Õó»0ÉæfØÝ@„#̏%*ãþU•Êlé·üiÙ\¾ÅŸÙ»Æøyö¡ÃÉvǧ‡¿„eÔ«jÿ݆떅 ¥&P"ƾrÿïUËrž#.ð7Ï_û«u”a:X˜„Ès+u‘ž#6ٙýþ.ÀÀ7µ*jH†þ”¦xii”Qš]d*ši‚—ea˜TÁŒ0ÙÿŠeTñhÞ¶ñïÕ¥ƒpvŒîm©TœYnœ44¼BÒÙl`…ÕÁËsO6e7ª¨5mÚ8øq훓Mmƶ9T¨¨ëÌFdMmT˜I†qx“Ý,ØY.䃆5¨mõyõx*ŧ7ŠFÎîs¢kCºFêâ ¬#y{¢ï4êÈh2ùÃá’f´Øäì¹a²…qS1a ïH²F#¸yí‹ÈdŒ¸ÐŽH?F:oÌÌü4ÃÃ)×Ц­ë^EúîÞK¨ŒëN‘±£\-˜ÑNàS4 '>:`«é”ßw´ÿJ±·ý4#.pó‹À@ĞGßF;tk5Sޒæ ш넞‰‡ gà w#6Hp,†#6¹^>`L³¬5¬R Eò™„ "IEq¸Ov˜]œ.fB¦æ<õ Ù3PEATV*AB“9wt¸¦cß·Y˜ÌÊ2 ¯kº\69‰¤U¥€ >È!<NÁ(¿K61$@ 0P’2îHqw”;ó\¨xƒH1Mï}Ÿlı38bÿûKuÊɀž–¬Æ\¬îÙ ,F#6"`–ºT70]#.ú wó­bs„ ‰‚$LjÄÔJƒlkY¥3[FÔm’¨ÌÒDŅ‘S_EÛWZªø|:Ö¾¸‚:?àE3€ÿt#%¿]Tµi¸#I(¼co¦üÛªözÜíSlÖÕïéñ#%Mþ}OÒÂFA~©o;|mq>§^²æF4?ícS9öÉ¬×¦åU1Š"ü«Ç»­'_û6Ä+W] 扄8uîKºƒxteæß¶}C3¿¾z„g,r.;À}²“½©½Ç0Àזf­ÜT9†P^]*zgâ_§Æ³ò8ΎQHÔ¼=‰ #6@C&9›Ò’#.³QÁOª‹#.D'ÒáG½\áUò»µŠšP®›CGݼòöœ²áž˜¾¦ÕÍ-ø­¾v챯¤ƒ[êk˜Ø´|nmcãm½(ÕìµoSEªMAj½óZåUìÞ݁y»¶ë€]#6.æäQ‰#. ©‘’| P?ç!xnãdN2Apã'PQ±Ôí±s¼p]º¡f!‘OVݤ—¿š7áUÁbÇá*J9…¨H{ÿî°÷cÍÔ¼(5É@$fáÌR¿æû'wØÊ=<Ñ܎§ÛÈ_.EúØqPôÇX¡ÿ’#"‹(]¨î;µ#D”)Qb(ÁmLÍtÖêÕÙjûËf¤ÅÍh é! H¤€ £þßÃ3ÏëÿÏئ¨¤"Žþ~˜™áã(ø{fYr0Ûm‹CòNÀ.!xN¦ çå,A‘<?à“‡áÿ¨  —ýþ­&^â|YY?÷ùB-Þ6áÍtçüŠ¤ÿÿ&EÐý hNí'»ÿ›cÿ`[Óúl¿‰·@³¼%ËAú¼Oìÿ»æÿÜíe÷øCâ.ÃG éʽ1ÍÀ‡ê'¼waÕBžÏ+“Üã!Éä,—yý>^#y;³9ø¾Šÿѵú½gþs(ž?l-A!ñÿÔ¥ÝóG#%‰#%(ö#6”CÛ¢ OùI[¥BY=‹”+¨›4ÃÔkéýÕsø]¯üžB_Fœ*ÀN#.ÿ6pŸñäÑÎJíâqTE3‚o¦«…ÆY̘wÈâfÓ§m3 ÊÊÇðç,Má†/-„±¿Ñ8¨–¼­§0aw<}8fJÃ$É o§‚ì]aðx`HŠ$Y@zõnÒ=®Ù i„ÿ~éŽ1éÿµ^#.Jz(ÎLPÛæc薪Æ"ÿ“â|xã‡ü†œgê?I¼Ëò~ÿð"‰ÿü]ÉáB@ä&öÐ
171 #<==
172 #-----BEGIN PGP SIGNATURE-----\n\niQIzBAABCgAdFiEEivIt5aBoIuNHTzxwSbTGfAUneqoFAl3aW3cACgkQSbTGfAUn\neqruqA//Y9oJ46ZR8W7YB/e45bfrYxGbN7NnkvkwSPNziObYur+n1QpQEOaPTn/U\n5kFtPWHXRJzaG/A9poKn7pl1Xd7Edcu1aalfoEazZbuD37VOxIp9lnrefCAeICqj\nGv0SD96Zac91CbA+b20Q4xnqxKMi3LSI4NPjfFGy62FkSk3MS4p6Rdp0/WAKwwNj\nw7WEjQCNmLb37z+FGSzXg28aljYeteBZEthsVmGJ5QqVwMBwgj2+y5FOTzFfxmqB\nrWgjFYS0l85kgYRZv9yzdNmFs5SScwafwpT8Xmdr49tFn/+0LxXyRxX+rdODgrpV\nY4EOiQz0fd6mMMnaTDXlLSXls3JyVYmbTjeNL/9gcHmnStzJ851CJQfyQg7A+JoC\nc7nz0HbiFyTgB+PUZr1OhGj3A7287o8XQ0tqR3oa7jXIOX0OynrGplMQKr++0jE1\nBgKzjLoE9CTbjkQfICLG+aUy3S1ZyDk/BcO+5+Ytbru+qXuDsIgAdVosMfNSv9jJ\nXvOINsbRMekdejYMZv8fIkn5OEjCFHVhNpobEsCb768bjB3p7alQGECBvjHCm6dy\nXZPzl9cBMWIXcBjPTS+GZj+PIXGcu76pbsx6HBHWf+uJ+4xgOsUCVu//0AV09jvA\n0MjtLWwQ8mdRH6Wt4hsp4HKtSvQrhmljf2OnuYBgaFmcdJkN1zI=\n=C0oT\n-----END PGP SIGNATURE-----\n
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os,sys,errno,re,shutil,stat
5 try:
6 import cPickle
7 except ImportError:
8 import pickle as cPickle
9 from waflib import Node,Runner,TaskGen,Utils,ConfigSet,Task,Logs,Options,Context,Errors
10 CACHE_DIR='c4che'
11 CACHE_SUFFIX='_cache.py'
12 INSTALL=1337
13 UNINSTALL=-1337
14 SAVED_ATTRS='root node_sigs task_sigs imp_sigs raw_deps node_deps'.split()
15 CFG_FILES='cfg_files'
16 POST_AT_ONCE=0
17 POST_LAZY=1
18 PROTOCOL=-1
19 if sys.platform=='cli':
20 PROTOCOL=0
21 class BuildContext(Context.Context):
22 '''executes the build'''
23 cmd='build'
24 variant=''
25 def __init__(self,**kw):
26 super(BuildContext,self).__init__(**kw)
27 self.is_install=0
28 self.top_dir=kw.get('top_dir',Context.top_dir)
29 self.out_dir=kw.get('out_dir',Context.out_dir)
30 self.run_dir=kw.get('run_dir',Context.run_dir)
31 self.launch_dir=Context.launch_dir
32 self.post_mode=POST_LAZY
33 self.cache_dir=kw.get('cache_dir')
34 if not self.cache_dir:
35 self.cache_dir=os.path.join(self.out_dir,CACHE_DIR)
36 self.all_envs={}
37 self.node_sigs={}
38 self.task_sigs={}
39 self.imp_sigs={}
40 self.node_deps={}
41 self.raw_deps={}
42 self.task_gen_cache_names={}
43 self.jobs=Options.options.jobs
44 self.targets=Options.options.targets
45 self.keep=Options.options.keep
46 self.progress_bar=Options.options.progress_bar
47 self.deps_man=Utils.defaultdict(list)
48 self.current_group=0
49 self.groups=[]
50 self.group_names={}
51 for v in SAVED_ATTRS:
52 if not hasattr(self,v):
53 setattr(self,v,{})
54 def get_variant_dir(self):
55 if not self.variant:
56 return self.out_dir
57 return os.path.join(self.out_dir,os.path.normpath(self.variant))
58 variant_dir=property(get_variant_dir,None)
59 def __call__(self,*k,**kw):
60 kw['bld']=self
61 ret=TaskGen.task_gen(*k,**kw)
62 self.task_gen_cache_names={}
63 self.add_to_group(ret,group=kw.get('group'))
64 return ret
65 def __copy__(self):
66 raise Errors.WafError('build contexts cannot be copied')
67 def load_envs(self):
68 node=self.root.find_node(self.cache_dir)
69 if not node:
70 raise Errors.WafError('The project was not configured: run "waf configure" first!')
71 lst=node.ant_glob('**/*%s'%CACHE_SUFFIX,quiet=True)
72 if not lst:
73 raise Errors.WafError('The cache directory is empty: reconfigure the project')
74 for x in lst:
75 name=x.path_from(node).replace(CACHE_SUFFIX,'').replace('\\','/')
76 env=ConfigSet.ConfigSet(x.abspath())
77 self.all_envs[name]=env
78 for f in env[CFG_FILES]:
79 newnode=self.root.find_resource(f)
80 if not newnode or not newnode.exists():
81 raise Errors.WafError('Missing configuration file %r, reconfigure the project!'%f)
82 def init_dirs(self):
83 if not(os.path.isabs(self.top_dir)and os.path.isabs(self.out_dir)):
84 raise Errors.WafError('The project was not configured: run "waf configure" first!')
85 self.path=self.srcnode=self.root.find_dir(self.top_dir)
86 self.bldnode=self.root.make_node(self.variant_dir)
87 self.bldnode.mkdir()
88 def execute(self):
89 self.restore()
90 if not self.all_envs:
91 self.load_envs()
92 self.execute_build()
93 def execute_build(self):
94 Logs.info("Waf: Entering directory `%s'",self.variant_dir)
95 self.recurse([self.run_dir])
96 self.pre_build()
97 self.timer=Utils.Timer()
98 try:
99 self.compile()
100 finally:
101 if self.progress_bar==1 and sys.stderr.isatty():
102 c=self.producer.processed or 1
103 m=self.progress_line(c,c,Logs.colors.BLUE,Logs.colors.NORMAL)
104 Logs.info(m,extra={'stream':sys.stderr,'c1':Logs.colors.cursor_off,'c2':Logs.colors.cursor_on})
105 Logs.info("Waf: Leaving directory `%s'",self.variant_dir)
106 try:
107 self.producer.bld=None
108 del self.producer
109 except AttributeError:
110 pass
111 self.post_build()
112 def restore(self):
113 try:
114 env=ConfigSet.ConfigSet(os.path.join(self.cache_dir,'build.config.py'))
115 except EnvironmentError:
116 pass
117 else:
118 if env.version<Context.HEXVERSION:
119 raise Errors.WafError('Project was configured with a different version of Waf, please reconfigure it')
120 for t in env.tools:
121 self.setup(**t)
122 dbfn=os.path.join(self.variant_dir,Context.DBFILE)
123 try:
124 data=Utils.readf(dbfn,'rb')
125 except(EnvironmentError,EOFError):
126 Logs.debug('build: Could not load the build cache %s (missing)',dbfn)
127 else:
128 try:
129 Node.pickle_lock.acquire()
130 Node.Nod3=self.node_class
131 try:
132 data=cPickle.loads(data)
133 except Exception as e:
134 Logs.debug('build: Could not pickle the build cache %s: %r',dbfn,e)
135 else:
136 for x in SAVED_ATTRS:
137 setattr(self,x,data.get(x,{}))
138 finally:
139 Node.pickle_lock.release()
140 self.init_dirs()
141 def store(self):
142 data={}
143 for x in SAVED_ATTRS:
144 data[x]=getattr(self,x)
145 db=os.path.join(self.variant_dir,Context.DBFILE)
146 try:
147 Node.pickle_lock.acquire()
148 Node.Nod3=self.node_class
149 x=cPickle.dumps(data,PROTOCOL)
150 finally:
151 Node.pickle_lock.release()
152 Utils.writef(db+'.tmp',x,m='wb')
153 try:
154 st=os.stat(db)
155 os.remove(db)
156 if not Utils.is_win32:
157 os.chown(db+'.tmp',st.st_uid,st.st_gid)
158 except(AttributeError,OSError):
159 pass
160 os.rename(db+'.tmp',db)
161 def compile(self):
162 Logs.debug('build: compile()')
163 self.producer=Runner.Parallel(self,self.jobs)
164 self.producer.biter=self.get_build_iterator()
165 try:
166 self.producer.start()
167 except KeyboardInterrupt:
168 if self.is_dirty():
169 self.store()
170 raise
171 else:
172 if self.is_dirty():
173 self.store()
174 if self.producer.error:
175 raise Errors.BuildError(self.producer.error)
176 def is_dirty(self):
177 return self.producer.dirty
178 def setup(self,tool,tooldir=None,funs=None):
179 if isinstance(tool,list):
180 for i in tool:
181 self.setup(i,tooldir)
182 return
183 module=Context.load_tool(tool,tooldir)
184 if hasattr(module,"setup"):
185 module.setup(self)
186 def get_env(self):
187 try:
188 return self.all_envs[self.variant]
189 except KeyError:
190 return self.all_envs['']
191 def set_env(self,val):
192 self.all_envs[self.variant]=val
193 env=property(get_env,set_env)
194 def add_manual_dependency(self,path,value):
195 if not path:
196 raise ValueError('Invalid input path %r'%path)
197 if isinstance(path,Node.Node):
198 node=path
199 elif os.path.isabs(path):
200 node=self.root.find_resource(path)
201 else:
202 node=self.path.find_resource(path)
203 if not node:
204 raise ValueError('Could not find the path %r'%path)
205 if isinstance(value,list):
206 self.deps_man[node].extend(value)
207 else:
208 self.deps_man[node].append(value)
209 def launch_node(self):
210 try:
211 return self.p_ln
212 except AttributeError:
213 self.p_ln=self.root.find_dir(self.launch_dir)
214 return self.p_ln
215 def hash_env_vars(self,env,vars_lst):
216 if not env.table:
217 env=env.parent
218 if not env:
219 return Utils.SIG_NIL
220 idx=str(id(env))+str(vars_lst)
221 try:
222 cache=self.cache_env
223 except AttributeError:
224 cache=self.cache_env={}
225 else:
226 try:
227 return self.cache_env[idx]
228 except KeyError:
229 pass
230 lst=[env[a]for a in vars_lst]
231 cache[idx]=ret=Utils.h_list(lst)
232 Logs.debug('envhash: %s %r',Utils.to_hex(ret),lst)
233 return ret
234 def get_tgen_by_name(self,name):
235 cache=self.task_gen_cache_names
236 if not cache:
237 for g in self.groups:
238 for tg in g:
239 try:
240 cache[tg.name]=tg
241 except AttributeError:
242 pass
243 try:
244 return cache[name]
245 except KeyError:
246 raise Errors.WafError('Could not find a task generator for the name %r'%name)
247 def progress_line(self,idx,total,col1,col2):
248 if not sys.stderr.isatty():
249 return''
250 n=len(str(total))
251 Utils.rot_idx+=1
252 ind=Utils.rot_chr[Utils.rot_idx%4]
253 pc=(100.*idx)/total
254 fs="[%%%dd/%%d][%%s%%2d%%%%%%s][%s]["%(n,ind)
255 left=fs%(idx,total,col1,pc,col2)
256 right='][%s%s%s]'%(col1,self.timer,col2)
257 cols=Logs.get_term_cols()-len(left)-len(right)+2*len(col1)+2*len(col2)
258 if cols<7:
259 cols=7
260 ratio=((cols*idx)//total)-1
261 bar=('='*ratio+'>').ljust(cols)
262 msg=Logs.indicator%(left,bar,right)
263 return msg
264 def declare_chain(self,*k,**kw):
265 return TaskGen.declare_chain(*k,**kw)
266 def pre_build(self):
267 for m in getattr(self,'pre_funs',[]):
268 m(self)
269 def post_build(self):
270 for m in getattr(self,'post_funs',[]):
271 m(self)
272 def add_pre_fun(self,meth):
273 try:
274 self.pre_funs.append(meth)
275 except AttributeError:
276 self.pre_funs=[meth]
277 def add_post_fun(self,meth):
278 try:
279 self.post_funs.append(meth)
280 except AttributeError:
281 self.post_funs=[meth]
282 def get_group(self,x):
283 if not self.groups:
284 self.add_group()
285 if x is None:
286 return self.groups[self.current_group]
287 if x in self.group_names:
288 return self.group_names[x]
289 return self.groups[x]
290 def add_to_group(self,tgen,group=None):
291 assert(isinstance(tgen,TaskGen.task_gen)or isinstance(tgen,Task.Task))
292 tgen.bld=self
293 self.get_group(group).append(tgen)
294 def get_group_name(self,g):
295 if not isinstance(g,list):
296 g=self.groups[g]
297 for x in self.group_names:
298 if id(self.group_names[x])==id(g):
299 return x
300 return''
301 def get_group_idx(self,tg):
302 se=id(tg)
303 for i,tmp in enumerate(self.groups):
304 for t in tmp:
305 if id(t)==se:
306 return i
307 return None
308 def add_group(self,name=None,move=True):
309 if name and name in self.group_names:
310 raise Errors.WafError('add_group: name %s already present',name)
311 g=[]
312 self.group_names[name]=g
313 self.groups.append(g)
314 if move:
315 self.current_group=len(self.groups)-1
316 def set_group(self,idx):
317 if isinstance(idx,str):
318 g=self.group_names[idx]
319 for i,tmp in enumerate(self.groups):
320 if id(g)==id(tmp):
321 self.current_group=i
322 break
323 else:
324 self.current_group=idx
325 def total(self):
326 total=0
327 for group in self.groups:
328 for tg in group:
329 try:
330 total+=len(tg.tasks)
331 except AttributeError:
332 total+=1
333 return total
334 def get_targets(self):
335 to_post=[]
336 min_grp=0
337 for name in self.targets.split(','):
338 tg=self.get_tgen_by_name(name)
339 m=self.get_group_idx(tg)
340 if m>min_grp:
341 min_grp=m
342 to_post=[tg]
343 elif m==min_grp:
344 to_post.append(tg)
345 return(min_grp,to_post)
346 def get_all_task_gen(self):
347 lst=[]
348 for g in self.groups:
349 lst.extend(g)
350 return lst
351 def post_group(self):
352 def tgpost(tg):
353 try:
354 f=tg.post
355 except AttributeError:
356 pass
357 else:
358 f()
359 if self.targets=='*':
360 for tg in self.groups[self.current_group]:
361 tgpost(tg)
362 elif self.targets:
363 if self.current_group<self._min_grp:
364 for tg in self.groups[self.current_group]:
365 tgpost(tg)
366 else:
367 for tg in self._exact_tg:
368 tg.post()
369 else:
370 ln=self.launch_node()
371 if ln.is_child_of(self.bldnode):
372 Logs.warn('Building from the build directory, forcing --targets=*')
373 ln=self.srcnode
374 elif not ln.is_child_of(self.srcnode):
375 Logs.warn('CWD %s is not under %s, forcing --targets=* (run distclean?)',ln.abspath(),self.srcnode.abspath())
376 ln=self.srcnode
377 def is_post(tg,ln):
378 try:
379 p=tg.path
380 except AttributeError:
381 pass
382 else:
383 if p.is_child_of(ln):
384 return True
385 def is_post_group():
386 for i,g in enumerate(self.groups):
387 if i>self.current_group:
388 for tg in g:
389 if is_post(tg,ln):
390 return True
391 if self.post_mode==POST_LAZY and ln!=self.srcnode:
392 if is_post_group():
393 ln=self.srcnode
394 for tg in self.groups[self.current_group]:
395 if is_post(tg,ln):
396 tgpost(tg)
397 def get_tasks_group(self,idx):
398 tasks=[]
399 for tg in self.groups[idx]:
400 try:
401 tasks.extend(tg.tasks)
402 except AttributeError:
403 tasks.append(tg)
404 return tasks
405 def get_build_iterator(self):
406 if self.targets and self.targets!='*':
407 (self._min_grp,self._exact_tg)=self.get_targets()
408 if self.post_mode!=POST_LAZY:
409 for self.current_group,_ in enumerate(self.groups):
410 self.post_group()
411 for self.current_group,_ in enumerate(self.groups):
412 if self.post_mode!=POST_AT_ONCE:
413 self.post_group()
414 tasks=self.get_tasks_group(self.current_group)
415 Task.set_file_constraints(tasks)
416 Task.set_precedence_constraints(tasks)
417 self.cur_tasks=tasks
418 if tasks:
419 yield tasks
420 while 1:
421 yield[]
422 def install_files(self,dest,files,**kw):
423 assert(dest)
424 tg=self(features='install_task',install_to=dest,install_from=files,**kw)
425 tg.dest=tg.install_to
426 tg.type='install_files'
427 if not kw.get('postpone',True):
428 tg.post()
429 return tg
430 def install_as(self,dest,srcfile,**kw):
431 assert(dest)
432 tg=self(features='install_task',install_to=dest,install_from=srcfile,**kw)
433 tg.dest=tg.install_to
434 tg.type='install_as'
435 if not kw.get('postpone',True):
436 tg.post()
437 return tg
438 def symlink_as(self,dest,src,**kw):
439 assert(dest)
440 tg=self(features='install_task',install_to=dest,install_from=src,**kw)
441 tg.dest=tg.install_to
442 tg.type='symlink_as'
443 tg.link=src
444 if not kw.get('postpone',True):
445 tg.post()
446 return tg
447 @TaskGen.feature('install_task')
448 @TaskGen.before_method('process_rule','process_source')
449 def process_install_task(self):
450 self.add_install_task(**self.__dict__)
451 @TaskGen.taskgen_method
452 def add_install_task(self,**kw):
453 if not self.bld.is_install:
454 return
455 if not kw['install_to']:
456 return
457 if kw['type']=='symlink_as'and Utils.is_win32:
458 if kw.get('win32_install'):
459 kw['type']='install_as'
460 else:
461 return
462 tsk=self.install_task=self.create_task('inst')
463 tsk.chmod=kw.get('chmod',Utils.O644)
464 tsk.link=kw.get('link','')or kw.get('install_from','')
465 tsk.relative_trick=kw.get('relative_trick',False)
466 tsk.type=kw['type']
467 tsk.install_to=tsk.dest=kw['install_to']
468 tsk.install_from=kw['install_from']
469 tsk.relative_base=kw.get('cwd')or kw.get('relative_base',self.path)
470 tsk.install_user=kw.get('install_user')
471 tsk.install_group=kw.get('install_group')
472 tsk.init_files()
473 if not kw.get('postpone',True):
474 tsk.run_now()
475 return tsk
476 @TaskGen.taskgen_method
477 def add_install_files(self,**kw):
478 kw['type']='install_files'
479 return self.add_install_task(**kw)
480 @TaskGen.taskgen_method
481 def add_install_as(self,**kw):
482 kw['type']='install_as'
483 return self.add_install_task(**kw)
484 @TaskGen.taskgen_method
485 def add_symlink_as(self,**kw):
486 kw['type']='symlink_as'
487 return self.add_install_task(**kw)
488 class inst(Task.Task):
489 def __str__(self):
490 return''
491 def uid(self):
492 lst=self.inputs+self.outputs+[self.link,self.generator.path.abspath()]
493 return Utils.h_list(lst)
494 def init_files(self):
495 if self.type=='symlink_as':
496 inputs=[]
497 else:
498 inputs=self.generator.to_nodes(self.install_from)
499 if self.type=='install_as':
500 assert len(inputs)==1
501 self.set_inputs(inputs)
502 dest=self.get_install_path()
503 outputs=[]
504 if self.type=='symlink_as':
505 if self.relative_trick:
506 self.link=os.path.relpath(self.link,os.path.dirname(dest))
507 outputs.append(self.generator.bld.root.make_node(dest))
508 elif self.type=='install_as':
509 outputs.append(self.generator.bld.root.make_node(dest))
510 else:
511 for y in inputs:
512 if self.relative_trick:
513 destfile=os.path.join(dest,y.path_from(self.relative_base))
514 else:
515 destfile=os.path.join(dest,y.name)
516 outputs.append(self.generator.bld.root.make_node(destfile))
517 self.set_outputs(outputs)
518 def runnable_status(self):
519 ret=super(inst,self).runnable_status()
520 if ret==Task.SKIP_ME and self.generator.bld.is_install:
521 return Task.RUN_ME
522 return ret
523 def post_run(self):
524 pass
525 def get_install_path(self,destdir=True):
526 if isinstance(self.install_to,Node.Node):
527 dest=self.install_to.abspath()
528 else:
529 dest=os.path.normpath(Utils.subst_vars(self.install_to,self.env))
530 if not os.path.isabs(dest):
531 dest=os.path.join(self.env.PREFIX,dest)
532 if destdir and Options.options.destdir:
533 dest=os.path.join(Options.options.destdir,os.path.splitdrive(dest)[1].lstrip(os.sep))
534 return dest
535 def copy_fun(self,src,tgt):
536 if Utils.is_win32 and len(tgt)>259 and not tgt.startswith('\\\\?\\'):
537 tgt='\\\\?\\'+tgt
538 shutil.copy2(src,tgt)
539 self.fix_perms(tgt)
540 def rm_empty_dirs(self,tgt):
541 while tgt:
542 tgt=os.path.dirname(tgt)
543 try:
544 os.rmdir(tgt)
545 except OSError:
546 break
547 def run(self):
548 is_install=self.generator.bld.is_install
549 if not is_install:
550 return
551 for x in self.outputs:
552 if is_install==INSTALL:
553 x.parent.mkdir()
554 if self.type=='symlink_as':
555 fun=is_install==INSTALL and self.do_link or self.do_unlink
556 fun(self.link,self.outputs[0].abspath())
557 else:
558 fun=is_install==INSTALL and self.do_install or self.do_uninstall
559 launch_node=self.generator.bld.launch_node()
560 for x,y in zip(self.inputs,self.outputs):
561 fun(x.abspath(),y.abspath(),x.path_from(launch_node))
562 def run_now(self):
563 status=self.runnable_status()
564 if status not in(Task.RUN_ME,Task.SKIP_ME):
565 raise Errors.TaskNotReady('Could not process %r: status %r'%(self,status))
566 self.run()
567 self.hasrun=Task.SUCCESS
568 def do_install(self,src,tgt,lbl,**kw):
569 if not Options.options.force:
570 try:
571 st1=os.stat(tgt)
572 st2=os.stat(src)
573 except OSError:
574 pass
575 else:
576 if st1.st_mtime+2>=st2.st_mtime and st1.st_size==st2.st_size:
577 if not self.generator.bld.progress_bar:
578 c1=Logs.colors.NORMAL
579 c2=Logs.colors.BLUE
580 Logs.info('%s- install %s%s%s (from %s)',c1,c2,tgt,c1,lbl)
581 return False
582 if not self.generator.bld.progress_bar:
583 c1=Logs.colors.NORMAL
584 c2=Logs.colors.BLUE
585 Logs.info('%s+ install %s%s%s (from %s)',c1,c2,tgt,c1,lbl)
586 try:
587 os.chmod(tgt,Utils.O644|stat.S_IMODE(os.stat(tgt).st_mode))
588 except EnvironmentError:
589 pass
590 try:
591 os.remove(tgt)
592 except OSError:
593 pass
594 try:
595 self.copy_fun(src,tgt)
596 except EnvironmentError as e:
597 if not os.path.exists(src):
598 Logs.error('File %r does not exist',src)
599 elif not os.path.isfile(src):
600 Logs.error('Input %r is not a file',src)
601 raise Errors.WafError('Could not install the file %r'%tgt,e)
602 def fix_perms(self,tgt):
603 if not Utils.is_win32:
604 user=getattr(self,'install_user',None)or getattr(self.generator,'install_user',None)
605 group=getattr(self,'install_group',None)or getattr(self.generator,'install_group',None)
606 if user or group:
607 Utils.lchown(tgt,user or-1,group or-1)
608 if not os.path.islink(tgt):
609 os.chmod(tgt,self.chmod)
610 def do_link(self,src,tgt,**kw):
611 if os.path.islink(tgt)and os.readlink(tgt)==src:
612 if not self.generator.bld.progress_bar:
613 c1=Logs.colors.NORMAL
614 c2=Logs.colors.BLUE
615 Logs.info('%s- symlink %s%s%s (to %s)',c1,c2,tgt,c1,src)
616 else:
617 try:
618 os.remove(tgt)
619 except OSError:
620 pass
621 if not self.generator.bld.progress_bar:
622 c1=Logs.colors.NORMAL
623 c2=Logs.colors.BLUE
624 Logs.info('%s+ symlink %s%s%s (to %s)',c1,c2,tgt,c1,src)
625 os.symlink(src,tgt)
626 self.fix_perms(tgt)
627 def do_uninstall(self,src,tgt,lbl,**kw):
628 if not self.generator.bld.progress_bar:
629 c1=Logs.colors.NORMAL
630 c2=Logs.colors.BLUE
631 Logs.info('%s- remove %s%s%s',c1,c2,tgt,c1)
632 try:
633 os.remove(tgt)
634 except OSError as e:
635 if e.errno!=errno.ENOENT:
636 if not getattr(self,'uninstall_error',None):
637 self.uninstall_error=True
638 Logs.warn('build: some files could not be uninstalled (retry with -vv to list them)')
639 if Logs.verbose>1:
640 Logs.warn('Could not remove %s (error code %r)',e.filename,e.errno)
641 self.rm_empty_dirs(tgt)
642 def do_unlink(self,src,tgt,**kw):
643 try:
644 if not self.generator.bld.progress_bar:
645 c1=Logs.colors.NORMAL
646 c2=Logs.colors.BLUE
647 Logs.info('%s- remove %s%s%s',c1,c2,tgt,c1)
648 os.remove(tgt)
649 except OSError:
650 pass
651 self.rm_empty_dirs(tgt)
652 class InstallContext(BuildContext):
653 '''installs the targets on the system'''
654 cmd='install'
655 def __init__(self,**kw):
656 super(InstallContext,self).__init__(**kw)
657 self.is_install=INSTALL
658 class UninstallContext(InstallContext):
659 '''removes the targets installed'''
660 cmd='uninstall'
661 def __init__(self,**kw):
662 super(UninstallContext,self).__init__(**kw)
663 self.is_install=UNINSTALL
664 class CleanContext(BuildContext):
665 '''cleans the project'''
666 cmd='clean'
667 def execute(self):
668 self.restore()
669 if not self.all_envs:
670 self.load_envs()
671 self.recurse([self.run_dir])
672 try:
673 self.clean()
674 finally:
675 self.store()
676 def clean(self):
677 Logs.debug('build: clean called')
678 if hasattr(self,'clean_files'):
679 for n in self.clean_files:
680 n.delete()
681 elif self.bldnode!=self.srcnode:
682 lst=[]
683 for env in self.all_envs.values():
684 lst.extend(self.root.find_or_declare(f)for f in env[CFG_FILES])
685 excluded_dirs='.lock* *conf_check_*/** config.log %s/*'%CACHE_DIR
686 for n in self.bldnode.ant_glob('**/*',excl=excluded_dirs,quiet=True):
687 if n in lst:
688 continue
689 n.delete()
690 self.root.children={}
691 for v in SAVED_ATTRS:
692 if v=='root':
693 continue
694 setattr(self,v,{})
695 class ListContext(BuildContext):
696 '''lists the targets to execute'''
697 cmd='list'
698 def execute(self):
699 self.restore()
700 if not self.all_envs:
701 self.load_envs()
702 self.recurse([self.run_dir])
703 self.pre_build()
704 self.timer=Utils.Timer()
705 for g in self.groups:
706 for tg in g:
707 try:
708 f=tg.post
709 except AttributeError:
710 pass
711 else:
712 f()
713 try:
714 self.get_tgen_by_name('')
715 except Errors.WafError:
716 pass
717 targets=sorted(self.task_gen_cache_names)
718 line_just=max(len(t)for t in targets)if targets else 0
719 for target in targets:
720 tgen=self.task_gen_cache_names[target]
721 descript=getattr(tgen,'description','')
722 if descript:
723 target=target.ljust(line_just)
724 descript=': %s'%descript
725 Logs.pprint('GREEN',target,label=descript)
726 class StepContext(BuildContext):
727 '''executes tasks in a step-by-step fashion, for debugging'''
728 cmd='step'
729 def __init__(self,**kw):
730 super(StepContext,self).__init__(**kw)
731 self.files=Options.options.files
732 def compile(self):
733 if not self.files:
734 Logs.warn('Add a pattern for the debug build, for example "waf step --files=main.c,app"')
735 BuildContext.compile(self)
736 return
737 targets=[]
738 if self.targets and self.targets!='*':
739 targets=self.targets.split(',')
740 for g in self.groups:
741 for tg in g:
742 if targets and tg.name not in targets:
743 continue
744 try:
745 f=tg.post
746 except AttributeError:
747 pass
748 else:
749 f()
750 for pat in self.files.split(','):
751 matcher=self.get_matcher(pat)
752 for tg in g:
753 if isinstance(tg,Task.Task):
754 lst=[tg]
755 else:
756 lst=tg.tasks
757 for tsk in lst:
758 do_exec=False
759 for node in tsk.inputs:
760 if matcher(node,output=False):
761 do_exec=True
762 break
763 for node in tsk.outputs:
764 if matcher(node,output=True):
765 do_exec=True
766 break
767 if do_exec:
768 ret=tsk.run()
769 Logs.info('%s -> exit %r',tsk,ret)
770 def get_matcher(self,pat):
771 inn=True
772 out=True
773 if pat.startswith('in:'):
774 out=False
775 pat=pat.replace('in:','')
776 elif pat.startswith('out:'):
777 inn=False
778 pat=pat.replace('out:','')
779 anode=self.root.find_node(pat)
780 pattern=None
781 if not anode:
782 if not pat.startswith('^'):
783 pat='^.+?%s'%pat
784 if not pat.endswith('$'):
785 pat='%s$'%pat
786 pattern=re.compile(pat)
787 def match(node,output):
788 if output and not out:
789 return False
790 if not output and not inn:
791 return False
792 if anode:
793 return anode==node
794 else:
795 return pattern.match(node.abspath())
796 return match
797 class EnvContext(BuildContext):
798 fun=cmd=None
799 def execute(self):
800 self.restore()
801 if not self.all_envs:
802 self.load_envs()
803 self.recurse([self.run_dir])
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import copy,re,os
5 from waflib import Logs,Utils
6 re_imp=re.compile(r'^(#)*?([^#=]*?)\ =\ (.*?)$',re.M)
7 class ConfigSet(object):
8 __slots__=('table','parent')
9 def __init__(self,filename=None):
10 self.table={}
11 if filename:
12 self.load(filename)
13 def __contains__(self,key):
14 if key in self.table:
15 return True
16 try:
17 return self.parent.__contains__(key)
18 except AttributeError:
19 return False
20 def keys(self):
21 keys=set()
22 cur=self
23 while cur:
24 keys.update(cur.table.keys())
25 cur=getattr(cur,'parent',None)
26 keys=list(keys)
27 keys.sort()
28 return keys
29 def __iter__(self):
30 return iter(self.keys())
31 def __str__(self):
32 return"\n".join(["%r %r"%(x,self.__getitem__(x))for x in self.keys()])
33 def __getitem__(self,key):
34 try:
35 while 1:
36 x=self.table.get(key)
37 if not x is None:
38 return x
39 self=self.parent
40 except AttributeError:
41 return[]
42 def __setitem__(self,key,value):
43 self.table[key]=value
44 def __delitem__(self,key):
45 self[key]=[]
46 def __getattr__(self,name):
47 if name in self.__slots__:
48 return object.__getattribute__(self,name)
49 else:
50 return self[name]
51 def __setattr__(self,name,value):
52 if name in self.__slots__:
53 object.__setattr__(self,name,value)
54 else:
55 self[name]=value
56 def __delattr__(self,name):
57 if name in self.__slots__:
58 object.__delattr__(self,name)
59 else:
60 del self[name]
61 def derive(self):
62 newenv=ConfigSet()
63 newenv.parent=self
64 return newenv
65 def detach(self):
66 tbl=self.get_merged_dict()
67 try:
68 delattr(self,'parent')
69 except AttributeError:
70 pass
71 else:
72 keys=tbl.keys()
73 for x in keys:
74 tbl[x]=copy.deepcopy(tbl[x])
75 self.table=tbl
76 return self
77 def get_flat(self,key):
78 s=self[key]
79 if isinstance(s,str):
80 return s
81 return' '.join(s)
82 def _get_list_value_for_modification(self,key):
83 try:
84 value=self.table[key]
85 except KeyError:
86 try:
87 value=self.parent[key]
88 except AttributeError:
89 value=[]
90 else:
91 if isinstance(value,list):
92 value=value[:]
93 else:
94 value=[value]
95 self.table[key]=value
96 else:
97 if not isinstance(value,list):
98 self.table[key]=value=[value]
99 return value
100 def append_value(self,var,val):
101 if isinstance(val,str):
102 val=[val]
103 current_value=self._get_list_value_for_modification(var)
104 current_value.extend(val)
105 def prepend_value(self,var,val):
106 if isinstance(val,str):
107 val=[val]
108 self.table[var]=val+self._get_list_value_for_modification(var)
109 def append_unique(self,var,val):
110 if isinstance(val,str):
111 val=[val]
112 current_value=self._get_list_value_for_modification(var)
113 for x in val:
114 if x not in current_value:
115 current_value.append(x)
116 def get_merged_dict(self):
117 table_list=[]
118 env=self
119 while 1:
120 table_list.insert(0,env.table)
121 try:
122 env=env.parent
123 except AttributeError:
124 break
125 merged_table={}
126 for table in table_list:
127 merged_table.update(table)
128 return merged_table
129 def store(self,filename):
130 try:
131 os.makedirs(os.path.split(filename)[0])
132 except OSError:
133 pass
134 buf=[]
135 merged_table=self.get_merged_dict()
136 keys=list(merged_table.keys())
137 keys.sort()
138 try:
139 fun=ascii
140 except NameError:
141 fun=repr
142 for k in keys:
143 if k!='undo_stack':
144 buf.append('%s = %s\n'%(k,fun(merged_table[k])))
145 Utils.writef(filename,''.join(buf))
146 def load(self,filename):
147 tbl=self.table
148 code=Utils.readf(filename,m='r')
149 for m in re_imp.finditer(code):
150 g=m.group
151 tbl[g(2)]=eval(g(3))
152 Logs.debug('env: %s',self.table)
153 def update(self,d):
154 self.table.update(d)
155 def stash(self):
156 orig=self.table
157 tbl=self.table=self.table.copy()
158 for x in tbl.keys():
159 tbl[x]=copy.deepcopy(tbl[x])
160 self.undo_stack=self.undo_stack+[orig]
161 def commit(self):
162 self.undo_stack.pop(-1)
163 def revert(self):
164 self.table=self.undo_stack.pop(-1)
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os,re,shlex,shutil,sys,time,traceback
5 from waflib import ConfigSet,Utils,Options,Logs,Context,Build,Errors
6 WAF_CONFIG_LOG='config.log'
7 autoconfig=False
8 conf_template='''# project %(app)s configured on %(now)s by
9 # waf %(wafver)s (abi %(abi)s, python %(pyver)x on %(systype)s)
10 # using %(args)s
11 #'''
12 class ConfigurationContext(Context.Context):
13 '''configures the project'''
14 cmd='configure'
15 error_handlers=[]
16 def __init__(self,**kw):
17 super(ConfigurationContext,self).__init__(**kw)
18 self.environ=dict(os.environ)
19 self.all_envs={}
20 self.top_dir=None
21 self.out_dir=None
22 self.tools=[]
23 self.hash=0
24 self.files=[]
25 self.tool_cache=[]
26 self.setenv('')
27 def setenv(self,name,env=None):
28 if name not in self.all_envs or env:
29 if not env:
30 env=ConfigSet.ConfigSet()
31 self.prepare_env(env)
32 else:
33 env=env.derive()
34 self.all_envs[name]=env
35 self.variant=name
36 def get_env(self):
37 return self.all_envs[self.variant]
38 def set_env(self,val):
39 self.all_envs[self.variant]=val
40 env=property(get_env,set_env)
41 def init_dirs(self):
42 top=self.top_dir
43 if not top:
44 top=Options.options.top
45 if not top:
46 top=getattr(Context.g_module,Context.TOP,None)
47 if not top:
48 top=self.path.abspath()
49 top=os.path.abspath(top)
50 self.srcnode=(os.path.isabs(top)and self.root or self.path).find_dir(top)
51 assert(self.srcnode)
52 out=self.out_dir
53 if not out:
54 out=Options.options.out
55 if not out:
56 out=getattr(Context.g_module,Context.OUT,None)
57 if not out:
58 out=Options.lockfile.replace('.lock-waf_%s_'%sys.platform,'').replace('.lock-waf','')
59 out=os.path.realpath(out)
60 self.bldnode=(os.path.isabs(out)and self.root or self.path).make_node(out)
61 self.bldnode.mkdir()
62 if not os.path.isdir(self.bldnode.abspath()):
63 self.fatal('Could not create the build directory %s'%self.bldnode.abspath())
64 def execute(self):
65 self.init_dirs()
66 self.cachedir=self.bldnode.make_node(Build.CACHE_DIR)
67 self.cachedir.mkdir()
68 path=os.path.join(self.bldnode.abspath(),WAF_CONFIG_LOG)
69 self.logger=Logs.make_logger(path,'cfg')
70 app=getattr(Context.g_module,'APPNAME','')
71 if app:
72 ver=getattr(Context.g_module,'VERSION','')
73 if ver:
74 app="%s (%s)"%(app,ver)
75 params={'now':time.ctime(),'pyver':sys.hexversion,'systype':sys.platform,'args':" ".join(sys.argv),'wafver':Context.WAFVERSION,'abi':Context.ABI,'app':app}
76 self.to_log(conf_template%params)
77 self.msg('Setting top to',self.srcnode.abspath())
78 self.msg('Setting out to',self.bldnode.abspath())
79 if id(self.srcnode)==id(self.bldnode):
80 Logs.warn('Setting top == out')
81 elif id(self.path)!=id(self.srcnode):
82 if self.srcnode.is_child_of(self.path):
83 Logs.warn('Are you certain that you do not want to set top="." ?')
84 super(ConfigurationContext,self).execute()
85 self.store()
86 Context.top_dir=self.srcnode.abspath()
87 Context.out_dir=self.bldnode.abspath()
88 env=ConfigSet.ConfigSet()
89 env.argv=sys.argv
90 env.options=Options.options.__dict__
91 env.config_cmd=self.cmd
92 env.run_dir=Context.run_dir
93 env.top_dir=Context.top_dir
94 env.out_dir=Context.out_dir
95 env.hash=self.hash
96 env.files=self.files
97 env.environ=dict(self.environ)
98 env.launch_dir=Context.launch_dir
99 if not(self.env.NO_LOCK_IN_RUN or env.environ.get('NO_LOCK_IN_RUN')or getattr(Options.options,'no_lock_in_run')):
100 env.store(os.path.join(Context.run_dir,Options.lockfile))
101 if not(self.env.NO_LOCK_IN_TOP or env.environ.get('NO_LOCK_IN_TOP')or getattr(Options.options,'no_lock_in_top')):
102 env.store(os.path.join(Context.top_dir,Options.lockfile))
103 if not(self.env.NO_LOCK_IN_OUT or env.environ.get('NO_LOCK_IN_OUT')or getattr(Options.options,'no_lock_in_out')):
104 env.store(os.path.join(Context.out_dir,Options.lockfile))
105 def prepare_env(self,env):
106 if not env.PREFIX:
107 if Options.options.prefix or Utils.is_win32:
108 env.PREFIX=Options.options.prefix
109 else:
110 env.PREFIX='/'
111 if not env.BINDIR:
112 if Options.options.bindir:
113 env.BINDIR=Options.options.bindir
114 else:
115 env.BINDIR=Utils.subst_vars('${PREFIX}/bin',env)
116 if not env.LIBDIR:
117 if Options.options.libdir:
118 env.LIBDIR=Options.options.libdir
119 else:
120 env.LIBDIR=Utils.subst_vars('${PREFIX}/lib%s'%Utils.lib64(),env)
121 def store(self):
122 n=self.cachedir.make_node('build.config.py')
123 n.write('version = 0x%x\ntools = %r\n'%(Context.HEXVERSION,self.tools))
124 if not self.all_envs:
125 self.fatal('nothing to store in the configuration context!')
126 for key in self.all_envs:
127 tmpenv=self.all_envs[key]
128 tmpenv.store(os.path.join(self.cachedir.abspath(),key+Build.CACHE_SUFFIX))
129 def load(self,tool_list,tooldir=None,funs=None,with_sys_path=True,cache=False):
130 tools=Utils.to_list(tool_list)
131 if tooldir:
132 tooldir=Utils.to_list(tooldir)
133 for tool in tools:
134 if cache:
135 mag=(tool,id(self.env),tooldir,funs)
136 if mag in self.tool_cache:
137 self.to_log('(tool %s is already loaded, skipping)'%tool)
138 continue
139 self.tool_cache.append(mag)
140 module=None
141 try:
142 module=Context.load_tool(tool,tooldir,ctx=self,with_sys_path=with_sys_path)
143 except ImportError as e:
144 self.fatal('Could not load the Waf tool %r from %r\n%s'%(tool,getattr(e,'waf_sys_path',sys.path),e))
145 except Exception as e:
146 self.to_log('imp %r (%r & %r)'%(tool,tooldir,funs))
147 self.to_log(traceback.format_exc())
148 raise
149 if funs is not None:
150 self.eval_rules(funs)
151 else:
152 func=getattr(module,'configure',None)
153 if func:
154 if type(func)is type(Utils.readf):
155 func(self)
156 else:
157 self.eval_rules(func)
158 self.tools.append({'tool':tool,'tooldir':tooldir,'funs':funs})
159 def post_recurse(self,node):
160 super(ConfigurationContext,self).post_recurse(node)
161 self.hash=Utils.h_list((self.hash,node.read('rb')))
162 self.files.append(node.abspath())
163 def eval_rules(self,rules):
164 self.rules=Utils.to_list(rules)
165 for x in self.rules:
166 f=getattr(self,x)
167 if not f:
168 self.fatal('No such configuration function %r'%x)
169 f()
170 def conf(f):
171 def fun(*k,**kw):
172 mandatory=kw.pop('mandatory',True)
173 try:
174 return f(*k,**kw)
175 except Errors.ConfigurationError:
176 if mandatory:
177 raise
178 fun.__name__=f.__name__
179 setattr(ConfigurationContext,f.__name__,fun)
180 setattr(Build.BuildContext,f.__name__,fun)
181 return f
182 @conf
183 def add_os_flags(self,var,dest=None,dup=False):
184 try:
185 flags=shlex.split(self.environ[var])
186 except KeyError:
187 return
188 if dup or''.join(flags)not in''.join(Utils.to_list(self.env[dest or var])):
189 self.env.append_value(dest or var,flags)
190 @conf
191 def cmd_to_list(self,cmd):
192 if isinstance(cmd,str):
193 if os.path.isfile(cmd):
194 return[cmd]
195 if os.sep=='/':
196 return shlex.split(cmd)
197 else:
198 try:
199 return shlex.split(cmd,posix=False)
200 except TypeError:
201 return shlex.split(cmd)
202 return cmd
203 @conf
204 def check_waf_version(self,mini='1.9.99',maxi='2.1.0',**kw):
205 self.start_msg('Checking for waf version in %s-%s'%(str(mini),str(maxi)),**kw)
206 ver=Context.HEXVERSION
207 if Utils.num2ver(mini)>ver:
208 self.fatal('waf version should be at least %r (%r found)'%(Utils.num2ver(mini),ver))
209 if Utils.num2ver(maxi)<ver:
210 self.fatal('waf version should be at most %r (%r found)'%(Utils.num2ver(maxi),ver))
211 self.end_msg('ok',**kw)
212 @conf
213 def find_file(self,filename,path_list=[]):
214 for n in Utils.to_list(filename):
215 for d in Utils.to_list(path_list):
216 p=os.path.expanduser(os.path.join(d,n))
217 if os.path.exists(p):
218 return p
219 self.fatal('Could not find %r'%filename)
220 @conf
221 def find_program(self,filename,**kw):
222 exts=kw.get('exts',Utils.is_win32 and'.exe,.com,.bat,.cmd'or',.sh,.pl,.py')
223 environ=kw.get('environ',getattr(self,'environ',os.environ))
224 ret=''
225 filename=Utils.to_list(filename)
226 msg=kw.get('msg',', '.join(filename))
227 var=kw.get('var','')
228 if not var:
229 var=re.sub(r'[-.]','_',filename[0].upper())
230 path_list=kw.get('path_list','')
231 if path_list:
232 path_list=Utils.to_list(path_list)
233 else:
234 path_list=environ.get('PATH','').split(os.pathsep)
235 if kw.get('value'):
236 ret=self.cmd_to_list(kw['value'])
237 elif environ.get(var):
238 ret=self.cmd_to_list(environ[var])
239 elif self.env[var]:
240 ret=self.cmd_to_list(self.env[var])
241 else:
242 if not ret:
243 ret=self.find_binary(filename,exts.split(','),path_list)
244 if not ret and Utils.winreg:
245 ret=Utils.get_registry_app_path(Utils.winreg.HKEY_CURRENT_USER,filename)
246 if not ret and Utils.winreg:
247 ret=Utils.get_registry_app_path(Utils.winreg.HKEY_LOCAL_MACHINE,filename)
248 ret=self.cmd_to_list(ret)
249 if ret:
250 if len(ret)==1:
251 retmsg=ret[0]
252 else:
253 retmsg=ret
254 else:
255 retmsg=False
256 self.msg('Checking for program %r'%msg,retmsg,**kw)
257 if not kw.get('quiet'):
258 self.to_log('find program=%r paths=%r var=%r -> %r'%(filename,path_list,var,ret))
259 if not ret:
260 self.fatal(kw.get('errmsg','')or'Could not find the program %r'%filename)
261 interpreter=kw.get('interpreter')
262 if interpreter is None:
263 if not Utils.check_exe(ret[0],env=environ):
264 self.fatal('Program %r is not executable'%ret)
265 self.env[var]=ret
266 else:
267 self.env[var]=self.env[interpreter]+ret
268 return ret
269 @conf
270 def find_binary(self,filenames,exts,paths):
271 for f in filenames:
272 for ext in exts:
273 exe_name=f+ext
274 if os.path.isabs(exe_name):
275 if os.path.isfile(exe_name):
276 return exe_name
277 else:
278 for path in paths:
279 x=os.path.expanduser(os.path.join(path,exe_name))
280 if os.path.isfile(x):
281 return x
282 return None
283 @conf
284 def run_build(self,*k,**kw):
285 buf=[]
286 for key in sorted(kw.keys()):
287 v=kw[key]
288 if hasattr(v,'__call__'):
289 buf.append(Utils.h_fun(v))
290 else:
291 buf.append(str(v))
292 h=Utils.h_list(buf)
293 dir=self.bldnode.abspath()+os.sep+(not Utils.is_win32 and'.'or'')+'conf_check_'+Utils.to_hex(h)
294 cachemode=kw.get('confcache',getattr(Options.options,'confcache',None))
295 if not cachemode and os.path.exists(dir):
296 shutil.rmtree(dir)
297 try:
298 os.makedirs(dir)
299 except OSError:
300 pass
301 try:
302 os.stat(dir)
303 except OSError:
304 self.fatal('cannot use the configuration test folder %r'%dir)
305 if cachemode==1:
306 try:
307 proj=ConfigSet.ConfigSet(os.path.join(dir,'cache_run_build'))
308 except EnvironmentError:
309 pass
310 else:
311 ret=proj['cache_run_build']
312 if isinstance(ret,str)and ret.startswith('Test does not build'):
313 self.fatal(ret)
314 return ret
315 bdir=os.path.join(dir,'testbuild')
316 if not os.path.exists(bdir):
317 os.makedirs(bdir)
318 cls_name=kw.get('run_build_cls')or getattr(self,'run_build_cls','build')
319 self.test_bld=bld=Context.create_context(cls_name,top_dir=dir,out_dir=bdir)
320 bld.init_dirs()
321 bld.progress_bar=0
322 bld.targets='*'
323 bld.logger=self.logger
324 bld.all_envs.update(self.all_envs)
325 bld.env=kw['env']
326 bld.kw=kw
327 bld.conf=self
328 kw['build_fun'](bld)
329 ret=-1
330 try:
331 try:
332 bld.compile()
333 except Errors.WafError:
334 ret='Test does not build: %s'%traceback.format_exc()
335 self.fatal(ret)
336 else:
337 ret=getattr(bld,'retval',0)
338 finally:
339 if cachemode:
340 proj=ConfigSet.ConfigSet()
341 proj['cache_run_build']=ret
342 proj.store(os.path.join(dir,'cache_run_build'))
343 else:
344 shutil.rmtree(dir)
345 return ret
346 @conf
347 def ret_msg(self,msg,args):
348 if isinstance(msg,str):
349 return msg
350 return msg(args)
351 @conf
352 def test(self,*k,**kw):
353 if not'env'in kw:
354 kw['env']=self.env.derive()
355 if kw.get('validate'):
356 kw['validate'](kw)
357 self.start_msg(kw['msg'],**kw)
358 ret=None
359 try:
360 ret=self.run_build(*k,**kw)
361 except self.errors.ConfigurationError:
362 self.end_msg(kw['errmsg'],'YELLOW',**kw)
363 if Logs.verbose>1:
364 raise
365 else:
366 self.fatal('The configuration failed')
367 else:
368 kw['success']=ret
369 if kw.get('post_check'):
370 ret=kw['post_check'](kw)
371 if ret:
372 self.end_msg(kw['errmsg'],'YELLOW',**kw)
373 self.fatal('The configuration failed %r'%ret)
374 else:
375 self.end_msg(self.ret_msg(kw['okmsg'],kw),**kw)
376 return ret
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os,re,sys
5 from waflib import Utils,Errors,Logs
6 import waflib.Node
7 if sys.hexversion>0x3040000:
8 import types
9 class imp(object):
10 new_module=lambda x:types.ModuleType(x)
11 else:
12 import imp
13 HEXVERSION=0x2001300
14 WAFVERSION="2.0.19"
15 WAFREVISION="e83405712e95b47c040763fdfa468c04dfe72e4b"
16 WAFNAME="waf"
17 ABI=20
18 DBFILE='.wafpickle-%s-%d-%d'%(sys.platform,sys.hexversion,ABI)
19 APPNAME='APPNAME'
20 VERSION='VERSION'
21 TOP='top'
22 OUT='out'
23 WSCRIPT_FILE='wscript'
24 launch_dir=''
25 run_dir=''
26 top_dir=''
27 out_dir=''
28 waf_dir=''
29 default_encoding=Utils.console_encoding()
30 g_module=None
31 STDOUT=1
32 STDERR=-1
33 BOTH=0
34 classes=[]
35 def create_context(cmd_name,*k,**kw):
36 for x in classes:
37 if x.cmd==cmd_name:
38 return x(*k,**kw)
39 ctx=Context(*k,**kw)
40 ctx.fun=cmd_name
41 return ctx
42 class store_context(type):
43 def __init__(cls,name,bases,dct):
44 super(store_context,cls).__init__(name,bases,dct)
45 name=cls.__name__
46 if name in('ctx','Context'):
47 return
48 try:
49 cls.cmd
50 except AttributeError:
51 raise Errors.WafError('Missing command for the context class %r (cmd)'%name)
52 if not getattr(cls,'fun',None):
53 cls.fun=cls.cmd
54 classes.insert(0,cls)
55 ctx=store_context('ctx',(object,),{})
56 class Context(ctx):
57 errors=Errors
58 tools={}
59 def __init__(self,**kw):
60 try:
61 rd=kw['run_dir']
62 except KeyError:
63 rd=run_dir
64 self.node_class=type('Nod3',(waflib.Node.Node,),{})
65 self.node_class.__module__='waflib.Node'
66 self.node_class.ctx=self
67 self.root=self.node_class('',None)
68 self.cur_script=None
69 self.path=self.root.find_dir(rd)
70 self.stack_path=[]
71 self.exec_dict={'ctx':self,'conf':self,'bld':self,'opt':self}
72 self.logger=None
73 def finalize(self):
74 try:
75 logger=self.logger
76 except AttributeError:
77 pass
78 else:
79 Logs.free_logger(logger)
80 delattr(self,'logger')
81 def load(self,tool_list,*k,**kw):
82 tools=Utils.to_list(tool_list)
83 path=Utils.to_list(kw.get('tooldir',''))
84 with_sys_path=kw.get('with_sys_path',True)
85 for t in tools:
86 module=load_tool(t,path,with_sys_path=with_sys_path)
87 fun=getattr(module,kw.get('name',self.fun),None)
88 if fun:
89 fun(self)
90 def execute(self):
91 self.recurse([os.path.dirname(g_module.root_path)])
92 def pre_recurse(self,node):
93 self.stack_path.append(self.cur_script)
94 self.cur_script=node
95 self.path=node.parent
96 def post_recurse(self,node):
97 self.cur_script=self.stack_path.pop()
98 if self.cur_script:
99 self.path=self.cur_script.parent
100 def recurse(self,dirs,name=None,mandatory=True,once=True,encoding=None):
101 try:
102 cache=self.recurse_cache
103 except AttributeError:
104 cache=self.recurse_cache={}
105 for d in Utils.to_list(dirs):
106 if not os.path.isabs(d):
107 d=os.path.join(self.path.abspath(),d)
108 WSCRIPT=os.path.join(d,WSCRIPT_FILE)
109 WSCRIPT_FUN=WSCRIPT+'_'+(name or self.fun)
110 node=self.root.find_node(WSCRIPT_FUN)
111 if node and(not once or node not in cache):
112 cache[node]=True
113 self.pre_recurse(node)
114 try:
115 function_code=node.read('r',encoding)
116 exec(compile(function_code,node.abspath(),'exec'),self.exec_dict)
117 finally:
118 self.post_recurse(node)
119 elif not node:
120 node=self.root.find_node(WSCRIPT)
121 tup=(node,name or self.fun)
122 if node and(not once or tup not in cache):
123 cache[tup]=True
124 self.pre_recurse(node)
125 try:
126 wscript_module=load_module(node.abspath(),encoding=encoding)
127 user_function=getattr(wscript_module,(name or self.fun),None)
128 if not user_function:
129 if not mandatory:
130 continue
131 raise Errors.WafError('No function %r defined in %s'%(name or self.fun,node.abspath()))
132 user_function(self)
133 finally:
134 self.post_recurse(node)
135 elif not node:
136 if not mandatory:
137 continue
138 try:
139 os.listdir(d)
140 except OSError:
141 raise Errors.WafError('Cannot read the folder %r'%d)
142 raise Errors.WafError('No wscript file in directory %s'%d)
143 def log_command(self,cmd,kw):
144 if Logs.verbose:
145 fmt=os.environ.get('WAF_CMD_FORMAT')
146 if fmt=='string':
147 if not isinstance(cmd,str):
148 cmd=Utils.shell_escape(cmd)
149 Logs.debug('runner: %r',cmd)
150 Logs.debug('runner_env: kw=%s',kw)
151 def exec_command(self,cmd,**kw):
152 subprocess=Utils.subprocess
153 kw['shell']=isinstance(cmd,str)
154 self.log_command(cmd,kw)
155 if self.logger:
156 self.logger.info(cmd)
157 if'stdout'not in kw:
158 kw['stdout']=subprocess.PIPE
159 if'stderr'not in kw:
160 kw['stderr']=subprocess.PIPE
161 if Logs.verbose and not kw['shell']and not Utils.check_exe(cmd[0]):
162 raise Errors.WafError('Program %s not found!'%cmd[0])
163 cargs={}
164 if'timeout'in kw:
165 if sys.hexversion>=0x3030000:
166 cargs['timeout']=kw['timeout']
167 if not'start_new_session'in kw:
168 kw['start_new_session']=True
169 del kw['timeout']
170 if'input'in kw:
171 if kw['input']:
172 cargs['input']=kw['input']
173 kw['stdin']=subprocess.PIPE
174 del kw['input']
175 if'cwd'in kw:
176 if not isinstance(kw['cwd'],str):
177 kw['cwd']=kw['cwd'].abspath()
178 encoding=kw.pop('decode_as',default_encoding)
179 try:
180 ret,out,err=Utils.run_process(cmd,kw,cargs)
181 except Exception as e:
182 raise Errors.WafError('Execution failure: %s'%str(e),ex=e)
183 if out:
184 if not isinstance(out,str):
185 out=out.decode(encoding,errors='replace')
186 if self.logger:
187 self.logger.debug('out: %s',out)
188 else:
189 Logs.info(out,extra={'stream':sys.stdout,'c1':''})
190 if err:
191 if not isinstance(err,str):
192 err=err.decode(encoding,errors='replace')
193 if self.logger:
194 self.logger.error('err: %s'%err)
195 else:
196 Logs.info(err,extra={'stream':sys.stderr,'c1':''})
197 return ret
198 def cmd_and_log(self,cmd,**kw):
199 subprocess=Utils.subprocess
200 kw['shell']=isinstance(cmd,str)
201 self.log_command(cmd,kw)
202 quiet=kw.pop('quiet',None)
203 to_ret=kw.pop('output',STDOUT)
204 if Logs.verbose and not kw['shell']and not Utils.check_exe(cmd[0]):
205 raise Errors.WafError('Program %r not found!'%cmd[0])
206 kw['stdout']=kw['stderr']=subprocess.PIPE
207 if quiet is None:
208 self.to_log(cmd)
209 cargs={}
210 if'timeout'in kw:
211 if sys.hexversion>=0x3030000:
212 cargs['timeout']=kw['timeout']
213 if not'start_new_session'in kw:
214 kw['start_new_session']=True
215 del kw['timeout']
216 if'input'in kw:
217 if kw['input']:
218 cargs['input']=kw['input']
219 kw['stdin']=subprocess.PIPE
220 del kw['input']
221 if'cwd'in kw:
222 if not isinstance(kw['cwd'],str):
223 kw['cwd']=kw['cwd'].abspath()
224 encoding=kw.pop('decode_as',default_encoding)
225 try:
226 ret,out,err=Utils.run_process(cmd,kw,cargs)
227 except Exception as e:
228 raise Errors.WafError('Execution failure: %s'%str(e),ex=e)
229 if not isinstance(out,str):
230 out=out.decode(encoding,errors='replace')
231 if not isinstance(err,str):
232 err=err.decode(encoding,errors='replace')
233 if out and quiet!=STDOUT and quiet!=BOTH:
234 self.to_log('out: %s'%out)
235 if err and quiet!=STDERR and quiet!=BOTH:
236 self.to_log('err: %s'%err)
237 if ret:
238 e=Errors.WafError('Command %r returned %r'%(cmd,ret))
239 e.returncode=ret
240 e.stderr=err
241 e.stdout=out
242 raise e
243 if to_ret==BOTH:
244 return(out,err)
245 elif to_ret==STDERR:
246 return err
247 return out
248 def fatal(self,msg,ex=None):
249 if self.logger:
250 self.logger.info('from %s: %s'%(self.path.abspath(),msg))
251 try:
252 logfile=self.logger.handlers[0].baseFilename
253 except AttributeError:
254 pass
255 else:
256 if os.environ.get('WAF_PRINT_FAILURE_LOG'):
257 msg='Log from (%s):\n%s\n'%(logfile,Utils.readf(logfile))
258 else:
259 msg='%s\n(complete log in %s)'%(msg,logfile)
260 raise self.errors.ConfigurationError(msg,ex=ex)
261 def to_log(self,msg):
262 if not msg:
263 return
264 if self.logger:
265 self.logger.info(msg)
266 else:
267 sys.stderr.write(str(msg))
268 sys.stderr.flush()
269 def msg(self,*k,**kw):
270 try:
271 msg=kw['msg']
272 except KeyError:
273 msg=k[0]
274 self.start_msg(msg,**kw)
275 try:
276 result=kw['result']
277 except KeyError:
278 result=k[1]
279 color=kw.get('color')
280 if not isinstance(color,str):
281 color=result and'GREEN'or'YELLOW'
282 self.end_msg(result,color,**kw)
283 def start_msg(self,*k,**kw):
284 if kw.get('quiet'):
285 return
286 msg=kw.get('msg')or k[0]
287 try:
288 if self.in_msg:
289 self.in_msg+=1
290 return
291 except AttributeError:
292 self.in_msg=0
293 self.in_msg+=1
294 try:
295 self.line_just=max(self.line_just,len(msg))
296 except AttributeError:
297 self.line_just=max(40,len(msg))
298 for x in(self.line_just*'-',msg):
299 self.to_log(x)
300 Logs.pprint('NORMAL',"%s :"%msg.ljust(self.line_just),sep='')
301 def end_msg(self,*k,**kw):
302 if kw.get('quiet'):
303 return
304 self.in_msg-=1
305 if self.in_msg:
306 return
307 result=kw.get('result')or k[0]
308 defcolor='GREEN'
309 if result is True:
310 msg='ok'
311 elif not result:
312 msg='not found'
313 defcolor='YELLOW'
314 else:
315 msg=str(result)
316 self.to_log(msg)
317 try:
318 color=kw['color']
319 except KeyError:
320 if len(k)>1 and k[1]in Logs.colors_lst:
321 color=k[1]
322 else:
323 color=defcolor
324 Logs.pprint(color,msg)
325 def load_special_tools(self,var,ban=[]):
326 if os.path.isdir(waf_dir):
327 lst=self.root.find_node(waf_dir).find_node('waflib/extras').ant_glob(var)
328 for x in lst:
329 if not x.name in ban:
330 load_tool(x.name.replace('.py',''))
331 else:
332 from zipfile import PyZipFile
333 waflibs=PyZipFile(waf_dir)
334 lst=waflibs.namelist()
335 for x in lst:
336 if not re.match('waflib/extras/%s'%var.replace('*','.*'),var):
337 continue
338 f=os.path.basename(x)
339 doban=False
340 for b in ban:
341 r=b.replace('*','.*')
342 if re.match(r,f):
343 doban=True
344 if not doban:
345 f=f.replace('.py','')
346 load_tool(f)
347 cache_modules={}
348 def load_module(path,encoding=None):
349 try:
350 return cache_modules[path]
351 except KeyError:
352 pass
353 module=imp.new_module(WSCRIPT_FILE)
354 try:
355 code=Utils.readf(path,m='r',encoding=encoding)
356 except EnvironmentError:
357 raise Errors.WafError('Could not read the file %r'%path)
358 module_dir=os.path.dirname(path)
359 sys.path.insert(0,module_dir)
360 try:
361 exec(compile(code,path,'exec'),module.__dict__)
362 finally:
363 sys.path.remove(module_dir)
364 cache_modules[path]=module
365 return module
366 def load_tool(tool,tooldir=None,ctx=None,with_sys_path=True):
367 if tool=='java':
368 tool='javaw'
369 else:
370 tool=tool.replace('++','xx')
371 if not with_sys_path:
372 back_path=sys.path
373 sys.path=[]
374 try:
375 if tooldir:
376 assert isinstance(tooldir,list)
377 sys.path=tooldir+sys.path
378 try:
379 __import__(tool)
380 except ImportError as e:
381 e.waf_sys_path=list(sys.path)
382 raise
383 finally:
384 for d in tooldir:
385 sys.path.remove(d)
386 ret=sys.modules[tool]
387 Context.tools[tool]=ret
388 return ret
389 else:
390 if not with_sys_path:
391 sys.path.insert(0,waf_dir)
392 try:
393 for x in('waflib.Tools.%s','waflib.extras.%s','waflib.%s','%s'):
394 try:
395 __import__(x%tool)
396 break
397 except ImportError:
398 x=None
399 else:
400 __import__(tool)
401 except ImportError as e:
402 e.waf_sys_path=list(sys.path)
403 raise
404 finally:
405 if not with_sys_path:
406 sys.path.remove(waf_dir)
407 ret=sys.modules[x%tool]
408 Context.tools[tool]=ret
409 return ret
410 finally:
411 if not with_sys_path:
412 sys.path+=back_path
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import traceback,sys
5 class WafError(Exception):
6 def __init__(self,msg='',ex=None):
7 Exception.__init__(self)
8 self.msg=msg
9 assert not isinstance(msg,Exception)
10 self.stack=[]
11 if ex:
12 if not msg:
13 self.msg=str(ex)
14 if isinstance(ex,WafError):
15 self.stack=ex.stack
16 else:
17 self.stack=traceback.extract_tb(sys.exc_info()[2])
18 self.stack+=traceback.extract_stack()[:-1]
19 self.verbose_msg=''.join(traceback.format_list(self.stack))
20 def __str__(self):
21 return str(self.msg)
22 class BuildError(WafError):
23 def __init__(self,error_tasks=[]):
24 self.tasks=error_tasks
25 WafError.__init__(self,self.format_error())
26 def format_error(self):
27 lst=['Build failed']
28 for tsk in self.tasks:
29 txt=tsk.format_error()
30 if txt:
31 lst.append(txt)
32 return'\n'.join(lst)
33 class ConfigurationError(WafError):
34 pass
35 class TaskRescan(WafError):
36 pass
37 class TaskNotReady(WafError):
38 pass
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os,re,traceback,sys
5 from waflib import Utils,ansiterm
6 if not os.environ.get('NOSYNC',False):
7 if sys.stdout.isatty()and id(sys.stdout)==id(sys.__stdout__):
8 sys.stdout=ansiterm.AnsiTerm(sys.stdout)
9 if sys.stderr.isatty()and id(sys.stderr)==id(sys.__stderr__):
10 sys.stderr=ansiterm.AnsiTerm(sys.stderr)
11 import logging
12 LOG_FORMAT=os.environ.get('WAF_LOG_FORMAT','%(asctime)s %(c1)s%(zone)s%(c2)s %(message)s')
13 HOUR_FORMAT=os.environ.get('WAF_HOUR_FORMAT','%H:%M:%S')
14 zones=[]
15 verbose=0
16 colors_lst={'USE':True,'BOLD':'\x1b[01;1m','RED':'\x1b[01;31m','GREEN':'\x1b[32m','YELLOW':'\x1b[33m','PINK':'\x1b[35m','BLUE':'\x1b[01;34m','CYAN':'\x1b[36m','GREY':'\x1b[37m','NORMAL':'\x1b[0m','cursor_on':'\x1b[?25h','cursor_off':'\x1b[?25l',}
17 indicator='\r\x1b[K%s%s%s'
18 try:
19 unicode
20 except NameError:
21 unicode=None
22 def enable_colors(use):
23 if use==1:
24 if not(sys.stderr.isatty()or sys.stdout.isatty()):
25 use=0
26 if Utils.is_win32 and os.name!='java':
27 term=os.environ.get('TERM','')
28 else:
29 term=os.environ.get('TERM','dumb')
30 if term in('dumb','emacs'):
31 use=0
32 if use>=1:
33 os.environ['TERM']='vt100'
34 colors_lst['USE']=use
35 try:
36 get_term_cols=ansiterm.get_term_cols
37 except AttributeError:
38 def get_term_cols():
39 return 80
40 get_term_cols.__doc__="""
41 Returns the console width in characters.
42
43 :return: the number of characters per line
44 :rtype: int
45 """
46 def get_color(cl):
47 if colors_lst['USE']:
48 return colors_lst.get(cl,'')
49 return''
50 class color_dict(object):
51 def __getattr__(self,a):
52 return get_color(a)
53 def __call__(self,a):
54 return get_color(a)
55 colors=color_dict()
56 re_log=re.compile(r'(\w+): (.*)',re.M)
57 class log_filter(logging.Filter):
58 def __init__(self,name=''):
59 logging.Filter.__init__(self,name)
60 def filter(self,rec):
61 rec.zone=rec.module
62 if rec.levelno>=logging.INFO:
63 return True
64 m=re_log.match(rec.msg)
65 if m:
66 rec.zone=m.group(1)
67 rec.msg=m.group(2)
68 if zones:
69 return getattr(rec,'zone','')in zones or'*'in zones
70 elif not verbose>2:
71 return False
72 return True
73 class log_handler(logging.StreamHandler):
74 def emit(self,record):
75 try:
76 try:
77 self.stream=record.stream
78 except AttributeError:
79 if record.levelno>=logging.WARNING:
80 record.stream=self.stream=sys.stderr
81 else:
82 record.stream=self.stream=sys.stdout
83 self.emit_override(record)
84 self.flush()
85 except(KeyboardInterrupt,SystemExit):
86 raise
87 except:
88 self.handleError(record)
89 def emit_override(self,record,**kw):
90 self.terminator=getattr(record,'terminator','\n')
91 stream=self.stream
92 if unicode:
93 msg=self.formatter.format(record)
94 fs='%s'+self.terminator
95 try:
96 if(isinstance(msg,unicode)and getattr(stream,'encoding',None)):
97 fs=fs.decode(stream.encoding)
98 try:
99 stream.write(fs%msg)
100 except UnicodeEncodeError:
101 stream.write((fs%msg).encode(stream.encoding))
102 else:
103 stream.write(fs%msg)
104 except UnicodeError:
105 stream.write((fs%msg).encode('utf-8'))
106 else:
107 logging.StreamHandler.emit(self,record)
108 class formatter(logging.Formatter):
109 def __init__(self):
110 logging.Formatter.__init__(self,LOG_FORMAT,HOUR_FORMAT)
111 def format(self,rec):
112 try:
113 msg=rec.msg.decode('utf-8')
114 except Exception:
115 msg=rec.msg
116 use=colors_lst['USE']
117 if(use==1 and rec.stream.isatty())or use==2:
118 c1=getattr(rec,'c1',None)
119 if c1 is None:
120 c1=''
121 if rec.levelno>=logging.ERROR:
122 c1=colors.RED
123 elif rec.levelno>=logging.WARNING:
124 c1=colors.YELLOW
125 elif rec.levelno>=logging.INFO:
126 c1=colors.GREEN
127 c2=getattr(rec,'c2',colors.NORMAL)
128 msg='%s%s%s'%(c1,msg,c2)
129 else:
130 msg=re.sub(r'\r(?!\n)|\x1B\[(K|.*?(m|h|l))','',msg)
131 if rec.levelno>=logging.INFO:
132 if rec.args:
133 try:
134 return msg%rec.args
135 except UnicodeDecodeError:
136 return msg.encode('utf-8')%rec.args
137 return msg
138 rec.msg=msg
139 rec.c1=colors.PINK
140 rec.c2=colors.NORMAL
141 return logging.Formatter.format(self,rec)
142 log=None
143 def debug(*k,**kw):
144 if verbose:
145 k=list(k)
146 k[0]=k[0].replace('\n',' ')
147 log.debug(*k,**kw)
148 def error(*k,**kw):
149 log.error(*k,**kw)
150 if verbose>2:
151 st=traceback.extract_stack()
152 if st:
153 st=st[:-1]
154 buf=[]
155 for filename,lineno,name,line in st:
156 buf.append(' File %r, line %d, in %s'%(filename,lineno,name))
157 if line:
158 buf.append(' %s'%line.strip())
159 if buf:
160 log.error('\n'.join(buf))
161 def warn(*k,**kw):
162 log.warning(*k,**kw)
163 def info(*k,**kw):
164 log.info(*k,**kw)
165 def init_log():
166 global log
167 log=logging.getLogger('waflib')
168 log.handlers=[]
169 log.filters=[]
170 hdlr=log_handler()
171 hdlr.setFormatter(formatter())
172 log.addHandler(hdlr)
173 log.addFilter(log_filter())
174 log.setLevel(logging.DEBUG)
175 def make_logger(path,name):
176 logger=logging.getLogger(name)
177 if sys.hexversion>0x3000000:
178 encoding=sys.stdout.encoding
179 else:
180 encoding=None
181 hdlr=logging.FileHandler(path,'w',encoding=encoding)
182 formatter=logging.Formatter('%(message)s')
183 hdlr.setFormatter(formatter)
184 logger.addHandler(hdlr)
185 logger.setLevel(logging.DEBUG)
186 return logger
187 def make_mem_logger(name,to_log,size=8192):
188 from logging.handlers import MemoryHandler
189 logger=logging.getLogger(name)
190 hdlr=MemoryHandler(size,target=to_log)
191 formatter=logging.Formatter('%(message)s')
192 hdlr.setFormatter(formatter)
193 logger.addHandler(hdlr)
194 logger.memhandler=hdlr
195 logger.setLevel(logging.DEBUG)
196 return logger
197 def free_logger(logger):
198 try:
199 for x in logger.handlers:
200 x.close()
201 logger.removeHandler(x)
202 except Exception:
203 pass
204 def pprint(col,msg,label='',sep='\n'):
205 info('%s%s%s %s',colors(col),msg,colors.NORMAL,label,extra={'terminator':sep})
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os,re,sys,shutil
5 from waflib import Utils,Errors
6 exclude_regs='''
7 **/*~
8 **/#*#
9 **/.#*
10 **/%*%
11 **/._*
12 **/*.swp
13 **/CVS
14 **/CVS/**
15 **/.cvsignore
16 **/SCCS
17 **/SCCS/**
18 **/vssver.scc
19 **/.svn
20 **/.svn/**
21 **/BitKeeper
22 **/.git
23 **/.git/**
24 **/.gitignore
25 **/.bzr
26 **/.bzrignore
27 **/.bzr/**
28 **/.hg
29 **/.hg/**
30 **/_MTN
31 **/_MTN/**
32 **/.arch-ids
33 **/{arch}
34 **/_darcs
35 **/_darcs/**
36 **/.intlcache
37 **/.DS_Store'''
38 def ant_matcher(s,ignorecase):
39 reflags=re.I if ignorecase else 0
40 ret=[]
41 for x in Utils.to_list(s):
42 x=x.replace('\\','/').replace('//','/')
43 if x.endswith('/'):
44 x+='**'
45 accu=[]
46 for k in x.split('/'):
47 if k=='**':
48 accu.append(k)
49 else:
50 k=k.replace('.','[.]').replace('*','.*').replace('?','.').replace('+','\\+')
51 k='^%s$'%k
52 try:
53 exp=re.compile(k,flags=reflags)
54 except Exception as e:
55 raise Errors.WafError('Invalid pattern: %s'%k,e)
56 else:
57 accu.append(exp)
58 ret.append(accu)
59 return ret
60 def ant_sub_filter(name,nn):
61 ret=[]
62 for lst in nn:
63 if not lst:
64 pass
65 elif lst[0]=='**':
66 ret.append(lst)
67 if len(lst)>1:
68 if lst[1].match(name):
69 ret.append(lst[2:])
70 else:
71 ret.append([])
72 elif lst[0].match(name):
73 ret.append(lst[1:])
74 return ret
75 def ant_sub_matcher(name,pats):
76 nacc=ant_sub_filter(name,pats[0])
77 nrej=ant_sub_filter(name,pats[1])
78 if[]in nrej:
79 nacc=[]
80 return[nacc,nrej]
81 class Node(object):
82 dict_class=dict
83 __slots__=('name','parent','children','cache_abspath','cache_isdir')
84 def __init__(self,name,parent):
85 self.name=name
86 self.parent=parent
87 if parent:
88 if name in parent.children:
89 raise Errors.WafError('node %s exists in the parent files %r already'%(name,parent))
90 parent.children[name]=self
91 def __setstate__(self,data):
92 self.name=data[0]
93 self.parent=data[1]
94 if data[2]is not None:
95 self.children=self.dict_class(data[2])
96 def __getstate__(self):
97 return(self.name,self.parent,getattr(self,'children',None))
98 def __str__(self):
99 return self.abspath()
100 def __repr__(self):
101 return self.abspath()
102 def __copy__(self):
103 raise Errors.WafError('nodes are not supposed to be copied')
104 def read(self,flags='r',encoding='latin-1'):
105 return Utils.readf(self.abspath(),flags,encoding)
106 def write(self,data,flags='w',encoding='latin-1'):
107 Utils.writef(self.abspath(),data,flags,encoding)
108 def read_json(self,convert=True,encoding='utf-8'):
109 import json
110 object_pairs_hook=None
111 if convert and sys.hexversion<0x3000000:
112 try:
113 _type=unicode
114 except NameError:
115 _type=str
116 def convert(value):
117 if isinstance(value,list):
118 return[convert(element)for element in value]
119 elif isinstance(value,_type):
120 return str(value)
121 else:
122 return value
123 def object_pairs(pairs):
124 return dict((str(pair[0]),convert(pair[1]))for pair in pairs)
125 object_pairs_hook=object_pairs
126 return json.loads(self.read(encoding=encoding),object_pairs_hook=object_pairs_hook)
127 def write_json(self,data,pretty=True):
128 import json
129 indent=2
130 separators=(',',': ')
131 sort_keys=pretty
132 newline=os.linesep
133 if not pretty:
134 indent=None
135 separators=(',',':')
136 newline=''
137 output=json.dumps(data,indent=indent,separators=separators,sort_keys=sort_keys)+newline
138 self.write(output,encoding='utf-8')
139 def exists(self):
140 return os.path.exists(self.abspath())
141 def isdir(self):
142 return os.path.isdir(self.abspath())
143 def chmod(self,val):
144 os.chmod(self.abspath(),val)
145 def delete(self,evict=True):
146 try:
147 try:
148 if os.path.isdir(self.abspath()):
149 shutil.rmtree(self.abspath())
150 else:
151 os.remove(self.abspath())
152 except OSError:
153 if os.path.exists(self.abspath()):
154 raise
155 finally:
156 if evict:
157 self.evict()
158 def evict(self):
159 del self.parent.children[self.name]
160 def suffix(self):
161 k=max(0,self.name.rfind('.'))
162 return self.name[k:]
163 def height(self):
164 d=self
165 val=-1
166 while d:
167 d=d.parent
168 val+=1
169 return val
170 def listdir(self):
171 lst=Utils.listdir(self.abspath())
172 lst.sort()
173 return lst
174 def mkdir(self):
175 if self.isdir():
176 return
177 try:
178 self.parent.mkdir()
179 except OSError:
180 pass
181 if self.name:
182 try:
183 os.makedirs(self.abspath())
184 except OSError:
185 pass
186 if not self.isdir():
187 raise Errors.WafError('Could not create the directory %r'%self)
188 try:
189 self.children
190 except AttributeError:
191 self.children=self.dict_class()
192 def find_node(self,lst):
193 if isinstance(lst,str):
194 lst=[x for x in Utils.split_path(lst)if x and x!='.']
195 if lst and lst[0].startswith('\\\\')and not self.parent:
196 node=self.ctx.root.make_node(lst[0])
197 node.cache_isdir=True
198 return node.find_node(lst[1:])
199 cur=self
200 for x in lst:
201 if x=='..':
202 cur=cur.parent or cur
203 continue
204 try:
205 ch=cur.children
206 except AttributeError:
207 cur.children=self.dict_class()
208 else:
209 try:
210 cur=ch[x]
211 continue
212 except KeyError:
213 pass
214 cur=self.__class__(x,cur)
215 if not cur.exists():
216 cur.evict()
217 return None
218 if not cur.exists():
219 cur.evict()
220 return None
221 return cur
222 def make_node(self,lst):
223 if isinstance(lst,str):
224 lst=[x for x in Utils.split_path(lst)if x and x!='.']
225 cur=self
226 for x in lst:
227 if x=='..':
228 cur=cur.parent or cur
229 continue
230 try:
231 cur=cur.children[x]
232 except AttributeError:
233 cur.children=self.dict_class()
234 except KeyError:
235 pass
236 else:
237 continue
238 cur=self.__class__(x,cur)
239 return cur
240 def search_node(self,lst):
241 if isinstance(lst,str):
242 lst=[x for x in Utils.split_path(lst)if x and x!='.']
243 cur=self
244 for x in lst:
245 if x=='..':
246 cur=cur.parent or cur
247 else:
248 try:
249 cur=cur.children[x]
250 except(AttributeError,KeyError):
251 return None
252 return cur
253 def path_from(self,node):
254 c1=self
255 c2=node
256 c1h=c1.height()
257 c2h=c2.height()
258 lst=[]
259 up=0
260 while c1h>c2h:
261 lst.append(c1.name)
262 c1=c1.parent
263 c1h-=1
264 while c2h>c1h:
265 up+=1
266 c2=c2.parent
267 c2h-=1
268 while not c1 is c2:
269 lst.append(c1.name)
270 up+=1
271 c1=c1.parent
272 c2=c2.parent
273 if c1.parent:
274 lst.extend(['..']*up)
275 lst.reverse()
276 return os.sep.join(lst)or'.'
277 else:
278 return self.abspath()
279 def abspath(self):
280 try:
281 return self.cache_abspath
282 except AttributeError:
283 pass
284 if not self.parent:
285 val=os.sep
286 elif not self.parent.name:
287 val=os.sep+self.name
288 else:
289 val=self.parent.abspath()+os.sep+self.name
290 self.cache_abspath=val
291 return val
292 if Utils.is_win32:
293 def abspath(self):
294 try:
295 return self.cache_abspath
296 except AttributeError:
297 pass
298 if not self.parent:
299 val=''
300 elif not self.parent.name:
301 val=self.name+os.sep
302 else:
303 val=self.parent.abspath().rstrip(os.sep)+os.sep+self.name
304 self.cache_abspath=val
305 return val
306 def is_child_of(self,node):
307 p=self
308 diff=self.height()-node.height()
309 while diff>0:
310 diff-=1
311 p=p.parent
312 return p is node
313 def ant_iter(self,accept=None,maxdepth=25,pats=[],dir=False,src=True,remove=True,quiet=False):
314 dircont=self.listdir()
315 try:
316 lst=set(self.children.keys())
317 except AttributeError:
318 self.children=self.dict_class()
319 else:
320 if remove:
321 for x in lst-set(dircont):
322 self.children[x].evict()
323 for name in dircont:
324 npats=accept(name,pats)
325 if npats and npats[0]:
326 accepted=[]in npats[0]
327 node=self.make_node([name])
328 isdir=node.isdir()
329 if accepted:
330 if isdir:
331 if dir:
332 yield node
333 elif src:
334 yield node
335 if isdir:
336 node.cache_isdir=True
337 if maxdepth:
338 for k in node.ant_iter(accept=accept,maxdepth=maxdepth-1,pats=npats,dir=dir,src=src,remove=remove,quiet=quiet):
339 yield k
340 def ant_glob(self,*k,**kw):
341 src=kw.get('src',True)
342 dir=kw.get('dir')
343 excl=kw.get('excl',exclude_regs)
344 incl=k and k[0]or kw.get('incl','**')
345 remove=kw.get('remove',True)
346 maxdepth=kw.get('maxdepth',25)
347 ignorecase=kw.get('ignorecase',False)
348 quiet=kw.get('quiet',False)
349 pats=(ant_matcher(incl,ignorecase),ant_matcher(excl,ignorecase))
350 if kw.get('generator'):
351 return Utils.lazy_generator(self.ant_iter,(ant_sub_matcher,maxdepth,pats,dir,src,remove,quiet))
352 it=self.ant_iter(ant_sub_matcher,maxdepth,pats,dir,src,remove,quiet)
353 if kw.get('flat'):
354 return' '.join(x.path_from(self)for x in it)
355 return list(it)
356 def is_src(self):
357 cur=self
358 x=self.ctx.srcnode
359 y=self.ctx.bldnode
360 while cur.parent:
361 if cur is y:
362 return False
363 if cur is x:
364 return True
365 cur=cur.parent
366 return False
367 def is_bld(self):
368 cur=self
369 y=self.ctx.bldnode
370 while cur.parent:
371 if cur is y:
372 return True
373 cur=cur.parent
374 return False
375 def get_src(self):
376 cur=self
377 x=self.ctx.srcnode
378 y=self.ctx.bldnode
379 lst=[]
380 while cur.parent:
381 if cur is y:
382 lst.reverse()
383 return x.make_node(lst)
384 if cur is x:
385 return self
386 lst.append(cur.name)
387 cur=cur.parent
388 return self
389 def get_bld(self):
390 cur=self
391 x=self.ctx.srcnode
392 y=self.ctx.bldnode
393 lst=[]
394 while cur.parent:
395 if cur is y:
396 return self
397 if cur is x:
398 lst.reverse()
399 return self.ctx.bldnode.make_node(lst)
400 lst.append(cur.name)
401 cur=cur.parent
402 lst.reverse()
403 if lst and Utils.is_win32 and len(lst[0])==2 and lst[0].endswith(':'):
404 lst[0]=lst[0][0]
405 return self.ctx.bldnode.make_node(['__root__']+lst)
406 def find_resource(self,lst):
407 if isinstance(lst,str):
408 lst=[x for x in Utils.split_path(lst)if x and x!='.']
409 node=self.get_bld().search_node(lst)
410 if not node:
411 node=self.get_src().find_node(lst)
412 if node and node.isdir():
413 return None
414 return node
415 def find_or_declare(self,lst):
416 if isinstance(lst,str)and os.path.isabs(lst):
417 node=self.ctx.root.make_node(lst)
418 else:
419 node=self.get_bld().make_node(lst)
420 node.parent.mkdir()
421 return node
422 def find_dir(self,lst):
423 if isinstance(lst,str):
424 lst=[x for x in Utils.split_path(lst)if x and x!='.']
425 node=self.find_node(lst)
426 if node and not node.isdir():
427 return None
428 return node
429 def change_ext(self,ext,ext_in=None):
430 name=self.name
431 if ext_in is None:
432 k=name.rfind('.')
433 if k>=0:
434 name=name[:k]+ext
435 else:
436 name=name+ext
437 else:
438 name=name[:-len(ext_in)]+ext
439 return self.parent.find_or_declare([name])
440 def bldpath(self):
441 return self.path_from(self.ctx.bldnode)
442 def srcpath(self):
443 return self.path_from(self.ctx.srcnode)
444 def relpath(self):
445 cur=self
446 x=self.ctx.bldnode
447 while cur.parent:
448 if cur is x:
449 return self.bldpath()
450 cur=cur.parent
451 return self.srcpath()
452 def bld_dir(self):
453 return self.parent.bldpath()
454 def h_file(self):
455 return Utils.h_file(self.abspath())
456 def get_bld_sig(self):
457 try:
458 cache=self.ctx.cache_sig
459 except AttributeError:
460 cache=self.ctx.cache_sig={}
461 try:
462 ret=cache[self]
463 except KeyError:
464 p=self.abspath()
465 try:
466 ret=cache[self]=self.h_file()
467 except EnvironmentError:
468 if self.isdir():
469 st=os.stat(p)
470 ret=cache[self]=Utils.h_list([p,st.st_ino,st.st_mode])
471 return ret
472 raise
473 return ret
474 pickle_lock=Utils.threading.Lock()
475 class Nod3(Node):
476 pass
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os,tempfile,optparse,sys,re
5 from waflib import Logs,Utils,Context,Errors
6 options=optparse.Values()
7 commands=[]
8 envvars=[]
9 lockfile=os.environ.get('WAFLOCK','.lock-waf_%s_build'%sys.platform)
10 class opt_parser(optparse.OptionParser):
11 def __init__(self,ctx,allow_unknown=False):
12 optparse.OptionParser.__init__(self,conflict_handler='resolve',add_help_option=False,version='%s %s (%s)'%(Context.WAFNAME,Context.WAFVERSION,Context.WAFREVISION))
13 self.formatter.width=Logs.get_term_cols()
14 self.ctx=ctx
15 self.allow_unknown=allow_unknown
16 def _process_args(self,largs,rargs,values):
17 while rargs:
18 try:
19 optparse.OptionParser._process_args(self,largs,rargs,values)
20 except(optparse.BadOptionError,optparse.AmbiguousOptionError)as e:
21 if self.allow_unknown:
22 largs.append(e.opt_str)
23 else:
24 self.error(str(e))
25 def print_usage(self,file=None):
26 return self.print_help(file)
27 def get_usage(self):
28 cmds_str={}
29 for cls in Context.classes:
30 if not cls.cmd or cls.cmd=='options'or cls.cmd.startswith('_'):
31 continue
32 s=cls.__doc__ or''
33 cmds_str[cls.cmd]=s
34 if Context.g_module:
35 for(k,v)in Context.g_module.__dict__.items():
36 if k in('options','init','shutdown'):
37 continue
38 if type(v)is type(Context.create_context):
39 if v.__doc__ and not k.startswith('_'):
40 cmds_str[k]=v.__doc__
41 just=0
42 for k in cmds_str:
43 just=max(just,len(k))
44 lst=[' %s: %s'%(k.ljust(just),v)for(k,v)in cmds_str.items()]
45 lst.sort()
46 ret='\n'.join(lst)
47 return'''%s [commands] [options]
48
49 Main commands (example: ./%s build -j4)
50 %s
51 '''%(Context.WAFNAME,Context.WAFNAME,ret)
52 class OptionsContext(Context.Context):
53 cmd='options'
54 fun='options'
55 def __init__(self,**kw):
56 super(OptionsContext,self).__init__(**kw)
57 self.parser=opt_parser(self)
58 self.option_groups={}
59 jobs=self.jobs()
60 p=self.add_option
61 color=os.environ.get('NOCOLOR','')and'no'or'auto'
62 if os.environ.get('CLICOLOR','')=='0':
63 color='no'
64 elif os.environ.get('CLICOLOR_FORCE','')=='1':
65 color='yes'
66 p('-c','--color',dest='colors',default=color,action='store',help='whether to use colors (yes/no/auto) [default: auto]',choices=('yes','no','auto'))
67 p('-j','--jobs',dest='jobs',default=jobs,type='int',help='amount of parallel jobs (%r)'%jobs)
68 p('-k','--keep',dest='keep',default=0,action='count',help='continue despite errors (-kk to try harder)')
69 p('-v','--verbose',dest='verbose',default=0,action='count',help='verbosity level -v -vv or -vvv [default: 0]')
70 p('--zones',dest='zones',default='',action='store',help='debugging zones (task_gen, deps, tasks, etc)')
71 p('--profile',dest='profile',default=0,action='store_true',help=optparse.SUPPRESS_HELP)
72 p('--pdb',dest='pdb',default=0,action='store_true',help=optparse.SUPPRESS_HELP)
73 p('-h','--help',dest='whelp',default=0,action='store_true',help="show this help message and exit")
74 gr=self.add_option_group('Configuration options')
75 self.option_groups['configure options']=gr
76 gr.add_option('-o','--out',action='store',default='',help='build dir for the project',dest='out')
77 gr.add_option('-t','--top',action='store',default='',help='src dir for the project',dest='top')
78 gr.add_option('--no-lock-in-run',action='store_true',default='',help=optparse.SUPPRESS_HELP,dest='no_lock_in_run')
79 gr.add_option('--no-lock-in-out',action='store_true',default='',help=optparse.SUPPRESS_HELP,dest='no_lock_in_out')
80 gr.add_option('--no-lock-in-top',action='store_true',default='',help=optparse.SUPPRESS_HELP,dest='no_lock_in_top')
81 default_prefix=getattr(Context.g_module,'default_prefix',os.environ.get('PREFIX'))
82 if not default_prefix:
83 if Utils.unversioned_sys_platform()=='win32':
84 d=tempfile.gettempdir()
85 default_prefix=d[0].upper()+d[1:]
86 else:
87 default_prefix='/usr/local/'
88 gr.add_option('--prefix',dest='prefix',default=default_prefix,help='installation prefix [default: %r]'%default_prefix)
89 gr.add_option('--bindir',dest='bindir',help='bindir')
90 gr.add_option('--libdir',dest='libdir',help='libdir')
91 gr=self.add_option_group('Build and installation options')
92 self.option_groups['build and install options']=gr
93 gr.add_option('-p','--progress',dest='progress_bar',default=0,action='count',help='-p: progress bar; -pp: ide output')
94 gr.add_option('--targets',dest='targets',default='',action='store',help='task generators, e.g. "target1,target2"')
95 gr=self.add_option_group('Step options')
96 self.option_groups['step options']=gr
97 gr.add_option('--files',dest='files',default='',action='store',help='files to process, by regexp, e.g. "*/main.c,*/test/main.o"')
98 default_destdir=os.environ.get('DESTDIR','')
99 gr=self.add_option_group('Installation and uninstallation options')
100 self.option_groups['install/uninstall options']=gr
101 gr.add_option('--destdir',help='installation root [default: %r]'%default_destdir,default=default_destdir,dest='destdir')
102 gr.add_option('-f','--force',dest='force',default=False,action='store_true',help='force file installation')
103 gr.add_option('--distcheck-args',metavar='ARGS',help='arguments to pass to distcheck',default=None,action='store')
104 def jobs(self):
105 count=int(os.environ.get('JOBS',0))
106 if count<1:
107 if'NUMBER_OF_PROCESSORS'in os.environ:
108 count=int(os.environ.get('NUMBER_OF_PROCESSORS',1))
109 else:
110 if hasattr(os,'sysconf_names'):
111 if'SC_NPROCESSORS_ONLN'in os.sysconf_names:
112 count=int(os.sysconf('SC_NPROCESSORS_ONLN'))
113 elif'SC_NPROCESSORS_CONF'in os.sysconf_names:
114 count=int(os.sysconf('SC_NPROCESSORS_CONF'))
115 if not count and os.name not in('nt','java'):
116 try:
117 tmp=self.cmd_and_log(['sysctl','-n','hw.ncpu'],quiet=0)
118 except Errors.WafError:
119 pass
120 else:
121 if re.match('^[0-9]+$',tmp):
122 count=int(tmp)
123 if count<1:
124 count=1
125 elif count>1024:
126 count=1024
127 return count
128 def add_option(self,*k,**kw):
129 return self.parser.add_option(*k,**kw)
130 def add_option_group(self,*k,**kw):
131 try:
132 gr=self.option_groups[k[0]]
133 except KeyError:
134 gr=self.parser.add_option_group(*k,**kw)
135 self.option_groups[k[0]]=gr
136 return gr
137 def get_option_group(self,opt_str):
138 try:
139 return self.option_groups[opt_str]
140 except KeyError:
141 for group in self.parser.option_groups:
142 if group.title==opt_str:
143 return group
144 return None
145 def sanitize_path(self,path,cwd=None):
146 if not cwd:
147 cwd=Context.launch_dir
148 p=os.path.expanduser(path)
149 p=os.path.join(cwd,p)
150 p=os.path.normpath(p)
151 p=os.path.abspath(p)
152 return p
153 def parse_cmd_args(self,_args=None,cwd=None,allow_unknown=False):
154 self.parser.allow_unknown=allow_unknown
155 (options,leftover_args)=self.parser.parse_args(args=_args)
156 envvars=[]
157 commands=[]
158 for arg in leftover_args:
159 if'='in arg:
160 envvars.append(arg)
161 elif arg!='options':
162 commands.append(arg)
163 if options.jobs<1:
164 options.jobs=1
165 for name in'top out destdir prefix bindir libdir'.split():
166 if getattr(options,name,None):
167 path=self.sanitize_path(getattr(options,name),cwd)
168 setattr(options,name,path)
169 return options,commands,envvars
170 def init_module_vars(self,arg_options,arg_commands,arg_envvars):
171 options.__dict__.clear()
172 del commands[:]
173 del envvars[:]
174 options.__dict__.update(arg_options.__dict__)
175 commands.extend(arg_commands)
176 envvars.extend(arg_envvars)
177 for var in envvars:
178 (name,value)=var.split('=',1)
179 os.environ[name.strip()]=value
180 def init_logs(self,options,commands,envvars):
181 Logs.verbose=options.verbose
182 if options.verbose>=1:
183 self.load('errcheck')
184 colors={'yes':2,'auto':1,'no':0}[options.colors]
185 Logs.enable_colors(colors)
186 if options.zones:
187 Logs.zones=options.zones.split(',')
188 if not Logs.verbose:
189 Logs.verbose=1
190 elif Logs.verbose>0:
191 Logs.zones=['runner']
192 if Logs.verbose>2:
193 Logs.zones=['*']
194 def parse_args(self,_args=None):
195 options,commands,envvars=self.parse_cmd_args()
196 self.init_logs(options,commands,envvars)
197 self.init_module_vars(options,commands,envvars)
198 def execute(self):
199 super(OptionsContext,self).execute()
200 self.parse_args()
201 Utils.alloc_process_pool(options.jobs)
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import heapq,traceback
5 try:
6 from queue import Queue,PriorityQueue
7 except ImportError:
8 from Queue import Queue
9 try:
10 from Queue import PriorityQueue
11 except ImportError:
12 class PriorityQueue(Queue):
13 def _init(self,maxsize):
14 self.maxsize=maxsize
15 self.queue=[]
16 def _put(self,item):
17 heapq.heappush(self.queue,item)
18 def _get(self):
19 return heapq.heappop(self.queue)
20 from waflib import Utils,Task,Errors,Logs
21 GAP=5
22 class PriorityTasks(object):
23 def __init__(self):
24 self.lst=[]
25 def __len__(self):
26 return len(self.lst)
27 def __iter__(self):
28 return iter(self.lst)
29 def __str__(self):
30 return'PriorityTasks: [%s]'%'\n '.join(str(x)for x in self.lst)
31 def clear(self):
32 self.lst=[]
33 def append(self,task):
34 heapq.heappush(self.lst,task)
35 def appendleft(self,task):
36 heapq.heappush(self.lst,task)
37 def pop(self):
38 return heapq.heappop(self.lst)
39 def extend(self,lst):
40 if self.lst:
41 for x in lst:
42 self.append(x)
43 else:
44 if isinstance(lst,list):
45 self.lst=lst
46 heapq.heapify(lst)
47 else:
48 self.lst=lst.lst
49 class Consumer(Utils.threading.Thread):
50 def __init__(self,spawner,task):
51 Utils.threading.Thread.__init__(self)
52 self.task=task
53 self.spawner=spawner
54 self.setDaemon(1)
55 self.start()
56 def run(self):
57 try:
58 if not self.spawner.master.stop:
59 self.spawner.master.process_task(self.task)
60 finally:
61 self.spawner.sem.release()
62 self.spawner.master.out.put(self.task)
63 self.task=None
64 self.spawner=None
65 class Spawner(Utils.threading.Thread):
66 def __init__(self,master):
67 Utils.threading.Thread.__init__(self)
68 self.master=master
69 self.sem=Utils.threading.Semaphore(master.numjobs)
70 self.setDaemon(1)
71 self.start()
72 def run(self):
73 try:
74 self.loop()
75 except Exception:
76 pass
77 def loop(self):
78 master=self.master
79 while 1:
80 task=master.ready.get()
81 self.sem.acquire()
82 if not master.stop:
83 task.log_display(task.generator.bld)
84 Consumer(self,task)
85 class Parallel(object):
86 def __init__(self,bld,j=2):
87 self.numjobs=j
88 self.bld=bld
89 self.outstanding=PriorityTasks()
90 self.postponed=PriorityTasks()
91 self.incomplete=set()
92 self.ready=PriorityQueue(0)
93 self.out=Queue(0)
94 self.count=0
95 self.processed=0
96 self.stop=False
97 self.error=[]
98 self.biter=None
99 self.dirty=False
100 self.revdeps=Utils.defaultdict(set)
101 self.spawner=None
102 if self.numjobs>1:
103 self.spawner=Spawner(self)
104 def get_next_task(self):
105 if not self.outstanding:
106 return None
107 return self.outstanding.pop()
108 def postpone(self,tsk):
109 self.postponed.append(tsk)
110 def refill_task_list(self):
111 while self.count>self.numjobs*GAP:
112 self.get_out()
113 while not self.outstanding:
114 if self.count:
115 self.get_out()
116 if self.outstanding:
117 break
118 elif self.postponed:
119 try:
120 cond=self.deadlock==self.processed
121 except AttributeError:
122 pass
123 else:
124 if cond:
125 lst=[]
126 for tsk in self.postponed:
127 deps=[id(x)for x in tsk.run_after if not x.hasrun]
128 lst.append('%s\t-> %r'%(repr(tsk),deps))
129 if not deps:
130 lst.append('\n task %r dependencies are done, check its *runnable_status*?'%id(tsk))
131 raise Errors.WafError('Deadlock detected: check the task build order%s'%''.join(lst))
132 self.deadlock=self.processed
133 if self.postponed:
134 self.outstanding.extend(self.postponed)
135 self.postponed.clear()
136 elif not self.count:
137 if self.incomplete:
138 for x in self.incomplete:
139 for k in x.run_after:
140 if not k.hasrun:
141 break
142 else:
143 self.incomplete.remove(x)
144 self.outstanding.append(x)
145 break
146 else:
147 if self.stop or self.error:
148 break
149 raise Errors.WafError('Broken revdeps detected on %r'%self.incomplete)
150 else:
151 tasks=next(self.biter)
152 ready,waiting=self.prio_and_split(tasks)
153 self.outstanding.extend(ready)
154 self.incomplete.update(waiting)
155 self.total=self.bld.total()
156 break
157 def add_more_tasks(self,tsk):
158 if getattr(tsk,'more_tasks',None):
159 more=set(tsk.more_tasks)
160 groups_done=set()
161 def iteri(a,b):
162 for x in a:
163 yield x
164 for x in b:
165 yield x
166 for x in iteri(self.outstanding,self.incomplete):
167 for k in x.run_after:
168 if isinstance(k,Task.TaskGroup):
169 if k not in groups_done:
170 groups_done.add(k)
171 for j in k.prev&more:
172 self.revdeps[j].add(k)
173 elif k in more:
174 self.revdeps[k].add(x)
175 ready,waiting=self.prio_and_split(tsk.more_tasks)
176 self.outstanding.extend(ready)
177 self.incomplete.update(waiting)
178 self.total+=len(tsk.more_tasks)
179 def mark_finished(self,tsk):
180 def try_unfreeze(x):
181 if x in self.incomplete:
182 for k in x.run_after:
183 if not k.hasrun:
184 break
185 else:
186 self.incomplete.remove(x)
187 self.outstanding.append(x)
188 if tsk in self.revdeps:
189 for x in self.revdeps[tsk]:
190 if isinstance(x,Task.TaskGroup):
191 x.prev.remove(tsk)
192 if not x.prev:
193 for k in x.next:
194 k.run_after.remove(x)
195 try_unfreeze(k)
196 x.next=[]
197 else:
198 try_unfreeze(x)
199 del self.revdeps[tsk]
200 if hasattr(tsk,'semaphore'):
201 sem=tsk.semaphore
202 try:
203 sem.release(tsk)
204 except KeyError:
205 pass
206 else:
207 while sem.waiting and not sem.is_locked():
208 x=sem.waiting.pop()
209 self._add_task(x)
210 def get_out(self):
211 tsk=self.out.get()
212 if not self.stop:
213 self.add_more_tasks(tsk)
214 self.mark_finished(tsk)
215 self.count-=1
216 self.dirty=True
217 return tsk
218 def add_task(self,tsk):
219 self.ready.put(tsk)
220 def _add_task(self,tsk):
221 if hasattr(tsk,'semaphore'):
222 sem=tsk.semaphore
223 try:
224 sem.acquire(tsk)
225 except IndexError:
226 sem.waiting.add(tsk)
227 return
228 self.count+=1
229 self.processed+=1
230 if self.numjobs==1:
231 tsk.log_display(tsk.generator.bld)
232 try:
233 self.process_task(tsk)
234 finally:
235 self.out.put(tsk)
236 else:
237 self.add_task(tsk)
238 def process_task(self,tsk):
239 tsk.process()
240 if tsk.hasrun!=Task.SUCCESS:
241 self.error_handler(tsk)
242 def skip(self,tsk):
243 tsk.hasrun=Task.SKIPPED
244 self.mark_finished(tsk)
245 def cancel(self,tsk):
246 tsk.hasrun=Task.CANCELED
247 self.mark_finished(tsk)
248 def error_handler(self,tsk):
249 if not self.bld.keep:
250 self.stop=True
251 self.error.append(tsk)
252 def task_status(self,tsk):
253 try:
254 return tsk.runnable_status()
255 except Exception:
256 self.processed+=1
257 tsk.err_msg=traceback.format_exc()
258 if not self.stop and self.bld.keep:
259 self.skip(tsk)
260 if self.bld.keep==1:
261 if Logs.verbose>1 or not self.error:
262 self.error.append(tsk)
263 self.stop=True
264 else:
265 if Logs.verbose>1:
266 self.error.append(tsk)
267 return Task.EXCEPTION
268 tsk.hasrun=Task.EXCEPTION
269 self.error_handler(tsk)
270 return Task.EXCEPTION
271 def start(self):
272 self.total=self.bld.total()
273 while not self.stop:
274 self.refill_task_list()
275 tsk=self.get_next_task()
276 if not tsk:
277 if self.count:
278 continue
279 else:
280 break
281 if tsk.hasrun:
282 self.processed+=1
283 continue
284 if self.stop:
285 break
286 st=self.task_status(tsk)
287 if st==Task.RUN_ME:
288 self._add_task(tsk)
289 elif st==Task.ASK_LATER:
290 self.postpone(tsk)
291 elif st==Task.SKIP_ME:
292 self.processed+=1
293 self.skip(tsk)
294 self.add_more_tasks(tsk)
295 elif st==Task.CANCEL_ME:
296 if Logs.verbose>1:
297 self.error.append(tsk)
298 self.processed+=1
299 self.cancel(tsk)
300 while self.error and self.count:
301 self.get_out()
302 self.ready.put(None)
303 if not self.stop:
304 assert not self.count
305 assert not self.postponed
306 assert not self.incomplete
307 def prio_and_split(self,tasks):
308 for x in tasks:
309 x.visited=0
310 reverse=self.revdeps
311 groups_done=set()
312 for x in tasks:
313 for k in x.run_after:
314 if isinstance(k,Task.TaskGroup):
315 if k not in groups_done:
316 groups_done.add(k)
317 for j in k.prev:
318 reverse[j].add(k)
319 else:
320 reverse[k].add(x)
321 def visit(n):
322 if isinstance(n,Task.TaskGroup):
323 return sum(visit(k)for k in n.next)
324 if n.visited==0:
325 n.visited=1
326 if n in reverse:
327 rev=reverse[n]
328 n.prio_order=n.tree_weight+len(rev)+sum(visit(k)for k in rev)
329 else:
330 n.prio_order=n.tree_weight
331 n.visited=2
332 elif n.visited==1:
333 raise Errors.WafError('Dependency cycle found!')
334 return n.prio_order
335 for x in tasks:
336 if x.visited!=0:
337 continue
338 try:
339 visit(x)
340 except Errors.WafError:
341 self.debug_cycles(tasks,reverse)
342 ready=[]
343 waiting=[]
344 for x in tasks:
345 for k in x.run_after:
346 if not k.hasrun:
347 waiting.append(x)
348 break
349 else:
350 ready.append(x)
351 return(ready,waiting)
352 def debug_cycles(self,tasks,reverse):
353 tmp={}
354 for x in tasks:
355 tmp[x]=0
356 def visit(n,acc):
357 if isinstance(n,Task.TaskGroup):
358 for k in n.next:
359 visit(k,acc)
360 return
361 if tmp[n]==0:
362 tmp[n]=1
363 for k in reverse.get(n,[]):
364 visit(k,[n]+acc)
365 tmp[n]=2
366 elif tmp[n]==1:
367 lst=[]
368 for tsk in acc:
369 lst.append(repr(tsk))
370 if tsk is n:
371 break
372 raise Errors.WafError('Task dependency cycle in "run_after" constraints: %s'%''.join(lst))
373 for x in tasks:
374 visit(x,[])
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from __future__ import with_statement
5 import os,shlex,shutil,traceback,errno,sys,stat
6 from waflib import Utils,Configure,Logs,Options,ConfigSet,Context,Errors,Build,Node
7 build_dir_override=None
8 no_climb_commands=['configure']
9 default_cmd="build"
10 def waf_entry_point(current_directory,version,wafdir):
11 Logs.init_log()
12 if Context.WAFVERSION!=version:
13 Logs.error('Waf script %r and library %r do not match (directory %r)',version,Context.WAFVERSION,wafdir)
14 sys.exit(1)
15 Context.waf_dir=wafdir
16 Context.run_dir=Context.launch_dir=current_directory
17 start_dir=current_directory
18 no_climb=os.environ.get('NOCLIMB')
19 if len(sys.argv)>1:
20 potential_wscript=os.path.join(current_directory,sys.argv[1])
21 if os.path.basename(potential_wscript)==Context.WSCRIPT_FILE and os.path.isfile(potential_wscript):
22 path=os.path.normpath(os.path.dirname(potential_wscript))
23 start_dir=os.path.abspath(path)
24 no_climb=True
25 sys.argv.pop(1)
26 ctx=Context.create_context('options')
27 (options,commands,env)=ctx.parse_cmd_args(allow_unknown=True)
28 if options.top:
29 start_dir=Context.run_dir=Context.top_dir=options.top
30 no_climb=True
31 if options.out:
32 Context.out_dir=options.out
33 if not no_climb:
34 for k in no_climb_commands:
35 for y in commands:
36 if y.startswith(k):
37 no_climb=True
38 break
39 cur=start_dir
40 while cur:
41 try:
42 lst=os.listdir(cur)
43 except OSError:
44 lst=[]
45 Logs.error('Directory %r is unreadable!',cur)
46 if Options.lockfile in lst:
47 env=ConfigSet.ConfigSet()
48 try:
49 env.load(os.path.join(cur,Options.lockfile))
50 ino=os.stat(cur)[stat.ST_INO]
51 except EnvironmentError:
52 pass
53 else:
54 for x in(env.run_dir,env.top_dir,env.out_dir):
55 if not x:
56 continue
57 if Utils.is_win32:
58 if cur==x:
59 load=True
60 break
61 else:
62 try:
63 ino2=os.stat(x)[stat.ST_INO]
64 except OSError:
65 pass
66 else:
67 if ino==ino2:
68 load=True
69 break
70 else:
71 Logs.warn('invalid lock file in %s',cur)
72 load=False
73 if load:
74 Context.run_dir=env.run_dir
75 Context.top_dir=env.top_dir
76 Context.out_dir=env.out_dir
77 break
78 if not Context.run_dir:
79 if Context.WSCRIPT_FILE in lst:
80 Context.run_dir=cur
81 next=os.path.dirname(cur)
82 if next==cur:
83 break
84 cur=next
85 if no_climb:
86 break
87 wscript=os.path.normpath(os.path.join(Context.run_dir,Context.WSCRIPT_FILE))
88 if not os.path.exists(wscript):
89 if options.whelp:
90 Logs.warn('These are the generic options (no wscript/project found)')
91 ctx.parser.print_help()
92 sys.exit(0)
93 Logs.error('Waf: Run from a folder containing a %r file (or try -h for the generic options)',Context.WSCRIPT_FILE)
94 sys.exit(1)
95 try:
96 os.chdir(Context.run_dir)
97 except OSError:
98 Logs.error('Waf: The folder %r is unreadable',Context.run_dir)
99 sys.exit(1)
100 try:
101 set_main_module(wscript)
102 except Errors.WafError as e:
103 Logs.pprint('RED',e.verbose_msg)
104 Logs.error(str(e))
105 sys.exit(1)
106 except Exception as e:
107 Logs.error('Waf: The wscript in %r is unreadable',Context.run_dir)
108 traceback.print_exc(file=sys.stdout)
109 sys.exit(2)
110 if options.profile:
111 import cProfile,pstats
112 cProfile.runctx('from waflib import Scripting; Scripting.run_commands()',{},{},'profi.txt')
113 p=pstats.Stats('profi.txt')
114 p.sort_stats('time').print_stats(75)
115 else:
116 try:
117 try:
118 run_commands()
119 except:
120 if options.pdb:
121 import pdb
122 type,value,tb=sys.exc_info()
123 traceback.print_exc()
124 pdb.post_mortem(tb)
125 else:
126 raise
127 except Errors.WafError as e:
128 if Logs.verbose>1:
129 Logs.pprint('RED',e.verbose_msg)
130 Logs.error(e.msg)
131 sys.exit(1)
132 except SystemExit:
133 raise
134 except Exception as e:
135 traceback.print_exc(file=sys.stdout)
136 sys.exit(2)
137 except KeyboardInterrupt:
138 Logs.pprint('RED','Interrupted')
139 sys.exit(68)
140 def set_main_module(file_path):
141 Context.g_module=Context.load_module(file_path)
142 Context.g_module.root_path=file_path
143 def set_def(obj):
144 name=obj.__name__
145 if not name in Context.g_module.__dict__:
146 setattr(Context.g_module,name,obj)
147 for k in(dist,distclean,distcheck):
148 set_def(k)
149 if not'init'in Context.g_module.__dict__:
150 Context.g_module.init=Utils.nada
151 if not'shutdown'in Context.g_module.__dict__:
152 Context.g_module.shutdown=Utils.nada
153 if not'options'in Context.g_module.__dict__:
154 Context.g_module.options=Utils.nada
155 def parse_options():
156 ctx=Context.create_context('options')
157 ctx.execute()
158 if not Options.commands:
159 if isinstance(default_cmd,list):
160 Options.commands.extend(default_cmd)
161 else:
162 Options.commands.append(default_cmd)
163 if Options.options.whelp:
164 ctx.parser.print_help()
165 sys.exit(0)
166 def run_command(cmd_name):
167 ctx=Context.create_context(cmd_name)
168 ctx.log_timer=Utils.Timer()
169 ctx.options=Options.options
170 ctx.cmd=cmd_name
171 try:
172 ctx.execute()
173 finally:
174 ctx.finalize()
175 return ctx
176 def run_commands():
177 parse_options()
178 run_command('init')
179 while Options.commands:
180 cmd_name=Options.commands.pop(0)
181 ctx=run_command(cmd_name)
182 Logs.info('%r finished successfully (%s)',cmd_name,ctx.log_timer)
183 run_command('shutdown')
184 def distclean_dir(dirname):
185 for(root,dirs,files)in os.walk(dirname):
186 for f in files:
187 if f.endswith(('.o','.moc','.exe')):
188 fname=os.path.join(root,f)
189 try:
190 os.remove(fname)
191 except OSError:
192 Logs.warn('Could not remove %r',fname)
193 for x in(Context.DBFILE,'config.log'):
194 try:
195 os.remove(x)
196 except OSError:
197 pass
198 try:
199 shutil.rmtree(Build.CACHE_DIR)
200 except OSError:
201 pass
202 def distclean(ctx):
203 '''removes build folders and data'''
204 def remove_and_log(k,fun):
205 try:
206 fun(k)
207 except EnvironmentError as e:
208 if e.errno!=errno.ENOENT:
209 Logs.warn('Could not remove %r',k)
210 if not Options.commands:
211 for k in os.listdir('.'):
212 for x in'.waf-2 waf-2 .waf3-2 waf3-2'.split():
213 if k.startswith(x):
214 remove_and_log(k,shutil.rmtree)
215 cur='.'
216 if ctx.options.no_lock_in_top:
217 cur=ctx.options.out
218 try:
219 lst=os.listdir(cur)
220 except OSError:
221 Logs.warn('Could not read %r',cur)
222 return
223 if Options.lockfile in lst:
224 f=os.path.join(cur,Options.lockfile)
225 try:
226 env=ConfigSet.ConfigSet(f)
227 except EnvironmentError:
228 Logs.warn('Could not read %r',f)
229 return
230 if not env.out_dir or not env.top_dir:
231 Logs.warn('Invalid lock file %r',f)
232 return
233 if env.out_dir==env.top_dir:
234 distclean_dir(env.out_dir)
235 else:
236 remove_and_log(env.out_dir,shutil.rmtree)
237 env_dirs=[env.out_dir]
238 if not ctx.options.no_lock_in_top:
239 env_dirs.append(env.top_dir)
240 if not ctx.options.no_lock_in_run:
241 env_dirs.append(env.run_dir)
242 for k in env_dirs:
243 p=os.path.join(k,Options.lockfile)
244 remove_and_log(p,os.remove)
245 class Dist(Context.Context):
246 '''creates an archive containing the project source code'''
247 cmd='dist'
248 fun='dist'
249 algo='tar.bz2'
250 ext_algo={}
251 def execute(self):
252 self.recurse([os.path.dirname(Context.g_module.root_path)])
253 self.archive()
254 def archive(self):
255 import tarfile
256 arch_name=self.get_arch_name()
257 try:
258 self.base_path
259 except AttributeError:
260 self.base_path=self.path
261 node=self.base_path.make_node(arch_name)
262 try:
263 node.delete()
264 except OSError:
265 pass
266 files=self.get_files()
267 if self.algo.startswith('tar.'):
268 tar=tarfile.open(node.abspath(),'w:'+self.algo.replace('tar.',''))
269 for x in files:
270 self.add_tar_file(x,tar)
271 tar.close()
272 elif self.algo=='zip':
273 import zipfile
274 zip=zipfile.ZipFile(node.abspath(),'w',compression=zipfile.ZIP_DEFLATED)
275 for x in files:
276 archive_name=self.get_base_name()+'/'+x.path_from(self.base_path)
277 zip.write(x.abspath(),archive_name,zipfile.ZIP_DEFLATED)
278 zip.close()
279 else:
280 self.fatal('Valid algo types are tar.bz2, tar.gz, tar.xz or zip')
281 try:
282 from hashlib import sha256
283 except ImportError:
284 digest=''
285 else:
286 digest=' (sha256=%r)'%sha256(node.read(flags='rb')).hexdigest()
287 Logs.info('New archive created: %s%s',self.arch_name,digest)
288 def get_tar_path(self,node):
289 return node.abspath()
290 def add_tar_file(self,x,tar):
291 p=self.get_tar_path(x)
292 tinfo=tar.gettarinfo(name=p,arcname=self.get_tar_prefix()+'/'+x.path_from(self.base_path))
293 tinfo.uid=0
294 tinfo.gid=0
295 tinfo.uname='root'
296 tinfo.gname='root'
297 if os.path.isfile(p):
298 with open(p,'rb')as f:
299 tar.addfile(tinfo,fileobj=f)
300 else:
301 tar.addfile(tinfo)
302 def get_tar_prefix(self):
303 try:
304 return self.tar_prefix
305 except AttributeError:
306 return self.get_base_name()
307 def get_arch_name(self):
308 try:
309 self.arch_name
310 except AttributeError:
311 self.arch_name=self.get_base_name()+'.'+self.ext_algo.get(self.algo,self.algo)
312 return self.arch_name
313 def get_base_name(self):
314 try:
315 self.base_name
316 except AttributeError:
317 appname=getattr(Context.g_module,Context.APPNAME,'noname')
318 version=getattr(Context.g_module,Context.VERSION,'1.0')
319 self.base_name=appname+'-'+version
320 return self.base_name
321 def get_excl(self):
322 try:
323 return self.excl
324 except AttributeError:
325 self.excl=Node.exclude_regs+' **/waf-2.* **/.waf-2.* **/waf3-2.* **/.waf3-2.* **/*~ **/*.rej **/*.orig **/*.pyc **/*.pyo **/*.bak **/*.swp **/.lock-w*'
326 if Context.out_dir:
327 nd=self.root.find_node(Context.out_dir)
328 if nd:
329 self.excl+=' '+nd.path_from(self.base_path)
330 return self.excl
331 def get_files(self):
332 try:
333 files=self.files
334 except AttributeError:
335 files=self.base_path.ant_glob('**/*',excl=self.get_excl())
336 return files
337 def dist(ctx):
338 '''makes a tarball for redistributing the sources'''
339 pass
340 class DistCheck(Dist):
341 fun='distcheck'
342 cmd='distcheck'
343 def execute(self):
344 self.recurse([os.path.dirname(Context.g_module.root_path)])
345 self.archive()
346 self.check()
347 def make_distcheck_cmd(self,tmpdir):
348 cfg=[]
349 if Options.options.distcheck_args:
350 cfg=shlex.split(Options.options.distcheck_args)
351 else:
352 cfg=[x for x in sys.argv if x.startswith('-')]
353 cmd=[sys.executable,sys.argv[0],'configure','build','install','uninstall','--destdir='+tmpdir]+cfg
354 return cmd
355 def check(self):
356 import tempfile,tarfile
357 with tarfile.open(self.get_arch_name())as t:
358 for x in t:
359 t.extract(x)
360 instdir=tempfile.mkdtemp('.inst',self.get_base_name())
361 cmd=self.make_distcheck_cmd(instdir)
362 ret=Utils.subprocess.Popen(cmd,cwd=self.get_base_name()).wait()
363 if ret:
364 raise Errors.WafError('distcheck failed with code %r'%ret)
365 if os.path.exists(instdir):
366 raise Errors.WafError('distcheck succeeded, but files were left in %s'%instdir)
367 shutil.rmtree(self.get_base_name())
368 def distcheck(ctx):
369 '''checks if the project compiles (tarball from 'dist')'''
370 pass
371 def autoconfigure(execute_method):
372 def execute(self):
373 if not Configure.autoconfig:
374 return execute_method(self)
375 env=ConfigSet.ConfigSet()
376 do_config=False
377 try:
378 env.load(os.path.join(Context.top_dir,Options.lockfile))
379 except EnvironmentError:
380 Logs.warn('Configuring the project')
381 do_config=True
382 else:
383 if env.run_dir!=Context.run_dir:
384 do_config=True
385 else:
386 h=0
387 for f in env.files:
388 try:
389 h=Utils.h_list((h,Utils.readf(f,'rb')))
390 except EnvironmentError:
391 do_config=True
392 break
393 else:
394 do_config=h!=env.hash
395 if do_config:
396 cmd=env.config_cmd or'configure'
397 if Configure.autoconfig=='clobber':
398 tmp=Options.options.__dict__
399 launch_dir_tmp=Context.launch_dir
400 if env.options:
401 Options.options.__dict__=env.options
402 Context.launch_dir=env.launch_dir
403 try:
404 run_command(cmd)
405 finally:
406 Options.options.__dict__=tmp
407 Context.launch_dir=launch_dir_tmp
408 else:
409 run_command(cmd)
410 run_command(self.cmd)
411 else:
412 return execute_method(self)
413 return execute
414 Build.BuildContext.execute=autoconfigure(Build.BuildContext.execute)
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os,re,sys,tempfile,traceback
5 from waflib import Utils,Logs,Errors
6 NOT_RUN=0
7 MISSING=1
8 CRASHED=2
9 EXCEPTION=3
10 CANCELED=4
11 SKIPPED=8
12 SUCCESS=9
13 ASK_LATER=-1
14 SKIP_ME=-2
15 RUN_ME=-3
16 CANCEL_ME=-4
17 COMPILE_TEMPLATE_SHELL='''
18 def f(tsk):
19 env = tsk.env
20 gen = tsk.generator
21 bld = gen.bld
22 cwdx = tsk.get_cwd()
23 p = env.get_flat
24 def to_list(xx):
25 if isinstance(xx, str): return [xx]
26 return xx
27 tsk.last_cmd = cmd = \'\'\' %s \'\'\' % s
28 return tsk.exec_command(cmd, cwd=cwdx, env=env.env or None)
29 '''
30 COMPILE_TEMPLATE_NOSHELL='''
31 def f(tsk):
32 env = tsk.env
33 gen = tsk.generator
34 bld = gen.bld
35 cwdx = tsk.get_cwd()
36 def to_list(xx):
37 if isinstance(xx, str): return [xx]
38 return xx
39 def merge(lst1, lst2):
40 if lst1 and lst2:
41 return lst1[:-1] + [lst1[-1] + lst2[0]] + lst2[1:]
42 return lst1 + lst2
43 lst = []
44 %s
45 if '' in lst:
46 lst = [x for x in lst if x]
47 tsk.last_cmd = lst
48 return tsk.exec_command(lst, cwd=cwdx, env=env.env or None)
49 '''
50 COMPILE_TEMPLATE_SIG_VARS='''
51 def f(tsk):
52 sig = tsk.generator.bld.hash_env_vars(tsk.env, tsk.vars)
53 tsk.m.update(sig)
54 env = tsk.env
55 gen = tsk.generator
56 bld = gen.bld
57 cwdx = tsk.get_cwd()
58 p = env.get_flat
59 buf = []
60 %s
61 tsk.m.update(repr(buf).encode())
62 '''
63 classes={}
64 class store_task_type(type):
65 def __init__(cls,name,bases,dict):
66 super(store_task_type,cls).__init__(name,bases,dict)
67 name=cls.__name__
68 if name!='evil'and name!='Task':
69 if getattr(cls,'run_str',None):
70 (f,dvars)=compile_fun(cls.run_str,cls.shell)
71 cls.hcode=Utils.h_cmd(cls.run_str)
72 cls.orig_run_str=cls.run_str
73 cls.run_str=None
74 cls.run=f
75 cls.vars=list(set(cls.vars+dvars))
76 cls.vars.sort()
77 if cls.vars:
78 fun=compile_sig_vars(cls.vars)
79 if fun:
80 cls.sig_vars=fun
81 elif getattr(cls,'run',None)and not'hcode'in cls.__dict__:
82 cls.hcode=Utils.h_cmd(cls.run)
83 getattr(cls,'register',classes)[name]=cls
84 evil=store_task_type('evil',(object,),{})
85 class Task(evil):
86 vars=[]
87 always_run=False
88 shell=False
89 color='GREEN'
90 ext_in=[]
91 ext_out=[]
92 before=[]
93 after=[]
94 hcode=Utils.SIG_NIL
95 keep_last_cmd=False
96 weight=0
97 tree_weight=0
98 prio_order=0
99 __slots__=('hasrun','generator','env','inputs','outputs','dep_nodes','run_after')
100 def __init__(self,*k,**kw):
101 self.hasrun=NOT_RUN
102 try:
103 self.generator=kw['generator']
104 except KeyError:
105 self.generator=self
106 self.env=kw['env']
107 self.inputs=[]
108 self.outputs=[]
109 self.dep_nodes=[]
110 self.run_after=set()
111 def __lt__(self,other):
112 return self.priority()>other.priority()
113 def __le__(self,other):
114 return self.priority()>=other.priority()
115 def __gt__(self,other):
116 return self.priority()<other.priority()
117 def __ge__(self,other):
118 return self.priority()<=other.priority()
119 def get_cwd(self):
120 bld=self.generator.bld
121 ret=getattr(self,'cwd',None)or getattr(bld,'cwd',bld.bldnode)
122 if isinstance(ret,str):
123 if os.path.isabs(ret):
124 ret=bld.root.make_node(ret)
125 else:
126 ret=self.generator.path.make_node(ret)
127 return ret
128 def quote_flag(self,x):
129 old=x
130 if'\\'in x:
131 x=x.replace('\\','\\\\')
132 if'"'in x:
133 x=x.replace('"','\\"')
134 if old!=x or' 'in x or'\t'in x or"'"in x:
135 x='"%s"'%x
136 return x
137 def priority(self):
138 return(self.weight+self.prio_order,-getattr(self.generator,'tg_idx_count',0))
139 def split_argfile(self,cmd):
140 return([cmd[0]],[self.quote_flag(x)for x in cmd[1:]])
141 def exec_command(self,cmd,**kw):
142 if not'cwd'in kw:
143 kw['cwd']=self.get_cwd()
144 if hasattr(self,'timeout'):
145 kw['timeout']=self.timeout
146 if self.env.PATH:
147 env=kw['env']=dict(kw.get('env')or self.env.env or os.environ)
148 env['PATH']=self.env.PATH if isinstance(self.env.PATH,str)else os.pathsep.join(self.env.PATH)
149 if hasattr(self,'stdout'):
150 kw['stdout']=self.stdout
151 if hasattr(self,'stderr'):
152 kw['stderr']=self.stderr
153 if not isinstance(cmd,str):
154 if Utils.is_win32:
155 too_long=sum([len(arg)for arg in cmd])+len(cmd)>8192
156 else:
157 too_long=len(cmd)>200000
158 if too_long and getattr(self,'allow_argsfile',True):
159 cmd,args=self.split_argfile(cmd)
160 try:
161 (fd,tmp)=tempfile.mkstemp()
162 os.write(fd,'\r\n'.join(args).encode())
163 os.close(fd)
164 if Logs.verbose:
165 Logs.debug('argfile: @%r -> %r',tmp,args)
166 return self.generator.bld.exec_command(cmd+['@'+tmp],**kw)
167 finally:
168 try:
169 os.remove(tmp)
170 except OSError:
171 pass
172 return self.generator.bld.exec_command(cmd,**kw)
173 def process(self):
174 try:
175 del self.generator.bld.task_sigs[self.uid()]
176 except KeyError:
177 pass
178 try:
179 ret=self.run()
180 except Exception:
181 self.err_msg=traceback.format_exc()
182 self.hasrun=EXCEPTION
183 else:
184 if ret:
185 self.err_code=ret
186 self.hasrun=CRASHED
187 else:
188 try:
189 self.post_run()
190 except Errors.WafError:
191 pass
192 except Exception:
193 self.err_msg=traceback.format_exc()
194 self.hasrun=EXCEPTION
195 else:
196 self.hasrun=SUCCESS
197 if self.hasrun!=SUCCESS and self.scan:
198 try:
199 del self.generator.bld.imp_sigs[self.uid()]
200 except KeyError:
201 pass
202 def log_display(self,bld):
203 if self.generator.bld.progress_bar==3:
204 return
205 s=self.display()
206 if s:
207 if bld.logger:
208 logger=bld.logger
209 else:
210 logger=Logs
211 if self.generator.bld.progress_bar==1:
212 c1=Logs.colors.cursor_off
213 c2=Logs.colors.cursor_on
214 logger.info(s,extra={'stream':sys.stderr,'terminator':'','c1':c1,'c2':c2})
215 else:
216 logger.info(s,extra={'terminator':'','c1':'','c2':''})
217 def display(self):
218 col1=Logs.colors(self.color)
219 col2=Logs.colors.NORMAL
220 master=self.generator.bld.producer
221 def cur():
222 return master.processed-master.ready.qsize()
223 if self.generator.bld.progress_bar==1:
224 return self.generator.bld.progress_line(cur(),master.total,col1,col2)
225 if self.generator.bld.progress_bar==2:
226 ela=str(self.generator.bld.timer)
227 try:
228 ins=','.join([n.name for n in self.inputs])
229 except AttributeError:
230 ins=''
231 try:
232 outs=','.join([n.name for n in self.outputs])
233 except AttributeError:
234 outs=''
235 return'|Total %s|Current %s|Inputs %s|Outputs %s|Time %s|\n'%(master.total,cur(),ins,outs,ela)
236 s=str(self)
237 if not s:
238 return None
239 total=master.total
240 n=len(str(total))
241 fs='[%%%dd/%%%dd] %%s%%s%%s%%s\n'%(n,n)
242 kw=self.keyword()
243 if kw:
244 kw+=' '
245 return fs%(cur(),total,kw,col1,s,col2)
246 def hash_constraints(self):
247 return(tuple(self.before),tuple(self.after),tuple(self.ext_in),tuple(self.ext_out),self.__class__.__name__,self.hcode)
248 def format_error(self):
249 if Logs.verbose:
250 msg=': %r\n%r'%(self,getattr(self,'last_cmd',''))
251 else:
252 msg=' (run with -v to display more information)'
253 name=getattr(self.generator,'name','')
254 if getattr(self,"err_msg",None):
255 return self.err_msg
256 elif not self.hasrun:
257 return'task in %r was not executed for some reason: %r'%(name,self)
258 elif self.hasrun==CRASHED:
259 try:
260 return' -> task in %r failed with exit status %r%s'%(name,self.err_code,msg)
261 except AttributeError:
262 return' -> task in %r failed%s'%(name,msg)
263 elif self.hasrun==MISSING:
264 return' -> missing files in %r%s'%(name,msg)
265 elif self.hasrun==CANCELED:
266 return' -> %r canceled because of missing dependencies'%name
267 else:
268 return'invalid status for task in %r: %r'%(name,self.hasrun)
269 def colon(self,var1,var2):
270 tmp=self.env[var1]
271 if not tmp:
272 return[]
273 if isinstance(var2,str):
274 it=self.env[var2]
275 else:
276 it=var2
277 if isinstance(tmp,str):
278 return[tmp%x for x in it]
279 else:
280 lst=[]
281 for y in it:
282 lst.extend(tmp)
283 lst.append(y)
284 return lst
285 def __str__(self):
286 name=self.__class__.__name__
287 if self.outputs:
288 if name.endswith(('lib','program'))or not self.inputs:
289 node=self.outputs[0]
290 return node.path_from(node.ctx.launch_node())
291 if not(self.inputs or self.outputs):
292 return self.__class__.__name__
293 if len(self.inputs)==1:
294 node=self.inputs[0]
295 return node.path_from(node.ctx.launch_node())
296 src_str=' '.join([a.path_from(a.ctx.launch_node())for a in self.inputs])
297 tgt_str=' '.join([a.path_from(a.ctx.launch_node())for a in self.outputs])
298 if self.outputs:
299 sep=' -> '
300 else:
301 sep=''
302 return'%s: %s%s%s'%(self.__class__.__name__,src_str,sep,tgt_str)
303 def keyword(self):
304 name=self.__class__.__name__
305 if name.endswith(('lib','program')):
306 return'Linking'
307 if len(self.inputs)==1 and len(self.outputs)==1:
308 return'Compiling'
309 if not self.inputs:
310 if self.outputs:
311 return'Creating'
312 else:
313 return'Running'
314 return'Processing'
315 def __repr__(self):
316 try:
317 ins=",".join([x.name for x in self.inputs])
318 outs=",".join([x.name for x in self.outputs])
319 except AttributeError:
320 ins=",".join([str(x)for x in self.inputs])
321 outs=",".join([str(x)for x in self.outputs])
322 return"".join(['\n\t{task %r: '%id(self),self.__class__.__name__," ",ins," -> ",outs,'}'])
323 def uid(self):
324 try:
325 return self.uid_
326 except AttributeError:
327 m=Utils.md5(self.__class__.__name__)
328 up=m.update
329 for x in self.inputs+self.outputs:
330 up(x.abspath())
331 self.uid_=m.digest()
332 return self.uid_
333 def set_inputs(self,inp):
334 if isinstance(inp,list):
335 self.inputs+=inp
336 else:
337 self.inputs.append(inp)
338 def set_outputs(self,out):
339 if isinstance(out,list):
340 self.outputs+=out
341 else:
342 self.outputs.append(out)
343 def set_run_after(self,task):
344 assert isinstance(task,Task)
345 self.run_after.add(task)
346 def signature(self):
347 try:
348 return self.cache_sig
349 except AttributeError:
350 pass
351 self.m=Utils.md5(self.hcode)
352 self.sig_explicit_deps()
353 self.sig_vars()
354 if self.scan:
355 try:
356 self.sig_implicit_deps()
357 except Errors.TaskRescan:
358 return self.signature()
359 ret=self.cache_sig=self.m.digest()
360 return ret
361 def runnable_status(self):
362 bld=self.generator.bld
363 if bld.is_install<0:
364 return SKIP_ME
365 for t in self.run_after:
366 if not t.hasrun:
367 return ASK_LATER
368 elif t.hasrun<SKIPPED:
369 return CANCEL_ME
370 try:
371 new_sig=self.signature()
372 except Errors.TaskNotReady:
373 return ASK_LATER
374 key=self.uid()
375 try:
376 prev_sig=bld.task_sigs[key]
377 except KeyError:
378 Logs.debug('task: task %r must run: it was never run before or the task code changed',self)
379 return RUN_ME
380 if new_sig!=prev_sig:
381 Logs.debug('task: task %r must run: the task signature changed',self)
382 return RUN_ME
383 for node in self.outputs:
384 sig=bld.node_sigs.get(node)
385 if not sig:
386 Logs.debug('task: task %r must run: an output node has no signature',self)
387 return RUN_ME
388 if sig!=key:
389 Logs.debug('task: task %r must run: an output node was produced by another task',self)
390 return RUN_ME
391 if not node.exists():
392 Logs.debug('task: task %r must run: an output node does not exist',self)
393 return RUN_ME
394 return(self.always_run and RUN_ME)or SKIP_ME
395 def post_run(self):
396 bld=self.generator.bld
397 for node in self.outputs:
398 if not node.exists():
399 self.hasrun=MISSING
400 self.err_msg='-> missing file: %r'%node.abspath()
401 raise Errors.WafError(self.err_msg)
402 bld.node_sigs[node]=self.uid()
403 bld.task_sigs[self.uid()]=self.signature()
404 if not self.keep_last_cmd:
405 try:
406 del self.last_cmd
407 except AttributeError:
408 pass
409 def sig_explicit_deps(self):
410 bld=self.generator.bld
411 upd=self.m.update
412 for x in self.inputs+self.dep_nodes:
413 upd(x.get_bld_sig())
414 if bld.deps_man:
415 additional_deps=bld.deps_man
416 for x in self.inputs+self.outputs:
417 try:
418 d=additional_deps[x]
419 except KeyError:
420 continue
421 for v in d:
422 try:
423 v=v.get_bld_sig()
424 except AttributeError:
425 if hasattr(v,'__call__'):
426 v=v()
427 upd(v)
428 def sig_deep_inputs(self):
429 bld=self.generator.bld
430 lst=[bld.task_sigs[bld.node_sigs[node]]for node in(self.inputs+self.dep_nodes)if node.is_bld()]
431 self.m.update(Utils.h_list(lst))
432 def sig_vars(self):
433 sig=self.generator.bld.hash_env_vars(self.env,self.vars)
434 self.m.update(sig)
435 scan=None
436 def sig_implicit_deps(self):
437 bld=self.generator.bld
438 key=self.uid()
439 prev=bld.imp_sigs.get(key,[])
440 if prev:
441 try:
442 if prev==self.compute_sig_implicit_deps():
443 return prev
444 except Errors.TaskNotReady:
445 raise
446 except EnvironmentError:
447 for x in bld.node_deps.get(self.uid(),[]):
448 if not x.is_bld()and not x.exists():
449 try:
450 del x.parent.children[x.name]
451 except KeyError:
452 pass
453 del bld.imp_sigs[key]
454 raise Errors.TaskRescan('rescan')
455 (bld.node_deps[key],bld.raw_deps[key])=self.scan()
456 if Logs.verbose:
457 Logs.debug('deps: scanner for %s: %r; unresolved: %r',self,bld.node_deps[key],bld.raw_deps[key])
458 try:
459 bld.imp_sigs[key]=self.compute_sig_implicit_deps()
460 except EnvironmentError:
461 for k in bld.node_deps.get(self.uid(),[]):
462 if not k.exists():
463 Logs.warn('Dependency %r for %r is missing: check the task declaration and the build order!',k,self)
464 raise
465 def compute_sig_implicit_deps(self):
466 upd=self.m.update
467 self.are_implicit_nodes_ready()
468 for k in self.generator.bld.node_deps.get(self.uid(),[]):
469 upd(k.get_bld_sig())
470 return self.m.digest()
471 def are_implicit_nodes_ready(self):
472 bld=self.generator.bld
473 try:
474 cache=bld.dct_implicit_nodes
475 except AttributeError:
476 bld.dct_implicit_nodes=cache={}
477 try:
478 dct=cache[bld.current_group]
479 except KeyError:
480 dct=cache[bld.current_group]={}
481 for tsk in bld.cur_tasks:
482 for x in tsk.outputs:
483 dct[x]=tsk
484 modified=False
485 for x in bld.node_deps.get(self.uid(),[]):
486 if x in dct:
487 self.run_after.add(dct[x])
488 modified=True
489 if modified:
490 for tsk in self.run_after:
491 if not tsk.hasrun:
492 raise Errors.TaskNotReady('not ready')
493 if sys.hexversion>0x3000000:
494 def uid(self):
495 try:
496 return self.uid_
497 except AttributeError:
498 m=Utils.md5(self.__class__.__name__.encode('latin-1','xmlcharrefreplace'))
499 up=m.update
500 for x in self.inputs+self.outputs:
501 up(x.abspath().encode('latin-1','xmlcharrefreplace'))
502 self.uid_=m.digest()
503 return self.uid_
504 uid.__doc__=Task.uid.__doc__
505 Task.uid=uid
506 def is_before(t1,t2):
507 to_list=Utils.to_list
508 for k in to_list(t2.ext_in):
509 if k in to_list(t1.ext_out):
510 return 1
511 if t1.__class__.__name__ in to_list(t2.after):
512 return 1
513 if t2.__class__.__name__ in to_list(t1.before):
514 return 1
515 return 0
516 def set_file_constraints(tasks):
517 ins=Utils.defaultdict(set)
518 outs=Utils.defaultdict(set)
519 for x in tasks:
520 for a in x.inputs:
521 ins[a].add(x)
522 for a in x.dep_nodes:
523 ins[a].add(x)
524 for a in x.outputs:
525 outs[a].add(x)
526 links=set(ins.keys()).intersection(outs.keys())
527 for k in links:
528 for a in ins[k]:
529 a.run_after.update(outs[k])
530 class TaskGroup(object):
531 def __init__(self,prev,next):
532 self.prev=prev
533 self.next=next
534 self.done=False
535 def get_hasrun(self):
536 for k in self.prev:
537 if not k.hasrun:
538 return NOT_RUN
539 return SUCCESS
540 hasrun=property(get_hasrun,None)
541 def set_precedence_constraints(tasks):
542 cstr_groups=Utils.defaultdict(list)
543 for x in tasks:
544 h=x.hash_constraints()
545 cstr_groups[h].append(x)
546 keys=list(cstr_groups.keys())
547 maxi=len(keys)
548 for i in range(maxi):
549 t1=cstr_groups[keys[i]][0]
550 for j in range(i+1,maxi):
551 t2=cstr_groups[keys[j]][0]
552 if is_before(t1,t2):
553 a=i
554 b=j
555 elif is_before(t2,t1):
556 a=j
557 b=i
558 else:
559 continue
560 a=cstr_groups[keys[a]]
561 b=cstr_groups[keys[b]]
562 if len(a)<2 or len(b)<2:
563 for x in b:
564 x.run_after.update(a)
565 else:
566 group=TaskGroup(set(a),set(b))
567 for x in b:
568 x.run_after.add(group)
569 def funex(c):
570 dc={}
571 exec(c,dc)
572 return dc['f']
573 re_cond=re.compile(r'(?P<var>\w+)|(?P<or>\|)|(?P<and>&)')
574 re_novar=re.compile(r'^(SRC|TGT)\W+.*?$')
575 reg_act=re.compile(r'(?P<backslash>\\)|(?P<dollar>\$\$)|(?P<subst>\$\{(?P<var>\w+)(?P<code>.*?)\})',re.M)
576 def compile_fun_shell(line):
577 extr=[]
578 def repl(match):
579 g=match.group
580 if g('dollar'):
581 return"$"
582 elif g('backslash'):
583 return'\\\\'
584 elif g('subst'):
585 extr.append((g('var'),g('code')))
586 return"%s"
587 return None
588 line=reg_act.sub(repl,line)or line
589 dvars=[]
590 def add_dvar(x):
591 if x not in dvars:
592 dvars.append(x)
593 def replc(m):
594 if m.group('and'):
595 return' and '
596 elif m.group('or'):
597 return' or '
598 else:
599 x=m.group('var')
600 add_dvar(x)
601 return'env[%r]'%x
602 parm=[]
603 app=parm.append
604 for(var,meth)in extr:
605 if var=='SRC':
606 if meth:
607 app('tsk.inputs%s'%meth)
608 else:
609 app('" ".join([a.path_from(cwdx) for a in tsk.inputs])')
610 elif var=='TGT':
611 if meth:
612 app('tsk.outputs%s'%meth)
613 else:
614 app('" ".join([a.path_from(cwdx) for a in tsk.outputs])')
615 elif meth:
616 if meth.startswith(':'):
617 add_dvar(var)
618 m=meth[1:]
619 if m=='SRC':
620 m='[a.path_from(cwdx) for a in tsk.inputs]'
621 elif m=='TGT':
622 m='[a.path_from(cwdx) for a in tsk.outputs]'
623 elif re_novar.match(m):
624 m='[tsk.inputs%s]'%m[3:]
625 elif re_novar.match(m):
626 m='[tsk.outputs%s]'%m[3:]
627 else:
628 add_dvar(m)
629 if m[:3]not in('tsk','gen','bld'):
630 m='%r'%m
631 app('" ".join(tsk.colon(%r, %s))'%(var,m))
632 elif meth.startswith('?'):
633 expr=re_cond.sub(replc,meth[1:])
634 app('p(%r) if (%s) else ""'%(var,expr))
635 else:
636 call='%s%s'%(var,meth)
637 add_dvar(call)
638 app(call)
639 else:
640 add_dvar(var)
641 app("p('%s')"%var)
642 if parm:
643 parm="%% (%s) "%(',\n\t\t'.join(parm))
644 else:
645 parm=''
646 c=COMPILE_TEMPLATE_SHELL%(line,parm)
647 Logs.debug('action: %s',c.strip().splitlines())
648 return(funex(c),dvars)
649 reg_act_noshell=re.compile(r"(?P<space>\s+)|(?P<subst>\$\{(?P<var>\w+)(?P<code>.*?)\})|(?P<text>([^$ \t\n\r\f\v]|\$\$)+)",re.M)
650 def compile_fun_noshell(line):
651 buf=[]
652 dvars=[]
653 merge=False
654 app=buf.append
655 def add_dvar(x):
656 if x not in dvars:
657 dvars.append(x)
658 def replc(m):
659 if m.group('and'):
660 return' and '
661 elif m.group('or'):
662 return' or '
663 else:
664 x=m.group('var')
665 add_dvar(x)
666 return'env[%r]'%x
667 for m in reg_act_noshell.finditer(line):
668 if m.group('space'):
669 merge=False
670 continue
671 elif m.group('text'):
672 app('[%r]'%m.group('text').replace('$$','$'))
673 elif m.group('subst'):
674 var=m.group('var')
675 code=m.group('code')
676 if var=='SRC':
677 if code:
678 app('[tsk.inputs%s]'%code)
679 else:
680 app('[a.path_from(cwdx) for a in tsk.inputs]')
681 elif var=='TGT':
682 if code:
683 app('[tsk.outputs%s]'%code)
684 else:
685 app('[a.path_from(cwdx) for a in tsk.outputs]')
686 elif code:
687 if code.startswith(':'):
688 add_dvar(var)
689 m=code[1:]
690 if m=='SRC':
691 m='[a.path_from(cwdx) for a in tsk.inputs]'
692 elif m=='TGT':
693 m='[a.path_from(cwdx) for a in tsk.outputs]'
694 elif re_novar.match(m):
695 m='[tsk.inputs%s]'%m[3:]
696 elif re_novar.match(m):
697 m='[tsk.outputs%s]'%m[3:]
698 else:
699 add_dvar(m)
700 if m[:3]not in('tsk','gen','bld'):
701 m='%r'%m
702 app('tsk.colon(%r, %s)'%(var,m))
703 elif code.startswith('?'):
704 expr=re_cond.sub(replc,code[1:])
705 app('to_list(env[%r] if (%s) else [])'%(var,expr))
706 else:
707 call='%s%s'%(var,code)
708 add_dvar(call)
709 app('to_list(%s)'%call)
710 else:
711 app('to_list(env[%r])'%var)
712 add_dvar(var)
713 if merge:
714 tmp='merge(%s, %s)'%(buf[-2],buf[-1])
715 del buf[-1]
716 buf[-1]=tmp
717 merge=True
718 buf=['lst.extend(%s)'%x for x in buf]
719 fun=COMPILE_TEMPLATE_NOSHELL%"\n\t".join(buf)
720 Logs.debug('action: %s',fun.strip().splitlines())
721 return(funex(fun),dvars)
722 def compile_fun(line,shell=False):
723 if isinstance(line,str):
724 if line.find('<')>0 or line.find('>')>0 or line.find('&&')>0:
725 shell=True
726 else:
727 dvars_lst=[]
728 funs_lst=[]
729 for x in line:
730 if isinstance(x,str):
731 fun,dvars=compile_fun(x,shell)
732 dvars_lst+=dvars
733 funs_lst.append(fun)
734 else:
735 funs_lst.append(x)
736 def composed_fun(task):
737 for x in funs_lst:
738 ret=x(task)
739 if ret:
740 return ret
741 return None
742 return composed_fun,dvars_lst
743 if shell:
744 return compile_fun_shell(line)
745 else:
746 return compile_fun_noshell(line)
747 def compile_sig_vars(vars):
748 buf=[]
749 for x in sorted(vars):
750 if x[:3]in('tsk','gen','bld'):
751 buf.append('buf.append(%s)'%x)
752 if buf:
753 return funex(COMPILE_TEMPLATE_SIG_VARS%'\n\t'.join(buf))
754 return None
755 def task_factory(name,func=None,vars=None,color='GREEN',ext_in=[],ext_out=[],before=[],after=[],shell=False,scan=None):
756 params={'vars':vars or[],'color':color,'name':name,'shell':shell,'scan':scan,}
757 if isinstance(func,str)or isinstance(func,tuple):
758 params['run_str']=func
759 else:
760 params['run']=func
761 cls=type(Task)(name,(Task,),params)
762 classes[name]=cls
763 if ext_in:
764 cls.ext_in=Utils.to_list(ext_in)
765 if ext_out:
766 cls.ext_out=Utils.to_list(ext_out)
767 if before:
768 cls.before=Utils.to_list(before)
769 if after:
770 cls.after=Utils.to_list(after)
771 return cls
772 def deep_inputs(cls):
773 def sig_explicit_deps(self):
774 Task.sig_explicit_deps(self)
775 Task.sig_deep_inputs(self)
776 cls.sig_explicit_deps=sig_explicit_deps
777 return cls
778 TaskBase=Task
779 class TaskSemaphore(object):
780 def __init__(self,num):
781 self.num=num
782 self.locking=set()
783 self.waiting=set()
784 def is_locked(self):
785 return len(self.locking)>=self.num
786 def acquire(self,tsk):
787 if self.is_locked():
788 raise IndexError('Cannot lock more %r'%self.locking)
789 self.locking.add(tsk)
790 def release(self,tsk):
791 self.locking.remove(tsk)
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import copy,re,os,functools
5 from waflib import Task,Utils,Logs,Errors,ConfigSet,Node
6 feats=Utils.defaultdict(set)
7 HEADER_EXTS=['.h','.hpp','.hxx','.hh']
8 class task_gen(object):
9 mappings=Utils.ordered_iter_dict()
10 prec=Utils.defaultdict(set)
11 def __init__(self,*k,**kw):
12 self.source=[]
13 self.target=''
14 self.meths=[]
15 self.features=[]
16 self.tasks=[]
17 if not'bld'in kw:
18 self.env=ConfigSet.ConfigSet()
19 self.idx=0
20 self.path=None
21 else:
22 self.bld=kw['bld']
23 self.env=self.bld.env.derive()
24 self.path=kw.get('path',self.bld.path)
25 path=self.path.abspath()
26 try:
27 self.idx=self.bld.idx[path]=self.bld.idx.get(path,0)+1
28 except AttributeError:
29 self.bld.idx={}
30 self.idx=self.bld.idx[path]=1
31 try:
32 self.tg_idx_count=self.bld.tg_idx_count=self.bld.tg_idx_count+1
33 except AttributeError:
34 self.tg_idx_count=self.bld.tg_idx_count=1
35 for key,val in kw.items():
36 setattr(self,key,val)
37 def __str__(self):
38 return"<task_gen %r declared in %s>"%(self.name,self.path.abspath())
39 def __repr__(self):
40 lst=[]
41 for x in self.__dict__:
42 if x not in('env','bld','compiled_tasks','tasks'):
43 lst.append("%s=%s"%(x,repr(getattr(self,x))))
44 return"bld(%s) in %s"%(", ".join(lst),self.path.abspath())
45 def get_cwd(self):
46 return self.bld.bldnode
47 def get_name(self):
48 try:
49 return self._name
50 except AttributeError:
51 if isinstance(self.target,list):
52 lst=[str(x)for x in self.target]
53 name=self._name=','.join(lst)
54 else:
55 name=self._name=str(self.target)
56 return name
57 def set_name(self,name):
58 self._name=name
59 name=property(get_name,set_name)
60 def to_list(self,val):
61 if isinstance(val,str):
62 return val.split()
63 else:
64 return val
65 def post(self):
66 if getattr(self,'posted',None):
67 return False
68 self.posted=True
69 keys=set(self.meths)
70 keys.update(feats['*'])
71 self.features=Utils.to_list(self.features)
72 for x in self.features:
73 st=feats[x]
74 if st:
75 keys.update(st)
76 elif not x in Task.classes:
77 Logs.warn('feature %r does not exist - bind at least one method to it?',x)
78 prec={}
79 prec_tbl=self.prec
80 for x in prec_tbl:
81 if x in keys:
82 prec[x]=prec_tbl[x]
83 tmp=[]
84 for a in keys:
85 for x in prec.values():
86 if a in x:
87 break
88 else:
89 tmp.append(a)
90 tmp.sort(reverse=True)
91 out=[]
92 while tmp:
93 e=tmp.pop()
94 if e in keys:
95 out.append(e)
96 try:
97 nlst=prec[e]
98 except KeyError:
99 pass
100 else:
101 del prec[e]
102 for x in nlst:
103 for y in prec:
104 if x in prec[y]:
105 break
106 else:
107 tmp.append(x)
108 tmp.sort(reverse=True)
109 if prec:
110 buf=['Cycle detected in the method execution:']
111 for k,v in prec.items():
112 buf.append('- %s after %s'%(k,[x for x in v if x in prec]))
113 raise Errors.WafError('\n'.join(buf))
114 self.meths=out
115 Logs.debug('task_gen: posting %s %d',self,id(self))
116 for x in out:
117 try:
118 v=getattr(self,x)
119 except AttributeError:
120 raise Errors.WafError('%r is not a valid task generator method'%x)
121 Logs.debug('task_gen: -> %s (%d)',x,id(self))
122 v()
123 Logs.debug('task_gen: posted %s',self.name)
124 return True
125 def get_hook(self,node):
126 name=node.name
127 for k in self.mappings:
128 try:
129 if name.endswith(k):
130 return self.mappings[k]
131 except TypeError:
132 if k.match(name):
133 return self.mappings[k]
134 keys=list(self.mappings.keys())
135 raise Errors.WafError("File %r has no mapping in %r (load a waf tool?)"%(node,keys))
136 def create_task(self,name,src=None,tgt=None,**kw):
137 task=Task.classes[name](env=self.env.derive(),generator=self)
138 if src:
139 task.set_inputs(src)
140 if tgt:
141 task.set_outputs(tgt)
142 task.__dict__.update(kw)
143 self.tasks.append(task)
144 return task
145 def clone(self,env):
146 newobj=self.bld()
147 for x in self.__dict__:
148 if x in('env','bld'):
149 continue
150 elif x in('path','features'):
151 setattr(newobj,x,getattr(self,x))
152 else:
153 setattr(newobj,x,copy.copy(getattr(self,x)))
154 newobj.posted=False
155 if isinstance(env,str):
156 newobj.env=self.bld.all_envs[env].derive()
157 else:
158 newobj.env=env.derive()
159 return newobj
160 def declare_chain(name='',rule=None,reentrant=None,color='BLUE',ext_in=[],ext_out=[],before=[],after=[],decider=None,scan=None,install_path=None,shell=False):
161 ext_in=Utils.to_list(ext_in)
162 ext_out=Utils.to_list(ext_out)
163 if not name:
164 name=rule
165 cls=Task.task_factory(name,rule,color=color,ext_in=ext_in,ext_out=ext_out,before=before,after=after,scan=scan,shell=shell)
166 def x_file(self,node):
167 if ext_in:
168 _ext_in=ext_in[0]
169 tsk=self.create_task(name,node)
170 cnt=0
171 ext=decider(self,node)if decider else cls.ext_out
172 for x in ext:
173 k=node.change_ext(x,ext_in=_ext_in)
174 tsk.outputs.append(k)
175 if reentrant!=None:
176 if cnt<int(reentrant):
177 self.source.append(k)
178 else:
179 for y in self.mappings:
180 if k.name.endswith(y):
181 self.source.append(k)
182 break
183 cnt+=1
184 if install_path:
185 self.install_task=self.add_install_files(install_to=install_path,install_from=tsk.outputs)
186 return tsk
187 for x in cls.ext_in:
188 task_gen.mappings[x]=x_file
189 return x_file
190 def taskgen_method(func):
191 setattr(task_gen,func.__name__,func)
192 return func
193 def feature(*k):
194 def deco(func):
195 setattr(task_gen,func.__name__,func)
196 for name in k:
197 feats[name].update([func.__name__])
198 return func
199 return deco
200 def before_method(*k):
201 def deco(func):
202 setattr(task_gen,func.__name__,func)
203 for fun_name in k:
204 task_gen.prec[func.__name__].add(fun_name)
205 return func
206 return deco
207 before=before_method
208 def after_method(*k):
209 def deco(func):
210 setattr(task_gen,func.__name__,func)
211 for fun_name in k:
212 task_gen.prec[fun_name].add(func.__name__)
213 return func
214 return deco
215 after=after_method
216 def extension(*k):
217 def deco(func):
218 setattr(task_gen,func.__name__,func)
219 for x in k:
220 task_gen.mappings[x]=func
221 return func
222 return deco
223 @taskgen_method
224 def to_nodes(self,lst,path=None):
225 tmp=[]
226 path=path or self.path
227 find=path.find_resource
228 if isinstance(lst,Node.Node):
229 lst=[lst]
230 for x in Utils.to_list(lst):
231 if isinstance(x,str):
232 node=find(x)
233 elif hasattr(x,'name'):
234 node=x
235 else:
236 tmp.extend(self.to_nodes(x))
237 continue
238 if not node:
239 raise Errors.WafError('source not found: %r in %r'%(x,self))
240 tmp.append(node)
241 return tmp
242 @feature('*')
243 def process_source(self):
244 self.source=self.to_nodes(getattr(self,'source',[]))
245 for node in self.source:
246 self.get_hook(node)(self,node)
247 @feature('*')
248 @before_method('process_source')
249 def process_rule(self):
250 if not getattr(self,'rule',None):
251 return
252 name=str(getattr(self,'name',None)or self.target or getattr(self.rule,'__name__',self.rule))
253 try:
254 cache=self.bld.cache_rule_attr
255 except AttributeError:
256 cache=self.bld.cache_rule_attr={}
257 chmod=getattr(self,'chmod',None)
258 shell=getattr(self,'shell',True)
259 color=getattr(self,'color','BLUE')
260 scan=getattr(self,'scan',None)
261 _vars=getattr(self,'vars',[])
262 cls_str=getattr(self,'cls_str',None)
263 cls_keyword=getattr(self,'cls_keyword',None)
264 use_cache=getattr(self,'cache_rule','True')
265 deep_inputs=getattr(self,'deep_inputs',False)
266 scan_val=has_deps=hasattr(self,'deps')
267 if scan:
268 scan_val=id(scan)
269 key=Utils.h_list((name,self.rule,chmod,shell,color,cls_str,cls_keyword,scan_val,_vars,deep_inputs))
270 cls=None
271 if use_cache:
272 try:
273 cls=cache[key]
274 except KeyError:
275 pass
276 if not cls:
277 rule=self.rule
278 if chmod is not None:
279 def chmod_fun(tsk):
280 for x in tsk.outputs:
281 os.chmod(x.abspath(),tsk.generator.chmod)
282 if isinstance(rule,tuple):
283 rule=list(rule)
284 rule.append(chmod_fun)
285 rule=tuple(rule)
286 else:
287 rule=(rule,chmod_fun)
288 cls=Task.task_factory(name,rule,_vars,shell=shell,color=color)
289 if cls_str:
290 setattr(cls,'__str__',self.cls_str)
291 if cls_keyword:
292 setattr(cls,'keyword',self.cls_keyword)
293 if deep_inputs:
294 Task.deep_inputs(cls)
295 if scan:
296 cls.scan=self.scan
297 elif has_deps:
298 def scan(self):
299 nodes=[]
300 for x in self.generator.to_list(getattr(self.generator,'deps',None)):
301 node=self.generator.path.find_resource(x)
302 if not node:
303 self.generator.bld.fatal('Could not find %r (was it declared?)'%x)
304 nodes.append(node)
305 return[nodes,[]]
306 cls.scan=scan
307 if use_cache:
308 cache[key]=cls
309 tsk=self.create_task(name)
310 for x in('after','before','ext_in','ext_out'):
311 setattr(tsk,x,getattr(self,x,[]))
312 if hasattr(self,'stdout'):
313 tsk.stdout=self.stdout
314 if hasattr(self,'stderr'):
315 tsk.stderr=self.stderr
316 if getattr(self,'timeout',None):
317 tsk.timeout=self.timeout
318 if getattr(self,'always',None):
319 tsk.always_run=True
320 if getattr(self,'target',None):
321 if isinstance(self.target,str):
322 self.target=self.target.split()
323 if not isinstance(self.target,list):
324 self.target=[self.target]
325 for x in self.target:
326 if isinstance(x,str):
327 tsk.outputs.append(self.path.find_or_declare(x))
328 else:
329 x.parent.mkdir()
330 tsk.outputs.append(x)
331 if getattr(self,'install_path',None):
332 self.install_task=self.add_install_files(install_to=self.install_path,install_from=tsk.outputs,chmod=getattr(self,'chmod',Utils.O644))
333 if getattr(self,'source',None):
334 tsk.inputs=self.to_nodes(self.source)
335 self.source=[]
336 if getattr(self,'cwd',None):
337 tsk.cwd=self.cwd
338 if isinstance(tsk.run,functools.partial):
339 tsk.run=functools.partial(tsk.run,tsk)
340 @feature('seq')
341 def sequence_order(self):
342 if self.meths and self.meths[-1]!='sequence_order':
343 self.meths.append('sequence_order')
344 return
345 if getattr(self,'seq_start',None):
346 return
347 if getattr(self.bld,'prev',None):
348 self.bld.prev.post()
349 for x in self.bld.prev.tasks:
350 for y in self.tasks:
351 y.set_run_after(x)
352 self.bld.prev=self
353 re_m4=re.compile(r'@(\w+)@',re.M)
354 class subst_pc(Task.Task):
355 def force_permissions(self):
356 if getattr(self.generator,'chmod',None):
357 for x in self.outputs:
358 os.chmod(x.abspath(),self.generator.chmod)
359 def run(self):
360 if getattr(self.generator,'is_copy',None):
361 for i,x in enumerate(self.outputs):
362 x.write(self.inputs[i].read('rb'),'wb')
363 stat=os.stat(self.inputs[i].abspath())
364 os.utime(self.outputs[i].abspath(),(stat.st_atime,stat.st_mtime))
365 self.force_permissions()
366 return None
367 if getattr(self.generator,'fun',None):
368 ret=self.generator.fun(self)
369 if not ret:
370 self.force_permissions()
371 return ret
372 code=self.inputs[0].read(encoding=getattr(self.generator,'encoding','latin-1'))
373 if getattr(self.generator,'subst_fun',None):
374 code=self.generator.subst_fun(self,code)
375 if code is not None:
376 self.outputs[0].write(code,encoding=getattr(self.generator,'encoding','latin-1'))
377 self.force_permissions()
378 return None
379 code=code.replace('%','%%')
380 lst=[]
381 def repl(match):
382 g=match.group
383 if g(1):
384 lst.append(g(1))
385 return"%%(%s)s"%g(1)
386 return''
387 code=getattr(self.generator,'re_m4',re_m4).sub(repl,code)
388 try:
389 d=self.generator.dct
390 except AttributeError:
391 d={}
392 for x in lst:
393 tmp=getattr(self.generator,x,'')or self.env[x]or self.env[x.upper()]
394 try:
395 tmp=''.join(tmp)
396 except TypeError:
397 tmp=str(tmp)
398 d[x]=tmp
399 code=code%d
400 self.outputs[0].write(code,encoding=getattr(self.generator,'encoding','latin-1'))
401 self.generator.bld.raw_deps[self.uid()]=lst
402 try:
403 delattr(self,'cache_sig')
404 except AttributeError:
405 pass
406 self.force_permissions()
407 def sig_vars(self):
408 bld=self.generator.bld
409 env=self.env
410 upd=self.m.update
411 if getattr(self.generator,'fun',None):
412 upd(Utils.h_fun(self.generator.fun).encode())
413 if getattr(self.generator,'subst_fun',None):
414 upd(Utils.h_fun(self.generator.subst_fun).encode())
415 vars=self.generator.bld.raw_deps.get(self.uid(),[])
416 act_sig=bld.hash_env_vars(env,vars)
417 upd(act_sig)
418 lst=[getattr(self.generator,x,'')for x in vars]
419 upd(Utils.h_list(lst))
420 return self.m.digest()
421 @extension('.pc.in')
422 def add_pcfile(self,node):
423 tsk=self.create_task('subst_pc',node,node.change_ext('.pc','.pc.in'))
424 self.install_task=self.add_install_files(install_to=getattr(self,'install_path','${LIBDIR}/pkgconfig/'),install_from=tsk.outputs)
425 class subst(subst_pc):
426 pass
427 @feature('subst')
428 @before_method('process_source','process_rule')
429 def process_subst(self):
430 src=Utils.to_list(getattr(self,'source',[]))
431 if isinstance(src,Node.Node):
432 src=[src]
433 tgt=Utils.to_list(getattr(self,'target',[]))
434 if isinstance(tgt,Node.Node):
435 tgt=[tgt]
436 if len(src)!=len(tgt):
437 raise Errors.WafError('invalid number of source/target for %r'%self)
438 for x,y in zip(src,tgt):
439 if not x or not y:
440 raise Errors.WafError('null source or target for %r'%self)
441 a,b=None,None
442 if isinstance(x,str)and isinstance(y,str)and x==y:
443 a=self.path.find_node(x)
444 b=self.path.get_bld().make_node(y)
445 if not os.path.isfile(b.abspath()):
446 b.parent.mkdir()
447 else:
448 if isinstance(x,str):
449 a=self.path.find_resource(x)
450 elif isinstance(x,Node.Node):
451 a=x
452 if isinstance(y,str):
453 b=self.path.find_or_declare(y)
454 elif isinstance(y,Node.Node):
455 b=y
456 if not a:
457 raise Errors.WafError('could not find %r for %r'%(x,self))
458 tsk=self.create_task('subst',a,b)
459 for k in('after','before','ext_in','ext_out'):
460 val=getattr(self,k,None)
461 if val:
462 setattr(tsk,k,val)
463 for xt in HEADER_EXTS:
464 if b.name.endswith(xt):
465 tsk.ext_out=tsk.ext_out+['.h']
466 break
467 inst_to=getattr(self,'install_path',None)
468 if inst_to:
469 self.install_task=self.add_install_files(install_to=inst_to,install_from=b,chmod=getattr(self,'chmod',Utils.O644))
470 self.source=[]
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib.Configure import conf
5 @conf
6 def find_ar(conf):
7 conf.load('ar')
8 def configure(conf):
9 conf.find_program('ar',var='AR')
10 conf.add_os_flags('ARFLAGS')
11 if not conf.env.ARFLAGS:
12 conf.env.ARFLAGS=['rcs']
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import re
5 from waflib import Errors,Logs,Task
6 from waflib.Tools.ccroot import link_task,stlink_task
7 from waflib.TaskGen import extension
8 from waflib.Tools import c_preproc
9 re_lines=re.compile('^[ \t]*(?:%)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef)[ \t]*(.*)\r*$',re.IGNORECASE|re.MULTILINE)
10 class asm_parser(c_preproc.c_parser):
11 def filter_comments(self,node):
12 code=node.read()
13 code=c_preproc.re_nl.sub('',code)
14 code=c_preproc.re_cpp.sub(c_preproc.repl,code)
15 return re_lines.findall(code)
16 class asm(Task.Task):
17 color='BLUE'
18 run_str='${AS} ${ASFLAGS} ${ASMPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${AS_SRC_F}${SRC} ${AS_TGT_F}${TGT}'
19 def scan(self):
20 if self.env.ASM_NAME=='gas':
21 return c_preproc.scan(self)
22 Logs.warn('There is no dependency scanner for Nasm!')
23 return[[],[]]
24 elif self.env.ASM_NAME=='nasm':
25 Logs.warn('The Nasm dependency scanner is incomplete!')
26 try:
27 incn=self.generator.includes_nodes
28 except AttributeError:
29 raise Errors.WafError('%r is missing the "asm" feature'%self.generator)
30 if c_preproc.go_absolute:
31 nodepaths=incn
32 else:
33 nodepaths=[x for x in incn if x.is_child_of(x.ctx.srcnode)or x.is_child_of(x.ctx.bldnode)]
34 tmp=asm_parser(nodepaths)
35 tmp.start(self.inputs[0],self.env)
36 return(tmp.nodes,tmp.names)
37 @extension('.s','.S','.asm','.ASM','.spp','.SPP')
38 def asm_hook(self,node):
39 return self.create_compiled_task('asm',node)
40 class asmprogram(link_task):
41 run_str='${ASLINK} ${ASLINKFLAGS} ${ASLNK_TGT_F}${TGT} ${ASLNK_SRC_F}${SRC}'
42 ext_out=['.bin']
43 inst_to='${BINDIR}'
44 class asmshlib(asmprogram):
45 inst_to='${LIBDIR}'
46 class asmstlib(stlink_task):
47 pass
48 def configure(conf):
49 conf.env.ASMPATH_ST='-I%s'
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib import Task
5 from waflib.TaskGen import extension
6 class bison(Task.Task):
7 color='BLUE'
8 run_str='${BISON} ${BISONFLAGS} ${SRC[0].abspath()} -o ${TGT[0].name}'
9 ext_out=['.h']
10 @extension('.y','.yc','.yy')
11 def big_bison(self,node):
12 has_h='-d'in self.env.BISONFLAGS
13 outs=[]
14 if node.name.endswith('.yc'):
15 outs.append(node.change_ext('.tab.cc'))
16 if has_h:
17 outs.append(node.change_ext('.tab.hh'))
18 else:
19 outs.append(node.change_ext('.tab.c'))
20 if has_h:
21 outs.append(node.change_ext('.tab.h'))
22 tsk=self.create_task('bison',node,outs)
23 tsk.cwd=node.parent.get_bld()
24 self.source.append(outs[0])
25 def configure(conf):
26 conf.find_program('bison',var='BISON')
27 conf.env.BISONFLAGS=['-d']
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib import TaskGen,Task
5 from waflib.Tools import c_preproc
6 from waflib.Tools.ccroot import link_task,stlink_task
7 @TaskGen.extension('.c')
8 def c_hook(self,node):
9 if not self.env.CC and self.env.CXX:
10 return self.create_compiled_task('cxx',node)
11 return self.create_compiled_task('c',node)
12 class c(Task.Task):
13 run_str='${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CC_SRC_F}${SRC} ${CC_TGT_F}${TGT[0].abspath()} ${CPPFLAGS}'
14 vars=['CCDEPS']
15 ext_in=['.h']
16 scan=c_preproc.scan
17 class cprogram(link_task):
18 run_str='${LINK_CC} ${LINKFLAGS} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LDFLAGS}'
19 ext_out=['.bin']
20 vars=['LINKDEPS']
21 inst_to='${BINDIR}'
22 class cshlib(cprogram):
23 inst_to='${LIBDIR}'
24 class cstlib(stlink_task):
25 pass
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib import Utils,Errors
5 from waflib.Configure import conf
6 def get_extensions(lst):
7 ret=[]
8 for x in Utils.to_list(lst):
9 if not isinstance(x,str):
10 x=x.name
11 ret.append(x[x.rfind('.')+1:])
12 return ret
13 def sniff_features(**kw):
14 exts=get_extensions(kw.get('source',[]))
15 typ=kw['typ']
16 feats=[]
17 for x in'cxx cpp c++ cc C'.split():
18 if x in exts:
19 feats.append('cxx')
20 break
21 if'c'in exts or'vala'in exts or'gs'in exts:
22 feats.append('c')
23 if's'in exts or'S'in exts:
24 feats.append('asm')
25 for x in'f f90 F F90 for FOR'.split():
26 if x in exts:
27 feats.append('fc')
28 break
29 if'd'in exts:
30 feats.append('d')
31 if'java'in exts:
32 feats.append('java')
33 return'java'
34 if typ in('program','shlib','stlib'):
35 will_link=False
36 for x in feats:
37 if x in('cxx','d','fc','c','asm'):
38 feats.append(x+typ)
39 will_link=True
40 if not will_link and not kw.get('features',[]):
41 raise Errors.WafError('Unable to determine how to link %r, try adding eg: features="c cshlib"?'%kw)
42 return feats
43 def set_features(kw,typ):
44 kw['typ']=typ
45 kw['features']=Utils.to_list(kw.get('features',[]))+Utils.to_list(sniff_features(**kw))
46 @conf
47 def program(bld,*k,**kw):
48 set_features(kw,'program')
49 return bld(*k,**kw)
50 @conf
51 def shlib(bld,*k,**kw):
52 set_features(kw,'shlib')
53 return bld(*k,**kw)
54 @conf
55 def stlib(bld,*k,**kw):
56 set_features(kw,'stlib')
57 return bld(*k,**kw)
58 @conf
59 def objects(bld,*k,**kw):
60 set_features(kw,'objects')
61 return bld(*k,**kw)
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from __future__ import with_statement
5 import os,re,shlex
6 from waflib import Build,Utils,Task,Options,Logs,Errors,Runner
7 from waflib.TaskGen import after_method,feature
8 from waflib.Configure import conf
9 WAF_CONFIG_H='config.h'
10 DEFKEYS='define_key'
11 INCKEYS='include_key'
12 SNIP_EMPTY_PROGRAM='''
13 int main(int argc, char **argv) {
14 (void)argc; (void)argv;
15 return 0;
16 }
17 '''
18 MACRO_TO_DESTOS={'__linux__':'linux','__GNU__':'gnu','__FreeBSD__':'freebsd','__NetBSD__':'netbsd','__OpenBSD__':'openbsd','__sun':'sunos','__hpux':'hpux','__sgi':'irix','_AIX':'aix','__CYGWIN__':'cygwin','__MSYS__':'cygwin','_UWIN':'uwin','_WIN64':'win32','_WIN32':'win32','__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__':'darwin','__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__':'darwin','__QNX__':'qnx','__native_client__':'nacl'}
19 MACRO_TO_DEST_CPU={'__x86_64__':'x86_64','__amd64__':'x86_64','__i386__':'x86','__ia64__':'ia','__mips__':'mips','__sparc__':'sparc','__alpha__':'alpha','__aarch64__':'aarch64','__thumb__':'thumb','__arm__':'arm','__hppa__':'hppa','__powerpc__':'powerpc','__ppc__':'powerpc','__convex__':'convex','__m68k__':'m68k','__s390x__':'s390x','__s390__':'s390','__sh__':'sh','__xtensa__':'xtensa',}
20 @conf
21 def parse_flags(self,line,uselib_store,env=None,force_static=False,posix=None):
22 assert(isinstance(line,str))
23 env=env or self.env
24 if posix is None:
25 posix=True
26 if'\\'in line:
27 posix=('\\ 'in line)or('\\\\'in line)
28 lex=shlex.shlex(line,posix=posix)
29 lex.whitespace_split=True
30 lex.commenters=''
31 lst=list(lex)
32 so_re=re.compile(r"\.so(?:\.[0-9]+)*$")
33 uselib=uselib_store
34 def app(var,val):
35 env.append_value('%s_%s'%(var,uselib),val)
36 def appu(var,val):
37 env.append_unique('%s_%s'%(var,uselib),val)
38 static=False
39 while lst:
40 x=lst.pop(0)
41 st=x[:2]
42 ot=x[2:]
43 if st=='-I'or st=='/I':
44 if not ot:
45 ot=lst.pop(0)
46 appu('INCLUDES',ot)
47 elif st=='-i':
48 tmp=[x,lst.pop(0)]
49 app('CFLAGS',tmp)
50 app('CXXFLAGS',tmp)
51 elif st=='-D'or(env.CXX_NAME=='msvc'and st=='/D'):
52 if not ot:
53 ot=lst.pop(0)
54 app('DEFINES',ot)
55 elif st=='-l':
56 if not ot:
57 ot=lst.pop(0)
58 prefix='STLIB'if(force_static or static)else'LIB'
59 app(prefix,ot)
60 elif st=='-L':
61 if not ot:
62 ot=lst.pop(0)
63 prefix='STLIBPATH'if(force_static or static)else'LIBPATH'
64 appu(prefix,ot)
65 elif x.startswith('/LIBPATH:'):
66 prefix='STLIBPATH'if(force_static or static)else'LIBPATH'
67 appu(prefix,x.replace('/LIBPATH:',''))
68 elif x.startswith('-std='):
69 prefix='CXXFLAGS'if'++'in x else'CFLAGS'
70 app(prefix,x)
71 elif x.startswith('+')or x in('-pthread','-fPIC','-fpic','-fPIE','-fpie'):
72 app('CFLAGS',x)
73 app('CXXFLAGS',x)
74 app('LINKFLAGS',x)
75 elif x=='-framework':
76 appu('FRAMEWORK',lst.pop(0))
77 elif x.startswith('-F'):
78 appu('FRAMEWORKPATH',x[2:])
79 elif x=='-Wl,-rpath'or x=='-Wl,-R':
80 app('RPATH',lst.pop(0).lstrip('-Wl,'))
81 elif x.startswith('-Wl,-R,'):
82 app('RPATH',x[7:])
83 elif x.startswith('-Wl,-R'):
84 app('RPATH',x[6:])
85 elif x.startswith('-Wl,-rpath,'):
86 app('RPATH',x[11:])
87 elif x=='-Wl,-Bstatic'or x=='-Bstatic':
88 static=True
89 elif x=='-Wl,-Bdynamic'or x=='-Bdynamic':
90 static=False
91 elif x.startswith('-Wl')or x in('-rdynamic','-pie'):
92 app('LINKFLAGS',x)
93 elif x.startswith(('-m','-f','-dynamic','-O','-g')):
94 app('CFLAGS',x)
95 app('CXXFLAGS',x)
96 elif x.startswith('-bundle'):
97 app('LINKFLAGS',x)
98 elif x.startswith(('-undefined','-Xlinker')):
99 arg=lst.pop(0)
100 app('LINKFLAGS',[x,arg])
101 elif x.startswith(('-arch','-isysroot')):
102 tmp=[x,lst.pop(0)]
103 app('CFLAGS',tmp)
104 app('CXXFLAGS',tmp)
105 app('LINKFLAGS',tmp)
106 elif x.endswith(('.a','.dylib','.lib'))or so_re.search(x):
107 appu('LINKFLAGS',x)
108 else:
109 self.to_log('Unhandled flag %r'%x)
110 @conf
111 def validate_cfg(self,kw):
112 if not'path'in kw:
113 if not self.env.PKGCONFIG:
114 self.find_program('pkg-config',var='PKGCONFIG')
115 kw['path']=self.env.PKGCONFIG
116 s=('atleast_pkgconfig_version'in kw)+('modversion'in kw)+('package'in kw)
117 if s!=1:
118 raise ValueError('exactly one of atleast_pkgconfig_version, modversion and package must be set')
119 if not'msg'in kw:
120 if'atleast_pkgconfig_version'in kw:
121 kw['msg']='Checking for pkg-config version >= %r'%kw['atleast_pkgconfig_version']
122 elif'modversion'in kw:
123 kw['msg']='Checking for %r version'%kw['modversion']
124 else:
125 kw['msg']='Checking for %r'%(kw['package'])
126 if not'okmsg'in kw and not'modversion'in kw:
127 kw['okmsg']='yes'
128 if not'errmsg'in kw:
129 kw['errmsg']='not found'
130 if'atleast_pkgconfig_version'in kw:
131 pass
132 elif'modversion'in kw:
133 if not'uselib_store'in kw:
134 kw['uselib_store']=kw['modversion']
135 if not'define_name'in kw:
136 kw['define_name']='%s_VERSION'%Utils.quote_define_name(kw['uselib_store'])
137 else:
138 if not'uselib_store'in kw:
139 kw['uselib_store']=Utils.to_list(kw['package'])[0].upper()
140 if not'define_name'in kw:
141 kw['define_name']=self.have_define(kw['uselib_store'])
142 @conf
143 def exec_cfg(self,kw):
144 path=Utils.to_list(kw['path'])
145 env=self.env.env or None
146 if kw.get('pkg_config_path'):
147 if not env:
148 env=dict(self.environ)
149 env['PKG_CONFIG_PATH']=kw['pkg_config_path']
150 def define_it():
151 define_name=kw['define_name']
152 if kw.get('global_define',1):
153 self.define(define_name,1,False)
154 else:
155 self.env.append_unique('DEFINES_%s'%kw['uselib_store'],"%s=1"%define_name)
156 if kw.get('add_have_to_env',1):
157 self.env[define_name]=1
158 if'atleast_pkgconfig_version'in kw:
159 cmd=path+['--atleast-pkgconfig-version=%s'%kw['atleast_pkgconfig_version']]
160 self.cmd_and_log(cmd,env=env)
161 return
162 if'modversion'in kw:
163 version=self.cmd_and_log(path+['--modversion',kw['modversion']],env=env).strip()
164 if not'okmsg'in kw:
165 kw['okmsg']=version
166 self.define(kw['define_name'],version)
167 return version
168 lst=[]+path
169 defi=kw.get('define_variable')
170 if not defi:
171 defi=self.env.PKG_CONFIG_DEFINES or{}
172 for key,val in defi.items():
173 lst.append('--define-variable=%s=%s'%(key,val))
174 static=kw.get('force_static',False)
175 if'args'in kw:
176 args=Utils.to_list(kw['args'])
177 if'--static'in args or'--static-libs'in args:
178 static=True
179 lst+=args
180 lst.extend(Utils.to_list(kw['package']))
181 if'variables'in kw:
182 v_env=kw.get('env',self.env)
183 vars=Utils.to_list(kw['variables'])
184 for v in vars:
185 val=self.cmd_and_log(lst+['--variable='+v],env=env).strip()
186 var='%s_%s'%(kw['uselib_store'],v)
187 v_env[var]=val
188 return
189 ret=self.cmd_and_log(lst,env=env)
190 define_it()
191 self.parse_flags(ret,kw['uselib_store'],kw.get('env',self.env),force_static=static,posix=kw.get('posix'))
192 return ret
193 @conf
194 def check_cfg(self,*k,**kw):
195 self.validate_cfg(kw)
196 if'msg'in kw:
197 self.start_msg(kw['msg'],**kw)
198 ret=None
199 try:
200 ret=self.exec_cfg(kw)
201 except self.errors.WafError as e:
202 if'errmsg'in kw:
203 self.end_msg(kw['errmsg'],'YELLOW',**kw)
204 if Logs.verbose>1:
205 self.to_log('Command failure: %s'%e)
206 self.fatal('The configuration failed')
207 else:
208 if not ret:
209 ret=True
210 kw['success']=ret
211 if'okmsg'in kw:
212 self.end_msg(self.ret_msg(kw['okmsg'],kw),**kw)
213 return ret
214 def build_fun(bld):
215 if bld.kw['compile_filename']:
216 node=bld.srcnode.make_node(bld.kw['compile_filename'])
217 node.write(bld.kw['code'])
218 o=bld(features=bld.kw['features'],source=bld.kw['compile_filename'],target='testprog')
219 for k,v in bld.kw.items():
220 setattr(o,k,v)
221 if not bld.kw.get('quiet'):
222 bld.conf.to_log("==>\n%s\n<=="%bld.kw['code'])
223 @conf
224 def validate_c(self,kw):
225 for x in('type_name','field_name','function_name'):
226 if x in kw:
227 Logs.warn('Invalid argument %r in test'%x)
228 if not'build_fun'in kw:
229 kw['build_fun']=build_fun
230 if not'env'in kw:
231 kw['env']=self.env.derive()
232 env=kw['env']
233 if not'compiler'in kw and not'features'in kw:
234 kw['compiler']='c'
235 if env.CXX_NAME and Task.classes.get('cxx'):
236 kw['compiler']='cxx'
237 if not self.env.CXX:
238 self.fatal('a c++ compiler is required')
239 else:
240 if not self.env.CC:
241 self.fatal('a c compiler is required')
242 if not'compile_mode'in kw:
243 kw['compile_mode']='c'
244 if'cxx'in Utils.to_list(kw.get('features',[]))or kw.get('compiler')=='cxx':
245 kw['compile_mode']='cxx'
246 if not'type'in kw:
247 kw['type']='cprogram'
248 if not'features'in kw:
249 if not'header_name'in kw or kw.get('link_header_test',True):
250 kw['features']=[kw['compile_mode'],kw['type']]
251 else:
252 kw['features']=[kw['compile_mode']]
253 else:
254 kw['features']=Utils.to_list(kw['features'])
255 if not'compile_filename'in kw:
256 kw['compile_filename']='test.c'+((kw['compile_mode']=='cxx')and'pp'or'')
257 def to_header(dct):
258 if'header_name'in dct:
259 dct=Utils.to_list(dct['header_name'])
260 return''.join(['#include <%s>\n'%x for x in dct])
261 return''
262 if'framework_name'in kw:
263 fwkname=kw['framework_name']
264 if not'uselib_store'in kw:
265 kw['uselib_store']=fwkname.upper()
266 if not kw.get('no_header'):
267 fwk='%s/%s.h'%(fwkname,fwkname)
268 if kw.get('remove_dot_h'):
269 fwk=fwk[:-2]
270 val=kw.get('header_name',[])
271 kw['header_name']=Utils.to_list(val)+[fwk]
272 kw['msg']='Checking for framework %s'%fwkname
273 kw['framework']=fwkname
274 elif'header_name'in kw:
275 if not'msg'in kw:
276 kw['msg']='Checking for header %s'%kw['header_name']
277 l=Utils.to_list(kw['header_name'])
278 assert len(l),'list of headers in header_name is empty'
279 kw['code']=to_header(kw)+SNIP_EMPTY_PROGRAM
280 if not'uselib_store'in kw:
281 kw['uselib_store']=l[0].upper()
282 if not'define_name'in kw:
283 kw['define_name']=self.have_define(l[0])
284 if'lib'in kw:
285 if not'msg'in kw:
286 kw['msg']='Checking for library %s'%kw['lib']
287 if not'uselib_store'in kw:
288 kw['uselib_store']=kw['lib'].upper()
289 if'stlib'in kw:
290 if not'msg'in kw:
291 kw['msg']='Checking for static library %s'%kw['stlib']
292 if not'uselib_store'in kw:
293 kw['uselib_store']=kw['stlib'].upper()
294 if'fragment'in kw:
295 kw['code']=kw['fragment']
296 if not'msg'in kw:
297 kw['msg']='Checking for code snippet'
298 if not'errmsg'in kw:
299 kw['errmsg']='no'
300 for(flagsname,flagstype)in(('cxxflags','compiler'),('cflags','compiler'),('linkflags','linker')):
301 if flagsname in kw:
302 if not'msg'in kw:
303 kw['msg']='Checking for %s flags %s'%(flagstype,kw[flagsname])
304 if not'errmsg'in kw:
305 kw['errmsg']='no'
306 if not'execute'in kw:
307 kw['execute']=False
308 if kw['execute']:
309 kw['features'].append('test_exec')
310 kw['chmod']=Utils.O755
311 if not'errmsg'in kw:
312 kw['errmsg']='not found'
313 if not'okmsg'in kw:
314 kw['okmsg']='yes'
315 if not'code'in kw:
316 kw['code']=SNIP_EMPTY_PROGRAM
317 if self.env[INCKEYS]:
318 kw['code']='\n'.join(['#include <%s>'%x for x in self.env[INCKEYS]])+'\n'+kw['code']
319 if kw.get('merge_config_header')or env.merge_config_header:
320 kw['code']='%s\n\n%s'%(self.get_config_header(),kw['code'])
321 env.DEFINES=[]
322 if not kw.get('success'):
323 kw['success']=None
324 if'define_name'in kw:
325 self.undefine(kw['define_name'])
326 if not'msg'in kw:
327 self.fatal('missing "msg" in conf.check(...)')
328 @conf
329 def post_check(self,*k,**kw):
330 is_success=0
331 if kw['execute']:
332 if kw['success']is not None:
333 if kw.get('define_ret'):
334 is_success=kw['success']
335 else:
336 is_success=(kw['success']==0)
337 else:
338 is_success=(kw['success']==0)
339 if kw.get('define_name'):
340 comment=kw.get('comment','')
341 define_name=kw['define_name']
342 if kw['execute']and kw.get('define_ret')and isinstance(is_success,str):
343 if kw.get('global_define',1):
344 self.define(define_name,is_success,quote=kw.get('quote',1),comment=comment)
345 else:
346 if kw.get('quote',1):
347 succ='"%s"'%is_success
348 else:
349 succ=int(is_success)
350 val='%s=%s'%(define_name,succ)
351 var='DEFINES_%s'%kw['uselib_store']
352 self.env.append_value(var,val)
353 else:
354 if kw.get('global_define',1):
355 self.define_cond(define_name,is_success,comment=comment)
356 else:
357 var='DEFINES_%s'%kw['uselib_store']
358 self.env.append_value(var,'%s=%s'%(define_name,int(is_success)))
359 if kw.get('add_have_to_env',1):
360 if kw.get('uselib_store'):
361 self.env[self.have_define(kw['uselib_store'])]=1
362 elif kw['execute']and kw.get('define_ret'):
363 self.env[define_name]=is_success
364 else:
365 self.env[define_name]=int(is_success)
366 if'header_name'in kw:
367 if kw.get('auto_add_header_name'):
368 self.env.append_value(INCKEYS,Utils.to_list(kw['header_name']))
369 if is_success and'uselib_store'in kw:
370 from waflib.Tools import ccroot
371 _vars=set()
372 for x in kw['features']:
373 if x in ccroot.USELIB_VARS:
374 _vars|=ccroot.USELIB_VARS[x]
375 for k in _vars:
376 x=k.lower()
377 if x in kw:
378 self.env.append_value(k+'_'+kw['uselib_store'],kw[x])
379 return is_success
380 @conf
381 def check(self,*k,**kw):
382 self.validate_c(kw)
383 self.start_msg(kw['msg'],**kw)
384 ret=None
385 try:
386 ret=self.run_build(*k,**kw)
387 except self.errors.ConfigurationError:
388 self.end_msg(kw['errmsg'],'YELLOW',**kw)
389 if Logs.verbose>1:
390 raise
391 else:
392 self.fatal('The configuration failed')
393 else:
394 kw['success']=ret
395 ret=self.post_check(*k,**kw)
396 if not ret:
397 self.end_msg(kw['errmsg'],'YELLOW',**kw)
398 self.fatal('The configuration failed %r'%ret)
399 else:
400 self.end_msg(self.ret_msg(kw['okmsg'],kw),**kw)
401 return ret
402 class test_exec(Task.Task):
403 color='PINK'
404 def run(self):
405 cmd=[self.inputs[0].abspath()]+getattr(self.generator,'test_args',[])
406 if getattr(self.generator,'rpath',None):
407 if getattr(self.generator,'define_ret',False):
408 self.generator.bld.retval=self.generator.bld.cmd_and_log(cmd)
409 else:
410 self.generator.bld.retval=self.generator.bld.exec_command(cmd)
411 else:
412 env=self.env.env or{}
413 env.update(dict(os.environ))
414 for var in('LD_LIBRARY_PATH','DYLD_LIBRARY_PATH','PATH'):
415 env[var]=self.inputs[0].parent.abspath()+os.path.pathsep+env.get(var,'')
416 if getattr(self.generator,'define_ret',False):
417 self.generator.bld.retval=self.generator.bld.cmd_and_log(cmd,env=env)
418 else:
419 self.generator.bld.retval=self.generator.bld.exec_command(cmd,env=env)
420 @feature('test_exec')
421 @after_method('apply_link')
422 def test_exec_fun(self):
423 self.create_task('test_exec',self.link_task.outputs[0])
424 @conf
425 def check_cxx(self,*k,**kw):
426 kw['compiler']='cxx'
427 return self.check(*k,**kw)
428 @conf
429 def check_cc(self,*k,**kw):
430 kw['compiler']='c'
431 return self.check(*k,**kw)
432 @conf
433 def set_define_comment(self,key,comment):
434 coms=self.env.DEFINE_COMMENTS
435 if not coms:
436 coms=self.env.DEFINE_COMMENTS={}
437 coms[key]=comment or''
438 @conf
439 def get_define_comment(self,key):
440 coms=self.env.DEFINE_COMMENTS or{}
441 return coms.get(key,'')
442 @conf
443 def define(self,key,val,quote=True,comment=''):
444 assert isinstance(key,str)
445 if not key:
446 return
447 if val is True:
448 val=1
449 elif val in(False,None):
450 val=0
451 if isinstance(val,int)or isinstance(val,float):
452 s='%s=%s'
453 else:
454 s=quote and'%s="%s"'or'%s=%s'
455 app=s%(key,str(val))
456 ban=key+'='
457 lst=self.env.DEFINES
458 for x in lst:
459 if x.startswith(ban):
460 lst[lst.index(x)]=app
461 break
462 else:
463 self.env.append_value('DEFINES',app)
464 self.env.append_unique(DEFKEYS,key)
465 self.set_define_comment(key,comment)
466 @conf
467 def undefine(self,key,comment=''):
468 assert isinstance(key,str)
469 if not key:
470 return
471 ban=key+'='
472 lst=[x for x in self.env.DEFINES if not x.startswith(ban)]
473 self.env.DEFINES=lst
474 self.env.append_unique(DEFKEYS,key)
475 self.set_define_comment(key,comment)
476 @conf
477 def define_cond(self,key,val,comment=''):
478 assert isinstance(key,str)
479 if not key:
480 return
481 if val:
482 self.define(key,1,comment=comment)
483 else:
484 self.undefine(key,comment=comment)
485 @conf
486 def is_defined(self,key):
487 assert key and isinstance(key,str)
488 ban=key+'='
489 for x in self.env.DEFINES:
490 if x.startswith(ban):
491 return True
492 return False
493 @conf
494 def get_define(self,key):
495 assert key and isinstance(key,str)
496 ban=key+'='
497 for x in self.env.DEFINES:
498 if x.startswith(ban):
499 return x[len(ban):]
500 return None
501 @conf
502 def have_define(self,key):
503 return(self.env.HAVE_PAT or'HAVE_%s')%Utils.quote_define_name(key)
504 @conf
505 def write_config_header(self,configfile='',guard='',top=False,defines=True,headers=False,remove=True,define_prefix=''):
506 if not configfile:
507 configfile=WAF_CONFIG_H
508 waf_guard=guard or'W_%s_WAF'%Utils.quote_define_name(configfile)
509 node=top and self.bldnode or self.path.get_bld()
510 node=node.make_node(configfile)
511 node.parent.mkdir()
512 lst=['/* WARNING! All changes made to this file will be lost! */\n']
513 lst.append('#ifndef %s\n#define %s\n'%(waf_guard,waf_guard))
514 lst.append(self.get_config_header(defines,headers,define_prefix=define_prefix))
515 lst.append('\n#endif /* %s */\n'%waf_guard)
516 node.write('\n'.join(lst))
517 self.env.append_unique(Build.CFG_FILES,[node.abspath()])
518 if remove:
519 for key in self.env[DEFKEYS]:
520 self.undefine(key)
521 self.env[DEFKEYS]=[]
522 @conf
523 def get_config_header(self,defines=True,headers=False,define_prefix=''):
524 lst=[]
525 if self.env.WAF_CONFIG_H_PRELUDE:
526 lst.append(self.env.WAF_CONFIG_H_PRELUDE)
527 if headers:
528 for x in self.env[INCKEYS]:
529 lst.append('#include <%s>'%x)
530 if defines:
531 tbl={}
532 for k in self.env.DEFINES:
533 a,_,b=k.partition('=')
534 tbl[a]=b
535 for k in self.env[DEFKEYS]:
536 caption=self.get_define_comment(k)
537 if caption:
538 caption=' /* %s */'%caption
539 try:
540 txt='#define %s%s %s%s'%(define_prefix,k,tbl[k],caption)
541 except KeyError:
542 txt='/* #undef %s%s */%s'%(define_prefix,k,caption)
543 lst.append(txt)
544 return"\n".join(lst)
545 @conf
546 def cc_add_flags(conf):
547 conf.add_os_flags('CPPFLAGS',dup=False)
548 conf.add_os_flags('CFLAGS',dup=False)
549 @conf
550 def cxx_add_flags(conf):
551 conf.add_os_flags('CPPFLAGS',dup=False)
552 conf.add_os_flags('CXXFLAGS',dup=False)
553 @conf
554 def link_add_flags(conf):
555 conf.add_os_flags('LINKFLAGS',dup=False)
556 conf.add_os_flags('LDFLAGS',dup=False)
557 @conf
558 def cc_load_tools(conf):
559 if not conf.env.DEST_OS:
560 conf.env.DEST_OS=Utils.unversioned_sys_platform()
561 conf.load('c')
562 @conf
563 def cxx_load_tools(conf):
564 if not conf.env.DEST_OS:
565 conf.env.DEST_OS=Utils.unversioned_sys_platform()
566 conf.load('cxx')
567 @conf
568 def get_cc_version(conf,cc,gcc=False,icc=False,clang=False):
569 cmd=cc+['-dM','-E','-']
570 env=conf.env.env or None
571 try:
572 out,err=conf.cmd_and_log(cmd,output=0,input='\n'.encode(),env=env)
573 except Errors.WafError:
574 conf.fatal('Could not determine the compiler version %r'%cmd)
575 if gcc:
576 if out.find('__INTEL_COMPILER')>=0:
577 conf.fatal('The intel compiler pretends to be gcc')
578 if out.find('__GNUC__')<0 and out.find('__clang__')<0:
579 conf.fatal('Could not determine the compiler type')
580 if icc and out.find('__INTEL_COMPILER')<0:
581 conf.fatal('Not icc/icpc')
582 if clang and out.find('__clang__')<0:
583 conf.fatal('Not clang/clang++')
584 if not clang and out.find('__clang__')>=0:
585 conf.fatal('Could not find gcc/g++ (only Clang), if renamed try eg: CC=gcc48 CXX=g++48 waf configure')
586 k={}
587 if icc or gcc or clang:
588 out=out.splitlines()
589 for line in out:
590 lst=shlex.split(line)
591 if len(lst)>2:
592 key=lst[1]
593 val=lst[2]
594 k[key]=val
595 def isD(var):
596 return var in k
597 if not conf.env.DEST_OS:
598 conf.env.DEST_OS=''
599 for i in MACRO_TO_DESTOS:
600 if isD(i):
601 conf.env.DEST_OS=MACRO_TO_DESTOS[i]
602 break
603 else:
604 if isD('__APPLE__')and isD('__MACH__'):
605 conf.env.DEST_OS='darwin'
606 elif isD('__unix__'):
607 conf.env.DEST_OS='generic'
608 if isD('__ELF__'):
609 conf.env.DEST_BINFMT='elf'
610 elif isD('__WINNT__')or isD('__CYGWIN__')or isD('_WIN32'):
611 conf.env.DEST_BINFMT='pe'
612 if not conf.env.IMPLIBDIR:
613 conf.env.IMPLIBDIR=conf.env.LIBDIR
614 conf.env.LIBDIR=conf.env.BINDIR
615 elif isD('__APPLE__'):
616 conf.env.DEST_BINFMT='mac-o'
617 if not conf.env.DEST_BINFMT:
618 conf.env.DEST_BINFMT=Utils.destos_to_binfmt(conf.env.DEST_OS)
619 for i in MACRO_TO_DEST_CPU:
620 if isD(i):
621 conf.env.DEST_CPU=MACRO_TO_DEST_CPU[i]
622 break
623 Logs.debug('ccroot: dest platform: '+' '.join([conf.env[x]or'?'for x in('DEST_OS','DEST_BINFMT','DEST_CPU')]))
624 if icc:
625 ver=k['__INTEL_COMPILER']
626 conf.env.CC_VERSION=(ver[:-2],ver[-2],ver[-1])
627 else:
628 if isD('__clang__')and isD('__clang_major__'):
629 conf.env.CC_VERSION=(k['__clang_major__'],k['__clang_minor__'],k['__clang_patchlevel__'])
630 else:
631 conf.env.CC_VERSION=(k['__GNUC__'],k['__GNUC_MINOR__'],k.get('__GNUC_PATCHLEVEL__','0'))
632 return k
633 @conf
634 def get_xlc_version(conf,cc):
635 cmd=cc+['-qversion']
636 try:
637 out,err=conf.cmd_and_log(cmd,output=0)
638 except Errors.WafError:
639 conf.fatal('Could not find xlc %r'%cmd)
640 for v in(r"IBM XL C/C\+\+.* V(?P<major>\d*)\.(?P<minor>\d*)",):
641 version_re=re.compile(v,re.I).search
642 match=version_re(out or err)
643 if match:
644 k=match.groupdict()
645 conf.env.CC_VERSION=(k['major'],k['minor'])
646 break
647 else:
648 conf.fatal('Could not determine the XLC version.')
649 @conf
650 def get_suncc_version(conf,cc):
651 cmd=cc+['-V']
652 try:
653 out,err=conf.cmd_and_log(cmd,output=0)
654 except Errors.WafError as e:
655 if not(hasattr(e,'returncode')and hasattr(e,'stdout')and hasattr(e,'stderr')):
656 conf.fatal('Could not find suncc %r'%cmd)
657 out=e.stdout
658 err=e.stderr
659 version=(out or err)
660 version=version.splitlines()[0]
661 version_re=re.compile(r'cc: (studio.*?|\s+)?(sun\s+(c\+\+|c)|(WorkShop\s+Compilers))?\s+(?P<major>\d*)\.(?P<minor>\d*)',re.I).search
662 match=version_re(version)
663 if match:
664 k=match.groupdict()
665 conf.env.CC_VERSION=(k['major'],k['minor'])
666 else:
667 conf.fatal('Could not determine the suncc version.')
668 @conf
669 def add_as_needed(self):
670 if self.env.DEST_BINFMT=='elf'and'gcc'in(self.env.CXX_NAME,self.env.CC_NAME):
671 self.env.append_unique('LINKFLAGS','-Wl,--as-needed')
672 class cfgtask(Task.Task):
673 def __init__(self,*k,**kw):
674 Task.Task.__init__(self,*k,**kw)
675 self.run_after=set()
676 def display(self):
677 return''
678 def runnable_status(self):
679 for x in self.run_after:
680 if not x.hasrun:
681 return Task.ASK_LATER
682 return Task.RUN_ME
683 def uid(self):
684 return Utils.SIG_NIL
685 def signature(self):
686 return Utils.SIG_NIL
687 def run(self):
688 conf=self.conf
689 bld=Build.BuildContext(top_dir=conf.srcnode.abspath(),out_dir=conf.bldnode.abspath())
690 bld.env=conf.env
691 bld.init_dirs()
692 bld.in_msg=1
693 bld.logger=self.logger
694 bld.multicheck_task=self
695 args=self.args
696 try:
697 if'func'in args:
698 bld.test(build_fun=args['func'],msg=args.get('msg',''),okmsg=args.get('okmsg',''),errmsg=args.get('errmsg',''),)
699 else:
700 args['multicheck_mandatory']=args.get('mandatory',True)
701 args['mandatory']=True
702 try:
703 bld.check(**args)
704 finally:
705 args['mandatory']=args['multicheck_mandatory']
706 except Exception:
707 return 1
708 def process(self):
709 Task.Task.process(self)
710 if'msg'in self.args:
711 with self.generator.bld.multicheck_lock:
712 self.conf.start_msg(self.args['msg'])
713 if self.hasrun==Task.NOT_RUN:
714 self.conf.end_msg('test cancelled','YELLOW')
715 elif self.hasrun!=Task.SUCCESS:
716 self.conf.end_msg(self.args.get('errmsg','no'),'YELLOW')
717 else:
718 self.conf.end_msg(self.args.get('okmsg','yes'),'GREEN')
719 @conf
720 def multicheck(self,*k,**kw):
721 self.start_msg(kw.get('msg','Executing %d configuration tests'%len(k)),**kw)
722 for var in('DEFINES',DEFKEYS):
723 self.env.append_value(var,[])
724 self.env.DEFINE_COMMENTS=self.env.DEFINE_COMMENTS or{}
725 class par(object):
726 def __init__(self):
727 self.keep=False
728 self.task_sigs={}
729 self.progress_bar=0
730 def total(self):
731 return len(tasks)
732 def to_log(self,*k,**kw):
733 return
734 bld=par()
735 bld.keep=kw.get('run_all_tests',True)
736 bld.imp_sigs={}
737 tasks=[]
738 id_to_task={}
739 for dct in k:
740 x=Task.classes['cfgtask'](bld=bld,env=None)
741 tasks.append(x)
742 x.args=dct
743 x.bld=bld
744 x.conf=self
745 x.args=dct
746 x.logger=Logs.make_mem_logger(str(id(x)),self.logger)
747 if'id'in dct:
748 id_to_task[dct['id']]=x
749 for x in tasks:
750 for key in Utils.to_list(x.args.get('before_tests',[])):
751 tsk=id_to_task[key]
752 if not tsk:
753 raise ValueError('No test named %r'%key)
754 tsk.run_after.add(x)
755 for key in Utils.to_list(x.args.get('after_tests',[])):
756 tsk=id_to_task[key]
757 if not tsk:
758 raise ValueError('No test named %r'%key)
759 x.run_after.add(tsk)
760 def it():
761 yield tasks
762 while 1:
763 yield[]
764 bld.producer=p=Runner.Parallel(bld,Options.options.jobs)
765 bld.multicheck_lock=Utils.threading.Lock()
766 p.biter=it()
767 self.end_msg('started')
768 p.start()
769 for x in tasks:
770 x.logger.memhandler.flush()
771 self.start_msg('-> processing test results')
772 if p.error:
773 for x in p.error:
774 if getattr(x,'err_msg',None):
775 self.to_log(x.err_msg)
776 self.end_msg('fail',color='RED')
777 raise Errors.WafError('There is an error in the library, read config.log for more information')
778 failure_count=0
779 for x in tasks:
780 if x.hasrun not in(Task.SUCCESS,Task.NOT_RUN):
781 failure_count+=1
782 if failure_count:
783 self.end_msg(kw.get('errmsg','%s test failed'%failure_count),color='YELLOW',**kw)
784 else:
785 self.end_msg('all ok',**kw)
786 for x in tasks:
787 if x.hasrun!=Task.SUCCESS:
788 if x.args.get('mandatory',True):
789 self.fatal(kw.get('fatalmsg')or'One of the tests has failed, read config.log for more information')
790 @conf
791 def check_gcc_o_space(self,mode='c'):
792 if int(self.env.CC_VERSION[0])>4:
793 return
794 self.env.stash()
795 if mode=='c':
796 self.env.CCLNK_TGT_F=['-o','']
797 elif mode=='cxx':
798 self.env.CXXLNK_TGT_F=['-o','']
799 features='%s %sshlib'%(mode,mode)
800 try:
801 self.check(msg='Checking if the -o link must be split from arguments',fragment=SNIP_EMPTY_PROGRAM,features=features)
802 except self.errors.ConfigurationError:
803 self.env.revert()
804 else:
805 self.env.commit()
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os,shutil,platform
5 from waflib import Task,Utils
6 from waflib.TaskGen import taskgen_method,feature,after_method,before_method
7 app_info='''
8 <?xml version="1.0" encoding="UTF-8"?>
9 <!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
10 <plist version="0.9">
11 <dict>
12 <key>CFBundlePackageType</key>
13 <string>APPL</string>
14 <key>CFBundleGetInfoString</key>
15 <string>Created by Waf</string>
16 <key>CFBundleSignature</key>
17 <string>????</string>
18 <key>NOTE</key>
19 <string>THIS IS A GENERATED FILE, DO NOT MODIFY</string>
20 <key>CFBundleExecutable</key>
21 <string>{app_name}</string>
22 </dict>
23 </plist>
24 '''
25 @feature('c','cxx')
26 def set_macosx_deployment_target(self):
27 if self.env.MACOSX_DEPLOYMENT_TARGET:
28 os.environ['MACOSX_DEPLOYMENT_TARGET']=self.env.MACOSX_DEPLOYMENT_TARGET
29 elif'MACOSX_DEPLOYMENT_TARGET'not in os.environ:
30 if Utils.unversioned_sys_platform()=='darwin':
31 os.environ['MACOSX_DEPLOYMENT_TARGET']='.'.join(platform.mac_ver()[0].split('.')[:2])
32 @taskgen_method
33 def create_bundle_dirs(self,name,out):
34 dir=out.parent.find_or_declare(name)
35 dir.mkdir()
36 macos=dir.find_or_declare(['Contents','MacOS'])
37 macos.mkdir()
38 return dir
39 def bundle_name_for_output(out):
40 name=out.name
41 k=name.rfind('.')
42 if k>=0:
43 name=name[:k]+'.app'
44 else:
45 name=name+'.app'
46 return name
47 @feature('cprogram','cxxprogram')
48 @after_method('apply_link')
49 def create_task_macapp(self):
50 if self.env.MACAPP or getattr(self,'mac_app',False):
51 out=self.link_task.outputs[0]
52 name=bundle_name_for_output(out)
53 dir=self.create_bundle_dirs(name,out)
54 n1=dir.find_or_declare(['Contents','MacOS',out.name])
55 self.apptask=self.create_task('macapp',self.link_task.outputs,n1)
56 inst_to=getattr(self,'install_path','/Applications')+'/%s/Contents/MacOS/'%name
57 self.add_install_files(install_to=inst_to,install_from=n1,chmod=Utils.O755)
58 if getattr(self,'mac_files',None):
59 mac_files_root=getattr(self,'mac_files_root',None)
60 if isinstance(mac_files_root,str):
61 mac_files_root=self.path.find_node(mac_files_root)
62 if not mac_files_root:
63 self.bld.fatal('Invalid mac_files_root %r'%self.mac_files_root)
64 res_dir=n1.parent.parent.make_node('Resources')
65 inst_to=getattr(self,'install_path','/Applications')+'/%s/Resources'%name
66 for node in self.to_nodes(self.mac_files):
67 relpath=node.path_from(mac_files_root or node.parent)
68 self.create_task('macapp',node,res_dir.make_node(relpath))
69 self.add_install_as(install_to=os.path.join(inst_to,relpath),install_from=node)
70 if getattr(self.bld,'is_install',None):
71 self.install_task.hasrun=Task.SKIP_ME
72 @feature('cprogram','cxxprogram')
73 @after_method('apply_link')
74 def create_task_macplist(self):
75 if self.env.MACAPP or getattr(self,'mac_app',False):
76 out=self.link_task.outputs[0]
77 name=bundle_name_for_output(out)
78 dir=self.create_bundle_dirs(name,out)
79 n1=dir.find_or_declare(['Contents','Info.plist'])
80 self.plisttask=plisttask=self.create_task('macplist',[],n1)
81 plisttask.context={'app_name':self.link_task.outputs[0].name,'env':self.env}
82 plist_ctx=getattr(self,'plist_context',None)
83 if(plist_ctx):
84 plisttask.context.update(plist_ctx)
85 if getattr(self,'mac_plist',False):
86 node=self.path.find_resource(self.mac_plist)
87 if node:
88 plisttask.inputs.append(node)
89 else:
90 plisttask.code=self.mac_plist
91 else:
92 plisttask.code=app_info
93 inst_to=getattr(self,'install_path','/Applications')+'/%s/Contents/'%name
94 self.add_install_files(install_to=inst_to,install_from=n1)
95 @feature('cshlib','cxxshlib')
96 @before_method('apply_link','propagate_uselib_vars')
97 def apply_bundle(self):
98 if self.env.MACBUNDLE or getattr(self,'mac_bundle',False):
99 self.env.LINKFLAGS_cshlib=self.env.LINKFLAGS_cxxshlib=[]
100 self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.macbundle_PATTERN
101 use=self.use=self.to_list(getattr(self,'use',[]))
102 if not'MACBUNDLE'in use:
103 use.append('MACBUNDLE')
104 app_dirs=['Contents','Contents/MacOS','Contents/Resources']
105 class macapp(Task.Task):
106 color='PINK'
107 def run(self):
108 self.outputs[0].parent.mkdir()
109 shutil.copy2(self.inputs[0].srcpath(),self.outputs[0].abspath())
110 class macplist(Task.Task):
111 color='PINK'
112 ext_in=['.bin']
113 def run(self):
114 if getattr(self,'code',None):
115 txt=self.code
116 else:
117 txt=self.inputs[0].read()
118 context=getattr(self,'context',{})
119 txt=txt.format(**context)
120 self.outputs[0].write(txt)
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import re,string,traceback
5 from waflib import Logs,Utils,Errors
6 class PreprocError(Errors.WafError):
7 pass
8 FILE_CACHE_SIZE=100000
9 LINE_CACHE_SIZE=100000
10 POPFILE='-'
11 recursion_limit=150
12 go_absolute=False
13 standard_includes=['/usr/local/include','/usr/include']
14 if Utils.is_win32:
15 standard_includes=[]
16 use_trigraphs=0
17 strict_quotes=0
18 g_optrans={'not':'!','not_eq':'!','and':'&&','and_eq':'&=','or':'||','or_eq':'|=','xor':'^','xor_eq':'^=','bitand':'&','bitor':'|','compl':'~',}
19 re_lines=re.compile('^[ \t]*(?:#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*)\r*$',re.IGNORECASE|re.MULTILINE)
20 re_mac=re.compile(r"^[a-zA-Z_]\w*")
21 re_fun=re.compile('^[a-zA-Z_][a-zA-Z0-9_]*[(]')
22 re_pragma_once=re.compile(r'^\s*once\s*',re.IGNORECASE)
23 re_nl=re.compile('\\\\\r*\n',re.MULTILINE)
24 re_cpp=re.compile(r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',re.DOTALL|re.MULTILINE)
25 trig_def=[('??'+a,b)for a,b in zip("=-/!'()<>",r'#~\|^[]{}')]
26 chr_esc={'0':0,'a':7,'b':8,'t':9,'n':10,'f':11,'v':12,'r':13,'\\':92,"'":39}
27 NUM='i'
28 OP='O'
29 IDENT='T'
30 STR='s'
31 CHAR='c'
32 tok_types=[NUM,STR,IDENT,OP]
33 exp_types=[r"""0[xX](?P<hex>[a-fA-F0-9]+)(?P<qual1>[uUlL]*)|L*?'(?P<char>(\\.|[^\\'])+)'|(?P<n1>\d+)[Ee](?P<exp0>[+-]*?\d+)(?P<float0>[fFlL]*)|(?P<n2>\d*\.\d+)([Ee](?P<exp1>[+-]*?\d+))?(?P<float1>[fFlL]*)|(?P<n4>\d+\.\d*)([Ee](?P<exp2>[+-]*?\d+))?(?P<float2>[fFlL]*)|(?P<oct>0*)(?P<n0>\d+)(?P<qual2>[uUlL]*)""",r'L?"([^"\\]|\\.)*"',r'[a-zA-Z_]\w*',r'%:%:|<<=|>>=|\.\.\.|<<|<%|<:|<=|>>|>=|\+\+|\+=|--|->|-=|\*=|/=|%:|%=|%>|==|&&|&=|\|\||\|=|\^=|:>|!=|##|[\(\)\{\}\[\]<>\?\|\^\*\+&=:!#;,%/\-\?\~\.]',]
34 re_clexer=re.compile('|'.join(["(?P<%s>%s)"%(name,part)for name,part in zip(tok_types,exp_types)]),re.M)
35 accepted='a'
36 ignored='i'
37 undefined='u'
38 skipped='s'
39 def repl(m):
40 s=m.group()
41 if s[0]=='/':
42 return' '
43 return s
44 prec={}
45 ops=['* / %','+ -','<< >>','< <= >= >','== !=','& | ^','&& ||',',']
46 for x,syms in enumerate(ops):
47 for u in syms.split():
48 prec[u]=x
49 def reduce_nums(val_1,val_2,val_op):
50 try:
51 a=0+val_1
52 except TypeError:
53 a=int(val_1)
54 try:
55 b=0+val_2
56 except TypeError:
57 b=int(val_2)
58 d=val_op
59 if d=='%':
60 c=a%b
61 elif d=='+':
62 c=a+b
63 elif d=='-':
64 c=a-b
65 elif d=='*':
66 c=a*b
67 elif d=='/':
68 c=a/b
69 elif d=='^':
70 c=a^b
71 elif d=='==':
72 c=int(a==b)
73 elif d=='|'or d=='bitor':
74 c=a|b
75 elif d=='||'or d=='or':
76 c=int(a or b)
77 elif d=='&'or d=='bitand':
78 c=a&b
79 elif d=='&&'or d=='and':
80 c=int(a and b)
81 elif d=='!='or d=='not_eq':
82 c=int(a!=b)
83 elif d=='^'or d=='xor':
84 c=int(a^b)
85 elif d=='<=':
86 c=int(a<=b)
87 elif d=='<':
88 c=int(a<b)
89 elif d=='>':
90 c=int(a>b)
91 elif d=='>=':
92 c=int(a>=b)
93 elif d=='<<':
94 c=a<<b
95 elif d=='>>':
96 c=a>>b
97 else:
98 c=0
99 return c
100 def get_num(lst):
101 if not lst:
102 raise PreprocError('empty list for get_num')
103 (p,v)=lst[0]
104 if p==OP:
105 if v=='(':
106 count_par=1
107 i=1
108 while i<len(lst):
109 (p,v)=lst[i]
110 if p==OP:
111 if v==')':
112 count_par-=1
113 if count_par==0:
114 break
115 elif v=='(':
116 count_par+=1
117 i+=1
118 else:
119 raise PreprocError('rparen expected %r'%lst)
120 (num,_)=get_term(lst[1:i])
121 return(num,lst[i+1:])
122 elif v=='+':
123 return get_num(lst[1:])
124 elif v=='-':
125 num,lst=get_num(lst[1:])
126 return(reduce_nums('-1',num,'*'),lst)
127 elif v=='!':
128 num,lst=get_num(lst[1:])
129 return(int(not int(num)),lst)
130 elif v=='~':
131 num,lst=get_num(lst[1:])
132 return(~int(num),lst)
133 else:
134 raise PreprocError('Invalid op token %r for get_num'%lst)
135 elif p==NUM:
136 return v,lst[1:]
137 elif p==IDENT:
138 return 0,lst[1:]
139 else:
140 raise PreprocError('Invalid token %r for get_num'%lst)
141 def get_term(lst):
142 if not lst:
143 raise PreprocError('empty list for get_term')
144 num,lst=get_num(lst)
145 if not lst:
146 return(num,[])
147 (p,v)=lst[0]
148 if p==OP:
149 if v==',':
150 return get_term(lst[1:])
151 elif v=='?':
152 count_par=0
153 i=1
154 while i<len(lst):
155 (p,v)=lst[i]
156 if p==OP:
157 if v==')':
158 count_par-=1
159 elif v=='(':
160 count_par+=1
161 elif v==':':
162 if count_par==0:
163 break
164 i+=1
165 else:
166 raise PreprocError('rparen expected %r'%lst)
167 if int(num):
168 return get_term(lst[1:i])
169 else:
170 return get_term(lst[i+1:])
171 else:
172 num2,lst=get_num(lst[1:])
173 if not lst:
174 num2=reduce_nums(num,num2,v)
175 return get_term([(NUM,num2)]+lst)
176 p2,v2=lst[0]
177 if p2!=OP:
178 raise PreprocError('op expected %r'%lst)
179 if prec[v2]>=prec[v]:
180 num2=reduce_nums(num,num2,v)
181 return get_term([(NUM,num2)]+lst)
182 else:
183 num3,lst=get_num(lst[1:])
184 num3=reduce_nums(num2,num3,v2)
185 return get_term([(NUM,num),(p,v),(NUM,num3)]+lst)
186 raise PreprocError('cannot reduce %r'%lst)
187 def reduce_eval(lst):
188 num,lst=get_term(lst)
189 return(NUM,num)
190 def stringize(lst):
191 lst=[str(v2)for(p2,v2)in lst]
192 return"".join(lst)
193 def paste_tokens(t1,t2):
194 p1=None
195 if t1[0]==OP and t2[0]==OP:
196 p1=OP
197 elif t1[0]==IDENT and(t2[0]==IDENT or t2[0]==NUM):
198 p1=IDENT
199 elif t1[0]==NUM and t2[0]==NUM:
200 p1=NUM
201 if not p1:
202 raise PreprocError('tokens do not make a valid paste %r and %r'%(t1,t2))
203 return(p1,t1[1]+t2[1])
204 def reduce_tokens(lst,defs,ban=[]):
205 i=0
206 while i<len(lst):
207 (p,v)=lst[i]
208 if p==IDENT and v=="defined":
209 del lst[i]
210 if i<len(lst):
211 (p2,v2)=lst[i]
212 if p2==IDENT:
213 if v2 in defs:
214 lst[i]=(NUM,1)
215 else:
216 lst[i]=(NUM,0)
217 elif p2==OP and v2=='(':
218 del lst[i]
219 (p2,v2)=lst[i]
220 del lst[i]
221 if v2 in defs:
222 lst[i]=(NUM,1)
223 else:
224 lst[i]=(NUM,0)
225 else:
226 raise PreprocError('Invalid define expression %r'%lst)
227 elif p==IDENT and v in defs:
228 if isinstance(defs[v],str):
229 a,b=extract_macro(defs[v])
230 defs[v]=b
231 macro_def=defs[v]
232 to_add=macro_def[1]
233 if isinstance(macro_def[0],list):
234 del lst[i]
235 accu=to_add[:]
236 reduce_tokens(accu,defs,ban+[v])
237 for tmp in accu:
238 lst.insert(i,tmp)
239 i+=1
240 else:
241 args=[]
242 del lst[i]
243 if i>=len(lst):
244 raise PreprocError('expected ( after %r (got nothing)'%v)
245 (p2,v2)=lst[i]
246 if p2!=OP or v2!='(':
247 raise PreprocError('expected ( after %r'%v)
248 del lst[i]
249 one_param=[]
250 count_paren=0
251 while i<len(lst):
252 p2,v2=lst[i]
253 del lst[i]
254 if p2==OP and count_paren==0:
255 if v2=='(':
256 one_param.append((p2,v2))
257 count_paren+=1
258 elif v2==')':
259 if one_param:
260 args.append(one_param)
261 break
262 elif v2==',':
263 if not one_param:
264 raise PreprocError('empty param in funcall %r'%v)
265 args.append(one_param)
266 one_param=[]
267 else:
268 one_param.append((p2,v2))
269 else:
270 one_param.append((p2,v2))
271 if v2=='(':
272 count_paren+=1
273 elif v2==')':
274 count_paren-=1
275 else:
276 raise PreprocError('malformed macro')
277 accu=[]
278 arg_table=macro_def[0]
279 j=0
280 while j<len(to_add):
281 (p2,v2)=to_add[j]
282 if p2==OP and v2=='#':
283 if j+1<len(to_add)and to_add[j+1][0]==IDENT and to_add[j+1][1]in arg_table:
284 toks=args[arg_table[to_add[j+1][1]]]
285 accu.append((STR,stringize(toks)))
286 j+=1
287 else:
288 accu.append((p2,v2))
289 elif p2==OP and v2=='##':
290 if accu and j+1<len(to_add):
291 t1=accu[-1]
292 if to_add[j+1][0]==IDENT and to_add[j+1][1]in arg_table:
293 toks=args[arg_table[to_add[j+1][1]]]
294 if toks:
295 accu[-1]=paste_tokens(t1,toks[0])
296 accu.extend(toks[1:])
297 else:
298 accu.append((p2,v2))
299 accu.extend(toks)
300 elif to_add[j+1][0]==IDENT and to_add[j+1][1]=='__VA_ARGS__':
301 va_toks=[]
302 st=len(macro_def[0])
303 pt=len(args)
304 for x in args[pt-st+1:]:
305 va_toks.extend(x)
306 va_toks.append((OP,','))
307 if va_toks:
308 va_toks.pop()
309 if len(accu)>1:
310 (p3,v3)=accu[-1]
311 (p4,v4)=accu[-2]
312 if v3=='##':
313 accu.pop()
314 if v4==','and pt<st:
315 accu.pop()
316 accu+=va_toks
317 else:
318 accu[-1]=paste_tokens(t1,to_add[j+1])
319 j+=1
320 else:
321 accu.append((p2,v2))
322 elif p2==IDENT and v2 in arg_table:
323 toks=args[arg_table[v2]]
324 reduce_tokens(toks,defs,ban+[v])
325 accu.extend(toks)
326 else:
327 accu.append((p2,v2))
328 j+=1
329 reduce_tokens(accu,defs,ban+[v])
330 for x in range(len(accu)-1,-1,-1):
331 lst.insert(i,accu[x])
332 i+=1
333 def eval_macro(lst,defs):
334 reduce_tokens(lst,defs,[])
335 if not lst:
336 raise PreprocError('missing tokens to evaluate')
337 if lst:
338 p,v=lst[0]
339 if p==IDENT and v not in defs:
340 raise PreprocError('missing macro %r'%lst)
341 p,v=reduce_eval(lst)
342 return int(v)!=0
343 def extract_macro(txt):
344 t=tokenize(txt)
345 if re_fun.search(txt):
346 p,name=t[0]
347 p,v=t[1]
348 if p!=OP:
349 raise PreprocError('expected (')
350 i=1
351 pindex=0
352 params={}
353 prev='('
354 while 1:
355 i+=1
356 p,v=t[i]
357 if prev=='(':
358 if p==IDENT:
359 params[v]=pindex
360 pindex+=1
361 prev=p
362 elif p==OP and v==')':
363 break
364 else:
365 raise PreprocError('unexpected token (3)')
366 elif prev==IDENT:
367 if p==OP and v==',':
368 prev=v
369 elif p==OP and v==')':
370 break
371 else:
372 raise PreprocError('comma or ... expected')
373 elif prev==',':
374 if p==IDENT:
375 params[v]=pindex
376 pindex+=1
377 prev=p
378 elif p==OP and v=='...':
379 raise PreprocError('not implemented (1)')
380 else:
381 raise PreprocError('comma or ... expected (2)')
382 elif prev=='...':
383 raise PreprocError('not implemented (2)')
384 else:
385 raise PreprocError('unexpected else')
386 return(name,[params,t[i+1:]])
387 else:
388 (p,v)=t[0]
389 if len(t)>1:
390 return(v,[[],t[1:]])
391 else:
392 return(v,[[],[('T','')]])
393 re_include=re.compile(r'^\s*(<(?:.*)>|"(?:.*)")')
394 def extract_include(txt,defs):
395 m=re_include.search(txt)
396 if m:
397 txt=m.group(1)
398 return txt[0],txt[1:-1]
399 toks=tokenize(txt)
400 reduce_tokens(toks,defs,['waf_include'])
401 if not toks:
402 raise PreprocError('could not parse include %r'%txt)
403 if len(toks)==1:
404 if toks[0][0]==STR:
405 return'"',toks[0][1]
406 else:
407 if toks[0][1]=='<'and toks[-1][1]=='>':
408 ret='<',stringize(toks).lstrip('<').rstrip('>')
409 return ret
410 raise PreprocError('could not parse include %r'%txt)
411 def parse_char(txt):
412 if not txt:
413 raise PreprocError('attempted to parse a null char')
414 if txt[0]!='\\':
415 return ord(txt)
416 c=txt[1]
417 if c=='x':
418 if len(txt)==4 and txt[3]in string.hexdigits:
419 return int(txt[2:],16)
420 return int(txt[2:],16)
421 elif c.isdigit():
422 if c=='0'and len(txt)==2:
423 return 0
424 for i in 3,2,1:
425 if len(txt)>i and txt[1:1+i].isdigit():
426 return(1+i,int(txt[1:1+i],8))
427 else:
428 try:
429 return chr_esc[c]
430 except KeyError:
431 raise PreprocError('could not parse char literal %r'%txt)
432 def tokenize(s):
433 return tokenize_private(s)[:]
434 def tokenize_private(s):
435 ret=[]
436 for match in re_clexer.finditer(s):
437 m=match.group
438 for name in tok_types:
439 v=m(name)
440 if v:
441 if name==IDENT:
442 if v in g_optrans:
443 name=OP
444 elif v.lower()=="true":
445 v=1
446 name=NUM
447 elif v.lower()=="false":
448 v=0
449 name=NUM
450 elif name==NUM:
451 if m('oct'):
452 v=int(v,8)
453 elif m('hex'):
454 v=int(m('hex'),16)
455 elif m('n0'):
456 v=m('n0')
457 else:
458 v=m('char')
459 if v:
460 v=parse_char(v)
461 else:
462 v=m('n2')or m('n4')
463 elif name==OP:
464 if v=='%:':
465 v='#'
466 elif v=='%:%:':
467 v='##'
468 elif name==STR:
469 v=v[1:-1]
470 ret.append((name,v))
471 break
472 return ret
473 def format_defines(lst):
474 ret=[]
475 for y in lst:
476 if y:
477 pos=y.find('=')
478 if pos==-1:
479 ret.append(y)
480 elif pos>0:
481 ret.append('%s %s'%(y[:pos],y[pos+1:]))
482 else:
483 raise ValueError('Invalid define expression %r'%y)
484 return ret
485 class c_parser(object):
486 def __init__(self,nodepaths=None,defines=None):
487 self.lines=[]
488 if defines is None:
489 self.defs={}
490 else:
491 self.defs=dict(defines)
492 self.state=[]
493 self.count_files=0
494 self.currentnode_stack=[]
495 self.nodepaths=nodepaths or[]
496 self.nodes=[]
497 self.names=[]
498 self.curfile=''
499 self.ban_includes=set()
500 self.listed=set()
501 def cached_find_resource(self,node,filename):
502 try:
503 cache=node.ctx.preproc_cache_node
504 except AttributeError:
505 cache=node.ctx.preproc_cache_node=Utils.lru_cache(FILE_CACHE_SIZE)
506 key=(node,filename)
507 try:
508 return cache[key]
509 except KeyError:
510 ret=node.find_resource(filename)
511 if ret:
512 if getattr(ret,'children',None):
513 ret=None
514 elif ret.is_child_of(node.ctx.bldnode):
515 tmp=node.ctx.srcnode.search_node(ret.path_from(node.ctx.bldnode))
516 if tmp and getattr(tmp,'children',None):
517 ret=None
518 cache[key]=ret
519 return ret
520 def tryfind(self,filename,kind='"',env=None):
521 if filename.endswith('.moc'):
522 self.names.append(filename)
523 return None
524 self.curfile=filename
525 found=None
526 if kind=='"':
527 if env.MSVC_VERSION:
528 for n in reversed(self.currentnode_stack):
529 found=self.cached_find_resource(n,filename)
530 if found:
531 break
532 else:
533 found=self.cached_find_resource(self.currentnode_stack[-1],filename)
534 if not found:
535 for n in self.nodepaths:
536 found=self.cached_find_resource(n,filename)
537 if found:
538 break
539 listed=self.listed
540 if found and not found in self.ban_includes:
541 if found not in listed:
542 listed.add(found)
543 self.nodes.append(found)
544 self.addlines(found)
545 else:
546 if filename not in listed:
547 listed.add(filename)
548 self.names.append(filename)
549 return found
550 def filter_comments(self,node):
551 code=node.read()
552 if use_trigraphs:
553 for(a,b)in trig_def:
554 code=code.split(a).join(b)
555 code=re_nl.sub('',code)
556 code=re_cpp.sub(repl,code)
557 return re_lines.findall(code)
558 def parse_lines(self,node):
559 try:
560 cache=node.ctx.preproc_cache_lines
561 except AttributeError:
562 cache=node.ctx.preproc_cache_lines=Utils.lru_cache(LINE_CACHE_SIZE)
563 try:
564 return cache[node]
565 except KeyError:
566 cache[node]=lines=self.filter_comments(node)
567 lines.append((POPFILE,''))
568 lines.reverse()
569 return lines
570 def addlines(self,node):
571 self.currentnode_stack.append(node.parent)
572 self.count_files+=1
573 if self.count_files>recursion_limit:
574 raise PreprocError('recursion limit exceeded')
575 if Logs.verbose:
576 Logs.debug('preproc: reading file %r',node)
577 try:
578 lines=self.parse_lines(node)
579 except EnvironmentError:
580 raise PreprocError('could not read the file %r'%node)
581 except Exception:
582 if Logs.verbose>0:
583 Logs.error('parsing %r failed %s',node,traceback.format_exc())
584 else:
585 self.lines.extend(lines)
586 def start(self,node,env):
587 Logs.debug('preproc: scanning %s (in %s)',node.name,node.parent.name)
588 self.current_file=node
589 self.addlines(node)
590 if env.DEFINES:
591 lst=format_defines(env.DEFINES)
592 lst.reverse()
593 self.lines.extend([('define',x)for x in lst])
594 while self.lines:
595 (token,line)=self.lines.pop()
596 if token==POPFILE:
597 self.count_files-=1
598 self.currentnode_stack.pop()
599 continue
600 try:
601 state=self.state
602 if token[:2]=='if':
603 state.append(undefined)
604 elif token=='endif':
605 state.pop()
606 if token[0]!='e':
607 if skipped in self.state or ignored in self.state:
608 continue
609 if token=='if':
610 ret=eval_macro(tokenize(line),self.defs)
611 if ret:
612 state[-1]=accepted
613 else:
614 state[-1]=ignored
615 elif token=='ifdef':
616 m=re_mac.match(line)
617 if m and m.group()in self.defs:
618 state[-1]=accepted
619 else:
620 state[-1]=ignored
621 elif token=='ifndef':
622 m=re_mac.match(line)
623 if m and m.group()in self.defs:
624 state[-1]=ignored
625 else:
626 state[-1]=accepted
627 elif token=='include'or token=='import':
628 (kind,inc)=extract_include(line,self.defs)
629 self.current_file=self.tryfind(inc,kind,env)
630 if token=='import':
631 self.ban_includes.add(self.current_file)
632 elif token=='elif':
633 if state[-1]==accepted:
634 state[-1]=skipped
635 elif state[-1]==ignored:
636 if eval_macro(tokenize(line),self.defs):
637 state[-1]=accepted
638 elif token=='else':
639 if state[-1]==accepted:
640 state[-1]=skipped
641 elif state[-1]==ignored:
642 state[-1]=accepted
643 elif token=='define':
644 try:
645 self.defs[self.define_name(line)]=line
646 except AttributeError:
647 raise PreprocError('Invalid define line %r'%line)
648 elif token=='undef':
649 m=re_mac.match(line)
650 if m and m.group()in self.defs:
651 self.defs.__delitem__(m.group())
652 elif token=='pragma':
653 if re_pragma_once.match(line.lower()):
654 self.ban_includes.add(self.current_file)
655 except Exception as e:
656 if Logs.verbose:
657 Logs.debug('preproc: line parsing failed (%s): %s %s',e,line,traceback.format_exc())
658 def define_name(self,line):
659 return re_mac.match(line).group()
660 def scan(task):
661 try:
662 incn=task.generator.includes_nodes
663 except AttributeError:
664 raise Errors.WafError('%r is missing a feature such as "c", "cxx" or "includes": '%task.generator)
665 if go_absolute:
666 nodepaths=incn+[task.generator.bld.root.find_dir(x)for x in standard_includes]
667 else:
668 nodepaths=[x for x in incn if x.is_child_of(x.ctx.srcnode)or x.is_child_of(x.ctx.bldnode)]
669 tmp=c_parser(nodepaths)
670 tmp.start(task.inputs[0],task.env)
671 return(tmp.nodes,tmp.names)
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib import Task
5 from waflib.Configure import conf
6 from waflib.TaskGen import feature,before_method,after_method
7 LIB_CODE='''
8 #ifdef _MSC_VER
9 #define testEXPORT __declspec(dllexport)
10 #else
11 #define testEXPORT
12 #endif
13 testEXPORT int lib_func(void) { return 9; }
14 '''
15 MAIN_CODE='''
16 #ifdef _MSC_VER
17 #define testEXPORT __declspec(dllimport)
18 #else
19 #define testEXPORT
20 #endif
21 testEXPORT int lib_func(void);
22 int main(int argc, char **argv) {
23 (void)argc; (void)argv;
24 return !(lib_func() == 9);
25 }
26 '''
27 @feature('link_lib_test')
28 @before_method('process_source')
29 def link_lib_test_fun(self):
30 def write_test_file(task):
31 task.outputs[0].write(task.generator.code)
32 rpath=[]
33 if getattr(self,'add_rpath',False):
34 rpath=[self.bld.path.get_bld().abspath()]
35 mode=self.mode
36 m='%s %s'%(mode,mode)
37 ex=self.test_exec and'test_exec'or''
38 bld=self.bld
39 bld(rule=write_test_file,target='test.'+mode,code=LIB_CODE)
40 bld(rule=write_test_file,target='main.'+mode,code=MAIN_CODE)
41 bld(features='%sshlib'%m,source='test.'+mode,target='test')
42 bld(features='%sprogram %s'%(m,ex),source='main.'+mode,target='app',use='test',rpath=rpath)
43 @conf
44 def check_library(self,mode=None,test_exec=True):
45 if not mode:
46 mode='c'
47 if self.env.CXX:
48 mode='cxx'
49 self.check(compile_filename=[],features='link_lib_test',msg='Checking for libraries',mode=mode,test_exec=test_exec)
50 INLINE_CODE='''
51 typedef int foo_t;
52 static %s foo_t static_foo () {return 0; }
53 %s foo_t foo () {
54 return 0;
55 }
56 '''
57 INLINE_VALUES=['inline','__inline__','__inline']
58 @conf
59 def check_inline(self,**kw):
60 self.start_msg('Checking for inline')
61 if not'define_name'in kw:
62 kw['define_name']='INLINE_MACRO'
63 if not'features'in kw:
64 if self.env.CXX:
65 kw['features']=['cxx']
66 else:
67 kw['features']=['c']
68 for x in INLINE_VALUES:
69 kw['fragment']=INLINE_CODE%(x,x)
70 try:
71 self.check(**kw)
72 except self.errors.ConfigurationError:
73 continue
74 else:
75 self.end_msg(x)
76 if x!='inline':
77 self.define('inline',x,quote=False)
78 return x
79 self.fatal('could not use inline functions')
80 LARGE_FRAGMENT='''#include <unistd.h>
81 int main(int argc, char **argv) {
82 (void)argc; (void)argv;
83 return !(sizeof(off_t) >= 8);
84 }
85 '''
86 @conf
87 def check_large_file(self,**kw):
88 if not'define_name'in kw:
89 kw['define_name']='HAVE_LARGEFILE'
90 if not'execute'in kw:
91 kw['execute']=True
92 if not'features'in kw:
93 if self.env.CXX:
94 kw['features']=['cxx','cxxprogram']
95 else:
96 kw['features']=['c','cprogram']
97 kw['fragment']=LARGE_FRAGMENT
98 kw['msg']='Checking for large file support'
99 ret=True
100 try:
101 if self.env.DEST_BINFMT!='pe':
102 ret=self.check(**kw)
103 except self.errors.ConfigurationError:
104 pass
105 else:
106 if ret:
107 return True
108 kw['msg']='Checking for -D_FILE_OFFSET_BITS=64'
109 kw['defines']=['_FILE_OFFSET_BITS=64']
110 try:
111 ret=self.check(**kw)
112 except self.errors.ConfigurationError:
113 pass
114 else:
115 self.define('_FILE_OFFSET_BITS',64)
116 return ret
117 self.fatal('There is no support for large files')
118 ENDIAN_FRAGMENT='''
119 #ifdef _MSC_VER
120 #define testshlib_EXPORT __declspec(dllexport)
121 #else
122 #define testshlib_EXPORT
123 #endif
124
125 short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
126 short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
127 int testshlib_EXPORT use_ascii (int i) {
128 return ascii_mm[i] + ascii_ii[i];
129 }
130 short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
131 short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
132 int use_ebcdic (int i) {
133 return ebcdic_mm[i] + ebcdic_ii[i];
134 }
135 extern int foo;
136 '''
137 class grep_for_endianness(Task.Task):
138 color='PINK'
139 def run(self):
140 txt=self.inputs[0].read(flags='rb').decode('latin-1')
141 if txt.find('LiTTleEnDian')>-1:
142 self.generator.tmp.append('little')
143 elif txt.find('BIGenDianSyS')>-1:
144 self.generator.tmp.append('big')
145 else:
146 return-1
147 @feature('grep_for_endianness')
148 @after_method('apply_link')
149 def grep_for_endianness_fun(self):
150 self.create_task('grep_for_endianness',self.link_task.outputs[0])
151 @conf
152 def check_endianness(self):
153 tmp=[]
154 def check_msg(self):
155 return tmp[0]
156 self.check(fragment=ENDIAN_FRAGMENT,features='c cshlib grep_for_endianness',msg='Checking for endianness',define='ENDIANNESS',tmp=tmp,okmsg=check_msg,confcache=None)
157 return tmp[0]
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os,re
5 from waflib import Task,Utils,Node,Errors,Logs
6 from waflib.TaskGen import after_method,before_method,feature,taskgen_method,extension
7 from waflib.Tools import c_aliases,c_preproc,c_config,c_osx,c_tests
8 from waflib.Configure import conf
9 SYSTEM_LIB_PATHS=['/usr/lib64','/usr/lib','/usr/local/lib64','/usr/local/lib']
10 USELIB_VARS=Utils.defaultdict(set)
11 USELIB_VARS['c']=set(['INCLUDES','FRAMEWORKPATH','DEFINES','CPPFLAGS','CCDEPS','CFLAGS','ARCH'])
12 USELIB_VARS['cxx']=set(['INCLUDES','FRAMEWORKPATH','DEFINES','CPPFLAGS','CXXDEPS','CXXFLAGS','ARCH'])
13 USELIB_VARS['d']=set(['INCLUDES','DFLAGS'])
14 USELIB_VARS['includes']=set(['INCLUDES','FRAMEWORKPATH','ARCH'])
15 USELIB_VARS['cprogram']=USELIB_VARS['cxxprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','FRAMEWORK','FRAMEWORKPATH','ARCH','LDFLAGS'])
16 USELIB_VARS['cshlib']=USELIB_VARS['cxxshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','FRAMEWORK','FRAMEWORKPATH','ARCH','LDFLAGS'])
17 USELIB_VARS['cstlib']=USELIB_VARS['cxxstlib']=set(['ARFLAGS','LINKDEPS'])
18 USELIB_VARS['dprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
19 USELIB_VARS['dshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
20 USELIB_VARS['dstlib']=set(['ARFLAGS','LINKDEPS'])
21 USELIB_VARS['asm']=set(['ASFLAGS'])
22 @taskgen_method
23 def create_compiled_task(self,name,node):
24 out='%s.%d.o'%(node.name,self.idx)
25 task=self.create_task(name,node,node.parent.find_or_declare(out))
26 try:
27 self.compiled_tasks.append(task)
28 except AttributeError:
29 self.compiled_tasks=[task]
30 return task
31 @taskgen_method
32 def to_incnodes(self,inlst):
33 lst=[]
34 seen=set()
35 for x in self.to_list(inlst):
36 if x in seen or not x:
37 continue
38 seen.add(x)
39 if isinstance(x,Node.Node):
40 lst.append(x)
41 else:
42 if os.path.isabs(x):
43 lst.append(self.bld.root.make_node(x)or x)
44 else:
45 if x[0]=='#':
46 p=self.bld.bldnode.make_node(x[1:])
47 v=self.bld.srcnode.make_node(x[1:])
48 else:
49 p=self.path.get_bld().make_node(x)
50 v=self.path.make_node(x)
51 if p.is_child_of(self.bld.bldnode):
52 p.mkdir()
53 lst.append(p)
54 lst.append(v)
55 return lst
56 @feature('c','cxx','d','asm','fc','includes')
57 @after_method('propagate_uselib_vars','process_source')
58 def apply_incpaths(self):
59 lst=self.to_incnodes(self.to_list(getattr(self,'includes',[]))+self.env.INCLUDES)
60 self.includes_nodes=lst
61 cwd=self.get_cwd()
62 self.env.INCPATHS=[x.path_from(cwd)for x in lst]
63 class link_task(Task.Task):
64 color='YELLOW'
65 weight=3
66 inst_to=None
67 chmod=Utils.O755
68 def add_target(self,target):
69 if isinstance(target,str):
70 base=self.generator.path
71 if target.startswith('#'):
72 target=target[1:]
73 base=self.generator.bld.bldnode
74 pattern=self.env[self.__class__.__name__+'_PATTERN']
75 if not pattern:
76 pattern='%s'
77 folder,name=os.path.split(target)
78 if self.__class__.__name__.find('shlib')>0 and getattr(self.generator,'vnum',None):
79 nums=self.generator.vnum.split('.')
80 if self.env.DEST_BINFMT=='pe':
81 name=name+'-'+nums[0]
82 elif self.env.DEST_OS=='openbsd':
83 pattern='%s.%s'%(pattern,nums[0])
84 if len(nums)>=2:
85 pattern+='.%s'%nums[1]
86 if folder:
87 tmp=folder+os.sep+pattern%name
88 else:
89 tmp=pattern%name
90 target=base.find_or_declare(tmp)
91 self.set_outputs(target)
92 def exec_command(self,*k,**kw):
93 ret=super(link_task,self).exec_command(*k,**kw)
94 if not ret and self.env.DO_MANIFEST:
95 ret=self.exec_mf()
96 return ret
97 def exec_mf(self):
98 if not self.env.MT:
99 return 0
100 manifest=None
101 for out_node in self.outputs:
102 if out_node.name.endswith('.manifest'):
103 manifest=out_node.abspath()
104 break
105 else:
106 return 0
107 mode=''
108 for x in Utils.to_list(self.generator.features):
109 if x in('cprogram','cxxprogram','fcprogram','fcprogram_test'):
110 mode=1
111 elif x in('cshlib','cxxshlib','fcshlib'):
112 mode=2
113 Logs.debug('msvc: embedding manifest in mode %r',mode)
114 lst=[]+self.env.MT
115 lst.extend(Utils.to_list(self.env.MTFLAGS))
116 lst.extend(['-manifest',manifest])
117 lst.append('-outputresource:%s;%s'%(self.outputs[0].abspath(),mode))
118 return super(link_task,self).exec_command(lst)
119 class stlink_task(link_task):
120 run_str='${AR} ${ARFLAGS} ${AR_TGT_F}${TGT} ${AR_SRC_F}${SRC}'
121 chmod=Utils.O644
122 def rm_tgt(cls):
123 old=cls.run
124 def wrap(self):
125 try:
126 os.remove(self.outputs[0].abspath())
127 except OSError:
128 pass
129 return old(self)
130 setattr(cls,'run',wrap)
131 rm_tgt(stlink_task)
132 @feature('skip_stlib_link_deps')
133 @before_method('process_use')
134 def apply_skip_stlib_link_deps(self):
135 self.env.SKIP_STLIB_LINK_DEPS=True
136 @feature('c','cxx','d','fc','asm')
137 @after_method('process_source')
138 def apply_link(self):
139 for x in self.features:
140 if x=='cprogram'and'cxx'in self.features:
141 x='cxxprogram'
142 elif x=='cshlib'and'cxx'in self.features:
143 x='cxxshlib'
144 if x in Task.classes:
145 if issubclass(Task.classes[x],link_task):
146 link=x
147 break
148 else:
149 return
150 objs=[t.outputs[0]for t in getattr(self,'compiled_tasks',[])]
151 self.link_task=self.create_task(link,objs)
152 self.link_task.add_target(self.target)
153 try:
154 inst_to=self.install_path
155 except AttributeError:
156 inst_to=self.link_task.inst_to
157 if inst_to:
158 self.install_task=self.add_install_files(install_to=inst_to,install_from=self.link_task.outputs[:],chmod=self.link_task.chmod,task=self.link_task)
159 @taskgen_method
160 def use_rec(self,name,**kw):
161 if name in self.tmp_use_not or name in self.tmp_use_seen:
162 return
163 try:
164 y=self.bld.get_tgen_by_name(name)
165 except Errors.WafError:
166 self.uselib.append(name)
167 self.tmp_use_not.add(name)
168 return
169 self.tmp_use_seen.append(name)
170 y.post()
171 y.tmp_use_objects=objects=kw.get('objects',True)
172 y.tmp_use_stlib=stlib=kw.get('stlib',True)
173 try:
174 link_task=y.link_task
175 except AttributeError:
176 y.tmp_use_var=''
177 else:
178 objects=False
179 if not isinstance(link_task,stlink_task):
180 stlib=False
181 y.tmp_use_var='LIB'
182 else:
183 y.tmp_use_var='STLIB'
184 p=self.tmp_use_prec
185 for x in self.to_list(getattr(y,'use',[])):
186 if self.env["STLIB_"+x]:
187 continue
188 try:
189 p[x].append(name)
190 except KeyError:
191 p[x]=[name]
192 self.use_rec(x,objects=objects,stlib=stlib)
193 @feature('c','cxx','d','use','fc')
194 @before_method('apply_incpaths','propagate_uselib_vars')
195 @after_method('apply_link','process_source')
196 def process_use(self):
197 use_not=self.tmp_use_not=set()
198 self.tmp_use_seen=[]
199 use_prec=self.tmp_use_prec={}
200 self.uselib=self.to_list(getattr(self,'uselib',[]))
201 self.includes=self.to_list(getattr(self,'includes',[]))
202 names=self.to_list(getattr(self,'use',[]))
203 for x in names:
204 self.use_rec(x)
205 for x in use_not:
206 if x in use_prec:
207 del use_prec[x]
208 out=self.tmp_use_sorted=[]
209 tmp=[]
210 for x in self.tmp_use_seen:
211 for k in use_prec.values():
212 if x in k:
213 break
214 else:
215 tmp.append(x)
216 while tmp:
217 e=tmp.pop()
218 out.append(e)
219 try:
220 nlst=use_prec[e]
221 except KeyError:
222 pass
223 else:
224 del use_prec[e]
225 for x in nlst:
226 for y in use_prec:
227 if x in use_prec[y]:
228 break
229 else:
230 tmp.append(x)
231 if use_prec:
232 raise Errors.WafError('Cycle detected in the use processing %r'%use_prec)
233 out.reverse()
234 link_task=getattr(self,'link_task',None)
235 for x in out:
236 y=self.bld.get_tgen_by_name(x)
237 var=y.tmp_use_var
238 if var and link_task:
239 if self.env.SKIP_STLIB_LINK_DEPS and isinstance(link_task,stlink_task):
240 pass
241 elif var=='LIB'or y.tmp_use_stlib or x in names:
242 self.env.append_value(var,[y.target[y.target.rfind(os.sep)+1:]])
243 self.link_task.dep_nodes.extend(y.link_task.outputs)
244 tmp_path=y.link_task.outputs[0].parent.path_from(self.get_cwd())
245 self.env.append_unique(var+'PATH',[tmp_path])
246 else:
247 if y.tmp_use_objects:
248 self.add_objects_from_tgen(y)
249 if getattr(y,'export_includes',None):
250 self.includes=self.includes+y.to_incnodes(y.export_includes)
251 if getattr(y,'export_defines',None):
252 self.env.append_value('DEFINES',self.to_list(y.export_defines))
253 for x in names:
254 try:
255 y=self.bld.get_tgen_by_name(x)
256 except Errors.WafError:
257 if not self.env['STLIB_'+x]and not x in self.uselib:
258 self.uselib.append(x)
259 else:
260 for k in self.to_list(getattr(y,'use',[])):
261 if not self.env['STLIB_'+k]and not k in self.uselib:
262 self.uselib.append(k)
263 @taskgen_method
264 def accept_node_to_link(self,node):
265 return not node.name.endswith('.pdb')
266 @taskgen_method
267 def add_objects_from_tgen(self,tg):
268 try:
269 link_task=self.link_task
270 except AttributeError:
271 pass
272 else:
273 for tsk in getattr(tg,'compiled_tasks',[]):
274 for x in tsk.outputs:
275 if self.accept_node_to_link(x):
276 link_task.inputs.append(x)
277 @taskgen_method
278 def get_uselib_vars(self):
279 _vars=set()
280 for x in self.features:
281 if x in USELIB_VARS:
282 _vars|=USELIB_VARS[x]
283 return _vars
284 @feature('c','cxx','d','fc','javac','cs','uselib','asm')
285 @after_method('process_use')
286 def propagate_uselib_vars(self):
287 _vars=self.get_uselib_vars()
288 env=self.env
289 app=env.append_value
290 feature_uselib=self.features+self.to_list(getattr(self,'uselib',[]))
291 for var in _vars:
292 y=var.lower()
293 val=getattr(self,y,[])
294 if val:
295 app(var,self.to_list(val))
296 for x in feature_uselib:
297 val=env['%s_%s'%(var,x)]
298 if val:
299 app(var,val)
300 @feature('cshlib','cxxshlib','fcshlib')
301 @after_method('apply_link')
302 def apply_implib(self):
303 if not self.env.DEST_BINFMT=='pe':
304 return
305 dll=self.link_task.outputs[0]
306 if isinstance(self.target,Node.Node):
307 name=self.target.name
308 else:
309 name=os.path.split(self.target)[1]
310 implib=self.env.implib_PATTERN%name
311 implib=dll.parent.find_or_declare(implib)
312 self.env.append_value('LINKFLAGS',self.env.IMPLIB_ST%implib.bldpath())
313 self.link_task.outputs.append(implib)
314 if getattr(self,'defs',None)and self.env.DEST_BINFMT=='pe':
315 node=self.path.find_resource(self.defs)
316 if not node:
317 raise Errors.WafError('invalid def file %r'%self.defs)
318 if self.env.def_PATTERN:
319 self.env.append_value('LINKFLAGS',self.env.def_PATTERN%node.path_from(self.get_cwd()))
320 self.link_task.dep_nodes.append(node)
321 else:
322 self.link_task.inputs.append(node)
323 if getattr(self,'install_task',None):
324 try:
325 inst_to=self.install_path_implib
326 except AttributeError:
327 try:
328 inst_to=self.install_path
329 except AttributeError:
330 inst_to='${IMPLIBDIR}'
331 self.install_task.install_to='${BINDIR}'
332 if not self.env.IMPLIBDIR:
333 self.env.IMPLIBDIR=self.env.LIBDIR
334 self.implib_install_task=self.add_install_files(install_to=inst_to,install_from=implib,chmod=self.link_task.chmod,task=self.link_task)
335 re_vnum=re.compile('^([1-9]\\d*|0)([.]([1-9]\\d*|0)){0,2}?$')
336 @feature('cshlib','cxxshlib','dshlib','fcshlib','vnum')
337 @after_method('apply_link','propagate_uselib_vars')
338 def apply_vnum(self):
339 if not getattr(self,'vnum','')or os.name!='posix'or self.env.DEST_BINFMT not in('elf','mac-o'):
340 return
341 link=self.link_task
342 if not re_vnum.match(self.vnum):
343 raise Errors.WafError('Invalid vnum %r for target %r'%(self.vnum,getattr(self,'name',self)))
344 nums=self.vnum.split('.')
345 node=link.outputs[0]
346 cnum=getattr(self,'cnum',str(nums[0]))
347 cnums=cnum.split('.')
348 if len(cnums)>len(nums)or nums[0:len(cnums)]!=cnums:
349 raise Errors.WafError('invalid compatibility version %s'%cnum)
350 libname=node.name
351 if libname.endswith('.dylib'):
352 name3=libname.replace('.dylib','.%s.dylib'%self.vnum)
353 name2=libname.replace('.dylib','.%s.dylib'%cnum)
354 else:
355 name3=libname+'.'+self.vnum
356 name2=libname+'.'+cnum
357 if self.env.SONAME_ST:
358 v=self.env.SONAME_ST%name2
359 self.env.append_value('LINKFLAGS',v.split())
360 if self.env.DEST_OS!='openbsd':
361 outs=[node.parent.make_node(name3)]
362 if name2!=name3:
363 outs.append(node.parent.make_node(name2))
364 self.create_task('vnum',node,outs)
365 if getattr(self,'install_task',None):
366 self.install_task.hasrun=Task.SKIPPED
367 self.install_task.no_errcheck_out=True
368 path=self.install_task.install_to
369 if self.env.DEST_OS=='openbsd':
370 libname=self.link_task.outputs[0].name
371 t1=self.add_install_as(install_to='%s/%s'%(path,libname),install_from=node,chmod=self.link_task.chmod)
372 self.vnum_install_task=(t1,)
373 else:
374 t1=self.add_install_as(install_to=path+os.sep+name3,install_from=node,chmod=self.link_task.chmod)
375 t3=self.add_symlink_as(install_to=path+os.sep+libname,install_from=name3)
376 if name2!=name3:
377 t2=self.add_symlink_as(install_to=path+os.sep+name2,install_from=name3)
378 self.vnum_install_task=(t1,t2,t3)
379 else:
380 self.vnum_install_task=(t1,t3)
381 if'-dynamiclib'in self.env.LINKFLAGS:
382 try:
383 inst_to=self.install_path
384 except AttributeError:
385 inst_to=self.link_task.inst_to
386 if inst_to:
387 p=Utils.subst_vars(inst_to,self.env)
388 path=os.path.join(p,name2)
389 self.env.append_value('LINKFLAGS',['-install_name',path])
390 self.env.append_value('LINKFLAGS','-Wl,-compatibility_version,%s'%cnum)
391 self.env.append_value('LINKFLAGS','-Wl,-current_version,%s'%self.vnum)
392 class vnum(Task.Task):
393 color='CYAN'
394 ext_in=['.bin']
395 def keyword(self):
396 return'Symlinking'
397 def run(self):
398 for x in self.outputs:
399 path=x.abspath()
400 try:
401 os.remove(path)
402 except OSError:
403 pass
404 try:
405 os.symlink(self.inputs[0].name,path)
406 except OSError:
407 return 1
408 class fake_shlib(link_task):
409 def runnable_status(self):
410 for t in self.run_after:
411 if not t.hasrun:
412 return Task.ASK_LATER
413 return Task.SKIP_ME
414 class fake_stlib(stlink_task):
415 def runnable_status(self):
416 for t in self.run_after:
417 if not t.hasrun:
418 return Task.ASK_LATER
419 return Task.SKIP_ME
420 @conf
421 def read_shlib(self,name,paths=[],export_includes=[],export_defines=[]):
422 return self(name=name,features='fake_lib',lib_paths=paths,lib_type='shlib',export_includes=export_includes,export_defines=export_defines)
423 @conf
424 def read_stlib(self,name,paths=[],export_includes=[],export_defines=[]):
425 return self(name=name,features='fake_lib',lib_paths=paths,lib_type='stlib',export_includes=export_includes,export_defines=export_defines)
426 lib_patterns={'shlib':['lib%s.so','%s.so','lib%s.dylib','lib%s.dll','%s.dll'],'stlib':['lib%s.a','%s.a','lib%s.dll','%s.dll','lib%s.lib','%s.lib'],}
427 @feature('fake_lib')
428 def process_lib(self):
429 node=None
430 names=[x%self.name for x in lib_patterns[self.lib_type]]
431 for x in self.lib_paths+[self.path]+SYSTEM_LIB_PATHS:
432 if not isinstance(x,Node.Node):
433 x=self.bld.root.find_node(x)or self.path.find_node(x)
434 if not x:
435 continue
436 for y in names:
437 node=x.find_node(y)
438 if node:
439 try:
440 Utils.h_file(node.abspath())
441 except EnvironmentError:
442 raise ValueError('Could not read %r'%y)
443 break
444 else:
445 continue
446 break
447 else:
448 raise Errors.WafError('could not find library %r'%self.name)
449 self.link_task=self.create_task('fake_%s'%self.lib_type,[],[node])
450 self.target=self.name
451 class fake_o(Task.Task):
452 def runnable_status(self):
453 return Task.SKIP_ME
454 @extension('.o','.obj')
455 def add_those_o_files(self,node):
456 tsk=self.create_task('fake_o',[],node)
457 try:
458 self.compiled_tasks.append(tsk)
459 except AttributeError:
460 self.compiled_tasks=[tsk]
461 @feature('fake_obj')
462 @before_method('process_source')
463 def process_objs(self):
464 for node in self.to_nodes(self.source):
465 self.add_those_o_files(node)
466 self.source=[]
467 @conf
468 def read_object(self,obj):
469 if not isinstance(obj,self.path.__class__):
470 obj=self.path.find_resource(obj)
471 return self(features='fake_obj',source=obj,name=obj.name)
472 @feature('cxxprogram','cprogram')
473 @after_method('apply_link','process_use')
474 def set_full_paths_hpux(self):
475 if self.env.DEST_OS!='hp-ux':
476 return
477 base=self.bld.bldnode.abspath()
478 for var in['LIBPATH','STLIBPATH']:
479 lst=[]
480 for x in self.env[var]:
481 if x.startswith('/'):
482 lst.append(x)
483 else:
484 lst.append(os.path.normpath(os.path.join(base,x)))
485 self.env[var]=lst
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib.Tools import ccroot,ar,gcc
5 from waflib.Configure import conf
6 @conf
7 def find_clang(conf):
8 cc=conf.find_program('clang',var='CC')
9 conf.get_cc_version(cc,clang=True)
10 conf.env.CC_NAME='clang'
11 def configure(conf):
12 conf.find_clang()
13 conf.find_program(['llvm-ar','ar'],var='AR')
14 conf.find_ar()
15 conf.gcc_common_flags()
16 conf.gcc_modifier_platform()
17 conf.cc_load_tools()
18 conf.cc_add_flags()
19 conf.link_add_flags()
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib.Tools import ccroot,ar,gxx
5 from waflib.Configure import conf
6 @conf
7 def find_clangxx(conf):
8 cxx=conf.find_program('clang++',var='CXX')
9 conf.get_cc_version(cxx,clang=True)
10 conf.env.CXX_NAME='clang'
11 def configure(conf):
12 conf.find_clangxx()
13 conf.find_program(['llvm-ar','ar'],var='AR')
14 conf.find_ar()
15 conf.gxx_common_flags()
16 conf.gxx_modifier_platform()
17 conf.cxx_load_tools()
18 conf.cxx_add_flags()
19 conf.link_add_flags()
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import re
5 from waflib.Tools import ccroot
6 from waflib import Utils
7 from waflib.Logs import debug
8 c_compiler={'win32':['msvc','gcc','clang'],'cygwin':['gcc'],'darwin':['clang','gcc'],'aix':['xlc','gcc','clang'],'linux':['gcc','clang','icc'],'sunos':['suncc','gcc'],'irix':['gcc','irixcc'],'hpux':['gcc'],'osf1V':['gcc'],'gnu':['gcc','clang'],'java':['gcc','msvc','clang','icc'],'default':['clang','gcc'],}
9 def default_compilers():
10 build_platform=Utils.unversioned_sys_platform()
11 possible_compiler_list=c_compiler.get(build_platform,c_compiler['default'])
12 return' '.join(possible_compiler_list)
13 def configure(conf):
14 try:
15 test_for_compiler=conf.options.check_c_compiler or default_compilers()
16 except AttributeError:
17 conf.fatal("Add options(opt): opt.load('compiler_c')")
18 for compiler in re.split('[ ,]+',test_for_compiler):
19 conf.env.stash()
20 conf.start_msg('Checking for %r (C compiler)'%compiler)
21 try:
22 conf.load(compiler)
23 except conf.errors.ConfigurationError as e:
24 conf.env.revert()
25 conf.end_msg(False)
26 debug('compiler_c: %r',e)
27 else:
28 if conf.env.CC:
29 conf.end_msg(conf.env.get_flat('CC'))
30 conf.env.COMPILER_CC=compiler
31 conf.env.commit()
32 break
33 conf.env.revert()
34 conf.end_msg(False)
35 else:
36 conf.fatal('could not configure a C compiler!')
37 def options(opt):
38 test_for_compiler=default_compilers()
39 opt.load_special_tools('c_*.py',ban=['c_dumbpreproc.py'])
40 cc_compiler_opts=opt.add_option_group('Configuration options')
41 cc_compiler_opts.add_option('--check-c-compiler',default=None,help='list of C compilers to try [%s]'%test_for_compiler,dest="check_c_compiler")
42 for x in test_for_compiler.split():
43 opt.load('%s'%x)
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import re
5 from waflib.Tools import ccroot
6 from waflib import Utils
7 from waflib.Logs import debug
8 cxx_compiler={'win32':['msvc','g++','clang++'],'cygwin':['g++'],'darwin':['clang++','g++'],'aix':['xlc++','g++','clang++'],'linux':['g++','clang++','icpc'],'sunos':['sunc++','g++'],'irix':['g++'],'hpux':['g++'],'osf1V':['g++'],'gnu':['g++','clang++'],'java':['g++','msvc','clang++','icpc'],'default':['clang++','g++']}
9 def default_compilers():
10 build_platform=Utils.unversioned_sys_platform()
11 possible_compiler_list=cxx_compiler.get(build_platform,cxx_compiler['default'])
12 return' '.join(possible_compiler_list)
13 def configure(conf):
14 try:
15 test_for_compiler=conf.options.check_cxx_compiler or default_compilers()
16 except AttributeError:
17 conf.fatal("Add options(opt): opt.load('compiler_cxx')")
18 for compiler in re.split('[ ,]+',test_for_compiler):
19 conf.env.stash()
20 conf.start_msg('Checking for %r (C++ compiler)'%compiler)
21 try:
22 conf.load(compiler)
23 except conf.errors.ConfigurationError as e:
24 conf.env.revert()
25 conf.end_msg(False)
26 debug('compiler_cxx: %r',e)
27 else:
28 if conf.env.CXX:
29 conf.end_msg(conf.env.get_flat('CXX'))
30 conf.env.COMPILER_CXX=compiler
31 conf.env.commit()
32 break
33 conf.env.revert()
34 conf.end_msg(False)
35 else:
36 conf.fatal('could not configure a C++ compiler!')
37 def options(opt):
38 test_for_compiler=default_compilers()
39 opt.load_special_tools('cxx_*.py')
40 cxx_compiler_opts=opt.add_option_group('Configuration options')
41 cxx_compiler_opts.add_option('--check-cxx-compiler',default=None,help='list of C++ compilers to try [%s]'%test_for_compiler,dest="check_cxx_compiler")
42 for x in test_for_compiler.split():
43 opt.load('%s'%x)
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import re
5 from waflib import Utils,Logs
6 d_compiler={'default':['gdc','dmd','ldc2']}
7 def default_compilers():
8 build_platform=Utils.unversioned_sys_platform()
9 possible_compiler_list=d_compiler.get(build_platform,d_compiler['default'])
10 return' '.join(possible_compiler_list)
11 def configure(conf):
12 try:
13 test_for_compiler=conf.options.check_d_compiler or default_compilers()
14 except AttributeError:
15 conf.fatal("Add options(opt): opt.load('compiler_d')")
16 for compiler in re.split('[ ,]+',test_for_compiler):
17 conf.env.stash()
18 conf.start_msg('Checking for %r (D compiler)'%compiler)
19 try:
20 conf.load(compiler)
21 except conf.errors.ConfigurationError as e:
22 conf.env.revert()
23 conf.end_msg(False)
24 Logs.debug('compiler_d: %r',e)
25 else:
26 if conf.env.D:
27 conf.end_msg(conf.env.get_flat('D'))
28 conf.env.COMPILER_D=compiler
29 conf.env.commit()
30 break
31 conf.env.revert()
32 conf.end_msg(False)
33 else:
34 conf.fatal('could not configure a D compiler!')
35 def options(opt):
36 test_for_compiler=default_compilers()
37 d_compiler_opts=opt.add_option_group('Configuration options')
38 d_compiler_opts.add_option('--check-d-compiler',default=None,help='list of D compilers to try [%s]'%test_for_compiler,dest='check_d_compiler')
39 for x in test_for_compiler.split():
40 opt.load('%s'%x)
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import re
5 from waflib import Utils,Logs
6 from waflib.Tools import fc
7 fc_compiler={'win32':['gfortran','ifort'],'darwin':['gfortran','g95','ifort'],'linux':['gfortran','g95','ifort'],'java':['gfortran','g95','ifort'],'default':['gfortran'],'aix':['gfortran']}
8 def default_compilers():
9 build_platform=Utils.unversioned_sys_platform()
10 possible_compiler_list=fc_compiler.get(build_platform,fc_compiler['default'])
11 return' '.join(possible_compiler_list)
12 def configure(conf):
13 try:
14 test_for_compiler=conf.options.check_fortran_compiler or default_compilers()
15 except AttributeError:
16 conf.fatal("Add options(opt): opt.load('compiler_fc')")
17 for compiler in re.split('[ ,]+',test_for_compiler):
18 conf.env.stash()
19 conf.start_msg('Checking for %r (Fortran compiler)'%compiler)
20 try:
21 conf.load(compiler)
22 except conf.errors.ConfigurationError as e:
23 conf.env.revert()
24 conf.end_msg(False)
25 Logs.debug('compiler_fortran: %r',e)
26 else:
27 if conf.env.FC:
28 conf.end_msg(conf.env.get_flat('FC'))
29 conf.env.COMPILER_FORTRAN=compiler
30 conf.env.commit()
31 break
32 conf.env.revert()
33 conf.end_msg(False)
34 else:
35 conf.fatal('could not configure a Fortran compiler!')
36 def options(opt):
37 test_for_compiler=default_compilers()
38 opt.load_special_tools('fc_*.py')
39 fortran_compiler_opts=opt.add_option_group('Configuration options')
40 fortran_compiler_opts.add_option('--check-fortran-compiler',default=None,help='list of Fortran compiler to try [%s]'%test_for_compiler,dest="check_fortran_compiler")
41 for x in test_for_compiler.split():
42 opt.load('%s'%x)
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib import Utils,Task,Options,Errors
5 from waflib.TaskGen import before_method,after_method,feature
6 from waflib.Tools import ccroot
7 from waflib.Configure import conf
8 ccroot.USELIB_VARS['cs']=set(['CSFLAGS','ASSEMBLIES','RESOURCES'])
9 ccroot.lib_patterns['csshlib']=['%s']
10 @feature('cs')
11 @before_method('process_source')
12 def apply_cs(self):
13 cs_nodes=[]
14 no_nodes=[]
15 for x in self.to_nodes(self.source):
16 if x.name.endswith('.cs'):
17 cs_nodes.append(x)
18 else:
19 no_nodes.append(x)
20 self.source=no_nodes
21 bintype=getattr(self,'bintype',self.gen.endswith('.dll')and'library'or'exe')
22 self.cs_task=tsk=self.create_task('mcs',cs_nodes,self.path.find_or_declare(self.gen))
23 tsk.env.CSTYPE='/target:%s'%bintype
24 tsk.env.OUT='/out:%s'%tsk.outputs[0].abspath()
25 self.env.append_value('CSFLAGS','/platform:%s'%getattr(self,'platform','anycpu'))
26 inst_to=getattr(self,'install_path',bintype=='exe'and'${BINDIR}'or'${LIBDIR}')
27 if inst_to:
28 mod=getattr(self,'chmod',bintype=='exe'and Utils.O755 or Utils.O644)
29 self.install_task=self.add_install_files(install_to=inst_to,install_from=self.cs_task.outputs[:],chmod=mod)
30 @feature('cs')
31 @after_method('apply_cs')
32 def use_cs(self):
33 names=self.to_list(getattr(self,'use',[]))
34 get=self.bld.get_tgen_by_name
35 for x in names:
36 try:
37 y=get(x)
38 except Errors.WafError:
39 self.env.append_value('CSFLAGS','/reference:%s'%x)
40 continue
41 y.post()
42 tsk=getattr(y,'cs_task',None)or getattr(y,'link_task',None)
43 if not tsk:
44 self.bld.fatal('cs task has no link task for use %r'%self)
45 self.cs_task.dep_nodes.extend(tsk.outputs)
46 self.cs_task.set_run_after(tsk)
47 self.env.append_value('CSFLAGS','/reference:%s'%tsk.outputs[0].abspath())
48 @feature('cs')
49 @after_method('apply_cs','use_cs')
50 def debug_cs(self):
51 csdebug=getattr(self,'csdebug',self.env.CSDEBUG)
52 if not csdebug:
53 return
54 node=self.cs_task.outputs[0]
55 if self.env.CS_NAME=='mono':
56 out=node.parent.find_or_declare(node.name+'.mdb')
57 else:
58 out=node.change_ext('.pdb')
59 self.cs_task.outputs.append(out)
60 if getattr(self,'install_task',None):
61 self.pdb_install_task=self.add_install_files(install_to=self.install_task.install_to,install_from=out)
62 if csdebug=='pdbonly':
63 val=['/debug+','/debug:pdbonly']
64 elif csdebug=='full':
65 val=['/debug+','/debug:full']
66 else:
67 val=['/debug-']
68 self.env.append_value('CSFLAGS',val)
69 @feature('cs')
70 @after_method('debug_cs')
71 def doc_cs(self):
72 csdoc=getattr(self,'csdoc',self.env.CSDOC)
73 if not csdoc:
74 return
75 node=self.cs_task.outputs[0]
76 out=node.change_ext('.xml')
77 self.cs_task.outputs.append(out)
78 if getattr(self,'install_task',None):
79 self.doc_install_task=self.add_install_files(install_to=self.install_task.install_to,install_from=out)
80 self.env.append_value('CSFLAGS','/doc:%s'%out.abspath())
81 class mcs(Task.Task):
82 color='YELLOW'
83 run_str='${MCS} ${CSTYPE} ${CSFLAGS} ${ASS_ST:ASSEMBLIES} ${RES_ST:RESOURCES} ${OUT} ${SRC}'
84 def split_argfile(self,cmd):
85 inline=[cmd[0]]
86 infile=[]
87 for x in cmd[1:]:
88 if x.lower()=='/noconfig':
89 inline.append(x)
90 else:
91 infile.append(self.quote_flag(x))
92 return(inline,infile)
93 def configure(conf):
94 csc=getattr(Options.options,'cscbinary',None)
95 if csc:
96 conf.env.MCS=csc
97 conf.find_program(['csc','mcs','gmcs'],var='MCS')
98 conf.env.ASS_ST='/r:%s'
99 conf.env.RES_ST='/resource:%s'
100 conf.env.CS_NAME='csc'
101 if str(conf.env.MCS).lower().find('mcs')>-1:
102 conf.env.CS_NAME='mono'
103 def options(opt):
104 opt.add_option('--with-csc-binary',type='string',dest='cscbinary')
105 class fake_csshlib(Task.Task):
106 color='YELLOW'
107 inst_to=None
108 def runnable_status(self):
109 return Task.SKIP_ME
110 @conf
111 def read_csshlib(self,name,paths=[]):
112 return self(name=name,features='fake_lib',lib_paths=paths,lib_type='csshlib')
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib import TaskGen,Task
5 from waflib.Tools import c_preproc
6 from waflib.Tools.ccroot import link_task,stlink_task
7 @TaskGen.extension('.cpp','.cc','.cxx','.C','.c++')
8 def cxx_hook(self,node):
9 return self.create_compiled_task('cxx',node)
10 if not'.c'in TaskGen.task_gen.mappings:
11 TaskGen.task_gen.mappings['.c']=TaskGen.task_gen.mappings['.cpp']
12 class cxx(Task.Task):
13 run_str='${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT[0].abspath()} ${CPPFLAGS}'
14 vars=['CXXDEPS']
15 ext_in=['.h']
16 scan=c_preproc.scan
17 class cxxprogram(link_task):
18 run_str='${LINK_CXX} ${LINKFLAGS} ${CXXLNK_SRC_F}${SRC} ${CXXLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LDFLAGS}'
19 vars=['LINKDEPS']
20 ext_out=['.bin']
21 inst_to='${BINDIR}'
22 class cxxshlib(cxxprogram):
23 inst_to='${LIBDIR}'
24 class cxxstlib(stlink_task):
25 pass
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib import Utils,Task,Errors
5 from waflib.TaskGen import taskgen_method,feature,extension
6 from waflib.Tools import d_scan,d_config
7 from waflib.Tools.ccroot import link_task,stlink_task
8 class d(Task.Task):
9 color='GREEN'
10 run_str='${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_SRC_F:SRC} ${D_TGT_F:TGT}'
11 scan=d_scan.scan
12 class d_with_header(d):
13 run_str='${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_HDR_F:tgt.outputs[1].bldpath()} ${D_SRC_F:SRC} ${D_TGT_F:tgt.outputs[0].bldpath()}'
14 class d_header(Task.Task):
15 color='BLUE'
16 run_str='${D} ${D_HEADER} ${SRC}'
17 class dprogram(link_task):
18 run_str='${D_LINKER} ${LINKFLAGS} ${DLNK_SRC_F}${SRC} ${DLNK_TGT_F:TGT} ${RPATH_ST:RPATH} ${DSTLIB_MARKER} ${DSTLIBPATH_ST:STLIBPATH} ${DSTLIB_ST:STLIB} ${DSHLIB_MARKER} ${DLIBPATH_ST:LIBPATH} ${DSHLIB_ST:LIB}'
19 inst_to='${BINDIR}'
20 class dshlib(dprogram):
21 inst_to='${LIBDIR}'
22 class dstlib(stlink_task):
23 pass
24 @extension('.d','.di','.D')
25 def d_hook(self,node):
26 ext=Utils.destos_to_binfmt(self.env.DEST_OS)=='pe'and'obj'or'o'
27 out='%s.%d.%s'%(node.name,self.idx,ext)
28 def create_compiled_task(self,name,node):
29 task=self.create_task(name,node,node.parent.find_or_declare(out))
30 try:
31 self.compiled_tasks.append(task)
32 except AttributeError:
33 self.compiled_tasks=[task]
34 return task
35 if getattr(self,'generate_headers',None):
36 tsk=create_compiled_task(self,'d_with_header',node)
37 tsk.outputs.append(node.change_ext(self.env.DHEADER_ext))
38 else:
39 tsk=create_compiled_task(self,'d',node)
40 return tsk
41 @taskgen_method
42 def generate_header(self,filename):
43 try:
44 self.header_lst.append([filename,self.install_path])
45 except AttributeError:
46 self.header_lst=[[filename,self.install_path]]
47 @feature('d')
48 def process_header(self):
49 for i in getattr(self,'header_lst',[]):
50 node=self.path.find_resource(i[0])
51 if not node:
52 raise Errors.WafError('file %r not found on d obj'%i[0])
53 self.create_task('d_header',node,node.change_ext('.di'))
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib import Utils
5 from waflib.Configure import conf
6 @conf
7 def d_platform_flags(self):
8 v=self.env
9 if not v.DEST_OS:
10 v.DEST_OS=Utils.unversioned_sys_platform()
11 binfmt=Utils.destos_to_binfmt(self.env.DEST_OS)
12 if binfmt=='pe':
13 v.dprogram_PATTERN='%s.exe'
14 v.dshlib_PATTERN='lib%s.dll'
15 v.dstlib_PATTERN='lib%s.a'
16 elif binfmt=='mac-o':
17 v.dprogram_PATTERN='%s'
18 v.dshlib_PATTERN='lib%s.dylib'
19 v.dstlib_PATTERN='lib%s.a'
20 else:
21 v.dprogram_PATTERN='%s'
22 v.dshlib_PATTERN='lib%s.so'
23 v.dstlib_PATTERN='lib%s.a'
24 DLIB='''
25 version(D_Version2) {
26 import std.stdio;
27 int main() {
28 writefln("phobos2");
29 return 0;
30 }
31 } else {
32 version(Tango) {
33 import tango.stdc.stdio;
34 int main() {
35 printf("tango");
36 return 0;
37 }
38 } else {
39 import std.stdio;
40 int main() {
41 writefln("phobos1");
42 return 0;
43 }
44 }
45 }
46 '''
47 @conf
48 def check_dlibrary(self,execute=True):
49 ret=self.check_cc(features='d dprogram',fragment=DLIB,compile_filename='test.d',execute=execute,define_ret=True)
50 if execute:
51 self.env.DLIBRARY=ret.strip()
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import re
5 from waflib import Utils
6 def filter_comments(filename):
7 txt=Utils.readf(filename)
8 i=0
9 buf=[]
10 max=len(txt)
11 begin=0
12 while i<max:
13 c=txt[i]
14 if c=='"'or c=="'":
15 buf.append(txt[begin:i])
16 delim=c
17 i+=1
18 while i<max:
19 c=txt[i]
20 if c==delim:
21 break
22 elif c=='\\':
23 i+=1
24 i+=1
25 i+=1
26 begin=i
27 elif c=='/':
28 buf.append(txt[begin:i])
29 i+=1
30 if i==max:
31 break
32 c=txt[i]
33 if c=='+':
34 i+=1
35 nesting=1
36 c=None
37 while i<max:
38 prev=c
39 c=txt[i]
40 if prev=='/'and c=='+':
41 nesting+=1
42 c=None
43 elif prev=='+'and c=='/':
44 nesting-=1
45 if nesting==0:
46 break
47 c=None
48 i+=1
49 elif c=='*':
50 i+=1
51 c=None
52 while i<max:
53 prev=c
54 c=txt[i]
55 if prev=='*'and c=='/':
56 break
57 i+=1
58 elif c=='/':
59 i+=1
60 while i<max and txt[i]!='\n':
61 i+=1
62 else:
63 begin=i-1
64 continue
65 i+=1
66 begin=i
67 buf.append(' ')
68 else:
69 i+=1
70 buf.append(txt[begin:])
71 return buf
72 class d_parser(object):
73 def __init__(self,env,incpaths):
74 self.allnames=[]
75 self.re_module=re.compile(r"module\s+([^;]+)")
76 self.re_import=re.compile(r"import\s+([^;]+)")
77 self.re_import_bindings=re.compile("([^:]+):(.*)")
78 self.re_import_alias=re.compile("[^=]+=(.+)")
79 self.env=env
80 self.nodes=[]
81 self.names=[]
82 self.incpaths=incpaths
83 def tryfind(self,filename):
84 found=0
85 for n in self.incpaths:
86 found=n.find_resource(filename.replace('.','/')+'.d')
87 if found:
88 self.nodes.append(found)
89 self.waiting.append(found)
90 break
91 if not found:
92 if not filename in self.names:
93 self.names.append(filename)
94 def get_strings(self,code):
95 self.module=''
96 lst=[]
97 mod_name=self.re_module.search(code)
98 if mod_name:
99 self.module=re.sub(r'\s+','',mod_name.group(1))
100 import_iterator=self.re_import.finditer(code)
101 if import_iterator:
102 for import_match in import_iterator:
103 import_match_str=re.sub(r'\s+','',import_match.group(1))
104 bindings_match=self.re_import_bindings.match(import_match_str)
105 if bindings_match:
106 import_match_str=bindings_match.group(1)
107 matches=import_match_str.split(',')
108 for match in matches:
109 alias_match=self.re_import_alias.match(match)
110 if alias_match:
111 match=alias_match.group(1)
112 lst.append(match)
113 return lst
114 def start(self,node):
115 self.waiting=[node]
116 while self.waiting:
117 nd=self.waiting.pop(0)
118 self.iter(nd)
119 def iter(self,node):
120 path=node.abspath()
121 code="".join(filter_comments(path))
122 names=self.get_strings(code)
123 for x in names:
124 if x in self.allnames:
125 continue
126 self.allnames.append(x)
127 self.tryfind(x)
128 def scan(self):
129 env=self.env
130 gruik=d_parser(env,self.generator.includes_nodes)
131 node=self.inputs[0]
132 gruik.start(node)
133 nodes=gruik.nodes
134 names=gruik.names
135 return(nodes,names)
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib import Task,Errors
5 from waflib.TaskGen import taskgen_method,before_method
6 @taskgen_method
7 def add_dbus_file(self,filename,prefix,mode):
8 if not hasattr(self,'dbus_lst'):
9 self.dbus_lst=[]
10 if not'process_dbus'in self.meths:
11 self.meths.append('process_dbus')
12 self.dbus_lst.append([filename,prefix,mode])
13 @before_method('process_source')
14 def process_dbus(self):
15 for filename,prefix,mode in getattr(self,'dbus_lst',[]):
16 node=self.path.find_resource(filename)
17 if not node:
18 raise Errors.WafError('file not found '+filename)
19 tsk=self.create_task('dbus_binding_tool',node,node.change_ext('.h'))
20 tsk.env.DBUS_BINDING_TOOL_PREFIX=prefix
21 tsk.env.DBUS_BINDING_TOOL_MODE=mode
22 class dbus_binding_tool(Task.Task):
23 color='BLUE'
24 ext_out=['.h']
25 run_str='${DBUS_BINDING_TOOL} --prefix=${DBUS_BINDING_TOOL_PREFIX} --mode=${DBUS_BINDING_TOOL_MODE} --output=${TGT} ${SRC}'
26 shell=True
27 def configure(conf):
28 conf.find_program('dbus-binding-tool',var='DBUS_BINDING_TOOL')
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import sys
5 from waflib.Tools import ar,d
6 from waflib.Configure import conf
7 @conf
8 def find_dmd(conf):
9 conf.find_program(['dmd','dmd2','ldc'],var='D')
10 out=conf.cmd_and_log(conf.env.D+['--help'])
11 if out.find("D Compiler v")==-1:
12 out=conf.cmd_and_log(conf.env.D+['-version'])
13 if out.find("based on DMD v1.")==-1:
14 conf.fatal("detected compiler is not dmd/ldc")
15 @conf
16 def common_flags_ldc(conf):
17 v=conf.env
18 v.DFLAGS=['-d-version=Posix']
19 v.LINKFLAGS=[]
20 v.DFLAGS_dshlib=['-relocation-model=pic']
21 @conf
22 def common_flags_dmd(conf):
23 v=conf.env
24 v.D_SRC_F=['-c']
25 v.D_TGT_F='-of%s'
26 v.D_LINKER=v.D
27 v.DLNK_SRC_F=''
28 v.DLNK_TGT_F='-of%s'
29 v.DINC_ST='-I%s'
30 v.DSHLIB_MARKER=v.DSTLIB_MARKER=''
31 v.DSTLIB_ST=v.DSHLIB_ST='-L-l%s'
32 v.DSTLIBPATH_ST=v.DLIBPATH_ST='-L-L%s'
33 v.LINKFLAGS_dprogram=['-quiet']
34 v.DFLAGS_dshlib=['-fPIC']
35 v.LINKFLAGS_dshlib=['-L-shared']
36 v.DHEADER_ext='.di'
37 v.DFLAGS_d_with_header=['-H','-Hf']
38 v.D_HDR_F='%s'
39 def configure(conf):
40 conf.find_dmd()
41 if sys.platform=='win32':
42 out=conf.cmd_and_log(conf.env.D+['--help'])
43 if out.find('D Compiler v2.')>-1:
44 conf.fatal('dmd2 on Windows is not supported, use gdc or ldc2 instead')
45 conf.load('ar')
46 conf.load('d')
47 conf.common_flags_dmd()
48 conf.d_platform_flags()
49 if str(conf.env.D).find('ldc')>-1:
50 conf.common_flags_ldc()
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 typos={'feature':'features','sources':'source','targets':'target','include':'includes','export_include':'export_includes','define':'defines','importpath':'includes','installpath':'install_path','iscopy':'is_copy','uses':'use',}
5 meths_typos=['__call__','program','shlib','stlib','objects']
6 import sys
7 from waflib import Logs,Build,Node,Task,TaskGen,ConfigSet,Errors,Utils
8 from waflib.Tools import ccroot
9 def check_same_targets(self):
10 mp=Utils.defaultdict(list)
11 uids={}
12 def check_task(tsk):
13 if not isinstance(tsk,Task.Task):
14 return
15 if hasattr(tsk,'no_errcheck_out'):
16 return
17 for node in tsk.outputs:
18 mp[node].append(tsk)
19 try:
20 uids[tsk.uid()].append(tsk)
21 except KeyError:
22 uids[tsk.uid()]=[tsk]
23 for g in self.groups:
24 for tg in g:
25 try:
26 for tsk in tg.tasks:
27 check_task(tsk)
28 except AttributeError:
29 check_task(tg)
30 dupe=False
31 for(k,v)in mp.items():
32 if len(v)>1:
33 dupe=True
34 msg='* Node %r is created more than once%s. The task generators are:'%(k,Logs.verbose==1 and" (full message on 'waf -v -v')"or"")
35 Logs.error(msg)
36 for x in v:
37 if Logs.verbose>1:
38 Logs.error(' %d. %r',1+v.index(x),x.generator)
39 else:
40 Logs.error(' %d. %r in %r',1+v.index(x),x.generator.name,getattr(x.generator,'path',None))
41 Logs.error('If you think that this is an error, set no_errcheck_out on the task instance')
42 if not dupe:
43 for(k,v)in uids.items():
44 if len(v)>1:
45 Logs.error('* Several tasks use the same identifier. Please check the information on\n https://waf.io/apidocs/Task.html?highlight=uid#waflib.Task.Task.uid')
46 tg_details=tsk.generator.name
47 if Logs.verbose>2:
48 tg_details=tsk.generator
49 for tsk in v:
50 Logs.error(' - object %r (%r) defined in %r',tsk.__class__.__name__,tsk,tg_details)
51 def check_invalid_constraints(self):
52 feat=set()
53 for x in list(TaskGen.feats.values()):
54 feat.union(set(x))
55 for(x,y)in TaskGen.task_gen.prec.items():
56 feat.add(x)
57 feat.union(set(y))
58 ext=set()
59 for x in TaskGen.task_gen.mappings.values():
60 ext.add(x.__name__)
61 invalid=ext&feat
62 if invalid:
63 Logs.error('The methods %r have invalid annotations: @extension <-> @feature/@before_method/@after_method',list(invalid))
64 for cls in list(Task.classes.values()):
65 if sys.hexversion>0x3000000 and issubclass(cls,Task.Task)and isinstance(cls.hcode,str):
66 raise Errors.WafError('Class %r has hcode value %r of type <str>, expecting <bytes> (use Utils.h_cmd() ?)'%(cls,cls.hcode))
67 for x in('before','after'):
68 for y in Utils.to_list(getattr(cls,x,[])):
69 if not Task.classes.get(y):
70 Logs.error('Erroneous order constraint %r=%r on task class %r',x,y,cls.__name__)
71 if getattr(cls,'rule',None):
72 Logs.error('Erroneous attribute "rule" on task class %r (rename to "run_str")',cls.__name__)
73 def replace(m):
74 oldcall=getattr(Build.BuildContext,m)
75 def call(self,*k,**kw):
76 ret=oldcall(self,*k,**kw)
77 for x in typos:
78 if x in kw:
79 if x=='iscopy'and'subst'in getattr(self,'features',''):
80 continue
81 Logs.error('Fix the typo %r -> %r on %r',x,typos[x],ret)
82 return ret
83 setattr(Build.BuildContext,m,call)
84 def enhance_lib():
85 for m in meths_typos:
86 replace(m)
87 def ant_glob(self,*k,**kw):
88 if k:
89 lst=Utils.to_list(k[0])
90 for pat in lst:
91 sp=pat.split('/')
92 if'..'in sp:
93 Logs.error("In ant_glob pattern %r: '..' means 'two dots', not 'parent directory'",k[0])
94 if'.'in sp:
95 Logs.error("In ant_glob pattern %r: '.' means 'one dot', not 'current directory'",k[0])
96 return self.old_ant_glob(*k,**kw)
97 Node.Node.old_ant_glob=Node.Node.ant_glob
98 Node.Node.ant_glob=ant_glob
99 def ant_iter(self,accept=None,maxdepth=25,pats=[],dir=False,src=True,remove=True,quiet=False):
100 if remove:
101 try:
102 if self.is_child_of(self.ctx.bldnode)and not quiet:
103 quiet=True
104 Logs.error('Calling ant_glob on build folders (%r) is dangerous: add quiet=True / remove=False',self)
105 except AttributeError:
106 pass
107 return self.old_ant_iter(accept,maxdepth,pats,dir,src,remove,quiet)
108 Node.Node.old_ant_iter=Node.Node.ant_iter
109 Node.Node.ant_iter=ant_iter
110 old=Task.is_before
111 def is_before(t1,t2):
112 ret=old(t1,t2)
113 if ret and old(t2,t1):
114 Logs.error('Contradictory order constraints in classes %r %r',t1,t2)
115 return ret
116 Task.is_before=is_before
117 def check_err_features(self):
118 lst=self.to_list(self.features)
119 if'shlib'in lst:
120 Logs.error('feature shlib -> cshlib, dshlib or cxxshlib')
121 for x in('c','cxx','d','fc'):
122 if not x in lst and lst and lst[0]in[x+y for y in('program','shlib','stlib')]:
123 Logs.error('%r features is probably missing %r',self,x)
124 TaskGen.feature('*')(check_err_features)
125 def check_err_order(self):
126 if not hasattr(self,'rule')and not'subst'in Utils.to_list(self.features):
127 for x in('before','after','ext_in','ext_out'):
128 if hasattr(self,x):
129 Logs.warn('Erroneous order constraint %r on non-rule based task generator %r',x,self)
130 else:
131 for x in('before','after'):
132 for y in self.to_list(getattr(self,x,[])):
133 if not Task.classes.get(y):
134 Logs.error('Erroneous order constraint %s=%r on %r (no such class)',x,y,self)
135 TaskGen.feature('*')(check_err_order)
136 def check_compile(self):
137 check_invalid_constraints(self)
138 try:
139 ret=self.orig_compile()
140 finally:
141 check_same_targets(self)
142 return ret
143 Build.BuildContext.orig_compile=Build.BuildContext.compile
144 Build.BuildContext.compile=check_compile
145 def use_rec(self,name,**kw):
146 try:
147 y=self.bld.get_tgen_by_name(name)
148 except Errors.WafError:
149 pass
150 else:
151 idx=self.bld.get_group_idx(self)
152 odx=self.bld.get_group_idx(y)
153 if odx>idx:
154 msg="Invalid 'use' across build groups:"
155 if Logs.verbose>1:
156 msg+='\n target %r\n uses:\n %r'%(self,y)
157 else:
158 msg+=" %r uses %r (try 'waf -v -v' for the full error)"%(self.name,name)
159 raise Errors.WafError(msg)
160 self.orig_use_rec(name,**kw)
161 TaskGen.task_gen.orig_use_rec=TaskGen.task_gen.use_rec
162 TaskGen.task_gen.use_rec=use_rec
163 def _getattr(self,name,default=None):
164 if name=='append'or name=='add':
165 raise Errors.WafError('env.append and env.add do not exist: use env.append_value/env.append_unique')
166 elif name=='prepend':
167 raise Errors.WafError('env.prepend does not exist: use env.prepend_value')
168 if name in self.__slots__:
169 return super(ConfigSet.ConfigSet,self).__getattr__(name,default)
170 else:
171 return self[name]
172 ConfigSet.ConfigSet.__getattr__=_getattr
173 def options(opt):
174 enhance_lib()
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib import Utils,Task,Errors
5 from waflib.Tools import ccroot,fc_config,fc_scan
6 from waflib.TaskGen import extension
7 from waflib.Configure import conf
8 ccroot.USELIB_VARS['fc']=set(['FCFLAGS','DEFINES','INCLUDES','FCPPFLAGS'])
9 ccroot.USELIB_VARS['fcprogram_test']=ccroot.USELIB_VARS['fcprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','LDFLAGS'])
10 ccroot.USELIB_VARS['fcshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','LDFLAGS'])
11 ccroot.USELIB_VARS['fcstlib']=set(['ARFLAGS','LINKDEPS'])
12 @extension('.f','.F','.f90','.F90','.for','.FOR','.f95','.F95','.f03','.F03','.f08','.F08')
13 def fc_hook(self,node):
14 return self.create_compiled_task('fc',node)
15 @conf
16 def modfile(conf,name):
17 if name.find(':')>=0:
18 separator=conf.env.FC_SUBMOD_SEPARATOR or'@'
19 modpath=name.split(':')
20 modname=modpath[0]+separator+modpath[-1]
21 suffix=conf.env.FC_SUBMOD_SUFFIX or'.smod'
22 else:
23 modname=name
24 suffix='.mod'
25 return{'lower':modname.lower()+suffix.lower(),'lower.MOD':modname.lower()+suffix.upper(),'UPPER.mod':modname.upper()+suffix.lower(),'UPPER':modname.upper()+suffix.upper()}[conf.env.FC_MOD_CAPITALIZATION or'lower']
26 def get_fortran_tasks(tsk):
27 bld=tsk.generator.bld
28 tasks=bld.get_tasks_group(bld.get_group_idx(tsk.generator))
29 return[x for x in tasks if isinstance(x,fc)and not getattr(x,'nomod',None)and not getattr(x,'mod_fortran_done',None)]
30 class fc(Task.Task):
31 color='GREEN'
32 run_str='${FC} ${FCFLAGS} ${FCINCPATH_ST:INCPATHS} ${FCDEFINES_ST:DEFINES} ${_FCMODOUTFLAGS} ${FC_TGT_F}${TGT[0].abspath()} ${FC_SRC_F}${SRC[0].abspath()} ${FCPPFLAGS}'
33 vars=["FORTRANMODPATHFLAG"]
34 def scan(self):
35 tmp=fc_scan.fortran_parser(self.generator.includes_nodes)
36 tmp.task=self
37 tmp.start(self.inputs[0])
38 return(tmp.nodes,tmp.names)
39 def runnable_status(self):
40 if getattr(self,'mod_fortran_done',None):
41 return super(fc,self).runnable_status()
42 bld=self.generator.bld
43 lst=get_fortran_tasks(self)
44 for tsk in lst:
45 tsk.mod_fortran_done=True
46 for tsk in lst:
47 ret=tsk.runnable_status()
48 if ret==Task.ASK_LATER:
49 for x in lst:
50 x.mod_fortran_done=None
51 return Task.ASK_LATER
52 ins=Utils.defaultdict(set)
53 outs=Utils.defaultdict(set)
54 for tsk in lst:
55 key=tsk.uid()
56 for x in bld.raw_deps[key]:
57 if x.startswith('MOD@'):
58 name=bld.modfile(x.replace('MOD@',''))
59 node=bld.srcnode.find_or_declare(name)
60 tsk.set_outputs(node)
61 outs[node].add(tsk)
62 for tsk in lst:
63 key=tsk.uid()
64 for x in bld.raw_deps[key]:
65 if x.startswith('USE@'):
66 name=bld.modfile(x.replace('USE@',''))
67 node=bld.srcnode.find_resource(name)
68 if node and node not in tsk.outputs:
69 if not node in bld.node_deps[key]:
70 bld.node_deps[key].append(node)
71 ins[node].add(tsk)
72 for k in ins.keys():
73 for a in ins[k]:
74 a.run_after.update(outs[k])
75 for x in outs[k]:
76 self.generator.bld.producer.revdeps[x].add(a)
77 tmp=[]
78 for t in outs[k]:
79 tmp.extend(t.outputs)
80 a.dep_nodes.extend(tmp)
81 a.dep_nodes.sort(key=lambda x:x.abspath())
82 for tsk in lst:
83 try:
84 delattr(tsk,'cache_sig')
85 except AttributeError:
86 pass
87 return super(fc,self).runnable_status()
88 class fcprogram(ccroot.link_task):
89 color='YELLOW'
90 run_str='${FC} ${LINKFLAGS} ${FCLNK_SRC_F}${SRC} ${FCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FCSTLIB_MARKER} ${FCSTLIBPATH_ST:STLIBPATH} ${FCSTLIB_ST:STLIB} ${FCSHLIB_MARKER} ${FCLIBPATH_ST:LIBPATH} ${FCLIB_ST:LIB} ${LDFLAGS}'
91 inst_to='${BINDIR}'
92 class fcshlib(fcprogram):
93 inst_to='${LIBDIR}'
94 class fcstlib(ccroot.stlink_task):
95 pass
96 class fcprogram_test(fcprogram):
97 def runnable_status(self):
98 ret=super(fcprogram_test,self).runnable_status()
99 if ret==Task.SKIP_ME:
100 ret=Task.RUN_ME
101 return ret
102 def exec_command(self,cmd,**kw):
103 bld=self.generator.bld
104 kw['shell']=isinstance(cmd,str)
105 kw['stdout']=kw['stderr']=Utils.subprocess.PIPE
106 kw['cwd']=self.get_cwd()
107 bld.out=bld.err=''
108 bld.to_log('command: %s\n'%cmd)
109 kw['output']=0
110 try:
111 (bld.out,bld.err)=bld.cmd_and_log(cmd,**kw)
112 except Errors.WafError:
113 return-1
114 if bld.out:
115 bld.to_log('out: %s\n'%bld.out)
116 if bld.err:
117 bld.to_log('err: %s\n'%bld.err)
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import re,os,sys,shlex
5 from waflib.Configure import conf
6 from waflib.TaskGen import feature,before_method
7 FC_FRAGMENT=' program main\n end program main\n'
8 FC_FRAGMENT2=' PROGRAM MAIN\n END\n'
9 @conf
10 def fc_flags(conf):
11 v=conf.env
12 v.FC_SRC_F=[]
13 v.FC_TGT_F=['-c','-o']
14 v.FCINCPATH_ST='-I%s'
15 v.FCDEFINES_ST='-D%s'
16 if not v.LINK_FC:
17 v.LINK_FC=v.FC
18 v.FCLNK_SRC_F=[]
19 v.FCLNK_TGT_F=['-o']
20 v.FCFLAGS_fcshlib=['-fpic']
21 v.LINKFLAGS_fcshlib=['-shared']
22 v.fcshlib_PATTERN='lib%s.so'
23 v.fcstlib_PATTERN='lib%s.a'
24 v.FCLIB_ST='-l%s'
25 v.FCLIBPATH_ST='-L%s'
26 v.FCSTLIB_ST='-l%s'
27 v.FCSTLIBPATH_ST='-L%s'
28 v.FCSTLIB_MARKER='-Wl,-Bstatic'
29 v.FCSHLIB_MARKER='-Wl,-Bdynamic'
30 v.SONAME_ST='-Wl,-h,%s'
31 @conf
32 def fc_add_flags(conf):
33 conf.add_os_flags('FCPPFLAGS',dup=False)
34 conf.add_os_flags('FCFLAGS',dup=False)
35 conf.add_os_flags('LINKFLAGS',dup=False)
36 conf.add_os_flags('LDFLAGS',dup=False)
37 @conf
38 def check_fortran(self,*k,**kw):
39 self.check_cc(fragment=FC_FRAGMENT,compile_filename='test.f',features='fc fcprogram',msg='Compiling a simple fortran app')
40 @conf
41 def check_fc(self,*k,**kw):
42 kw['compiler']='fc'
43 if not'compile_mode'in kw:
44 kw['compile_mode']='fc'
45 if not'type'in kw:
46 kw['type']='fcprogram'
47 if not'compile_filename'in kw:
48 kw['compile_filename']='test.f90'
49 if not'code'in kw:
50 kw['code']=FC_FRAGMENT
51 return self.check(*k,**kw)
52 @conf
53 def fortran_modifier_darwin(conf):
54 v=conf.env
55 v.FCFLAGS_fcshlib=['-fPIC']
56 v.LINKFLAGS_fcshlib=['-dynamiclib']
57 v.fcshlib_PATTERN='lib%s.dylib'
58 v.FRAMEWORKPATH_ST='-F%s'
59 v.FRAMEWORK_ST=['-framework']
60 v.LINKFLAGS_fcstlib=[]
61 v.FCSHLIB_MARKER=''
62 v.FCSTLIB_MARKER=''
63 v.SONAME_ST=''
64 @conf
65 def fortran_modifier_win32(conf):
66 v=conf.env
67 v.fcprogram_PATTERN=v.fcprogram_test_PATTERN='%s.exe'
68 v.fcshlib_PATTERN='%s.dll'
69 v.implib_PATTERN='%s.dll.a'
70 v.IMPLIB_ST='-Wl,--out-implib,%s'
71 v.FCFLAGS_fcshlib=[]
72 v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
73 @conf
74 def fortran_modifier_cygwin(conf):
75 fortran_modifier_win32(conf)
76 v=conf.env
77 v.fcshlib_PATTERN='cyg%s.dll'
78 v.append_value('LINKFLAGS_fcshlib',['-Wl,--enable-auto-image-base'])
79 v.FCFLAGS_fcshlib=[]
80 @conf
81 def check_fortran_dummy_main(self,*k,**kw):
82 if not self.env.CC:
83 self.fatal('A c compiler is required for check_fortran_dummy_main')
84 lst=['MAIN__','__MAIN','_MAIN','MAIN_','MAIN']
85 lst.extend([m.lower()for m in lst])
86 lst.append('')
87 self.start_msg('Detecting whether we need a dummy main')
88 for main in lst:
89 kw['fortran_main']=main
90 try:
91 self.check_cc(fragment='int %s() { return 0; }\n'%(main or'test'),features='c fcprogram',mandatory=True)
92 if not main:
93 self.env.FC_MAIN=-1
94 self.end_msg('no')
95 else:
96 self.env.FC_MAIN=main
97 self.end_msg('yes %s'%main)
98 break
99 except self.errors.ConfigurationError:
100 pass
101 else:
102 self.end_msg('not found')
103 self.fatal('could not detect whether fortran requires a dummy main, see the config.log')
104 GCC_DRIVER_LINE=re.compile('^Driving:')
105 POSIX_STATIC_EXT=re.compile(r'\S+\.a')
106 POSIX_LIB_FLAGS=re.compile(r'-l\S+')
107 @conf
108 def is_link_verbose(self,txt):
109 assert isinstance(txt,str)
110 for line in txt.splitlines():
111 if not GCC_DRIVER_LINE.search(line):
112 if POSIX_STATIC_EXT.search(line)or POSIX_LIB_FLAGS.search(line):
113 return True
114 return False
115 @conf
116 def check_fortran_verbose_flag(self,*k,**kw):
117 self.start_msg('fortran link verbose flag')
118 for x in('-v','--verbose','-verbose','-V'):
119 try:
120 self.check_cc(features='fc fcprogram_test',fragment=FC_FRAGMENT2,compile_filename='test.f',linkflags=[x],mandatory=True)
121 except self.errors.ConfigurationError:
122 pass
123 else:
124 if self.is_link_verbose(self.test_bld.err)or self.is_link_verbose(self.test_bld.out):
125 self.end_msg(x)
126 break
127 else:
128 self.end_msg('failure')
129 self.fatal('Could not obtain the fortran link verbose flag (see config.log)')
130 self.env.FC_VERBOSE_FLAG=x
131 return x
132 LINKFLAGS_IGNORED=[r'-lang*',r'-lcrt[a-zA-Z0-9\.]*\.o',r'-lc$',r'-lSystem',r'-libmil',r'-LIST:*',r'-LNO:*']
133 if os.name=='nt':
134 LINKFLAGS_IGNORED.extend([r'-lfrt*',r'-luser32',r'-lkernel32',r'-ladvapi32',r'-lmsvcrt',r'-lshell32',r'-lmingw',r'-lmoldname'])
135 else:
136 LINKFLAGS_IGNORED.append(r'-lgcc*')
137 RLINKFLAGS_IGNORED=[re.compile(f)for f in LINKFLAGS_IGNORED]
138 def _match_ignore(line):
139 for i in RLINKFLAGS_IGNORED:
140 if i.match(line):
141 return True
142 return False
143 def parse_fortran_link(lines):
144 final_flags=[]
145 for line in lines:
146 if not GCC_DRIVER_LINE.match(line):
147 _parse_flink_line(line,final_flags)
148 return final_flags
149 SPACE_OPTS=re.compile('^-[LRuYz]$')
150 NOSPACE_OPTS=re.compile('^-[RL]')
151 def _parse_flink_token(lexer,token,tmp_flags):
152 if _match_ignore(token):
153 pass
154 elif token.startswith('-lkernel32')and sys.platform=='cygwin':
155 tmp_flags.append(token)
156 elif SPACE_OPTS.match(token):
157 t=lexer.get_token()
158 if t.startswith('P,'):
159 t=t[2:]
160 for opt in t.split(os.pathsep):
161 tmp_flags.append('-L%s'%opt)
162 elif NOSPACE_OPTS.match(token):
163 tmp_flags.append(token)
164 elif POSIX_LIB_FLAGS.match(token):
165 tmp_flags.append(token)
166 else:
167 pass
168 t=lexer.get_token()
169 return t
170 def _parse_flink_line(line,final_flags):
171 lexer=shlex.shlex(line,posix=True)
172 lexer.whitespace_split=True
173 t=lexer.get_token()
174 tmp_flags=[]
175 while t:
176 t=_parse_flink_token(lexer,t,tmp_flags)
177 final_flags.extend(tmp_flags)
178 return final_flags
179 @conf
180 def check_fortran_clib(self,autoadd=True,*k,**kw):
181 if not self.env.FC_VERBOSE_FLAG:
182 self.fatal('env.FC_VERBOSE_FLAG is not set: execute check_fortran_verbose_flag?')
183 self.start_msg('Getting fortran runtime link flags')
184 try:
185 self.check_cc(fragment=FC_FRAGMENT2,compile_filename='test.f',features='fc fcprogram_test',linkflags=[self.env.FC_VERBOSE_FLAG])
186 except Exception:
187 self.end_msg(False)
188 if kw.get('mandatory',True):
189 conf.fatal('Could not find the c library flags')
190 else:
191 out=self.test_bld.err
192 flags=parse_fortran_link(out.splitlines())
193 self.end_msg('ok (%s)'%' '.join(flags))
194 self.env.LINKFLAGS_CLIB=flags
195 return flags
196 return[]
197 def getoutput(conf,cmd,stdin=False):
198 from waflib import Errors
199 if conf.env.env:
200 env=conf.env.env
201 else:
202 env=dict(os.environ)
203 env['LANG']='C'
204 input=stdin and'\n'.encode()or None
205 try:
206 out,err=conf.cmd_and_log(cmd,env=env,output=0,input=input)
207 except Errors.WafError as e:
208 if not(hasattr(e,'stderr')and hasattr(e,'stdout')):
209 raise e
210 else:
211 out=e.stdout
212 err=e.stderr
213 except Exception:
214 conf.fatal('could not determine the compiler version %r'%cmd)
215 return(out,err)
216 ROUTINES_CODE="""\
217 subroutine foobar()
218 return
219 end
220 subroutine foo_bar()
221 return
222 end
223 """
224 MAIN_CODE="""
225 void %(dummy_func_nounder)s(void);
226 void %(dummy_func_under)s(void);
227 int %(main_func_name)s() {
228 %(dummy_func_nounder)s();
229 %(dummy_func_under)s();
230 return 0;
231 }
232 """
233 @feature('link_main_routines_func')
234 @before_method('process_source')
235 def link_main_routines_tg_method(self):
236 def write_test_file(task):
237 task.outputs[0].write(task.generator.code)
238 bld=self.bld
239 bld(rule=write_test_file,target='main.c',code=MAIN_CODE%self.__dict__)
240 bld(rule=write_test_file,target='test.f',code=ROUTINES_CODE)
241 bld(features='fc fcstlib',source='test.f',target='test')
242 bld(features='c fcprogram',source='main.c',target='app',use='test')
243 def mangling_schemes():
244 for u in('_',''):
245 for du in('','_'):
246 for c in("lower","upper"):
247 yield(u,du,c)
248 def mangle_name(u,du,c,name):
249 return getattr(name,c)()+u+(name.find('_')!=-1 and du or'')
250 @conf
251 def check_fortran_mangling(self,*k,**kw):
252 if not self.env.CC:
253 self.fatal('A c compiler is required for link_main_routines')
254 if not self.env.FC:
255 self.fatal('A fortran compiler is required for link_main_routines')
256 if not self.env.FC_MAIN:
257 self.fatal('Checking for mangling requires self.env.FC_MAIN (execute "check_fortran_dummy_main" first?)')
258 self.start_msg('Getting fortran mangling scheme')
259 for(u,du,c)in mangling_schemes():
260 try:
261 self.check_cc(compile_filename=[],features='link_main_routines_func',msg='nomsg',errmsg='nomsg',dummy_func_nounder=mangle_name(u,du,c,'foobar'),dummy_func_under=mangle_name(u,du,c,'foo_bar'),main_func_name=self.env.FC_MAIN)
262 except self.errors.ConfigurationError:
263 pass
264 else:
265 self.end_msg("ok ('%s', '%s', '%s-case')"%(u,du,c))
266 self.env.FORTRAN_MANGLING=(u,du,c)
267 break
268 else:
269 self.end_msg(False)
270 self.fatal('mangler not found')
271 return(u,du,c)
272 @feature('pyext')
273 @before_method('propagate_uselib_vars','apply_link')
274 def set_lib_pat(self):
275 self.env.fcshlib_PATTERN=self.env.pyext_PATTERN
276 @conf
277 def detect_openmp(self):
278 for x in('-fopenmp','-openmp','-mp','-xopenmp','-omp','-qsmp=omp'):
279 try:
280 self.check_fc(msg='Checking for OpenMP flag %s'%x,fragment='program main\n call omp_get_num_threads()\nend program main',fcflags=x,linkflags=x,uselib_store='OPENMP')
281 except self.errors.ConfigurationError:
282 pass
283 else:
284 break
285 else:
286 self.fatal('Could not find OpenMP')
287 @conf
288 def check_gfortran_o_space(self):
289 if self.env.FC_NAME!='GFORTRAN'or int(self.env.FC_VERSION[0])>4:
290 return
291 self.env.stash()
292 self.env.FCLNK_TGT_F=['-o','']
293 try:
294 self.check_fc(msg='Checking if the -o link must be split from arguments',fragment=FC_FRAGMENT,features='fc fcshlib')
295 except self.errors.ConfigurationError:
296 self.env.revert()
297 else:
298 self.env.commit()
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import re
5 INC_REGEX=r"""(?:^|['">]\s*;)\s*(?:|#\s*)INCLUDE\s+(?:\w+_)?[<"'](.+?)(?=["'>])"""
6 USE_REGEX=r"""(?:^|;)\s*USE(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(\w+)"""
7 MOD_REGEX=r"""(?:^|;)\s*MODULE(?!\s+(?:PROCEDURE|SUBROUTINE|FUNCTION))\s+(\w+)"""
8 SMD_REGEX=r"""(?:^|;)\s*SUBMODULE\s*\(([\w:]+)\)\s*(\w+)"""
9 re_inc=re.compile(INC_REGEX,re.I)
10 re_use=re.compile(USE_REGEX,re.I)
11 re_mod=re.compile(MOD_REGEX,re.I)
12 re_smd=re.compile(SMD_REGEX,re.I)
13 class fortran_parser(object):
14 def __init__(self,incpaths):
15 self.seen=[]
16 self.nodes=[]
17 self.names=[]
18 self.incpaths=incpaths
19 def find_deps(self,node):
20 txt=node.read()
21 incs=[]
22 uses=[]
23 mods=[]
24 for line in txt.splitlines():
25 m=re_inc.search(line)
26 if m:
27 incs.append(m.group(1))
28 m=re_use.search(line)
29 if m:
30 uses.append(m.group(1))
31 m=re_mod.search(line)
32 if m:
33 mods.append(m.group(1))
34 m=re_smd.search(line)
35 if m:
36 uses.append(m.group(1))
37 mods.append('{0}:{1}'.format(m.group(1),m.group(2)))
38 return(incs,uses,mods)
39 def start(self,node):
40 self.waiting=[node]
41 while self.waiting:
42 nd=self.waiting.pop(0)
43 self.iter(nd)
44 def iter(self,node):
45 incs,uses,mods=self.find_deps(node)
46 for x in incs:
47 if x in self.seen:
48 continue
49 self.seen.append(x)
50 self.tryfind_header(x)
51 for x in uses:
52 name="USE@%s"%x
53 if not name in self.names:
54 self.names.append(name)
55 for x in mods:
56 name="MOD@%s"%x
57 if not name in self.names:
58 self.names.append(name)
59 def tryfind_header(self,filename):
60 found=None
61 for n in self.incpaths:
62 found=n.find_resource(filename)
63 if found:
64 self.nodes.append(found)
65 self.waiting.append(found)
66 break
67 if not found:
68 if not filename in self.names:
69 self.names.append(filename)
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os,re
5 from waflib import Task,TaskGen
6 from waflib.Tools import ccroot
7 def decide_ext(self,node):
8 if'cxx'in self.features:
9 return['.lex.cc']
10 return['.lex.c']
11 def flexfun(tsk):
12 env=tsk.env
13 bld=tsk.generator.bld
14 wd=bld.variant_dir
15 def to_list(xx):
16 if isinstance(xx,str):
17 return[xx]
18 return xx
19 tsk.last_cmd=lst=[]
20 lst.extend(to_list(env.FLEX))
21 lst.extend(to_list(env.FLEXFLAGS))
22 inputs=[a.path_from(tsk.get_cwd())for a in tsk.inputs]
23 if env.FLEX_MSYS:
24 inputs=[x.replace(os.sep,'/')for x in inputs]
25 lst.extend(inputs)
26 lst=[x for x in lst if x]
27 txt=bld.cmd_and_log(lst,cwd=wd,env=env.env or None,quiet=0)
28 tsk.outputs[0].write(txt.replace('\r\n','\n').replace('\r','\n'))
29 TaskGen.declare_chain(name='flex',rule=flexfun,ext_in='.l',decider=decide_ext,)
30 Task.classes['flex'].vars=['FLEXFLAGS','FLEX']
31 ccroot.USELIB_VARS['c'].add('FLEXFLAGS')
32 ccroot.USELIB_VARS['cxx'].add('FLEXFLAGS')
33 def configure(conf):
34 conf.find_program('flex',var='FLEX')
35 conf.env.FLEXFLAGS=['-t']
36 if re.search(r"\\msys\\[0-9.]+\\bin\\flex.exe$",conf.env.FLEX[0]):
37 conf.env.FLEX_MSYS=True
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import re
5 from waflib import Utils
6 from waflib.Tools import fc,fc_config,fc_scan,ar
7 from waflib.Configure import conf
8 @conf
9 def find_g95(conf):
10 fc=conf.find_program('g95',var='FC')
11 conf.get_g95_version(fc)
12 conf.env.FC_NAME='G95'
13 @conf
14 def g95_flags(conf):
15 v=conf.env
16 v.FCFLAGS_fcshlib=['-fPIC']
17 v.FORTRANMODFLAG=['-fmod=','']
18 v.FCFLAGS_DEBUG=['-Werror']
19 @conf
20 def g95_modifier_win32(conf):
21 fc_config.fortran_modifier_win32(conf)
22 @conf
23 def g95_modifier_cygwin(conf):
24 fc_config.fortran_modifier_cygwin(conf)
25 @conf
26 def g95_modifier_darwin(conf):
27 fc_config.fortran_modifier_darwin(conf)
28 @conf
29 def g95_modifier_platform(conf):
30 dest_os=conf.env.DEST_OS or Utils.unversioned_sys_platform()
31 g95_modifier_func=getattr(conf,'g95_modifier_'+dest_os,None)
32 if g95_modifier_func:
33 g95_modifier_func()
34 @conf
35 def get_g95_version(conf,fc):
36 version_re=re.compile(r"g95\s*(?P<major>\d*)\.(?P<minor>\d*)").search
37 cmd=fc+['--version']
38 out,err=fc_config.getoutput(conf,cmd,stdin=False)
39 if out:
40 match=version_re(out)
41 else:
42 match=version_re(err)
43 if not match:
44 conf.fatal('cannot determine g95 version')
45 k=match.groupdict()
46 conf.env.FC_VERSION=(k['major'],k['minor'])
47 def configure(conf):
48 conf.find_g95()
49 conf.find_ar()
50 conf.fc_flags()
51 conf.fc_add_flags()
52 conf.g95_flags()
53 conf.g95_modifier_platform()
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import waflib.Tools.asm
5 from waflib.Tools import ar
6 def configure(conf):
7 conf.find_program(['gas','gcc'],var='AS')
8 conf.env.AS_TGT_F=['-c','-o']
9 conf.env.ASLNK_TGT_F=['-o']
10 conf.find_ar()
11 conf.load('asm')
12 conf.env.ASM_NAME='gas'
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib.Tools import ccroot,ar
5 from waflib.Configure import conf
6 @conf
7 def find_gcc(conf):
8 cc=conf.find_program(['gcc','cc'],var='CC')
9 conf.get_cc_version(cc,gcc=True)
10 conf.env.CC_NAME='gcc'
11 @conf
12 def gcc_common_flags(conf):
13 v=conf.env
14 v.CC_SRC_F=[]
15 v.CC_TGT_F=['-c','-o']
16 if not v.LINK_CC:
17 v.LINK_CC=v.CC
18 v.CCLNK_SRC_F=[]
19 v.CCLNK_TGT_F=['-o']
20 v.CPPPATH_ST='-I%s'
21 v.DEFINES_ST='-D%s'
22 v.LIB_ST='-l%s'
23 v.LIBPATH_ST='-L%s'
24 v.STLIB_ST='-l%s'
25 v.STLIBPATH_ST='-L%s'
26 v.RPATH_ST='-Wl,-rpath,%s'
27 v.SONAME_ST='-Wl,-h,%s'
28 v.SHLIB_MARKER='-Wl,-Bdynamic'
29 v.STLIB_MARKER='-Wl,-Bstatic'
30 v.cprogram_PATTERN='%s'
31 v.CFLAGS_cshlib=['-fPIC']
32 v.LINKFLAGS_cshlib=['-shared']
33 v.cshlib_PATTERN='lib%s.so'
34 v.LINKFLAGS_cstlib=['-Wl,-Bstatic']
35 v.cstlib_PATTERN='lib%s.a'
36 v.LINKFLAGS_MACBUNDLE=['-bundle','-undefined','dynamic_lookup']
37 v.CFLAGS_MACBUNDLE=['-fPIC']
38 v.macbundle_PATTERN='%s.bundle'
39 @conf
40 def gcc_modifier_win32(conf):
41 v=conf.env
42 v.cprogram_PATTERN='%s.exe'
43 v.cshlib_PATTERN='%s.dll'
44 v.implib_PATTERN='%s.dll.a'
45 v.IMPLIB_ST='-Wl,--out-implib,%s'
46 v.CFLAGS_cshlib=[]
47 v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
48 @conf
49 def gcc_modifier_cygwin(conf):
50 gcc_modifier_win32(conf)
51 v=conf.env
52 v.cshlib_PATTERN='cyg%s.dll'
53 v.append_value('LINKFLAGS_cshlib',['-Wl,--enable-auto-image-base'])
54 v.CFLAGS_cshlib=[]
55 @conf
56 def gcc_modifier_darwin(conf):
57 v=conf.env
58 v.CFLAGS_cshlib=['-fPIC']
59 v.LINKFLAGS_cshlib=['-dynamiclib']
60 v.cshlib_PATTERN='lib%s.dylib'
61 v.FRAMEWORKPATH_ST='-F%s'
62 v.FRAMEWORK_ST=['-framework']
63 v.ARCH_ST=['-arch']
64 v.LINKFLAGS_cstlib=[]
65 v.SHLIB_MARKER=[]
66 v.STLIB_MARKER=[]
67 v.SONAME_ST=[]
68 @conf
69 def gcc_modifier_aix(conf):
70 v=conf.env
71 v.LINKFLAGS_cprogram=['-Wl,-brtl']
72 v.LINKFLAGS_cshlib=['-shared','-Wl,-brtl,-bexpfull']
73 v.SHLIB_MARKER=[]
74 @conf
75 def gcc_modifier_hpux(conf):
76 v=conf.env
77 v.SHLIB_MARKER=[]
78 v.STLIB_MARKER=[]
79 v.CFLAGS_cshlib=['-fPIC','-DPIC']
80 v.cshlib_PATTERN='lib%s.sl'
81 @conf
82 def gcc_modifier_openbsd(conf):
83 conf.env.SONAME_ST=[]
84 @conf
85 def gcc_modifier_osf1V(conf):
86 v=conf.env
87 v.SHLIB_MARKER=[]
88 v.STLIB_MARKER=[]
89 v.SONAME_ST=[]
90 @conf
91 def gcc_modifier_platform(conf):
92 gcc_modifier_func=getattr(conf,'gcc_modifier_'+conf.env.DEST_OS,None)
93 if gcc_modifier_func:
94 gcc_modifier_func()
95 def configure(conf):
96 conf.find_gcc()
97 conf.find_ar()
98 conf.gcc_common_flags()
99 conf.gcc_modifier_platform()
100 conf.cc_load_tools()
101 conf.cc_add_flags()
102 conf.link_add_flags()
103 conf.check_gcc_o_space()
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib.Tools import ar,d
5 from waflib.Configure import conf
6 @conf
7 def find_gdc(conf):
8 conf.find_program('gdc',var='D')
9 out=conf.cmd_and_log(conf.env.D+['--version'])
10 if out.find("gdc")==-1:
11 conf.fatal("detected compiler is not gdc")
12 @conf
13 def common_flags_gdc(conf):
14 v=conf.env
15 v.DFLAGS=[]
16 v.D_SRC_F=['-c']
17 v.D_TGT_F='-o%s'
18 v.D_LINKER=v.D
19 v.DLNK_SRC_F=''
20 v.DLNK_TGT_F='-o%s'
21 v.DINC_ST='-I%s'
22 v.DSHLIB_MARKER=v.DSTLIB_MARKER=''
23 v.DSTLIB_ST=v.DSHLIB_ST='-l%s'
24 v.DSTLIBPATH_ST=v.DLIBPATH_ST='-L%s'
25 v.LINKFLAGS_dshlib=['-shared']
26 v.DHEADER_ext='.di'
27 v.DFLAGS_d_with_header='-fintfc'
28 v.D_HDR_F='-fintfc-file=%s'
29 def configure(conf):
30 conf.find_gdc()
31 conf.load('ar')
32 conf.load('d')
33 conf.common_flags_gdc()
34 conf.d_platform_flags()
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import re
5 from waflib import Utils
6 from waflib.Tools import fc,fc_config,fc_scan,ar
7 from waflib.Configure import conf
8 @conf
9 def find_gfortran(conf):
10 fc=conf.find_program(['gfortran','g77'],var='FC')
11 conf.get_gfortran_version(fc)
12 conf.env.FC_NAME='GFORTRAN'
13 @conf
14 def gfortran_flags(conf):
15 v=conf.env
16 v.FCFLAGS_fcshlib=['-fPIC']
17 v.FORTRANMODFLAG=['-J','']
18 v.FCFLAGS_DEBUG=['-Werror']
19 @conf
20 def gfortran_modifier_win32(conf):
21 fc_config.fortran_modifier_win32(conf)
22 @conf
23 def gfortran_modifier_cygwin(conf):
24 fc_config.fortran_modifier_cygwin(conf)
25 @conf
26 def gfortran_modifier_darwin(conf):
27 fc_config.fortran_modifier_darwin(conf)
28 @conf
29 def gfortran_modifier_platform(conf):
30 dest_os=conf.env.DEST_OS or Utils.unversioned_sys_platform()
31 gfortran_modifier_func=getattr(conf,'gfortran_modifier_'+dest_os,None)
32 if gfortran_modifier_func:
33 gfortran_modifier_func()
34 @conf
35 def get_gfortran_version(conf,fc):
36 version_re=re.compile(r"GNU\s*Fortran",re.I).search
37 cmd=fc+['--version']
38 out,err=fc_config.getoutput(conf,cmd,stdin=False)
39 if out:
40 match=version_re(out)
41 else:
42 match=version_re(err)
43 if not match:
44 conf.fatal('Could not determine the compiler type')
45 cmd=fc+['-dM','-E','-']
46 out,err=fc_config.getoutput(conf,cmd,stdin=True)
47 if out.find('__GNUC__')<0:
48 conf.fatal('Could not determine the compiler type')
49 k={}
50 out=out.splitlines()
51 import shlex
52 for line in out:
53 lst=shlex.split(line)
54 if len(lst)>2:
55 key=lst[1]
56 val=lst[2]
57 k[key]=val
58 def isD(var):
59 return var in k
60 def isT(var):
61 return var in k and k[var]!='0'
62 conf.env.FC_VERSION=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__'])
63 def configure(conf):
64 conf.find_gfortran()
65 conf.find_ar()
66 conf.fc_flags()
67 conf.fc_add_flags()
68 conf.gfortran_flags()
69 conf.gfortran_modifier_platform()
70 conf.check_gfortran_o_space()
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os
5 import functools
6 from waflib import Context,Task,Utils,Options,Errors,Logs
7 from waflib.TaskGen import taskgen_method,before_method,feature,extension
8 from waflib.Configure import conf
9 @taskgen_method
10 def add_marshal_file(self,filename,prefix):
11 if not hasattr(self,'marshal_list'):
12 self.marshal_list=[]
13 self.meths.append('process_marshal')
14 self.marshal_list.append((filename,prefix))
15 @before_method('process_source')
16 def process_marshal(self):
17 for f,prefix in getattr(self,'marshal_list',[]):
18 node=self.path.find_resource(f)
19 if not node:
20 raise Errors.WafError('file not found %r'%f)
21 h_node=node.change_ext('.h')
22 c_node=node.change_ext('.c')
23 task=self.create_task('glib_genmarshal',node,[h_node,c_node])
24 task.env.GLIB_GENMARSHAL_PREFIX=prefix
25 self.source=self.to_nodes(getattr(self,'source',[]))
26 self.source.append(c_node)
27 class glib_genmarshal(Task.Task):
28 vars=['GLIB_GENMARSHAL_PREFIX','GLIB_GENMARSHAL']
29 color='BLUE'
30 ext_out=['.h']
31 def run(self):
32 bld=self.generator.bld
33 get=self.env.get_flat
34 cmd1="%s %s --prefix=%s --header > %s"%(get('GLIB_GENMARSHAL'),self.inputs[0].srcpath(),get('GLIB_GENMARSHAL_PREFIX'),self.outputs[0].abspath())
35 ret=bld.exec_command(cmd1)
36 if ret:
37 return ret
38 c='''#include "%s"\n'''%self.outputs[0].name
39 self.outputs[1].write(c)
40 cmd2="%s %s --prefix=%s --body >> %s"%(get('GLIB_GENMARSHAL'),self.inputs[0].srcpath(),get('GLIB_GENMARSHAL_PREFIX'),self.outputs[1].abspath())
41 return bld.exec_command(cmd2)
42 @taskgen_method
43 def add_enums_from_template(self,source='',target='',template='',comments=''):
44 if not hasattr(self,'enums_list'):
45 self.enums_list=[]
46 self.meths.append('process_enums')
47 self.enums_list.append({'source':source,'target':target,'template':template,'file-head':'','file-prod':'','file-tail':'','enum-prod':'','value-head':'','value-prod':'','value-tail':'','comments':comments})
48 @taskgen_method
49 def add_enums(self,source='',target='',file_head='',file_prod='',file_tail='',enum_prod='',value_head='',value_prod='',value_tail='',comments=''):
50 if not hasattr(self,'enums_list'):
51 self.enums_list=[]
52 self.meths.append('process_enums')
53 self.enums_list.append({'source':source,'template':'','target':target,'file-head':file_head,'file-prod':file_prod,'file-tail':file_tail,'enum-prod':enum_prod,'value-head':value_head,'value-prod':value_prod,'value-tail':value_tail,'comments':comments})
54 @before_method('process_source')
55 def process_enums(self):
56 for enum in getattr(self,'enums_list',[]):
57 task=self.create_task('glib_mkenums')
58 env=task.env
59 inputs=[]
60 source_list=self.to_list(enum['source'])
61 if not source_list:
62 raise Errors.WafError('missing source '+str(enum))
63 source_list=[self.path.find_resource(k)for k in source_list]
64 inputs+=source_list
65 env.GLIB_MKENUMS_SOURCE=[k.abspath()for k in source_list]
66 if not enum['target']:
67 raise Errors.WafError('missing target '+str(enum))
68 tgt_node=self.path.find_or_declare(enum['target'])
69 if tgt_node.name.endswith('.c'):
70 self.source.append(tgt_node)
71 env.GLIB_MKENUMS_TARGET=tgt_node.abspath()
72 options=[]
73 if enum['template']:
74 template_node=self.path.find_resource(enum['template'])
75 options.append('--template %s'%(template_node.abspath()))
76 inputs.append(template_node)
77 params={'file-head':'--fhead','file-prod':'--fprod','file-tail':'--ftail','enum-prod':'--eprod','value-head':'--vhead','value-prod':'--vprod','value-tail':'--vtail','comments':'--comments'}
78 for param,option in params.items():
79 if enum[param]:
80 options.append('%s %r'%(option,enum[param]))
81 env.GLIB_MKENUMS_OPTIONS=' '.join(options)
82 task.set_inputs(inputs)
83 task.set_outputs(tgt_node)
84 class glib_mkenums(Task.Task):
85 run_str='${GLIB_MKENUMS} ${GLIB_MKENUMS_OPTIONS} ${GLIB_MKENUMS_SOURCE} > ${GLIB_MKENUMS_TARGET}'
86 color='PINK'
87 ext_out=['.h']
88 @taskgen_method
89 def add_settings_schemas(self,filename_list):
90 if not hasattr(self,'settings_schema_files'):
91 self.settings_schema_files=[]
92 if not isinstance(filename_list,list):
93 filename_list=[filename_list]
94 self.settings_schema_files.extend(filename_list)
95 @taskgen_method
96 def add_settings_enums(self,namespace,filename_list):
97 if hasattr(self,'settings_enum_namespace'):
98 raise Errors.WafError("Tried to add gsettings enums to %r more than once"%self.name)
99 self.settings_enum_namespace=namespace
100 if not isinstance(filename_list,list):
101 filename_list=[filename_list]
102 self.settings_enum_files=filename_list
103 @feature('glib2')
104 def process_settings(self):
105 enums_tgt_node=[]
106 install_files=[]
107 settings_schema_files=getattr(self,'settings_schema_files',[])
108 if settings_schema_files and not self.env.GLIB_COMPILE_SCHEMAS:
109 raise Errors.WafError("Unable to process GSettings schemas - glib-compile-schemas was not found during configure")
110 if hasattr(self,'settings_enum_files'):
111 enums_task=self.create_task('glib_mkenums')
112 source_list=self.settings_enum_files
113 source_list=[self.path.find_resource(k)for k in source_list]
114 enums_task.set_inputs(source_list)
115 enums_task.env.GLIB_MKENUMS_SOURCE=[k.abspath()for k in source_list]
116 target=self.settings_enum_namespace+'.enums.xml'
117 tgt_node=self.path.find_or_declare(target)
118 enums_task.set_outputs(tgt_node)
119 enums_task.env.GLIB_MKENUMS_TARGET=tgt_node.abspath()
120 enums_tgt_node=[tgt_node]
121 install_files.append(tgt_node)
122 options='--comments "<!-- @comment@ -->" --fhead "<schemalist>" --vhead " <@type@ id=\\"%s.@EnumName@\\">" --vprod " <value nick=\\"@valuenick@\\" value=\\"@valuenum@\\"/>" --vtail " </@type@>" --ftail "</schemalist>" '%(self.settings_enum_namespace)
123 enums_task.env.GLIB_MKENUMS_OPTIONS=options
124 for schema in settings_schema_files:
125 schema_task=self.create_task('glib_validate_schema')
126 schema_node=self.path.find_resource(schema)
127 if not schema_node:
128 raise Errors.WafError("Cannot find the schema file %r"%schema)
129 install_files.append(schema_node)
130 source_list=enums_tgt_node+[schema_node]
131 schema_task.set_inputs(source_list)
132 schema_task.env.GLIB_COMPILE_SCHEMAS_OPTIONS=[("--schema-file="+k.abspath())for k in source_list]
133 target_node=schema_node.change_ext('.xml.valid')
134 schema_task.set_outputs(target_node)
135 schema_task.env.GLIB_VALIDATE_SCHEMA_OUTPUT=target_node.abspath()
136 def compile_schemas_callback(bld):
137 if not bld.is_install:
138 return
139 compile_schemas=Utils.to_list(bld.env.GLIB_COMPILE_SCHEMAS)
140 destdir=Options.options.destdir
141 paths=bld._compile_schemas_registered
142 if destdir:
143 paths=(os.path.join(destdir,path.lstrip(os.sep))for path in paths)
144 for path in paths:
145 Logs.pprint('YELLOW','Updating GSettings schema cache %r'%path)
146 if self.bld.exec_command(compile_schemas+[path]):
147 Logs.warn('Could not update GSettings schema cache %r'%path)
148 if self.bld.is_install:
149 schemadir=self.env.GSETTINGSSCHEMADIR
150 if not schemadir:
151 raise Errors.WafError('GSETTINGSSCHEMADIR not defined (should have been set up automatically during configure)')
152 if install_files:
153 self.add_install_files(install_to=schemadir,install_from=install_files)
154 registered_schemas=getattr(self.bld,'_compile_schemas_registered',None)
155 if not registered_schemas:
156 registered_schemas=self.bld._compile_schemas_registered=set()
157 self.bld.add_post_fun(compile_schemas_callback)
158 registered_schemas.add(schemadir)
159 class glib_validate_schema(Task.Task):
160 run_str='rm -f ${GLIB_VALIDATE_SCHEMA_OUTPUT} && ${GLIB_COMPILE_SCHEMAS} --dry-run ${GLIB_COMPILE_SCHEMAS_OPTIONS} && touch ${GLIB_VALIDATE_SCHEMA_OUTPUT}'
161 color='PINK'
162 @extension('.gresource.xml')
163 def process_gresource_source(self,node):
164 if not self.env.GLIB_COMPILE_RESOURCES:
165 raise Errors.WafError("Unable to process GResource file - glib-compile-resources was not found during configure")
166 if'gresource'in self.features:
167 return
168 h_node=node.change_ext('_xml.h')
169 c_node=node.change_ext('_xml.c')
170 self.create_task('glib_gresource_source',node,[h_node,c_node])
171 self.source.append(c_node)
172 @feature('gresource')
173 def process_gresource_bundle(self):
174 for i in self.to_list(self.source):
175 node=self.path.find_resource(i)
176 task=self.create_task('glib_gresource_bundle',node,node.change_ext(''))
177 inst_to=getattr(self,'install_path',None)
178 if inst_to:
179 self.add_install_files(install_to=inst_to,install_from=task.outputs)
180 class glib_gresource_base(Task.Task):
181 color='BLUE'
182 base_cmd='${GLIB_COMPILE_RESOURCES} --sourcedir=${SRC[0].parent.srcpath()} --sourcedir=${SRC[0].bld_dir()}'
183 def scan(self):
184 bld=self.generator.bld
185 kw={}
186 kw['cwd']=self.get_cwd()
187 kw['quiet']=Context.BOTH
188 cmd=Utils.subst_vars('${GLIB_COMPILE_RESOURCES} --sourcedir=%s --sourcedir=%s --generate-dependencies %s'%(self.inputs[0].parent.srcpath(),self.inputs[0].bld_dir(),self.inputs[0].bldpath()),self.env)
189 output=bld.cmd_and_log(cmd,**kw)
190 nodes=[]
191 names=[]
192 for dep in output.splitlines():
193 if dep:
194 node=bld.bldnode.find_node(dep)
195 if node:
196 nodes.append(node)
197 else:
198 names.append(dep)
199 return(nodes,names)
200 class glib_gresource_source(glib_gresource_base):
201 vars=['GLIB_COMPILE_RESOURCES']
202 fun_h=Task.compile_fun_shell(glib_gresource_base.base_cmd+' --target=${TGT[0].abspath()} --generate-header ${SRC}')
203 fun_c=Task.compile_fun_shell(glib_gresource_base.base_cmd+' --target=${TGT[1].abspath()} --generate-source ${SRC}')
204 ext_out=['.h']
205 def run(self):
206 return self.fun_h[0](self)or self.fun_c[0](self)
207 class glib_gresource_bundle(glib_gresource_base):
208 run_str=glib_gresource_base.base_cmd+' --target=${TGT} ${SRC}'
209 shell=True
210 @conf
211 def find_glib_genmarshal(conf):
212 conf.find_program('glib-genmarshal',var='GLIB_GENMARSHAL')
213 @conf
214 def find_glib_mkenums(conf):
215 if not conf.env.PERL:
216 conf.find_program('perl',var='PERL')
217 conf.find_program('glib-mkenums',interpreter='PERL',var='GLIB_MKENUMS')
218 @conf
219 def find_glib_compile_schemas(conf):
220 conf.find_program('glib-compile-schemas',var='GLIB_COMPILE_SCHEMAS')
221 def getstr(varname):
222 return getattr(Options.options,varname,getattr(conf.env,varname,''))
223 gsettingsschemadir=getstr('GSETTINGSSCHEMADIR')
224 if not gsettingsschemadir:
225 datadir=getstr('DATADIR')
226 if not datadir:
227 prefix=conf.env.PREFIX
228 datadir=os.path.join(prefix,'share')
229 gsettingsschemadir=os.path.join(datadir,'glib-2.0','schemas')
230 conf.env.GSETTINGSSCHEMADIR=gsettingsschemadir
231 @conf
232 def find_glib_compile_resources(conf):
233 conf.find_program('glib-compile-resources',var='GLIB_COMPILE_RESOURCES')
234 def configure(conf):
235 conf.find_glib_genmarshal()
236 conf.find_glib_mkenums()
237 conf.find_glib_compile_schemas(mandatory=False)
238 conf.find_glib_compile_resources(mandatory=False)
239 def options(opt):
240 gr=opt.add_option_group('Installation directories')
241 gr.add_option('--gsettingsschemadir',help='GSettings schema location [DATADIR/glib-2.0/schemas]',default='',dest='GSETTINGSSCHEMADIR')
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os,re
5 from waflib import Utils,Options,Context
6 gnuopts='''
7 bindir, user commands, ${EXEC_PREFIX}/bin
8 sbindir, system binaries, ${EXEC_PREFIX}/sbin
9 libexecdir, program-specific binaries, ${EXEC_PREFIX}/libexec
10 sysconfdir, host-specific configuration, ${PREFIX}/etc
11 sharedstatedir, architecture-independent variable data, ${PREFIX}/com
12 localstatedir, variable data, ${PREFIX}/var
13 libdir, object code libraries, ${EXEC_PREFIX}/lib%s
14 includedir, header files, ${PREFIX}/include
15 oldincludedir, header files for non-GCC compilers, /usr/include
16 datarootdir, architecture-independent data root, ${PREFIX}/share
17 datadir, architecture-independent data, ${DATAROOTDIR}
18 infodir, GNU "info" documentation, ${DATAROOTDIR}/info
19 localedir, locale-dependent data, ${DATAROOTDIR}/locale
20 mandir, manual pages, ${DATAROOTDIR}/man
21 docdir, documentation root, ${DATAROOTDIR}/doc/${PACKAGE}
22 htmldir, HTML documentation, ${DOCDIR}
23 dvidir, DVI documentation, ${DOCDIR}
24 pdfdir, PDF documentation, ${DOCDIR}
25 psdir, PostScript documentation, ${DOCDIR}
26 '''%Utils.lib64()
27 _options=[x.split(', ')for x in gnuopts.splitlines()if x]
28 def configure(conf):
29 def get_param(varname,default):
30 return getattr(Options.options,varname,'')or default
31 env=conf.env
32 env.LIBDIR=env.BINDIR=[]
33 env.EXEC_PREFIX=get_param('EXEC_PREFIX',env.PREFIX)
34 env.PACKAGE=getattr(Context.g_module,'APPNAME',None)or env.PACKAGE
35 complete=False
36 iter=0
37 while not complete and iter<len(_options)+1:
38 iter+=1
39 complete=True
40 for name,help,default in _options:
41 name=name.upper()
42 if not env[name]:
43 try:
44 env[name]=Utils.subst_vars(get_param(name,default).replace('/',os.sep),env)
45 except TypeError:
46 complete=False
47 if not complete:
48 lst=[x for x,_,_ in _options if not env[x.upper()]]
49 raise conf.errors.WafError('Variable substitution failure %r'%lst)
50 def options(opt):
51 inst_dir=opt.add_option_group('Installation prefix','By default, "waf install" will put the files in\
52 "/usr/local/bin", "/usr/local/lib" etc. An installation prefix other\
53 than "/usr/local" can be given using "--prefix", for example "--prefix=$HOME"')
54 for k in('--prefix','--destdir'):
55 option=opt.parser.get_option(k)
56 if option:
57 opt.parser.remove_option(k)
58 inst_dir.add_option(option)
59 inst_dir.add_option('--exec-prefix',help='installation prefix for binaries [PREFIX]',default='',dest='EXEC_PREFIX')
60 dirs_options=opt.add_option_group('Installation directories')
61 for name,help,default in _options:
62 option_name='--'+name
63 str_default=default
64 str_help='%s [%s]'%(help,re.sub(r'\$\{([^}]+)\}',r'\1',str_default))
65 dirs_options.add_option(option_name,help=str_help,default='',dest=name.upper())
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib.Tools import ccroot,ar
5 from waflib.Configure import conf
6 @conf
7 def find_gxx(conf):
8 cxx=conf.find_program(['g++','c++'],var='CXX')
9 conf.get_cc_version(cxx,gcc=True)
10 conf.env.CXX_NAME='gcc'
11 @conf
12 def gxx_common_flags(conf):
13 v=conf.env
14 v.CXX_SRC_F=[]
15 v.CXX_TGT_F=['-c','-o']
16 if not v.LINK_CXX:
17 v.LINK_CXX=v.CXX
18 v.CXXLNK_SRC_F=[]
19 v.CXXLNK_TGT_F=['-o']
20 v.CPPPATH_ST='-I%s'
21 v.DEFINES_ST='-D%s'
22 v.LIB_ST='-l%s'
23 v.LIBPATH_ST='-L%s'
24 v.STLIB_ST='-l%s'
25 v.STLIBPATH_ST='-L%s'
26 v.RPATH_ST='-Wl,-rpath,%s'
27 v.SONAME_ST='-Wl,-h,%s'
28 v.SHLIB_MARKER='-Wl,-Bdynamic'
29 v.STLIB_MARKER='-Wl,-Bstatic'
30 v.cxxprogram_PATTERN='%s'
31 v.CXXFLAGS_cxxshlib=['-fPIC']
32 v.LINKFLAGS_cxxshlib=['-shared']
33 v.cxxshlib_PATTERN='lib%s.so'
34 v.LINKFLAGS_cxxstlib=['-Wl,-Bstatic']
35 v.cxxstlib_PATTERN='lib%s.a'
36 v.LINKFLAGS_MACBUNDLE=['-bundle','-undefined','dynamic_lookup']
37 v.CXXFLAGS_MACBUNDLE=['-fPIC']
38 v.macbundle_PATTERN='%s.bundle'
39 @conf
40 def gxx_modifier_win32(conf):
41 v=conf.env
42 v.cxxprogram_PATTERN='%s.exe'
43 v.cxxshlib_PATTERN='%s.dll'
44 v.implib_PATTERN='%s.dll.a'
45 v.IMPLIB_ST='-Wl,--out-implib,%s'
46 v.CXXFLAGS_cxxshlib=[]
47 v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
48 @conf
49 def gxx_modifier_cygwin(conf):
50 gxx_modifier_win32(conf)
51 v=conf.env
52 v.cxxshlib_PATTERN='cyg%s.dll'
53 v.append_value('LINKFLAGS_cxxshlib',['-Wl,--enable-auto-image-base'])
54 v.CXXFLAGS_cxxshlib=[]
55 @conf
56 def gxx_modifier_darwin(conf):
57 v=conf.env
58 v.CXXFLAGS_cxxshlib=['-fPIC']
59 v.LINKFLAGS_cxxshlib=['-dynamiclib']
60 v.cxxshlib_PATTERN='lib%s.dylib'
61 v.FRAMEWORKPATH_ST='-F%s'
62 v.FRAMEWORK_ST=['-framework']
63 v.ARCH_ST=['-arch']
64 v.LINKFLAGS_cxxstlib=[]
65 v.SHLIB_MARKER=[]
66 v.STLIB_MARKER=[]
67 v.SONAME_ST=[]
68 @conf
69 def gxx_modifier_aix(conf):
70 v=conf.env
71 v.LINKFLAGS_cxxprogram=['-Wl,-brtl']
72 v.LINKFLAGS_cxxshlib=['-shared','-Wl,-brtl,-bexpfull']
73 v.SHLIB_MARKER=[]
74 @conf
75 def gxx_modifier_hpux(conf):
76 v=conf.env
77 v.SHLIB_MARKER=[]
78 v.STLIB_MARKER=[]
79 v.CFLAGS_cxxshlib=['-fPIC','-DPIC']
80 v.cxxshlib_PATTERN='lib%s.sl'
81 @conf
82 def gxx_modifier_openbsd(conf):
83 conf.env.SONAME_ST=[]
84 @conf
85 def gcc_modifier_osf1V(conf):
86 v=conf.env
87 v.SHLIB_MARKER=[]
88 v.STLIB_MARKER=[]
89 v.SONAME_ST=[]
90 @conf
91 def gxx_modifier_platform(conf):
92 gxx_modifier_func=getattr(conf,'gxx_modifier_'+conf.env.DEST_OS,None)
93 if gxx_modifier_func:
94 gxx_modifier_func()
95 def configure(conf):
96 conf.find_gxx()
97 conf.find_ar()
98 conf.gxx_common_flags()
99 conf.gxx_modifier_platform()
100 conf.cxx_load_tools()
101 conf.cxx_add_flags()
102 conf.link_add_flags()
103 conf.check_gcc_o_space('cxx')
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import sys
5 from waflib.Tools import ccroot,ar,gcc
6 from waflib.Configure import conf
7 @conf
8 def find_icc(conf):
9 cc=conf.find_program(['icc','ICL'],var='CC')
10 conf.get_cc_version(cc,icc=True)
11 conf.env.CC_NAME='icc'
12 def configure(conf):
13 conf.find_icc()
14 conf.find_ar()
15 conf.gcc_common_flags()
16 conf.gcc_modifier_platform()
17 conf.cc_load_tools()
18 conf.cc_add_flags()
19 conf.link_add_flags()
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import sys
5 from waflib.Tools import ccroot,ar,gxx
6 from waflib.Configure import conf
7 @conf
8 def find_icpc(conf):
9 cxx=conf.find_program('icpc',var='CXX')
10 conf.get_cc_version(cxx,icc=True)
11 conf.env.CXX_NAME='icc'
12 def configure(conf):
13 conf.find_icpc()
14 conf.find_ar()
15 conf.gxx_common_flags()
16 conf.gxx_modifier_platform()
17 conf.cxx_load_tools()
18 conf.cxx_add_flags()
19 conf.link_add_flags()
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os,re,traceback
5 from waflib import Utils,Logs,Errors
6 from waflib.Tools import fc,fc_config,fc_scan,ar,ccroot
7 from waflib.Configure import conf
8 from waflib.TaskGen import after_method,feature
9 @conf
10 def find_ifort(conf):
11 fc=conf.find_program('ifort',var='FC')
12 conf.get_ifort_version(fc)
13 conf.env.FC_NAME='IFORT'
14 @conf
15 def ifort_modifier_win32(self):
16 v=self.env
17 v.IFORT_WIN32=True
18 v.FCSTLIB_MARKER=''
19 v.FCSHLIB_MARKER=''
20 v.FCLIB_ST=v.FCSTLIB_ST='%s.lib'
21 v.FCLIBPATH_ST=v.STLIBPATH_ST='/LIBPATH:%s'
22 v.FCINCPATH_ST='/I%s'
23 v.FCDEFINES_ST='/D%s'
24 v.fcprogram_PATTERN=v.fcprogram_test_PATTERN='%s.exe'
25 v.fcshlib_PATTERN='%s.dll'
26 v.fcstlib_PATTERN=v.implib_PATTERN='%s.lib'
27 v.FCLNK_TGT_F='/out:'
28 v.FC_TGT_F=['/c','/o','']
29 v.FCFLAGS_fcshlib=''
30 v.LINKFLAGS_fcshlib='/DLL'
31 v.AR_TGT_F='/out:'
32 v.IMPLIB_ST='/IMPLIB:%s'
33 v.append_value('LINKFLAGS','/subsystem:console')
34 if v.IFORT_MANIFEST:
35 v.append_value('LINKFLAGS',['/MANIFEST'])
36 @conf
37 def ifort_modifier_darwin(conf):
38 fc_config.fortran_modifier_darwin(conf)
39 @conf
40 def ifort_modifier_platform(conf):
41 dest_os=conf.env.DEST_OS or Utils.unversioned_sys_platform()
42 ifort_modifier_func=getattr(conf,'ifort_modifier_'+dest_os,None)
43 if ifort_modifier_func:
44 ifort_modifier_func()
45 @conf
46 def get_ifort_version(conf,fc):
47 version_re=re.compile(r"\bIntel\b.*\bVersion\s*(?P<major>\d*)\.(?P<minor>\d*)",re.I).search
48 if Utils.is_win32:
49 cmd=fc
50 else:
51 cmd=fc+['-logo']
52 out,err=fc_config.getoutput(conf,cmd,stdin=False)
53 match=version_re(out)or version_re(err)
54 if not match:
55 conf.fatal('cannot determine ifort version.')
56 k=match.groupdict()
57 conf.env.FC_VERSION=(k['major'],k['minor'])
58 def configure(conf):
59 if Utils.is_win32:
60 compiler,version,path,includes,libdirs,arch=conf.detect_ifort()
61 v=conf.env
62 v.DEST_CPU=arch
63 v.PATH=path
64 v.INCLUDES=includes
65 v.LIBPATH=libdirs
66 v.MSVC_COMPILER=compiler
67 try:
68 v.MSVC_VERSION=float(version)
69 except ValueError:
70 v.MSVC_VERSION=float(version[:-3])
71 conf.find_ifort_win32()
72 conf.ifort_modifier_win32()
73 else:
74 conf.find_ifort()
75 conf.find_program('xiar',var='AR')
76 conf.find_ar()
77 conf.fc_flags()
78 conf.fc_add_flags()
79 conf.ifort_modifier_platform()
80 all_ifort_platforms=[('intel64','amd64'),('em64t','amd64'),('ia32','x86'),('Itanium','ia64')]
81 @conf
82 def gather_ifort_versions(conf,versions):
83 version_pattern=re.compile(r'^...?.?\....?.?')
84 try:
85 all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Compilers\\Fortran')
86 except OSError:
87 try:
88 all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Compilers\\Fortran')
89 except OSError:
90 return
91 index=0
92 while 1:
93 try:
94 version=Utils.winreg.EnumKey(all_versions,index)
95 except OSError:
96 break
97 index+=1
98 if not version_pattern.match(version):
99 continue
100 targets={}
101 for target,arch in all_ifort_platforms:
102 if target=='intel64':
103 targetDir='EM64T_NATIVE'
104 else:
105 targetDir=target
106 try:
107 Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir)
108 icl_version=Utils.winreg.OpenKey(all_versions,version)
109 path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
110 except OSError:
111 pass
112 else:
113 batch_file=os.path.join(path,'bin','ifortvars.bat')
114 if os.path.isfile(batch_file):
115 targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file)
116 for target,arch in all_ifort_platforms:
117 try:
118 icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+target)
119 path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
120 except OSError:
121 continue
122 else:
123 batch_file=os.path.join(path,'bin','ifortvars.bat')
124 if os.path.isfile(batch_file):
125 targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file)
126 major=version[0:2]
127 versions['intel '+major]=targets
128 @conf
129 def setup_ifort(conf,versiondict):
130 platforms=Utils.to_list(conf.env.MSVC_TARGETS)or[i for i,j in all_ifort_platforms]
131 desired_versions=conf.env.MSVC_VERSIONS or list(reversed(list(versiondict.keys())))
132 for version in desired_versions:
133 try:
134 targets=versiondict[version]
135 except KeyError:
136 continue
137 for arch in platforms:
138 try:
139 cfg=targets[arch]
140 except KeyError:
141 continue
142 cfg.evaluate()
143 if cfg.is_valid:
144 compiler,revision=version.rsplit(' ',1)
145 return compiler,revision,cfg.bindirs,cfg.incdirs,cfg.libdirs,cfg.cpu
146 conf.fatal('ifort: Impossible to find a valid architecture for building %r - %r'%(desired_versions,list(versiondict.keys())))
147 @conf
148 def get_ifort_version_win32(conf,compiler,version,target,vcvars):
149 try:
150 conf.msvc_cnt+=1
151 except AttributeError:
152 conf.msvc_cnt=1
153 batfile=conf.bldnode.make_node('waf-print-msvc-%d.bat'%conf.msvc_cnt)
154 batfile.write("""@echo off
155 set INCLUDE=
156 set LIB=
157 call "%s" %s
158 echo PATH=%%PATH%%
159 echo INCLUDE=%%INCLUDE%%
160 echo LIB=%%LIB%%;%%LIBPATH%%
161 """%(vcvars,target))
162 sout=conf.cmd_and_log(['cmd.exe','/E:on','/V:on','/C',batfile.abspath()])
163 batfile.delete()
164 lines=sout.splitlines()
165 if not lines[0]:
166 lines.pop(0)
167 MSVC_PATH=MSVC_INCDIR=MSVC_LIBDIR=None
168 for line in lines:
169 if line.startswith('PATH='):
170 path=line[5:]
171 MSVC_PATH=path.split(';')
172 elif line.startswith('INCLUDE='):
173 MSVC_INCDIR=[i for i in line[8:].split(';')if i]
174 elif line.startswith('LIB='):
175 MSVC_LIBDIR=[i for i in line[4:].split(';')if i]
176 if None in(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR):
177 conf.fatal('ifort: Could not find a valid architecture for building (get_ifort_version_win32)')
178 env=dict(os.environ)
179 env.update(PATH=path)
180 compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
181 fc=conf.find_program(compiler_name,path_list=MSVC_PATH)
182 if'CL'in env:
183 del(env['CL'])
184 try:
185 conf.cmd_and_log(fc+['/help'],env=env)
186 except UnicodeError:
187 st=traceback.format_exc()
188 if conf.logger:
189 conf.logger.error(st)
190 conf.fatal('ifort: Unicode error - check the code page?')
191 except Exception as e:
192 Logs.debug('ifort: get_ifort_version: %r %r %r -> failure %s',compiler,version,target,str(e))
193 conf.fatal('ifort: cannot run the compiler in get_ifort_version (run with -v to display errors)')
194 else:
195 Logs.debug('ifort: get_ifort_version: %r %r %r -> OK',compiler,version,target)
196 finally:
197 conf.env[compiler_name]=''
198 return(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR)
199 class target_compiler(object):
200 def __init__(self,ctx,compiler,cpu,version,bat_target,bat,callback=None):
201 self.conf=ctx
202 self.name=None
203 self.is_valid=False
204 self.is_done=False
205 self.compiler=compiler
206 self.cpu=cpu
207 self.version=version
208 self.bat_target=bat_target
209 self.bat=bat
210 self.callback=callback
211 def evaluate(self):
212 if self.is_done:
213 return
214 self.is_done=True
215 try:
216 vs=self.conf.get_ifort_version_win32(self.compiler,self.version,self.bat_target,self.bat)
217 except Errors.ConfigurationError:
218 self.is_valid=False
219 return
220 if self.callback:
221 vs=self.callback(self,vs)
222 self.is_valid=True
223 (self.bindirs,self.incdirs,self.libdirs)=vs
224 def __str__(self):
225 return str((self.bindirs,self.incdirs,self.libdirs))
226 def __repr__(self):
227 return repr((self.bindirs,self.incdirs,self.libdirs))
228 @conf
229 def detect_ifort(self):
230 return self.setup_ifort(self.get_ifort_versions(False))
231 @conf
232 def get_ifort_versions(self,eval_and_save=True):
233 dct={}
234 self.gather_ifort_versions(dct)
235 return dct
236 def _get_prog_names(self,compiler):
237 if compiler=='intel':
238 compiler_name='ifort'
239 linker_name='XILINK'
240 lib_name='XILIB'
241 else:
242 compiler_name='CL'
243 linker_name='LINK'
244 lib_name='LIB'
245 return compiler_name,linker_name,lib_name
246 @conf
247 def find_ifort_win32(conf):
248 v=conf.env
249 path=v.PATH
250 compiler=v.MSVC_COMPILER
251 version=v.MSVC_VERSION
252 compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
253 v.IFORT_MANIFEST=(compiler=='intel'and version>=11)
254 fc=conf.find_program(compiler_name,var='FC',path_list=path)
255 env=dict(conf.environ)
256 if path:
257 env.update(PATH=';'.join(path))
258 if not conf.cmd_and_log(fc+['/nologo','/help'],env=env):
259 conf.fatal('not intel fortran compiler could not be identified')
260 v.FC_NAME='IFORT'
261 if not v.LINK_FC:
262 conf.find_program(linker_name,var='LINK_FC',path_list=path,mandatory=True)
263 if not v.AR:
264 conf.find_program(lib_name,path_list=path,var='AR',mandatory=True)
265 v.ARFLAGS=['/nologo']
266 if v.IFORT_MANIFEST:
267 conf.find_program('MT',path_list=path,var='MT')
268 v.MTFLAGS=['/nologo']
269 try:
270 conf.load('winres')
271 except Errors.WafError:
272 Logs.warn('Resource compiler not found. Compiling resource file is disabled')
273 @after_method('apply_link')
274 @feature('fc')
275 def apply_flags_ifort(self):
276 if not self.env.IFORT_WIN32 or not getattr(self,'link_task',None):
277 return
278 is_static=isinstance(self.link_task,ccroot.stlink_task)
279 subsystem=getattr(self,'subsystem','')
280 if subsystem:
281 subsystem='/subsystem:%s'%subsystem
282 flags=is_static and'ARFLAGS'or'LINKFLAGS'
283 self.env.append_value(flags,subsystem)
284 if not is_static:
285 for f in self.env.LINKFLAGS:
286 d=f.lower()
287 if d[1:]=='debug':
288 pdbnode=self.link_task.outputs[0].change_ext('.pdb')
289 self.link_task.outputs.append(pdbnode)
290 if getattr(self,'install_task',None):
291 self.pdb_install_task=self.add_install_files(install_to=self.install_task.install_to,install_from=pdbnode)
292 break
293 @feature('fcprogram','fcshlib','fcprogram_test')
294 @after_method('apply_link')
295 def apply_manifest_ifort(self):
296 if self.env.IFORT_WIN32 and getattr(self,'link_task',None):
297 self.link_task.env.FC=self.env.LINK_FC
298 if self.env.IFORT_WIN32 and self.env.IFORT_MANIFEST and getattr(self,'link_task',None):
299 out_node=self.link_task.outputs[0]
300 man_node=out_node.parent.find_or_declare(out_node.name+'.manifest')
301 self.link_task.outputs.append(man_node)
302 self.env.DO_MANIFEST=True
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from __future__ import with_statement
5 import os,re
6 from waflib import Context,Task,Utils,Logs
7 import waflib.Tools.ccroot
8 from waflib.TaskGen import feature,before_method,taskgen_method
9 from waflib.Logs import error
10 from waflib.Configure import conf
11 _style_flags={'ba':'-b','desktop':'-d','keys':'-k','quoted':'--quoted-style','quotedxml':'--quotedxml-style','rfc822deb':'-r','schemas':'-s','xml':'-x',}
12 @taskgen_method
13 def ensure_localedir(self):
14 if not self.env.LOCALEDIR:
15 if self.env.DATAROOTDIR:
16 self.env.LOCALEDIR=os.path.join(self.env.DATAROOTDIR,'locale')
17 else:
18 self.env.LOCALEDIR=os.path.join(self.env.PREFIX,'share','locale')
19 @before_method('process_source')
20 @feature('intltool_in')
21 def apply_intltool_in_f(self):
22 try:
23 self.meths.remove('process_source')
24 except ValueError:
25 pass
26 self.ensure_localedir()
27 podir=getattr(self,'podir','.')
28 podirnode=self.path.find_dir(podir)
29 if not podirnode:
30 error("could not find the podir %r"%podir)
31 return
32 cache=getattr(self,'intlcache','.intlcache')
33 self.env.INTLCACHE=[os.path.join(str(self.path.get_bld()),podir,cache)]
34 self.env.INTLPODIR=podirnode.bldpath()
35 self.env.append_value('INTLFLAGS',getattr(self,'flags',self.env.INTLFLAGS_DEFAULT))
36 if'-c'in self.env.INTLFLAGS:
37 self.bld.fatal('Redundant -c flag in intltool task %r'%self)
38 style=getattr(self,'style',None)
39 if style:
40 try:
41 style_flag=_style_flags[style]
42 except KeyError:
43 self.bld.fatal('intltool_in style "%s" is not valid'%style)
44 self.env.append_unique('INTLFLAGS',[style_flag])
45 for i in self.to_list(self.source):
46 node=self.path.find_resource(i)
47 task=self.create_task('intltool',node,node.change_ext(''))
48 inst=getattr(self,'install_path',None)
49 if inst:
50 self.add_install_files(install_to=inst,install_from=task.outputs)
51 @feature('intltool_po')
52 def apply_intltool_po(self):
53 try:
54 self.meths.remove('process_source')
55 except ValueError:
56 pass
57 self.ensure_localedir()
58 appname=getattr(self,'appname',getattr(Context.g_module,Context.APPNAME,'set_your_app_name'))
59 podir=getattr(self,'podir','.')
60 inst=getattr(self,'install_path','${LOCALEDIR}')
61 linguas=self.path.find_node(os.path.join(podir,'LINGUAS'))
62 if linguas:
63 with open(linguas.abspath())as f:
64 langs=[]
65 for line in f.readlines():
66 if not line.startswith('#'):
67 langs+=line.split()
68 re_linguas=re.compile('[-a-zA-Z_@.]+')
69 for lang in langs:
70 if re_linguas.match(lang):
71 node=self.path.find_resource(os.path.join(podir,re_linguas.match(lang).group()+'.po'))
72 task=self.create_task('po',node,node.change_ext('.mo'))
73 if inst:
74 filename=task.outputs[0].name
75 (langname,ext)=os.path.splitext(filename)
76 inst_file=inst+os.sep+langname+os.sep+'LC_MESSAGES'+os.sep+appname+'.mo'
77 self.add_install_as(install_to=inst_file,install_from=task.outputs[0],chmod=getattr(self,'chmod',Utils.O644))
78 else:
79 Logs.pprint('RED',"Error no LINGUAS file found in po directory")
80 class po(Task.Task):
81 run_str='${MSGFMT} -o ${TGT} ${SRC}'
82 color='BLUE'
83 class intltool(Task.Task):
84 run_str='${INTLTOOL} ${INTLFLAGS} ${INTLCACHE_ST:INTLCACHE} ${INTLPODIR} ${SRC} ${TGT}'
85 color='BLUE'
86 @conf
87 def find_msgfmt(conf):
88 conf.find_program('msgfmt',var='MSGFMT')
89 @conf
90 def find_intltool_merge(conf):
91 if not conf.env.PERL:
92 conf.find_program('perl',var='PERL')
93 conf.env.INTLCACHE_ST='--cache=%s'
94 conf.env.INTLFLAGS_DEFAULT=['-q','-u']
95 conf.find_program('intltool-merge',interpreter='PERL',var='INTLTOOL')
96 def configure(conf):
97 conf.find_msgfmt()
98 conf.find_intltool_merge()
99 if conf.env.CC or conf.env.CXX:
100 conf.check(header_name='locale.h')
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib import Errors
5 from waflib.Tools import ccroot,ar
6 from waflib.Configure import conf
7 @conf
8 def find_irixcc(conf):
9 v=conf.env
10 cc=None
11 if v.CC:
12 cc=v.CC
13 elif'CC'in conf.environ:
14 cc=conf.environ['CC']
15 if not cc:
16 cc=conf.find_program('cc',var='CC')
17 if not cc:
18 conf.fatal('irixcc was not found')
19 try:
20 conf.cmd_and_log(cc+['-version'])
21 except Errors.WafError:
22 conf.fatal('%r -version could not be executed'%cc)
23 v.CC=cc
24 v.CC_NAME='irix'
25 @conf
26 def irixcc_common_flags(conf):
27 v=conf.env
28 v.CC_SRC_F=''
29 v.CC_TGT_F=['-c','-o']
30 v.CPPPATH_ST='-I%s'
31 v.DEFINES_ST='-D%s'
32 if not v.LINK_CC:
33 v.LINK_CC=v.CC
34 v.CCLNK_SRC_F=''
35 v.CCLNK_TGT_F=['-o']
36 v.LIB_ST='-l%s'
37 v.LIBPATH_ST='-L%s'
38 v.STLIB_ST='-l%s'
39 v.STLIBPATH_ST='-L%s'
40 v.cprogram_PATTERN='%s'
41 v.cshlib_PATTERN='lib%s.so'
42 v.cstlib_PATTERN='lib%s.a'
43 def configure(conf):
44 conf.find_irixcc()
45 conf.find_cpp()
46 conf.find_ar()
47 conf.irixcc_common_flags()
48 conf.cc_load_tools()
49 conf.cc_add_flags()
50 conf.link_add_flags()
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os,shutil
5 from waflib import Task,Utils,Errors,Node
6 from waflib.Configure import conf
7 from waflib.TaskGen import feature,before_method,after_method,taskgen_method
8 from waflib.Tools import ccroot
9 ccroot.USELIB_VARS['javac']=set(['CLASSPATH','JAVACFLAGS'])
10 SOURCE_RE='**/*.java'
11 JAR_RE='**/*'
12 class_check_source='''
13 public class Test {
14 public static void main(String[] argv) {
15 Class lib;
16 if (argv.length < 1) {
17 System.err.println("Missing argument");
18 System.exit(77);
19 }
20 try {
21 lib = Class.forName(argv[0]);
22 } catch (ClassNotFoundException e) {
23 System.err.println("ClassNotFoundException");
24 System.exit(1);
25 }
26 lib = null;
27 System.exit(0);
28 }
29 }
30 '''
31 @feature('javac')
32 @before_method('process_source')
33 def apply_java(self):
34 Utils.def_attrs(self,jarname='',classpath='',sourcepath='.',srcdir='.',jar_mf_attributes={},jar_mf_classpath=[])
35 outdir=getattr(self,'outdir',None)
36 if outdir:
37 if not isinstance(outdir,Node.Node):
38 outdir=self.path.get_bld().make_node(self.outdir)
39 else:
40 outdir=self.path.get_bld()
41 outdir.mkdir()
42 self.outdir=outdir
43 self.env.OUTDIR=outdir.abspath()
44 self.javac_task=tsk=self.create_task('javac')
45 tmp=[]
46 srcdir=getattr(self,'srcdir','')
47 if isinstance(srcdir,Node.Node):
48 srcdir=[srcdir]
49 for x in Utils.to_list(srcdir):
50 if isinstance(x,Node.Node):
51 y=x
52 else:
53 y=self.path.find_dir(x)
54 if not y:
55 self.bld.fatal('Could not find the folder %s from %s'%(x,self.path))
56 tmp.append(y)
57 tsk.srcdir=tmp
58 if getattr(self,'compat',None):
59 tsk.env.append_value('JAVACFLAGS',['-source',str(self.compat)])
60 if hasattr(self,'sourcepath'):
61 fold=[isinstance(x,Node.Node)and x or self.path.find_dir(x)for x in self.to_list(self.sourcepath)]
62 names=os.pathsep.join([x.srcpath()for x in fold])
63 else:
64 names=[x.srcpath()for x in tsk.srcdir]
65 if names:
66 tsk.env.append_value('JAVACFLAGS',['-sourcepath',names])
67 @taskgen_method
68 def java_use_rec(self,name,**kw):
69 if name in self.tmp_use_seen:
70 return
71 self.tmp_use_seen.append(name)
72 try:
73 y=self.bld.get_tgen_by_name(name)
74 except Errors.WafError:
75 self.uselib.append(name)
76 return
77 else:
78 y.post()
79 if hasattr(y,'jar_task'):
80 self.use_lst.append(y.jar_task.outputs[0].abspath())
81 else:
82 if hasattr(y,'outdir'):
83 self.use_lst.append(y.outdir.abspath())
84 else:
85 self.use_lst.append(y.path.get_bld().abspath())
86 for x in self.to_list(getattr(y,'use',[])):
87 self.java_use_rec(x)
88 @feature('javac')
89 @before_method('propagate_uselib_vars')
90 @after_method('apply_java')
91 def use_javac_files(self):
92 self.use_lst=[]
93 self.tmp_use_seen=[]
94 self.uselib=self.to_list(getattr(self,'uselib',[]))
95 names=self.to_list(getattr(self,'use',[]))
96 get=self.bld.get_tgen_by_name
97 for x in names:
98 try:
99 tg=get(x)
100 except Errors.WafError:
101 self.uselib.append(x)
102 else:
103 tg.post()
104 if hasattr(tg,'jar_task'):
105 self.use_lst.append(tg.jar_task.outputs[0].abspath())
106 self.javac_task.set_run_after(tg.jar_task)
107 self.javac_task.dep_nodes.extend(tg.jar_task.outputs)
108 else:
109 if hasattr(tg,'outdir'):
110 base_node=tg.outdir
111 else:
112 base_node=tg.path.get_bld()
113 self.use_lst.append(base_node.abspath())
114 self.javac_task.dep_nodes.extend([x for x in base_node.ant_glob(JAR_RE,remove=False,quiet=True)])
115 for tsk in tg.tasks:
116 self.javac_task.set_run_after(tsk)
117 if getattr(self,'recurse_use',False)or self.bld.env.RECURSE_JAVA:
118 self.java_use_rec(x)
119 self.env.append_value('CLASSPATH',self.use_lst)
120 @feature('javac')
121 @after_method('apply_java','propagate_uselib_vars','use_javac_files')
122 def set_classpath(self):
123 if getattr(self,'classpath',None):
124 self.env.append_unique('CLASSPATH',getattr(self,'classpath',[]))
125 for x in self.tasks:
126 x.env.CLASSPATH=os.pathsep.join(self.env.CLASSPATH)+os.pathsep
127 @feature('jar')
128 @after_method('apply_java','use_javac_files')
129 @before_method('process_source')
130 def jar_files(self):
131 destfile=getattr(self,'destfile','test.jar')
132 jaropts=getattr(self,'jaropts',[])
133 manifest=getattr(self,'manifest',None)
134 basedir=getattr(self,'basedir',None)
135 if basedir:
136 if not isinstance(self.basedir,Node.Node):
137 basedir=self.path.get_bld().make_node(basedir)
138 else:
139 basedir=self.path.get_bld()
140 if not basedir:
141 self.bld.fatal('Could not find the basedir %r for %r'%(self.basedir,self))
142 self.jar_task=tsk=self.create_task('jar_create')
143 if manifest:
144 jarcreate=getattr(self,'jarcreate','cfm')
145 if not isinstance(manifest,Node.Node):
146 node=self.path.find_resource(manifest)
147 else:
148 node=manifest
149 if not node:
150 self.bld.fatal('invalid manifest file %r for %r'%(manifest,self))
151 tsk.dep_nodes.append(node)
152 jaropts.insert(0,node.abspath())
153 else:
154 jarcreate=getattr(self,'jarcreate','cf')
155 if not isinstance(destfile,Node.Node):
156 destfile=self.path.find_or_declare(destfile)
157 if not destfile:
158 self.bld.fatal('invalid destfile %r for %r'%(destfile,self))
159 tsk.set_outputs(destfile)
160 tsk.basedir=basedir
161 jaropts.append('-C')
162 jaropts.append(basedir.bldpath())
163 jaropts.append('.')
164 tsk.env.JAROPTS=jaropts
165 tsk.env.JARCREATE=jarcreate
166 if getattr(self,'javac_task',None):
167 tsk.set_run_after(self.javac_task)
168 @feature('jar')
169 @after_method('jar_files')
170 def use_jar_files(self):
171 self.uselib=self.to_list(getattr(self,'uselib',[]))
172 names=self.to_list(getattr(self,'use',[]))
173 get=self.bld.get_tgen_by_name
174 for x in names:
175 try:
176 y=get(x)
177 except Errors.WafError:
178 self.uselib.append(x)
179 else:
180 y.post()
181 self.jar_task.run_after.update(y.tasks)
182 class JTask(Task.Task):
183 def split_argfile(self,cmd):
184 inline=[cmd[0]]
185 infile=[]
186 for x in cmd[1:]:
187 if x.startswith('-J'):
188 inline.append(x)
189 else:
190 infile.append(self.quote_flag(x))
191 return(inline,infile)
192 class jar_create(JTask):
193 color='GREEN'
194 run_str='${JAR} ${JARCREATE} ${TGT} ${JAROPTS}'
195 def runnable_status(self):
196 for t in self.run_after:
197 if not t.hasrun:
198 return Task.ASK_LATER
199 if not self.inputs:
200 try:
201 self.inputs=[x for x in self.basedir.ant_glob(JAR_RE,remove=False,quiet=True)if id(x)!=id(self.outputs[0])]
202 except Exception:
203 raise Errors.WafError('Could not find the basedir %r for %r'%(self.basedir,self))
204 return super(jar_create,self).runnable_status()
205 class javac(JTask):
206 color='BLUE'
207 run_str='${JAVAC} -classpath ${CLASSPATH} -d ${OUTDIR} ${JAVACFLAGS} ${SRC}'
208 vars=['CLASSPATH','JAVACFLAGS','JAVAC','OUTDIR']
209 def uid(self):
210 lst=[self.__class__.__name__,self.generator.outdir.abspath()]
211 for x in self.srcdir:
212 lst.append(x.abspath())
213 return Utils.h_list(lst)
214 def runnable_status(self):
215 for t in self.run_after:
216 if not t.hasrun:
217 return Task.ASK_LATER
218 if not self.inputs:
219 self.inputs=[]
220 for x in self.srcdir:
221 if x.exists():
222 self.inputs.extend(x.ant_glob(SOURCE_RE,remove=False,quiet=True))
223 return super(javac,self).runnable_status()
224 def post_run(self):
225 for node in self.generator.outdir.ant_glob('**/*.class',quiet=True):
226 self.generator.bld.node_sigs[node]=self.uid()
227 self.generator.bld.task_sigs[self.uid()]=self.cache_sig
228 @feature('javadoc')
229 @after_method('process_rule')
230 def create_javadoc(self):
231 tsk=self.create_task('javadoc')
232 tsk.classpath=getattr(self,'classpath',[])
233 self.javadoc_package=Utils.to_list(self.javadoc_package)
234 if not isinstance(self.javadoc_output,Node.Node):
235 self.javadoc_output=self.bld.path.find_or_declare(self.javadoc_output)
236 class javadoc(Task.Task):
237 color='BLUE'
238 def __str__(self):
239 return'%s: %s -> %s\n'%(self.__class__.__name__,self.generator.srcdir,self.generator.javadoc_output)
240 def run(self):
241 env=self.env
242 bld=self.generator.bld
243 wd=bld.bldnode
244 srcpath=self.generator.path.abspath()+os.sep+self.generator.srcdir
245 srcpath+=os.pathsep
246 srcpath+=self.generator.path.get_bld().abspath()+os.sep+self.generator.srcdir
247 classpath=env.CLASSPATH
248 classpath+=os.pathsep
249 classpath+=os.pathsep.join(self.classpath)
250 classpath="".join(classpath)
251 self.last_cmd=lst=[]
252 lst.extend(Utils.to_list(env.JAVADOC))
253 lst.extend(['-d',self.generator.javadoc_output.abspath()])
254 lst.extend(['-sourcepath',srcpath])
255 lst.extend(['-classpath',classpath])
256 lst.extend(['-subpackages'])
257 lst.extend(self.generator.javadoc_package)
258 lst=[x for x in lst if x]
259 self.generator.bld.cmd_and_log(lst,cwd=wd,env=env.env or None,quiet=0)
260 def post_run(self):
261 nodes=self.generator.javadoc_output.ant_glob('**',quiet=True)
262 for node in nodes:
263 self.generator.bld.node_sigs[node]=self.uid()
264 self.generator.bld.task_sigs[self.uid()]=self.cache_sig
265 def configure(self):
266 java_path=self.environ['PATH'].split(os.pathsep)
267 v=self.env
268 if'JAVA_HOME'in self.environ:
269 java_path=[os.path.join(self.environ['JAVA_HOME'],'bin')]+java_path
270 self.env.JAVA_HOME=[self.environ['JAVA_HOME']]
271 for x in'javac java jar javadoc'.split():
272 self.find_program(x,var=x.upper(),path_list=java_path,mandatory=(x not in('javadoc')))
273 if'CLASSPATH'in self.environ:
274 v.CLASSPATH=self.environ['CLASSPATH']
275 if not v.JAR:
276 self.fatal('jar is required for making java packages')
277 if not v.JAVAC:
278 self.fatal('javac is required for compiling java classes')
279 v.JARCREATE='cf'
280 v.JAVACFLAGS=[]
281 @conf
282 def check_java_class(self,classname,with_classpath=None):
283 javatestdir='.waf-javatest'
284 classpath=javatestdir
285 if self.env.CLASSPATH:
286 classpath+=os.pathsep+self.env.CLASSPATH
287 if isinstance(with_classpath,str):
288 classpath+=os.pathsep+with_classpath
289 shutil.rmtree(javatestdir,True)
290 os.mkdir(javatestdir)
291 Utils.writef(os.path.join(javatestdir,'Test.java'),class_check_source)
292 self.exec_command(self.env.JAVAC+[os.path.join(javatestdir,'Test.java')],shell=False)
293 cmd=self.env.JAVA+['-cp',classpath,'Test',classname]
294 self.to_log("%s\n"%str(cmd))
295 found=self.exec_command(cmd,shell=False)
296 self.msg('Checking for java class %s'%classname,not found)
297 shutil.rmtree(javatestdir,True)
298 return found
299 @conf
300 def check_jni_headers(conf):
301 if not conf.env.CC_NAME and not conf.env.CXX_NAME:
302 conf.fatal('load a compiler first (gcc, g++, ..)')
303 if not conf.env.JAVA_HOME:
304 conf.fatal('set JAVA_HOME in the system environment')
305 javaHome=conf.env.JAVA_HOME[0]
306 dir=conf.root.find_dir(conf.env.JAVA_HOME[0]+'/include')
307 if dir is None:
308 dir=conf.root.find_dir(conf.env.JAVA_HOME[0]+'/../Headers')
309 if dir is None:
310 conf.fatal('JAVA_HOME does not seem to be set properly')
311 f=dir.ant_glob('**/(jni|jni_md).h')
312 incDirs=[x.parent.abspath()for x in f]
313 dir=conf.root.find_dir(conf.env.JAVA_HOME[0])
314 f=dir.ant_glob('**/*jvm.(so|dll|dylib)')
315 libDirs=[x.parent.abspath()for x in f]or[javaHome]
316 f=dir.ant_glob('**/*jvm.(lib)')
317 if f:
318 libDirs=[[x,y.parent.abspath()]for x in libDirs for y in f]
319 if conf.env.DEST_OS=='freebsd':
320 conf.env.append_unique('LINKFLAGS_JAVA','-pthread')
321 for d in libDirs:
322 try:
323 conf.check(header_name='jni.h',define_name='HAVE_JNI_H',lib='jvm',libpath=d,includes=incDirs,uselib_store='JAVA',uselib='JAVA')
324 except Exception:
325 pass
326 else:
327 break
328 else:
329 conf.fatal('could not find lib jvm in %r (see config.log)'%libDirs)
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib.Tools import ar,d
5 from waflib.Configure import conf
6 @conf
7 def find_ldc2(conf):
8 conf.find_program(['ldc2'],var='D')
9 out=conf.cmd_and_log(conf.env.D+['-version'])
10 if out.find("based on DMD v2.")==-1:
11 conf.fatal("detected compiler is not ldc2")
12 @conf
13 def common_flags_ldc2(conf):
14 v=conf.env
15 v.D_SRC_F=['-c']
16 v.D_TGT_F='-of%s'
17 v.D_LINKER=v.D
18 v.DLNK_SRC_F=''
19 v.DLNK_TGT_F='-of%s'
20 v.DINC_ST='-I%s'
21 v.DSHLIB_MARKER=v.DSTLIB_MARKER=''
22 v.DSTLIB_ST=v.DSHLIB_ST='-L-l%s'
23 v.DSTLIBPATH_ST=v.DLIBPATH_ST='-L-L%s'
24 v.LINKFLAGS_dshlib=['-L-shared']
25 v.DHEADER_ext='.di'
26 v.DFLAGS_d_with_header=['-H','-Hf']
27 v.D_HDR_F='%s'
28 v.LINKFLAGS=[]
29 v.DFLAGS_dshlib=['-relocation-model=pic']
30 def configure(conf):
31 conf.find_ldc2()
32 conf.load('ar')
33 conf.load('d')
34 conf.common_flags_ldc2()
35 conf.d_platform_flags()
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib.TaskGen import extension
5 from waflib import Task
6 @extension('.lua')
7 def add_lua(self,node):
8 tsk=self.create_task('luac',node,node.change_ext('.luac'))
9 inst_to=getattr(self,'install_path',self.env.LUADIR and'${LUADIR}'or None)
10 if inst_to:
11 self.add_install_files(install_to=inst_to,install_from=tsk.outputs)
12 return tsk
13 class luac(Task.Task):
14 run_str='${LUAC} -s -o ${TGT} ${SRC}'
15 color='PINK'
16 def configure(conf):
17 conf.find_program('luac',var='LUAC')
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os,stat
5 from waflib import Utils,Build,Node
6 STRONGEST=True
7 Build.SAVED_ATTRS.append('hashes_md5_tstamp')
8 def h_file(self):
9 filename=self.abspath()
10 st=os.stat(filename)
11 cache=self.ctx.hashes_md5_tstamp
12 if filename in cache and cache[filename][0]==st.st_mtime:
13 return cache[filename][1]
14 if STRONGEST:
15 ret=Utils.h_file(filename)
16 else:
17 if stat.S_ISDIR(st[stat.ST_MODE]):
18 raise IOError('Not a file')
19 ret=Utils.md5(str((st.st_mtime,st.st_size)).encode()).digest()
20 cache[filename]=(st.st_mtime,ret)
21 return ret
22 h_file.__doc__=Node.Node.h_file.__doc__
23 Node.Node.h_file=h_file
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os,sys,re,traceback
5 from waflib import Utils,Logs,Options,Errors
6 from waflib.TaskGen import after_method,feature
7 from waflib.Configure import conf
8 from waflib.Tools import ccroot,c,cxx,ar
9 g_msvc_systemlibs='''
10 aclui activeds ad1 adptif adsiid advapi32 asycfilt authz bhsupp bits bufferoverflowu cabinet
11 cap certadm certidl ciuuid clusapi comctl32 comdlg32 comsupp comsuppd comsuppw comsuppwd comsvcs
12 credui crypt32 cryptnet cryptui d3d8thk daouuid dbgeng dbghelp dciman32 ddao35 ddao35d
13 ddao35u ddao35ud delayimp dhcpcsvc dhcpsapi dlcapi dnsapi dsprop dsuiext dtchelp
14 faultrep fcachdll fci fdi framedyd framedyn gdi32 gdiplus glauxglu32 gpedit gpmuuid
15 gtrts32w gtrtst32hlink htmlhelp httpapi icm32 icmui imagehlp imm32 iphlpapi iprop
16 kernel32 ksguid ksproxy ksuser libcmt libcmtd libcpmt libcpmtd loadperf lz32 mapi
17 mapi32 mgmtapi minidump mmc mobsync mpr mprapi mqoa mqrt msacm32 mscms mscoree
18 msdasc msimg32 msrating mstask msvcmrt msvcurt msvcurtd mswsock msxml2 mtx mtxdm
19 netapi32 nmapinmsupp npptools ntdsapi ntdsbcli ntmsapi ntquery odbc32 odbcbcp
20 odbccp32 oldnames ole32 oleacc oleaut32 oledb oledlgolepro32 opends60 opengl32
21 osptk parser pdh penter pgobootrun pgort powrprof psapi ptrustm ptrustmd ptrustu
22 ptrustud qosname rasapi32 rasdlg rassapi resutils riched20 rpcndr rpcns4 rpcrt4 rtm
23 rtutils runtmchk scarddlg scrnsave scrnsavw secur32 sensapi setupapi sfc shell32
24 shfolder shlwapi sisbkup snmpapi sporder srclient sti strsafe svcguid tapi32 thunk32
25 traffic unicows url urlmon user32 userenv usp10 uuid uxtheme vcomp vcompd vdmdbg
26 version vfw32 wbemuuid webpost wiaguid wininet winmm winscard winspool winstrm
27 wintrust wldap32 wmiutils wow32 ws2_32 wsnmp32 wsock32 wst wtsapi32 xaswitch xolehlp
28 '''.split()
29 all_msvc_platforms=[('x64','amd64'),('x86','x86'),('ia64','ia64'),('x86_amd64','amd64'),('x86_ia64','ia64'),('x86_arm','arm'),('x86_arm64','arm64'),('amd64_x86','x86'),('amd64_arm','arm'),('amd64_arm64','arm64')]
30 all_wince_platforms=[('armv4','arm'),('armv4i','arm'),('mipsii','mips'),('mipsii_fp','mips'),('mipsiv','mips'),('mipsiv_fp','mips'),('sh4','sh'),('x86','cex86')]
31 all_icl_platforms=[('intel64','amd64'),('em64t','amd64'),('ia32','x86'),('Itanium','ia64')]
32 def options(opt):
33 opt.add_option('--msvc_version',type='string',help='msvc version, eg: "msvc 10.0,msvc 9.0"',default='')
34 opt.add_option('--msvc_targets',type='string',help='msvc targets, eg: "x64,arm"',default='')
35 opt.add_option('--no-msvc-lazy',action='store_false',help='lazily check msvc target environments',default=True,dest='msvc_lazy')
36 @conf
37 def setup_msvc(conf,versiondict):
38 platforms=getattr(Options.options,'msvc_targets','').split(',')
39 if platforms==['']:
40 platforms=Utils.to_list(conf.env.MSVC_TARGETS)or[i for i,j in all_msvc_platforms+all_icl_platforms+all_wince_platforms]
41 desired_versions=getattr(Options.options,'msvc_version','').split(',')
42 if desired_versions==['']:
43 desired_versions=conf.env.MSVC_VERSIONS or list(reversed(sorted(versiondict.keys())))
44 lazy_detect=getattr(Options.options,'msvc_lazy',True)
45 if conf.env.MSVC_LAZY_AUTODETECT is False:
46 lazy_detect=False
47 if not lazy_detect:
48 for val in versiondict.values():
49 for arch in list(val.keys()):
50 cfg=val[arch]
51 cfg.evaluate()
52 if not cfg.is_valid:
53 del val[arch]
54 conf.env.MSVC_INSTALLED_VERSIONS=versiondict
55 for version in desired_versions:
56 Logs.debug('msvc: detecting %r - %r',version,desired_versions)
57 try:
58 targets=versiondict[version]
59 except KeyError:
60 continue
61 seen=set()
62 for arch in platforms:
63 if arch in seen:
64 continue
65 else:
66 seen.add(arch)
67 try:
68 cfg=targets[arch]
69 except KeyError:
70 continue
71 cfg.evaluate()
72 if cfg.is_valid:
73 compiler,revision=version.rsplit(' ',1)
74 return compiler,revision,cfg.bindirs,cfg.incdirs,cfg.libdirs,cfg.cpu
75 conf.fatal('msvc: Impossible to find a valid architecture for building %r - %r'%(desired_versions,list(versiondict.keys())))
76 @conf
77 def get_msvc_version(conf,compiler,version,target,vcvars):
78 Logs.debug('msvc: get_msvc_version: %r %r %r',compiler,version,target)
79 try:
80 conf.msvc_cnt+=1
81 except AttributeError:
82 conf.msvc_cnt=1
83 batfile=conf.bldnode.make_node('waf-print-msvc-%d.bat'%conf.msvc_cnt)
84 batfile.write("""@echo off
85 set INCLUDE=
86 set LIB=
87 call "%s" %s
88 echo PATH=%%PATH%%
89 echo INCLUDE=%%INCLUDE%%
90 echo LIB=%%LIB%%;%%LIBPATH%%
91 """%(vcvars,target))
92 sout=conf.cmd_and_log(['cmd.exe','/E:on','/V:on','/C',batfile.abspath()])
93 lines=sout.splitlines()
94 if not lines[0]:
95 lines.pop(0)
96 MSVC_PATH=MSVC_INCDIR=MSVC_LIBDIR=None
97 for line in lines:
98 if line.startswith('PATH='):
99 path=line[5:]
100 MSVC_PATH=path.split(';')
101 elif line.startswith('INCLUDE='):
102 MSVC_INCDIR=[i for i in line[8:].split(';')if i]
103 elif line.startswith('LIB='):
104 MSVC_LIBDIR=[i for i in line[4:].split(';')if i]
105 if None in(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR):
106 conf.fatal('msvc: Could not find a valid architecture for building (get_msvc_version_3)')
107 env=dict(os.environ)
108 env.update(PATH=path)
109 compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
110 cxx=conf.find_program(compiler_name,path_list=MSVC_PATH)
111 if'CL'in env:
112 del(env['CL'])
113 try:
114 conf.cmd_and_log(cxx+['/help'],env=env)
115 except UnicodeError:
116 st=traceback.format_exc()
117 if conf.logger:
118 conf.logger.error(st)
119 conf.fatal('msvc: Unicode error - check the code page?')
120 except Exception as e:
121 Logs.debug('msvc: get_msvc_version: %r %r %r -> failure %s',compiler,version,target,str(e))
122 conf.fatal('msvc: cannot run the compiler in get_msvc_version (run with -v to display errors)')
123 else:
124 Logs.debug('msvc: get_msvc_version: %r %r %r -> OK',compiler,version,target)
125 finally:
126 conf.env[compiler_name]=''
127 return(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR)
128 def gather_wince_supported_platforms():
129 supported_wince_platforms=[]
130 try:
131 ce_sdk=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Windows CE Tools\\SDKs')
132 except OSError:
133 try:
134 ce_sdk=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Windows CE Tools\\SDKs')
135 except OSError:
136 ce_sdk=''
137 if not ce_sdk:
138 return supported_wince_platforms
139 index=0
140 while 1:
141 try:
142 sdk_device=Utils.winreg.EnumKey(ce_sdk,index)
143 sdk=Utils.winreg.OpenKey(ce_sdk,sdk_device)
144 except OSError:
145 break
146 index+=1
147 try:
148 path,type=Utils.winreg.QueryValueEx(sdk,'SDKRootDir')
149 except OSError:
150 try:
151 path,type=Utils.winreg.QueryValueEx(sdk,'SDKInformation')
152 except OSError:
153 continue
154 path,xml=os.path.split(path)
155 path=str(path)
156 path,device=os.path.split(path)
157 if not device:
158 path,device=os.path.split(path)
159 platforms=[]
160 for arch,compiler in all_wince_platforms:
161 if os.path.isdir(os.path.join(path,device,'Lib',arch)):
162 platforms.append((arch,compiler,os.path.join(path,device,'Include',arch),os.path.join(path,device,'Lib',arch)))
163 if platforms:
164 supported_wince_platforms.append((device,platforms))
165 return supported_wince_platforms
166 def gather_msvc_detected_versions():
167 version_pattern=re.compile(r'^(\d\d?\.\d\d?)(Exp)?$')
168 detected_versions=[]
169 for vcver,vcvar in(('VCExpress','Exp'),('VisualStudio','')):
170 prefix='SOFTWARE\\Wow6432node\\Microsoft\\'+vcver
171 try:
172 all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix)
173 except OSError:
174 prefix='SOFTWARE\\Microsoft\\'+vcver
175 try:
176 all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix)
177 except OSError:
178 continue
179 index=0
180 while 1:
181 try:
182 version=Utils.winreg.EnumKey(all_versions,index)
183 except OSError:
184 break
185 index+=1
186 match=version_pattern.match(version)
187 if match:
188 versionnumber=float(match.group(1))
189 else:
190 continue
191 detected_versions.append((versionnumber,version+vcvar,prefix+'\\'+version))
192 def fun(tup):
193 return tup[0]
194 detected_versions.sort(key=fun)
195 return detected_versions
196 class target_compiler(object):
197 def __init__(self,ctx,compiler,cpu,version,bat_target,bat,callback=None):
198 self.conf=ctx
199 self.name=None
200 self.is_valid=False
201 self.is_done=False
202 self.compiler=compiler
203 self.cpu=cpu
204 self.version=version
205 self.bat_target=bat_target
206 self.bat=bat
207 self.callback=callback
208 def evaluate(self):
209 if self.is_done:
210 return
211 self.is_done=True
212 try:
213 vs=self.conf.get_msvc_version(self.compiler,self.version,self.bat_target,self.bat)
214 except Errors.ConfigurationError:
215 self.is_valid=False
216 return
217 if self.callback:
218 vs=self.callback(self,vs)
219 self.is_valid=True
220 (self.bindirs,self.incdirs,self.libdirs)=vs
221 def __str__(self):
222 return str((self.compiler,self.cpu,self.version,self.bat_target,self.bat))
223 def __repr__(self):
224 return repr((self.compiler,self.cpu,self.version,self.bat_target,self.bat))
225 @conf
226 def gather_wsdk_versions(conf,versions):
227 version_pattern=re.compile(r'^v..?.?\...?.?')
228 try:
229 all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Microsoft SDKs\\Windows')
230 except OSError:
231 try:
232 all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows')
233 except OSError:
234 return
235 index=0
236 while 1:
237 try:
238 version=Utils.winreg.EnumKey(all_versions,index)
239 except OSError:
240 break
241 index+=1
242 if not version_pattern.match(version):
243 continue
244 try:
245 msvc_version=Utils.winreg.OpenKey(all_versions,version)
246 path,type=Utils.winreg.QueryValueEx(msvc_version,'InstallationFolder')
247 except OSError:
248 continue
249 if path and os.path.isfile(os.path.join(path,'bin','SetEnv.cmd')):
250 targets={}
251 for target,arch in all_msvc_platforms:
252 targets[target]=target_compiler(conf,'wsdk',arch,version,'/'+target,os.path.join(path,'bin','SetEnv.cmd'))
253 versions['wsdk '+version[1:]]=targets
254 @conf
255 def gather_msvc_targets(conf,versions,version,vc_path):
256 targets={}
257 if os.path.isfile(os.path.join(vc_path,'VC','Auxiliary','Build','vcvarsall.bat')):
258 for target,realtarget in all_msvc_platforms[::-1]:
259 targets[target]=target_compiler(conf,'msvc',realtarget,version,target,os.path.join(vc_path,'VC','Auxiliary','Build','vcvarsall.bat'))
260 elif os.path.isfile(os.path.join(vc_path,'vcvarsall.bat')):
261 for target,realtarget in all_msvc_platforms[::-1]:
262 targets[target]=target_compiler(conf,'msvc',realtarget,version,target,os.path.join(vc_path,'vcvarsall.bat'))
263 elif os.path.isfile(os.path.join(vc_path,'Common7','Tools','vsvars32.bat')):
264 targets['x86']=target_compiler(conf,'msvc','x86',version,'x86',os.path.join(vc_path,'Common7','Tools','vsvars32.bat'))
265 elif os.path.isfile(os.path.join(vc_path,'Bin','vcvars32.bat')):
266 targets['x86']=target_compiler(conf,'msvc','x86',version,'',os.path.join(vc_path,'Bin','vcvars32.bat'))
267 if targets:
268 versions['msvc %s'%version]=targets
269 @conf
270 def gather_wince_targets(conf,versions,version,vc_path,vsvars,supported_platforms):
271 for device,platforms in supported_platforms:
272 targets={}
273 for platform,compiler,include,lib in platforms:
274 winCEpath=os.path.join(vc_path,'ce')
275 if not os.path.isdir(winCEpath):
276 continue
277 if os.path.isdir(os.path.join(winCEpath,'lib',platform)):
278 bindirs=[os.path.join(winCEpath,'bin',compiler),os.path.join(winCEpath,'bin','x86_'+compiler)]
279 incdirs=[os.path.join(winCEpath,'include'),os.path.join(winCEpath,'atlmfc','include'),include]
280 libdirs=[os.path.join(winCEpath,'lib',platform),os.path.join(winCEpath,'atlmfc','lib',platform),lib]
281 def combine_common(obj,compiler_env):
282 (common_bindirs,_1,_2)=compiler_env
283 return(bindirs+common_bindirs,incdirs,libdirs)
284 targets[platform]=target_compiler(conf,'msvc',platform,version,'x86',vsvars,combine_common)
285 if targets:
286 versions[device+' '+version]=targets
287 @conf
288 def gather_winphone_targets(conf,versions,version,vc_path,vsvars):
289 targets={}
290 for target,realtarget in all_msvc_platforms[::-1]:
291 targets[target]=target_compiler(conf,'winphone',realtarget,version,target,vsvars)
292 if targets:
293 versions['winphone '+version]=targets
294 @conf
295 def gather_vswhere_versions(conf,versions):
296 try:
297 import json
298 except ImportError:
299 Logs.error('Visual Studio 2017 detection requires Python 2.6')
300 return
301 prg_path=os.environ.get('ProgramFiles(x86)',os.environ.get('ProgramFiles','C:\\Program Files (x86)'))
302 vswhere=os.path.join(prg_path,'Microsoft Visual Studio','Installer','vswhere.exe')
303 args=[vswhere,'-products','*','-legacy','-format','json']
304 try:
305 txt=conf.cmd_and_log(args)
306 except Errors.WafError as e:
307 Logs.debug('msvc: vswhere.exe failed %s',e)
308 return
309 if sys.version_info[0]<3:
310 txt=txt.decode(Utils.console_encoding())
311 arr=json.loads(txt)
312 arr.sort(key=lambda x:x['installationVersion'])
313 for entry in arr:
314 ver=entry['installationVersion']
315 ver=str('.'.join(ver.split('.')[:2]))
316 path=str(os.path.abspath(entry['installationPath']))
317 if os.path.exists(path)and('msvc %s'%ver)not in versions:
318 conf.gather_msvc_targets(versions,ver,path)
319 @conf
320 def gather_msvc_versions(conf,versions):
321 vc_paths=[]
322 for(v,version,reg)in gather_msvc_detected_versions():
323 try:
324 try:
325 msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,reg+"\\Setup\\VC")
326 except OSError:
327 msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,reg+"\\Setup\\Microsoft Visual C++")
328 path,type=Utils.winreg.QueryValueEx(msvc_version,'ProductDir')
329 except OSError:
330 try:
331 msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,"SOFTWARE\\Wow6432node\\Microsoft\\VisualStudio\\SxS\\VS7")
332 path,type=Utils.winreg.QueryValueEx(msvc_version,version)
333 except OSError:
334 continue
335 else:
336 vc_paths.append((version,os.path.abspath(str(path))))
337 continue
338 else:
339 vc_paths.append((version,os.path.abspath(str(path))))
340 wince_supported_platforms=gather_wince_supported_platforms()
341 for version,vc_path in vc_paths:
342 vs_path=os.path.dirname(vc_path)
343 vsvars=os.path.join(vs_path,'Common7','Tools','vsvars32.bat')
344 if wince_supported_platforms and os.path.isfile(vsvars):
345 conf.gather_wince_targets(versions,version,vc_path,vsvars,wince_supported_platforms)
346 for version,vc_path in vc_paths:
347 vs_path=os.path.dirname(vc_path)
348 vsvars=os.path.join(vs_path,'VC','WPSDK','WP80','vcvarsphoneall.bat')
349 if os.path.isfile(vsvars):
350 conf.gather_winphone_targets(versions,'8.0',vc_path,vsvars)
351 break
352 for version,vc_path in vc_paths:
353 vs_path=os.path.dirname(vc_path)
354 conf.gather_msvc_targets(versions,version,vc_path)
355 @conf
356 def gather_icl_versions(conf,versions):
357 version_pattern=re.compile(r'^...?.?\....?.?')
358 try:
359 all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Compilers\\C++')
360 except OSError:
361 try:
362 all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Compilers\\C++')
363 except OSError:
364 return
365 index=0
366 while 1:
367 try:
368 version=Utils.winreg.EnumKey(all_versions,index)
369 except OSError:
370 break
371 index+=1
372 if not version_pattern.match(version):
373 continue
374 targets={}
375 for target,arch in all_icl_platforms:
376 if target=='intel64':
377 targetDir='EM64T_NATIVE'
378 else:
379 targetDir=target
380 try:
381 Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir)
382 icl_version=Utils.winreg.OpenKey(all_versions,version)
383 path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
384 except OSError:
385 pass
386 else:
387 batch_file=os.path.join(path,'bin','iclvars.bat')
388 if os.path.isfile(batch_file):
389 targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file)
390 for target,arch in all_icl_platforms:
391 try:
392 icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+target)
393 path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
394 except OSError:
395 continue
396 else:
397 batch_file=os.path.join(path,'bin','iclvars.bat')
398 if os.path.isfile(batch_file):
399 targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file)
400 major=version[0:2]
401 versions['intel '+major]=targets
402 @conf
403 def gather_intel_composer_versions(conf,versions):
404 version_pattern=re.compile(r'^...?.?\...?.?.?')
405 try:
406 all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Suites')
407 except OSError:
408 try:
409 all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Suites')
410 except OSError:
411 return
412 index=0
413 while 1:
414 try:
415 version=Utils.winreg.EnumKey(all_versions,index)
416 except OSError:
417 break
418 index+=1
419 if not version_pattern.match(version):
420 continue
421 targets={}
422 for target,arch in all_icl_platforms:
423 if target=='intel64':
424 targetDir='EM64T_NATIVE'
425 else:
426 targetDir=target
427 try:
428 try:
429 defaults=Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\'+targetDir)
430 except OSError:
431 if targetDir=='EM64T_NATIVE':
432 defaults=Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\EM64T')
433 else:
434 raise
435 uid,type=Utils.winreg.QueryValueEx(defaults,'SubKey')
436 Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++\\'+targetDir)
437 icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++')
438 path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
439 except OSError:
440 pass
441 else:
442 batch_file=os.path.join(path,'bin','iclvars.bat')
443 if os.path.isfile(batch_file):
444 targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file)
445 compilervars_warning_attr='_compilervars_warning_key'
446 if version[0:2]=='13'and getattr(conf,compilervars_warning_attr,True):
447 setattr(conf,compilervars_warning_attr,False)
448 patch_url='http://software.intel.com/en-us/forums/topic/328487'
449 compilervars_arch=os.path.join(path,'bin','compilervars_arch.bat')
450 for vscomntool in('VS110COMNTOOLS','VS100COMNTOOLS'):
451 if vscomntool in os.environ:
452 vs_express_path=os.environ[vscomntool]+r'..\IDE\VSWinExpress.exe'
453 dev_env_path=os.environ[vscomntool]+r'..\IDE\devenv.exe'
454 if(r'if exist "%VS110COMNTOOLS%..\IDE\VSWinExpress.exe"'in Utils.readf(compilervars_arch)and not os.path.exists(vs_express_path)and not os.path.exists(dev_env_path)):
455 Logs.warn(('The Intel compilervar_arch.bat only checks for one Visual Studio SKU ''(VSWinExpress.exe) but it does not seem to be installed at %r. ''The intel command line set up will fail to configure unless the file %r''is patched. See: %s')%(vs_express_path,compilervars_arch,patch_url))
456 major=version[0:2]
457 versions['intel '+major]=targets
458 @conf
459 def detect_msvc(self):
460 return self.setup_msvc(self.get_msvc_versions())
461 @conf
462 def get_msvc_versions(self):
463 dct=Utils.ordered_iter_dict()
464 self.gather_icl_versions(dct)
465 self.gather_intel_composer_versions(dct)
466 self.gather_wsdk_versions(dct)
467 self.gather_msvc_versions(dct)
468 self.gather_vswhere_versions(dct)
469 Logs.debug('msvc: detected versions %r',list(dct.keys()))
470 return dct
471 @conf
472 def find_lt_names_msvc(self,libname,is_static=False):
473 lt_names=['lib%s.la'%libname,'%s.la'%libname,]
474 for path in self.env.LIBPATH:
475 for la in lt_names:
476 laf=os.path.join(path,la)
477 dll=None
478 if os.path.exists(laf):
479 ltdict=Utils.read_la_file(laf)
480 lt_libdir=None
481 if ltdict.get('libdir',''):
482 lt_libdir=ltdict['libdir']
483 if not is_static and ltdict.get('library_names',''):
484 dllnames=ltdict['library_names'].split()
485 dll=dllnames[0].lower()
486 dll=re.sub(r'\.dll$','',dll)
487 return(lt_libdir,dll,False)
488 elif ltdict.get('old_library',''):
489 olib=ltdict['old_library']
490 if os.path.exists(os.path.join(path,olib)):
491 return(path,olib,True)
492 elif lt_libdir!=''and os.path.exists(os.path.join(lt_libdir,olib)):
493 return(lt_libdir,olib,True)
494 else:
495 return(None,olib,True)
496 else:
497 raise self.errors.WafError('invalid libtool object file: %s'%laf)
498 return(None,None,None)
499 @conf
500 def libname_msvc(self,libname,is_static=False):
501 lib=libname.lower()
502 lib=re.sub(r'\.lib$','',lib)
503 if lib in g_msvc_systemlibs:
504 return lib
505 lib=re.sub('^lib','',lib)
506 if lib=='m':
507 return None
508 (lt_path,lt_libname,lt_static)=self.find_lt_names_msvc(lib,is_static)
509 if lt_path!=None and lt_libname!=None:
510 if lt_static:
511 return os.path.join(lt_path,lt_libname)
512 if lt_path!=None:
513 _libpaths=[lt_path]+self.env.LIBPATH
514 else:
515 _libpaths=self.env.LIBPATH
516 static_libs=['lib%ss.lib'%lib,'lib%s.lib'%lib,'%ss.lib'%lib,'%s.lib'%lib,]
517 dynamic_libs=['lib%s.dll.lib'%lib,'lib%s.dll.a'%lib,'%s.dll.lib'%lib,'%s.dll.a'%lib,'lib%s_d.lib'%lib,'%s_d.lib'%lib,'%s.lib'%lib,]
518 libnames=static_libs
519 if not is_static:
520 libnames=dynamic_libs+static_libs
521 for path in _libpaths:
522 for libn in libnames:
523 if os.path.exists(os.path.join(path,libn)):
524 Logs.debug('msvc: lib found: %s',os.path.join(path,libn))
525 return re.sub(r'\.lib$','',libn)
526 self.fatal('The library %r could not be found'%libname)
527 return re.sub(r'\.lib$','',libname)
528 @conf
529 def check_lib_msvc(self,libname,is_static=False,uselib_store=None):
530 libn=self.libname_msvc(libname,is_static)
531 if not uselib_store:
532 uselib_store=libname.upper()
533 if False and is_static:
534 self.env['STLIB_'+uselib_store]=[libn]
535 else:
536 self.env['LIB_'+uselib_store]=[libn]
537 @conf
538 def check_libs_msvc(self,libnames,is_static=False):
539 for libname in Utils.to_list(libnames):
540 self.check_lib_msvc(libname,is_static)
541 def configure(conf):
542 conf.autodetect(True)
543 conf.find_msvc()
544 conf.msvc_common_flags()
545 conf.cc_load_tools()
546 conf.cxx_load_tools()
547 conf.cc_add_flags()
548 conf.cxx_add_flags()
549 conf.link_add_flags()
550 conf.visual_studio_add_flags()
551 @conf
552 def no_autodetect(conf):
553 conf.env.NO_MSVC_DETECT=1
554 configure(conf)
555 @conf
556 def autodetect(conf,arch=False):
557 v=conf.env
558 if v.NO_MSVC_DETECT:
559 return
560 compiler,version,path,includes,libdirs,cpu=conf.detect_msvc()
561 if arch:
562 v.DEST_CPU=cpu
563 v.PATH=path
564 v.INCLUDES=includes
565 v.LIBPATH=libdirs
566 v.MSVC_COMPILER=compiler
567 try:
568 v.MSVC_VERSION=float(version)
569 except ValueError:
570 v.MSVC_VERSION=float(version[:-3])
571 def _get_prog_names(conf,compiler):
572 if compiler=='intel':
573 compiler_name='ICL'
574 linker_name='XILINK'
575 lib_name='XILIB'
576 else:
577 compiler_name='CL'
578 linker_name='LINK'
579 lib_name='LIB'
580 return compiler_name,linker_name,lib_name
581 @conf
582 def find_msvc(conf):
583 if sys.platform=='cygwin':
584 conf.fatal('MSVC module does not work under cygwin Python!')
585 v=conf.env
586 path=v.PATH
587 compiler=v.MSVC_COMPILER
588 version=v.MSVC_VERSION
589 compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
590 v.MSVC_MANIFEST=(compiler=='msvc'and version>=8)or(compiler=='wsdk'and version>=6)or(compiler=='intel'and version>=11)
591 cxx=conf.find_program(compiler_name,var='CXX',path_list=path)
592 env=dict(conf.environ)
593 if path:
594 env.update(PATH=';'.join(path))
595 if not conf.cmd_and_log(cxx+['/nologo','/help'],env=env):
596 conf.fatal('the msvc compiler could not be identified')
597 v.CC=v.CXX=cxx
598 v.CC_NAME=v.CXX_NAME='msvc'
599 if not v.LINK_CXX:
600 conf.find_program(linker_name,path_list=path,errmsg='%s was not found (linker)'%linker_name,var='LINK_CXX')
601 if not v.LINK_CC:
602 v.LINK_CC=v.LINK_CXX
603 if not v.AR:
604 stliblink=conf.find_program(lib_name,path_list=path,var='AR')
605 if not stliblink:
606 return
607 v.ARFLAGS=['/nologo']
608 if v.MSVC_MANIFEST:
609 conf.find_program('MT',path_list=path,var='MT')
610 v.MTFLAGS=['/nologo']
611 try:
612 conf.load('winres')
613 except Errors.ConfigurationError:
614 Logs.warn('Resource compiler not found. Compiling resource file is disabled')
615 @conf
616 def visual_studio_add_flags(self):
617 v=self.env
618 if self.environ.get('INCLUDE'):
619 v.prepend_value('INCLUDES',[x for x in self.environ['INCLUDE'].split(';')if x])
620 if self.environ.get('LIB'):
621 v.prepend_value('LIBPATH',[x for x in self.environ['LIB'].split(';')if x])
622 @conf
623 def msvc_common_flags(conf):
624 v=conf.env
625 v.DEST_BINFMT='pe'
626 v.append_value('CFLAGS',['/nologo'])
627 v.append_value('CXXFLAGS',['/nologo'])
628 v.append_value('LINKFLAGS',['/nologo'])
629 v.DEFINES_ST='/D%s'
630 v.CC_SRC_F=''
631 v.CC_TGT_F=['/c','/Fo']
632 v.CXX_SRC_F=''
633 v.CXX_TGT_F=['/c','/Fo']
634 if(v.MSVC_COMPILER=='msvc'and v.MSVC_VERSION>=8)or(v.MSVC_COMPILER=='wsdk'and v.MSVC_VERSION>=6):
635 v.CC_TGT_F=['/FC']+v.CC_TGT_F
636 v.CXX_TGT_F=['/FC']+v.CXX_TGT_F
637 v.CPPPATH_ST='/I%s'
638 v.AR_TGT_F=v.CCLNK_TGT_F=v.CXXLNK_TGT_F='/OUT:'
639 v.CFLAGS_CRT_MULTITHREADED=v.CXXFLAGS_CRT_MULTITHREADED=['/MT']
640 v.CFLAGS_CRT_MULTITHREADED_DLL=v.CXXFLAGS_CRT_MULTITHREADED_DLL=['/MD']
641 v.CFLAGS_CRT_MULTITHREADED_DBG=v.CXXFLAGS_CRT_MULTITHREADED_DBG=['/MTd']
642 v.CFLAGS_CRT_MULTITHREADED_DLL_DBG=v.CXXFLAGS_CRT_MULTITHREADED_DLL_DBG=['/MDd']
643 v.LIB_ST='%s.lib'
644 v.LIBPATH_ST='/LIBPATH:%s'
645 v.STLIB_ST='%s.lib'
646 v.STLIBPATH_ST='/LIBPATH:%s'
647 if v.MSVC_MANIFEST:
648 v.append_value('LINKFLAGS',['/MANIFEST'])
649 v.CFLAGS_cshlib=[]
650 v.CXXFLAGS_cxxshlib=[]
651 v.LINKFLAGS_cshlib=v.LINKFLAGS_cxxshlib=['/DLL']
652 v.cshlib_PATTERN=v.cxxshlib_PATTERN='%s.dll'
653 v.implib_PATTERN='%s.lib'
654 v.IMPLIB_ST='/IMPLIB:%s'
655 v.LINKFLAGS_cstlib=[]
656 v.cstlib_PATTERN=v.cxxstlib_PATTERN='%s.lib'
657 v.cprogram_PATTERN=v.cxxprogram_PATTERN='%s.exe'
658 v.def_PATTERN='/def:%s'
659 @after_method('apply_link')
660 @feature('c','cxx')
661 def apply_flags_msvc(self):
662 if self.env.CC_NAME!='msvc'or not getattr(self,'link_task',None):
663 return
664 is_static=isinstance(self.link_task,ccroot.stlink_task)
665 subsystem=getattr(self,'subsystem','')
666 if subsystem:
667 subsystem='/subsystem:%s'%subsystem
668 flags=is_static and'ARFLAGS'or'LINKFLAGS'
669 self.env.append_value(flags,subsystem)
670 if not is_static:
671 for f in self.env.LINKFLAGS:
672 d=f.lower()
673 if d[1:]in('debug','debug:full','debug:fastlink'):
674 pdbnode=self.link_task.outputs[0].change_ext('.pdb')
675 self.link_task.outputs.append(pdbnode)
676 if getattr(self,'install_task',None):
677 self.pdb_install_task=self.add_install_files(install_to=self.install_task.install_to,install_from=pdbnode)
678 break
679 @feature('cprogram','cshlib','cxxprogram','cxxshlib')
680 @after_method('apply_link')
681 def apply_manifest(self):
682 if self.env.CC_NAME=='msvc'and self.env.MSVC_MANIFEST and getattr(self,'link_task',None):
683 out_node=self.link_task.outputs[0]
684 man_node=out_node.parent.find_or_declare(out_node.name+'.manifest')
685 self.link_task.outputs.append(man_node)
686 self.env.DO_MANIFEST=True
687 def make_winapp(self,family):
688 append=self.env.append_unique
689 append('DEFINES','WINAPI_FAMILY=%s'%family)
690 append('CXXFLAGS',['/ZW','/TP'])
691 for lib_path in self.env.LIBPATH:
692 append('CXXFLAGS','/AI%s'%lib_path)
693 @feature('winphoneapp')
694 @after_method('process_use')
695 @after_method('propagate_uselib_vars')
696 def make_winphone_app(self):
697 make_winapp(self,'WINAPI_FAMILY_PHONE_APP')
698 self.env.append_unique('LINKFLAGS',['/NODEFAULTLIB:ole32.lib','PhoneAppModelHost.lib'])
699 @feature('winapp')
700 @after_method('process_use')
701 @after_method('propagate_uselib_vars')
702 def make_windows_app(self):
703 make_winapp(self,'WINAPI_FAMILY_DESKTOP_APP')
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os
5 import waflib.Tools.asm
6 from waflib.TaskGen import feature
7 @feature('asm')
8 def apply_nasm_vars(self):
9 self.env.append_value('ASFLAGS',self.to_list(getattr(self,'nasm_flags',[])))
10 def configure(conf):
11 conf.find_program(['nasm','yasm'],var='AS')
12 conf.env.AS_TGT_F=['-o']
13 conf.env.ASLNK_TGT_F=['-o']
14 conf.load('asm')
15 conf.env.ASMPATH_ST='-I%s'+os.sep
16 txt=conf.cmd_and_log(conf.env.AS+['--version'])
17 if'yasm'in txt.lower():
18 conf.env.ASM_NAME='yasm'
19 else:
20 conf.env.ASM_NAME='nasm'
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib import Task
5 def build(bld):
6 def run(self):
7 for x in self.outputs:
8 x.write('')
9 for(name,cls)in Task.classes.items():
10 cls.run=run
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os
5 from waflib import Task,Options,Utils,Errors
6 from waflib.Configure import conf
7 from waflib.TaskGen import extension,feature,before_method
8 @before_method('apply_incpaths','apply_link','propagate_uselib_vars')
9 @feature('perlext')
10 def init_perlext(self):
11 self.uselib=self.to_list(getattr(self,'uselib',[]))
12 if not'PERLEXT'in self.uselib:
13 self.uselib.append('PERLEXT')
14 self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.perlext_PATTERN
15 @extension('.xs')
16 def xsubpp_file(self,node):
17 outnode=node.change_ext('.c')
18 self.create_task('xsubpp',node,outnode)
19 self.source.append(outnode)
20 class xsubpp(Task.Task):
21 run_str='${PERL} ${XSUBPP} -noprototypes -typemap ${EXTUTILS_TYPEMAP} ${SRC} > ${TGT}'
22 color='BLUE'
23 ext_out=['.h']
24 @conf
25 def check_perl_version(self,minver=None):
26 res=True
27 if minver:
28 cver='.'.join(map(str,minver))
29 else:
30 cver=''
31 self.start_msg('Checking for minimum perl version %s'%cver)
32 perl=self.find_program('perl',var='PERL',value=getattr(Options.options,'perlbinary',None))
33 version=self.cmd_and_log(perl+["-e",'printf \"%vd\", $^V'])
34 if not version:
35 res=False
36 version="Unknown"
37 elif not minver is None:
38 ver=tuple(map(int,version.split(".")))
39 if ver<minver:
40 res=False
41 self.end_msg(version,color=res and'GREEN'or'YELLOW')
42 return res
43 @conf
44 def check_perl_module(self,module):
45 cmd=self.env.PERL+['-e','use %s'%module]
46 self.start_msg('perl module %s'%module)
47 try:
48 r=self.cmd_and_log(cmd)
49 except Errors.WafError:
50 self.end_msg(False)
51 return None
52 self.end_msg(r or True)
53 return r
54 @conf
55 def check_perl_ext_devel(self):
56 env=self.env
57 perl=env.PERL
58 if not perl:
59 self.fatal('find perl first')
60 def cmd_perl_config(s):
61 return perl+['-MConfig','-e','print \"%s\"'%s]
62 def cfg_str(cfg):
63 return self.cmd_and_log(cmd_perl_config(cfg))
64 def cfg_lst(cfg):
65 return Utils.to_list(cfg_str(cfg))
66 def find_xsubpp():
67 for var in('privlib','vendorlib'):
68 xsubpp=cfg_lst('$Config{%s}/ExtUtils/xsubpp$Config{exe_ext}'%var)
69 if xsubpp and os.path.isfile(xsubpp[0]):
70 return xsubpp
71 return self.find_program('xsubpp')
72 env.LINKFLAGS_PERLEXT=cfg_lst('$Config{lddlflags}')
73 env.INCLUDES_PERLEXT=cfg_lst('$Config{archlib}/CORE')
74 env.CFLAGS_PERLEXT=cfg_lst('$Config{ccflags} $Config{cccdlflags}')
75 env.EXTUTILS_TYPEMAP=cfg_lst('$Config{privlib}/ExtUtils/typemap')
76 env.XSUBPP=find_xsubpp()
77 if not getattr(Options.options,'perlarchdir',None):
78 env.ARCHDIR_PERL=cfg_str('$Config{sitearch}')
79 else:
80 env.ARCHDIR_PERL=getattr(Options.options,'perlarchdir')
81 env.perlext_PATTERN='%s.'+cfg_str('$Config{dlext}')
82 def options(opt):
83 opt.add_option('--with-perl-binary',type='string',dest='perlbinary',help='Specify alternate perl binary',default=None)
84 opt.add_option('--with-perl-archdir',type='string',dest='perlarchdir',help='Specify directory where to install arch specific files',default=None)
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os,sys
5 from waflib import Errors,Logs,Node,Options,Task,Utils
6 from waflib.TaskGen import extension,before_method,after_method,feature
7 from waflib.Configure import conf
8 FRAG='''
9 #include <Python.h>
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13 void Py_Initialize(void);
14 void Py_Finalize(void);
15 #ifdef __cplusplus
16 }
17 #endif
18 int main(int argc, char **argv)
19 {
20 (void)argc; (void)argv;
21 Py_Initialize();
22 Py_Finalize();
23 return 0;
24 }
25 '''
26 INST='''
27 import sys, py_compile
28 py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3], True)
29 '''
30 DISTUTILS_IMP=['from distutils.sysconfig import get_config_var, get_python_lib']
31 @before_method('process_source')
32 @feature('py')
33 def feature_py(self):
34 self.install_path=getattr(self,'install_path','${PYTHONDIR}')
35 install_from=getattr(self,'install_from',None)
36 if install_from and not isinstance(install_from,Node.Node):
37 install_from=self.path.find_dir(install_from)
38 self.install_from=install_from
39 ver=self.env.PYTHON_VERSION
40 if not ver:
41 self.bld.fatal('Installing python files requires PYTHON_VERSION, try conf.check_python_version')
42 if int(ver.replace('.',''))>31:
43 self.install_32=True
44 @extension('.py')
45 def process_py(self,node):
46 assert(hasattr(self,'install_path')),'add features="py" for target "%s" in "%s/wscript".'%(self.target,self.path.nice_path())
47 self.install_from=getattr(self,'install_from',None)
48 relative_trick=getattr(self,'relative_trick',True)
49 if self.install_from:
50 assert isinstance(self.install_from,Node.Node),'add features="py" for target "%s" in "%s/wscript" (%s).'%(self.target,self.path.nice_path(),type(self.install_from))
51 if self.install_path:
52 if self.install_from:
53 self.add_install_files(install_to=self.install_path,install_from=node,cwd=self.install_from,relative_trick=relative_trick)
54 else:
55 self.add_install_files(install_to=self.install_path,install_from=node,relative_trick=relative_trick)
56 lst=[]
57 if self.env.PYC:
58 lst.append('pyc')
59 if self.env.PYO:
60 lst.append('pyo')
61 if self.install_path:
62 if self.install_from:
63 target_dir=node.path_from(self.install_from)if relative_trick else node.name
64 pyd=Utils.subst_vars("%s/%s"%(self.install_path,target_dir),self.env)
65 else:
66 target_dir=node.path_from(self.path)if relative_trick else node.name
67 pyd=Utils.subst_vars("%s/%s"%(self.install_path,target_dir),self.env)
68 else:
69 pyd=node.abspath()
70 for ext in lst:
71 if self.env.PYTAG and not self.env.NOPYCACHE:
72 name=node.name[:-3]
73 pyobj=node.parent.get_bld().make_node('__pycache__').make_node("%s.%s.%s"%(name,self.env.PYTAG,ext))
74 pyobj.parent.mkdir()
75 else:
76 pyobj=node.change_ext(".%s"%ext)
77 tsk=self.create_task(ext,node,pyobj)
78 tsk.pyd=pyd
79 if self.install_path:
80 self.add_install_files(install_to=os.path.dirname(pyd),install_from=pyobj,cwd=node.parent.get_bld(),relative_trick=relative_trick)
81 class pyc(Task.Task):
82 color='PINK'
83 def __str__(self):
84 node=self.outputs[0]
85 return node.path_from(node.ctx.launch_node())
86 def run(self):
87 cmd=[Utils.subst_vars('${PYTHON}',self.env),'-c',INST,self.inputs[0].abspath(),self.outputs[0].abspath(),self.pyd]
88 ret=self.generator.bld.exec_command(cmd)
89 return ret
90 class pyo(Task.Task):
91 color='PINK'
92 def __str__(self):
93 node=self.outputs[0]
94 return node.path_from(node.ctx.launch_node())
95 def run(self):
96 cmd=[Utils.subst_vars('${PYTHON}',self.env),Utils.subst_vars('${PYFLAGS_OPT}',self.env),'-c',INST,self.inputs[0].abspath(),self.outputs[0].abspath(),self.pyd]
97 ret=self.generator.bld.exec_command(cmd)
98 return ret
99 @feature('pyext')
100 @before_method('propagate_uselib_vars','apply_link')
101 @after_method('apply_bundle')
102 def init_pyext(self):
103 self.uselib=self.to_list(getattr(self,'uselib',[]))
104 if not'PYEXT'in self.uselib:
105 self.uselib.append('PYEXT')
106 self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.macbundle_PATTERN=self.env.pyext_PATTERN
107 self.env.fcshlib_PATTERN=self.env.dshlib_PATTERN=self.env.pyext_PATTERN
108 try:
109 if not self.install_path:
110 return
111 except AttributeError:
112 self.install_path='${PYTHONARCHDIR}'
113 @feature('pyext')
114 @before_method('apply_link','apply_bundle')
115 def set_bundle(self):
116 if Utils.unversioned_sys_platform()=='darwin':
117 self.mac_bundle=True
118 @before_method('propagate_uselib_vars')
119 @feature('pyembed')
120 def init_pyembed(self):
121 self.uselib=self.to_list(getattr(self,'uselib',[]))
122 if not'PYEMBED'in self.uselib:
123 self.uselib.append('PYEMBED')
124 @conf
125 def get_python_variables(self,variables,imports=None):
126 if not imports:
127 try:
128 imports=self.python_imports
129 except AttributeError:
130 imports=DISTUTILS_IMP
131 program=list(imports)
132 program.append('')
133 for v in variables:
134 program.append("print(repr(%s))"%v)
135 os_env=dict(os.environ)
136 try:
137 del os_env['MACOSX_DEPLOYMENT_TARGET']
138 except KeyError:
139 pass
140 try:
141 out=self.cmd_and_log(self.env.PYTHON+['-c','\n'.join(program)],env=os_env)
142 except Errors.WafError:
143 self.fatal('The distutils module is unusable: install "python-devel"?')
144 self.to_log(out)
145 return_values=[]
146 for s in out.splitlines():
147 s=s.strip()
148 if not s:
149 continue
150 if s=='None':
151 return_values.append(None)
152 elif(s[0]=="'"and s[-1]=="'")or(s[0]=='"'and s[-1]=='"'):
153 return_values.append(eval(s))
154 elif s[0].isdigit():
155 return_values.append(int(s))
156 else:break
157 return return_values
158 @conf
159 def test_pyembed(self,mode,msg='Testing pyembed configuration'):
160 self.check(header_name='Python.h',define_name='HAVE_PYEMBED',msg=msg,fragment=FRAG,errmsg='Could not build a python embedded interpreter',features='%s %sprogram pyembed'%(mode,mode))
161 @conf
162 def test_pyext(self,mode,msg='Testing pyext configuration'):
163 self.check(header_name='Python.h',define_name='HAVE_PYEXT',msg=msg,fragment=FRAG,errmsg='Could not build python extensions',features='%s %sshlib pyext'%(mode,mode))
164 @conf
165 def python_cross_compile(self,features='pyembed pyext'):
166 features=Utils.to_list(features)
167 if not('PYTHON_LDFLAGS'in self.environ or'PYTHON_PYEXT_LDFLAGS'in self.environ or'PYTHON_PYEMBED_LDFLAGS'in self.environ):
168 return False
169 for x in'PYTHON_VERSION PYTAG pyext_PATTERN'.split():
170 if not x in self.environ:
171 self.fatal('Please set %s in the os environment'%x)
172 else:
173 self.env[x]=self.environ[x]
174 xx=self.env.CXX_NAME and'cxx'or'c'
175 if'pyext'in features:
176 flags=self.environ.get('PYTHON_PYEXT_LDFLAGS',self.environ.get('PYTHON_LDFLAGS'))
177 if flags is None:
178 self.fatal('No flags provided through PYTHON_PYEXT_LDFLAGS as required')
179 else:
180 self.parse_flags(flags,'PYEXT')
181 self.test_pyext(xx)
182 if'pyembed'in features:
183 flags=self.environ.get('PYTHON_PYEMBED_LDFLAGS',self.environ.get('PYTHON_LDFLAGS'))
184 if flags is None:
185 self.fatal('No flags provided through PYTHON_PYEMBED_LDFLAGS as required')
186 else:
187 self.parse_flags(flags,'PYEMBED')
188 self.test_pyembed(xx)
189 return True
190 @conf
191 def check_python_headers(conf,features='pyembed pyext'):
192 features=Utils.to_list(features)
193 assert('pyembed'in features)or('pyext'in features),"check_python_headers features must include 'pyembed' and/or 'pyext'"
194 env=conf.env
195 if not env.CC_NAME and not env.CXX_NAME:
196 conf.fatal('load a compiler first (gcc, g++, ..)')
197 if conf.python_cross_compile(features):
198 return
199 if not env.PYTHON_VERSION:
200 conf.check_python_version()
201 pybin=env.PYTHON
202 if not pybin:
203 conf.fatal('Could not find the python executable')
204 v='prefix SO LDFLAGS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET LDSHARED CFLAGS LDVERSION'.split()
205 try:
206 lst=conf.get_python_variables(["get_config_var('%s') or ''"%x for x in v])
207 except RuntimeError:
208 conf.fatal("Python development headers not found (-v for details).")
209 vals=['%s = %r'%(x,y)for(x,y)in zip(v,lst)]
210 conf.to_log("Configuration returned from %r:\n%s\n"%(pybin,'\n'.join(vals)))
211 dct=dict(zip(v,lst))
212 x='MACOSX_DEPLOYMENT_TARGET'
213 if dct[x]:
214 env[x]=conf.environ[x]=dct[x]
215 env.pyext_PATTERN='%s'+dct['SO']
216 num='.'.join(env.PYTHON_VERSION.split('.')[:2])
217 conf.find_program([''.join(pybin)+'-config','python%s-config'%num,'python-config-%s'%num,'python%sm-config'%num],var='PYTHON_CONFIG',msg="python-config",mandatory=False)
218 if env.PYTHON_CONFIG:
219 if conf.env.HAVE_PYTHON_H:
220 return
221 all_flags=[['--cflags','--libs','--ldflags']]
222 if sys.hexversion<0x2070000:
223 all_flags=[[k]for k in all_flags[0]]
224 xx=env.CXX_NAME and'cxx'or'c'
225 if'pyembed'in features:
226 for flags in all_flags:
227 embedflags=flags+['--embed']
228 try:
229 conf.check_cfg(msg='Asking python-config for pyembed %r flags'%' '.join(embedflags),path=env.PYTHON_CONFIG,package='',uselib_store='PYEMBED',args=embedflags)
230 except conf.errors.ConfigurationError:
231 conf.check_cfg(msg='Asking python-config for pyembed %r flags'%' '.join(flags),path=env.PYTHON_CONFIG,package='',uselib_store='PYEMBED',args=flags)
232 try:
233 conf.test_pyembed(xx)
234 except conf.errors.ConfigurationError:
235 if dct['Py_ENABLE_SHARED']and dct['LIBDIR']:
236 env.append_unique('LIBPATH_PYEMBED',[dct['LIBDIR']])
237 conf.test_pyembed(xx)
238 else:
239 raise
240 if'pyext'in features:
241 for flags in all_flags:
242 conf.check_cfg(msg='Asking python-config for pyext %r flags'%' '.join(flags),path=env.PYTHON_CONFIG,package='',uselib_store='PYEXT',args=flags)
243 try:
244 conf.test_pyext(xx)
245 except conf.errors.ConfigurationError:
246 if dct['Py_ENABLE_SHARED']and dct['LIBDIR']:
247 env.append_unique('LIBPATH_PYEXT',[dct['LIBDIR']])
248 conf.test_pyext(xx)
249 else:
250 raise
251 conf.define('HAVE_PYTHON_H',1)
252 return
253 all_flags=dct['LDFLAGS']+' '+dct['CFLAGS']
254 conf.parse_flags(all_flags,'PYEMBED')
255 all_flags=dct['LDFLAGS']+' '+dct['LDSHARED']+' '+dct['CFLAGS']
256 conf.parse_flags(all_flags,'PYEXT')
257 result=None
258 if not dct["LDVERSION"]:
259 dct["LDVERSION"]=env.PYTHON_VERSION
260 for name in('python'+dct['LDVERSION'],'python'+env.PYTHON_VERSION+'m','python'+env.PYTHON_VERSION.replace('.','')):
261 if not result and env.LIBPATH_PYEMBED:
262 path=env.LIBPATH_PYEMBED
263 conf.to_log("\n\n# Trying default LIBPATH_PYEMBED: %r\n"%path)
264 result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in LIBPATH_PYEMBED'%name)
265 if not result and dct['LIBDIR']:
266 path=[dct['LIBDIR']]
267 conf.to_log("\n\n# try again with -L$python_LIBDIR: %r\n"%path)
268 result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in LIBDIR'%name)
269 if not result and dct['LIBPL']:
270 path=[dct['LIBPL']]
271 conf.to_log("\n\n# try again with -L$python_LIBPL (some systems don't install the python library in $prefix/lib)\n")
272 result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in python_LIBPL'%name)
273 if not result:
274 path=[os.path.join(dct['prefix'],"libs")]
275 conf.to_log("\n\n# try again with -L$prefix/libs, and pythonXY name rather than pythonX.Y (win32)\n")
276 result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in $prefix/libs'%name)
277 if result:
278 break
279 if result:
280 env.LIBPATH_PYEMBED=path
281 env.append_value('LIB_PYEMBED',[name])
282 else:
283 conf.to_log("\n\n### LIB NOT FOUND\n")
284 if Utils.is_win32 or dct['Py_ENABLE_SHARED']:
285 env.LIBPATH_PYEXT=env.LIBPATH_PYEMBED
286 env.LIB_PYEXT=env.LIB_PYEMBED
287 conf.to_log("Include path for Python extensions (found via distutils module): %r\n"%(dct['INCLUDEPY'],))
288 env.INCLUDES_PYEXT=[dct['INCLUDEPY']]
289 env.INCLUDES_PYEMBED=[dct['INCLUDEPY']]
290 if env.CC_NAME=='gcc':
291 env.append_unique('CFLAGS_PYEMBED',['-fno-strict-aliasing'])
292 env.append_unique('CFLAGS_PYEXT',['-fno-strict-aliasing'])
293 if env.CXX_NAME=='gcc':
294 env.append_unique('CXXFLAGS_PYEMBED',['-fno-strict-aliasing'])
295 env.append_unique('CXXFLAGS_PYEXT',['-fno-strict-aliasing'])
296 if env.CC_NAME=="msvc":
297 from distutils.msvccompiler import MSVCCompiler
298 dist_compiler=MSVCCompiler()
299 dist_compiler.initialize()
300 env.append_value('CFLAGS_PYEXT',dist_compiler.compile_options)
301 env.append_value('CXXFLAGS_PYEXT',dist_compiler.compile_options)
302 env.append_value('LINKFLAGS_PYEXT',dist_compiler.ldflags_shared)
303 conf.check(header_name='Python.h',define_name='HAVE_PYTHON_H',uselib='PYEMBED',fragment=FRAG,errmsg='Distutils not installed? Broken python installation? Get python-config now!')
304 @conf
305 def check_python_version(conf,minver=None):
306 assert minver is None or isinstance(minver,tuple)
307 pybin=conf.env.PYTHON
308 if not pybin:
309 conf.fatal('could not find the python executable')
310 cmd=pybin+['-c','import sys\nfor x in sys.version_info: print(str(x))']
311 Logs.debug('python: Running python command %r',cmd)
312 lines=conf.cmd_and_log(cmd).split()
313 assert len(lines)==5,"found %r lines, expected 5: %r"%(len(lines),lines)
314 pyver_tuple=(int(lines[0]),int(lines[1]),int(lines[2]),lines[3],int(lines[4]))
315 result=(minver is None)or(pyver_tuple>=minver)
316 if result:
317 pyver='.'.join([str(x)for x in pyver_tuple[:2]])
318 conf.env.PYTHON_VERSION=pyver
319 if'PYTHONDIR'in conf.env:
320 pydir=conf.env.PYTHONDIR
321 elif'PYTHONDIR'in conf.environ:
322 pydir=conf.environ['PYTHONDIR']
323 else:
324 if Utils.is_win32:
325 (python_LIBDEST,pydir)=conf.get_python_variables(["get_config_var('LIBDEST') or ''","get_python_lib(standard_lib=0) or ''"])
326 else:
327 python_LIBDEST=None
328 (pydir,)=conf.get_python_variables(["get_python_lib(standard_lib=0, prefix=%r) or ''"%conf.env.PREFIX])
329 if python_LIBDEST is None:
330 if conf.env.LIBDIR:
331 python_LIBDEST=os.path.join(conf.env.LIBDIR,'python'+pyver)
332 else:
333 python_LIBDEST=os.path.join(conf.env.PREFIX,'lib','python'+pyver)
334 if'PYTHONARCHDIR'in conf.env:
335 pyarchdir=conf.env.PYTHONARCHDIR
336 elif'PYTHONARCHDIR'in conf.environ:
337 pyarchdir=conf.environ['PYTHONARCHDIR']
338 else:
339 (pyarchdir,)=conf.get_python_variables(["get_python_lib(plat_specific=1, standard_lib=0, prefix=%r) or ''"%conf.env.PREFIX])
340 if not pyarchdir:
341 pyarchdir=pydir
342 if hasattr(conf,'define'):
343 conf.define('PYTHONDIR',pydir)
344 conf.define('PYTHONARCHDIR',pyarchdir)
345 conf.env.PYTHONDIR=pydir
346 conf.env.PYTHONARCHDIR=pyarchdir
347 pyver_full='.'.join(map(str,pyver_tuple[:3]))
348 if minver is None:
349 conf.msg('Checking for python version',pyver_full)
350 else:
351 minver_str='.'.join(map(str,minver))
352 conf.msg('Checking for python version >= %s'%(minver_str,),pyver_full,color=result and'GREEN'or'YELLOW')
353 if not result:
354 conf.fatal('The python version is too old, expecting %r'%(minver,))
355 PYTHON_MODULE_TEMPLATE='''
356 import %s as current_module
357 version = getattr(current_module, '__version__', None)
358 if version is not None:
359 print(str(version))
360 else:
361 print('unknown version')
362 '''
363 @conf
364 def check_python_module(conf,module_name,condition=''):
365 msg="Checking for python module %r"%module_name
366 if condition:
367 msg='%s (%s)'%(msg,condition)
368 conf.start_msg(msg)
369 try:
370 ret=conf.cmd_and_log(conf.env.PYTHON+['-c',PYTHON_MODULE_TEMPLATE%module_name])
371 except Errors.WafError:
372 conf.end_msg(False)
373 conf.fatal('Could not find the python module %r'%module_name)
374 ret=ret.strip()
375 if condition:
376 conf.end_msg(ret)
377 if ret=='unknown version':
378 conf.fatal('Could not check the %s version'%module_name)
379 from distutils.version import LooseVersion
380 def num(*k):
381 if isinstance(k[0],int):
382 return LooseVersion('.'.join([str(x)for x in k]))
383 else:
384 return LooseVersion(k[0])
385 d={'num':num,'ver':LooseVersion(ret)}
386 ev=eval(condition,{},d)
387 if not ev:
388 conf.fatal('The %s version does not satisfy the requirements'%module_name)
389 else:
390 if ret=='unknown version':
391 conf.end_msg(True)
392 else:
393 conf.end_msg(ret)
394 def configure(conf):
395 v=conf.env
396 if getattr(Options.options,'pythondir',None):
397 v.PYTHONDIR=Options.options.pythondir
398 if getattr(Options.options,'pythonarchdir',None):
399 v.PYTHONARCHDIR=Options.options.pythonarchdir
400 if getattr(Options.options,'nopycache',None):
401 v.NOPYCACHE=Options.options.nopycache
402 if not v.PYTHON:
403 v.PYTHON=[getattr(Options.options,'python',None)or sys.executable]
404 v.PYTHON=Utils.to_list(v.PYTHON)
405 conf.find_program('python',var='PYTHON')
406 v.PYFLAGS=''
407 v.PYFLAGS_OPT='-O'
408 v.PYC=getattr(Options.options,'pyc',1)
409 v.PYO=getattr(Options.options,'pyo',1)
410 try:
411 v.PYTAG=conf.cmd_and_log(conf.env.PYTHON+['-c',"import sys\ntry:\n print(sys.implementation.cache_tag)\nexcept AttributeError:\n import imp\n print(imp.get_tag())\n"]).strip()
412 except Errors.WafError:
413 pass
414 def options(opt):
415 pyopt=opt.add_option_group("Python Options")
416 pyopt.add_option('--nopyc',dest='pyc',action='store_false',default=1,help='Do not install bytecode compiled .pyc files (configuration) [Default:install]')
417 pyopt.add_option('--nopyo',dest='pyo',action='store_false',default=1,help='Do not install optimised compiled .pyo files (configuration) [Default:install]')
418 pyopt.add_option('--nopycache',dest='nopycache',action='store_true',help='Do not use __pycache__ directory to install objects [Default:auto]')
419 pyopt.add_option('--python',dest="python",help='python binary to be used [Default: %s]'%sys.executable)
420 pyopt.add_option('--pythondir',dest='pythondir',help='Installation path for python modules (py, platform-independent .py and .pyc files)')
421 pyopt.add_option('--pythonarchdir',dest='pythonarchdir',help='Installation path for python extension (pyext, platform-dependent .so or .dylib files)')
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from __future__ import with_statement
5 try:
6 from xml.sax import make_parser
7 from xml.sax.handler import ContentHandler
8 except ImportError:
9 has_xml=False
10 ContentHandler=object
11 else:
12 has_xml=True
13 import os,sys,re
14 from waflib.Tools import cxx
15 from waflib import Build,Task,Utils,Options,Errors,Context
16 from waflib.TaskGen import feature,after_method,extension,before_method
17 from waflib.Configure import conf
18 from waflib import Logs
19 MOC_H=['.h','.hpp','.hxx','.hh']
20 EXT_RCC=['.qrc']
21 EXT_UI=['.ui']
22 EXT_QT5=['.cpp','.cc','.cxx','.C']
23 class qxx(Task.classes['cxx']):
24 def __init__(self,*k,**kw):
25 Task.Task.__init__(self,*k,**kw)
26 self.moc_done=0
27 def runnable_status(self):
28 if self.moc_done:
29 return Task.Task.runnable_status(self)
30 else:
31 for t in self.run_after:
32 if not t.hasrun:
33 return Task.ASK_LATER
34 self.add_moc_tasks()
35 return Task.Task.runnable_status(self)
36 def create_moc_task(self,h_node,m_node):
37 try:
38 moc_cache=self.generator.bld.moc_cache
39 except AttributeError:
40 moc_cache=self.generator.bld.moc_cache={}
41 try:
42 return moc_cache[h_node]
43 except KeyError:
44 tsk=moc_cache[h_node]=Task.classes['moc'](env=self.env,generator=self.generator)
45 tsk.set_inputs(h_node)
46 tsk.set_outputs(m_node)
47 tsk.env.append_unique('MOC_FLAGS','-i')
48 if self.generator:
49 self.generator.tasks.append(tsk)
50 gen=self.generator.bld.producer
51 gen.outstanding.append(tsk)
52 gen.total+=1
53 return tsk
54 else:
55 delattr(self,'cache_sig')
56 def add_moc_tasks(self):
57 node=self.inputs[0]
58 bld=self.generator.bld
59 if bld.is_install==Build.UNINSTALL:
60 return
61 try:
62 self.signature()
63 except KeyError:
64 pass
65 else:
66 delattr(self,'cache_sig')
67 include_nodes=[node.parent]+self.generator.includes_nodes
68 moctasks=[]
69 mocfiles=set()
70 for d in bld.raw_deps.get(self.uid(),[]):
71 if not d.endswith('.moc'):
72 continue
73 if d in mocfiles:
74 continue
75 mocfiles.add(d)
76 h_node=None
77 base2=d[:-4]
78 prefix=node.name[:node.name.rfind('.')]
79 if base2==prefix:
80 h_node=node
81 else:
82 for x in include_nodes:
83 for e in MOC_H:
84 h_node=x.find_node(base2+e)
85 if h_node:
86 break
87 else:
88 continue
89 break
90 if h_node:
91 m_node=h_node.change_ext('.moc')
92 else:
93 raise Errors.WafError('No source found for %r which is a moc file'%d)
94 task=self.create_moc_task(h_node,m_node)
95 moctasks.append(task)
96 self.run_after.update(set(moctasks))
97 self.moc_done=1
98 class trans_update(Task.Task):
99 run_str='${QT_LUPDATE} ${SRC} -ts ${TGT}'
100 color='BLUE'
101 class XMLHandler(ContentHandler):
102 def __init__(self):
103 ContentHandler.__init__(self)
104 self.buf=[]
105 self.files=[]
106 def startElement(self,name,attrs):
107 if name=='file':
108 self.buf=[]
109 def endElement(self,name):
110 if name=='file':
111 self.files.append(str(''.join(self.buf)))
112 def characters(self,cars):
113 self.buf.append(cars)
114 @extension(*EXT_RCC)
115 def create_rcc_task(self,node):
116 rcnode=node.change_ext('_rc.%d.cpp'%self.idx)
117 self.create_task('rcc',node,rcnode)
118 cpptask=self.create_task('cxx',rcnode,rcnode.change_ext('.o'))
119 try:
120 self.compiled_tasks.append(cpptask)
121 except AttributeError:
122 self.compiled_tasks=[cpptask]
123 return cpptask
124 @extension(*EXT_UI)
125 def create_uic_task(self,node):
126 try:
127 uic_cache=self.bld.uic_cache
128 except AttributeError:
129 uic_cache=self.bld.uic_cache={}
130 if node not in uic_cache:
131 uictask=uic_cache[node]=self.create_task('ui5',node)
132 uictask.outputs=[node.parent.find_or_declare(self.env.ui_PATTERN%node.name[:-3])]
133 @extension('.ts')
134 def add_lang(self,node):
135 self.lang=self.to_list(getattr(self,'lang',[]))+[node]
136 @feature('qt5')
137 @before_method('process_source')
138 def process_mocs(self):
139 lst=self.to_nodes(getattr(self,'moc',[]))
140 self.source=self.to_list(getattr(self,'source',[]))
141 for x in lst:
142 prefix=x.name[:x.name.rfind('.')]
143 moc_target='moc_%s.%d.cpp'%(prefix,self.idx)
144 moc_node=x.parent.find_or_declare(moc_target)
145 self.source.append(moc_node)
146 self.create_task('moc',x,moc_node)
147 @feature('qt5')
148 @after_method('apply_link')
149 def apply_qt5(self):
150 if getattr(self,'lang',None):
151 qmtasks=[]
152 for x in self.to_list(self.lang):
153 if isinstance(x,str):
154 x=self.path.find_resource(x+'.ts')
155 qmtasks.append(self.create_task('ts2qm',x,x.change_ext('.%d.qm'%self.idx)))
156 if getattr(self,'update',None)and Options.options.trans_qt5:
157 cxxnodes=[a.inputs[0]for a in self.compiled_tasks]+[a.inputs[0]for a in self.tasks if a.inputs and a.inputs[0].name.endswith('.ui')]
158 for x in qmtasks:
159 self.create_task('trans_update',cxxnodes,x.inputs)
160 if getattr(self,'langname',None):
161 qmnodes=[x.outputs[0]for x in qmtasks]
162 rcnode=self.langname
163 if isinstance(rcnode,str):
164 rcnode=self.path.find_or_declare(rcnode+('.%d.qrc'%self.idx))
165 t=self.create_task('qm2rcc',qmnodes,rcnode)
166 k=create_rcc_task(self,t.outputs[0])
167 self.link_task.inputs.append(k.outputs[0])
168 lst=[]
169 for flag in self.to_list(self.env.CXXFLAGS):
170 if len(flag)<2:
171 continue
172 f=flag[0:2]
173 if f in('-D','-I','/D','/I'):
174 if(f[0]=='/'):
175 lst.append('-'+flag[1:])
176 else:
177 lst.append(flag)
178 self.env.append_value('MOC_FLAGS',lst)
179 @extension(*EXT_QT5)
180 def cxx_hook(self,node):
181 return self.create_compiled_task('qxx',node)
182 class rcc(Task.Task):
183 color='BLUE'
184 run_str='${QT_RCC} -name ${tsk.rcname()} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}'
185 ext_out=['.h']
186 def rcname(self):
187 return os.path.splitext(self.inputs[0].name)[0]
188 def scan(self):
189 if not has_xml:
190 Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!')
191 return([],[])
192 parser=make_parser()
193 curHandler=XMLHandler()
194 parser.setContentHandler(curHandler)
195 with open(self.inputs[0].abspath(),'r')as f:
196 parser.parse(f)
197 nodes=[]
198 names=[]
199 root=self.inputs[0].parent
200 for x in curHandler.files:
201 nd=root.find_resource(x)
202 if nd:
203 nodes.append(nd)
204 else:
205 names.append(x)
206 return(nodes,names)
207 def quote_flag(self,x):
208 return x
209 class moc(Task.Task):
210 color='BLUE'
211 run_str='${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}'
212 def quote_flag(self,x):
213 return x
214 class ui5(Task.Task):
215 color='BLUE'
216 run_str='${QT_UIC} ${SRC} -o ${TGT}'
217 ext_out=['.h']
218 class ts2qm(Task.Task):
219 color='BLUE'
220 run_str='${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}'
221 class qm2rcc(Task.Task):
222 color='BLUE'
223 after='ts2qm'
224 def run(self):
225 txt='\n'.join(['<file>%s</file>'%k.path_from(self.outputs[0].parent)for k in self.inputs])
226 code='<!DOCTYPE RCC><RCC version="1.0">\n<qresource>\n%s\n</qresource>\n</RCC>'%txt
227 self.outputs[0].write(code)
228 def configure(self):
229 self.find_qt5_binaries()
230 self.set_qt5_libs_dir()
231 self.set_qt5_libs_to_check()
232 self.set_qt5_defines()
233 self.find_qt5_libraries()
234 self.add_qt5_rpath()
235 self.simplify_qt5_libs()
236 if not has_xml:
237 Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!')
238 if'COMPILER_CXX'not in self.env:
239 self.fatal('No CXX compiler defined: did you forget to configure compiler_cxx first?')
240 frag='#include <QMap>\nint main(int argc, char **argv) {QMap<int,int> m;return m.keys().size();}\n'
241 uses='QT5CORE'
242 for flag in[[],'-fPIE','-fPIC','-std=c++11',['-std=c++11','-fPIE'],['-std=c++11','-fPIC']]:
243 msg='See if Qt files compile '
244 if flag:
245 msg+='with %s'%flag
246 try:
247 self.check(features='qt5 cxx',use=uses,uselib_store='qt5',cxxflags=flag,fragment=frag,msg=msg)
248 except self.errors.ConfigurationError:
249 pass
250 else:
251 break
252 else:
253 self.fatal('Could not build a simple Qt application')
254 if Utils.unversioned_sys_platform()=='freebsd':
255 frag='#include <QMap>\nint main(int argc, char **argv) {QMap<int,int> m;return m.keys().size();}\n'
256 try:
257 self.check(features='qt5 cxx cxxprogram',use=uses,fragment=frag,msg='Can we link Qt programs on FreeBSD directly?')
258 except self.errors.ConfigurationError:
259 self.check(features='qt5 cxx cxxprogram',use=uses,uselib_store='qt5',libpath='/usr/local/lib',fragment=frag,msg='Is /usr/local/lib required?')
260 @conf
261 def find_qt5_binaries(self):
262 env=self.env
263 opt=Options.options
264 qtdir=getattr(opt,'qtdir','')
265 qtbin=getattr(opt,'qtbin','')
266 paths=[]
267 if qtdir:
268 qtbin=os.path.join(qtdir,'bin')
269 if not qtdir:
270 qtdir=self.environ.get('QT5_ROOT','')
271 qtbin=self.environ.get('QT5_BIN')or os.path.join(qtdir,'bin')
272 if qtbin:
273 paths=[qtbin]
274 if not qtdir:
275 paths=self.environ.get('PATH','').split(os.pathsep)
276 paths.extend(['/usr/share/qt5/bin','/usr/local/lib/qt5/bin'])
277 try:
278 lst=Utils.listdir('/usr/local/Trolltech/')
279 except OSError:
280 pass
281 else:
282 if lst:
283 lst.sort()
284 lst.reverse()
285 qtdir='/usr/local/Trolltech/%s/'%lst[0]
286 qtbin=os.path.join(qtdir,'bin')
287 paths.append(qtbin)
288 cand=None
289 prev_ver=['5','0','0']
290 for qmk in('qmake-qt5','qmake5','qmake'):
291 try:
292 qmake=self.find_program(qmk,path_list=paths)
293 except self.errors.ConfigurationError:
294 pass
295 else:
296 try:
297 version=self.cmd_and_log(qmake+['-query','QT_VERSION']).strip()
298 except self.errors.WafError:
299 pass
300 else:
301 if version:
302 new_ver=version.split('.')
303 if new_ver>prev_ver:
304 cand=qmake
305 prev_ver=new_ver
306 if not cand:
307 try:
308 self.find_program('qtchooser')
309 except self.errors.ConfigurationError:
310 pass
311 else:
312 cmd=self.env.QTCHOOSER+['-qt=5','-run-tool=qmake']
313 try:
314 version=self.cmd_and_log(cmd+['-query','QT_VERSION'])
315 except self.errors.WafError:
316 pass
317 else:
318 cand=cmd
319 if cand:
320 self.env.QMAKE=cand
321 else:
322 self.fatal('Could not find qmake for qt5')
323 self.env.QT_HOST_BINS=qtbin=self.cmd_and_log(self.env.QMAKE+['-query','QT_HOST_BINS']).strip()
324 paths.insert(0,qtbin)
325 def find_bin(lst,var):
326 if var in env:
327 return
328 for f in lst:
329 try:
330 ret=self.find_program(f,path_list=paths)
331 except self.errors.ConfigurationError:
332 pass
333 else:
334 env[var]=ret
335 break
336 find_bin(['uic-qt5','uic'],'QT_UIC')
337 if not env.QT_UIC:
338 self.fatal('cannot find the uic compiler for qt5')
339 self.start_msg('Checking for uic version')
340 uicver=self.cmd_and_log(env.QT_UIC+['-version'],output=Context.BOTH)
341 uicver=''.join(uicver).strip()
342 uicver=uicver.replace('Qt User Interface Compiler ','').replace('User Interface Compiler for Qt','')
343 self.end_msg(uicver)
344 if uicver.find(' 3.')!=-1 or uicver.find(' 4.')!=-1:
345 self.fatal('this uic compiler is for qt3 or qt4, add uic for qt5 to your path')
346 find_bin(['moc-qt5','moc'],'QT_MOC')
347 find_bin(['rcc-qt5','rcc'],'QT_RCC')
348 find_bin(['lrelease-qt5','lrelease'],'QT_LRELEASE')
349 find_bin(['lupdate-qt5','lupdate'],'QT_LUPDATE')
350 env.UIC_ST='%s -o %s'
351 env.MOC_ST='-o'
352 env.ui_PATTERN='ui_%s.h'
353 env.QT_LRELEASE_FLAGS=['-silent']
354 env.MOCCPPPATH_ST='-I%s'
355 env.MOCDEFINES_ST='-D%s'
356 @conf
357 def set_qt5_libs_dir(self):
358 env=self.env
359 qtlibs=getattr(Options.options,'qtlibs',None)or self.environ.get('QT5_LIBDIR')
360 if not qtlibs:
361 try:
362 qtlibs=self.cmd_and_log(env.QMAKE+['-query','QT_INSTALL_LIBS']).strip()
363 except Errors.WafError:
364 qtdir=self.cmd_and_log(env.QMAKE+['-query','QT_INSTALL_PREFIX']).strip()
365 qtlibs=os.path.join(qtdir,'lib')
366 self.msg('Found the Qt5 libraries in',qtlibs)
367 env.QTLIBS=qtlibs
368 @conf
369 def find_single_qt5_lib(self,name,uselib,qtlibs,qtincludes,force_static):
370 env=self.env
371 if force_static:
372 exts=('.a','.lib')
373 prefix='STLIB'
374 else:
375 exts=('.so','.lib')
376 prefix='LIB'
377 def lib_names():
378 for x in exts:
379 for k in('','5')if Utils.is_win32 else['']:
380 for p in('lib',''):
381 yield(p,name,k,x)
382 for tup in lib_names():
383 k=''.join(tup)
384 path=os.path.join(qtlibs,k)
385 if os.path.exists(path):
386 if env.DEST_OS=='win32':
387 libval=''.join(tup[:-1])
388 else:
389 libval=name
390 env.append_unique(prefix+'_'+uselib,libval)
391 env.append_unique('%sPATH_%s'%(prefix,uselib),qtlibs)
392 env.append_unique('INCLUDES_'+uselib,qtincludes)
393 env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,name.replace('Qt5','Qt')))
394 return k
395 return False
396 @conf
397 def find_qt5_libraries(self):
398 env=self.env
399 qtincludes=self.environ.get('QT5_INCLUDES')or self.cmd_and_log(env.QMAKE+['-query','QT_INSTALL_HEADERS']).strip()
400 force_static=self.environ.get('QT5_FORCE_STATIC')
401 try:
402 if self.environ.get('QT5_XCOMPILE'):
403 self.fatal('QT5_XCOMPILE Disables pkg-config detection')
404 self.check_cfg(atleast_pkgconfig_version='0.1')
405 except self.errors.ConfigurationError:
406 for i in self.qt5_vars:
407 uselib=i.upper()
408 if Utils.unversioned_sys_platform()=='darwin':
409 fwk=i.replace('Qt5','Qt')
410 frameworkName=fwk+'.framework'
411 qtDynamicLib=os.path.join(env.QTLIBS,frameworkName,fwk)
412 if os.path.exists(qtDynamicLib):
413 env.append_unique('FRAMEWORK_'+uselib,fwk)
414 env.append_unique('FRAMEWORKPATH_'+uselib,env.QTLIBS)
415 self.msg('Checking for %s'%i,qtDynamicLib,'GREEN')
416 else:
417 self.msg('Checking for %s'%i,False,'YELLOW')
418 env.append_unique('INCLUDES_'+uselib,os.path.join(env.QTLIBS,frameworkName,'Headers'))
419 else:
420 ret=self.find_single_qt5_lib(i,uselib,env.QTLIBS,qtincludes,force_static)
421 if not force_static and not ret:
422 ret=self.find_single_qt5_lib(i,uselib,env.QTLIBS,qtincludes,True)
423 self.msg('Checking for %s'%i,ret,'GREEN'if ret else'YELLOW')
424 else:
425 path='%s:%s:%s/pkgconfig:/usr/lib/qt5/lib/pkgconfig:/opt/qt5/lib/pkgconfig:/usr/lib/qt5/lib:/opt/qt5/lib'%(self.environ.get('PKG_CONFIG_PATH',''),env.QTLIBS,env.QTLIBS)
426 for i in self.qt5_vars:
427 self.check_cfg(package=i,args='--cflags --libs',mandatory=False,force_static=force_static,pkg_config_path=path)
428 @conf
429 def simplify_qt5_libs(self):
430 env=self.env
431 def process_lib(vars_,coreval):
432 for d in vars_:
433 var=d.upper()
434 if var=='QTCORE':
435 continue
436 value=env['LIBPATH_'+var]
437 if value:
438 core=env[coreval]
439 accu=[]
440 for lib in value:
441 if lib in core:
442 continue
443 accu.append(lib)
444 env['LIBPATH_'+var]=accu
445 process_lib(self.qt5_vars,'LIBPATH_QTCORE')
446 @conf
447 def add_qt5_rpath(self):
448 env=self.env
449 if getattr(Options.options,'want_rpath',False):
450 def process_rpath(vars_,coreval):
451 for d in vars_:
452 var=d.upper()
453 value=env['LIBPATH_'+var]
454 if value:
455 core=env[coreval]
456 accu=[]
457 for lib in value:
458 if var!='QTCORE':
459 if lib in core:
460 continue
461 accu.append('-Wl,--rpath='+lib)
462 env['RPATH_'+var]=accu
463 process_rpath(self.qt5_vars,'LIBPATH_QTCORE')
464 @conf
465 def set_qt5_libs_to_check(self):
466 self.qt5_vars=Utils.to_list(getattr(self,'qt5_vars',[]))
467 if not self.qt5_vars:
468 dirlst=Utils.listdir(self.env.QTLIBS)
469 pat=self.env.cxxshlib_PATTERN
470 if Utils.is_win32:
471 pat=pat.replace('.dll','.lib')
472 if self.environ.get('QT5_FORCE_STATIC'):
473 pat=self.env.cxxstlib_PATTERN
474 if Utils.unversioned_sys_platform()=='darwin':
475 pat=r"%s\.framework"
476 re_qt=re.compile(pat%'Qt5?(?P<name>.*)'+'$')
477 for x in dirlst:
478 m=re_qt.match(x)
479 if m:
480 self.qt5_vars.append("Qt5%s"%m.group('name'))
481 if not self.qt5_vars:
482 self.fatal('cannot find any Qt5 library (%r)'%self.env.QTLIBS)
483 qtextralibs=getattr(Options.options,'qtextralibs',None)
484 if qtextralibs:
485 self.qt5_vars.extend(qtextralibs.split(','))
486 @conf
487 def set_qt5_defines(self):
488 if sys.platform!='win32':
489 return
490 for x in self.qt5_vars:
491 y=x.replace('Qt5','Qt')[2:].upper()
492 self.env.append_unique('DEFINES_%s'%x.upper(),'QT_%s_LIB'%y)
493 def options(opt):
494 opt.add_option('--want-rpath',action='store_true',default=False,dest='want_rpath',help='enable the rpath for qt libraries')
495 for i in'qtdir qtbin qtlibs'.split():
496 opt.add_option('--'+i,type='string',default='',dest=i)
497 opt.add_option('--translate',action='store_true',help='collect translation strings',dest='trans_qt5',default=False)
498 opt.add_option('--qtextralibs',type='string',default='',dest='qtextralibs',help='additional qt libraries on the system to add to default ones, comma separated')
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os
5 from waflib import Errors,Options,Task,Utils
6 from waflib.TaskGen import before_method,feature,extension
7 from waflib.Configure import conf
8 @feature('rubyext')
9 @before_method('apply_incpaths','process_source','apply_bundle','apply_link')
10 def init_rubyext(self):
11 self.install_path='${ARCHDIR_RUBY}'
12 self.uselib=self.to_list(getattr(self,'uselib',''))
13 if not'RUBY'in self.uselib:
14 self.uselib.append('RUBY')
15 if not'RUBYEXT'in self.uselib:
16 self.uselib.append('RUBYEXT')
17 @feature('rubyext')
18 @before_method('apply_link','propagate_uselib_vars')
19 def apply_ruby_so_name(self):
20 self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.rubyext_PATTERN
21 @conf
22 def check_ruby_version(self,minver=()):
23 ruby=self.find_program('ruby',var='RUBY',value=Options.options.rubybinary)
24 try:
25 version=self.cmd_and_log(ruby+['-e','puts defined?(VERSION) ? VERSION : RUBY_VERSION']).strip()
26 except Errors.WafError:
27 self.fatal('could not determine ruby version')
28 self.env.RUBY_VERSION=version
29 try:
30 ver=tuple(map(int,version.split('.')))
31 except Errors.WafError:
32 self.fatal('unsupported ruby version %r'%version)
33 cver=''
34 if minver:
35 cver='> '+'.'.join(str(x)for x in minver)
36 if ver<minver:
37 self.fatal('ruby is too old %r'%ver)
38 self.msg('Checking for ruby version %s'%cver,version)
39 @conf
40 def check_ruby_ext_devel(self):
41 if not self.env.RUBY:
42 self.fatal('ruby detection is required first')
43 if not self.env.CC_NAME and not self.env.CXX_NAME:
44 self.fatal('load a c/c++ compiler first')
45 version=tuple(map(int,self.env.RUBY_VERSION.split(".")))
46 def read_out(cmd):
47 return Utils.to_list(self.cmd_and_log(self.env.RUBY+['-rrbconfig','-e',cmd]))
48 def read_config(key):
49 return read_out('puts RbConfig::CONFIG[%r]'%key)
50 cpppath=archdir=read_config('archdir')
51 if version>=(1,9,0):
52 ruby_hdrdir=read_config('rubyhdrdir')
53 cpppath+=ruby_hdrdir
54 if version>=(2,0,0):
55 cpppath+=read_config('rubyarchhdrdir')
56 cpppath+=[os.path.join(ruby_hdrdir[0],read_config('arch')[0])]
57 self.check(header_name='ruby.h',includes=cpppath,errmsg='could not find ruby header file',link_header_test=False)
58 self.env.LIBPATH_RUBYEXT=read_config('libdir')
59 self.env.LIBPATH_RUBYEXT+=archdir
60 self.env.INCLUDES_RUBYEXT=cpppath
61 self.env.CFLAGS_RUBYEXT=read_config('CCDLFLAGS')
62 self.env.rubyext_PATTERN='%s.'+read_config('DLEXT')[0]
63 flags=read_config('LDSHARED')
64 while flags and flags[0][0]!='-':
65 flags=flags[1:]
66 if len(flags)>1 and flags[1]=="ppc":
67 flags=flags[2:]
68 self.env.LINKFLAGS_RUBYEXT=flags
69 self.env.LINKFLAGS_RUBYEXT+=read_config('LIBS')
70 self.env.LINKFLAGS_RUBYEXT+=read_config('LIBRUBYARG_SHARED')
71 if Options.options.rubyarchdir:
72 self.env.ARCHDIR_RUBY=Options.options.rubyarchdir
73 else:
74 self.env.ARCHDIR_RUBY=read_config('sitearchdir')[0]
75 if Options.options.rubylibdir:
76 self.env.LIBDIR_RUBY=Options.options.rubylibdir
77 else:
78 self.env.LIBDIR_RUBY=read_config('sitelibdir')[0]
79 @conf
80 def check_ruby_module(self,module_name):
81 self.start_msg('Ruby module %s'%module_name)
82 try:
83 self.cmd_and_log(self.env.RUBY+['-e','require \'%s\';puts 1'%module_name])
84 except Errors.WafError:
85 self.end_msg(False)
86 self.fatal('Could not find the ruby module %r'%module_name)
87 self.end_msg(True)
88 @extension('.rb')
89 def process(self,node):
90 return self.create_task('run_ruby',node)
91 class run_ruby(Task.Task):
92 run_str='${RUBY} ${RBFLAGS} -I ${SRC[0].parent.abspath()} ${SRC}'
93 def options(opt):
94 opt.add_option('--with-ruby-archdir',type='string',dest='rubyarchdir',help='Specify directory where to install arch specific files')
95 opt.add_option('--with-ruby-libdir',type='string',dest='rubylibdir',help='Specify alternate ruby library path')
96 opt.add_option('--with-ruby-binary',type='string',dest='rubybinary',help='Specify alternate ruby binary')
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib import Errors
5 from waflib.Tools import ccroot,ar
6 from waflib.Configure import conf
7 @conf
8 def find_scc(conf):
9 v=conf.env
10 cc=conf.find_program('cc',var='CC')
11 try:
12 conf.cmd_and_log(cc+['-flags'])
13 except Errors.WafError:
14 conf.fatal('%r is not a Sun compiler'%cc)
15 v.CC_NAME='sun'
16 conf.get_suncc_version(cc)
17 @conf
18 def scc_common_flags(conf):
19 v=conf.env
20 v.CC_SRC_F=[]
21 v.CC_TGT_F=['-c','-o','']
22 if not v.LINK_CC:
23 v.LINK_CC=v.CC
24 v.CCLNK_SRC_F=''
25 v.CCLNK_TGT_F=['-o','']
26 v.CPPPATH_ST='-I%s'
27 v.DEFINES_ST='-D%s'
28 v.LIB_ST='-l%s'
29 v.LIBPATH_ST='-L%s'
30 v.STLIB_ST='-l%s'
31 v.STLIBPATH_ST='-L%s'
32 v.SONAME_ST='-Wl,-h,%s'
33 v.SHLIB_MARKER='-Bdynamic'
34 v.STLIB_MARKER='-Bstatic'
35 v.cprogram_PATTERN='%s'
36 v.CFLAGS_cshlib=['-xcode=pic32','-DPIC']
37 v.LINKFLAGS_cshlib=['-G']
38 v.cshlib_PATTERN='lib%s.so'
39 v.LINKFLAGS_cstlib=['-Bstatic']
40 v.cstlib_PATTERN='lib%s.a'
41 def configure(conf):
42 conf.find_scc()
43 conf.find_ar()
44 conf.scc_common_flags()
45 conf.cc_load_tools()
46 conf.cc_add_flags()
47 conf.link_add_flags()
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib import Errors
5 from waflib.Tools import ccroot,ar
6 from waflib.Configure import conf
7 @conf
8 def find_sxx(conf):
9 v=conf.env
10 cc=conf.find_program(['CC','c++'],var='CXX')
11 try:
12 conf.cmd_and_log(cc+['-flags'])
13 except Errors.WafError:
14 conf.fatal('%r is not a Sun compiler'%cc)
15 v.CXX_NAME='sun'
16 conf.get_suncc_version(cc)
17 @conf
18 def sxx_common_flags(conf):
19 v=conf.env
20 v.CXX_SRC_F=[]
21 v.CXX_TGT_F=['-c','-o','']
22 if not v.LINK_CXX:
23 v.LINK_CXX=v.CXX
24 v.CXXLNK_SRC_F=[]
25 v.CXXLNK_TGT_F=['-o','']
26 v.CPPPATH_ST='-I%s'
27 v.DEFINES_ST='-D%s'
28 v.LIB_ST='-l%s'
29 v.LIBPATH_ST='-L%s'
30 v.STLIB_ST='-l%s'
31 v.STLIBPATH_ST='-L%s'
32 v.SONAME_ST='-Wl,-h,%s'
33 v.SHLIB_MARKER='-Bdynamic'
34 v.STLIB_MARKER='-Bstatic'
35 v.cxxprogram_PATTERN='%s'
36 v.CXXFLAGS_cxxshlib=['-xcode=pic32','-DPIC']
37 v.LINKFLAGS_cxxshlib=['-G']
38 v.cxxshlib_PATTERN='lib%s.so'
39 v.LINKFLAGS_cxxstlib=['-Bstatic']
40 v.cxxstlib_PATTERN='lib%s.a'
41 def configure(conf):
42 conf.find_sxx()
43 conf.find_ar()
44 conf.sxx_common_flags()
45 conf.cxx_load_tools()
46 conf.cxx_add_flags()
47 conf.link_add_flags()
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os,re
5 from waflib import Utils,Task,Errors,Logs,Node
6 from waflib.TaskGen import feature,before_method
7 re_bibunit=re.compile(r'\\(?P<type>putbib)\[(?P<file>[^\[\]]*)\]',re.M)
8 def bibunitscan(self):
9 node=self.inputs[0]
10 nodes=[]
11 if not node:
12 return nodes
13 code=node.read()
14 for match in re_bibunit.finditer(code):
15 path=match.group('file')
16 if path:
17 found=None
18 for k in('','.bib'):
19 Logs.debug('tex: trying %s%s',path,k)
20 fi=node.parent.find_resource(path+k)
21 if fi:
22 found=True
23 nodes.append(fi)
24 if not found:
25 Logs.debug('tex: could not find %s',path)
26 Logs.debug('tex: found the following bibunit files: %s',nodes)
27 return nodes
28 exts_deps_tex=['','.ltx','.tex','.bib','.pdf','.png','.eps','.ps','.sty']
29 exts_tex=['.ltx','.tex']
30 re_tex=re.compile(r'\\(?P<type>usepackage|RequirePackage|include|bibliography([^\[\]{}]*)|putbib|includegraphics|input|import|bringin|lstinputlisting)(\[[^\[\]]*\])?{(?P<file>[^{}]*)}',re.M)
31 g_bibtex_re=re.compile('bibdata',re.M)
32 g_glossaries_re=re.compile('\\@newglossary',re.M)
33 class tex(Task.Task):
34 bibtex_fun,_=Task.compile_fun('${BIBTEX} ${BIBTEXFLAGS} ${SRCFILE}',shell=False)
35 bibtex_fun.__doc__="""
36 Execute the program **bibtex**
37 """
38 makeindex_fun,_=Task.compile_fun('${MAKEINDEX} ${MAKEINDEXFLAGS} ${SRCFILE}',shell=False)
39 makeindex_fun.__doc__="""
40 Execute the program **makeindex**
41 """
42 makeglossaries_fun,_=Task.compile_fun('${MAKEGLOSSARIES} ${SRCFILE}',shell=False)
43 makeglossaries_fun.__doc__="""
44 Execute the program **makeglossaries**
45 """
46 def exec_command(self,cmd,**kw):
47 if self.env.PROMPT_LATEX:
48 kw['stdout']=kw['stderr']=None
49 return super(tex,self).exec_command(cmd,**kw)
50 def scan_aux(self,node):
51 nodes=[node]
52 re_aux=re.compile(r'\\@input{(?P<file>[^{}]*)}',re.M)
53 def parse_node(node):
54 code=node.read()
55 for match in re_aux.finditer(code):
56 path=match.group('file')
57 found=node.parent.find_or_declare(path)
58 if found and found not in nodes:
59 Logs.debug('tex: found aux node %r',found)
60 nodes.append(found)
61 parse_node(found)
62 parse_node(node)
63 return nodes
64 def scan(self):
65 node=self.inputs[0]
66 nodes=[]
67 names=[]
68 seen=[]
69 if not node:
70 return(nodes,names)
71 def parse_node(node):
72 if node in seen:
73 return
74 seen.append(node)
75 code=node.read()
76 for match in re_tex.finditer(code):
77 multibib=match.group('type')
78 if multibib and multibib.startswith('bibliography'):
79 multibib=multibib[len('bibliography'):]
80 if multibib.startswith('style'):
81 continue
82 else:
83 multibib=None
84 for path in match.group('file').split(','):
85 if path:
86 add_name=True
87 found=None
88 for k in exts_deps_tex:
89 for up in self.texinputs_nodes:
90 Logs.debug('tex: trying %s%s',path,k)
91 found=up.find_resource(path+k)
92 if found:
93 break
94 for tsk in self.generator.tasks:
95 if not found or found in tsk.outputs:
96 break
97 else:
98 nodes.append(found)
99 add_name=False
100 for ext in exts_tex:
101 if found.name.endswith(ext):
102 parse_node(found)
103 break
104 if found and multibib and found.name.endswith('.bib'):
105 try:
106 self.multibibs.append(found)
107 except AttributeError:
108 self.multibibs=[found]
109 if add_name:
110 names.append(path)
111 parse_node(node)
112 for x in nodes:
113 x.parent.get_bld().mkdir()
114 Logs.debug("tex: found the following : %s and names %s",nodes,names)
115 return(nodes,names)
116 def check_status(self,msg,retcode):
117 if retcode!=0:
118 raise Errors.WafError('%r command exit status %r'%(msg,retcode))
119 def info(self,*k,**kw):
120 try:
121 info=self.generator.bld.conf.logger.info
122 except AttributeError:
123 info=Logs.info
124 info(*k,**kw)
125 def bibfile(self):
126 for aux_node in self.aux_nodes:
127 try:
128 ct=aux_node.read()
129 except EnvironmentError:
130 Logs.error('Error reading %s: %r',aux_node.abspath())
131 continue
132 if g_bibtex_re.findall(ct):
133 self.info('calling bibtex')
134 self.env.env={}
135 self.env.env.update(os.environ)
136 self.env.env.update({'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()})
137 self.env.SRCFILE=aux_node.name[:-4]
138 self.check_status('error when calling bibtex',self.bibtex_fun())
139 for node in getattr(self,'multibibs',[]):
140 self.env.env={}
141 self.env.env.update(os.environ)
142 self.env.env.update({'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()})
143 self.env.SRCFILE=node.name[:-4]
144 self.check_status('error when calling bibtex',self.bibtex_fun())
145 def bibunits(self):
146 try:
147 bibunits=bibunitscan(self)
148 except OSError:
149 Logs.error('error bibunitscan')
150 else:
151 if bibunits:
152 fn=['bu'+str(i)for i in range(1,len(bibunits)+1)]
153 if fn:
154 self.info('calling bibtex on bibunits')
155 for f in fn:
156 self.env.env={'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()}
157 self.env.SRCFILE=f
158 self.check_status('error when calling bibtex',self.bibtex_fun())
159 def makeindex(self):
160 self.idx_node=self.inputs[0].change_ext('.idx')
161 try:
162 idx_path=self.idx_node.abspath()
163 os.stat(idx_path)
164 except OSError:
165 self.info('index file %s absent, not calling makeindex',idx_path)
166 else:
167 self.info('calling makeindex')
168 self.env.SRCFILE=self.idx_node.name
169 self.env.env={}
170 self.check_status('error when calling makeindex %s'%idx_path,self.makeindex_fun())
171 def bibtopic(self):
172 p=self.inputs[0].parent.get_bld()
173 if os.path.exists(os.path.join(p.abspath(),'btaux.aux')):
174 self.aux_nodes+=p.ant_glob('*[0-9].aux')
175 def makeglossaries(self):
176 src_file=self.inputs[0].abspath()
177 base_file=os.path.basename(src_file)
178 base,_=os.path.splitext(base_file)
179 for aux_node in self.aux_nodes:
180 try:
181 ct=aux_node.read()
182 except EnvironmentError:
183 Logs.error('Error reading %s: %r',aux_node.abspath())
184 continue
185 if g_glossaries_re.findall(ct):
186 if not self.env.MAKEGLOSSARIES:
187 raise Errors.WafError("The program 'makeglossaries' is missing!")
188 Logs.warn('calling makeglossaries')
189 self.env.SRCFILE=base
190 self.check_status('error when calling makeglossaries %s'%base,self.makeglossaries_fun())
191 return
192 def texinputs(self):
193 return os.pathsep.join([k.abspath()for k in self.texinputs_nodes])+os.pathsep
194 def run(self):
195 env=self.env
196 if not env.PROMPT_LATEX:
197 env.append_value('LATEXFLAGS','-interaction=batchmode')
198 env.append_value('PDFLATEXFLAGS','-interaction=batchmode')
199 env.append_value('XELATEXFLAGS','-interaction=batchmode')
200 self.cwd=self.inputs[0].parent.get_bld()
201 self.info('first pass on %s',self.__class__.__name__)
202 cur_hash=self.hash_aux_nodes()
203 self.call_latex()
204 self.hash_aux_nodes()
205 self.bibtopic()
206 self.bibfile()
207 self.bibunits()
208 self.makeindex()
209 self.makeglossaries()
210 for i in range(10):
211 prev_hash=cur_hash
212 cur_hash=self.hash_aux_nodes()
213 if not cur_hash:
214 Logs.error('No aux.h to process')
215 if cur_hash and cur_hash==prev_hash:
216 break
217 self.info('calling %s',self.__class__.__name__)
218 self.call_latex()
219 def hash_aux_nodes(self):
220 try:
221 self.aux_nodes
222 except AttributeError:
223 try:
224 self.aux_nodes=self.scan_aux(self.inputs[0].change_ext('.aux'))
225 except IOError:
226 return None
227 return Utils.h_list([Utils.h_file(x.abspath())for x in self.aux_nodes])
228 def call_latex(self):
229 self.env.env={}
230 self.env.env.update(os.environ)
231 self.env.env.update({'TEXINPUTS':self.texinputs()})
232 self.env.SRCFILE=self.inputs[0].abspath()
233 self.check_status('error when calling latex',self.texfun())
234 class latex(tex):
235 texfun,vars=Task.compile_fun('${LATEX} ${LATEXFLAGS} ${SRCFILE}',shell=False)
236 class pdflatex(tex):
237 texfun,vars=Task.compile_fun('${PDFLATEX} ${PDFLATEXFLAGS} ${SRCFILE}',shell=False)
238 class xelatex(tex):
239 texfun,vars=Task.compile_fun('${XELATEX} ${XELATEXFLAGS} ${SRCFILE}',shell=False)
240 class dvips(Task.Task):
241 run_str='${DVIPS} ${DVIPSFLAGS} ${SRC} -o ${TGT}'
242 color='BLUE'
243 after=['latex','pdflatex','xelatex']
244 class dvipdf(Task.Task):
245 run_str='${DVIPDF} ${DVIPDFFLAGS} ${SRC} ${TGT}'
246 color='BLUE'
247 after=['latex','pdflatex','xelatex']
248 class pdf2ps(Task.Task):
249 run_str='${PDF2PS} ${PDF2PSFLAGS} ${SRC} ${TGT}'
250 color='BLUE'
251 after=['latex','pdflatex','xelatex']
252 @feature('tex')
253 @before_method('process_source')
254 def apply_tex(self):
255 if not getattr(self,'type',None)in('latex','pdflatex','xelatex'):
256 self.type='pdflatex'
257 outs=Utils.to_list(getattr(self,'outs',[]))
258 try:
259 self.generator.bld.conf
260 except AttributeError:
261 default_prompt=False
262 else:
263 default_prompt=True
264 self.env.PROMPT_LATEX=getattr(self,'prompt',default_prompt)
265 deps_lst=[]
266 if getattr(self,'deps',None):
267 deps=self.to_list(self.deps)
268 for dep in deps:
269 if isinstance(dep,str):
270 n=self.path.find_resource(dep)
271 if not n:
272 self.bld.fatal('Could not find %r for %r'%(dep,self))
273 if not n in deps_lst:
274 deps_lst.append(n)
275 elif isinstance(dep,Node.Node):
276 deps_lst.append(dep)
277 for node in self.to_nodes(self.source):
278 if self.type=='latex':
279 task=self.create_task('latex',node,node.change_ext('.dvi'))
280 elif self.type=='pdflatex':
281 task=self.create_task('pdflatex',node,node.change_ext('.pdf'))
282 elif self.type=='xelatex':
283 task=self.create_task('xelatex',node,node.change_ext('.pdf'))
284 task.env=self.env
285 if deps_lst:
286 for n in deps_lst:
287 if not n in task.dep_nodes:
288 task.dep_nodes.append(n)
289 if hasattr(self,'texinputs_nodes'):
290 task.texinputs_nodes=self.texinputs_nodes
291 else:
292 task.texinputs_nodes=[node.parent,node.parent.get_bld(),self.path,self.path.get_bld()]
293 lst=os.environ.get('TEXINPUTS','')
294 if self.env.TEXINPUTS:
295 lst+=os.pathsep+self.env.TEXINPUTS
296 if lst:
297 lst=lst.split(os.pathsep)
298 for x in lst:
299 if x:
300 if os.path.isabs(x):
301 p=self.bld.root.find_node(x)
302 if p:
303 task.texinputs_nodes.append(p)
304 else:
305 Logs.error('Invalid TEXINPUTS folder %s',x)
306 else:
307 Logs.error('Cannot resolve relative paths in TEXINPUTS %s',x)
308 if self.type=='latex':
309 if'ps'in outs:
310 tsk=self.create_task('dvips',task.outputs,node.change_ext('.ps'))
311 tsk.env.env=dict(os.environ)
312 if'pdf'in outs:
313 tsk=self.create_task('dvipdf',task.outputs,node.change_ext('.pdf'))
314 tsk.env.env=dict(os.environ)
315 elif self.type=='pdflatex':
316 if'ps'in outs:
317 self.create_task('pdf2ps',task.outputs,node.change_ext('.ps'))
318 self.source=[]
319 def configure(self):
320 v=self.env
321 for p in'tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps makeglossaries'.split():
322 try:
323 self.find_program(p,var=p.upper())
324 except self.errors.ConfigurationError:
325 pass
326 v.DVIPSFLAGS='-Ppdf'
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import re
5 from waflib import Build,Context,Errors,Logs,Node,Options,Task,Utils
6 from waflib.TaskGen import extension,taskgen_method
7 from waflib.Configure import conf
8 class valac(Task.Task):
9 vars=["VALAC","VALAC_VERSION","VALAFLAGS"]
10 ext_out=['.h']
11 def run(self):
12 cmd=self.env.VALAC+self.env.VALAFLAGS
13 resources=getattr(self,'vala_exclude',[])
14 cmd.extend([a.abspath()for a in self.inputs if a not in resources])
15 ret=self.exec_command(cmd,cwd=self.vala_dir_node.abspath())
16 if ret:
17 return ret
18 if self.generator.dump_deps_node:
19 self.generator.dump_deps_node.write('\n'.join(self.generator.packages))
20 return ret
21 @taskgen_method
22 def init_vala_task(self):
23 self.profile=getattr(self,'profile','gobject')
24 self.packages=packages=Utils.to_list(getattr(self,'packages',[]))
25 self.use=Utils.to_list(getattr(self,'use',[]))
26 if packages and not self.use:
27 self.use=packages[:]
28 if self.profile=='gobject':
29 if not'GOBJECT'in self.use:
30 self.use.append('GOBJECT')
31 def addflags(flags):
32 self.env.append_value('VALAFLAGS',flags)
33 if self.profile:
34 addflags('--profile=%s'%self.profile)
35 valatask=self.valatask
36 if hasattr(self,'vala_dir'):
37 if isinstance(self.vala_dir,str):
38 valatask.vala_dir_node=self.path.get_bld().make_node(self.vala_dir)
39 try:
40 valatask.vala_dir_node.mkdir()
41 except OSError:
42 raise self.bld.fatal('Cannot create the vala dir %r'%valatask.vala_dir_node)
43 else:
44 valatask.vala_dir_node=self.vala_dir
45 else:
46 valatask.vala_dir_node=self.path.get_bld()
47 addflags('--directory=%s'%valatask.vala_dir_node.abspath())
48 if hasattr(self,'thread'):
49 if self.profile=='gobject':
50 if not'GTHREAD'in self.use:
51 self.use.append('GTHREAD')
52 else:
53 Logs.warn('Profile %s means no threading support',self.profile)
54 self.thread=False
55 if self.thread:
56 addflags('--thread')
57 self.is_lib='cprogram'not in self.features
58 if self.is_lib:
59 addflags('--library=%s'%self.target)
60 h_node=valatask.vala_dir_node.find_or_declare('%s.h'%self.target)
61 valatask.outputs.append(h_node)
62 addflags('--header=%s'%h_node.name)
63 valatask.outputs.append(valatask.vala_dir_node.find_or_declare('%s.vapi'%self.target))
64 if getattr(self,'gir',None):
65 gir_node=valatask.vala_dir_node.find_or_declare('%s.gir'%self.gir)
66 addflags('--gir=%s'%gir_node.name)
67 valatask.outputs.append(gir_node)
68 self.vala_target_glib=getattr(self,'vala_target_glib',getattr(Options.options,'vala_target_glib',None))
69 if self.vala_target_glib:
70 addflags('--target-glib=%s'%self.vala_target_glib)
71 addflags(['--define=%s'%x for x in Utils.to_list(getattr(self,'vala_defines',[]))])
72 packages_private=Utils.to_list(getattr(self,'packages_private',[]))
73 addflags(['--pkg=%s'%x for x in packages_private])
74 def _get_api_version():
75 api_version='1.0'
76 if hasattr(Context.g_module,'API_VERSION'):
77 version=Context.g_module.API_VERSION.split(".")
78 if version[0]=="0":
79 api_version="0."+version[1]
80 else:
81 api_version=version[0]+".0"
82 return api_version
83 self.includes=Utils.to_list(getattr(self,'includes',[]))
84 valatask.install_path=getattr(self,'install_path','')
85 valatask.vapi_path=getattr(self,'vapi_path','${DATAROOTDIR}/vala/vapi')
86 valatask.pkg_name=getattr(self,'pkg_name',self.env.PACKAGE)
87 valatask.header_path=getattr(self,'header_path','${INCLUDEDIR}/%s-%s'%(valatask.pkg_name,_get_api_version()))
88 valatask.install_binding=getattr(self,'install_binding',True)
89 self.vapi_dirs=vapi_dirs=Utils.to_list(getattr(self,'vapi_dirs',[]))
90 if hasattr(self,'use'):
91 local_packages=Utils.to_list(self.use)[:]
92 seen=[]
93 while len(local_packages)>0:
94 package=local_packages.pop()
95 if package in seen:
96 continue
97 seen.append(package)
98 try:
99 package_obj=self.bld.get_tgen_by_name(package)
100 except Errors.WafError:
101 continue
102 package_obj.post()
103 package_name=package_obj.target
104 task=getattr(package_obj,'valatask',None)
105 if task:
106 for output in task.outputs:
107 if output.name==package_name+".vapi":
108 valatask.set_run_after(task)
109 if package_name not in packages:
110 packages.append(package_name)
111 if output.parent not in vapi_dirs:
112 vapi_dirs.append(output.parent)
113 if output.parent not in self.includes:
114 self.includes.append(output.parent)
115 if hasattr(package_obj,'use'):
116 lst=self.to_list(package_obj.use)
117 lst.reverse()
118 local_packages=[pkg for pkg in lst if pkg not in seen]+local_packages
119 addflags(['--pkg=%s'%p for p in packages])
120 for vapi_dir in vapi_dirs:
121 if isinstance(vapi_dir,Node.Node):
122 v_node=vapi_dir
123 else:
124 v_node=self.path.find_dir(vapi_dir)
125 if not v_node:
126 Logs.warn('Unable to locate Vala API directory: %r',vapi_dir)
127 else:
128 addflags('--vapidir=%s'%v_node.abspath())
129 self.dump_deps_node=None
130 if self.is_lib and self.packages:
131 self.dump_deps_node=valatask.vala_dir_node.find_or_declare('%s.deps'%self.target)
132 valatask.outputs.append(self.dump_deps_node)
133 if self.is_lib and valatask.install_binding:
134 headers_list=[o for o in valatask.outputs if o.suffix()==".h"]
135 if headers_list:
136 self.install_vheader=self.add_install_files(install_to=valatask.header_path,install_from=headers_list)
137 vapi_list=[o for o in valatask.outputs if(o.suffix()in(".vapi",".deps"))]
138 if vapi_list:
139 self.install_vapi=self.add_install_files(install_to=valatask.vapi_path,install_from=vapi_list)
140 gir_list=[o for o in valatask.outputs if o.suffix()=='.gir']
141 if gir_list:
142 self.install_gir=self.add_install_files(install_to=getattr(self,'gir_path','${DATAROOTDIR}/gir-1.0'),install_from=gir_list)
143 if hasattr(self,'vala_resources'):
144 nodes=self.to_nodes(self.vala_resources)
145 valatask.vala_exclude=getattr(valatask,'vala_exclude',[])+nodes
146 valatask.inputs.extend(nodes)
147 for x in nodes:
148 addflags(['--gresources',x.abspath()])
149 @extension('.vala','.gs')
150 def vala_file(self,node):
151 try:
152 valatask=self.valatask
153 except AttributeError:
154 valatask=self.valatask=self.create_task('valac')
155 self.init_vala_task()
156 valatask.inputs.append(node)
157 name=node.name[:node.name.rfind('.')]+'.c'
158 c_node=valatask.vala_dir_node.find_or_declare(name)
159 valatask.outputs.append(c_node)
160 self.source.append(c_node)
161 @extension('.vapi')
162 def vapi_file(self,node):
163 try:
164 valatask=self.valatask
165 except AttributeError:
166 valatask=self.valatask=self.create_task('valac')
167 self.init_vala_task()
168 valatask.inputs.append(node)
169 @conf
170 def find_valac(self,valac_name,min_version):
171 valac=self.find_program(valac_name,var='VALAC')
172 try:
173 output=self.cmd_and_log(valac+['--version'])
174 except Errors.WafError:
175 valac_version=None
176 else:
177 ver=re.search(r'\d+.\d+.\d+',output).group().split('.')
178 valac_version=tuple([int(x)for x in ver])
179 self.msg('Checking for %s version >= %r'%(valac_name,min_version),valac_version,valac_version and valac_version>=min_version)
180 if valac and valac_version<min_version:
181 self.fatal("%s version %r is too old, need >= %r"%(valac_name,valac_version,min_version))
182 self.env.VALAC_VERSION=valac_version
183 return valac
184 @conf
185 def check_vala(self,min_version=(0,8,0),branch=None):
186 if self.env.VALA_MINVER:
187 min_version=self.env.VALA_MINVER
188 if self.env.VALA_MINVER_BRANCH:
189 branch=self.env.VALA_MINVER_BRANCH
190 if not branch:
191 branch=min_version[:2]
192 try:
193 find_valac(self,'valac-%d.%d'%(branch[0],branch[1]),min_version)
194 except self.errors.ConfigurationError:
195 find_valac(self,'valac',min_version)
196 @conf
197 def check_vala_deps(self):
198 if not self.env.HAVE_GOBJECT:
199 pkg_args={'package':'gobject-2.0','uselib_store':'GOBJECT','args':'--cflags --libs'}
200 if getattr(Options.options,'vala_target_glib',None):
201 pkg_args['atleast_version']=Options.options.vala_target_glib
202 self.check_cfg(**pkg_args)
203 if not self.env.HAVE_GTHREAD:
204 pkg_args={'package':'gthread-2.0','uselib_store':'GTHREAD','args':'--cflags --libs'}
205 if getattr(Options.options,'vala_target_glib',None):
206 pkg_args['atleast_version']=Options.options.vala_target_glib
207 self.check_cfg(**pkg_args)
208 def configure(self):
209 self.load('gnu_dirs')
210 self.check_vala_deps()
211 self.check_vala()
212 self.add_os_flags('VALAFLAGS')
213 self.env.append_unique('VALAFLAGS',['-C'])
214 def options(opt):
215 opt.load('gnu_dirs')
216 valaopts=opt.add_option_group('Vala Compiler Options')
217 valaopts.add_option('--vala-target-glib',default=None,dest='vala_target_glib',metavar='MAJOR.MINOR',help='Target version of glib for Vala GObject code generation')
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os,shlex,sys
5 from waflib.TaskGen import feature,after_method,taskgen_method
6 from waflib import Utils,Task,Logs,Options
7 from waflib.Tools import ccroot
8 testlock=Utils.threading.Lock()
9 SCRIPT_TEMPLATE="""#! %(python)s
10 import subprocess, sys
11 cmd = %(cmd)r
12 # if you want to debug with gdb:
13 #cmd = ['gdb', '-args'] + cmd
14 env = %(env)r
15 status = subprocess.call(cmd, env=env, cwd=%(cwd)r, shell=isinstance(cmd, str))
16 sys.exit(status)
17 """
18 @taskgen_method
19 def handle_ut_cwd(self,key):
20 cwd=getattr(self,key,None)
21 if cwd:
22 if isinstance(cwd,str):
23 if os.path.isabs(cwd):
24 self.ut_cwd=self.bld.root.make_node(cwd)
25 else:
26 self.ut_cwd=self.path.make_node(cwd)
27 @feature('test_scripts')
28 def make_interpreted_test(self):
29 for x in['test_scripts_source','test_scripts_template']:
30 if not hasattr(self,x):
31 Logs.warn('a test_scripts taskgen i missing %s'%x)
32 return
33 self.ut_run,lst=Task.compile_fun(self.test_scripts_template,shell=getattr(self,'test_scripts_shell',False))
34 script_nodes=self.to_nodes(self.test_scripts_source)
35 for script_node in script_nodes:
36 tsk=self.create_task('utest',[script_node])
37 tsk.vars=lst+tsk.vars
38 tsk.env['SCRIPT']=script_node.path_from(tsk.get_cwd())
39 self.handle_ut_cwd('test_scripts_cwd')
40 env=getattr(self,'test_scripts_env',None)
41 if env:
42 self.ut_env=env
43 else:
44 self.ut_env=dict(os.environ)
45 paths=getattr(self,'test_scripts_paths',{})
46 for(k,v)in paths.items():
47 p=self.ut_env.get(k,'').split(os.pathsep)
48 if isinstance(v,str):
49 v=v.split(os.pathsep)
50 self.ut_env[k]=os.pathsep.join(p+v)
51 @feature('test')
52 @after_method('apply_link','process_use')
53 def make_test(self):
54 if not getattr(self,'link_task',None):
55 return
56 tsk=self.create_task('utest',self.link_task.outputs)
57 if getattr(self,'ut_str',None):
58 self.ut_run,lst=Task.compile_fun(self.ut_str,shell=getattr(self,'ut_shell',False))
59 tsk.vars=lst+tsk.vars
60 self.handle_ut_cwd('ut_cwd')
61 if not hasattr(self,'ut_paths'):
62 paths=[]
63 for x in self.tmp_use_sorted:
64 try:
65 y=self.bld.get_tgen_by_name(x).link_task
66 except AttributeError:
67 pass
68 else:
69 if not isinstance(y,ccroot.stlink_task):
70 paths.append(y.outputs[0].parent.abspath())
71 self.ut_paths=os.pathsep.join(paths)+os.pathsep
72 if not hasattr(self,'ut_env'):
73 self.ut_env=dct=dict(os.environ)
74 def add_path(var):
75 dct[var]=self.ut_paths+dct.get(var,'')
76 if Utils.is_win32:
77 add_path('PATH')
78 elif Utils.unversioned_sys_platform()=='darwin':
79 add_path('DYLD_LIBRARY_PATH')
80 add_path('LD_LIBRARY_PATH')
81 else:
82 add_path('LD_LIBRARY_PATH')
83 if not hasattr(self,'ut_cmd'):
84 self.ut_cmd=getattr(Options.options,'testcmd',False)
85 @taskgen_method
86 def add_test_results(self,tup):
87 Logs.debug("ut: %r",tup)
88 try:
89 self.utest_results.append(tup)
90 except AttributeError:
91 self.utest_results=[tup]
92 try:
93 self.bld.utest_results.append(tup)
94 except AttributeError:
95 self.bld.utest_results=[tup]
96 @Task.deep_inputs
97 class utest(Task.Task):
98 color='PINK'
99 after=['vnum','inst']
100 vars=[]
101 def runnable_status(self):
102 if getattr(Options.options,'no_tests',False):
103 return Task.SKIP_ME
104 ret=super(utest,self).runnable_status()
105 if ret==Task.SKIP_ME:
106 if getattr(Options.options,'all_tests',False):
107 return Task.RUN_ME
108 return ret
109 def get_test_env(self):
110 return self.generator.ut_env
111 def post_run(self):
112 super(utest,self).post_run()
113 if getattr(Options.options,'clear_failed_tests',False)and self.waf_unit_test_results[1]:
114 self.generator.bld.task_sigs[self.uid()]=None
115 def run(self):
116 if hasattr(self.generator,'ut_run'):
117 return self.generator.ut_run(self)
118 self.ut_exec=getattr(self.generator,'ut_exec',[self.inputs[0].abspath()])
119 ut_cmd=getattr(self.generator,'ut_cmd',False)
120 if ut_cmd:
121 self.ut_exec=shlex.split(ut_cmd%' '.join(self.ut_exec))
122 return self.exec_command(self.ut_exec)
123 def exec_command(self,cmd,**kw):
124 self.generator.bld.log_command(cmd,kw)
125 if getattr(Options.options,'dump_test_scripts',False):
126 script_code=SCRIPT_TEMPLATE%{'python':sys.executable,'env':self.get_test_env(),'cwd':self.get_cwd().abspath(),'cmd':cmd}
127 script_file=self.inputs[0].abspath()+'_run.py'
128 Utils.writef(script_file,script_code,encoding='utf-8')
129 os.chmod(script_file,Utils.O755)
130 if Logs.verbose>1:
131 Logs.info('Test debug file written as %r'%script_file)
132 proc=Utils.subprocess.Popen(cmd,cwd=self.get_cwd().abspath(),env=self.get_test_env(),stderr=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE,shell=isinstance(cmd,str))
133 (stdout,stderr)=proc.communicate()
134 self.waf_unit_test_results=tup=(self.inputs[0].abspath(),proc.returncode,stdout,stderr)
135 testlock.acquire()
136 try:
137 return self.generator.add_test_results(tup)
138 finally:
139 testlock.release()
140 def get_cwd(self):
141 return getattr(self.generator,'ut_cwd',self.inputs[0].parent)
142 def summary(bld):
143 lst=getattr(bld,'utest_results',[])
144 if lst:
145 Logs.pprint('CYAN','execution summary')
146 total=len(lst)
147 tfail=len([x for x in lst if x[1]])
148 Logs.pprint('GREEN',' tests that pass %d/%d'%(total-tfail,total))
149 for(f,code,out,err)in lst:
150 if not code:
151 Logs.pprint('GREEN',' %s'%f)
152 Logs.pprint('GREEN'if tfail==0 else'RED',' tests that fail %d/%d'%(tfail,total))
153 for(f,code,out,err)in lst:
154 if code:
155 Logs.pprint('RED',' %s'%f)
156 def set_exit_code(bld):
157 lst=getattr(bld,'utest_results',[])
158 for(f,code,out,err)in lst:
159 if code:
160 msg=[]
161 if out:
162 msg.append('stdout:%s%s'%(os.linesep,out.decode('utf-8')))
163 if err:
164 msg.append('stderr:%s%s'%(os.linesep,err.decode('utf-8')))
165 bld.fatal(os.linesep.join(msg))
166 def options(opt):
167 opt.add_option('--notests',action='store_true',default=False,help='Exec no unit tests',dest='no_tests')
168 opt.add_option('--alltests',action='store_true',default=False,help='Exec all unit tests',dest='all_tests')
169 opt.add_option('--clear-failed',action='store_true',default=False,help='Force failed unit tests to run again next time',dest='clear_failed_tests')
170 opt.add_option('--testcmd',action='store',default=False,dest='testcmd',help='Run the unit tests using the test-cmd string example "--testcmd="valgrind --error-exitcode=1 %s" to run under valgrind')
171 opt.add_option('--dump-test-scripts',action='store_true',default=False,help='Create python scripts to help debug tests',dest='dump_test_scripts')
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import re
5 from waflib import Task
6 from waflib.TaskGen import extension
7 from waflib.Tools import c_preproc
8 @extension('.rc')
9 def rc_file(self,node):
10 obj_ext='.rc.o'
11 if self.env.WINRC_TGT_F=='/fo':
12 obj_ext='.res'
13 rctask=self.create_task('winrc',node,node.change_ext(obj_ext))
14 try:
15 self.compiled_tasks.append(rctask)
16 except AttributeError:
17 self.compiled_tasks=[rctask]
18 re_lines=re.compile(r'(?:^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*?)\s*$)|'r'(?:^\w+[ \t]*(ICON|BITMAP|CURSOR|HTML|FONT|MESSAGETABLE|TYPELIB|REGISTRY|D3DFX)[ \t]*(.*?)\s*$)',re.IGNORECASE|re.MULTILINE)
19 class rc_parser(c_preproc.c_parser):
20 def filter_comments(self,node):
21 code=node.read()
22 if c_preproc.use_trigraphs:
23 for(a,b)in c_preproc.trig_def:
24 code=code.split(a).join(b)
25 code=c_preproc.re_nl.sub('',code)
26 code=c_preproc.re_cpp.sub(c_preproc.repl,code)
27 ret=[]
28 for m in re.finditer(re_lines,code):
29 if m.group(2):
30 ret.append((m.group(2),m.group(3)))
31 else:
32 ret.append(('include',m.group(5)))
33 return ret
34 class winrc(Task.Task):
35 run_str='${WINRC} ${WINRCFLAGS} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${WINRC_TGT_F} ${TGT} ${WINRC_SRC_F} ${SRC}'
36 color='BLUE'
37 def scan(self):
38 tmp=rc_parser(self.generator.includes_nodes)
39 tmp.start(self.inputs[0],self.env)
40 return(tmp.nodes,tmp.names)
41 def configure(conf):
42 v=conf.env
43 if not v.WINRC:
44 if v.CC_NAME=='msvc':
45 conf.find_program('RC',var='WINRC',path_list=v.PATH)
46 v.WINRC_TGT_F='/fo'
47 v.WINRC_SRC_F=''
48 else:
49 conf.find_program('windres',var='WINRC',path_list=v.PATH)
50 v.WINRC_TGT_F='-o'
51 v.WINRC_SRC_F='-i'
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib.Tools import ccroot,ar
5 from waflib.Configure import conf
6 @conf
7 def find_xlc(conf):
8 cc=conf.find_program(['xlc_r','xlc'],var='CC')
9 conf.get_xlc_version(cc)
10 conf.env.CC_NAME='xlc'
11 @conf
12 def xlc_common_flags(conf):
13 v=conf.env
14 v.CC_SRC_F=[]
15 v.CC_TGT_F=['-c','-o']
16 if not v.LINK_CC:
17 v.LINK_CC=v.CC
18 v.CCLNK_SRC_F=[]
19 v.CCLNK_TGT_F=['-o']
20 v.CPPPATH_ST='-I%s'
21 v.DEFINES_ST='-D%s'
22 v.LIB_ST='-l%s'
23 v.LIBPATH_ST='-L%s'
24 v.STLIB_ST='-l%s'
25 v.STLIBPATH_ST='-L%s'
26 v.RPATH_ST='-Wl,-rpath,%s'
27 v.SONAME_ST=[]
28 v.SHLIB_MARKER=[]
29 v.STLIB_MARKER=[]
30 v.LINKFLAGS_cprogram=['-Wl,-brtl']
31 v.cprogram_PATTERN='%s'
32 v.CFLAGS_cshlib=['-fPIC']
33 v.LINKFLAGS_cshlib=['-G','-Wl,-brtl,-bexpfull']
34 v.cshlib_PATTERN='lib%s.so'
35 v.LINKFLAGS_cstlib=[]
36 v.cstlib_PATTERN='lib%s.a'
37 def configure(conf):
38 conf.find_xlc()
39 conf.find_ar()
40 conf.xlc_common_flags()
41 conf.cc_load_tools()
42 conf.cc_add_flags()
43 conf.link_add_flags()
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from waflib.Tools import ccroot,ar
5 from waflib.Configure import conf
6 @conf
7 def find_xlcxx(conf):
8 cxx=conf.find_program(['xlc++_r','xlc++'],var='CXX')
9 conf.get_xlc_version(cxx)
10 conf.env.CXX_NAME='xlc++'
11 @conf
12 def xlcxx_common_flags(conf):
13 v=conf.env
14 v.CXX_SRC_F=[]
15 v.CXX_TGT_F=['-c','-o']
16 if not v.LINK_CXX:
17 v.LINK_CXX=v.CXX
18 v.CXXLNK_SRC_F=[]
19 v.CXXLNK_TGT_F=['-o']
20 v.CPPPATH_ST='-I%s'
21 v.DEFINES_ST='-D%s'
22 v.LIB_ST='-l%s'
23 v.LIBPATH_ST='-L%s'
24 v.STLIB_ST='-l%s'
25 v.STLIBPATH_ST='-L%s'
26 v.RPATH_ST='-Wl,-rpath,%s'
27 v.SONAME_ST=[]
28 v.SHLIB_MARKER=[]
29 v.STLIB_MARKER=[]
30 v.LINKFLAGS_cxxprogram=['-Wl,-brtl']
31 v.cxxprogram_PATTERN='%s'
32 v.CXXFLAGS_cxxshlib=['-fPIC']
33 v.LINKFLAGS_cxxshlib=['-G','-Wl,-brtl,-bexpfull']
34 v.cxxshlib_PATTERN='lib%s.so'
35 v.LINKFLAGS_cxxstlib=[]
36 v.cxxstlib_PATTERN='lib%s.a'
37 def configure(conf):
38 conf.find_xlcxx()
39 conf.find_ar()
40 conf.xlcxx_common_flags()
41 conf.cxx_load_tools()
42 conf.cxx_add_flags()
43 conf.link_add_flags()
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from __future__ import with_statement
5 import atexit,os,sys,errno,inspect,re,datetime,platform,base64,signal,functools,time
6 try:
7 import cPickle
8 except ImportError:
9 import pickle as cPickle
10 if os.name=='posix'and sys.version_info[0]<3:
11 try:
12 import subprocess32 as subprocess
13 except ImportError:
14 import subprocess
15 else:
16 import subprocess
17 try:
18 TimeoutExpired=subprocess.TimeoutExpired
19 except AttributeError:
20 class TimeoutExpired(Exception):
21 pass
22 from collections import deque,defaultdict
23 try:
24 import _winreg as winreg
25 except ImportError:
26 try:
27 import winreg
28 except ImportError:
29 winreg=None
30 from waflib import Errors
31 try:
32 from hashlib import md5
33 except ImportError:
34 try:
35 from hashlib import sha1 as md5
36 except ImportError:
37 pass
38 else:
39 try:
40 md5().digest()
41 except ValueError:
42 from hashlib import sha1 as md5
43 try:
44 import threading
45 except ImportError:
46 if not'JOBS'in os.environ:
47 os.environ['JOBS']='1'
48 class threading(object):
49 pass
50 class Lock(object):
51 def acquire(self):
52 pass
53 def release(self):
54 pass
55 threading.Lock=threading.Thread=Lock
56 SIG_NIL='SIG_NIL_SIG_NIL_'.encode()
57 O644=420
58 O755=493
59 rot_chr=['\\','|','/','-']
60 rot_idx=0
61 class ordered_iter_dict(dict):
62 def __init__(self,*k,**kw):
63 self.lst=deque()
64 dict.__init__(self,*k,**kw)
65 def clear(self):
66 dict.clear(self)
67 self.lst=deque()
68 def __setitem__(self,key,value):
69 if key in dict.keys(self):
70 self.lst.remove(key)
71 dict.__setitem__(self,key,value)
72 self.lst.append(key)
73 def __delitem__(self,key):
74 dict.__delitem__(self,key)
75 try:
76 self.lst.remove(key)
77 except ValueError:
78 pass
79 def __iter__(self):
80 return reversed(self.lst)
81 def keys(self):
82 return reversed(self.lst)
83 class lru_node(object):
84 __slots__=('next','prev','key','val')
85 def __init__(self):
86 self.next=self
87 self.prev=self
88 self.key=None
89 self.val=None
90 class lru_cache(object):
91 __slots__=('maxlen','table','head')
92 def __init__(self,maxlen=100):
93 self.maxlen=maxlen
94 self.table={}
95 self.head=lru_node()
96 self.head.next=self.head
97 self.head.prev=self.head
98 def __getitem__(self,key):
99 node=self.table[key]
100 if node is self.head:
101 return node.val
102 node.prev.next=node.next
103 node.next.prev=node.prev
104 node.next=self.head.next
105 node.prev=self.head
106 self.head=node.next.prev=node.prev.next=node
107 return node.val
108 def __setitem__(self,key,val):
109 if key in self.table:
110 node=self.table[key]
111 node.val=val
112 self.__getitem__(key)
113 else:
114 if len(self.table)<self.maxlen:
115 node=lru_node()
116 node.prev=self.head
117 node.next=self.head.next
118 node.prev.next=node.next.prev=node
119 else:
120 node=self.head=self.head.next
121 try:
122 del self.table[node.key]
123 except KeyError:
124 pass
125 node.key=key
126 node.val=val
127 self.table[key]=node
128 class lazy_generator(object):
129 def __init__(self,fun,params):
130 self.fun=fun
131 self.params=params
132 def __iter__(self):
133 return self
134 def __next__(self):
135 try:
136 it=self.it
137 except AttributeError:
138 it=self.it=self.fun(*self.params)
139 return next(it)
140 next=__next__
141 is_win32=os.sep=='\\'or sys.platform=='win32'or os.name=='nt'
142 def readf(fname,m='r',encoding='latin-1'):
143 if sys.hexversion>0x3000000 and not'b'in m:
144 m+='b'
145 with open(fname,m)as f:
146 txt=f.read()
147 if encoding:
148 txt=txt.decode(encoding)
149 else:
150 txt=txt.decode()
151 else:
152 with open(fname,m)as f:
153 txt=f.read()
154 return txt
155 def writef(fname,data,m='w',encoding='latin-1'):
156 if sys.hexversion>0x3000000 and not'b'in m:
157 data=data.encode(encoding)
158 m+='b'
159 with open(fname,m)as f:
160 f.write(data)
161 def h_file(fname):
162 m=md5()
163 with open(fname,'rb')as f:
164 while fname:
165 fname=f.read(200000)
166 m.update(fname)
167 return m.digest()
168 def readf_win32(f,m='r',encoding='latin-1'):
169 flags=os.O_NOINHERIT|os.O_RDONLY
170 if'b'in m:
171 flags|=os.O_BINARY
172 if'+'in m:
173 flags|=os.O_RDWR
174 try:
175 fd=os.open(f,flags)
176 except OSError:
177 raise IOError('Cannot read from %r'%f)
178 if sys.hexversion>0x3000000 and not'b'in m:
179 m+='b'
180 with os.fdopen(fd,m)as f:
181 txt=f.read()
182 if encoding:
183 txt=txt.decode(encoding)
184 else:
185 txt=txt.decode()
186 else:
187 with os.fdopen(fd,m)as f:
188 txt=f.read()
189 return txt
190 def writef_win32(f,data,m='w',encoding='latin-1'):
191 if sys.hexversion>0x3000000 and not'b'in m:
192 data=data.encode(encoding)
193 m+='b'
194 flags=os.O_CREAT|os.O_TRUNC|os.O_WRONLY|os.O_NOINHERIT
195 if'b'in m:
196 flags|=os.O_BINARY
197 if'+'in m:
198 flags|=os.O_RDWR
199 try:
200 fd=os.open(f,flags)
201 except OSError:
202 raise OSError('Cannot write to %r'%f)
203 with os.fdopen(fd,m)as f:
204 f.write(data)
205 def h_file_win32(fname):
206 try:
207 fd=os.open(fname,os.O_BINARY|os.O_RDONLY|os.O_NOINHERIT)
208 except OSError:
209 raise OSError('Cannot read from %r'%fname)
210 m=md5()
211 with os.fdopen(fd,'rb')as f:
212 while fname:
213 fname=f.read(200000)
214 m.update(fname)
215 return m.digest()
216 readf_unix=readf
217 writef_unix=writef
218 h_file_unix=h_file
219 if hasattr(os,'O_NOINHERIT')and sys.hexversion<0x3040000:
220 readf=readf_win32
221 writef=writef_win32
222 h_file=h_file_win32
223 try:
224 x=''.encode('hex')
225 except LookupError:
226 import binascii
227 def to_hex(s):
228 ret=binascii.hexlify(s)
229 if not isinstance(ret,str):
230 ret=ret.decode('utf-8')
231 return ret
232 else:
233 def to_hex(s):
234 return s.encode('hex')
235 to_hex.__doc__="""
236 Return the hexadecimal representation of a string
237
238 :param s: string to convert
239 :type s: string
240 """
241 def listdir_win32(s):
242 if not s:
243 try:
244 import ctypes
245 except ImportError:
246 return[x+':\\'for x in'ABCDEFGHIJKLMNOPQRSTUVWXYZ']
247 else:
248 dlen=4
249 maxdrives=26
250 buf=ctypes.create_string_buffer(maxdrives*dlen)
251 ndrives=ctypes.windll.kernel32.GetLogicalDriveStringsA(maxdrives*dlen,ctypes.byref(buf))
252 return[str(buf.raw[4*i:4*i+2].decode('ascii'))for i in range(int(ndrives/dlen))]
253 if len(s)==2 and s[1]==":":
254 s+=os.sep
255 if not os.path.isdir(s):
256 e=OSError('%s is not a directory'%s)
257 e.errno=errno.ENOENT
258 raise e
259 return os.listdir(s)
260 listdir=os.listdir
261 if is_win32:
262 listdir=listdir_win32
263 def num2ver(ver):
264 if isinstance(ver,str):
265 ver=tuple(ver.split('.'))
266 if isinstance(ver,tuple):
267 ret=0
268 for i in range(4):
269 if i<len(ver):
270 ret+=256**(3-i)*int(ver[i])
271 return ret
272 return ver
273 def to_list(val):
274 if isinstance(val,str):
275 return val.split()
276 else:
277 return val
278 def console_encoding():
279 try:
280 import ctypes
281 except ImportError:
282 pass
283 else:
284 try:
285 codepage=ctypes.windll.kernel32.GetConsoleCP()
286 except AttributeError:
287 pass
288 else:
289 if codepage:
290 return'cp%d'%codepage
291 return sys.stdout.encoding or('cp1252'if is_win32 else'latin-1')
292 def split_path_unix(path):
293 return path.split('/')
294 def split_path_cygwin(path):
295 if path.startswith('//'):
296 ret=path.split('/')[2:]
297 ret[0]='/'+ret[0]
298 return ret
299 return path.split('/')
300 re_sp=re.compile('[/\\\\]+')
301 def split_path_win32(path):
302 if path.startswith('\\\\'):
303 ret=re_sp.split(path)[1:]
304 ret[0]='\\\\'+ret[0]
305 if ret[0]=='\\\\?':
306 return ret[1:]
307 return ret
308 return re_sp.split(path)
309 msysroot=None
310 def split_path_msys(path):
311 if path.startswith(('/','\\'))and not path.startswith(('//','\\\\')):
312 global msysroot
313 if not msysroot:
314 msysroot=subprocess.check_output(['cygpath','-w','/']).decode(sys.stdout.encoding or'latin-1')
315 msysroot=msysroot.strip()
316 path=os.path.normpath(msysroot+os.sep+path)
317 return split_path_win32(path)
318 if sys.platform=='cygwin':
319 split_path=split_path_cygwin
320 elif is_win32:
321 if os.environ.get('MSYSTEM')and sys.executable.startswith('/'):
322 split_path=split_path_msys
323 else:
324 split_path=split_path_win32
325 else:
326 split_path=split_path_unix
327 split_path.__doc__="""
328 Splits a path by / or \\; do not confuse this function with with ``os.path.split``
329
330 :type path: string
331 :param path: path to split
332 :return: list of string
333 """
334 def check_dir(path):
335 if not os.path.isdir(path):
336 try:
337 os.makedirs(path)
338 except OSError as e:
339 if not os.path.isdir(path):
340 raise Errors.WafError('Cannot create the folder %r'%path,ex=e)
341 def check_exe(name,env=None):
342 if not name:
343 raise ValueError('Cannot execute an empty string!')
344 def is_exe(fpath):
345 return os.path.isfile(fpath)and os.access(fpath,os.X_OK)
346 fpath,fname=os.path.split(name)
347 if fpath and is_exe(name):
348 return os.path.abspath(name)
349 else:
350 env=env or os.environ
351 for path in env['PATH'].split(os.pathsep):
352 path=path.strip('"')
353 exe_file=os.path.join(path,name)
354 if is_exe(exe_file):
355 return os.path.abspath(exe_file)
356 return None
357 def def_attrs(cls,**kw):
358 for k,v in kw.items():
359 if not hasattr(cls,k):
360 setattr(cls,k,v)
361 def quote_define_name(s):
362 fu=re.sub('[^a-zA-Z0-9]','_',s)
363 fu=re.sub('_+','_',fu)
364 fu=fu.upper()
365 return fu
366 re_sh=re.compile('\\s|\'|"')
367 def shell_escape(cmd):
368 if isinstance(cmd,str):
369 return cmd
370 return' '.join(repr(x)if re_sh.search(x)else x for x in cmd)
371 def h_list(lst):
372 return md5(repr(lst).encode()).digest()
373 if sys.hexversion<0x3000000:
374 def h_list_python2(lst):
375 return md5(repr(lst)).digest()
376 h_list_python2.__doc__=h_list.__doc__
377 h_list=h_list_python2
378 def h_fun(fun):
379 try:
380 return fun.code
381 except AttributeError:
382 if isinstance(fun,functools.partial):
383 code=list(fun.args)
384 code.extend(sorted(fun.keywords.items()))
385 code.append(h_fun(fun.func))
386 fun.code=h_list(code)
387 return fun.code
388 try:
389 h=inspect.getsource(fun)
390 except EnvironmentError:
391 h='nocode'
392 try:
393 fun.code=h
394 except AttributeError:
395 pass
396 return h
397 def h_cmd(ins):
398 if isinstance(ins,str):
399 ret=ins
400 elif isinstance(ins,list)or isinstance(ins,tuple):
401 ret=str([h_cmd(x)for x in ins])
402 else:
403 ret=str(h_fun(ins))
404 if sys.hexversion>0x3000000:
405 ret=ret.encode('latin-1','xmlcharrefreplace')
406 return ret
407 reg_subst=re.compile(r"(\\\\)|(\$\$)|\$\{([^}]+)\}")
408 def subst_vars(expr,params):
409 def repl_var(m):
410 if m.group(1):
411 return'\\'
412 if m.group(2):
413 return'$'
414 try:
415 return params.get_flat(m.group(3))
416 except AttributeError:
417 return params[m.group(3)]
418 return reg_subst.sub(repl_var,expr)
419 def destos_to_binfmt(key):
420 if key=='darwin':
421 return'mac-o'
422 elif key in('win32','cygwin','uwin','msys'):
423 return'pe'
424 return'elf'
425 def unversioned_sys_platform():
426 s=sys.platform
427 if s.startswith('java'):
428 from java.lang import System
429 s=System.getProperty('os.name')
430 if s=='Mac OS X':
431 return'darwin'
432 elif s.startswith('Windows '):
433 return'win32'
434 elif s=='OS/2':
435 return'os2'
436 elif s=='HP-UX':
437 return'hp-ux'
438 elif s in('SunOS','Solaris'):
439 return'sunos'
440 else:s=s.lower()
441 if s=='powerpc':
442 return'darwin'
443 if s=='win32'or s=='os2':
444 return s
445 if s=='cli'and os.name=='nt':
446 return'win32'
447 return re.split(r'\d+$',s)[0]
448 def nada(*k,**kw):
449 pass
450 class Timer(object):
451 def __init__(self):
452 self.start_time=self.now()
453 def __str__(self):
454 delta=self.now()-self.start_time
455 if not isinstance(delta,datetime.timedelta):
456 delta=datetime.timedelta(seconds=delta)
457 days=delta.days
458 hours,rem=divmod(delta.seconds,3600)
459 minutes,seconds=divmod(rem,60)
460 seconds+=delta.microseconds*1e-6
461 result=''
462 if days:
463 result+='%dd'%days
464 if days or hours:
465 result+='%dh'%hours
466 if days or hours or minutes:
467 result+='%dm'%minutes
468 return'%s%.3fs'%(result,seconds)
469 def now(self):
470 return datetime.datetime.utcnow()
471 if hasattr(time,'perf_counter'):
472 def now(self):
473 return time.perf_counter()
474 def read_la_file(path):
475 sp=re.compile(r'^([^=]+)=\'(.*)\'$')
476 dc={}
477 for line in readf(path).splitlines():
478 try:
479 _,left,right,_=sp.split(line.strip())
480 dc[left]=right
481 except ValueError:
482 pass
483 return dc
484 def run_once(fun):
485 cache={}
486 def wrap(*k):
487 try:
488 return cache[k]
489 except KeyError:
490 ret=fun(*k)
491 cache[k]=ret
492 return ret
493 wrap.__cache__=cache
494 wrap.__name__=fun.__name__
495 return wrap
496 def get_registry_app_path(key,filename):
497 if not winreg:
498 return None
499 try:
500 result=winreg.QueryValue(key,"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\%s.exe"%filename[0])
501 except OSError:
502 pass
503 else:
504 if os.path.isfile(result):
505 return result
506 def lib64():
507 if os.sep=='/':
508 if platform.architecture()[0]=='64bit':
509 if os.path.exists('/usr/lib64')and not os.path.exists('/usr/lib32'):
510 return'64'
511 return''
512 def sane_path(p):
513 return os.path.abspath(os.path.expanduser(p))
514 process_pool=[]
515 def get_process():
516 try:
517 return process_pool.pop()
518 except IndexError:
519 filepath=os.path.dirname(os.path.abspath(__file__))+os.sep+'processor.py'
520 cmd=[sys.executable,'-c',readf(filepath)]
521 return subprocess.Popen(cmd,stdout=subprocess.PIPE,stdin=subprocess.PIPE,bufsize=0,close_fds=not is_win32)
522 def run_prefork_process(cmd,kwargs,cargs):
523 if not kwargs.get('env'):
524 kwargs['env']=dict(os.environ)
525 try:
526 obj=base64.b64encode(cPickle.dumps([cmd,kwargs,cargs]))
527 except(TypeError,AttributeError):
528 return run_regular_process(cmd,kwargs,cargs)
529 proc=get_process()
530 if not proc:
531 return run_regular_process(cmd,kwargs,cargs)
532 proc.stdin.write(obj)
533 proc.stdin.write('\n'.encode())
534 proc.stdin.flush()
535 obj=proc.stdout.readline()
536 if not obj:
537 raise OSError('Preforked sub-process %r died'%proc.pid)
538 process_pool.append(proc)
539 lst=cPickle.loads(base64.b64decode(obj))
540 assert len(lst)==5
541 ret,out,err,ex,trace=lst
542 if ex:
543 if ex=='OSError':
544 raise OSError(trace)
545 elif ex=='ValueError':
546 raise ValueError(trace)
547 elif ex=='TimeoutExpired':
548 exc=TimeoutExpired(cmd,timeout=cargs['timeout'],output=out)
549 exc.stderr=err
550 raise exc
551 else:
552 raise Exception(trace)
553 return ret,out,err
554 def lchown(path,user=-1,group=-1):
555 if isinstance(user,str):
556 import pwd
557 entry=pwd.getpwnam(user)
558 if not entry:
559 raise OSError('Unknown user %r'%user)
560 user=entry[2]
561 if isinstance(group,str):
562 import grp
563 entry=grp.getgrnam(group)
564 if not entry:
565 raise OSError('Unknown group %r'%group)
566 group=entry[2]
567 return os.lchown(path,user,group)
568 def run_regular_process(cmd,kwargs,cargs={}):
569 proc=subprocess.Popen(cmd,**kwargs)
570 if kwargs.get('stdout')or kwargs.get('stderr'):
571 try:
572 out,err=proc.communicate(**cargs)
573 except TimeoutExpired:
574 if kwargs.get('start_new_session')and hasattr(os,'killpg'):
575 os.killpg(proc.pid,signal.SIGKILL)
576 else:
577 proc.kill()
578 out,err=proc.communicate()
579 exc=TimeoutExpired(proc.args,timeout=cargs['timeout'],output=out)
580 exc.stderr=err
581 raise exc
582 status=proc.returncode
583 else:
584 out,err=(None,None)
585 try:
586 status=proc.wait(**cargs)
587 except TimeoutExpired as e:
588 if kwargs.get('start_new_session')and hasattr(os,'killpg'):
589 os.killpg(proc.pid,signal.SIGKILL)
590 else:
591 proc.kill()
592 proc.wait()
593 raise e
594 return status,out,err
595 def run_process(cmd,kwargs,cargs={}):
596 if kwargs.get('stdout')and kwargs.get('stderr'):
597 return run_prefork_process(cmd,kwargs,cargs)
598 else:
599 return run_regular_process(cmd,kwargs,cargs)
600 def alloc_process_pool(n,force=False):
601 global run_process,get_process,alloc_process_pool
602 if not force:
603 n=max(n-len(process_pool),0)
604 try:
605 lst=[get_process()for x in range(n)]
606 except OSError:
607 run_process=run_regular_process
608 get_process=alloc_process_pool=nada
609 else:
610 for x in lst:
611 process_pool.append(x)
612 def atexit_pool():
613 for k in process_pool:
614 try:
615 os.kill(k.pid,9)
616 except OSError:
617 pass
618 else:
619 k.wait()
620 if(sys.hexversion<0x207000f and not is_win32)or sys.hexversion>=0x306000f:
621 atexit.register(atexit_pool)
622 if os.environ.get('WAF_NO_PREFORK')or sys.platform=='cli'or not sys.executable:
623 run_process=run_regular_process
624 get_process=alloc_process_pool=nada
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os,re,sys
5 from waflib import Utils
6 wlock=Utils.threading.Lock()
7 try:
8 from ctypes import Structure,windll,c_short,c_ushort,c_ulong,c_int,byref,c_wchar,POINTER,c_long
9 except ImportError:
10 class AnsiTerm(object):
11 def __init__(self,stream):
12 self.stream=stream
13 try:
14 self.errors=self.stream.errors
15 except AttributeError:
16 pass
17 self.encoding=self.stream.encoding
18 def write(self,txt):
19 try:
20 wlock.acquire()
21 self.stream.write(txt)
22 self.stream.flush()
23 finally:
24 wlock.release()
25 def fileno(self):
26 return self.stream.fileno()
27 def flush(self):
28 self.stream.flush()
29 def isatty(self):
30 return self.stream.isatty()
31 else:
32 class COORD(Structure):
33 _fields_=[("X",c_short),("Y",c_short)]
34 class SMALL_RECT(Structure):
35 _fields_=[("Left",c_short),("Top",c_short),("Right",c_short),("Bottom",c_short)]
36 class CONSOLE_SCREEN_BUFFER_INFO(Structure):
37 _fields_=[("Size",COORD),("CursorPosition",COORD),("Attributes",c_ushort),("Window",SMALL_RECT),("MaximumWindowSize",COORD)]
38 class CONSOLE_CURSOR_INFO(Structure):
39 _fields_=[('dwSize',c_ulong),('bVisible',c_int)]
40 try:
41 _type=unicode
42 except NameError:
43 _type=str
44 to_int=lambda number,default:number and int(number)or default
45 STD_OUTPUT_HANDLE=-11
46 STD_ERROR_HANDLE=-12
47 windll.kernel32.GetStdHandle.argtypes=[c_ulong]
48 windll.kernel32.GetStdHandle.restype=c_ulong
49 windll.kernel32.GetConsoleScreenBufferInfo.argtypes=[c_ulong,POINTER(CONSOLE_SCREEN_BUFFER_INFO)]
50 windll.kernel32.GetConsoleScreenBufferInfo.restype=c_long
51 windll.kernel32.SetConsoleTextAttribute.argtypes=[c_ulong,c_ushort]
52 windll.kernel32.SetConsoleTextAttribute.restype=c_long
53 windll.kernel32.FillConsoleOutputCharacterW.argtypes=[c_ulong,c_wchar,c_ulong,POINTER(COORD),POINTER(c_ulong)]
54 windll.kernel32.FillConsoleOutputCharacterW.restype=c_long
55 windll.kernel32.FillConsoleOutputAttribute.argtypes=[c_ulong,c_ushort,c_ulong,POINTER(COORD),POINTER(c_ulong)]
56 windll.kernel32.FillConsoleOutputAttribute.restype=c_long
57 windll.kernel32.SetConsoleCursorPosition.argtypes=[c_ulong,POINTER(COORD)]
58 windll.kernel32.SetConsoleCursorPosition.restype=c_long
59 windll.kernel32.SetConsoleCursorInfo.argtypes=[c_ulong,POINTER(CONSOLE_CURSOR_INFO)]
60 windll.kernel32.SetConsoleCursorInfo.restype=c_long
61 class AnsiTerm(object):
62 def __init__(self,s):
63 self.stream=s
64 try:
65 self.errors=s.errors
66 except AttributeError:
67 pass
68 self.encoding=s.encoding
69 self.cursor_history=[]
70 handle=(s.fileno()==2)and STD_ERROR_HANDLE or STD_OUTPUT_HANDLE
71 self.hconsole=windll.kernel32.GetStdHandle(handle)
72 self._sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
73 self._csinfo=CONSOLE_CURSOR_INFO()
74 windll.kernel32.GetConsoleCursorInfo(self.hconsole,byref(self._csinfo))
75 self._orig_sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
76 r=windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole,byref(self._orig_sbinfo))
77 self._isatty=r==1
78 def screen_buffer_info(self):
79 windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole,byref(self._sbinfo))
80 return self._sbinfo
81 def clear_line(self,param):
82 mode=param and int(param)or 0
83 sbinfo=self.screen_buffer_info()
84 if mode==1:
85 line_start=COORD(0,sbinfo.CursorPosition.Y)
86 line_length=sbinfo.Size.X
87 elif mode==2:
88 line_start=COORD(sbinfo.CursorPosition.X,sbinfo.CursorPosition.Y)
89 line_length=sbinfo.Size.X-sbinfo.CursorPosition.X
90 else:
91 line_start=sbinfo.CursorPosition
92 line_length=sbinfo.Size.X-sbinfo.CursorPosition.X
93 chars_written=c_ulong()
94 windll.kernel32.FillConsoleOutputCharacterW(self.hconsole,c_wchar(' '),line_length,line_start,byref(chars_written))
95 windll.kernel32.FillConsoleOutputAttribute(self.hconsole,sbinfo.Attributes,line_length,line_start,byref(chars_written))
96 def clear_screen(self,param):
97 mode=to_int(param,0)
98 sbinfo=self.screen_buffer_info()
99 if mode==1:
100 clear_start=COORD(0,0)
101 clear_length=sbinfo.CursorPosition.X*sbinfo.CursorPosition.Y
102 elif mode==2:
103 clear_start=COORD(0,0)
104 clear_length=sbinfo.Size.X*sbinfo.Size.Y
105 windll.kernel32.SetConsoleCursorPosition(self.hconsole,clear_start)
106 else:
107 clear_start=sbinfo.CursorPosition
108 clear_length=((sbinfo.Size.X-sbinfo.CursorPosition.X)+sbinfo.Size.X*(sbinfo.Size.Y-sbinfo.CursorPosition.Y))
109 chars_written=c_ulong()
110 windll.kernel32.FillConsoleOutputCharacterW(self.hconsole,c_wchar(' '),clear_length,clear_start,byref(chars_written))
111 windll.kernel32.FillConsoleOutputAttribute(self.hconsole,sbinfo.Attributes,clear_length,clear_start,byref(chars_written))
112 def push_cursor(self,param):
113 sbinfo=self.screen_buffer_info()
114 self.cursor_history.append(sbinfo.CursorPosition)
115 def pop_cursor(self,param):
116 if self.cursor_history:
117 old_pos=self.cursor_history.pop()
118 windll.kernel32.SetConsoleCursorPosition(self.hconsole,old_pos)
119 def set_cursor(self,param):
120 y,sep,x=param.partition(';')
121 x=to_int(x,1)-1
122 y=to_int(y,1)-1
123 sbinfo=self.screen_buffer_info()
124 new_pos=COORD(min(max(0,x),sbinfo.Size.X),min(max(0,y),sbinfo.Size.Y))
125 windll.kernel32.SetConsoleCursorPosition(self.hconsole,new_pos)
126 def set_column(self,param):
127 x=to_int(param,1)-1
128 sbinfo=self.screen_buffer_info()
129 new_pos=COORD(min(max(0,x),sbinfo.Size.X),sbinfo.CursorPosition.Y)
130 windll.kernel32.SetConsoleCursorPosition(self.hconsole,new_pos)
131 def move_cursor(self,x_offset=0,y_offset=0):
132 sbinfo=self.screen_buffer_info()
133 new_pos=COORD(min(max(0,sbinfo.CursorPosition.X+x_offset),sbinfo.Size.X),min(max(0,sbinfo.CursorPosition.Y+y_offset),sbinfo.Size.Y))
134 windll.kernel32.SetConsoleCursorPosition(self.hconsole,new_pos)
135 def move_up(self,param):
136 self.move_cursor(y_offset=-to_int(param,1))
137 def move_down(self,param):
138 self.move_cursor(y_offset=to_int(param,1))
139 def move_left(self,param):
140 self.move_cursor(x_offset=-to_int(param,1))
141 def move_right(self,param):
142 self.move_cursor(x_offset=to_int(param,1))
143 def next_line(self,param):
144 sbinfo=self.screen_buffer_info()
145 self.move_cursor(x_offset=-sbinfo.CursorPosition.X,y_offset=to_int(param,1))
146 def prev_line(self,param):
147 sbinfo=self.screen_buffer_info()
148 self.move_cursor(x_offset=-sbinfo.CursorPosition.X,y_offset=-to_int(param,1))
149 def rgb2bgr(self,c):
150 return((c&1)<<2)|(c&2)|((c&4)>>2)
151 def set_color(self,param):
152 cols=param.split(';')
153 sbinfo=self.screen_buffer_info()
154 attr=sbinfo.Attributes
155 for c in cols:
156 c=to_int(c,0)
157 if 29<c<38:
158 attr=(attr&0xfff0)|self.rgb2bgr(c-30)
159 elif 39<c<48:
160 attr=(attr&0xff0f)|(self.rgb2bgr(c-40)<<4)
161 elif c==0:
162 attr=self._orig_sbinfo.Attributes
163 elif c==1:
164 attr|=0x08
165 elif c==4:
166 attr|=0x80
167 elif c==7:
168 attr=(attr&0xff88)|((attr&0x70)>>4)|((attr&0x07)<<4)
169 windll.kernel32.SetConsoleTextAttribute(self.hconsole,attr)
170 def show_cursor(self,param):
171 self._csinfo.bVisible=1
172 windll.kernel32.SetConsoleCursorInfo(self.hconsole,byref(self._csinfo))
173 def hide_cursor(self,param):
174 self._csinfo.bVisible=0
175 windll.kernel32.SetConsoleCursorInfo(self.hconsole,byref(self._csinfo))
176 ansi_command_table={'A':move_up,'B':move_down,'C':move_right,'D':move_left,'E':next_line,'F':prev_line,'G':set_column,'H':set_cursor,'f':set_cursor,'J':clear_screen,'K':clear_line,'h':show_cursor,'l':hide_cursor,'m':set_color,'s':push_cursor,'u':pop_cursor,}
177 ansi_tokens=re.compile(r'(?:\x1b\[([0-9?;]*)([a-zA-Z])|([^\x1b]+))')
178 def write(self,text):
179 try:
180 wlock.acquire()
181 if self._isatty:
182 for param,cmd,txt in self.ansi_tokens.findall(text):
183 if cmd:
184 cmd_func=self.ansi_command_table.get(cmd)
185 if cmd_func:
186 cmd_func(self,param)
187 else:
188 self.writeconsole(txt)
189 else:
190 self.stream.write(text)
191 finally:
192 wlock.release()
193 def writeconsole(self,txt):
194 chars_written=c_ulong()
195 writeconsole=windll.kernel32.WriteConsoleA
196 if isinstance(txt,_type):
197 writeconsole=windll.kernel32.WriteConsoleW
198 done=0
199 todo=len(txt)
200 chunk=32<<10
201 while todo!=0:
202 doing=min(chunk,todo)
203 buf=txt[done:done+doing]
204 r=writeconsole(self.hconsole,buf,doing,byref(chars_written),None)
205 if r==0:
206 chunk>>=1
207 continue
208 done+=doing
209 todo-=doing
210 def fileno(self):
211 return self.stream.fileno()
212 def flush(self):
213 pass
214 def isatty(self):
215 return self._isatty
216 if sys.stdout.isatty()or sys.stderr.isatty():
217 handle=sys.stdout.isatty()and STD_OUTPUT_HANDLE or STD_ERROR_HANDLE
218 console=windll.kernel32.GetStdHandle(handle)
219 sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
220 def get_term_cols():
221 windll.kernel32.GetConsoleScreenBufferInfo(console,byref(sbinfo))
222 return sbinfo.Size.X-1
223 try:
224 import struct,fcntl,termios
225 except ImportError:
226 pass
227 else:
228 if(sys.stdout.isatty()or sys.stderr.isatty())and os.environ.get('TERM','')not in('dumb','emacs'):
229 FD=sys.stdout.isatty()and sys.stdout.fileno()or sys.stderr.fileno()
230 def fun():
231 return struct.unpack("HHHH",fcntl.ioctl(FD,termios.TIOCGWINSZ,struct.pack("HHHH",0,0,0,0)))[1]
232 try:
233 fun()
234 except Exception as e:
235 pass
236 else:
237 get_term_cols=fun
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import sys
5 from waflib import ConfigSet,Logs,Options,Scripting,Task,Build,Configure,Node,Runner,TaskGen,Utils,Errors,Context
6 sys.modules['Environment']=ConfigSet
7 ConfigSet.Environment=ConfigSet.ConfigSet
8 sys.modules['Logs']=Logs
9 sys.modules['Options']=Options
10 sys.modules['Scripting']=Scripting
11 sys.modules['Task']=Task
12 sys.modules['Build']=Build
13 sys.modules['Configure']=Configure
14 sys.modules['Node']=Node
15 sys.modules['Runner']=Runner
16 sys.modules['TaskGen']=TaskGen
17 sys.modules['Utils']=Utils
18 sys.modules['Constants']=Context
19 Context.SRCDIR=''
20 Context.BLDDIR=''
21 from waflib.Tools import c_preproc
22 sys.modules['preproc']=c_preproc
23 from waflib.Tools import c_config
24 sys.modules['config_c']=c_config
25 ConfigSet.ConfigSet.copy=ConfigSet.ConfigSet.derive
26 ConfigSet.ConfigSet.set_variant=Utils.nada
27 Utils.pproc=Utils.subprocess
28 Build.BuildContext.add_subdirs=Build.BuildContext.recurse
29 Build.BuildContext.new_task_gen=Build.BuildContext.__call__
30 Build.BuildContext.is_install=0
31 Node.Node.relpath_gen=Node.Node.path_from
32 Utils.pproc=Utils.subprocess
33 Utils.get_term_cols=Logs.get_term_cols
34 def cmd_output(cmd,**kw):
35 silent=False
36 if'silent'in kw:
37 silent=kw['silent']
38 del(kw['silent'])
39 if'e'in kw:
40 tmp=kw['e']
41 del(kw['e'])
42 kw['env']=tmp
43 kw['shell']=isinstance(cmd,str)
44 kw['stdout']=Utils.subprocess.PIPE
45 if silent:
46 kw['stderr']=Utils.subprocess.PIPE
47 try:
48 p=Utils.subprocess.Popen(cmd,**kw)
49 output=p.communicate()[0]
50 except OSError as e:
51 raise ValueError(str(e))
52 if p.returncode:
53 if not silent:
54 msg="command execution failed: %s -> %r"%(cmd,str(output))
55 raise ValueError(msg)
56 output=''
57 return output
58 Utils.cmd_output=cmd_output
59 def name_to_obj(self,s,env=None):
60 if Logs.verbose:
61 Logs.warn('compat: change "name_to_obj(name, env)" by "get_tgen_by_name(name)"')
62 return self.get_tgen_by_name(s)
63 Build.BuildContext.name_to_obj=name_to_obj
64 def env_of_name(self,name):
65 try:
66 return self.all_envs[name]
67 except KeyError:
68 Logs.error('no such environment: '+name)
69 return None
70 Build.BuildContext.env_of_name=env_of_name
71 def set_env_name(self,name,env):
72 self.all_envs[name]=env
73 return env
74 Configure.ConfigurationContext.set_env_name=set_env_name
75 def retrieve(self,name,fromenv=None):
76 try:
77 env=self.all_envs[name]
78 except KeyError:
79 env=ConfigSet.ConfigSet()
80 self.prepare_env(env)
81 self.all_envs[name]=env
82 else:
83 if fromenv:
84 Logs.warn('The environment %s may have been configured already',name)
85 return env
86 Configure.ConfigurationContext.retrieve=retrieve
87 Configure.ConfigurationContext.sub_config=Configure.ConfigurationContext.recurse
88 Configure.ConfigurationContext.check_tool=Configure.ConfigurationContext.load
89 Configure.conftest=Configure.conf
90 Configure.ConfigurationError=Errors.ConfigurationError
91 Utils.WafError=Errors.WafError
92 Options.OptionsContext.sub_options=Options.OptionsContext.recurse
93 Options.OptionsContext.tool_options=Context.Context.load
94 Options.Handler=Options.OptionsContext
95 Task.simple_task_type=Task.task_type_from_func=Task.task_factory
96 Task.Task.classes=Task.classes
97 def setitem(self,key,value):
98 if key.startswith('CCFLAGS'):
99 key=key[1:]
100 self.table[key]=value
101 ConfigSet.ConfigSet.__setitem__=setitem
102 @TaskGen.feature('d')
103 @TaskGen.before('apply_incpaths')
104 def old_importpaths(self):
105 if getattr(self,'importpaths',[]):
106 self.includes=self.importpaths
107 from waflib import Context
108 eld=Context.load_tool
109 def load_tool(*k,**kw):
110 ret=eld(*k,**kw)
111 if'set_options'in ret.__dict__:
112 if Logs.verbose:
113 Logs.warn('compat: rename "set_options" to options')
114 ret.options=ret.set_options
115 if'detect'in ret.__dict__:
116 if Logs.verbose:
117 Logs.warn('compat: rename "detect" to "configure"')
118 ret.configure=ret.detect
119 return ret
120 Context.load_tool=load_tool
121 def get_curdir(self):
122 return self.path.abspath()
123 Context.Context.curdir=property(get_curdir,Utils.nada)
124 def get_srcdir(self):
125 return self.srcnode.abspath()
126 Configure.ConfigurationContext.srcdir=property(get_srcdir,Utils.nada)
127 def get_blddir(self):
128 return self.bldnode.abspath()
129 Configure.ConfigurationContext.blddir=property(get_blddir,Utils.nada)
130 Configure.ConfigurationContext.check_message_1=Configure.ConfigurationContext.start_msg
131 Configure.ConfigurationContext.check_message_2=Configure.ConfigurationContext.end_msg
132 rev=Context.load_module
133 def load_module(path,encoding=None):
134 ret=rev(path,encoding)
135 if'set_options'in ret.__dict__:
136 if Logs.verbose:
137 Logs.warn('compat: rename "set_options" to "options" (%r)',path)
138 ret.options=ret.set_options
139 if'srcdir'in ret.__dict__:
140 if Logs.verbose:
141 Logs.warn('compat: rename "srcdir" to "top" (%r)',path)
142 ret.top=ret.srcdir
143 if'blddir'in ret.__dict__:
144 if Logs.verbose:
145 Logs.warn('compat: rename "blddir" to "out" (%r)',path)
146 ret.out=ret.blddir
147 Utils.g_module=Context.g_module
148 Options.launch_dir=Context.launch_dir
149 return ret
150 Context.load_module=load_module
151 old_post=TaskGen.task_gen.post
152 def post(self):
153 self.features=self.to_list(self.features)
154 if'cc'in self.features:
155 if Logs.verbose:
156 Logs.warn('compat: the feature cc does not exist anymore (use "c")')
157 self.features.remove('cc')
158 self.features.append('c')
159 if'cstaticlib'in self.features:
160 if Logs.verbose:
161 Logs.warn('compat: the feature cstaticlib does not exist anymore (use "cstlib" or "cxxstlib")')
162 self.features.remove('cstaticlib')
163 self.features.append(('cxx'in self.features)and'cxxstlib'or'cstlib')
164 if getattr(self,'ccflags',None):
165 if Logs.verbose:
166 Logs.warn('compat: "ccflags" was renamed to "cflags"')
167 self.cflags=self.ccflags
168 return old_post(self)
169 TaskGen.task_gen.post=post
170 def waf_version(*k,**kw):
171 Logs.warn('wrong version (waf_version was removed in waf 1.6)')
172 Utils.waf_version=waf_version
173 import os
174 @TaskGen.feature('c','cxx','d')
175 @TaskGen.before('apply_incpaths','propagate_uselib_vars')
176 @TaskGen.after('apply_link','process_source')
177 def apply_uselib_local(self):
178 env=self.env
179 from waflib.Tools.ccroot import stlink_task
180 self.uselib=self.to_list(getattr(self,'uselib',[]))
181 self.includes=self.to_list(getattr(self,'includes',[]))
182 names=self.to_list(getattr(self,'uselib_local',[]))
183 get=self.bld.get_tgen_by_name
184 seen=set()
185 seen_uselib=set()
186 tmp=Utils.deque(names)
187 if tmp:
188 if Logs.verbose:
189 Logs.warn('compat: "uselib_local" is deprecated, replace by "use"')
190 while tmp:
191 lib_name=tmp.popleft()
192 if lib_name in seen:
193 continue
194 y=get(lib_name)
195 y.post()
196 seen.add(lib_name)
197 if getattr(y,'uselib_local',None):
198 for x in self.to_list(getattr(y,'uselib_local',[])):
199 obj=get(x)
200 obj.post()
201 if getattr(obj,'link_task',None):
202 if not isinstance(obj.link_task,stlink_task):
203 tmp.append(x)
204 if getattr(y,'link_task',None):
205 link_name=y.target[y.target.rfind(os.sep)+1:]
206 if isinstance(y.link_task,stlink_task):
207 env.append_value('STLIB',[link_name])
208 else:
209 env.append_value('LIB',[link_name])
210 self.link_task.set_run_after(y.link_task)
211 self.link_task.dep_nodes+=y.link_task.outputs
212 tmp_path=y.link_task.outputs[0].parent.bldpath()
213 if not tmp_path in env['LIBPATH']:
214 env.prepend_value('LIBPATH',[tmp_path])
215 for v in self.to_list(getattr(y,'uselib',[])):
216 if v not in seen_uselib:
217 seen_uselib.add(v)
218 if not env['STLIB_'+v]:
219 if not v in self.uselib:
220 self.uselib.insert(0,v)
221 if getattr(y,'export_includes',None):
222 self.includes.extend(y.to_incnodes(y.export_includes))
223 @TaskGen.feature('cprogram','cxxprogram','cstlib','cxxstlib','cshlib','cxxshlib','dprogram','dstlib','dshlib')
224 @TaskGen.after('apply_link')
225 def apply_objdeps(self):
226 names=getattr(self,'add_objects',[])
227 if not names:
228 return
229 names=self.to_list(names)
230 get=self.bld.get_tgen_by_name
231 seen=[]
232 while names:
233 x=names[0]
234 if x in seen:
235 names=names[1:]
236 continue
237 y=get(x)
238 if getattr(y,'add_objects',None):
239 added=0
240 lst=y.to_list(y.add_objects)
241 lst.reverse()
242 for u in lst:
243 if u in seen:
244 continue
245 added=1
246 names=[u]+names
247 if added:
248 continue
249 y.post()
250 seen.append(x)
251 for t in getattr(y,'compiled_tasks',[]):
252 self.link_task.inputs.extend(t.outputs)
253 @TaskGen.after('apply_link')
254 def process_obj_files(self):
255 if not hasattr(self,'obj_files'):
256 return
257 for x in self.obj_files:
258 node=self.path.find_resource(x)
259 self.link_task.inputs.append(node)
260 @TaskGen.taskgen_method
261 def add_obj_file(self,file):
262 if not hasattr(self,'obj_files'):
263 self.obj_files=[]
264 if not'process_obj_files'in self.meths:
265 self.meths.append('process_obj_files')
266 self.obj_files.append(file)
267 old_define=Configure.ConfigurationContext.__dict__['define']
268 @Configure.conf
269 def define(self,key,val,quote=True,comment=''):
270 old_define(self,key,val,quote,comment)
271 if key.startswith('HAVE_'):
272 self.env[key]=1
273 old_undefine=Configure.ConfigurationContext.__dict__['undefine']
274 @Configure.conf
275 def undefine(self,key,comment=''):
276 old_undefine(self,key,comment)
277 if key.startswith('HAVE_'):
278 self.env[key]=0
279 def set_incdirs(self,val):
280 Logs.warn('compat: change "export_incdirs" by "export_includes"')
281 self.export_includes=val
282 TaskGen.task_gen.export_incdirs=property(None,set_incdirs)
283 def install_dir(self,path):
284 if not path:
285 return[]
286 destpath=Utils.subst_vars(path,self.env)
287 if self.is_install>0:
288 Logs.info('* creating %s',destpath)
289 Utils.check_dir(destpath)
290 elif self.is_install<0:
291 Logs.info('* removing %s',destpath)
292 try:
293 os.remove(destpath)
294 except OSError:
295 pass
296 Build.BuildContext.install_dir=install_dir
297 repl={'apply_core':'process_source','apply_lib_vars':'process_source','apply_obj_vars':'propagate_uselib_vars','exec_rule':'process_rule'}
298 def after(*k):
299 k=[repl.get(key,key)for key in k]
300 return TaskGen.after_method(*k)
301 def before(*k):
302 k=[repl.get(key,key)for key in k]
303 return TaskGen.before_method(*k)
304 TaskGen.before=before
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 from __future__ import with_statement
5 import os
6 all_modifs={}
7 def fixdir(dir):
8 for k in all_modifs:
9 for v in all_modifs[k]:
10 modif(os.path.join(dir,'waflib'),k,v)
11 def modif(dir,name,fun):
12 if name=='*':
13 lst=[]
14 for y in'. Tools extras'.split():
15 for x in os.listdir(os.path.join(dir,y)):
16 if x.endswith('.py'):
17 lst.append(y+os.sep+x)
18 for x in lst:
19 modif(dir,x,fun)
20 return
21 filename=os.path.join(dir,name)
22 with open(filename,'r')as f:
23 txt=f.read()
24 txt=fun(txt)
25 with open(filename,'w')as f:
26 f.write(txt)
27 def subst(*k):
28 def do_subst(fun):
29 for x in k:
30 try:
31 all_modifs[x].append(fun)
32 except KeyError:
33 all_modifs[x]=[fun]
34 return fun
35 return do_subst
36 @subst('*')
37 def r1(code):
38 code=code.replace('as e:',',e:')
39 code=code.replace(".decode(sys.stdout.encoding or'latin-1',errors='replace')",'')
40 return code.replace('.encode()','')
41 @subst('Runner.py')
42 def r4(code):
43 return code.replace('next(self.biter)','self.biter.next()')
44 @subst('Context.py')
45 def r5(code):
46 return code.replace("('Execution failure: %s'%str(e),ex=e)","('Execution failure: %s'%str(e),ex=e),None,sys.exc_info()[2]")
0 #! /usr/bin/env python
1 # encoding: utf-8
2 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
3
4 import os,sys,traceback,base64,signal
5 try:
6 import cPickle
7 except ImportError:
8 import pickle as cPickle
9 try:
10 import subprocess32 as subprocess
11 except ImportError:
12 import subprocess
13 try:
14 TimeoutExpired=subprocess.TimeoutExpired
15 except AttributeError:
16 class TimeoutExpired(Exception):
17 pass
18 def run():
19 txt=sys.stdin.readline().strip()
20 if not txt:
21 sys.exit(1)
22 [cmd,kwargs,cargs]=cPickle.loads(base64.b64decode(txt))
23 cargs=cargs or{}
24 if not'close_fds'in kwargs:
25 kwargs['close_fds']=False
26 ret=1
27 out,err,ex,trace=(None,None,None,None)
28 try:
29 proc=subprocess.Popen(cmd,**kwargs)
30 try:
31 out,err=proc.communicate(**cargs)
32 except TimeoutExpired:
33 if kwargs.get('start_new_session')and hasattr(os,'killpg'):
34 os.killpg(proc.pid,signal.SIGKILL)
35 else:
36 proc.kill()
37 out,err=proc.communicate()
38 exc=TimeoutExpired(proc.args,timeout=cargs['timeout'],output=out)
39 exc.stderr=err
40 raise exc
41 ret=proc.returncode
42 except Exception as e:
43 exc_type,exc_value,tb=sys.exc_info()
44 exc_lines=traceback.format_exception(exc_type,exc_value,tb)
45 trace=str(cmd)+'\n'+''.join(exc_lines)
46 ex=e.__class__.__name__
47 tmp=[ret,out,err,ex,trace]
48 obj=base64.b64encode(cPickle.dumps(tmp))
49 sys.stdout.write(obj.decode())
50 sys.stdout.write('\n')
51 sys.stdout.flush()
52 while 1:
53 try:
54 run()
55 except KeyboardInterrupt:
56 break