summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2016-04-16 21:58:13 +0100
committerCarl Hetherington <cth@carlh.net>2016-04-16 21:58:13 +0100
commit7e091d5e82f741f63c28f975ac62eb6469b12406 (patch)
tree85b798bc27ba1bba588bfda20a984891d1e41b37
parent33db6994787edf34d9aa8027827f18426a01000e (diff)
Unpack waf; try to fix up debian/copyright.
-rw-r--r--debian/copyright46
-rwxr-xr-xwaf4
-rw-r--r--waflib/Build.py759
-rw-r--r--waflib/ConfigSet.py153
-rw-r--r--waflib/Configure.py379
-rw-r--r--waflib/Context.py394
-rw-r--r--waflib/Errors.py37
-rw-r--r--waflib/Logs.py200
-rw-r--r--waflib/Node.py491
-rw-r--r--waflib/Options.py147
-rw-r--r--waflib/Runner.py207
-rw-r--r--waflib/Scripting.py407
-rw-r--r--waflib/Task.py692
-rw-r--r--waflib/TaskGen.py434
-rw-r--r--waflib/Tools/__init__.py4
-rw-r--r--waflib/Tools/ar.py13
-rw-r--r--waflib/Tools/asm.py24
-rw-r--r--waflib/Tools/bison.py28
-rw-r--r--waflib/Tools/c.py26
-rw-r--r--waflib/Tools/c_aliases.py63
-rw-r--r--waflib/Tools/c_config.py760
-rw-r--r--waflib/Tools/c_osx.py137
-rw-r--r--waflib/Tools/c_preproc.py611
-rw-r--r--waflib/Tools/c_tests.py152
-rw-r--r--waflib/Tools/ccroot.py447
-rw-r--r--waflib/Tools/clang.py20
-rw-r--r--waflib/Tools/clangxx.py20
-rw-r--r--waflib/Tools/compiler_c.py40
-rw-r--r--waflib/Tools/compiler_cxx.py40
-rw-r--r--waflib/Tools/compiler_d.py37
-rw-r--r--waflib/Tools/compiler_fc.py39
-rw-r--r--waflib/Tools/cs.py132
-rw-r--r--waflib/Tools/cxx.py26
-rw-r--r--waflib/Tools/d.py54
-rw-r--r--waflib/Tools/d_config.py52
-rw-r--r--waflib/Tools/d_scan.py133
-rw-r--r--waflib/Tools/dbus.py29
-rw-r--r--waflib/Tools/dmd.py51
-rw-r--r--waflib/Tools/errcheck.py163
-rw-r--r--waflib/Tools/fc.py115
-rw-r--r--waflib/Tools/fc_config.py286
-rw-r--r--waflib/Tools/fc_scan.py64
-rw-r--r--waflib/Tools/flex.py32
-rw-r--r--waflib/Tools/g95.py54
-rw-r--r--waflib/Tools/gas.py12
-rw-r--r--waflib/Tools/gcc.py102
-rw-r--r--waflib/Tools/gdc.py35
-rw-r--r--waflib/Tools/gfortran.py68
-rw-r--r--waflib/Tools/glib2.py234
-rw-r--r--waflib/Tools/gnu_dirs.py66
-rw-r--r--waflib/Tools/gxx.py102
-rw-r--r--waflib/Tools/icc.py22
-rw-r--r--waflib/Tools/icpc.py22
-rw-r--r--waflib/Tools/ifort.py433
-rw-r--r--waflib/Tools/intltool.py97
-rw-r--r--waflib/Tools/irixcc.py45
-rw-r--r--waflib/Tools/javaw.py305
-rw-r--r--waflib/Tools/kde4.py48
-rw-r--r--waflib/Tools/ldc2.py36
-rw-r--r--waflib/Tools/lua.py18
-rw-r--r--waflib/Tools/msvc.py809
-rw-r--r--waflib/Tools/nasm.py16
-rw-r--r--waflib/Tools/perl.py90
-rw-r--r--waflib/Tools/python.py399
-rw-r--r--waflib/Tools/qt4.py442
-rw-r--r--waflib/Tools/qt5.py489
-rw-r--r--waflib/Tools/ruby.py103
-rw-r--r--waflib/Tools/suncc.py46
-rw-r--r--waflib/Tools/suncxx.py46
-rw-r--r--waflib/Tools/tex.py317
-rw-r--r--waflib/Tools/vala.py211
-rw-r--r--waflib/Tools/waf_unit_test.py106
-rw-r--r--waflib/Tools/winres.py85
-rw-r--r--waflib/Tools/xlc.py43
-rw-r--r--waflib/Tools/xlcxx.py43
-rw-r--r--waflib/Utils.py468
-rw-r--r--waflib/__init__.py4
-rw-r--r--waflib/ansiterm.py238
-rw-r--r--waflib/extras/__init__.py4
-rw-r--r--waflib/extras/compat15.py301
-rw-r--r--waflib/fixpy2.py53
81 files changed, 13943 insertions, 17 deletions
diff --git a/debian/copyright b/debian/copyright
index 4ab8bab..4b769a7 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -1,20 +1,9 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: libcxml
-Source: <url://example.com>
+Source: <http://carlh.net/libcxml>
Files: *
-Copyright: <years> <put author's name and email here>
- <years> <likewise for another author>
-License: <special license>
- <Put the license of the package here indented by 1 space>
- <This follows the format of Description: lines in control file>
- .
- <Including paragraphs>
-
-# If you want to use GPL v2 or later for the /debian/* files use
-# the following clauses, or change it to suit. Delete these two lines
-Files: debian/*
-Copyright: 2016 Carl Hetherington <cth@carlh.net>
+Copyright: 2012-2016 Carl Hetherington <cth@carlh.net>
License: GPL-2+
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -36,3 +25,34 @@ License: GPL-2+
# different copyright/license attached and list them here.
# Please avoid picking licenses with terms that are more restrictive than the
# packaged work, as it may make Debian's contributions unacceptable upstream.
+
+Files: waf waflib/*
+Copyright: © 2005-2010 Thomas Nagy
+License: BSD-3-clause
+
+License: BSD-3-clause
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ .
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ .
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ .
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file
diff --git a/waf b/waf
index 4b322f1..57987ec 100755
--- a/waf
+++ b/waf
@@ -164,7 +164,3 @@ if __name__ == '__main__':
from waflib import Scripting
Scripting.waf_entry_point(cwd, VERSION, wafdir)
-#==>
-#BZh91AY&SYmEKQ#/#,Y #%H4#,`(br}#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,ӭul]Z}i{l4ﱮ_plkLϱdzvݺ{]xԴRq楯y\e hgEm.ǻuw׺]2]yk={[yw@=ggkWe}}}owNz#,#,#,#,y#,x->#,<*{WLaOl5nۧF#,m6 PPu(QB#5JJeGc@#,P6bAnׯZ>H'{p#/KvPZ6tj>ޏ{zl_7Z}ۡMZlζˮ83oM<k=bWGӪUrz5O{y뽇z#/o3PKhF;l5#5v꽍٦f{%ՎڻsgR˒}}ށ#/#//Z"i@[sǭ^s +ހ>Bq*KxG5_/=='}>9믽e6mvun{E{6u.#/N»^FM>O}ӈXL|RZu.9.;/nۯ7rj;<Fognjz|`uu-y=g#, J=#@S{0)RO5^^N>3ek|Pܧ;{U)+Kw^|#,=u #,=^|vާvqw{]8tz#Hۘ@^vlλzދg|6%WWݶx};e>&{o=}{ok:{}kL}>>ya۽v֊ﰣqM_^/:5x_-IڝynO@}o+LUS4Z:=ua+W{Sofw[{\7v_|\V:/nR+wц#/_wہ@mg#,#,:;5kGvsɮW"}t@x6wuNVvFH.SyUr^N/FϧOЦq^;N!yNēN{ovkwV]vzskNۮo6So#|w M @#,ɠ#/iOD=CjAxJhD@i2hj6SD4'#,#,#,4#,#,A!! Abh'Sh 6D='67#,#,#,#,#,'QI4j<iSf=OHz@#/#,#,3I#,#,#,#,$#, i0M#,"{IIO$z4#,#,#,#,j"#, Ѡ#5=SC<zꘀ #,+mbcֹu~S)#5=3&-5VWmV#' #o{Mg5ǜo9̦.n9s-J}B-~ZRkD&T%(xT)U\E<7^I̶XI&>rVL*iH ?#/7R Ye˩jҵZ*1m#,-BIX(Ȃ![*E#,|R‚  FVmkjL@ ı &D4c6QSR%%(ҊmELXXMSQTDJ 4M-J̠I,hM0F)6"JmIJZS"@ %#5`2)lQmT#/A&()%҉YFiUI6d̙4lUZff6mKM5-M2jadS$djFB*M&LZH-h!`3M1lb`4HA31#/I((lR@Kɡ#2f)2Ac%4TZ#/5*ECI4l(Q&ȥ1PlMe2&FR)6T2(EBH6"X5 "J*5D3b $Ԗ)1Hd3Fa-S J!*M M%`Ĕ,0l#M#FJ!e$ ),0ɥjih#/K264ed&bIZHXCeA̠ƣfSKS[M!3HDjL@IK-,QQD‚#/&$Ȉ4 #$4P!3-EaJ!&B6Qli&I% EȶF̆L&ʓL1*1 PDTSb(2bJE*I!e2,Jiɲf&ɣ&B`B5$)YIY6J@!%(E3A2H0M*6BeȔbLE#/&60FTi#/*%k,Qe"f&DJ,5JJ256h(0IS@Hb)cIlFe3K*Mjdcal#5(Fhemv4%J2SXEbQITD%KAQV"Ɩ!e) RF*&,k&Cc)Ebd5-*c$&,32Ye#k*ERX$)dԈɦVD5 [%YYJSL+f(i5KMD%ƱX3hH3`FѶѱQ3L5E!4jQHmbY05Rhe1%h5(ږm$5!bVA,#ei6F&l3)#5I6ԲZRɶmZ4fk32IKYRSJ( C5J4Qb- 3ѵ$JME2iIFL#/%0ŠE,AieHi)e6hbĄTZ, bcl3K1`2FLlBK!IlI&h42S2T4Rma3`#5TX1S6RBlE543 3hFhɩ"aK-$L؅3R2I҈Jԙ6lei+#dfMBT)Fj[,شIlbTQfJfdѩH$FY1Қ#@Y6Jhbb&I F5BTmm1I2 &h K#5e$*50ie24´mIkhЙfHA ,#/RJQliI&k2*HI"*ƆMEc&&VJQ%4ET*Je)F`$Qdd06KdԛjIEJj&CI3dRTXiH- h#53BFV&#JKEhƲEd6%`1#hTh1E& VZSTj-V1Y-f(#(1B$4lVmhҚHe#5&ѐ66hTZI5f͐Ī1h,UMIH()DF`ƒ-dԖIeM‘QIFkTeCI$Z66Z[$Il%E$ѭFhڡK&ZeJ2bFL`lMlTȨ1$I2$jMfV?5K& |RZdI-I/E򻴖^|ưTƪ?,S^‰bObM4d7%č3m5T;%v>zyg̳',uc/eLY]Z1, tu-'e)QjoQmnfN1jqq=c,’6r6=)`S5KJ|9WY[#nei-M(@ _Q eRFƶh&O9Q 6Y6?݀45ȤU5vZQX?haR^ԛ2*2dXaZ3#,#57AOS(C (`)<sX;ҵTؖQ GgbQ0XDl`q R(jah1'lx]]nHo7-E]:.Ess&ՐUR '!!la>UAҼurKe f>Dӧ&9%CE%OUm@QE{zY]J4}]0n(iJn@rpe˒nN銃}K[lU ,D(FR-"MTFzUiz``ΙO-Li6J@`@hԨOV<ՀژD{q`CU}]l]~>ٛVp򅧆o;J0)jeN8TLhj0CfB(t\÷%v3ISʉf0 09!Κچ{z XZ%l(Oa"O– :>0@fPeJ#5WɗRcݿZ6G"_7v$#}_zF: e.W7"^*P$csWLViУ?.]u61^9d5˖ƫ)84mw {_K幣U\XQd$a됻 (hdSC"ʌ&/_W xoW{J_7*#5yWMu4"1SJBVbcXjOW#k"ȆkP?V"0KElz'< "1Ҷd< !w뼮m9u#EsHsAuBzZŎPwQ&қPTD׾XIraivdF90 L"Kv6m-82Q`"#5(@%.}UbdtA30"+it!cE0ꆀ6v,MP$Xb T}uV HCZ*SHuqf?Nyaڻ:uf/ji80jN Ho/9`>/,)B)A:+v#W*|u &7DjBQN84K&d#5*mg|͟QNo (|(s_|V'rI3mc+-IEMT}[@0Ž$‰hJZX|*&dFڐmĎȎ0Ggk;e x ǜnoqO.w􇞘7p3=FP'HOhhq{2oҿѯ%B҄:?_ͺCGʊo.WwD+:y/"]O{{X*Rpkq*(V1)"Mݴf솘PcM1AīpҤV=A=Fn.=oeH!a$hN|dm]-єL@:<!io h-HAWs2pTj]𫳃-NH#5Ft>;֔?݌v3ܥD#PbӮZ:4@I*h=(<+4|#5B_x >4]GH |]#5b".x#/.Sθtaaؔ7lDݶ1m,8Hѓr.>y#/A; o͘HjEAhlWâ(v\v01:e9J0GIܕ[O6{0)JjU׍.agmAg@I#5Bމ`Ga-{_#/[%sO>ѻ5F31 8 971Fmz(-|4bdj~.QʤX=_oxpU5W,{#ֳ'Ti<P8):YmMbw@ @a=xեd}y+Mub#5n3M6~R-١\x@p8\6irt{PAFhSC1bR`^;4l)WZvEeCL;&#/Fҧt^yyxq.K3ᘝQI:d$Zg7B=0JBJq}>4iD%RRǒ"[Co&#5qE1{~Y>kZ;xZoLhVR9H`Mux7cOrJD2Ǎ: uvOreDe$:3w׈X *B,J⡜^0swÓXF;n^߇\T#5pLt"3t8ǧњMH(1BP0Ajfӻ}s[{C}>7M/e-oe#5#5ּ dSR{^{}i#,$ NjGG5IO?˖WgLg]E*; z/o/bwA^?%g%zn|ö.?#}$q<e#^a"XsF{\nj!;CFbJS4JQt:eUG+j:x+fK`-.+͓=h1#5̊SEQsʦBDzcFs?clXH:8wYBL]<CPb_BPzv/qc;+0Ks`!ԈYi+*n㻶Y<{`D)0@eYJ`{r1u b6׹ &F{2'Z28L$M }9 7%Lț C#ynr"wg{tȈi7mQp'C]o{+p>=^En Fcvf,#/,gg!#5~Pi::К:䲦QiW9kdUWkB#/IMvg(:0"p8H/F@:JgêUבe;tʙ3۹C~ۏzM,Tw6j)!kv|CP.QGB|r=*D2,Ѯw3J?JwHMS֥XTj,)<'i~Gu>w9w5Lf8$ZLf4.ҜLVsR`Y ALjg)œBj~oJ4}vZZU):g{u8Px󘳜le:o]<{ǽY/?35_1)4:m˿Cu (b1#/4c-;2ǣ1T]cFzfY#5FmUSZ6I+dU^S#/4O D=[q1UOֱZ~3"Yc|4oZ0]yQQF#/6#/AAz`eTT,UQPzkLCh%jVMP-R.dNdMd<qY@DfjJ%#5(TuJVTǞvrPJZmƪ/cAKv+NiPI/:t[c%9&SofEv{Y!c߸c30YwK8reLw>J;i]\Q?8Uؖ#/ yJRN5Z+H5Z:||jnṽhq֎٘atI#&Zċ# Cm).#/6Git/iP-~Z0:~J+JmM}/sڻ^i@%CAThݰ|Ƌ[4wpUϧ#稺f\bLcBV8q^ &[>ܵk6l<9^K#/Sm/;)tVE,iw-#54&7ߺutdwi#/>Z~ә]wD|}>#uɝMgYYRTYqfб*qojf+?gmK&LC}W$3ӫ4e)ޫbՓ|Ʃڲ>u?#/$i[S߹ԉ̓|Ӡ#/Sw?{F._Y$Fl;timvCO+)~:*xd!4W'߶Q1o؄IfOz6k.&܂ws$D9812ͻs#On6؛*3ל[LhW"#1|#,TMEMqovs6]/q\<$AC}%LSM$V9l{zk;O~)tW\kרUoL|^ӑssٍeݛanʑ j@zA63W{xa$++o}Z@e]ҡ3T?مSU5an~bPI /;#5 ުR9K8ǣ9ѽ(Kh-Gs(k8Aqj wǔUsǓόUy_'~+~Xg]I#/LxBw3>gGBBq]!w]Ϝ]vgNM4aB9s5xsG YY$z@3^Gt+%y ݽ,|RT$ICY;gX$MC٢vgdK9oIV]JvsȵPRѮa3Q٬C >B0TUBEe([(hG\IIުKD+QYf_m#/t};x#Zַ>c8K|MPP和Dd!,IK惐eNMbd];>U!yzwgЪP[@?@L$NLjUPX[7ev4PiϛiyЏI'iq vy#/z8Zj wz{&|IZXDF ޏyT,c@#,`>nfkX~8~%ec< Ui۠Go _;#/[Daw "ŋ>gΤٵ]'nefqU őz='U.a6|vOsӤQɚo$!U,U}Z#W`u80HE[^ۏ`//]#/tP^(wQnV%tb(mݽpL'o 5's/@ VM^%-baݗb~c -tP#51UO,P&w̯m?buY뵮9T?M,xg ڡF΃ӮݷXGU^eku'TIAHk+~F!Ivs^Qs@M=#/fQL"SL+ܡKSiԣsOǃ:NVʹSsAPT%B'? u'.B驱Ph`1վ@vh7)wy*ޑI$5!e̍r&mCC(W&HLRiBY{Nl͡3)G54n@;7覧͑)uVfe5IDj߄!@hG4hf6DX9FF)ĻnZCDKmIyնa4A?g X< Z3޴Ic#/Hc?XXv[٠*뉣QְƟ{wN4FLdIAۃ3[BwE f찲8pVC #5L5i8.^Tiݬ40\s\ll=lpvM#/>W{l3㢏̶WTxTs+•S{EP~n^&¶P.XZ9IѮ=SF9g!8yW4`yt17,/+i'}nߔl#:>s򚧘l;B`idVF8qtyG65#/+oE{fw pp(&dqӍ|fI˿1 Ucv餑&`q|kL 5XQpj23(!;A|Y#5mJ:!ӷkMV1Ǔ&a/'kòԉ*NuDL3J?g<@dCD#5j3xXTin:2.\ iQccyH,la%Bt0?q.C`B=u"1v b*pe6o!!&[3F a6?>6L\Auͷ.ӪR|n [#5 h;2JASģ6.fJfZ%+|bcNG.g]w$93?5J7*Wkjr {o;XZwwٷ n3@\Hfŏ]Zdj!v5n>Os5_FjE[7sn(D㿁㩁۲f}o(}˥/o3M#/*\Sc"]teL(Dv5yCeKyl!8UdI 06`BB[Ce؁x\NX?~ZWxV8gE/ptv61+- Ku!+5D7KaA٦qd=3`QSObYuvL 7` _3ldZ+C|9ϻ{}2%\zmoM[ j=4q0HYa8B󺻼4;,iJH,XLֿo?Gߜ=r8Le%0(5aHRP+>{jEDEAa zV %YbT}~Z 9; < 9F*PO~+fcW%0HXf0fd<wTuH6\E0i]*ꂝD\Ll`M6WŶu=&0t"|"nLMov=E'8HSϷ!#N^ Zi[<.6P*#57ePS7bPG戎R֟2T4`@8jLLFK"f 噛#5`g-TbB®]Mt:ˮ^6-Jh?1%0")" GJ.ϯwySICQ(`a k5U4[5-Qaɋ#/XEV\ !<rn⯄VVɭQ魰BhDF{IpkN:W9HUغU.Ho>]V"/z(~r#5+jO AK]c٫jv={[vdIj=qFRUxoͥpUswU+nn:.zӖe~<P11gM7*_'0J7(#5H0Q車W2rՓuܹh) OntI [_ٿ]A8VTP[ԓNq|tK[yVW6NᡗM<u, L:FUhއ1;<u\alh#/WgĒ$AGKd@;PH@v6MMpd6H*U\ ,gj cH1?ݦcCt m\(y\T0Bf q?I|ZjOB(=+8I'S\TW VRg(THtLJ3-F4ib*QnJհi2؟jzQ]j=>HƑ @ dJ/5뱱^j-/Fd" REH4I#/ I.aϳ=u:jc5VRk/Iv޼scˁ#sDOGMF)Hcp"MUoWuuG#){Sd>?rdr6&foٲj[!J!bSB%Mk6{fp#/2ѲgZwʏ/80n\9P$=Xu,[&i /RdOʪ)(d.Z(QET(0QϵL:+wڌgw9!JiKۥsfN~\n6$<>).X! &}b 2 zl vLTd$yD}^gNьRuƖ8Tݮq/}/)$^sfl*rʴ̋U,^;\Mt0se#5k,6EUPq'=q#^D>lF)NBxSqF* Y$/#/2& ܲda=ݭ,\&f*Zj!;19TuCBs U.$ڌr\H͹-inDSU<*.;`X&cf֡ ndLNk8HQr>zehS30gc`L#~m!##ǁ/FTo]ltQ~Pbi걭 #/QmaՁ-;ݾҌ[C%߁Ij<yuB?j`?hW,h֎2>r#o"'R PxW+ۓi"#]1BF]ȌĽ4=9xOsz_;DU}></12nG&iLCkbԃu߫/5֓*:rٕ_^+]Z!>*6mc>N+~>ų3f_:ʹؽgDK;#5 EQx4{hyOfEʼnb|_'AC9<9ztFBӖP!׭Lk;w鷕#5iYŽ5VGW3a14 QcziIP%4Qhը%BF*hҪB-IWNX0; ]sW{ws"[A!!Bb3vL%LHfʖ%If&ңkvlQY\vq0Ι &1 =Ű^[-?MnzMve4.Z)M!t}^Mzߣϻ1DF"wh#52ObS&H'{_LxAN+Q dD>{]Lv0Q0$3~rBEXڌxgbdHudY#5gEkK^]JIm\%%Q.?SV%l"eHh#5[*]11CHOџ0xjg/$(o%_#5U0}q_^?3: [46?SL[13N?$y%1@zq m"z_ ׸n"=xM *3 IU+N_F,#I@*".N#5èPCdQ.q.CBk݅gbkdE=l|DU)I0 J#·MjjfuW/$㇮C?>Tb-߻񧮿ڸsǞ>8[%hy*M"MyJNm>ֿ*Ei|Xgav1t=H:oR<5{-G"j Q&j(*#,Jo|ezmf~?þ)頬M''V7q,RveSw28/Vd$/@T\cL3cv-EأL>4#,%3#5O=Q[MW9et=c_[*[شE͜ϥzd aB#5L445>KW*Yz=RL?ܲ\*wy~|ά܏N& ^ ?.T8#/Z5{ąco0Ns :9t "uO|U&;l}I~ޚG-Dǯ, ooc|HxGDy!&B1d8W_?uٓf!*O@|+N/?ugYny^9̜S:gwiDIM~4 LFڟ{!V4 A2IbBpVl#Y.tcHLJ~ z0:* #5|KTR#, TDDEW LoϗMea%'_\Zn2Sh2P, A1 Ҍ]oFi31-t1zԿͳff{{>th|tܻXgKzuGqs#/xT{s 3Gƚ/P?^tiʼrgQuBU~TrO~Cȷx8OM wkrWD_)u^xͧwD͟<ӻzs˟=m5;z4\5^-m7~}7VGifƜףɻ#/+%B{bq9N+Ž:ނ,9?fg=|Ż#/JGFju~~=vl?0zJOtVyl4S\,ZIp=%>^.S]ZUU:k;9]1Ǝ|vnjgmJyݗIͮ\2+ׯ#5U<8<pm~:~E|ٷԴJC?wŲyvC2ݳD'r.gmQ+ao.]e=WUZeB+Z#5kvPܩQSu&73 >Ig朗ѽSIR$Mx~O6{!׿?y- +d_v:'=ʢAPe ʝ^luo>änJbۣ̚ڏ՟g՛B\z*zƿW51/U[dXhݹgW=9µYg^Y}O]/n{kv+Mrd܄ZK\68j˝qpGtKװ3fٶaȗ|~lmٺOywXo?[|MB-^]>&>D(hwsZIP؝FFU!d9SqCH"L$⟐_ *l>@EZ25fGi ߻_~z<E艻{*Ňak"fmziuW7wޘxwxWy>#9spXo뭼;ϏofolWECT|_~˳s+\~_x~;t~Ia<B(1{ 5{߻=Wn0<|cMhi{aPA43+ϱЃ5cIncɇ|]>&^<OR庯j1/E?|-*]gs+*I ;>7ͫ/=f8|EW.vծ|'ӏi̝S|Rzۻlرu+ZtPgJP9[V1qB T/;WR؞/ݩtT벙^ǮeJKNWfTSsv'k)s Q)cy#EI'!i!Z9/?#/^k#5 >_;*kM;:'Sf<)>8r߄1dsh!r˦~rl}5սwTb<PȏvDNԽv~Uޱ޷!ZPZ\ZgW DKBQx 3dYfHgYpha-f*rϯəlӛ[;haubq&%ɄzV1 V}2+ IW k-{f'o}=uۏ9c{bgצ^cfmv8BP+P[iM>(c9HJYW=K`Բy5|Vr]:vwG/#t5/#/p<l{I_/dnF y!4"6}F8#/ÛՍc4G26tsyJ\Q`d`>p#IȃU^^J.Ew˻/$Wa\qZ̹%`Ϟ*;GA֏utaV$CcE(8#5*"jDF 6Ξ[k[ `Ҏ LXVaHhYSIU X0#@Ӷk,06Y8h $mE=MX޳!uX~1&~Zj]'hkQXغ913S%R(ȝ t{t/9h#08$øJ:QFk1}KIPc 0i`QV M@4 D A<wofIxS-gol,)~tgҷ1Q/4Wh?9YlZ%C̷a_#/z~ӮDՋu~-2]%<{nw;mx'=i1i5B}#5>fŮ>_^ZiBB D8%kw?Afowqע}Y?iI)B1x^@?O%>?㪥4N=/gu~>w祑kݸ5z(}spG|?~Ao{8VHm0acb!h22!In0KJإ%IH@H2)#,iuF$ZLڛ&ɮ^ĎS)jr7h(UX`ȣH*V&efeX6<+-iNF<+ړ{̈́f#/IEANivyN=QR29DInB pcK J )"%桶2)@lƃ2#/e&:E'(<)LRۊX-7օ̤J#5%F#50 (lR>7MiƗs6B⢷f /ZUV jPX`- ed?@Q<NabfԕVZ*qPQh\5CB!J|}Xom#kj:e^=<{ +wNnO76̾s뉧mi#/7.\ @QSCvStiç޿&y5m76oԷt]QxvWsغ|2򽓢L5jg]yd޽8P՟kLUۣWPUⓖN(t8XQB*<7!Tn>'Ѹ.j.DGqrhs#/1>=j0}'tP0sM8#/$Ҿ0,.e/~hs7Q8m5_:{dltTmg"vSRi vIn7]#/CThb0IDZ^1fe!i?#8^[50!5;<(.#v;)|o2{\nXƖTM ڭEU6?SQױfhTU[wBۤ/BBW&/^a6yMRFjnH$ohq#/<ڔ%赵&r;_56UȇV1'}}CnL頀 Dڤldq!b?ӗM608;"·L!O7ztwO_DɋcꀠTH(Qk(VML ]Ƃ^1a[Tu] r2Ifq|(x8V3]*0be#5MxX0g⭖g1@aٲ=h;_FC4Fݣ*%i'eCK9ntlV Ƒ:iC9*i3b4PK5j&JQ@z+F ,#Q6<RGs!iaEpVvxU`.x.8҆Uуz8%iت,T2Dd$~2)( xZtm\% 0ʕgXP8EuկTg9n$6ʆF4|59?IM0qd"H =g:q[kyӖviFvvv Am4"aQ#/8<]aN>k`bJ.^ )ivr6Qk0wc+z;EAhk Z4!<Xt ywžS`:RcXp BF Hns]pjŕVBq>5M)4ܦ &?}ʪ;CS^_kw3^cr*>V)mItҁHlu~&|f7TΘ77lӀDc#5DxS &21 1l'bF֓qB2,Ter9qUTМjdą9SL̅A Za|C;Ү-jތe]J1@l*Cr[9P@ tДC0]#áfӳAqCI*V&sb-^,\y`tZiAȤ GbvHƈ鐔ORkYkӿwTGgǫ{1J6O)Wj63srZ0ɩ4NX#I(9NlGqVdcLprvaGQ#5&Ӌ0ԄL#f#/j̐ ;d3,X nbIQp.6Aal#f*U2es]כW]9wP$$`ݚbVMw+^" 7+]](҆R mdGդtD(4x8)#5 Ȓ45lˌH#/ao|!BiNb!8#/oDJ[ˀ%U;3a/8k fA#/;~doa]78:ɰ`BLvP|lkx ГZͩu4f}]6ɲ,&M+wn#/ 8,F r7QJ--vmktQ6v5#5',jv+z΃+GcvsҴXqW/!X:X1qfn\Hk ƻ\ٜLOpsn\..LҪZ%'frfODHa;#/bL^v\#/<LE#5x^'>7->6WoS-~oFqR2>De^F/K }`sD!!&|=mw%O~k esQ?"0J+Uny\(qUF̳Sls]$:dsu%̧_#5sL3ϋ{7f|2SD錙49i[>&02@rCwf˙YmsDz;A:vY1b]2CDv!Roqb|)ipg'ZlGL#/{Oqg=oX[å@cCY2Kdu}<k4W$|U7[0}D4JH﵁N܊$(k~=3@Rp9o#L3v.\cGę, ZҨf٢#mR[u9ȔNLM3ٛ+Bc!?2$?M6R;bx+\@[c.eb<tp<gAΪxUS#<m1:Ca|UR(8R:!},D}ß}{iFjo7Fԭ.򼛡!ԍ&+sg1ώu ~NNgA(9ѥww(Uw杘z}q:cͪD(Wa^CM=t# Hx#SAr &c KeghMPyL.u։$#6!}:(4Y*yoՁn8k 7|IMM@<{UPΫg#/*ɝ' թHD&)evE؆~u_aueTsy͵g4-٘"V90GCڟ1ssyڻ}-r&d)kUA>ވk;95[\A|+/wb$-2 ex2f*)ї-q2\3bBb`Eof/\d#/$] PqA;H;3i3ϵ@)DۜsLTHJ&=S^;y3ԞK#/a#J('Zen Zoܲ[^o(5do]h=OhG&{#5dZgHz뺁CZ$VfS%{i n˧(0G˫)'|Yxhv!Ƽ1׌sF[Huh劥xZ_)DijL< yc̯EOON4Z&NFCe5$?S?D3ʎN6v.:!H<]27|j$Ӂ0T$=̓,agG>Dމ@'.'_%暷 Ugn=-Mro^bZkI&t:p2-{n}n10cb(_Fձ+V-[}ʲP̍ <P#/^JT/75"L*+xBJBeӵZ  7<z}~3a~vG Nvv`AySܖN9D`u՚{vX4m܋a$y!f Pc[}deyҸ\'|stL9(!WZgOHqn.?ooio4FCNȍsyMJ{Y\~B$xOrʯgMG䵁"o#u['[xpaǗJ/wC#/foM>Gv3^1'b/Mфnev;J)lʗqµwv]έjf;ÿQ_'.=Ӌ+~ݑjaߋgXXl#5ya(\Cvw3qf2N"^JH!և˂S'* {\q#/3ӆ_gP]<_篵Y:p"&-P&5*ZLʙᐙET4 ˩:GX_sB;2וZ~gqwFGF"[1jjuI&VڛzClg* ] ]jPP-~#/Sa[f<ҋr9bvzg\|Q h!^Mmc۸.Hn%V3ONc3i{=լ{|6RZoc.i.(aU%E;·aQ&-FL4aW*$MV !ɏI9GתbDd:ޤ-WjjW^6U;KWUvQ.*J#,ܑ$s\8' {ǧ̿=s./8<W=Z8l`;1)qZzΨ{Q‘N'{#,߮Fěnh;m1M#ˎq(VU qC%I<͙4sH51$1Ȑ'lLq-wqVa4&n2/Go\\t%*2L$m,<#5S2[s} AR&9rD,(K賨!LFFvP!fyni&aF,=x)Re޹=5"^#?#eO-eQ~,x-L lgWHח̣}܈Inh{aЌؚTyV驵0avD^f~MQNAWG~ݎQ3])#/l\|H.f|`khd7}ggXVX%AEV } /AFsY~aG6q;J*89Bʏ7oz<}*ɴQmqI88ZTD[CNVFܳk%E^V4[w \3:jRk)rP௼m9e7ƫKpWW>]4v2YsuJ*rO$pzoƼv'fʔ#HUi_}HDƚc1I=RYSeY8=XlY$]|txJeĴN <ck\y!<2זTNzw^PRiK?79{kYX~m'mY™o "쮅e5,[Pyo,/ m4H"$!L&tWsWf55fHl*;ڮLOt3dcu r#5a I<%(GU.xԒqf=boG*0'e{,bDD) B=QeG9l5aիs*+󧤝̉{öJEidʣo c[ >6h_Tvt޿/>J1"U5(n2*KCz׍_[bQA]#fqiׇUyNOS瞝q 7u'#5y$ rd53v{-q14Ltpo6Yu"2WΪ9VBc[#5U;elaW[Sk\Vd.an5ĝ$5jwǺ&6Kxkk7qӶd"`|HE3=k}ZǾ3NX^X\$ΞHi%F裣|<D U1{u?o!7t+Կhkq3Wbb-xD:hvU:s?jZQG=y{8o~$F'7 4 WǞkni95#5C59mh3?lMAص`[U5<Ü[Un>3bg\#uNI{w>Y7Nnu6L55ʅvY nGF9Ն).<9ZYyByjrOpe{#鰞b\A<`STO<A׳cnF<n|ć"R# k !6}sH#54џkUo9\A~(fvf%|yS`"7l6R"$d\42SJk*#]󾄈JH>JYL.gBVAeUbU2<e爯CTsH<cD֞%{t=6N.lqN8eyV,݌i]X=Iݱw <;BH|&cs'SDfٜ9 O|5V(nT碷w#5_!{kp$]1r!  0rK)}4BP1'uI[S:Fο3r[aCW#ʿ2{d=\<ZRti H\9+_OW7̖HI&K]zƼ3ZR}.HwGW:V!8q/|zOOj"c)s_~)FeuoD Vu#eLT2Kȇz$yoSd43!]G.pv35|}w;jgO,n}_}[i2yfI>no]`D{TwjuD4<梺c.甴}O>kJb~n9FI럿O#YB*4/92W^my$L{7D.ɢ98}Ǘ#:HJka#//w]3mWQUpͦdE^sz0E-+aMk!J7YO+O++^A & S؞Q#/ԝ2G#5BAhwl*Nn-z!>+5S]S5Ot#5Tt><qbO#H}nmvxi黖h\=wub`-4OuSnI|5URN(CuS4JQs|!Z>ϺSPׅz>74"x0ݍ zЍXn9~]Vro.iG\\\$yȼAw2 T܋ NW4fFٿWJﺙafZF z$?CYײew$ |<._a¹XGFdx!+x#5B:&adΓ Rª hR#5DMhDc7,O=P1e0|eɇUlޞ"^UPԛzn=c&˗M%;>^X4}sIڹG{"Bo.ZcJš&Bd[ }ά!#5%PVoWA-\c#,1D^뢊nyz_Nn/vtw~rk$cyco`]]~.Ŗ2Ooģ529#/K%yܟZ<ⒾeB;sni[%uՑuDz D]S1 +Fa  #1騃4u2#/w@kS.sϞwWCtp/Yk͗xGb;;.;EǴwΡ;a'/[ʩ ܷBvǑ(c|7㟨]b։CdYTc<7WӋUw=Z0knDqqZ7PlRjsTտI,e 51fnM<YdIu[\gWnV$Q>եTbL/b0׈֟O]MznKҿӪܼ yWAF.#5{/~ mqoG:7R<:ߣ2cAu^N!Cڊ\Ā C E|HY9(Kʿ%#/'F/;̝j><n ?~2NIq 6WfnM #J,>`_dG2/^3=͎ڮtìl5JP?HK3O2Y<T Lc1. Ѥ#/kU򄞗A ȒG֚d̷Ś3 j-17ĊѝhK•BqyƍOG|`xO Qb(D\d, XWli2뉷OؕrqIzWֻ,DVŶzo]9ZbNoqQlё;}UCܝ-:cTsVCmdGl*:IyH~|,=?n,OGvȖ vH=1x3!>*ݻLl72R o(Lb5~CNw{E.H^:;tBz<&TcK#/vGPfef|zm$爄r{pr>ISyYCd5)cы<xd֛q[)Rԁ'1?2rTgl8Ǥm0ϖ<f&&q̯6e347m+ӍrR }P.dž?g@^,嫶c:M:#,pin-camvҙˎ!hJ3m׆o~oA1 [Fy]}g1S;IvQƆ#/~5لTDJv_,pc~Nt"ww__n4N-uF:W|~gbkK#C tJpx})) A.碐Ȅt3QPu,~;[Mc5)h,onI|\!#h,ǨV47F<Q9Ns_)ls+[-ּ3li26J:nW)C>{R\٭3Dɾd7F?H\Z H\ u?5Ud!z!ҘIhN#/$ۘtaql1Vd>C0JDm"+&-X(f#%!D 1&H+PiQc7`; sJmb U֭U"@1,>*qp۹'jWZR4?XlFHN/FT ylW#/2_Db0=KE*<YTVqHTA|eeF\PO7(Y~^ꚽF|[Mh(P7fzf{!PL1ʔ9C59CSU|.fw1'gs+M-=Zqjm}~DkR$I JP|Bm&2Q@Β;dR'~UtbDIsvC٥JEP hQc6AQO꫞6з='dXY}<a!E'FlZEf|'H4_;!KSNbbAM뮇hAZ -ΰ#,Z[(fPGŸ"#/Tm6H;HuǮ#5Զqi ED͕)2$C7$I@MR : vX#5֏iG!ioŶ,O(O6QFlN:H7>on~3}S*Br{o=tͶa#/J*#4W0SFq߇J6HGmօǕ=#ŀV{y`w_(tbGrX|Ulo,;gxaD,#5Jύ>GwG#$Ѓ-#,x1w@P[wpIM=SRMݡA~q18D7CVKmռN̓a*RhlWfQF=ڦ9.w:3t)IgR FݍpцVLMva5# ?3TւqBR7t)mG(eA0 ygDߔ_Y*k~+Q_*KNNJ=L 4qRhKnf=`{NV5tr~]O#@<x_"[k5rW&3/h0gJB(ċ! d#5ō2Hv;٬kh/۱-ۘwl_iQid_=_~daD5BL ) biSjW~F(?{0ُN]x@uvmamBLw<$1CH\|q({4>tFCP 4 &"Ӣ{tHwaP7v[J/y]TM8L -1>hfkbRMdRsӚmex:#/^,󄑢A{%dyЪ] WY0kNRF9WdoaK|X" 2CɔPQM ~㙴a#5bI#5Wcj9e[ncVtSr72A!t~T%IiLY-ٳttiq\;oNN/+#/zTR8 )#/#/_#/#/z1/ggsԃ( l%supIY GA6x=W#" ;MN]ߑ;|K4!/@CCWW|3bі뭈71|16c.<5o OCIf;#)a,~~X3qvXgj3+՜;s1sOu'GNBˬG?šQ,]XLI,uH|i8J(M<K#5Ԍwr^)?HBloOGIq`LU9hE,Z;蚐P@Ϫ&x݂&Vfd76=ZEkh/«20hE--Q#,ߦX`˟_Zmo/&ۥT-D)@:dr̐xz4nj1aptƿ͚*.L昌'[ *Ijbj-<(5G|zl)QuTSǜx>}wA/Wl#/s3GJ+M %L\h婍LU2klg&jiXLPiVq!o8s +#/ZלLVN<EHY(A\.{jَWNvinJӌ)6t5vjvBg$ #/#/` 3vUo#5fvT9a fÍ,}k֩e&rnxR0!h,f]>|fñ}/7MA)(c5iEIc#5m99ʉxm4l4jA8MA#5hӷҷp&V &E&u<"Jl =>M|4"RszH?WXR.O.Z MP0Ja"6._o/<1*I aʪTz36;MX}c! D&a<d; nvnk5sǐI7{Yr۠T!O! d3IgadEMzs#/!U\$v-xaohs36zoH:i)7O%!yQq&P"s[rm[-Ɏ܇[a-,[ʨ9“s"xYj`75#$6#/BN\:dTEJD̔+^V?EVF&"D]9E}a=֡6 =`˱"A '*Ο/4)x^1>kV~tӬ 0|e\gn$#5q:3c|I&D?frd9 BMtܿu-}8A^ZO `xCQV-@F); Hb{cو_c9E#,ZI @EL0*"ï.%%R zG1iEJID*Ζͭ3<6f",`R`Su&gX@'q(&52I|]c/c3|!ٹ<"fD]q?l6%[#/^!j 9qL=M(apRjMTZXxe1cHI~({^z-#5?GJ(9ވ?rgCi>.s`?Q;#λcrwyo iV,;mGJl)],x3A##/%i!aHlu#58 sV;8P7(hWPa)/zU#/;he#5O3š 5!#FoտeC[:12 p:D>F͇(wQga(0š{z+BC0QEjun#/,YѠ$d^O39:iHPYET, q<35wmG&#/3pV` I$#5**P!*Y_AD}#/B<XԔ "B(T{#/y#/Pyg0[F p8mymp΢H]! ?9r':"MP:1H70Nl`;(Άq̣PKD}|U&>ul*4T۬%qk^80 <'OH<,u#)<O}FpW|ydLddND83#!4EgE8T#5%WWM7UBD N<dPF-KfP"G꯷/+H5ItD/TmGNGt׼uJn1-Ȫ%ɕ37yzI ,jzS&|YNjO!R(όs1>+#ԁH <XILD(7%#,^EJXÎwL/a%7 hibm0:WVF#,~y#eoy]aס0聦vN^\тʎ"oa mVsm|ELb$@Z﷬*`yzQv HUnUMy(t@0UeN!鯅8Ɉ!Jt&X$4Iǻ~6gպc{lpSo -Sv)  Pӟ!ܪh4718CAĹ`%ẨTza8R`(#50!L`iNW p4:R%-#,0ў1LնqVˈL0 oLk0WX>\^*pEN>>#L(1#(.UԸO{ɹ5DV% R] (׬^YO sУS7ś`CwȢ*ᩈwńNqV4Ϗ=9P a=JJC#,AH=a ȼHН}=QՂ)tEkag=L+ M)DN$[$!!&A #xK",Mσ3rr4&z8J VɛXX#[`Z;#5dtSO+ks<pc}k.4>!u~HWZu' e*:*#5Cr 2'oh(:ϲ`Lw@,7kW*/-SKUBZ#5SB6$W(M%C8/:좐fgR<#/1ThzʮelUdߜBDH$ mTK=hA0i*zM[ufr7 63PA9 N-X󹌊t;TP1m2RH(XxM(!2J97>SXc$T#r8"pyK}hG4!'))dt-vE؅[rCq[aҸ2.ˁ8#/(6 mJUKfQL:kȳ>~N\&Ϳ2BV~c7n#/ɌyC4 FDA'iT68|#52"),(5#)Pp 9QHmt,\tvvG.K} vCEΎ1d4>?P=M!5HS|z~x!ˣ47F'q0t,#[A1,Xwl#5{؋KK9lwܷ#,!I'D:u!zs,ykl;@#5LqZE ̬#/u;)Cnuf5W~"&9)#A-3aF@J2}yB;Zv`Yԃmţֺ,%)1D5$:0lTLؚ57q=%$7#,zۘ4zmSS߆t;J,uBuR!"TIȃ5~#y5$!t$cClzEu]u&fr^j`KJ E#,6z~ M: A2ANvl1vkB>܀سp?tL“712>9X+s:ŀx~ϘdcD>Xv~Beo{lP3\yEzC~UdM"aiK(S&Rif챇mOt<#5VZ:\XJ%o|~&b A+: @#50Y3zta/da1A_?!!a/ t]a&ex@=IXtQBׂeuүʥ>bmEoOwYm<p잵~_?~Jruڈ(+`\,HZ-GU#5F(Kkc3,`U&vcsA.򰿖uTWnD;!%Bm<w٦璣P>uw'.pQ̆!3ss#u1ygW[#saI $(HB?%6 LOya1ZDoHj/a|bB/P2w3ur æ;qHqKD[8VޱY~G#52y_~eu]fWx /}?30_}R6-bjy;#/`o~Vև(uDY_s j&8c_yfeG4ʊ$zj1rVaDk<q=j)EER4v21뻐H22fN"Wlh]uo9q!(OeTQ3äؘ܆h-6S1/\&-E3;zmKȱd19>ZWG-g2mjg}ag+%޳6aw1rNNs5311P`Kty!woő`N1/(Kk*>$>@~1[+9RqX̰r#,&sCR"&H<Lj㷯{(ػ.qAc?.hD d(|m7#/@OmLoO`^.޲]p0ttWG)xty(kawu+u-j߮(<uXfOs2G#/(Ǖn/R|F;-R!4 f<yp[5 kZ5zpGye>:l ^uyɢ`Y-Amz5yT禇˫ѥ"ߗ '9i#5|f"Ώ޸] <H~_?-uhΔ4$.+?7f<drbk znLFA[k$;4a2EӴp+D=#, E\/Vf}|Kz%ݯ;䮆2dIXfZvU醫\zgSKYT$У$nkXO-qW!hqފ,#,$Ϩ>1z1[ĺ|ZӒ"kmYlk=x|DYe-bBfGC\".}yfn޽5Ϝvc1#, Eb"P>!#޳9NgLOp޶f` 'e3h 愀)9⬣u49s"➺_Mُ75L."H{upUg:z8]<Tx/$;seOժ-&Û`ЛGf`M߰ݨG44뷎3Gԅ؃}3n3GNBˎRL7*tҘ&~F#5ol=%g4aV5뙍uhLخC2j{ Y a:R;U#s[+Pr $CԢ>}ߚ2۝!@3<Nf?iA^# <^ťhm-43#,ս#/N,W?]߈!V  =PI E/l0iQw""JBPKEy>'#5|#/y;bs*/ΠCxo.^Nʔ:2t7OĆ!8Kےri(<AaNbSʏw5/Ow<0z*/1INyw4O^]/ /Lz MPF$sHDO\OQv/u\̉z}N'z&]G:q~|83M0-^\{uz+s>ۈMgUb6vLtOt*ddtjC~yRX~Lw$j«JϜf.(|v5|cw1Y%;;v{]S0{#5O~aSFҺ}#5 SSa:; b4͑M0v8Lu_z<QCY-_e"ϯ# *6yIGTWU/dzI#;~?NXg֩23k1ݏWÿ.QlU}ૢu#6oZ|ey|?u#/y̞0y e}?6Kk6^$dӬ}lAd0)eӚ*bf\=~]H3GY'{l;8,JŞc.`gG3q[Ci30ԊF^;l˚kFwX56ZY}.suV̐s9wWi&yZ_yc'-0̽%uϝAt?whll?CUl s#ʷdR.)N}rGio6#)CW_gߍ. ,O/D(-_ZA*9Z܊pQe$n9w;-k1#/ҷ1S2}j07?mKIlKpėmۿJ炩F%3)m5S0Wk(N>vZ9J =T*;Rk ᖦR^4p#5~zHڞ$Op|-a{#aPt΢j+V3ZmY·EېHD۴BdBi]k%K~fQx & ۴P18G $jŋ%{jYBD^i/80(OD,|-$ʽ.kstӑM@/( 4(@vχ$葠9#ƍ_#5tM4aG.q"I";Z~˰#5]5/CKKSdixj!q mAV-#b09P<Q(4#:!F =9-&8 J+B:1F+; Ca1dHFPR}#/S<#/V;0ǫ9DAgCe57"Pqɽj(%<JP˙,b7xfvԳlgE8q&5xAwE''qݜᭅ<Aѧ[(<Ēy03 W )8&/+Kt"Jq!5g|ܺY%,#,6) )`@0i#56x"\uX@L/)X3 WgBPc?54)rJ'A[1xW@.##TJg-]VyfZgwh<? ׆1y|[ɑ N}_xl[RQݹ3}H\XwKQ QW΀BL^T!eQt- _r,K' Q =(/~ҕdBM;2cȡ#5}gH$^Ǘ`#H3^_djEVUYg|HHCf Ca=9rl^?Ǹ"n.jtji C702fO:15Ojf#56eCS(pr1"9sOۀhAuuT>UphnkYB.'Aly! wmA/ҳ4޿Yw611>o7?\/M<#5g"ѠMSfZtY>"Y:u7R#9D/;+:L20;.RU]>McNnI#/O峿,M61}^'[X* J|wsiH޴V<>O+7NEȄ*jI@JH8;׬su 0b.TStǪJ+3Ndl%fg kDI!{H_wۆ϶>e(nv"<B.&twtCYLs$hede^VZku$$Gpq3 ݀Hb0PڋV#,;O=z&Ze27&q!Y}.+W/b\ n&݈vWdH%=2!-56lCO@&=Js#,y]a>Vm@{y OAׄy \ޏv,TN-e{ed:*gsC;'J~lHg ͮEW7u+luSfMYL`fe#/k8 uq凛9,x$YGCMp@pkI_luPaw=Hw>ɩ;qx,CʍXL!T2jve.l: esj52"X~O{{ay}ۣѷnVKJ3lʺ5NҖ1,i{lӅڳ ucNi0tl_6Κ#{Ag<{]^sS)Zijތ@]ۻ}ٿ<0U&7ߵ7Ȅu0$/ *gsᚾ}+ 97uE4J ﭱeO"&ܵ*NaĚcU:bxx*Gsf&#/f2J&fEVfE*8R|ZV2r8MͫKp`}7'˵UQy9ͦQ#/(8zXiKe(UW0~y^(:zKkǒ dVjNJ~nNE^P4Ǝ#5BGeS i)lO>hfjjf )t~3ߘ BS/jn+o%CK,kUE.ЇHVD/$ۻD|v>} 1(ǝqEٰe% u2<z,QnܽaNYj1|%~ݫθKӹivATz//5JpQ#/"\3Q}z;}:S#v$Bc;Ԍ/)BTzED^asnWV`r*B ru2W>i,Ѹ.'gb9YV#5k6#5*t0#/2RJ~G`jM]beqKAJ`bi8!#/w=+-W8#,pCۈ\w_c]gѿ_tyC9YHfQ5(s68e6;iDv7:Lӊ:CÎ}y!!T}E#/nE Q&Ga #/=4!Kki7s;cQ(>=9\eV,,Y9i@{}6_w0RDXy0h~=O6{k1|=9Xƶd{<ȽRi##5;7PR*&vlVO^55q&Y_f_#5mڕ+ FoӜpيvcgUrR~y"ij!4f䋝dKm@(wa=Ǔ&Q\'9݂-ߏGlM,]_y?dCW6#/nP<W6쭲)9.9>sl:颅\`gvՇ9>Y0k|`6U%b[ya>,q+Ci1by3?T..>)xquzIo`5qY"c0c5-]lj1{bٚccGN=wFz^`#59HmjTDN#~<&}<p:RQ43?ٽrFmw5@#<ԖPS&79\*E6Hc>n. Eg: %{½(a#/8knXŖS4AT(qݞ2^M}Pm͵LtU#3mk$䂄ƿǡvȺ_=77n A FQWbr%)pr17 X۟~:S~:kQ˴88̄q0k13%u0#Pè!(##nj럁f](h0rt^DYU{U jz e~0^+cxXuFOUYbpw *wIsϠZ.7A&ATi$tny[_qsKk*9&`e>U\7&GI8<g[Cϴ4bƮXHD1%97Kp7ӗמ}7[}XI֣9ɇO- j߇iRO2 :=JƳeS4Z&*~T6*RB)ª3zw 6y;?<ܫKJ{[3myt;7:b~a^#5ڷS"ϣmȺG{K{,;sO9ve >~_MY+YcQTkC+g.U՘.45םgS{w3߶ nԷU@\l#5Z,,ndqrK[߈j[%&LPI~ba-#׶,Ps0e^8;='=a ӣM9YlV= ;J͸jV}g~f;P>w맶ZGVOA@%[?GxQD>FL+ЙDBq<wW9sVjʍ<S9-[61_SY{Krr{ycv<SYsyV՞r_eo|~l| 5c~og?ZV#/ ǖZ~X&e@vH9 [_$~t6}/\ ~b#,_`#/`MBI?/#,!ߢa##/6%VpU",#,ˎ_ykfDO+hk ح?=6 yu n4Lv7*p2_vCJn5 B"N֘IEoRO 3 z1~Ĉj U1[`bv|}}h=;!#,dE, .LH}52UuY'צ* 69ܼAOO.wwXg\MZ%Z߲mǸFG$-~ALyO/<GJ[,-TtőCAtƍr4Șt,c@zr>8;:#/y>1}~G6SA`''jYA"aKQ=eks=Z>'2ٟY*v}7W=;cU%b.qJX\@"j.6IN$6$RgRDuOA<ޤ?GbALx*UVa|OR<G7kn#/$5FSq#P-"#/ )"bNc{\`pRK$a-":\Nk"G:,dLXTJ#/p/hQh:H+P#/ #5ݙyտȓD@ޒx͉.tJQBa2Ddݠx#5V}xT1+\kgDƋFhU<C{JXqտ<v ,ćlYI#ʙgKZe z., NʡIEi( 0a3{ I+?bEy224<1nQN.\m>: (8<&'[_}fD8RH?]; F#y4IO}r$Ւ9J>pm9P{T)LHqDBD"S.ŹSHB3B= 8?#/IJ7ysRT4S4RƳrlm4UQ֫lm ϟgzag?q88?qGzNs,Xiu9r4 w`],͈C-~F*^=C$%Rff{6nkKIk}/eʆ(&?)#,Z`TS3|sVL[Wwt$N ҵ~aA|!K4i#,,*!5@Dهgp]8ԂXd#eJӥaE"E|4:#/_Qqi,BT<@#,6?i`>|v#aGdC1 >J 46}"*֦rNP Kb]; #,GD6d6Qbf(h=4xė9F)R 02!IY"{Owy_#,Ț># Fm~n5UB"{i{Ty7, ?_9Xf&f4eSu0b. Xr!_7G=/#,tal `6#$3<mFX =.Y%z#5nU[u<hqkrI F5+||ǷHIT|U3z5#zZ&`\SXD"x NģuEiVeCMfD!cGX@8l|߯,2"H~xِ,"s0F3ͮX>r6WUtvμwCŢ$G$I#`~ xa>Dyq#,u(KC!%px_GK7?h(w|4fȂdBދX}AɃ8)ID8nHtHU]O<'Wp))BCx6,M^#yk#OF#/Sf%;S-QSנg#,qOHPF!d㲀~0#//\n566ןf@x$<pd֗_2ecc!EakZ]#5?r:nnį,XIp¼wϴY=LQb9rrXp 7ób 0|RƲS84۾|?Y|Q-If(,|@€v@7 #/痬-#,pxUվ h H#,?apճ#,<<%r"  e=͉}b( !S(!>X^X)gH#,QTCP>C?3OZ}@pH9#+9 ~~pm> ^F4w_lr  $({];7paެ{E;#Dc;x$dl6Aç]qwAр}g"D<#,;4| p-9сP$!!|4ȳ֧Kpx('B&Ex'7AjXGt" :dCp#5 )t_dc+ }eV=(~t3yxh *(k-A[06bz$y\U=@f{8-@qͲ4dGH^}3DIVWǻ?> ۦrܫk|[<IF?;##}F Nr}r!]gz:+}F٨dD]aUXOcOdA@[ yó(刴CRЇ>nz$F$A‰`(20*u4Qf#5B߅44ʽ~TN;:)1Jf &aQ$&$0buq#&nO5NǨǠm}i-#,ďOg{C1 xX#/_Ϭ<*B2 v;DjvKg''ÝX0>+ۿAS#,6nrt`9+R>SAv%V^}ML7 i3ҷ?)*绶'mYC^cCh:iH#/3D"G[#/B31tF®(wfCOj6ryf-`"÷خ[#,9R|;,p\q6{˼ *{cx۰}F`0")*F >#,d1EɊne)}a2}̄9hhX\Wl1CWlhYy홤wNA$D"DQ D]~b!.̅Qg}Mw u5@bIrI2qDf̦BLHzѽ`.~P+gP}BQp="#5 P~ X2b`hXPR@D0!#,bE&Idzj4jZ`Ro<fFG&AB<A#ܫJQ_j4OP~1)ټL}9J#5IحG(G>aC5A#U+)'Qҡ@ m&S3oy[;skZفB#bA#eSmw^xˮ[Q{{>!9諁$:`xZ]kupA>@%|( B#,U4ð)^ 8lBB)#56 %1:hfȁ|⥅o =ve^EyѢA 7'^Sq2m80-lBɣ4{^w[F#,fm= zwwXʕ!^$;g"ظn骔UQ|7+?nC .Ij^THn}`cboZߜ16}ثKL #,$ &Oq0Y J<$ 2d#T@s}h"r#GSBPJfXu2rrٱH&*7 "?P>'п#;OZp!b÷㛁$! #Ux37^7Sɰ%by bȱ;PFKdZ*v$exzOgG<v/S4#/Ɣ) #/$?I'}k}qHf[ QcQ!E>#5M .JGD|̢RN%ي+.ĩ%#/ `i1;&(rE2# q8D\k\qxe~`9hTȉ\#y0nxhoHAL#,T7#/ l-#,@c?R(C.L-z&#5t fǨu׾M" 겦#5.DՏ X9r:P׈{;JEX`&@Yo񳛹4^m@1K I2mN/2Eh0(^I},#/P $4) zj&D);&$M/9ѣD&$Zf12:6A<evrlwC5s<%jfgv' m3D=w]S{RD]#5&.A+Ū9Wa֗^̥#]@$ <PIeI$Î ;l h7n\V LP ~(gr7F0rF* F@lr7ފ~xOZ/$hW0b %-LssFEQB=\W<LOR!e/,<h<(R,R#/w3vA&?޿O~B⚾"vR3n`BQ}/ =c^65iKVRMΟGgchL!0IyvHGiDi2L/TQ^G4 Xt}pf D |,8ݵ|ۻ3q׋?$L@FL+Z4F t^pB7A#5C-4Hp\B@`IG`UӠL(&\ B$` .pmKsL& Z*{fT7|٠=CpbqXtL?ğ=TVrG.\'8b\pqqp C <o/ߵ|{kgNj1(#5"ϴYcft(#,^M#5o\n[ #.Dg9.RxdL&ڊ4Bh׷-mpC [lu$*PAbɡ)TT nc!6_W:뇤k_eOf~hDkQPHC;!{qj#,l>{Wn88JnG`Tv)$+W <L!{+>U#WtŊ2-#5KW iLY_ٲ#l #ݟŵqnsTD?aȞԭ[i#/<eRF9#1<AhA$FaĿOO^<j xQ" -߉lO3J%P+6Q@w#,nb㰻da)}N0ΓapQ#,~/E۱NtNkb#F0"1;r23uFf"81໏{ٳf Sx{eb7daKyѥj )KĦ! K(#5}#5ﶿP|Kw|9 T{OobUy w>ڡ+Хff,x s&ЂAxno++'corX9oڗO>_õD~G!W*z&*|O[|vKyyZo.q26 j A ,L~AF hinݴKbDɌJ1V4J#4(P+mu6IX^F *4S g#/܄+xpKf=8 $Fh B(f~}BcY$&1t4AebʍZpqy :0G o~HwtGR*ts k*VLv ;/7Ly{ȃHDS.W?=;~c~/V@;Z߃lFQkgxګy/3bl~Ve!/f= rj-"N Wڐ2t3%'3@@D' Et@?c.ӿuQ챗#/7dr*!9Nc͏qF;O7BbqaH̀>>tɧK71n젤WP0-PBB$R$R#5"Fd(;wI2dxDrdgq!w 3g׶[)6hJYDlDt#>j)P =n7*ہA'PI%l$d 4h@+!vksZ~S!MONZ3h>"#,R]"AHZig#/y!-p=3U<mE^:EnB8<rOƪS=;iG\;\׾f DLhc _wsI;-d1+aYTGҵ@Y'qg`hiA"N0D44|6I&Єu W-DW2Z9{%$AQ)|rEy!V=!#/i:aˡ.Z(}U}B~\lG[I+_OJܵv,<4" A0\&C>E#qVyO;#,&U^#,V#/ A/Ei$ж4H,-+[ VFl/F%D @jT#_US$hd8eb퍯\%:LPKw~=oRJ]<Eǩ}v#Z#/1Rm}.ەF~Y#/˛}&G;/k7ȸ칳\*LFHzm*Y^B<P˰@M G5Asc jRsM&qQ=%=PztJ6^dxvgwHB^Q#/к;;KEIsy!`r6;p{QU9U1#01QS4h5)+5$ Q᭽9>fY0nEl{8lZ:{V*_8T50O~>_.ќx`KtymG"k#/&j-ҥYa]XR*,$3QGeR;tḍ]>mtNxPI_:wMg9y9+7=i<ь1!υ#51E㓶NZwmAߝar;<邺2 !(O~gƓX;0!sG;)`ۧw\#/s%yOnpȇmdE,0;% c-{U3G꫃~s|m΋fO5qow\;>Ð1 kc}_XL:nWWwgL:Vϛk{ީq:n={r7 \;=T ̈P1󰡼؈Q#,("0cՒ^7R@̄J PwASkw^ElUN٠BxFsd4(V*r.g]zBeY.Oqzydh<O"ˑs\F۸5j(vLwL/OmIhh~?.ap<d1_/t΄wQq=Xb?MQӼ?t*xB,IvHQ!  ͚Gs}fTTGq[P/54L8!g_%^{s#/&`z?Z;+UU`Ѻxk565\= a0-}[pٍͅNsu-Q#QשqΤ:)a$4v;\!5Khp'GN!#/K$p%-1'#/0|ø:#^#/B*gg#,z{:_П^_"ıC^m{cQTUTAT#n2PCa_@`8!M:iD'^o:.\,RPoy88>'̬>Si(ab`&@@ rQyW:Ф5ܒe2W&.֊cfJ3,x~? <4#YXaET0PJA 1QL{8#,p}郛!^^~c^t'E{(,$!amaTbj;[!tvK.}ڿ[w}ƭΓjCY]4߼]MC7m;Sxl³d Fn`((YM" ]VӌA&LJ/ޕu[5Re,oo-]cU!%%TN!!Qn" z`m̦6~I| 0‰! +(yr.zy KKcDw}Q&;,CbٺE \(B,B&ðvȆIg1G&6)QI'72YĎ{o믉|]T-4d_. 01˳vyhzt,@zl qLB3v۠ztjZEYߕ<Nzb =Fo8 4)ʎ|D%c8$h1 TȀ@jpyγ5:z${&fU^M*WMgyx `7>/5Nzᎍ.ԣ)mk{Ui;QiL<4h6qcWPr̜"#Ӑm!wh^Ǝ\a[YNZ)lx4S ^ds>!4b]n&CF2g47(e׼4,J'j=f)c M8M|9ewCF $dIk6l~zɫR{!6R`jӼ'D!22$.3HQ^5#yq3ө)kyz,|cFwu  ;#/|4 >8Hkݡ9\x:GՔj+ܗ7G"&(pzc&ǡ q9#s os2,m#/haX}ԃ9oVqwx4z/s9L6mt^J$9^s b;xb<xc$ ϔ&a#5 8+j8pfvڨ욯BX:=n#5\wRxnZXv pRy"!^MKHB*XdjfTOS^dNd񞀓vh^Mfy#,G@o7#e}ujUmeĠƹkbBv#,l1'@$D``r8 Yvaۂqшp7y BDq.q.sxYLF$#R$'/xcN_rR##,`D;B2ffX3" ̒vK_ӛU3ߝ ,3wї9bJE ;U(`𫡘6M|<y=C™"c̰#sG,=]Jy84&B;Ha]aUӭםfC`gNF2ʠ<DB:-,|tj88< 1cst|/M0iqCTF"],<ώ2,E{H=Fc*2NQo[m6.H =ҪX,e™L54ۋ4{B$ߓĠ RܑQWc:'-Q,>\eRwX-H/Sd @3çif׃>Ooqc-,#/M,~QÉ 6ԐiN<Ҧ2 1ٴ׽d$ nyJD{Z$` L}\]/b`ȉ(ܤ&QD^"@g0Ghj{0e! \(Bg@= IMmu±)HHv@xd>dj;ɣ`DCɡK-!fBAG1iLi:6/b-j~`33)JcXCt3(Hb0#,] ;x8!=f#5E!SNٍ9}^1#5 !`v#/s 3n%%={#:1@9s( SCgU@,lKd\SU3X712Vpne.S`a2=͂!{dk2Fz9.ХaO%PȷL#5d@gHzNcpd#:7p)%l9{^Ž23^2l#/Fq[*.IeRPY.s>Şcm]ꮪ]yv$:W.DES1;|8)5sZNcʹ>۠Cndm#5U$53:glf-r%a=MXȵF%F#, q.&gE;-(j;2a!ljofrBgH"-3$(z}&[iu&yŋ]D >͌:?A!=0|xJ""VE ږ,KINw]#/f^z(>%.X`**,F"Y*( BQ^(h\!:.m6#9 ãǾ0?Ū? I5}* }zvgk)4ڷճdz=JHl=-)#,iϠ&jRQd) M"HAHNQlƀ9J\iFFMlZ)r3O:9q۹x .^<,~.T4=('k{r5{Ue\saR| " % A& s=$O}4#,TfD@7) @;S(hBDwsҥIäyk1EAPpV Eʀ?A&F71FkpLhc M`|{LȪM~eh:BH #,=fG@ 2cSuQhbXXP32[ jFO#,kV[tGɀ+@`@ $E.(A0 $'!:aDD$E"DW.)$[u[O.';tUթIlNXk#5iB LBɑ6SnW,jw^K{"oK)%4[ݼz\175K˻5k.Ά74b>tk&OR*x hD޿32FRbkͫm`\ q3K`Z6YEEb?)'Ov+EcBu‰QCț0JEj+jNIA,У3Z$`8r$RU"qQv Dd"F,Ft#۳UHA1&OӃ_J 'e#T0ɮ\;ҒhEd$rHJntBt)%A~,D Ǯiu.0Z]]mr852/6݃ȓ8A4Ra#5\K!1#/#/8 U^!%W/N/us@T{0徨(oɻnj좍AѳL˗e!ə}g(!EBRuvqܜNrA5OM&t#,(3}D~@ BT"j̢,'IחQm 94RsfnKc@wxum>ga,eTJ$hdTwi #/mFEJ$*Z̅*-Նʊ͚*؂N ' mʓ8l|a2 Ȩ(V#,@[YLopBT`3#/ U$̌i(-;#,% X8e:b=sz#/|U_ GFLM67L(sCIFEh 6ZEWZ92銯ڶD_n@V@۴Sc :hg=9ҭAm*]%]%#,ܿ;sD*;6Oۼ<6ޯd͚̪*JekrY+JfœEƵt-q+*+8(n#, @A]}z>v[it .7|^ z*,Ă$N"}v>:ٻW6ځ9!u.$@ 2[p,)Й@e*?K#5)Q`+T:n;N9Xh)Q\X/$&IeTi'T ?<UjRA;7k]$T`g7 eSn">:x1#/o / (gT{hbn#/bDgdAcDHӹ2l`z<S9tvdLCc̮Cȫ0Ӊb}xa?rلm{O~8k_SD\m0h#/&<Gj+RǬL%hw@HQ'4!q:CKHxޡ4!+)#,[0>ݞaW\0ڂDvvudC!<R '#p>q Y:@iŢ6AU#/o{d䀶x$ U 6$cLǬzsE#5PǛ36pBAtʼnaDp@oO " $(⒢T;5<Ҟ1gN\ހ܄#ŏ~RBֈ)eb]VAHz$ #5DHx2#,B1X#,d==vߟsMjX3 vN#5QHFO~ms`j#/6#}@d#,  `|dSdo(ߞ$P8"[PO|RMamC. sgBL̒eZmr#bҤGHJ8,Gt>4g#xVcmֿ[DDL.z `tx~{Ss{.7;g֜<ԲZF[Q0I~1^zT<-`OdΙX۲X-Sdc(: MrwGuVlZn uc:K=VuAڨFjJ5C!+B1O;#5<>?f×˻щ\^6&3Xi[}^i8 66 `ڎ̄G;8{-75 hZ]zэ修Z[[',͵&ff@ J0bc詪&h 66mM0xC"o)b/rޙ/f_#,`#3Fk k FfiɓX,K/@lgp½v79isj.uCqѤFa" L(8A(2p5S(SMUJ,b1d;v%D%&~ԄȢ)q=DZ CDAF`I=h}j#/PwL!!sDNj1;-9#,rFT͜ CG糐xM}`z| jFB*)ZP|*o/FGHqB:lN0$=HDg3vkRwL qd[ 2!}c+v@VMAF6(,O#/ũ)dR%EԳDuKk^/xLj9bԲ! M;K SIyy %l+[ھhjFRȫQ5S b4Z9^PmU{.\^oߛt2D.E#U #E0AuQ- YJCGB!#/>#/'Qtp#,#,r#ɍC C7;i=h%[,9pQ9lGJejĐ3&޵@i߱M +e~+I%KL*dž|v[H'$'ӁzSbI"jn]h;ݭo#CT7!Q4#,#/$&HYJnBGA8Xn%(.db$P(a }h62`4LT5Bކ٣I <}O*-2<[Yi"mmĄV#,^a_ #/\vHPK#,I:RD#C.#X7`q/Ȣj֙" wbwXD#v;ᶖCdXS 449DGC4zwo5mx30ᤆZt6]Od34Q/|r2oD,Hu#/}g#cZ1C%ґ5)$6߀n!4ZʻI e@̝\\6NF¶n$)pjJ~ճr6~~3С׎hPsÅ jʌ4G9(!EUC377nA /N6A Q]\| B)L\aa{ylj -" ꄄTe,9[3CH&%V YAU*#,EV$:ĒA̻F$*$,#2\c 3֓=<ͨl3PA50t,-(jىI0̋#,o)MD2 lF#55`RWG'V/yeoˋ$;T2.; P O,HȅEDk-6PPrQ'HŴ^S܂}̶IMKue%#/OwQ9o̒$J@9:qi#,,F($/d~F6#poK%EKF T+ntN"s-qE(Y? B+!)Dl>W}&ϙk2/;I3z߅jwHeSRp0{&q"TI<h+ae "QdAU͋@*ƆCAR fŀ,W6قX4ʶxpi:s79I|a @XN`{gb~]f#/:Dۤ?Է䆘 !nP<ƏXwYj'I\AQÅ VѸ4m3d.t$AG@._se})NIzG#kcn9& Rh #~r8.A0@Oq6 7T1ܿ67 {Qջ-ᦓcE%L@lzv%8F3F*,T(X} &}kMʪ!2n"3P#*J$a;fF@VAꞞyfbTl"$1n>[\Q bD BNKQPa0NmjpvTs#n#/~s_{`sp#,*/Z2)Mzw0doO*TW48:%(Xr5gY3Bnc1o|p#/7[sQ!A9.%Zo-wJ,i#5#,U@W@t`?)@M5B2K '2/ZK@K:E ȍ #54 IT<Fج`h5QiDM(% --HX (bȡlNi#/:sm;/sg+s.dú1s5Lm%j Rk}xF4P52q t' 襺A.B舕S1P1Mˇ f2:t҃ uiHY_Z##İs%e#/#5KZ j-)Kkv1Q9#M1[m0[>pǝh8ٜO&WM8Z\a,a#/ROKl=a<VN-ſI+p5AI$ Fh>k;5y2z/m5Qvbʢ'G0 c#, ϗ;4 A6e0!4ǥ.ƃ&Ǝ%"n3MI#5iI#/ #5 E4c=[&h&AYb  @#5 Z}d @쑿ih`^6wnɧU>0G{`H@ GYn#,5ӫMc=&1ƀwNGG"a樌^oq)8?L`OAM gdw!B*B"svYƉl6-oȹunIKmj6Ԅ`EUE$A #5i#,zȑ|:iC$[X7zЀm TuVzqHD!2@H%2RkHS$̖blZL2d6T!#0)6IJ̑ۦ&Mi4hRYS)#0(#/ID*hR$IIbb QPZ4M(EiKQ( Fe1!QMgz;8,09.ۜX&A~u=Jُf̈x=;p%S*F9.e :y~)W/te#/D!$t2X-q1zMF߅7y9,碓칷[BJG6k˥gd$|>/}!a h\#y,P!p ^F#, @9/rcP,SiZMa4L$$,qpx}miTx0QʙL1?bχ F=D؄}DM ! Zť=c;Ե}"DcqC‘[oZ}>rd/F t* J^faH1ՋZ 1d~杁{?Wݭ۵-ѵcH%#V i8$i m M(#%j7N.""<a$a]-'Jd47fy&9L"$8ӷX;&F|;3O1-\{ 5])v.F7$۫isx:a k2,PL"Lvח+|oxc&qzs#/Q^c.r&ٕr J>3]{DưAarPOezAiB|J{L fev^`G$YK#5<@؏#@e?o-t;͔@kb<<c/Ѵ5kr!V iBvW5I5-?mg:eY| :YP첪S||S%Jĩ=~ʎVpj@{% ܬ!ϑЍ3 [Y Y#,7\F0rs'B;mˤ7#5 ,>!C $ba#/}CogZIvƤP`M2!F Ӆ-̭;Z#Xe$|2}?VlfIԆ)ZQWo a31Mf.2^By51-,.KWZ1fޞ1`9۩LKКB$mJ 6tAIΉ>wwws!YL\.i T0R0JtɞOK7?z~#˭;"F`dά#5C0jv cTX~ܷ1Rogr3% LB 2>t#/<;;, 7xdC@p5Uƈڜy(a\rmzW2ZBA Wo0q52vس/uyh ;v[$33u,fwcbRd,vrh L_;l\;Nq#,X(c(He5-1”qDW;4Xa&(~]OuێLsx)ns/x.>Y㦫kL:Cؑ26I7= c-lvۅ%ޓ*oNdΦD@ߙ9;6.n%G=a읿n ˇbs'\R]j)XqM<cakCF1#51٢co˄r^b#,-4U#eΆML/|CHPuMA2M]{hH.5&(  ˕FIŝaIӶ! B,k#/ -z9225qˡKJn4ߢi75\Й<LALDpnٷD]ЎuG4ɬӒ#u7e-\@v_-qWP㞁C,2%hnf?% 2F:*/9s $fZyY1ZsE-. #/:Rѣ^mTZicd@d!L6-3˅BshXI9QM#/TȍvunH'{$hCL%}#r&9K}2WQÒ1QrrCxj?6`\35ǎ1n`՚l a˥$\]]7*,ZV"ь5bԔxց´Q)hDz9Mlz)InJVo4cr̘ cGqz]VW֯a0C<t4 }R>C#弗q.gx70ln6i¸q-n#ll#/j&(]&M7K}KJRrAa`"m86vcpLc+э\Zsl\#/eS!(BfkKZエk**)jݔJfGVXnC#B(Bۂ i#5'Ks \ ϕ1GQmPrIYM1C8CG2>TP.e[FPaN+img`r5U/V@Cd&^,I53S Qv9 Ta%3 8][PJc$d"mKJPTÔ3 31zCmΕ`LowB\G,A(Y+;tcI7rX<5iaNF:tt4 6XKe:G #5&$Y< kCEe9ziDSQHn!s(aMd&U2LTB@O6fRTQv(bȰ2P40dzݘphU-`J8T-!jYlY)7P10`aVe6IO$a`J^AX6ҌM +dLRٲ[,Ա2evgrxVE0`QhcgYfΔ:]֩ZRz LiM+3w- /с!+)e#, 8:Ha <>V-gnK`lErץ}Ď`G+PP}R9AsI`TiBf9h'Vm#,@ ΆEܝ3#/L3dJ׼сLMmH) #/#H. UV8(|WA]GDXj(L :#,߱ou)&Z7-m^%-OnL6CCۅo4Xn74"/|#-J:?ike$#3 93 }hELȆ ǠpqD` #/AĶ@ǝh۲MQf&GcrV HurU1.I8ɽ0(v)7Fk6&¥$,3HB*و@c8pvxI,afл/Y%z`XFuCTk@ ,׫z6/#5&i`pW5M4f3cm,Oq5#;pd0r\A᭍ʡJ,&0 "B @BEM )h RJU#5#/Wx;wV춌M!>cNTzqB#A!!ApV^;U KEj431[>q9"_ADpX[d.Ћih#5tݺR͎Aid-+X#dk`(o [FFK #5Mݧ`b̸;bmMv*|.㩴8KdB$1СU{n:kemi-m&@U P8C#/yPJ,Ъ1:z E[g?P;q: E]vM+okl%ɦcI]wfsuQmy#mg}Ƨp<Ia7f)ڡ#/^(DpqqpCE—q27"د' Uo o3@fL/V7VF@5xD˘d;$H*5^9͒5K(^|PfWـ׆@1 bQ1茁S(ֆn viI#5\oT>g,rHȳ"Q#/F2>Uq B0#/7>Gއa$RQ+F%E-35PhE#/ I#,U&aY_hS߷qLC]N*~Mž˦|}95v Kى#M h$FYDҠro!{M@H q:-'e #fu/V*(~RH)#,RZ ;#,v6hSXd&AUh*1"F#tJ4&i#,\% īmXԸD1!pHO<D~ÂQGHĎZ"U00迭J s53TtĂo|ōGqߗ<e@Mhtr\pҵvM iE+aW<Yz5UF+y7ʍ##5;#5+#bۃM,1E-QBQE>3pL\e&EK1dfwGbv#/]! Bj l].t$ q.[YD*"Ix,؊(FXB`>d0A |A$& ?mFƆ~#o] 35o]Ȋæ!Ͻ k@nmpF_ol==1ɶW3yQKc+Ch laoZ4cXEz:ҙǥ VP[M3.)dCa074#53#3fi&;dѱ!6=.٢@.I9`5#/#`keL;CڠҖS3:g"K` A=:j4Y%v~g3j qv6K:AF%X)r)\d #,T0L1  C#/ 9Z$#5YE03#/nh/[棈 ? RD^NFe ejpH] 'fn ?Q?TpΠH5$L]YG=#,Z@P)^ d#,NqNU4QUUU#54FH[hbդU~+Ȓ8}ϸdhs#5}#5PO`8:ubrakwG#/dA, q2enjMtuiub;EF1p1\PitR 1;K4yYZ:ݭt &)U pQPYbȅ13ˏ5B"Q(D еfK-g)\:;X3BQ2qo#"찘J|!ֵ̕+;vՙ{o(Q4,mM/tQ6e)gL}`dCR MN2Jc`Vwvf˗\ ,,C "( Ő9xokeAE #,PJ` F2<݈ Jte.%qZȹ4R&nĉ@KB҅8Ѕ٦#5:zzٟ55]ݒm[}F.KawsK\fηs]Nh6Wi+rݤů;5;Ow^o5jB-TjCh*i#/#/ii"V#,n^62I I6V6ԢX1b"C0 fl#/+[IQY$AG?I{%"Й1}`NM.Ģ-"THlob ;;L'^aKZYL?yb<@#/NtFLJmz׫=TKy#,UEz,qP H|{LK8~L/B`BjԂ~#5lBfhZ4XR#/BDd7Qfv[M)a3ߥ}9-X6kP%,jT5\n 3v'ݬJs\mje2+@̐3p zϱk#l r*+xg"DevJ9g 끑t/Ѕ(7$tx<Ce<VN؊ ƌ8a}.%d298#,Y, h'B"Pu#/t*SZ|J8wPT }5^WG"BIgb2ʼneAT -Z/WR3XڌDcm2h'uPIUnh2Lkyk\-m#LYM5Q[ $]a+Yif1%jږ/{56ԮKnھ;]*b11*UI-nrbIljMc[kdMoԓPՏ<K&Zm,3f5mlF61-*kήwI1B &%m kxKq`FH N V w+J¹E^>kӡ{ƤkTcEnLRY&mfvc-LԄr(|[[孠޺fҢYiElJK?__&m#|)DgvJJƶrQmo#/ԈY5PH%A@$E 5-%&i0jIk)6ͦV̵SE*Kb#EL-0Pl2%I)B2)(5&T5)YJjE(%i6jɵ4,TIYZPlH$e)3jdK61&V"FԔԦ*֥L4MJUK**|ݭMi)*M6mTi*͖cZlZj5jUPCIF9/HpnNoMYHe{20cB'~へ hY$=!^#/)Du/1_n'=Pk4#5.,=,kg]b٠3mezˣ>2A1`ydE,u}8MCFlt+YE Q(fIQ֚M$DDjXU#/ #,;{dkX',5vK60&Ӓv~#, 1"|uE.y!Jӯ2Cst!\\:q1"v_ B*75<D2e@<|.I`Q}UYdQ0-߷3y VI4k0iE( ;(liK3iڈ8LR"sP#fc;8ewC"i1R  @#,#,F-0諺\#/+s@+C WF׉ŅΆfw=*X" #,lp)GXP8B; *V];1׶Afn?V;vaĺo||CWkDGPpBd#XNpZ#5ٺLuAQWE0YEݣ1QmYH31keIIV~&1(.]zzKw|z4kT}Om3E?#/#[Fj%80nHpYݐ7#/&iV*N#/Gmh-lF6(*#/+~Q5#,~(k0c'1jбbw#,-v~rCJ ӝh%&lR)ϲ= va7'f#L]jrkCz6I}\DX7U-hu?j5g!lY>0"t^+A#/tySyjzMI!4#o{a^E\^iYO<Fu]иF qWX4沶e͒QW]kcB7kR1qP6M!]"LHeEZP+HڹcZPPRJA7+'+N7HI!X;A5gZX=4GAFM#/P**0f=EdѝhduejC2)BP aAr+0Ld^z.5'[3D#5Gx?!QT9M)hw)_c#PEzqMKCr UKQ4`L~%cPt#"#,HiTlZŤŊ a&B[e՛2Fe$qJL h#/"#,#lb#5&G*Tch,-: ukQ5; 墬l4QYTQ׶Plv;wy#/cSf<E;bgi-Bzْd NRN\XU8Eq: v#/i2v5uS\n8dBDJ(A" K 1#c|ܴCbެQoC^(;rXB#,N@(:q,$Z.oituqU Xq*0᫬a`yْV@Q3T=umSM* 2 Mv|wIKoWg\$n=Z7K7xorWsMS툔nQHcM3 n#LdؖMcB= v.g~Y /]o[WaǫWmius7[RZ+VّQ# )?#M'٘zIƊxwz=X%T >W<|:xPӷrNA4btG R]Sc#Ng#>n,DB!L8r$JI֥ [JYkmGmȶ+jY>!S@`FeAB*\B#0}ז׃d>ɷ#1@ð3;x]ܩq@"Z#4ŖW_x ,Bkd+!ՁE:A#/b`5|ܤ(B1UmrͲ%6W]6M5jX,IkQlh?#,a#,AP"P7!Ba1Na3BUk0+"A0f6Ŀ&/``i4<rS5~E7 aK2bjq4#/@!{P6qJ*P*B0XawݟH̬cwe̚ '\OU-_b54uRA #54!8N6zT 02囑p6D"V-_y a7P堩 #AI:,ZA~]<>` `3c0-*m#,AV4Jg?+U4;㺣,7"I ψ>;vI#,%Ch#/;ǑOYyvǺ.uQ!«6FnCw7iD=wyG"T"q#pvv- @Y^F#Kj(h bXTe[1nXo:2 B?PCq#/e؃=_0[=CmVKbRj,muUKji+Z5FŘTD$A% !&#,3=wpAWVJPe$" %#59#:BaXLhcAُw53a Osarz( 8%cQ:GU,!Hw< 1HR**+v<j2_{knft5-J=G6-CxĝEWTTH{q{B0vx "]R33g+!D@̲Vh?a8OQ!70< \sqm{5_*0wMèpK%0#,7HRv:070,5`1Oxܣx|\mYtEB!#5EMʆ2`C+4E*ihQc2X7r{#Egujbvd& 6oZ $d gzHL)Yiz f—@KrSclH˪V(#5J4@oYG"UK/Y܈y9M\Iwmj2zd]0m6(56qN*Ѽ""'Ya#r@84=Tw&b7<;v1l(,11-#5H( ˭4#/G&iAЌ?mҟ9V'i8C7'Oj¢le#/Fd(;[\ک,Pġ7'<C!?=0ßFNH4#5ߵO#/0ư"1R˱ZӮ5imkyEy6`mk\[%D(XPj@*IV'iL#,A2#5XzfyE_`A,iQsk4Oa!UDX@IF%rP2E5 ndꮵw{rl1b?$2xO%Im2:͖mFUm4uɬlT]+껵^ W B(E[5Ѧ&+RZd 0HjA -wB~w#/EebL#/#,#HfA$5#,@2fD&DbL&YĜUЊ@Mzpp(>Qhc10*5ÅhmXp[,&#/ǟqM+1y~N,HVRhx;;R# 8J<R6USK^4R ~}_=!P6Q&-[T&"`ռSh 1W6s(5&*RVѵ [iWRk%XQ۰-@m߿p;#ivҁEǀ42tJ;yoTU7miЏ6U&$gm(8`qDUa3HzmW"( Q!#&R+YO@a ] 1Gw'`u$Lq[ q%wRh"h)V`m#/dzznh5RȬC :'tQPnv@s7i5${1#,(20نA #/ F%#,>f՚0n(c<1Ыr#,*MTI%F8Y0z$it6uuOb{_zi|N&M~hֈb-"jM$%"m%21֛2hJK?qeR%XQM)i6LKfJƛYM-d։Pj"ZQU-*kU)h5z#/iO?6d"f#cD5$AJ Zj5kZn[2@$dHbuC~H_ro[W(MԿꄉ ˔uV,#/K>av\#,2~:(۰`ܧ.Hw`w0WAhDMzӊ A2=PU*PQ/j[(qXO"< ̕mB$!=L=|⪐h"jD98'ݕ2337}&$ziDk*4 @<{G#/gA'1#,bjIķXjP3v<䱬N Hw0lḆ\\(Hġk<!pI0Z~g!G i|@4/Myl&"Nk[FYD0uű[dBdbe^^07 sC+_} S .6i@11f&K>^&m5F~RE AN䥂(#bKw>d6kG:htt#,=_݌p2ɼnHcT=1,2&,KQCOun<XPĶ7ߤ)143,ei*MIkqx˯m{VksoC@Ĵsw*=$;:%DT Xa2 ;h4@' )]HCMhzuynBG|:A,\t#5ĊqL%88@!D)iЂRwLA?-rHqטvF1XcPDS`"!#5D($YDNO^4ڨ;@?=n>4T$Y`UD)-SƓ~˼S.(۠XcQq-' ˆAydfe@v`bqLq m]*HJJdݝ-tvw"\++6-Ky7<yrBΥ~I#k,'>͕E\P3HoVLƢ"3wkMm*o#/'Eq8A-H0z ] ,ӌQU̜<e͟B'0rwdj*yK5^P @3)c޷ԺWRa0;aDȢ߅o}g%.̡T BIn[FRP#[$Y Ti$kҢf/vAW<rG$bBLCh~Ņ'6A5F#,7Oߝ(F[$&ZJcnB?ja䥅Jk.91-ax}LQ#/fξ@kjGRРٱ]`B@F(iR@HE(f#5w:S tEvoοP1u5鬙kbD(uv9t` xD$6!UdE:`VAA%ZK\Gep^j<}]j~hu]vxPD^QZJW 6B #,Ƅ6% 1(2*TUF (PH}WCȢP;{kT `SU(^W{1\*&GaW0 n(w##57xnmĬc[p(#5a;@#:/2(_R(Ǧ9Z6IN0JlC*Dh) 6L"lsEg6f%YSd WL ƞB]0ȉۭDHٓ/mZhl0#/s`UD7wD01l2{TEO8 pB@u"T#,/-֗77KcI괌#d=^ix=KZ#/'6᭕FsLu8&:h)#,y, *]ZRjZ6eL֨RU["W]ڹ!(`)(Oݸc!<Yhj_Hq#5==ֳVB1NG^u\T[YGA C#:8mNY`/ $kR/~Ey'P<ֻf4$'2h8}nl@Q:P#5FQA4'^ #5 1W)1Lŋ=_ ))*l#/r(\4JMfAwYKj>#/ܑcVN}M<M#gz8!2vu#/e;|j`DF`(jDyy#,zOIۀQ`4j{~ۇ^Ȕޅd(NȔtHQ|&4@{R!*܈7,c !`|VcSWn;><DחnOd`:g3!#T%T@DgD47:͟v ^}r G1+>irC'*YC(9$ 2idHA-"g7{=ـ/B6.W_E+ Q!yV`dvʗRڝ՞vӽl[zt֯ћSM_uҕĝVxțFFRs$h1j$_b7蒤=? Ǖhr[F*&k㱐xjV#~HReulLеd#/04孭Io#|Nz>P 4ǖ" R7%C2m﹄G#`#5H_8FHTը,\J v,nVi6ilUu[7e4\Jm}Rb`@E9q`@:DoU<Գ5Dz"*45!>MI3lAlcZ<#/rģI-{l>@ kQ LUMFa8֬bE,4#/SչW#/6MJ16߸7pl#/_p6h^on,ES`[`<On^e}+"36k-ocۺ9J4SQcmY\рvfc&,$lFǪ˵Koh\1b-nwhg50#/$2#,v>]Զ#5hXUջDA RF~VZ*֏3%Hk)JFl(3TqMP90yEAug#/TC~z,^G"`=<I:~4OZi[9 P}gI0IFK#tH dZvζ0\7 wn;#/8ȁ lҬ܁p#/\yܽ"03ziK(IRaDVIu}YK=.!< E0'!e)5›1k 3oŐ0? T7 ܄A t&4q`e3bXFML-#/dl߂@rM?27!SѰSXǕ۬R5v |7R~"@ ;2^|72ȵxQmŶjQ!FҠHP4&0___l'a;H@?U{ ؎tOqqF(nao3[AD̹"12ā-+|ǚpA̟#,`8!o#$Q[4ƐycP!X20ݡ ú4_U Q(O^ԪI(9<B`0P"dvIO!#/[Iԣy3}3B|Fo1=<6} e֎b<j KB}mJ-7M6$D=gc2mb^>T#/*UJ<d𵊇\n◠"Β6T_- ALh_hGKEAsР@TbJ<ܜ?wu6Qjp|0Y"XP"\ g/.n3%WvҮFmήۮ.+6LƁt&}[jԄrxCuqU:Tcq٫LnOՖr˲cXB/|4צA#/~KqU3!F)ֿ+l9z{Yci+*7shW堗Yk-,$#/[WF(CЃ/KΥ@)h嬧h*KKOf"2|9)xy.R+n-S+1d$0#5;ʖє$Ƅb( pр]=ܥr%A#/ɪi:5SHA "d" 4!ccb]Y=?[#,aAVȥvm}%y+Ys^uvicMwtO&6ͦ4hxyrutwⴥnr{YLQ I͕DMPI6lRdj-+v4뻺ܛ3MnEDo<7PU .sQ+zYVThT.#Mg*#IQ٫"e!q]\1pdkuRsatomRQ#54ha#$[+13q]f#,34@k#/7s C!LmqƟSBˆƩ Z|Zmt0G5OyVw6䦄bP2&D"#"kJvmPٌcd@xی iu`Pi-+BH#/[qcFwqf9sb8э .26 V6N@ LmZ ҭY&\YmjC$;O42MOg=h"lCҙ8C&kuxfP<B43zzLbHv\U+#5fCSb Xob"<LE-`tޞU%RߞcAG%D4ba%FY/hl "tm03LHh[~IkуC7P؍Kx҃(LY!#/6#X UQm5oPD򆐘vΑYLUeȮ)(tjB,1iǿ{æf(%H?A$`8$CL4&Nll̪JF7tb#5Q&c J( #5d#5ʖ``1D#/*B1.%I.7qE;wTt;~uyCaꛯ8ň)#/F<>o6M]ҫ!~ԡ{aM dpAlMH?.xS>Cŧ1M|,d50n>03hkľEFo5qIE.8<<4fji 4cCU5ٔ.!CF^2nNmEv>a0cc󱱗mi`Q00!OeSiAL]-#%/F 8]T(I8.0ayExѭퟧfpuꛧ<#5Ԥ%q y+ҜcQMBBni<ur>Iłd8Γ#5<0H:@i}᤿5K`S#/$S}aS.=qP@o "ˆZKd8("|hUlCHMq2J .Vɼm*6mIZ*K][r׍hifِ§v֒Ml#, BAB2l@PKG ;Ȩ)Jkauv`Jl5YpMZҔջ-Zl8P76XjbH2@'%|my3D[kF.>/=e5)ʄ!EV񫩕I?P%X2ض-1YƣTmTͣEE3FVe$RŴ%kfv#5$9 Aﰡ:,֭{{#/&Մky_W|vm#/O:Oͷr]VÁP"#,H@rM*+~&\J[[v"V)O7]&ki)&m&VқVTW[KIQM!6^ A~jIJU G&0A F;JCay8 XEV)!P\7JW#5#/xaN"W]0mhP{5>o>O~#5?^H)AE~֕84}&mf,FE[TlcUcJY 2$hNJnLc,zdǿaCsb-PZR#5(P !gꮤM;:>$Q8du<^wᲩ[5]mY`[hƂQg{42-?⠈#;fu`vHO*Qt?0T!L3KܺnE2-!`yf@<`MmcTm-_}-HGLJ&12g#,KEdχQlՍZ5\յuX1nǝ>pD  <0?a?C_XZQA&_yqV0%h BKF@Xͅ؁Pl4$ڶvվ5IQUMoڼ݉ƮJ(DeR{%!a#ZawiZ{ҥcl‚L#5X*id-Y*  f c Š(T(`4t6L磻\EC2q4b( 1T _IP#/JKpc4a`sqcfL&CsWРqc0Ԗnݚ3@9@zDTQ1#,2vIihqX=nGo7ggHUy78~XC8GG!HC{z:\9pXɟW𶖬1] q{8띩q8 (΀TǍPUA v&ɷ䘎YJ蒤HB e#Ixm 2#5?Uy,)ji-: [G0Kl@(`-YEl8<WH#^y>;u茒i~6a!gtDž+Qˮ645A@>AEU&+t\զ[MJ!VwPDw&V3u6\JհfӱF{ͅwٸI -U#4櫆I<eS^s JjIm+bѠcA[k;uyGK\wn]/xWmveu5UmMO5ړ&i6uY.ݔE+;*Nbc(TEP()qU'p`ٷ׽U[9Q$;-F :E H@SUڣ$GފxH7#,|`HLkݰޚ7zu?GsԛNtXfmQ)$ #5uZ*bp?„#,X(g:l*&XEXD0I$OaPB5+uwREEwm>!g#55jLRg AέR&HzM!;H@01B"fou֭mikʟnջl&4:d'@k:dG)R0 L0)A(#5l`|SCX @#/YfU4֦i/#,1۳0VQ#,umlʢԙ` *`T#0FJRRj0'P"$P prꃎs[S>5\,AL~>47H΄x²gWLlf-mEwc~#,b BO!{?=^"E#,e08g+`_}CyfHC I4>7z8blfh J 兡 #>,-j#6 `j#/$Ւ1W&h8$B(rA#/ڲ0@Ed&1<#5b#NMX; AMX`]Lw淈-GXjW/*ⶫW5Rk;fN={nj0#h~bH$G("c\<. Hk_*-jFi,%!Q*6TbIE#,5AE@w@ALZ`m6]C<HA}~ɨ'bW}$ !A@%(Р7#/|򳱆Ovj)$ yDzAD(B E>AX46Y7OmwMf#/bubF(yC?4Y53AgO6zƖlvA[>pZJ*m5FvC$MUtHF 0cKOxn]!p#/2Z}G%R,N 2MOBPZ Lڽϰtvc#5vbz"'/#/gyA 1>FTWlAv FE"HRD'#,#,C"XS#5`y`~#ި$ BﺌP>du`B#4趿nU 'oBx|WӗJ."5'ᱽ}P9JH( o#M-6h%w̰:wf79 Ӥ*cL@gТ\i`z\^!![$f4XBKLȭ*`&Y4n"Z}_$?/x*ۖ&o#/hHba !d;_/Q}h7"/:x/mۙUT`s6]Y3P{4֚;VBEe0:vr`4#/'8eFjqEb",q#/#+L m-0fQ2grI !.L; HNUkbf CǯFsSطR' Kv+`ǔ7={9 lGf-2>#ݺxZœxnǟSeI|>:lP#5.^)Iz npLMf f揇l5^.Jud&#5!3@8)PhȘz#/QO@'1k:#/s>;YZ*ovfaUAݞ@J8EuBscŚ.oAMı @ipn"RVeA`T#p@~K?|v=0 iL$DXݖY` (4m#5h(>1m#/?9MI#5BHj}_5}J#/~ʭѭnDFFrٚ@7<*Veevvxw$NIY|h"'d<CrX !߈h!2ocnZqpD=ؖad1m" #,O2kp` Sct|]LW 91☖Fqex@?fUa';߼tN*&d8F#/b=uYf:Ux1HI$6]0|XBma3|HMJQ8,W7lƟ 910H%"Da|>_UwH0KU#/+g~Z}/0#/M:14=ه=.<4-Pr<ΜD1mz-jq admC\j0լ-KT\c# ^%#5I<A=Ȑٌ݂ P##, iG5fff\PۘسyF5.&<DD[|k.:#,Ȫ)B'|1#5F#r#$,X1#VpPFT ؒbcbb™3Lw蘴lScm"ea_V6xVݞA*R#,fP,)0Y !$G3<7 mWI'tSgPL[՟-?Rh_0/yy"'ѧلT6 <>#5jwx<C3hl&W-7Ao@4PCrA)FP%DE!] O*܆~ҿ׽m OTۍ@>]`*t[6pbZ`RڡoB7#/]}ٜf <F[CؘUUFa߁`}쥑(- ,HZ}x& B#/"PԳˣt3쵢H";r{~SH«mRQc[eRVjlX*@B,ݲnxR! ;#5KDRH(Eݏ4o<dRlI&#/4$ġ%AʚKH"Bʔd)ks`Z#,Ǎ14tGJf:cΞQuu9.*v3#/&Èm1A i%Q:+Wwi#Zt+*qifg,LkzH 8 \@ !)IٜB@صYt+t'a@q(#T&@b8Cq\Z.=x:oS,j ߎ gb5< 1wq&Dd$(c_#1QkR34V5 OY;1ZI 4DF@m#/24A#I`m CbHRg~\&g%%J6ĆŲ1p.c6ьV#5Z;nR.r!E%#,8f?#,*@c 3Wn].jw[u{#/'ӚQA<#,B#5#,{ZmU+qؼA Xc)0B?'Y ]5]ѣ<W/#5@Wj2ae(hbltl(\8lM msm-˷qJrHU=y#iGM(Eqd D,DCtFX8#QI_S=Ok{%{M- 6:7&+UKd2mbBXN5R+%"{2d+ 316C `Rtn(#IB=$y*`ɳco(jz݊f;Pd.ijfyP"eMXum[ #5ds"X,#ˌ25`ښkh1GC7DAj3l3 Yڨ8#/j,őoR flYn(94Tց5#57 d.vt<`yᴬf#/j4j#/ b#5fE(ȒɦbLMcHB^>hq0X>i Nm(v$El2[Bf,Di4ND$119#,(`P腤䡬GV:XiǓF}#,cm6&0hT"m#/,)^FJ&{Xg&AkcG6L~cA*u6(&B-#/4cl[n1gM#m>Jash(˰֚b…tDTѤpEНUHOID6<yp4t=(YeU$9H|m'#,:hF [s(ؘ;0fȈi-*@4!BQ bJ"4l`^)"4fjܑi%0**Mw-ݛ^M]WbkF Qd`!GQ#5?w#,YCBd1#,.&OϺP6$-ِ#,.v~O2E@_3#5#/((B2 nH B"ȢDFh, B'A9^H;y{m# BR!KFyhˆ7wRNևuדxŜcn*sjG%⋱tRSRHC)gvRKʉ#/0-2coPDS{n)ZƸK޸k!`6w/ȟG]!I.6Aȿx_N!q; HHD<K'QȉV_z,OVz= v S}59T׬Vk=0Uxo>F*;2 yg!"^gUݾt48Y/#/H"L(pDE2%t`Y{OGwR*mTXt\T*#,;5k79O.|`Jٕ[Yì"hFb"TY@hZўS~'c5nZUI'(i(0%$٫o}6rQBT@C!U5AtKQV[OW4m淍_nkžWbW[k5shx;Zɵ!nk`[%B KV#/p^ud5\W’,b#HaN@{4T8"|@\Gؙb4c@I#,GĊ #,z@?ˀEKomW$4P!S)J#?q @>%X)ԉn"ȁUEl﵍%٥mw#5tX.BT%pZj-j&ںY$#5jK6V#5vؑDNDQ$VHAT} #,#,tP*'UOFAGB&q #5!zMX=`YH'J^`d:>BbEcdR@l14щ-3DJI2VŶVJU*ũcXf^hik2@ 91ȑ>)pM#/1<1HEd%T5Ah GGX"W#5)`#/eldE1T:UF44D"22*T #,fiL"'k&%Y;7 O®׽^PD AF B c#5Fևh.*W N0^6shhyKk#/EU)^}#,1 6۱!77q)2um:;9tM`,#5Y!VF@A1ީ-$<8kbHe.#,m“$Fb{]5LrەFU\\ֻ+kA.qY DbVU6dX|?fm8A凔}crB'Ä͸=PnO12R_'v۸ϯo. eu={pliܓ;:7OKt k/)΅-ۏ[/}E/,L'rB9]tMߊkGWtYA3[5lJڇEyF]!%#,WN-b2 ttUuĶCLK7ZXn?v#,:ÙN-Q6<h099{V48=4γ|=vL:8Dwwj% ]Nkant{u^9{FǟI?9 ~\͕Dl>7ʲ*pD5]NuDTSLEHEmy,[xvvb)WbOdbL(D2Swȴ;KOy7cқcP4с*mWϒq[kwy@co{T<#1܇Q'wb@뾽ʎu~HR*WOv5>#F#5wT 'RN rld5<eS]=3gH:&f#|8JjZJv0! uxǘ!̮ZQsQ!8s;È+u5LldR-ߧXRpf(%t&!Hj@"k/N~#ngFpg&ݻArմq6?q䗙%bLn8Y|)بDٺvKxdB3zM,4C^Ro~2_&OOs7}kcvӗ#n8щH˻<|:`D[e1\ʤӱﳷ .u#џ^$U|3H%LGȴ$PԪs,lu;tm_8's]1`ܩGA#5?#v(+t>T=< Ax@2#5Շ&Gc'!c#/Xej#/*ԕ<XG_q4b8;z=A~xHjqD1#/*Βv6)){oxl4gw `sїϕ8ՅLbY-\/ILIU)dm9mRÔ(YJ^X*'$tx%S4!2B2Їsle!Ҋ #+`3\!l2 9FwPW da!H6}i*ͮ,j]vmH+ndlr-Eg2Pj] At#,)z)( #5F#,B(D[d۫vmĀRF,NH-I @#/3@(Ou Ё> 9A%A\=Z?|4G(="LȻC=G/Kߞ<>7p%RhCِLs;IH)Y.$gF\m>Ӝ>OzһP{M9jj?/#/ۿk7UwFe1w16 X'#, JķukL9w*Gn|Pz il0;8~kFds$.jS$2*!Sږ3o`b#4@R 8D悚yvvb;8=qIzӾ.ThnAҦq<3G:M^OKp| 9#/5U #5h*N5Qu}X5EGmae"5#/PA8<WVE6%݃:#8RL$,DkMߏ5Ǣ:>N<Y)HiuzUxӆ#5b%jC1KՈ4Г*fJ#5I:/>) FToA\p Sh%V*RXs)fVjrʌ̕|Lvl*C_mPX =;ֈ缹e!M,-7R3u3ey@((̈gPy {ʤjPׂ%:f,ҭ&CcѮd҆#/&B\H֖N,a$߾Mn!: ، ;$7j0~jxdjl#/~T~?"%>=Lo25!*}D*sfҳ1fsWD<=^HQU:@ZXCVFѱDw*I0 65'm_okV-C0x5EƔtZJF08 D@fޭQAksmͨv<QWխU""jkUzֺze#,rX`0T"((T- S@uN-,neM!BF%_<X[]-HA=1DT%?6LaW?<3_u<r"JPi  ߥ}7#/7!b?S6mpY2h*6iY)mM`0gVYBLǓA)BEIj#/U.>iGyYUSq"T'+AB`daLbBQVd{&0dUCw6=>rFaFvO9"}(Z]`@U#Dj#2Yj2ZL3^vEޓ')c !b3+nxK#c7l܁AAlȱ65љIs{)FmbmjZ#/Hj0$_u*qԊw#5Fu(3ƈ)a)pM,(PcfHSK21w̢xpk3 iY.lo! RƱ@+\ФIR7vmoĨ#/)l41lBM[:J6jje*XaLV1.ۗKG]Ȍ3Ek:@awm hqi2iq<˵aQٔ~nUJ5bࣄBc9GpF2 QU#cDF2#/BRhl;1F%c4-]Fipy+`zWdpTa#jP˲ԣr۰ꠃ? GҦfn*jR-yZzpmW\8@se-:1s[u,-J`qu6i.aZ JF$go$i-2FHFK3*ӌ!^5EIPQo#/:p0G 0%2Ȑ۾lDqJs;*ǎ}+?_X~;h4n>ξwz_3+#,B6iJ>X"B*Q)#5UHk2I=(e!eSgy[i T2۳ $UUFJ2*{џ/PE+ICcj=¾C^A"qm!JP@AJ&a28b̈́[Մzl uqFN!ݽx5i]tjaQp%-T3=gu2^? ;Q<THQ 6o-A#9(Vk{]LRQa#,XA)k˫RpSEE?A(}$$cPQѭ(F$QRRaV2j٦Z)*-&6fdɥ)HZiRfJmlliR,ԩh5"ɛ 02[V1ҿ%މ h/%PyteO\\DsV|aAd<oJ 9TOyTPK4jD6C]2,#/M/X_Pa#5*|Ka\zu/b\#,>ppjUZ#/5G4AoD.F#5v~YzOgM#55n 5/ )"kI}ծ[1)4H)-A_r]jB#5PFR>eπ`'qx!B*Oۘ\3W@d}^j@j" QjxoC]+L"kVRQE4\#/4weٓ$X#,4w$l&1HmM$P* Xj%%ݛ&czzmF:*KHƑ#55Q#5E#,8'5 6FK^P{7g_y-Fޭ"bTiYDqbفl.g.jR4/ d$1A`Q<,1:5$m|ڬ 8tDn`*LCq- "I$PٷdÊgb(HѨ7$ǡi;M#/\W_78ڕ(,/d"B_60 h*sa-n]MA}RЗ0 T%|#, p{ W(4n%Ԣ[xc%~~>OjI:?SQ*):#se#8ba~X2aWJӭzTZ64.#51B}%s]k^v-ai=v䜭r4i>4"< f׸"5,:㻁;˶Lg&؛>f;}J`8$DW5Oا#/˝E`V@)2g 611}Xwh7!#QT7vuI3>_b7Olbwr>^BIDI(%B(jt큃 }'‘n,,).D~G~ǭn~MLFB P,+rc`6'^]hl0UqQ$*}_m[x`fo\e#/1IqokB%W*Y5X6Gg|]821w:*DyG7pl 9R%T:+\~q5gFԲ40bj"Bl3 2&#,LfڟZV) l!4vW"ihbE`BFȄTIx6;8Gxk9ɢK7Pe=#,˳RƘȭhRĹ6sLvA8M'&y DZ(`nQ?i``P̃"7VhͤB[BңS4,UMFY-ms=rkܱQ dg[YE`ٙNcQW gC #SAc՛f&3F|N.c(Fu0\;95`.iа;eC&:V3+:)t[C;Β[.59'<XЎ8-TGIAʅ 4IA#5(4Ýo^+ޞFfkqǗSJj9ڛ cLhG2AkHqlc`CF8 DI"L2C4 xvMBr4"jDβb|ErEbݍc,n#/3AkP- A wFHJKy|2<ht:]#"|͔@4'vdX܏MנarlTew.)z[#594SZ_CJDDP҉,R;a;CCݐ[y&LLs uIf?soYJđq4f@o܌0>LÙSs\Iu`B2 #/H%@ڙju >r+RfCe2g=mtyBCi fE2#,7 @杯̇jXH8΍.Q0tWF;btcir8M(e#?h0._҃ ̖57Ha< $t3 Slti#,sUP& mN5:[V-Pd+к0psW).(Ki 5fP`dYc0;1 \Zg;0SC#,ʩ&;X){(zphKbK&2_6S9`ʌwLx51X0͓~G36 x4~F(ky%\}GGѼ_kp9kIXOb\8WL3f G xıuړ #5tښbo["l]D!*~ ƹȴ7NP٨]<n7Z  zbd׎(102lU7^*X)tfH -1la@1GYv",;CɏZҾR41~X0*ƻ#Ff;&ld#/3Jv2/5ʷF*VDtCH>4[ u,w1`GBmXcyӌ0fE4QHPz!hEAFH"PMO6;S]-2m)\g`unsEv#D" 3Q4"6#/K2DbHbj0Iz#/UO/wHRYu,DJb(Ů#,1a"/eHڂhC3biRCiQ p abb_B֊*EsI`dl!LZ6؈X&݄<B9J(vTPa #5N5P>z}'яuF TTEAGnP]f^=`*;EHH) 5#,E~[ײUAs}<Rt!h}Yn#/ 1DI6C{PUɭd68FﴐMF4ceTdza1MǰQJ( KnZrWO2"H값t֩M7w#sL hR*Q~%Ɂ&He_fơgR"V(nވbm.N柩+5)ʂb}"97METa%{6Iz;x),l._-(Pb⊉`WΌx#Dptr9_MC#,O)1q|:@>* &ɸU$_.h"%Q v@PO.M31<+"ƒbP28dTLc`4kxKbT[A! d A5%TABJJ :#, >l|si(A:nKwLCdd&`R, N{ӳ|B|&>~Fp)~嚈Ά3FPp RKs1VDD 9Y~И]caS&J%u'CAMM iLx)A!H"Cɩ#,0BX<C0m#i#/SuxYz~W&B.Yanp.=qvBtE9"%ks f({AH?[^6ER_ilUH6d5ҌҸ<OE"E I F^dI'W-G*BZ(РK""8[(AK$Aqb#5bA^U lN0ȟ}jmۼ#/UL}m,1+\u01}*f*}3~`P$A #,RE#,22{Nt _O~l&D)萃F&@M6Ee̩T(Gjm9Z]$EuK.Ռ.)@#5ȡ8 o$#/#5b&B!%uPNd;O_vDbLgӁ:·j Ge:zF<5@;:6NEAR!e w˾!Z~N*}f,ŹmOUS/VKh/|tS3;gEe#,#z4Y8?M%N,i!ʅ_#= \lHmc]sF"3+L…mPs,ǍH\h~JubB=ܧPvb~1UrM7=.I}폧.Q?F)dxܼ"D " $Yј"JPkljE+J5m])5k]#/ݨyy#/;Wro=7O]zY > ؂lHa>6LNpN=AU7#5h|>#,t"qvl"HjTv#5d:cDA\r,#/r}MB~e0a##K5 N"i1XY:Ed<饤CM"!,Fهa4š}C;PC-`k9NP+Z-sN ; ÷gl۔I6j*,YphYh[QU#,E% 6آj21pA-a]Z06pM NNJJRS,s#,&àN|P#,:v`R)eZҠA! .d|yl C7Y0ӮepLC8P$ E`AAU=|M#Ɖa-@!R.B6#,Rj#5~'$ceY>QŜ+4Stx_Rk ߅?ɨ|>>o*̌>k,"{M 3Ah'ĖoN憨m4kʫ@(#,$HE*oh侒 ZDbl *|d,)_vX.bv-$HL\VaI)"th5x^5^o+|MET"6uۨ &KQD Q底66@J *p$lO_wy$@! 9@eDM"!5H#,ok",H1FItI܂HKJ$*ehYfKfm_c}W)TCQ4e,ҐIOEP|f7@,)I#,Oc_T6bldMڊ*eF{j@B {(#,D"D-A5uwI⯐A5Cxt{Ġ"WDLp1 $NJ3)S T<j.#‰^?ֽPV$w{>½`Ϟf)B%A{iq2 F1MCXSyL@A|Am6$ɭR)6t )sV7T"J=Z`JH(HeXOnKݨZ} @xR<T-iH؜4#:أ"HhxBVlL?,g.[6oYhD x`n}:(52&RESE)(*"2UBȭm5#5-JᕳQ|dK,'2nD*QE1cGh5 *`'\p]%n ȂdCDZPi!$`'VXjc>W69>Zؖ0l(Cmw_~C+CaXe-#"T44x d`;:`&lkrܒ}}*+|˱\ڍZ[[ƣErG6#Qd8$-#,,&OQϢIu#r"ĺ33AZMM ( phX}tf]JC`aP%LipCq5u]a%AB0Xskn^o*IbݚUҦԡ{V+*TQvך+A#,Ac)H&5h`[R4fZnNERDBNεm!XK=ۗૂYgUf48/1aU3qyjI벩"/PXL*&J8z0lcM=#/fB("y%!^K BA"5#/:8$Q; 6_c MZ׎_k|iinۦJ -~?Prg<h_cBQQ0mT#/(PD>r8_`L9`~٤q<EbHX(MˉKV#5v94k%PmLzl"F\HbqKM|hͤ†pdLT=Ic0d(R CJ'#g1#^3!<2z?2P?>ʿDB6 ʇryc;ݦ"jIb8h#ߎ'\:-i#,e#CaU݁hz:9(dj2*&5趙m߶F [v3äB4Db'RmI*B#BC_`N"Rº#,m2ha/b"fg;Q۬;h-O5zwhi∤A c+qz)\ X7 ut %)`a<z*~L]74̺DSo\-ba.g__~Ͷ^7?_}~<W<n?Y{>_χ~O787v]b"jy65M\?9J<BU!pE!#ZWnwi|y$1y2IRCl`ݐG(Ay4!z#,63]ꥂ?ߞi\pxqF_TK,5()A@|n&8t00QaS<S̍x/?yz6QmI I'e I?@Iq ieq&!3"2*rg {0B ܔ&QFi4).Y/$1UjU2D)(pqX0+ANL1#/(=8C(hkTmѤEpq1ZᖰFHC#/eV#/(kIJi%KK#/(R͎o'?&#/~]13.bV.ȜƲ5(^r#%sVoUyI9ovy#h1 #e۳5c+KMoX`9$C#/VB<)a׻ F6 .׷*Ř/S8`y3DEa 銐Hs#1X͡&Hc|E!Q{ŐP~2 E$yJ'\3Z#,1-  bfiX(/a狸1giZ##R^<S  J%BATZʶJkLC`]#,2ʀqS#,?@2?&<*(y-'3( %T@b(yCGU?ꑌ yN`54%2gFc!t#5dxttt,TG3 #5%so0{Bdk:uNV*K~x=%ȼ=ͩpc]*Se`nL2\as. #^ٲ>,7tQy>*m4ؚ=({.eoD'4TCVzID%%-Wnmk^}IQTZDh#/1(мfӬ"5a+O(~^ K?ď Ki @r19Nac#56K*%*I}0$&Pk##=#5'e".hpH!!7E qFO$v' zj*bECkf˛%jFjro%Wؽh53_Zȣh#,wւw!=~({f80m֟x;.x#/gȤ?EBZv#/l'<U6U']ŨS#/J>{pWi.#/ZXw솯S#l1<yv֏?'* @c\(ks96(hiBos#,g=ə&Y TJ^A/\B:H>zev񉒩~yAS>ӶVJszKpYk#DZ! ^G,$ }YOu68'L*ϫϣo3͏~WՑRs;jb/5Y_V7|{~.p ڋ
-#<==
-#-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v2\n\niQIcBAABCgAGBQJWpU3oAAoJEGelZe39+Q5kv04P/iyvALGAg2Z8oICEDjFkEXWW\nh2CMGLItAhqb3xNeV8WUMMpY4MbRRpN6cU/SPmt+as4oVn2pozca93eWD7yOxukK\n10seOyLTBamS0Wf+BNr6jYXZRQ2N7inc2p6AD75pMOFSg2HeIeQJ0aUIAxNeeojZ\nmUiLYMdtcrF1Kh7KWZAkYSbIAEjJeobLqk2oY7UyqKcODc4RtZJV1InnO4DItEWD\nnd3F5kkVMw4pwYAXaikmCXYBKHXdF5w82KxqEjrAWSoULipX0BVCsSbQ2L0UOs5h\nKXUS4M7AaYKyCcO17E7CnVXaW+vOVyGEECxtSaExWgK5MvYHIGE1OFvb12PkUvUY\nc7CiBxk6X5eZkPyxgxDj20r8zNQVGZ8jDI8Wg08yTAl8+09qCtkE8gGMdNeHYwX8\n2xDH+A3+19022ZZdyO2t5+2AzU6Kkl1qTPKaXJWFRtr8ApD45Y4D3/GAsTNqdOMi\nWeh1XvqQdHjm9rEoJX8aBXShzCMCNhmZalbUhrdzQY6/hnl0PqnlPtyvtkjCvWoF\nXLF6q8YV/ZtqCc36vePZ6lpUQB6FG3g6fhMGraT2VOmT3TROcG17pqIz5y9+85xy\nVSaDc82uHlyzIsZ7vuhV6d9x4yXnFkjMAogCJv6mitFbQsd+LtXYkU+2Zq6wOoEp\ndLLfK0Km4Vs9FYAUbuUi\n=7D7V\n-----END PGP SIGNATURE-----\n
diff --git a/waflib/Build.py b/waflib/Build.py
new file mode 100644
index 0000000..f24ce07
--- /dev/null
+++ b/waflib/Build.py
@@ -0,0 +1,759 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,sys,errno,re,shutil,stat
+try:
+ import cPickle
+except ImportError:
+ import pickle as cPickle
+from waflib import Runner,TaskGen,Utils,ConfigSet,Task,Logs,Options,Context,Errors
+import waflib.Node
+CACHE_DIR='c4che'
+CACHE_SUFFIX='_cache.py'
+INSTALL=1337
+UNINSTALL=-1337
+SAVED_ATTRS='root node_deps raw_deps task_sigs'.split()
+CFG_FILES='cfg_files'
+POST_AT_ONCE=0
+POST_LAZY=1
+POST_BOTH=2
+PROTOCOL=-1
+if sys.platform=='cli':
+ PROTOCOL=0
+class BuildContext(Context.Context):
+ '''executes the build'''
+ cmd='build'
+ variant=''
+ def __init__(self,**kw):
+ super(BuildContext,self).__init__(**kw)
+ self.is_install=0
+ self.top_dir=kw.get('top_dir',Context.top_dir)
+ self.run_dir=kw.get('run_dir',Context.run_dir)
+ self.post_mode=POST_AT_ONCE
+ self.out_dir=kw.get('out_dir',Context.out_dir)
+ self.cache_dir=kw.get('cache_dir',None)
+ if not self.cache_dir:
+ self.cache_dir=os.path.join(self.out_dir,CACHE_DIR)
+ self.all_envs={}
+ self.task_sigs={}
+ self.node_deps={}
+ self.raw_deps={}
+ self.cache_dir_contents={}
+ self.task_gen_cache_names={}
+ self.launch_dir=Context.launch_dir
+ self.jobs=Options.options.jobs
+ self.targets=Options.options.targets
+ self.keep=Options.options.keep
+ self.progress_bar=Options.options.progress_bar
+ self.deps_man=Utils.defaultdict(list)
+ self.current_group=0
+ self.groups=[]
+ self.group_names={}
+ def get_variant_dir(self):
+ if not self.variant:
+ return self.out_dir
+ return os.path.join(self.out_dir,self.variant)
+ variant_dir=property(get_variant_dir,None)
+ def __call__(self,*k,**kw):
+ kw['bld']=self
+ ret=TaskGen.task_gen(*k,**kw)
+ self.task_gen_cache_names={}
+ self.add_to_group(ret,group=kw.get('group',None))
+ return ret
+ def rule(self,*k,**kw):
+ def f(rule):
+ ret=self(*k,**kw)
+ ret.rule=rule
+ return ret
+ return f
+ def __copy__(self):
+ raise Errors.WafError('build contexts are not supposed to be copied')
+ def install_files(self,*k,**kw):
+ pass
+ def install_as(self,*k,**kw):
+ pass
+ def symlink_as(self,*k,**kw):
+ pass
+ def load_envs(self):
+ node=self.root.find_node(self.cache_dir)
+ if not node:
+ raise Errors.WafError('The project was not configured: run "waf configure" first!')
+ lst=node.ant_glob('**/*%s'%CACHE_SUFFIX,quiet=True)
+ if not lst:
+ raise Errors.WafError('The cache directory is empty: reconfigure the project')
+ for x in lst:
+ name=x.path_from(node).replace(CACHE_SUFFIX,'').replace('\\','/')
+ env=ConfigSet.ConfigSet(x.abspath())
+ self.all_envs[name]=env
+ for f in env[CFG_FILES]:
+ newnode=self.root.find_resource(f)
+ try:
+ h=Utils.h_file(newnode.abspath())
+ except(IOError,AttributeError):
+ Logs.error('cannot find %r'%f)
+ h=Utils.SIG_NIL
+ newnode.sig=h
+ def init_dirs(self):
+ if not(os.path.isabs(self.top_dir)and os.path.isabs(self.out_dir)):
+ raise Errors.WafError('The project was not configured: run "waf configure" first!')
+ self.path=self.srcnode=self.root.find_dir(self.top_dir)
+ self.bldnode=self.root.make_node(self.variant_dir)
+ self.bldnode.mkdir()
+ def execute(self):
+ self.restore()
+ if not self.all_envs:
+ self.load_envs()
+ self.execute_build()
+ def execute_build(self):
+ Logs.info("Waf: Entering directory `%s'"%self.variant_dir)
+ self.recurse([self.run_dir])
+ self.pre_build()
+ self.timer=Utils.Timer()
+ try:
+ self.compile()
+ finally:
+ if self.progress_bar==1 and sys.stderr.isatty():
+ c=len(self.returned_tasks)or 1
+ m=self.progress_line(c,c,Logs.colors.BLUE,Logs.colors.NORMAL)
+ Logs.info(m,extra={'stream':sys.stderr,'c1':Logs.colors.cursor_off,'c2':Logs.colors.cursor_on})
+ Logs.info("Waf: Leaving directory `%s'"%self.variant_dir)
+ self.post_build()
+ def restore(self):
+ try:
+ env=ConfigSet.ConfigSet(os.path.join(self.cache_dir,'build.config.py'))
+ except EnvironmentError:
+ pass
+ else:
+ if env['version']<Context.HEXVERSION:
+ raise Errors.WafError('Version mismatch! reconfigure the project')
+ for t in env['tools']:
+ self.setup(**t)
+ dbfn=os.path.join(self.variant_dir,Context.DBFILE)
+ try:
+ data=Utils.readf(dbfn,'rb')
+ except(IOError,EOFError):
+ Logs.debug('build: Could not load the build cache %s (missing)'%dbfn)
+ else:
+ try:
+ waflib.Node.pickle_lock.acquire()
+ waflib.Node.Nod3=self.node_class
+ try:
+ data=cPickle.loads(data)
+ except Exception ,e:
+ Logs.debug('build: Could not pickle the build cache %s: %r'%(dbfn,e))
+ else:
+ for x in SAVED_ATTRS:
+ setattr(self,x,data[x])
+ finally:
+ waflib.Node.pickle_lock.release()
+ self.init_dirs()
+ def store(self):
+ data={}
+ for x in SAVED_ATTRS:
+ data[x]=getattr(self,x)
+ db=os.path.join(self.variant_dir,Context.DBFILE)
+ try:
+ waflib.Node.pickle_lock.acquire()
+ waflib.Node.Nod3=self.node_class
+ x=cPickle.dumps(data,PROTOCOL)
+ finally:
+ waflib.Node.pickle_lock.release()
+ Utils.writef(db+'.tmp',x,m='wb')
+ try:
+ st=os.stat(db)
+ os.remove(db)
+ if not Utils.is_win32:
+ os.chown(db+'.tmp',st.st_uid,st.st_gid)
+ except(AttributeError,OSError):
+ pass
+ os.rename(db+'.tmp',db)
+ def compile(self):
+ Logs.debug('build: compile()')
+ self.producer=Runner.Parallel(self,self.jobs)
+ self.producer.biter=self.get_build_iterator()
+ self.returned_tasks=[]
+ try:
+ self.producer.start()
+ except KeyboardInterrupt:
+ self.store()
+ raise
+ else:
+ if self.producer.dirty:
+ self.store()
+ if self.producer.error:
+ raise Errors.BuildError(self.producer.error)
+ def setup(self,tool,tooldir=None,funs=None):
+ if isinstance(tool,list):
+ for i in tool:self.setup(i,tooldir)
+ return
+ module=Context.load_tool(tool,tooldir)
+ if hasattr(module,"setup"):module.setup(self)
+ def get_env(self):
+ try:
+ return self.all_envs[self.variant]
+ except KeyError:
+ return self.all_envs['']
+ def set_env(self,val):
+ self.all_envs[self.variant]=val
+ env=property(get_env,set_env)
+ def add_manual_dependency(self,path,value):
+ if path is None:
+ raise ValueError('Invalid input')
+ if isinstance(path,waflib.Node.Node):
+ node=path
+ elif os.path.isabs(path):
+ node=self.root.find_resource(path)
+ else:
+ node=self.path.find_resource(path)
+ if isinstance(value,list):
+ self.deps_man[id(node)].extend(value)
+ else:
+ self.deps_man[id(node)].append(value)
+ def launch_node(self):
+ try:
+ return self.p_ln
+ except AttributeError:
+ self.p_ln=self.root.find_dir(self.launch_dir)
+ return self.p_ln
+ def hash_env_vars(self,env,vars_lst):
+ if not env.table:
+ env=env.parent
+ if not env:
+ return Utils.SIG_NIL
+ idx=str(id(env))+str(vars_lst)
+ try:
+ cache=self.cache_env
+ except AttributeError:
+ cache=self.cache_env={}
+ else:
+ try:
+ return self.cache_env[idx]
+ except KeyError:
+ pass
+ lst=[env[a]for a in vars_lst]
+ ret=Utils.h_list(lst)
+ Logs.debug('envhash: %s %r',Utils.to_hex(ret),lst)
+ cache[idx]=ret
+ return ret
+ def get_tgen_by_name(self,name):
+ cache=self.task_gen_cache_names
+ if not cache:
+ for g in self.groups:
+ for tg in g:
+ try:
+ cache[tg.name]=tg
+ except AttributeError:
+ pass
+ try:
+ return cache[name]
+ except KeyError:
+ raise Errors.WafError('Could not find a task generator for the name %r'%name)
+ def progress_line(self,state,total,col1,col2):
+ if not sys.stderr.isatty():
+ return''
+ n=len(str(total))
+ Utils.rot_idx+=1
+ ind=Utils.rot_chr[Utils.rot_idx%4]
+ pc=(100.*state)/total
+ eta=str(self.timer)
+ fs="[%%%dd/%%%dd][%%s%%2d%%%%%%s][%s]["%(n,n,ind)
+ left=fs%(state,total,col1,pc,col2)
+ right='][%s%s%s]'%(col1,eta,col2)
+ cols=Logs.get_term_cols()-len(left)-len(right)+2*len(col1)+2*len(col2)
+ if cols<7:cols=7
+ ratio=((cols*state)//total)-1
+ bar=('='*ratio+'>').ljust(cols)
+ msg=Logs.indicator%(left,bar,right)
+ return msg
+ def declare_chain(self,*k,**kw):
+ return TaskGen.declare_chain(*k,**kw)
+ def pre_build(self):
+ for m in getattr(self,'pre_funs',[]):
+ m(self)
+ def post_build(self):
+ for m in getattr(self,'post_funs',[]):
+ m(self)
+ def add_pre_fun(self,meth):
+ try:
+ self.pre_funs.append(meth)
+ except AttributeError:
+ self.pre_funs=[meth]
+ def add_post_fun(self,meth):
+ try:
+ self.post_funs.append(meth)
+ except AttributeError:
+ self.post_funs=[meth]
+ def get_group(self,x):
+ if not self.groups:
+ self.add_group()
+ if x is None:
+ return self.groups[self.current_group]
+ if x in self.group_names:
+ return self.group_names[x]
+ return self.groups[x]
+ def add_to_group(self,tgen,group=None):
+ assert(isinstance(tgen,TaskGen.task_gen)or isinstance(tgen,Task.TaskBase))
+ tgen.bld=self
+ self.get_group(group).append(tgen)
+ def get_group_name(self,g):
+ if not isinstance(g,list):
+ g=self.groups[g]
+ for x in self.group_names:
+ if id(self.group_names[x])==id(g):
+ return x
+ return''
+ def get_group_idx(self,tg):
+ se=id(tg)
+ for i in range(len(self.groups)):
+ for t in self.groups[i]:
+ if id(t)==se:
+ return i
+ return None
+ def add_group(self,name=None,move=True):
+ if name and name in self.group_names:
+ Logs.error('add_group: name %s already present'%name)
+ g=[]
+ self.group_names[name]=g
+ self.groups.append(g)
+ if move:
+ self.current_group=len(self.groups)-1
+ def set_group(self,idx):
+ if isinstance(idx,str):
+ g=self.group_names[idx]
+ for i in range(len(self.groups)):
+ if id(g)==id(self.groups[i]):
+ self.current_group=i
+ break
+ else:
+ self.current_group=idx
+ def total(self):
+ total=0
+ for group in self.groups:
+ for tg in group:
+ try:
+ total+=len(tg.tasks)
+ except AttributeError:
+ total+=1
+ return total
+ def get_targets(self):
+ to_post=[]
+ min_grp=0
+ for name in self.targets.split(','):
+ tg=self.get_tgen_by_name(name)
+ m=self.get_group_idx(tg)
+ if m>min_grp:
+ min_grp=m
+ to_post=[tg]
+ elif m==min_grp:
+ to_post.append(tg)
+ return(min_grp,to_post)
+ def get_all_task_gen(self):
+ lst=[]
+ for g in self.groups:
+ lst.extend(g)
+ return lst
+ def post_group(self):
+ if self.targets=='*':
+ for tg in self.groups[self.cur]:
+ try:
+ f=tg.post
+ except AttributeError:
+ pass
+ else:
+ f()
+ elif self.targets:
+ if self.cur<self._min_grp:
+ for tg in self.groups[self.cur]:
+ try:
+ f=tg.post
+ except AttributeError:
+ pass
+ else:
+ f()
+ else:
+ for tg in self._exact_tg:
+ tg.post()
+ else:
+ ln=self.launch_node()
+ if ln.is_child_of(self.bldnode):
+ Logs.warn('Building from the build directory, forcing --targets=*')
+ ln=self.srcnode
+ elif not ln.is_child_of(self.srcnode):
+ Logs.warn('CWD %s is not under %s, forcing --targets=* (run distclean?)'%(ln.abspath(),self.srcnode.abspath()))
+ ln=self.srcnode
+ for tg in self.groups[self.cur]:
+ try:
+ f=tg.post
+ except AttributeError:
+ pass
+ else:
+ if tg.path.is_child_of(ln):
+ f()
+ def get_tasks_group(self,idx):
+ tasks=[]
+ for tg in self.groups[idx]:
+ try:
+ tasks.extend(tg.tasks)
+ except AttributeError:
+ tasks.append(tg)
+ return tasks
+ def get_build_iterator(self):
+ self.cur=0
+ if self.targets and self.targets!='*':
+ (self._min_grp,self._exact_tg)=self.get_targets()
+ global lazy_post
+ if self.post_mode!=POST_LAZY:
+ while self.cur<len(self.groups):
+ self.post_group()
+ self.cur+=1
+ self.cur=0
+ while self.cur<len(self.groups):
+ if self.post_mode!=POST_AT_ONCE:
+ self.post_group()
+ tasks=self.get_tasks_group(self.cur)
+ Task.set_file_constraints(tasks)
+ Task.set_precedence_constraints(tasks)
+ self.cur_tasks=tasks
+ self.cur+=1
+ if not tasks:
+ continue
+ yield tasks
+ while 1:
+ yield[]
+class inst(Task.Task):
+ color='CYAN'
+ def uid(self):
+ lst=[self.dest,self.path]+self.source
+ return Utils.h_list(repr(lst))
+ def post(self):
+ buf=[]
+ for x in self.source:
+ if isinstance(x,waflib.Node.Node):
+ y=x
+ else:
+ y=self.path.find_resource(x)
+ if not y:
+ if os.path.isabs(x):
+ y=self.bld.root.make_node(x)
+ else:
+ y=self.path.make_node(x)
+ buf.append(y)
+ self.inputs=buf
+ def runnable_status(self):
+ ret=super(inst,self).runnable_status()
+ if ret==Task.SKIP_ME:
+ return Task.RUN_ME
+ return ret
+ def __str__(self):
+ return''
+ def run(self):
+ return self.generator.exec_task()
+ def get_install_path(self,destdir=True):
+ dest=Utils.subst_vars(self.dest,self.env)
+ dest=dest.replace('/',os.sep)
+ if destdir and Options.options.destdir:
+ dest=os.path.join(Options.options.destdir,os.path.splitdrive(dest)[1].lstrip(os.sep))
+ return dest
+ def exec_install_files(self):
+ destpath=self.get_install_path()
+ if not destpath:
+ raise Errors.WafError('unknown installation path %r'%self.generator)
+ for x,y in zip(self.source,self.inputs):
+ if self.relative_trick:
+ destfile=os.path.join(destpath,y.path_from(self.path))
+ else:
+ destfile=os.path.join(destpath,y.name)
+ self.generator.bld.do_install(y.abspath(),destfile,chmod=self.chmod,tsk=self)
+ def exec_install_as(self):
+ destfile=self.get_install_path()
+ self.generator.bld.do_install(self.inputs[0].abspath(),destfile,chmod=self.chmod,tsk=self)
+ def exec_symlink_as(self):
+ destfile=self.get_install_path()
+ src=self.link
+ if self.relative_trick:
+ src=os.path.relpath(src,os.path.dirname(destfile))
+ self.generator.bld.do_link(src,destfile,tsk=self)
+class InstallContext(BuildContext):
+ '''installs the targets on the system'''
+ cmd='install'
+ def __init__(self,**kw):
+ super(InstallContext,self).__init__(**kw)
+ self.uninstall=[]
+ self.is_install=INSTALL
+ def copy_fun(self,src,tgt,**kw):
+ if Utils.is_win32 and len(tgt)>259 and not tgt.startswith('\\\\?\\'):
+ tgt='\\\\?\\'+tgt
+ shutil.copy2(src,tgt)
+ os.chmod(tgt,kw.get('chmod',Utils.O644))
+ def do_install(self,src,tgt,**kw):
+ d,_=os.path.split(tgt)
+ if not d:
+ raise Errors.WafError('Invalid installation given %r->%r'%(src,tgt))
+ Utils.check_dir(d)
+ srclbl=src.replace(self.srcnode.abspath()+os.sep,'')
+ if not Options.options.force:
+ try:
+ st1=os.stat(tgt)
+ st2=os.stat(src)
+ except OSError:
+ pass
+ else:
+ if st1.st_mtime+2>=st2.st_mtime and st1.st_size==st2.st_size:
+ if not self.progress_bar:
+ Logs.info('- install %s (from %s)'%(tgt,srclbl))
+ return False
+ if not self.progress_bar:
+ Logs.info('+ install %s (from %s)'%(tgt,srclbl))
+ try:
+ os.chmod(tgt,Utils.O644|stat.S_IMODE(os.stat(tgt).st_mode))
+ except EnvironmentError:
+ pass
+ try:
+ os.remove(tgt)
+ except OSError:
+ pass
+ try:
+ self.copy_fun(src,tgt,**kw)
+ except IOError:
+ try:
+ os.stat(src)
+ except EnvironmentError:
+ Logs.error('File %r does not exist'%src)
+ raise Errors.WafError('Could not install the file %r'%tgt)
+ def do_link(self,src,tgt,**kw):
+ d,_=os.path.split(tgt)
+ Utils.check_dir(d)
+ link=False
+ if not os.path.islink(tgt):
+ link=True
+ elif os.readlink(tgt)!=src:
+ link=True
+ if link:
+ try:os.remove(tgt)
+ except OSError:pass
+ if not self.progress_bar:
+ Logs.info('+ symlink %s (to %s)'%(tgt,src))
+ os.symlink(src,tgt)
+ else:
+ if not self.progress_bar:
+ Logs.info('- symlink %s (to %s)'%(tgt,src))
+ def run_task_now(self,tsk,postpone):
+ tsk.post()
+ if not postpone:
+ if tsk.runnable_status()==Task.ASK_LATER:
+ raise self.WafError('cannot post the task %r'%tsk)
+ tsk.run()
+ tsk.hasrun=True
+ def install_files(self,dest,files,env=None,chmod=Utils.O644,relative_trick=False,cwd=None,add=True,postpone=True,task=None):
+ assert(dest)
+ tsk=inst(env=env or self.env)
+ tsk.bld=self
+ tsk.path=cwd or self.path
+ tsk.chmod=chmod
+ tsk.task=task
+ if isinstance(files,waflib.Node.Node):
+ tsk.source=[files]
+ else:
+ tsk.source=Utils.to_list(files)
+ tsk.dest=dest
+ tsk.exec_task=tsk.exec_install_files
+ tsk.relative_trick=relative_trick
+ if add:self.add_to_group(tsk)
+ self.run_task_now(tsk,postpone)
+ return tsk
+ def install_as(self,dest,srcfile,env=None,chmod=Utils.O644,cwd=None,add=True,postpone=True,task=None):
+ assert(dest)
+ tsk=inst(env=env or self.env)
+ tsk.bld=self
+ tsk.path=cwd or self.path
+ tsk.chmod=chmod
+ tsk.source=[srcfile]
+ tsk.task=task
+ tsk.dest=dest
+ tsk.exec_task=tsk.exec_install_as
+ if add:self.add_to_group(tsk)
+ self.run_task_now(tsk,postpone)
+ return tsk
+ def symlink_as(self,dest,src,env=None,cwd=None,add=True,postpone=True,relative_trick=False,task=None):
+ if Utils.is_win32:
+ return
+ assert(dest)
+ tsk=inst(env=env or self.env)
+ tsk.bld=self
+ tsk.dest=dest
+ tsk.path=cwd or self.path
+ tsk.source=[]
+ tsk.task=task
+ tsk.link=src
+ tsk.relative_trick=relative_trick
+ tsk.exec_task=tsk.exec_symlink_as
+ if add:self.add_to_group(tsk)
+ self.run_task_now(tsk,postpone)
+ return tsk
+class UninstallContext(InstallContext):
+ '''removes the targets installed'''
+ cmd='uninstall'
+ def __init__(self,**kw):
+ super(UninstallContext,self).__init__(**kw)
+ self.is_install=UNINSTALL
+ def rm_empty_dirs(self,tgt):
+ while tgt:
+ tgt=os.path.dirname(tgt)
+ try:
+ os.rmdir(tgt)
+ except OSError:
+ break
+ def do_install(self,src,tgt,**kw):
+ if not self.progress_bar:
+ Logs.info('- remove %s'%tgt)
+ self.uninstall.append(tgt)
+ try:
+ os.remove(tgt)
+ except OSError ,e:
+ if e.errno!=errno.ENOENT:
+ if not getattr(self,'uninstall_error',None):
+ self.uninstall_error=True
+ Logs.warn('build: some files could not be uninstalled (retry with -vv to list them)')
+ if Logs.verbose>1:
+ Logs.warn('Could not remove %s (error code %r)'%(e.filename,e.errno))
+ self.rm_empty_dirs(tgt)
+ def do_link(self,src,tgt,**kw):
+ try:
+ if not self.progress_bar:
+ Logs.info('- remove %s'%tgt)
+ os.remove(tgt)
+ except OSError:
+ pass
+ self.rm_empty_dirs(tgt)
+ def execute(self):
+ try:
+ def runnable_status(self):
+ return Task.SKIP_ME
+ setattr(Task.Task,'runnable_status_back',Task.Task.runnable_status)
+ setattr(Task.Task,'runnable_status',runnable_status)
+ super(UninstallContext,self).execute()
+ finally:
+ setattr(Task.Task,'runnable_status',Task.Task.runnable_status_back)
+class CleanContext(BuildContext):
+ '''cleans the project'''
+ cmd='clean'
+ def execute(self):
+ self.restore()
+ if not self.all_envs:
+ self.load_envs()
+ self.recurse([self.run_dir])
+ try:
+ self.clean()
+ finally:
+ self.store()
+ def clean(self):
+ Logs.debug('build: clean called')
+ if self.bldnode!=self.srcnode:
+ lst=[]
+ for e in self.all_envs.values():
+ lst.extend(self.root.find_or_declare(f)for f in e[CFG_FILES])
+ for n in self.bldnode.ant_glob('**/*',excl='.lock* *conf_check_*/** config.log c4che/*',quiet=True):
+ if n in lst:
+ continue
+ n.delete()
+ self.root.children={}
+ for v in'node_deps task_sigs raw_deps'.split():
+ setattr(self,v,{})
+class ListContext(BuildContext):
+ '''lists the targets to execute'''
+ cmd='list'
+ def execute(self):
+ self.restore()
+ if not self.all_envs:
+ self.load_envs()
+ self.recurse([self.run_dir])
+ self.pre_build()
+ self.timer=Utils.Timer()
+ for g in self.groups:
+ for tg in g:
+ try:
+ f=tg.post
+ except AttributeError:
+ pass
+ else:
+ f()
+ try:
+ self.get_tgen_by_name('')
+ except Exception:
+ pass
+ lst=list(self.task_gen_cache_names.keys())
+ lst.sort()
+ for k in lst:
+ Logs.pprint('GREEN',k)
+class StepContext(BuildContext):
+ '''executes tasks in a step-by-step fashion, for debugging'''
+ cmd='step'
+ def __init__(self,**kw):
+ super(StepContext,self).__init__(**kw)
+ self.files=Options.options.files
+ def compile(self):
+ if not self.files:
+ Logs.warn('Add a pattern for the debug build, for example "waf step --files=main.c,app"')
+ BuildContext.compile(self)
+ return
+ targets=None
+ if self.targets and self.targets!='*':
+ targets=self.targets.split(',')
+ for g in self.groups:
+ for tg in g:
+ if targets and tg.name not in targets:
+ continue
+ try:
+ f=tg.post
+ except AttributeError:
+ pass
+ else:
+ f()
+ for pat in self.files.split(','):
+ matcher=self.get_matcher(pat)
+ for tg in g:
+ if isinstance(tg,Task.TaskBase):
+ lst=[tg]
+ else:
+ lst=tg.tasks
+ for tsk in lst:
+ do_exec=False
+ for node in getattr(tsk,'inputs',[]):
+ if matcher(node,output=False):
+ do_exec=True
+ break
+ for node in getattr(tsk,'outputs',[]):
+ if matcher(node,output=True):
+ do_exec=True
+ break
+ if do_exec:
+ ret=tsk.run()
+ Logs.info('%s -> exit %r'%(str(tsk),ret))
+ def get_matcher(self,pat):
+ inn=True
+ out=True
+ if pat.startswith('in:'):
+ out=False
+ pat=pat.replace('in:','')
+ elif pat.startswith('out:'):
+ inn=False
+ pat=pat.replace('out:','')
+ anode=self.root.find_node(pat)
+ pattern=None
+ if not anode:
+ if not pat.startswith('^'):
+ pat='^.+?%s'%pat
+ if not pat.endswith('$'):
+ pat='%s$'%pat
+ pattern=re.compile(pat)
+ def match(node,output):
+ if output==True and not out:
+ return False
+ if output==False and not inn:
+ return False
+ if anode:
+ return anode==node
+ else:
+ return pattern.match(node.abspath())
+ return match
diff --git a/waflib/ConfigSet.py b/waflib/ConfigSet.py
new file mode 100644
index 0000000..3a86efe
--- /dev/null
+++ b/waflib/ConfigSet.py
@@ -0,0 +1,153 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import copy,re,os
+from waflib import Logs,Utils
+re_imp=re.compile('^(#)*?([^#=]*?)\ =\ (.*?)$',re.M)
+class ConfigSet(object):
+ __slots__=('table','parent')
+ def __init__(self,filename=None):
+ self.table={}
+ if filename:
+ self.load(filename)
+ def __contains__(self,key):
+ if key in self.table:return True
+ try:return self.parent.__contains__(key)
+ except AttributeError:return False
+ def keys(self):
+ keys=set()
+ cur=self
+ while cur:
+ keys.update(cur.table.keys())
+ cur=getattr(cur,'parent',None)
+ keys=list(keys)
+ keys.sort()
+ return keys
+ def __str__(self):
+ return"\n".join(["%r %r"%(x,self.__getitem__(x))for x in self.keys()])
+ def __getitem__(self,key):
+ try:
+ while 1:
+ x=self.table.get(key,None)
+ if not x is None:
+ return x
+ self=self.parent
+ except AttributeError:
+ return[]
+ def __setitem__(self,key,value):
+ self.table[key]=value
+ def __delitem__(self,key):
+ self[key]=[]
+ def __getattr__(self,name):
+ if name in self.__slots__:
+ return object.__getattr__(self,name)
+ else:
+ return self[name]
+ def __setattr__(self,name,value):
+ if name in self.__slots__:
+ object.__setattr__(self,name,value)
+ else:
+ self[name]=value
+ def __delattr__(self,name):
+ if name in self.__slots__:
+ object.__delattr__(self,name)
+ else:
+ del self[name]
+ def derive(self):
+ newenv=ConfigSet()
+ newenv.parent=self
+ return newenv
+ def detach(self):
+ tbl=self.get_merged_dict()
+ try:
+ delattr(self,'parent')
+ except AttributeError:
+ pass
+ else:
+ keys=tbl.keys()
+ for x in keys:
+ tbl[x]=copy.deepcopy(tbl[x])
+ self.table=tbl
+ return self
+ def get_flat(self,key):
+ s=self[key]
+ if isinstance(s,str):return s
+ return' '.join(s)
+ def _get_list_value_for_modification(self,key):
+ try:
+ value=self.table[key]
+ except KeyError:
+ try:value=self.parent[key]
+ except AttributeError:value=[]
+ if isinstance(value,list):
+ value=value[:]
+ else:
+ value=[value]
+ else:
+ if not isinstance(value,list):
+ value=[value]
+ self.table[key]=value
+ return value
+ def append_value(self,var,val):
+ if isinstance(val,str):
+ val=[val]
+ current_value=self._get_list_value_for_modification(var)
+ current_value.extend(val)
+ def prepend_value(self,var,val):
+ if isinstance(val,str):
+ val=[val]
+ self.table[var]=val+self._get_list_value_for_modification(var)
+ def append_unique(self,var,val):
+ if isinstance(val,str):
+ val=[val]
+ current_value=self._get_list_value_for_modification(var)
+ for x in val:
+ if x not in current_value:
+ current_value.append(x)
+ def get_merged_dict(self):
+ table_list=[]
+ env=self
+ while 1:
+ table_list.insert(0,env.table)
+ try:env=env.parent
+ except AttributeError:break
+ merged_table={}
+ for table in table_list:
+ merged_table.update(table)
+ return merged_table
+ def store(self,filename):
+ try:
+ os.makedirs(os.path.split(filename)[0])
+ except OSError:
+ pass
+ buf=[]
+ merged_table=self.get_merged_dict()
+ keys=list(merged_table.keys())
+ keys.sort()
+ try:
+ fun=ascii
+ except NameError:
+ fun=repr
+ for k in keys:
+ if k!='undo_stack':
+ buf.append('%s = %s\n'%(k,fun(merged_table[k])))
+ Utils.writef(filename,''.join(buf))
+ def load(self,filename):
+ tbl=self.table
+ code=Utils.readf(filename,m='rU')
+ for m in re_imp.finditer(code):
+ g=m.group
+ tbl[g(2)]=eval(g(3))
+ Logs.debug('env: %s'%str(self.table))
+ def update(self,d):
+ for k,v in d.items():
+ self[k]=v
+ def stash(self):
+ orig=self.table
+ tbl=self.table=self.table.copy()
+ for x in tbl.keys():
+ tbl[x]=copy.deepcopy(tbl[x])
+ self.undo_stack=self.undo_stack+[orig]
+ def revert(self):
+ self.table=self.undo_stack.pop(-1)
diff --git a/waflib/Configure.py b/waflib/Configure.py
new file mode 100644
index 0000000..97ce134
--- /dev/null
+++ b/waflib/Configure.py
@@ -0,0 +1,379 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,shlex,sys,time,re,shutil
+from waflib import ConfigSet,Utils,Options,Logs,Context,Build,Errors
+BREAK='break'
+CONTINUE='continue'
+WAF_CONFIG_LOG='config.log'
+autoconfig=False
+conf_template='''# project %(app)s configured on %(now)s by
+# waf %(wafver)s (abi %(abi)s, python %(pyver)x on %(systype)s)
+# using %(args)s
+#'''
+class ConfigurationContext(Context.Context):
+ '''configures the project'''
+ cmd='configure'
+ error_handlers=[]
+ def __init__(self,**kw):
+ super(ConfigurationContext,self).__init__(**kw)
+ self.environ=dict(os.environ)
+ self.all_envs={}
+ self.top_dir=None
+ self.out_dir=None
+ self.tools=[]
+ self.hash=0
+ self.files=[]
+ self.tool_cache=[]
+ self.setenv('')
+ def setenv(self,name,env=None):
+ if name not in self.all_envs or env:
+ if not env:
+ env=ConfigSet.ConfigSet()
+ self.prepare_env(env)
+ else:
+ env=env.derive()
+ self.all_envs[name]=env
+ self.variant=name
+ def get_env(self):
+ return self.all_envs[self.variant]
+ def set_env(self,val):
+ self.all_envs[self.variant]=val
+ env=property(get_env,set_env)
+ def init_dirs(self):
+ top=self.top_dir
+ if not top:
+ top=Options.options.top
+ if not top:
+ top=getattr(Context.g_module,Context.TOP,None)
+ if not top:
+ top=self.path.abspath()
+ top=os.path.abspath(top)
+ self.srcnode=(os.path.isabs(top)and self.root or self.path).find_dir(top)
+ assert(self.srcnode)
+ out=self.out_dir
+ if not out:
+ out=Options.options.out
+ if not out:
+ out=getattr(Context.g_module,Context.OUT,None)
+ if not out:
+ out=Options.lockfile.replace('.lock-waf_%s_'%sys.platform,'').replace('.lock-waf','')
+ out=os.path.realpath(out)
+ self.bldnode=(os.path.isabs(out)and self.root or self.path).make_node(out)
+ self.bldnode.mkdir()
+ if not os.path.isdir(self.bldnode.abspath()):
+ conf.fatal('Could not create the build directory %s'%self.bldnode.abspath())
+ def execute(self):
+ self.init_dirs()
+ self.cachedir=self.bldnode.make_node(Build.CACHE_DIR)
+ self.cachedir.mkdir()
+ path=os.path.join(self.bldnode.abspath(),WAF_CONFIG_LOG)
+ self.logger=Logs.make_logger(path,'cfg')
+ app=getattr(Context.g_module,'APPNAME','')
+ if app:
+ ver=getattr(Context.g_module,'VERSION','')
+ if ver:
+ app="%s (%s)"%(app,ver)
+ params={'now':time.ctime(),'pyver':sys.hexversion,'systype':sys.platform,'args':" ".join(sys.argv),'wafver':Context.WAFVERSION,'abi':Context.ABI,'app':app}
+ self.to_log(conf_template%params)
+ self.msg('Setting top to',self.srcnode.abspath())
+ self.msg('Setting out to',self.bldnode.abspath())
+ if id(self.srcnode)==id(self.bldnode):
+ Logs.warn('Setting top == out (remember to use "update_outputs")')
+ elif id(self.path)!=id(self.srcnode):
+ if self.srcnode.is_child_of(self.path):
+ Logs.warn('Are you certain that you do not want to set top="." ?')
+ super(ConfigurationContext,self).execute()
+ self.store()
+ Context.top_dir=self.srcnode.abspath()
+ Context.out_dir=self.bldnode.abspath()
+ env=ConfigSet.ConfigSet()
+ env['argv']=sys.argv
+ env['options']=Options.options.__dict__
+ env.run_dir=Context.run_dir
+ env.top_dir=Context.top_dir
+ env.out_dir=Context.out_dir
+ env['hash']=self.hash
+ env['files']=self.files
+ env['environ']=dict(self.environ)
+ if not self.env.NO_LOCK_IN_RUN and not getattr(Options.options,'no_lock_in_run'):
+ env.store(os.path.join(Context.run_dir,Options.lockfile))
+ if not self.env.NO_LOCK_IN_TOP and not getattr(Options.options,'no_lock_in_top'):
+ env.store(os.path.join(Context.top_dir,Options.lockfile))
+ if not self.env.NO_LOCK_IN_OUT and not getattr(Options.options,'no_lock_in_out'):
+ env.store(os.path.join(Context.out_dir,Options.lockfile))
+ def prepare_env(self,env):
+ if not env.PREFIX:
+ if Options.options.prefix or Utils.is_win32:
+ env.PREFIX=Utils.sane_path(Options.options.prefix)
+ else:
+ env.PREFIX=''
+ if not env.BINDIR:
+ if Options.options.bindir:
+ env.BINDIR=Utils.sane_path(Options.options.bindir)
+ else:
+ env.BINDIR=Utils.subst_vars('${PREFIX}/bin',env)
+ if not env.LIBDIR:
+ if Options.options.libdir:
+ env.LIBDIR=Utils.sane_path(Options.options.libdir)
+ else:
+ env.LIBDIR=Utils.subst_vars('${PREFIX}/lib%s'%Utils.lib64(),env)
+ def store(self):
+ n=self.cachedir.make_node('build.config.py')
+ n.write('version = 0x%x\ntools = %r\n'%(Context.HEXVERSION,self.tools))
+ if not self.all_envs:
+ self.fatal('nothing to store in the configuration context!')
+ for key in self.all_envs:
+ tmpenv=self.all_envs[key]
+ tmpenv.store(os.path.join(self.cachedir.abspath(),key+Build.CACHE_SUFFIX))
+ def load(self,input,tooldir=None,funs=None,with_sys_path=True):
+ tools=Utils.to_list(input)
+ if tooldir:tooldir=Utils.to_list(tooldir)
+ for tool in tools:
+ mag=(tool,id(self.env),tooldir,funs)
+ if mag in self.tool_cache:
+ self.to_log('(tool %s is already loaded, skipping)'%tool)
+ continue
+ self.tool_cache.append(mag)
+ module=None
+ try:
+ module=Context.load_tool(tool,tooldir,ctx=self,with_sys_path=with_sys_path)
+ except ImportError ,e:
+ self.fatal('Could not load the Waf tool %r from %r\n%s'%(tool,sys.path,e))
+ except Exception ,e:
+ self.to_log('imp %r (%r & %r)'%(tool,tooldir,funs))
+ self.to_log(Utils.ex_stack())
+ raise
+ if funs is not None:
+ self.eval_rules(funs)
+ else:
+ func=getattr(module,'configure',None)
+ if func:
+ if type(func)is type(Utils.readf):func(self)
+ else:self.eval_rules(func)
+ self.tools.append({'tool':tool,'tooldir':tooldir,'funs':funs})
+ def post_recurse(self,node):
+ super(ConfigurationContext,self).post_recurse(node)
+ self.hash=Utils.h_list((self.hash,node.read('rb')))
+ self.files.append(node.abspath())
+ def eval_rules(self,rules):
+ self.rules=Utils.to_list(rules)
+ for x in self.rules:
+ f=getattr(self,x)
+ if not f:self.fatal("No such method '%s'."%x)
+ try:
+ f()
+ except Exception ,e:
+ ret=self.err_handler(x,e)
+ if ret==BREAK:
+ break
+ elif ret==CONTINUE:
+ continue
+ else:
+ raise
+ def err_handler(self,fun,error):
+ pass
+def conf(f):
+ def fun(*k,**kw):
+ mandatory=True
+ if'mandatory'in kw:
+ mandatory=kw['mandatory']
+ del kw['mandatory']
+ try:
+ return f(*k,**kw)
+ except Errors.ConfigurationError:
+ if mandatory:
+ raise
+ fun.__name__=f.__name__
+ setattr(ConfigurationContext,f.__name__,fun)
+ setattr(Build.BuildContext,f.__name__,fun)
+ return f
+@conf
+def add_os_flags(self,var,dest=None,dup=True):
+ try:
+ flags=shlex.split(self.environ[var])
+ except KeyError:
+ return
+ if dup or''.join(flags)not in''.join(Utils.to_list(self.env[dest or var])):
+ self.env.append_value(dest or var,flags)
+@conf
+def cmd_to_list(self,cmd):
+ if isinstance(cmd,str)and cmd.find(' '):
+ try:
+ os.stat(cmd)
+ except OSError:
+ return shlex.split(cmd)
+ else:
+ return[cmd]
+ return cmd
+@conf
+def check_waf_version(self,mini='1.7.99',maxi='1.9.0',**kw):
+ self.start_msg('Checking for waf version in %s-%s'%(str(mini),str(maxi)),**kw)
+ ver=Context.HEXVERSION
+ if Utils.num2ver(mini)>ver:
+ self.fatal('waf version should be at least %r (%r found)'%(Utils.num2ver(mini),ver))
+ if Utils.num2ver(maxi)<ver:
+ self.fatal('waf version should be at most %r (%r found)'%(Utils.num2ver(maxi),ver))
+ self.end_msg('ok',**kw)
+@conf
+def find_file(self,filename,path_list=[]):
+ for n in Utils.to_list(filename):
+ for d in Utils.to_list(path_list):
+ p=os.path.expanduser(os.path.join(d,n))
+ if os.path.exists(p):
+ return p
+ self.fatal('Could not find %r'%filename)
+@conf
+def find_program(self,filename,**kw):
+ exts=kw.get('exts',Utils.is_win32 and'.exe,.com,.bat,.cmd'or',.sh,.pl,.py')
+ environ=kw.get('environ',getattr(self,'environ',os.environ))
+ ret=''
+ filename=Utils.to_list(filename)
+ msg=kw.get('msg',', '.join(filename))
+ var=kw.get('var','')
+ if not var:
+ var=re.sub(r'[-.]','_',filename[0].upper())
+ path_list=kw.get('path_list','')
+ if path_list:
+ path_list=Utils.to_list(path_list)
+ else:
+ path_list=environ.get('PATH','').split(os.pathsep)
+ if var in environ:
+ filename=environ[var]
+ if os.path.isfile(filename):
+ ret=[filename]
+ else:
+ ret=self.cmd_to_list(filename)
+ elif self.env[var]:
+ ret=self.env[var]
+ ret=self.cmd_to_list(ret)
+ else:
+ if not ret:
+ ret=self.find_binary(filename,exts.split(','),path_list)
+ if not ret and Utils.winreg:
+ ret=Utils.get_registry_app_path(Utils.winreg.HKEY_CURRENT_USER,filename)
+ if not ret and Utils.winreg:
+ ret=Utils.get_registry_app_path(Utils.winreg.HKEY_LOCAL_MACHINE,filename)
+ ret=self.cmd_to_list(ret)
+ if ret:
+ if len(ret)==1:
+ retmsg=ret[0]
+ else:
+ retmsg=ret
+ else:
+ retmsg=False
+ self.msg("Checking for program '%s'"%msg,retmsg,**kw)
+ if not kw.get('quiet',None):
+ self.to_log('find program=%r paths=%r var=%r -> %r'%(filename,path_list,var,ret))
+ if not ret:
+ self.fatal(kw.get('errmsg','')or'Could not find the program %r'%filename)
+ interpreter=kw.get('interpreter',None)
+ if interpreter is None:
+ if not Utils.check_exe(ret[0],env=environ):
+ self.fatal('Program %r is not executable'%ret)
+ self.env[var]=ret
+ else:
+ self.env[var]=self.env[interpreter]+ret
+ return ret
+@conf
+def find_binary(self,filenames,exts,paths):
+ for f in filenames:
+ for ext in exts:
+ exe_name=f+ext
+ if os.path.isabs(exe_name):
+ if os.path.isfile(exe_name):
+ return exe_name
+ else:
+ for path in paths:
+ x=os.path.expanduser(os.path.join(path,exe_name))
+ if os.path.isfile(x):
+ return x
+ return None
+@conf
+def run_build(self,*k,**kw):
+ lst=[str(v)for(p,v)in kw.items()if p!='env']
+ h=Utils.h_list(lst)
+ dir=self.bldnode.abspath()+os.sep+(not Utils.is_win32 and'.'or'')+'conf_check_'+Utils.to_hex(h)
+ try:
+ os.makedirs(dir)
+ except OSError:
+ pass
+ try:
+ os.stat(dir)
+ except OSError:
+ self.fatal('cannot use the configuration test folder %r'%dir)
+ cachemode=getattr(Options.options,'confcache',None)
+ if cachemode==1:
+ try:
+ proj=ConfigSet.ConfigSet(os.path.join(dir,'cache_run_build'))
+ except OSError:
+ pass
+ except IOError:
+ pass
+ else:
+ ret=proj['cache_run_build']
+ if isinstance(ret,str)and ret.startswith('Test does not build'):
+ self.fatal(ret)
+ return ret
+ bdir=os.path.join(dir,'testbuild')
+ if not os.path.exists(bdir):
+ os.makedirs(bdir)
+ self.test_bld=bld=Build.BuildContext(top_dir=dir,out_dir=bdir)
+ bld.init_dirs()
+ bld.progress_bar=0
+ bld.targets='*'
+ bld.logger=self.logger
+ bld.all_envs.update(self.all_envs)
+ bld.env=kw['env']
+ bld.kw=kw
+ bld.conf=self
+ kw['build_fun'](bld)
+ ret=-1
+ try:
+ try:
+ bld.compile()
+ except Errors.WafError:
+ ret='Test does not build: %s'%Utils.ex_stack()
+ self.fatal(ret)
+ else:
+ ret=getattr(bld,'retval',0)
+ finally:
+ if cachemode==1:
+ proj=ConfigSet.ConfigSet()
+ proj['cache_run_build']=ret
+ proj.store(os.path.join(dir,'cache_run_build'))
+ else:
+ shutil.rmtree(dir)
+ return ret
+@conf
+def ret_msg(self,msg,args):
+ if isinstance(msg,str):
+ return msg
+ return msg(args)
+@conf
+def test(self,*k,**kw):
+ if not'env'in kw:
+ kw['env']=self.env.derive()
+ if kw.get('validate',None):
+ kw['validate'](kw)
+ self.start_msg(kw['msg'],**kw)
+ ret=None
+ try:
+ ret=self.run_build(*k,**kw)
+ except self.errors.ConfigurationError:
+ self.end_msg(kw['errmsg'],'YELLOW',**kw)
+ if Logs.verbose>1:
+ raise
+ else:
+ self.fatal('The configuration failed')
+ else:
+ kw['success']=ret
+ if kw.get('post_check',None):
+ ret=kw['post_check'](kw)
+ if ret:
+ self.end_msg(kw['errmsg'],'YELLOW',**kw)
+ self.fatal('The configuration failed %r'%ret)
+ else:
+ self.end_msg(self.ret_msg(kw['okmsg'],kw),**kw)
+ return ret
diff --git a/waflib/Context.py b/waflib/Context.py
new file mode 100644
index 0000000..0034186
--- /dev/null
+++ b/waflib/Context.py
@@ -0,0 +1,394 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,re,imp,sys
+from waflib import Utils,Errors,Logs
+import waflib.Node
+HEXVERSION=0x1081300
+WAFVERSION="1.8.19"
+WAFREVISION="f14a6d43092d3419d90c1ce16b9d3c700309d7b3"
+ABI=98
+DBFILE='.wafpickle-%s-%d-%d'%(sys.platform,sys.hexversion,ABI)
+APPNAME='APPNAME'
+VERSION='VERSION'
+TOP='top'
+OUT='out'
+WSCRIPT_FILE='wscript'
+launch_dir=''
+run_dir=''
+top_dir=''
+out_dir=''
+waf_dir=''
+local_repo=''
+remote_repo='https://raw.githubusercontent.com/waf-project/waf/master/'
+remote_locs=['waflib/extras','waflib/Tools']
+g_module=None
+STDOUT=1
+STDERR=-1
+BOTH=0
+classes=[]
+def create_context(cmd_name,*k,**kw):
+ global classes
+ for x in classes:
+ if x.cmd==cmd_name:
+ return x(*k,**kw)
+ ctx=Context(*k,**kw)
+ ctx.fun=cmd_name
+ return ctx
+class store_context(type):
+ def __init__(cls,name,bases,dict):
+ super(store_context,cls).__init__(name,bases,dict)
+ name=cls.__name__
+ if name=='ctx'or name=='Context':
+ return
+ try:
+ cls.cmd
+ except AttributeError:
+ raise Errors.WafError('Missing command for the context class %r (cmd)'%name)
+ if not getattr(cls,'fun',None):
+ cls.fun=cls.cmd
+ global classes
+ classes.insert(0,cls)
+ctx=store_context('ctx',(object,),{})
+class Context(ctx):
+ errors=Errors
+ tools={}
+ def __init__(self,**kw):
+ try:
+ rd=kw['run_dir']
+ except KeyError:
+ global run_dir
+ rd=run_dir
+ self.node_class=type("Nod3",(waflib.Node.Node,),{})
+ self.node_class.__module__="waflib.Node"
+ self.node_class.ctx=self
+ self.root=self.node_class('',None)
+ self.cur_script=None
+ self.path=self.root.find_dir(rd)
+ self.stack_path=[]
+ self.exec_dict={'ctx':self,'conf':self,'bld':self,'opt':self}
+ self.logger=None
+ def __hash__(self):
+ return id(self)
+ def finalize(self):
+ try:
+ logger=self.logger
+ except AttributeError:
+ pass
+ else:
+ Logs.free_logger(logger)
+ delattr(self,'logger')
+ def load(self,tool_list,*k,**kw):
+ tools=Utils.to_list(tool_list)
+ path=Utils.to_list(kw.get('tooldir',''))
+ with_sys_path=kw.get('with_sys_path',True)
+ for t in tools:
+ module=load_tool(t,path,with_sys_path=with_sys_path)
+ fun=getattr(module,kw.get('name',self.fun),None)
+ if fun:
+ fun(self)
+ def execute(self):
+ global g_module
+ self.recurse([os.path.dirname(g_module.root_path)])
+ def pre_recurse(self,node):
+ self.stack_path.append(self.cur_script)
+ self.cur_script=node
+ self.path=node.parent
+ def post_recurse(self,node):
+ self.cur_script=self.stack_path.pop()
+ if self.cur_script:
+ self.path=self.cur_script.parent
+ def recurse(self,dirs,name=None,mandatory=True,once=True,encoding=None):
+ try:
+ cache=self.recurse_cache
+ except AttributeError:
+ cache=self.recurse_cache={}
+ for d in Utils.to_list(dirs):
+ if not os.path.isabs(d):
+ d=os.path.join(self.path.abspath(),d)
+ WSCRIPT=os.path.join(d,WSCRIPT_FILE)
+ WSCRIPT_FUN=WSCRIPT+'_'+(name or self.fun)
+ node=self.root.find_node(WSCRIPT_FUN)
+ if node and(not once or node not in cache):
+ cache[node]=True
+ self.pre_recurse(node)
+ try:
+ function_code=node.read('rU',encoding)
+ exec(compile(function_code,node.abspath(),'exec'),self.exec_dict)
+ finally:
+ self.post_recurse(node)
+ elif not node:
+ node=self.root.find_node(WSCRIPT)
+ tup=(node,name or self.fun)
+ if node and(not once or tup not in cache):
+ cache[tup]=True
+ self.pre_recurse(node)
+ try:
+ wscript_module=load_module(node.abspath(),encoding=encoding)
+ user_function=getattr(wscript_module,(name or self.fun),None)
+ if not user_function:
+ if not mandatory:
+ continue
+ raise Errors.WafError('No function %s defined in %s'%(name or self.fun,node.abspath()))
+ user_function(self)
+ finally:
+ self.post_recurse(node)
+ elif not node:
+ if not mandatory:
+ continue
+ try:
+ os.listdir(d)
+ except OSError:
+ raise Errors.WafError('Cannot read the folder %r'%d)
+ raise Errors.WafError('No wscript file in directory %s'%d)
+ def exec_command(self,cmd,**kw):
+ subprocess=Utils.subprocess
+ kw['shell']=isinstance(cmd,str)
+ Logs.debug('runner: %r'%(cmd,))
+ Logs.debug('runner_env: kw=%s'%kw)
+ if self.logger:
+ self.logger.info(cmd)
+ if'stdout'not in kw:
+ kw['stdout']=subprocess.PIPE
+ if'stderr'not in kw:
+ kw['stderr']=subprocess.PIPE
+ if Logs.verbose and not kw['shell']and not Utils.check_exe(cmd[0]):
+ raise Errors.WafError("Program %s not found!"%cmd[0])
+ wargs={}
+ if'timeout'in kw:
+ if kw['timeout']is not None:
+ wargs['timeout']=kw['timeout']
+ del kw['timeout']
+ if'input'in kw:
+ if kw['input']:
+ wargs['input']=kw['input']
+ kw['stdin']=Utils.subprocess.PIPE
+ del kw['input']
+ try:
+ if kw['stdout']or kw['stderr']:
+ p=subprocess.Popen(cmd,**kw)
+ (out,err)=p.communicate(**wargs)
+ ret=p.returncode
+ else:
+ out,err=(None,None)
+ ret=subprocess.Popen(cmd,**kw).wait(**wargs)
+ except Exception ,e:
+ raise Errors.WafError('Execution failure: %s'%str(e),ex=e)
+ if out:
+ if not isinstance(out,str):
+ out=out.decode(sys.stdout.encoding or'iso8859-1')
+ if self.logger:
+ self.logger.debug('out: %s'%out)
+ else:
+ Logs.info(out,extra={'stream':sys.stdout,'c1':''})
+ if err:
+ if not isinstance(err,str):
+ err=err.decode(sys.stdout.encoding or'iso8859-1')
+ if self.logger:
+ self.logger.error('err: %s'%err)
+ else:
+ Logs.info(err,extra={'stream':sys.stderr,'c1':''})
+ return ret
+ def cmd_and_log(self,cmd,**kw):
+ subprocess=Utils.subprocess
+ kw['shell']=isinstance(cmd,str)
+ Logs.debug('runner: %r'%(cmd,))
+ if'quiet'in kw:
+ quiet=kw['quiet']
+ del kw['quiet']
+ else:
+ quiet=None
+ if'output'in kw:
+ to_ret=kw['output']
+ del kw['output']
+ else:
+ to_ret=STDOUT
+ if Logs.verbose and not kw['shell']and not Utils.check_exe(cmd[0]):
+ raise Errors.WafError("Program %s not found!"%cmd[0])
+ kw['stdout']=kw['stderr']=subprocess.PIPE
+ if quiet is None:
+ self.to_log(cmd)
+ wargs={}
+ if'timeout'in kw:
+ if kw['timeout']is not None:
+ wargs['timeout']=kw['timeout']
+ del kw['timeout']
+ if'input'in kw:
+ if kw['input']:
+ wargs['input']=kw['input']
+ kw['stdin']=Utils.subprocess.PIPE
+ del kw['input']
+ try:
+ p=subprocess.Popen(cmd,**kw)
+ (out,err)=p.communicate(**wargs)
+ except Exception ,e:
+ raise Errors.WafError('Execution failure: %s'%str(e),ex=e)
+ if not isinstance(out,str):
+ out=out.decode(sys.stdout.encoding or'iso8859-1')
+ if not isinstance(err,str):
+ err=err.decode(sys.stdout.encoding or'iso8859-1')
+ if out and quiet!=STDOUT and quiet!=BOTH:
+ self.to_log('out: %s'%out)
+ if err and quiet!=STDERR and quiet!=BOTH:
+ self.to_log('err: %s'%err)
+ if p.returncode:
+ e=Errors.WafError('Command %r returned %r'%(cmd,p.returncode))
+ e.returncode=p.returncode
+ e.stderr=err
+ e.stdout=out
+ raise e
+ if to_ret==BOTH:
+ return(out,err)
+ elif to_ret==STDERR:
+ return err
+ return out
+ def fatal(self,msg,ex=None):
+ if self.logger:
+ self.logger.info('from %s: %s'%(self.path.abspath(),msg))
+ try:
+ msg='%s\n(complete log in %s)'%(msg,self.logger.handlers[0].baseFilename)
+ except Exception:
+ pass
+ raise self.errors.ConfigurationError(msg,ex=ex)
+ def to_log(self,msg):
+ if not msg:
+ return
+ if self.logger:
+ self.logger.info(msg)
+ else:
+ sys.stderr.write(str(msg))
+ sys.stderr.flush()
+ def msg(self,*k,**kw):
+ try:
+ msg=kw['msg']
+ except KeyError:
+ msg=k[0]
+ self.start_msg(msg,**kw)
+ try:
+ result=kw['result']
+ except KeyError:
+ result=k[1]
+ color=kw.get('color',None)
+ if not isinstance(color,str):
+ color=result and'GREEN'or'YELLOW'
+ self.end_msg(result,color,**kw)
+ def start_msg(self,*k,**kw):
+ if kw.get('quiet',None):
+ return
+ msg=kw.get('msg',None)or k[0]
+ try:
+ if self.in_msg:
+ self.in_msg+=1
+ return
+ except AttributeError:
+ self.in_msg=0
+ self.in_msg+=1
+ try:
+ self.line_just=max(self.line_just,len(msg))
+ except AttributeError:
+ self.line_just=max(40,len(msg))
+ for x in(self.line_just*'-',msg):
+ self.to_log(x)
+ Logs.pprint('NORMAL',"%s :"%msg.ljust(self.line_just),sep='')
+ def end_msg(self,*k,**kw):
+ if kw.get('quiet',None):
+ return
+ self.in_msg-=1
+ if self.in_msg:
+ return
+ result=kw.get('result',None)or k[0]
+ defcolor='GREEN'
+ if result==True:
+ msg='ok'
+ elif result==False:
+ msg='not found'
+ defcolor='YELLOW'
+ else:
+ msg=str(result)
+ self.to_log(msg)
+ try:
+ color=kw['color']
+ except KeyError:
+ if len(k)>1 and k[1]in Logs.colors_lst:
+ color=k[1]
+ else:
+ color=defcolor
+ Logs.pprint(color,msg)
+ def load_special_tools(self,var,ban=[]):
+ global waf_dir
+ if os.path.isdir(waf_dir):
+ lst=self.root.find_node(waf_dir).find_node('waflib/extras').ant_glob(var)
+ for x in lst:
+ if not x.name in ban:
+ load_tool(x.name.replace('.py',''))
+ else:
+ from zipfile import PyZipFile
+ waflibs=PyZipFile(waf_dir)
+ lst=waflibs.namelist()
+ for x in lst:
+ if not re.match("waflib/extras/%s"%var.replace("*",".*"),var):
+ continue
+ f=os.path.basename(x)
+ doban=False
+ for b in ban:
+ r=b.replace("*",".*")
+ if re.match(r,f):
+ doban=True
+ if not doban:
+ f=f.replace('.py','')
+ load_tool(f)
+cache_modules={}
+def load_module(path,encoding=None):
+ try:
+ return cache_modules[path]
+ except KeyError:
+ pass
+ module=imp.new_module(WSCRIPT_FILE)
+ try:
+ code=Utils.readf(path,m='rU',encoding=encoding)
+ except EnvironmentError:
+ raise Errors.WafError('Could not read the file %r'%path)
+ module_dir=os.path.dirname(path)
+ sys.path.insert(0,module_dir)
+ try:exec(compile(code,path,'exec'),module.__dict__)
+ finally:sys.path.remove(module_dir)
+ cache_modules[path]=module
+ return module
+def load_tool(tool,tooldir=None,ctx=None,with_sys_path=True):
+ if tool=='java':
+ tool='javaw'
+ else:
+ tool=tool.replace('++','xx')
+ origSysPath=sys.path
+ if not with_sys_path:sys.path=[]
+ try:
+ if tooldir:
+ assert isinstance(tooldir,list)
+ sys.path=tooldir+sys.path
+ try:
+ __import__(tool)
+ finally:
+ for d in tooldir:
+ sys.path.remove(d)
+ ret=sys.modules[tool]
+ Context.tools[tool]=ret
+ return ret
+ else:
+ if not with_sys_path:sys.path.insert(0,waf_dir)
+ try:
+ for x in('waflib.Tools.%s','waflib.extras.%s','waflib.%s','%s'):
+ try:
+ __import__(x%tool)
+ break
+ except ImportError:
+ x=None
+ if x is None:
+ __import__(tool)
+ finally:
+ if not with_sys_path:sys.path.remove(waf_dir)
+ ret=sys.modules[x%tool]
+ Context.tools[tool]=ret
+ return ret
+ finally:
+ if not with_sys_path:sys.path+=origSysPath
diff --git a/waflib/Errors.py b/waflib/Errors.py
new file mode 100644
index 0000000..3d98c8d
--- /dev/null
+++ b/waflib/Errors.py
@@ -0,0 +1,37 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import traceback,sys
+class WafError(Exception):
+ def __init__(self,msg='',ex=None):
+ self.msg=msg
+ assert not isinstance(msg,Exception)
+ self.stack=[]
+ if ex:
+ if not msg:
+ self.msg=str(ex)
+ if isinstance(ex,WafError):
+ self.stack=ex.stack
+ else:
+ self.stack=traceback.extract_tb(sys.exc_info()[2])
+ self.stack+=traceback.extract_stack()[:-1]
+ self.verbose_msg=''.join(traceback.format_list(self.stack))
+ def __str__(self):
+ return str(self.msg)
+class BuildError(WafError):
+ def __init__(self,error_tasks=[]):
+ self.tasks=error_tasks
+ WafError.__init__(self,self.format_error())
+ def format_error(self):
+ lst=['Build failed']
+ for tsk in self.tasks:
+ txt=tsk.format_error()
+ if txt:lst.append(txt)
+ return'\n'.join(lst)
+class ConfigurationError(WafError):
+ pass
+class TaskRescan(WafError):
+ pass
+class TaskNotReady(WafError):
+ pass
diff --git a/waflib/Logs.py b/waflib/Logs.py
new file mode 100644
index 0000000..984ac1b
--- /dev/null
+++ b/waflib/Logs.py
@@ -0,0 +1,200 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,re,traceback,sys
+from waflib import Utils,ansiterm
+if not os.environ.get('NOSYNC',False):
+ if sys.stdout.isatty()and id(sys.stdout)==id(sys.__stdout__):
+ sys.stdout=ansiterm.AnsiTerm(sys.stdout)
+ if sys.stderr.isatty()and id(sys.stderr)==id(sys.__stderr__):
+ sys.stderr=ansiterm.AnsiTerm(sys.stderr)
+import logging
+LOG_FORMAT=os.environ.get('WAF_LOG_FORMAT','%(asctime)s %(c1)s%(zone)s%(c2)s %(message)s')
+HOUR_FORMAT=os.environ.get('WAF_HOUR_FORMAT','%H:%M:%S')
+zones=''
+verbose=0
+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',}
+indicator='\r\x1b[K%s%s%s'
+try:
+ unicode
+except NameError:
+ unicode=None
+def enable_colors(use):
+ if use==1:
+ if not(sys.stderr.isatty()or sys.stdout.isatty()):
+ use=0
+ if Utils.is_win32 and os.name!='java':
+ term=os.environ.get('TERM','')
+ else:
+ term=os.environ.get('TERM','dumb')
+ if term in('dumb','emacs'):
+ use=0
+ if use>=1:
+ os.environ['TERM']='vt100'
+ colors_lst['USE']=use
+try:
+ get_term_cols=ansiterm.get_term_cols
+except AttributeError:
+ def get_term_cols():
+ return 80
+get_term_cols.__doc__="""
+ Get the console width in characters.
+
+ :return: the number of characters per line
+ :rtype: int
+ """
+def get_color(cl):
+ if not colors_lst['USE']:return''
+ return colors_lst.get(cl,'')
+class color_dict(object):
+ def __getattr__(self,a):
+ return get_color(a)
+ def __call__(self,a):
+ return get_color(a)
+colors=color_dict()
+re_log=re.compile(r'(\w+): (.*)',re.M)
+class log_filter(logging.Filter):
+ def __init__(self,name=None):
+ pass
+ def filter(self,rec):
+ rec.zone=rec.module
+ if rec.levelno>=logging.INFO:
+ return True
+ m=re_log.match(rec.msg)
+ if m:
+ rec.zone=m.group(1)
+ rec.msg=m.group(2)
+ if zones:
+ return getattr(rec,'zone','')in zones or'*'in zones
+ elif not verbose>2:
+ return False
+ return True
+class log_handler(logging.StreamHandler):
+ def emit(self,record):
+ try:
+ try:
+ self.stream=record.stream
+ except AttributeError:
+ if record.levelno>=logging.WARNING:
+ record.stream=self.stream=sys.stderr
+ else:
+ record.stream=self.stream=sys.stdout
+ self.emit_override(record)
+ self.flush()
+ except(KeyboardInterrupt,SystemExit):
+ raise
+ except:
+ self.handleError(record)
+ def emit_override(self,record,**kw):
+ self.terminator=getattr(record,'terminator','\n')
+ stream=self.stream
+ if unicode:
+ msg=self.formatter.format(record)
+ fs='%s'+self.terminator
+ try:
+ if(isinstance(msg,unicode)and getattr(stream,'encoding',None)):
+ fs=fs.decode(stream.encoding)
+ try:
+ stream.write(fs%msg)
+ except UnicodeEncodeError:
+ stream.write((fs%msg).encode(stream.encoding))
+ else:
+ stream.write(fs%msg)
+ except UnicodeError:
+ stream.write((fs%msg).encode("UTF-8"))
+ else:
+ logging.StreamHandler.emit(self,record)
+class formatter(logging.Formatter):
+ def __init__(self):
+ logging.Formatter.__init__(self,LOG_FORMAT,HOUR_FORMAT)
+ def format(self,rec):
+ try:
+ msg=rec.msg.decode('utf-8')
+ except Exception:
+ msg=rec.msg
+ use=colors_lst['USE']
+ if(use==1 and rec.stream.isatty())or use==2:
+ c1=getattr(rec,'c1',None)
+ if c1 is None:
+ c1=''
+ if rec.levelno>=logging.ERROR:
+ c1=colors.RED
+ elif rec.levelno>=logging.WARNING:
+ c1=colors.YELLOW
+ elif rec.levelno>=logging.INFO:
+ c1=colors.GREEN
+ c2=getattr(rec,'c2',colors.NORMAL)
+ msg='%s%s%s'%(c1,msg,c2)
+ else:
+ msg=msg.replace('\r','\n')
+ msg=re.sub(r'\x1B\[(K|.*?(m|h|l))','',msg)
+ if rec.levelno>=logging.INFO:
+ return msg
+ rec.msg=msg
+ rec.c1=colors.PINK
+ rec.c2=colors.NORMAL
+ return logging.Formatter.format(self,rec)
+log=None
+def debug(*k,**kw):
+ if verbose:
+ k=list(k)
+ k[0]=k[0].replace('\n',' ')
+ global log
+ log.debug(*k,**kw)
+def error(*k,**kw):
+ global log
+ log.error(*k,**kw)
+ if verbose>2:
+ st=traceback.extract_stack()
+ if st:
+ st=st[:-1]
+ buf=[]
+ for filename,lineno,name,line in st:
+ buf.append(' File "%s", line %d, in %s'%(filename,lineno,name))
+ if line:
+ buf.append(' %s'%line.strip())
+ if buf:log.error("\n".join(buf))
+def warn(*k,**kw):
+ global log
+ log.warn(*k,**kw)
+def info(*k,**kw):
+ global log
+ log.info(*k,**kw)
+def init_log():
+ global log
+ log=logging.getLogger('waflib')
+ log.handlers=[]
+ log.filters=[]
+ hdlr=log_handler()
+ hdlr.setFormatter(formatter())
+ log.addHandler(hdlr)
+ log.addFilter(log_filter())
+ log.setLevel(logging.DEBUG)
+def make_logger(path,name):
+ logger=logging.getLogger(name)
+ hdlr=logging.FileHandler(path,'w')
+ formatter=logging.Formatter('%(message)s')
+ hdlr.setFormatter(formatter)
+ logger.addHandler(hdlr)
+ logger.setLevel(logging.DEBUG)
+ return logger
+def make_mem_logger(name,to_log,size=8192):
+ from logging.handlers import MemoryHandler
+ logger=logging.getLogger(name)
+ hdlr=MemoryHandler(size,target=to_log)
+ formatter=logging.Formatter('%(message)s')
+ hdlr.setFormatter(formatter)
+ logger.addHandler(hdlr)
+ logger.memhandler=hdlr
+ logger.setLevel(logging.DEBUG)
+ return logger
+def free_logger(logger):
+ try:
+ for x in logger.handlers:
+ x.close()
+ logger.removeHandler(x)
+ except Exception:
+ pass
+def pprint(col,msg,label='',sep='\n'):
+ info("%s%s%s %s"%(colors(col),msg,colors.NORMAL,label),extra={'terminator':sep})
diff --git a/waflib/Node.py b/waflib/Node.py
new file mode 100644
index 0000000..85e3910
--- /dev/null
+++ b/waflib/Node.py
@@ -0,0 +1,491 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,re,sys,shutil
+from waflib import Utils,Errors
+exclude_regs='''
+**/*~
+**/#*#
+**/.#*
+**/%*%
+**/._*
+**/CVS
+**/CVS/**
+**/.cvsignore
+**/SCCS
+**/SCCS/**
+**/vssver.scc
+**/.svn
+**/.svn/**
+**/BitKeeper
+**/.git
+**/.git/**
+**/.gitignore
+**/.bzr
+**/.bzrignore
+**/.bzr/**
+**/.hg
+**/.hg/**
+**/_MTN
+**/_MTN/**
+**/.arch-ids
+**/{arch}
+**/_darcs
+**/_darcs/**
+**/.intlcache
+**/.DS_Store'''
+split_path=Utils.split_path
+split_path_unix=Utils.split_path_unix
+split_path_cygwin=Utils.split_path_cygwin
+split_path_win32=Utils.split_path_win32
+class Node(object):
+ dict_class=dict
+ __slots__=('name','sig','children','parent','cache_abspath','cache_isdir','cache_sig')
+ def __init__(self,name,parent):
+ self.name=name
+ self.parent=parent
+ if parent:
+ if name in parent.children:
+ raise Errors.WafError('node %s exists in the parent files %r already'%(name,parent))
+ parent.children[name]=self
+ def __setstate__(self,data):
+ self.name=data[0]
+ self.parent=data[1]
+ if data[2]is not None:
+ self.children=self.dict_class(data[2])
+ if data[3]is not None:
+ self.sig=data[3]
+ def __getstate__(self):
+ return(self.name,self.parent,getattr(self,'children',None),getattr(self,'sig',None))
+ def __str__(self):
+ return self.name
+ def __repr__(self):
+ return self.abspath()
+ def __hash__(self):
+ return id(self)
+ def __eq__(self,node):
+ return id(self)==id(node)
+ def __copy__(self):
+ raise Errors.WafError('nodes are not supposed to be copied')
+ def read(self,flags='r',encoding='ISO8859-1'):
+ return Utils.readf(self.abspath(),flags,encoding)
+ def write(self,data,flags='w',encoding='ISO8859-1'):
+ Utils.writef(self.abspath(),data,flags,encoding)
+ def read_json(self,convert=True,encoding='utf-8'):
+ import json
+ object_pairs_hook=None
+ if convert and sys.hexversion<0x3000000:
+ try:
+ _type=unicode
+ except NameError:
+ _type=str
+ def convert(value):
+ if isinstance(value,list):
+ return[convert(element)for element in value]
+ elif isinstance(value,_type):
+ return str(value)
+ else:
+ return value
+ def object_pairs(pairs):
+ return dict((str(pair[0]),convert(pair[1]))for pair in pairs)
+ object_pairs_hook=object_pairs
+ return json.loads(self.read(encoding=encoding),object_pairs_hook=object_pairs_hook)
+ def write_json(self,data,pretty=True):
+ import json
+ indent=2
+ separators=(',',': ')
+ sort_keys=pretty
+ newline=os.linesep
+ if not pretty:
+ indent=None
+ separators=(',',':')
+ newline=''
+ output=json.dumps(data,indent=indent,separators=separators,sort_keys=sort_keys)+newline
+ self.write(output,encoding='utf-8')
+ def chmod(self,val):
+ os.chmod(self.abspath(),val)
+ def delete(self):
+ try:
+ try:
+ if hasattr(self,'children'):
+ shutil.rmtree(self.abspath())
+ else:
+ os.remove(self.abspath())
+ except OSError ,e:
+ if os.path.exists(self.abspath()):
+ raise e
+ finally:
+ self.evict()
+ def evict(self):
+ del self.parent.children[self.name]
+ def suffix(self):
+ k=max(0,self.name.rfind('.'))
+ return self.name[k:]
+ def height(self):
+ d=self
+ val=-1
+ while d:
+ d=d.parent
+ val+=1
+ return val
+ def listdir(self):
+ lst=Utils.listdir(self.abspath())
+ lst.sort()
+ return lst
+ def mkdir(self):
+ if getattr(self,'cache_isdir',None):
+ return
+ try:
+ self.parent.mkdir()
+ except OSError:
+ pass
+ if self.name:
+ try:
+ os.makedirs(self.abspath())
+ except OSError:
+ pass
+ if not os.path.isdir(self.abspath()):
+ raise Errors.WafError('Could not create the directory %s'%self.abspath())
+ try:
+ self.children
+ except AttributeError:
+ self.children=self.dict_class()
+ self.cache_isdir=True
+ def find_node(self,lst):
+ if isinstance(lst,str):
+ lst=[x for x in split_path(lst)if x and x!='.']
+ cur=self
+ for x in lst:
+ if x=='..':
+ cur=cur.parent or cur
+ continue
+ try:
+ ch=cur.children
+ except AttributeError:
+ cur.children=self.dict_class()
+ else:
+ try:
+ cur=ch[x]
+ continue
+ except KeyError:
+ pass
+ cur=self.__class__(x,cur)
+ try:
+ os.stat(cur.abspath())
+ except OSError:
+ cur.evict()
+ return None
+ ret=cur
+ try:
+ os.stat(ret.abspath())
+ except OSError:
+ ret.evict()
+ return None
+ try:
+ while not getattr(cur.parent,'cache_isdir',None):
+ cur=cur.parent
+ cur.cache_isdir=True
+ except AttributeError:
+ pass
+ return ret
+ def make_node(self,lst):
+ if isinstance(lst,str):
+ lst=[x for x in split_path(lst)if x and x!='.']
+ cur=self
+ for x in lst:
+ if x=='..':
+ cur=cur.parent or cur
+ continue
+ if getattr(cur,'children',{}):
+ if x in cur.children:
+ cur=cur.children[x]
+ continue
+ else:
+ cur.children=self.dict_class()
+ cur=self.__class__(x,cur)
+ return cur
+ def search_node(self,lst):
+ if isinstance(lst,str):
+ lst=[x for x in split_path(lst)if x and x!='.']
+ cur=self
+ for x in lst:
+ if x=='..':
+ cur=cur.parent or cur
+ else:
+ try:
+ cur=cur.children[x]
+ except(AttributeError,KeyError):
+ return None
+ return cur
+ def path_from(self,node):
+ c1=self
+ c2=node
+ c1h=c1.height()
+ c2h=c2.height()
+ lst=[]
+ up=0
+ while c1h>c2h:
+ lst.append(c1.name)
+ c1=c1.parent
+ c1h-=1
+ while c2h>c1h:
+ up+=1
+ c2=c2.parent
+ c2h-=1
+ while id(c1)!=id(c2):
+ lst.append(c1.name)
+ up+=1
+ c1=c1.parent
+ c2=c2.parent
+ if c1.parent:
+ for i in range(up):
+ lst.append('..')
+ else:
+ if lst and not Utils.is_win32:
+ lst.append('')
+ lst.reverse()
+ return os.sep.join(lst)or'.'
+ def abspath(self):
+ try:
+ return self.cache_abspath
+ except AttributeError:
+ pass
+ if not self.parent:
+ val=os.sep
+ elif not self.parent.name:
+ val=os.sep+self.name
+ else:
+ val=self.parent.abspath()+os.sep+self.name
+ self.cache_abspath=val
+ return val
+ if Utils.is_win32:
+ def abspath(self):
+ try:
+ return self.cache_abspath
+ except AttributeError:
+ pass
+ if not self.parent:
+ val=''
+ elif not self.parent.name:
+ val=self.name+os.sep
+ else:
+ val=self.parent.abspath().rstrip(os.sep)+os.sep+self.name
+ self.cache_abspath=val
+ return val
+ def is_child_of(self,node):
+ p=self
+ diff=self.height()-node.height()
+ while diff>0:
+ diff-=1
+ p=p.parent
+ return id(p)==id(node)
+ def ant_iter(self,accept=None,maxdepth=25,pats=[],dir=False,src=True,remove=True):
+ dircont=self.listdir()
+ dircont.sort()
+ try:
+ lst=set(self.children.keys())
+ except AttributeError:
+ self.children=self.dict_class()
+ else:
+ if remove:
+ for x in lst-set(dircont):
+ self.children[x].evict()
+ for name in dircont:
+ npats=accept(name,pats)
+ if npats and npats[0]:
+ accepted=[]in npats[0]
+ node=self.make_node([name])
+ isdir=os.path.isdir(node.abspath())
+ if accepted:
+ if isdir:
+ if dir:
+ yield node
+ else:
+ if src:
+ yield node
+ if getattr(node,'cache_isdir',None)or isdir:
+ node.cache_isdir=True
+ if maxdepth:
+ for k in node.ant_iter(accept=accept,maxdepth=maxdepth-1,pats=npats,dir=dir,src=src,remove=remove):
+ yield k
+ raise StopIteration
+ def ant_glob(self,*k,**kw):
+ src=kw.get('src',True)
+ dir=kw.get('dir',False)
+ excl=kw.get('excl',exclude_regs)
+ incl=k and k[0]or kw.get('incl','**')
+ reflags=kw.get('ignorecase',0)and re.I
+ def to_pat(s):
+ lst=Utils.to_list(s)
+ ret=[]
+ for x in lst:
+ x=x.replace('\\','/').replace('//','/')
+ if x.endswith('/'):
+ x+='**'
+ lst2=x.split('/')
+ accu=[]
+ for k in lst2:
+ if k=='**':
+ accu.append(k)
+ else:
+ k=k.replace('.','[.]').replace('*','.*').replace('?','.').replace('+','\\+')
+ k='^%s$'%k
+ try:
+ accu.append(re.compile(k,flags=reflags))
+ except Exception ,e:
+ raise Errors.WafError("Invalid pattern: %s"%k,e)
+ ret.append(accu)
+ return ret
+ def filtre(name,nn):
+ ret=[]
+ for lst in nn:
+ if not lst:
+ pass
+ elif lst[0]=='**':
+ ret.append(lst)
+ if len(lst)>1:
+ if lst[1].match(name):
+ ret.append(lst[2:])
+ else:
+ ret.append([])
+ elif lst[0].match(name):
+ ret.append(lst[1:])
+ return ret
+ def accept(name,pats):
+ nacc=filtre(name,pats[0])
+ nrej=filtre(name,pats[1])
+ if[]in nrej:
+ nacc=[]
+ return[nacc,nrej]
+ ret=[x for x in self.ant_iter(accept=accept,pats=[to_pat(incl),to_pat(excl)],maxdepth=kw.get('maxdepth',25),dir=dir,src=src,remove=kw.get('remove',True))]
+ if kw.get('flat',False):
+ return' '.join([x.path_from(self)for x in ret])
+ return ret
+ def is_src(self):
+ cur=self
+ x=id(self.ctx.srcnode)
+ y=id(self.ctx.bldnode)
+ while cur.parent:
+ if id(cur)==y:
+ return False
+ if id(cur)==x:
+ return True
+ cur=cur.parent
+ return False
+ def is_bld(self):
+ cur=self
+ y=id(self.ctx.bldnode)
+ while cur.parent:
+ if id(cur)==y:
+ return True
+ cur=cur.parent
+ return False
+ def get_src(self):
+ cur=self
+ x=id(self.ctx.srcnode)
+ y=id(self.ctx.bldnode)
+ lst=[]
+ while cur.parent:
+ if id(cur)==y:
+ lst.reverse()
+ return self.ctx.srcnode.make_node(lst)
+ if id(cur)==x:
+ return self
+ lst.append(cur.name)
+ cur=cur.parent
+ return self
+ def get_bld(self):
+ cur=self
+ x=id(self.ctx.srcnode)
+ y=id(self.ctx.bldnode)
+ lst=[]
+ while cur.parent:
+ if id(cur)==y:
+ return self
+ if id(cur)==x:
+ lst.reverse()
+ return self.ctx.bldnode.make_node(lst)
+ lst.append(cur.name)
+ cur=cur.parent
+ lst.reverse()
+ if lst and Utils.is_win32 and len(lst[0])==2 and lst[0].endswith(':'):
+ lst[0]=lst[0][0]
+ return self.ctx.bldnode.make_node(['__root__']+lst)
+ def find_resource(self,lst):
+ if isinstance(lst,str):
+ lst=[x for x in split_path(lst)if x and x!='.']
+ node=self.get_bld().search_node(lst)
+ if not node:
+ self=self.get_src()
+ node=self.find_node(lst)
+ if node:
+ if os.path.isdir(node.abspath()):
+ return None
+ return node
+ def find_or_declare(self,lst):
+ if isinstance(lst,str):
+ lst=[x for x in split_path(lst)if x and x!='.']
+ node=self.get_bld().search_node(lst)
+ if node:
+ if not os.path.isfile(node.abspath()):
+ node.sig=None
+ node.parent.mkdir()
+ return node
+ self=self.get_src()
+ node=self.find_node(lst)
+ if node:
+ if not os.path.isfile(node.abspath()):
+ node.sig=None
+ node.parent.mkdir()
+ return node
+ node=self.get_bld().make_node(lst)
+ node.parent.mkdir()
+ return node
+ def find_dir(self,lst):
+ if isinstance(lst,str):
+ lst=[x for x in split_path(lst)if x and x!='.']
+ node=self.find_node(lst)
+ try:
+ if not os.path.isdir(node.abspath()):
+ return None
+ except(OSError,AttributeError):
+ return None
+ return node
+ def change_ext(self,ext,ext_in=None):
+ name=self.name
+ if ext_in is None:
+ k=name.rfind('.')
+ if k>=0:
+ name=name[:k]+ext
+ else:
+ name=name+ext
+ else:
+ name=name[:-len(ext_in)]+ext
+ return self.parent.find_or_declare([name])
+ def bldpath(self):
+ return self.path_from(self.ctx.bldnode)
+ def srcpath(self):
+ return self.path_from(self.ctx.srcnode)
+ def relpath(self):
+ cur=self
+ x=id(self.ctx.bldnode)
+ while cur.parent:
+ if id(cur)==x:
+ return self.bldpath()
+ cur=cur.parent
+ return self.srcpath()
+ def bld_dir(self):
+ return self.parent.bldpath()
+ def get_bld_sig(self):
+ try:
+ return self.cache_sig
+ except AttributeError:
+ pass
+ if not self.is_bld()or self.ctx.bldnode is self.ctx.srcnode:
+ self.sig=Utils.h_file(self.abspath())
+ self.cache_sig=ret=self.sig
+ return ret
+pickle_lock=Utils.threading.Lock()
+class Nod3(Node):
+ pass
diff --git a/waflib/Options.py b/waflib/Options.py
new file mode 100644
index 0000000..5101f5f
--- /dev/null
+++ b/waflib/Options.py
@@ -0,0 +1,147 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,tempfile,optparse,sys,re
+from waflib import Logs,Utils,Context
+cmds='distclean configure build install clean uninstall check dist distcheck'.split()
+options={}
+commands=[]
+envvars=[]
+lockfile=os.environ.get('WAFLOCK','.lock-waf_%s_build'%sys.platform)
+platform=Utils.unversioned_sys_platform()
+class opt_parser(optparse.OptionParser):
+ def __init__(self,ctx):
+ optparse.OptionParser.__init__(self,conflict_handler="resolve",version='waf %s (%s)'%(Context.WAFVERSION,Context.WAFREVISION))
+ self.formatter.width=Logs.get_term_cols()
+ self.ctx=ctx
+ def print_usage(self,file=None):
+ return self.print_help(file)
+ def get_usage(self):
+ cmds_str={}
+ for cls in Context.classes:
+ if not cls.cmd or cls.cmd=='options'or cls.cmd.startswith('_'):
+ continue
+ s=cls.__doc__ or''
+ cmds_str[cls.cmd]=s
+ if Context.g_module:
+ for(k,v)in Context.g_module.__dict__.items():
+ if k in('options','init','shutdown'):
+ continue
+ if type(v)is type(Context.create_context):
+ if v.__doc__ and not k.startswith('_'):
+ cmds_str[k]=v.__doc__
+ just=0
+ for k in cmds_str:
+ just=max(just,len(k))
+ lst=[' %s: %s'%(k.ljust(just),v)for(k,v)in cmds_str.items()]
+ lst.sort()
+ ret='\n'.join(lst)
+ return'''waf [commands] [options]
+
+Main commands (example: ./waf build -j4)
+%s
+'''%ret
+class OptionsContext(Context.Context):
+ cmd='options'
+ fun='options'
+ def __init__(self,**kw):
+ super(OptionsContext,self).__init__(**kw)
+ self.parser=opt_parser(self)
+ self.option_groups={}
+ jobs=self.jobs()
+ p=self.add_option
+ color=os.environ.get('NOCOLOR','')and'no'or'auto'
+ p('-c','--color',dest='colors',default=color,action='store',help='whether to use colors (yes/no/auto) [default: auto]',choices=('yes','no','auto'))
+ p('-j','--jobs',dest='jobs',default=jobs,type='int',help='amount of parallel jobs (%r)'%jobs)
+ p('-k','--keep',dest='keep',default=0,action='count',help='continue despite errors (-kk to try harder)')
+ p('-v','--verbose',dest='verbose',default=0,action='count',help='verbosity level -v -vv or -vvv [default: 0]')
+ p('--zones',dest='zones',default='',action='store',help='debugging zones (task_gen, deps, tasks, etc)')
+ gr=self.add_option_group('Configuration options')
+ self.option_groups['configure options']=gr
+ gr.add_option('-o','--out',action='store',default='',help='build dir for the project',dest='out')
+ gr.add_option('-t','--top',action='store',default='',help='src dir for the project',dest='top')
+ gr.add_option('--no-lock-in-run',action='store_true',default='',help=optparse.SUPPRESS_HELP,dest='no_lock_in_run')
+ gr.add_option('--no-lock-in-out',action='store_true',default='',help=optparse.SUPPRESS_HELP,dest='no_lock_in_out')
+ gr.add_option('--no-lock-in-top',action='store_true',default='',help=optparse.SUPPRESS_HELP,dest='no_lock_in_top')
+ default_prefix=getattr(Context.g_module,'default_prefix',os.environ.get('PREFIX'))
+ if not default_prefix:
+ if platform=='win32':
+ d=tempfile.gettempdir()
+ default_prefix=d[0].upper()+d[1:]
+ else:
+ default_prefix='/usr/local/'
+ gr.add_option('--prefix',dest='prefix',default=default_prefix,help='installation prefix [default: %r]'%default_prefix)
+ gr.add_option('--bindir',dest='bindir',help='bindir')
+ gr.add_option('--libdir',dest='libdir',help='libdir')
+ gr=self.add_option_group('Build and installation options')
+ self.option_groups['build and install options']=gr
+ gr.add_option('-p','--progress',dest='progress_bar',default=0,action='count',help='-p: progress bar; -pp: ide output')
+ gr.add_option('--targets',dest='targets',default='',action='store',help='task generators, e.g. "target1,target2"')
+ gr=self.add_option_group('Step options')
+ self.option_groups['step options']=gr
+ gr.add_option('--files',dest='files',default='',action='store',help='files to process, by regexp, e.g. "*/main.c,*/test/main.o"')
+ default_destdir=os.environ.get('DESTDIR','')
+ gr=self.add_option_group('Installation and uninstallation options')
+ self.option_groups['install/uninstall options']=gr
+ gr.add_option('--destdir',help='installation root [default: %r]'%default_destdir,default=default_destdir,dest='destdir')
+ gr.add_option('-f','--force',dest='force',default=False,action='store_true',help='force file installation')
+ gr.add_option('--distcheck-args',metavar='ARGS',help='arguments to pass to distcheck',default=None,action='store')
+ def jobs(self):
+ count=int(os.environ.get('JOBS',0))
+ if count<1:
+ if'NUMBER_OF_PROCESSORS'in os.environ:
+ count=int(os.environ.get('NUMBER_OF_PROCESSORS',1))
+ else:
+ if hasattr(os,'sysconf_names'):
+ if'SC_NPROCESSORS_ONLN'in os.sysconf_names:
+ count=int(os.sysconf('SC_NPROCESSORS_ONLN'))
+ elif'SC_NPROCESSORS_CONF'in os.sysconf_names:
+ count=int(os.sysconf('SC_NPROCESSORS_CONF'))
+ if not count and os.name not in('nt','java'):
+ try:
+ tmp=self.cmd_and_log(['sysctl','-n','hw.ncpu'],quiet=0)
+ except Exception:
+ pass
+ else:
+ if re.match('^[0-9]+$',tmp):
+ count=int(tmp)
+ if count<1:
+ count=1
+ elif count>1024:
+ count=1024
+ return count
+ def add_option(self,*k,**kw):
+ return self.parser.add_option(*k,**kw)
+ def add_option_group(self,*k,**kw):
+ try:
+ gr=self.option_groups[k[0]]
+ except KeyError:
+ gr=self.parser.add_option_group(*k,**kw)
+ self.option_groups[k[0]]=gr
+ return gr
+ def get_option_group(self,opt_str):
+ try:
+ return self.option_groups[opt_str]
+ except KeyError:
+ for group in self.parser.option_groups:
+ if group.title==opt_str:
+ return group
+ return None
+ def parse_args(self,_args=None):
+ global options,commands,envvars
+ (options,leftover_args)=self.parser.parse_args(args=_args)
+ for arg in leftover_args:
+ if'='in arg:
+ envvars.append(arg)
+ else:
+ commands.append(arg)
+ if options.destdir:
+ options.destdir=Utils.sane_path(options.destdir)
+ if options.verbose>=1:
+ self.load('errcheck')
+ colors={'yes':2,'auto':1,'no':0}[options.colors]
+ Logs.enable_colors(colors)
+ def execute(self):
+ super(OptionsContext,self).execute()
+ self.parse_args()
diff --git a/waflib/Runner.py b/waflib/Runner.py
new file mode 100644
index 0000000..c22503e
--- /dev/null
+++ b/waflib/Runner.py
@@ -0,0 +1,207 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import random,atexit
+try:
+ from queue import Queue
+except ImportError:
+ from Queue import Queue
+from waflib import Utils,Task,Errors,Logs
+GAP=10
+class TaskConsumer(Utils.threading.Thread):
+ def __init__(self):
+ Utils.threading.Thread.__init__(self)
+ self.ready=Queue()
+ self.setDaemon(1)
+ self.start()
+ def run(self):
+ try:
+ self.loop()
+ except Exception:
+ pass
+ def loop(self):
+ while 1:
+ tsk=self.ready.get()
+ if not isinstance(tsk,Task.TaskBase):
+ tsk(self)
+ else:
+ tsk.process()
+pool=Queue()
+def get_pool():
+ try:
+ return pool.get(False)
+ except Exception:
+ return TaskConsumer()
+def put_pool(x):
+ pool.put(x)
+def _free_resources():
+ global pool
+ lst=[]
+ while pool.qsize():
+ lst.append(pool.get())
+ for x in lst:
+ x.ready.put(None)
+ for x in lst:
+ x.join()
+ pool=None
+atexit.register(_free_resources)
+class Parallel(object):
+ def __init__(self,bld,j=2):
+ self.numjobs=j
+ self.bld=bld
+ self.outstanding=[]
+ self.frozen=[]
+ self.out=Queue(0)
+ self.count=0
+ self.processed=1
+ self.stop=False
+ self.error=[]
+ self.biter=None
+ self.dirty=False
+ def get_next_task(self):
+ if not self.outstanding:
+ return None
+ return self.outstanding.pop(0)
+ def postpone(self,tsk):
+ if random.randint(0,1):
+ self.frozen.insert(0,tsk)
+ else:
+ self.frozen.append(tsk)
+ def refill_task_list(self):
+ while self.count>self.numjobs*GAP:
+ self.get_out()
+ while not self.outstanding:
+ if self.count:
+ self.get_out()
+ elif self.frozen:
+ try:
+ cond=self.deadlock==self.processed
+ except AttributeError:
+ pass
+ else:
+ if cond:
+ msg='check the build order for the tasks'
+ for tsk in self.frozen:
+ if not tsk.run_after:
+ msg='check the methods runnable_status'
+ break
+ lst=[]
+ for tsk in self.frozen:
+ lst.append('%s\t-> %r'%(repr(tsk),[id(x)for x in tsk.run_after]))
+ raise Errors.WafError('Deadlock detected: %s%s'%(msg,''.join(lst)))
+ self.deadlock=self.processed
+ if self.frozen:
+ self.outstanding+=self.frozen
+ self.frozen=[]
+ elif not self.count:
+ self.outstanding.extend(self.biter.next())
+ self.total=self.bld.total()
+ break
+ def add_more_tasks(self,tsk):
+ if getattr(tsk,'more_tasks',None):
+ self.outstanding+=tsk.more_tasks
+ self.total+=len(tsk.more_tasks)
+ def get_out(self):
+ tsk=self.out.get()
+ if not self.stop:
+ self.add_more_tasks(tsk)
+ self.count-=1
+ self.dirty=True
+ return tsk
+ def add_task(self,tsk):
+ try:
+ self.pool
+ except AttributeError:
+ self.init_task_pool()
+ self.ready.put(tsk)
+ def init_task_pool(self):
+ pool=self.pool=[get_pool()for i in range(self.numjobs)]
+ self.ready=Queue(0)
+ def setq(consumer):
+ consumer.ready=self.ready
+ for x in pool:
+ x.ready.put(setq)
+ return pool
+ def free_task_pool(self):
+ def setq(consumer):
+ consumer.ready=Queue(0)
+ self.out.put(self)
+ try:
+ pool=self.pool
+ except AttributeError:
+ pass
+ else:
+ for x in pool:
+ self.ready.put(setq)
+ for x in pool:
+ self.get_out()
+ for x in pool:
+ put_pool(x)
+ self.pool=[]
+ def skip(self,tsk):
+ tsk.hasrun=Task.SKIPPED
+ def error_handler(self,tsk):
+ if hasattr(tsk,'scan')and hasattr(tsk,'uid'):
+ key=(tsk.uid(),'imp')
+ try:
+ del self.bld.task_sigs[key]
+ except KeyError:
+ pass
+ if not self.bld.keep:
+ self.stop=True
+ self.error.append(tsk)
+ def task_status(self,tsk):
+ try:
+ return tsk.runnable_status()
+ except Exception:
+ self.processed+=1
+ tsk.err_msg=Utils.ex_stack()
+ if not self.stop and self.bld.keep:
+ self.skip(tsk)
+ if self.bld.keep==1:
+ if Logs.verbose>1 or not self.error:
+ self.error.append(tsk)
+ self.stop=True
+ else:
+ if Logs.verbose>1:
+ self.error.append(tsk)
+ return Task.EXCEPTION
+ tsk.hasrun=Task.EXCEPTION
+ self.error_handler(tsk)
+ return Task.EXCEPTION
+ def start(self):
+ self.total=self.bld.total()
+ while not self.stop:
+ self.refill_task_list()
+ tsk=self.get_next_task()
+ if not tsk:
+ if self.count:
+ continue
+ else:
+ break
+ if tsk.hasrun:
+ self.processed+=1
+ continue
+ if self.stop:
+ break
+ st=self.task_status(tsk)
+ if st==Task.RUN_ME:
+ tsk.position=(self.processed,self.total)
+ self.count+=1
+ tsk.master=self
+ self.processed+=1
+ if self.numjobs==1:
+ tsk.process()
+ else:
+ self.add_task(tsk)
+ if st==Task.ASK_LATER:
+ self.postpone(tsk)
+ elif st==Task.SKIP_ME:
+ self.processed+=1
+ self.skip(tsk)
+ self.add_more_tasks(tsk)
+ while self.error and self.count:
+ self.get_out()
+ assert(self.count==0 or self.stop)
+ self.free_task_pool()
diff --git a/waflib/Scripting.py b/waflib/Scripting.py
new file mode 100644
index 0000000..0457e7a
--- /dev/null
+++ b/waflib/Scripting.py
@@ -0,0 +1,407 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,shlex,shutil,traceback,errno,sys,stat
+from waflib import Utils,Configure,Logs,Options,ConfigSet,Context,Errors,Build,Node
+build_dir_override=None
+no_climb_commands=['configure']
+default_cmd="build"
+def waf_entry_point(current_directory,version,wafdir):
+ Logs.init_log()
+ if Context.WAFVERSION!=version:
+ Logs.error('Waf script %r and library %r do not match (directory %r)'%(version,Context.WAFVERSION,wafdir))
+ sys.exit(1)
+ if'--version'in sys.argv:
+ Context.run_dir=current_directory
+ ctx=Context.create_context('options')
+ ctx.curdir=current_directory
+ ctx.parse_args()
+ sys.exit(0)
+ if len(sys.argv)>1:
+ potential_wscript=os.path.join(current_directory,sys.argv[1])
+ if os.path.basename(potential_wscript)=='wscript'and os.path.isfile(potential_wscript):
+ current_directory=os.path.normpath(os.path.dirname(potential_wscript))
+ sys.argv.pop(1)
+ Context.waf_dir=wafdir
+ Context.launch_dir=current_directory
+ no_climb=os.environ.get('NOCLIMB',None)
+ if not no_climb:
+ for k in no_climb_commands:
+ for y in sys.argv:
+ if y.startswith(k):
+ no_climb=True
+ break
+ for i,x in enumerate(sys.argv):
+ if x.startswith('--top='):
+ Context.run_dir=Context.top_dir=Utils.sane_path(x[6:])
+ sys.argv[i]='--top='+Context.run_dir
+ if x.startswith('--out='):
+ Context.out_dir=Utils.sane_path(x[6:])
+ sys.argv[i]='--out='+Context.out_dir
+ cur=current_directory
+ while cur and not Context.top_dir:
+ lst=os.listdir(cur)
+ if Options.lockfile in lst:
+ env=ConfigSet.ConfigSet()
+ try:
+ env.load(os.path.join(cur,Options.lockfile))
+ ino=os.stat(cur)[stat.ST_INO]
+ except Exception:
+ pass
+ else:
+ for x in(env.run_dir,env.top_dir,env.out_dir):
+ if Utils.is_win32:
+ if cur==x:
+ load=True
+ break
+ else:
+ try:
+ ino2=os.stat(x)[stat.ST_INO]
+ except OSError:
+ pass
+ else:
+ if ino==ino2:
+ load=True
+ break
+ else:
+ Logs.warn('invalid lock file in %s'%cur)
+ load=False
+ if load:
+ Context.run_dir=env.run_dir
+ Context.top_dir=env.top_dir
+ Context.out_dir=env.out_dir
+ break
+ if not Context.run_dir:
+ if Context.WSCRIPT_FILE in lst:
+ Context.run_dir=cur
+ next=os.path.dirname(cur)
+ if next==cur:
+ break
+ cur=next
+ if no_climb:
+ break
+ if not Context.run_dir:
+ if'-h'in sys.argv or'--help'in sys.argv:
+ Logs.warn('No wscript file found: the help message may be incomplete')
+ Context.run_dir=current_directory
+ ctx=Context.create_context('options')
+ ctx.curdir=current_directory
+ ctx.parse_args()
+ sys.exit(0)
+ Logs.error('Waf: Run from a directory containing a file named %r'%Context.WSCRIPT_FILE)
+ sys.exit(1)
+ try:
+ os.chdir(Context.run_dir)
+ except OSError:
+ Logs.error('Waf: The folder %r is unreadable'%Context.run_dir)
+ sys.exit(1)
+ try:
+ set_main_module(os.path.normpath(os.path.join(Context.run_dir,Context.WSCRIPT_FILE)))
+ except Errors.WafError ,e:
+ Logs.pprint('RED',e.verbose_msg)
+ Logs.error(str(e))
+ sys.exit(1)
+ except Exception ,e:
+ Logs.error('Waf: The wscript in %r is unreadable'%Context.run_dir,e)
+ traceback.print_exc(file=sys.stdout)
+ sys.exit(2)
+ try:
+ run_commands()
+ except Errors.WafError ,e:
+ if Logs.verbose>1:
+ Logs.pprint('RED',e.verbose_msg)
+ Logs.error(e.msg)
+ sys.exit(1)
+ except SystemExit:
+ raise
+ except Exception ,e:
+ traceback.print_exc(file=sys.stdout)
+ sys.exit(2)
+ except KeyboardInterrupt:
+ Logs.pprint('RED','Interrupted')
+ sys.exit(68)
+def set_main_module(file_path):
+ Context.g_module=Context.load_module(file_path)
+ Context.g_module.root_path=file_path
+ def set_def(obj):
+ name=obj.__name__
+ if not name in Context.g_module.__dict__:
+ setattr(Context.g_module,name,obj)
+ for k in(update,dist,distclean,distcheck):
+ set_def(k)
+ if not'init'in Context.g_module.__dict__:
+ Context.g_module.init=Utils.nada
+ if not'shutdown'in Context.g_module.__dict__:
+ Context.g_module.shutdown=Utils.nada
+ if not'options'in Context.g_module.__dict__:
+ Context.g_module.options=Utils.nada
+def parse_options():
+ Context.create_context('options').execute()
+ for var in Options.envvars:
+ (name,value)=var.split('=',1)
+ os.environ[name.strip()]=value
+ if not Options.commands:
+ Options.commands=[default_cmd]
+ Options.commands=[x for x in Options.commands if x!='options']
+ Logs.verbose=Options.options.verbose
+ if Options.options.zones:
+ Logs.zones=Options.options.zones.split(',')
+ if not Logs.verbose:
+ Logs.verbose=1
+ elif Logs.verbose>0:
+ Logs.zones=['runner']
+ if Logs.verbose>2:
+ Logs.zones=['*']
+def run_command(cmd_name):
+ ctx=Context.create_context(cmd_name)
+ ctx.log_timer=Utils.Timer()
+ ctx.options=Options.options
+ ctx.cmd=cmd_name
+ try:
+ ctx.execute()
+ finally:
+ ctx.finalize()
+ return ctx
+def run_commands():
+ parse_options()
+ run_command('init')
+ while Options.commands:
+ cmd_name=Options.commands.pop(0)
+ ctx=run_command(cmd_name)
+ Logs.info('%r finished successfully (%s)'%(cmd_name,str(ctx.log_timer)))
+ run_command('shutdown')
+def _can_distclean(name):
+ for k in'.o .moc .exe'.split():
+ if name.endswith(k):
+ return True
+ return False
+def distclean_dir(dirname):
+ for(root,dirs,files)in os.walk(dirname):
+ for f in files:
+ if _can_distclean(f):
+ fname=os.path.join(root,f)
+ try:
+ os.remove(fname)
+ except OSError:
+ Logs.warn('Could not remove %r'%fname)
+ for x in(Context.DBFILE,'config.log'):
+ try:
+ os.remove(x)
+ except OSError:
+ pass
+ try:
+ shutil.rmtree('c4che')
+ except OSError:
+ pass
+def distclean(ctx):
+ '''removes the build directory'''
+ lst=os.listdir('.')
+ for f in lst:
+ if f==Options.lockfile:
+ try:
+ proj=ConfigSet.ConfigSet(f)
+ except IOError:
+ Logs.warn('Could not read %r'%f)
+ continue
+ if proj['out_dir']!=proj['top_dir']:
+ try:
+ shutil.rmtree(proj['out_dir'])
+ except IOError:
+ pass
+ except OSError ,e:
+ if e.errno!=errno.ENOENT:
+ Logs.warn('Could not remove %r'%proj['out_dir'])
+ else:
+ distclean_dir(proj['out_dir'])
+ for k in(proj['out_dir'],proj['top_dir'],proj['run_dir']):
+ p=os.path.join(k,Options.lockfile)
+ try:
+ os.remove(p)
+ except OSError ,e:
+ if e.errno!=errno.ENOENT:
+ Logs.warn('Could not remove %r'%p)
+ if not Options.commands:
+ for x in'.waf-1. waf-1. .waf3-1. waf3-1.'.split():
+ if f.startswith(x):
+ shutil.rmtree(f,ignore_errors=True)
+class Dist(Context.Context):
+ '''creates an archive containing the project source code'''
+ cmd='dist'
+ fun='dist'
+ algo='tar.bz2'
+ ext_algo={}
+ def execute(self):
+ self.recurse([os.path.dirname(Context.g_module.root_path)])
+ self.archive()
+ def archive(self):
+ import tarfile
+ arch_name=self.get_arch_name()
+ try:
+ self.base_path
+ except AttributeError:
+ self.base_path=self.path
+ node=self.base_path.make_node(arch_name)
+ try:
+ node.delete()
+ except OSError:
+ pass
+ files=self.get_files()
+ if self.algo.startswith('tar.'):
+ tar=tarfile.open(arch_name,'w:'+self.algo.replace('tar.',''))
+ for x in files:
+ self.add_tar_file(x,tar)
+ tar.close()
+ elif self.algo=='zip':
+ import zipfile
+ zip=zipfile.ZipFile(arch_name,'w',compression=zipfile.ZIP_DEFLATED)
+ for x in files:
+ archive_name=self.get_base_name()+'/'+x.path_from(self.base_path)
+ zip.write(x.abspath(),archive_name,zipfile.ZIP_DEFLATED)
+ zip.close()
+ else:
+ self.fatal('Valid algo types are tar.bz2, tar.gz, tar.xz or zip')
+ try:
+ from hashlib import sha1 as sha
+ except ImportError:
+ from sha import sha
+ try:
+ digest=" (sha=%r)"%sha(node.read()).hexdigest()
+ except Exception:
+ digest=''
+ Logs.info('New archive created: %s%s'%(self.arch_name,digest))
+ def get_tar_path(self,node):
+ return node.abspath()
+ def add_tar_file(self,x,tar):
+ p=self.get_tar_path(x)
+ tinfo=tar.gettarinfo(name=p,arcname=self.get_tar_prefix()+'/'+x.path_from(self.base_path))
+ tinfo.uid=0
+ tinfo.gid=0
+ tinfo.uname='root'
+ tinfo.gname='root'
+ fu=None
+ try:
+ fu=open(p,'rb')
+ tar.addfile(tinfo,fileobj=fu)
+ finally:
+ if fu:
+ fu.close()
+ def get_tar_prefix(self):
+ try:
+ return self.tar_prefix
+ except AttributeError:
+ return self.get_base_name()
+ def get_arch_name(self):
+ try:
+ self.arch_name
+ except AttributeError:
+ self.arch_name=self.get_base_name()+'.'+self.ext_algo.get(self.algo,self.algo)
+ return self.arch_name
+ def get_base_name(self):
+ try:
+ self.base_name
+ except AttributeError:
+ appname=getattr(Context.g_module,Context.APPNAME,'noname')
+ version=getattr(Context.g_module,Context.VERSION,'1.0')
+ self.base_name=appname+'-'+version
+ return self.base_name
+ def get_excl(self):
+ try:
+ return self.excl
+ except AttributeError:
+ self.excl=Node.exclude_regs+' **/waf-1.8.* **/.waf-1.8* **/waf3-1.8.* **/.waf3-1.8* **/*~ **/*.rej **/*.orig **/*.pyc **/*.pyo **/*.bak **/*.swp **/.lock-w*'
+ if Context.out_dir:
+ nd=self.root.find_node(Context.out_dir)
+ if nd:
+ self.excl+=' '+nd.path_from(self.base_path)
+ return self.excl
+ def get_files(self):
+ try:
+ files=self.files
+ except AttributeError:
+ files=self.base_path.ant_glob('**/*',excl=self.get_excl())
+ return files
+def dist(ctx):
+ '''makes a tarball for redistributing the sources'''
+ pass
+class DistCheck(Dist):
+ fun='distcheck'
+ cmd='distcheck'
+ def execute(self):
+ self.recurse([os.path.dirname(Context.g_module.root_path)])
+ self.archive()
+ self.check()
+ def check(self):
+ import tempfile,tarfile
+ t=None
+ try:
+ t=tarfile.open(self.get_arch_name())
+ for x in t:
+ t.extract(x)
+ finally:
+ if t:
+ t.close()
+ cfg=[]
+ if Options.options.distcheck_args:
+ cfg=shlex.split(Options.options.distcheck_args)
+ else:
+ cfg=[x for x in sys.argv if x.startswith('-')]
+ instdir=tempfile.mkdtemp('.inst',self.get_base_name())
+ ret=Utils.subprocess.Popen([sys.executable,sys.argv[0],'configure','install','uninstall','--destdir='+instdir]+cfg,cwd=self.get_base_name()).wait()
+ if ret:
+ raise Errors.WafError('distcheck failed with code %i'%ret)
+ if os.path.exists(instdir):
+ raise Errors.WafError('distcheck succeeded, but files were left in %s'%instdir)
+ shutil.rmtree(self.get_base_name())
+def distcheck(ctx):
+ '''checks if the project compiles (tarball from 'dist')'''
+ pass
+def update(ctx):
+ lst=Options.options.files
+ if lst:
+ lst=lst.split(',')
+ else:
+ path=os.path.join(Context.waf_dir,'waflib','extras')
+ lst=[x for x in Utils.listdir(path)if x.endswith('.py')]
+ for x in lst:
+ tool=x.replace('.py','')
+ if not tool:
+ continue
+ try:
+ dl=Configure.download_tool
+ except AttributeError:
+ ctx.fatal('The command "update" is dangerous; include the tool "use_config" in your project!')
+ try:
+ dl(tool,force=True,ctx=ctx)
+ except Errors.WafError:
+ Logs.error('Could not find the tool %r in the remote repository'%x)
+ else:
+ Logs.warn('Updated %r'%tool)
+def autoconfigure(execute_method):
+ def execute(self):
+ if not Configure.autoconfig:
+ return execute_method(self)
+ env=ConfigSet.ConfigSet()
+ do_config=False
+ try:
+ env.load(os.path.join(Context.top_dir,Options.lockfile))
+ except Exception:
+ Logs.warn('Configuring the project')
+ do_config=True
+ else:
+ if env.run_dir!=Context.run_dir:
+ do_config=True
+ else:
+ h=0
+ for f in env['files']:
+ h=Utils.h_list((h,Utils.readf(f,'rb')))
+ do_config=h!=env.hash
+ if do_config:
+ Options.commands.insert(0,self.cmd)
+ Options.commands.insert(0,'configure')
+ if Configure.autoconfig=='clobber':
+ Options.options.__dict__=env.options
+ return
+ return execute_method(self)
+ return execute
+Build.BuildContext.execute=autoconfigure(Build.BuildContext.execute)
diff --git a/waflib/Task.py b/waflib/Task.py
new file mode 100644
index 0000000..6070f68
--- /dev/null
+++ b/waflib/Task.py
@@ -0,0 +1,692 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,re,sys
+from waflib import Utils,Logs,Errors
+NOT_RUN=0
+MISSING=1
+CRASHED=2
+EXCEPTION=3
+SKIPPED=8
+SUCCESS=9
+ASK_LATER=-1
+SKIP_ME=-2
+RUN_ME=-3
+COMPILE_TEMPLATE_SHELL='''
+def f(tsk):
+ env = tsk.env
+ gen = tsk.generator
+ bld = gen.bld
+ cwdx = getattr(bld, 'cwdx', bld.bldnode) # TODO single cwd value in waf 1.9
+ wd = getattr(tsk, 'cwd', None)
+ p = env.get_flat
+ tsk.last_cmd = cmd = \'\'\' %s \'\'\' % s
+ return tsk.exec_command(cmd, cwd=wd, env=env.env or None)
+'''
+COMPILE_TEMPLATE_NOSHELL='''
+def f(tsk):
+ env = tsk.env
+ gen = tsk.generator
+ bld = gen.bld
+ cwdx = getattr(bld, 'cwdx', bld.bldnode) # TODO single cwd value in waf 1.9
+ wd = getattr(tsk, 'cwd', None)
+ def to_list(xx):
+ if isinstance(xx, str): return [xx]
+ return xx
+ tsk.last_cmd = lst = []
+ %s
+ lst = [x for x in lst if x]
+ return tsk.exec_command(lst, cwd=wd, env=env.env or None)
+'''
+classes={}
+class store_task_type(type):
+ def __init__(cls,name,bases,dict):
+ super(store_task_type,cls).__init__(name,bases,dict)
+ name=cls.__name__
+ if name.endswith('_task'):
+ name=name.replace('_task','')
+ if name!='evil'and name!='TaskBase':
+ global classes
+ if getattr(cls,'run_str',None):
+ (f,dvars)=compile_fun(cls.run_str,cls.shell)
+ cls.hcode=Utils.h_cmd(cls.run_str)
+ cls.orig_run_str=cls.run_str
+ cls.run_str=None
+ cls.run=f
+ cls.vars=list(set(cls.vars+dvars))
+ cls.vars.sort()
+ elif getattr(cls,'run',None)and not'hcode'in cls.__dict__:
+ cls.hcode=Utils.h_cmd(cls.run)
+ getattr(cls,'register',classes)[name]=cls
+evil=store_task_type('evil',(object,),{})
+class TaskBase(evil):
+ color='GREEN'
+ ext_in=[]
+ ext_out=[]
+ before=[]
+ after=[]
+ hcode=''
+ def __init__(self,*k,**kw):
+ self.hasrun=NOT_RUN
+ try:
+ self.generator=kw['generator']
+ except KeyError:
+ self.generator=self
+ def __repr__(self):
+ return'\n\t{task %r: %s %s}'%(self.__class__.__name__,id(self),str(getattr(self,'fun','')))
+ def __str__(self):
+ if hasattr(self,'fun'):
+ return self.fun.__name__
+ return self.__class__.__name__
+ def __hash__(self):
+ return id(self)
+ def keyword(self):
+ if hasattr(self,'fun'):
+ return'Function'
+ return'Processing'
+ def exec_command(self,cmd,**kw):
+ bld=self.generator.bld
+ try:
+ if not kw.get('cwd',None):
+ kw['cwd']=bld.cwd
+ except AttributeError:
+ bld.cwd=kw['cwd']=bld.variant_dir
+ return bld.exec_command(cmd,**kw)
+ def runnable_status(self):
+ return RUN_ME
+ def process(self):
+ m=self.master
+ if m.stop:
+ m.out.put(self)
+ return
+ try:
+ del self.generator.bld.task_sigs[self.uid()]
+ except KeyError:
+ pass
+ try:
+ self.generator.bld.returned_tasks.append(self)
+ self.log_display(self.generator.bld)
+ ret=self.run()
+ except Exception:
+ self.err_msg=Utils.ex_stack()
+ self.hasrun=EXCEPTION
+ m.error_handler(self)
+ m.out.put(self)
+ return
+ if ret:
+ self.err_code=ret
+ self.hasrun=CRASHED
+ else:
+ try:
+ self.post_run()
+ except Errors.WafError:
+ pass
+ except Exception:
+ self.err_msg=Utils.ex_stack()
+ self.hasrun=EXCEPTION
+ else:
+ self.hasrun=SUCCESS
+ if self.hasrun!=SUCCESS:
+ m.error_handler(self)
+ m.out.put(self)
+ def run(self):
+ if hasattr(self,'fun'):
+ return self.fun(self)
+ return 0
+ def post_run(self):
+ pass
+ def log_display(self,bld):
+ if self.generator.bld.progress_bar==3:
+ return
+ s=self.display()
+ if s:
+ if bld.logger:
+ logger=bld.logger
+ else:
+ logger=Logs
+ if self.generator.bld.progress_bar==1:
+ c1=Logs.colors.cursor_off
+ c2=Logs.colors.cursor_on
+ logger.info(s,extra={'stream':sys.stderr,'terminator':'','c1':c1,'c2':c2})
+ else:
+ logger.info(s,extra={'terminator':'','c1':'','c2':''})
+ def display(self):
+ col1=Logs.colors(self.color)
+ col2=Logs.colors.NORMAL
+ master=self.master
+ def cur():
+ tmp=-1
+ if hasattr(master,'ready'):
+ tmp-=master.ready.qsize()
+ return master.processed+tmp
+ if self.generator.bld.progress_bar==1:
+ return self.generator.bld.progress_line(cur(),master.total,col1,col2)
+ if self.generator.bld.progress_bar==2:
+ ela=str(self.generator.bld.timer)
+ try:
+ ins=','.join([n.name for n in self.inputs])
+ except AttributeError:
+ ins=''
+ try:
+ outs=','.join([n.name for n in self.outputs])
+ except AttributeError:
+ outs=''
+ return'|Total %s|Current %s|Inputs %s|Outputs %s|Time %s|\n'%(master.total,cur(),ins,outs,ela)
+ s=str(self)
+ if not s:
+ return None
+ total=master.total
+ n=len(str(total))
+ fs='[%%%dd/%%%dd] %%s%%s%%s%%s\n'%(n,n)
+ kw=self.keyword()
+ if kw:
+ kw+=' '
+ return fs%(cur(),total,kw,col1,s,col2)
+ def attr(self,att,default=None):
+ ret=getattr(self,att,self)
+ if ret is self:return getattr(self.__class__,att,default)
+ return ret
+ def hash_constraints(self):
+ cls=self.__class__
+ tup=(str(cls.before),str(cls.after),str(cls.ext_in),str(cls.ext_out),cls.__name__,cls.hcode)
+ h=hash(tup)
+ return h
+ def format_error(self):
+ msg=getattr(self,'last_cmd','')
+ name=getattr(self.generator,'name','')
+ if getattr(self,"err_msg",None):
+ return self.err_msg
+ elif not self.hasrun:
+ return'task in %r was not executed for some reason: %r'%(name,self)
+ elif self.hasrun==CRASHED:
+ try:
+ return' -> task in %r failed (exit status %r): %r\n%r'%(name,self.err_code,self,msg)
+ except AttributeError:
+ return' -> task in %r failed: %r\n%r'%(name,self,msg)
+ elif self.hasrun==MISSING:
+ return' -> missing files in %r: %r\n%r'%(name,self,msg)
+ else:
+ return'invalid status for task in %r: %r'%(name,self.hasrun)
+ def colon(self,var1,var2):
+ tmp=self.env[var1]
+ if not tmp:
+ return[]
+ if isinstance(var2,str):
+ it=self.env[var2]
+ else:
+ it=var2
+ if isinstance(tmp,str):
+ return[tmp%x for x in it]
+ else:
+ lst=[]
+ for y in it:
+ lst.extend(tmp)
+ lst.append(y)
+ return lst
+class Task(TaskBase):
+ vars=[]
+ shell=False
+ def __init__(self,*k,**kw):
+ TaskBase.__init__(self,*k,**kw)
+ self.env=kw['env']
+ self.inputs=[]
+ self.outputs=[]
+ self.dep_nodes=[]
+ self.run_after=set([])
+ def __str__(self):
+ name=self.__class__.__name__
+ if self.outputs:
+ if(name.endswith('lib')or name.endswith('program'))or not self.inputs:
+ node=self.outputs[0]
+ return node.path_from(node.ctx.launch_node())
+ if not(self.inputs or self.outputs):
+ return self.__class__.__name__
+ if len(self.inputs)==1:
+ node=self.inputs[0]
+ return node.path_from(node.ctx.launch_node())
+ src_str=' '.join([a.path_from(a.ctx.launch_node())for a in self.inputs])
+ tgt_str=' '.join([a.path_from(a.ctx.launch_node())for a in self.outputs])
+ if self.outputs:sep=' -> '
+ else:sep=''
+ return'%s: %s%s%s'%(self.__class__.__name__.replace('_task',''),src_str,sep,tgt_str)
+ def keyword(self):
+ name=self.__class__.__name__
+ if name.endswith('lib')or name.endswith('program'):
+ return'Linking'
+ if len(self.inputs)==1 and len(self.outputs)==1:
+ return'Compiling'
+ if not self.inputs:
+ if self.outputs:
+ return'Creating'
+ else:
+ return'Running'
+ return'Processing'
+ def __repr__(self):
+ try:
+ ins=",".join([x.name for x in self.inputs])
+ outs=",".join([x.name for x in self.outputs])
+ except AttributeError:
+ ins=",".join([str(x)for x in self.inputs])
+ outs=",".join([str(x)for x in self.outputs])
+ return"".join(['\n\t{task %r: '%id(self),self.__class__.__name__," ",ins," -> ",outs,'}'])
+ def uid(self):
+ try:
+ return self.uid_
+ except AttributeError:
+ m=Utils.md5()
+ up=m.update
+ up(self.__class__.__name__)
+ for x in self.inputs+self.outputs:
+ up(x.abspath())
+ self.uid_=m.digest()
+ return self.uid_
+ def set_inputs(self,inp):
+ if isinstance(inp,list):self.inputs+=inp
+ else:self.inputs.append(inp)
+ def set_outputs(self,out):
+ if isinstance(out,list):self.outputs+=out
+ else:self.outputs.append(out)
+ def set_run_after(self,task):
+ assert isinstance(task,TaskBase)
+ self.run_after.add(task)
+ def signature(self):
+ try:return self.cache_sig
+ except AttributeError:pass
+ self.m=Utils.md5()
+ self.m.update(self.hcode)
+ self.sig_explicit_deps()
+ self.sig_vars()
+ if self.scan:
+ try:
+ self.sig_implicit_deps()
+ except Errors.TaskRescan:
+ return self.signature()
+ ret=self.cache_sig=self.m.digest()
+ return ret
+ def runnable_status(self):
+ for t in self.run_after:
+ if not t.hasrun:
+ return ASK_LATER
+ bld=self.generator.bld
+ try:
+ new_sig=self.signature()
+ except Errors.TaskNotReady:
+ return ASK_LATER
+ key=self.uid()
+ try:
+ prev_sig=bld.task_sigs[key]
+ except KeyError:
+ Logs.debug("task: task %r must run as it was never run before or the task code changed"%self)
+ return RUN_ME
+ for node in self.outputs:
+ try:
+ if node.sig!=new_sig:
+ return RUN_ME
+ except AttributeError:
+ Logs.debug("task: task %r must run as the output nodes do not exist"%self)
+ return RUN_ME
+ if new_sig!=prev_sig:
+ return RUN_ME
+ return SKIP_ME
+ def post_run(self):
+ bld=self.generator.bld
+ sig=self.signature()
+ for node in self.outputs:
+ try:
+ os.stat(node.abspath())
+ except OSError:
+ self.hasrun=MISSING
+ self.err_msg='-> missing file: %r'%node.abspath()
+ raise Errors.WafError(self.err_msg)
+ node.sig=node.cache_sig=sig
+ bld.task_sigs[self.uid()]=self.cache_sig
+ def sig_explicit_deps(self):
+ bld=self.generator.bld
+ upd=self.m.update
+ for x in self.inputs+self.dep_nodes:
+ try:
+ upd(x.get_bld_sig())
+ except(AttributeError,TypeError):
+ raise Errors.WafError('Missing node signature for %r (required by %r)'%(x,self))
+ if bld.deps_man:
+ additional_deps=bld.deps_man
+ for x in self.inputs+self.outputs:
+ try:
+ d=additional_deps[id(x)]
+ except KeyError:
+ continue
+ for v in d:
+ if isinstance(v,bld.root.__class__):
+ try:
+ v=v.get_bld_sig()
+ except AttributeError:
+ raise Errors.WafError('Missing node signature for %r (required by %r)'%(v,self))
+ elif hasattr(v,'__call__'):
+ v=v()
+ upd(v)
+ return self.m.digest()
+ def sig_vars(self):
+ bld=self.generator.bld
+ env=self.env
+ upd=self.m.update
+ act_sig=bld.hash_env_vars(env,self.__class__.vars)
+ upd(act_sig)
+ dep_vars=getattr(self,'dep_vars',None)
+ if dep_vars:
+ upd(bld.hash_env_vars(env,dep_vars))
+ return self.m.digest()
+ scan=None
+ def sig_implicit_deps(self):
+ bld=self.generator.bld
+ key=self.uid()
+ prev=bld.task_sigs.get((key,'imp'),[])
+ if prev:
+ try:
+ if prev==self.compute_sig_implicit_deps():
+ return prev
+ except Errors.TaskNotReady:
+ raise
+ except EnvironmentError:
+ for x in bld.node_deps.get(self.uid(),[]):
+ if not x.is_bld():
+ try:
+ os.stat(x.abspath())
+ except OSError:
+ try:
+ del x.parent.children[x.name]
+ except KeyError:
+ pass
+ del bld.task_sigs[(key,'imp')]
+ raise Errors.TaskRescan('rescan')
+ (nodes,names)=self.scan()
+ if Logs.verbose:
+ Logs.debug('deps: scanner for %s returned %s %s'%(str(self),str(nodes),str(names)))
+ bld.node_deps[key]=nodes
+ bld.raw_deps[key]=names
+ self.are_implicit_nodes_ready()
+ try:
+ bld.task_sigs[(key,'imp')]=sig=self.compute_sig_implicit_deps()
+ except Exception:
+ if Logs.verbose:
+ for k in bld.node_deps.get(self.uid(),[]):
+ try:
+ k.get_bld_sig()
+ except Exception:
+ Logs.warn('Missing signature for node %r (may cause rebuilds)'%k)
+ else:
+ return sig
+ def compute_sig_implicit_deps(self):
+ upd=self.m.update
+ bld=self.generator.bld
+ self.are_implicit_nodes_ready()
+ for k in bld.node_deps.get(self.uid(),[]):
+ upd(k.get_bld_sig())
+ return self.m.digest()
+ def are_implicit_nodes_ready(self):
+ bld=self.generator.bld
+ try:
+ cache=bld.dct_implicit_nodes
+ except AttributeError:
+ bld.dct_implicit_nodes=cache={}
+ try:
+ dct=cache[bld.cur]
+ except KeyError:
+ dct=cache[bld.cur]={}
+ for tsk in bld.cur_tasks:
+ for x in tsk.outputs:
+ dct[x]=tsk
+ modified=False
+ for x in bld.node_deps.get(self.uid(),[]):
+ if x in dct:
+ self.run_after.add(dct[x])
+ modified=True
+ if modified:
+ for tsk in self.run_after:
+ if not tsk.hasrun:
+ raise Errors.TaskNotReady('not ready')
+if sys.hexversion>0x3000000:
+ def uid(self):
+ try:
+ return self.uid_
+ except AttributeError:
+ m=Utils.md5()
+ up=m.update
+ up(self.__class__.__name__.encode('iso8859-1','xmlcharrefreplace'))
+ for x in self.inputs+self.outputs:
+ up(x.abspath().encode('iso8859-1','xmlcharrefreplace'))
+ self.uid_=m.digest()
+ return self.uid_
+ uid.__doc__=Task.uid.__doc__
+ Task.uid=uid
+def is_before(t1,t2):
+ to_list=Utils.to_list
+ for k in to_list(t2.ext_in):
+ if k in to_list(t1.ext_out):
+ return 1
+ if t1.__class__.__name__ in to_list(t2.after):
+ return 1
+ if t2.__class__.__name__ in to_list(t1.before):
+ return 1
+ return 0
+def set_file_constraints(tasks):
+ ins=Utils.defaultdict(set)
+ outs=Utils.defaultdict(set)
+ for x in tasks:
+ for a in getattr(x,'inputs',[])+getattr(x,'dep_nodes',[]):
+ ins[id(a)].add(x)
+ for a in getattr(x,'outputs',[]):
+ outs[id(a)].add(x)
+ links=set(ins.keys()).intersection(outs.keys())
+ for k in links:
+ for a in ins[k]:
+ a.run_after.update(outs[k])
+def set_precedence_constraints(tasks):
+ cstr_groups=Utils.defaultdict(list)
+ for x in tasks:
+ h=x.hash_constraints()
+ cstr_groups[h].append(x)
+ keys=list(cstr_groups.keys())
+ maxi=len(keys)
+ for i in range(maxi):
+ t1=cstr_groups[keys[i]][0]
+ for j in range(i+1,maxi):
+ t2=cstr_groups[keys[j]][0]
+ if is_before(t1,t2):
+ a=i
+ b=j
+ elif is_before(t2,t1):
+ a=j
+ b=i
+ else:
+ continue
+ aval=set(cstr_groups[keys[a]])
+ for x in cstr_groups[keys[b]]:
+ x.run_after.update(aval)
+def funex(c):
+ dc={}
+ exec(c,dc)
+ return dc['f']
+re_novar=re.compile(r"^(SRC|TGT)\W+.*?$")
+reg_act=re.compile(r"(?P<backslash>\\)|(?P<dollar>\$\$)|(?P<subst>\$\{(?P<var>\w+)(?P<code>.*?)\})",re.M)
+def compile_fun_shell(line):
+ extr=[]
+ def repl(match):
+ g=match.group
+ if g('dollar'):return"$"
+ elif g('backslash'):return'\\\\'
+ elif g('subst'):extr.append((g('var'),g('code')));return"%s"
+ return None
+ line=reg_act.sub(repl,line)or line
+ parm=[]
+ dvars=[]
+ app=parm.append
+ for(var,meth)in extr:
+ if var=='SRC':
+ if meth:app('tsk.inputs%s'%meth)
+ else:app('" ".join([a.path_from(cwdx) for a in tsk.inputs])')
+ elif var=='TGT':
+ if meth:app('tsk.outputs%s'%meth)
+ else:app('" ".join([a.path_from(cwdx) for a in tsk.outputs])')
+ elif meth:
+ if meth.startswith(':'):
+ if var not in dvars:
+ dvars.append(var)
+ m=meth[1:]
+ if m=='SRC':
+ m='[a.path_from(cwdx) for a in tsk.inputs]'
+ elif m=='TGT':
+ m='[a.path_from(cwdx) for a in tsk.outputs]'
+ elif re_novar.match(m):
+ m='[tsk.inputs%s]'%m[3:]
+ elif re_novar.match(m):
+ m='[tsk.outputs%s]'%m[3:]
+ elif m[:3]not in('tsk','gen','bld'):
+ dvars.append(meth[1:])
+ m='%r'%m
+ app('" ".join(tsk.colon(%r, %s))'%(var,m))
+ else:
+ app('%s%s'%(var,meth))
+ else:
+ if var not in dvars:
+ dvars.append(var)
+ app("p('%s')"%var)
+ if parm:parm="%% (%s) "%(',\n\t\t'.join(parm))
+ else:parm=''
+ c=COMPILE_TEMPLATE_SHELL%(line,parm)
+ Logs.debug('action: %s'%c.strip().splitlines())
+ return(funex(c),dvars)
+def compile_fun_noshell(line):
+ extr=[]
+ def repl(match):
+ g=match.group
+ if g('dollar'):return"$"
+ elif g('backslash'):return'\\'
+ elif g('subst'):extr.append((g('var'),g('code')));return"<<|@|>>"
+ return None
+ line2=reg_act.sub(repl,line)
+ params=line2.split('<<|@|>>')
+ assert(extr)
+ buf=[]
+ dvars=[]
+ app=buf.append
+ for x in range(len(extr)):
+ params[x]=params[x].strip()
+ if params[x]:
+ app("lst.extend(%r)"%params[x].split())
+ (var,meth)=extr[x]
+ if var=='SRC':
+ if meth:app('lst.append(tsk.inputs%s)'%meth)
+ else:app("lst.extend([a.path_from(cwdx) for a in tsk.inputs])")
+ elif var=='TGT':
+ if meth:app('lst.append(tsk.outputs%s)'%meth)
+ else:app("lst.extend([a.path_from(cwdx) for a in tsk.outputs])")
+ elif meth:
+ if meth.startswith(':'):
+ if not var in dvars:
+ dvars.append(var)
+ m=meth[1:]
+ if m=='SRC':
+ m='[a.path_from(cwdx) for a in tsk.inputs]'
+ elif m=='TGT':
+ m='[a.path_from(cwdx) for a in tsk.outputs]'
+ elif re_novar.match(m):
+ m='[tsk.inputs%s]'%m[3:]
+ elif re_novar.match(m):
+ m='[tsk.outputs%s]'%m[3:]
+ elif m[:3]not in('tsk','gen','bld'):
+ dvars.append(m)
+ m='%r'%m
+ app('lst.extend(tsk.colon(%r, %s))'%(var,m))
+ else:
+ app('lst.extend(gen.to_list(%s%s))'%(var,meth))
+ else:
+ app('lst.extend(to_list(env[%r]))'%var)
+ if not var in dvars:
+ dvars.append(var)
+ if extr:
+ if params[-1]:
+ app("lst.extend(%r)"%params[-1].split())
+ fun=COMPILE_TEMPLATE_NOSHELL%"\n\t".join(buf)
+ Logs.debug('action: %s'%fun.strip().splitlines())
+ return(funex(fun),dvars)
+def compile_fun(line,shell=False):
+ if isinstance(line,str):
+ if line.find('<')>0 or line.find('>')>0 or line.find('&&')>0:
+ shell=True
+ else:
+ dvars_lst=[]
+ funs_lst=[]
+ for x in line:
+ if isinstance(x,str):
+ fun,dvars=compile_fun(x,shell)
+ dvars_lst+=dvars
+ funs_lst.append(fun)
+ else:
+ funs_lst.append(x)
+ def composed_fun(task):
+ for x in funs_lst:
+ ret=x(task)
+ if ret:
+ return ret
+ return None
+ return composed_fun,dvars
+ if shell:
+ return compile_fun_shell(line)
+ else:
+ return compile_fun_noshell(line)
+def task_factory(name,func=None,vars=None,color='GREEN',ext_in=[],ext_out=[],before=[],after=[],shell=False,scan=None):
+ params={'vars':vars or[],'color':color,'name':name,'ext_in':Utils.to_list(ext_in),'ext_out':Utils.to_list(ext_out),'before':Utils.to_list(before),'after':Utils.to_list(after),'shell':shell,'scan':scan,}
+ if isinstance(func,str)or isinstance(func,tuple):
+ params['run_str']=func
+ else:
+ params['run']=func
+ cls=type(Task)(name,(Task,),params)
+ global classes
+ classes[name]=cls
+ return cls
+def always_run(cls):
+ old=cls.runnable_status
+ def always(self):
+ ret=old(self)
+ if ret==SKIP_ME:
+ ret=RUN_ME
+ return ret
+ cls.runnable_status=always
+ return cls
+def update_outputs(cls):
+ old_post_run=cls.post_run
+ def post_run(self):
+ old_post_run(self)
+ for node in self.outputs:
+ node.sig=node.cache_sig=Utils.h_file(node.abspath())
+ self.generator.bld.task_sigs[node.abspath()]=self.uid()
+ cls.post_run=post_run
+ old_runnable_status=cls.runnable_status
+ def runnable_status(self):
+ status=old_runnable_status(self)
+ if status!=RUN_ME:
+ return status
+ try:
+ bld=self.generator.bld
+ prev_sig=bld.task_sigs[self.uid()]
+ if prev_sig==self.signature():
+ for x in self.outputs:
+ if not x.is_child_of(bld.bldnode):
+ x.sig=Utils.h_file(x.abspath())
+ if not x.sig or bld.task_sigs[x.abspath()]!=self.uid():
+ return RUN_ME
+ return SKIP_ME
+ except OSError:
+ pass
+ except IOError:
+ pass
+ except KeyError:
+ pass
+ except IndexError:
+ pass
+ except AttributeError:
+ pass
+ return RUN_ME
+ cls.runnable_status=runnable_status
+ return cls
diff --git a/waflib/TaskGen.py b/waflib/TaskGen.py
new file mode 100644
index 0000000..046f1f9
--- /dev/null
+++ b/waflib/TaskGen.py
@@ -0,0 +1,434 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import copy,re,os
+from waflib import Task,Utils,Logs,Errors,ConfigSet,Node
+feats=Utils.defaultdict(set)
+HEADER_EXTS=['.h','.hpp','.hxx','.hh']
+class task_gen(object):
+ mappings=Utils.ordered_iter_dict()
+ prec=Utils.defaultdict(list)
+ def __init__(self,*k,**kw):
+ self.source=''
+ self.target=''
+ self.meths=[]
+ self.prec=Utils.defaultdict(list)
+ self.mappings={}
+ self.features=[]
+ self.tasks=[]
+ if not'bld'in kw:
+ self.env=ConfigSet.ConfigSet()
+ self.idx=0
+ self.path=None
+ else:
+ self.bld=kw['bld']
+ self.env=self.bld.env.derive()
+ self.path=self.bld.path
+ try:
+ self.idx=self.bld.idx[id(self.path)]=self.bld.idx.get(id(self.path),0)+1
+ except AttributeError:
+ self.bld.idx={}
+ self.idx=self.bld.idx[id(self.path)]=1
+ for key,val in kw.items():
+ setattr(self,key,val)
+ def __str__(self):
+ return"<task_gen %r declared in %s>"%(self.name,self.path.abspath())
+ def __repr__(self):
+ lst=[]
+ for x in self.__dict__.keys():
+ if x not in('env','bld','compiled_tasks','tasks'):
+ lst.append("%s=%s"%(x,repr(getattr(self,x))))
+ return"bld(%s) in %s"%(", ".join(lst),self.path.abspath())
+ def get_name(self):
+ try:
+ return self._name
+ except AttributeError:
+ if isinstance(self.target,list):
+ lst=[str(x)for x in self.target]
+ name=self._name=','.join(lst)
+ else:
+ name=self._name=str(self.target)
+ return name
+ def set_name(self,name):
+ self._name=name
+ name=property(get_name,set_name)
+ def to_list(self,val):
+ if isinstance(val,str):return val.split()
+ else:return val
+ def post(self):
+ if getattr(self,'posted',None):
+ return False
+ self.posted=True
+ keys=set(self.meths)
+ self.features=Utils.to_list(self.features)
+ for x in self.features+['*']:
+ st=feats[x]
+ if not st:
+ if not x in Task.classes:
+ Logs.warn('feature %r does not exist - bind at least one method to it'%x)
+ keys.update(list(st))
+ prec={}
+ prec_tbl=self.prec or task_gen.prec
+ for x in prec_tbl:
+ if x in keys:
+ prec[x]=prec_tbl[x]
+ tmp=[]
+ for a in keys:
+ for x in prec.values():
+ if a in x:break
+ else:
+ tmp.append(a)
+ tmp.sort()
+ out=[]
+ while tmp:
+ e=tmp.pop()
+ if e in keys:out.append(e)
+ try:
+ nlst=prec[e]
+ except KeyError:
+ pass
+ else:
+ del prec[e]
+ for x in nlst:
+ for y in prec:
+ if x in prec[y]:
+ break
+ else:
+ tmp.append(x)
+ if prec:
+ txt='\n'.join(['- %s after %s'%(k,repr(v))for k,v in prec.items()])
+ raise Errors.WafError('Cycle detected in the method execution\n%s'%txt)
+ out.reverse()
+ self.meths=out
+ Logs.debug('task_gen: posting %s %d'%(self,id(self)))
+ for x in out:
+ try:
+ v=getattr(self,x)
+ except AttributeError:
+ raise Errors.WafError('%r is not a valid task generator method'%x)
+ Logs.debug('task_gen: -> %s (%d)'%(x,id(self)))
+ v()
+ Logs.debug('task_gen: posted %s'%self.name)
+ return True
+ def get_hook(self,node):
+ name=node.name
+ if self.mappings:
+ for k in self.mappings:
+ if name.endswith(k):
+ return self.mappings[k]
+ for k in task_gen.mappings:
+ if name.endswith(k):
+ return task_gen.mappings[k]
+ raise Errors.WafError("File %r has no mapping in %r (have you forgotten to load a waf tool?)"%(node,task_gen.mappings.keys()))
+ def create_task(self,name,src=None,tgt=None,**kw):
+ task=Task.classes[name](env=self.env.derive(),generator=self)
+ if src:
+ task.set_inputs(src)
+ if tgt:
+ task.set_outputs(tgt)
+ task.__dict__.update(kw)
+ self.tasks.append(task)
+ return task
+ def clone(self,env):
+ newobj=self.bld()
+ for x in self.__dict__:
+ if x in('env','bld'):
+ continue
+ elif x in('path','features'):
+ setattr(newobj,x,getattr(self,x))
+ else:
+ setattr(newobj,x,copy.copy(getattr(self,x)))
+ newobj.posted=False
+ if isinstance(env,str):
+ newobj.env=self.bld.all_envs[env].derive()
+ else:
+ newobj.env=env.derive()
+ return newobj
+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):
+ ext_in=Utils.to_list(ext_in)
+ ext_out=Utils.to_list(ext_out)
+ if not name:
+ name=rule
+ cls=Task.task_factory(name,rule,color=color,ext_in=ext_in,ext_out=ext_out,before=before,after=after,scan=scan,shell=shell)
+ def x_file(self,node):
+ ext=decider and decider(self,node)or cls.ext_out
+ if ext_in:
+ _ext_in=ext_in[0]
+ tsk=self.create_task(name,node)
+ cnt=0
+ keys=set(self.mappings.keys())|set(self.__class__.mappings.keys())
+ for x in ext:
+ k=node.change_ext(x,ext_in=_ext_in)
+ tsk.outputs.append(k)
+ if reentrant!=None:
+ if cnt<int(reentrant):
+ self.source.append(k)
+ else:
+ for y in keys:
+ if k.name.endswith(y):
+ self.source.append(k)
+ break
+ cnt+=1
+ if install_path:
+ self.bld.install_files(install_path,tsk.outputs)
+ return tsk
+ for x in cls.ext_in:
+ task_gen.mappings[x]=x_file
+ return x_file
+def taskgen_method(func):
+ setattr(task_gen,func.__name__,func)
+ return func
+def feature(*k):
+ def deco(func):
+ setattr(task_gen,func.__name__,func)
+ for name in k:
+ feats[name].update([func.__name__])
+ return func
+ return deco
+def before_method(*k):
+ def deco(func):
+ setattr(task_gen,func.__name__,func)
+ for fun_name in k:
+ if not func.__name__ in task_gen.prec[fun_name]:
+ task_gen.prec[fun_name].append(func.__name__)
+ return func
+ return deco
+before=before_method
+def after_method(*k):
+ def deco(func):
+ setattr(task_gen,func.__name__,func)
+ for fun_name in k:
+ if not fun_name in task_gen.prec[func.__name__]:
+ task_gen.prec[func.__name__].append(fun_name)
+ return func
+ return deco
+after=after_method
+def extension(*k):
+ def deco(func):
+ setattr(task_gen,func.__name__,func)
+ for x in k:
+ task_gen.mappings[x]=func
+ return func
+ return deco
+@taskgen_method
+def to_nodes(self,lst,path=None):
+ tmp=[]
+ path=path or self.path
+ find=path.find_resource
+ if isinstance(lst,Node.Node):
+ lst=[lst]
+ for x in Utils.to_list(lst):
+ if isinstance(x,str):
+ node=find(x)
+ else:
+ node=x
+ if not node:
+ raise Errors.WafError("source not found: %r in %r"%(x,self))
+ tmp.append(node)
+ return tmp
+@feature('*')
+def process_source(self):
+ self.source=self.to_nodes(getattr(self,'source',[]))
+ for node in self.source:
+ self.get_hook(node)(self,node)
+@feature('*')
+@before_method('process_source')
+def process_rule(self):
+ if not getattr(self,'rule',None):
+ return
+ name=str(getattr(self,'name',None)or self.target or getattr(self.rule,'__name__',self.rule))
+ try:
+ cache=self.bld.cache_rule_attr
+ except AttributeError:
+ cache=self.bld.cache_rule_attr={}
+ cls=None
+ if getattr(self,'cache_rule','True'):
+ try:
+ cls=cache[(name,self.rule)]
+ except KeyError:
+ pass
+ if not cls:
+ rule=self.rule
+ if hasattr(self,'chmod'):
+ def chmod_fun(tsk):
+ for x in tsk.outputs:
+ os.chmod(x.abspath(),self.chmod)
+ rule=(self.rule,chmod_fun)
+ cls=Task.task_factory(name,rule,getattr(self,'vars',[]),shell=getattr(self,'shell',True),color=getattr(self,'color','BLUE'),scan=getattr(self,'scan',None))
+ if getattr(self,'scan',None):
+ cls.scan=self.scan
+ elif getattr(self,'deps',None):
+ def scan(self):
+ nodes=[]
+ for x in self.generator.to_list(getattr(self.generator,'deps',None)):
+ node=self.generator.path.find_resource(x)
+ if not node:
+ self.generator.bld.fatal('Could not find %r (was it declared?)'%x)
+ nodes.append(node)
+ return[nodes,[]]
+ cls.scan=scan
+ if getattr(self,'update_outputs',None):
+ Task.update_outputs(cls)
+ if getattr(self,'always',None):
+ Task.always_run(cls)
+ for x in('after','before','ext_in','ext_out'):
+ setattr(cls,x,getattr(self,x,[]))
+ if getattr(self,'cache_rule','True'):
+ cache[(name,self.rule)]=cls
+ if getattr(self,'cls_str',None):
+ setattr(cls,'__str__',self.cls_str)
+ if getattr(self,'cls_keyword',None):
+ setattr(cls,'keyword',self.cls_keyword)
+ tsk=self.create_task(name)
+ if getattr(self,'target',None):
+ if isinstance(self.target,str):
+ self.target=self.target.split()
+ if not isinstance(self.target,list):
+ self.target=[self.target]
+ for x in self.target:
+ if isinstance(x,str):
+ tsk.outputs.append(self.path.find_or_declare(x))
+ else:
+ x.parent.mkdir()
+ tsk.outputs.append(x)
+ if getattr(self,'install_path',None):
+ self.bld.install_files(self.install_path,tsk.outputs,chmod=getattr(self,'chmod',Utils.O644))
+ if getattr(self,'source',None):
+ tsk.inputs=self.to_nodes(self.source)
+ self.source=[]
+ if getattr(self,'cwd',None):
+ tsk.cwd=self.cwd
+@feature('seq')
+def sequence_order(self):
+ if self.meths and self.meths[-1]!='sequence_order':
+ self.meths.append('sequence_order')
+ return
+ if getattr(self,'seq_start',None):
+ return
+ if getattr(self.bld,'prev',None):
+ self.bld.prev.post()
+ for x in self.bld.prev.tasks:
+ for y in self.tasks:
+ y.set_run_after(x)
+ self.bld.prev=self
+re_m4=re.compile('@(\w+)@',re.M)
+class subst_pc(Task.Task):
+ def force_permissions(self):
+ if getattr(self.generator,'chmod',None):
+ for x in self.outputs:
+ os.chmod(x.abspath(),self.generator.chmod)
+ def run(self):
+ if getattr(self.generator,'is_copy',None):
+ for i,x in enumerate(self.outputs):
+ x.write(self.inputs[i].read('rb'),'wb')
+ self.force_permissions()
+ return None
+ if getattr(self.generator,'fun',None):
+ ret=self.generator.fun(self)
+ if not ret:
+ self.force_permissions()
+ return ret
+ code=self.inputs[0].read(encoding=getattr(self.generator,'encoding','ISO8859-1'))
+ if getattr(self.generator,'subst_fun',None):
+ code=self.generator.subst_fun(self,code)
+ if code is not None:
+ self.outputs[0].write(code,encoding=getattr(self.generator,'encoding','ISO8859-1'))
+ self.force_permissions()
+ return None
+ code=code.replace('%','%%')
+ lst=[]
+ def repl(match):
+ g=match.group
+ if g(1):
+ lst.append(g(1))
+ return"%%(%s)s"%g(1)
+ return''
+ global re_m4
+ code=getattr(self.generator,'re_m4',re_m4).sub(repl,code)
+ try:
+ d=self.generator.dct
+ except AttributeError:
+ d={}
+ for x in lst:
+ tmp=getattr(self.generator,x,'')or self.env[x]or self.env[x.upper()]
+ try:
+ tmp=''.join(tmp)
+ except TypeError:
+ tmp=str(tmp)
+ d[x]=tmp
+ code=code%d
+ self.outputs[0].write(code,encoding=getattr(self.generator,'encoding','ISO8859-1'))
+ self.generator.bld.raw_deps[self.uid()]=self.dep_vars=lst
+ try:delattr(self,'cache_sig')
+ except AttributeError:pass
+ self.force_permissions()
+ def sig_vars(self):
+ bld=self.generator.bld
+ env=self.env
+ upd=self.m.update
+ if getattr(self.generator,'fun',None):
+ upd(Utils.h_fun(self.generator.fun))
+ if getattr(self.generator,'subst_fun',None):
+ upd(Utils.h_fun(self.generator.subst_fun))
+ vars=self.generator.bld.raw_deps.get(self.uid(),[])
+ act_sig=bld.hash_env_vars(env,vars)
+ upd(act_sig)
+ lst=[getattr(self.generator,x,'')for x in vars]
+ upd(Utils.h_list(lst))
+ return self.m.digest()
+@extension('.pc.in')
+def add_pcfile(self,node):
+ tsk=self.create_task('subst_pc',node,node.change_ext('.pc','.pc.in'))
+ self.bld.install_files(getattr(self,'install_path','${LIBDIR}/pkgconfig/'),tsk.outputs)
+class subst(subst_pc):
+ pass
+@feature('subst')
+@before_method('process_source','process_rule')
+def process_subst(self):
+ src=Utils.to_list(getattr(self,'source',[]))
+ if isinstance(src,Node.Node):
+ src=[src]
+ tgt=Utils.to_list(getattr(self,'target',[]))
+ if isinstance(tgt,Node.Node):
+ tgt=[tgt]
+ if len(src)!=len(tgt):
+ raise Errors.WafError('invalid number of source/target for %r'%self)
+ for x,y in zip(src,tgt):
+ if not x or not y:
+ raise Errors.WafError('null source or target for %r'%self)
+ a,b=None,None
+ if isinstance(x,str)and isinstance(y,str)and x==y:
+ a=self.path.find_node(x)
+ b=self.path.get_bld().make_node(y)
+ if not os.path.isfile(b.abspath()):
+ b.sig=None
+ b.parent.mkdir()
+ else:
+ if isinstance(x,str):
+ a=self.path.find_resource(x)
+ elif isinstance(x,Node.Node):
+ a=x
+ if isinstance(y,str):
+ b=self.path.find_or_declare(y)
+ elif isinstance(y,Node.Node):
+ b=y
+ if not a:
+ raise Errors.WafError('could not find %r for %r'%(x,self))
+ has_constraints=False
+ tsk=self.create_task('subst',a,b)
+ for k in('after','before','ext_in','ext_out'):
+ val=getattr(self,k,None)
+ if val:
+ has_constraints=True
+ setattr(tsk,k,val)
+ if not has_constraints:
+ global HEADER_EXTS
+ for xt in HEADER_EXTS:
+ if b.name.endswith(xt):
+ tsk.before=[k for k in('c','cxx')if k in Task.classes]
+ break
+ inst_to=getattr(self,'install_path',None)
+ if inst_to:
+ self.bld.install_files(inst_to,b,chmod=getattr(self,'chmod',Utils.O644))
+ self.source=[]
diff --git a/waflib/Tools/__init__.py b/waflib/Tools/__init__.py
new file mode 100644
index 0000000..55e850d
--- /dev/null
+++ b/waflib/Tools/__init__.py
@@ -0,0 +1,4 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
diff --git a/waflib/Tools/ar.py b/waflib/Tools/ar.py
new file mode 100644
index 0000000..5921ce1
--- /dev/null
+++ b/waflib/Tools/ar.py
@@ -0,0 +1,13 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib.Configure import conf
+@conf
+def find_ar(conf):
+ conf.load('ar')
+def configure(conf):
+ conf.find_program('ar',var='AR')
+ conf.add_os_flags('ARFLAGS')
+ if not conf.env.ARFLAGS:
+ conf.env.ARFLAGS=['rcs']
diff --git a/waflib/Tools/asm.py b/waflib/Tools/asm.py
new file mode 100644
index 0000000..3f1e135
--- /dev/null
+++ b/waflib/Tools/asm.py
@@ -0,0 +1,24 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib import Task
+import waflib.Task
+from waflib.Tools.ccroot import link_task,stlink_task
+from waflib.TaskGen import extension
+class asm(Task.Task):
+ color='BLUE'
+ run_str='${AS} ${ASFLAGS} ${ASMPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${AS_SRC_F}${SRC} ${AS_TGT_F}${TGT}'
+@extension('.s','.S','.asm','.ASM','.spp','.SPP')
+def asm_hook(self,node):
+ return self.create_compiled_task('asm',node)
+class asmprogram(link_task):
+ run_str='${ASLINK} ${ASLINKFLAGS} ${ASLNK_TGT_F}${TGT} ${ASLNK_SRC_F}${SRC}'
+ ext_out=['.bin']
+ inst_to='${BINDIR}'
+class asmshlib(asmprogram):
+ inst_to='${LIBDIR}'
+class asmstlib(stlink_task):
+ pass
+def configure(conf):
+ conf.env['ASMPATH_ST']='-I%s'
diff --git a/waflib/Tools/bison.py b/waflib/Tools/bison.py
new file mode 100644
index 0000000..c85c8d6
--- /dev/null
+++ b/waflib/Tools/bison.py
@@ -0,0 +1,28 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib import Task
+from waflib.TaskGen import extension
+class bison(Task.Task):
+ color='BLUE'
+ run_str='${BISON} ${BISONFLAGS} ${SRC[0].abspath()} -o ${TGT[0].name}'
+ ext_out=['.h']
+@extension('.y','.yc','.yy')
+def big_bison(self,node):
+ has_h='-d'in self.env['BISONFLAGS']
+ outs=[]
+ if node.name.endswith('.yc'):
+ outs.append(node.change_ext('.tab.cc'))
+ if has_h:
+ outs.append(node.change_ext('.tab.hh'))
+ else:
+ outs.append(node.change_ext('.tab.c'))
+ if has_h:
+ outs.append(node.change_ext('.tab.h'))
+ tsk=self.create_task('bison',node,outs)
+ tsk.cwd=node.parent.get_bld().abspath()
+ self.source.append(outs[0])
+def configure(conf):
+ conf.find_program('bison',var='BISON')
+ conf.env.BISONFLAGS=['-d']
diff --git a/waflib/Tools/c.py b/waflib/Tools/c.py
new file mode 100644
index 0000000..e3e7665
--- /dev/null
+++ b/waflib/Tools/c.py
@@ -0,0 +1,26 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib import TaskGen,Task
+from waflib.Tools import c_preproc
+from waflib.Tools.ccroot import link_task,stlink_task
+@TaskGen.extension('.c')
+def c_hook(self,node):
+ if not self.env.CC and self.env.CXX:
+ return self.create_compiled_task('cxx',node)
+ return self.create_compiled_task('c',node)
+class c(Task.Task):
+ run_str='${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CC_SRC_F}${SRC} ${CC_TGT_F}${TGT[0].abspath()}'
+ vars=['CCDEPS']
+ ext_in=['.h']
+ scan=c_preproc.scan
+class cprogram(link_task):
+ 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}'
+ ext_out=['.bin']
+ vars=['LINKDEPS']
+ inst_to='${BINDIR}'
+class cshlib(cprogram):
+ inst_to='${LIBDIR}'
+class cstlib(stlink_task):
+ pass
diff --git a/waflib/Tools/c_aliases.py b/waflib/Tools/c_aliases.py
new file mode 100644
index 0000000..e947f0d
--- /dev/null
+++ b/waflib/Tools/c_aliases.py
@@ -0,0 +1,63 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib import Utils,Errors
+from waflib.Configure import conf
+def get_extensions(lst):
+ ret=[]
+ for x in Utils.to_list(lst):
+ try:
+ if not isinstance(x,str):
+ x=x.name
+ ret.append(x[x.rfind('.')+1:])
+ except Exception:
+ pass
+ return ret
+def sniff_features(**kw):
+ exts=get_extensions(kw['source'])
+ type=kw['_type']
+ feats=[]
+ for x in'cxx cpp c++ cc C'.split():
+ if x in exts:
+ feats.append('cxx')
+ break
+ if'c'in exts or'vala'in exts or'gs'in exts:
+ feats.append('c')
+ for x in'f f90 F F90 for FOR'.split():
+ if x in exts:
+ feats.append('fc')
+ break
+ if'd'in exts:
+ feats.append('d')
+ if'java'in exts:
+ feats.append('java')
+ return'java'
+ if type in('program','shlib','stlib'):
+ will_link=False
+ for x in feats:
+ if x in('cxx','d','fc','c'):
+ feats.append(x+type)
+ will_link=True
+ if not will_link and not kw.get('features',[]):
+ raise Errors.WafError('Cannot link from %r, try passing eg: features="c cprogram"?'%kw)
+ return feats
+def set_features(kw,_type):
+ kw['_type']=_type
+ kw['features']=Utils.to_list(kw.get('features',[]))+Utils.to_list(sniff_features(**kw))
+@conf
+def program(bld,*k,**kw):
+ set_features(kw,'program')
+ return bld(*k,**kw)
+@conf
+def shlib(bld,*k,**kw):
+ set_features(kw,'shlib')
+ return bld(*k,**kw)
+@conf
+def stlib(bld,*k,**kw):
+ set_features(kw,'stlib')
+ return bld(*k,**kw)
+@conf
+def objects(bld,*k,**kw):
+ set_features(kw,'objects')
+ return bld(*k,**kw)
diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py
new file mode 100644
index 0000000..856e7b0
--- /dev/null
+++ b/waflib/Tools/c_config.py
@@ -0,0 +1,760 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,re,shlex
+from waflib import Build,Utils,Task,Options,Logs,Errors,Runner
+from waflib.TaskGen import after_method,feature
+from waflib.Configure import conf
+WAF_CONFIG_H='config.h'
+DEFKEYS='define_key'
+INCKEYS='include_key'
+cfg_ver={'atleast-version':'>=','exact-version':'==','max-version':'<=',}
+SNIP_FUNCTION='''
+int main(int argc, char **argv) {
+ void (*p)();
+ (void)argc; (void)argv;
+ p=(void(*)())(%s);
+ return !p;
+}
+'''
+SNIP_TYPE='''
+int main(int argc, char **argv) {
+ (void)argc; (void)argv;
+ if ((%(type_name)s *) 0) return 0;
+ if (sizeof (%(type_name)s)) return 0;
+ return 1;
+}
+'''
+SNIP_EMPTY_PROGRAM='''
+int main(int argc, char **argv) {
+ (void)argc; (void)argv;
+ return 0;
+}
+'''
+SNIP_FIELD='''
+int main(int argc, char **argv) {
+ char *off;
+ (void)argc; (void)argv;
+ off = (char*) &((%(type_name)s*)0)->%(field_name)s;
+ return (size_t) off < sizeof(%(type_name)s);
+}
+'''
+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'}
+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',}
+@conf
+def parse_flags(self,line,uselib_store,env=None,force_static=False,posix=None):
+ assert(isinstance(line,str))
+ env=env or self.env
+ if posix is None:
+ posix=True
+ if'\\'in line:
+ posix=('\\ 'in line)or('\\\\'in line)
+ lex=shlex.shlex(line,posix=posix)
+ lex.whitespace_split=True
+ lex.commenters=''
+ lst=list(lex)
+ app=env.append_value
+ appu=env.append_unique
+ uselib=uselib_store
+ static=False
+ while lst:
+ x=lst.pop(0)
+ st=x[:2]
+ ot=x[2:]
+ if st=='-I'or st=='/I':
+ if not ot:ot=lst.pop(0)
+ appu('INCLUDES_'+uselib,[ot])
+ elif st=='-i':
+ tmp=[x,lst.pop(0)]
+ app('CFLAGS',tmp)
+ app('CXXFLAGS',tmp)
+ elif st=='-D'or(env.CXX_NAME=='msvc'and st=='/D'):
+ if not ot:ot=lst.pop(0)
+ app('DEFINES_'+uselib,[ot])
+ elif st=='-l':
+ if not ot:ot=lst.pop(0)
+ prefix=(force_static or static)and'STLIB_'or'LIB_'
+ appu(prefix+uselib,[ot])
+ elif st=='-L':
+ if not ot:ot=lst.pop(0)
+ prefix=(force_static or static)and'STLIBPATH_'or'LIBPATH_'
+ appu(prefix+uselib,[ot])
+ elif x.startswith('/LIBPATH:'):
+ prefix=(force_static or static)and'STLIBPATH_'or'LIBPATH_'
+ appu(prefix+uselib,[x.replace('/LIBPATH:','')])
+ elif x=='-pthread'or x.startswith('+')or x.startswith('-std'):
+ app('CFLAGS_'+uselib,[x])
+ app('CXXFLAGS_'+uselib,[x])
+ app('LINKFLAGS_'+uselib,[x])
+ elif x=='-framework':
+ appu('FRAMEWORK_'+uselib,[lst.pop(0)])
+ elif x.startswith('-F'):
+ appu('FRAMEWORKPATH_'+uselib,[x[2:]])
+ elif x=='-Wl,-rpath'or x=='-Wl,-R':
+ app('RPATH_'+uselib,lst.pop(0).lstrip('-Wl,'))
+ elif x.startswith('-Wl,-R,'):
+ app('RPATH_'+uselib,x[7:])
+ elif x.startswith('-Wl,-R'):
+ app('RPATH_'+uselib,x[6:])
+ elif x.startswith('-Wl,-rpath,'):
+ app('RPATH_'+uselib,x[11:])
+ elif x=='-Wl,-Bstatic'or x=='-Bstatic':
+ static=True
+ elif x=='-Wl,-Bdynamic'or x=='-Bdynamic':
+ static=False
+ elif x.startswith('-Wl'):
+ app('LINKFLAGS_'+uselib,[x])
+ elif x.startswith('-m')or x.startswith('-f')or x.startswith('-dynamic'):
+ app('CFLAGS_'+uselib,[x])
+ app('CXXFLAGS_'+uselib,[x])
+ elif x.startswith('-bundle'):
+ app('LINKFLAGS_'+uselib,[x])
+ elif x.startswith('-undefined')or x.startswith('-Xlinker'):
+ arg=lst.pop(0)
+ app('LINKFLAGS_'+uselib,[x,arg])
+ elif x.startswith('-arch')or x.startswith('-isysroot'):
+ tmp=[x,lst.pop(0)]
+ app('CFLAGS_'+uselib,tmp)
+ app('CXXFLAGS_'+uselib,tmp)
+ app('LINKFLAGS_'+uselib,tmp)
+ elif x.endswith('.a')or x.endswith('.so')or x.endswith('.dylib')or x.endswith('.lib'):
+ appu('LINKFLAGS_'+uselib,[x])
+@conf
+def validate_cfg(self,kw):
+ if not'path'in kw:
+ if not self.env.PKGCONFIG:
+ self.find_program('pkg-config',var='PKGCONFIG')
+ kw['path']=self.env.PKGCONFIG
+ if'atleast_pkgconfig_version'in kw:
+ if not'msg'in kw:
+ kw['msg']='Checking for pkg-config version >= %r'%kw['atleast_pkgconfig_version']
+ return
+ if not'okmsg'in kw:
+ kw['okmsg']='yes'
+ if not'errmsg'in kw:
+ kw['errmsg']='not found'
+ if'modversion'in kw:
+ if not'msg'in kw:
+ kw['msg']='Checking for %r version'%kw['modversion']
+ return
+ for x in cfg_ver.keys():
+ y=x.replace('-','_')
+ if y in kw:
+ if not'package'in kw:
+ raise ValueError('%s requires a package'%x)
+ if not'msg'in kw:
+ kw['msg']='Checking for %r %s %s'%(kw['package'],cfg_ver[x],kw[y])
+ return
+ if not'define_name'in kw:
+ pkgname=kw.get('uselib_store',kw['package'].upper())
+ kw['define_name']=self.have_define(pkgname)
+ if not'uselib_store'in kw:
+ self.undefine(kw['define_name'])
+ if not'msg'in kw:
+ kw['msg']='Checking for %r'%(kw['package']or kw['path'])
+@conf
+def exec_cfg(self,kw):
+ path=Utils.to_list(kw['path'])
+ env=self.env.env or None
+ def define_it():
+ pkgname=kw.get('uselib_store',kw['package'].upper())
+ if kw.get('global_define'):
+ self.define(self.have_define(kw['package']),1,False)
+ else:
+ self.env.append_unique('DEFINES_%s'%pkgname,"%s=1"%self.have_define(pkgname))
+ self.env[self.have_define(pkgname)]=1
+ if'atleast_pkgconfig_version'in kw:
+ cmd=path+['--atleast-pkgconfig-version=%s'%kw['atleast_pkgconfig_version']]
+ self.cmd_and_log(cmd,env=env)
+ if not'okmsg'in kw:
+ kw['okmsg']='yes'
+ return
+ for x in cfg_ver:
+ y=x.replace('-','_')
+ if y in kw:
+ self.cmd_and_log(path+['--%s=%s'%(x,kw[y]),kw['package']],env=env)
+ if not'okmsg'in kw:
+ kw['okmsg']='yes'
+ define_it()
+ break
+ if'modversion'in kw:
+ version=self.cmd_and_log(path+['--modversion',kw['modversion']],env=env).strip()
+ self.define('%s_VERSION'%Utils.quote_define_name(kw.get('uselib_store',kw['modversion'])),version)
+ return version
+ lst=[]+path
+ defi=kw.get('define_variable',None)
+ if not defi:
+ defi=self.env.PKG_CONFIG_DEFINES or{}
+ for key,val in defi.items():
+ lst.append('--define-variable=%s=%s'%(key,val))
+ static=kw.get('force_static',False)
+ if'args'in kw:
+ args=Utils.to_list(kw['args'])
+ if'--static'in args or'--static-libs'in args:
+ static=True
+ lst+=args
+ lst.extend(Utils.to_list(kw['package']))
+ if'variables'in kw:
+ v_env=kw.get('env',self.env)
+ uselib=kw.get('uselib_store',kw['package'].upper())
+ vars=Utils.to_list(kw['variables'])
+ for v in vars:
+ val=self.cmd_and_log(lst+['--variable='+v],env=env).strip()
+ var='%s_%s'%(uselib,v)
+ v_env[var]=val
+ if not'okmsg'in kw:
+ kw['okmsg']='yes'
+ return
+ ret=self.cmd_and_log(lst,env=env)
+ if not'okmsg'in kw:
+ kw['okmsg']='yes'
+ define_it()
+ self.parse_flags(ret,kw.get('uselib_store',kw['package'].upper()),kw.get('env',self.env),force_static=static,posix=kw.get('posix',None))
+ return ret
+@conf
+def check_cfg(self,*k,**kw):
+ if k:
+ lst=k[0].split()
+ kw['package']=lst[0]
+ kw['args']=' '.join(lst[1:])
+ self.validate_cfg(kw)
+ if'msg'in kw:
+ self.start_msg(kw['msg'],**kw)
+ ret=None
+ try:
+ ret=self.exec_cfg(kw)
+ except self.errors.WafError:
+ if'errmsg'in kw:
+ self.end_msg(kw['errmsg'],'YELLOW',**kw)
+ if Logs.verbose>1:
+ raise
+ else:
+ self.fatal('The configuration failed')
+ else:
+ if not ret:
+ ret=True
+ kw['success']=ret
+ if'okmsg'in kw:
+ self.end_msg(self.ret_msg(kw['okmsg'],kw),**kw)
+ return ret
+def build_fun(bld):
+ if bld.kw['compile_filename']:
+ node=bld.srcnode.make_node(bld.kw['compile_filename'])
+ node.write(bld.kw['code'])
+ o=bld(features=bld.kw['features'],source=bld.kw['compile_filename'],target='testprog')
+ for k,v in bld.kw.items():
+ setattr(o,k,v)
+ if not bld.kw.get('quiet',None):
+ bld.conf.to_log("==>\n%s\n<=="%bld.kw['code'])
+@conf
+def validate_c(self,kw):
+ if not'build_fun'in kw:
+ kw['build_fun']=build_fun
+ if not'env'in kw:
+ kw['env']=self.env.derive()
+ env=kw['env']
+ if not'compiler'in kw and not'features'in kw:
+ kw['compiler']='c'
+ if env['CXX_NAME']and Task.classes.get('cxx',None):
+ kw['compiler']='cxx'
+ if not self.env['CXX']:
+ self.fatal('a c++ compiler is required')
+ else:
+ if not self.env['CC']:
+ self.fatal('a c compiler is required')
+ if not'compile_mode'in kw:
+ kw['compile_mode']='c'
+ if'cxx'in Utils.to_list(kw.get('features',[]))or kw.get('compiler','')=='cxx':
+ kw['compile_mode']='cxx'
+ if not'type'in kw:
+ kw['type']='cprogram'
+ if not'features'in kw:
+ if not'header_name'in kw or kw.get('link_header_test',True):
+ kw['features']=[kw['compile_mode'],kw['type']]
+ else:
+ kw['features']=[kw['compile_mode']]
+ else:
+ kw['features']=Utils.to_list(kw['features'])
+ if not'compile_filename'in kw:
+ kw['compile_filename']='test.c'+((kw['compile_mode']=='cxx')and'pp'or'')
+ def to_header(dct):
+ if'header_name'in dct:
+ dct=Utils.to_list(dct['header_name'])
+ return''.join(['#include <%s>\n'%x for x in dct])
+ return''
+ if'framework_name'in kw:
+ fwkname=kw['framework_name']
+ if not'uselib_store'in kw:
+ kw['uselib_store']=fwkname.upper()
+ if not kw.get('no_header',False):
+ if not'header_name'in kw:
+ kw['header_name']=[]
+ fwk='%s/%s.h'%(fwkname,fwkname)
+ if kw.get('remove_dot_h',None):
+ fwk=fwk[:-2]
+ kw['header_name']=Utils.to_list(kw['header_name'])+[fwk]
+ kw['msg']='Checking for framework %s'%fwkname
+ kw['framework']=fwkname
+ if'function_name'in kw:
+ fu=kw['function_name']
+ if not'msg'in kw:
+ kw['msg']='Checking for function %s'%fu
+ kw['code']=to_header(kw)+SNIP_FUNCTION%fu
+ if not'uselib_store'in kw:
+ kw['uselib_store']=fu.upper()
+ if not'define_name'in kw:
+ kw['define_name']=self.have_define(fu)
+ elif'type_name'in kw:
+ tu=kw['type_name']
+ if not'header_name'in kw:
+ kw['header_name']='stdint.h'
+ if'field_name'in kw:
+ field=kw['field_name']
+ kw['code']=to_header(kw)+SNIP_FIELD%{'type_name':tu,'field_name':field}
+ if not'msg'in kw:
+ kw['msg']='Checking for field %s in %s'%(field,tu)
+ if not'define_name'in kw:
+ kw['define_name']=self.have_define((tu+'_'+field).upper())
+ else:
+ kw['code']=to_header(kw)+SNIP_TYPE%{'type_name':tu}
+ if not'msg'in kw:
+ kw['msg']='Checking for type %s'%tu
+ if not'define_name'in kw:
+ kw['define_name']=self.have_define(tu.upper())
+ elif'header_name'in kw:
+ if not'msg'in kw:
+ kw['msg']='Checking for header %s'%kw['header_name']
+ l=Utils.to_list(kw['header_name'])
+ assert len(l)>0,'list of headers in header_name is empty'
+ kw['code']=to_header(kw)+SNIP_EMPTY_PROGRAM
+ if not'uselib_store'in kw:
+ kw['uselib_store']=l[0].upper()
+ if not'define_name'in kw:
+ kw['define_name']=self.have_define(l[0])
+ if'lib'in kw:
+ if not'msg'in kw:
+ kw['msg']='Checking for library %s'%kw['lib']
+ if not'uselib_store'in kw:
+ kw['uselib_store']=kw['lib'].upper()
+ if'stlib'in kw:
+ if not'msg'in kw:
+ kw['msg']='Checking for static library %s'%kw['stlib']
+ if not'uselib_store'in kw:
+ kw['uselib_store']=kw['stlib'].upper()
+ if'fragment'in kw:
+ kw['code']=kw['fragment']
+ if not'msg'in kw:
+ kw['msg']='Checking for code snippet'
+ if not'errmsg'in kw:
+ kw['errmsg']='no'
+ for(flagsname,flagstype)in(('cxxflags','compiler'),('cflags','compiler'),('linkflags','linker')):
+ if flagsname in kw:
+ if not'msg'in kw:
+ kw['msg']='Checking for %s flags %s'%(flagstype,kw[flagsname])
+ if not'errmsg'in kw:
+ kw['errmsg']='no'
+ if not'execute'in kw:
+ kw['execute']=False
+ if kw['execute']:
+ kw['features'].append('test_exec')
+ kw['chmod']=493
+ if not'errmsg'in kw:
+ kw['errmsg']='not found'
+ if not'okmsg'in kw:
+ kw['okmsg']='yes'
+ if not'code'in kw:
+ kw['code']=SNIP_EMPTY_PROGRAM
+ if self.env[INCKEYS]:
+ kw['code']='\n'.join(['#include <%s>'%x for x in self.env[INCKEYS]])+'\n'+kw['code']
+ if kw.get('merge_config_header',False)or env.merge_config_header:
+ kw['code']='%s\n\n%s'%(self.get_config_header(),kw['code'])
+ env.DEFINES=[]
+ if not kw.get('success'):kw['success']=None
+ if'define_name'in kw:
+ self.undefine(kw['define_name'])
+ if not'msg'in kw:
+ self.fatal('missing "msg" in conf.check(...)')
+@conf
+def post_check(self,*k,**kw):
+ is_success=0
+ if kw['execute']:
+ if kw['success']is not None:
+ if kw.get('define_ret',False):
+ is_success=kw['success']
+ else:
+ is_success=(kw['success']==0)
+ else:
+ is_success=(kw['success']==0)
+ if'define_name'in kw:
+ comment=kw.get('comment','')
+ define_name=kw['define_name']
+ if'header_name'in kw or'function_name'in kw or'type_name'in kw or'fragment'in kw:
+ if kw['execute']and kw.get('define_ret',None)and isinstance(is_success,str):
+ self.define(define_name,is_success,quote=kw.get('quote',1),comment=comment)
+ else:
+ self.define_cond(define_name,is_success,comment=comment)
+ else:
+ self.define_cond(define_name,is_success,comment=comment)
+ if kw.get('global_define',None):
+ self.env[kw['define_name']]=is_success
+ if'header_name'in kw:
+ if kw.get('auto_add_header_name',False):
+ self.env.append_value(INCKEYS,Utils.to_list(kw['header_name']))
+ if is_success and'uselib_store'in kw:
+ from waflib.Tools import ccroot
+ _vars=set([])
+ for x in kw['features']:
+ if x in ccroot.USELIB_VARS:
+ _vars|=ccroot.USELIB_VARS[x]
+ for k in _vars:
+ lk=k.lower()
+ if lk in kw:
+ val=kw[lk]
+ if isinstance(val,str):
+ val=val.rstrip(os.path.sep)
+ self.env.append_unique(k+'_'+kw['uselib_store'],Utils.to_list(val))
+ return is_success
+@conf
+def check(self,*k,**kw):
+ self.validate_c(kw)
+ self.start_msg(kw['msg'],**kw)
+ ret=None
+ try:
+ ret=self.run_build(*k,**kw)
+ except self.errors.ConfigurationError:
+ self.end_msg(kw['errmsg'],'YELLOW',**kw)
+ if Logs.verbose>1:
+ raise
+ else:
+ self.fatal('The configuration failed')
+ else:
+ kw['success']=ret
+ ret=self.post_check(*k,**kw)
+ if not ret:
+ self.end_msg(kw['errmsg'],'YELLOW',**kw)
+ self.fatal('The configuration failed %r'%ret)
+ else:
+ self.end_msg(self.ret_msg(kw['okmsg'],kw),**kw)
+ return ret
+class test_exec(Task.Task):
+ color='PINK'
+ def run(self):
+ if getattr(self.generator,'rpath',None):
+ if getattr(self.generator,'define_ret',False):
+ self.generator.bld.retval=self.generator.bld.cmd_and_log([self.inputs[0].abspath()])
+ else:
+ self.generator.bld.retval=self.generator.bld.exec_command([self.inputs[0].abspath()])
+ else:
+ env=self.env.env or{}
+ env.update(dict(os.environ))
+ for var in('LD_LIBRARY_PATH','DYLD_LIBRARY_PATH','PATH'):
+ env[var]=self.inputs[0].parent.abspath()+os.path.pathsep+env.get(var,'')
+ if getattr(self.generator,'define_ret',False):
+ self.generator.bld.retval=self.generator.bld.cmd_and_log([self.inputs[0].abspath()],env=env)
+ else:
+ self.generator.bld.retval=self.generator.bld.exec_command([self.inputs[0].abspath()],env=env)
+@feature('test_exec')
+@after_method('apply_link')
+def test_exec_fun(self):
+ self.create_task('test_exec',self.link_task.outputs[0])
+@conf
+def check_cxx(self,*k,**kw):
+ kw['compiler']='cxx'
+ return self.check(*k,**kw)
+@conf
+def check_cc(self,*k,**kw):
+ kw['compiler']='c'
+ return self.check(*k,**kw)
+@conf
+def set_define_comment(self,key,comment):
+ coms=self.env.DEFINE_COMMENTS
+ if not coms:
+ coms=self.env.DEFINE_COMMENTS={}
+ coms[key]=comment or''
+@conf
+def get_define_comment(self,key):
+ coms=self.env.DEFINE_COMMENTS or{}
+ return coms.get(key,'')
+@conf
+def define(self,key,val,quote=True,comment=''):
+ assert key and isinstance(key,str)
+ if val is True:
+ val=1
+ elif val in(False,None):
+ val=0
+ if isinstance(val,int)or isinstance(val,float):
+ s='%s=%s'
+ else:
+ s=quote and'%s="%s"'or'%s=%s'
+ app=s%(key,str(val))
+ ban=key+'='
+ lst=self.env['DEFINES']
+ for x in lst:
+ if x.startswith(ban):
+ lst[lst.index(x)]=app
+ break
+ else:
+ self.env.append_value('DEFINES',app)
+ self.env.append_unique(DEFKEYS,key)
+ self.set_define_comment(key,comment)
+@conf
+def undefine(self,key,comment=''):
+ assert key and isinstance(key,str)
+ ban=key+'='
+ lst=[x for x in self.env['DEFINES']if not x.startswith(ban)]
+ self.env['DEFINES']=lst
+ self.env.append_unique(DEFKEYS,key)
+ self.set_define_comment(key,comment)
+@conf
+def define_cond(self,key,val,comment=''):
+ assert key and isinstance(key,str)
+ if val:
+ self.define(key,1,comment=comment)
+ else:
+ self.undefine(key,comment=comment)
+@conf
+def is_defined(self,key):
+ assert key and isinstance(key,str)
+ ban=key+'='
+ for x in self.env['DEFINES']:
+ if x.startswith(ban):
+ return True
+ return False
+@conf
+def get_define(self,key):
+ assert key and isinstance(key,str)
+ ban=key+'='
+ for x in self.env['DEFINES']:
+ if x.startswith(ban):
+ return x[len(ban):]
+ return None
+@conf
+def have_define(self,key):
+ return(self.env.HAVE_PAT or'HAVE_%s')%Utils.quote_define_name(key)
+@conf
+def write_config_header(self,configfile='',guard='',top=False,defines=True,headers=False,remove=True,define_prefix=''):
+ if not configfile:configfile=WAF_CONFIG_H
+ waf_guard=guard or'W_%s_WAF'%Utils.quote_define_name(configfile)
+ node=top and self.bldnode or self.path.get_bld()
+ node=node.make_node(configfile)
+ node.parent.mkdir()
+ lst=['/* WARNING! All changes made to this file will be lost! */\n']
+ lst.append('#ifndef %s\n#define %s\n'%(waf_guard,waf_guard))
+ lst.append(self.get_config_header(defines,headers,define_prefix=define_prefix))
+ lst.append('\n#endif /* %s */\n'%waf_guard)
+ node.write('\n'.join(lst))
+ self.env.append_unique(Build.CFG_FILES,[node.abspath()])
+ if remove:
+ for key in self.env[DEFKEYS]:
+ self.undefine(key)
+ self.env[DEFKEYS]=[]
+@conf
+def get_config_header(self,defines=True,headers=False,define_prefix=''):
+ lst=[]
+ if self.env.WAF_CONFIG_H_PRELUDE:
+ lst.append(self.env.WAF_CONFIG_H_PRELUDE)
+ if headers:
+ for x in self.env[INCKEYS]:
+ lst.append('#include <%s>'%x)
+ if defines:
+ tbl={}
+ for k in self.env['DEFINES']:
+ a,_,b=k.partition('=')
+ tbl[a]=b
+ for k in self.env[DEFKEYS]:
+ caption=self.get_define_comment(k)
+ if caption:
+ caption=' /* %s */'%caption
+ try:
+ txt='#define %s%s %s%s'%(define_prefix,k,tbl[k],caption)
+ except KeyError:
+ txt='/* #undef %s%s */%s'%(define_prefix,k,caption)
+ lst.append(txt)
+ return"\n".join(lst)
+@conf
+def cc_add_flags(conf):
+ conf.add_os_flags('CPPFLAGS',dup=False)
+ conf.add_os_flags('CFLAGS',dup=False)
+@conf
+def cxx_add_flags(conf):
+ conf.add_os_flags('CPPFLAGS',dup=False)
+ conf.add_os_flags('CXXFLAGS',dup=False)
+@conf
+def link_add_flags(conf):
+ conf.add_os_flags('LINKFLAGS',dup=False)
+ conf.add_os_flags('LDFLAGS',dup=False)
+@conf
+def cc_load_tools(conf):
+ if not conf.env.DEST_OS:
+ conf.env.DEST_OS=Utils.unversioned_sys_platform()
+ conf.load('c')
+@conf
+def cxx_load_tools(conf):
+ if not conf.env.DEST_OS:
+ conf.env.DEST_OS=Utils.unversioned_sys_platform()
+ conf.load('cxx')
+@conf
+def get_cc_version(conf,cc,gcc=False,icc=False,clang=False):
+ cmd=cc+['-dM','-E','-']
+ env=conf.env.env or None
+ try:
+ out,err=conf.cmd_and_log(cmd,output=0,input='\n',env=env)
+ except Exception:
+ conf.fatal('Could not determine the compiler version %r'%cmd)
+ if gcc:
+ if out.find('__INTEL_COMPILER')>=0:
+ conf.fatal('The intel compiler pretends to be gcc')
+ if out.find('__GNUC__')<0 and out.find('__clang__')<0:
+ conf.fatal('Could not determine the compiler type')
+ if icc and out.find('__INTEL_COMPILER')<0:
+ conf.fatal('Not icc/icpc')
+ if clang and out.find('__clang__')<0:
+ conf.fatal('Not clang/clang++')
+ if not clang and out.find('__clang__')>=0:
+ conf.fatal('Could not find gcc/g++ (only Clang), if renamed try eg: CC=gcc48 CXX=g++48 waf configure')
+ k={}
+ if icc or gcc or clang:
+ out=out.splitlines()
+ for line in out:
+ lst=shlex.split(line)
+ if len(lst)>2:
+ key=lst[1]
+ val=lst[2]
+ k[key]=val
+ def isD(var):
+ return var in k
+ if not conf.env.DEST_OS:
+ conf.env.DEST_OS=''
+ for i in MACRO_TO_DESTOS:
+ if isD(i):
+ conf.env.DEST_OS=MACRO_TO_DESTOS[i]
+ break
+ else:
+ if isD('__APPLE__')and isD('__MACH__'):
+ conf.env.DEST_OS='darwin'
+ elif isD('__unix__'):
+ conf.env.DEST_OS='generic'
+ if isD('__ELF__'):
+ conf.env.DEST_BINFMT='elf'
+ elif isD('__WINNT__')or isD('__CYGWIN__')or isD('_WIN32'):
+ conf.env.DEST_BINFMT='pe'
+ conf.env.LIBDIR=conf.env.BINDIR
+ elif isD('__APPLE__'):
+ conf.env.DEST_BINFMT='mac-o'
+ if not conf.env.DEST_BINFMT:
+ conf.env.DEST_BINFMT=Utils.destos_to_binfmt(conf.env.DEST_OS)
+ for i in MACRO_TO_DEST_CPU:
+ if isD(i):
+ conf.env.DEST_CPU=MACRO_TO_DEST_CPU[i]
+ break
+ Logs.debug('ccroot: dest platform: '+' '.join([conf.env[x]or'?'for x in('DEST_OS','DEST_BINFMT','DEST_CPU')]))
+ if icc:
+ ver=k['__INTEL_COMPILER']
+ conf.env['CC_VERSION']=(ver[:-2],ver[-2],ver[-1])
+ else:
+ if isD('__clang__')and isD('__clang_major__'):
+ conf.env['CC_VERSION']=(k['__clang_major__'],k['__clang_minor__'],k['__clang_patchlevel__'])
+ else:
+ conf.env['CC_VERSION']=(k['__GNUC__'],k['__GNUC_MINOR__'],k.get('__GNUC_PATCHLEVEL__','0'))
+ return k
+@conf
+def get_xlc_version(conf,cc):
+ cmd=cc+['-qversion']
+ try:
+ out,err=conf.cmd_and_log(cmd,output=0)
+ except Errors.WafError:
+ conf.fatal('Could not find xlc %r'%cmd)
+ for v in(r"IBM XL C/C\+\+.* V(?P<major>\d*)\.(?P<minor>\d*)",):
+ version_re=re.compile(v,re.I).search
+ match=version_re(out or err)
+ if match:
+ k=match.groupdict()
+ conf.env['CC_VERSION']=(k['major'],k['minor'])
+ break
+ else:
+ conf.fatal('Could not determine the XLC version.')
+@conf
+def get_suncc_version(conf,cc):
+ cmd=cc+['-V']
+ try:
+ out,err=conf.cmd_and_log(cmd,output=0)
+ except Errors.WafError ,e:
+ if not(hasattr(e,'returncode')and hasattr(e,'stdout')and hasattr(e,'stderr')):
+ conf.fatal('Could not find suncc %r'%cmd)
+ out=e.stdout
+ err=e.stderr
+ version=(out or err)
+ version=version.splitlines()[0]
+ version_re=re.compile(r'cc: (studio.*?|\s+)?sun\s+(c\+\+|c)\s+(?P<major>\d*)\.(?P<minor>\d*)',re.I).search
+ match=version_re(version)
+ if match:
+ k=match.groupdict()
+ conf.env['CC_VERSION']=(k['major'],k['minor'])
+ else:
+ conf.fatal('Could not determine the suncc version.')
+@conf
+def add_as_needed(self):
+ if self.env.DEST_BINFMT=='elf'and'gcc'in(self.env.CXX_NAME,self.env.CC_NAME):
+ self.env.append_unique('LINKFLAGS','-Wl,--as-needed')
+class cfgtask(Task.TaskBase):
+ def display(self):
+ return''
+ def runnable_status(self):
+ return Task.RUN_ME
+ def uid(self):
+ return Utils.SIG_NIL
+ def run(self):
+ conf=self.conf
+ bld=Build.BuildContext(top_dir=conf.srcnode.abspath(),out_dir=conf.bldnode.abspath())
+ bld.env=conf.env
+ bld.init_dirs()
+ bld.in_msg=1
+ bld.logger=self.logger
+ try:
+ bld.check(**self.args)
+ except Exception:
+ return 1
+@conf
+def multicheck(self,*k,**kw):
+ self.start_msg(kw.get('msg','Executing %d configuration tests'%len(k)),**kw)
+ class par(object):
+ def __init__(self):
+ self.keep=False
+ self.returned_tasks=[]
+ self.task_sigs={}
+ self.progress_bar=0
+ def total(self):
+ return len(tasks)
+ def to_log(self,*k,**kw):
+ return
+ bld=par()
+ tasks=[]
+ for dct in k:
+ x=cfgtask(bld=bld)
+ tasks.append(x)
+ x.args=dct
+ x.bld=bld
+ x.conf=self
+ x.args=dct
+ x.logger=Logs.make_mem_logger(str(id(x)),self.logger)
+ def it():
+ yield tasks
+ while 1:
+ yield[]
+ p=Runner.Parallel(bld,Options.options.jobs)
+ p.biter=it()
+ p.start()
+ for x in tasks:
+ x.logger.memhandler.flush()
+ if p.error:
+ for x in p.error:
+ if getattr(x,'err_msg',None):
+ self.to_log(x.err_msg)
+ self.end_msg('fail',color='RED')
+ raise Errors.WafError('There is an error in the library, read config.log for more information')
+ for x in tasks:
+ if x.hasrun!=Task.SUCCESS:
+ self.end_msg(kw.get('errmsg','no'),color='YELLOW',**kw)
+ self.fatal(kw.get('fatalmsg',None)or'One of the tests has failed, read config.log for more information')
+ self.end_msg('ok',**kw)
diff --git a/waflib/Tools/c_osx.py b/waflib/Tools/c_osx.py
new file mode 100644
index 0000000..8cb4bce
--- /dev/null
+++ b/waflib/Tools/c_osx.py
@@ -0,0 +1,137 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,shutil,platform
+from waflib import Task,Utils,Errors
+from waflib.TaskGen import taskgen_method,feature,after_method,before_method
+app_info='''
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Created by Waf</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>NOTE</key>
+ <string>THIS IS A GENERATED FILE, DO NOT MODIFY</string>
+ <key>CFBundleExecutable</key>
+ <string>{app_name}</string>
+</dict>
+</plist>
+'''
+@feature('c','cxx')
+def set_macosx_deployment_target(self):
+ if self.env['MACOSX_DEPLOYMENT_TARGET']:
+ os.environ['MACOSX_DEPLOYMENT_TARGET']=self.env['MACOSX_DEPLOYMENT_TARGET']
+ elif'MACOSX_DEPLOYMENT_TARGET'not in os.environ:
+ if Utils.unversioned_sys_platform()=='darwin':
+ os.environ['MACOSX_DEPLOYMENT_TARGET']='.'.join(platform.mac_ver()[0].split('.')[:2])
+@taskgen_method
+def create_bundle_dirs(self,name,out):
+ dir=out.parent.find_or_declare(name)
+ dir.mkdir()
+ macos=dir.find_or_declare(['Contents','MacOS'])
+ macos.mkdir()
+ return dir
+def bundle_name_for_output(out):
+ name=out.name
+ k=name.rfind('.')
+ if k>=0:
+ name=name[:k]+'.app'
+ else:
+ name=name+'.app'
+ return name
+@feature('cprogram','cxxprogram')
+@after_method('apply_link')
+def create_task_macapp(self):
+ if self.env['MACAPP']or getattr(self,'mac_app',False):
+ out=self.link_task.outputs[0]
+ name=bundle_name_for_output(out)
+ dir=self.create_bundle_dirs(name,out)
+ n1=dir.find_or_declare(['Contents','MacOS',out.name])
+ self.apptask=self.create_task('macapp',self.link_task.outputs,n1)
+ inst_to=getattr(self,'install_path','/Applications')+'/%s/Contents/MacOS/'%name
+ self.bld.install_files(inst_to,n1,chmod=Utils.O755)
+ if getattr(self,'mac_files',None):
+ mac_files_root=getattr(self,'mac_files_root',None)
+ if isinstance(mac_files_root,str):
+ mac_files_root=self.path.find_node(mac_files_root)
+ if not mac_files_root:
+ self.bld.fatal('Invalid mac_files_root %r'%self.mac_files_root)
+ res_dir=n1.parent.parent.make_node('Resources')
+ inst_to=getattr(self,'install_path','/Applications')+'/%s/Resources'%name
+ for node in self.to_nodes(self.mac_files):
+ relpath=node.path_from(mac_files_root or node.parent)
+ self.create_task('macapp',node,res_dir.make_node(relpath))
+ self.bld.install_as(os.path.join(inst_to,relpath),node)
+ if getattr(self,'mac_resources',None):
+ res_dir=n1.parent.parent.make_node('Resources')
+ inst_to=getattr(self,'install_path','/Applications')+'/%s/Resources'%name
+ for x in self.to_list(self.mac_resources):
+ node=self.path.find_node(x)
+ if not node:
+ raise Errors.WafError('Missing mac_resource %r in %r'%(x,self))
+ parent=node.parent
+ if os.path.isdir(node.abspath()):
+ nodes=node.ant_glob('**')
+ else:
+ nodes=[node]
+ for node in nodes:
+ rel=node.path_from(parent)
+ self.create_task('macapp',node,res_dir.make_node(rel))
+ self.bld.install_as(inst_to+'/%s'%rel,node)
+ if getattr(self.bld,'is_install',None):
+ self.install_task.hasrun=Task.SKIP_ME
+@feature('cprogram','cxxprogram')
+@after_method('apply_link')
+def create_task_macplist(self):
+ if self.env['MACAPP']or getattr(self,'mac_app',False):
+ out=self.link_task.outputs[0]
+ name=bundle_name_for_output(out)
+ dir=self.create_bundle_dirs(name,out)
+ n1=dir.find_or_declare(['Contents','Info.plist'])
+ self.plisttask=plisttask=self.create_task('macplist',[],n1)
+ plisttask.context={'app_name':self.link_task.outputs[0].name,'env':self.env}
+ plist_ctx=getattr(self,'plist_context',None)
+ if(plist_ctx):
+ plisttask.context.update(plist_ctx)
+ if getattr(self,'mac_plist',False):
+ node=self.path.find_resource(self.mac_plist)
+ if node:
+ plisttask.inputs.append(node)
+ else:
+ plisttask.code=self.mac_plist
+ else:
+ plisttask.code=app_info
+ inst_to=getattr(self,'install_path','/Applications')+'/%s/Contents/'%name
+ self.bld.install_files(inst_to,n1)
+@feature('cshlib','cxxshlib')
+@before_method('apply_link','propagate_uselib_vars')
+def apply_bundle(self):
+ if self.env['MACBUNDLE']or getattr(self,'mac_bundle',False):
+ self.env['LINKFLAGS_cshlib']=self.env['LINKFLAGS_cxxshlib']=[]
+ self.env['cshlib_PATTERN']=self.env['cxxshlib_PATTERN']=self.env['macbundle_PATTERN']
+ use=self.use=self.to_list(getattr(self,'use',[]))
+ if not'MACBUNDLE'in use:
+ use.append('MACBUNDLE')
+app_dirs=['Contents','Contents/MacOS','Contents/Resources']
+class macapp(Task.Task):
+ color='PINK'
+ def run(self):
+ self.outputs[0].parent.mkdir()
+ shutil.copy2(self.inputs[0].srcpath(),self.outputs[0].abspath())
+class macplist(Task.Task):
+ color='PINK'
+ ext_in=['.bin']
+ def run(self):
+ if getattr(self,'code',None):
+ txt=self.code
+ else:
+ txt=self.inputs[0].read()
+ context=getattr(self,'context',{})
+ txt=txt.format(**context)
+ self.outputs[0].write(txt)
diff --git a/waflib/Tools/c_preproc.py b/waflib/Tools/c_preproc.py
new file mode 100644
index 0000000..e1a8c7e
--- /dev/null
+++ b/waflib/Tools/c_preproc.py
@@ -0,0 +1,611 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import re,string,traceback
+from waflib import Logs,Utils,Errors
+from waflib.Logs import debug,error
+class PreprocError(Errors.WafError):
+ pass
+POPFILE='-'
+recursion_limit=150
+go_absolute=False
+standard_includes=['/usr/include']
+if Utils.is_win32:
+ standard_includes=[]
+use_trigraphs=0
+strict_quotes=0
+g_optrans={'not':'!','not_eq':'!','and':'&&','and_eq':'&=','or':'||','or_eq':'|=','xor':'^','xor_eq':'^=','bitand':'&','bitor':'|','compl':'~',}
+re_lines=re.compile('^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*)\r*$',re.IGNORECASE|re.MULTILINE)
+re_mac=re.compile("^[a-zA-Z_]\w*")
+re_fun=re.compile('^[a-zA-Z_][a-zA-Z0-9_]*[(]')
+re_pragma_once=re.compile('^\s*once\s*',re.IGNORECASE)
+re_nl=re.compile('\\\\\r*\n',re.MULTILINE)
+re_cpp=re.compile(r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',re.DOTALL|re.MULTILINE)
+trig_def=[('??'+a,b)for a,b in zip("=-/!'()<>",r'#~\|^[]{}')]
+chr_esc={'0':0,'a':7,'b':8,'t':9,'n':10,'f':11,'v':12,'r':13,'\\':92,"'":39}
+NUM='i'
+OP='O'
+IDENT='T'
+STR='s'
+CHAR='c'
+tok_types=[NUM,STR,IDENT,OP]
+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'%:%:|<<=|>>=|\.\.\.|<<|<%|<:|<=|>>|>=|\+\+|\+=|--|->|-=|\*=|/=|%:|%=|%>|==|&&|&=|\|\||\|=|\^=|:>|!=|##|[\(\)\{\}\[\]<>\?\|\^\*\+&=:!#;,%/\-\?\~\.]',]
+re_clexer=re.compile('|'.join(["(?P<%s>%s)"%(name,part)for name,part in zip(tok_types,exp_types)]),re.M)
+accepted='a'
+ignored='i'
+undefined='u'
+skipped='s'
+def repl(m):
+ s=m.group(0)
+ if s.startswith('/'):
+ return' '
+ return s
+def filter_comments(filename):
+ code=Utils.readf(filename)
+ if use_trigraphs:
+ for(a,b)in trig_def:code=code.split(a).join(b)
+ code=re_nl.sub('',code)
+ code=re_cpp.sub(repl,code)
+ return[(m.group(2),m.group(3))for m in re.finditer(re_lines,code)]
+prec={}
+ops=['* / %','+ -','<< >>','< <= >= >','== !=','& | ^','&& ||',',']
+for x in range(len(ops)):
+ syms=ops[x]
+ for u in syms.split():
+ prec[u]=x
+def trimquotes(s):
+ if not s:return''
+ s=s.rstrip()
+ if s[0]=="'"and s[-1]=="'":return s[1:-1]
+ return s
+def reduce_nums(val_1,val_2,val_op):
+ try:a=0+val_1
+ except TypeError:a=int(val_1)
+ try:b=0+val_2
+ except TypeError:b=int(val_2)
+ d=val_op
+ if d=='%':c=a%b
+ elif d=='+':c=a+b
+ elif d=='-':c=a-b
+ elif d=='*':c=a*b
+ elif d=='/':c=a/b
+ elif d=='^':c=a^b
+ elif d=='==':c=int(a==b)
+ elif d=='|'or d=='bitor':c=a|b
+ elif d=='||'or d=='or':c=int(a or b)
+ elif d=='&'or d=='bitand':c=a&b
+ elif d=='&&'or d=='and':c=int(a and b)
+ elif d=='!='or d=='not_eq':c=int(a!=b)
+ elif d=='^'or d=='xor':c=int(a^b)
+ elif d=='<=':c=int(a<=b)
+ elif d=='<':c=int(a<b)
+ elif d=='>':c=int(a>b)
+ elif d=='>=':c=int(a>=b)
+ elif d=='<<':c=a<<b
+ elif d=='>>':c=a>>b
+ else:c=0
+ return c
+def get_num(lst):
+ if not lst:raise PreprocError("empty list for get_num")
+ (p,v)=lst[0]
+ if p==OP:
+ if v=='(':
+ count_par=1
+ i=1
+ while i<len(lst):
+ (p,v)=lst[i]
+ if p==OP:
+ if v==')':
+ count_par-=1
+ if count_par==0:
+ break
+ elif v=='(':
+ count_par+=1
+ i+=1
+ else:
+ raise PreprocError("rparen expected %r"%lst)
+ (num,_)=get_term(lst[1:i])
+ return(num,lst[i+1:])
+ elif v=='+':
+ return get_num(lst[1:])
+ elif v=='-':
+ num,lst=get_num(lst[1:])
+ return(reduce_nums('-1',num,'*'),lst)
+ elif v=='!':
+ num,lst=get_num(lst[1:])
+ return(int(not int(num)),lst)
+ elif v=='~':
+ num,lst=get_num(lst[1:])
+ return(~int(num),lst)
+ else:
+ raise PreprocError("Invalid op token %r for get_num"%lst)
+ elif p==NUM:
+ return v,lst[1:]
+ elif p==IDENT:
+ return 0,lst[1:]
+ else:
+ raise PreprocError("Invalid token %r for get_num"%lst)
+def get_term(lst):
+ if not lst:raise PreprocError("empty list for get_term")
+ num,lst=get_num(lst)
+ if not lst:
+ return(num,[])
+ (p,v)=lst[0]
+ if p==OP:
+ if v==',':
+ return get_term(lst[1:])
+ elif v=='?':
+ count_par=0
+ i=1
+ while i<len(lst):
+ (p,v)=lst[i]
+ if p==OP:
+ if v==')':
+ count_par-=1
+ elif v=='(':
+ count_par+=1
+ elif v==':':
+ if count_par==0:
+ break
+ i+=1
+ else:
+ raise PreprocError("rparen expected %r"%lst)
+ if int(num):
+ return get_term(lst[1:i])
+ else:
+ return get_term(lst[i+1:])
+ else:
+ num2,lst=get_num(lst[1:])
+ if not lst:
+ num2=reduce_nums(num,num2,v)
+ return get_term([(NUM,num2)]+lst)
+ p2,v2=lst[0]
+ if p2!=OP:
+ raise PreprocError("op expected %r"%lst)
+ if prec[v2]>=prec[v]:
+ num2=reduce_nums(num,num2,v)
+ return get_term([(NUM,num2)]+lst)
+ else:
+ num3,lst=get_num(lst[1:])
+ num3=reduce_nums(num2,num3,v2)
+ return get_term([(NUM,num),(p,v),(NUM,num3)]+lst)
+ raise PreprocError("cannot reduce %r"%lst)
+def reduce_eval(lst):
+ num,lst=get_term(lst)
+ return(NUM,num)
+def stringize(lst):
+ lst=[str(v2)for(p2,v2)in lst]
+ return"".join(lst)
+def paste_tokens(t1,t2):
+ p1=None
+ if t1[0]==OP and t2[0]==OP:
+ p1=OP
+ elif t1[0]==IDENT and(t2[0]==IDENT or t2[0]==NUM):
+ p1=IDENT
+ elif t1[0]==NUM and t2[0]==NUM:
+ p1=NUM
+ if not p1:
+ raise PreprocError('tokens do not make a valid paste %r and %r'%(t1,t2))
+ return(p1,t1[1]+t2[1])
+def reduce_tokens(lst,defs,ban=[]):
+ i=0
+ while i<len(lst):
+ (p,v)=lst[i]
+ if p==IDENT and v=="defined":
+ del lst[i]
+ if i<len(lst):
+ (p2,v2)=lst[i]
+ if p2==IDENT:
+ if v2 in defs:
+ lst[i]=(NUM,1)
+ else:
+ lst[i]=(NUM,0)
+ elif p2==OP and v2=='(':
+ del lst[i]
+ (p2,v2)=lst[i]
+ del lst[i]
+ if v2 in defs:
+ lst[i]=(NUM,1)
+ else:
+ lst[i]=(NUM,0)
+ else:
+ raise PreprocError("Invalid define expression %r"%lst)
+ elif p==IDENT and v in defs:
+ if isinstance(defs[v],str):
+ a,b=extract_macro(defs[v])
+ defs[v]=b
+ macro_def=defs[v]
+ to_add=macro_def[1]
+ if isinstance(macro_def[0],list):
+ del lst[i]
+ accu=to_add[:]
+ reduce_tokens(accu,defs,ban+[v])
+ for x in range(len(accu)):
+ lst.insert(i,accu[x])
+ i+=1
+ else:
+ args=[]
+ del lst[i]
+ if i>=len(lst):
+ raise PreprocError("expected '(' after %r (got nothing)"%v)
+ (p2,v2)=lst[i]
+ if p2!=OP or v2!='(':
+ raise PreprocError("expected '(' after %r"%v)
+ del lst[i]
+ one_param=[]
+ count_paren=0
+ while i<len(lst):
+ p2,v2=lst[i]
+ del lst[i]
+ if p2==OP and count_paren==0:
+ if v2=='(':
+ one_param.append((p2,v2))
+ count_paren+=1
+ elif v2==')':
+ if one_param:args.append(one_param)
+ break
+ elif v2==',':
+ if not one_param:raise PreprocError("empty param in funcall %s"%v)
+ args.append(one_param)
+ one_param=[]
+ else:
+ one_param.append((p2,v2))
+ else:
+ one_param.append((p2,v2))
+ if v2=='(':count_paren+=1
+ elif v2==')':count_paren-=1
+ else:
+ raise PreprocError('malformed macro')
+ accu=[]
+ arg_table=macro_def[0]
+ j=0
+ while j<len(to_add):
+ (p2,v2)=to_add[j]
+ if p2==OP and v2=='#':
+ if j+1<len(to_add)and to_add[j+1][0]==IDENT and to_add[j+1][1]in arg_table:
+ toks=args[arg_table[to_add[j+1][1]]]
+ accu.append((STR,stringize(toks)))
+ j+=1
+ else:
+ accu.append((p2,v2))
+ elif p2==OP and v2=='##':
+ if accu and j+1<len(to_add):
+ t1=accu[-1]
+ if to_add[j+1][0]==IDENT and to_add[j+1][1]in arg_table:
+ toks=args[arg_table[to_add[j+1][1]]]
+ if toks:
+ accu[-1]=paste_tokens(t1,toks[0])
+ accu.extend(toks[1:])
+ else:
+ accu.append((p2,v2))
+ accu.extend(toks)
+ elif to_add[j+1][0]==IDENT and to_add[j+1][1]=='__VA_ARGS__':
+ va_toks=[]
+ st=len(macro_def[0])
+ pt=len(args)
+ for x in args[pt-st+1:]:
+ va_toks.extend(x)
+ va_toks.append((OP,','))
+ if va_toks:va_toks.pop()
+ if len(accu)>1:
+ (p3,v3)=accu[-1]
+ (p4,v4)=accu[-2]
+ if v3=='##':
+ accu.pop()
+ if v4==','and pt<st:
+ accu.pop()
+ accu+=va_toks
+ else:
+ accu[-1]=paste_tokens(t1,to_add[j+1])
+ j+=1
+ else:
+ accu.append((p2,v2))
+ elif p2==IDENT and v2 in arg_table:
+ toks=args[arg_table[v2]]
+ reduce_tokens(toks,defs,ban+[v])
+ accu.extend(toks)
+ else:
+ accu.append((p2,v2))
+ j+=1
+ reduce_tokens(accu,defs,ban+[v])
+ for x in range(len(accu)-1,-1,-1):
+ lst.insert(i,accu[x])
+ i+=1
+def eval_macro(lst,defs):
+ reduce_tokens(lst,defs,[])
+ if not lst:raise PreprocError("missing tokens to evaluate")
+ (p,v)=reduce_eval(lst)
+ return int(v)!=0
+def extract_macro(txt):
+ t=tokenize(txt)
+ if re_fun.search(txt):
+ p,name=t[0]
+ p,v=t[1]
+ if p!=OP:raise PreprocError("expected open parenthesis")
+ i=1
+ pindex=0
+ params={}
+ prev='('
+ while 1:
+ i+=1
+ p,v=t[i]
+ if prev=='(':
+ if p==IDENT:
+ params[v]=pindex
+ pindex+=1
+ prev=p
+ elif p==OP and v==')':
+ break
+ else:
+ raise PreprocError("unexpected token (3)")
+ elif prev==IDENT:
+ if p==OP and v==',':
+ prev=v
+ elif p==OP and v==')':
+ break
+ else:
+ raise PreprocError("comma or ... expected")
+ elif prev==',':
+ if p==IDENT:
+ params[v]=pindex
+ pindex+=1
+ prev=p
+ elif p==OP and v=='...':
+ raise PreprocError("not implemented (1)")
+ else:
+ raise PreprocError("comma or ... expected (2)")
+ elif prev=='...':
+ raise PreprocError("not implemented (2)")
+ else:
+ raise PreprocError("unexpected else")
+ return(name,[params,t[i+1:]])
+ else:
+ (p,v)=t[0]
+ if len(t)>1:
+ return(v,[[],t[1:]])
+ else:
+ return(v,[[],[('T','')]])
+re_include=re.compile('^\s*(<(?P<a>.*)>|"(?P<b>.*)")')
+def extract_include(txt,defs):
+ m=re_include.search(txt)
+ if m:
+ if m.group('a'):return'<',m.group('a')
+ if m.group('b'):return'"',m.group('b')
+ toks=tokenize(txt)
+ reduce_tokens(toks,defs,['waf_include'])
+ if not toks:
+ raise PreprocError("could not parse include %s"%txt)
+ if len(toks)==1:
+ if toks[0][0]==STR:
+ return'"',toks[0][1]
+ else:
+ if toks[0][1]=='<'and toks[-1][1]=='>':
+ ret='<',stringize(toks).lstrip('<').rstrip('>')
+ return ret
+ raise PreprocError("could not parse include %s."%txt)
+def parse_char(txt):
+ if not txt:raise PreprocError("attempted to parse a null char")
+ if txt[0]!='\\':
+ return ord(txt)
+ c=txt[1]
+ if c=='x':
+ if len(txt)==4 and txt[3]in string.hexdigits:return int(txt[2:],16)
+ return int(txt[2:],16)
+ elif c.isdigit():
+ if c=='0'and len(txt)==2:return 0
+ for i in 3,2,1:
+ if len(txt)>i and txt[1:1+i].isdigit():
+ return(1+i,int(txt[1:1+i],8))
+ else:
+ try:return chr_esc[c]
+ except KeyError:raise PreprocError("could not parse char literal '%s'"%txt)
+def tokenize(s):
+ return tokenize_private(s)[:]
+@Utils.run_once
+def tokenize_private(s):
+ ret=[]
+ for match in re_clexer.finditer(s):
+ m=match.group
+ for name in tok_types:
+ v=m(name)
+ if v:
+ if name==IDENT:
+ try:
+ g_optrans[v];
+ name=OP
+ except KeyError:
+ if v.lower()=="true":
+ v=1
+ name=NUM
+ elif v.lower()=="false":
+ v=0
+ name=NUM
+ elif name==NUM:
+ if m('oct'):v=int(v,8)
+ elif m('hex'):v=int(m('hex'),16)
+ elif m('n0'):v=m('n0')
+ else:
+ v=m('char')
+ if v:v=parse_char(v)
+ else:v=m('n2')or m('n4')
+ elif name==OP:
+ if v=='%:':v='#'
+ elif v=='%:%:':v='##'
+ elif name==STR:
+ v=v[1:-1]
+ ret.append((name,v))
+ break
+ return ret
+@Utils.run_once
+def define_name(line):
+ return re_mac.match(line).group(0)
+class c_parser(object):
+ def __init__(self,nodepaths=None,defines=None):
+ self.lines=[]
+ if defines is None:
+ self.defs={}
+ else:
+ self.defs=dict(defines)
+ self.state=[]
+ self.count_files=0
+ self.currentnode_stack=[]
+ self.nodepaths=nodepaths or[]
+ self.nodes=[]
+ self.names=[]
+ self.curfile=''
+ self.ban_includes=set([])
+ def cached_find_resource(self,node,filename):
+ try:
+ nd=node.ctx.cache_nd
+ except AttributeError:
+ nd=node.ctx.cache_nd={}
+ tup=(node,filename)
+ try:
+ return nd[tup]
+ except KeyError:
+ ret=node.find_resource(filename)
+ if ret:
+ if getattr(ret,'children',None):
+ ret=None
+ elif ret.is_child_of(node.ctx.bldnode):
+ tmp=node.ctx.srcnode.search_node(ret.path_from(node.ctx.bldnode))
+ if tmp and getattr(tmp,'children',None):
+ ret=None
+ nd[tup]=ret
+ return ret
+ def tryfind(self,filename):
+ if filename.endswith('.moc'):
+ self.names.append(filename)
+ return None
+ self.curfile=filename
+ found=self.cached_find_resource(self.currentnode_stack[-1],filename)
+ for n in self.nodepaths:
+ if found:
+ break
+ found=self.cached_find_resource(n,filename)
+ if found and not found in self.ban_includes:
+ self.nodes.append(found)
+ self.addlines(found)
+ else:
+ if not filename in self.names:
+ self.names.append(filename)
+ return found
+ def addlines(self,node):
+ self.currentnode_stack.append(node.parent)
+ filepath=node.abspath()
+ self.count_files+=1
+ if self.count_files>recursion_limit:
+ raise PreprocError("recursion limit exceeded")
+ pc=self.parse_cache
+ debug('preproc: reading file %r',filepath)
+ try:
+ lns=pc[filepath]
+ except KeyError:
+ pass
+ else:
+ self.lines.extend(lns)
+ return
+ try:
+ lines=filter_comments(filepath)
+ lines.append((POPFILE,''))
+ lines.reverse()
+ pc[filepath]=lines
+ self.lines.extend(lines)
+ except IOError:
+ raise PreprocError("could not read the file %s"%filepath)
+ except Exception:
+ if Logs.verbose>0:
+ error("parsing %s failed"%filepath)
+ traceback.print_exc()
+ def start(self,node,env):
+ debug('preproc: scanning %s (in %s)',node.name,node.parent.name)
+ bld=node.ctx
+ try:
+ self.parse_cache=bld.parse_cache
+ except AttributeError:
+ self.parse_cache=bld.parse_cache={}
+ self.current_file=node
+ self.addlines(node)
+ if env['DEFINES']:
+ try:
+ lst=['%s %s'%(x[0],trimquotes('='.join(x[1:])))for x in[y.split('=')for y in env['DEFINES']]]
+ lst.reverse()
+ self.lines.extend([('define',x)for x in lst])
+ except AttributeError:
+ pass
+ while self.lines:
+ (token,line)=self.lines.pop()
+ if token==POPFILE:
+ self.count_files-=1
+ self.currentnode_stack.pop()
+ continue
+ try:
+ ve=Logs.verbose
+ if ve:debug('preproc: line is %s - %s state is %s',token,line,self.state)
+ state=self.state
+ if token[:2]=='if':
+ state.append(undefined)
+ elif token=='endif':
+ state.pop()
+ if token[0]!='e':
+ if skipped in self.state or ignored in self.state:
+ continue
+ if token=='if':
+ ret=eval_macro(tokenize(line),self.defs)
+ if ret:state[-1]=accepted
+ else:state[-1]=ignored
+ elif token=='ifdef':
+ m=re_mac.match(line)
+ if m and m.group(0)in self.defs:state[-1]=accepted
+ else:state[-1]=ignored
+ elif token=='ifndef':
+ m=re_mac.match(line)
+ if m and m.group(0)in self.defs:state[-1]=ignored
+ else:state[-1]=accepted
+ elif token=='include'or token=='import':
+ (kind,inc)=extract_include(line,self.defs)
+ if ve:debug('preproc: include found %s (%s) ',inc,kind)
+ if kind=='"'or not strict_quotes:
+ self.current_file=self.tryfind(inc)
+ if token=='import':
+ self.ban_includes.add(self.current_file)
+ elif token=='elif':
+ if state[-1]==accepted:
+ state[-1]=skipped
+ elif state[-1]==ignored:
+ if eval_macro(tokenize(line),self.defs):
+ state[-1]=accepted
+ elif token=='else':
+ if state[-1]==accepted:state[-1]=skipped
+ elif state[-1]==ignored:state[-1]=accepted
+ elif token=='define':
+ try:
+ self.defs[define_name(line)]=line
+ except Exception:
+ raise PreprocError("Invalid define line %s"%line)
+ elif token=='undef':
+ m=re_mac.match(line)
+ if m and m.group(0)in self.defs:
+ self.defs.__delitem__(m.group(0))
+ elif token=='pragma':
+ if re_pragma_once.match(line.lower()):
+ self.ban_includes.add(self.current_file)
+ except Exception ,e:
+ if Logs.verbose:
+ debug('preproc: line parsing failed (%s): %s %s',e,line,Utils.ex_stack())
+def scan(task):
+ global go_absolute
+ try:
+ incn=task.generator.includes_nodes
+ except AttributeError:
+ raise Errors.WafError('%r is missing a feature such as "c", "cxx" or "includes": '%task.generator)
+ if go_absolute:
+ nodepaths=incn+[task.generator.bld.root.find_dir(x)for x in standard_includes]
+ else:
+ nodepaths=[x for x in incn if x.is_child_of(x.ctx.srcnode)or x.is_child_of(x.ctx.bldnode)]
+ tmp=c_parser(nodepaths)
+ tmp.start(task.inputs[0],task.env)
+ if Logs.verbose:
+ debug('deps: deps for %r: %r; unresolved %r'%(task.inputs,tmp.nodes,tmp.names))
+ return(tmp.nodes,tmp.names)
diff --git a/waflib/Tools/c_tests.py b/waflib/Tools/c_tests.py
new file mode 100644
index 0000000..7791f23
--- /dev/null
+++ b/waflib/Tools/c_tests.py
@@ -0,0 +1,152 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib import Task
+from waflib.Configure import conf
+from waflib.TaskGen import feature,before_method,after_method
+LIB_CODE='''
+#ifdef _MSC_VER
+#define testEXPORT __declspec(dllexport)
+#else
+#define testEXPORT
+#endif
+testEXPORT int lib_func(void) { return 9; }
+'''
+MAIN_CODE='''
+#ifdef _MSC_VER
+#define testEXPORT __declspec(dllimport)
+#else
+#define testEXPORT
+#endif
+testEXPORT int lib_func(void);
+int main(int argc, char **argv) {
+ (void)argc; (void)argv;
+ return !(lib_func() == 9);
+}
+'''
+@feature('link_lib_test')
+@before_method('process_source')
+def link_lib_test_fun(self):
+ def write_test_file(task):
+ task.outputs[0].write(task.generator.code)
+ rpath=[]
+ if getattr(self,'add_rpath',False):
+ rpath=[self.bld.path.get_bld().abspath()]
+ mode=self.mode
+ m='%s %s'%(mode,mode)
+ ex=self.test_exec and'test_exec'or''
+ bld=self.bld
+ bld(rule=write_test_file,target='test.'+mode,code=LIB_CODE)
+ bld(rule=write_test_file,target='main.'+mode,code=MAIN_CODE)
+ bld(features='%sshlib'%m,source='test.'+mode,target='test')
+ bld(features='%sprogram %s'%(m,ex),source='main.'+mode,target='app',use='test',rpath=rpath)
+@conf
+def check_library(self,mode=None,test_exec=True):
+ if not mode:
+ mode='c'
+ if self.env.CXX:
+ mode='cxx'
+ self.check(compile_filename=[],features='link_lib_test',msg='Checking for libraries',mode=mode,test_exec=test_exec,)
+INLINE_CODE='''
+typedef int foo_t;
+static %s foo_t static_foo () {return 0; }
+%s foo_t foo () {
+ return 0;
+}
+'''
+INLINE_VALUES=['inline','__inline__','__inline']
+@conf
+def check_inline(self,**kw):
+ self.start_msg('Checking for inline')
+ if not'define_name'in kw:
+ kw['define_name']='INLINE_MACRO'
+ if not'features'in kw:
+ if self.env.CXX:
+ kw['features']=['cxx']
+ else:
+ kw['features']=['c']
+ for x in INLINE_VALUES:
+ kw['fragment']=INLINE_CODE%(x,x)
+ try:
+ self.check(**kw)
+ except self.errors.ConfigurationError:
+ continue
+ else:
+ self.end_msg(x)
+ if x!='inline':
+ self.define('inline',x,quote=False)
+ return x
+ self.fatal('could not use inline functions')
+LARGE_FRAGMENT='''#include <unistd.h>
+int main(int argc, char **argv) {
+ (void)argc; (void)argv;
+ return !(sizeof(off_t) >= 8);
+}
+'''
+@conf
+def check_large_file(self,**kw):
+ if not'define_name'in kw:
+ kw['define_name']='HAVE_LARGEFILE'
+ if not'execute'in kw:
+ kw['execute']=True
+ if not'features'in kw:
+ if self.env.CXX:
+ kw['features']=['cxx','cxxprogram']
+ else:
+ kw['features']=['c','cprogram']
+ kw['fragment']=LARGE_FRAGMENT
+ kw['msg']='Checking for large file support'
+ ret=True
+ try:
+ if self.env.DEST_BINFMT!='pe':
+ ret=self.check(**kw)
+ except self.errors.ConfigurationError:
+ pass
+ else:
+ if ret:
+ return True
+ kw['msg']='Checking for -D_FILE_OFFSET_BITS=64'
+ kw['defines']=['_FILE_OFFSET_BITS=64']
+ try:
+ ret=self.check(**kw)
+ except self.errors.ConfigurationError:
+ pass
+ else:
+ self.define('_FILE_OFFSET_BITS',64)
+ return ret
+ self.fatal('There is no support for large files')
+ENDIAN_FRAGMENT='''
+short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+int use_ascii (int i) {
+ return ascii_mm[i] + ascii_ii[i];
+}
+short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+int use_ebcdic (int i) {
+ return ebcdic_mm[i] + ebcdic_ii[i];
+}
+extern int foo;
+'''
+class grep_for_endianness(Task.Task):
+ color='PINK'
+ def run(self):
+ txt=self.inputs[0].read(flags='rb').decode('iso8859-1')
+ if txt.find('LiTTleEnDian')>-1:
+ self.generator.tmp.append('little')
+ elif txt.find('BIGenDianSyS')>-1:
+ self.generator.tmp.append('big')
+ else:
+ return-1
+@feature('grep_for_endianness')
+@after_method('process_source')
+def grep_for_endianness_fun(self):
+ self.create_task('grep_for_endianness',self.compiled_tasks[0].outputs[0])
+@conf
+def check_endianness(self):
+ tmp=[]
+ def check_msg(self):
+ return tmp[0]
+ self.check(fragment=ENDIAN_FRAGMENT,features='c grep_for_endianness',msg="Checking for endianness",define='ENDIANNESS',tmp=tmp,okmsg=check_msg)
+ return tmp[0]
diff --git a/waflib/Tools/ccroot.py b/waflib/Tools/ccroot.py
new file mode 100644
index 0000000..498a0ab
--- /dev/null
+++ b/waflib/Tools/ccroot.py
@@ -0,0 +1,447 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,re
+from waflib import Task,Utils,Node,Errors
+from waflib.TaskGen import after_method,before_method,feature,taskgen_method,extension
+from waflib.Tools import c_aliases,c_preproc,c_config,c_osx,c_tests
+from waflib.Configure import conf
+SYSTEM_LIB_PATHS=['/usr/lib64','/usr/lib','/usr/local/lib64','/usr/local/lib']
+USELIB_VARS=Utils.defaultdict(set)
+USELIB_VARS['c']=set(['INCLUDES','FRAMEWORKPATH','DEFINES','CPPFLAGS','CCDEPS','CFLAGS','ARCH'])
+USELIB_VARS['cxx']=set(['INCLUDES','FRAMEWORKPATH','DEFINES','CPPFLAGS','CXXDEPS','CXXFLAGS','ARCH'])
+USELIB_VARS['d']=set(['INCLUDES','DFLAGS'])
+USELIB_VARS['includes']=set(['INCLUDES','FRAMEWORKPATH','ARCH'])
+USELIB_VARS['cprogram']=USELIB_VARS['cxxprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','FRAMEWORK','FRAMEWORKPATH','ARCH','LDFLAGS'])
+USELIB_VARS['cshlib']=USELIB_VARS['cxxshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','FRAMEWORK','FRAMEWORKPATH','ARCH','LDFLAGS'])
+USELIB_VARS['cstlib']=USELIB_VARS['cxxstlib']=set(['ARFLAGS','LINKDEPS'])
+USELIB_VARS['dprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
+USELIB_VARS['dshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
+USELIB_VARS['dstlib']=set(['ARFLAGS','LINKDEPS'])
+USELIB_VARS['asm']=set(['ASFLAGS'])
+@taskgen_method
+def create_compiled_task(self,name,node):
+ out='%s.%d.o'%(node.name,self.idx)
+ task=self.create_task(name,node,node.parent.find_or_declare(out))
+ try:
+ self.compiled_tasks.append(task)
+ except AttributeError:
+ self.compiled_tasks=[task]
+ return task
+@taskgen_method
+def to_incnodes(self,inlst):
+ lst=[]
+ seen=set([])
+ for x in self.to_list(inlst):
+ if x in seen or not x:
+ continue
+ seen.add(x)
+ if isinstance(x,Node.Node):
+ lst.append(x)
+ else:
+ if os.path.isabs(x):
+ lst.append(self.bld.root.make_node(x)or x)
+ else:
+ if x[0]=='#':
+ p=self.bld.bldnode.make_node(x[1:])
+ v=self.bld.srcnode.make_node(x[1:])
+ else:
+ p=self.path.get_bld().make_node(x)
+ v=self.path.make_node(x)
+ if p.is_child_of(self.bld.bldnode):
+ p.mkdir()
+ lst.append(p)
+ lst.append(v)
+ return lst
+@feature('c','cxx','d','asm','fc','includes')
+@after_method('propagate_uselib_vars','process_source')
+def apply_incpaths(self):
+ lst=self.to_incnodes(self.to_list(getattr(self,'includes',[]))+self.env['INCLUDES'])
+ self.includes_nodes=lst
+ self.env['INCPATHS']=[x.abspath()for x in lst]
+class link_task(Task.Task):
+ color='YELLOW'
+ inst_to=None
+ chmod=Utils.O755
+ def add_target(self,target):
+ if isinstance(target,str):
+ pattern=self.env[self.__class__.__name__+'_PATTERN']
+ if not pattern:
+ pattern='%s'
+ folder,name=os.path.split(target)
+ if self.__class__.__name__.find('shlib')>0 and getattr(self.generator,'vnum',None):
+ nums=self.generator.vnum.split('.')
+ if self.env.DEST_BINFMT=='pe':
+ name=name+'-'+nums[0]
+ elif self.env.DEST_OS=='openbsd':
+ pattern='%s.%s'%(pattern,nums[0])
+ if len(nums)>=2:
+ pattern+='.%s'%nums[1]
+ if folder:
+ tmp=folder+os.sep+pattern%name
+ else:
+ tmp=pattern%name
+ target=self.generator.path.find_or_declare(tmp)
+ self.set_outputs(target)
+class stlink_task(link_task):
+ run_str='${AR} ${ARFLAGS} ${AR_TGT_F}${TGT} ${AR_SRC_F}${SRC}'
+ chmod=Utils.O644
+def rm_tgt(cls):
+ old=cls.run
+ def wrap(self):
+ try:os.remove(self.outputs[0].abspath())
+ except OSError:pass
+ return old(self)
+ setattr(cls,'run',wrap)
+rm_tgt(stlink_task)
+@feature('c','cxx','d','fc','asm')
+@after_method('process_source')
+def apply_link(self):
+ for x in self.features:
+ if x=='cprogram'and'cxx'in self.features:
+ x='cxxprogram'
+ elif x=='cshlib'and'cxx'in self.features:
+ x='cxxshlib'
+ if x in Task.classes:
+ if issubclass(Task.classes[x],link_task):
+ link=x
+ break
+ else:
+ return
+ objs=[t.outputs[0]for t in getattr(self,'compiled_tasks',[])]
+ self.link_task=self.create_task(link,objs)
+ self.link_task.add_target(self.target)
+ try:
+ inst_to=self.install_path
+ except AttributeError:
+ inst_to=self.link_task.__class__.inst_to
+ if inst_to:
+ self.install_task=self.bld.install_files(inst_to,self.link_task.outputs[:],env=self.env,chmod=self.link_task.chmod,task=self.link_task)
+@taskgen_method
+def use_rec(self,name,**kw):
+ if name in self.tmp_use_not or name in self.tmp_use_seen:
+ return
+ try:
+ y=self.bld.get_tgen_by_name(name)
+ except Errors.WafError:
+ self.uselib.append(name)
+ self.tmp_use_not.add(name)
+ return
+ self.tmp_use_seen.append(name)
+ y.post()
+ y.tmp_use_objects=objects=kw.get('objects',True)
+ y.tmp_use_stlib=stlib=kw.get('stlib',True)
+ try:
+ link_task=y.link_task
+ except AttributeError:
+ y.tmp_use_var=''
+ else:
+ objects=False
+ if not isinstance(link_task,stlink_task):
+ stlib=False
+ y.tmp_use_var='LIB'
+ else:
+ y.tmp_use_var='STLIB'
+ p=self.tmp_use_prec
+ for x in self.to_list(getattr(y,'use',[])):
+ if self.env["STLIB_"+x]:
+ continue
+ try:
+ p[x].append(name)
+ except KeyError:
+ p[x]=[name]
+ self.use_rec(x,objects=objects,stlib=stlib)
+@feature('c','cxx','d','use','fc')
+@before_method('apply_incpaths','propagate_uselib_vars')
+@after_method('apply_link','process_source')
+def process_use(self):
+ use_not=self.tmp_use_not=set([])
+ self.tmp_use_seen=[]
+ use_prec=self.tmp_use_prec={}
+ self.uselib=self.to_list(getattr(self,'uselib',[]))
+ self.includes=self.to_list(getattr(self,'includes',[]))
+ names=self.to_list(getattr(self,'use',[]))
+ for x in names:
+ self.use_rec(x)
+ for x in use_not:
+ if x in use_prec:
+ del use_prec[x]
+ out=[]
+ tmp=[]
+ for x in self.tmp_use_seen:
+ for k in use_prec.values():
+ if x in k:
+ break
+ else:
+ tmp.append(x)
+ while tmp:
+ e=tmp.pop()
+ out.append(e)
+ try:
+ nlst=use_prec[e]
+ except KeyError:
+ pass
+ else:
+ del use_prec[e]
+ for x in nlst:
+ for y in use_prec:
+ if x in use_prec[y]:
+ break
+ else:
+ tmp.append(x)
+ if use_prec:
+ raise Errors.WafError('Cycle detected in the use processing %r'%use_prec)
+ out.reverse()
+ link_task=getattr(self,'link_task',None)
+ for x in out:
+ y=self.bld.get_tgen_by_name(x)
+ var=y.tmp_use_var
+ if var and link_task:
+ if var=='LIB'or y.tmp_use_stlib or x in names:
+ self.env.append_value(var,[y.target[y.target.rfind(os.sep)+1:]])
+ self.link_task.dep_nodes.extend(y.link_task.outputs)
+ tmp_path=y.link_task.outputs[0].parent.path_from(self.bld.bldnode)
+ self.env.append_unique(var+'PATH',[tmp_path])
+ else:
+ if y.tmp_use_objects:
+ self.add_objects_from_tgen(y)
+ if getattr(y,'export_includes',None):
+ self.includes.extend(y.to_incnodes(y.export_includes))
+ if getattr(y,'export_defines',None):
+ self.env.append_value('DEFINES',self.to_list(y.export_defines))
+ for x in names:
+ try:
+ y=self.bld.get_tgen_by_name(x)
+ except Errors.WafError:
+ if not self.env['STLIB_'+x]and not x in self.uselib:
+ self.uselib.append(x)
+ else:
+ for k in self.to_list(getattr(y,'use',[])):
+ if not self.env['STLIB_'+k]and not k in self.uselib:
+ self.uselib.append(k)
+@taskgen_method
+def accept_node_to_link(self,node):
+ return not node.name.endswith('.pdb')
+@taskgen_method
+def add_objects_from_tgen(self,tg):
+ try:
+ link_task=self.link_task
+ except AttributeError:
+ pass
+ else:
+ for tsk in getattr(tg,'compiled_tasks',[]):
+ for x in tsk.outputs:
+ if self.accept_node_to_link(x):
+ link_task.inputs.append(x)
+@taskgen_method
+def get_uselib_vars(self):
+ _vars=set([])
+ for x in self.features:
+ if x in USELIB_VARS:
+ _vars|=USELIB_VARS[x]
+ return _vars
+@feature('c','cxx','d','fc','javac','cs','uselib','asm')
+@after_method('process_use')
+def propagate_uselib_vars(self):
+ _vars=self.get_uselib_vars()
+ env=self.env
+ app=env.append_value
+ feature_uselib=self.features+self.to_list(getattr(self,'uselib',[]))
+ for var in _vars:
+ y=var.lower()
+ val=getattr(self,y,[])
+ if val:
+ app(var,self.to_list(val))
+ for x in feature_uselib:
+ val=env['%s_%s'%(var,x)]
+ if val:
+ app(var,val)
+@feature('cshlib','cxxshlib','fcshlib')
+@after_method('apply_link')
+def apply_implib(self):
+ if not self.env.DEST_BINFMT=='pe':
+ return
+ dll=self.link_task.outputs[0]
+ if isinstance(self.target,Node.Node):
+ name=self.target.name
+ else:
+ name=os.path.split(self.target)[1]
+ implib=self.env['implib_PATTERN']%name
+ implib=dll.parent.find_or_declare(implib)
+ self.env.append_value('LINKFLAGS',self.env['IMPLIB_ST']%implib.bldpath())
+ self.link_task.outputs.append(implib)
+ if getattr(self,'defs',None)and self.env.DEST_BINFMT=='pe':
+ node=self.path.find_resource(self.defs)
+ if not node:
+ raise Errors.WafError('invalid def file %r'%self.defs)
+ if'msvc'in(self.env.CC_NAME,self.env.CXX_NAME):
+ self.env.append_value('LINKFLAGS','/def:%s'%node.path_from(self.bld.bldnode))
+ self.link_task.dep_nodes.append(node)
+ else:
+ self.link_task.inputs.append(node)
+ if getattr(self,'install_task',None):
+ try:
+ inst_to=self.install_path_implib
+ except AttributeError:
+ try:
+ inst_to=self.install_path
+ except AttributeError:
+ inst_to='${IMPLIBDIR}'
+ self.install_task.dest='${BINDIR}'
+ if not self.env.IMPLIBDIR:
+ self.env.IMPLIBDIR=self.env.LIBDIR
+ self.implib_install_task=self.bld.install_files(inst_to,implib,env=self.env,chmod=self.link_task.chmod,task=self.link_task)
+re_vnum=re.compile('^([1-9]\\d*|0)([.]([1-9]\\d*|0)){0,2}?$')
+@feature('cshlib','cxxshlib','dshlib','fcshlib','vnum')
+@after_method('apply_link','propagate_uselib_vars')
+def apply_vnum(self):
+ if not getattr(self,'vnum','')or os.name!='posix'or self.env.DEST_BINFMT not in('elf','mac-o'):
+ return
+ link=self.link_task
+ if not re_vnum.match(self.vnum):
+ raise Errors.WafError('Invalid vnum %r for target %r'%(self.vnum,getattr(self,'name',self)))
+ nums=self.vnum.split('.')
+ node=link.outputs[0]
+ cnum=getattr(self,'cnum',str(nums[0]))
+ cnums=cnum.split('.')
+ if len(cnums)>len(nums)or nums[0:len(cnums)]!=cnums:
+ raise Errors.WafError('invalid compatibility version %s'%cnum)
+ libname=node.name
+ if libname.endswith('.dylib'):
+ name3=libname.replace('.dylib','.%s.dylib'%self.vnum)
+ name2=libname.replace('.dylib','.%s.dylib'%cnum)
+ else:
+ name3=libname+'.'+self.vnum
+ name2=libname+'.'+cnum
+ if self.env.SONAME_ST:
+ v=self.env.SONAME_ST%name2
+ self.env.append_value('LINKFLAGS',v.split())
+ if self.env.DEST_OS!='openbsd':
+ outs=[node.parent.find_or_declare(name3)]
+ if name2!=name3:
+ outs.append(node.parent.find_or_declare(name2))
+ self.create_task('vnum',node,outs)
+ if getattr(self,'install_task',None):
+ self.install_task.hasrun=Task.SKIP_ME
+ bld=self.bld
+ path=self.install_task.dest
+ if self.env.DEST_OS=='openbsd':
+ libname=self.link_task.outputs[0].name
+ t1=bld.install_as('%s%s%s'%(path,os.sep,libname),node,env=self.env,chmod=self.link_task.chmod)
+ self.vnum_install_task=(t1,)
+ else:
+ t1=bld.install_as(path+os.sep+name3,node,env=self.env,chmod=self.link_task.chmod)
+ t3=bld.symlink_as(path+os.sep+libname,name3)
+ if name2!=name3:
+ t2=bld.symlink_as(path+os.sep+name2,name3)
+ self.vnum_install_task=(t1,t2,t3)
+ else:
+ self.vnum_install_task=(t1,t3)
+ if'-dynamiclib'in self.env['LINKFLAGS']:
+ try:
+ inst_to=self.install_path
+ except AttributeError:
+ inst_to=self.link_task.__class__.inst_to
+ if inst_to:
+ p=Utils.subst_vars(inst_to,self.env)
+ path=os.path.join(p,name2)
+ self.env.append_value('LINKFLAGS',['-install_name',path])
+ self.env.append_value('LINKFLAGS','-Wl,-compatibility_version,%s'%cnum)
+ self.env.append_value('LINKFLAGS','-Wl,-current_version,%s'%self.vnum)
+class vnum(Task.Task):
+ color='CYAN'
+ quient=True
+ ext_in=['.bin']
+ def keyword(self):
+ return'Symlinking'
+ def run(self):
+ for x in self.outputs:
+ path=x.abspath()
+ try:
+ os.remove(path)
+ except OSError:
+ pass
+ try:
+ os.symlink(self.inputs[0].name,path)
+ except OSError:
+ return 1
+class fake_shlib(link_task):
+ def runnable_status(self):
+ for t in self.run_after:
+ if not t.hasrun:
+ return Task.ASK_LATER
+ for x in self.outputs:
+ x.sig=Utils.h_file(x.abspath())
+ return Task.SKIP_ME
+class fake_stlib(stlink_task):
+ def runnable_status(self):
+ for t in self.run_after:
+ if not t.hasrun:
+ return Task.ASK_LATER
+ for x in self.outputs:
+ x.sig=Utils.h_file(x.abspath())
+ return Task.SKIP_ME
+@conf
+def read_shlib(self,name,paths=[],export_includes=[],export_defines=[]):
+ return self(name=name,features='fake_lib',lib_paths=paths,lib_type='shlib',export_includes=export_includes,export_defines=export_defines)
+@conf
+def read_stlib(self,name,paths=[],export_includes=[],export_defines=[]):
+ return self(name=name,features='fake_lib',lib_paths=paths,lib_type='stlib',export_includes=export_includes,export_defines=export_defines)
+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'],}
+@feature('fake_lib')
+def process_lib(self):
+ node=None
+ names=[x%self.name for x in lib_patterns[self.lib_type]]
+ for x in self.lib_paths+[self.path]+SYSTEM_LIB_PATHS:
+ if not isinstance(x,Node.Node):
+ x=self.bld.root.find_node(x)or self.path.find_node(x)
+ if not x:
+ continue
+ for y in names:
+ node=x.find_node(y)
+ if node:
+ node.sig=Utils.h_file(node.abspath())
+ break
+ else:
+ continue
+ break
+ else:
+ raise Errors.WafError('could not find library %r'%self.name)
+ self.link_task=self.create_task('fake_%s'%self.lib_type,[],[node])
+ self.target=self.name
+class fake_o(Task.Task):
+ def runnable_status(self):
+ return Task.SKIP_ME
+@extension('.o','.obj')
+def add_those_o_files(self,node):
+ tsk=self.create_task('fake_o',[],node)
+ try:
+ self.compiled_tasks.append(tsk)
+ except AttributeError:
+ self.compiled_tasks=[tsk]
+@feature('fake_obj')
+@before_method('process_source')
+def process_objs(self):
+ for node in self.to_nodes(self.source):
+ self.add_those_o_files(node)
+ self.source=[]
+@conf
+def read_object(self,obj):
+ if not isinstance(obj,self.path.__class__):
+ obj=self.path.find_resource(obj)
+ return self(features='fake_obj',source=obj,name=obj.name)
+@feature('cxxprogram','cprogram')
+@after_method('apply_link','process_use')
+def set_full_paths_hpux(self):
+ if self.env.DEST_OS!='hp-ux':
+ return
+ base=self.bld.bldnode.abspath()
+ for var in['LIBPATH','STLIBPATH']:
+ lst=[]
+ for x in self.env[var]:
+ if x.startswith('/'):
+ lst.append(x)
+ else:
+ lst.append(os.path.normpath(os.path.join(base,x)))
+ self.env[var]=lst
diff --git a/waflib/Tools/clang.py b/waflib/Tools/clang.py
new file mode 100644
index 0000000..9379f5a
--- /dev/null
+++ b/waflib/Tools/clang.py
@@ -0,0 +1,20 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib.Tools import ccroot,ar,gcc
+from waflib.Configure import conf
+@conf
+def find_clang(conf):
+ cc=conf.find_program('clang',var='CC')
+ conf.get_cc_version(cc,clang=True)
+ conf.env.CC_NAME='clang'
+def configure(conf):
+ conf.find_clang()
+ conf.find_program(['llvm-ar','ar'],var='AR')
+ conf.find_ar()
+ conf.gcc_common_flags()
+ conf.gcc_modifier_platform()
+ conf.cc_load_tools()
+ conf.cc_add_flags()
+ conf.link_add_flags()
diff --git a/waflib/Tools/clangxx.py b/waflib/Tools/clangxx.py
new file mode 100644
index 0000000..fc97135
--- /dev/null
+++ b/waflib/Tools/clangxx.py
@@ -0,0 +1,20 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib.Tools import ccroot,ar,gxx
+from waflib.Configure import conf
+@conf
+def find_clangxx(conf):
+ cxx=conf.find_program('clang++',var='CXX')
+ conf.get_cc_version(cxx,clang=True)
+ conf.env.CXX_NAME='clang'
+def configure(conf):
+ conf.find_clangxx()
+ conf.find_program(['llvm-ar','ar'],var='AR')
+ conf.find_ar()
+ conf.gxx_common_flags()
+ conf.gxx_modifier_platform()
+ conf.cxx_load_tools()
+ conf.cxx_add_flags()
+ conf.link_add_flags()
diff --git a/waflib/Tools/compiler_c.py b/waflib/Tools/compiler_c.py
new file mode 100644
index 0000000..3d7f34e
--- /dev/null
+++ b/waflib/Tools/compiler_c.py
@@ -0,0 +1,40 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import re
+from waflib.Tools import ccroot
+from waflib import Utils
+from waflib.Logs import debug
+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':['gcc','clang'],}
+def default_compilers():
+ build_platform=Utils.unversioned_sys_platform()
+ possible_compiler_list=c_compiler.get(build_platform,c_compiler['default'])
+ return' '.join(possible_compiler_list)
+def configure(conf):
+ try:test_for_compiler=conf.options.check_c_compiler or default_compilers()
+ except AttributeError:conf.fatal("Add options(opt): opt.load('compiler_c')")
+ for compiler in re.split('[ ,]+',test_for_compiler):
+ conf.env.stash()
+ conf.start_msg('Checking for %r (C compiler)'%compiler)
+ try:
+ conf.load(compiler)
+ except conf.errors.ConfigurationError ,e:
+ conf.env.revert()
+ conf.end_msg(False)
+ debug('compiler_c: %r'%e)
+ else:
+ if conf.env['CC']:
+ conf.end_msg(conf.env.get_flat('CC'))
+ conf.env['COMPILER_CC']=compiler
+ break
+ conf.end_msg(False)
+ else:
+ conf.fatal('could not configure a C compiler!')
+def options(opt):
+ test_for_compiler=default_compilers()
+ opt.load_special_tools('c_*.py',ban=['c_dumbpreproc.py'])
+ cc_compiler_opts=opt.add_option_group('Configuration options')
+ 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")
+ for x in test_for_compiler.split():
+ opt.load('%s'%x)
diff --git a/waflib/Tools/compiler_cxx.py b/waflib/Tools/compiler_cxx.py
new file mode 100644
index 0000000..eb5d8da
--- /dev/null
+++ b/waflib/Tools/compiler_cxx.py
@@ -0,0 +1,40 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import re
+from waflib.Tools import ccroot
+from waflib import Utils
+from waflib.Logs import debug
+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':['g++','clang++']}
+def default_compilers():
+ build_platform=Utils.unversioned_sys_platform()
+ possible_compiler_list=cxx_compiler.get(build_platform,cxx_compiler['default'])
+ return' '.join(possible_compiler_list)
+def configure(conf):
+ try:test_for_compiler=conf.options.check_cxx_compiler or default_compilers()
+ except AttributeError:conf.fatal("Add options(opt): opt.load('compiler_cxx')")
+ for compiler in re.split('[ ,]+',test_for_compiler):
+ conf.env.stash()
+ conf.start_msg('Checking for %r (C++ compiler)'%compiler)
+ try:
+ conf.load(compiler)
+ except conf.errors.ConfigurationError ,e:
+ conf.env.revert()
+ conf.end_msg(False)
+ debug('compiler_cxx: %r'%e)
+ else:
+ if conf.env['CXX']:
+ conf.end_msg(conf.env.get_flat('CXX'))
+ conf.env['COMPILER_CXX']=compiler
+ break
+ conf.end_msg(False)
+ else:
+ conf.fatal('could not configure a C++ compiler!')
+def options(opt):
+ test_for_compiler=default_compilers()
+ opt.load_special_tools('cxx_*.py')
+ cxx_compiler_opts=opt.add_option_group('Configuration options')
+ 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")
+ for x in test_for_compiler.split():
+ opt.load('%s'%x)
diff --git a/waflib/Tools/compiler_d.py b/waflib/Tools/compiler_d.py
new file mode 100644
index 0000000..0d81675
--- /dev/null
+++ b/waflib/Tools/compiler_d.py
@@ -0,0 +1,37 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils,Logs
+d_compiler={'default':['gdc','dmd','ldc2']}
+def default_compilers():
+ build_platform=Utils.unversioned_sys_platform()
+ possible_compiler_list=d_compiler.get(build_platform,d_compiler['default'])
+ return' '.join(possible_compiler_list)
+def configure(conf):
+ try:test_for_compiler=conf.options.check_d_compiler or default_compilers()
+ except AttributeError:conf.fatal("Add options(opt): opt.load('compiler_d')")
+ for compiler in re.split('[ ,]+',test_for_compiler):
+ conf.env.stash()
+ conf.start_msg('Checking for %r (D compiler)'%compiler)
+ try:
+ conf.load(compiler)
+ except conf.errors.ConfigurationError ,e:
+ conf.env.revert()
+ conf.end_msg(False)
+ Logs.debug('compiler_d: %r'%e)
+ else:
+ if conf.env.D:
+ conf.end_msg(conf.env.get_flat('D'))
+ conf.env['COMPILER_D']=compiler
+ break
+ conf.end_msg(False)
+ else:
+ conf.fatal('could not configure a D compiler!')
+def options(opt):
+ test_for_compiler=default_compilers()
+ d_compiler_opts=opt.add_option_group('Configuration options')
+ 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')
+ for x in test_for_compiler.split():
+ opt.load('%s'%x)
diff --git a/waflib/Tools/compiler_fc.py b/waflib/Tools/compiler_fc.py
new file mode 100644
index 0000000..2cdeeb4
--- /dev/null
+++ b/waflib/Tools/compiler_fc.py
@@ -0,0 +1,39 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils,Logs
+from waflib.Tools import fc
+fc_compiler={'win32':['gfortran','ifort'],'darwin':['gfortran','g95','ifort'],'linux':['gfortran','g95','ifort'],'java':['gfortran','g95','ifort'],'default':['gfortran'],'aix':['gfortran']}
+def default_compilers():
+ build_platform=Utils.unversioned_sys_platform()
+ possible_compiler_list=fc_compiler.get(build_platform,fc_compiler['default'])
+ return' '.join(possible_compiler_list)
+def configure(conf):
+ try:test_for_compiler=conf.options.check_fortran_compiler or default_compilers()
+ except AttributeError:conf.fatal("Add options(opt): opt.load('compiler_fc')")
+ for compiler in re.split('[ ,]+',test_for_compiler):
+ conf.env.stash()
+ conf.start_msg('Checking for %r (Fortran compiler)'%compiler)
+ try:
+ conf.load(compiler)
+ except conf.errors.ConfigurationError ,e:
+ conf.env.revert()
+ conf.end_msg(False)
+ Logs.debug('compiler_fortran: %r'%e)
+ else:
+ if conf.env['FC']:
+ conf.end_msg(conf.env.get_flat('FC'))
+ conf.env.COMPILER_FORTRAN=compiler
+ break
+ conf.end_msg(False)
+ else:
+ conf.fatal('could not configure a Fortran compiler!')
+def options(opt):
+ test_for_compiler=default_compilers()
+ opt.load_special_tools('fc_*.py')
+ fortran_compiler_opts=opt.add_option_group('Configuration options')
+ 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")
+ for x in test_for_compiler.split():
+ opt.load('%s'%x)
diff --git a/waflib/Tools/cs.py b/waflib/Tools/cs.py
new file mode 100644
index 0000000..8f1589a
--- /dev/null
+++ b/waflib/Tools/cs.py
@@ -0,0 +1,132 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib import Utils,Task,Options,Errors
+from waflib.TaskGen import before_method,after_method,feature
+from waflib.Tools import ccroot
+from waflib.Configure import conf
+import os,tempfile
+ccroot.USELIB_VARS['cs']=set(['CSFLAGS','ASSEMBLIES','RESOURCES'])
+ccroot.lib_patterns['csshlib']=['%s']
+@feature('cs')
+@before_method('process_source')
+def apply_cs(self):
+ cs_nodes=[]
+ no_nodes=[]
+ for x in self.to_nodes(self.source):
+ if x.name.endswith('.cs'):
+ cs_nodes.append(x)
+ else:
+ no_nodes.append(x)
+ self.source=no_nodes
+ bintype=getattr(self,'bintype',self.gen.endswith('.dll')and'library'or'exe')
+ self.cs_task=tsk=self.create_task('mcs',cs_nodes,self.path.find_or_declare(self.gen))
+ tsk.env.CSTYPE='/target:%s'%bintype
+ tsk.env.OUT='/out:%s'%tsk.outputs[0].abspath()
+ self.env.append_value('CSFLAGS','/platform:%s'%getattr(self,'platform','anycpu'))
+ inst_to=getattr(self,'install_path',bintype=='exe'and'${BINDIR}'or'${LIBDIR}')
+ if inst_to:
+ mod=getattr(self,'chmod',bintype=='exe'and Utils.O755 or Utils.O644)
+ self.install_task=self.bld.install_files(inst_to,self.cs_task.outputs[:],env=self.env,chmod=mod)
+@feature('cs')
+@after_method('apply_cs')
+def use_cs(self):
+ names=self.to_list(getattr(self,'use',[]))
+ get=self.bld.get_tgen_by_name
+ for x in names:
+ try:
+ y=get(x)
+ except Errors.WafError:
+ self.env.append_value('CSFLAGS','/reference:%s'%x)
+ continue
+ y.post()
+ tsk=getattr(y,'cs_task',None)or getattr(y,'link_task',None)
+ if not tsk:
+ self.bld.fatal('cs task has no link task for use %r'%self)
+ self.cs_task.dep_nodes.extend(tsk.outputs)
+ self.cs_task.set_run_after(tsk)
+ self.env.append_value('CSFLAGS','/reference:%s'%tsk.outputs[0].abspath())
+@feature('cs')
+@after_method('apply_cs','use_cs')
+def debug_cs(self):
+ csdebug=getattr(self,'csdebug',self.env.CSDEBUG)
+ if not csdebug:
+ return
+ node=self.cs_task.outputs[0]
+ if self.env.CS_NAME=='mono':
+ out=node.parent.find_or_declare(node.name+'.mdb')
+ else:
+ out=node.change_ext('.pdb')
+ self.cs_task.outputs.append(out)
+ try:
+ self.install_task.source.append(out)
+ except AttributeError:
+ pass
+ if csdebug=='pdbonly':
+ val=['/debug+','/debug:pdbonly']
+ elif csdebug=='full':
+ val=['/debug+','/debug:full']
+ else:
+ val=['/debug-']
+ self.env.append_value('CSFLAGS',val)
+class mcs(Task.Task):
+ color='YELLOW'
+ run_str='${MCS} ${CSTYPE} ${CSFLAGS} ${ASS_ST:ASSEMBLIES} ${RES_ST:RESOURCES} ${OUT} ${SRC}'
+ def exec_command(self,cmd,**kw):
+ bld=self.generator.bld
+ try:
+ if not kw.get('cwd',None):
+ kw['cwd']=bld.cwd
+ except AttributeError:
+ bld.cwd=kw['cwd']=bld.variant_dir
+ try:
+ tmp=None
+ if isinstance(cmd,list)and len(' '.join(cmd))>=8192:
+ program=cmd[0]
+ cmd=[self.quote_response_command(x)for x in cmd]
+ (fd,tmp)=tempfile.mkstemp()
+ os.write(fd,'\r\n'.join(i.replace('\\','\\\\')for i in cmd[1:]))
+ os.close(fd)
+ cmd=[program,'@'+tmp]
+ ret=self.generator.bld.exec_command(cmd,**kw)
+ finally:
+ if tmp:
+ try:
+ os.remove(tmp)
+ except OSError:
+ pass
+ return ret
+ def quote_response_command(self,flag):
+ if flag.lower()=='/noconfig':
+ return''
+ if flag.find(' ')>-1:
+ for x in('/r:','/reference:','/resource:','/lib:','/out:'):
+ if flag.startswith(x):
+ flag='%s"%s"'%(x,'","'.join(flag[len(x):].split(',')))
+ break
+ else:
+ flag='"%s"'%flag
+ return flag
+def configure(conf):
+ csc=getattr(Options.options,'cscbinary',None)
+ if csc:
+ conf.env.MCS=csc
+ conf.find_program(['csc','mcs','gmcs'],var='MCS')
+ conf.env.ASS_ST='/r:%s'
+ conf.env.RES_ST='/resource:%s'
+ conf.env.CS_NAME='csc'
+ if str(conf.env.MCS).lower().find('mcs')>-1:
+ conf.env.CS_NAME='mono'
+def options(opt):
+ opt.add_option('--with-csc-binary',type='string',dest='cscbinary')
+class fake_csshlib(Task.Task):
+ color='YELLOW'
+ inst_to=None
+ def runnable_status(self):
+ for x in self.outputs:
+ x.sig=Utils.h_file(x.abspath())
+ return Task.SKIP_ME
+@conf
+def read_csshlib(self,name,paths=[]):
+ return self(name=name,features='fake_lib',lib_paths=paths,lib_type='csshlib')
diff --git a/waflib/Tools/cxx.py b/waflib/Tools/cxx.py
new file mode 100644
index 0000000..6f039e9
--- /dev/null
+++ b/waflib/Tools/cxx.py
@@ -0,0 +1,26 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib import TaskGen,Task
+from waflib.Tools import c_preproc
+from waflib.Tools.ccroot import link_task,stlink_task
+@TaskGen.extension('.cpp','.cc','.cxx','.C','.c++')
+def cxx_hook(self,node):
+ return self.create_compiled_task('cxx',node)
+if not'.c'in TaskGen.task_gen.mappings:
+ TaskGen.task_gen.mappings['.c']=TaskGen.task_gen.mappings['.cpp']
+class cxx(Task.Task):
+ run_str='${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT[0].abspath()}'
+ vars=['CXXDEPS']
+ ext_in=['.h']
+ scan=c_preproc.scan
+class cxxprogram(link_task):
+ 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}'
+ vars=['LINKDEPS']
+ ext_out=['.bin']
+ inst_to='${BINDIR}'
+class cxxshlib(cxxprogram):
+ inst_to='${LIBDIR}'
+class cxxstlib(stlink_task):
+ pass
diff --git a/waflib/Tools/d.py b/waflib/Tools/d.py
new file mode 100644
index 0000000..e8c98f0
--- /dev/null
+++ b/waflib/Tools/d.py
@@ -0,0 +1,54 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib import Utils,Task,Errors
+from waflib.TaskGen import taskgen_method,feature,extension
+from waflib.Tools import d_scan,d_config
+from waflib.Tools.ccroot import link_task,stlink_task
+class d(Task.Task):
+ color='GREEN'
+ run_str='${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_SRC_F:SRC} ${D_TGT_F:TGT}'
+ scan=d_scan.scan
+class d_with_header(d):
+ 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()}'
+class d_header(Task.Task):
+ color='BLUE'
+ run_str='${D} ${D_HEADER} ${SRC}'
+class dprogram(link_task):
+ 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}'
+ inst_to='${BINDIR}'
+class dshlib(dprogram):
+ inst_to='${LIBDIR}'
+class dstlib(stlink_task):
+ pass
+@extension('.d','.di','.D')
+def d_hook(self,node):
+ ext=Utils.destos_to_binfmt(self.env.DEST_OS)=='pe'and'obj'or'o'
+ out='%s.%d.%s'%(node.name,self.idx,ext)
+ def create_compiled_task(self,name,node):
+ task=self.create_task(name,node,node.parent.find_or_declare(out))
+ try:
+ self.compiled_tasks.append(task)
+ except AttributeError:
+ self.compiled_tasks=[task]
+ return task
+ if getattr(self,'generate_headers',None):
+ tsk=create_compiled_task(self,'d_with_header',node)
+ tsk.outputs.append(node.change_ext(self.env['DHEADER_ext']))
+ else:
+ tsk=create_compiled_task(self,'d',node)
+ return tsk
+@taskgen_method
+def generate_header(self,filename):
+ try:
+ self.header_lst.append([filename,self.install_path])
+ except AttributeError:
+ self.header_lst=[[filename,self.install_path]]
+@feature('d')
+def process_header(self):
+ for i in getattr(self,'header_lst',[]):
+ node=self.path.find_resource(i[0])
+ if not node:
+ raise Errors.WafError('file %r not found on d obj'%i[0])
+ self.create_task('d_header',node,node.change_ext('.di'))
diff --git a/waflib/Tools/d_config.py b/waflib/Tools/d_config.py
new file mode 100644
index 0000000..71b7b6e
--- /dev/null
+++ b/waflib/Tools/d_config.py
@@ -0,0 +1,52 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib import Utils
+from waflib.Configure import conf
+@conf
+def d_platform_flags(self):
+ v=self.env
+ if not v.DEST_OS:
+ v.DEST_OS=Utils.unversioned_sys_platform()
+ binfmt=Utils.destos_to_binfmt(self.env.DEST_OS)
+ if binfmt=='pe':
+ v['dprogram_PATTERN']='%s.exe'
+ v['dshlib_PATTERN']='lib%s.dll'
+ v['dstlib_PATTERN']='lib%s.a'
+ elif binfmt=='mac-o':
+ v['dprogram_PATTERN']='%s'
+ v['dshlib_PATTERN']='lib%s.dylib'
+ v['dstlib_PATTERN']='lib%s.a'
+ else:
+ v['dprogram_PATTERN']='%s'
+ v['dshlib_PATTERN']='lib%s.so'
+ v['dstlib_PATTERN']='lib%s.a'
+DLIB='''
+version(D_Version2) {
+ import std.stdio;
+ int main() {
+ writefln("phobos2");
+ return 0;
+ }
+} else {
+ version(Tango) {
+ import tango.stdc.stdio;
+ int main() {
+ printf("tango");
+ return 0;
+ }
+ } else {
+ import std.stdio;
+ int main() {
+ writefln("phobos1");
+ return 0;
+ }
+ }
+}
+'''
+@conf
+def check_dlibrary(self,execute=True):
+ ret=self.check_cc(features='d dprogram',fragment=DLIB,compile_filename='test.d',execute=execute,define_ret=True)
+ if execute:
+ self.env.DLIBRARY=ret.strip()
diff --git a/waflib/Tools/d_scan.py b/waflib/Tools/d_scan.py
new file mode 100644
index 0000000..47f9196
--- /dev/null
+++ b/waflib/Tools/d_scan.py
@@ -0,0 +1,133 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils,Logs
+def filter_comments(filename):
+ txt=Utils.readf(filename)
+ i=0
+ buf=[]
+ max=len(txt)
+ begin=0
+ while i<max:
+ c=txt[i]
+ if c=='"'or c=="'":
+ buf.append(txt[begin:i])
+ delim=c
+ i+=1
+ while i<max:
+ c=txt[i]
+ if c==delim:break
+ elif c=='\\':
+ i+=1
+ i+=1
+ i+=1
+ begin=i
+ elif c=='/':
+ buf.append(txt[begin:i])
+ i+=1
+ if i==max:break
+ c=txt[i]
+ if c=='+':
+ i+=1
+ nesting=1
+ c=None
+ while i<max:
+ prev=c
+ c=txt[i]
+ if prev=='/'and c=='+':
+ nesting+=1
+ c=None
+ elif prev=='+'and c=='/':
+ nesting-=1
+ if nesting==0:break
+ c=None
+ i+=1
+ elif c=='*':
+ i+=1
+ c=None
+ while i<max:
+ prev=c
+ c=txt[i]
+ if prev=='*'and c=='/':break
+ i+=1
+ elif c=='/':
+ i+=1
+ while i<max and txt[i]!='\n':
+ i+=1
+ else:
+ begin=i-1
+ continue
+ i+=1
+ begin=i
+ buf.append(' ')
+ else:
+ i+=1
+ buf.append(txt[begin:])
+ return buf
+class d_parser(object):
+ def __init__(self,env,incpaths):
+ self.allnames=[]
+ self.re_module=re.compile("module\s+([^;]+)")
+ self.re_import=re.compile("import\s+([^;]+)")
+ self.re_import_bindings=re.compile("([^:]+):(.*)")
+ self.re_import_alias=re.compile("[^=]+=(.+)")
+ self.env=env
+ self.nodes=[]
+ self.names=[]
+ self.incpaths=incpaths
+ def tryfind(self,filename):
+ found=0
+ for n in self.incpaths:
+ found=n.find_resource(filename.replace('.','/')+'.d')
+ if found:
+ self.nodes.append(found)
+ self.waiting.append(found)
+ break
+ if not found:
+ if not filename in self.names:
+ self.names.append(filename)
+ def get_strings(self,code):
+ self.module=''
+ lst=[]
+ mod_name=self.re_module.search(code)
+ if mod_name:
+ self.module=re.sub('\s+','',mod_name.group(1))
+ import_iterator=self.re_import.finditer(code)
+ if import_iterator:
+ for import_match in import_iterator:
+ import_match_str=re.sub('\s+','',import_match.group(1))
+ bindings_match=self.re_import_bindings.match(import_match_str)
+ if bindings_match:
+ import_match_str=bindings_match.group(1)
+ matches=import_match_str.split(',')
+ for match in matches:
+ alias_match=self.re_import_alias.match(match)
+ if alias_match:
+ match=alias_match.group(1)
+ lst.append(match)
+ return lst
+ def start(self,node):
+ self.waiting=[node]
+ while self.waiting:
+ nd=self.waiting.pop(0)
+ self.iter(nd)
+ def iter(self,node):
+ path=node.abspath()
+ code="".join(filter_comments(path))
+ names=self.get_strings(code)
+ for x in names:
+ if x in self.allnames:continue
+ self.allnames.append(x)
+ self.tryfind(x)
+def scan(self):
+ env=self.env
+ gruik=d_parser(env,self.generator.includes_nodes)
+ node=self.inputs[0]
+ gruik.start(node)
+ nodes=gruik.nodes
+ names=gruik.names
+ if Logs.verbose:
+ Logs.debug('deps: deps for %s: %r; unresolved %r'%(str(node),nodes,names))
+ return(nodes,names)
diff --git a/waflib/Tools/dbus.py b/waflib/Tools/dbus.py
new file mode 100644
index 0000000..9ce00d1
--- /dev/null
+++ b/waflib/Tools/dbus.py
@@ -0,0 +1,29 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib import Task,Errors
+from waflib.TaskGen import taskgen_method,before_method
+@taskgen_method
+def add_dbus_file(self,filename,prefix,mode):
+ if not hasattr(self,'dbus_lst'):
+ self.dbus_lst=[]
+ if not'process_dbus'in self.meths:
+ self.meths.append('process_dbus')
+ self.dbus_lst.append([filename,prefix,mode])
+@before_method('apply_core')
+def process_dbus(self):
+ for filename,prefix,mode in getattr(self,'dbus_lst',[]):
+ node=self.path.find_resource(filename)
+ if not node:
+ raise Errors.WafError('file not found '+filename)
+ tsk=self.create_task('dbus_binding_tool',node,node.change_ext('.h'))
+ tsk.env.DBUS_BINDING_TOOL_PREFIX=prefix
+ tsk.env.DBUS_BINDING_TOOL_MODE=mode
+class dbus_binding_tool(Task.Task):
+ color='BLUE'
+ ext_out=['.h']
+ run_str='${DBUS_BINDING_TOOL} --prefix=${DBUS_BINDING_TOOL_PREFIX} --mode=${DBUS_BINDING_TOOL_MODE} --output=${TGT} ${SRC}'
+ shell=True
+def configure(conf):
+ conf.find_program('dbus-binding-tool',var='DBUS_BINDING_TOOL')
diff --git a/waflib/Tools/dmd.py b/waflib/Tools/dmd.py
new file mode 100644
index 0000000..59aab6d
--- /dev/null
+++ b/waflib/Tools/dmd.py
@@ -0,0 +1,51 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import sys
+from waflib.Tools import ar,d
+from waflib.Configure import conf
+@conf
+def find_dmd(conf):
+ conf.find_program(['dmd','dmd2','ldc'],var='D')
+ out=conf.cmd_and_log(conf.env.D+['--help'])
+ if out.find("D Compiler v")==-1:
+ out=conf.cmd_and_log(conf.env.D+['-version'])
+ if out.find("based on DMD v1.")==-1:
+ conf.fatal("detected compiler is not dmd/ldc")
+@conf
+def common_flags_ldc(conf):
+ v=conf.env
+ v['DFLAGS']=['-d-version=Posix']
+ v['LINKFLAGS']=[]
+ v['DFLAGS_dshlib']=['-relocation-model=pic']
+@conf
+def common_flags_dmd(conf):
+ v=conf.env
+ v['D_SRC_F']=['-c']
+ v['D_TGT_F']='-of%s'
+ v['D_LINKER']=v['D']
+ v['DLNK_SRC_F']=''
+ v['DLNK_TGT_F']='-of%s'
+ v['DINC_ST']='-I%s'
+ v['DSHLIB_MARKER']=v['DSTLIB_MARKER']=''
+ v['DSTLIB_ST']=v['DSHLIB_ST']='-L-l%s'
+ v['DSTLIBPATH_ST']=v['DLIBPATH_ST']='-L-L%s'
+ v['LINKFLAGS_dprogram']=['-quiet']
+ v['DFLAGS_dshlib']=['-fPIC']
+ v['LINKFLAGS_dshlib']=['-L-shared']
+ v['DHEADER_ext']='.di'
+ v.DFLAGS_d_with_header=['-H','-Hf']
+ v['D_HDR_F']='%s'
+def configure(conf):
+ conf.find_dmd()
+ if sys.platform=='win32':
+ out=conf.cmd_and_log(conf.env.D+['--help'])
+ if out.find("D Compiler v2.")>-1:
+ conf.fatal('dmd2 on Windows is not supported, use gdc or ldc2 instead')
+ conf.load('ar')
+ conf.load('d')
+ conf.common_flags_dmd()
+ conf.d_platform_flags()
+ if str(conf.env.D).find('ldc')>-1:
+ conf.common_flags_ldc()
diff --git a/waflib/Tools/errcheck.py b/waflib/Tools/errcheck.py
new file mode 100644
index 0000000..421dfa6
--- /dev/null
+++ b/waflib/Tools/errcheck.py
@@ -0,0 +1,163 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+typos={'feature':'features','sources':'source','targets':'target','include':'includes','export_include':'export_includes','define':'defines','importpath':'includes','installpath':'install_path','iscopy':'is_copy',}
+meths_typos=['__call__','program','shlib','stlib','objects']
+import sys
+from waflib import Logs,Build,Node,Task,TaskGen,ConfigSet,Errors,Utils
+import waflib.Tools.ccroot
+def check_same_targets(self):
+ mp=Utils.defaultdict(list)
+ uids={}
+ def check_task(tsk):
+ if not isinstance(tsk,Task.Task):
+ return
+ for node in tsk.outputs:
+ mp[node].append(tsk)
+ try:
+ uids[tsk.uid()].append(tsk)
+ except KeyError:
+ uids[tsk.uid()]=[tsk]
+ for g in self.groups:
+ for tg in g:
+ try:
+ for tsk in tg.tasks:
+ check_task(tsk)
+ except AttributeError:
+ check_task(tg)
+ dupe=False
+ for(k,v)in mp.items():
+ if len(v)>1:
+ dupe=True
+ 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"")
+ Logs.error(msg)
+ for x in v:
+ if Logs.verbose>1:
+ Logs.error(' %d. %r'%(1+v.index(x),x.generator))
+ else:
+ Logs.error(' %d. %r in %r'%(1+v.index(x),x.generator.name,getattr(x.generator,'path',None)))
+ if not dupe:
+ for(k,v)in uids.items():
+ if len(v)>1:
+ 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')
+ for tsk in v:
+ Logs.error(' - object %r (%r) defined in %r'%(tsk.__class__.__name__,tsk,tsk.generator))
+def check_invalid_constraints(self):
+ feat=set([])
+ for x in list(TaskGen.feats.values()):
+ feat.union(set(x))
+ for(x,y)in TaskGen.task_gen.prec.items():
+ feat.add(x)
+ feat.union(set(y))
+ ext=set([])
+ for x in TaskGen.task_gen.mappings.values():
+ ext.add(x.__name__)
+ invalid=ext&feat
+ if invalid:
+ Logs.error('The methods %r have invalid annotations: @extension <-> @feature/@before_method/@after_method'%list(invalid))
+ for cls in list(Task.classes.values()):
+ if sys.hexversion>0x3000000 and issubclass(cls,Task.Task)and isinstance(cls.hcode,str):
+ raise Errors.WafError('Class %r has hcode value %r of type <str>, expecting <bytes> (use Utils.h_cmd() ?)'%(cls,cls.hcode))
+ for x in('before','after'):
+ for y in Utils.to_list(getattr(cls,x,[])):
+ if not Task.classes.get(y,None):
+ Logs.error('Erroneous order constraint %r=%r on task class %r'%(x,y,cls.__name__))
+ if getattr(cls,'rule',None):
+ Logs.error('Erroneous attribute "rule" on task class %r (rename to "run_str")'%cls.__name__)
+def replace(m):
+ oldcall=getattr(Build.BuildContext,m)
+ def call(self,*k,**kw):
+ ret=oldcall(self,*k,**kw)
+ for x in typos:
+ if x in kw:
+ if x=='iscopy'and'subst'in getattr(self,'features',''):
+ continue
+ Logs.error('Fix the typo %r -> %r on %r'%(x,typos[x],ret))
+ return ret
+ setattr(Build.BuildContext,m,call)
+def enhance_lib():
+ for m in meths_typos:
+ replace(m)
+ def ant_glob(self,*k,**kw):
+ if k:
+ lst=Utils.to_list(k[0])
+ for pat in lst:
+ if'..'in pat.split('/'):
+ Logs.error("In ant_glob pattern %r: '..' means 'two dots', not 'parent directory'"%k[0])
+ if kw.get('remove',True):
+ try:
+ if self.is_child_of(self.ctx.bldnode)and not kw.get('quiet',False):
+ Logs.error('Using ant_glob on the build folder (%r) is dangerous (quiet=True to disable this warning)'%self)
+ except AttributeError:
+ pass
+ return self.old_ant_glob(*k,**kw)
+ Node.Node.old_ant_glob=Node.Node.ant_glob
+ Node.Node.ant_glob=ant_glob
+ old=Task.is_before
+ def is_before(t1,t2):
+ ret=old(t1,t2)
+ if ret and old(t2,t1):
+ Logs.error('Contradictory order constraints in classes %r %r'%(t1,t2))
+ return ret
+ Task.is_before=is_before
+ def check_err_features(self):
+ lst=self.to_list(self.features)
+ if'shlib'in lst:
+ Logs.error('feature shlib -> cshlib, dshlib or cxxshlib')
+ for x in('c','cxx','d','fc'):
+ if not x in lst and lst and lst[0]in[x+y for y in('program','shlib','stlib')]:
+ Logs.error('%r features is probably missing %r'%(self,x))
+ TaskGen.feature('*')(check_err_features)
+ def check_err_order(self):
+ if not hasattr(self,'rule')and not'subst'in Utils.to_list(self.features):
+ for x in('before','after','ext_in','ext_out'):
+ if hasattr(self,x):
+ Logs.warn('Erroneous order constraint %r on non-rule based task generator %r'%(x,self))
+ else:
+ for x in('before','after'):
+ for y in self.to_list(getattr(self,x,[])):
+ if not Task.classes.get(y,None):
+ Logs.error('Erroneous order constraint %s=%r on %r (no such class)'%(x,y,self))
+ TaskGen.feature('*')(check_err_order)
+ def check_compile(self):
+ check_invalid_constraints(self)
+ try:
+ ret=self.orig_compile()
+ finally:
+ check_same_targets(self)
+ return ret
+ Build.BuildContext.orig_compile=Build.BuildContext.compile
+ Build.BuildContext.compile=check_compile
+ def use_rec(self,name,**kw):
+ try:
+ y=self.bld.get_tgen_by_name(name)
+ except Errors.WafError:
+ pass
+ else:
+ idx=self.bld.get_group_idx(self)
+ odx=self.bld.get_group_idx(y)
+ if odx>idx:
+ msg="Invalid 'use' across build groups:"
+ if Logs.verbose>1:
+ msg+='\n target %r\n uses:\n %r'%(self,y)
+ else:
+ msg+=" %r uses %r (try 'waf -v -v' for the full error)"%(self.name,name)
+ raise Errors.WafError(msg)
+ self.orig_use_rec(name,**kw)
+ TaskGen.task_gen.orig_use_rec=TaskGen.task_gen.use_rec
+ TaskGen.task_gen.use_rec=use_rec
+ def getattri(self,name,default=None):
+ if name=='append'or name=='add':
+ raise Errors.WafError('env.append and env.add do not exist: use env.append_value/env.append_unique')
+ elif name=='prepend':
+ raise Errors.WafError('env.prepend does not exist: use env.prepend_value')
+ if name in self.__slots__:
+ return object.__getattr__(self,name,default)
+ else:
+ return self[name]
+ ConfigSet.ConfigSet.__getattr__=getattri
+def options(opt):
+ enhance_lib()
+def configure(conf):
+ pass
diff --git a/waflib/Tools/fc.py b/waflib/Tools/fc.py
new file mode 100644
index 0000000..bc9f0b0
--- /dev/null
+++ b/waflib/Tools/fc.py
@@ -0,0 +1,115 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib import Utils,Task,Logs
+from waflib.Tools import ccroot,fc_config,fc_scan
+from waflib.TaskGen import feature,extension
+from waflib.Configure import conf
+ccroot.USELIB_VARS['fc']=set(['FCFLAGS','DEFINES','INCLUDES'])
+ccroot.USELIB_VARS['fcprogram_test']=ccroot.USELIB_VARS['fcprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
+ccroot.USELIB_VARS['fcshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
+ccroot.USELIB_VARS['fcstlib']=set(['ARFLAGS','LINKDEPS'])
+@feature('fcprogram','fcshlib','fcstlib','fcprogram_test')
+def dummy(self):
+ pass
+@extension('.f','.f90','.F','.F90','.for','.FOR')
+def fc_hook(self,node):
+ return self.create_compiled_task('fc',node)
+@conf
+def modfile(conf,name):
+ return{'lower':name.lower()+'.mod','lower.MOD':name.upper()+'.MOD','UPPER.mod':name.upper()+'.mod','UPPER':name.upper()+'.MOD'}[conf.env.FC_MOD_CAPITALIZATION or'lower']
+def get_fortran_tasks(tsk):
+ bld=tsk.generator.bld
+ tasks=bld.get_tasks_group(bld.get_group_idx(tsk.generator))
+ return[x for x in tasks if isinstance(x,fc)and not getattr(x,'nomod',None)and not getattr(x,'mod_fortran_done',None)]
+class fc(Task.Task):
+ color='GREEN'
+ run_str='${FC} ${FCFLAGS} ${FCINCPATH_ST:INCPATHS} ${FCDEFINES_ST:DEFINES} ${_FCMODOUTFLAGS} ${FC_TGT_F}${TGT[0].abspath()} ${FC_SRC_F}${SRC[0].abspath()}'
+ vars=["FORTRANMODPATHFLAG"]
+ def scan(self):
+ tmp=fc_scan.fortran_parser(self.generator.includes_nodes)
+ tmp.task=self
+ tmp.start(self.inputs[0])
+ if Logs.verbose:
+ Logs.debug('deps: deps for %r: %r; unresolved %r'%(self.inputs,tmp.nodes,tmp.names))
+ return(tmp.nodes,tmp.names)
+ def runnable_status(self):
+ if getattr(self,'mod_fortran_done',None):
+ return super(fc,self).runnable_status()
+ bld=self.generator.bld
+ lst=get_fortran_tasks(self)
+ for tsk in lst:
+ tsk.mod_fortran_done=True
+ for tsk in lst:
+ ret=tsk.runnable_status()
+ if ret==Task.ASK_LATER:
+ for x in lst:
+ x.mod_fortran_done=None
+ return Task.ASK_LATER
+ ins=Utils.defaultdict(set)
+ outs=Utils.defaultdict(set)
+ for tsk in lst:
+ key=tsk.uid()
+ for x in bld.raw_deps[key]:
+ if x.startswith('MOD@'):
+ name=bld.modfile(x.replace('MOD@',''))
+ node=bld.srcnode.find_or_declare(name)
+ if not getattr(node,'sig',None):
+ node.sig=Utils.SIG_NIL
+ tsk.set_outputs(node)
+ outs[id(node)].add(tsk)
+ for tsk in lst:
+ key=tsk.uid()
+ for x in bld.raw_deps[key]:
+ if x.startswith('USE@'):
+ name=bld.modfile(x.replace('USE@',''))
+ node=bld.srcnode.find_resource(name)
+ if node and node not in tsk.outputs:
+ if not node in bld.node_deps[key]:
+ bld.node_deps[key].append(node)
+ ins[id(node)].add(tsk)
+ for k in ins.keys():
+ for a in ins[k]:
+ a.run_after.update(outs[k])
+ tmp=[]
+ for t in outs[k]:
+ tmp.extend(t.outputs)
+ a.dep_nodes.extend(tmp)
+ a.dep_nodes.sort(key=lambda x:x.abspath())
+ for tsk in lst:
+ try:
+ delattr(tsk,'cache_sig')
+ except AttributeError:
+ pass
+ return super(fc,self).runnable_status()
+class fcprogram(ccroot.link_task):
+ color='YELLOW'
+ 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}'
+ inst_to='${BINDIR}'
+class fcshlib(fcprogram):
+ inst_to='${LIBDIR}'
+class fcprogram_test(fcprogram):
+ def runnable_status(self):
+ ret=super(fcprogram_test,self).runnable_status()
+ if ret==Task.SKIP_ME:
+ ret=Task.RUN_ME
+ return ret
+ def exec_command(self,cmd,**kw):
+ bld=self.generator.bld
+ kw['shell']=isinstance(cmd,str)
+ kw['stdout']=kw['stderr']=Utils.subprocess.PIPE
+ kw['cwd']=bld.variant_dir
+ bld.out=bld.err=''
+ bld.to_log('command: %s\n'%cmd)
+ kw['output']=0
+ try:
+ (bld.out,bld.err)=bld.cmd_and_log(cmd,**kw)
+ except Exception:
+ return-1
+ if bld.out:
+ bld.to_log("out: %s\n"%bld.out)
+ if bld.err:
+ bld.to_log("err: %s\n"%bld.err)
+class fcstlib(ccroot.stlink_task):
+ pass
diff --git a/waflib/Tools/fc_config.py b/waflib/Tools/fc_config.py
new file mode 100644
index 0000000..f57ae90
--- /dev/null
+++ b/waflib/Tools/fc_config.py
@@ -0,0 +1,286 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import re,os,sys,shlex
+from waflib.Configure import conf
+from waflib.TaskGen import feature,before_method
+FC_FRAGMENT=' program main\n end program main\n'
+FC_FRAGMENT2=' PROGRAM MAIN\n END\n'
+@conf
+def fc_flags(conf):
+ v=conf.env
+ v['FC_SRC_F']=[]
+ v['FC_TGT_F']=['-c','-o']
+ v['FCINCPATH_ST']='-I%s'
+ v['FCDEFINES_ST']='-D%s'
+ if not v['LINK_FC']:v['LINK_FC']=v['FC']
+ v['FCLNK_SRC_F']=[]
+ v['FCLNK_TGT_F']=['-o']
+ v['FCFLAGS_fcshlib']=['-fpic']
+ v['LINKFLAGS_fcshlib']=['-shared']
+ v['fcshlib_PATTERN']='lib%s.so'
+ v['fcstlib_PATTERN']='lib%s.a'
+ v['FCLIB_ST']='-l%s'
+ v['FCLIBPATH_ST']='-L%s'
+ v['FCSTLIB_ST']='-l%s'
+ v['FCSTLIBPATH_ST']='-L%s'
+ v['FCSTLIB_MARKER']='-Wl,-Bstatic'
+ v['FCSHLIB_MARKER']='-Wl,-Bdynamic'
+ v['SONAME_ST']='-Wl,-h,%s'
+@conf
+def fc_add_flags(conf):
+ conf.add_os_flags('FCFLAGS',dup=False)
+ conf.add_os_flags('LINKFLAGS',dup=False)
+ conf.add_os_flags('LDFLAGS',dup=False)
+@conf
+def check_fortran(self,*k,**kw):
+ self.check_cc(fragment=FC_FRAGMENT,compile_filename='test.f',features='fc fcprogram',msg='Compiling a simple fortran app')
+@conf
+def check_fc(self,*k,**kw):
+ kw['compiler']='fc'
+ if not'compile_mode'in kw:
+ kw['compile_mode']='fc'
+ if not'type'in kw:
+ kw['type']='fcprogram'
+ if not'compile_filename'in kw:
+ kw['compile_filename']='test.f90'
+ if not'code'in kw:
+ kw['code']=FC_FRAGMENT
+ return self.check(*k,**kw)
+@conf
+def fortran_modifier_darwin(conf):
+ v=conf.env
+ v['FCFLAGS_fcshlib']=['-fPIC']
+ v['LINKFLAGS_fcshlib']=['-dynamiclib']
+ v['fcshlib_PATTERN']='lib%s.dylib'
+ v['FRAMEWORKPATH_ST']='-F%s'
+ v['FRAMEWORK_ST']='-framework %s'
+ v['LINKFLAGS_fcstlib']=[]
+ v['FCSHLIB_MARKER']=''
+ v['FCSTLIB_MARKER']=''
+ v['SONAME_ST']=''
+@conf
+def fortran_modifier_win32(conf):
+ v=conf.env
+ v['fcprogram_PATTERN']=v['fcprogram_test_PATTERN']='%s.exe'
+ v['fcshlib_PATTERN']='%s.dll'
+ v['implib_PATTERN']='lib%s.dll.a'
+ v['IMPLIB_ST']='-Wl,--out-implib,%s'
+ v['FCFLAGS_fcshlib']=[]
+ v.append_value('FCFLAGS_fcshlib',['-DDLL_EXPORT'])
+ v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
+@conf
+def fortran_modifier_cygwin(conf):
+ fortran_modifier_win32(conf)
+ v=conf.env
+ v['fcshlib_PATTERN']='cyg%s.dll'
+ v.append_value('LINKFLAGS_fcshlib',['-Wl,--enable-auto-image-base'])
+ v['FCFLAGS_fcshlib']=[]
+@conf
+def check_fortran_dummy_main(self,*k,**kw):
+ if not self.env.CC:
+ self.fatal('A c compiler is required for check_fortran_dummy_main')
+ lst=['MAIN__','__MAIN','_MAIN','MAIN_','MAIN']
+ lst.extend([m.lower()for m in lst])
+ lst.append('')
+ self.start_msg('Detecting whether we need a dummy main')
+ for main in lst:
+ kw['fortran_main']=main
+ try:
+ self.check_cc(fragment='int %s() { return 0; }\n'%(main or'test'),features='c fcprogram',mandatory=True)
+ if not main:
+ self.env.FC_MAIN=-1
+ self.end_msg('no')
+ else:
+ self.env.FC_MAIN=main
+ self.end_msg('yes %s'%main)
+ break
+ except self.errors.ConfigurationError:
+ pass
+ else:
+ self.end_msg('not found')
+ self.fatal('could not detect whether fortran requires a dummy main, see the config.log')
+GCC_DRIVER_LINE=re.compile('^Driving:')
+POSIX_STATIC_EXT=re.compile('\S+\.a')
+POSIX_LIB_FLAGS=re.compile('-l\S+')
+@conf
+def is_link_verbose(self,txt):
+ assert isinstance(txt,str)
+ for line in txt.splitlines():
+ if not GCC_DRIVER_LINE.search(line):
+ if POSIX_STATIC_EXT.search(line)or POSIX_LIB_FLAGS.search(line):
+ return True
+ return False
+@conf
+def check_fortran_verbose_flag(self,*k,**kw):
+ self.start_msg('fortran link verbose flag')
+ for x in('-v','--verbose','-verbose','-V'):
+ try:
+ self.check_cc(features='fc fcprogram_test',fragment=FC_FRAGMENT2,compile_filename='test.f',linkflags=[x],mandatory=True)
+ except self.errors.ConfigurationError:
+ pass
+ else:
+ if self.is_link_verbose(self.test_bld.err)or self.is_link_verbose(self.test_bld.out):
+ self.end_msg(x)
+ break
+ else:
+ self.end_msg('failure')
+ self.fatal('Could not obtain the fortran link verbose flag (see config.log)')
+ self.env.FC_VERBOSE_FLAG=x
+ return x
+LINKFLAGS_IGNORED=[r'-lang*',r'-lcrt[a-zA-Z0-9\.]*\.o',r'-lc$',r'-lSystem',r'-libmil',r'-LIST:*',r'-LNO:*']
+if os.name=='nt':
+ LINKFLAGS_IGNORED.extend([r'-lfrt*',r'-luser32',r'-lkernel32',r'-ladvapi32',r'-lmsvcrt',r'-lshell32',r'-lmingw',r'-lmoldname'])
+else:
+ LINKFLAGS_IGNORED.append(r'-lgcc*')
+RLINKFLAGS_IGNORED=[re.compile(f)for f in LINKFLAGS_IGNORED]
+def _match_ignore(line):
+ for i in RLINKFLAGS_IGNORED:
+ if i.match(line):
+ return True
+ return False
+def parse_fortran_link(lines):
+ final_flags=[]
+ for line in lines:
+ if not GCC_DRIVER_LINE.match(line):
+ _parse_flink_line(line,final_flags)
+ return final_flags
+SPACE_OPTS=re.compile('^-[LRuYz]$')
+NOSPACE_OPTS=re.compile('^-[RL]')
+def _parse_flink_token(lexer,token,tmp_flags):
+ if _match_ignore(token):
+ pass
+ elif token.startswith('-lkernel32')and sys.platform=='cygwin':
+ tmp_flags.append(token)
+ elif SPACE_OPTS.match(token):
+ t=lexer.get_token()
+ if t.startswith('P,'):
+ t=t[2:]
+ for opt in t.split(os.pathsep):
+ tmp_flags.append('-L%s'%opt)
+ elif NOSPACE_OPTS.match(token):
+ tmp_flags.append(token)
+ elif POSIX_LIB_FLAGS.match(token):
+ tmp_flags.append(token)
+ else:
+ pass
+ t=lexer.get_token()
+ return t
+def _parse_flink_line(line,final_flags):
+ lexer=shlex.shlex(line,posix=True)
+ lexer.whitespace_split=True
+ t=lexer.get_token()
+ tmp_flags=[]
+ while t:
+ t=_parse_flink_token(lexer,t,tmp_flags)
+ final_flags.extend(tmp_flags)
+ return final_flags
+@conf
+def check_fortran_clib(self,autoadd=True,*k,**kw):
+ if not self.env.FC_VERBOSE_FLAG:
+ self.fatal('env.FC_VERBOSE_FLAG is not set: execute check_fortran_verbose_flag?')
+ self.start_msg('Getting fortran runtime link flags')
+ try:
+ self.check_cc(fragment=FC_FRAGMENT2,compile_filename='test.f',features='fc fcprogram_test',linkflags=[self.env.FC_VERBOSE_FLAG])
+ except Exception:
+ self.end_msg(False)
+ if kw.get('mandatory',True):
+ conf.fatal('Could not find the c library flags')
+ else:
+ out=self.test_bld.err
+ flags=parse_fortran_link(out.splitlines())
+ self.end_msg('ok (%s)'%' '.join(flags))
+ self.env.LINKFLAGS_CLIB=flags
+ return flags
+ return[]
+def getoutput(conf,cmd,stdin=False):
+ from waflib import Errors
+ if conf.env.env:
+ env=conf.env.env
+ else:
+ env=dict(os.environ)
+ env['LANG']='C'
+ input=stdin and'\n'or None
+ try:
+ out,err=conf.cmd_and_log(cmd,env=env,output=0,input=input)
+ except Errors.WafError ,e:
+ if not(hasattr(e,'stderr')and hasattr(e,'stdout')):
+ raise e
+ else:
+ out=e.stdout
+ err=e.stderr
+ except Exception:
+ conf.fatal('could not determine the compiler version %r'%cmd)
+ return(out,err)
+ROUTINES_CODE="""\
+ subroutine foobar()
+ return
+ end
+ subroutine foo_bar()
+ return
+ end
+"""
+MAIN_CODE="""
+void %(dummy_func_nounder)s(void);
+void %(dummy_func_under)s(void);
+int %(main_func_name)s() {
+ %(dummy_func_nounder)s();
+ %(dummy_func_under)s();
+ return 0;
+}
+"""
+@feature('link_main_routines_func')
+@before_method('process_source')
+def link_main_routines_tg_method(self):
+ def write_test_file(task):
+ task.outputs[0].write(task.generator.code)
+ bld=self.bld
+ bld(rule=write_test_file,target='main.c',code=MAIN_CODE%self.__dict__)
+ bld(rule=write_test_file,target='test.f',code=ROUTINES_CODE)
+ bld(features='fc fcstlib',source='test.f',target='test')
+ bld(features='c fcprogram',source='main.c',target='app',use='test')
+def mangling_schemes():
+ for u in('_',''):
+ for du in('','_'):
+ for c in("lower","upper"):
+ yield(u,du,c)
+def mangle_name(u,du,c,name):
+ return getattr(name,c)()+u+(name.find('_')!=-1 and du or'')
+@conf
+def check_fortran_mangling(self,*k,**kw):
+ if not self.env.CC:
+ self.fatal('A c compiler is required for link_main_routines')
+ if not self.env.FC:
+ self.fatal('A fortran compiler is required for link_main_routines')
+ if not self.env.FC_MAIN:
+ self.fatal('Checking for mangling requires self.env.FC_MAIN (execute "check_fortran_dummy_main" first?)')
+ self.start_msg('Getting fortran mangling scheme')
+ for(u,du,c)in mangling_schemes():
+ try:
+ self.check_cc(compile_filename=[],features='link_main_routines_func',msg='nomsg',errmsg='nomsg',mandatory=True,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)
+ except self.errors.ConfigurationError:
+ pass
+ else:
+ self.end_msg("ok ('%s', '%s', '%s-case')"%(u,du,c))
+ self.env.FORTRAN_MANGLING=(u,du,c)
+ break
+ else:
+ self.end_msg(False)
+ self.fatal('mangler not found')
+ return(u,du,c)
+@feature('pyext')
+@before_method('propagate_uselib_vars','apply_link')
+def set_lib_pat(self):
+ self.env['fcshlib_PATTERN']=self.env['pyext_PATTERN']
+@conf
+def detect_openmp(self):
+ for x in('-fopenmp','-openmp','-mp','-xopenmp','-omp','-qsmp=omp'):
+ try:
+ 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')
+ except self.errors.ConfigurationError:
+ pass
+ else:
+ break
+ else:
+ self.fatal('Could not find OpenMP')
diff --git a/waflib/Tools/fc_scan.py b/waflib/Tools/fc_scan.py
new file mode 100644
index 0000000..c07a22d
--- /dev/null
+++ b/waflib/Tools/fc_scan.py
@@ -0,0 +1,64 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import re
+INC_REGEX="""(?:^|['">]\s*;)\s*(?:|#\s*)INCLUDE\s+(?:\w+_)?[<"'](.+?)(?=["'>])"""
+USE_REGEX="""(?:^|;)\s*USE(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(\w+)"""
+MOD_REGEX="""(?:^|;)\s*MODULE(?!\s*PROCEDURE)(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(\w+)"""
+re_inc=re.compile(INC_REGEX,re.I)
+re_use=re.compile(USE_REGEX,re.I)
+re_mod=re.compile(MOD_REGEX,re.I)
+class fortran_parser(object):
+ def __init__(self,incpaths):
+ self.seen=[]
+ self.nodes=[]
+ self.names=[]
+ self.incpaths=incpaths
+ def find_deps(self,node):
+ txt=node.read()
+ incs=[]
+ uses=[]
+ mods=[]
+ for line in txt.splitlines():
+ m=re_inc.search(line)
+ if m:
+ incs.append(m.group(1))
+ m=re_use.search(line)
+ if m:
+ uses.append(m.group(1))
+ m=re_mod.search(line)
+ if m:
+ mods.append(m.group(1))
+ return(incs,uses,mods)
+ def start(self,node):
+ self.waiting=[node]
+ while self.waiting:
+ nd=self.waiting.pop(0)
+ self.iter(nd)
+ def iter(self,node):
+ incs,uses,mods=self.find_deps(node)
+ for x in incs:
+ if x in self.seen:
+ continue
+ self.seen.append(x)
+ self.tryfind_header(x)
+ for x in uses:
+ name="USE@%s"%x
+ if not name in self.names:
+ self.names.append(name)
+ for x in mods:
+ name="MOD@%s"%x
+ if not name in self.names:
+ self.names.append(name)
+ def tryfind_header(self,filename):
+ found=None
+ for n in self.incpaths:
+ found=n.find_resource(filename)
+ if found:
+ self.nodes.append(found)
+ self.waiting.append(found)
+ break
+ if not found:
+ if not filename in self.names:
+ self.names.append(filename)
diff --git a/waflib/Tools/flex.py b/waflib/Tools/flex.py
new file mode 100644
index 0000000..7a04074
--- /dev/null
+++ b/waflib/Tools/flex.py
@@ -0,0 +1,32 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import waflib.TaskGen,os,re
+def decide_ext(self,node):
+ if'cxx'in self.features:
+ return['.lex.cc']
+ return['.lex.c']
+def flexfun(tsk):
+ env=tsk.env
+ bld=tsk.generator.bld
+ wd=bld.variant_dir
+ def to_list(xx):
+ if isinstance(xx,str):return[xx]
+ return xx
+ tsk.last_cmd=lst=[]
+ lst.extend(to_list(env['FLEX']))
+ lst.extend(to_list(env['FLEXFLAGS']))
+ inputs=[a.path_from(bld.bldnode)for a in tsk.inputs]
+ if env.FLEX_MSYS:
+ inputs=[x.replace(os.sep,'/')for x in inputs]
+ lst.extend(inputs)
+ lst=[x for x in lst if x]
+ txt=bld.cmd_and_log(lst,cwd=wd,env=env.env or None,quiet=0)
+ tsk.outputs[0].write(txt.replace('\r\n','\n').replace('\r','\n'))
+waflib.TaskGen.declare_chain(name='flex',rule=flexfun,ext_in='.l',decider=decide_ext,)
+def configure(conf):
+ conf.find_program('flex',var='FLEX')
+ conf.env.FLEXFLAGS=['-t']
+ if re.search(r"\\msys\\[0-9.]+\\bin\\flex.exe$",conf.env.FLEX[0]):
+ conf.env.FLEX_MSYS=True
diff --git a/waflib/Tools/g95.py b/waflib/Tools/g95.py
new file mode 100644
index 0000000..6524e1c
--- /dev/null
+++ b/waflib/Tools/g95.py
@@ -0,0 +1,54 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils
+from waflib.Tools import fc,fc_config,fc_scan,ar
+from waflib.Configure import conf
+@conf
+def find_g95(conf):
+ fc=conf.find_program('g95',var='FC')
+ conf.get_g95_version(fc)
+ conf.env.FC_NAME='G95'
+@conf
+def g95_flags(conf):
+ v=conf.env
+ v['FCFLAGS_fcshlib']=['-fPIC']
+ v['FORTRANMODFLAG']=['-fmod=','']
+ v['FCFLAGS_DEBUG']=['-Werror']
+@conf
+def g95_modifier_win32(conf):
+ fc_config.fortran_modifier_win32(conf)
+@conf
+def g95_modifier_cygwin(conf):
+ fc_config.fortran_modifier_cygwin(conf)
+@conf
+def g95_modifier_darwin(conf):
+ fc_config.fortran_modifier_darwin(conf)
+@conf
+def g95_modifier_platform(conf):
+ dest_os=conf.env['DEST_OS']or Utils.unversioned_sys_platform()
+ g95_modifier_func=getattr(conf,'g95_modifier_'+dest_os,None)
+ if g95_modifier_func:
+ g95_modifier_func()
+@conf
+def get_g95_version(conf,fc):
+ version_re=re.compile(r"g95\s*(?P<major>\d*)\.(?P<minor>\d*)").search
+ cmd=fc+['--version']
+ out,err=fc_config.getoutput(conf,cmd,stdin=False)
+ if out:
+ match=version_re(out)
+ else:
+ match=version_re(err)
+ if not match:
+ conf.fatal('cannot determine g95 version')
+ k=match.groupdict()
+ conf.env['FC_VERSION']=(k['major'],k['minor'])
+def configure(conf):
+ conf.find_g95()
+ conf.find_ar()
+ conf.fc_flags()
+ conf.fc_add_flags()
+ conf.g95_flags()
+ conf.g95_modifier_platform()
diff --git a/waflib/Tools/gas.py b/waflib/Tools/gas.py
new file mode 100644
index 0000000..4817c23
--- /dev/null
+++ b/waflib/Tools/gas.py
@@ -0,0 +1,12 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import waflib.Tools.asm
+from waflib.Tools import ar
+def configure(conf):
+ conf.find_program(['gas','gcc'],var='AS')
+ conf.env.AS_TGT_F=['-c','-o']
+ conf.env.ASLNK_TGT_F=['-o']
+ conf.find_ar()
+ conf.load('asm')
diff --git a/waflib/Tools/gcc.py b/waflib/Tools/gcc.py
new file mode 100644
index 0000000..a3c7720
--- /dev/null
+++ b/waflib/Tools/gcc.py
@@ -0,0 +1,102 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_gcc(conf):
+ cc=conf.find_program(['gcc','cc'],var='CC')
+ conf.get_cc_version(cc,gcc=True)
+ conf.env.CC_NAME='gcc'
+@conf
+def gcc_common_flags(conf):
+ v=conf.env
+ v['CC_SRC_F']=[]
+ v['CC_TGT_F']=['-c','-o']
+ if not v['LINK_CC']:v['LINK_CC']=v['CC']
+ v['CCLNK_SRC_F']=[]
+ v['CCLNK_TGT_F']=['-o']
+ v['CPPPATH_ST']='-I%s'
+ v['DEFINES_ST']='-D%s'
+ v['LIB_ST']='-l%s'
+ v['LIBPATH_ST']='-L%s'
+ v['STLIB_ST']='-l%s'
+ v['STLIBPATH_ST']='-L%s'
+ v['RPATH_ST']='-Wl,-rpath,%s'
+ v['SONAME_ST']='-Wl,-h,%s'
+ v['SHLIB_MARKER']='-Wl,-Bdynamic'
+ v['STLIB_MARKER']='-Wl,-Bstatic'
+ v['cprogram_PATTERN']='%s'
+ v['CFLAGS_cshlib']=['-fPIC']
+ v['LINKFLAGS_cshlib']=['-shared']
+ v['cshlib_PATTERN']='lib%s.so'
+ v['LINKFLAGS_cstlib']=['-Wl,-Bstatic']
+ v['cstlib_PATTERN']='lib%s.a'
+ v['LINKFLAGS_MACBUNDLE']=['-bundle','-undefined','dynamic_lookup']
+ v['CFLAGS_MACBUNDLE']=['-fPIC']
+ v['macbundle_PATTERN']='%s.bundle'
+@conf
+def gcc_modifier_win32(conf):
+ v=conf.env
+ v['cprogram_PATTERN']='%s.exe'
+ v['cshlib_PATTERN']='%s.dll'
+ v['implib_PATTERN']='lib%s.dll.a'
+ v['IMPLIB_ST']='-Wl,--out-implib,%s'
+ v['CFLAGS_cshlib']=[]
+ v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
+@conf
+def gcc_modifier_cygwin(conf):
+ gcc_modifier_win32(conf)
+ v=conf.env
+ v['cshlib_PATTERN']='cyg%s.dll'
+ v.append_value('LINKFLAGS_cshlib',['-Wl,--enable-auto-image-base'])
+ v['CFLAGS_cshlib']=[]
+@conf
+def gcc_modifier_darwin(conf):
+ v=conf.env
+ v['CFLAGS_cshlib']=['-fPIC']
+ v['LINKFLAGS_cshlib']=['-dynamiclib']
+ v['cshlib_PATTERN']='lib%s.dylib'
+ v['FRAMEWORKPATH_ST']='-F%s'
+ v['FRAMEWORK_ST']=['-framework']
+ v['ARCH_ST']=['-arch']
+ v['LINKFLAGS_cstlib']=[]
+ v['SHLIB_MARKER']=[]
+ v['STLIB_MARKER']=[]
+ v['SONAME_ST']=[]
+@conf
+def gcc_modifier_aix(conf):
+ v=conf.env
+ v['LINKFLAGS_cprogram']=['-Wl,-brtl']
+ v['LINKFLAGS_cshlib']=['-shared','-Wl,-brtl,-bexpfull']
+ v['SHLIB_MARKER']=[]
+@conf
+def gcc_modifier_hpux(conf):
+ v=conf.env
+ v['SHLIB_MARKER']=[]
+ v['STLIB_MARKER']=[]
+ v['CFLAGS_cshlib']=['-fPIC','-DPIC']
+ v['cshlib_PATTERN']='lib%s.sl'
+@conf
+def gcc_modifier_openbsd(conf):
+ conf.env.SONAME_ST=[]
+@conf
+def gcc_modifier_osf1V(conf):
+ v=conf.env
+ v['SHLIB_MARKER']=[]
+ v['STLIB_MARKER']=[]
+ v['SONAME_ST']=[]
+@conf
+def gcc_modifier_platform(conf):
+ gcc_modifier_func=getattr(conf,'gcc_modifier_'+conf.env.DEST_OS,None)
+ if gcc_modifier_func:
+ gcc_modifier_func()
+def configure(conf):
+ conf.find_gcc()
+ conf.find_ar()
+ conf.gcc_common_flags()
+ conf.gcc_modifier_platform()
+ conf.cc_load_tools()
+ conf.cc_add_flags()
+ conf.link_add_flags()
diff --git a/waflib/Tools/gdc.py b/waflib/Tools/gdc.py
new file mode 100644
index 0000000..acfea4a
--- /dev/null
+++ b/waflib/Tools/gdc.py
@@ -0,0 +1,35 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib.Tools import ar,d
+from waflib.Configure import conf
+@conf
+def find_gdc(conf):
+ conf.find_program('gdc',var='D')
+ out=conf.cmd_and_log(conf.env.D+['--version'])
+ if out.find("gdc")==-1:
+ conf.fatal("detected compiler is not gdc")
+@conf
+def common_flags_gdc(conf):
+ v=conf.env
+ v['DFLAGS']=[]
+ v['D_SRC_F']=['-c']
+ v['D_TGT_F']='-o%s'
+ v['D_LINKER']=v['D']
+ v['DLNK_SRC_F']=''
+ v['DLNK_TGT_F']='-o%s'
+ v['DINC_ST']='-I%s'
+ v['DSHLIB_MARKER']=v['DSTLIB_MARKER']=''
+ v['DSTLIB_ST']=v['DSHLIB_ST']='-l%s'
+ v['DSTLIBPATH_ST']=v['DLIBPATH_ST']='-L%s'
+ v['LINKFLAGS_dshlib']=['-shared']
+ v['DHEADER_ext']='.di'
+ v.DFLAGS_d_with_header='-fintfc'
+ v['D_HDR_F']='-fintfc-file=%s'
+def configure(conf):
+ conf.find_gdc()
+ conf.load('ar')
+ conf.load('d')
+ conf.common_flags_gdc()
+ conf.d_platform_flags()
diff --git a/waflib/Tools/gfortran.py b/waflib/Tools/gfortran.py
new file mode 100644
index 0000000..a0ea00b
--- /dev/null
+++ b/waflib/Tools/gfortran.py
@@ -0,0 +1,68 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils
+from waflib.Tools import fc,fc_config,fc_scan,ar
+from waflib.Configure import conf
+@conf
+def find_gfortran(conf):
+ fc=conf.find_program(['gfortran','g77'],var='FC')
+ conf.get_gfortran_version(fc)
+ conf.env.FC_NAME='GFORTRAN'
+@conf
+def gfortran_flags(conf):
+ v=conf.env
+ v['FCFLAGS_fcshlib']=['-fPIC']
+ v['FORTRANMODFLAG']=['-J','']
+ v['FCFLAGS_DEBUG']=['-Werror']
+@conf
+def gfortran_modifier_win32(conf):
+ fc_config.fortran_modifier_win32(conf)
+@conf
+def gfortran_modifier_cygwin(conf):
+ fc_config.fortran_modifier_cygwin(conf)
+@conf
+def gfortran_modifier_darwin(conf):
+ fc_config.fortran_modifier_darwin(conf)
+@conf
+def gfortran_modifier_platform(conf):
+ dest_os=conf.env['DEST_OS']or Utils.unversioned_sys_platform()
+ gfortran_modifier_func=getattr(conf,'gfortran_modifier_'+dest_os,None)
+ if gfortran_modifier_func:
+ gfortran_modifier_func()
+@conf
+def get_gfortran_version(conf,fc):
+ version_re=re.compile(r"GNU\s*Fortran",re.I).search
+ cmd=fc+['--version']
+ out,err=fc_config.getoutput(conf,cmd,stdin=False)
+ if out:match=version_re(out)
+ else:match=version_re(err)
+ if not match:
+ conf.fatal('Could not determine the compiler type')
+ cmd=fc+['-dM','-E','-']
+ out,err=fc_config.getoutput(conf,cmd,stdin=True)
+ if out.find('__GNUC__')<0:
+ conf.fatal('Could not determine the compiler type')
+ k={}
+ out=out.splitlines()
+ import shlex
+ for line in out:
+ lst=shlex.split(line)
+ if len(lst)>2:
+ key=lst[1]
+ val=lst[2]
+ k[key]=val
+ def isD(var):
+ return var in k
+ def isT(var):
+ return var in k and k[var]!='0'
+ conf.env['FC_VERSION']=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__'])
+def configure(conf):
+ conf.find_gfortran()
+ conf.find_ar()
+ conf.fc_flags()
+ conf.fc_add_flags()
+ conf.gfortran_flags()
+ conf.gfortran_modifier_platform()
diff --git a/waflib/Tools/glib2.py b/waflib/Tools/glib2.py
new file mode 100644
index 0000000..47ee823
--- /dev/null
+++ b/waflib/Tools/glib2.py
@@ -0,0 +1,234 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os
+from waflib import Context,Task,Utils,Options,Errors,Logs
+from waflib.TaskGen import taskgen_method,before_method,feature,extension
+from waflib.Configure import conf
+@taskgen_method
+def add_marshal_file(self,filename,prefix):
+ if not hasattr(self,'marshal_list'):
+ self.marshal_list=[]
+ self.meths.append('process_marshal')
+ self.marshal_list.append((filename,prefix))
+@before_method('process_source')
+def process_marshal(self):
+ for f,prefix in getattr(self,'marshal_list',[]):
+ node=self.path.find_resource(f)
+ if not node:
+ raise Errors.WafError('file not found %r'%f)
+ h_node=node.change_ext('.h')
+ c_node=node.change_ext('.c')
+ task=self.create_task('glib_genmarshal',node,[h_node,c_node])
+ task.env.GLIB_GENMARSHAL_PREFIX=prefix
+ self.source=self.to_nodes(getattr(self,'source',[]))
+ self.source.append(c_node)
+class glib_genmarshal(Task.Task):
+ def run(self):
+ bld=self.inputs[0].__class__.ctx
+ get=self.env.get_flat
+ cmd1="%s %s --prefix=%s --header > %s"%(get('GLIB_GENMARSHAL'),self.inputs[0].srcpath(),get('GLIB_GENMARSHAL_PREFIX'),self.outputs[0].abspath())
+ ret=bld.exec_command(cmd1)
+ if ret:return ret
+ c='''#include "%s"\n'''%self.outputs[0].name
+ self.outputs[1].write(c)
+ cmd2="%s %s --prefix=%s --body >> %s"%(get('GLIB_GENMARSHAL'),self.inputs[0].srcpath(),get('GLIB_GENMARSHAL_PREFIX'),self.outputs[1].abspath())
+ return bld.exec_command(cmd2)
+ vars=['GLIB_GENMARSHAL_PREFIX','GLIB_GENMARSHAL']
+ color='BLUE'
+ ext_out=['.h']
+@taskgen_method
+def add_enums_from_template(self,source='',target='',template='',comments=''):
+ if not hasattr(self,'enums_list'):
+ self.enums_list=[]
+ self.meths.append('process_enums')
+ 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})
+@taskgen_method
+def add_enums(self,source='',target='',file_head='',file_prod='',file_tail='',enum_prod='',value_head='',value_prod='',value_tail='',comments=''):
+ if not hasattr(self,'enums_list'):
+ self.enums_list=[]
+ self.meths.append('process_enums')
+ 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})
+@before_method('process_source')
+def process_enums(self):
+ for enum in getattr(self,'enums_list',[]):
+ task=self.create_task('glib_mkenums')
+ env=task.env
+ inputs=[]
+ source_list=self.to_list(enum['source'])
+ if not source_list:
+ raise Errors.WafError('missing source '+str(enum))
+ source_list=[self.path.find_resource(k)for k in source_list]
+ inputs+=source_list
+ env['GLIB_MKENUMS_SOURCE']=[k.abspath()for k in source_list]
+ if not enum['target']:
+ raise Errors.WafError('missing target '+str(enum))
+ tgt_node=self.path.find_or_declare(enum['target'])
+ if tgt_node.name.endswith('.c'):
+ self.source.append(tgt_node)
+ env['GLIB_MKENUMS_TARGET']=tgt_node.abspath()
+ options=[]
+ if enum['template']:
+ template_node=self.path.find_resource(enum['template'])
+ options.append('--template %s'%(template_node.abspath()))
+ inputs.append(template_node)
+ params={'file-head':'--fhead','file-prod':'--fprod','file-tail':'--ftail','enum-prod':'--eprod','value-head':'--vhead','value-prod':'--vprod','value-tail':'--vtail','comments':'--comments'}
+ for param,option in params.items():
+ if enum[param]:
+ options.append('%s %r'%(option,enum[param]))
+ env['GLIB_MKENUMS_OPTIONS']=' '.join(options)
+ task.set_inputs(inputs)
+ task.set_outputs(tgt_node)
+class glib_mkenums(Task.Task):
+ run_str='${GLIB_MKENUMS} ${GLIB_MKENUMS_OPTIONS} ${GLIB_MKENUMS_SOURCE} > ${GLIB_MKENUMS_TARGET}'
+ color='PINK'
+ ext_out=['.h']
+@taskgen_method
+def add_settings_schemas(self,filename_list):
+ if not hasattr(self,'settings_schema_files'):
+ self.settings_schema_files=[]
+ if not isinstance(filename_list,list):
+ filename_list=[filename_list]
+ self.settings_schema_files.extend(filename_list)
+@taskgen_method
+def add_settings_enums(self,namespace,filename_list):
+ if hasattr(self,'settings_enum_namespace'):
+ raise Errors.WafError("Tried to add gsettings enums to '%s' more than once"%self.name)
+ self.settings_enum_namespace=namespace
+ if type(filename_list)!='list':
+ filename_list=[filename_list]
+ self.settings_enum_files=filename_list
+@feature('glib2')
+def process_settings(self):
+ enums_tgt_node=[]
+ install_files=[]
+ settings_schema_files=getattr(self,'settings_schema_files',[])
+ if settings_schema_files and not self.env['GLIB_COMPILE_SCHEMAS']:
+ raise Errors.WafError("Unable to process GSettings schemas - glib-compile-schemas was not found during configure")
+ if hasattr(self,'settings_enum_files'):
+ enums_task=self.create_task('glib_mkenums')
+ source_list=self.settings_enum_files
+ source_list=[self.path.find_resource(k)for k in source_list]
+ enums_task.set_inputs(source_list)
+ enums_task.env['GLIB_MKENUMS_SOURCE']=[k.abspath()for k in source_list]
+ target=self.settings_enum_namespace+'.enums.xml'
+ tgt_node=self.path.find_or_declare(target)
+ enums_task.set_outputs(tgt_node)
+ enums_task.env['GLIB_MKENUMS_TARGET']=tgt_node.abspath()
+ enums_tgt_node=[tgt_node]
+ install_files.append(tgt_node)
+ options='--comments "<!-- @comment@ -->" --fhead "<schemalist>" --vhead " <@type@ id=\\"%s.@EnumName@\\">" --vprod " <value nick=\\"@valuenick@\\" value=\\"@valuenum@\\"/>" --vtail " </@type@>" --ftail "</schemalist>" '%(self.settings_enum_namespace)
+ enums_task.env['GLIB_MKENUMS_OPTIONS']=options
+ for schema in settings_schema_files:
+ schema_task=self.create_task('glib_validate_schema')
+ schema_node=self.path.find_resource(schema)
+ if not schema_node:
+ raise Errors.WafError("Cannot find the schema file '%s'"%schema)
+ install_files.append(schema_node)
+ source_list=enums_tgt_node+[schema_node]
+ schema_task.set_inputs(source_list)
+ schema_task.env['GLIB_COMPILE_SCHEMAS_OPTIONS']=[("--schema-file="+k.abspath())for k in source_list]
+ target_node=schema_node.change_ext('.xml.valid')
+ schema_task.set_outputs(target_node)
+ schema_task.env['GLIB_VALIDATE_SCHEMA_OUTPUT']=target_node.abspath()
+ def compile_schemas_callback(bld):
+ if not bld.is_install:return
+ Logs.pprint('YELLOW','Updating GSettings schema cache')
+ command=Utils.subst_vars("${GLIB_COMPILE_SCHEMAS} ${GSETTINGSSCHEMADIR}",bld.env)
+ self.bld.exec_command(command)
+ if self.bld.is_install:
+ if not self.env['GSETTINGSSCHEMADIR']:
+ raise Errors.WafError('GSETTINGSSCHEMADIR not defined (should have been set up automatically during configure)')
+ if install_files:
+ self.bld.install_files(self.env['GSETTINGSSCHEMADIR'],install_files)
+ if not hasattr(self.bld,'_compile_schemas_registered'):
+ self.bld.add_post_fun(compile_schemas_callback)
+ self.bld._compile_schemas_registered=True
+class glib_validate_schema(Task.Task):
+ run_str='rm -f ${GLIB_VALIDATE_SCHEMA_OUTPUT} && ${GLIB_COMPILE_SCHEMAS} --dry-run ${GLIB_COMPILE_SCHEMAS_OPTIONS} && touch ${GLIB_VALIDATE_SCHEMA_OUTPUT}'
+ color='PINK'
+@extension('.gresource.xml')
+def process_gresource_source(self,node):
+ if not self.env['GLIB_COMPILE_RESOURCES']:
+ raise Errors.WafError("Unable to process GResource file - glib-compile-resources was not found during configure")
+ if'gresource'in self.features:
+ return
+ h_node=node.change_ext('_xml.h')
+ c_node=node.change_ext('_xml.c')
+ self.create_task('glib_gresource_source',node,[h_node,c_node])
+ self.source.append(c_node)
+@feature('gresource')
+def process_gresource_bundle(self):
+ for i in self.to_list(self.source):
+ node=self.path.find_resource(i)
+ task=self.create_task('glib_gresource_bundle',node,node.change_ext(''))
+ inst_to=getattr(self,'install_path',None)
+ if inst_to:
+ self.bld.install_files(inst_to,task.outputs)
+class glib_gresource_base(Task.Task):
+ color='BLUE'
+ base_cmd='${GLIB_COMPILE_RESOURCES} --sourcedir=${SRC[0].parent.srcpath()} --sourcedir=${SRC[0].bld_dir()}'
+ def scan(self):
+ bld=self.generator.bld
+ kw={}
+ try:
+ if not kw.get('cwd',None):
+ kw['cwd']=bld.cwd
+ except AttributeError:
+ bld.cwd=kw['cwd']=bld.variant_dir
+ kw['quiet']=Context.BOTH
+ 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)
+ output=bld.cmd_and_log(cmd,**kw)
+ nodes=[]
+ names=[]
+ for dep in output.splitlines():
+ if dep:
+ node=bld.bldnode.find_node(dep)
+ if node:
+ nodes.append(node)
+ else:
+ names.append(dep)
+ return(nodes,names)
+class glib_gresource_source(glib_gresource_base):
+ vars=['GLIB_COMPILE_RESOURCES']
+ fun_h=Task.compile_fun_shell(glib_gresource_base.base_cmd+' --target=${TGT[0].abspath()} --generate-header ${SRC}')
+ fun_c=Task.compile_fun_shell(glib_gresource_base.base_cmd+' --target=${TGT[1].abspath()} --generate-source ${SRC}')
+ ext_out=['.h']
+ def run(self):
+ return self.fun_h[0](self)or self.fun_c[0](self)
+class glib_gresource_bundle(glib_gresource_base):
+ run_str=glib_gresource_base.base_cmd+' --target=${TGT} ${SRC}'
+ shell=True
+@conf
+def find_glib_genmarshal(conf):
+ conf.find_program('glib-genmarshal',var='GLIB_GENMARSHAL')
+@conf
+def find_glib_mkenums(conf):
+ if not conf.env.PERL:
+ conf.find_program('perl',var='PERL')
+ conf.find_program('glib-mkenums',interpreter='PERL',var='GLIB_MKENUMS')
+@conf
+def find_glib_compile_schemas(conf):
+ conf.find_program('glib-compile-schemas',var='GLIB_COMPILE_SCHEMAS')
+ def getstr(varname):
+ return getattr(Options.options,varname,getattr(conf.env,varname,''))
+ gsettingsschemadir=getstr('GSETTINGSSCHEMADIR')
+ if not gsettingsschemadir:
+ datadir=getstr('DATADIR')
+ if not datadir:
+ prefix=conf.env['PREFIX']
+ datadir=os.path.join(prefix,'share')
+ gsettingsschemadir=os.path.join(datadir,'glib-2.0','schemas')
+ conf.env['GSETTINGSSCHEMADIR']=gsettingsschemadir
+@conf
+def find_glib_compile_resources(conf):
+ conf.find_program('glib-compile-resources',var='GLIB_COMPILE_RESOURCES')
+def configure(conf):
+ conf.find_glib_genmarshal()
+ conf.find_glib_mkenums()
+ conf.find_glib_compile_schemas(mandatory=False)
+ conf.find_glib_compile_resources(mandatory=False)
+def options(opt):
+ gr=opt.add_option_group('Installation directories')
+ gr.add_option('--gsettingsschemadir',help='GSettings schema location [DATADIR/glib-2.0/schemas]',default='',dest='GSETTINGSSCHEMADIR')
diff --git a/waflib/Tools/gnu_dirs.py b/waflib/Tools/gnu_dirs.py
new file mode 100644
index 0000000..21a6288
--- /dev/null
+++ b/waflib/Tools/gnu_dirs.py
@@ -0,0 +1,66 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,re
+from waflib import Utils,Options,Context
+gnuopts='''
+bindir, user commands, ${EXEC_PREFIX}/bin
+sbindir, system binaries, ${EXEC_PREFIX}/sbin
+libexecdir, program-specific binaries, ${EXEC_PREFIX}/libexec
+sysconfdir, host-specific configuration, ${PREFIX}/etc
+sharedstatedir, architecture-independent variable data, ${PREFIX}/com
+localstatedir, variable data, ${PREFIX}/var
+libdir, object code libraries, ${EXEC_PREFIX}/lib%s
+includedir, header files, ${PREFIX}/include
+oldincludedir, header files for non-GCC compilers, /usr/include
+datarootdir, architecture-independent data root, ${PREFIX}/share
+datadir, architecture-independent data, ${DATAROOTDIR}
+infodir, GNU "info" documentation, ${DATAROOTDIR}/info
+localedir, locale-dependent data, ${DATAROOTDIR}/locale
+mandir, manual pages, ${DATAROOTDIR}/man
+docdir, documentation root, ${DATAROOTDIR}/doc/${PACKAGE}
+htmldir, HTML documentation, ${DOCDIR}
+dvidir, DVI documentation, ${DOCDIR}
+pdfdir, PDF documentation, ${DOCDIR}
+psdir, PostScript documentation, ${DOCDIR}
+'''%Utils.lib64()
+_options=[x.split(', ')for x in gnuopts.splitlines()if x]
+def configure(conf):
+ def get_param(varname,default):
+ return getattr(Options.options,varname,'')or default
+ env=conf.env
+ env.LIBDIR=env.BINDIR=[]
+ env.EXEC_PREFIX=get_param('EXEC_PREFIX',env.PREFIX)
+ env.PACKAGE=getattr(Context.g_module,'APPNAME',None)or env.PACKAGE
+ complete=False
+ iter=0
+ while not complete and iter<len(_options)+1:
+ iter+=1
+ complete=True
+ for name,help,default in _options:
+ name=name.upper()
+ if not env[name]:
+ try:
+ env[name]=Utils.subst_vars(get_param(name,default).replace('/',os.sep),env)
+ except TypeError:
+ complete=False
+ if not complete:
+ lst=[x for x,_,_ in _options if not env[x.upper()]]
+ raise conf.errors.WafError('Variable substitution failure %r'%lst)
+def options(opt):
+ inst_dir=opt.add_option_group('Installation prefix','By default, "waf install" will put the files in\
+ "/usr/local/bin", "/usr/local/lib" etc. An installation prefix other\
+ than "/usr/local" can be given using "--prefix", for example "--prefix=$HOME"')
+ for k in('--prefix','--destdir'):
+ option=opt.parser.get_option(k)
+ if option:
+ opt.parser.remove_option(k)
+ inst_dir.add_option(option)
+ inst_dir.add_option('--exec-prefix',help='installation prefix for binaries [PREFIX]',default='',dest='EXEC_PREFIX')
+ dirs_options=opt.add_option_group('Installation directories')
+ for name,help,default in _options:
+ option_name='--'+name
+ str_default=default
+ str_help='%s [%s]'%(help,re.sub(r'\$\{([^}]+)\}',r'\1',str_default))
+ dirs_options.add_option(option_name,help=str_help,default='',dest=name.upper())
diff --git a/waflib/Tools/gxx.py b/waflib/Tools/gxx.py
new file mode 100644
index 0000000..332c953
--- /dev/null
+++ b/waflib/Tools/gxx.py
@@ -0,0 +1,102 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_gxx(conf):
+ cxx=conf.find_program(['g++','c++'],var='CXX')
+ conf.get_cc_version(cxx,gcc=True)
+ conf.env.CXX_NAME='gcc'
+@conf
+def gxx_common_flags(conf):
+ v=conf.env
+ v['CXX_SRC_F']=[]
+ v['CXX_TGT_F']=['-c','-o']
+ if not v['LINK_CXX']:v['LINK_CXX']=v['CXX']
+ v['CXXLNK_SRC_F']=[]
+ v['CXXLNK_TGT_F']=['-o']
+ v['CPPPATH_ST']='-I%s'
+ v['DEFINES_ST']='-D%s'
+ v['LIB_ST']='-l%s'
+ v['LIBPATH_ST']='-L%s'
+ v['STLIB_ST']='-l%s'
+ v['STLIBPATH_ST']='-L%s'
+ v['RPATH_ST']='-Wl,-rpath,%s'
+ v['SONAME_ST']='-Wl,-h,%s'
+ v['SHLIB_MARKER']='-Wl,-Bdynamic'
+ v['STLIB_MARKER']='-Wl,-Bstatic'
+ v['cxxprogram_PATTERN']='%s'
+ v['CXXFLAGS_cxxshlib']=['-fPIC']
+ v['LINKFLAGS_cxxshlib']=['-shared']
+ v['cxxshlib_PATTERN']='lib%s.so'
+ v['LINKFLAGS_cxxstlib']=['-Wl,-Bstatic']
+ v['cxxstlib_PATTERN']='lib%s.a'
+ v['LINKFLAGS_MACBUNDLE']=['-bundle','-undefined','dynamic_lookup']
+ v['CXXFLAGS_MACBUNDLE']=['-fPIC']
+ v['macbundle_PATTERN']='%s.bundle'
+@conf
+def gxx_modifier_win32(conf):
+ v=conf.env
+ v['cxxprogram_PATTERN']='%s.exe'
+ v['cxxshlib_PATTERN']='%s.dll'
+ v['implib_PATTERN']='lib%s.dll.a'
+ v['IMPLIB_ST']='-Wl,--out-implib,%s'
+ v['CXXFLAGS_cxxshlib']=[]
+ v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
+@conf
+def gxx_modifier_cygwin(conf):
+ gxx_modifier_win32(conf)
+ v=conf.env
+ v['cxxshlib_PATTERN']='cyg%s.dll'
+ v.append_value('LINKFLAGS_cxxshlib',['-Wl,--enable-auto-image-base'])
+ v['CXXFLAGS_cxxshlib']=[]
+@conf
+def gxx_modifier_darwin(conf):
+ v=conf.env
+ v['CXXFLAGS_cxxshlib']=['-fPIC']
+ v['LINKFLAGS_cxxshlib']=['-dynamiclib']
+ v['cxxshlib_PATTERN']='lib%s.dylib'
+ v['FRAMEWORKPATH_ST']='-F%s'
+ v['FRAMEWORK_ST']=['-framework']
+ v['ARCH_ST']=['-arch']
+ v['LINKFLAGS_cxxstlib']=[]
+ v['SHLIB_MARKER']=[]
+ v['STLIB_MARKER']=[]
+ v['SONAME_ST']=[]
+@conf
+def gxx_modifier_aix(conf):
+ v=conf.env
+ v['LINKFLAGS_cxxprogram']=['-Wl,-brtl']
+ v['LINKFLAGS_cxxshlib']=['-shared','-Wl,-brtl,-bexpfull']
+ v['SHLIB_MARKER']=[]
+@conf
+def gxx_modifier_hpux(conf):
+ v=conf.env
+ v['SHLIB_MARKER']=[]
+ v['STLIB_MARKER']=[]
+ v['CFLAGS_cxxshlib']=['-fPIC','-DPIC']
+ v['cxxshlib_PATTERN']='lib%s.sl'
+@conf
+def gxx_modifier_openbsd(conf):
+ conf.env.SONAME_ST=[]
+@conf
+def gcc_modifier_osf1V(conf):
+ v=conf.env
+ v['SHLIB_MARKER']=[]
+ v['STLIB_MARKER']=[]
+ v['SONAME_ST']=[]
+@conf
+def gxx_modifier_platform(conf):
+ gxx_modifier_func=getattr(conf,'gxx_modifier_'+conf.env.DEST_OS,None)
+ if gxx_modifier_func:
+ gxx_modifier_func()
+def configure(conf):
+ conf.find_gxx()
+ conf.find_ar()
+ conf.gxx_common_flags()
+ conf.gxx_modifier_platform()
+ conf.cxx_load_tools()
+ conf.cxx_add_flags()
+ conf.link_add_flags()
diff --git a/waflib/Tools/icc.py b/waflib/Tools/icc.py
new file mode 100644
index 0000000..9b7aa03
--- /dev/null
+++ b/waflib/Tools/icc.py
@@ -0,0 +1,22 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import sys
+from waflib.Tools import ccroot,ar,gcc
+from waflib.Configure import conf
+@conf
+def find_icc(conf):
+ if sys.platform=='cygwin':
+ conf.fatal('The Intel compiler does not work on Cygwin')
+ cc=conf.find_program(['icc','ICL'],var='CC')
+ conf.get_cc_version(cc,icc=True)
+ conf.env.CC_NAME='icc'
+def configure(conf):
+ conf.find_icc()
+ conf.find_ar()
+ conf.gcc_common_flags()
+ conf.gcc_modifier_platform()
+ conf.cc_load_tools()
+ conf.cc_add_flags()
+ conf.link_add_flags()
diff --git a/waflib/Tools/icpc.py b/waflib/Tools/icpc.py
new file mode 100644
index 0000000..1e9b6cc
--- /dev/null
+++ b/waflib/Tools/icpc.py
@@ -0,0 +1,22 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import sys
+from waflib.Tools import ccroot,ar,gxx
+from waflib.Configure import conf
+@conf
+def find_icpc(conf):
+ if sys.platform=='cygwin':
+ conf.fatal('The Intel compiler does not work on Cygwin')
+ cxx=conf.find_program('icpc',var='CXX')
+ conf.get_cc_version(cxx,icc=True)
+ conf.env.CXX_NAME='icc'
+def configure(conf):
+ conf.find_icpc()
+ conf.find_ar()
+ conf.gxx_common_flags()
+ conf.gxx_modifier_platform()
+ conf.cxx_load_tools()
+ conf.cxx_add_flags()
+ conf.link_add_flags()
diff --git a/waflib/Tools/ifort.py b/waflib/Tools/ifort.py
new file mode 100644
index 0000000..41fa604
--- /dev/null
+++ b/waflib/Tools/ifort.py
@@ -0,0 +1,433 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils
+from waflib.Tools import fc,fc_config,fc_scan,ar
+from waflib.Configure import conf
+@conf
+def find_ifort(conf):
+ fc=conf.find_program('ifort',var='FC')
+ conf.get_ifort_version(fc)
+ conf.env.FC_NAME='IFORT'
+@conf
+def ifort_modifier_win32(self):
+ v=self.env
+ v.IFORT_WIN32=True
+ v.FCSTLIB_MARKER=''
+ v.FCSHLIB_MARKER=''
+ v.FCLIB_ST=v.FCSTLIB_ST='%s.lib'
+ v.FCLIBPATH_ST=v.STLIBPATH_ST='/LIBPATH:%s'
+ v.FCINCPATH_ST='/I%s'
+ v.FCDEFINES_ST='/D%s'
+ v.fcprogram_PATTERN=v.fcprogram_test_PATTERN='%s.exe'
+ v.fcshlib_PATTERN='%s.dll'
+ v.fcstlib_PATTERN=v.implib_PATTERN='%s.lib'
+ v.FCLNK_TGT_F='/out:'
+ v.FC_TGT_F=['/c','/o','']
+ v.FCFLAGS_fcshlib=''
+ v.LINKFLAGS_fcshlib='/DLL'
+ v.AR_TGT_F='/out:'
+ v.IMPLIB_ST='/IMPLIB:%s'
+ v.append_value('LINKFLAGS','/subsystem:console')
+ if v.IFORT_MANIFEST:
+ v.append_value('LINKFLAGS',['/MANIFEST'])
+@conf
+def ifort_modifier_darwin(conf):
+ fc_config.fortran_modifier_darwin(conf)
+@conf
+def ifort_modifier_platform(conf):
+ dest_os=conf.env.DEST_OS or Utils.unversioned_sys_platform()
+ ifort_modifier_func=getattr(conf,'ifort_modifier_'+dest_os,None)
+ if ifort_modifier_func:
+ ifort_modifier_func()
+@conf
+def get_ifort_version(conf,fc):
+ version_re=re.compile(r"\bIntel\b.*\bVersion\s*(?P<major>\d*)\.(?P<minor>\d*)",re.I).search
+ if Utils.is_win32:
+ cmd=fc
+ else:
+ cmd=fc+['-logo']
+ out,err=fc_config.getoutput(conf,cmd,stdin=False)
+ match=version_re(out)or version_re(err)
+ if not match:
+ conf.fatal('cannot determine ifort version.')
+ k=match.groupdict()
+ conf.env['FC_VERSION']=(k['major'],k['minor'])
+def configure(conf):
+ if Utils.is_win32:
+ compiler,version,path,includes,libdirs,arch=conf.detect_ifort(True)
+ v=conf.env
+ v.DEST_CPU=arch
+ v.PATH=path
+ v.INCLUDES=includes
+ v.LIBPATH=libdirs
+ v.MSVC_COMPILER=compiler
+ try:
+ v.MSVC_VERSION=float(version)
+ except Exception:
+ raise
+ v.MSVC_VERSION=float(version[:-3])
+ conf.find_ifort_win32()
+ conf.ifort_modifier_win32()
+ else:
+ conf.find_ifort()
+ conf.find_program('xiar',var='AR')
+ conf.find_ar()
+ conf.fc_flags()
+ conf.fc_add_flags()
+ conf.ifort_modifier_platform()
+import os,sys,re,tempfile
+from waflib import Task,Logs,Options,Errors
+from waflib.Logs import debug,warn
+from waflib.TaskGen import after_method,feature
+from waflib.Configure import conf
+from waflib.Tools import ccroot,ar,winres
+all_ifort_platforms=[('intel64','amd64'),('em64t','amd64'),('ia32','x86'),('Itanium','ia64')]
+@conf
+def gather_ifort_versions(conf,versions):
+ version_pattern=re.compile('^...?.?\....?.?')
+ try:
+ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Compilers\\Fortran')
+ except WindowsError:
+ try:
+ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Compilers\\Fortran')
+ except WindowsError:
+ return
+ index=0
+ while 1:
+ try:
+ version=Utils.winreg.EnumKey(all_versions,index)
+ except WindowsError:
+ break
+ index=index+1
+ if not version_pattern.match(version):
+ continue
+ targets=[]
+ for target,arch in all_ifort_platforms:
+ try:
+ if target=='intel64':targetDir='EM64T_NATIVE'
+ else:targetDir=target
+ Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir)
+ icl_version=Utils.winreg.OpenKey(all_versions,version)
+ path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
+ batch_file=os.path.join(path,'bin','iclvars.bat')
+ if os.path.isfile(batch_file):
+ try:
+ targets.append((target,(arch,get_compiler_env(conf,'intel',version,target,batch_file))))
+ except conf.errors.ConfigurationError:
+ pass
+ except WindowsError:
+ pass
+ for target,arch in all_ifort_platforms:
+ try:
+ icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+target)
+ path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
+ batch_file=os.path.join(path,'bin','iclvars.bat')
+ if os.path.isfile(batch_file):
+ try:
+ targets.append((target,(arch,get_compiler_env(conf,'intel',version,target,batch_file))))
+ except conf.errors.ConfigurationError:
+ pass
+ except WindowsError:
+ continue
+ major=version[0:2]
+ versions.append(('intel '+major,targets))
+def setup_ifort(conf,versions,arch=False):
+ platforms=Utils.to_list(conf.env['MSVC_TARGETS'])or[i for i,j in all_ifort_platforms]
+ desired_versions=conf.env['MSVC_VERSIONS']or[v for v,_ in versions][::-1]
+ versiondict=dict(versions)
+ for version in desired_versions:
+ try:
+ targets=dict(versiondict[version])
+ for target in platforms:
+ try:
+ try:
+ realtarget,(p1,p2,p3)=targets[target]
+ except conf.errors.ConfigurationError:
+ del(targets[target])
+ else:
+ compiler,revision=version.rsplit(' ',1)
+ if arch:
+ return compiler,revision,p1,p2,p3,realtarget
+ else:
+ return compiler,revision,p1,p2,p3
+ except KeyError:
+ continue
+ except KeyError:
+ continue
+ conf.fatal('msvc: Impossible to find a valid architecture for building (in setup_ifort)')
+@conf
+def get_ifort_version_win32(conf,compiler,version,target,vcvars):
+ try:
+ conf.msvc_cnt+=1
+ except AttributeError:
+ conf.msvc_cnt=1
+ batfile=conf.bldnode.make_node('waf-print-msvc-%d.bat'%conf.msvc_cnt)
+ batfile.write("""@echo off
+set INCLUDE=
+set LIB=
+call "%s" %s
+echo PATH=%%PATH%%
+echo INCLUDE=%%INCLUDE%%
+echo LIB=%%LIB%%;%%LIBPATH%%
+"""%(vcvars,target))
+ sout=conf.cmd_and_log(['cmd.exe','/E:on','/V:on','/C',batfile.abspath()])
+ batfile.delete()
+ lines=sout.splitlines()
+ if not lines[0]:
+ lines.pop(0)
+ MSVC_PATH=MSVC_INCDIR=MSVC_LIBDIR=None
+ for line in lines:
+ if line.startswith('PATH='):
+ path=line[5:]
+ MSVC_PATH=path.split(';')
+ elif line.startswith('INCLUDE='):
+ MSVC_INCDIR=[i for i in line[8:].split(';')if i]
+ elif line.startswith('LIB='):
+ MSVC_LIBDIR=[i for i in line[4:].split(';')if i]
+ if None in(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR):
+ conf.fatal('msvc: Could not find a valid architecture for building (get_ifort_version_win32)')
+ env=dict(os.environ)
+ env.update(PATH=path)
+ compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
+ fc=conf.find_program(compiler_name,path_list=MSVC_PATH)
+ if'CL'in env:
+ del(env['CL'])
+ try:
+ try:
+ conf.cmd_and_log(fc+['/help'],env=env)
+ except UnicodeError:
+ st=Utils.ex_stack()
+ if conf.logger:
+ conf.logger.error(st)
+ conf.fatal('msvc: Unicode error - check the code page?')
+ except Exception ,e:
+ debug('msvc: get_ifort_version: %r %r %r -> failure %s'%(compiler,version,target,str(e)))
+ conf.fatal('msvc: cannot run the compiler in get_ifort_version (run with -v to display errors)')
+ else:
+ debug('msvc: get_ifort_version: %r %r %r -> OK',compiler,version,target)
+ finally:
+ conf.env[compiler_name]=''
+ return(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR)
+def get_compiler_env(conf,compiler,version,bat_target,bat,select=None):
+ lazy=getattr(Options.options,'msvc_lazy',True)
+ if conf.env.MSVC_LAZY_AUTODETECT is False:
+ lazy=False
+ def msvc_thunk():
+ vs=conf.get_ifort_version_win32(compiler,version,bat_target,bat)
+ if select:
+ return select(vs)
+ else:
+ return vs
+ return lazytup(msvc_thunk,lazy,([],[],[]))
+class lazytup(object):
+ def __init__(self,fn,lazy=True,default=None):
+ self.fn=fn
+ self.default=default
+ if not lazy:
+ self.evaluate()
+ def __len__(self):
+ self.evaluate()
+ return len(self.value)
+ def __iter__(self):
+ self.evaluate()
+ for i,v in enumerate(self.value):
+ yield v
+ def __getitem__(self,i):
+ self.evaluate()
+ return self.value[i]
+ def __repr__(self):
+ if hasattr(self,'value'):
+ return repr(self.value)
+ elif self.default:
+ return repr(self.default)
+ else:
+ self.evaluate()
+ return repr(self.value)
+ def evaluate(self):
+ if hasattr(self,'value'):
+ return
+ self.value=self.fn()
+@conf
+def get_ifort_versions(conf,eval_and_save=True):
+ if conf.env['IFORT_INSTALLED_VERSIONS']:
+ return conf.env['IFORT_INSTALLED_VERSIONS']
+ lst=[]
+ conf.gather_ifort_versions(lst)
+ if eval_and_save:
+ def checked_target(t):
+ target,(arch,paths)=t
+ try:
+ paths.evaluate()
+ except conf.errors.ConfigurationError:
+ return None
+ else:
+ return t
+ lst=[(version,list(filter(checked_target,targets)))for version,targets in lst]
+ conf.env['IFORT_INSTALLED_VERSIONS']=lst
+ return lst
+@conf
+def detect_ifort(conf,arch=False):
+ versions=get_ifort_versions(conf,False)
+ return setup_ifort(conf,versions,arch)
+def _get_prog_names(conf,compiler):
+ if compiler=='intel':
+ compiler_name='ifort'
+ linker_name='XILINK'
+ lib_name='XILIB'
+ else:
+ compiler_name='CL'
+ linker_name='LINK'
+ lib_name='LIB'
+ return compiler_name,linker_name,lib_name
+@conf
+def find_ifort_win32(conf):
+ v=conf.env
+ path=v['PATH']
+ compiler=v['MSVC_COMPILER']
+ version=v['MSVC_VERSION']
+ compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
+ v.IFORT_MANIFEST=(compiler=='intel'and version>=11)
+ fc=conf.find_program(compiler_name,var='FC',path_list=path)
+ env=dict(conf.environ)
+ if path:env.update(PATH=';'.join(path))
+ if not conf.cmd_and_log(fc+['/nologo','/help'],env=env):
+ conf.fatal('not intel fortran compiler could not be identified')
+ v['FC_NAME']='IFORT'
+ if not v['LINK_FC']:
+ conf.find_program(linker_name,var='LINK_FC',path_list=path,mandatory=True)
+ if not v['AR']:
+ conf.find_program(lib_name,path_list=path,var='AR',mandatory=True)
+ v['ARFLAGS']=['/NOLOGO']
+ if v.IFORT_MANIFEST:
+ conf.find_program('MT',path_list=path,var='MT')
+ v['MTFLAGS']=['/NOLOGO']
+ try:
+ conf.load('winres')
+ except Errors.WafError:
+ warn('Resource compiler not found. Compiling resource file is disabled')
+@after_method('apply_link')
+@feature('fc')
+def apply_flags_ifort(self):
+ if not self.env.IFORT_WIN32 or not getattr(self,'link_task',None):
+ return
+ is_static=isinstance(self.link_task,ccroot.stlink_task)
+ subsystem=getattr(self,'subsystem','')
+ if subsystem:
+ subsystem='/subsystem:%s'%subsystem
+ flags=is_static and'ARFLAGS'or'LINKFLAGS'
+ self.env.append_value(flags,subsystem)
+ if not is_static:
+ for f in self.env.LINKFLAGS:
+ d=f.lower()
+ if d[1:]=='debug':
+ pdbnode=self.link_task.outputs[0].change_ext('.pdb')
+ self.link_task.outputs.append(pdbnode)
+ if getattr(self,'install_task',None):
+ self.pdb_install_task=self.bld.install_files(self.install_task.dest,pdbnode,env=self.env)
+ break
+@feature('fcprogram','fcshlib','fcprogram_test')
+@after_method('apply_link')
+def apply_manifest_ifort(self):
+ if self.env.IFORT_WIN32 and getattr(self,'link_task',None):
+ self.link_task.env.FC=self.env.LINK_FC
+ if self.env.IFORT_WIN32 and self.env.IFORT_MANIFEST and getattr(self,'link_task',None):
+ out_node=self.link_task.outputs[0]
+ man_node=out_node.parent.find_or_declare(out_node.name+'.manifest')
+ self.link_task.outputs.append(man_node)
+ self.link_task.do_manifest=True
+def exec_mf(self):
+ env=self.env
+ mtool=env['MT']
+ if not mtool:
+ return 0
+ self.do_manifest=False
+ outfile=self.outputs[0].abspath()
+ manifest=None
+ for out_node in self.outputs:
+ if out_node.name.endswith('.manifest'):
+ manifest=out_node.abspath()
+ break
+ if manifest is None:
+ return 0
+ mode=''
+ if'fcprogram'in self.generator.features or'fcprogram_test'in self.generator.features:
+ mode='1'
+ elif'fcshlib'in self.generator.features:
+ mode='2'
+ debug('msvc: embedding manifest in mode %r'%mode)
+ lst=[]+mtool
+ lst.extend(Utils.to_list(env['MTFLAGS']))
+ lst.extend(['-manifest',manifest])
+ lst.append('-outputresource:%s;%s'%(outfile,mode))
+ return self.exec_command(lst)
+def quote_response_command(self,flag):
+ if flag.find(' ')>-1:
+ for x in('/LIBPATH:','/IMPLIB:','/OUT:','/I'):
+ if flag.startswith(x):
+ flag='%s"%s"'%(x,flag[len(x):])
+ break
+ else:
+ flag='"%s"'%flag
+ return flag
+def exec_response_command(self,cmd,**kw):
+ try:
+ tmp=None
+ if sys.platform.startswith('win')and isinstance(cmd,list)and len(' '.join(cmd))>=8192:
+ program=cmd[0]
+ cmd=[self.quote_response_command(x)for x in cmd]
+ (fd,tmp)=tempfile.mkstemp()
+ os.write(fd,'\r\n'.join(i.replace('\\','\\\\')for i in cmd[1:]))
+ os.close(fd)
+ cmd=[program,'@'+tmp]
+ ret=super(self.__class__,self).exec_command(cmd,**kw)
+ finally:
+ if tmp:
+ try:
+ os.remove(tmp)
+ except OSError:
+ pass
+ return ret
+def exec_command_ifort(self,*k,**kw):
+ if isinstance(k[0],list):
+ lst=[]
+ carry=''
+ for a in k[0]:
+ if a=='/Fo'or a=='/doc'or a[-1]==':':
+ carry=a
+ else:
+ lst.append(carry+a)
+ carry=''
+ k=[lst]
+ if self.env['PATH']:
+ env=dict(self.env.env or os.environ)
+ env.update(PATH=';'.join(self.env['PATH']))
+ kw['env']=env
+ if not'cwd'in kw:
+ kw['cwd']=self.generator.bld.variant_dir
+ ret=self.exec_response_command(k[0],**kw)
+ if not ret and getattr(self,'do_manifest',None):
+ ret=self.exec_mf()
+ return ret
+def wrap_class(class_name):
+ cls=Task.classes.get(class_name,None)
+ if not cls:
+ return None
+ derived_class=type(class_name,(cls,),{})
+ def exec_command(self,*k,**kw):
+ if self.env.IFORT_WIN32:
+ return self.exec_command_ifort(*k,**kw)
+ else:
+ return super(derived_class,self).exec_command(*k,**kw)
+ derived_class.exec_command=exec_command
+ derived_class.exec_response_command=exec_response_command
+ derived_class.quote_response_command=quote_response_command
+ derived_class.exec_command_ifort=exec_command_ifort
+ derived_class.exec_mf=exec_mf
+ if hasattr(cls,'hcode'):
+ derived_class.hcode=cls.hcode
+ return derived_class
+for k in'fc fcprogram fcprogram_test fcshlib fcstlib'.split():
+ wrap_class(k)
diff --git a/waflib/Tools/intltool.py b/waflib/Tools/intltool.py
new file mode 100644
index 0000000..c751e26
--- /dev/null
+++ b/waflib/Tools/intltool.py
@@ -0,0 +1,97 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,re
+from waflib import Context,Task,Utils,Logs
+import waflib.Tools.ccroot
+from waflib.TaskGen import feature,before_method,taskgen_method
+from waflib.Logs import error
+from waflib.Configure import conf
+_style_flags={'ba':'-b','desktop':'-d','keys':'-k','quoted':'--quoted-style','quotedxml':'--quotedxml-style','rfc822deb':'-r','schemas':'-s','xml':'-x',}
+@taskgen_method
+def ensure_localedir(self):
+ if not self.env.LOCALEDIR:
+ if self.env.DATAROOTDIR:
+ self.env.LOCALEDIR=os.path.join(self.env.DATAROOTDIR,'locale')
+ else:
+ self.env.LOCALEDIR=os.path.join(self.env.PREFIX,'share','locale')
+@before_method('process_source')
+@feature('intltool_in')
+def apply_intltool_in_f(self):
+ try:self.meths.remove('process_source')
+ except ValueError:pass
+ self.ensure_localedir()
+ podir=getattr(self,'podir','.')
+ podirnode=self.path.find_dir(podir)
+ if not podirnode:
+ error("could not find the podir %r"%podir)
+ return
+ cache=getattr(self,'intlcache','.intlcache')
+ self.env.INTLCACHE=[os.path.join(str(self.path.get_bld()),podir,cache)]
+ self.env.INTLPODIR=podirnode.bldpath()
+ self.env.append_value('INTLFLAGS',getattr(self,'flags',self.env.INTLFLAGS_DEFAULT))
+ if'-c'in self.env.INTLFLAGS:
+ self.bld.fatal('Redundant -c flag in intltool task %r'%self)
+ style=getattr(self,'style',None)
+ if style:
+ try:
+ style_flag=_style_flags[style]
+ except KeyError:
+ self.bld.fatal('intltool_in style "%s" is not valid'%style)
+ self.env.append_unique('INTLFLAGS',[style_flag])
+ for i in self.to_list(self.source):
+ node=self.path.find_resource(i)
+ task=self.create_task('intltool',node,node.change_ext(''))
+ inst=getattr(self,'install_path',None)
+ if inst:
+ self.bld.install_files(inst,task.outputs)
+@feature('intltool_po')
+def apply_intltool_po(self):
+ try:self.meths.remove('process_source')
+ except ValueError:pass
+ self.ensure_localedir()
+ appname=getattr(self,'appname',getattr(Context.g_module,Context.APPNAME,'set_your_app_name'))
+ podir=getattr(self,'podir','.')
+ inst=getattr(self,'install_path','${LOCALEDIR}')
+ linguas=self.path.find_node(os.path.join(podir,'LINGUAS'))
+ if linguas:
+ file=open(linguas.abspath())
+ langs=[]
+ for line in file.readlines():
+ if not line.startswith('#'):
+ langs+=line.split()
+ file.close()
+ re_linguas=re.compile('[-a-zA-Z_@.]+')
+ for lang in langs:
+ if re_linguas.match(lang):
+ node=self.path.find_resource(os.path.join(podir,re_linguas.match(lang).group()+'.po'))
+ task=self.create_task('po',node,node.change_ext('.mo'))
+ if inst:
+ filename=task.outputs[0].name
+ (langname,ext)=os.path.splitext(filename)
+ inst_file=inst+os.sep+langname+os.sep+'LC_MESSAGES'+os.sep+appname+'.mo'
+ self.bld.install_as(inst_file,task.outputs[0],chmod=getattr(self,'chmod',Utils.O644),env=task.env)
+ else:
+ Logs.pprint('RED',"Error no LINGUAS file found in po directory")
+class po(Task.Task):
+ run_str='${MSGFMT} -o ${TGT} ${SRC}'
+ color='BLUE'
+class intltool(Task.Task):
+ run_str='${INTLTOOL} ${INTLFLAGS} ${INTLCACHE_ST:INTLCACHE} ${INTLPODIR} ${SRC} ${TGT}'
+ color='BLUE'
+@conf
+def find_msgfmt(conf):
+ conf.find_program('msgfmt',var='MSGFMT')
+@conf
+def find_intltool_merge(conf):
+ if not conf.env.PERL:
+ conf.find_program('perl',var='PERL')
+ conf.env.INTLCACHE_ST='--cache=%s'
+ conf.env.INTLFLAGS_DEFAULT=['-q','-u']
+ conf.find_program('intltool-merge',interpreter='PERL',var='INTLTOOL')
+def configure(conf):
+ conf.find_msgfmt()
+ conf.find_intltool_merge()
+ if conf.env.CC or conf.env.CXX:
+ conf.check(header_name='locale.h')
diff --git a/waflib/Tools/irixcc.py b/waflib/Tools/irixcc.py
new file mode 100644
index 0000000..74a36cf
--- /dev/null
+++ b/waflib/Tools/irixcc.py
@@ -0,0 +1,45 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_irixcc(conf):
+ v=conf.env
+ cc=None
+ if v['CC']:cc=v['CC']
+ elif'CC'in conf.environ:cc=conf.environ['CC']
+ if not cc:cc=conf.find_program('cc',var='CC')
+ if not cc:conf.fatal('irixcc was not found')
+ try:
+ conf.cmd_and_log(cc+['-version'])
+ except Exception:
+ conf.fatal('%r -version could not be executed'%cc)
+ v['CC']=cc
+ v['CC_NAME']='irix'
+@conf
+def irixcc_common_flags(conf):
+ v=conf.env
+ v['CC_SRC_F']=''
+ v['CC_TGT_F']=['-c','-o']
+ v['CPPPATH_ST']='-I%s'
+ v['DEFINES_ST']='-D%s'
+ if not v['LINK_CC']:v['LINK_CC']=v['CC']
+ v['CCLNK_SRC_F']=''
+ v['CCLNK_TGT_F']=['-o']
+ v['LIB_ST']='-l%s'
+ v['LIBPATH_ST']='-L%s'
+ v['STLIB_ST']='-l%s'
+ v['STLIBPATH_ST']='-L%s'
+ v['cprogram_PATTERN']='%s'
+ v['cshlib_PATTERN']='lib%s.so'
+ v['cstlib_PATTERN']='lib%s.a'
+def configure(conf):
+ conf.find_irixcc()
+ conf.find_cpp()
+ conf.find_ar()
+ conf.irixcc_common_flags()
+ conf.cc_load_tools()
+ conf.cc_add_flags()
+ conf.link_add_flags()
diff --git a/waflib/Tools/javaw.py b/waflib/Tools/javaw.py
new file mode 100644
index 0000000..ae2a673
--- /dev/null
+++ b/waflib/Tools/javaw.py
@@ -0,0 +1,305 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,tempfile,shutil
+from waflib import Task,Utils,Errors,Node,Logs
+from waflib.Configure import conf
+from waflib.TaskGen import feature,before_method,after_method
+from waflib.Tools import ccroot
+ccroot.USELIB_VARS['javac']=set(['CLASSPATH','JAVACFLAGS'])
+SOURCE_RE='**/*.java'
+JAR_RE='**/*'
+class_check_source='''
+public class Test {
+ public static void main(String[] argv) {
+ Class lib;
+ if (argv.length < 1) {
+ System.err.println("Missing argument");
+ System.exit(77);
+ }
+ try {
+ lib = Class.forName(argv[0]);
+ } catch (ClassNotFoundException e) {
+ System.err.println("ClassNotFoundException");
+ System.exit(1);
+ }
+ lib = null;
+ System.exit(0);
+ }
+}
+'''
+@feature('javac')
+@before_method('process_source')
+def apply_java(self):
+ Utils.def_attrs(self,jarname='',classpath='',sourcepath='.',srcdir='.',jar_mf_attributes={},jar_mf_classpath=[])
+ outdir=getattr(self,'outdir',None)
+ if outdir:
+ if not isinstance(outdir,Node.Node):
+ outdir=self.path.get_bld().make_node(self.outdir)
+ else:
+ outdir=self.path.get_bld()
+ outdir.mkdir()
+ self.outdir=outdir
+ self.env['OUTDIR']=outdir.abspath()
+ self.javac_task=tsk=self.create_task('javac')
+ tmp=[]
+ srcdir=getattr(self,'srcdir','')
+ if isinstance(srcdir,Node.Node):
+ srcdir=[srcdir]
+ for x in Utils.to_list(srcdir):
+ if isinstance(x,Node.Node):
+ y=x
+ else:
+ y=self.path.find_dir(x)
+ if not y:
+ self.bld.fatal('Could not find the folder %s from %s'%(x,self.path))
+ tmp.append(y)
+ tsk.srcdir=tmp
+ if getattr(self,'compat',None):
+ tsk.env.append_value('JAVACFLAGS',['-source',self.compat])
+ if hasattr(self,'sourcepath'):
+ fold=[isinstance(x,Node.Node)and x or self.path.find_dir(x)for x in self.to_list(self.sourcepath)]
+ names=os.pathsep.join([x.srcpath()for x in fold])
+ else:
+ names=[x.srcpath()for x in tsk.srcdir]
+ if names:
+ tsk.env.append_value('JAVACFLAGS',['-sourcepath',names])
+@feature('javac')
+@after_method('apply_java')
+def use_javac_files(self):
+ lst=[]
+ self.uselib=self.to_list(getattr(self,'uselib',[]))
+ names=self.to_list(getattr(self,'use',[]))
+ get=self.bld.get_tgen_by_name
+ for x in names:
+ try:
+ y=get(x)
+ except Exception:
+ self.uselib.append(x)
+ else:
+ y.post()
+ lst.append(y.jar_task.outputs[0].abspath())
+ self.javac_task.set_run_after(y.jar_task)
+ if lst:
+ self.env.append_value('CLASSPATH',lst)
+@feature('javac')
+@after_method('apply_java','propagate_uselib_vars','use_javac_files')
+def set_classpath(self):
+ self.env.append_value('CLASSPATH',getattr(self,'classpath',[]))
+ for x in self.tasks:
+ x.env.CLASSPATH=os.pathsep.join(self.env.CLASSPATH)+os.pathsep
+@feature('jar')
+@after_method('apply_java','use_javac_files')
+@before_method('process_source')
+def jar_files(self):
+ destfile=getattr(self,'destfile','test.jar')
+ jaropts=getattr(self,'jaropts',[])
+ manifest=getattr(self,'manifest',None)
+ basedir=getattr(self,'basedir',None)
+ if basedir:
+ if not isinstance(self.basedir,Node.Node):
+ basedir=self.path.get_bld().make_node(basedir)
+ else:
+ basedir=self.path.get_bld()
+ if not basedir:
+ self.bld.fatal('Could not find the basedir %r for %r'%(self.basedir,self))
+ self.jar_task=tsk=self.create_task('jar_create')
+ if manifest:
+ jarcreate=getattr(self,'jarcreate','cfm')
+ node=self.path.find_node(manifest)
+ tsk.dep_nodes.append(node)
+ jaropts.insert(0,node.abspath())
+ else:
+ jarcreate=getattr(self,'jarcreate','cf')
+ if not isinstance(destfile,Node.Node):
+ destfile=self.path.find_or_declare(destfile)
+ if not destfile:
+ self.bld.fatal('invalid destfile %r for %r'%(destfile,self))
+ tsk.set_outputs(destfile)
+ tsk.basedir=basedir
+ jaropts.append('-C')
+ jaropts.append(basedir.bldpath())
+ jaropts.append('.')
+ tsk.env['JAROPTS']=jaropts
+ tsk.env['JARCREATE']=jarcreate
+ if getattr(self,'javac_task',None):
+ tsk.set_run_after(self.javac_task)
+@feature('jar')
+@after_method('jar_files')
+def use_jar_files(self):
+ self.uselib=self.to_list(getattr(self,'uselib',[]))
+ names=self.to_list(getattr(self,'use',[]))
+ get=self.bld.get_tgen_by_name
+ for x in names:
+ try:
+ y=get(x)
+ except Exception:
+ self.uselib.append(x)
+ else:
+ y.post()
+ self.jar_task.run_after.update(y.tasks)
+class jar_create(Task.Task):
+ color='GREEN'
+ run_str='${JAR} ${JARCREATE} ${TGT} ${JAROPTS}'
+ def runnable_status(self):
+ for t in self.run_after:
+ if not t.hasrun:
+ return Task.ASK_LATER
+ if not self.inputs:
+ global JAR_RE
+ try:
+ self.inputs=[x for x in self.basedir.ant_glob(JAR_RE,remove=False)if id(x)!=id(self.outputs[0])]
+ except Exception:
+ raise Errors.WafError('Could not find the basedir %r for %r'%(self.basedir,self))
+ return super(jar_create,self).runnable_status()
+class javac(Task.Task):
+ color='BLUE'
+ vars=['CLASSPATH','JAVACFLAGS','JAVAC','OUTDIR']
+ def runnable_status(self):
+ for t in self.run_after:
+ if not t.hasrun:
+ return Task.ASK_LATER
+ if not self.inputs:
+ global SOURCE_RE
+ self.inputs=[]
+ for x in self.srcdir:
+ self.inputs.extend(x.ant_glob(SOURCE_RE,remove=False))
+ return super(javac,self).runnable_status()
+ def run(self):
+ env=self.env
+ gen=self.generator
+ bld=gen.bld
+ wd=bld.bldnode.abspath()
+ def to_list(xx):
+ if isinstance(xx,str):return[xx]
+ return xx
+ cmd=[]
+ cmd.extend(to_list(env['JAVAC']))
+ cmd.extend(['-classpath'])
+ cmd.extend(to_list(env['CLASSPATH']))
+ cmd.extend(['-d'])
+ cmd.extend(to_list(env['OUTDIR']))
+ cmd.extend(to_list(env['JAVACFLAGS']))
+ files=[a.path_from(bld.bldnode)for a in self.inputs]
+ tmp=None
+ try:
+ if len(str(files))+len(str(cmd))>8192:
+ (fd,tmp)=tempfile.mkstemp(dir=bld.bldnode.abspath())
+ try:
+ os.write(fd,'\n'.join(files))
+ finally:
+ if tmp:
+ os.close(fd)
+ if Logs.verbose:
+ Logs.debug('runner: %r'%(cmd+files))
+ cmd.append('@'+tmp)
+ else:
+ cmd+=files
+ ret=self.exec_command(cmd,cwd=wd,env=env.env or None)
+ finally:
+ if tmp:
+ os.remove(tmp)
+ return ret
+ def post_run(self):
+ for n in self.generator.outdir.ant_glob('**/*.class'):
+ n.sig=Utils.h_file(n.abspath())
+ self.generator.bld.task_sigs[self.uid()]=self.cache_sig
+@feature('javadoc')
+@after_method('process_rule')
+def create_javadoc(self):
+ tsk=self.create_task('javadoc')
+ tsk.classpath=getattr(self,'classpath',[])
+ self.javadoc_package=Utils.to_list(self.javadoc_package)
+ if not isinstance(self.javadoc_output,Node.Node):
+ self.javadoc_output=self.bld.path.find_or_declare(self.javadoc_output)
+class javadoc(Task.Task):
+ color='BLUE'
+ def __str__(self):
+ return'%s: %s -> %s\n'%(self.__class__.__name__,self.generator.srcdir,self.generator.javadoc_output)
+ def run(self):
+ env=self.env
+ bld=self.generator.bld
+ wd=bld.bldnode.abspath()
+ srcpath=self.generator.path.abspath()+os.sep+self.generator.srcdir
+ srcpath+=os.pathsep
+ srcpath+=self.generator.path.get_bld().abspath()+os.sep+self.generator.srcdir
+ classpath=env.CLASSPATH
+ classpath+=os.pathsep
+ classpath+=os.pathsep.join(self.classpath)
+ classpath="".join(classpath)
+ self.last_cmd=lst=[]
+ lst.extend(Utils.to_list(env['JAVADOC']))
+ lst.extend(['-d',self.generator.javadoc_output.abspath()])
+ lst.extend(['-sourcepath',srcpath])
+ lst.extend(['-classpath',classpath])
+ lst.extend(['-subpackages'])
+ lst.extend(self.generator.javadoc_package)
+ lst=[x for x in lst if x]
+ self.generator.bld.cmd_and_log(lst,cwd=wd,env=env.env or None,quiet=0)
+ def post_run(self):
+ nodes=self.generator.javadoc_output.ant_glob('**')
+ for x in nodes:
+ x.sig=Utils.h_file(x.abspath())
+ self.generator.bld.task_sigs[self.uid()]=self.cache_sig
+def configure(self):
+ java_path=self.environ['PATH'].split(os.pathsep)
+ v=self.env
+ if'JAVA_HOME'in self.environ:
+ java_path=[os.path.join(self.environ['JAVA_HOME'],'bin')]+java_path
+ self.env['JAVA_HOME']=[self.environ['JAVA_HOME']]
+ for x in'javac java jar javadoc'.split():
+ self.find_program(x,var=x.upper(),path_list=java_path)
+ if'CLASSPATH'in self.environ:
+ v['CLASSPATH']=self.environ['CLASSPATH']
+ if not v['JAR']:self.fatal('jar is required for making java packages')
+ if not v['JAVAC']:self.fatal('javac is required for compiling java classes')
+ v['JARCREATE']='cf'
+ v['JAVACFLAGS']=[]
+@conf
+def check_java_class(self,classname,with_classpath=None):
+ javatestdir='.waf-javatest'
+ classpath=javatestdir
+ if self.env['CLASSPATH']:
+ classpath+=os.pathsep+self.env['CLASSPATH']
+ if isinstance(with_classpath,str):
+ classpath+=os.pathsep+with_classpath
+ shutil.rmtree(javatestdir,True)
+ os.mkdir(javatestdir)
+ Utils.writef(os.path.join(javatestdir,'Test.java'),class_check_source)
+ self.exec_command(self.env['JAVAC']+[os.path.join(javatestdir,'Test.java')],shell=False)
+ cmd=self.env['JAVA']+['-cp',classpath,'Test',classname]
+ self.to_log("%s\n"%str(cmd))
+ found=self.exec_command(cmd,shell=False)
+ self.msg('Checking for java class %s'%classname,not found)
+ shutil.rmtree(javatestdir,True)
+ return found
+@conf
+def check_jni_headers(conf):
+ if not conf.env.CC_NAME and not conf.env.CXX_NAME:
+ conf.fatal('load a compiler first (gcc, g++, ..)')
+ if not conf.env.JAVA_HOME:
+ conf.fatal('set JAVA_HOME in the system environment')
+ javaHome=conf.env['JAVA_HOME'][0]
+ dir=conf.root.find_dir(conf.env.JAVA_HOME[0]+'/include')
+ if dir is None:
+ dir=conf.root.find_dir(conf.env.JAVA_HOME[0]+'/../Headers')
+ if dir is None:
+ conf.fatal('JAVA_HOME does not seem to be set properly')
+ f=dir.ant_glob('**/(jni|jni_md).h')
+ incDirs=[x.parent.abspath()for x in f]
+ dir=conf.root.find_dir(conf.env.JAVA_HOME[0])
+ f=dir.ant_glob('**/*jvm.(so|dll|dylib)')
+ libDirs=[x.parent.abspath()for x in f]or[javaHome]
+ f=dir.ant_glob('**/*jvm.(lib)')
+ if f:
+ libDirs=[[x,y.parent.abspath()]for x in libDirs for y in f]
+ for d in libDirs:
+ try:
+ conf.check(header_name='jni.h',define_name='HAVE_JNI_H',lib='jvm',libpath=d,includes=incDirs,uselib_store='JAVA',uselib='JAVA')
+ except Exception:
+ pass
+ else:
+ break
+ else:
+ conf.fatal('could not find lib jvm in %r (see config.log)'%libDirs)
diff --git a/waflib/Tools/kde4.py b/waflib/Tools/kde4.py
new file mode 100644
index 0000000..3e90377
--- /dev/null
+++ b/waflib/Tools/kde4.py
@@ -0,0 +1,48 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,re
+from waflib import Task,Utils
+from waflib.TaskGen import feature
+@feature('msgfmt')
+def apply_msgfmt(self):
+ for lang in self.to_list(self.langs):
+ node=self.path.find_resource(lang+'.po')
+ task=self.create_task('msgfmt',node,node.change_ext('.mo'))
+ langname=lang.split('/')
+ langname=langname[-1]
+ inst=getattr(self,'install_path','${KDE4_LOCALE_INSTALL_DIR}')
+ self.bld.install_as(inst+os.sep+langname+os.sep+'LC_MESSAGES'+os.sep+getattr(self,'appname','set_your_appname')+'.mo',task.outputs[0],chmod=getattr(self,'chmod',Utils.O644))
+class msgfmt(Task.Task):
+ color='BLUE'
+ run_str='${MSGFMT} ${SRC} -o ${TGT}'
+def configure(self):
+ kdeconfig=self.find_program('kde4-config')
+ prefix=self.cmd_and_log(kdeconfig+['--prefix']).strip()
+ fname='%s/share/apps/cmake/modules/KDELibsDependencies.cmake'%prefix
+ try:os.stat(fname)
+ except OSError:
+ fname='%s/share/kde4/apps/cmake/modules/KDELibsDependencies.cmake'%prefix
+ try:os.stat(fname)
+ except OSError:self.fatal('could not open %s'%fname)
+ try:
+ txt=Utils.readf(fname)
+ except EnvironmentError:
+ self.fatal('could not read %s'%fname)
+ txt=txt.replace('\\\n','\n')
+ fu=re.compile('#(.*)\n')
+ txt=fu.sub('',txt)
+ setregexp=re.compile('([sS][eE][tT]\s*\()\s*([^\s]+)\s+\"([^"]+)\"\)')
+ found=setregexp.findall(txt)
+ for(_,key,val)in found:
+ self.env[key]=val
+ self.env['LIB_KDECORE']=['kdecore']
+ self.env['LIB_KDEUI']=['kdeui']
+ self.env['LIB_KIO']=['kio']
+ self.env['LIB_KHTML']=['khtml']
+ self.env['LIB_KPARTS']=['kparts']
+ self.env['LIBPATH_KDECORE']=[os.path.join(self.env.KDE4_LIB_INSTALL_DIR,'kde4','devel'),self.env.KDE4_LIB_INSTALL_DIR]
+ self.env['INCLUDES_KDECORE']=[self.env['KDE4_INCLUDE_INSTALL_DIR']]
+ self.env.append_value('INCLUDES_KDECORE',[self.env['KDE4_INCLUDE_INSTALL_DIR']+os.sep+'KDE'])
+ self.find_program('msgfmt',var='MSGFMT')
diff --git a/waflib/Tools/ldc2.py b/waflib/Tools/ldc2.py
new file mode 100644
index 0000000..75162e4
--- /dev/null
+++ b/waflib/Tools/ldc2.py
@@ -0,0 +1,36 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib.Tools import ar,d
+from waflib.Configure import conf
+@conf
+def find_ldc2(conf):
+ conf.find_program(['ldc2'],var='D')
+ out=conf.cmd_and_log(conf.env.D+['-version'])
+ if out.find("based on DMD v2.")==-1:
+ conf.fatal("detected compiler is not ldc2")
+@conf
+def common_flags_ldc2(conf):
+ v=conf.env
+ v['D_SRC_F']=['-c']
+ v['D_TGT_F']='-of%s'
+ v['D_LINKER']=v['D']
+ v['DLNK_SRC_F']=''
+ v['DLNK_TGT_F']='-of%s'
+ v['DINC_ST']='-I%s'
+ v['DSHLIB_MARKER']=v['DSTLIB_MARKER']=''
+ v['DSTLIB_ST']=v['DSHLIB_ST']='-L-l%s'
+ v['DSTLIBPATH_ST']=v['DLIBPATH_ST']='-L-L%s'
+ v['LINKFLAGS_dshlib']=['-L-shared']
+ v['DHEADER_ext']='.di'
+ v['DFLAGS_d_with_header']=['-H','-Hf']
+ v['D_HDR_F']='%s'
+ v['LINKFLAGS']=[]
+ v['DFLAGS_dshlib']=['-relocation-model=pic']
+def configure(conf):
+ conf.find_ldc2()
+ conf.load('ar')
+ conf.load('d')
+ conf.common_flags_ldc2()
+ conf.d_platform_flags()
diff --git a/waflib/Tools/lua.py b/waflib/Tools/lua.py
new file mode 100644
index 0000000..b801d5f
--- /dev/null
+++ b/waflib/Tools/lua.py
@@ -0,0 +1,18 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib.TaskGen import extension
+from waflib import Task
+@extension('.lua')
+def add_lua(self,node):
+ tsk=self.create_task('luac',node,node.change_ext('.luac'))
+ inst_to=getattr(self,'install_path',self.env.LUADIR and'${LUADIR}'or None)
+ if inst_to:
+ self.bld.install_files(inst_to,tsk.outputs)
+ return tsk
+class luac(Task.Task):
+ run_str='${LUAC} -s -o ${TGT} ${SRC}'
+ color='PINK'
+def configure(conf):
+ conf.find_program('luac',var='LUAC')
diff --git a/waflib/Tools/msvc.py b/waflib/Tools/msvc.py
new file mode 100644
index 0000000..919c825
--- /dev/null
+++ b/waflib/Tools/msvc.py
@@ -0,0 +1,809 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,sys,re,tempfile
+from waflib import Utils,Task,Logs,Options,Errors
+from waflib.Logs import debug,warn
+from waflib.TaskGen import after_method,feature
+from waflib.Configure import conf
+from waflib.Tools import ccroot,c,cxx,ar,winres
+g_msvc_systemlibs='''
+aclui activeds ad1 adptif adsiid advapi32 asycfilt authz bhsupp bits bufferoverflowu cabinet
+cap certadm certidl ciuuid clusapi comctl32 comdlg32 comsupp comsuppd comsuppw comsuppwd comsvcs
+credui crypt32 cryptnet cryptui d3d8thk daouuid dbgeng dbghelp dciman32 ddao35 ddao35d
+ddao35u ddao35ud delayimp dhcpcsvc dhcpsapi dlcapi dnsapi dsprop dsuiext dtchelp
+faultrep fcachdll fci fdi framedyd framedyn gdi32 gdiplus glauxglu32 gpedit gpmuuid
+gtrts32w gtrtst32hlink htmlhelp httpapi icm32 icmui imagehlp imm32 iphlpapi iprop
+kernel32 ksguid ksproxy ksuser libcmt libcmtd libcpmt libcpmtd loadperf lz32 mapi
+mapi32 mgmtapi minidump mmc mobsync mpr mprapi mqoa mqrt msacm32 mscms mscoree
+msdasc msimg32 msrating mstask msvcmrt msvcurt msvcurtd mswsock msxml2 mtx mtxdm
+netapi32 nmapinmsupp npptools ntdsapi ntdsbcli ntmsapi ntquery odbc32 odbcbcp
+odbccp32 oldnames ole32 oleacc oleaut32 oledb oledlgolepro32 opends60 opengl32
+osptk parser pdh penter pgobootrun pgort powrprof psapi ptrustm ptrustmd ptrustu
+ptrustud qosname rasapi32 rasdlg rassapi resutils riched20 rpcndr rpcns4 rpcrt4 rtm
+rtutils runtmchk scarddlg scrnsave scrnsavw secur32 sensapi setupapi sfc shell32
+shfolder shlwapi sisbkup snmpapi sporder srclient sti strsafe svcguid tapi32 thunk32
+traffic unicows url urlmon user32 userenv usp10 uuid uxtheme vcomp vcompd vdmdbg
+version vfw32 wbemuuid webpost wiaguid wininet winmm winscard winspool winstrm
+wintrust wldap32 wmiutils wow32 ws2_32 wsnmp32 wsock32 wst wtsapi32 xaswitch xolehlp
+'''.split()
+all_msvc_platforms=[('x64','amd64'),('x86','x86'),('ia64','ia64'),('x86_amd64','amd64'),('x86_ia64','ia64'),('x86_arm','arm'),('amd64_x86','x86'),('amd64_arm','arm')]
+all_wince_platforms=[('armv4','arm'),('armv4i','arm'),('mipsii','mips'),('mipsii_fp','mips'),('mipsiv','mips'),('mipsiv_fp','mips'),('sh4','sh'),('x86','cex86')]
+all_icl_platforms=[('intel64','amd64'),('em64t','amd64'),('ia32','x86'),('Itanium','ia64')]
+def options(opt):
+ opt.add_option('--msvc_version',type='string',help='msvc version, eg: "msvc 10.0,msvc 9.0"',default='')
+ opt.add_option('--msvc_targets',type='string',help='msvc targets, eg: "x64,arm"',default='')
+ opt.add_option('--msvc_lazy_autodetect',action='store_true',help='lazily check msvc target environments')
+def setup_msvc(conf,versions,arch=False):
+ platforms=getattr(Options.options,'msvc_targets','').split(',')
+ if platforms==['']:
+ platforms=Utils.to_list(conf.env['MSVC_TARGETS'])or[i for i,j in all_msvc_platforms+all_icl_platforms+all_wince_platforms]
+ desired_versions=getattr(Options.options,'msvc_version','').split(',')
+ if desired_versions==['']:
+ desired_versions=conf.env['MSVC_VERSIONS']or[v for v,_ in versions][::-1]
+ versiondict=dict(versions)
+ for version in desired_versions:
+ try:
+ targets=dict(versiondict[version])
+ for target in platforms:
+ try:
+ try:
+ realtarget,(p1,p2,p3)=targets[target]
+ except conf.errors.ConfigurationError:
+ del(targets[target])
+ else:
+ compiler,revision=version.rsplit(' ',1)
+ if arch:
+ return compiler,revision,p1,p2,p3,realtarget
+ else:
+ return compiler,revision,p1,p2,p3
+ except KeyError:continue
+ except KeyError:continue
+ conf.fatal('msvc: Impossible to find a valid architecture for building (in setup_msvc)')
+@conf
+def get_msvc_version(conf,compiler,version,target,vcvars):
+ debug('msvc: get_msvc_version: %r %r %r',compiler,version,target)
+ try:
+ conf.msvc_cnt+=1
+ except AttributeError:
+ conf.msvc_cnt=1
+ batfile=conf.bldnode.make_node('waf-print-msvc-%d.bat'%conf.msvc_cnt)
+ batfile.write("""@echo off
+set INCLUDE=
+set LIB=
+call "%s" %s
+echo PATH=%%PATH%%
+echo INCLUDE=%%INCLUDE%%
+echo LIB=%%LIB%%;%%LIBPATH%%
+"""%(vcvars,target))
+ sout=conf.cmd_and_log(['cmd.exe','/E:on','/V:on','/C',batfile.abspath()])
+ lines=sout.splitlines()
+ if not lines[0]:
+ lines.pop(0)
+ MSVC_PATH=MSVC_INCDIR=MSVC_LIBDIR=None
+ for line in lines:
+ if line.startswith('PATH='):
+ path=line[5:]
+ MSVC_PATH=path.split(';')
+ elif line.startswith('INCLUDE='):
+ MSVC_INCDIR=[i for i in line[8:].split(';')if i]
+ elif line.startswith('LIB='):
+ MSVC_LIBDIR=[i for i in line[4:].split(';')if i]
+ if None in(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR):
+ conf.fatal('msvc: Could not find a valid architecture for building (get_msvc_version_3)')
+ env=dict(os.environ)
+ env.update(PATH=path)
+ compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
+ cxx=conf.find_program(compiler_name,path_list=MSVC_PATH)
+ if'CL'in env:
+ del(env['CL'])
+ try:
+ try:
+ conf.cmd_and_log(cxx+['/help'],env=env)
+ except UnicodeError:
+ st=Utils.ex_stack()
+ if conf.logger:
+ conf.logger.error(st)
+ conf.fatal('msvc: Unicode error - check the code page?')
+ except Exception ,e:
+ debug('msvc: get_msvc_version: %r %r %r -> failure %s'%(compiler,version,target,str(e)))
+ conf.fatal('msvc: cannot run the compiler in get_msvc_version (run with -v to display errors)')
+ else:
+ debug('msvc: get_msvc_version: %r %r %r -> OK',compiler,version,target)
+ finally:
+ conf.env[compiler_name]=''
+ return(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR)
+@conf
+def gather_wsdk_versions(conf,versions):
+ version_pattern=re.compile('^v..?.?\...?.?')
+ try:
+ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Microsoft SDKs\\Windows')
+ except WindowsError:
+ try:
+ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows')
+ except WindowsError:
+ return
+ index=0
+ while 1:
+ try:
+ version=Utils.winreg.EnumKey(all_versions,index)
+ except WindowsError:
+ break
+ index=index+1
+ if not version_pattern.match(version):
+ continue
+ try:
+ msvc_version=Utils.winreg.OpenKey(all_versions,version)
+ path,type=Utils.winreg.QueryValueEx(msvc_version,'InstallationFolder')
+ except WindowsError:
+ continue
+ if path and os.path.isfile(os.path.join(path,'bin','SetEnv.cmd')):
+ targets=[]
+ for target,arch in all_msvc_platforms:
+ try:
+ targets.append((target,(arch,get_compiler_env(conf,'wsdk',version,'/'+target,os.path.join(path,'bin','SetEnv.cmd')))))
+ except conf.errors.ConfigurationError:
+ pass
+ versions.append(('wsdk '+version[1:],targets))
+def gather_wince_supported_platforms():
+ supported_wince_platforms=[]
+ try:
+ ce_sdk=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Windows CE Tools\\SDKs')
+ except WindowsError:
+ try:
+ ce_sdk=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Windows CE Tools\\SDKs')
+ except WindowsError:
+ ce_sdk=''
+ if not ce_sdk:
+ return supported_wince_platforms
+ ce_index=0
+ while 1:
+ try:
+ sdk_device=Utils.winreg.EnumKey(ce_sdk,ce_index)
+ except WindowsError:
+ break
+ ce_index=ce_index+1
+ sdk=Utils.winreg.OpenKey(ce_sdk,sdk_device)
+ try:
+ path,type=Utils.winreg.QueryValueEx(sdk,'SDKRootDir')
+ except WindowsError:
+ try:
+ path,type=Utils.winreg.QueryValueEx(sdk,'SDKInformation')
+ path,xml=os.path.split(path)
+ except WindowsError:
+ continue
+ path=str(path)
+ path,device=os.path.split(path)
+ if not device:
+ path,device=os.path.split(path)
+ platforms=[]
+ for arch,compiler in all_wince_platforms:
+ if os.path.isdir(os.path.join(path,device,'Lib',arch)):
+ platforms.append((arch,compiler,os.path.join(path,device,'Include',arch),os.path.join(path,device,'Lib',arch)))
+ if platforms:
+ supported_wince_platforms.append((device,platforms))
+ return supported_wince_platforms
+def gather_msvc_detected_versions():
+ version_pattern=re.compile('^(\d\d?\.\d\d?)(Exp)?$')
+ detected_versions=[]
+ for vcver,vcvar in(('VCExpress','Exp'),('VisualStudio','')):
+ try:
+ prefix='SOFTWARE\\Wow6432node\\Microsoft\\'+vcver
+ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix)
+ except WindowsError:
+ try:
+ prefix='SOFTWARE\\Microsoft\\'+vcver
+ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix)
+ except WindowsError:
+ continue
+ index=0
+ while 1:
+ try:
+ version=Utils.winreg.EnumKey(all_versions,index)
+ except WindowsError:
+ break
+ index=index+1
+ match=version_pattern.match(version)
+ if not match:
+ continue
+ else:
+ versionnumber=float(match.group(1))
+ detected_versions.append((versionnumber,version+vcvar,prefix+"\\"+version))
+ def fun(tup):
+ return tup[0]
+ detected_versions.sort(key=fun)
+ return detected_versions
+def get_compiler_env(conf,compiler,version,bat_target,bat,select=None):
+ lazy=getattr(Options.options,'msvc_lazy_autodetect',False)or conf.env['MSVC_LAZY_AUTODETECT']
+ def msvc_thunk():
+ vs=conf.get_msvc_version(compiler,version,bat_target,bat)
+ if select:
+ return select(vs)
+ else:
+ return vs
+ return lazytup(msvc_thunk,lazy,([],[],[]))
+class lazytup(object):
+ def __init__(self,fn,lazy=True,default=None):
+ self.fn=fn
+ self.default=default
+ if not lazy:
+ self.evaluate()
+ def __len__(self):
+ self.evaluate()
+ return len(self.value)
+ def __iter__(self):
+ self.evaluate()
+ for i,v in enumerate(self.value):
+ yield v
+ def __getitem__(self,i):
+ self.evaluate()
+ return self.value[i]
+ def __repr__(self):
+ if hasattr(self,'value'):
+ return repr(self.value)
+ elif self.default:
+ return repr(self.default)
+ else:
+ self.evaluate()
+ return repr(self.value)
+ def evaluate(self):
+ if hasattr(self,'value'):
+ return
+ self.value=self.fn()
+@conf
+def gather_msvc_targets(conf,versions,version,vc_path):
+ targets=[]
+ if os.path.isfile(os.path.join(vc_path,'vcvarsall.bat')):
+ for target,realtarget in all_msvc_platforms[::-1]:
+ try:
+ targets.append((target,(realtarget,get_compiler_env(conf,'msvc',version,target,os.path.join(vc_path,'vcvarsall.bat')))))
+ except conf.errors.ConfigurationError:
+ pass
+ elif os.path.isfile(os.path.join(vc_path,'Common7','Tools','vsvars32.bat')):
+ try:
+ targets.append(('x86',('x86',get_compiler_env(conf,'msvc',version,'x86',os.path.join(vc_path,'Common7','Tools','vsvars32.bat')))))
+ except conf.errors.ConfigurationError:
+ pass
+ elif os.path.isfile(os.path.join(vc_path,'Bin','vcvars32.bat')):
+ try:
+ targets.append(('x86',('x86',get_compiler_env(conf,'msvc',version,'',os.path.join(vc_path,'Bin','vcvars32.bat')))))
+ except conf.errors.ConfigurationError:
+ pass
+ if targets:
+ versions.append(('msvc '+version,targets))
+@conf
+def gather_wince_targets(conf,versions,version,vc_path,vsvars,supported_platforms):
+ for device,platforms in supported_platforms:
+ cetargets=[]
+ for platform,compiler,include,lib in platforms:
+ winCEpath=os.path.join(vc_path,'ce')
+ if not os.path.isdir(winCEpath):
+ continue
+ if os.path.isdir(os.path.join(winCEpath,'lib',platform)):
+ bindirs=[os.path.join(winCEpath,'bin',compiler),os.path.join(winCEpath,'bin','x86_'+compiler)]
+ incdirs=[os.path.join(winCEpath,'include'),os.path.join(winCEpath,'atlmfc','include'),include]
+ libdirs=[os.path.join(winCEpath,'lib',platform),os.path.join(winCEpath,'atlmfc','lib',platform),lib]
+ def combine_common(compiler_env):
+ (common_bindirs,_1,_2)=compiler_env
+ return(bindirs+common_bindirs,incdirs,libdirs)
+ try:
+ cetargets.append((platform,(platform,get_compiler_env(conf,'msvc',version,'x86',vsvars,combine_common))))
+ except conf.errors.ConfigurationError:
+ continue
+ if cetargets:
+ versions.append((device+' '+version,cetargets))
+@conf
+def gather_winphone_targets(conf,versions,version,vc_path,vsvars):
+ targets=[]
+ for target,realtarget in all_msvc_platforms[::-1]:
+ try:
+ targets.append((target,(realtarget,get_compiler_env(conf,'winphone',version,target,vsvars))))
+ except conf.errors.ConfigurationError:
+ pass
+ if targets:
+ versions.append(('winphone '+version,targets))
+@conf
+def gather_msvc_versions(conf,versions):
+ vc_paths=[]
+ for(v,version,reg)in gather_msvc_detected_versions():
+ try:
+ try:
+ msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,reg+"\\Setup\\VC")
+ except WindowsError:
+ msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,reg+"\\Setup\\Microsoft Visual C++")
+ path,type=Utils.winreg.QueryValueEx(msvc_version,'ProductDir')
+ vc_paths.append((version,os.path.abspath(str(path))))
+ except WindowsError:
+ continue
+ wince_supported_platforms=gather_wince_supported_platforms()
+ for version,vc_path in vc_paths:
+ vs_path=os.path.dirname(vc_path)
+ vsvars=os.path.join(vs_path,'Common7','Tools','vsvars32.bat')
+ if wince_supported_platforms and os.path.isfile(vsvars):
+ conf.gather_wince_targets(versions,version,vc_path,vsvars,wince_supported_platforms)
+ for version,vc_path in vc_paths:
+ vs_path=os.path.dirname(vc_path)
+ vsvars=os.path.join(vs_path,'VC','WPSDK','WP80','vcvarsphoneall.bat')
+ if os.path.isfile(vsvars):
+ conf.gather_winphone_targets(versions,'8.0',vc_path,vsvars)
+ break
+ for version,vc_path in vc_paths:
+ vs_path=os.path.dirname(vc_path)
+ conf.gather_msvc_targets(versions,version,vc_path)
+@conf
+def gather_icl_versions(conf,versions):
+ version_pattern=re.compile('^...?.?\....?.?')
+ try:
+ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Compilers\\C++')
+ except WindowsError:
+ try:
+ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Compilers\\C++')
+ except WindowsError:
+ return
+ index=0
+ while 1:
+ try:
+ version=Utils.winreg.EnumKey(all_versions,index)
+ except WindowsError:
+ break
+ index=index+1
+ if not version_pattern.match(version):
+ continue
+ targets=[]
+ for target,arch in all_icl_platforms:
+ try:
+ if target=='intel64':targetDir='EM64T_NATIVE'
+ else:targetDir=target
+ Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir)
+ icl_version=Utils.winreg.OpenKey(all_versions,version)
+ path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
+ batch_file=os.path.join(path,'bin','iclvars.bat')
+ if os.path.isfile(batch_file):
+ try:
+ targets.append((target,(arch,get_compiler_env(conf,'intel',version,target,batch_file))))
+ except conf.errors.ConfigurationError:
+ pass
+ except WindowsError:
+ pass
+ for target,arch in all_icl_platforms:
+ try:
+ icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+target)
+ path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
+ batch_file=os.path.join(path,'bin','iclvars.bat')
+ if os.path.isfile(batch_file):
+ try:
+ targets.append((target,(arch,get_compiler_env(conf,'intel',version,target,batch_file))))
+ except conf.errors.ConfigurationError:
+ pass
+ except WindowsError:
+ continue
+ major=version[0:2]
+ versions.append(('intel '+major,targets))
+@conf
+def gather_intel_composer_versions(conf,versions):
+ version_pattern=re.compile('^...?.?\...?.?.?')
+ try:
+ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Suites')
+ except WindowsError:
+ try:
+ all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Suites')
+ except WindowsError:
+ return
+ index=0
+ while 1:
+ try:
+ version=Utils.winreg.EnumKey(all_versions,index)
+ except WindowsError:
+ break
+ index=index+1
+ if not version_pattern.match(version):
+ continue
+ targets=[]
+ for target,arch in all_icl_platforms:
+ try:
+ if target=='intel64':targetDir='EM64T_NATIVE'
+ else:targetDir=target
+ try:
+ defaults=Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\'+targetDir)
+ except WindowsError:
+ if targetDir=='EM64T_NATIVE':
+ defaults=Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\EM64T')
+ else:
+ raise WindowsError
+ uid,type=Utils.winreg.QueryValueEx(defaults,'SubKey')
+ Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++\\'+targetDir)
+ icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++')
+ path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
+ batch_file=os.path.join(path,'bin','iclvars.bat')
+ if os.path.isfile(batch_file):
+ try:
+ targets.append((target,(arch,get_compiler_env(conf,'intel',version,target,batch_file))))
+ except conf.errors.ConfigurationError:
+ pass
+ compilervars_warning_attr='_compilervars_warning_key'
+ if version[0:2]=='13'and getattr(conf,compilervars_warning_attr,True):
+ setattr(conf,compilervars_warning_attr,False)
+ patch_url='http://software.intel.com/en-us/forums/topic/328487'
+ compilervars_arch=os.path.join(path,'bin','compilervars_arch.bat')
+ for vscomntool in('VS110COMNTOOLS','VS100COMNTOOLS'):
+ if vscomntool in os.environ:
+ vs_express_path=os.environ[vscomntool]+r'..\IDE\VSWinExpress.exe'
+ dev_env_path=os.environ[vscomntool]+r'..\IDE\devenv.exe'
+ 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)):
+ 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))
+ except WindowsError:
+ pass
+ major=version[0:2]
+ versions.append(('intel '+major,targets))
+@conf
+def get_msvc_versions(conf,eval_and_save=True):
+ if conf.env['MSVC_INSTALLED_VERSIONS']:
+ return conf.env['MSVC_INSTALLED_VERSIONS']
+ lst=[]
+ conf.gather_icl_versions(lst)
+ conf.gather_intel_composer_versions(lst)
+ conf.gather_wsdk_versions(lst)
+ conf.gather_msvc_versions(lst)
+ if eval_and_save:
+ def checked_target(t):
+ target,(arch,paths)=t
+ try:
+ paths.evaluate()
+ except conf.errors.ConfigurationError:
+ return None
+ else:
+ return t
+ lst=[(version,list(filter(checked_target,targets)))for version,targets in lst]
+ conf.env['MSVC_INSTALLED_VERSIONS']=lst
+ return lst
+@conf
+def print_all_msvc_detected(conf):
+ for version,targets in conf.env['MSVC_INSTALLED_VERSIONS']:
+ Logs.info(version)
+ for target,l in targets:
+ Logs.info("\t"+target)
+@conf
+def detect_msvc(conf,arch=False):
+ lazy_detect=getattr(Options.options,'msvc_lazy_autodetect',False)or conf.env['MSVC_LAZY_AUTODETECT']
+ versions=get_msvc_versions(conf,not lazy_detect)
+ return setup_msvc(conf,versions,arch)
+@conf
+def find_lt_names_msvc(self,libname,is_static=False):
+ lt_names=['lib%s.la'%libname,'%s.la'%libname,]
+ for path in self.env['LIBPATH']:
+ for la in lt_names:
+ laf=os.path.join(path,la)
+ dll=None
+ if os.path.exists(laf):
+ ltdict=Utils.read_la_file(laf)
+ lt_libdir=None
+ if ltdict.get('libdir',''):
+ lt_libdir=ltdict['libdir']
+ if not is_static and ltdict.get('library_names',''):
+ dllnames=ltdict['library_names'].split()
+ dll=dllnames[0].lower()
+ dll=re.sub('\.dll$','',dll)
+ return(lt_libdir,dll,False)
+ elif ltdict.get('old_library',''):
+ olib=ltdict['old_library']
+ if os.path.exists(os.path.join(path,olib)):
+ return(path,olib,True)
+ elif lt_libdir!=''and os.path.exists(os.path.join(lt_libdir,olib)):
+ return(lt_libdir,olib,True)
+ else:
+ return(None,olib,True)
+ else:
+ raise self.errors.WafError('invalid libtool object file: %s'%laf)
+ return(None,None,None)
+@conf
+def libname_msvc(self,libname,is_static=False):
+ lib=libname.lower()
+ lib=re.sub('\.lib$','',lib)
+ if lib in g_msvc_systemlibs:
+ return lib
+ lib=re.sub('^lib','',lib)
+ if lib=='m':
+ return None
+ (lt_path,lt_libname,lt_static)=self.find_lt_names_msvc(lib,is_static)
+ if lt_path!=None and lt_libname!=None:
+ if lt_static==True:
+ return os.path.join(lt_path,lt_libname)
+ if lt_path!=None:
+ _libpaths=[lt_path]+self.env['LIBPATH']
+ else:
+ _libpaths=self.env['LIBPATH']
+ static_libs=['lib%ss.lib'%lib,'lib%s.lib'%lib,'%ss.lib'%lib,'%s.lib'%lib,]
+ 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,]
+ libnames=static_libs
+ if not is_static:
+ libnames=dynamic_libs+static_libs
+ for path in _libpaths:
+ for libn in libnames:
+ if os.path.exists(os.path.join(path,libn)):
+ debug('msvc: lib found: %s'%os.path.join(path,libn))
+ return re.sub('\.lib$','',libn)
+ self.fatal("The library %r could not be found"%libname)
+ return re.sub('\.lib$','',libname)
+@conf
+def check_lib_msvc(self,libname,is_static=False,uselib_store=None):
+ libn=self.libname_msvc(libname,is_static)
+ if not uselib_store:
+ uselib_store=libname.upper()
+ if False and is_static:
+ self.env['STLIB_'+uselib_store]=[libn]
+ else:
+ self.env['LIB_'+uselib_store]=[libn]
+@conf
+def check_libs_msvc(self,libnames,is_static=False):
+ for libname in Utils.to_list(libnames):
+ self.check_lib_msvc(libname,is_static)
+def configure(conf):
+ conf.autodetect(True)
+ conf.find_msvc()
+ conf.msvc_common_flags()
+ conf.cc_load_tools()
+ conf.cxx_load_tools()
+ conf.cc_add_flags()
+ conf.cxx_add_flags()
+ conf.link_add_flags()
+ conf.visual_studio_add_flags()
+@conf
+def no_autodetect(conf):
+ conf.env.NO_MSVC_DETECT=1
+ configure(conf)
+@conf
+def autodetect(conf,arch=False):
+ v=conf.env
+ if v.NO_MSVC_DETECT:
+ return
+ if arch:
+ compiler,version,path,includes,libdirs,arch=conf.detect_msvc(True)
+ v['DEST_CPU']=arch
+ else:
+ compiler,version,path,includes,libdirs=conf.detect_msvc()
+ v['PATH']=path
+ v['INCLUDES']=includes
+ v['LIBPATH']=libdirs
+ v['MSVC_COMPILER']=compiler
+ try:
+ v['MSVC_VERSION']=float(version)
+ except Exception:
+ v['MSVC_VERSION']=float(version[:-3])
+def _get_prog_names(conf,compiler):
+ if compiler=='intel':
+ compiler_name='ICL'
+ linker_name='XILINK'
+ lib_name='XILIB'
+ else:
+ compiler_name='CL'
+ linker_name='LINK'
+ lib_name='LIB'
+ return compiler_name,linker_name,lib_name
+@conf
+def find_msvc(conf):
+ if sys.platform=='cygwin':
+ conf.fatal('MSVC module does not work under cygwin Python!')
+ v=conf.env
+ path=v['PATH']
+ compiler=v['MSVC_COMPILER']
+ version=v['MSVC_VERSION']
+ compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
+ v.MSVC_MANIFEST=(compiler=='msvc'and version>=8)or(compiler=='wsdk'and version>=6)or(compiler=='intel'and version>=11)
+ cxx=conf.find_program(compiler_name,var='CXX',path_list=path)
+ env=dict(conf.environ)
+ if path:env.update(PATH=';'.join(path))
+ if not conf.cmd_and_log(cxx+['/nologo','/help'],env=env):
+ conf.fatal('the msvc compiler could not be identified')
+ v['CC']=v['CXX']=cxx
+ v['CC_NAME']=v['CXX_NAME']='msvc'
+ if not v['LINK_CXX']:
+ link=conf.find_program(linker_name,path_list=path)
+ if link:v['LINK_CXX']=link
+ else:conf.fatal('%s was not found (linker)'%linker_name)
+ v['LINK']=link
+ if not v['LINK_CC']:
+ v['LINK_CC']=v['LINK_CXX']
+ if not v['AR']:
+ stliblink=conf.find_program(lib_name,path_list=path,var='AR')
+ if not stliblink:return
+ v['ARFLAGS']=['/NOLOGO']
+ if v.MSVC_MANIFEST:
+ conf.find_program('MT',path_list=path,var='MT')
+ v['MTFLAGS']=['/NOLOGO']
+ try:
+ conf.load('winres')
+ except Errors.WafError:
+ warn('Resource compiler not found. Compiling resource file is disabled')
+@conf
+def visual_studio_add_flags(self):
+ v=self.env
+ try:v.prepend_value('INCLUDES',[x for x in self.environ['INCLUDE'].split(';')if x])
+ except Exception:pass
+ try:v.prepend_value('LIBPATH',[x for x in self.environ['LIB'].split(';')if x])
+ except Exception:pass
+@conf
+def msvc_common_flags(conf):
+ v=conf.env
+ v['DEST_BINFMT']='pe'
+ v.append_value('CFLAGS',['/nologo'])
+ v.append_value('CXXFLAGS',['/nologo'])
+ v['DEFINES_ST']='/D%s'
+ v['CC_SRC_F']=''
+ v['CC_TGT_F']=['/c','/Fo']
+ v['CXX_SRC_F']=''
+ v['CXX_TGT_F']=['/c','/Fo']
+ if(v.MSVC_COMPILER=='msvc'and v.MSVC_VERSION>=8)or(v.MSVC_COMPILER=='wsdk'and v.MSVC_VERSION>=6):
+ v['CC_TGT_F']=['/FC']+v['CC_TGT_F']
+ v['CXX_TGT_F']=['/FC']+v['CXX_TGT_F']
+ v['CPPPATH_ST']='/I%s'
+ v['AR_TGT_F']=v['CCLNK_TGT_F']=v['CXXLNK_TGT_F']='/OUT:'
+ v['CFLAGS_CONSOLE']=v['CXXFLAGS_CONSOLE']=['/SUBSYSTEM:CONSOLE']
+ v['CFLAGS_NATIVE']=v['CXXFLAGS_NATIVE']=['/SUBSYSTEM:NATIVE']
+ v['CFLAGS_POSIX']=v['CXXFLAGS_POSIX']=['/SUBSYSTEM:POSIX']
+ v['CFLAGS_WINDOWS']=v['CXXFLAGS_WINDOWS']=['/SUBSYSTEM:WINDOWS']
+ v['CFLAGS_WINDOWSCE']=v['CXXFLAGS_WINDOWSCE']=['/SUBSYSTEM:WINDOWSCE']
+ v['CFLAGS_CRT_MULTITHREADED']=v['CXXFLAGS_CRT_MULTITHREADED']=['/MT']
+ v['CFLAGS_CRT_MULTITHREADED_DLL']=v['CXXFLAGS_CRT_MULTITHREADED_DLL']=['/MD']
+ v['CFLAGS_CRT_MULTITHREADED_DBG']=v['CXXFLAGS_CRT_MULTITHREADED_DBG']=['/MTd']
+ v['CFLAGS_CRT_MULTITHREADED_DLL_DBG']=v['CXXFLAGS_CRT_MULTITHREADED_DLL_DBG']=['/MDd']
+ v['LIB_ST']='%s.lib'
+ v['LIBPATH_ST']='/LIBPATH:%s'
+ v['STLIB_ST']='%s.lib'
+ v['STLIBPATH_ST']='/LIBPATH:%s'
+ v.append_value('LINKFLAGS',['/NOLOGO'])
+ if v['MSVC_MANIFEST']:
+ v.append_value('LINKFLAGS',['/MANIFEST'])
+ v['CFLAGS_cshlib']=[]
+ v['CXXFLAGS_cxxshlib']=[]
+ v['LINKFLAGS_cshlib']=v['LINKFLAGS_cxxshlib']=['/DLL']
+ v['cshlib_PATTERN']=v['cxxshlib_PATTERN']='%s.dll'
+ v['implib_PATTERN']='%s.lib'
+ v['IMPLIB_ST']='/IMPLIB:%s'
+ v['LINKFLAGS_cstlib']=[]
+ v['cstlib_PATTERN']=v['cxxstlib_PATTERN']='%s.lib'
+ v['cprogram_PATTERN']=v['cxxprogram_PATTERN']='%s.exe'
+@after_method('apply_link')
+@feature('c','cxx')
+def apply_flags_msvc(self):
+ if self.env.CC_NAME!='msvc'or not getattr(self,'link_task',None):
+ return
+ is_static=isinstance(self.link_task,ccroot.stlink_task)
+ subsystem=getattr(self,'subsystem','')
+ if subsystem:
+ subsystem='/subsystem:%s'%subsystem
+ flags=is_static and'ARFLAGS'or'LINKFLAGS'
+ self.env.append_value(flags,subsystem)
+ if not is_static:
+ for f in self.env.LINKFLAGS:
+ d=f.lower()
+ if d[1:]=='debug':
+ pdbnode=self.link_task.outputs[0].change_ext('.pdb')
+ self.link_task.outputs.append(pdbnode)
+ if getattr(self,'install_task',None):
+ self.pdb_install_task=self.bld.install_files(self.install_task.dest,pdbnode,env=self.env)
+ break
+@feature('cprogram','cshlib','cxxprogram','cxxshlib')
+@after_method('apply_link')
+def apply_manifest(self):
+ if self.env.CC_NAME=='msvc'and self.env.MSVC_MANIFEST and getattr(self,'link_task',None):
+ out_node=self.link_task.outputs[0]
+ man_node=out_node.parent.find_or_declare(out_node.name+'.manifest')
+ self.link_task.outputs.append(man_node)
+ self.link_task.do_manifest=True
+def exec_mf(self):
+ env=self.env
+ mtool=env['MT']
+ if not mtool:
+ return 0
+ self.do_manifest=False
+ outfile=self.outputs[0].abspath()
+ manifest=None
+ for out_node in self.outputs:
+ if out_node.name.endswith('.manifest'):
+ manifest=out_node.abspath()
+ break
+ if manifest is None:
+ return 0
+ mode=''
+ if'cprogram'in self.generator.features or'cxxprogram'in self.generator.features:
+ mode='1'
+ elif'cshlib'in self.generator.features or'cxxshlib'in self.generator.features:
+ mode='2'
+ debug('msvc: embedding manifest in mode %r'%mode)
+ lst=[]+mtool
+ lst.extend(Utils.to_list(env['MTFLAGS']))
+ lst.extend(['-manifest',manifest])
+ lst.append('-outputresource:%s;%s'%(outfile,mode))
+ return self.exec_command(lst)
+def quote_response_command(self,flag):
+ if flag.find(' ')>-1:
+ for x in('/LIBPATH:','/IMPLIB:','/OUT:','/I'):
+ if flag.startswith(x):
+ flag='%s"%s"'%(x,flag[len(x):])
+ break
+ else:
+ flag='"%s"'%flag
+ return flag
+def exec_response_command(self,cmd,**kw):
+ try:
+ tmp=None
+ if sys.platform.startswith('win')and isinstance(cmd,list)and len(' '.join(cmd))>=8192:
+ program=cmd[0]
+ cmd=[self.quote_response_command(x)for x in cmd]
+ (fd,tmp)=tempfile.mkstemp()
+ os.write(fd,'\r\n'.join(i.replace('\\','\\\\')for i in cmd[1:]))
+ os.close(fd)
+ cmd=[program,'@'+tmp]
+ ret=self.generator.bld.exec_command(cmd,**kw)
+ finally:
+ if tmp:
+ try:
+ os.remove(tmp)
+ except OSError:
+ pass
+ return ret
+def exec_command_msvc(self,*k,**kw):
+ if isinstance(k[0],list):
+ lst=[]
+ carry=''
+ for a in k[0]:
+ if a=='/Fo'or a=='/doc'or a[-1]==':':
+ carry=a
+ else:
+ lst.append(carry+a)
+ carry=''
+ k=[lst]
+ if self.env['PATH']:
+ env=dict(self.env.env or os.environ)
+ env.update(PATH=';'.join(self.env['PATH']))
+ kw['env']=env
+ bld=self.generator.bld
+ try:
+ if not kw.get('cwd',None):
+ kw['cwd']=bld.cwd
+ except AttributeError:
+ bld.cwd=kw['cwd']=bld.variant_dir
+ ret=self.exec_response_command(k[0],**kw)
+ if not ret and getattr(self,'do_manifest',None):
+ ret=self.exec_mf()
+ return ret
+def wrap_class(class_name):
+ cls=Task.classes.get(class_name,None)
+ if not cls:
+ return None
+ derived_class=type(class_name,(cls,),{})
+ def exec_command(self,*k,**kw):
+ if self.env['CC_NAME']=='msvc':
+ return self.exec_command_msvc(*k,**kw)
+ else:
+ return super(derived_class,self).exec_command(*k,**kw)
+ derived_class.exec_command=exec_command
+ derived_class.exec_response_command=exec_response_command
+ derived_class.quote_response_command=quote_response_command
+ derived_class.exec_command_msvc=exec_command_msvc
+ derived_class.exec_mf=exec_mf
+ if hasattr(cls,'hcode'):
+ derived_class.hcode=cls.hcode
+ return derived_class
+for k in'c cxx cprogram cxxprogram cshlib cxxshlib cstlib cxxstlib'.split():
+ wrap_class(k)
+def make_winapp(self,family):
+ append=self.env.append_unique
+ append('DEFINES','WINAPI_FAMILY=%s'%family)
+ append('CXXFLAGS','/ZW')
+ append('CXXFLAGS','/TP')
+ for lib_path in self.env.LIBPATH:
+ append('CXXFLAGS','/AI%s'%lib_path)
+@feature('winphoneapp')
+@after_method('process_use')
+@after_method('propagate_uselib_vars')
+def make_winphone_app(self):
+ make_winapp(self,'WINAPI_FAMILY_PHONE_APP')
+ conf.env.append_unique('LINKFLAGS','/NODEFAULTLIB:ole32.lib')
+ conf.env.append_unique('LINKFLAGS','PhoneAppModelHost.lib')
+@feature('winapp')
+@after_method('process_use')
+@after_method('propagate_uselib_vars')
+def make_windows_app(self):
+ make_winapp(self,'WINAPI_FAMILY_DESKTOP_APP')
diff --git a/waflib/Tools/nasm.py b/waflib/Tools/nasm.py
new file mode 100644
index 0000000..a107298
--- /dev/null
+++ b/waflib/Tools/nasm.py
@@ -0,0 +1,16 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os
+import waflib.Tools.asm
+from waflib.TaskGen import feature
+@feature('asm')
+def apply_nasm_vars(self):
+ self.env.append_value('ASFLAGS',self.to_list(getattr(self,'nasm_flags',[])))
+def configure(conf):
+ conf.find_program(['nasm','yasm'],var='AS')
+ conf.env.AS_TGT_F=['-o']
+ conf.env.ASLNK_TGT_F=['-o']
+ conf.load('asm')
+ conf.env.ASMPATH_ST='-I%s'+os.sep
diff --git a/waflib/Tools/perl.py b/waflib/Tools/perl.py
new file mode 100644
index 0000000..d065f3f
--- /dev/null
+++ b/waflib/Tools/perl.py
@@ -0,0 +1,90 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os
+from waflib import Task,Options,Utils
+from waflib.Configure import conf
+from waflib.TaskGen import extension,feature,before_method
+@before_method('apply_incpaths','apply_link','propagate_uselib_vars')
+@feature('perlext')
+def init_perlext(self):
+ self.uselib=self.to_list(getattr(self,'uselib',[]))
+ if not'PERLEXT'in self.uselib:self.uselib.append('PERLEXT')
+ self.env['cshlib_PATTERN']=self.env['cxxshlib_PATTERN']=self.env['perlext_PATTERN']
+@extension('.xs')
+def xsubpp_file(self,node):
+ outnode=node.change_ext('.c')
+ self.create_task('xsubpp',node,outnode)
+ self.source.append(outnode)
+class xsubpp(Task.Task):
+ run_str='${PERL} ${XSUBPP} -noprototypes -typemap ${EXTUTILS_TYPEMAP} ${SRC} > ${TGT}'
+ color='BLUE'
+ ext_out=['.h']
+@conf
+def check_perl_version(self,minver=None):
+ res=True
+ if minver:
+ cver='.'.join(map(str,minver))
+ else:
+ cver=''
+ self.start_msg('Checking for minimum perl version %s'%cver)
+ perl=getattr(Options.options,'perlbinary',None)
+ if not perl:
+ perl=self.find_program('perl',var='PERL')
+ if not perl:
+ self.end_msg("Perl not found",color="YELLOW")
+ return False
+ self.env['PERL']=perl
+ version=self.cmd_and_log(self.env.PERL+["-e",'printf \"%vd\", $^V'])
+ if not version:
+ res=False
+ version="Unknown"
+ elif not minver is None:
+ ver=tuple(map(int,version.split(".")))
+ if ver<minver:
+ res=False
+ self.end_msg(version,color=res and"GREEN"or"YELLOW")
+ return res
+@conf
+def check_perl_module(self,module):
+ cmd=self.env.PERL+['-e','use %s'%module]
+ self.start_msg('perl module %s'%module)
+ try:
+ r=self.cmd_and_log(cmd)
+ except Exception:
+ self.end_msg(False)
+ return None
+ self.end_msg(r or True)
+ return r
+@conf
+def check_perl_ext_devel(self):
+ env=self.env
+ perl=env.PERL
+ if not perl:
+ self.fatal('find perl first')
+ def cmd_perl_config(s):
+ return perl+['-MConfig','-e','print \"%s\"'%s]
+ def cfg_str(cfg):
+ return self.cmd_and_log(cmd_perl_config(cfg))
+ def cfg_lst(cfg):
+ return Utils.to_list(cfg_str(cfg))
+ def find_xsubpp():
+ for var in('privlib','vendorlib'):
+ xsubpp=cfg_lst('$Config{%s}/ExtUtils/xsubpp$Config{exe_ext}'%var)
+ if xsubpp and os.path.isfile(xsubpp[0]):
+ return xsubpp
+ return self.find_program('xsubpp')
+ env['LINKFLAGS_PERLEXT']=cfg_lst('$Config{lddlflags}')
+ env['INCLUDES_PERLEXT']=cfg_lst('$Config{archlib}/CORE')
+ env['CFLAGS_PERLEXT']=cfg_lst('$Config{ccflags} $Config{cccdlflags}')
+ env['EXTUTILS_TYPEMAP']=cfg_lst('$Config{privlib}/ExtUtils/typemap')
+ env['XSUBPP']=find_xsubpp()
+ if not getattr(Options.options,'perlarchdir',None):
+ env['ARCHDIR_PERL']=cfg_str('$Config{sitearch}')
+ else:
+ env['ARCHDIR_PERL']=getattr(Options.options,'perlarchdir')
+ env['perlext_PATTERN']='%s.'+cfg_str('$Config{dlext}')
+def options(opt):
+ opt.add_option('--with-perl-binary',type='string',dest='perlbinary',help='Specify alternate perl binary',default=None)
+ opt.add_option('--with-perl-archdir',type='string',dest='perlarchdir',help='Specify directory where to install arch specific files',default=None)
diff --git a/waflib/Tools/python.py b/waflib/Tools/python.py
new file mode 100644
index 0000000..557d8eb
--- /dev/null
+++ b/waflib/Tools/python.py
@@ -0,0 +1,399 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib import Utils,Options,Errors,Logs,Task,Node
+from waflib.TaskGen import extension,before_method,after_method,feature
+from waflib.Configure import conf
+FRAG='''
+#include <Python.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void Py_Initialize(void);
+ void Py_Finalize(void);
+#ifdef __cplusplus
+}
+#endif
+int main(int argc, char **argv)
+{
+ (void)argc; (void)argv;
+ Py_Initialize();
+ Py_Finalize();
+ return 0;
+}
+'''
+INST='''
+import sys, py_compile
+py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3], True)
+'''
+DISTUTILS_IMP=['from distutils.sysconfig import get_config_var, get_python_lib']
+@before_method('process_source')
+@feature('py')
+def feature_py(self):
+ self.install_path=getattr(self,'install_path','${PYTHONDIR}')
+ install_from=getattr(self,'install_from',None)
+ if install_from and not isinstance(install_from,Node.Node):
+ install_from=self.path.find_dir(install_from)
+ self.install_from=install_from
+ ver=self.env.PYTHON_VERSION
+ if not ver:
+ self.bld.fatal('Installing python files requires PYTHON_VERSION, try conf.check_python_version')
+ if int(ver.replace('.',''))>31:
+ self.install_32=True
+@extension('.py')
+def process_py(self,node):
+ assert(getattr(self,'install_path')),'add features="py"'
+ if self.install_path:
+ if self.install_from:
+ self.bld.install_files(self.install_path,[node],cwd=self.install_from,relative_trick=True)
+ else:
+ self.bld.install_files(self.install_path,[node],relative_trick=True)
+ lst=[]
+ if self.env.PYC:
+ lst.append('pyc')
+ if self.env.PYO:
+ lst.append('pyo')
+ if self.install_path:
+ if self.install_from:
+ pyd=Utils.subst_vars("%s/%s"%(self.install_path,node.path_from(self.install_from)),self.env)
+ else:
+ pyd=Utils.subst_vars("%s/%s"%(self.install_path,node.path_from(self.path)),self.env)
+ else:
+ pyd=node.abspath()
+ for ext in lst:
+ if self.env.PYTAG:
+ name=node.name[:-3]
+ pyobj=node.parent.get_bld().make_node('__pycache__').make_node("%s.%s.%s"%(name,self.env.PYTAG,ext))
+ pyobj.parent.mkdir()
+ else:
+ pyobj=node.change_ext(".%s"%ext)
+ tsk=self.create_task(ext,node,pyobj)
+ tsk.pyd=pyd
+ if self.install_path:
+ self.bld.install_files(os.path.dirname(pyd),pyobj,cwd=node.parent.get_bld(),relative_trick=True)
+class pyc(Task.Task):
+ color='PINK'
+ def run(self):
+ cmd=[Utils.subst_vars('${PYTHON}',self.env),'-c',INST,self.inputs[0].abspath(),self.outputs[0].abspath(),self.pyd]
+ ret=self.generator.bld.exec_command(cmd)
+ return ret
+class pyo(Task.Task):
+ color='PINK'
+ def run(self):
+ 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]
+ ret=self.generator.bld.exec_command(cmd)
+ return ret
+@feature('pyext')
+@before_method('propagate_uselib_vars','apply_link')
+@after_method('apply_bundle')
+def init_pyext(self):
+ self.uselib=self.to_list(getattr(self,'uselib',[]))
+ if not'PYEXT'in self.uselib:
+ self.uselib.append('PYEXT')
+ self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.macbundle_PATTERN=self.env.pyext_PATTERN
+ self.env.fcshlib_PATTERN=self.env.dshlib_PATTERN=self.env.pyext_PATTERN
+ try:
+ if not self.install_path:
+ return
+ except AttributeError:
+ self.install_path='${PYTHONARCHDIR}'
+@feature('pyext')
+@before_method('apply_link','apply_bundle')
+def set_bundle(self):
+ if Utils.unversioned_sys_platform()=='darwin':
+ self.mac_bundle=True
+@before_method('propagate_uselib_vars')
+@feature('pyembed')
+def init_pyembed(self):
+ self.uselib=self.to_list(getattr(self,'uselib',[]))
+ if not'PYEMBED'in self.uselib:
+ self.uselib.append('PYEMBED')
+@conf
+def get_python_variables(self,variables,imports=None):
+ if not imports:
+ try:
+ imports=self.python_imports
+ except AttributeError:
+ imports=DISTUTILS_IMP
+ program=list(imports)
+ program.append('')
+ for v in variables:
+ program.append("print(repr(%s))"%v)
+ os_env=dict(os.environ)
+ try:
+ del os_env['MACOSX_DEPLOYMENT_TARGET']
+ except KeyError:
+ pass
+ try:
+ out=self.cmd_and_log(self.env.PYTHON+['-c','\n'.join(program)],env=os_env)
+ except Errors.WafError:
+ self.fatal('The distutils module is unusable: install "python-devel"?')
+ self.to_log(out)
+ return_values=[]
+ for s in out.splitlines():
+ s=s.strip()
+ if not s:
+ continue
+ if s=='None':
+ return_values.append(None)
+ elif(s[0]=="'"and s[-1]=="'")or(s[0]=='"'and s[-1]=='"'):
+ return_values.append(eval(s))
+ elif s[0].isdigit():
+ return_values.append(int(s))
+ else:break
+ return return_values
+@conf
+def test_pyembed(self,mode,msg='Testing pyembed configuration'):
+ 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))
+@conf
+def test_pyext(self,mode,msg='Testing pyext configuration'):
+ 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))
+@conf
+def python_cross_compile(self,features='pyembed pyext'):
+ features=Utils.to_list(features)
+ if not('PYTHON_LDFLAGS'in self.environ or'PYTHON_PYEXT_LDFLAGS'in self.environ or'PYTHON_PYEMBED_LDFLAGS'in self.environ):
+ return False
+ for x in'PYTHON_VERSION PYTAG pyext_PATTERN'.split():
+ if not x in self.environ:
+ self.fatal('Please set %s in the os environment'%x)
+ else:
+ self.env[x]=self.environ[x]
+ xx=self.env.CXX_NAME and'cxx'or'c'
+ if'pyext'in features:
+ flags=self.environ.get('PYTHON_PYEXT_LDFLAGS',self.environ.get('PYTHON_LDFLAGS',None))
+ if flags is None:
+ self.fatal('No flags provided through PYTHON_PYEXT_LDFLAGS as required')
+ else:
+ self.parse_flags(flags,'PYEXT')
+ self.test_pyext(xx)
+ if'pyembed'in features:
+ flags=self.environ.get('PYTHON_PYEMBED_LDFLAGS',self.environ.get('PYTHON_LDFLAGS',None))
+ if flags is None:
+ self.fatal('No flags provided through PYTHON_PYEMBED_LDFLAGS as required')
+ else:
+ self.parse_flags(flags,'PYEMBED')
+ self.test_pyembed(xx)
+ return True
+@conf
+def check_python_headers(conf,features='pyembed pyext'):
+ features=Utils.to_list(features)
+ assert('pyembed'in features)or('pyext'in features),"check_python_headers features must include 'pyembed' and/or 'pyext'"
+ env=conf.env
+ if not env['CC_NAME']and not env['CXX_NAME']:
+ conf.fatal('load a compiler first (gcc, g++, ..)')
+ if conf.python_cross_compile(features):
+ return
+ if not env['PYTHON_VERSION']:
+ conf.check_python_version()
+ pybin=env.PYTHON
+ if not pybin:
+ conf.fatal('Could not find the python executable')
+ v='prefix SO LDFLAGS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET LDSHARED CFLAGS LDVERSION'.split()
+ try:
+ lst=conf.get_python_variables(["get_config_var('%s') or ''"%x for x in v])
+ except RuntimeError:
+ conf.fatal("Python development headers not found (-v for details).")
+ vals=['%s = %r'%(x,y)for(x,y)in zip(v,lst)]
+ conf.to_log("Configuration returned from %r:\n%s\n"%(pybin,'\n'.join(vals)))
+ dct=dict(zip(v,lst))
+ x='MACOSX_DEPLOYMENT_TARGET'
+ if dct[x]:
+ env[x]=conf.environ[x]=dct[x]
+ env['pyext_PATTERN']='%s'+dct['SO']
+ num='.'.join(env['PYTHON_VERSION'].split('.')[:2])
+ 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)
+ if env.PYTHON_CONFIG:
+ all_flags=[['--cflags','--libs','--ldflags']]
+ if sys.hexversion<0x2070000:
+ all_flags=[[k]for k in all_flags[0]]
+ xx=env.CXX_NAME and'cxx'or'c'
+ if'pyembed'in features:
+ for flags in all_flags:
+ conf.check_cfg(msg='Asking python-config for pyembed %r flags'%' '.join(flags),path=env.PYTHON_CONFIG,package='',uselib_store='PYEMBED',args=flags)
+ try:
+ conf.test_pyembed(xx)
+ except conf.errors.ConfigurationError:
+ if dct['Py_ENABLE_SHARED']and dct['LIBDIR']:
+ env.append_unique('LIBPATH_PYEMBED',[dct['LIBDIR']])
+ conf.test_pyembed(xx)
+ else:
+ raise
+ if'pyext'in features:
+ for flags in all_flags:
+ conf.check_cfg(msg='Asking python-config for pyext %r flags'%' '.join(flags),path=env.PYTHON_CONFIG,package='',uselib_store='PYEXT',args=flags)
+ try:
+ conf.test_pyext(xx)
+ except conf.errors.ConfigurationError:
+ if dct['Py_ENABLE_SHARED']and dct['LIBDIR']:
+ env.append_unique('LIBPATH_PYEXT',[dct['LIBDIR']])
+ conf.test_pyext(xx)
+ else:
+ raise
+ conf.define('HAVE_PYTHON_H',1)
+ return
+ all_flags=dct['LDFLAGS']+' '+dct['CFLAGS']
+ conf.parse_flags(all_flags,'PYEMBED')
+ all_flags=dct['LDFLAGS']+' '+dct['LDSHARED']+' '+dct['CFLAGS']
+ conf.parse_flags(all_flags,'PYEXT')
+ result=None
+ if not dct["LDVERSION"]:
+ dct["LDVERSION"]=env['PYTHON_VERSION']
+ for name in('python'+dct['LDVERSION'],'python'+env['PYTHON_VERSION']+'m','python'+env['PYTHON_VERSION'].replace('.','')):
+ if not result and env['LIBPATH_PYEMBED']:
+ path=env['LIBPATH_PYEMBED']
+ conf.to_log("\n\n# Trying default LIBPATH_PYEMBED: %r\n"%path)
+ result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in LIBPATH_PYEMBED'%name)
+ if not result and dct['LIBDIR']:
+ path=[dct['LIBDIR']]
+ conf.to_log("\n\n# try again with -L$python_LIBDIR: %r\n"%path)
+ result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in LIBDIR'%name)
+ if not result and dct['LIBPL']:
+ path=[dct['LIBPL']]
+ conf.to_log("\n\n# try again with -L$python_LIBPL (some systems don't install the python library in $prefix/lib)\n")
+ result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in python_LIBPL'%name)
+ if not result:
+ path=[os.path.join(dct['prefix'],"libs")]
+ conf.to_log("\n\n# try again with -L$prefix/libs, and pythonXY name rather than pythonX.Y (win32)\n")
+ result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in $prefix/libs'%name)
+ if result:
+ break
+ if result:
+ env['LIBPATH_PYEMBED']=path
+ env.append_value('LIB_PYEMBED',[name])
+ else:
+ conf.to_log("\n\n### LIB NOT FOUND\n")
+ if Utils.is_win32 or dct['Py_ENABLE_SHARED']:
+ env['LIBPATH_PYEXT']=env['LIBPATH_PYEMBED']
+ env['LIB_PYEXT']=env['LIB_PYEMBED']
+ conf.to_log("Include path for Python extensions (found via distutils module): %r\n"%(dct['INCLUDEPY'],))
+ env['INCLUDES_PYEXT']=[dct['INCLUDEPY']]
+ env['INCLUDES_PYEMBED']=[dct['INCLUDEPY']]
+ if env['CC_NAME']=='gcc':
+ env.append_value('CFLAGS_PYEMBED',['-fno-strict-aliasing'])
+ env.append_value('CFLAGS_PYEXT',['-fno-strict-aliasing'])
+ if env['CXX_NAME']=='gcc':
+ env.append_value('CXXFLAGS_PYEMBED',['-fno-strict-aliasing'])
+ env.append_value('CXXFLAGS_PYEXT',['-fno-strict-aliasing'])
+ if env.CC_NAME=="msvc":
+ from distutils.msvccompiler import MSVCCompiler
+ dist_compiler=MSVCCompiler()
+ dist_compiler.initialize()
+ env.append_value('CFLAGS_PYEXT',dist_compiler.compile_options)
+ env.append_value('CXXFLAGS_PYEXT',dist_compiler.compile_options)
+ env.append_value('LINKFLAGS_PYEXT',dist_compiler.ldflags_shared)
+ 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!')
+@conf
+def check_python_version(conf,minver=None):
+ assert minver is None or isinstance(minver,tuple)
+ pybin=conf.env['PYTHON']
+ if not pybin:
+ conf.fatal('could not find the python executable')
+ cmd=pybin+['-c','import sys\nfor x in sys.version_info: print(str(x))']
+ Logs.debug('python: Running python command %r'%cmd)
+ lines=conf.cmd_and_log(cmd).split()
+ assert len(lines)==5,"found %i lines, expected 5: %r"%(len(lines),lines)
+ pyver_tuple=(int(lines[0]),int(lines[1]),int(lines[2]),lines[3],int(lines[4]))
+ result=(minver is None)or(pyver_tuple>=minver)
+ if result:
+ pyver='.'.join([str(x)for x in pyver_tuple[:2]])
+ conf.env['PYTHON_VERSION']=pyver
+ if'PYTHONDIR'in conf.env:
+ pydir=conf.env['PYTHONDIR']
+ elif'PYTHONDIR'in conf.environ:
+ pydir=conf.environ['PYTHONDIR']
+ else:
+ if Utils.is_win32:
+ (python_LIBDEST,pydir)=conf.get_python_variables(["get_config_var('LIBDEST') or ''","get_python_lib(standard_lib=0) or ''"])
+ else:
+ python_LIBDEST=None
+ (pydir,)=conf.get_python_variables(["get_python_lib(standard_lib=0, prefix=%r) or ''"%conf.env.PREFIX])
+ if python_LIBDEST is None:
+ if conf.env['LIBDIR']:
+ python_LIBDEST=os.path.join(conf.env['LIBDIR'],"python"+pyver)
+ else:
+ python_LIBDEST=os.path.join(conf.env['PREFIX'],"lib","python"+pyver)
+ if'PYTHONARCHDIR'in conf.env:
+ pyarchdir=conf.env['PYTHONARCHDIR']
+ elif'PYTHONARCHDIR'in conf.environ:
+ pyarchdir=conf.environ['PYTHONARCHDIR']
+ else:
+ (pyarchdir,)=conf.get_python_variables(["get_python_lib(plat_specific=1, standard_lib=0, prefix=%r) or ''"%conf.env.PREFIX])
+ if not pyarchdir:
+ pyarchdir=pydir
+ if hasattr(conf,'define'):
+ conf.define('PYTHONDIR',pydir)
+ conf.define('PYTHONARCHDIR',pyarchdir)
+ conf.env['PYTHONDIR']=pydir
+ conf.env['PYTHONARCHDIR']=pyarchdir
+ pyver_full='.'.join(map(str,pyver_tuple[:3]))
+ if minver is None:
+ conf.msg('Checking for python version',pyver_full)
+ else:
+ minver_str='.'.join(map(str,minver))
+ conf.msg('Checking for python version',pyver_tuple,">= %s"%(minver_str,)and'GREEN'or'YELLOW')
+ if not result:
+ conf.fatal('The python version is too old, expecting %r'%(minver,))
+PYTHON_MODULE_TEMPLATE='''
+import %s as current_module
+version = getattr(current_module, '__version__', None)
+if version is not None:
+ print(str(version))
+else:
+ print('unknown version')
+'''
+@conf
+def check_python_module(conf,module_name,condition=''):
+ msg="Checking for python module '%s'"%module_name
+ if condition:
+ msg='%s (%s)'%(msg,condition)
+ conf.start_msg(msg)
+ try:
+ ret=conf.cmd_and_log(conf.env['PYTHON']+['-c',PYTHON_MODULE_TEMPLATE%module_name])
+ except Exception:
+ conf.end_msg(False)
+ conf.fatal('Could not find the python module %r'%module_name)
+ ret=ret.strip()
+ if condition:
+ conf.end_msg(ret)
+ if ret=='unknown version':
+ conf.fatal('Could not check the %s version'%module_name)
+ from distutils.version import LooseVersion
+ def num(*k):
+ if isinstance(k[0],int):
+ return LooseVersion('.'.join([str(x)for x in k]))
+ else:
+ return LooseVersion(k[0])
+ d={'num':num,'ver':LooseVersion(ret)}
+ ev=eval(condition,{},d)
+ if not ev:
+ conf.fatal('The %s version does not satisfy the requirements'%module_name)
+ else:
+ if ret=='unknown version':
+ conf.end_msg(True)
+ else:
+ conf.end_msg(ret)
+def configure(conf):
+ v=conf.env
+ v['PYTHON']=Options.options.python or os.environ.get('PYTHON',sys.executable)
+ if Options.options.pythondir:
+ v['PYTHONDIR']=Options.options.pythondir
+ if Options.options.pythonarchdir:
+ v['PYTHONARCHDIR']=Options.options.pythonarchdir
+ conf.find_program('python',var='PYTHON')
+ v['PYFLAGS']=''
+ v['PYFLAGS_OPT']='-O'
+ v['PYC']=getattr(Options.options,'pyc',1)
+ v['PYO']=getattr(Options.options,'pyo',1)
+ try:
+ v.PYTAG=conf.cmd_and_log(conf.env.PYTHON+['-c',"import imp;print(imp.get_tag())"]).strip()
+ except Errors.WafError:
+ pass
+def options(opt):
+ pyopt=opt.add_option_group("Python Options")
+ pyopt.add_option('--nopyc',dest='pyc',action='store_false',default=1,help='Do not install bytecode compiled .pyc files (configuration) [Default:install]')
+ pyopt.add_option('--nopyo',dest='pyo',action='store_false',default=1,help='Do not install optimised compiled .pyo files (configuration) [Default:install]')
+ pyopt.add_option('--python',dest="python",help='python binary to be used [Default: %s]'%sys.executable)
+ pyopt.add_option('--pythondir',dest='pythondir',help='Installation path for python modules (py, platform-independent .py and .pyc files)')
+ pyopt.add_option('--pythonarchdir',dest='pythonarchdir',help='Installation path for python extension (pyext, platform-dependent .so or .dylib files)')
diff --git a/waflib/Tools/qt4.py b/waflib/Tools/qt4.py
new file mode 100644
index 0000000..896c5b4
--- /dev/null
+++ b/waflib/Tools/qt4.py
@@ -0,0 +1,442 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+try:
+ from xml.sax import make_parser
+ from xml.sax.handler import ContentHandler
+except ImportError:
+ has_xml=False
+ ContentHandler=object
+else:
+ has_xml=True
+import os,sys
+from waflib.Tools import cxx
+from waflib import Task,Utils,Options,Errors,Context
+from waflib.TaskGen import feature,after_method,extension
+from waflib.Configure import conf
+from waflib import Logs
+MOC_H=['.h','.hpp','.hxx','.hh']
+EXT_RCC=['.qrc']
+EXT_UI=['.ui']
+EXT_QT4=['.cpp','.cc','.cxx','.C']
+QT4_LIBS="QtCore QtGui QtUiTools QtNetwork QtOpenGL QtSql QtSvg QtTest QtXml QtXmlPatterns QtWebKit Qt3Support QtHelp QtScript QtDeclarative QtDesigner"
+class qxx(Task.classes['cxx']):
+ def __init__(self,*k,**kw):
+ Task.Task.__init__(self,*k,**kw)
+ self.moc_done=0
+ def runnable_status(self):
+ if self.moc_done:
+ return Task.Task.runnable_status(self)
+ else:
+ for t in self.run_after:
+ if not t.hasrun:
+ return Task.ASK_LATER
+ self.add_moc_tasks()
+ return Task.Task.runnable_status(self)
+ def create_moc_task(self,h_node,m_node):
+ try:
+ moc_cache=self.generator.bld.moc_cache
+ except AttributeError:
+ moc_cache=self.generator.bld.moc_cache={}
+ try:
+ return moc_cache[h_node]
+ except KeyError:
+ tsk=moc_cache[h_node]=Task.classes['moc'](env=self.env,generator=self.generator)
+ tsk.set_inputs(h_node)
+ tsk.set_outputs(m_node)
+ if self.generator:
+ self.generator.tasks.append(tsk)
+ gen=self.generator.bld.producer
+ gen.outstanding.insert(0,tsk)
+ gen.total+=1
+ return tsk
+ def moc_h_ext(self):
+ ext=[]
+ try:
+ ext=Options.options.qt_header_ext.split()
+ except AttributeError:
+ pass
+ if not ext:
+ ext=MOC_H
+ return ext
+ def add_moc_tasks(self):
+ node=self.inputs[0]
+ bld=self.generator.bld
+ try:
+ self.signature()
+ except KeyError:
+ pass
+ else:
+ delattr(self,'cache_sig')
+ include_nodes=[node.parent]+self.generator.includes_nodes
+ moctasks=[]
+ mocfiles=set([])
+ for d in bld.raw_deps.get(self.uid(),[]):
+ if not d.endswith('.moc'):
+ continue
+ if d in mocfiles:
+ continue
+ mocfiles.add(d)
+ h_node=None
+ base2=d[:-4]
+ for x in include_nodes:
+ for e in self.moc_h_ext():
+ h_node=x.find_node(base2+e)
+ if h_node:
+ break
+ if h_node:
+ m_node=h_node.change_ext('.moc')
+ break
+ else:
+ for k in EXT_QT4:
+ if base2.endswith(k):
+ for x in include_nodes:
+ h_node=x.find_node(base2)
+ if h_node:
+ break
+ if h_node:
+ m_node=h_node.change_ext(k+'.moc')
+ break
+ if not h_node:
+ raise Errors.WafError('No source found for %r which is a moc file'%d)
+ task=self.create_moc_task(h_node,m_node)
+ moctasks.append(task)
+ self.run_after.update(set(moctasks))
+ self.moc_done=1
+class trans_update(Task.Task):
+ run_str='${QT_LUPDATE} ${SRC} -ts ${TGT}'
+ color='BLUE'
+Task.update_outputs(trans_update)
+class XMLHandler(ContentHandler):
+ def __init__(self):
+ self.buf=[]
+ self.files=[]
+ def startElement(self,name,attrs):
+ if name=='file':
+ self.buf=[]
+ def endElement(self,name):
+ if name=='file':
+ self.files.append(str(''.join(self.buf)))
+ def characters(self,cars):
+ self.buf.append(cars)
+@extension(*EXT_RCC)
+def create_rcc_task(self,node):
+ rcnode=node.change_ext('_rc.cpp')
+ self.create_task('rcc',node,rcnode)
+ cpptask=self.create_task('cxx',rcnode,rcnode.change_ext('.o'))
+ try:
+ self.compiled_tasks.append(cpptask)
+ except AttributeError:
+ self.compiled_tasks=[cpptask]
+ return cpptask
+@extension(*EXT_UI)
+def create_uic_task(self,node):
+ uictask=self.create_task('ui4',node)
+ uictask.outputs=[self.path.find_or_declare(self.env['ui_PATTERN']%node.name[:-3])]
+@extension('.ts')
+def add_lang(self,node):
+ self.lang=self.to_list(getattr(self,'lang',[]))+[node]
+@feature('qt4')
+@after_method('apply_link')
+def apply_qt4(self):
+ if getattr(self,'lang',None):
+ qmtasks=[]
+ for x in self.to_list(self.lang):
+ if isinstance(x,str):
+ x=self.path.find_resource(x+'.ts')
+ qmtasks.append(self.create_task('ts2qm',x,x.change_ext('.qm')))
+ if getattr(self,'update',None)and Options.options.trans_qt4:
+ cxxnodes=[a.inputs[0]for a in self.compiled_tasks]+[a.inputs[0]for a in self.tasks if getattr(a,'inputs',None)and a.inputs[0].name.endswith('.ui')]
+ for x in qmtasks:
+ self.create_task('trans_update',cxxnodes,x.inputs)
+ if getattr(self,'langname',None):
+ qmnodes=[x.outputs[0]for x in qmtasks]
+ rcnode=self.langname
+ if isinstance(rcnode,str):
+ rcnode=self.path.find_or_declare(rcnode+'.qrc')
+ t=self.create_task('qm2rcc',qmnodes,rcnode)
+ k=create_rcc_task(self,t.outputs[0])
+ self.link_task.inputs.append(k.outputs[0])
+ lst=[]
+ for flag in self.to_list(self.env['CXXFLAGS']):
+ if len(flag)<2:continue
+ f=flag[0:2]
+ if f in('-D','-I','/D','/I'):
+ if(f[0]=='/'):
+ lst.append('-'+flag[1:])
+ else:
+ lst.append(flag)
+ self.env.append_value('MOC_FLAGS',lst)
+@extension(*EXT_QT4)
+def cxx_hook(self,node):
+ return self.create_compiled_task('qxx',node)
+class rcc(Task.Task):
+ color='BLUE'
+ run_str='${QT_RCC} -name ${tsk.rcname()} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}'
+ ext_out=['.h']
+ def rcname(self):
+ return os.path.splitext(self.inputs[0].name)[0]
+ def scan(self):
+ if not has_xml:
+ Logs.error('no xml support was found, the rcc dependencies will be incomplete!')
+ return([],[])
+ parser=make_parser()
+ curHandler=XMLHandler()
+ parser.setContentHandler(curHandler)
+ fi=open(self.inputs[0].abspath(),'r')
+ try:
+ parser.parse(fi)
+ finally:
+ fi.close()
+ nodes=[]
+ names=[]
+ root=self.inputs[0].parent
+ for x in curHandler.files:
+ nd=root.find_resource(x)
+ if nd:nodes.append(nd)
+ else:names.append(x)
+ return(nodes,names)
+class moc(Task.Task):
+ color='BLUE'
+ run_str='${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}'
+ def keyword(self):
+ return"Creating"
+ def __str__(self):
+ return self.outputs[0].path_from(self.generator.bld.launch_node())
+class ui4(Task.Task):
+ color='BLUE'
+ run_str='${QT_UIC} ${SRC} -o ${TGT}'
+ ext_out=['.h']
+class ts2qm(Task.Task):
+ color='BLUE'
+ run_str='${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}'
+class qm2rcc(Task.Task):
+ color='BLUE'
+ after='ts2qm'
+ def run(self):
+ txt='\n'.join(['<file>%s</file>'%k.path_from(self.outputs[0].parent)for k in self.inputs])
+ code='<!DOCTYPE RCC><RCC version="1.0">\n<qresource>\n%s\n</qresource>\n</RCC>'%txt
+ self.outputs[0].write(code)
+def configure(self):
+ self.find_qt4_binaries()
+ self.set_qt4_libs_to_check()
+ self.set_qt4_defines()
+ self.find_qt4_libraries()
+ self.add_qt4_rpath()
+ self.simplify_qt4_libs()
+@conf
+def find_qt4_binaries(self):
+ env=self.env
+ opt=Options.options
+ qtdir=getattr(opt,'qtdir','')
+ qtbin=getattr(opt,'qtbin','')
+ paths=[]
+ if qtdir:
+ qtbin=os.path.join(qtdir,'bin')
+ if not qtdir:
+ qtdir=os.environ.get('QT4_ROOT','')
+ qtbin=os.environ.get('QT4_BIN',None)or os.path.join(qtdir,'bin')
+ if qtbin:
+ paths=[qtbin]
+ if not qtdir:
+ paths=os.environ.get('PATH','').split(os.pathsep)
+ paths.append('/usr/share/qt4/bin/')
+ try:
+ lst=Utils.listdir('/usr/local/Trolltech/')
+ except OSError:
+ pass
+ else:
+ if lst:
+ lst.sort()
+ lst.reverse()
+ qtdir='/usr/local/Trolltech/%s/'%lst[0]
+ qtbin=os.path.join(qtdir,'bin')
+ paths.append(qtbin)
+ cand=None
+ prev_ver=['4','0','0']
+ for qmk in('qmake-qt4','qmake4','qmake'):
+ try:
+ qmake=self.find_program(qmk,path_list=paths)
+ except self.errors.ConfigurationError:
+ pass
+ else:
+ try:
+ version=self.cmd_and_log(qmake+['-query','QT_VERSION']).strip()
+ except self.errors.WafError:
+ pass
+ else:
+ if version:
+ new_ver=version.split('.')
+ if new_ver>prev_ver:
+ cand=qmake
+ prev_ver=new_ver
+ if cand:
+ self.env.QMAKE=cand
+ else:
+ self.fatal('Could not find qmake for qt4')
+ qtbin=self.cmd_and_log(self.env.QMAKE+['-query','QT_INSTALL_BINS']).strip()+os.sep
+ def find_bin(lst,var):
+ if var in env:
+ return
+ for f in lst:
+ try:
+ ret=self.find_program(f,path_list=paths)
+ except self.errors.ConfigurationError:
+ pass
+ else:
+ env[var]=ret
+ break
+ find_bin(['uic-qt3','uic3'],'QT_UIC3')
+ find_bin(['uic-qt4','uic'],'QT_UIC')
+ if not env.QT_UIC:
+ self.fatal('cannot find the uic compiler for qt4')
+ self.start_msg('Checking for uic version')
+ uicver=self.cmd_and_log(env.QT_UIC+["-version"],output=Context.BOTH)
+ uicver=''.join(uicver).strip()
+ uicver=uicver.replace('Qt User Interface Compiler ','').replace('User Interface Compiler for Qt','')
+ self.end_msg(uicver)
+ if uicver.find(' 3.')!=-1:
+ self.fatal('this uic compiler is for qt3, add uic for qt4 to your path')
+ find_bin(['moc-qt4','moc'],'QT_MOC')
+ find_bin(['rcc-qt4','rcc'],'QT_RCC')
+ find_bin(['lrelease-qt4','lrelease'],'QT_LRELEASE')
+ find_bin(['lupdate-qt4','lupdate'],'QT_LUPDATE')
+ env['UIC3_ST']='%s -o %s'
+ env['UIC_ST']='%s -o %s'
+ env['MOC_ST']='-o'
+ env['ui_PATTERN']='ui_%s.h'
+ env['QT_LRELEASE_FLAGS']=['-silent']
+ env.MOCCPPPATH_ST='-I%s'
+ env.MOCDEFINES_ST='-D%s'
+@conf
+def find_qt4_libraries(self):
+ qtlibs=getattr(Options.options,'qtlibs',None)or os.environ.get("QT4_LIBDIR",None)
+ if not qtlibs:
+ try:
+ qtlibs=self.cmd_and_log(self.env.QMAKE+['-query','QT_INSTALL_LIBS']).strip()
+ except Errors.WafError:
+ qtdir=self.cmd_and_log(self.env.QMAKE+['-query','QT_INSTALL_PREFIX']).strip()+os.sep
+ qtlibs=os.path.join(qtdir,'lib')
+ self.msg('Found the Qt4 libraries in',qtlibs)
+ qtincludes=os.environ.get("QT4_INCLUDES",None)or self.cmd_and_log(self.env.QMAKE+['-query','QT_INSTALL_HEADERS']).strip()
+ env=self.env
+ if not'PKG_CONFIG_PATH'in os.environ:
+ os.environ['PKG_CONFIG_PATH']='%s:%s/pkgconfig:/usr/lib/qt4/lib/pkgconfig:/opt/qt4/lib/pkgconfig:/usr/lib/qt4/lib:/opt/qt4/lib'%(qtlibs,qtlibs)
+ try:
+ if os.environ.get("QT4_XCOMPILE",None):
+ raise self.errors.ConfigurationError()
+ self.check_cfg(atleast_pkgconfig_version='0.1')
+ except self.errors.ConfigurationError:
+ for i in self.qt4_vars:
+ uselib=i.upper()
+ if Utils.unversioned_sys_platform()=="darwin":
+ frameworkName=i+".framework"
+ qtDynamicLib=os.path.join(qtlibs,frameworkName,i)
+ if os.path.exists(qtDynamicLib):
+ env.append_unique('FRAMEWORK_'+uselib,i)
+ self.msg('Checking for %s'%i,qtDynamicLib,'GREEN')
+ else:
+ self.msg('Checking for %s'%i,False,'YELLOW')
+ env.append_unique('INCLUDES_'+uselib,os.path.join(qtlibs,frameworkName,'Headers'))
+ elif env.DEST_OS!="win32":
+ qtDynamicLib=os.path.join(qtlibs,"lib"+i+".so")
+ qtStaticLib=os.path.join(qtlibs,"lib"+i+".a")
+ if os.path.exists(qtDynamicLib):
+ env.append_unique('LIB_'+uselib,i)
+ self.msg('Checking for %s'%i,qtDynamicLib,'GREEN')
+ elif os.path.exists(qtStaticLib):
+ env.append_unique('LIB_'+uselib,i)
+ self.msg('Checking for %s'%i,qtStaticLib,'GREEN')
+ else:
+ self.msg('Checking for %s'%i,False,'YELLOW')
+ env.append_unique('LIBPATH_'+uselib,qtlibs)
+ env.append_unique('INCLUDES_'+uselib,qtincludes)
+ env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i))
+ else:
+ for k in("lib%s.a","lib%s4.a","%s.lib","%s4.lib"):
+ lib=os.path.join(qtlibs,k%i)
+ if os.path.exists(lib):
+ env.append_unique('LIB_'+uselib,i+k[k.find("%s")+2:k.find('.')])
+ self.msg('Checking for %s'%i,lib,'GREEN')
+ break
+ else:
+ self.msg('Checking for %s'%i,False,'YELLOW')
+ env.append_unique('LIBPATH_'+uselib,qtlibs)
+ env.append_unique('INCLUDES_'+uselib,qtincludes)
+ env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i))
+ uselib=i.upper()+"_debug"
+ for k in("lib%sd.a","lib%sd4.a","%sd.lib","%sd4.lib"):
+ lib=os.path.join(qtlibs,k%i)
+ if os.path.exists(lib):
+ env.append_unique('LIB_'+uselib,i+k[k.find("%s")+2:k.find('.')])
+ self.msg('Checking for %s'%i,lib,'GREEN')
+ break
+ else:
+ self.msg('Checking for %s'%i,False,'YELLOW')
+ env.append_unique('LIBPATH_'+uselib,qtlibs)
+ env.append_unique('INCLUDES_'+uselib,qtincludes)
+ env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i))
+ else:
+ for i in self.qt4_vars_debug+self.qt4_vars:
+ self.check_cfg(package=i,args='--cflags --libs',mandatory=False)
+@conf
+def simplify_qt4_libs(self):
+ env=self.env
+ def process_lib(vars_,coreval):
+ for d in vars_:
+ var=d.upper()
+ if var=='QTCORE':
+ continue
+ value=env['LIBPATH_'+var]
+ if value:
+ core=env[coreval]
+ accu=[]
+ for lib in value:
+ if lib in core:
+ continue
+ accu.append(lib)
+ env['LIBPATH_'+var]=accu
+ process_lib(self.qt4_vars,'LIBPATH_QTCORE')
+ process_lib(self.qt4_vars_debug,'LIBPATH_QTCORE_DEBUG')
+@conf
+def add_qt4_rpath(self):
+ env=self.env
+ if getattr(Options.options,'want_rpath',False):
+ def process_rpath(vars_,coreval):
+ for d in vars_:
+ var=d.upper()
+ value=env['LIBPATH_'+var]
+ if value:
+ core=env[coreval]
+ accu=[]
+ for lib in value:
+ if var!='QTCORE':
+ if lib in core:
+ continue
+ accu.append('-Wl,--rpath='+lib)
+ env['RPATH_'+var]=accu
+ process_rpath(self.qt4_vars,'LIBPATH_QTCORE')
+ process_rpath(self.qt4_vars_debug,'LIBPATH_QTCORE_DEBUG')
+@conf
+def set_qt4_libs_to_check(self):
+ if not hasattr(self,'qt4_vars'):
+ self.qt4_vars=QT4_LIBS
+ self.qt4_vars=Utils.to_list(self.qt4_vars)
+ if not hasattr(self,'qt4_vars_debug'):
+ self.qt4_vars_debug=[a+'_debug'for a in self.qt4_vars]
+ self.qt4_vars_debug=Utils.to_list(self.qt4_vars_debug)
+@conf
+def set_qt4_defines(self):
+ if sys.platform!='win32':
+ return
+ for x in self.qt4_vars:
+ y=x[2:].upper()
+ self.env.append_unique('DEFINES_%s'%x.upper(),'QT_%s_LIB'%y)
+ self.env.append_unique('DEFINES_%s_DEBUG'%x.upper(),'QT_%s_LIB'%y)
+def options(opt):
+ opt.add_option('--want-rpath',action='store_true',default=False,dest='want_rpath',help='enable the rpath for qt libraries')
+ opt.add_option('--header-ext',type='string',default='',help='header extension for moc files',dest='qt_header_ext')
+ for i in'qtdir qtbin qtlibs'.split():
+ opt.add_option('--'+i,type='string',default='',dest=i)
+ opt.add_option('--translate',action="store_true",help="collect translation strings",dest="trans_qt4",default=False)
diff --git a/waflib/Tools/qt5.py b/waflib/Tools/qt5.py
new file mode 100644
index 0000000..f69c79d
--- /dev/null
+++ b/waflib/Tools/qt5.py
@@ -0,0 +1,489 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+try:
+ from xml.sax import make_parser
+ from xml.sax.handler import ContentHandler
+except ImportError:
+ has_xml=False
+ ContentHandler=object
+else:
+ has_xml=True
+import os,sys
+from waflib.Tools import cxx
+from waflib import Task,Utils,Options,Errors,Context
+from waflib.TaskGen import feature,after_method,extension
+from waflib.Configure import conf
+from waflib import Logs
+MOC_H=['.h','.hpp','.hxx','.hh']
+EXT_RCC=['.qrc']
+EXT_UI=['.ui']
+EXT_QT5=['.cpp','.cc','.cxx','.C']
+QT5_LIBS='''
+qtmain
+Qt5Bluetooth
+Qt5CLucene
+Qt5Concurrent
+Qt5Core
+Qt5DBus
+Qt5Declarative
+Qt5DesignerComponents
+Qt5Designer
+Qt5Gui
+Qt5Help
+Qt5MultimediaQuick_p
+Qt5Multimedia
+Qt5MultimediaWidgets
+Qt5Network
+Qt5Nfc
+Qt5OpenGL
+Qt5Positioning
+Qt5PrintSupport
+Qt5Qml
+Qt5QuickParticles
+Qt5Quick
+Qt5QuickTest
+Qt5Script
+Qt5ScriptTools
+Qt5Sensors
+Qt5SerialPort
+Qt5Sql
+Qt5Svg
+Qt5Test
+Qt5WebKit
+Qt5WebKitWidgets
+Qt5Widgets
+Qt5WinExtras
+Qt5X11Extras
+Qt5XmlPatterns
+Qt5Xml'''
+class qxx(Task.classes['cxx']):
+ def __init__(self,*k,**kw):
+ Task.Task.__init__(self,*k,**kw)
+ self.moc_done=0
+ def runnable_status(self):
+ if self.moc_done:
+ return Task.Task.runnable_status(self)
+ else:
+ for t in self.run_after:
+ if not t.hasrun:
+ return Task.ASK_LATER
+ self.add_moc_tasks()
+ return Task.Task.runnable_status(self)
+ def create_moc_task(self,h_node,m_node):
+ try:
+ moc_cache=self.generator.bld.moc_cache
+ except AttributeError:
+ moc_cache=self.generator.bld.moc_cache={}
+ try:
+ return moc_cache[h_node]
+ except KeyError:
+ tsk=moc_cache[h_node]=Task.classes['moc'](env=self.env,generator=self.generator)
+ tsk.set_inputs(h_node)
+ tsk.set_outputs(m_node)
+ if self.generator:
+ self.generator.tasks.append(tsk)
+ gen=self.generator.bld.producer
+ gen.outstanding.insert(0,tsk)
+ gen.total+=1
+ return tsk
+ else:
+ delattr(self,'cache_sig')
+ def moc_h_ext(self):
+ ext=[]
+ try:
+ ext=Options.options.qt_header_ext.split()
+ except AttributeError:
+ pass
+ if not ext:
+ ext=MOC_H
+ return ext
+ def add_moc_tasks(self):
+ node=self.inputs[0]
+ bld=self.generator.bld
+ try:
+ self.signature()
+ except KeyError:
+ pass
+ else:
+ delattr(self,'cache_sig')
+ include_nodes=[node.parent]+self.generator.includes_nodes
+ moctasks=[]
+ mocfiles=set([])
+ for d in bld.raw_deps.get(self.uid(),[]):
+ if not d.endswith('.moc'):
+ continue
+ if d in mocfiles:
+ continue
+ mocfiles.add(d)
+ h_node=None
+ base2=d[:-4]
+ for x in include_nodes:
+ for e in self.moc_h_ext():
+ h_node=x.find_node(base2+e)
+ if h_node:
+ break
+ if h_node:
+ m_node=h_node.change_ext('.moc')
+ break
+ else:
+ for k in EXT_QT5:
+ if base2.endswith(k):
+ for x in include_nodes:
+ h_node=x.find_node(base2)
+ if h_node:
+ break
+ if h_node:
+ m_node=h_node.change_ext(k+'.moc')
+ break
+ if not h_node:
+ raise Errors.WafError('No source found for %r which is a moc file'%d)
+ task=self.create_moc_task(h_node,m_node)
+ moctasks.append(task)
+ self.run_after.update(set(moctasks))
+ self.moc_done=1
+class trans_update(Task.Task):
+ run_str='${QT_LUPDATE} ${SRC} -ts ${TGT}'
+ color='BLUE'
+Task.update_outputs(trans_update)
+class XMLHandler(ContentHandler):
+ def __init__(self):
+ self.buf=[]
+ self.files=[]
+ def startElement(self,name,attrs):
+ if name=='file':
+ self.buf=[]
+ def endElement(self,name):
+ if name=='file':
+ self.files.append(str(''.join(self.buf)))
+ def characters(self,cars):
+ self.buf.append(cars)
+@extension(*EXT_RCC)
+def create_rcc_task(self,node):
+ rcnode=node.change_ext('_rc.cpp')
+ self.create_task('rcc',node,rcnode)
+ cpptask=self.create_task('cxx',rcnode,rcnode.change_ext('.o'))
+ try:
+ self.compiled_tasks.append(cpptask)
+ except AttributeError:
+ self.compiled_tasks=[cpptask]
+ return cpptask
+@extension(*EXT_UI)
+def create_uic_task(self,node):
+ uictask=self.create_task('ui5',node)
+ uictask.outputs=[self.path.find_or_declare(self.env['ui_PATTERN']%node.name[:-3])]
+@extension('.ts')
+def add_lang(self,node):
+ self.lang=self.to_list(getattr(self,'lang',[]))+[node]
+@feature('qt5')
+@after_method('apply_link')
+def apply_qt5(self):
+ if getattr(self,'lang',None):
+ qmtasks=[]
+ for x in self.to_list(self.lang):
+ if isinstance(x,str):
+ x=self.path.find_resource(x+'.ts')
+ qmtasks.append(self.create_task('ts2qm',x,x.change_ext('.qm')))
+ if getattr(self,'update',None)and Options.options.trans_qt5:
+ cxxnodes=[a.inputs[0]for a in self.compiled_tasks]+[a.inputs[0]for a in self.tasks if getattr(a,'inputs',None)and a.inputs[0].name.endswith('.ui')]
+ for x in qmtasks:
+ self.create_task('trans_update',cxxnodes,x.inputs)
+ if getattr(self,'langname',None):
+ qmnodes=[x.outputs[0]for x in qmtasks]
+ rcnode=self.langname
+ if isinstance(rcnode,str):
+ rcnode=self.path.find_or_declare(rcnode+'.qrc')
+ t=self.create_task('qm2rcc',qmnodes,rcnode)
+ k=create_rcc_task(self,t.outputs[0])
+ self.link_task.inputs.append(k.outputs[0])
+ lst=[]
+ for flag in self.to_list(self.env['CXXFLAGS']):
+ if len(flag)<2:continue
+ f=flag[0:2]
+ if f in('-D','-I','/D','/I'):
+ if(f[0]=='/'):
+ lst.append('-'+flag[1:])
+ else:
+ lst.append(flag)
+ self.env.append_value('MOC_FLAGS',lst)
+@extension(*EXT_QT5)
+def cxx_hook(self,node):
+ return self.create_compiled_task('qxx',node)
+class rcc(Task.Task):
+ color='BLUE'
+ run_str='${QT_RCC} -name ${tsk.rcname()} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}'
+ ext_out=['.h']
+ def rcname(self):
+ return os.path.splitext(self.inputs[0].name)[0]
+ def scan(self):
+ if not has_xml:
+ Logs.error('no xml support was found, the rcc dependencies will be incomplete!')
+ return([],[])
+ parser=make_parser()
+ curHandler=XMLHandler()
+ parser.setContentHandler(curHandler)
+ fi=open(self.inputs[0].abspath(),'r')
+ try:
+ parser.parse(fi)
+ finally:
+ fi.close()
+ nodes=[]
+ names=[]
+ root=self.inputs[0].parent
+ for x in curHandler.files:
+ nd=root.find_resource(x)
+ if nd:nodes.append(nd)
+ else:names.append(x)
+ return(nodes,names)
+class moc(Task.Task):
+ color='BLUE'
+ run_str='${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}'
+class ui5(Task.Task):
+ color='BLUE'
+ run_str='${QT_UIC} ${SRC} -o ${TGT}'
+ ext_out=['.h']
+class ts2qm(Task.Task):
+ color='BLUE'
+ run_str='${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}'
+class qm2rcc(Task.Task):
+ color='BLUE'
+ after='ts2qm'
+ def run(self):
+ txt='\n'.join(['<file>%s</file>'%k.path_from(self.outputs[0].parent)for k in self.inputs])
+ code='<!DOCTYPE RCC><RCC version="1.0">\n<qresource>\n%s\n</qresource>\n</RCC>'%txt
+ self.outputs[0].write(code)
+def configure(self):
+ self.find_qt5_binaries()
+ self.set_qt5_libs_to_check()
+ self.set_qt5_defines()
+ self.find_qt5_libraries()
+ self.add_qt5_rpath()
+ self.simplify_qt5_libs()
+@conf
+def find_qt5_binaries(self):
+ env=self.env
+ opt=Options.options
+ qtdir=getattr(opt,'qtdir','')
+ qtbin=getattr(opt,'qtbin','')
+ paths=[]
+ if qtdir:
+ qtbin=os.path.join(qtdir,'bin')
+ if not qtdir:
+ qtdir=os.environ.get('QT5_ROOT','')
+ qtbin=os.environ.get('QT5_BIN',None)or os.path.join(qtdir,'bin')
+ if qtbin:
+ paths=[qtbin]
+ if not qtdir:
+ paths=os.environ.get('PATH','').split(os.pathsep)
+ paths.append('/usr/share/qt5/bin/')
+ try:
+ lst=Utils.listdir('/usr/local/Trolltech/')
+ except OSError:
+ pass
+ else:
+ if lst:
+ lst.sort()
+ lst.reverse()
+ qtdir='/usr/local/Trolltech/%s/'%lst[0]
+ qtbin=os.path.join(qtdir,'bin')
+ paths.append(qtbin)
+ cand=None
+ prev_ver=['5','0','0']
+ for qmk in('qmake-qt5','qmake5','qmake'):
+ try:
+ qmake=self.find_program(qmk,path_list=paths)
+ except self.errors.ConfigurationError:
+ pass
+ else:
+ try:
+ version=self.cmd_and_log(qmake+['-query','QT_VERSION']).strip()
+ except self.errors.WafError:
+ pass
+ else:
+ if version:
+ new_ver=version.split('.')
+ if new_ver>prev_ver:
+ cand=qmake
+ prev_ver=new_ver
+ if not cand:
+ try:
+ self.find_program('qtchooser')
+ except self.errors.ConfigurationError:
+ pass
+ else:
+ cmd=self.env.QTCHOOSER+['-qt=5','-run-tool=qmake']
+ try:
+ version=self.cmd_and_log(cmd+['-query','QT_VERSION'])
+ except self.errors.WafError:
+ pass
+ else:
+ cand=cmd
+ if cand:
+ self.env.QMAKE=cand
+ else:
+ self.fatal('Could not find qmake for qt5')
+ self.env.QT_INSTALL_BINS=qtbin=self.cmd_and_log(self.env.QMAKE+['-query','QT_INSTALL_BINS']).strip()+os.sep
+ paths.insert(0,qtbin)
+ def find_bin(lst,var):
+ if var in env:
+ return
+ for f in lst:
+ try:
+ ret=self.find_program(f,path_list=paths)
+ except self.errors.ConfigurationError:
+ pass
+ else:
+ env[var]=ret
+ break
+ find_bin(['uic-qt5','uic'],'QT_UIC')
+ if not env.QT_UIC:
+ self.fatal('cannot find the uic compiler for qt5')
+ self.start_msg('Checking for uic version')
+ uicver=self.cmd_and_log(env.QT_UIC+['-version'],output=Context.BOTH)
+ uicver=''.join(uicver).strip()
+ uicver=uicver.replace('Qt User Interface Compiler ','').replace('User Interface Compiler for Qt','')
+ self.end_msg(uicver)
+ if uicver.find(' 3.')!=-1 or uicver.find(' 4.')!=-1:
+ self.fatal('this uic compiler is for qt3 or qt5, add uic for qt5 to your path')
+ find_bin(['moc-qt5','moc'],'QT_MOC')
+ find_bin(['rcc-qt5','rcc'],'QT_RCC')
+ find_bin(['lrelease-qt5','lrelease'],'QT_LRELEASE')
+ find_bin(['lupdate-qt5','lupdate'],'QT_LUPDATE')
+ env['UIC_ST']='%s -o %s'
+ env['MOC_ST']='-o'
+ env['ui_PATTERN']='ui_%s.h'
+ env['QT_LRELEASE_FLAGS']=['-silent']
+ env.MOCCPPPATH_ST='-I%s'
+ env.MOCDEFINES_ST='-D%s'
+@conf
+def find_qt5_libraries(self):
+ qtlibs=getattr(Options.options,'qtlibs',None)or os.environ.get("QT5_LIBDIR",None)
+ if not qtlibs:
+ try:
+ qtlibs=self.cmd_and_log(self.env.QMAKE+['-query','QT_INSTALL_LIBS']).strip()
+ except Errors.WafError:
+ qtdir=self.cmd_and_log(self.env.QMAKE+['-query','QT_INSTALL_PREFIX']).strip()+os.sep
+ qtlibs=os.path.join(qtdir,'lib')
+ self.msg('Found the Qt5 libraries in',qtlibs)
+ qtincludes=os.environ.get("QT5_INCLUDES",None)or self.cmd_and_log(self.env.QMAKE+['-query','QT_INSTALL_HEADERS']).strip()
+ env=self.env
+ if not'PKG_CONFIG_PATH'in os.environ:
+ os.environ['PKG_CONFIG_PATH']='%s:%s/pkgconfig:/usr/lib/qt5/lib/pkgconfig:/opt/qt5/lib/pkgconfig:/usr/lib/qt5/lib:/opt/qt5/lib'%(qtlibs,qtlibs)
+ try:
+ if os.environ.get("QT5_XCOMPILE",None):
+ raise self.errors.ConfigurationError()
+ self.check_cfg(atleast_pkgconfig_version='0.1')
+ except self.errors.ConfigurationError:
+ for i in self.qt5_vars:
+ uselib=i.upper()
+ if Utils.unversioned_sys_platform()=="darwin":
+ frameworkName=i+".framework"
+ qtDynamicLib=os.path.join(qtlibs,frameworkName,i)
+ if os.path.exists(qtDynamicLib):
+ env.append_unique('FRAMEWORK_'+uselib,i)
+ self.msg('Checking for %s'%i,qtDynamicLib,'GREEN')
+ else:
+ self.msg('Checking for %s'%i,False,'YELLOW')
+ env.append_unique('INCLUDES_'+uselib,os.path.join(qtlibs,frameworkName,'Headers'))
+ elif env.DEST_OS!="win32":
+ qtDynamicLib=os.path.join(qtlibs,"lib"+i+".so")
+ qtStaticLib=os.path.join(qtlibs,"lib"+i+".a")
+ if os.path.exists(qtDynamicLib):
+ env.append_unique('LIB_'+uselib,i)
+ self.msg('Checking for %s'%i,qtDynamicLib,'GREEN')
+ elif os.path.exists(qtStaticLib):
+ env.append_unique('LIB_'+uselib,i)
+ self.msg('Checking for %s'%i,qtStaticLib,'GREEN')
+ else:
+ self.msg('Checking for %s'%i,False,'YELLOW')
+ env.append_unique('LIBPATH_'+uselib,qtlibs)
+ env.append_unique('INCLUDES_'+uselib,qtincludes)
+ env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i))
+ else:
+ for k in("lib%s.a","lib%s5.a","%s.lib","%s5.lib"):
+ lib=os.path.join(qtlibs,k%i)
+ if os.path.exists(lib):
+ env.append_unique('LIB_'+uselib,i+k[k.find("%s")+2:k.find('.')])
+ self.msg('Checking for %s'%i,lib,'GREEN')
+ break
+ else:
+ self.msg('Checking for %s'%i,False,'YELLOW')
+ env.append_unique('LIBPATH_'+uselib,qtlibs)
+ env.append_unique('INCLUDES_'+uselib,qtincludes)
+ env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i.replace('Qt5','Qt')))
+ uselib=i.upper()+"_debug"
+ for k in("lib%sd.a","lib%sd5.a","%sd.lib","%sd5.lib"):
+ lib=os.path.join(qtlibs,k%i)
+ if os.path.exists(lib):
+ env.append_unique('LIB_'+uselib,i+k[k.find("%s")+2:k.find('.')])
+ self.msg('Checking for %s'%i,lib,'GREEN')
+ break
+ else:
+ self.msg('Checking for %s'%i,False,'YELLOW')
+ env.append_unique('LIBPATH_'+uselib,qtlibs)
+ env.append_unique('INCLUDES_'+uselib,qtincludes)
+ env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i.replace('Qt5','Qt')))
+ else:
+ for i in self.qt5_vars_debug+self.qt5_vars:
+ self.check_cfg(package=i,args='--cflags --libs',mandatory=False)
+@conf
+def simplify_qt5_libs(self):
+ env=self.env
+ def process_lib(vars_,coreval):
+ for d in vars_:
+ var=d.upper()
+ if var=='QTCORE':
+ continue
+ value=env['LIBPATH_'+var]
+ if value:
+ core=env[coreval]
+ accu=[]
+ for lib in value:
+ if lib in core:
+ continue
+ accu.append(lib)
+ env['LIBPATH_'+var]=accu
+ process_lib(self.qt5_vars,'LIBPATH_QTCORE')
+ process_lib(self.qt5_vars_debug,'LIBPATH_QTCORE_DEBUG')
+@conf
+def add_qt5_rpath(self):
+ env=self.env
+ if getattr(Options.options,'want_rpath',False):
+ def process_rpath(vars_,coreval):
+ for d in vars_:
+ var=d.upper()
+ value=env['LIBPATH_'+var]
+ if value:
+ core=env[coreval]
+ accu=[]
+ for lib in value:
+ if var!='QTCORE':
+ if lib in core:
+ continue
+ accu.append('-Wl,--rpath='+lib)
+ env['RPATH_'+var]=accu
+ process_rpath(self.qt5_vars,'LIBPATH_QTCORE')
+ process_rpath(self.qt5_vars_debug,'LIBPATH_QTCORE_DEBUG')
+@conf
+def set_qt5_libs_to_check(self):
+ if not hasattr(self,'qt5_vars'):
+ self.qt5_vars=QT5_LIBS
+ self.qt5_vars=Utils.to_list(self.qt5_vars)
+ if not hasattr(self,'qt5_vars_debug'):
+ self.qt5_vars_debug=[a+'_debug'for a in self.qt5_vars]
+ self.qt5_vars_debug=Utils.to_list(self.qt5_vars_debug)
+@conf
+def set_qt5_defines(self):
+ if sys.platform!='win32':
+ return
+ for x in self.qt5_vars:
+ y=x.replace('Qt5','Qt')[2:].upper()
+ self.env.append_unique('DEFINES_%s'%x.upper(),'QT_%s_LIB'%y)
+ self.env.append_unique('DEFINES_%s_DEBUG'%x.upper(),'QT_%s_LIB'%y)
+def options(opt):
+ opt.add_option('--want-rpath',action='store_true',default=False,dest='want_rpath',help='enable the rpath for qt libraries')
+ opt.add_option('--header-ext',type='string',default='',help='header extension for moc files',dest='qt_header_ext')
+ for i in'qtdir qtbin qtlibs'.split():
+ opt.add_option('--'+i,type='string',default='',dest=i)
+ opt.add_option('--translate',action="store_true",help="collect translation strings",dest="trans_qt5",default=False)
diff --git a/waflib/Tools/ruby.py b/waflib/Tools/ruby.py
new file mode 100644
index 0000000..39c170a
--- /dev/null
+++ b/waflib/Tools/ruby.py
@@ -0,0 +1,103 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os
+from waflib import Options,Utils,Task
+from waflib.TaskGen import before_method,feature,extension
+from waflib.Configure import conf
+@feature('rubyext')
+@before_method('apply_incpaths','apply_lib_vars','apply_bundle','apply_link')
+def init_rubyext(self):
+ self.install_path='${ARCHDIR_RUBY}'
+ self.uselib=self.to_list(getattr(self,'uselib',''))
+ if not'RUBY'in self.uselib:
+ self.uselib.append('RUBY')
+ if not'RUBYEXT'in self.uselib:
+ self.uselib.append('RUBYEXT')
+@feature('rubyext')
+@before_method('apply_link','propagate_uselib')
+def apply_ruby_so_name(self):
+ self.env['cshlib_PATTERN']=self.env['cxxshlib_PATTERN']=self.env['rubyext_PATTERN']
+@conf
+def check_ruby_version(self,minver=()):
+ if Options.options.rubybinary:
+ self.env.RUBY=Options.options.rubybinary
+ else:
+ self.find_program('ruby',var='RUBY')
+ ruby=self.env.RUBY
+ try:
+ version=self.cmd_and_log(ruby+['-e','puts defined?(VERSION) ? VERSION : RUBY_VERSION']).strip()
+ except Exception:
+ self.fatal('could not determine ruby version')
+ self.env.RUBY_VERSION=version
+ try:
+ ver=tuple(map(int,version.split(".")))
+ except Exception:
+ self.fatal('unsupported ruby version %r'%version)
+ cver=''
+ if minver:
+ if ver<minver:
+ self.fatal('ruby is too old %r'%ver)
+ cver='.'.join([str(x)for x in minver])
+ else:
+ cver=ver
+ self.msg('Checking for ruby version %s'%str(minver or''),cver)
+@conf
+def check_ruby_ext_devel(self):
+ if not self.env.RUBY:
+ self.fatal('ruby detection is required first')
+ if not self.env.CC_NAME and not self.env.CXX_NAME:
+ self.fatal('load a c/c++ compiler first')
+ version=tuple(map(int,self.env.RUBY_VERSION.split(".")))
+ def read_out(cmd):
+ return Utils.to_list(self.cmd_and_log(self.env.RUBY+['-rrbconfig','-e',cmd]))
+ def read_config(key):
+ return read_out('puts RbConfig::CONFIG[%r]'%key)
+ cpppath=archdir=read_config('archdir')
+ if version>=(1,9,0):
+ ruby_hdrdir=read_config('rubyhdrdir')
+ cpppath+=ruby_hdrdir
+ if version>=(2,0,0):
+ cpppath+=read_config('rubyarchhdrdir')
+ cpppath+=[os.path.join(ruby_hdrdir[0],read_config('arch')[0])]
+ self.check(header_name='ruby.h',includes=cpppath,errmsg='could not find ruby header file',link_header_test=False)
+ self.env.LIBPATH_RUBYEXT=read_config('libdir')
+ self.env.LIBPATH_RUBYEXT+=archdir
+ self.env.INCLUDES_RUBYEXT=cpppath
+ self.env.CFLAGS_RUBYEXT=read_config('CCDLFLAGS')
+ self.env.rubyext_PATTERN='%s.'+read_config('DLEXT')[0]
+ flags=read_config('LDSHARED')
+ while flags and flags[0][0]!='-':
+ flags=flags[1:]
+ if len(flags)>1 and flags[1]=="ppc":
+ flags=flags[2:]
+ self.env.LINKFLAGS_RUBYEXT=flags
+ self.env.LINKFLAGS_RUBYEXT+=read_config('LIBS')
+ self.env.LINKFLAGS_RUBYEXT+=read_config('LIBRUBYARG_SHARED')
+ if Options.options.rubyarchdir:
+ self.env.ARCHDIR_RUBY=Options.options.rubyarchdir
+ else:
+ self.env.ARCHDIR_RUBY=read_config('sitearchdir')[0]
+ if Options.options.rubylibdir:
+ self.env.LIBDIR_RUBY=Options.options.rubylibdir
+ else:
+ self.env.LIBDIR_RUBY=read_config('sitelibdir')[0]
+@conf
+def check_ruby_module(self,module_name):
+ self.start_msg('Ruby module %s'%module_name)
+ try:
+ self.cmd_and_log(self.env.RUBY+['-e','require \'%s\';puts 1'%module_name])
+ except Exception:
+ self.end_msg(False)
+ self.fatal('Could not find the ruby module %r'%module_name)
+ self.end_msg(True)
+@extension('.rb')
+def process(self,node):
+ return self.create_task('run_ruby',node)
+class run_ruby(Task.Task):
+ run_str='${RUBY} ${RBFLAGS} -I ${SRC[0].parent.abspath()} ${SRC}'
+def options(opt):
+ opt.add_option('--with-ruby-archdir',type='string',dest='rubyarchdir',help='Specify directory where to install arch specific files')
+ opt.add_option('--with-ruby-libdir',type='string',dest='rubylibdir',help='Specify alternate ruby library path')
+ opt.add_option('--with-ruby-binary',type='string',dest='rubybinary',help='Specify alternate ruby binary')
diff --git a/waflib/Tools/suncc.py b/waflib/Tools/suncc.py
new file mode 100644
index 0000000..f014abf
--- /dev/null
+++ b/waflib/Tools/suncc.py
@@ -0,0 +1,46 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_scc(conf):
+ v=conf.env
+ cc=conf.find_program('cc',var='CC')
+ try:
+ conf.cmd_and_log(cc+['-flags'])
+ except Exception:
+ conf.fatal('%r is not a Sun compiler'%cc)
+ v.CC_NAME='sun'
+ conf.get_suncc_version(cc)
+@conf
+def scc_common_flags(conf):
+ v=conf.env
+ v['CC_SRC_F']=[]
+ v['CC_TGT_F']=['-c','-o']
+ if not v['LINK_CC']:v['LINK_CC']=v['CC']
+ v['CCLNK_SRC_F']=''
+ v['CCLNK_TGT_F']=['-o']
+ v['CPPPATH_ST']='-I%s'
+ v['DEFINES_ST']='-D%s'
+ v['LIB_ST']='-l%s'
+ v['LIBPATH_ST']='-L%s'
+ v['STLIB_ST']='-l%s'
+ v['STLIBPATH_ST']='-L%s'
+ v['SONAME_ST']='-Wl,-h,%s'
+ v['SHLIB_MARKER']='-Bdynamic'
+ v['STLIB_MARKER']='-Bstatic'
+ v['cprogram_PATTERN']='%s'
+ v['CFLAGS_cshlib']=['-xcode=pic32','-DPIC']
+ v['LINKFLAGS_cshlib']=['-G']
+ v['cshlib_PATTERN']='lib%s.so'
+ v['LINKFLAGS_cstlib']=['-Bstatic']
+ v['cstlib_PATTERN']='lib%s.a'
+def configure(conf):
+ conf.find_scc()
+ conf.find_ar()
+ conf.scc_common_flags()
+ conf.cc_load_tools()
+ conf.cc_add_flags()
+ conf.link_add_flags()
diff --git a/waflib/Tools/suncxx.py b/waflib/Tools/suncxx.py
new file mode 100644
index 0000000..7130fdf
--- /dev/null
+++ b/waflib/Tools/suncxx.py
@@ -0,0 +1,46 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_sxx(conf):
+ v=conf.env
+ cc=conf.find_program(['CC','c++'],var='CXX')
+ try:
+ conf.cmd_and_log(cc+['-flags'])
+ except Exception:
+ conf.fatal('%r is not a Sun compiler'%cc)
+ v.CXX_NAME='sun'
+ conf.get_suncc_version(cc)
+@conf
+def sxx_common_flags(conf):
+ v=conf.env
+ v['CXX_SRC_F']=[]
+ v['CXX_TGT_F']=['-c','-o']
+ if not v['LINK_CXX']:v['LINK_CXX']=v['CXX']
+ v['CXXLNK_SRC_F']=[]
+ v['CXXLNK_TGT_F']=['-o']
+ v['CPPPATH_ST']='-I%s'
+ v['DEFINES_ST']='-D%s'
+ v['LIB_ST']='-l%s'
+ v['LIBPATH_ST']='-L%s'
+ v['STLIB_ST']='-l%s'
+ v['STLIBPATH_ST']='-L%s'
+ v['SONAME_ST']='-Wl,-h,%s'
+ v['SHLIB_MARKER']='-Bdynamic'
+ v['STLIB_MARKER']='-Bstatic'
+ v['cxxprogram_PATTERN']='%s'
+ v['CXXFLAGS_cxxshlib']=['-xcode=pic32','-DPIC']
+ v['LINKFLAGS_cxxshlib']=['-G']
+ v['cxxshlib_PATTERN']='lib%s.so'
+ v['LINKFLAGS_cxxstlib']=['-Bstatic']
+ v['cxxstlib_PATTERN']='lib%s.a'
+def configure(conf):
+ conf.find_sxx()
+ conf.find_ar()
+ conf.sxx_common_flags()
+ conf.cxx_load_tools()
+ conf.cxx_add_flags()
+ conf.link_add_flags()
diff --git a/waflib/Tools/tex.py b/waflib/Tools/tex.py
new file mode 100644
index 0000000..a91fd91
--- /dev/null
+++ b/waflib/Tools/tex.py
@@ -0,0 +1,317 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,re
+from waflib import Utils,Task,Errors,Logs,Node
+from waflib.TaskGen import feature,before_method
+re_bibunit=re.compile(r'\\(?P<type>putbib)\[(?P<file>[^\[\]]*)\]',re.M)
+def bibunitscan(self):
+ node=self.inputs[0]
+ nodes=[]
+ if not node:return nodes
+ code=node.read()
+ for match in re_bibunit.finditer(code):
+ path=match.group('file')
+ if path:
+ for k in('','.bib'):
+ Logs.debug('tex: trying %s%s'%(path,k))
+ fi=node.parent.find_resource(path+k)
+ if fi:
+ nodes.append(fi)
+ else:
+ Logs.debug('tex: could not find %s'%path)
+ Logs.debug("tex: found the following bibunit files: %s"%nodes)
+ return nodes
+exts_deps_tex=['','.ltx','.tex','.bib','.pdf','.png','.eps','.ps','.sty']
+exts_tex=['.ltx','.tex']
+re_tex=re.compile(r'\\(?P<type>usepackage|RequirePackage|include|bibliography([^\[\]{}]*)|putbib|includegraphics|input|import|bringin|lstinputlisting)(\[[^\[\]]*\])?{(?P<file>[^{}]*)}',re.M)
+g_bibtex_re=re.compile('bibdata',re.M)
+g_glossaries_re=re.compile('\\@newglossary',re.M)
+class tex(Task.Task):
+ bibtex_fun,_=Task.compile_fun('${BIBTEX} ${BIBTEXFLAGS} ${SRCFILE}',shell=False)
+ bibtex_fun.__doc__="""
+ Execute the program **bibtex**
+ """
+ makeindex_fun,_=Task.compile_fun('${MAKEINDEX} ${MAKEINDEXFLAGS} ${SRCFILE}',shell=False)
+ makeindex_fun.__doc__="""
+ Execute the program **makeindex**
+ """
+ makeglossaries_fun,_=Task.compile_fun('${MAKEGLOSSARIES} ${SRCFILE}',shell=False)
+ makeglossaries_fun.__doc__="""
+ Execute the program **makeglossaries**
+ """
+ def exec_command(self,cmd,**kw):
+ bld=self.generator.bld
+ Logs.info('runner: %r'%cmd)
+ try:
+ if not kw.get('cwd',None):
+ kw['cwd']=bld.cwd
+ except AttributeError:
+ bld.cwd=kw['cwd']=bld.variant_dir
+ return Utils.subprocess.Popen(cmd,**kw).wait()
+ def scan_aux(self,node):
+ nodes=[node]
+ re_aux=re.compile(r'\\@input{(?P<file>[^{}]*)}',re.M)
+ def parse_node(node):
+ code=node.read()
+ for match in re_aux.finditer(code):
+ path=match.group('file')
+ found=node.parent.find_or_declare(path)
+ if found and found not in nodes:
+ Logs.debug('tex: found aux node '+found.abspath())
+ nodes.append(found)
+ parse_node(found)
+ parse_node(node)
+ return nodes
+ def scan(self):
+ node=self.inputs[0]
+ nodes=[]
+ names=[]
+ seen=[]
+ if not node:return(nodes,names)
+ def parse_node(node):
+ if node in seen:
+ return
+ seen.append(node)
+ code=node.read()
+ global re_tex
+ for match in re_tex.finditer(code):
+ multibib=match.group('type')
+ if multibib and multibib.startswith('bibliography'):
+ multibib=multibib[len('bibliography'):]
+ if multibib.startswith('style'):
+ continue
+ else:
+ multibib=None
+ for path in match.group('file').split(','):
+ if path:
+ add_name=True
+ found=None
+ for k in exts_deps_tex:
+ for up in self.texinputs_nodes:
+ Logs.debug('tex: trying %s%s'%(path,k))
+ found=up.find_resource(path+k)
+ if found:
+ break
+ for tsk in self.generator.tasks:
+ if not found or found in tsk.outputs:
+ break
+ else:
+ nodes.append(found)
+ add_name=False
+ for ext in exts_tex:
+ if found.name.endswith(ext):
+ parse_node(found)
+ break
+ if found and multibib and found.name.endswith('.bib'):
+ try:
+ self.multibibs.append(found)
+ except AttributeError:
+ self.multibibs=[found]
+ if add_name:
+ names.append(path)
+ parse_node(node)
+ for x in nodes:
+ x.parent.get_bld().mkdir()
+ Logs.debug("tex: found the following : %s and names %s"%(nodes,names))
+ return(nodes,names)
+ def check_status(self,msg,retcode):
+ if retcode!=0:
+ raise Errors.WafError("%r command exit status %r"%(msg,retcode))
+ def bibfile(self):
+ for aux_node in self.aux_nodes:
+ try:
+ ct=aux_node.read()
+ except EnvironmentError:
+ Logs.error('Error reading %s: %r'%aux_node.abspath())
+ continue
+ if g_bibtex_re.findall(ct):
+ Logs.info('calling bibtex')
+ self.env.env={}
+ self.env.env.update(os.environ)
+ self.env.env.update({'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()})
+ self.env.SRCFILE=aux_node.name[:-4]
+ self.check_status('error when calling bibtex',self.bibtex_fun())
+ for node in getattr(self,'multibibs',[]):
+ self.env.env={}
+ self.env.env.update(os.environ)
+ self.env.env.update({'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()})
+ self.env.SRCFILE=node.name[:-4]
+ self.check_status('error when calling bibtex',self.bibtex_fun())
+ def bibunits(self):
+ try:
+ bibunits=bibunitscan(self)
+ except OSError:
+ Logs.error('error bibunitscan')
+ else:
+ if bibunits:
+ fn=['bu'+str(i)for i in range(1,len(bibunits)+1)]
+ if fn:
+ Logs.info('calling bibtex on bibunits')
+ for f in fn:
+ self.env.env={'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()}
+ self.env.SRCFILE=f
+ self.check_status('error when calling bibtex',self.bibtex_fun())
+ def makeindex(self):
+ self.idx_node=self.inputs[0].change_ext('.idx')
+ try:
+ idx_path=self.idx_node.abspath()
+ os.stat(idx_path)
+ except OSError:
+ Logs.info('index file %s absent, not calling makeindex'%idx_path)
+ else:
+ Logs.info('calling makeindex')
+ self.env.SRCFILE=self.idx_node.name
+ self.env.env={}
+ self.check_status('error when calling makeindex %s'%idx_path,self.makeindex_fun())
+ def bibtopic(self):
+ p=self.inputs[0].parent.get_bld()
+ if os.path.exists(os.path.join(p.abspath(),'btaux.aux')):
+ self.aux_nodes+=p.ant_glob('*[0-9].aux')
+ def makeglossaries(self):
+ src_file=self.inputs[0].abspath()
+ base_file=os.path.basename(src_file)
+ base,_=os.path.splitext(base_file)
+ for aux_node in self.aux_nodes:
+ try:
+ ct=aux_node.read()
+ except EnvironmentError:
+ Logs.error('Error reading %s: %r'%aux_node.abspath())
+ continue
+ if g_glossaries_re.findall(ct):
+ if not self.env.MAKEGLOSSARIES:
+ raise Errors.WafError("The program 'makeglossaries' is missing!")
+ Logs.warn('calling makeglossaries')
+ self.env.SRCFILE=base
+ self.check_status('error when calling makeglossaries %s'%base,self.makeglossaries_fun())
+ return
+ def texinputs(self):
+ return os.pathsep.join([k.abspath()for k in self.texinputs_nodes])+os.pathsep
+ def run(self):
+ env=self.env
+ if not env['PROMPT_LATEX']:
+ env.append_value('LATEXFLAGS','-interaction=batchmode')
+ env.append_value('PDFLATEXFLAGS','-interaction=batchmode')
+ env.append_value('XELATEXFLAGS','-interaction=batchmode')
+ self.cwd=self.inputs[0].parent.get_bld().abspath()
+ Logs.info('first pass on %s'%self.__class__.__name__)
+ cur_hash=self.hash_aux_nodes()
+ self.call_latex()
+ self.hash_aux_nodes()
+ self.bibtopic()
+ self.bibfile()
+ self.bibunits()
+ self.makeindex()
+ self.makeglossaries()
+ for i in range(10):
+ prev_hash=cur_hash
+ cur_hash=self.hash_aux_nodes()
+ if not cur_hash:
+ Logs.error('No aux.h to process')
+ if cur_hash and cur_hash==prev_hash:
+ break
+ Logs.info('calling %s'%self.__class__.__name__)
+ self.call_latex()
+ def hash_aux_nodes(self):
+ try:
+ self.aux_nodes
+ except AttributeError:
+ try:
+ self.aux_nodes=self.scan_aux(self.inputs[0].change_ext('.aux'))
+ except IOError:
+ return None
+ return Utils.h_list([Utils.h_file(x.abspath())for x in self.aux_nodes])
+ def call_latex(self):
+ self.env.env={}
+ self.env.env.update(os.environ)
+ self.env.env.update({'TEXINPUTS':self.texinputs()})
+ self.env.SRCFILE=self.inputs[0].abspath()
+ self.check_status('error when calling latex',self.texfun())
+class latex(tex):
+ texfun,vars=Task.compile_fun('${LATEX} ${LATEXFLAGS} ${SRCFILE}',shell=False)
+class pdflatex(tex):
+ texfun,vars=Task.compile_fun('${PDFLATEX} ${PDFLATEXFLAGS} ${SRCFILE}',shell=False)
+class xelatex(tex):
+ texfun,vars=Task.compile_fun('${XELATEX} ${XELATEXFLAGS} ${SRCFILE}',shell=False)
+class dvips(Task.Task):
+ run_str='${DVIPS} ${DVIPSFLAGS} ${SRC} -o ${TGT}'
+ color='BLUE'
+ after=['latex','pdflatex','xelatex']
+class dvipdf(Task.Task):
+ run_str='${DVIPDF} ${DVIPDFFLAGS} ${SRC} ${TGT}'
+ color='BLUE'
+ after=['latex','pdflatex','xelatex']
+class pdf2ps(Task.Task):
+ run_str='${PDF2PS} ${PDF2PSFLAGS} ${SRC} ${TGT}'
+ color='BLUE'
+ after=['latex','pdflatex','xelatex']
+@feature('tex')
+@before_method('process_source')
+def apply_tex(self):
+ if not getattr(self,'type',None)in('latex','pdflatex','xelatex'):
+ self.type='pdflatex'
+ outs=Utils.to_list(getattr(self,'outs',[]))
+ self.env['PROMPT_LATEX']=getattr(self,'prompt',1)
+ deps_lst=[]
+ if getattr(self,'deps',None):
+ deps=self.to_list(self.deps)
+ for dep in deps:
+ if isinstance(dep,str):
+ n=self.path.find_resource(dep)
+ if not n:
+ self.bld.fatal('Could not find %r for %r'%(dep,self))
+ if not n in deps_lst:
+ deps_lst.append(n)
+ elif isinstance(dep,Node.Node):
+ deps_lst.append(dep)
+ for node in self.to_nodes(self.source):
+ if self.type=='latex':
+ task=self.create_task('latex',node,node.change_ext('.dvi'))
+ elif self.type=='pdflatex':
+ task=self.create_task('pdflatex',node,node.change_ext('.pdf'))
+ elif self.type=='xelatex':
+ task=self.create_task('xelatex',node,node.change_ext('.pdf'))
+ task.env=self.env
+ if deps_lst:
+ for n in deps_lst:
+ if not n in task.dep_nodes:
+ task.dep_nodes.append(n)
+ if hasattr(self,'texinputs_nodes'):
+ task.texinputs_nodes=self.texinputs_nodes
+ else:
+ task.texinputs_nodes=[node.parent,node.parent.get_bld(),self.path,self.path.get_bld()]
+ lst=os.environ.get('TEXINPUTS','')
+ if self.env.TEXINPUTS:
+ lst+=os.pathsep+self.env.TEXINPUTS
+ if lst:
+ lst=lst.split(os.pathsep)
+ for x in lst:
+ if x:
+ if os.path.isabs(x):
+ p=self.bld.root.find_node(x)
+ if p:
+ task.texinputs_nodes.append(p)
+ else:
+ Logs.error('Invalid TEXINPUTS folder %s'%x)
+ else:
+ Logs.error('Cannot resolve relative paths in TEXINPUTS %s'%x)
+ if self.type=='latex':
+ if'ps'in outs:
+ tsk=self.create_task('dvips',task.outputs,node.change_ext('.ps'))
+ tsk.env.env=dict(os.environ)
+ if'pdf'in outs:
+ tsk=self.create_task('dvipdf',task.outputs,node.change_ext('.pdf'))
+ tsk.env.env=dict(os.environ)
+ elif self.type=='pdflatex':
+ if'ps'in outs:
+ self.create_task('pdf2ps',task.outputs,node.change_ext('.ps'))
+ self.source=[]
+def configure(self):
+ v=self.env
+ for p in'tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps makeglossaries'.split():
+ try:
+ self.find_program(p,var=p.upper())
+ except self.errors.ConfigurationError:
+ pass
+ v['DVIPSFLAGS']='-Ppdf'
diff --git a/waflib/Tools/vala.py b/waflib/Tools/vala.py
new file mode 100644
index 0000000..68af651
--- /dev/null
+++ b/waflib/Tools/vala.py
@@ -0,0 +1,211 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import re
+from waflib import Context,Task,Utils,Logs,Options,Errors,Node
+from waflib.TaskGen import extension,taskgen_method
+from waflib.Configure import conf
+class valac(Task.Task):
+ vars=["VALAC","VALAC_VERSION","VALAFLAGS"]
+ ext_out=['.h']
+ def run(self):
+ cmd=self.env.VALAC+self.env.VALAFLAGS
+ resources=getattr(self,'vala_exclude',[])
+ cmd.extend([a.abspath()for a in self.inputs if a not in resources])
+ ret=self.exec_command(cmd,cwd=self.vala_dir_node.abspath())
+ if ret:
+ return ret
+ if self.generator.dump_deps_node:
+ self.generator.dump_deps_node.write('\n'.join(self.generator.packages))
+ return ret
+valac=Task.update_outputs(valac)
+@taskgen_method
+def init_vala_task(self):
+ self.profile=getattr(self,'profile','gobject')
+ if self.profile=='gobject':
+ self.uselib=Utils.to_list(getattr(self,'uselib',[]))
+ if not'GOBJECT'in self.uselib:
+ self.uselib.append('GOBJECT')
+ def addflags(flags):
+ self.env.append_value('VALAFLAGS',flags)
+ if self.profile:
+ addflags('--profile=%s'%self.profile)
+ valatask=self.valatask
+ if hasattr(self,'vala_dir'):
+ if isinstance(self.vala_dir,str):
+ valatask.vala_dir_node=self.path.get_bld().make_node(self.vala_dir)
+ try:
+ valatask.vala_dir_node.mkdir()
+ except OSError:
+ raise self.bld.fatal('Cannot create the vala dir %r'%valatask.vala_dir_node)
+ else:
+ valatask.vala_dir_node=self.vala_dir
+ else:
+ valatask.vala_dir_node=self.path.get_bld()
+ addflags('--directory=%s'%valatask.vala_dir_node.abspath())
+ if hasattr(self,'thread'):
+ if self.profile=='gobject':
+ if not'GTHREAD'in self.uselib:
+ self.uselib.append('GTHREAD')
+ else:
+ Logs.warn("Profile %s means no threading support"%self.profile)
+ self.thread=False
+ if self.thread:
+ addflags('--thread')
+ self.is_lib='cprogram'not in self.features
+ if self.is_lib:
+ addflags('--library=%s'%self.target)
+ h_node=valatask.vala_dir_node.find_or_declare('%s.h'%self.target)
+ valatask.outputs.append(h_node)
+ addflags('--header=%s'%h_node.name)
+ valatask.outputs.append(valatask.vala_dir_node.find_or_declare('%s.vapi'%self.target))
+ if getattr(self,'gir',None):
+ gir_node=valatask.vala_dir_node.find_or_declare('%s.gir'%self.gir)
+ addflags('--gir=%s'%gir_node.name)
+ valatask.outputs.append(gir_node)
+ self.vala_target_glib=getattr(self,'vala_target_glib',getattr(Options.options,'vala_target_glib',None))
+ if self.vala_target_glib:
+ addflags('--target-glib=%s'%self.vala_target_glib)
+ addflags(['--define=%s'%x for x in getattr(self,'vala_defines',[])])
+ packages_private=Utils.to_list(getattr(self,'packages_private',[]))
+ addflags(['--pkg=%s'%x for x in packages_private])
+ def _get_api_version():
+ api_version='1.0'
+ if hasattr(Context.g_module,'API_VERSION'):
+ version=Context.g_module.API_VERSION.split(".")
+ if version[0]=="0":
+ api_version="0."+version[1]
+ else:
+ api_version=version[0]+".0"
+ return api_version
+ self.includes=Utils.to_list(getattr(self,'includes',[]))
+ self.uselib=self.to_list(getattr(self,'uselib',[]))
+ valatask.install_path=getattr(self,'install_path','')
+ valatask.vapi_path=getattr(self,'vapi_path','${DATAROOTDIR}/vala/vapi')
+ valatask.pkg_name=getattr(self,'pkg_name',self.env['PACKAGE'])
+ valatask.header_path=getattr(self,'header_path','${INCLUDEDIR}/%s-%s'%(valatask.pkg_name,_get_api_version()))
+ valatask.install_binding=getattr(self,'install_binding',True)
+ self.packages=packages=Utils.to_list(getattr(self,'packages',[]))
+ self.vapi_dirs=vapi_dirs=Utils.to_list(getattr(self,'vapi_dirs',[]))
+ if hasattr(self,'use'):
+ local_packages=Utils.to_list(self.use)[:]
+ seen=[]
+ while len(local_packages)>0:
+ package=local_packages.pop()
+ if package in seen:
+ continue
+ seen.append(package)
+ try:
+ package_obj=self.bld.get_tgen_by_name(package)
+ except Errors.WafError:
+ continue
+ package_name=package_obj.target
+ for task in package_obj.tasks:
+ for output in task.outputs:
+ if output.name==package_name+".vapi":
+ valatask.set_run_after(task)
+ if package_name not in packages:
+ packages.append(package_name)
+ if output.parent not in vapi_dirs:
+ vapi_dirs.append(output.parent)
+ if output.parent not in self.includes:
+ self.includes.append(output.parent)
+ if hasattr(package_obj,'use'):
+ lst=self.to_list(package_obj.use)
+ lst.reverse()
+ local_packages=[pkg for pkg in lst if pkg not in seen]+local_packages
+ addflags(['--pkg=%s'%p for p in packages])
+ for vapi_dir in vapi_dirs:
+ if isinstance(vapi_dir,Node.Node):
+ v_node=vapi_dir
+ else:
+ v_node=self.path.find_dir(vapi_dir)
+ if not v_node:
+ Logs.warn('Unable to locate Vala API directory: %r'%vapi_dir)
+ else:
+ addflags('--vapidir=%s'%v_node.abspath())
+ self.dump_deps_node=None
+ if self.is_lib and self.packages:
+ self.dump_deps_node=valatask.vala_dir_node.find_or_declare('%s.deps'%self.target)
+ valatask.outputs.append(self.dump_deps_node)
+ self.includes.append(self.bld.srcnode.abspath())
+ self.includes.append(self.bld.bldnode.abspath())
+ if self.is_lib and valatask.install_binding:
+ headers_list=[o for o in valatask.outputs if o.suffix()==".h"]
+ try:
+ self.install_vheader.source=headers_list
+ except AttributeError:
+ self.install_vheader=self.bld.install_files(valatask.header_path,headers_list,self.env)
+ vapi_list=[o for o in valatask.outputs if(o.suffix()in(".vapi",".deps"))]
+ try:
+ self.install_vapi.source=vapi_list
+ except AttributeError:
+ self.install_vapi=self.bld.install_files(valatask.vapi_path,vapi_list,self.env)
+ gir_list=[o for o in valatask.outputs if o.suffix()=='.gir']
+ try:
+ self.install_gir.source=gir_list
+ except AttributeError:
+ self.install_gir=self.bld.install_files(getattr(self,'gir_path','${DATAROOTDIR}/gir-1.0'),gir_list,self.env)
+ if hasattr(self,'vala_resources'):
+ nodes=self.to_nodes(self.vala_resources)
+ valatask.vala_exclude=getattr(valatask,'vala_exclude',[])+nodes
+ valatask.inputs.extend(nodes)
+ for x in nodes:
+ addflags(['--gresources',x.abspath()])
+@extension('.vala','.gs')
+def vala_file(self,node):
+ try:
+ valatask=self.valatask
+ except AttributeError:
+ valatask=self.valatask=self.create_task('valac')
+ self.init_vala_task()
+ valatask.inputs.append(node)
+ name=node.name[:node.name.rfind('.')]+'.c'
+ c_node=valatask.vala_dir_node.find_or_declare(name)
+ valatask.outputs.append(c_node)
+ self.source.append(c_node)
+@conf
+def find_valac(self,valac_name,min_version):
+ valac=self.find_program(valac_name,var='VALAC')
+ try:
+ output=self.cmd_and_log(valac+['--version'])
+ except Exception:
+ valac_version=None
+ else:
+ ver=re.search(r'\d+.\d+.\d+',output).group(0).split('.')
+ valac_version=tuple([int(x)for x in ver])
+ self.msg('Checking for %s version >= %r'%(valac_name,min_version),valac_version,valac_version and valac_version>=min_version)
+ if valac and valac_version<min_version:
+ self.fatal("%s version %r is too old, need >= %r"%(valac_name,valac_version,min_version))
+ self.env['VALAC_VERSION']=valac_version
+ return valac
+@conf
+def check_vala(self,min_version=(0,8,0),branch=None):
+ if not branch:
+ branch=min_version[:2]
+ try:
+ find_valac(self,'valac-%d.%d'%(branch[0],branch[1]),min_version)
+ except self.errors.ConfigurationError:
+ find_valac(self,'valac',min_version)
+@conf
+def check_vala_deps(self):
+ if not self.env['HAVE_GOBJECT']:
+ pkg_args={'package':'gobject-2.0','uselib_store':'GOBJECT','args':'--cflags --libs'}
+ if getattr(Options.options,'vala_target_glib',None):
+ pkg_args['atleast_version']=Options.options.vala_target_glib
+ self.check_cfg(**pkg_args)
+ if not self.env['HAVE_GTHREAD']:
+ pkg_args={'package':'gthread-2.0','uselib_store':'GTHREAD','args':'--cflags --libs'}
+ if getattr(Options.options,'vala_target_glib',None):
+ pkg_args['atleast_version']=Options.options.vala_target_glib
+ self.check_cfg(**pkg_args)
+def configure(self):
+ self.load('gnu_dirs')
+ self.check_vala_deps()
+ self.check_vala()
+ self.env.VALAFLAGS=['-C']
+def options(opt):
+ opt.load('gnu_dirs')
+ valaopts=opt.add_option_group('Vala Compiler Options')
+ 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')
diff --git a/waflib/Tools/waf_unit_test.py b/waflib/Tools/waf_unit_test.py
new file mode 100644
index 0000000..d07e1ed
--- /dev/null
+++ b/waflib/Tools/waf_unit_test.py
@@ -0,0 +1,106 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os
+from waflib.TaskGen import feature,after_method,taskgen_method
+from waflib import Utils,Task,Logs,Options
+testlock=Utils.threading.Lock()
+@feature('test')
+@after_method('apply_link')
+def make_test(self):
+ if getattr(self,'link_task',None):
+ self.create_task('utest',self.link_task.outputs)
+@taskgen_method
+def add_test_results(self,tup):
+ Logs.debug("ut: %r",tup)
+ self.utest_result=tup
+ try:
+ self.bld.utest_results.append(tup)
+ except AttributeError:
+ self.bld.utest_results=[tup]
+class utest(Task.Task):
+ color='PINK'
+ after=['vnum','inst']
+ vars=[]
+ def runnable_status(self):
+ if getattr(Options.options,'no_tests',False):
+ return Task.SKIP_ME
+ ret=super(utest,self).runnable_status()
+ if ret==Task.SKIP_ME:
+ if getattr(Options.options,'all_tests',False):
+ return Task.RUN_ME
+ return ret
+ def add_path(self,dct,path,var):
+ dct[var]=os.pathsep.join(Utils.to_list(path)+[os.environ.get(var,'')])
+ def get_test_env(self):
+ try:
+ fu=getattr(self.generator.bld,'all_test_paths')
+ except AttributeError:
+ fu=os.environ.copy()
+ lst=[]
+ for g in self.generator.bld.groups:
+ for tg in g:
+ if getattr(tg,'link_task',None):
+ s=tg.link_task.outputs[0].parent.abspath()
+ if s not in lst:
+ lst.append(s)
+ if Utils.is_win32:
+ self.add_path(fu,lst,'PATH')
+ elif Utils.unversioned_sys_platform()=='darwin':
+ self.add_path(fu,lst,'DYLD_LIBRARY_PATH')
+ self.add_path(fu,lst,'LD_LIBRARY_PATH')
+ else:
+ self.add_path(fu,lst,'LD_LIBRARY_PATH')
+ self.generator.bld.all_test_paths=fu
+ return fu
+ def run(self):
+ filename=self.inputs[0].abspath()
+ self.ut_exec=getattr(self.generator,'ut_exec',[filename])
+ if getattr(self.generator,'ut_fun',None):
+ self.generator.ut_fun(self)
+ cwd=getattr(self.generator,'ut_cwd','')or self.inputs[0].parent.abspath()
+ testcmd=getattr(self.generator,'ut_cmd',False)or getattr(Options.options,'testcmd',False)
+ if testcmd:
+ self.ut_exec=(testcmd%self.ut_exec[0]).split(' ')
+ proc=Utils.subprocess.Popen(self.ut_exec,cwd=cwd,env=self.get_test_env(),stderr=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE)
+ (stdout,stderr)=proc.communicate()
+ self.waf_unit_test_results=tup=(filename,proc.returncode,stdout,stderr)
+ testlock.acquire()
+ try:
+ return self.generator.add_test_results(tup)
+ finally:
+ testlock.release()
+ def post_run(self):
+ super(utest,self).post_run()
+ if getattr(Options.options,'clear_failed_tests',False)and self.waf_unit_test_results[1]:
+ self.generator.bld.task_sigs[self.uid()]=None
+def summary(bld):
+ lst=getattr(bld,'utest_results',[])
+ if lst:
+ Logs.pprint('CYAN','execution summary')
+ total=len(lst)
+ tfail=len([x for x in lst if x[1]])
+ Logs.pprint('CYAN',' tests that pass %d/%d'%(total-tfail,total))
+ for(f,code,out,err)in lst:
+ if not code:
+ Logs.pprint('CYAN',' %s'%f)
+ Logs.pprint('CYAN',' tests that fail %d/%d'%(tfail,total))
+ for(f,code,out,err)in lst:
+ if code:
+ Logs.pprint('CYAN',' %s'%f)
+def set_exit_code(bld):
+ lst=getattr(bld,'utest_results',[])
+ for(f,code,out,err)in lst:
+ if code:
+ msg=[]
+ if out:
+ msg.append('stdout:%s%s'%(os.linesep,out.decode('utf-8')))
+ if err:
+ msg.append('stderr:%s%s'%(os.linesep,err.decode('utf-8')))
+ bld.fatal(os.linesep.join(msg))
+def options(opt):
+ opt.add_option('--notests',action='store_true',default=False,help='Exec no unit tests',dest='no_tests')
+ opt.add_option('--alltests',action='store_true',default=False,help='Exec all unit tests',dest='all_tests')
+ opt.add_option('--clear-failed',action='store_true',default=False,help='Force failed unit tests to run again next time',dest='clear_failed_tests')
+ opt.add_option('--testcmd',action='store',default=False,help='Run the unit tests using the test-cmd string'' example "--test-cmd="valgrind --error-exitcode=1'' %s" to run under valgrind',dest='testcmd')
diff --git a/waflib/Tools/winres.py b/waflib/Tools/winres.py
new file mode 100644
index 0000000..a055887
--- /dev/null
+++ b/waflib/Tools/winres.py
@@ -0,0 +1,85 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import re,traceback
+from waflib import Task,Logs,Utils
+from waflib.TaskGen import extension
+from waflib.Tools import c_preproc
+@extension('.rc')
+def rc_file(self,node):
+ obj_ext='.rc.o'
+ if self.env['WINRC_TGT_F']=='/fo':
+ obj_ext='.res'
+ rctask=self.create_task('winrc',node,node.change_ext(obj_ext))
+ try:
+ self.compiled_tasks.append(rctask)
+ except AttributeError:
+ self.compiled_tasks=[rctask]
+re_lines=re.compile('(?:^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*?)\s*$)|''(?:^\w+[ \t]*(ICON|BITMAP|CURSOR|HTML|FONT|MESSAGETABLE|TYPELIB|REGISTRY|D3DFX)[ \t]*(.*?)\s*$)',re.IGNORECASE|re.MULTILINE)
+class rc_parser(c_preproc.c_parser):
+ def filter_comments(self,filepath):
+ code=Utils.readf(filepath)
+ if c_preproc.use_trigraphs:
+ for(a,b)in c_preproc.trig_def:code=code.split(a).join(b)
+ code=c_preproc.re_nl.sub('',code)
+ code=c_preproc.re_cpp.sub(c_preproc.repl,code)
+ ret=[]
+ for m in re.finditer(re_lines,code):
+ if m.group(2):
+ ret.append((m.group(2),m.group(3)))
+ else:
+ ret.append(('include',m.group(5)))
+ return ret
+ def addlines(self,node):
+ self.currentnode_stack.append(node.parent)
+ filepath=node.abspath()
+ self.count_files+=1
+ if self.count_files>c_preproc.recursion_limit:
+ raise c_preproc.PreprocError("recursion limit exceeded")
+ pc=self.parse_cache
+ Logs.debug('preproc: reading file %r',filepath)
+ try:
+ lns=pc[filepath]
+ except KeyError:
+ pass
+ else:
+ self.lines.extend(lns)
+ return
+ try:
+ lines=self.filter_comments(filepath)
+ lines.append((c_preproc.POPFILE,''))
+ lines.reverse()
+ pc[filepath]=lines
+ self.lines.extend(lines)
+ except IOError:
+ raise c_preproc.PreprocError("could not read the file %s"%filepath)
+ except Exception:
+ if Logs.verbose>0:
+ Logs.error("parsing %s failed"%filepath)
+ traceback.print_exc()
+class winrc(Task.Task):
+ run_str='${WINRC} ${WINRCFLAGS} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${WINRC_TGT_F} ${TGT} ${WINRC_SRC_F} ${SRC}'
+ color='BLUE'
+ def scan(self):
+ tmp=rc_parser(self.generator.includes_nodes)
+ tmp.start(self.inputs[0],self.env)
+ nodes=tmp.nodes
+ names=tmp.names
+ if Logs.verbose:
+ Logs.debug('deps: deps for %s: %r; unresolved %r'%(str(self),nodes,names))
+ return(nodes,names)
+def configure(conf):
+ v=conf.env
+ v['WINRC_TGT_F']='-o'
+ v['WINRC_SRC_F']='-i'
+ if not conf.env.WINRC:
+ if v.CC_NAME=='msvc':
+ conf.find_program('RC',var='WINRC',path_list=v['PATH'])
+ v['WINRC_TGT_F']='/fo'
+ v['WINRC_SRC_F']=''
+ else:
+ conf.find_program('windres',var='WINRC',path_list=v['PATH'])
+ if not conf.env.WINRC:
+ conf.fatal('winrc was not found!')
+ v['WINRCFLAGS']=[]
diff --git a/waflib/Tools/xlc.py b/waflib/Tools/xlc.py
new file mode 100644
index 0000000..c56443b
--- /dev/null
+++ b/waflib/Tools/xlc.py
@@ -0,0 +1,43 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_xlc(conf):
+ cc=conf.find_program(['xlc_r','xlc'],var='CC')
+ conf.get_xlc_version(cc)
+ conf.env.CC_NAME='xlc'
+@conf
+def xlc_common_flags(conf):
+ v=conf.env
+ v['CC_SRC_F']=[]
+ v['CC_TGT_F']=['-c','-o']
+ if not v['LINK_CC']:v['LINK_CC']=v['CC']
+ v['CCLNK_SRC_F']=[]
+ v['CCLNK_TGT_F']=['-o']
+ v['CPPPATH_ST']='-I%s'
+ v['DEFINES_ST']='-D%s'
+ v['LIB_ST']='-l%s'
+ v['LIBPATH_ST']='-L%s'
+ v['STLIB_ST']='-l%s'
+ v['STLIBPATH_ST']='-L%s'
+ v['RPATH_ST']='-Wl,-rpath,%s'
+ v['SONAME_ST']=[]
+ v['SHLIB_MARKER']=[]
+ v['STLIB_MARKER']=[]
+ v['LINKFLAGS_cprogram']=['-Wl,-brtl']
+ v['cprogram_PATTERN']='%s'
+ v['CFLAGS_cshlib']=['-fPIC']
+ v['LINKFLAGS_cshlib']=['-G','-Wl,-brtl,-bexpfull']
+ v['cshlib_PATTERN']='lib%s.so'
+ v['LINKFLAGS_cstlib']=[]
+ v['cstlib_PATTERN']='lib%s.a'
+def configure(conf):
+ conf.find_xlc()
+ conf.find_ar()
+ conf.xlc_common_flags()
+ conf.cc_load_tools()
+ conf.cc_add_flags()
+ conf.link_add_flags()
diff --git a/waflib/Tools/xlcxx.py b/waflib/Tools/xlcxx.py
new file mode 100644
index 0000000..f348bbf
--- /dev/null
+++ b/waflib/Tools/xlcxx.py
@@ -0,0 +1,43 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_xlcxx(conf):
+ cxx=conf.find_program(['xlc++_r','xlc++'],var='CXX')
+ conf.get_xlc_version(cxx)
+ conf.env.CXX_NAME='xlc++'
+@conf
+def xlcxx_common_flags(conf):
+ v=conf.env
+ v['CXX_SRC_F']=[]
+ v['CXX_TGT_F']=['-c','-o']
+ if not v['LINK_CXX']:v['LINK_CXX']=v['CXX']
+ v['CXXLNK_SRC_F']=[]
+ v['CXXLNK_TGT_F']=['-o']
+ v['CPPPATH_ST']='-I%s'
+ v['DEFINES_ST']='-D%s'
+ v['LIB_ST']='-l%s'
+ v['LIBPATH_ST']='-L%s'
+ v['STLIB_ST']='-l%s'
+ v['STLIBPATH_ST']='-L%s'
+ v['RPATH_ST']='-Wl,-rpath,%s'
+ v['SONAME_ST']=[]
+ v['SHLIB_MARKER']=[]
+ v['STLIB_MARKER']=[]
+ v['LINKFLAGS_cxxprogram']=['-Wl,-brtl']
+ v['cxxprogram_PATTERN']='%s'
+ v['CXXFLAGS_cxxshlib']=['-fPIC']
+ v['LINKFLAGS_cxxshlib']=['-G','-Wl,-brtl,-bexpfull']
+ v['cxxshlib_PATTERN']='lib%s.so'
+ v['LINKFLAGS_cxxstlib']=[]
+ v['cxxstlib_PATTERN']='lib%s.a'
+def configure(conf):
+ conf.find_xlcxx()
+ conf.find_ar()
+ conf.xlcxx_common_flags()
+ conf.cxx_load_tools()
+ conf.cxx_add_flags()
+ conf.link_add_flags()
diff --git a/waflib/Utils.py b/waflib/Utils.py
new file mode 100644
index 0000000..6c2a8e0
--- /dev/null
+++ b/waflib/Utils.py
@@ -0,0 +1,468 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,sys,errno,traceback,inspect,re,shutil,datetime,gc,platform
+import subprocess
+from collections import deque,defaultdict
+try:
+ import _winreg as winreg
+except ImportError:
+ try:
+ import winreg
+ except ImportError:
+ winreg=None
+from waflib import Errors
+try:
+ from collections import UserDict
+except ImportError:
+ from UserDict import UserDict
+try:
+ from hashlib import md5
+except ImportError:
+ try:
+ from md5 import md5
+ except ImportError:
+ pass
+try:
+ import threading
+except ImportError:
+ if not'JOBS'in os.environ:
+ os.environ['JOBS']='1'
+ class threading(object):
+ pass
+ class Lock(object):
+ def acquire(self):
+ pass
+ def release(self):
+ pass
+ threading.Lock=threading.Thread=Lock
+else:
+ run_old=threading.Thread.run
+ def run(*args,**kwargs):
+ try:
+ run_old(*args,**kwargs)
+ except(KeyboardInterrupt,SystemExit):
+ raise
+ except Exception:
+ sys.excepthook(*sys.exc_info())
+ threading.Thread.run=run
+SIG_NIL='iluvcuteoverload'
+O644=420
+O755=493
+rot_chr=['\\','|','/','-']
+rot_idx=0
+try:
+ from collections import OrderedDict as ordered_iter_dict
+except ImportError:
+ class ordered_iter_dict(dict):
+ def __init__(self,*k,**kw):
+ self.lst=[]
+ dict.__init__(self,*k,**kw)
+ def clear(self):
+ dict.clear(self)
+ self.lst=[]
+ def __setitem__(self,key,value):
+ dict.__setitem__(self,key,value)
+ try:
+ self.lst.remove(key)
+ except ValueError:
+ pass
+ self.lst.append(key)
+ def __delitem__(self,key):
+ dict.__delitem__(self,key)
+ try:
+ self.lst.remove(key)
+ except ValueError:
+ pass
+ def __iter__(self):
+ for x in self.lst:
+ yield x
+ def keys(self):
+ return self.lst
+is_win32=os.sep=='\\'or sys.platform=='win32'
+def readf(fname,m='r',encoding='ISO8859-1'):
+ if sys.hexversion>0x3000000 and not'b'in m:
+ m+='b'
+ f=open(fname,m)
+ try:
+ txt=f.read()
+ finally:
+ f.close()
+ if encoding:
+ txt=txt.decode(encoding)
+ else:
+ txt=txt.decode()
+ else:
+ f=open(fname,m)
+ try:
+ txt=f.read()
+ finally:
+ f.close()
+ return txt
+def writef(fname,data,m='w',encoding='ISO8859-1'):
+ if sys.hexversion>0x3000000 and not'b'in m:
+ data=data.encode(encoding)
+ m+='b'
+ f=open(fname,m)
+ try:
+ f.write(data)
+ finally:
+ f.close()
+def h_file(fname):
+ f=open(fname,'rb')
+ m=md5()
+ try:
+ while fname:
+ fname=f.read(200000)
+ m.update(fname)
+ finally:
+ f.close()
+ return m.digest()
+def readf_win32(f,m='r',encoding='ISO8859-1'):
+ flags=os.O_NOINHERIT|os.O_RDONLY
+ if'b'in m:
+ flags|=os.O_BINARY
+ if'+'in m:
+ flags|=os.O_RDWR
+ try:
+ fd=os.open(f,flags)
+ except OSError:
+ raise IOError('Cannot read from %r'%f)
+ if sys.hexversion>0x3000000 and not'b'in m:
+ m+='b'
+ f=os.fdopen(fd,m)
+ try:
+ txt=f.read()
+ finally:
+ f.close()
+ if encoding:
+ txt=txt.decode(encoding)
+ else:
+ txt=txt.decode()
+ else:
+ f=os.fdopen(fd,m)
+ try:
+ txt=f.read()
+ finally:
+ f.close()
+ return txt
+def writef_win32(f,data,m='w',encoding='ISO8859-1'):
+ if sys.hexversion>0x3000000 and not'b'in m:
+ data=data.encode(encoding)
+ m+='b'
+ flags=os.O_CREAT|os.O_TRUNC|os.O_WRONLY|os.O_NOINHERIT
+ if'b'in m:
+ flags|=os.O_BINARY
+ if'+'in m:
+ flags|=os.O_RDWR
+ try:
+ fd=os.open(f,flags)
+ except OSError:
+ raise IOError('Cannot write to %r'%f)
+ f=os.fdopen(fd,m)
+ try:
+ f.write(data)
+ finally:
+ f.close()
+def h_file_win32(fname):
+ try:
+ fd=os.open(fname,os.O_BINARY|os.O_RDONLY|os.O_NOINHERIT)
+ except OSError:
+ raise IOError('Cannot read from %r'%fname)
+ f=os.fdopen(fd,'rb')
+ m=md5()
+ try:
+ while fname:
+ fname=f.read(200000)
+ m.update(fname)
+ finally:
+ f.close()
+ return m.digest()
+readf_unix=readf
+writef_unix=writef
+h_file_unix=h_file
+if hasattr(os,'O_NOINHERIT')and sys.hexversion<0x3040000:
+ readf=readf_win32
+ writef=writef_win32
+ h_file=h_file_win32
+try:
+ x=''.encode('hex')
+except LookupError:
+ import binascii
+ def to_hex(s):
+ ret=binascii.hexlify(s)
+ if not isinstance(ret,str):
+ ret=ret.decode('utf-8')
+ return ret
+else:
+ def to_hex(s):
+ return s.encode('hex')
+to_hex.__doc__="""
+Return the hexadecimal representation of a string
+
+:param s: string to convert
+:type s: string
+"""
+def listdir_win32(s):
+ if not s:
+ try:
+ import ctypes
+ except ImportError:
+ return[x+':\\'for x in list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')]
+ else:
+ dlen=4
+ maxdrives=26
+ buf=ctypes.create_string_buffer(maxdrives*dlen)
+ ndrives=ctypes.windll.kernel32.GetLogicalDriveStringsA(maxdrives*dlen,ctypes.byref(buf))
+ return[str(buf.raw[4*i:4*i+2].decode('ascii'))for i in range(int(ndrives/dlen))]
+ if len(s)==2 and s[1]==":":
+ s+=os.sep
+ if not os.path.isdir(s):
+ e=OSError('%s is not a directory'%s)
+ e.errno=errno.ENOENT
+ raise e
+ return os.listdir(s)
+listdir=os.listdir
+if is_win32:
+ listdir=listdir_win32
+def num2ver(ver):
+ if isinstance(ver,str):
+ ver=tuple(ver.split('.'))
+ if isinstance(ver,tuple):
+ ret=0
+ for i in range(4):
+ if i<len(ver):
+ ret+=256**(3-i)*int(ver[i])
+ return ret
+ return ver
+def ex_stack():
+ exc_type,exc_value,tb=sys.exc_info()
+ exc_lines=traceback.format_exception(exc_type,exc_value,tb)
+ return''.join(exc_lines)
+def to_list(sth):
+ if isinstance(sth,str):
+ return sth.split()
+ else:
+ return sth
+def split_path_unix(path):
+ return path.split('/')
+def split_path_cygwin(path):
+ if path.startswith('//'):
+ ret=path.split('/')[2:]
+ ret[0]='/'+ret[0]
+ return ret
+ return path.split('/')
+re_sp=re.compile('[/\\\\]')
+def split_path_win32(path):
+ if path.startswith('\\\\'):
+ ret=re.split(re_sp,path)[2:]
+ ret[0]='\\'+ret[0]
+ return ret
+ return re.split(re_sp,path)
+msysroot=None
+def split_path_msys(path):
+ if(path.startswith('/')or path.startswith('\\'))and not path.startswith('//')and not path.startswith('\\\\'):
+ global msysroot
+ if not msysroot:
+ msysroot=subprocess.check_output(['cygpath','-w','/']).decode(sys.stdout.encoding or'iso8859-1')
+ msysroot=msysroot.strip()
+ path=os.path.normpath(msysroot+os.sep+path)
+ return split_path_win32(path)
+if sys.platform=='cygwin':
+ split_path=split_path_cygwin
+elif is_win32:
+ if os.environ.get('MSYSTEM',None):
+ split_path=split_path_msys
+ else:
+ split_path=split_path_win32
+else:
+ split_path=split_path_unix
+split_path.__doc__="""
+Split a path by / or \\. This function is not like os.path.split
+
+:type path: string
+:param path: path to split
+:return: list of strings
+"""
+def check_dir(path):
+ if not os.path.isdir(path):
+ try:
+ os.makedirs(path)
+ except OSError ,e:
+ if not os.path.isdir(path):
+ raise Errors.WafError('Cannot create the folder %r'%path,ex=e)
+def check_exe(name,env=None):
+ if not name:
+ raise ValueError('Cannot execute an empty string!')
+ def is_exe(fpath):
+ return os.path.isfile(fpath)and os.access(fpath,os.X_OK)
+ fpath,fname=os.path.split(name)
+ if fpath and is_exe(name):
+ return os.path.abspath(name)
+ else:
+ env=env or os.environ
+ for path in env["PATH"].split(os.pathsep):
+ path=path.strip('"')
+ exe_file=os.path.join(path,name)
+ if is_exe(exe_file):
+ return os.path.abspath(exe_file)
+ return None
+def def_attrs(cls,**kw):
+ for k,v in kw.items():
+ if not hasattr(cls,k):
+ setattr(cls,k,v)
+def quote_define_name(s):
+ fu=re.sub('[^a-zA-Z0-9]','_',s)
+ fu=re.sub('_+','_',fu)
+ fu=fu.upper()
+ return fu
+def h_list(lst):
+ m=md5()
+ m.update(str(lst))
+ return m.digest()
+def h_fun(fun):
+ try:
+ return fun.code
+ except AttributeError:
+ try:
+ h=inspect.getsource(fun)
+ except IOError:
+ h="nocode"
+ try:
+ fun.code=h
+ except AttributeError:
+ pass
+ return h
+def h_cmd(ins):
+ if isinstance(ins,str):
+ ret=ins
+ elif isinstance(ins,list)or isinstance(ins,tuple):
+ ret=str([h_cmd(x)for x in ins])
+ else:
+ ret=str(h_fun(ins))
+ if sys.hexversion>0x3000000:
+ ret=ret.encode('iso8859-1','xmlcharrefreplace')
+ return ret
+reg_subst=re.compile(r"(\\\\)|(\$\$)|\$\{([^}]+)\}")
+def subst_vars(expr,params):
+ def repl_var(m):
+ if m.group(1):
+ return'\\'
+ if m.group(2):
+ return'$'
+ try:
+ return params.get_flat(m.group(3))
+ except AttributeError:
+ return params[m.group(3)]
+ return reg_subst.sub(repl_var,expr)
+def destos_to_binfmt(key):
+ if key=='darwin':
+ return'mac-o'
+ elif key in('win32','cygwin','uwin','msys'):
+ return'pe'
+ return'elf'
+def unversioned_sys_platform():
+ s=sys.platform
+ if s.startswith('java'):
+ from java.lang import System
+ s=System.getProperty('os.name')
+ if s=='Mac OS X':
+ return'darwin'
+ elif s.startswith('Windows '):
+ return'win32'
+ elif s=='OS/2':
+ return'os2'
+ elif s=='HP-UX':
+ return'hp-ux'
+ elif s in('SunOS','Solaris'):
+ return'sunos'
+ else:s=s.lower()
+ if s=='powerpc':
+ return'darwin'
+ if s=='win32'or s=='os2':
+ return s
+ if s=='cli'and os.name=='nt':
+ return'win32'
+ return re.split('\d+$',s)[0]
+def nada(*k,**kw):
+ pass
+class Timer(object):
+ def __init__(self):
+ self.start_time=datetime.datetime.utcnow()
+ def __str__(self):
+ delta=datetime.datetime.utcnow()-self.start_time
+ days=delta.days
+ hours,rem=divmod(delta.seconds,3600)
+ minutes,seconds=divmod(rem,60)
+ seconds+=delta.microseconds*1e-6
+ result=''
+ if days:
+ result+='%dd'%days
+ if days or hours:
+ result+='%dh'%hours
+ if days or hours or minutes:
+ result+='%dm'%minutes
+ return'%s%.3fs'%(result,seconds)
+if is_win32:
+ old=shutil.copy2
+ def copy2(src,dst):
+ old(src,dst)
+ shutil.copystat(src,dst)
+ setattr(shutil,'copy2',copy2)
+if os.name=='java':
+ try:
+ gc.disable()
+ gc.enable()
+ except NotImplementedError:
+ gc.disable=gc.enable
+def read_la_file(path):
+ sp=re.compile(r'^([^=]+)=\'(.*)\'$')
+ dc={}
+ for line in readf(path).splitlines():
+ try:
+ _,left,right,_=sp.split(line.strip())
+ dc[left]=right
+ except ValueError:
+ pass
+ return dc
+def nogc(fun):
+ def f(*k,**kw):
+ try:
+ gc.disable()
+ ret=fun(*k,**kw)
+ finally:
+ gc.enable()
+ return ret
+ f.__doc__=fun.__doc__
+ return f
+def run_once(fun):
+ cache={}
+ def wrap(k):
+ try:
+ return cache[k]
+ except KeyError:
+ ret=fun(k)
+ cache[k]=ret
+ return ret
+ wrap.__cache__=cache
+ wrap.__name__=fun.__name__
+ return wrap
+def get_registry_app_path(key,filename):
+ if not winreg:
+ return None
+ try:
+ result=winreg.QueryValue(key,"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\%s.exe"%filename[0])
+ except WindowsError:
+ pass
+ else:
+ if os.path.isfile(result):
+ return result
+def lib64():
+ if os.sep=='/':
+ if platform.architecture()[0]=='64bit':
+ if os.path.exists('/usr/lib64')and not os.path.exists('/usr/lib32'):
+ return'64'
+ return''
+def sane_path(p):
+ return os.path.abspath(os.path.expanduser(p))
diff --git a/waflib/__init__.py b/waflib/__init__.py
new file mode 100644
index 0000000..55e850d
--- /dev/null
+++ b/waflib/__init__.py
@@ -0,0 +1,4 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
diff --git a/waflib/ansiterm.py b/waflib/ansiterm.py
new file mode 100644
index 0000000..8de767d
--- /dev/null
+++ b/waflib/ansiterm.py
@@ -0,0 +1,238 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,re,sys
+from waflib import Utils
+wlock=Utils.threading.Lock()
+try:
+ from ctypes import Structure,windll,c_short,c_ushort,c_ulong,c_int,byref,c_wchar,POINTER,c_long
+except ImportError:
+ class AnsiTerm(object):
+ def __init__(self,stream):
+ self.stream=stream
+ try:
+ self.errors=self.stream.errors
+ except AttributeError:
+ pass
+ self.encoding=self.stream.encoding
+ def write(self,txt):
+ try:
+ wlock.acquire()
+ self.stream.write(txt)
+ self.stream.flush()
+ finally:
+ wlock.release()
+ def fileno(self):
+ return self.stream.fileno()
+ def flush(self):
+ self.stream.flush()
+ def isatty(self):
+ return self.stream.isatty()
+else:
+ class COORD(Structure):
+ _fields_=[("X",c_short),("Y",c_short)]
+ class SMALL_RECT(Structure):
+ _fields_=[("Left",c_short),("Top",c_short),("Right",c_short),("Bottom",c_short)]
+ class CONSOLE_SCREEN_BUFFER_INFO(Structure):
+ _fields_=[("Size",COORD),("CursorPosition",COORD),("Attributes",c_ushort),("Window",SMALL_RECT),("MaximumWindowSize",COORD)]
+ class CONSOLE_CURSOR_INFO(Structure):
+ _fields_=[('dwSize',c_ulong),('bVisible',c_int)]
+ try:
+ _type=unicode
+ except NameError:
+ _type=str
+ to_int=lambda number,default:number and int(number)or default
+ STD_OUTPUT_HANDLE=-11
+ STD_ERROR_HANDLE=-12
+ windll.kernel32.GetStdHandle.argtypes=[c_ulong]
+ windll.kernel32.GetStdHandle.restype=c_ulong
+ windll.kernel32.GetConsoleScreenBufferInfo.argtypes=[c_ulong,POINTER(CONSOLE_SCREEN_BUFFER_INFO)]
+ windll.kernel32.GetConsoleScreenBufferInfo.restype=c_long
+ windll.kernel32.SetConsoleTextAttribute.argtypes=[c_ulong,c_ushort]
+ windll.kernel32.SetConsoleTextAttribute.restype=c_long
+ windll.kernel32.FillConsoleOutputCharacterW.argtypes=[c_ulong,c_wchar,c_ulong,POINTER(COORD),POINTER(c_ulong)]
+ windll.kernel32.FillConsoleOutputCharacterW.restype=c_long
+ windll.kernel32.FillConsoleOutputAttribute.argtypes=[c_ulong,c_ushort,c_ulong,POINTER(COORD),POINTER(c_ulong)]
+ windll.kernel32.FillConsoleOutputAttribute.restype=c_long
+ windll.kernel32.SetConsoleCursorPosition.argtypes=[c_ulong,POINTER(COORD)]
+ windll.kernel32.SetConsoleCursorPosition.restype=c_long
+ windll.kernel32.SetConsoleCursorInfo.argtypes=[c_ulong,POINTER(CONSOLE_CURSOR_INFO)]
+ windll.kernel32.SetConsoleCursorInfo.restype=c_long
+ class AnsiTerm(object):
+ def __init__(self,s):
+ self.stream=s
+ try:
+ self.errors=s.errors
+ except AttributeError:
+ pass
+ self.encoding=s.encoding
+ self.cursor_history=[]
+ handle=(s.fileno()==2)and STD_ERROR_HANDLE or STD_OUTPUT_HANDLE
+ self.hconsole=windll.kernel32.GetStdHandle(handle)
+ self._sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
+ self._csinfo=CONSOLE_CURSOR_INFO()
+ windll.kernel32.GetConsoleCursorInfo(self.hconsole,byref(self._csinfo))
+ self._orig_sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
+ r=windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole,byref(self._orig_sbinfo))
+ self._isatty=r==1
+ def screen_buffer_info(self):
+ windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole,byref(self._sbinfo))
+ return self._sbinfo
+ def clear_line(self,param):
+ mode=param and int(param)or 0
+ sbinfo=self.screen_buffer_info()
+ if mode==1:
+ line_start=COORD(0,sbinfo.CursorPosition.Y)
+ line_length=sbinfo.Size.X
+ elif mode==2:
+ line_start=COORD(sbinfo.CursorPosition.X,sbinfo.CursorPosition.Y)
+ line_length=sbinfo.Size.X-sbinfo.CursorPosition.X
+ else:
+ line_start=sbinfo.CursorPosition
+ line_length=sbinfo.Size.X-sbinfo.CursorPosition.X
+ chars_written=c_ulong()
+ windll.kernel32.FillConsoleOutputCharacterW(self.hconsole,c_wchar(' '),line_length,line_start,byref(chars_written))
+ windll.kernel32.FillConsoleOutputAttribute(self.hconsole,sbinfo.Attributes,line_length,line_start,byref(chars_written))
+ def clear_screen(self,param):
+ mode=to_int(param,0)
+ sbinfo=self.screen_buffer_info()
+ if mode==1:
+ clear_start=COORD(0,0)
+ clear_length=sbinfo.CursorPosition.X*sbinfo.CursorPosition.Y
+ elif mode==2:
+ clear_start=COORD(0,0)
+ clear_length=sbinfo.Size.X*sbinfo.Size.Y
+ windll.kernel32.SetConsoleCursorPosition(self.hconsole,clear_start)
+ else:
+ clear_start=sbinfo.CursorPosition
+ clear_length=((sbinfo.Size.X-sbinfo.CursorPosition.X)+sbinfo.Size.X*(sbinfo.Size.Y-sbinfo.CursorPosition.Y))
+ chars_written=c_ulong()
+ windll.kernel32.FillConsoleOutputCharacterW(self.hconsole,c_wchar(' '),clear_length,clear_start,byref(chars_written))
+ windll.kernel32.FillConsoleOutputAttribute(self.hconsole,sbinfo.Attributes,clear_length,clear_start,byref(chars_written))
+ def push_cursor(self,param):
+ sbinfo=self.screen_buffer_info()
+ self.cursor_history.append(sbinfo.CursorPosition)
+ def pop_cursor(self,param):
+ if self.cursor_history:
+ old_pos=self.cursor_history.pop()
+ windll.kernel32.SetConsoleCursorPosition(self.hconsole,old_pos)
+ def set_cursor(self,param):
+ y,sep,x=param.partition(';')
+ x=to_int(x,1)-1
+ y=to_int(y,1)-1
+ sbinfo=self.screen_buffer_info()
+ new_pos=COORD(min(max(0,x),sbinfo.Size.X),min(max(0,y),sbinfo.Size.Y))
+ windll.kernel32.SetConsoleCursorPosition(self.hconsole,new_pos)
+ def set_column(self,param):
+ x=to_int(param,1)-1
+ sbinfo=self.screen_buffer_info()
+ new_pos=COORD(min(max(0,x),sbinfo.Size.X),sbinfo.CursorPosition.Y)
+ windll.kernel32.SetConsoleCursorPosition(self.hconsole,new_pos)
+ def move_cursor(self,x_offset=0,y_offset=0):
+ sbinfo=self.screen_buffer_info()
+ 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))
+ windll.kernel32.SetConsoleCursorPosition(self.hconsole,new_pos)
+ def move_up(self,param):
+ self.move_cursor(y_offset=-to_int(param,1))
+ def move_down(self,param):
+ self.move_cursor(y_offset=to_int(param,1))
+ def move_left(self,param):
+ self.move_cursor(x_offset=-to_int(param,1))
+ def move_right(self,param):
+ self.move_cursor(x_offset=to_int(param,1))
+ def next_line(self,param):
+ sbinfo=self.screen_buffer_info()
+ self.move_cursor(x_offset=-sbinfo.CursorPosition.X,y_offset=to_int(param,1))
+ def prev_line(self,param):
+ sbinfo=self.screen_buffer_info()
+ self.move_cursor(x_offset=-sbinfo.CursorPosition.X,y_offset=-to_int(param,1))
+ def rgb2bgr(self,c):
+ return((c&1)<<2)|(c&2)|((c&4)>>2)
+ def set_color(self,param):
+ cols=param.split(';')
+ sbinfo=self.screen_buffer_info()
+ attr=sbinfo.Attributes
+ for c in cols:
+ c=to_int(c,0)
+ if 29<c<38:
+ attr=(attr&0xfff0)|self.rgb2bgr(c-30)
+ elif 39<c<48:
+ attr=(attr&0xff0f)|(self.rgb2bgr(c-40)<<4)
+ elif c==0:
+ attr=self._orig_sbinfo.Attributes
+ elif c==1:
+ attr|=0x08
+ elif c==4:
+ attr|=0x80
+ elif c==7:
+ attr=(attr&0xff88)|((attr&0x70)>>4)|((attr&0x07)<<4)
+ windll.kernel32.SetConsoleTextAttribute(self.hconsole,attr)
+ def show_cursor(self,param):
+ self._csinfo.bVisible=1
+ windll.kernel32.SetConsoleCursorInfo(self.hconsole,byref(self._csinfo))
+ def hide_cursor(self,param):
+ self._csinfo.bVisible=0
+ windll.kernel32.SetConsoleCursorInfo(self.hconsole,byref(self._csinfo))
+ 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,}
+ ansi_tokens=re.compile('(?:\x1b\[([0-9?;]*)([a-zA-Z])|([^\x1b]+))')
+ def write(self,text):
+ try:
+ wlock.acquire()
+ if self._isatty:
+ for param,cmd,txt in self.ansi_tokens.findall(text):
+ if cmd:
+ cmd_func=self.ansi_command_table.get(cmd)
+ if cmd_func:
+ cmd_func(self,param)
+ else:
+ self.writeconsole(txt)
+ else:
+ self.stream.write(text)
+ finally:
+ wlock.release()
+ def writeconsole(self,txt):
+ chars_written=c_ulong()
+ writeconsole=windll.kernel32.WriteConsoleA
+ if isinstance(txt,_type):
+ writeconsole=windll.kernel32.WriteConsoleW
+ done=0
+ todo=len(txt)
+ chunk=32<<10
+ while todo!=0:
+ doing=min(chunk,todo)
+ buf=txt[done:done+doing]
+ r=writeconsole(self.hconsole,buf,doing,byref(chars_written),None)
+ if r==0:
+ chunk>>=1
+ continue
+ done+=doing
+ todo-=doing
+ def fileno(self):
+ return self.stream.fileno()
+ def flush(self):
+ pass
+ def isatty(self):
+ return self._isatty
+ if sys.stdout.isatty()or sys.stderr.isatty():
+ handle=sys.stdout.isatty()and STD_OUTPUT_HANDLE or STD_ERROR_HANDLE
+ console=windll.kernel32.GetStdHandle(handle)
+ sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
+ def get_term_cols():
+ windll.kernel32.GetConsoleScreenBufferInfo(console,byref(sbinfo))
+ return sbinfo.Size.X-1
+try:
+ import struct,fcntl,termios
+except ImportError:
+ pass
+else:
+ if(sys.stdout.isatty()or sys.stderr.isatty())and os.environ.get('TERM','')not in('dumb','emacs'):
+ FD=sys.stdout.isatty()and sys.stdout.fileno()or sys.stderr.fileno()
+ def fun():
+ return struct.unpack("HHHH",fcntl.ioctl(FD,termios.TIOCGWINSZ,struct.pack("HHHH",0,0,0,0)))[1]
+ try:
+ fun()
+ except Exception ,e:
+ pass
+ else:
+ get_term_cols=fun
diff --git a/waflib/extras/__init__.py b/waflib/extras/__init__.py
new file mode 100644
index 0000000..55e850d
--- /dev/null
+++ b/waflib/extras/__init__.py
@@ -0,0 +1,4 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
diff --git a/waflib/extras/compat15.py b/waflib/extras/compat15.py
new file mode 100644
index 0000000..aa30079
--- /dev/null
+++ b/waflib/extras/compat15.py
@@ -0,0 +1,301 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import sys
+from waflib import ConfigSet,Logs,Options,Scripting,Task,Build,Configure,Node,Runner,TaskGen,Utils,Errors,Context
+sys.modules['Environment']=ConfigSet
+ConfigSet.Environment=ConfigSet.ConfigSet
+sys.modules['Logs']=Logs
+sys.modules['Options']=Options
+sys.modules['Scripting']=Scripting
+sys.modules['Task']=Task
+sys.modules['Build']=Build
+sys.modules['Configure']=Configure
+sys.modules['Node']=Node
+sys.modules['Runner']=Runner
+sys.modules['TaskGen']=TaskGen
+sys.modules['Utils']=Utils
+sys.modules['Constants']=Context
+Context.SRCDIR=''
+Context.BLDDIR=''
+from waflib.Tools import c_preproc
+sys.modules['preproc']=c_preproc
+from waflib.Tools import c_config
+sys.modules['config_c']=c_config
+ConfigSet.ConfigSet.copy=ConfigSet.ConfigSet.derive
+ConfigSet.ConfigSet.set_variant=Utils.nada
+Utils.pproc=Utils.subprocess
+Build.BuildContext.add_subdirs=Build.BuildContext.recurse
+Build.BuildContext.new_task_gen=Build.BuildContext.__call__
+Build.BuildContext.is_install=0
+Node.Node.relpath_gen=Node.Node.path_from
+Utils.pproc=Utils.subprocess
+Utils.get_term_cols=Logs.get_term_cols
+def cmd_output(cmd,**kw):
+ silent=False
+ if'silent'in kw:
+ silent=kw['silent']
+ del(kw['silent'])
+ if'e'in kw:
+ tmp=kw['e']
+ del(kw['e'])
+ kw['env']=tmp
+ kw['shell']=isinstance(cmd,str)
+ kw['stdout']=Utils.subprocess.PIPE
+ if silent:
+ kw['stderr']=Utils.subprocess.PIPE
+ try:
+ p=Utils.subprocess.Popen(cmd,**kw)
+ output=p.communicate()[0]
+ except OSError ,e:
+ raise ValueError(str(e))
+ if p.returncode:
+ if not silent:
+ msg="command execution failed: %s -> %r"%(cmd,str(output))
+ raise ValueError(msg)
+ output=''
+ return output
+Utils.cmd_output=cmd_output
+def name_to_obj(self,s,env=None):
+ if Logs.verbose:
+ Logs.warn('compat: change "name_to_obj(name, env)" by "get_tgen_by_name(name)"')
+ return self.get_tgen_by_name(s)
+Build.BuildContext.name_to_obj=name_to_obj
+def env_of_name(self,name):
+ try:
+ return self.all_envs[name]
+ except KeyError:
+ Logs.error('no such environment: '+name)
+ return None
+Build.BuildContext.env_of_name=env_of_name
+def set_env_name(self,name,env):
+ self.all_envs[name]=env
+ return env
+Configure.ConfigurationContext.set_env_name=set_env_name
+def retrieve(self,name,fromenv=None):
+ try:
+ env=self.all_envs[name]
+ except KeyError:
+ env=ConfigSet.ConfigSet()
+ self.prepare_env(env)
+ self.all_envs[name]=env
+ else:
+ if fromenv:
+ Logs.warn("The environment %s may have been configured already"%name)
+ return env
+Configure.ConfigurationContext.retrieve=retrieve
+Configure.ConfigurationContext.sub_config=Configure.ConfigurationContext.recurse
+Configure.ConfigurationContext.check_tool=Configure.ConfigurationContext.load
+Configure.conftest=Configure.conf
+Configure.ConfigurationError=Errors.ConfigurationError
+Utils.WafError=Errors.WafError
+Options.OptionsContext.sub_options=Options.OptionsContext.recurse
+Options.OptionsContext.tool_options=Context.Context.load
+Options.Handler=Options.OptionsContext
+Task.simple_task_type=Task.task_type_from_func=Task.task_factory
+Task.TaskBase.classes=Task.classes
+def setitem(self,key,value):
+ if key.startswith('CCFLAGS'):
+ key=key[1:]
+ self.table[key]=value
+ConfigSet.ConfigSet.__setitem__=setitem
+@TaskGen.feature('d')
+@TaskGen.before('apply_incpaths')
+def old_importpaths(self):
+ if getattr(self,'importpaths',[]):
+ self.includes=self.importpaths
+from waflib import Context
+eld=Context.load_tool
+def load_tool(*k,**kw):
+ ret=eld(*k,**kw)
+ if'set_options'in ret.__dict__:
+ if Logs.verbose:
+ Logs.warn('compat: rename "set_options" to options')
+ ret.options=ret.set_options
+ if'detect'in ret.__dict__:
+ if Logs.verbose:
+ Logs.warn('compat: rename "detect" to "configure"')
+ ret.configure=ret.detect
+ return ret
+Context.load_tool=load_tool
+def get_curdir(self):
+ return self.path.abspath()
+Context.Context.curdir=property(get_curdir,Utils.nada)
+def get_srcdir(self):
+ return self.srcnode.abspath()
+Configure.ConfigurationContext.srcdir=property(get_srcdir,Utils.nada)
+def get_blddir(self):
+ return self.bldnode.abspath()
+Configure.ConfigurationContext.blddir=property(get_blddir,Utils.nada)
+Configure.ConfigurationContext.check_message_1=Configure.ConfigurationContext.start_msg
+Configure.ConfigurationContext.check_message_2=Configure.ConfigurationContext.end_msg
+rev=Context.load_module
+def load_module(path,encoding=None):
+ ret=rev(path,encoding)
+ if'set_options'in ret.__dict__:
+ if Logs.verbose:
+ Logs.warn('compat: rename "set_options" to "options" (%r)'%path)
+ ret.options=ret.set_options
+ if'srcdir'in ret.__dict__:
+ if Logs.verbose:
+ Logs.warn('compat: rename "srcdir" to "top" (%r)'%path)
+ ret.top=ret.srcdir
+ if'blddir'in ret.__dict__:
+ if Logs.verbose:
+ Logs.warn('compat: rename "blddir" to "out" (%r)'%path)
+ ret.out=ret.blddir
+ Utils.g_module=Context.g_module
+ Options.launch_dir=Context.launch_dir
+ return ret
+Context.load_module=load_module
+old_post=TaskGen.task_gen.post
+def post(self):
+ self.features=self.to_list(self.features)
+ if'cc'in self.features:
+ if Logs.verbose:
+ Logs.warn('compat: the feature cc does not exist anymore (use "c")')
+ self.features.remove('cc')
+ self.features.append('c')
+ if'cstaticlib'in self.features:
+ if Logs.verbose:
+ Logs.warn('compat: the feature cstaticlib does not exist anymore (use "cstlib" or "cxxstlib")')
+ self.features.remove('cstaticlib')
+ self.features.append(('cxx'in self.features)and'cxxstlib'or'cstlib')
+ if getattr(self,'ccflags',None):
+ if Logs.verbose:
+ Logs.warn('compat: "ccflags" was renamed to "cflags"')
+ self.cflags=self.ccflags
+ return old_post(self)
+TaskGen.task_gen.post=post
+def waf_version(*k,**kw):
+ Logs.warn('wrong version (waf_version was removed in waf 1.6)')
+Utils.waf_version=waf_version
+import os
+@TaskGen.feature('c','cxx','d')
+@TaskGen.before('apply_incpaths','propagate_uselib_vars')
+@TaskGen.after('apply_link','process_source')
+def apply_uselib_local(self):
+ env=self.env
+ from waflib.Tools.ccroot import stlink_task
+ self.uselib=self.to_list(getattr(self,'uselib',[]))
+ self.includes=self.to_list(getattr(self,'includes',[]))
+ names=self.to_list(getattr(self,'uselib_local',[]))
+ get=self.bld.get_tgen_by_name
+ seen=set([])
+ seen_uselib=set([])
+ tmp=Utils.deque(names)
+ if tmp:
+ if Logs.verbose:
+ Logs.warn('compat: "uselib_local" is deprecated, replace by "use"')
+ while tmp:
+ lib_name=tmp.popleft()
+ if lib_name in seen:
+ continue
+ y=get(lib_name)
+ y.post()
+ seen.add(lib_name)
+ if getattr(y,'uselib_local',None):
+ for x in self.to_list(getattr(y,'uselib_local',[])):
+ obj=get(x)
+ obj.post()
+ if getattr(obj,'link_task',None):
+ if not isinstance(obj.link_task,stlink_task):
+ tmp.append(x)
+ if getattr(y,'link_task',None):
+ link_name=y.target[y.target.rfind(os.sep)+1:]
+ if isinstance(y.link_task,stlink_task):
+ env.append_value('STLIB',[link_name])
+ else:
+ env.append_value('LIB',[link_name])
+ self.link_task.set_run_after(y.link_task)
+ self.link_task.dep_nodes+=y.link_task.outputs
+ tmp_path=y.link_task.outputs[0].parent.bldpath()
+ if not tmp_path in env['LIBPATH']:
+ env.prepend_value('LIBPATH',[tmp_path])
+ for v in self.to_list(getattr(y,'uselib',[])):
+ if v not in seen_uselib:
+ seen_uselib.add(v)
+ if not env['STLIB_'+v]:
+ if not v in self.uselib:
+ self.uselib.insert(0,v)
+ if getattr(y,'export_includes',None):
+ self.includes.extend(y.to_incnodes(y.export_includes))
+@TaskGen.feature('cprogram','cxxprogram','cstlib','cxxstlib','cshlib','cxxshlib','dprogram','dstlib','dshlib')
+@TaskGen.after('apply_link')
+def apply_objdeps(self):
+ names=getattr(self,'add_objects',[])
+ if not names:
+ return
+ names=self.to_list(names)
+ get=self.bld.get_tgen_by_name
+ seen=[]
+ while names:
+ x=names[0]
+ if x in seen:
+ names=names[1:]
+ continue
+ y=get(x)
+ if getattr(y,'add_objects',None):
+ added=0
+ lst=y.to_list(y.add_objects)
+ lst.reverse()
+ for u in lst:
+ if u in seen:continue
+ added=1
+ names=[u]+names
+ if added:continue
+ y.post()
+ seen.append(x)
+ for t in getattr(y,'compiled_tasks',[]):
+ self.link_task.inputs.extend(t.outputs)
+@TaskGen.after('apply_link')
+def process_obj_files(self):
+ if not hasattr(self,'obj_files'):
+ return
+ for x in self.obj_files:
+ node=self.path.find_resource(x)
+ self.link_task.inputs.append(node)
+@TaskGen.taskgen_method
+def add_obj_file(self,file):
+ if not hasattr(self,'obj_files'):self.obj_files=[]
+ if not'process_obj_files'in self.meths:self.meths.append('process_obj_files')
+ self.obj_files.append(file)
+old_define=Configure.ConfigurationContext.__dict__['define']
+@Configure.conf
+def define(self,key,val,quote=True,comment=''):
+ old_define(self,key,val,quote,comment)
+ if key.startswith('HAVE_'):
+ self.env[key]=1
+old_undefine=Configure.ConfigurationContext.__dict__['undefine']
+@Configure.conf
+def undefine(self,key,comment=''):
+ old_undefine(self,key,comment)
+ if key.startswith('HAVE_'):
+ self.env[key]=0
+def set_incdirs(self,val):
+ Logs.warn('compat: change "export_incdirs" by "export_includes"')
+ self.export_includes=val
+TaskGen.task_gen.export_incdirs=property(None,set_incdirs)
+def install_dir(self,path):
+ if not path:
+ return[]
+ destpath=Utils.subst_vars(path,self.env)
+ if self.is_install>0:
+ Logs.info('* creating %s'%destpath)
+ Utils.check_dir(destpath)
+ elif self.is_install<0:
+ Logs.info('* removing %s'%destpath)
+ try:
+ os.remove(destpath)
+ except OSError:
+ pass
+Build.BuildContext.install_dir=install_dir
+repl={'apply_core':'process_source','apply_lib_vars':'process_source','apply_obj_vars':'propagate_uselib_vars','exec_rule':'process_rule'}
+def after(*k):
+ k=[repl.get(key,key)for key in k]
+ return TaskGen.after_method(*k)
+def before(*k):
+ k=[repl.get(key,key)for key in k]
+ return TaskGen.before_method(*k)
+TaskGen.before=before
diff --git a/waflib/fixpy2.py b/waflib/fixpy2.py
new file mode 100644
index 0000000..5e434d1
--- /dev/null
+++ b/waflib/fixpy2.py
@@ -0,0 +1,53 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os
+all_modifs={}
+def fixdir(dir):
+ global all_modifs
+ for k in all_modifs:
+ for v in all_modifs[k]:
+ modif(os.path.join(dir,'waflib'),k,v)
+def modif(dir,name,fun):
+ if name=='*':
+ lst=[]
+ for y in'. Tools extras'.split():
+ for x in os.listdir(os.path.join(dir,y)):
+ if x.endswith('.py'):
+ lst.append(y+os.sep+x)
+ for x in lst:
+ modif(dir,x,fun)
+ return
+ filename=os.path.join(dir,name)
+ f=open(filename,'r')
+ try:
+ txt=f.read()
+ finally:
+ f.close()
+ txt=fun(txt)
+ f=open(filename,'w')
+ try:
+ f.write(txt)
+ finally:
+ f.close()
+def subst(*k):
+ def do_subst(fun):
+ global all_modifs
+ for x in k:
+ try:
+ all_modifs[x].append(fun)
+ except KeyError:
+ all_modifs[x]=[fun]
+ return fun
+ return do_subst
+@subst('*')
+def r1(code):
+ code=code.replace(',e:',',e:')
+ code=code.replace("",'')
+ code=code.replace('','')
+ return code
+@subst('Runner.py')
+def r4(code):
+ code=code.replace('next(self.biter)','self.biter.next()')
+ return code