HH__PAGEZEROx__TEXT__text__TEXT __stubs__TEXT__stub_helper__TEXT`L`__cstring__TEXTA__const__TEXT__unwind_info__TEXT__eh_frame__TEXTXaXx__DATA  __dyld__DATA__got__DATAHq__la_symbol_ptr__DATAXXz__const__DATA__data__DATApp__common__DATA0 __bss__DATAPH__LINKEDIT@,4/X Px(, /usr/lib/dyld&e9̖;$ * h;/System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices 8/usr/lib/libSystem.B.dylib 8 /usr/lib/libgcc_s.1.dylib hW/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation&)jHHH}HuHUHAWAVATSHIIAD=WL%XL5YI$Hu HHHHHQt/uH.LH;H[uH"HHtHHHt蠂H=XHuZUH=rHuGH}Ht豂HDLLH ȂASLSAS%K%JUHAWAVSPHA1(ILTt$H<H51HL\A HDH[A^A_]UHAWAVATSH1[(IA1HC(IH51HLL1HH蔃tHH5{1HLHAD[A\A^A_]UHAVSH@IH@HH1Hu&HÊt <\u/HLH@[A^]UHAWAVAUATSHHHuԿ1sysdHuп2sysVHu̿3sysHDmA DeD}L5uAD$w HH DL411HeH5H$A*HHRH5iHWA*HUH&H5JHWA*H)HH5'HHLHH[A\A]A^A_]UH1B]UHSHxH1&8tHuHt 1 u@HHx[]UHSPH1%HH߉H[]UHHHu襀1u EЃHĀ]UHAWAVAUATSPI1O%Iǿ Iľ/L蜀IMtQLL)H{ID$HLHfID$LILL)HiID$IHL0OID$f.LHx4ID$HLI|$PI$LLH[A\A]A^A_]UHSP8HH;Ht ~H{n~H{e~H]~1H[]UHSPHHpHHPH[]UHAWAVSHxHHHHPHH5E11H1HpIǾHG HpL~u$x%f=HADHx[A^A_]UHAWAVSPI!II?1HtH~ I?~1HIGt.x.tHI1H}uѻLH[A^A_]UHAWAVSPHA1"IǾL]}t$HCH5Ƅ1HLcA HDH[A^A_]UHAWAVAUATSPI 12ALD 1LD3"Hþ;HK}Iž:H;}MuIHuL I9sAMuLH&E1E1HAILH)LHL LH5L L1L3Hu:L IEL'A^L 1A9AL H[A\A]A^A_]UHAWAVSPHA1 IL{tH"HcH51HLADH[A^A_]UHAWAVSHxHA1 IHpL{tHyuiH5ςl11HH5HzHuHHH5݂HRH*EHHB uH5F1HLA!yH5Q1HL~ADHx[A^A_]UHAWAVAUATSHIH=OH5UyHH}H}yIH0y1EEÉEHMHEщUՉUAIIHD]DAщMIHHAEI EI(EH0@H8@I EH(H0H8D$XD\$8L$D|$ \$PT$HDt$@t$0DL$(|$Dl$D$H5_H]1UMDMHyLHHĸ[A\A]A^A_]UHAVSHE115[ ! u 7\u"t $t/u x$tx:uAHD[A^]UHAWAVAUATSHI+ILjH5ʀHL!H5HL!H5HLu!IHyHyE11HyLHLxMDAH51LLHC H= NwLH, 1LEu=H5L LH L11LO ILL HL1H5L HLH5L HLH5Lc HLH5L@ HL11LR11LFAIcI4Ɗ<-u ~-uH6HIH@ [A^]fUHH1yuH 1y tHA ]UHlHQ1uH uHH(]UHCH1yuH]UHAVSAH!HQ1w+H58HcHHDHQ1uH[A^]ÃuHH(UHHG@HHG]UHHG@HHG]UHHGH*@HHG]UHAWAVATSIIHHC HHxH;HprH"LcHLL I$AD$HC[A\A^A_]UHAVSHIHtHjLHH[A^]}IF@HIF[A^]UHAWAVSPIIHHC HHxH;HprH舆HLLH[A^A_]UHAVSHIHt))P)`)p)])e)m)u)}LHL@H8H0HC HHxH;HprHH HEHEHEE0EHUHLH[A^]UHAWAVSPIIIF HHxH;HprL虅IF(I;FPt H@HHPIVxL}Lx INHcHHH)хINtHtHtLL INHuHAIFH[A^A_]UHHGɉ@HHG]UHHGH0@HG]UHHGH8@HGHG H9]UHSPHHSHHHHH[]FUHAWAVSHIHILhHLHTHEEHKHUHLFHCH[A^A_]UHSPH4H8HsH-HKHHQ@AH[]UHAVSAHH8D+HKHH@AHC[A^]UHAWAVATSAAHHC HHxH;HprH虃LcHDDn)I$AD$HC[A\A^A_]UHSPHpHcHHtu HHH HC H1HtHCH@HCH[]UHSPHHt!tu0HKHH@HA$HHKHPxHA HC@HCH[]UHSPHHKHQHHHFHCH[]UHAWAVSHIHvILwfHLHAHEEHKHHUHL_FHCH[A^A_]UHAWAVSPIII_I6HSL ,HKHKHIGx|HHA tI6F t LˈIGHIGH[A^A_]UHAWAVATSAHILcI6HD.IL$HAL$HHCx|HHA tI6F t HTHCHHC[A\A^A_]UHSPH7HK1҃ytHQHcHHu%HHHQtOB tIH0F t@H6u%HHHQt%B tH0F tHʇ HC HHCH[]UHAWAVSPHHtuHKHQH0HV"uDHHSHRHQxǁHKL{HQB AtH0F tH1 HE1IIDH[A^A_]UHAVSAHHCHcHH)H]nAuHCHK(H;ArHA[A^]UHAWAVSHA։ItLIIG@I)IG@E1IOHcHH)HMDuH)H5/HULYpAuIOIW(H;JrHJH[A^A_]UHHVH]mUHHHuHUHOH+O@H5HUE1oH]UHAVSIHHC(H;CPt H@HHPHSx1HwIHH HKHAHCHHHKINHH@HsHFHCH1H[A^]lUHAWAVSH(HHIHHkHEL}LHJ_LLHfpH([A^A_]UHHHHWzu HRz t]Hr E1HH]aqUHG ]UHAVSII^ HHc HHCp1HCxHCp1Ls1wHCxH m#CxcHcH HKxHH)s(HCp1*6(HSpHSpHKx1H9wL+}{!u[A^]WfuUH#`1]UHSPHH0HSHHHKHQHHDHKH[]UHAVSI|=IF HHxH;HprL|IVI+VHLEHcHI)F(u$I^H5(f1L<HCIF[A^]UHHt HG H@HHG H@]UHHG HPHp]UHAVSIHHC HHxH;HprH{HC(H;CPt H@HHPHSxHLHKHAHCH([A^]UHAVSHAHHUHD'HtHMHSH1H2IJHCH[A^]UH1uaHy t*1~Ry 19|HHcHHD(HHd.1~(Hy 19wH|HcHL(HIH HO8HH]UHAWAVSPAHIHULDjIMtAHCHHHKHMHPH@AHCx|HB tI7F tH{LH[A^A_]UHAWAVSHxIAHHp1LtbH5gHpHINH}H5g^uAtLHxHuH gHxH5g1HDMA4H5vg1HDL(HxH5ug1HL Hx[A^A_]UHAVSHIHt))P)`)p)])e)m)u)}LHL@H8H0H HEHEHEE0EHHUHLPHGHH[A^]UHAWAVSPIAHH߉HH5f1HL7HDHH[A^A_]+UHSHxHHUKt1H5fHUHLM~HUH5ff1HH5b1HHx[]UHAWAVAUATSPIAIHt1LDw 1LDII<$Ht1L[t=I|HHuH5e1LLJLDHH[A\A]A^A_]:H[A\A]A^A_]UHAWAVATSIIAHv~HDL[A\A^A_]#Mt1MtLa[IL[A\A^A_]UHAWAVSPAIHHuL-LDHHH[A^A_]UHAVSIHLEH1u;H11HHtHL [A^]UHAWAVATSIAHIMtDHDt5HLH tHHDL,E1L[A\A^A_]UHAVSIHt[A^]H5 d1HL[A^]/UHAWAVSPAAHD9u H[A^A_]HDHDHH[A^A_]UHAVSAHrt[A^]HcHD[A^]UHAVSHAH,Wf.u;z9HDEEu H)HDHEH[A^]UHAVSHEAH~HDH[A^]kEH[A^]UHAWAVSPAIHHu*LDuLLDHHH[A^A_]UHAWAVSPIAHB~HDH[A^A_]zLH[A^A_]UHAWAVSPIHE1tKHLHHtHA HDH[A^A_]UHAWAVSPI׉I'='w L\LLSE1t"L3AL6DH[A^A_]UH1]UHAWAVAUATSPAIHIHE1I?tIGE1AH8H@uH3aL LH.LtVLLHDHtH5`1LHL@LHLDLI?tUD)EDEDA~LAuIwLED8ILuoIMuALDH[A\A]A^A_]+UHAWAVAUATSPAII1HEо.LUHHuLUHLIM)LLLL.LVuOL;.DD1LeLLLLLSLuL;.Lk0L*LmHEH[A\A]A^A_]UHAWAVAUATSH8IIHILLTHLHHDžHLTIMtYLLLLH)LHL4TLLHLLHH/TIMuHTLLHHaL"HDž1HH8[A\A]A^A_]UHH~HFHF]UHAWAVATSIHIMt0MIIL9r LnI HHPIMu[A\A^A_]UHAVSHIH$SLHH[A^]UHSPHBH{s-CH[]UHSPHtHBHHH[]UHAVSHHLs1L)tH{L4L3C[A^]UHAWAVAUATSPIA~|aM~LEIAL-ANT ~AIA9|I9wLDVD)AFH[A\A]A^A_]UHAVSHHLsHULEHUH;HH)H9v&Ht LnCHHPHEHLH[A^]UHAWAVSPAIA'='w LEtL,tJ1LDL/HþL`LDt%1LD3L3HLD H[A^A_]UHAWAVSPA׉IExS'='w L\1LpLDIcL1LH[A^A_]H[A^A_]UHAWAVAUATSHHIgHDžt>H5uZ1LHwH5eZHNHHHu1H5IZH50ZL]HH8HN#u:DžHN tuHAƸzHjNHAƃubHt]HH5VHNHHHuH5YLHNtuDžAHDO1LIH5HLH3AHHNMAEtH2MEt)LH5YL+AL#DH[A\A]A^A_]UHAWAVATSAIH8L8/NI1HDHHH5X1HLMHD[A\A^A_]UHAVSIH;tIHX8H{XL1u'HKHHrLHIHDH[A^]UHHHuHUH5HUH]UHHN1HtH HFH]UHAVSHHIH:MH]HEH5HULHH[A^]UHSPH=(1HHtH50HHH[]UHHHt H]WLK1]UHSPH٠H1HH5W1HHIK1H[]ÐUHAVSH+L5WHLHNHLH5WHHWHH5WHH HSH5WH8H wH61HHHiH5WWHHD[A^]UHAWAVATSAIILDuH5S1LueLLD'LLpLDSw]LAAwLruH5S1LLLD7HcH (HH5MS1LLLAD[A\A^A_]UHSHxH1H9tJHt6u-HU1HH6HDHx[]UHAWAVSPIIH1HHLHLH[A^A_]UHSPHfHH1HH[]UHAVSIBHþL HcLHYLL[A^]UHSPHHRHEHH[]UHAVSHsAHH2uHmAD[A^]UHAVSHV1HH2Hu511HHHyHraHt/H;HAƾHEuHQHHH[A^]UHSPHHKtHH[]4HkS1HL4HÅx D9AODHLLOA)DH[A^A_]UHSPH1HHLHt>HHWf.u(z&H]H H1=HZuHeuH58K1HOH[]UHAVSHAƾHEtAtHJH2HJHltH5J1HHH [A^]UHAWAVAUATSPI Hþ u/LLnL1LIčC#rHIL`HuL<IH]I9t@HL%ܐA@H]H{@x ADHH߉IƾH}HH5yH1HL[A^]þHH=HH5;HHEH_˾1HHHC믾HI_UHSPH~HH߉ HHH[]UHAWAVATSILKHþL~L LnI1EA)|DA9xHALDgt6LCA9~þL-A9uD[A\A^A_]H5F1L[A\A^A_]bUHSPHkHDH1HHHHH[]UHAWAVSHxIzu L>tLLIEyHFLHpLD'uHFLH5FHpL )LuH5rF1LD'Hx[A^A_]UHSPHtHHhH[]UHAVSIHHFiH41H@HBt2Ht*H7HL[A^]IH5.F1HR1[A^]ÐUHG0;G4~[tOLcHLPC ȃ?u=91AAAA9|"TD9~= C,GJ9~$ HG@։]h]UH  AD HGP]DUHAVSHHDs8C8HCPEHuHD'EH[A^]UH  HGP]UHt5t,HH@Hc΋ t Lu]]UH փHGP]UHG0G4]UH9W0uW4Hw8]xA]UHO0O4Hw8]PUHAWAVAUATSPDEAA׉ItRHcIMHIAtDtLDLޅuUDADuH[A\A]A^A_]UHAWAVSPLcHLpDӉL=|HH5^Dp?C# CH[A^A_]UHAVSIA^ uAFu KJ9K<HlSrUHAWAVAUATSPIIIA> uAFuAL$J9AL$Av uu{J9K< ։4A AGAF& 1HLMH[A^A_]HLIwAVHLIwAVHIGIFIIOINIH[A^A_]HLLHLLH[A^A_]=DKR^eUHAWAVAUATSPMIAԉuHLAHLA? uAOu SJ9K uANu SJ9K u[A^]þH4SHDEtг脴HtHHaE~AHDD[A\A^A_]UHAVSIHH50#HHH HʪHu)IcH oH4HݧIcv(HHx S [A^]1H[A^]阮UHSPHH5葩HPHxuH[]þH1H航H5PH@H HH[]UHAVSIHH9tHH蔞HơH诟HL[A^]NUHHAE1DȸHDHGpOhOluADGd]UHHGp]UHGd]UHGh]UHHO(~%LGP1L9vAHAHx u+q$H؅߅t Bt1H+OPvHỉBt]UHAWAVATSIIFPHcNtH LuIGILhHIG1HE!HcCtHtYIOPHHHUHDL(MtH]ADك00G1E;T$LDHM;^H]AADك0  H]1/D9&1HuBH}1A?HcH]ȋ4D!փ"u9|1@H}HuH]ɉHMHuH}D|LUDHuDLD] 1ۅ~HuHuULg HEULED|H}HuD]u5DHMH]D9ÄDEEy3O1D9OHcIHHEȋ HL׃?H]#H IHHc HL1HE;EID$HMHcH1ۃ|]HMtHM1D9g$GHHMȋ?1ۃ"CHuHpH+=Hu1D9 HuL79D9ظEG1D9GHHMȋ?!ȃ"}9HM9DD_1D9z9DDG1HM99\HMA%1ۍD11ۅ8D0D9+1HMA@91HEA;D$XHIL$ HHp9H}D9t"HpH}H<1;H9|HMDk1AHEu5HuGHHMȋ?"weHpHsU=HuwJHEDD9~;t 1D9.9DND98D91 IcHMȋHx[A\A]A^A_]L6JJ6e}llYUHAWAVSPIHHHEHcHHkLt HHCHHHHHHCK 7HHCL7HHsHC8H)HHHsHFHCHH HH[A^A_]*UHSPH-xHKH HI HQ(1HtH H[]UHHVzu.H y u%H9w(tHF HG0HFH HI H+AH]UHtt u&1u%t1;OL| Ws19~]UHAVSHIFsIFHHH @C6uH5uH5LHCHI^[A^]UHAWAVSPAHLHHurDs HC HtVHCPHC(H0HsHHSHD:fCbfC`CeH; IGIHC HDI?HUHAWAVSHIIHEHHHHHHHPBu HLAHHHEHĨ[A^A_]UHAWAVATSAII^@EgDxIcVXHIcHLHbQLQIF@EfXIcHHIN8INH)HHINIHQH)HHHQH HuIN(IVP8HrH)HHHrH2H)HHH2HrH)HHHrH(H9vINH)HHIF[A\A^A_]UHAWAVATSAHALsP|(HcC\HHMcJH HLjP HPMcHCPD{\HK(L)HHHK(K HDHCH[A\A^A_]UHwX9}]{]sUHAWAVATSHHLspM{eHCHK(H{@II)LaI)hUu EHH+SPHỉUHS8H)H@HVHCHK(H@HACeHhHACeHC(HK@IL`IL{HĀ[A\A^A_]UHAWAVAUATSHHAIHA}u H{@HLIML+s@A|$tH HLHCL9vHHHHHH@L9wHCHK8H)HHnHCH{@HHCHC@N,0I $J 0AL$BL0HK@IUI)HC(Hs0Hpz t9HK8H+KH@H HC(H;CH8H(HC(3H}Lb HC8H+CAt$sHHH9 HHK@J)AD$rqLsLH)HNED$qA9~4)ALIVAx)HuHNt1LsDLMD}1LMLeAΉME)LEHC HHxH;HprHLmHD]HEEDu~LDmHEA)IcHAI)E1L{AHHuDKL'HC 'HIE9uH5HHL}LH*E@LsLmLeLMLELMED}tvHcHHLH)HIvAHsH2I6RAVADr?H)HIDHSHrHsHpH20rHD9|HtHCHHHKH8@M)HAHK@J)HPJL)HHK@HKHHDx Cdt1HHC(H@HHP AHsHHH)H'AMt HKAD$qHHDH9vHCIHC(H;CHt H(HC(HLhL0LsAT$sHLHPIL$HK0@$Dx HC @HH9rHSE1CdtHHK0E11HHC0DHH[A\A]A^A_]UHSPHs\!N}7H{\!N|H51HHC(H(HC(H[]þHUHAWAVSPHIAFdtaM~@LIF(HHH y u3AFdu*IF(H$QɉP$tLAFduL)I^@IV(HBIF(HrHJB IvHRIV0tOPHI;^s HqH;H9{yHHHu&~υ1HvHHHIvH[A^A_]UHAWAVSPAIHC`f=fC`ruH571Hf=sNHLDu HfK`HC HHxH;Hps H[A^A_]HH[A^A_]HUHAVSHC <tu HC(H;CPt H5fC`f=rH5HiAYfC`fCbHSHcHH)H5H3AEt!Ds HSHDHCHK(HADs fK`D[A^]UHAWAVSPIHHC(L8L{L@HLH IAGHCHK8H)HHHCHHCH[A^A_]UHSPH{ t/HC(C HHH y t6Ht1HC(H@HC#HHtH[]HHCHC(H+CPHiHH[]UHAVSAHfC`f;CbvH5G1HHCIcHH)HCC [A^]UHAWAVAUATSHIHfC`fELk(LcPCeEHHEL{AEtSM)L{@HLHDL;fEfC`HCPJ (HK(J (HKJD(HC0EψCeHHEHDH[A\A]A^A_]UHAVSHHcC\H=!N|^HK(LsPL)HiN?HH5 HLEHCPC\ NHK(L)HHHK(H4 HCH[A^]UHAVSH0HHuHUHEHEHKLH+K@H5*HUAHuHU1HAEDH0[A^]UHAWAVATSIII<$AIF HHxH;HprL= AHaHDEI4$IL$ IT$LIAwpIVxLIM|$ Apt1LID(HAGp9|IFL @IFIN8H)HLEIFHIF[A\A^A_]UHAWAVAUATSH8IIIHH]LuLeDELmL HLLA։EHU1LEH8[A\A]A^A_]UHAWAVAUATSH(IIIF@1H9t 1A|$HDLcAF`EAD$uI<$IL$HuԺAT$AD$ANdMԅuI<$IL$HuԺAT$AD$ANpMԅuI<$IL$HuԺAT$AD$ANqMԅuI<$IL$HuԺAT$AD$ANrMԅuI<$IL$HuԺAT$AD$ANsMԅuI<$IL$HuԺAT$AD$I~AvPLEnLDmAD$uI<$IL$HuAT$AD$EM~A Mԅu I<$IL$HuAT$AD$A t)u3ADEȅuPI<$IL$Hu2I|L-u(ALMDžuI<$IL$HuAT$AD$AD$HAUE~XD}ԅuI<$IL$HuԺAT$AD$E~1IF Iv@HINHuAVAFu;HHUI>INHHEA~uI>INHuAVAFH[A^]UHAWAVSPHAID}{u1H;HKHuSCuIcHH;HKLSCH[A^A_]UHAWAVATSIAID(Hc11M?HúLHC LsD{ H[A\A^A_]UHAWAVATSI׉I(Hc11>IƺLLJAF M~A^ tHcID HHuL[A\A^A_]UHAVSI11ҹ(>Hú LH HCHCC H[A^]UHAWAVSPILw HHHHHt"L9xruH AV !tRH J11ҹ(>@ AN H LxH HHIHHIHH HAIH[A^A_]UHHFH9FtHFHN HAHFHH (1]=UHAWAVSPIHHHtpL{ HFL9rcHHN AW !u3HNHVH~ HWHVHz HHV@F HNH HQHHuH[A^A_]UHAVSI11ҹx<Hú LH@ HC`HCXHCPHCHHC@HC8HC0HC(HC HCHCCpH[A^]UHAVSHIHsHcSPH1X<Hs HcSXH1LB<HsHcSLH1L,<Hs(HcSTH1L<Hs0HcS\H1L<Hs8HcSHH1L;x1LH[A^];UH~ F Ƀ(Hc1];UHDG\1E~4H0H 9W"9~tHD9|HGH]UHAWAVAUATSPAH}Lg I$HE1HE1IEAF tyurI~HtcG u]HEH@ H8uHt;IF Ml(AN IHID$PHuM6 HIL0Mt$PL3MuAF AF IHLbLH[A\A]A^A_]UHSPHHHC HxPuH[]UHAWAVAUATSPIM~ IGPHH9tH HIGPIHH HC $AO K H{HtqG ukI8sHtUEfeMopAFeIOxHIOpINHH@AIFHX@IvHF IF1LLEfeMopH[A\A]A^A_]UHAWAVATSIM~ AG CIw(H7A ~'E11I7HHLHAE;g |[A\A^A_]UHAWAVAUATSHIIIH Lo H}Eu AI{uHHH}C AuFHII;](uHIE(Cw8H HcHH}HG HHSH1E$AM K IIHu`gH}H9H}HnHS H(1H}H*8H}H}H}HH}H0I LH[A\A]A^A_]fSUHAWAVSPIMw Ak HHEIFxI+FpILwAN!tH)HtIH=w4IFx:IHH(\(HHIcHHIIFxIFpH[A^A_]UHAWAVAUATSHIMf 1AL$!HHHc HLI|$89LH[A\A]A^A_]I\$xIcD$$HAL$$I $H4HLXAD$$A;D$ |AD$!ID$xH)I$ ?It$0Ml$x(LID$0H8I^ KC 9sA|L]HShHAIIIGHHsXLL5I|$PNLRI$HedHI$dqM$I$L9tUHAVSHLs AF!<w/AF$IF(IF0IFHIF@IF8AF!<tHA~!uHAHuA~!uIHH(\(HHIcHIFp[A^]UHAVSII^ HCHHC@HC8HF tH~H|HvxF tH\IF |HF tH:HC![A^]UHH !u H]F $O N ]UHAWAVSPHIL=C $C Kw^Ic LHs HC tF tLH[C u-IF8HC0IF8HCIF8HIF8HChI^8H[A^A_]HCx|H0F t LQHCHKH9ùK ǚrUHHG f HH@HN0Hp@]UHHG HH(HHp(@ $F V]UHHO HA(HHq(F u1y!u F HFx|HB t]$I N ]UHAVSII4HtF tLyHH%u[A^]UHAWAVAUATSHIM|$8AO AG AW1H5*HcHIG0ID$8IGH@ tLHIGH@ I$@HHxML IkLhHHE̾vLMLHH t1HHAw @@AO IL$HIO0M|$HH6H-IO IGID$8IwF tLA MAO E1ɸI_0ȃ;|HsF t LAG HAA9|IID$8ID$@IM|$@AO A|IwxF tLMIGIO(IWPH9IwIHrI9LBH(H9vI_@IGhID$8MIG@Ht` AGL~5E1IO<|HtF t LAGLHAA9|AGH~IO8HHtb HuAGX~(1IO H4HtF t LAGXH9|IcO\H~IW0H:Htg HuIcWPHIcwLIcTIc_HHHHHHHDx6HH9s({|H3F tL7IGCHL9vAG\=!NI_XsEMcw8Mt1LHHIG<|HtF tLHAu1LeIG HEAO AAIcHL,EMw C|.uC<.|ZC. Pu"C<.|Kt.F tH}Љ]ڋĒu&C|.|Kt.F tH}AƉ3DIAu<HMuAg IcG8H HcH HD@M+g@IO(I+OPHi9}|LIAI_XAGXA9}[|LHcHIcO\H Hȸ\Iw F tLkAG t(M1It(F t LKAG H9|1A Ƀ(HH[A\A]A^A_]òHA>UHW1|-H?O uO u1u u]UHAVSIHz3H51LlH3L]k1L9rHsHHu[A^]UHSPHH5.{HeHwHoH`41H~H5%HHdH5)H\3H~H56HH)H0H H>H)H0H H H)H0H 1HHbHHlH5PH&HvpHobH[]UHAVSIH1 m1HLkH6H[A^]BnUHAVSIH1$zHH;<H1L[A^]UHSPHhH5H iH[]UHAWAVATSIAIH+EL ~HcHDdnHcHSoHL[A\A^A_]^mUHAVSIHM@yHH;<H1L[A^]UHAWAVATSI׉ItLIjULc0LgDeHMtH51LLhH51LHhLLg[A\A^A_]UHAVSHrIIHeHEjHmL[A^]UHSPHbuHjHHH[]> UHSPH H1HH[]UHH]UHAWAVSPHb~X1HvIHIH5vLHIu HLH#_H߉a)HiHHqa1HmhH5HgH[A^A_]UHAWAVATSH1vIH1HuIH$ILLHI$t[A\A^A_]1HL[A\A^A_]ZUHH?]UHAWAVATSH1uIH51HuIHI1BLLHI$t[A\A^A_]1HL[A\A^A_]UHSPHHHH[],UHAVSIH{HHt [A^]11L[A^]]UHAVSH`vHocIHLH,gMt;H=ht*Hp`tI>tH5HcH5d Hd[A^]UHSPHHHH[]UHAWAVAUATSPIId\AAAA)L^u'Et5L`LH52LHUysEu1HUоHLH;EDAu1LDH[A\A]A^A_]UHAWAVSPAIDKfLaHHu"AIcH ,HH51LspHH[A^A_]UHAWAVAUATSHAII6[LEuLLLHMAōYHsHLsAA)DLmL]uAL_HuzLADL11LbAD1L_IMtA}*tLH:nAEat%lu:LLLLHALHLLA2nuB1LH5HUu=ELaAEt(AEHLnAE1Lt11L EuLYL`HE)ÉH[A\A]A^A_]UHAWAVATSH IIHHtxH%yHþHLHtBLHHt| tKHLxHþHLXHuHxL|^HH@HHhxH [A\A^A_]UHAWAVAUATSHIIILLwLBxL9IGݾHHLHI9t)I)H9tHwL]HHwH[A\A]A^A_]UHAWAVAUATSPIAHZ~e1H\IHMt)RILLHIEuHLBHYHDjdHDH[A\A]A^A_]aUHAVSIH8HH5[1HLT_1H5\HH[A^]=kUHAVSIHoHHHuH51LkH[A^]UHSPH1H H[]UHAVSAHYHD_H5H[A^]C_UHAWAVATSI\HHuH5-1L8kLHAHmt+8HH531LH[A\A^A_]jAEu6LZE1t"E11LUL0XL D[A\A^A_]UHSPHaHH_H[HH[]UHSPHSH1HH[]>UHSPH%HHH[]UHAWAVSPHIHAH &HSkAǾ1HoIcHLHZt11HH[A^A_]L>HH[H[A^A_]UHAWAVSPHfIH &1HjAǾHnIcH߯1LH1HH[A^A_] UHSPHHHH[]UUHSPHHkH8tH1H[]UHSPHHkHHtH51H[H5 HZH[]ÐUHAWAVAUATSPI1AL-'%N<+LLLHcH D` HAHuH[A\A]A^A_]UHAVSIw.HcH#D<%HcH $H[A^]þgI~8t H5jH5j1[A^],UHAWAVATSHPAIHHsPHLePL-H{8KH5@1LMi,IEtELc8Aw1H HCHHHDHH51LL,H{8HP[A\A^A_]UHW]?UHAWAVSPHL{8L>bIHC0HpLLxu @LH[A^A_]UHSPHCX.H{8C HS@HC0CCHKPHCHH0HP HKHHHA H{@HHH@HtHGHHHO H[]UHSPHCC{ uHsH&CHC HH@HCHKC H[]UHAWAVAUATSHHuIIGHH@L-LA@LAA}Z yAu ~u'[w HcADre&"_1'(-t.CI@HHH@HuhHGHHHOA-A-I@HHH@Hu-HGHHHOHA[u=LIOHHAx1LDIGHH@^AAv+I@HHH@Hu賽HGHHHOsIc?GЃ *wrA#DI@HHH@HtBHGHHHO6.L0I@HHH@Ht!HGHHHO起AA_襷AH5Lvt!H5uLcDA#AЃ A.wLHuADH[A\A]A^A_]ÐDKRUHSPHHs(KC H[]UHAVSHD3H{@HHH@HtHGHHHO¶ t u0D9t+H{@HHH@HtHGHHHO舶CH=K|SH5H[A^][A^]UHAWAVATSIE4$DI|$@HHH@HtHGHHHOA$E1=uD1۾=LII|$@HHH@Hu޵HGHHHOA$Ã=tD9DEA1D[A\A^A_]UHAWAVSPAIH3H{@HHH@HtHGHHHOd t uHXZD  Mt H߉mH{@HHH@Hu\뵃[udHD9u3H7H{@HHH@HuʹHGHHHOEgHGHHHOL]eH,D9.3HH{@HHH@HtuHGHHHOi HHCMHCHH@MHbH5rHEHaH5m[Mt'HCHAOHcH0HPCD?HH)HIH[A^A_]UHAWAVATSAII\$HHKHSHAH9v:HH9rH5w1LHSL<II|$8u HH3L HL{HKHQHSD4[A\A^A_]UHAVSIAH~H1Ht;LDI~@HHH@HtHGHHHOɲA[A^]UHAWAVATSIH3HH{@HHH@Hu 色HGHHHO03FЃ rÃ.tH5OH;tH5?H(;L= A;w HcADVEH,V(EHCH[]UHSPHUYyHCH[]UHAWAVATSHI貮HHi@HH?H=i)*^,EL0<tRLVIEH{L@PA*EYSX՗LvLUIƾLUIE9}HLOD)D*EYWA*XL( uLE~BH[A\A^A_]H51LH[A\A^A_]?PUH"U觭1]UHSPHaTHBH[]UHSPH5TMHAH[]UHSPH TQHAH[]UHSPHS耭HAH[]UHSPHSNHgAH[]UHAWAVAUATSPDIIIIA9}M9| 1LL CHcH1IH9vH5qE11LީIcIHcILLIALH[A\A]A^A_]UHAWAVAUATSPHIIMo I}AUIMuHt LL)I]xLH[A\A]A^A_]UHH51C1]UHAWAVATSIH5PH5E11LAHLEH5ڽH LETLE;Ly:1LCL% K4'1LsAL}EII uH8LDH5H%H 'LH5HH LH5 Lk?HL'DHLTHLC11LBHLCL$:H 1LSL7[A\A^A_]UHSPH-OHH;Ht H1H[]UHAWAVSPIIHHHt=HH HHTHHHLTHW7 HL>HLH[A^A_]BUHAWAVAUATSHxI1 NIL6AEfHzL@LDL|@L9t^LS6LLSHtH5'1LL#KAL8LDLBH?L?L8þL5uzL58H,LALLF=H߿LA.LPHHPIDL)LLHL8>H9t6HF:H H9H5׽1HLHHH=Hd6tH5ý1HHH51H:AL%AǾHD>H6u"1Hv8H1HLLHHHL:HAH5t5H>6uH2hHDVL=HLq<HL>HL]:H6AH85tHL>HL[A\A^A_]UHAVSH1{IIHӻH AH (HcHHE@@@=HE@@@AG@=Mw0IHruH5LIHrHr%1ҹE1LCHMAAAF=uXIwI0@EHMAAA=u$HE@@@LHufAW=]W;ۃ VE1H HcHA+$A ^A H tHcHAa<uA O>A >A6A.A &A AAAAL5cLmDA^;EvbL%I0DDeLeLPAT^LLHzAI0uLHIQAEL5ucuDIO8fI`H8[A\A]A^A_]L詴AO1LHuDHE@@@Lk O{{{{{{{GGGGGGUHAWAVAUATSH8IHL{0Dc 11E1L?AEEELmAEAEAE EuEEEEH{0LD{H{}Lm8HEpU̹2L}SELLDE}2tȋC[t=uHѻ{ =u HL HLSC;t,uH豲{}t}u먾}{HDMЅtYEt@Huw)LOBHEpU̹LRMLCMHEpULRMcIH@AF#$}D IH@B?}% IHIBH8[A\A]A^A_]UHAWAVAUATSHhˉ|AHpIHXHX`(LEt.H5L茰1LHULcMl$0MuAFrAD$1ۃ)uL'AD$L=t?=ueD{LHƉD H56A~ruAOXHcA9^D}Mo N D!HHcHHH4HuIA9|I4$H1LEt$ I$[A\A^A_]UHAWAVAUATSPIILHHL9vD$LDAT1H)H9sH}Lw AF !HIL,MmMt;M9euIuLL`uAE AN !4AE ID$HLurLcIL$11LIMeA] IF @ $AE AEAE I}LLd`CD,IF p N!HHa?sIĄM{LHuL4HM`OAGfuuMgA[tI~1H56ieLLMI1I;t{MgLL;LLbȍAЃ xA;N}HcHMd(Iu I~1H5nhHcHMd(IFH)L9fHcHID HHL|I?L1IM&*+-H]иAOtAuI~1H5GhAO8 IVH9UиA_HEЊ8u u8HEHHEH9иrrLH 1tdLHuLLH[A\A]A^A_])Ml$HLHLHu'I;^s;LLuHH[A\A]A^A_]1I;^HDA)u0I-IIcFHHJL1~2H9HIu6IǹLHLH[A\A]A^A_]I~H5g1LcIHK+D& KD&(LHL*HMKD&(H1:fnyySeUHAWAVAUATSPIIIAD$M„ADDI|$HeDE~1LLLA9uDH[A\A]A^A_]UHAWAVSPH9s~6LcINt;(ItDIH{Jt; uPHH+3H[A^A_]H{t8H52e1H[A^A_]~H{H5,e1lH{Jt; L H)HHH[A^A_]UHAWAVAUATSPAIIHLckI |H{H5d1LHL| IcHL(AECHLL~HuKH[A\A]A^A_]UHAWAVSPIII_A[uNA^IGHD؊L=duI~1LHK<%u{H[HDHˊ<]uH#%u;uI~H5?d1IILHH[A^A_]UHAWAVAUATSPIAH^~^HEDHCL9s_EA%suDu=HH&@-uHL9sD9D9H|D9tHHCL9rEDH[A\A]A^A_]UH[t.t#%uv]H]19]UHAWAVAUATSPIIII1M9ov*A|LLtHIDI;Gr1Hx&IItLLHuHH[H[A\A]A^A_]UHAWAVSPAADBk,at^cutAIcHs#D<w^H HcHA\IcH9#DE  @g:\~UHAWAVAUATSH8IHIǾ1LILLLK7HLHL9=LLLDžLHLIMuHH;v1=LH+L9HLLzHHLTH8[A\A]A^A_]UHH1]ÐUHAWAVAUATSPIIIAFu$A,*f.uz~ A;\$8LL\HLkLL輣u4{ uA~| IEI;tH[ HuH5`11L=I+\$ HiA\$8AL$8HcH)}1IT$Ã|H@t*AAFH INDVAL$ 19}MI|$ HcHH |u H(9|*HDIDAFID$ HIVDAFH[A\A]A^A_]FUHH *1H9N t N ]UHAWAVAUATSH(ẢIIMco8A9AG EIG HE} LLLLuLD A9A_8HcHHE]LpAI_AB<3tH}LDnJL3HB 3HIE9|˃}|I_IwIH}LHM臒 H}ҒI_HAMALmt@IcHHMH\E{tHSLLH HKHHAEH)HuH9t#IcHH1LH([A\A]A^A_]H([A\A]A^A_]UHAWAVATSAAI11ҹ@輑HúLH aHCC HCC8C H)HC LHDLHDH[A\A^A_]UHAWAVSPI|"M~IvIcV8I8HHcH# rM~I8IA9}HcHHDH9|AH[A^A_]UHAWAVATSIItKʉǟDp|H5]1LS:D|,HcHH 11L肐H'ID$ E11;L軐ID$ At%HH 1HAAH(9|HcEt$ H HID$([A\A^A_]UHAVSHIHs H~'H9tK HHH1L܏HsHcS8H1LƏ@1LH[A^]鰏UHHF;G8s HHHG<*E4HHS%yuAf.Euz HI HuHH]UHWf.uzHG /EfH~EEO ΃1HHHG ]UHO #F HH HHO H$yuH9qt HI HuH]UHAWAVSPIAGL5$tiu$A,*f.u(z&H[A^A_]uI7H[A^A_]`L/HH{L蒝u H[ HuILH[A^A_]UHFȃw"H cHcHO #H:O ΃1H#]HO #P HcHHHG ]æUHAWAVSPIHIHLH;/C t H[A^A_]AFuAf.{H5Y uH5yY1L6LHLH[A^A_]UHAWAVAUATSHHIILHIA~uHs$I9THXID$ IL$(HH9vsHK؃{uHI\$(IvL~L9HHA L9uHY IF HC IFHCIFHCIINHKHIF AFLHHI\$(W)E)E)E)E)p)`EHEED$81ɺAξD9Ɖ~D9DC19)ID$HcHH\1;H9|lj`AH|AL$ AA1L`HP HLHPHPAIcAHHAAtI|$ |H@tDHXLz1Ʌ~:1E11LHA]~ 9DOO9tI9| E11LHHPALD)LL|LLHXHĘ[A\A]A^A_]IF HC I^ IHXHIFCAF|H@ tAD$ t LLYLHĘ[A\A]A^A_]UHAWAVSHIILH;Ԋu*EEHULLH[A^A_]UHAWAVSHHIILHH;uH]EHULLH[A^A_]UHAWAVATSIEf8EtAL$IFH|H I9F twAD$ALDxt(C?=Er޻sLÃxulDD)v+C'LjxDDADD)؃Aw6D11Ar'B!SH|DDDD)كwˉ[A\A^A_]UHSPH1u/,*f.uzρw菗HH[]UHH5GHi]UHAWAVAUATSH(IHN:HIƾLLHþL3~Ls L IHLwD9}/LLL\ HLLdA9uuHLD- HH([A\A]A^A_]UHAVSHHHHfE1HHGtPHHHHHtAD[A^]UHAWAVATSILIƾLE~hALULHLfLDLFuL藿HÍCD9|E1D[A\A^A_]UHSPH4HHcHxH[]UHSHHHHWEtoHHuHgf.EwHsu"HE[EEu EWHH[]UHAWAVATSI1LIAL5tPufLIE9EME9~,A\$LLDD9AELD1[A\A^A_]H5 Q1L[A\A^A_]UHAWAVAUATSPImL(IIc־LIE1E~cE9^ALDE9}+A]LLD!A9AuLLDDH[A\A]A^A_]UHSPHH5P1HH<H[]UHAVSHrH-IH4(HH~H+HOHD1[A^]UHAWAVAUATSH(AAIE9xLeLDLDLQuLλ LDLDDD)CG`f=fG`r)IVH5IH I1螏I>)I>>IIH@L8@ I>HGHO8H)H\+I>HGHHGLcHHEI_@LAG`LAGdHuʺLEAGpHu˺LEAGqHu̺LEAGrHuͺLEAGsL8AAI>|IcH11Hz {IcHIGEgPLHHFLÃI>HcH11~zIąMgA_LID$HuAIMgLHuE΃wH HcHC,)I>IV1H5HH G輍I>#'uuLHul}CD,C,кLHuBECD,C,LsKD,C,yIGA_LLÃI>~]HcH11DyIG A_X~NK1HIG H9u~0A1Iw@LIO HHA9u HyIG A_XL3AAI>|IcH11Hx yIcHIG(EgTLHHALAAI>~lIcH11{xEIG0Eg\~\1DHHuLCIO0HLIO0DLIO0D HAu pxIG0Eg\L[ÃI>~aHcH11wIG8A_H~RHtعIW8HH9uA1LIO8HHA9u wIG8A_HL7u)I>IVH5EH NE18I>$IH@fH`LH[A\A]A^A_]f)b3UHLuaHQHG]UHAVSHHHuHU1Ht0H;Hs IHUHLlH;HUHLH[A^]UHSPHHu:Ey,H;HSH5DH ~D1CH;#EH[]UHSPHH{Ht/H;HSH5GDH D1H;H[]Z#H[]UHSPHGuH-u&H?HHu腅tEC1HH[]UHAWAVSH(HI1{u>H54L}L!L!LLH諿HCH([A^A_]UHAWAVAUATSHHMHUIHAGE1uSIIHHu[HEȃxH{HG IF H(1tIMu3l1HLIA}uHILHBIAEtUAAcML[H5B1HH[A\A]A^A_]!HUHHMHBAH[A\A]A^A_]LHuLLLEH[A\A]A^A_]UHAVSIHL+s@HCH2H0RPHCHHPIHHCIHH AHH(HsHC8H)H0H#HsHF0HCHg*HCHK@HPHSHPJ1@BD1[A^]UHAWAVAUATSHHMHUIHAEE1u\IuHuHHUIAHEHxHG HC H0IMu.hHLIA~uHLHA AFAAcMVH5A1HH[A\A]A^A_]KHMHIAAGy|-H@ t$HE@ tHHuH[A\A]A^A_]AH[A\A]A^A_]IIGIHANHIGIMHHAMHIGHUH HH JH(IGHUH HH0JH8IwIG8H)H@L!IwHF@IG1LH[A\A]A^A_]m(UHAWAVSPIHICA;FuNuH;I6V.uAf. LHLt H[A^A_]LHLH[A^A_]_UHAWAVAUATSPIIMoMt$LLKuQI\$MLTHH9t/L9t.HAMl I)MtH)LLt L9H[A\A]A^A_]UHAWAVAUATSPAHUIHDFIA|$AtTHHuD&LHt6HsHLLLEHKQtu 91DDH[A\A]A^A_]UHAWAVSPIHIKHwHHc HHI;H[A^A_]H IH9tHqHRLzH1HtIwLHHMaIOQt)u$9A;Af~1뀀tttUHAWAVATSIHI1Ht}1C uuID$ HHHI1MtRL9tJ1MtF1AG u=ID$ HHLIH1HtLH}1IEL[A\A^A_]UHAWAVAUATSH8AILuINLcLuIN|1BD1N$1w B|1tSH}LHMvHMu;ALuLLLLgLLLOI$L`MuJD18 Lu+HM]AA|TAAtH}Lt7IHXHL)H9r1H}H5;!IAIE9|DuDmH}Hw HXLIEIcHE~BHEH+EHHMLlDu1IuL~I<HLLIAEL}IL+}LuLLH IHMJ9BD9]DmELuLLA))AH8[A\A]A^A_]UHAWAVAUATSPEIIIHDxuHLD1ɃxtHLHLMH[A\A]A^A_]UHAWAVAUATSHhuIID$(H@ID$ID$(MT$0+HIMt$MwMT$0MWAGID$(HID$(H@HHEMD$H@ H@HEMD$MMWAA\$d AD$lAD$luMt$0MT$0t.u*AD$hAD$lHUMLHUMIttID$(H@HH@ HHH@(LH)H1HtHc֋t,M9s'1HtI)IHII B49tLLIA|$ L`MD$DMIO 0Ѓ?%H ZHcHHIIADCD0HHMHIDCD0ACD0IMEfHLBHBL9HsDHEHD(H@HI @CD0!HHUHEH@HEEMT$0HuLLL# MT$0HL%HEH@HEEMT$0HHUHuLLL HEHt(HFI HCL0HC|0mIB `F VMLL#7MT$0HHLLULEILwADwwLDLUHHEBD0VHI4I KLADCDMT$0LӁHIHpHLoHHLHHLHHLHHLHHLHHIA|fW! HALɰ  A< HM,ADIE~@fbf\f|fACD0IMT$0M׾)L%ID$ HHxH;HprL.MD$HIK0ADCD0MHLMT$0HLMT$0'HL&CL0ɰ  A9 HI ADHֲ  9 HэQI΅tIIMMD$MT$0LLL]I EVID$(H@ID$CtIIMMD$MT$0LӺLL  CLCD Wf.AX4f.s/HUI]HIHEMT$0KD0HxC|0LLLEMMLEHsH5-31LLMFLIHUHE I]HI4IIK(KD0PCD(CD0XKD0KD0@CD0CD0HIICD0ADKD0`ID$MT$0MLMMD$ID$(H@ID$AD I K (CD(AAEuMl$ID$(M)IAH@ID$u AWIMC|0M1Dk2CT=A;V8~LULLLELELUELUIcHHI\LEAC/LLHKH H;|HC@ tAF t LLN2HAELULEWMLLL<%IM;LMLEHEHHPH@ H@ L,A]pLUL{#LUHELh tcCHEE1Ct?u HEHD(HHuL#HMJD(IA9|HEHHHGMHEHMHHEBD0MT$0ID$ HHxH;Hp^LL**M|$(II+_HHEH@ @q)΅EMT$0ID$8I+D$HcH9LULubuLUMD$MHcLHLID$MELDILELLLLMIIC|(tAMLLM MHu(H5/1LL IHUHMHEkA|HE9HUHMNHHUoL%HIjHHULk%HLeHHU%HLHHU%HLHHU%HLHHU%HLHLHHU%HLHLMT$0A LLLH#LÃMI}MM*HHEHIHHELӁHIHHMLӁHIf.?HcMACD0CD00CD08 ʅ)HcHH)I1H9}IH|IyAAHHI9uLDILELLLMD$IHHEHzu yuXCD0SMT$0ALLoHHEHzuyu \fMT$0A2HHEHzuyu Y2MT$0AHHEHzu!yu^ACD0MT$0ALHHEHzu@yu:E M^MMMYEM\AMFMT$0A ULHHEHzu3yu- MMbMAEICD0MT$0A LLLIDILEMT$0HA;HuvLLHLIڅ]LDILELHLLLDILEAA;@u46H9I01D9{LHL`HHLIHHUHM_\HxHcM1ACD019!19H I CD0AGHMMT$0LHA LLLFH.)LLHʃuAf.OLILLLEu0 LHuLuLLHUD9IuAGHMMD$IM|$(MwI_I$LtIwLJIGIH)HHIOIL$1I;\$IN1HHQSHHHI;\$rtLHJDID$I$tMLLLIMMT$0LLMtUBu EDM|$0Hh[A\A]A^A_]H '1LH2U3S!HuL#Ht-AAAHJc HX|LHLHMEjurLHLb\MYG^AE^MYEM\HE@_fW]HE@H8[A\A]A^A_]]UHSPHHsH{ HUSHtHUHtHHHHHKH[]UHSPHH;tHC HtHHCHHCH[]UHH~ HVHNHFH]UHAWAVAUATSPIIIE1MtAE1Lvt.I$It$I9IFLHI)$I\$II)uMLH[A\A]A^A_]UHAVSHHHSH9s%H A LCIFHwH3LU H CVHLs[A^]%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%V%W%W%W%W%W% W% W%W%W%W%W%W%W%W%W%W% W%"W%$W%&W%(W%*W%,W%.W%0W%2W%4W%6W%8W%:W%W%@W%BW%DW%FW%HW%JW%LW%NW%PW%RW%TW%VW%XW%ZW%\W%^W%`W%bW%dW%fW%hW%jW%lW%nW%pW%rW%tW%vW%xW%zWLS8{LS,{LS {LS{LS{LSzLSzLSzLSzLSzLSzLSzLSzLSzLSzLSzLSxzLSlzLS`zLSTzLSHzLSlevel out of rangecallreturnlinetail returnflnSu>%sfunction or level expectedinvalid optionsourceshort_srclinedefinedlastlinedefinedwhatcurrentlinenupsnamenamewhatactivelinesfuncexternal hooklua_debug> cont =(debug command)attempt to %s %s '%s' (a %s value)attempt to %s a %s valueconcatenateperform arithmetic onattempt to compare two %s valuesattempt to compare %s with %s%s:%d: %slocalglobalfieldupvalue=[C]CmainLuatail=(tail call)(*temporary)not enough memoryerror in error handlingC stack overflowcannot resume non-suspended coroutineattempt to yield across metamethod/C-call boundarystack overflowpackagetableiomathstdinstdoutstderrpopenFILE*%s: %scannot close standard filecloseflushinputlinesoutputtmpfilewritestandard %s file is closed%.14gclosed filefiletoo many argumentsinvalid format%lfwattempt to use a closed filefile is already closed__close__indexseeksetvbuf__gcfile (closed)file (%p)nofullsetcurendandbreakdoelseelseifforfunctionifinnotorrepeatthenuntilwhile.....==>=<=~=char(%d)%c%s near '%s'invalid long string delimiter.Ee+-malformed numberlexical element too longunfinished stringescape sequence too largeunfinished long stringunfinished long commentnesting of [[...]] is deprecatedchunk has too many linespihugefmodmodabsacosasinatan2atanceilcoshcosdegexpfloorfrexpldexplog10logmaxminmodfpowradrandomrandomseedsinhsinsqrttanhtaninterval is emptywrong number of argumentsmemory allocation error: block too big_LOADLIBloadersLUA_PATH./?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/lib/lua/5.1/?.lua;/usr/local/lib/lua/5.1/?/init.luacpathLUA_CPATH./?.so;/usr/local/lib/lua/5.1/?.so;/usr/local/lib/lua/5.1/loadall.so/ ; ? ! -configloadedpreloadmodulerequireloop or previous error loading module '%s''package.loaders' must be a tablemodule '%s' not found:%s_NAME'module' not called from a Lua function_M_PACKAGE;;;; no module '%s' in file '%s'error loading module '%s' from file '%s': %ssymbol '%s' not founddyld not presentfile is not a bundlelibrary is for wrong CPU typebad formatcannot access fileunable to load library%s%sLOADLIB: __luaopen_%s'package.%s' must be a string no file '%s''package.preload' must be a table no field package.preload['%s']loadlibseeallinit(null)%p% [string ""]MOVELOADKLOADBOOLLOADNILGETUPVALGETGLOBALGETTABLESETGLOBALSETUPVALSETTABLENEWTABLESELFADDSUBMULDIVMODPOWUNMNOTLENCONCATJMPEQLTLETESTTESTSETCALLTAILCALLRETURNFORLOOPFORPREPTFORLOOPSETLISTCLOSECLOSUREVARARGclockdatedifftimeexecuteexitgetenvremoverenamesetlocaletimetmpname/tmp/lua_XXXXXXunable to generate a unique filenamesechourdaymonthyearisdstfield '%s' missing in date tableallcollatectypemonetarynumeric*twdayydaysyntax errorvariables in assignmentcannot use '...' outside a vararg functionselfarg or '...' expectedlocal variablestoo many local variablesitems in a constructormain function has more than %d %sfunction at line %d has more than %d %sambiguous syntax (function call x new statement)function arguments expectedunexpected symbolupvaluesno loop to break'=' or 'in' expected(for generator)(for state)(for control)(for index)(for limit)(for step)'%s' expected (to close '%s' at line %d)'%s' expectedchunk has too many syntax levelsgmatchgfindbytechardumpfindformatgsublenlowermatchrepreversesubupper^$*+?.([%-too many capturesinvalid capture indexunfinished capturemissing '[' after '%%f' in patternmalformed pattern (ends with '%%')malformed pattern (missing ']')unbalanced patterninvalid pattern capturestring/function/table expectedinvalid replacement value (a %s)'string.gfind' was renamed to 'string.gmatch'invalid option '%%%c' to 'format'\r\000-+ #0invalid format (repeated flags)invalid format (width or precision too long)unable to dump given functioninvalid valuestring slice too longtable index is niltable index is NaNtable overflowinvalid key to 'next'concatforeachforeachigetnmaxninsertsetnsortinvalid order function for sorting'setn' is obsoletewrong number of arguments to 'insert'invalid value (%s) at index %d in table for 'concat'booleanuserdatanumberthreadprotoupval__newindex__eq__add__sub__mul__div__mod__pow__unm__len__lt__le__concat__callbinary string=?code too deepbad codeunexpected endbad constantbad integer%s: %s in precompiled chunkbad headerindexloop in gettableloop in settablestring length overflowget length of'for' initial value must be a number'for' limit must be a number'for' step must be a numberfunction os.executef(cmd, ...) cmd = string.format(cmd, unpack(arg)) return os.execute(cmd) end function os.findlib(libname) local path, formats if os.is("windows") then formats = { "%s.dll", "%s" } path = os.getenv("PATH") elseif os.is("haiku") then formats = { "lib%s.so", "%s.so" } path = os.getenv("LIBRARY_PATH") else if os.is("macosx") then formats = { "lib%s.dylib", "%s.dylib" } path = os.getenv("DYLD_LIBRARY_PATH") else formats = { "lib%s.so", "%s.so" } path = os.getenv("LD_LIBRARY_PATH") or "" io.input("/etc/ld.so.conf") if io.input() then for line in io.lines() do path = path .. ":" .. line end io.input():close() end end table.insert(formats, "%s") path = path or "" if os.is64bit() then path = path .. ":/lib64:/usr/lib64/:usr/local/lib64" end path = path .. ":/lib:/usr/lib:/usr/local/lib" end for _, fmt in ipairs(formats) do local name = string.format(fmt, libname) local result = os.pathsearch(name, path) if result then return result end end end function os.get() return _OPTIONS.os or _OS end function os.is(id) return (os.get():lower() == id:lower()) end local _64BitHostTypes = { "x86_64", "ia64", "amd64", "ppc64", "powerpc64", "sparc64" } function os.is64bit() if (os._is64bit()) then return true end local arch if _OS == "windows" then arch = os.getenv("PROCESSOR_ARCHITECTURE") elseif _OS == "macosx" then arch = os.outputof("echo $HOSTTYPE") else arch = os.outputof("uname -m") end arch = arch:lower() for _, hosttype in ipairs(_64BitHostTypes) do if arch:find(hosttype) then return true end end return false end local function domatch(result, mask, wantfiles) if mask:startswith("./") then mask = mask:sub(3) end local basedir = mask local starpos = mask:find("%*") if starpos then basedir = basedir:sub(1, starpos - 1) end basedir = path.getdirectory(basedir) if (basedir == ".") then basedir = "" end local recurse = mask:find("**", nil, true) mask = path.wildcards(mask) local function matchwalker(basedir) local wildcard = path.join(basedir, "*") local m = os.matchstart(wildcard) while (os.matchnext(m)) do local isfile = os.matchisfile(m) if ((wantfiles and isfile) or (not wantfiles and not isfile)) then local fname = path.join(basedir, os.matchname(m)) if fname:match(mask) == fname then table.insert(result, fname) end end end os.matchdone(m) if recurse then m = os.matchstart(wildcard) while (os.matchnext(m)) do if not os.matchisfile(m) then local dirname = os.matchname(m) matchwalker(path.join(basedir, dirname)) end end os.matchdone(m) end end matchwalker(basedir) end function os.matchdirs(...) local result = { } for _, mask in ipairs(arg) do domatch(result, mask, false) end return result end function os.matchfiles(...) local result = { } for _, mask in ipairs(arg) do domatch(result, mask, true) end return result end local builtin_mkdir = os.mkdir function os.mkdir(p) local dir = iif(p:startswith("/"), "/", "") for part in p:gmatch("[^/]+") do dir = dir .. part if (part ~= "" and not path.isabsolute(part) and not os.isdir(dir)) then local ok, err = builtin_mkdir(dir) if (not ok) then return nil, err end end dir = dir .. "/" end return true end function os.outputof(cmd) local pipe = io.popen(cmd) local result = pipe:read('*a') pipe:close() return result end local builtin_rmdir = os.rmdir function os.rmdir(p) local dirs = os.matchdirs(p .. "/*") for _, dname in ipairs(dirs) do os.rmdir(dname) end local files = os.matchfiles(p .. "/*") for _, fname in ipairs(files) do os.remove(fname) end builtin_rmdir(p) end function path.appendextension(p, ext) local endquote if p:endswith('"') then p = p:sub(1, -2) endquote = '"' end if not p:endswith(ext) then p = p .. ext end if endquote then p = p .. endquote end return p end function path.getabsolute(p) if type(p) == "table" then local result = {} for _, value in ipairs(p) do table.insert(result, path.getabsolute(value)) end return result end p = path.translate(p, "/") if (p == "") then p = "." end local result = iif (path.isabsolute(p), nil, os.getcwd()) for n, part in ipairs(p:explode("/", true)) do if (part == "" and n == 1) then result = "/" elseif (part == "..") then result = path.getdirectory(result) elseif (part ~= ".") then if (part:startswith("$") and n > 1) then result = result .. "/" .. part else result = path.join(result, part) end end end result = iif(result:endswith("/"), result:sub(1, -2), result) return result end function path.getbasename(p) local name = path.getname(p) local i = name:findlast(".", true) if (i) then return name:sub(1, i - 1) else return name end end function path.getdirectory(p) local i = p:findlast("/", true) if (i) then if i > 1 then i = i - 1 end return p:sub(1, i) else return "." end end function path.getdrive(p) local ch1 = p:sub(1,1) local ch2 = p:sub(2,2) if ch2 == ":" then return ch1 end end function path.getextension(p) local i = p:findlast(".", true) if (i) then return p:sub(i) else return "" end end function path.getname(p) local i = p:findlast("[/\\]") if (i) then return p:sub(i + 1) else return p end end function path.getrelative(src, dst) src = path.getabsolute(src) dst = path.getabsolute(dst) if (src == dst) then return "." end if dst:startswith("$") then return dst end src = src .. "/" dst = dst .. "/" local idx = 0 while (true) do local tst = src:find("/", idx + 1, true) if tst then if src:sub(1,tst) == dst:sub(1,tst) then idx = tst else break end else break end end local first = src:find("/", 0, true) if idx <= first then return dst:sub(1, -2) end src = src:sub(idx + 1) dst = dst:sub(idx + 1) local result = "" idx = src:find("/") while (idx) do result = result .. "../" idx = src:find("/", idx + 1) end result = result .. dst return result:sub(1, -2) end function path.hasextension(fname, extensions) local fext = path.getextension(fname):lower() if type(extensions) == "table" then for _, extension in pairs(extensions) do if fext == extension then return true end end return false else return (fext == extensions) end end function path.iscfile(fname) return path.hasextension(fname, { ".c", ".s", ".m" }) end function path.iscppfile(fname) return path.hasextension(fname, { ".cc", ".cpp", ".cxx", ".c", ".s", ".m", ".mm" }) end function path.iscppheader(fname) return path.hasextension(fname, { ".h", ".hh", ".hpp", ".hxx" }) end function path.isframework(fname) return path.hasextension(fname, ".framework") end function path.isobjectfile(fname) return path.hasextension(fname, { ".o", ".obj" }) end function path.isresourcefile(fname) return path.hasextension(fname, ".rc") end function path.join(...) local numargs = select("#", ...) if numargs == 0 then return ""; end local allparts = {} for i = numargs, 1, -1 do local part = select(i, ...) if part and #part > 0 and part ~= "." then while part:endswith("/") do part = part:sub(1, -2) end table.insert(allparts, 1, part) if path.isabsolute(part) then break end end end return table.concat(allparts, "/") end function path.rebase(p, oldbase, newbase) p = path.getabsolute(path.join(oldbase, p)) p = path.getrelative(newbase, p) return p end function path.translate(p, sep) if type(p) == "table" then local result = { } for _, value in ipairs(p) do table.insert(result, path.translate(value)) end return result else if not sep then sep = "\\" end local result = p:gsub("[/\\]", sep) return result end end function path.wildcards(pattern) pattern = pattern:gsub("([%+%.%-%^%$%(%)%%])", "%%%1") pattern = pattern:gsub("%*%*", "\001") pattern = pattern:gsub("%*", "\002") pattern = pattern:gsub("\001", ".*") pattern = pattern:gsub("\002", "[^/]*") return pattern end function string.explode(s, pattern, plain) if (pattern == '') then return false end local pos = 0 local arr = { } for st,sp in function() return s:find(pattern, pos, plain) end do table.insert(arr, s:sub(pos, st-1)) pos = sp + 1 end table.insert(arr, s:sub(pos)) return arr end function string.findlast(s, pattern, plain) local curr = 0 repeat local next = s:find(pattern, curr + 1, plain) if (next) then curr = next end until (not next) if (curr > 0) then return curr end end function string.startswith(haystack, needle) return (haystack:find(needle, 1, true) == 1) end function table.contains(t, value) for _,v in pairs(t) do if (v == value) then return true end end return false end function table.extract(arr, fname) local result = { } for _,v in ipairs(arr) do table.insert(result, v[fname]) end return result end function table.flatten(arr) local result = { } local function flatten(arr) for _, v in ipairs(arr) do if type(v) == "table" then flatten(v) else table.insert(result, v) end end end flatten(arr) return result end function table.implode(arr, before, after, between) local result = "" for _,v in ipairs(arr) do if (result ~= "" and between) then result = result .. between end result = result .. before .. v .. after end return result end function table.insertflat(tbl, values) if type(values) == "table" then for _, value in ipairs(values) do table.insertflat(tbl, value) end else table.insert(tbl, values) end end function table.isempty(t) return not next(t) end function table.join(...) local result = { } for _,t in ipairs(arg) do if type(t) == "table" then for _,v in ipairs(t) do table.insert(result, v) end else table.insert(result, t) end end return result end function table.keys(tbl) local keys = {} for k, _ in pairs(tbl) do table.insert(keys, k) end return keys end function table.merge(...) local result = { } for _,t in ipairs(arg) do if type(t) == "table" then for k,v in pairs(t) do result[k] = v end else error("invalid value") end end return result end function table.translate(arr, translation) local result = { } for _, value in ipairs(arr) do local tvalue if type(translation) == "function" then tvalue = translation(value) else tvalue = translation[value] end if (tvalue) then table.insert(result, tvalue) end end return result end function io.capture() io.captured = '' end function io.endcapture() local captured = io.captured io.captured = nil return captured end local builtin_open = io.open function io.open(fname, mode) if (mode) then if (mode:find("w")) then local dir = path.getdirectory(fname) ok, err = os.mkdir(dir) if (not ok) then error(err, 0) end end end return builtin_open(fname, mode) end function io.printf(msg, ...) if not io.eol then io.eol = "\n" end if not io.indent then io.indent = "\t" end if type(msg) == "number" then s = string.rep(io.indent, msg) .. string.format(unpack(arg)) else s = string.format(msg, unpack(arg)) end if io.captured then io.captured = io.captured .. s .. io.eol else io.write(s) io.write(io.eol) end end _p = io.printf _x = function(msg, ...) for i=2, #arg do arg[i] = premake.esc(arg[i]) end io.printf(msg, unpack(arg)) end premake = { } premake5 = { } premake.tools = { } premake.platforms = { Native = { cfgsuffix = "", }, x32 = { cfgsuffix = "32", }, x64 = { cfgsuffix = "64", }, Universal = { cfgsuffix = "univ", }, Universal32 = { cfgsuffix = "univ32", }, Universal64 = { cfgsuffix = "univ64", }, PS3 = { cfgsuffix = "ps3", iscrosscompiler = true, nosharedlibs = true, namestyle = "PS3", }, WiiDev = { cfgsuffix = "wii", iscrosscompiler = true, namestyle = "PS3", }, Xbox360 = { cfgsuffix = "xbox360", iscrosscompiler = true, namestyle = "windows", }, iPhone = { cfgsuffix = "iphone", }, } local builtin_dofile = dofile function dofile(fname) local oldcwd = os.getcwd() local oldfile = _SCRIPT if (not os.isfile(fname)) then local path = os.pathsearch(fname, _OPTIONS["scripts"], os.getenv("PREMAKE_PATH")) if (path) then fname = path.."/"..fname end end _SCRIPT = path.getabsolute(fname) local newcwd = path.getdirectory(_SCRIPT) os.chdir(newcwd) local a, b, c, d, e, f = builtin_dofile(_SCRIPT) _SCRIPT = oldfile os.chdir(oldcwd) return a, b, c, d, e, f end function iif(expr, trueval, falseval) if (expr) then return trueval else return falseval end end io._includedFiles = { } function include(filename) if os.isdir(filename) then filename = path.join(filename, "premake4.lua") end filename = path.getabsolute(filename) if not io._includedFiles[filename] then io._includedFiles[filename] = true dofile(filename) end end function printf(msg, ...) print(string.format(msg, unpack(arg))) end local builtin_type = type function type(t) local mt = getmetatable(t) if (mt) then if (mt.__type) then return mt.__type end end return builtin_type(t) end premake.action = { } premake.action.list = { } function premake.action.add(a) local missing for _, field in ipairs({"description", "trigger"}) do if (not a[field]) then missing = field end end if (missing) then error("action needs a " .. missing, 3) end premake.action.list[a.trigger] = a end function premake.action.call(name) local a = premake.action.list[name] if a.isnextgen then if _ACTION:endswith("ng") then _ACTION = _ACTION:sub(1, -3) end for sln in premake.solution.each() do if a.onsolution then a.onsolution(sln) end for prj in premake.solution.eachproject_ng(sln) do if a.onproject then a.onproject(prj) end end end else for sln in premake.solution.each() do if a.onsolution then a.onsolution(sln) end for prj in premake.solution.eachproject(sln) do if a.onproject then a.onproject(prj) end end end end if a.execute then a.execute() end end function premake.action.current() return premake.action.get(_ACTION) end function premake.action.get(name) return premake.action.list[name] end function premake.action.each() local keys = { } for _, action in pairs(premake.action.list) do table.insert(keys, action.trigger) end table.sort(keys) local i = 0 return function() i = i + 1 return premake.action.list[keys[i]] end end function premake.action.set(name) _ACTION = name local action = premake.action.get(name) if action then _OS = action.os or _OS end end function premake.action.supports(action, feature) if not action then return false end if action.valid_languages then if table.contains(action.valid_languages, feature) then return true end end if action.valid_kinds then if table.contains(action.valid_kinds, feature) then return true end end return false end premake.option = { } premake.option.list = { } function premake.option.add(opt) local missing for _, field in ipairs({ "description", "trigger" }) do if (not opt[field]) then missing = field end end if (missing) then error("option needs a " .. missing, 3) end premake.option.list[opt.trigger] = opt end function premake.option.get(name) return premake.option.list[name] end function premake.option.each() local keys = { } for _, option in pairs(premake.option.list) do table.insert(keys, option.trigger) end table.sort(keys) local i = 0 return function() i = i + 1 return premake.option.list[keys[i]] end end function premake.option.validate(values) for key, value in pairs(values) do local opt = premake.option.get(key) if (not opt) then return false, "invalid option '" .. key .. "'" end if (opt.value and value == "") then return false, "no value specified for option '" .. key .. "'" end if (opt.allowed) then for _, match in ipairs(opt.allowed) do if (match[1] == value) then return true end end return false, "invalid value '" .. value .. "' for option '" .. key .. "'" end end return true end premake.tree = { } local tree = premake.tree function tree.new(n) local t = { name = n, children = { } } return t end function tree.add(tr, p, onaddfunc) if p == "." then return tr end local parentnode = tree.add(tr, path.getdirectory(p), onaddfunc) local childname = path.getname(p) local childnode = parentnode.children[childname] if not childnode or childnode.path ~= p then childnode = tree.insert(parentnode, tree.new(childname)) childnode.path = p if onaddfunc then onaddfunc(childnode) end end return childnode end function tree.insert(parent, child) table.insert(parent.children, child) if child.name then parent.children[child.name] = child end child.parent = parent return child end function tree.getlocalpath(node) if node.parent.path then return node.name elseif node.cfg then return node.cfg.name else return node.path end end function tree.remove(node) local children = node.parent.children for i = 1, #children do if children[i] == node then table.remove(children, i) end end node.children = {} end function tree.sort(tr) tree.traverse(tr, { onnode = function(node) table.sort(node.children, function(a,b) return a.name < b.name end) end }, true) end function tree.traverse(t, fn, includeroot, initialdepth) local donode, dochildren donode = function(node, fn, depth) if node.isremoved then return end if fn.onnode then fn.onnode(node, depth) end if #node.children > 0 then if fn.onbranchenter then fn.onbranchenter(node, depth) end if fn.onbranch then fn.onbranch(node, depth) end dochildren(node, fn, depth + 1) if fn.onbranchexit then fn.onbranchexit(node, depth) end else if fn.onleaf then fn.onleaf(node, depth) end end end dochildren = function(parent, fn, depth) local i = 1 while i <= #parent.children do local node = parent.children[i] donode(node, fn, depth) if node == parent.children[i] then i = i + 1 end end end if not initialdepth then initialdepth = 0 end if includeroot then donode(t, fn, initialdepth) else dochildren(t, fn, initialdepth) end end function tree.trimroot(tr) local trimmed while #tr.children == 1 do local node = tr.children[1] if #node.children == 0 then break end trimmed = true local numChildren = #node.children for i = 1, numChildren do local child = node.children[i] child.parent = node.parent tr.children[i] = child end end local dotdot local count = #tr.children repeat dotdot = false for i = 1, count do local node = tr.children[i] if node.name == ".." and #node.children == 1 then local child = node.children[1] child.parent = node.parent tr.children[i] = child trimmed = true dotdot = true end end until not dotdot if trimmed then tree.traverse(tr, { onnode = function(node) if node.parent.path then node.path = path.join(node.parent.path, node.name) else node.path = node.name end end }, false) end end premake.project = { } function premake.project.buildsourcetree(prj) local tr = premake.tree.new(prj.name) tr.project = prj local isvpath local function onadd(node) node.isvpath = isvpath end for fcfg in premake.project.eachfile(prj) do isvpath = (fcfg.name ~= fcfg.vpath) local node = premake.tree.add(tr, fcfg.vpath, onadd) node.cfg = fcfg end premake.tree.sort(tr) return tr end function premake.eachconfig(prj, platform) if prj.project then prj = prj.project end local cfgs = prj.solution.configurations local i = 0 return function () i = i + 1 if i <= #cfgs then return premake.getconfig(prj, cfgs[i], platform) end end end function premake.project.eachfile(prj) if not prj.project then prj = premake.getconfig(prj) end local i = 0 local t = prj.files return function () i = i + 1 if (i <= #t) then local fcfg = prj.__fileconfigs[t[i]] fcfg.vpath = premake.project.getvpath(prj, fcfg.name) return fcfg end end end function premake.esc(value) if (type(value) == "table") then local result = { } for _,v in ipairs(value) do table.insert(result, premake.esc(v)) end return result else value = string.gsub(value, '&', "&") value = value:gsub('"', """) value = value:gsub("'", "'") value = value:gsub('<', "<") value = value:gsub('>', ">") value = value:gsub('\r', " ") value = value:gsub('\n', " ") return value end end function premake.filterplatforms(sln, map, default) local result = { } local keys = { } if sln.platforms then for _, p in ipairs(sln.platforms) do if map[p] and not table.contains(keys, map[p]) then table.insert(result, p) table.insert(keys, map[p]) end end end if #result == 0 and default then table.insert(result, default) end return result end function premake.findproject(name) for sln in premake.solution.each() do for prj in premake.solution.eachproject(sln) do if (prj.name == name) then return prj end end end end function premake.findfile(prj, extension) for _, fname in ipairs(prj.files) do if fname:endswith(extension) then return fname end end end function premake.getconfig(prj, cfgname, pltname) prj = prj.project or prj if pltname == "Native" or not table.contains(prj.solution.platforms or {}, pltname) then pltname = nil end local key = (cfgname or "") if pltname then key = key .. pltname end return prj.__configs[key] end function premake.getconfigname(cfgname, platform, useshortname) if cfgname then local name = cfgname if platform and platform ~= "Native" then if useshortname then name = name .. premake.platforms[platform].cfgsuffix else name = name .. "|" .. platform end end return iif(useshortname, name:lower(), name) end end function premake.getdependencies(prj) prj = prj.project or prj local results = { } for _, cfg in pairs(prj.__configs) do for _, link in ipairs(cfg.links) do local dep = premake.findproject(link) if dep and not table.contains(results, dep) then table.insert(results, dep) end end end return results end function premake.project.getfilename(prj, pattern) local fname = pattern:gsub("%%%%", prj.name) fname = path.join(prj.location, fname) return path.getrelative(os.getcwd(), fname) end function premake.getlinks(cfg, kind, part) local result = iif (part == "directory" and kind == "all", cfg.libdirs, {}) local cfgname = iif(cfg.name == cfg.project.name, "", cfg.name) local pathstyle = premake.getpathstyle(cfg) local namestyle = premake.getnamestyle(cfg) local function canlink(source, target) if (target.kind ~= "SharedLib" and target.kind ~= "StaticLib") then return false end if premake.iscppproject(source) then return premake.iscppproject(target) elseif premake.isdotnetproject(source) then return premake.isdotnetproject(target) end end for _, link in ipairs(cfg.links) do local item local prj = premake.findproject(link) if prj and kind ~= "system" then local prjcfg = premake.getconfig(prj, cfgname, cfg.platform) if kind == "dependencies" or canlink(cfg, prjcfg) then if (part == "directory") then item = path.rebase(prjcfg.linktarget.directory, prjcfg.location, cfg.location) elseif (part == "basename") then item = prjcfg.linktarget.basename elseif (part == "fullpath") then item = path.rebase(prjcfg.linktarget.fullpath, prjcfg.location, cfg.location) elseif (part == "object") then item = prjcfg end end elseif not prj and (kind == "system" or kind == "all") then if (part == "directory") then local dir = path.getdirectory(link) if (dir ~= ".") then item = dir end elseif (part == "fullpath") then item = link if namestyle == "windows" then if premake.iscppproject(cfg) then item = item .. ".lib" elseif premake.isdotnetproject(cfg) then item = item .. ".dll" end end if item:find("/", nil, true) then item = path.getrelative(cfg.basedir, item) end else item = link end end if item then if pathstyle == "windows" and part ~= "object" then item = path.translate(item, "\\") end if not table.contains(result, item) then table.insert(result, item) end end end return result end function premake.getnamestyle(cfg) return premake.platforms[cfg.platform].namestyle or premake.gettool(cfg).namestyle or "posix" end function premake.getpathstyle(cfg) if premake.action.current().os == "windows" then return "windows" else return "posix" end end function premake.gettarget(cfg, direction, pathstyle, namestyle, system) if system == "bsd" or system == "solaris" then system = "linux" end local kind = cfg.kind if premake.iscppproject(cfg) then if (namestyle == "windows" or system == "windows") and kind == "SharedLib" and direction == "link" and not cfg.flags.NoImportLib then kind = "StaticLib" end if namestyle == "posix" and system == "windows" and kind ~= "StaticLib" then namestyle = "windows" end end local field = iif(direction == "build", "target", "implib") local name = cfg[field.."name"] or cfg.targetname or cfg.project.name local dir = cfg[field.."dir"] or cfg.targetdir or path.getrelative(cfg.location, cfg.basedir) local prefix = "" local suffix = "" local ext = "" local bundlepath, bundlename if namestyle == "windows" then if kind == "ConsoleApp" or kind == "WindowedApp" then ext = ".exe" elseif kind == "SharedLib" then ext = ".dll" elseif kind == "StaticLib" then ext = ".lib" end elseif namestyle == "posix" then if kind == "WindowedApp" and system == "macosx" then bundlename = name .. ".app" bundlepath = path.join(dir, bundlename) dir = path.join(bundlepath, "Contents/MacOS") elseif kind == "SharedLib" then prefix = "lib" ext = iif(system == "macosx", ".dylib", ".so") elseif kind == "StaticLib" then prefix = "lib" ext = ".a" end elseif namestyle == "PS3" then if kind == "ConsoleApp" or kind == "WindowedApp" then ext = ".elf" elseif kind == "StaticLib" then prefix = "lib" ext = ".a" end end prefix = cfg[field.."prefix"] or cfg.targetprefix or prefix suffix = cfg[field.."suffix"] or cfg.targetsuffix or suffix ext = cfg[field.."extension"] or cfg.targetextension or ext local result = { } result.basename = name .. suffix result.name = prefix .. name .. suffix .. ext result.directory = dir result.prefix = prefix result.suffix = suffix result.fullpath = path.join(result.directory, result.name) result.bundlepath = bundlepath or result.fullpath if pathstyle == "windows" then result.directory = path.translate(result.directory, "\\") result.fullpath = path.translate(result.fullpath, "\\") end return result end function premake.gettool(cfg) if premake.iscppproject(cfg) then if _OPTIONS.cc then return premake[_OPTIONS.cc] end local action = premake.action.current() if action.valid_tools then return premake[action.valid_tools.cc[1]] end return premake.gcc else return premake.dotnet end end function premake.project.getvpath(prj, filename) local vpath = filename for replacement,patterns in pairs(prj.vpaths) do for _,pattern in ipairs(patterns) do local i = vpath:find(path.wildcards(pattern)) if i == 1 then i = pattern:find("*", 1, true) or (pattern:len() + 1) local leaf = vpath:sub(i) if leaf:startswith("/") then leaf = leaf:sub(2) end local stem = "" if replacement:len() > 0 then stem, stars = replacement:gsub("%*", "") if stars == 0 then leaf = path.getname(leaf) end end vpath = path.join(stem, leaf) end end end local changed repeat changed = true if vpath:startswith("./") then vpath = vpath:sub(3) elseif vpath:startswith("../") then vpath = vpath:sub(4) else changed = false end until not changed return vpath end function premake.hascppproject(sln) for prj in premake.solution.eachproject(sln) do if premake.iscppproject(prj) then return true end end end function premake.hasdotnetproject(sln) for prj in premake.solution.eachproject(sln) do if premake.isdotnetproject(prj) then return true end end end function premake.project.iscproject(prj) local language = prj.language or prj.solution.language return language == "C" end function premake.iscppproject(prj) local language = prj.language or prj.solution.language return language == "C" or language == "C++" end function premake.isdotnetproject(prj) local language = prj.language or prj.solution.language return language == "C#" end premake.config = { } local config = premake.config function premake.config.isdebugbuild(cfg) if cfg.flags.Optimize or cfg.flags.OptimizeSize or cfg.flags.OptimizeSpeed then return false end if not cfg.flags.Symbols then return false end return true end function premake.config.canincrementallink(cfg) if cfg.kind == "StaticLib" or config.isoptimizedbuild(cfg) or cfg.flags.NoIncrementalLink then return false end return true end function premake.config.isoptimizedbuild(cfg) return cfg.flags.Optimize or cfg.flags.OptimizeSize or cfg.flags.OptimizeSpeed end premake.bake = { } local bake = premake.bake local nocopy = { blocks = true, keywords = true, projects = true, __configs = true, } local nocascade = { makesettings = true, } local keeprelative = { basedir = true, location = true, } function premake.getactiveterms() local terms = { _action = _ACTION:lower(), os = os.get() } for key, value in pairs(_OPTIONS) do if value ~= "" then table.insert(terms, value:lower()) else table.insert(terms, key:lower()) end end return terms end function premake.iskeywordmatch(keyword, terms) if keyword:startswith("not ") then return not premake.iskeywordmatch(keyword:sub(5), terms) end for _, pattern in ipairs(keyword:explode(" or ")) do for termkey, term in pairs(terms) do if term:match(pattern) == term then return termkey end end end end function premake.iskeywordsmatch(keywords, terms) local hasrequired = false for _, keyword in ipairs(keywords) do local matched = premake.iskeywordmatch(keyword, terms) if not matched then return false end if matched == "required" then hasrequired = true end end if terms.required and not hasrequired then return false else return true end end local function adjustpaths(location, obj) function adjustpathlist(list) for i, p in ipairs(list) do list[i] = path.getrelative(location, p) end end for name, value in pairs(obj) do local field = premake.fields[name] if field and value and not keeprelative[name] then if field.kind == "path" then obj[name] = path.getrelative(location, value) elseif field.kind == "dirlist" or field.kind == "filelist" then adjustpathlist(value) elseif field.kind == "keypath" then for k,v in pairs(value) do adjustpathlist(v) end end end end end local function mergefield(kind, dest, src) local tbl = dest or { } if kind == "keyvalue" or kind == "keypath" then for key, value in pairs(src) do tbl[key] = mergefield("list", tbl[key], value) end else for _, item in ipairs(src) do if not tbl[item] then table.insert(tbl, item) tbl[item] = item end end end return tbl end local function mergeobject(dest, src) if not src then return end for fieldname, value in pairs(src) do if not nocopy[fieldname] then local field = premake.fields[fieldname] if field then if type(value) == "table" then dest[fieldname] = mergefield(field.kind, dest[fieldname], value) else dest[fieldname] = value end else dest[fieldname] = value end end end end local function merge(dest, obj, basis, terms, cfgname, pltname) local key = cfgname or "" pltname = pltname or "Native" if pltname ~= "Native" then key = key .. pltname end terms.config = (cfgname or ""):lower() terms.platform = pltname:lower() local cfg = {} mergeobject(cfg, basis[key]) adjustpaths(obj.location, cfg) mergeobject(cfg, obj) if (cfg.kind) then terms['kind']=cfg.kind:lower() end for _, blk in ipairs(obj.blocks) do if (premake.iskeywordsmatch(blk.keywords, terms))then mergeobject(cfg, blk) if (cfg.kind and not cfg.terms.kind) then cfg.terms['kind'] = cfg.kind:lower() terms['kind'] = cfg.kind:lower() end end end cfg.name = cfgname cfg.platform = pltname for k,v in pairs(terms) do cfg.terms[k] =v end dest[key] = cfg end local function collapse(obj, basis) local result = {} basis = basis or {} local sln = obj.solution or obj local terms = premake.getactiveterms() merge(result, obj, basis, terms)--this adjusts terms for _, cfgname in ipairs(sln.configurations) do local terms_local = {} for k,v in pairs(terms)do terms_local[k]=v end merge(result, obj, basis, terms_local, cfgname, "Native")--terms cam also be adjusted here for _, pltname in ipairs(sln.platforms or {}) do if pltname ~= "Native" then merge(result, obj, basis,terms_local, cfgname, pltname)--terms also here end end end return result end local function builduniquedirs() local num_variations = 4 local cfg_dirs = {} local hit_counts = {} for sln in premake.solution.each() do for _, prj in ipairs(sln.projects) do for _, cfg in pairs(prj.__configs) do local dirs = { } dirs[1] = path.getabsolute(path.join(cfg.location, cfg.objdir or cfg.project.objdir or "obj")) dirs[2] = path.join(dirs[1], iif(cfg.platform == "Native", "", cfg.platform)) dirs[3] = path.join(dirs[2], cfg.name) dirs[4] = path.join(dirs[3], cfg.project.name) cfg_dirs[cfg] = dirs local start = iif(cfg.name, 2, 1) for v = start, num_variations do local d = dirs[v] hit_counts[d] = (hit_counts[d] or 0) + 1 end end end end for sln in premake.solution.each() do for _, prj in ipairs(sln.projects) do for _, cfg in pairs(prj.__configs) do local dir local start = iif(cfg.name, 2, 1) for v = start, num_variations do dir = cfg_dirs[cfg][v] if hit_counts[dir] == 1 then break end end cfg.objectsdir = path.getrelative(cfg.location, dir) end end end end local function buildtargets() for sln in premake.solution.each() do for _, prj in ipairs(sln.projects) do for _, cfg in pairs(prj.__configs) do local pathstyle = premake.getpathstyle(cfg) local namestyle = premake.getnamestyle(cfg) cfg.buildtarget = premake.gettarget(cfg, "build", pathstyle, namestyle, cfg.system) cfg.linktarget = premake.gettarget(cfg, "link", pathstyle, namestyle, cfg.system) if pathstyle == "windows" then cfg.objectsdir = path.translate(cfg.objectsdir, "\\") end end end end end local function getCfgKind(cfg) if(cfg.kind) then return cfg.kind; end if(cfg.project.__configs[""] and cfg.project.__configs[""].kind) then return cfg.project.__configs[""].kind; end return nil end local function getprojrec(dstArray, foundList, cfg, cfgname, searchField, bLinkage) if(not cfg) then return end local foundUsePrjs = {}; for _, useName in ipairs(cfg[searchField]) do local testName = useName:lower(); if((not foundList[testName])) then local theProj = nil; local theUseProj = nil; for _, prj in ipairs(cfg.project.solution.projects) do if (prj.name:lower() == testName) then if(prj.usage) then theUseProj = prj; else theProj = prj; end end end --Must connect to a usage project. if(theUseProj) then foundList[testName] = true; local prjEntry = { name = testName, proj = theProj, usageProj = theUseProj, bLinkageOnly = bLinkage, }; dstArray[testName] = prjEntry; table.insert(foundUsePrjs, theUseProj); end end end for _, usePrj in ipairs(foundUsePrjs) do --Links can only recurse through static libraries. if((searchField ~= "links") or (getCfgKind(usePrj.__configs[cfgname]) == "StaticLib")) then getprojrec(dstArray, foundList, usePrj.__configs[cfgname], cfgname, searchField, bLinkage); end end end -- -- This function will recursively get all projects that the given configuration has in its "uses" -- field. The return values are a list of tables. Each table in that list contains the following: --name = The lowercase name of the project. --proj = The project. Can be nil if it is usage-only. --usageProj = The usage project. Can't be nil, as using a project that has no -- usage project is not put into the list. --bLinkageOnly = If this is true, then only the linkage information should be copied. -- The recursion will only look at the "uses" field on *usage* projects. -- This function will also add projects to the list that are mentioned in the "links" -- field of usage projects. These will only copy linker information, but they will recurse. -- through other "links" fields. -- local function getprojectsconnections(cfg, cfgname) local dstArray = {}; local foundList = {}; foundList[cfg.project.name:lower()] = true; --First, follow the uses recursively. getprojrec(dstArray, foundList, cfg, cfgname, "uses", false); --Next, go through all of the usage projects and recursively get their links. --But only if they're not already there. Get the links as linkage-only. local linkArray = {}; for prjName, prjEntry in pairs(dstArray) do getprojrec(linkArray, foundList, prjEntry.usageProj.__configs[cfgname], cfgname, "links", true); end --Copy from linkArray into dstArray. for prjName, prjEntry in pairs(linkArray) do dstArray[prjName] = prjEntry; end return dstArray; end local function isnameofproj(cfg, strName) local sln = cfg.project.solution; local strTest = strName:lower(); for prjIx, prj in ipairs(sln.projects) do if (prj.name:lower() == strTest) then return true; end end return false; end -- -- Copies the field from dstCfg to srcCfg. -- local function copydependentfield(srcCfg, dstCfg, strSrcField) local srcField = premake.fields[strSrcField]; local strDstField = strSrcField; if type(srcCfg[strSrcField]) == "table" then --handle paths. if (srcField.kind == "dirlist" or srcField.kind == "filelist") and (not keeprelative[strSrcField]) then for i,p in ipairs(srcCfg[strSrcField]) do table.insert(dstCfg[strDstField], path.rebase(p, srcCfg.project.location, dstCfg.project.location)) end else if(strSrcField == "links") then for i,p in ipairs(srcCfg[strSrcField]) do if(not isnameofproj(dstCfg, p)) then table.insert(dstCfg[strDstField], p) else printf("Failed to copy '%s' from proj '%s'.", p, srcCfg.project.name); end end else for i,p in ipairs(srcCfg[strSrcField]) do table.insert(dstCfg[strDstField], p) end end end else if(srcField.kind == "path" and (not keeprelative[strSrcField])) then dstCfg[strDstField] = path.rebase(srcCfg[strSrcField], prj.location, dstCfg.project.location); else dstCfg[strDstField] = srcCfg[strSrcField]; end end end -- -- This function will take the list of project entries and apply their usage project data -- to the given configuration. It will copy compiling information for the projects that are -- not listed as linkage-only. It will copy the linking information for projects only if -- the source project is not a static library. It won't copy linking information -- if the project is in this solution; instead it will add that project to the configuration's -- links field, expecting that Premake will handle the rest. -- local function copyusagedata(cfg, cfgname, linkToProjs) local myPrj = cfg.project; local bIsStaticLib = (getCfgKind(cfg) == "StaticLib"); for prjName, prjEntry in pairs(linkToProjs) do local srcPrj = prjEntry.usageProj; local srcCfg = srcPrj.__configs[cfgname]; for name, field in pairs(premake.fields) do if(srcCfg[name]) then if(field.usagecopy) then if(not prjEntry.bLinkageOnly) then copydependentfield(srcCfg, cfg, name) end elseif(field.linkagecopy) then --Copy the linkage data if we're building a non-static thing --and this is a pure usage project. If it's not pure-usage, then --we will simply put the project's name in the links field later. if((not bIsStaticLib) and (not prjEntry.proj)) then copydependentfield(srcCfg, cfg, name) end end end end if((not bIsStaticLib) and prjEntry.proj) then table.insert(cfg.links, prjEntry.proj.name); end end end function premake.bake.buildconfigs() for sln in premake.solution.each() do for _, prj in ipairs(sln.projects) do prj.location = prj.location or sln.location or prj.basedir adjustpaths(prj.location, prj) for _, blk in ipairs(prj.blocks) do adjustpaths(prj.location, blk) end end sln.location = sln.location or sln.basedir end for sln in premake.solution.each() do local basis = collapse(sln) for _, prj in ipairs(sln.projects) do prj.__configs = collapse(prj, basis) for _, cfg in pairs(prj.__configs) do bake.postprocess(prj, cfg) end end end for sln in premake.solution.each() do for prjIx, prj in ipairs(sln.projects) do if(not prj.usage) then for cfgname, cfg in pairs(prj.__configs) do local usesPrjs = getprojectsconnections(cfg, cfgname); copyusagedata(cfg, cfgname, usesPrjs) end end end end for sln in premake.solution.each() do local removeList = {}; for index, prj in ipairs(sln.projects) do if(prj.usage) then table.insert(removeList, 1, index); --Add in reverse order. end end for _, index in ipairs(removeList) do table.remove(sln.projects, index); end end builduniquedirs() buildtargets(cfg) end function premake.bake.postprocess(prj, cfg) cfg.project = prj cfg.shortname = premake.getconfigname(cfg.name, cfg.platform, true) cfg.longname = premake.getconfigname(cfg.name, cfg.platform) cfg.location = cfg.location or cfg.basedir local platform = premake.platforms[cfg.platform] if platform.iscrosscompiler then cfg.system = cfg.platform else cfg.system = os.get() end if cfg.kind == "SharedLib" and platform.nosharedlibs then cfg.kind = "StaticLib" end local files = { } for _, fname in ipairs(cfg.files) do local excluded = false for _, exclude in ipairs(cfg.excludes) do excluded = (fname == exclude) if (excluded) then break end end if (not excluded) then table.insert(files, fname) end end cfg.files = files for name, field in pairs(premake.fields) do if field.isflags then local values = cfg[name] for _, flag in ipairs(values) do values[flag] = true end end end cfg.__fileconfigs = { } for _, fname in ipairs(cfg.files) do cfg.terms.required = fname:lower() local fcfg = {} for _, blk in ipairs(cfg.project.blocks) do if (premake.iskeywordsmatch(blk.keywords, cfg.terms)) then mergeobject(fcfg, blk) end end fcfg.name = fname cfg.__fileconfigs[fname] = fcfg table.insert(cfg.__fileconfigs, fcfg) end end premake.fields = { architecture = { kind = "string", scope = "config", allowed = { "x32", "x64", }, }, basedir = { kind = "path", scope = "container", }, buildaction = { kind = "string", scope = "config", allowed = { "Compile", "Copy", "Embed", "None" } }, buildoptions = { kind = "list", scope = "config", }, buildrule = { kind = "object", scope = "config", }, configurations = { kind = "list", scope = "container", }, debugargs = { kind = "list", scope = "config", }, debugdir = { kind = "path", scope = "config", }, debugenvs = { kind = "list", scope = "config", }, debugformat = { kind = "string", scope = "config", allowed = { "c7", } }, defines = { kind = "list", scope = "config", }, xcodebuildsettings = { kind = "list", scope = "config", }, deploymentoptions = { kind = "list", scope = "config", usagecopy = true, }, excludes = { kind = "filelist", scope = "config", }, files = { kind = "filelist", scope = "config", }, flags = { kind = "list", scope = "config", isflags = true, usagecopy = true, allowed = { "DebugEnvsDontMerge", "DebugEnvsInherit", "EnableSSE", "EnableSSE2", "ExtraWarnings", "FatalWarnings", "FloatFast", "FloatStrict", "Managed", "MFC", "NativeWChar", "No64BitChecks", "NoEditAndContinue", "NoExceptions", "NoFramePointer", "NoImportLib", "NoIncrementalLink", "NoManifest", "NoMinimalRebuild", "NoNativeWChar", "NoPCH", "NoRTTI", "Optimize", "OptimizeSize", "OptimizeSpeed", "SEH", "StaticRuntime", "Symbols", "Unicode", "Unsafe", "WinMain", }, aliases = { Optimise = 'Optimize', OptimiseSize = 'OptimizeSize', OptimiseSpeed = 'OptimizeSpeed', }, }, framework = { kind = "string", scope = "container", allowed = { "1.0", "1.1", "2.0", "3.0", "3.5", "4.0" } }, imagepath = { kind = "path", scope = "config", }, imageoptions = { kind = "list", scope = "config", }, implibdir = { kind = "path", scope = "config", }, implibextension = { kind = "string", scope = "config", }, implibname = { kind = "string", scope = "config", }, implibprefix = { kind = "string", scope = "config", }, implibsuffix = { kind = "string", scope = "config", }, includedirs = { kind = "dirlist", scope = "config", usagecopy = true, }, kind = { kind = "string", scope = "config", allowed = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" } }, language = { kind = "string", scope = "container", allowed = { "C", "C++", "C#" } }, libdirs = { kind = "dirlist", scope = "config", linkagecopy = true, }, linkoptions = { kind = "list", scope = "config", }, links = { kind = "list", scope = "config", allowed = function(value) if value:find('/', nil, true) then value = path.getabsolute(value) end return value end, linkagecopy = true, }, location = { kind = "path", scope = "container", }, makesettings = { kind = "list", scope = "config", }, objdir = { kind = "path", scope = "config", }, pchheader = { kind = "string", scope = "config", }, pchsource = { kind = "path", scope = "config", }, platforms = { kind = "list", scope = "container", }, postbuildcommands = { kind = "list", scope = "config", }, prebuildcommands = { kind = "list", scope = "config", }, prelinkcommands = { kind = "list", scope = "config", }, resdefines = { kind = "list", scope = "config", }, resincludedirs = { kind = "dirlist", scope = "config", }, resoptions = { kind = "list", scope = "config", }, system = { kind = "string", scope = "config", allowed = function(value) value = value:lower() if premake.systems[value] then return value else return nil, "unknown system" end end, }, targetdir = { kind = "path", scope = "config", }, targetextension = { kind = "string", scope = "config", }, targetname = { kind = "string", scope = "config", }, targetprefix = { kind = "string", scope = "config", }, targetsuffix = { kind = "string", scope = "config", }, toolset = { kind = "string", scope = "config", allowed = { "gcc" }, }, trimpaths = { kind = "dirlist", scope = "config", }, uuid = { kind = "string", scope = "container", allowed = function(value) local ok = true if (#value ~= 36) then ok = false end for i=1,36 do local ch = value:sub(i,i) if (not ch:find("[ABCDEFabcdef0123456789-]")) then ok = false end end if (value:sub(9,9) ~= "-") then ok = false end if (value:sub(14,14) ~= "-") then ok = false end if (value:sub(19,19) ~= "-") then ok = false end if (value:sub(24,24) ~= "-") then ok = false end if (not ok) then return nil, "invalid UUID" end return value:upper() end }, uses = { kind = "list", scope = "config", }, vpaths = { kind = "keypath", scope = "container", }, } function premake.checkvalue(value, allowed, aliases) if aliases then for k,v in pairs(aliases) do if value:lower() == k:lower() then value = v break end end end if allowed then if type(allowed) == "function" then return allowed(value) else for _,v in ipairs(allowed) do if value:lower() == v:lower() then return v end end return nil, "invalid value '" .. value .. "'" end else return value end end function premake.getobject(t) local container if (t == "container" or t == "solution") then container = premake.CurrentContainer else container = premake.CurrentConfiguration end if t == "solution" then if type(container) == "project" then container = container.solution end if type(container) ~= "solution" then container = nil end end local msg if (not container) then if (t == "container") then msg = "no active solution or project" elseif (t == "solution") then msg = "no active solution" else msg = "no active solution, project, or configuration" end end return container, msg end function premake.setobject(obj, fieldname, value) obj[fieldname] = value return value end function premake.setarray(obj, fieldname, value, allowed, aliases) obj[fieldname] = obj[fieldname] or {} local function add(value, depth) if type(value) == "table" then for _,v in ipairs(value) do add(v, depth + 1) end else value, err = premake.checkvalue(value, allowed, aliases) if not value then error(err, depth) end obj[fieldname] = table.join(obj[fieldname], value) end end if value then add(value, 5) end return obj[fieldname] end local function domatchedarray(obj, fieldname, value, matchfunc) local result = { } function makeabsolute(value, depth) if (type(value) == "table") then for _, item in ipairs(value) do makeabsolute(item, depth + 1) end elseif type(value) == "string" then if value:find("*") then makeabsolute(matchfunc(value), depth + 1) else table.insert(result, path.getabsolute(value)) end else error("Invalid value in list: expected string, got " .. type(value), depth) end end makeabsolute(value, 3) return premake.setarray(obj, fieldname, result) end function premake.setdirarray(obj, fieldname, value) function set(value) if value:find("*") then value = os.matchdirs(value) end return path.getabsolute(value) end return premake.setarray(obj, fieldname, value, set) end function premake.setfilearray(obj, fieldname, value) function set(value) if value:find("*") then value = os.matchfiles(value) end return path.getabsolute(value) end return premake.setarray(obj, fieldname, value, set) end function premake.setkeyvalue(ctype, fieldname, values) local container, err = premake.getobject(ctype) if not container then error(err, 4) end if type(values) ~= "table" then error("invalid value; table expected", 4) end container[fieldname] = container[fieldname] or {} local field = container[fieldname] or {} for key,value in pairs(values) do field[key] = field[key] or {} table.insertflat(field[key], value) end return field end function premake.setstring(ctype, fieldname, value, allowed, aliases) local container, err = premake.getobject(ctype) if (not container) then error(err, 4) end if (value) then value, err = premake.checkvalue(value, allowed, aliases) if (not value) then error(err, 4) end container[fieldname] = value end return container[fieldname] end local function accessor(name, value) local field = premake.fields[name] local kind = field.kind local scope = field.scope local allowed = field.allowed local aliases = field.aliases if (kind == "string" or kind == "path") and value then if type(value) ~= "string" then error("string value expected", 3) end end local container, err = premake.getobject(scope) if (not container) then error(err, 3) end if kind == "string" then return premake.setstring(scope, name, value, allowed, aliases) elseif kind == "path" then if value then value = path.getabsolute(value) end return premake.setstring(scope, name, value) elseif kind == "list" then return premake.setarray(container, name, value, allowed, aliases) elseif kind == "dirlist" then return premake.setdirarray(container, name, value) elseif kind == "filelist" then return premake.setfilearray(container, name, value) elseif kind == "keyvalue" or kind == "keypath" then return premake.setkeyvalue(scope, name, value) elseif kind == "object" then return premake.setobject(container, name, value) end end function premake.remove(fieldname, value) local kind = premake.fields[fieldname].kind function set(value) if kind ~= "list" and not value:startswith("**") then return path.getabsolute(value) else return value end end local cfg = premake.getobject(premake.fields[fieldname].scope) cfg.removes = cfg.removes or {} cfg.removes[fieldname] = premake.setarray(cfg.removes, fieldname, value, set) end for name, info in pairs(premake.fields) do _G[name] = function(value) return accessor(name, value) end if info.kind == "list" or info.kind == "dirlist" or info.kind == "filelist" then _G["remove"..name] = function(value) premake.remove(name, value) end end end function excludes(value) removefiles(value) return accessor("excludes", value) end function configuration(terms) if not terms then return premake.CurrentConfiguration end local container, err = premake.getobject("container") if (not container) then error(err, 2) end local cfg = { } cfg.terms = table.flatten({terms}) table.insert(container.blocks, cfg) premake.CurrentConfiguration = cfg cfg.keywords = { } for _, word in ipairs(cfg.terms) do table.insert(cfg.keywords, path.wildcards(word):lower()) end for name, field in pairs(premake.fields) do if (field.kind ~= "string" and field.kind ~= "path") then cfg[name] = { } end end return cfg end local function createproject(name, sln, isUsage) local prj = {} setmetatable(prj, { __type = "project", }) table.insert(sln.projects, prj) if(isUsage) then if(sln.projects[name]) then sln.projects[name].usageProj = prj; else sln.projects[name] = prj end else if(sln.projects[name]) then prj.usageProj = sln.projects[name]; end sln.projects[name] = prj end prj.solution = sln prj.name = name prj.basedir = os.getcwd() prj.script = _SCRIPT prj.uuid = os.uuid() prj.blocks = { } prj.usage = isUsage; return prj; end function usage(name) if (not name) then if(type(premake.CurrentContainer) ~= "project") then return nil end if(not premake.CurrentContainer.usage) then return nil end return premake.CurrentContainer end local sln if (type(premake.CurrentContainer) == "project") then sln = premake.CurrentContainer.solution else sln = premake.CurrentContainer end if (type(sln) ~= "solution") then error("no active solution", 2) end -- if this is a new project, or the project in that slot doesn't have a usage, create it if((not sln.projects[name]) or ((not sln.projects[name].usage) and (not sln.projects[name].usageProj))) then premake.CurrentContainer = createproject(name, sln, true) else premake.CurrentContainer = iff(sln.projects[name].usage, sln.projects[name], sln.projects[name].usageProj) end -- add an empty, global configuration to the project configuration { } return premake.CurrentContainer end function project(name) if (not name) then --Only return non-usage projects if(type(premake.CurrentContainer) ~= "project") then return nil end if(premake.CurrentContainer.usage) then return nil end return premake.CurrentContainer end -- identify the parent solution local sln if (type(premake.CurrentContainer) == "project") then sln = premake.CurrentContainer.solution else sln = premake.CurrentContainer end if (type(sln) ~= "solution") then error("no active solution", 2) end -- if this is a new project, or the old project is a usage project, create it if((not sln.projects[name]) or sln.projects[name].usage) then premake.CurrentContainer = createproject(name, sln) else premake.CurrentContainer = sln.projects[name]; end configuration { } return premake.CurrentContainer end function solution(name) if not name then if type(premake.CurrentContainer) == "project" then return premake.CurrentContainer.solution else return premake.CurrentContainer end end premake.CurrentContainer = premake.solution.get(name) if (not premake.CurrentContainer) then premake.CurrentContainer = premake.solution.new(name) end configuration { } return premake.CurrentContainer end function newaction(a) premake.action.add(a) end function newoption(opt) premake.option.add(opt) end newoption { trigger = "cc", value = "VALUE", description = "Choose a C/C++ compiler set", allowed = { { "gcc", "GNU GCC (gcc/g++)" }, { "ow", "OpenWatcom" }, } } newoption { trigger = "dotnet", value = "VALUE", description = "Choose a .NET compiler set", allowed = { { "msnet", "Microsoft .NET (csc)" }, { "mono", "Novell Mono (mcs)" }, { "pnet", "Portable.NET (cscc)" }, } } newoption { trigger = "file", value = "FILE", description = "Read FILE as a Premake script; default is 'premake4.lua'" } newoption { trigger = "help", description = "Display this information" } newoption { trigger = "os", value = "VALUE", description = "Generate files for a different operating system", allowed = { { "bsd", "OpenBSD, NetBSD, or FreeBSD" }, { "haiku", "Haiku" }, { "linux", "Linux" }, { "macosx", "Apple Mac OS X" }, { "solaris", "Solaris" }, { "windows", "Microsoft Windows" }, } } newoption { trigger = "platform", value = "VALUE", description = "Add target architecture (if supported by action)", allowed = { { "x32", "32-bit" }, { "x64", "64-bit" }, { "universal", "Mac OS X Universal, 32- and 64-bit" }, { "universal32", "Mac OS X Universal, 32-bit only" }, { "universal64", "Mac OS X Universal, 64-bit only" }, { "ps3", "Playstation 3 (experimental)" }, { "xbox360", "Xbox 360 (experimental)" }, { "iphone", "iPhone" }, } } newoption { trigger = "scripts", value = "path", description = "Search for additional scripts on the given path" } newoption { trigger = "version", description = "Display version information" } function premake.checkprojects() local action = premake.action.current() for sln in premake.solution.each() do if (#sln.projects == 0) then return nil, "solution '" .. sln.name .. "' needs at least one project" end if (#sln.configurations == 0) then return nil, "solution '" .. sln.name .. "' needs configurations" end for prj in premake.solution.eachproject(sln) do if (not prj.language) then return nil, "project '" ..prj.name .. "' needs a language" end if (action.valid_languages) then if (not table.contains(action.valid_languages, prj.language)) then return nil, "the " .. action.shortname .. " action does not support " .. prj.language .. " projects" end end for cfg in premake.eachconfig(prj) do if (not cfg.kind) then return nil, "project '" ..prj.name .. "' needs a kind in configuration '" .. cfg.name .. "'" end if (action.valid_kinds) then if (not table.contains(action.valid_kinds, cfg.kind)) then return nil, "the " .. action.shortname .. " action does not support " .. cfg.kind .. " projects" end end end if action.oncheckproject then action.oncheckproject(prj) end end end return true end function premake.checktools() local action = premake.action.current() if (not action.valid_tools) then return true end for tool, values in pairs(action.valid_tools) do if (_OPTIONS[tool]) then if (not table.contains(values, _OPTIONS[tool])) then return nil, "the " .. action.shortname .. " action does not support /" .. tool .. "=" .. _OPTIONS[tool] .. " (yet)" end else _OPTIONS[tool] = values[1] end end return true end function premake.showhelp() printf("Premake %s, a build script generator", _PREMAKE_VERSION) printf(_PREMAKE_COPYRIGHT) printf("%s %s", _VERSION, _COPYRIGHT) printf("") printf("Usage: premake4 [options] action [arguments]") printf("") printf("OPTIONS") printf("") for option in premake.option.each() do local trigger = option.trigger local description = option.description if (option.value) then trigger = trigger .. "=" .. option.value end if (option.allowed) then description = description .. "; one of:" end printf(" --%-15s %s", trigger, description) if (option.allowed) then for _, value in ipairs(option.allowed) do printf(" %-14s %s", value[1], value[2]) end end printf("") end printf("ACTIONS") printf("") for action in premake.action.each() do printf(" %-17s %s", action.trigger, action.description) end printf("") printf("For additional information, see http://industriousone.com/premake") end premake.C = "C" premake.C7 = "c7" premake.CONSOLEAPP = "ConsoleApp" premake.CPP = "C++" premake.GCC = "gcc" premake.HAIKU = "haiku" premake.MACOSX = "macosx" premake.POSIX = "posix" premake.PS3 = "ps3" premake.SHAREDLIB = "SharedLib" premake.STATICLIB = "StaticLib" premake.WINDOWEDAPP = "WindowedApp" premake.WINDOWS = "windows" premake.X32 = "x32" premake.X64 = "x64" premake.XBOX360 = "xbox360" premake.systems = { linux = { sharedlib = { prefix = "lib", extension = ".so" }, staticlib = { prefix = "lib", extension = ".a" }, }, macosx = { sharedlib = { prefix = "lib", extension = ".dylib" }, staticlib = { prefix = "lib", extension = ".a" }, }, ps3 = { consoleapp = { extension = ".elf" }, sharedlib = { prefix = "lib" }, staticlib = { prefix = "lib", extension = ".a" }, }, windows = { consoleapp = { extension = ".exe" }, windowedapp = { extension = ".exe" }, sharedlib = { extension = ".dll" }, staticlib = { extension = ".lib" }, } } premake.systems.bsd = premake.systems.linux premake.systems.haiku = premake.systems.linux premake.systems.solaris = premake.systems.linux premake.systems.xbox360 = premake.systems.windows function premake.generate(obj, filename, callback) filename = premake.project.getfilename(obj, filename) printf("Generating %s...", filename) local f, err = io.open(filename, "wb") if (not f) then error(err, 0) end io.output(f) callback(obj) f:close() end premake5.oven = { } local oven = premake5.oven local nomerge = { keywords = true, removes = true } function oven.bake(container, filterTerms, filterField) filterTerms = filterTerms or {} for key, value in pairs(filterTerms) do filterTerms[key] = value:lower() end local cfg if container.solution then cfg = oven.bake(container.solution, filterTerms, filterField) else cfg = {} end cfg[type(container)] = container for _, block in ipairs(container.blocks) do if oven.filter(block, filterTerms) then oven.merge(cfg, block, filterField) end end cfg.terms = filterTerms return cfg end function oven.bakefile(cfg, filename) local fcfg = {} filename = { filename } for _, block in ipairs(cfg.solution.blocks) do if oven.filter(block, cfg.terms, filename) then oven.mergefile(fcfg, cfg, block) end end for _, block in ipairs(cfg.project.blocks) do if oven.filter(block, cfg.terms, filename) then oven.mergefile(fcfg, cfg, block) end end return fcfg end function oven.filter(block, anyOfThese, allOfThese) allOfThese = allOfThese or {} for _, term in ipairs(allOfThese) do local matched = false for _, keyword in ipairs(block.keywords) do if oven.testkeyword(keyword, { term }) then matched = true break end end if not matched then return false end end for _, keyword in ipairs(block.keywords) do if not oven.testkeyword(keyword, anyOfThese) and not oven.testkeyword(keyword, allOfThese) then return false end end return true end function oven.testkeyword(keyword, terms) if keyword:startswith("not ") then return not oven.testkeyword(keyword:sub(5), terms) end for _, pattern in ipairs(keyword:explode(" or ")) do for _, term in pairs(terms) do if term:match(pattern) == term then return true end end end return false end function oven.merge(cfg, block, filterField) if filterField then if block[filterField] then oven.mergefield(cfg, filterField, block[filterField]) end else for key, value in pairs(block) do if not nomerge[key] then oven.mergefield(cfg, key, value) end end end if block.removes then oven.remove(cfg, block.removes, filterField) end return cfg end function oven.mergefile(fcfg, cfg, block) for key, value in pairs(block) do if not fcfg[key] then oven.merge(fcfg, cfg, key) end oven.merge(fcfg, block, key) end end function oven.mergefield(cfg, name, value) local field = premake.fields[name] if not field then cfg[name] = value return end if field.kind == "keyvalue" or field.kind == "keypath" then cfg[name] = cfg[name] or {} for key, keyvalue in pairs(value) do cfg[name][key] = oven.mergetables(cfg[name][key] or {}, keyvalue) end elseif field.kind == "object" then cfg[name] = value elseif type(value) == "table" then cfg[name] = oven.mergetables(cfg[name] or {}, value) else cfg[name] = value end end function oven.mergetables(original, additions) for _, item in ipairs(additions) do if not original[item] then original[item] = item table.insert(original, item) end end return original end function oven.remove(cfg, removes, filterField) if filterField then oven.removefromfield(cfg[filterField], removes[filterField]) else for fieldname, values in pairs(removes) do oven.removefromfield(cfg[fieldname], values) end end end function oven.removefromfield(field, removes) if field and removes then for key, pattern in ipairs(removes) do pattern = path.wildcards(pattern):lower() local i = 1 while i <= #field do local value = field[i]:lower() if value:match(pattern) == value then field[field[i]] = nil table.remove(field, i) else i = i + 1 end end end end end premake5.project = { } local project = premake5.project function project.bakeconfigs(prj) local configs = {} configs["*"] = project.getconfig(prj) for cfg in project.eachconfig(prj) do local key = cfg.buildcfg .. (cfg.platform or "") configs[key] = cfg end prj.configs = configs end function project.eachconfig(prj, field, filename) local buildconfigs = prj.configurations or {} local platforms = prj.platforms or {} local i = 0 local j = #platforms return function () j = j + 1 if j > #platforms then i = i + 1 j = 1 end if i > #buildconfigs then return nil end return project.getconfig(prj, buildconfigs[i], platforms[j], field, filenamae) end end function project.findproject(name) for sln in premake.solution.each() do for _, prj in ipairs(sln.projects) do if (prj.name == name) then return prj end end end end function project.getconfig(prj, buildcfg, platform, field, filename) if not filename and prj.configs then local key = (buildcfg or "*") .. (platform or "") return prj.configs[key] end local system local architecture if platform then system = premake.checkvalue(platform, premake.fields.system.allowed) architecture = premake.checkvalue(platform, premake.fields.architecture.allowed) end local cfg = premake5.oven.bake(prj, { buildcfg, platform, _ACTION }, "system") system = cfg.system or system or premake.action.current().os or os.get() cfg = premake5.oven.bake(prj, { buildcfg, platform, _ACTION, system }, field) cfg.project = prj cfg.buildcfg = buildcfg cfg.platform = platform cfg.system = system cfg.architecture = cfg.architecture or architecture return cfg end function project.getdependencies(prj) local result = {} for cfg in project.eachconfig(prj, nil, "links") do for _, link in ipairs(cfg.links) do local dep = project.findproject(link) if dep and not table.contains(result, dep) then table.insert(result, dep) end end end return result end function project.getfileconfig(prj, filename) local fcfg = {} fcfg.abspath = filename fcfg.relpath = project.getrelative(prj, filename) local vpath = project.getvpath(prj, filename) if vpath ~= filename then fcfg.vpath = vpath else fcfg.vpath = fcfg.relpath end return fcfg end function project.getlocation(prj, relativeto) local location = prj.location or prj.solution.location or prj.basedir if relativeto then location = path.getrelative(relativeto, location) end return location end function project.getrelative(prj, filename) if type(filename) == "table" then local result = {} for i, name in ipairs(filename) do result[i] = project.getrelative(prj, name) end return result else if filename then return path.getrelative(project.getlocation(prj), filename) end end end function project.getsourcetree(prj) prj = prj.project or prj if prj.sourcetree then return prj.sourcetree end local files = {} for _, block in ipairs(prj.blocks) do for _, file in ipairs(block.files) do files[file] = file end end local tr = premake.tree.new(prj.name) for file in pairs(files) do local fcfg = project.getfileconfig(prj, file) local node = premake.tree.add(tr, fcfg.vpath, function(node) if fcfg.vpath == fcfg.relpath then node.realpath = node.path end end) for key, value in pairs(fcfg) do node[key] = value end end premake.tree.trimroot(tr) premake.tree.sort(tr) prj.sourcetree = tr return tr end function project.getvpath(prj, filename) local vpath = filename local relpath = path.getrelative(prj.basedir, filename) for replacement,patterns in pairs(prj.vpaths or {}) do for _,pattern in ipairs(patterns) do local i = relpath:find(path.wildcards(pattern)) if i == 1 then i = pattern:find("*", 1, true) or (pattern:len() + 1) local leaf = relpath:sub(i) if leaf:startswith("/") then leaf = leaf:sub(2) end local stem = "" if replacement:len() > 0 then stem, stars = replacement:gsub("%*", "") if stars == 0 then leaf = path.getname(leaf) end end vpath = path.join(stem, leaf) end end end return vpath end function project.hasconfig(prj, buildcfg, platform) if buildcfg and not prj.configurations[buildcfg] then return false end if platform and not prj.platforms[platform] then return false end return true end premake5.config = { } local project = premake5.project local config = premake5.config local oven = premake5.oven local function buildtargetinfo(cfg, kind, field) local basedir = project.getlocation(cfg.project) local directory = cfg[field.."dir"] or cfg.targetdir or basedir local basename = cfg[field.."name"] or cfg.targetname or cfg.project.name local bundlename = "" local bundlepath = "" local suffix = "" local sysinfo = premake.systems[cfg.system][kind:lower()] or {} local prefix = sysinfo.prefix or "" local extension = sysinfo.extension or "" if cfg.system == premake.MACOSX and kind == premake.WINDOWEDAPP then bundlename = basename .. ".app" bundlepath = path.join(bundlename, "Contents/MacOS") end prefix = cfg[field.."prefix"] or cfg.targetprefix or prefix suffix = cfg[field.."suffix"] or cfg.targetsuffix or suffix extension = cfg[field.."extension"] or cfg.targetextension or extension local info = {} info.directory = project.getrelative(cfg.project, directory) info.basename = prefix .. basename .. suffix info.name = info.basename .. extension info.extension = extension info.abspath = path.join(directory, info.name) info.fullpath = path.join(info.directory, info.name) info.bundlename = bundlename info.bundlepath = path.join(info.directory, bundlepath) info.prefix = prefix info.suffix = suffix return info end function config.findfile(cfg, ext) for _, fname in ipairs(cfg.files) do if fname:endswith(ext) then return project.getrelative(cfg.project, fname) end end end function config.getfileconfig(cfg, filename) local fcfg = cfg.files[filename] if not fcfg then return nil end if type(fcfg) ~= "table" then fcfg = oven.bakefile(cfg, filename) cfg.files[filename] = fcfg end return fcfg end function config.getlinkinfo(cfg) if cfg.linkinfo then return cfg.linkinfo end local kind = cfg.kind local field = "target" if premake.iscppproject(cfg.project) then if cfg.system == premake.WINDOWS and kind == premake.SHAREDLIB and not cfg.flags.NoImportLib then kind = premake.STATICLIB field = "implib" end end local info = buildtargetinfo(cfg, kind, field) cfg.linkinfo = info return info end function config.getlinks(cfg, kind, part) local result = iif (part == "directory" and kind == "all", cfg.libdirs, {}) local function canlink(source, target) if (target.kind ~= "SharedLib" and target.kind ~= "StaticLib") then return false end if premake.iscppproject(source.project) then return premake.iscppproject(target.project) elseif premake.isdotnetproject(source.project) then return premake.isdotnetproject(target.project) end end for _, link in ipairs(cfg.links) do local item local prj = premake.solution.findproject(cfg.solution, link) if prj and kind ~= "system" then local prjcfg = project.getconfig(prj, cfg.buildcfg, cfg.platform) if kind == "dependencies" or canlink(cfg, prjcfg) then if part == "object" then item = prjcfg elseif part == "basename" then item = config.getlinkinfo(prjcfg).basename else item = path.rebase(config.getlinkinfo(prjcfg).fullpath, project.getlocation(prjcfg.project), project.getlocation(cfg.project)) if item == "directory" then item = path.getdirectory(item) end end end elseif not prj and (kind == "system" or kind == "all") then if part == "directory" then local dir = path.getdirectory(link) if dir ~= "." then item = dir end elseif part == "fullpath" then item = link if cfg.system == premake.WINDOWS then if premake.iscppproject(cfg.project) then item = path.appendextension(item, ".lib") elseif premake.isdotnetproject(cfg.project) then item = path.appendextension(item, ".dll") end end if item:find("/", nil, true) then item = project.getrelative(cfg.project, item) end else item = link end end if item and not table.contains(result, item) then table.insert(result, item) end end return result end function config.gettargetinfo(cfg) if cfg.targetinfo then return cfg.targetinfo end local info = buildtargetinfo(cfg, cfg.kind, "target") cfg.targetinfo = info return info end function config.getuniqueobjdir(cfg) if cfg.uniqueobjdir then return cfg.uniqueobjdir end local function getobjdirs(cfg) local dirs = {} local dir = path.getabsolute(path.join(project.getlocation(cfg.project), cfg.objdir or "obj")) table.insert(dirs, dir) if cfg.platform then dir = path.join(dir, cfg.platform) table.insert(dirs, dir) end dir = path.join(dir, cfg.buildcfg) table.insert(dirs, dir) dir = path.join(dir, cfg.project.name) table.insert(dirs, dir) return dirs end local counts = {} for sln in premake.solution.each() do for prj in premake.solution.eachproject_ng(sln) do for testcfg in project.eachconfig(prj, "objdir") do local dirs = getobjdirs(testcfg) for _, dir in ipairs(dirs) do counts[dir] = (counts[dir] or 0) + 1 end end end end local dirs = getobjdirs(cfg) for _, dir in ipairs(dirs) do if counts[dir] == 1 then cfg.uniqueobjdir = project.getrelative(cfg.project, dir) return cfg.uniqueobjdir end end end premake.solution = { } local solution = premake.solution local oven = premake5.oven local project = premake5.project premake.solution.list = { } function solution.new(name) local sln = { } table.insert(premake.solution.list, sln) premake.solution.list[name] = sln setmetatable(sln, { __type="solution" }) sln.name = name sln.basedir = os.getcwd() sln.projects = { } sln.blocks = { } sln.configurations = { } return sln end function solution.bakeprojects(sln) for i = 1, #sln.projects do local prj = solution.getproject_ng(sln, i) sln.projects[i].rootcfg = prj project.bakeconfigs(prj) end end function solution.each() local i = 0 return function () i = i + 1 if i <= #premake.solution.list then return premake.solution.list[i] end end end function solution.eachconfig(sln) if not sln.configs then local configurations = {} local platforms = {} for prj in solution.eachproject_ng(sln) do if prj.configurations then for _, cfg in ipairs(prj.configurations) do if not configurations[cfg] then table.insert(configurations, cfg) configurations[cfg] = cfg end end end if prj.platforms then for _, plt in ipairs(prj.platforms) do if not platforms[plt] then table.insert(platforms, plt) platforms[plt] = plt end end end end sln.configs = {} for _, cfg in ipairs(configurations) do if #platforms > 0 then for _, plt in ipairs(platforms) do table.insert(sln.configs, { buildcfg=cfg, platform=plt }) end else table.insert(sln.configs, { buildcfg=cfg }) end end end local i = 0 return function() i = i + 1 if i > #sln.configs then return nil else return sln.configs[i] end end end function solution.eachproject(sln) local i = 0 return function () i = i + 1 if i <= #sln.projects then return premake.solution.getproject(sln, i) end end end function solution.eachproject_ng(sln) local i = 0 return function () i = i + 1 if i <= #sln.projects then return premake.solution.getproject_ng(sln, i) end end end function solution.findproject(sln, name) name = name:lower() for _, prj in ipairs(sln.projects) do if name == prj.name:lower() then return prj end end return nil end function solution.get(key) return premake.solution.list[key] end function solution.getlocation(sln) return sln.location or sln.basedir end function solution.getproject(sln, idx) local prj = sln.projects[idx] local cfg = premake.getconfig(prj) cfg.name = prj.name return cfg end function solution.getproject_ng(sln, idx) local prj = sln.projects[idx] if prj.rootcfg then return prj.rootcfg else local cfg = oven.merge({}, sln) cfg = oven.merge(cfg, prj) cfg = oven.merge(cfg, project.getconfig(prj)) return cfg end end premake.dotnet = { } premake.dotnet.namestyle = "windows" local flags = { FatalWarning = "/warnaserror", Optimize = "/optimize", OptimizeSize = "/optimize", OptimizeSpeed = "/optimize", Symbols = "/debug", Unsafe = "/unsafe" } function premake.dotnet.getbuildaction(fcfg) local ext = path.getextension(fcfg.name):lower() if fcfg.buildaction == "Compile" or ext == ".cs" then return "Compile" elseif fcfg.buildaction == "Embed" or ext == ".resx" then return "EmbeddedResource" elseif fcfg.buildaction == "Copy" or ext == ".asax" or ext == ".aspx" then return "Content" else return "None" end end function premake.dotnet.getcompilervar(cfg) if (_OPTIONS.dotnet == "msnet") then return "csc" elseif (_OPTIONS.dotnet == "mono") then if (cfg.framework <= "1.1") then return "mcs" elseif (cfg.framework >= "4.0") then return "dmcs" else return "gmcs" end else return "cscc" end end function premake.dotnet.getflags(cfg) local result = table.translate(cfg.flags, flags) return result end function premake.dotnet.getkind(cfg) if (cfg.kind == "ConsoleApp") then return "Exe" elseif (cfg.kind == "WindowedApp") then return "WinExe" elseif (cfg.kind == "SharedLib") then return "Library" end endpremake.tools.gcc = {} local gcc = premake.tools.gcc local project = premake5.project local config = premake5.config gcc.sysflags = { x32 = { cflags = "-m32", ldflags = { "-m32", "-L/usr/lib32" } }, x64 = { cflags = "-m64", ldflags = { "-m64", "-L/usr/lib64" } } } function gcc.getcppflags(cfg) local flags = { "-MMD" } if cfg.system ~= premake.HAIKU then table.insert(flags, "-MP") end return flags end gcc.cflags = { EnableSSE = "-msse", EnableSSE2 = "-msse2", ExtraWarnings = "-Wall", FatalWarnings = "-Werror", FloatFast = "-ffast-math", FloatStrict = "-ffloat-store", NoFramePointer = "-fomit-frame-pointer", Optimize = "-O2", OptimizeSize = "-Os", OptimizeSpeed = "-O3", Symbols = "-g", } function gcc.getcflags(cfg) local flags = table.translate(cfg.flags, gcc.cflags) local sysflags = gcc.sysflags[cfg.architecture] or {} flags = table.join(flags, sysflags.cflags) if cfg.system ~= premake.WINDOWS and cfg.kind == premake.SHAREDLIB then table.insert(flags, "-fPIC") end return flags end gcc.cxxflags = { NoExceptions = "-fno-exceptions", NoRTTI = "-fno-rtti", } function gcc.getcxxflags(cfg) local flags = table.translate(cfg.flags, gcc.cxxflags) return flags end function gcc.getldflags(cfg) local flags = {} if not cfg.flags.Symbols then end if cfg.kind == premake.SHAREDLIB then if cfg.system == premake.MACOSX then flags = table.join(flags, { "-dynamiclib", "-flat_namespace" }) else table.insert(flags, "-shared") end if cfg.system == "windows" and not cfg.flags.NoImportLib then table.insert(flags, '-Wl,--out-implib="' .. config.getlinkinfo(cfg).fullpath .. '"') end end if cfg.kind == premake.WINDOWEDAPP and cfg.system == premake.WINDOWS then table.insert(flags, "-mwindows") end local sysflags = gcc.sysflags[cfg.architecture] or {} flags = table.join(flags, sysflags.ldflags) return flags end function gcc.getlinks(cfg, systemonly) local result = {} local links if not systemonly then links = config.getlinks(cfg, "siblings", "object") for _, link in ipairs(links) do if link.kind == premake.STATICLIB then local linkinfo = config.getlinkinfo(link) table.insert(result, project.getrelative(cfg.project, linkinfo.abspath)) else table.insert(result, "-l" .. link.basename) end end end links = config.getlinks(cfg, "system", "basename") for _, link in ipairs(links) do if path.isframework(link) then table.insert(result, "-framework " .. path.getbasename(link)) elseif path.isobjectfile(link) then table.insert(result, link) else table.insert(result, "-l" .. link) end end return result end premake.gcc = { } premake.gcc.cc = "gcc" premake.gcc.cxx = "g++" premake.gcc.ar = "ar" local cflags = { EnableSSE = "-msse", EnableSSE2 = "-msse2", ExtraWarnings = "-Wall", FatalWarnings = "-Werror", FloatFast = "-ffast-math", FloatStrict = "-ffloat-store", NoFramePointer = "-fomit-frame-pointer", Optimize = "-O2", OptimizeSize = "-Os", OptimizeSpeed = "-O3", Symbols = "-g", } local cxxflags = { NoExceptions = "-fno-exceptions", NoRTTI = "-fno-rtti", } premake.gcc.platforms = { Native = { cppflags = "-MMD", }, x32 = { cppflags = "-MMD", flags = "-m32", ldflags = "-L/usr/lib32", }, x64 = { cppflags = "-MMD", flags = "-m64", ldflags = "-L/usr/lib64", }, Universal = { cppflags = "", flags = "-arch i386 -arch x86_64 -arch ppc -arch ppc64", }, Universal32 = { cppflags = "", flags = "-arch i386 -arch ppc", }, Universal64 = { cppflags = "", flags = "-arch x86_64 -arch ppc64", }, PS3 = { cc = "ppu-lv2-g++", cxx = "ppu-lv2-g++", ar = "ppu-lv2-ar", cppflags = "-MMD", }, WiiDev = { cppflags = "-MMD -MP -I$(LIBOGC_INC) $(MACHDEP)", ldflags= "-L$(LIBOGC_LIB) $(MACHDEP)", cfgsettings = [[ ifeq ($(strip $(DEVKITPPC)),) $(error "DEVKITPPC environment variable is not set")' endif include $(DEVKITPPC)/wii_rules']], }, } local platforms = premake.gcc.platforms function premake.gcc.getcppflags(cfg) local flags = { } table.insert(flags, platforms[cfg.platform].cppflags) if flags[1]:startswith("-MMD") and cfg.system ~= "haiku" then table.insert(flags, "-MP") end return flags end function premake.gcc.getcflags(cfg) local result = table.translate(cfg.flags, cflags) table.insert(result, platforms[cfg.platform].flags) if cfg.system ~= "windows" and cfg.kind == "SharedLib" then table.insert(result, "-fPIC") end return result end function premake.gcc.getcxxflags(cfg) local result = table.translate(cfg.flags, cxxflags) return result end function premake.gcc.getldflags(cfg) local result = { } -- OS X clang has another bug related to dead code elmination, so disable this hack if not cfg.flags.Symbols then end if cfg.kind == "SharedLib" then if cfg.system == "macosx" then result = table.join(result, { "-dynamiclib", "-flat_namespace" }) else table.insert(result, "-shared") end if cfg.system == "windows" and not cfg.flags.NoImportLib then table.insert(result, '-Wl,--out-implib="' .. cfg.linktarget.fullpath .. '"') end end if cfg.kind == "WindowedApp" and cfg.system == "windows" then table.insert(result, "-mwindows") end local platform = platforms[cfg.platform] table.insert(result, platform.flags) table.insert(result, platform.ldflags) return result end function premake.gcc.getlibdirflags(cfg) local result = { } for _, value in ipairs(premake.getlinks(cfg, "all", "directory")) do table.insert(result, '-L' .. _MAKE.esc(value)) end return result end function premake.gcc.getlinkflags(cfg) local result = { } for _, value in ipairs(premake.getlinks(cfg, "siblings", "object")) do if (value.kind == "StaticLib") then local pathstyle = premake.getpathstyle(value) local namestyle = premake.getnamestyle(value) local linktarget = premake.gettarget(value, "link", pathstyle, namestyle, cfg.system) local rebasedpath = path.rebase(linktarget.fullpath, value.location, cfg.location) table.insert(result, rebasedpath) else table.insert(result, '-l' .. _MAKE.esc(value.linktarget.basename)) end end for _, value in ipairs(premake.getlinks(cfg, "system", "basename")) do if path.getextension(value) == ".framework" then table.insert(result, '-framework ' .. _MAKE.esc(path.getbasename(value))) else table.insert(result, '-l' .. _MAKE.esc(value)) end end return result end function premake.gcc.getdefines(defines) local result = { } for _,def in ipairs(defines) do table.insert(result, '-D' .. def) end return result end function premake.gcc.getincludedirs(includedirs) local result = { } for _,dir in ipairs(includedirs) do table.insert(result, "-I" .. _MAKE.esc(dir)) end return result end function premake.gcc.getcfgsettings(cfg) return platforms[cfg.platform].cfgsettings end premake.msc = { } premake.msc.namestyle = "windows" premake.ow = { } premake.ow.namestyle = "windows" premake.ow.cc = "WCL386" premake.ow.cxx = "WCL386" premake.ow.ar = "ar" local cflags = { ExtraWarnings = "-wx", FatalWarning = "-we", FloatFast = "-omn", FloatStrict = "-op", Optimize = "-ox", OptimizeSize = "-os", OptimizeSpeed = "-ot", Symbols = "-d2", } local cxxflags = { NoExceptions = "-xd", NoRTTI = "-xr", } premake.ow.platforms = { Native = { flags = "" }, } function premake.ow.getcppflags(cfg) return {} end function premake.ow.getcflags(cfg) local result = table.translate(cfg.flags, cflags) if (cfg.flags.Symbols) then table.insert(result, "-hw") -- Watcom debug format for Watcom debugger end return result end function premake.ow.getcxxflags(cfg) local result = table.translate(cfg.flags, cxxflags) return result end function premake.ow.getldflags(cfg) local result = { } if (cfg.flags.Symbols) then table.insert(result, "op symf") end return result end function premake.ow.getlinkflags(cfg) local result = { } return result end function premake.ow.getdefines(defines) local result = { } for _,def in ipairs(defines) do table.insert(result, '-D' .. def) end return result end function premake.ow.getincludedirs(includedirs) local result = { } for _,dir in ipairs(includedirs) do table.insert(result, '-I "' .. dir .. '"') end return result end premake.tools.snc = {} local snc = premake.tools.snc local config = premake5.config snc.sysflags = { } function snc.getcppflags(cfg) return { "-MMD", "-MP" } end snc.cflags = { ExtraWarnings = "-Xdiag=2", FatalWarnings = "-Xquit=2", } function snc.getcflags(cfg) local flags = table.translate(cfg.flags, snc.cflags) return flags end snc.cxxflags = { NoExceptions = "-Xc-=exceptions", NoRTTI = "-Xc-=rtti", } function snc.getcxxflags(cfg) local flags = table.translate(cfg.flags, snc.cxxflags) if not cfg.flags.NoExceptions then table.insert(flags, "-Xc+=exceptions") end if not cfg.flags.NoRTTI then table.insert(flags, "-Xc+=rtti") end return flags end function snc.getldflags(cfg) local flags = { } if not cfg.flags.Symbols then table.insert(flags, "-s") end return flags end snc.getlinks = premake.tools.gcc.getlinks premake.snc = { } premake.snc.cc = "snc" premake.snc.cxx = "g++" premake.snc.ar = "ar" local cflags = { ExtraWarnings = "-Xdiag=2", FatalWarnings = "-Xquit=2", } local cxxflags = { NoExceptions = "", -- No exceptions is the default in the SNC compiler. NoRTTI = "-Xc-=rtti", } premake.snc.platforms = { PS3 = { cc = "ppu-lv2-g++", cxx = "ppu-lv2-g++", ar = "ppu-lv2-ar", cppflags = "-MMD -MP", } } local platforms = premake.snc.platforms function premake.snc.getcppflags(cfg) local result = { } table.insert(result, platforms[cfg.platform].cppflags) return result end function premake.snc.getcflags(cfg) local result = table.translate(cfg.flags, cflags) table.insert(result, platforms["PS3"].flags) if cfg.kind == "SharedLib" then table.insert(result, "-fPIC") end return result end function premake.snc.getcxxflags(cfg) local result = table.translate(cfg.flags, cxxflags) return result end function premake.snc.getldflags(cfg) local result = { } if not cfg.flags.Symbols then table.insert(result, "-s") end if cfg.kind == "SharedLib" then table.insert(result, "-shared") if not cfg.flags.NoImportLib then table.insert(result, '-Wl,--out-implib="' .. cfg.linktarget.fullpath .. '"') end end local platform = platforms["PS3"] table.insert(result, platform.flags) table.insert(result, platform.ldflags) return result end function premake.snc.getlibdirflags(cfg) local result = { } for _, value in ipairs(premake.getlinks(cfg, "all", "directory")) do table.insert(result, '-L' .. _MAKE.esc(value)) end return result end function premake.snc.getlinkflags(cfg) local result = { } for _, value in ipairs(premake.getlinks(cfg, "all", "basename")) do table.insert(result, '-l' .. _MAKE.esc(value)) end return result end function premake.snc.getdefines(defines) local result = { } for _,def in ipairs(defines) do table.insert(result, '-D' .. def) end return result end function premake.snc.getincludedirs(includedirs) local result = { } for _,dir in ipairs(includedirs) do table.insert(result, "-I" .. _MAKE.esc(dir)) end return result end premake.codeblocks = { } newaction { trigger = "codeblocks", shortname = "Code::Blocks", description = "Generate Code::Blocks project files", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, valid_languages = { "C", "C++" }, valid_tools = { cc = { "gcc", "ow" }, }, onsolution = function(sln) premake.generate(sln, "%%.workspace", premake.codeblocks.workspace) end, onproject = function(prj) premake.generate(prj, "%%.cbp", premake.codeblocks.cbp) end, oncleansolution = function(sln) premake.clean.file(sln, "%%.workspace") end, oncleanproject = function(prj) premake.clean.file(prj, "%%.cbp") premake.clean.file(prj, "%%.depend") premake.clean.file(prj, "%%.layout") end } function premake.codeblocks.workspace(sln) _p('') _p('') _p(1,'', sln.name) for prj in premake.solution.eachproject(sln) do local fname = path.join(path.getrelative(sln.location, prj.location), prj.name) local active = iif(prj.project == sln.projects[1], ' active="1"', '') _p(2,'', fname, active) for _,dep in ipairs(premake.getdependencies(prj)) do _p(3,'', path.join(path.getrelative(sln.location, dep.location), dep.name)) end _p(2,'') end _p(1,'') _p('') end local codeblocks = premake.codeblocks function codeblocks.files(prj) local pchheader if (prj.pchheader) then pchheader = path.getrelative(prj.location, prj.pchheader) end for fcfg in premake.project.eachfile(prj) do _p(2,'', premake.esc(fcfg.name)) if fcfg.name ~= fcfg.vpath then _p(3,'') end end function premake.codeblocks.debugenvs(cfg) if premake.gettool(cfg) == premake.gcc then _p(3,'') _p(4,'', premake.esc(cfg.longname)) local args = '' local sz = #cfg.debugenvs for idx, v in ipairs(cfg.debugenvs) do args = args .. 'set env ' .. v if sz ~= idx then args = args .. ' ' end end _p(5,'',args) _p(4,'') _p(3,'') else error('Sorry at this moment there is no support for debug environment variables with this debugger and codeblocks') end end function premake.codeblocks.cbp(prj) local cc = premake.gettool(prj) _p('') _p('') _p(1,'') _p(1,'') _p(2,'') _p('') _p('') end premake.codelite = { } newaction { trigger = "codelite", shortname = "CodeLite", description = "Generate CodeLite project files", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, valid_languages = { "C", "C++" }, valid_tools = { cc = { "gcc" }, }, onsolution = function(sln) premake.generate(sln, "%%.workspace", premake.codelite.workspace) end, onproject = function(prj) premake.generate(prj, "%%.project", premake.codelite.project) end, oncleansolution = function(sln) premake.clean.file(sln, "%%.workspace") premake.clean.file(sln, "%%_wsp.mk") premake.clean.file(sln, "%%.tags") end, oncleanproject = function(prj) premake.clean.file(prj, "%%.project") premake.clean.file(prj, "%%.mk") premake.clean.file(prj, "%%.list") premake.clean.file(prj, "%%.out") end } function premake.codelite.workspace(sln) _p('') _p('', premake.esc(sln.name), premake.esc(sln.name)) for i,prj in ipairs(sln.projects) do local name = premake.esc(prj.name) local fname = path.join(path.getrelative(sln.location, prj.location), prj.name) local active = iif(i==1, "Yes", "No") _p(' ', name, fname, active) end local platforms = premake.filterplatforms(sln, premake[_OPTIONS.cc].platforms, "Native") for i = #platforms, 1, -1 do if premake.platforms[platforms[i]].iscrosscompiler then table.remove(platforms, i) end end _p(' ') for _, platform in ipairs(platforms) do for _, cfgname in ipairs(sln.configurations) do local name = premake.getconfigname(cfgname, platform) _p(' ', name) for _,prj in ipairs(sln.projects) do _p(' ', prj.name, name) end _p(' ') end end _p(' ') _p('') end local codelite = premake.codelite local tree = premake.tree function codelite.files(prj) local tr = premake.project.buildsourcetree(prj) tree.traverse(tr, { onbranchenter = function(node, depth) _p(depth, '', node.name) end, onbranchexit = function(node, depth) _p(depth, '') end, onleaf = function(node, depth) _p(depth, '', node.cfg.name) end, }, false, 1) end function premake.codelite.project(prj) io.indent = " " _p('') _p('', premake.esc(prj.name)) codelite.files(prj) local types = { ConsoleApp = "Executable", WindowedApp = "Executable", StaticLib = "Static Library", SharedLib = "Dynamic Library", } _p(' ', types[prj.kind]) local platforms = premake.filterplatforms(prj.solution, premake[_OPTIONS.cc].platforms, "Native") for i = #platforms, 1, -1 do if premake.platforms[platforms[i]].iscrosscompiler then table.remove(platforms, i) end end for _, platform in ipairs(platforms) do for cfg in premake.eachconfig(prj, platform) do local name = premake.esc(cfg.longname) local compiler = iif(cfg.language == "C", "gcc", "g++") _p(' ', name, compiler, types[cfg.kind]) local fname = premake.esc(cfg.buildtarget.fullpath) local objdir = premake.esc(cfg.objectsdir) local runcmd = cfg.buildtarget.name local rundir = cfg.debugdir or cfg.buildtarget.directory local runargs = table.concat(cfg.debugargs, " ") local pause = iif(cfg.kind == "WindowedApp", "no", "yes") _p(' ', fname, objdir, runcmd, runargs, rundir, pause) local flags = premake.esc(table.join(premake.gcc.getcflags(cfg), premake.gcc.getcxxflags(cfg), cfg.buildoptions)) _p(' ', table.concat(flags, ";")) for _,v in ipairs(cfg.includedirs) do _p(' ', premake.esc(v)) end for _,v in ipairs(cfg.defines) do _p(' ', premake.esc(v)) end _p(' ') flags = premake.esc(table.join(premake.gcc.getldflags(cfg), cfg.linkoptions)) _p(' ', table.concat(flags, ";")) for _,v in ipairs(premake.getlinks(cfg, "all", "directory")) do _p(' ', premake.esc(v)) end for _,v in ipairs(premake.getlinks(cfg, "all", "basename")) do _p(' ', premake.esc(v)) end _p(' ') if premake.findfile(cfg, ".rc") then local defines = table.implode(table.join(cfg.defines, cfg.resdefines), "-D", ";", "") local options = table.concat(cfg.resoptions, ";") _p(' ', defines, options) for _,v in ipairs(table.join(cfg.includedirs, cfg.resincludedirs)) do _p(' ', premake.esc(v)) end _p(' ') else _p(' ') end if #cfg.prebuildcommands > 0 then _p(' ') for _,v in ipairs(cfg.prebuildcommands) do _p(' %s', premake.esc(v)) end _p(' ') end if #cfg.postbuildcommands > 0 then _p(' ') for _,v in ipairs(cfg.postbuildcommands) do _p(' %s', premake.esc(v)) end _p(' ') end _p(' ') _p(' ') _p(' ') _p(' ') _p(' ') _p(' None') _p(' ') _p(' ') _p(' ') _p(' ') _p(' ') _p(' ') _p(' ') end end _p(' ') for _, platform in ipairs(platforms) do for cfg in premake.eachconfig(prj, platform) do _p(' ', cfg.longname) for _,dep in ipairs(premake.getdependencies(prj)) do _p(' ', dep.name) end _p(' ') end end _p('') end _MAKE = { } premake.make = { } local make = premake.make function _MAKE.esc(value) local result if (type(value) == "table") then result = { } for _,v in ipairs(value) do table.insert(result, _MAKE.esc(v)) end return result else result = value:gsub("\\", "\\\\") result = result:gsub(" ", "\\ ") result = result:gsub("%(", "\\%(") result = result:gsub("%)", "\\%)") result = result:gsub("$\\%((.-)\\%)", "$%(%1%)") return result end end function premake.make_copyrule(source, target) _p('%s: %s', target, source) _p('\t@echo Copying $(notdir %s)', target) _p('ifeq (posix,$(SHELLTYPE))') _p('\t$(SILENT) cp -fR %s %s', source, target) _p('else') _p('\t$(SILENT) copy /Y $(subst /,\\\\,%s) $(subst /,\\\\,%s)', source, target) _p('endif') end function premake.make_mkdirrule(var) _p('\t@echo Creating %s', var) _p('ifeq (posix,$(SHELLTYPE))') _p('\t$(SILENT) mkdir -p %s', var) _p('else') _p('\t$(SILENT) mkdir $(subst /,\\\\,%s)', var) _p('endif') _p('') end function _MAKE.getmakefilename(this, searchprjs) local count = 0 for sln in premake.solution.each() do if (sln.location == this.location) then count = count + 1 end if (searchprjs) then for _,prj in ipairs(sln.projects) do if (prj.location == this.location) then count = count + 1 end end end end if (count == 1) then return "Makefile" else return this.name .. ".make" end end function _MAKE.getnames(tbl) local result = table.extract(tbl, "name") for k,v in pairs(result) do result[k] = _MAKE.esc(v) end return result end function make.settings(cfg, cc) if #cfg.makesettings > 0 then for _, value in ipairs(cfg.makesettings) do _p(value) end end local toolsettings = cc.platforms[cfg.platform].cfgsettings if toolsettings then _p(toolsettings) end end newaction { trigger = "gmake", shortname = "GNU Make", description = "Generate GNU makefiles for POSIX, MinGW, and Cygwin", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, valid_languages = { "C", "C++", "C#" }, valid_tools = { cc = { "gcc" }, dotnet = { "mono", "msnet", "pnet" }, }, onsolution = function(sln) premake.generate(sln, _MAKE.getmakefilename(sln, false), premake.make_solution) end, onproject = function(prj) local makefile = _MAKE.getmakefilename(prj, true) if premake.isdotnetproject(prj) then premake.generate(prj, makefile, premake.make_csharp) else premake.generate(prj, makefile, premake.make_cpp) end end, oncleansolution = function(sln) premake.clean.file(sln, _MAKE.getmakefilename(sln, false)) end, oncleanproject = function(prj) premake.clean.file(prj, _MAKE.getmakefilename(prj, true)) end } function premake.make_solution(sln) local cc = premake[_OPTIONS.cc] local platforms = premake.filterplatforms(sln, cc.platforms, "Native") _p('# %s solution makefile autogenerated by Premake', premake.action.current().shortname) _p('# Type "make help" for usage help') _p('') _p('ifndef config') _p(' config=%s', _MAKE.esc(premake.getconfigname(sln.configurations[1], platforms[1], true))) _p('endif') _p('export config') _p('') _p('PROJECTS := %s', table.concat(_MAKE.esc(table.extract(sln.projects, "name")), " ")) _p('') _p('.PHONY: all clean help $(PROJECTS)') _p('') _p('all: $(PROJECTS)') _p('') for _, prj in ipairs(sln.projects) do _p('%s: %s', _MAKE.esc(prj.name), table.concat(_MAKE.esc(table.extract(premake.getdependencies(prj), "name")), " ")) _p('\t@echo "==== Building %s ($(config)) ===="', prj.name) _p('\t@${MAKE} --no-print-directory -C %s -f %s', _MAKE.esc(path.getrelative(sln.location, prj.location)), _MAKE.esc(_MAKE.getmakefilename(prj, true))) _p('') end _p('clean:') for _ ,prj in ipairs(sln.projects) do _p('\t@${MAKE} --no-print-directory -C %s -f %s clean', _MAKE.esc(path.getrelative(sln.location, prj.location)), _MAKE.esc(_MAKE.getmakefilename(prj, true))) end _p('') _p('help:') _p(1,'@echo "Usage: make [config=name] [target]"') _p(1,'@echo ""') _p(1,'@echo "CONFIGURATIONS:"') local cfgpairs = { } for _, platform in ipairs(platforms) do for _, cfgname in ipairs(sln.configurations) do _p(1,'@echo " %s"', premake.getconfigname(cfgname, platform, true)) end end _p(1,'@echo ""') _p(1,'@echo "TARGETS:"') _p(1,'@echo " all (default)"') _p(1,'@echo " clean"') for _, prj in ipairs(sln.projects) do _p(1,'@echo " %s"', prj.name) end _p(1,'@echo ""') _p(1,'@echo "For more information, see http://industriousone.com/premake/quick-start"') end premake.make.cpp = { } local cpp = premake.make.cpp local make = premake.make function premake.make_cpp(prj) local cc = premake.gettool(prj) local platforms = premake.filterplatforms(prj.solution, cc.platforms, "Native") premake.gmake_cpp_header(prj, cc, platforms) for _, platform in ipairs(platforms) do for cfg in premake.eachconfig(prj, platform) do premake.gmake_cpp_config(cfg, cc) end end _p('OBJECTS := \\') for _, file in ipairs(prj.files) do if path.iscppfile(file) then _p('\t$(OBJDIR)/%s.o \\', _MAKE.esc(path.getbasename(file))) end end _p('') _p('RESOURCES := \\') for _, file in ipairs(prj.files) do if path.isresourcefile(file) then _p('\t$(OBJDIR)/%s.res \\', _MAKE.esc(path.getbasename(file))) end end _p('') _p('SHELLTYPE := msdos') _p('ifeq (,$(ComSpec)$(COMSPEC))') _p(' SHELLTYPE := posix') _p('endif') _p('ifeq (/bin,$(findstring /bin,$(SHELL)))') _p(' SHELLTYPE := posix') _p('endif') _p('') _p('.PHONY: clean prebuild prelink') _p('') if os.is("MacOSX") and prj.kind == "WindowedApp" then _p('all: $(TARGETDIR) $(OBJDIR) prebuild prelink $(TARGET) $(dir $(TARGETDIR))PkgInfo $(dir $(TARGETDIR))Info.plist') else _p('all: $(TARGETDIR) $(OBJDIR) prebuild prelink $(TARGET)') end _p('\t@:') _p('') _p('$(TARGET): $(GCH) $(OBJECTS) $(LDDEPS) $(RESOURCES)') _p('\t@echo Linking %s', prj.name) _p('\t$(SILENT) $(LINKCMD)') _p('\t$(POSTBUILDCMDS)') _p('') _p('$(TARGETDIR):') premake.make_mkdirrule("$(TARGETDIR)") _p('$(OBJDIR):') premake.make_mkdirrule("$(OBJDIR)") if os.is("MacOSX") and prj.kind == "WindowedApp" then _p('$(dir $(TARGETDIR))PkgInfo:') _p('$(dir $(TARGETDIR))Info.plist:') _p('') end _p('clean:') _p('\t@echo Cleaning %s', prj.name) _p('ifeq (posix,$(SHELLTYPE))') _p('\t$(SILENT) rm -f $(TARGET)') _p('\t$(SILENT) rm -rf $(OBJDIR)') _p('else') _p('\t$(SILENT) if exist $(subst /,\\\\,$(TARGET)) del $(subst /,\\\\,$(TARGET))') _p('\t$(SILENT) if exist $(subst /,\\\\,$(OBJDIR)) rmdir /s /q $(subst /,\\\\,$(OBJDIR))') _p('endif') _p('') _p('prebuild:') _p('\t$(PREBUILDCMDS)') _p('') _p('prelink:') _p('\t$(PRELINKCMDS)') _p('') cpp.pchrules(prj) for _, file in ipairs(prj.files) do if path.iscppfile(file) then _p('$(OBJDIR)/%s.o: %s', _MAKE.esc(path.getbasename(file)), _MAKE.esc(file)) _p('\t@echo $(notdir $<)') cpp.buildcommand(path.iscfile(file)) elseif (path.getextension(file) == ".rc") then _p('$(OBJDIR)/%s.res: %s', _MAKE.esc(path.getbasename(file)), _MAKE.esc(file)) _p('\t@echo $(notdir $<)') _p('\t$(SILENT) $(RESCOMP) $< -O coff -o "$@" $(RESFLAGS)') end end _p('') _p('-include $(OBJECTS:%%.o=%%.d)') end function premake.gmake_cpp_header(prj, cc, platforms) _p('# %s project makefile autogenerated by Premake', premake.action.current().shortname) _p('ifndef config') _p(' config=%s', _MAKE.esc(premake.getconfigname(prj.solution.configurations[1], platforms[1], true))) _p('endif') _p('') _p('ifndef verbose') _p(' SILENT = @') _p('endif') _p('') _p('ifndef CC') _p(' CC = %s', cc.cc) _p('endif') _p('') _p('ifndef CXX') _p(' CXX = %s', cc.cxx) _p('endif') _p('') _p('ifndef AR') _p(' AR = %s', cc.ar) _p('endif') _p('') _p('ifndef RESCOMP') _p(' ifdef WINDRES') _p(' RESCOMP = $(WINDRES)') _p(' else') _p(' RESCOMP = windres') _p(' endif') _p('endif') _p('') end function premake.gmake_cpp_config(cfg, cc) _p('ifeq ($(config),%s)', _MAKE.esc(cfg.shortname)) cpp.platformtools(cfg, cc) _p(' OBJDIR = %s', _MAKE.esc(cfg.objectsdir)) _p(' TARGETDIR = %s', _MAKE.esc(cfg.buildtarget.directory)) _p(' TARGET = $(TARGETDIR)/%s', _MAKE.esc(cfg.buildtarget.name)) _p(' DEFINES += %s', table.concat(cc.getdefines(cfg.defines), " ")) _p(' INCLUDES += %s', table.concat(cc.getincludedirs(cfg.includedirs), " ")) cpp.flags(cfg, cc) cpp.pchconfig(cfg) _p(' LIBS += %s', table.concat(cc.getlinkflags(cfg), " ")) _p(' LDDEPS += %s', table.concat(_MAKE.esc(premake.getlinks(cfg, "siblings", "fullpath")), " ")) if cfg.kind == "StaticLib" then if cfg.platform:startswith("Universal") then _p(' LINKCMD = libtool -o $(TARGET) $(OBJECTS)') else _p(' LINKCMD = $(AR) -rcs $(TARGET) $(OBJECTS)') end else _p(' LINKCMD = $(%s) -o $(TARGET) $(OBJECTS) $(RESOURCES) $(ARCH) $(LIBS) $(LDFLAGS)', iif(cfg.language == "C", "CC", "CXX")) end _p(' define PREBUILDCMDS') if #cfg.prebuildcommands > 0 then _p('\t@echo Running pre-build commands') _p('\t%s', table.implode(cfg.prebuildcommands, "", "", "\n\t")) end _p(' endef') _p(' define PRELINKCMDS') if #cfg.prelinkcommands > 0 then _p('\t@echo Running pre-link commands') _p('\t%s', table.implode(cfg.prelinkcommands, "", "", "\n\t")) end _p(' endef') _p(' define POSTBUILDCMDS') if #cfg.postbuildcommands > 0 then _p('\t@echo Running post-build commands') _p('\t%s', table.implode(cfg.postbuildcommands, "", "", "\n\t")) end _p(' endef') make.settings(cfg, cc) _p('endif') _p('') end function cpp.platformtools(cfg, cc) local platform = cc.platforms[cfg.platform] if platform.cc then _p(' CC = %s', platform.cc) end if platform.cxx then _p(' CXX = %s', platform.cxx) end if platform.ar then _p(' AR = %s', platform.ar) end end function cpp.flags(cfg, cc) _p(' CPPFLAGS += %s $(DEFINES) $(INCLUDES)', table.concat(cc.getcppflags(cfg), " ")) _p(' CFLAGS += $(CPPFLAGS) $(ARCH) %s', table.concat(table.join(cc.getcflags(cfg), cfg.buildoptions), " ")) _p(' CXXFLAGS += $(CFLAGS) %s', table.concat(cc.getcxxflags(cfg), " ")) _p(' LDFLAGS += %s', table.concat(table.join(cc.getlibdirflags(cfg), cc.getldflags(cfg), cfg.linkoptions), " ")) _p(' RESFLAGS += $(DEFINES) $(INCLUDES) %s', table.concat(table.join(cc.getdefines(cfg.resdefines), cc.getincludedirs(cfg.resincludedirs), cfg.resoptions), " ")) end function cpp.pchconfig(cfg) local pchheader = cfg.pchheader for _, incdir in ipairs(cfg.includedirs) do local testname = path.join(incdir, cfg.pchheader) if os.isfile(testname) then pchheader = testname break end end if not cfg.flags.NoPCH and cfg.pchheader then _p(' PCH = %s', _MAKE.esc(path.getrelative(cfg.location, cfg.pchheader))) _p(' GCH = $(OBJDIR)/%s.gch', _MAKE.esc(path.getname(cfg.pchheader))) _p(' CPPFLAGS += -I$(OBJDIR) -include $(OBJDIR)/%s', _MAKE.esc(path.getname(cfg.pchheader))) end end function cpp.pchrules(prj) _p('ifneq (,$(PCH))') _p('$(GCH): $(PCH)') _p('\t@echo $(notdir $<)') _p('ifeq (posix,$(SHELLTYPE))') _p('\t-$(SILENT) cp $< $(OBJDIR)') _p('else') _p('\t$(SILENT) xcopy /D /Y /Q "$(subst /,\\,$<)" "$(subst /,\\,$(OBJDIR))" 1>nul') _p('endif') cpp.buildcommand(prj.language == "C") _p('endif') _p('') end function cpp.buildcommand(iscfile) local flags = iif(iscfile, '$(CC) $(CFLAGS)', '$(CXX) $(CXXFLAGS)') _p('\t$(SILENT) %s -o "$@" -MF $(@:%%.o=%%.d) -c "$<"', flags) end local function getresourcefilename(cfg, fname) if path.getextension(fname) == ".resx" then local name = cfg.buildtarget.basename .. "." local dir = path.getdirectory(fname) if dir ~= "." then name = name .. path.translate(dir, ".") .. "." end return "$(OBJDIR)/" .. _MAKE.esc(name .. path.getbasename(fname)) .. ".resources" else return fname end end function premake.make_csharp(prj) local csc = premake.dotnet local cfglibs = { } local cfgpairs = { } local anycfg for cfg in premake.eachconfig(prj) do anycfg = cfg cfglibs[cfg] = premake.getlinks(cfg, "siblings", "fullpath") cfgpairs[cfg] = { } for _, fname in ipairs(cfglibs[cfg]) do if path.getdirectory(fname) ~= cfg.buildtarget.directory then cfgpairs[cfg]["$(TARGETDIR)/" .. _MAKE.esc(path.getname(fname))] = _MAKE.esc(fname) end end end local sources = {} local embedded = { } local copypairs = { } for fcfg in premake.project.eachfile(prj) do local action = csc.getbuildaction(fcfg) if action == "Compile" then table.insert(sources, fcfg.name) elseif action == "EmbeddedResource" then table.insert(embedded, fcfg.name) elseif action == "Content" then copypairs["$(TARGETDIR)/" .. _MAKE.esc(path.getname(fcfg.name))] = _MAKE.esc(fcfg.name) elseif path.getname(fcfg.name):lower() == "app.config" then copypairs["$(TARGET).config"] = _MAKE.esc(fcfg.name) end end local paths = table.translate(prj.libdirs, function(v) return path.join(prj.basedir, v) end) paths = table.join({prj.basedir}, paths) for _, libname in ipairs(premake.getlinks(prj, "system", "fullpath")) do local libdir = os.pathsearch(libname..".dll", unpack(paths)) if (libdir) then local target = "$(TARGETDIR)/" .. _MAKE.esc(path.getname(libname)) local source = path.getrelative(prj.basedir, path.join(libdir, libname))..".dll" copypairs[target] = _MAKE.esc(source) end end _p('# %s project makefile autogenerated by Premake', premake.action.current().shortname) _p('') _p('ifndef config') _p(' config=%s', _MAKE.esc(prj.configurations[1]:lower())) _p('endif') _p('') _p('ifndef verbose') _p(' SILENT = @') _p('endif') _p('') _p('ifndef CSC') _p(' CSC=%s', csc.getcompilervar(prj)) _p('endif') _p('') _p('ifndef RESGEN') _p(' RESGEN=resgen') _p('endif') _p('') local platforms = premake.filterplatforms(prj.solution, premake[_OPTIONS.cc].platforms) table.insert(platforms, 1, "") for cfg in premake.eachconfig(prj) do premake.gmake_cs_config(cfg, csc, cfglibs) end _p('# To maintain compatibility with VS.NET, these values must be set at the project level') _p('TARGET := $(TARGETDIR)/%s', _MAKE.esc(prj.buildtarget.name)) _p('FLAGS += /t:%s %s', csc.getkind(prj):lower(), table.implode(_MAKE.esc(prj.libdirs), "/lib:", "", " ")) _p('REFERENCES += %s', table.implode(_MAKE.esc(premake.getlinks(prj, "system", "basename")), "/r:", ".dll", " ")) _p('') _p('SOURCES := \\') for _, fname in ipairs(sources) do _p('\t%s \\', _MAKE.esc(path.translate(fname))) end _p('') _p('EMBEDFILES := \\') for _, fname in ipairs(embedded) do _p('\t%s \\', getresourcefilename(prj, fname)) end _p('') _p('COPYFILES += \\') for target, source in pairs(cfgpairs[anycfg]) do _p('\t%s \\', target) end for target, source in pairs(copypairs) do _p('\t%s \\', target) end _p('') _p('SHELLTYPE := msdos') _p('ifeq (,$(ComSpec)$(COMSPEC))') _p(' SHELLTYPE := posix') _p('endif') _p('ifeq (/bin,$(findstring /bin,$(SHELL)))') _p(' SHELLTYPE := posix') _p('endif') _p('') _p('.PHONY: clean prebuild prelink') _p('') _p('all: $(TARGETDIR) $(OBJDIR) prebuild $(EMBEDFILES) $(COPYFILES) prelink $(TARGET)') _p('') _p('$(TARGET): $(SOURCES) $(EMBEDFILES) $(DEPENDS)') _p('\t$(SILENT) $(CSC) /nologo /out:$@ $(FLAGS) $(REFERENCES) $(SOURCES) $(patsubst %%,/resource:%%,$(EMBEDFILES))') _p('\t$(POSTBUILDCMDS)') _p('') _p('$(TARGETDIR):') premake.make_mkdirrule("$(TARGETDIR)") _p('$(OBJDIR):') premake.make_mkdirrule("$(OBJDIR)") _p('clean:') _p('\t@echo Cleaning %s', prj.name) _p('ifeq (posix,$(SHELLTYPE))') _p('\t$(SILENT) rm -f $(TARGETDIR)/%s.* $(COPYFILES)', prj.buildtarget.basename) _p('\t$(SILENT) rm -rf $(OBJDIR)') _p('else') _p('\t$(SILENT) if exist $(subst /,\\\\,$(TARGETDIR)/%s.*) del $(subst /,\\\\,$(TARGETDIR)/%s.*)', prj.buildtarget.basename, prj.buildtarget.basename) for target, source in pairs(cfgpairs[anycfg]) do _p('\t$(SILENT) if exist $(subst /,\\\\,%s) del $(subst /,\\\\,%s)', target, target) end for target, source in pairs(copypairs) do _p('\t$(SILENT) if exist $(subst /,\\\\,%s) del $(subst /,\\\\,%s)', target, target) end _p('\t$(SILENT) if exist $(subst /,\\\\,$(OBJDIR)) rmdir /s /q $(subst /,\\\\,$(OBJDIR))') _p('endif') _p('') _p('prebuild:') _p('\t$(PREBUILDCMDS)') _p('') _p('prelink:') _p('\t$(PRELINKCMDS)') _p('') _p('# Per-configuration copied file rules') for cfg in premake.eachconfig(prj) do _p('ifneq (,$(findstring %s,$(config)))', _MAKE.esc(cfg.name:lower())) for target, source in pairs(cfgpairs[cfg]) do premake.make_copyrule(source, target) end _p('endif') _p('') end _p('# Copied file rules') for target, source in pairs(copypairs) do premake.make_copyrule(source, target) end _p('# Embedded file rules') for _, fname in ipairs(embedded) do if path.getextension(fname) == ".resx" then _p('%s: %s', getresourcefilename(prj, fname), _MAKE.esc(fname)) _p('\t$(SILENT) $(RESGEN) $^ $@') end _p('') end end function premake.gmake_cs_config(cfg, csc, cfglibs) _p('ifneq (,$(findstring %s,$(config)))', _MAKE.esc(cfg.name:lower())) _p(' TARGETDIR := %s', _MAKE.esc(cfg.buildtarget.directory)) _p(' OBJDIR := %s', _MAKE.esc(cfg.objectsdir)) _p(' DEPENDS := %s', table.concat(_MAKE.esc(premake.getlinks(cfg, "dependencies", "fullpath")), " ")) _p(' REFERENCES := %s', table.implode(_MAKE.esc(cfglibs[cfg]), "/r:", "", " ")) _p(' FLAGS += %s %s', table.implode(cfg.defines, "/d:", "", " "), table.concat(table.join(csc.getflags(cfg), cfg.buildoptions), " ")) _p(' define PREBUILDCMDS') if #cfg.prebuildcommands > 0 then _p('\t@echo Running pre-build commands') _p('\t%s', table.implode(cfg.prebuildcommands, "", "", "\n\t")) end _p(' endef') _p(' define PRELINKCMDS') if #cfg.prelinkcommands > 0 then _p('\t@echo Running pre-link commands') _p('\t%s', table.implode(cfg.prelinkcommands, "", "", "\n\t")) end _p(' endef') _p(' define POSTBUILDCMDS') if #cfg.postbuildcommands > 0 then _p('\t@echo Running post-build commands') _p('\t%s', table.implode(cfg.postbuildcommands, "", "", "\n\t")) end _p(' endef') _p('endif') _p('') end premake.vstudio = { } local vstudio = premake.vstudio local project = premake5.project newaction { trigger = "vs2008ng", shortname = "Visual Studio 2008 Next-gen", description = "Experimental Microsoft Visual Studio 2008 project files", os = "windows", isnextgen = true, valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, valid_languages = { "C", "C++", "C#" }, valid_tools = { cc = { "msc" }, dotnet = { "msnet" }, }, onsolution = function(sln) premake.generate(sln, "%%.sln", vstudio.sln2005.generate_ng) end, onproject = function(prj) if premake.isdotnetproject(prj) then premake.generate(prj, "%%.csproj", vstudio.cs2005.generate_ng) premake.generate(prj, "%%.csproj.user", vstudio.cs2005.generate_user_ng) else premake.generate(prj, "%%.vcproj", vstudio.vc200x.generate_ng) premake.generate(prj, "%%.vcproj.user", vstudio.vc200x.generate_user_ng) end end, oncleansolution = vstudio.cleansolution, oncleanproject = vstudio.cleanproject, oncleantarget = vstudio.cleantarget } newaction { trigger = "vs2010ng", shortname = "Visual Studio 2010 Next-gen", description = "Experimental Microsoft Visual Studio 2010 project files", os = "windows", isnextgen = true, valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, valid_languages = { "C", "C++", "C#" }, valid_tools = { cc = { "msc" }, dotnet = { "msnet" }, }, onsolution = function(sln) premake.generate(sln, "%%.sln", vstudio.sln2005.generate_ng) end, onproject = function(prj) if premake.isdotnetproject(prj) then premake.generate(prj, "%%.csproj", vstudio.cs2005.generate_ng) premake.generate(prj, "%%.csproj.user", vstudio.cs2005.generate_user_ng) else premake.generate(prj, "%%.vcxproj", vstudio.vc2010.generate_ng) premake.generate(prj, "%%.vcxproj.user", vstudio.vc2010.generate_user_ng) premake.generate(prj, "%%.vcxproj.filters", vstudio.vc2010.generate_filters_ng) end end, oncleansolution = vstudio.cleansolution, oncleanproject = vstudio.cleanproject, oncleantarget = vstudio.cleantarget } vstudio.vs200x_architectures = { x64 = "x64", xbox360 = "Xbox 360", } vstudio.vs2010_architectures = { } function vstudio.architecture(cfg) local arch if _ACTION >= "vs2010" then arch = vstudio.vs2010_architectures[cfg.architecture] or vstudio.vs2010_architectures[cfg.system] end arch = arch or vstudio.vs200x_architectures[cfg.architecture] or vstudio.vs200x_architectures[cfg.system] or "Win32" return arch end function vstudio.configname(cfg) local platform = vstudio.projectplatform(cfg) local architecture = vstudio.architecture(cfg) return platform .. "|" .. architecture end function vstudio.projectfile_ng(prj) local extension if prj.language == "C#" then extension = ".csproj" else extension = iif(_ACTION > "vs2008", ".vcxproj", ".vcproj") end local location = project.getlocation(prj) local filename = path.join(location, prj.name) .. extension return filename end vstudio.platforms = { any = "Any CPU", mixed = "Mixed Platforms", Native = "Win32", x86 = "x86", x32 = "Win32", x64 = "x64", PS3 = "PS3", Xbox360 = "Xbox 360", } function vstudio.arch(prj) if (prj.language == "C#") then if (_ACTION < "vs2005") then return ".NET" else return "Any CPU" end else return "Win32" end end function vstudio.buildconfigs(sln) local cfgs = { } local platforms = premake.filterplatforms(sln, vstudio.platforms, "Native") local hascpp = premake.hascppproject(sln) local hasdotnet = premake.hasdotnetproject(sln) if hasdotnet and (_ACTION > "vs2008" or hascpp) then table.insert(platforms, 1, "mixed") end if hasdotnet and (_ACTION < "vs2010" or not hascpp) then table.insert(platforms, 1, "any") end if _ACTION > "vs2008" then local platforms2010 = { } for _, platform in ipairs(platforms) do if vstudio.platforms[platform] == "Win32" then if hascpp then table.insert(platforms2010, platform) end if hasdotnet then table.insert(platforms2010, "x86") end else table.insert(platforms2010, platform) end end platforms = platforms2010 end for _, buildcfg in ipairs(sln.configurations) do for _, platform in ipairs(platforms) do local entry = { } entry.src_buildcfg = buildcfg entry.src_platform = platform if platform ~= "PS3" then entry.buildcfg = buildcfg entry.platform = vstudio.platforms[platform] else entry.buildcfg = platform .. " " .. buildcfg entry.platform = "Win32" end entry.name = entry.buildcfg .. "|" .. entry.platform entry.isreal = (platform ~= "any" and platform ~= "mixed") table.insert(cfgs, entry) end end return cfgs end function vstudio.cleansolution(sln) premake.clean.file(sln, "%%.sln") premake.clean.file(sln, "%%.suo") premake.clean.file(sln, "%%.ncb") premake.clean.file(sln, "%%.userprefs") premake.clean.file(sln, "%%.usertasks") end function vstudio.cleanproject(prj) local fname = premake.project.getfilename(prj, "%%") os.remove(fname .. ".vcproj") os.remove(fname .. ".vcproj.user") os.remove(fname .. ".vcxproj") os.remove(fname .. ".vcxproj.user") os.remove(fname .. ".vcxproj.filters") os.remove(fname .. ".csproj") os.remove(fname .. ".csproj.user") os.remove(fname .. ".pidb") os.remove(fname .. ".sdf") end function vstudio.cleantarget(name) os.remove(name .. ".pdb") os.remove(name .. ".idb") os.remove(name .. ".ilk") os.remove(name .. ".vshost.exe") os.remove(name .. ".exe.manifest") end function vstudio.platform(cfg) return cfg.platform or "Win32" end function vstudio.projectplatform(cfg) local platform = cfg.buildcfg if cfg.platform then platform = platform .. " " .. cfg.platform end return platform end function vstudio.projectfile(prj) local extension if prj.language == "C#" then extension = ".csproj" else extension = iif(_ACTION > "vs2008", ".vcxproj", ".vcproj") end local fname = path.join(prj.location, prj.name) return fname..extension end function vstudio.tool(prj) if (prj.language == "C#") then return "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC" else return "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942" end end newaction { trigger = "vs2002", shortname = "Visual Studio 2002", description = "Generate Microsoft Visual Studio 2002 project files", os = "windows", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, valid_languages = { "C", "C++", "C#" }, valid_tools = { cc = { "msc" }, dotnet = { "msnet" }, }, onsolution = function(sln) premake.generate(sln, "%%.sln", vstudio.sln2002.generate) end, onproject = function(prj) if premake.isdotnetproject(prj) then premake.generate(prj, "%%.csproj", vstudio.cs2002.generate) premake.generate(prj, "%%.csproj.user", vstudio.cs2002.generate_user) else premake.generate(prj, "%%.vcproj", vstudio.vc200x.generate) premake.generate(prj, "%%.vcproj.user", vstudio.vc200x.generate_user) end end, oncleansolution = premake.vstudio.cleansolution, oncleanproject = premake.vstudio.cleanproject, oncleantarget = premake.vstudio.cleantarget } newaction { trigger = "vs2003", shortname = "Visual Studio 2003", description = "Generate Microsoft Visual Studio 2003 project files", os = "windows", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, valid_languages = { "C", "C++", "C#" }, valid_tools = { cc = { "msc" }, dotnet = { "msnet" }, }, onsolution = function(sln) premake.generate(sln, "%%.sln", vstudio.sln2003.generate) end, onproject = function(prj) if premake.isdotnetproject(prj) then premake.generate(prj, "%%.csproj", vstudio.cs2002.generate) premake.generate(prj, "%%.csproj.user", vstudio.cs2002.generate_user) else premake.generate(prj, "%%.vcproj", vstudio.vc200x.generate) premake.generate(prj, "%%.vcproj.user", vstudio.vc200x.generate_user) end end, oncleansolution = premake.vstudio.cleansolution, oncleanproject = premake.vstudio.cleanproject, oncleantarget = premake.vstudio.cleantarget } newaction { trigger = "vs2005", shortname = "Visual Studio 2005", description = "Generate Microsoft Visual Studio 2005 project files", os = "windows", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, valid_languages = { "C", "C++", "C#" }, valid_tools = { cc = { "msc" }, dotnet = { "msnet" }, }, onsolution = function(sln) premake.generate(sln, "%%.sln", vstudio.sln2005.generate) end, onproject = function(prj) if premake.isdotnetproject(prj) then premake.generate(prj, "%%.csproj", vstudio.cs2005.generate) premake.generate(prj, "%%.csproj.user", vstudio.cs2005.generate_user) else premake.generate(prj, "%%.vcproj", vstudio.vc200x.generate) premake.generate(prj, "%%.vcproj.user", vstudio.vc200x.generate_user) end end, oncleansolution = vstudio.cleansolution, oncleanproject = vstudio.cleanproject, oncleantarget = vstudio.cleantarget } newaction { trigger = "vs2008", shortname = "Visual Studio 2008", description = "Generate Microsoft Visual Studio 2008 project files", os = "windows", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, valid_languages = { "C", "C++", "C#" }, valid_tools = { cc = { "msc" }, dotnet = { "msnet" }, }, onsolution = function(sln) premake.generate(sln, "%%.sln", vstudio.sln2005.generate) end, onproject = function(prj) if premake.isdotnetproject(prj) then premake.generate(prj, "%%.csproj", vstudio.cs2005.generate) premake.generate(prj, "%%.csproj.user", vstudio.cs2005.generate_user) else premake.generate(prj, "%%.vcproj", vstudio.vc200x.generate) premake.generate(prj, "%%.vcproj.user", vstudio.vc200x.generate_user) end end, oncleansolution = vstudio.cleansolution, oncleanproject = vstudio.cleanproject, oncleantarget = vstudio.cleantarget } newaction { trigger = "vs2010", shortname = "Visual Studio 2010", description = "Generate Visual Studio 2010 project files", os = "windows", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, valid_languages = { "C", "C++", "C#"}, valid_tools = { cc = { "msc" }, dotnet = { "msnet" }, }, onsolution = function(sln) premake.generate(sln, "%%.sln", vstudio.sln2005.generate) end, onproject = function(prj) if premake.isdotnetproject(prj) then premake.generate(prj, "%%.csproj", vstudio.cs2005.generate) premake.generate(prj, "%%.csproj.user", vstudio.cs2005.generate_user) else premake.generate(prj, "%%.vcxproj", premake.vs2010_vcxproj) premake.generate(prj, "%%.vcxproj.user", premake.vs2010_vcxproj_user) premake.generate(prj, "%%.vcxproj.filters", vstudio.vc2010.generate_filters) end end, oncleansolution = premake.vstudio.cleansolution, oncleanproject = premake.vstudio.cleanproject, oncleantarget = premake.vstudio.cleantarget }premake.vstudio.sln2002 = { } local vstudio = premake.vstudio local sln2002 = premake.vstudio.sln2002 function sln2002.generate(sln) io.eol = '\r\n' sln.vstudio_configs = premake.vstudio.buildconfigs(sln) _p('Microsoft Visual Studio Solution File, Format Version 7.00') for prj in premake.solution.eachproject(sln) do local projpath = path.translate(path.getrelative(sln.location, vstudio.projectfile(prj))) _p('Project("{%s}") = "%s", "%s", "{%s}"', vstudio.tool(prj), prj.name, projpath, prj.uuid) _p('EndProject') end _p('Global') _p(1,'GlobalSection(SolutionConfiguration) = preSolution') for i, cfgname in ipairs(sln.configurations) do _p(2,'ConfigName.%d = %s', i - 1, cfgname) end _p(1,'EndGlobalSection') _p(1,'GlobalSection(ProjectDependencies) = postSolution') _p(1,'EndGlobalSection') _p(1,'GlobalSection(ProjectConfiguration) = postSolution') for prj in premake.solution.eachproject(sln) do for _, cfgname in ipairs(sln.configurations) do _p(2,'{%s}.%s.ActiveCfg = %s|%s', prj.uuid, cfgname, cfgname, vstudio.arch(prj)) _p(2,'{%s}.%s.Build.0 = %s|%s', prj.uuid, cfgname, cfgname, vstudio.arch(prj)) end end _p(1,'EndGlobalSection') _p(1,'GlobalSection(ExtensibilityGlobals) = postSolution') _p(1,'EndGlobalSection') _p(1,'GlobalSection(ExtensibilityAddIns) = postSolution') _p(1,'EndGlobalSection') _p('EndGlobal') end premake.vstudio.cs2002 = { } local vstudio = premake.vstudio local cs2002 = premake.vstudio.cs2002 local function getelements(prj, action, fname) if action == "Compile" and fname:endswith(".cs") then return "SubTypeCode" end if action == "EmbeddedResource" and fname:endswith(".resx") then local basename = fname:sub(1, -6) local testname = path.getname(basename .. ".cs") if premake.findfile(prj, testname) then return "Dependency", testname end end return "None" end function cs2002.Files(prj) local tr = premake.project.buildsourcetree(prj) premake.tree.traverse(tr, { onleaf = function(node) local action = premake.dotnet.getbuildaction(node.cfg) local fname = path.translate(premake.esc(node.cfg.name), "\\") local elements, dependency = getelements(prj, action, node.path) _p(4,'') end }, false) end function cs2002.generate(prj) io.eol = "\r\n" _p('') _p(1,'') _p(2,'') _p(3,'') for cfg in premake.eachconfig(prj) do _p(4,'') end _p(3,'') _p(3,'') for _, ref in ipairs(premake.getlinks(prj, "siblings", "object")) do _p(4,'') end for _, linkname in ipairs(premake.getlinks(prj, "system", "fullpath")) do _p(4,'') end _p(3,'') _p(2,'') _p(2,'') _p(3,'') cs2002.Files(prj) _p(3,'') _p(2,'') _p(1,'') _p('') end local cs2002 = premake.vstudio.cs2002 function cs2002.generate_user(prj) io.eol = "\r\n" _p('') _p(1,'') _p(2,'') local refpaths = table.translate(prj.libdirs, function(v) return path.getabsolute(prj.location .. "/" .. v) end) _p(3,'', path.translate(table.concat(refpaths, ";"), "\\")) for cfg in premake.eachconfig(prj) do _p(4,'') end _p(3,'') _p(2,'') _p(2,'') _p(1,'') _p('') end premake.vstudio.vc200x = { } local vstudio = premake.vstudio local vc200x = premake.vstudio.vc200x local config = premake5.config local project = premake5.project local tree = premake.tree function vc200x.generate_ng(prj) io.eol = "\r\n" vc200x.xmldeclaration() vc200x.visualStudioProject(prj) vc200x.platforms(prj) if _ACTION > "vs2003" then _p(1,'') _p(1,'') end _p(1,'') for cfg in project.eachconfig(prj) do vc200x.configuration(cfg) vc200x.tools(cfg) _p(2,'') end _p(1,'') _p(1,'') _p(1,'') _p(1,'') vc200x.files_ng(prj) _p(1,'') _p(1,'') _p(1,'') _p('') end local function bool(value) if (_ACTION < "vs2005") then return iif(value, "TRUE", "FALSE") else return iif(value, "true", "false") end end function vc200x.xmldeclaration(element) _p('') end function vc200x.visualStudioProject(prj) _p(' "vs2003" then _x(1,'RootNamespace="%s"', prj.name) end _p(1,'Keyword="%s"', iif(prj.flags.Managed, "ManagedCProj", "Win32Proj")) _p(1,'>') end function vc200x.platforms(prj) _p(1,'') architectures = { } for cfg in project.eachconfig(prj) do local arch = vstudio.architecture(cfg) if not architectures[arch] then _p(2,'') architectures[arch] = true end end _p(1,'') end function vc200x.configuration(cfg) _p(2,'') end function vc200x.tools(cfg) for _, tool in ipairs(vc200x.gettools(cfg)) do if vc200x.toolmap[tool] then vc200x.toolmap[tool](cfg) else vc200x.tool(tool) end end end function vc200x.tool(name) _p(3,'') end function vc200x.VCCLCompilerTool_ng(cfg) _p(3,'') end function vc200x.VCCLBuiltInCompilerTool(cfg) if #cfg.buildoptions > 0 then _x(4,'AdditionalOptions="%s"', table.concat(cfg.buildoptions, " ")) end _p(4,'Optimization="%s"', vc200x.optimization(cfg)) if cfg.flags.NoFramePointer then _p(4,'OmitFramePointers="%s"', bool(true)) end vc200x.additionalIncludeDirectories(cfg, cfg.includedirs) vc200x.preprocessorDefinitions(cfg, cfg.defines) if premake.config.isdebugbuild(cfg) and cfg.debugformat ~= "c7" and not cfg.flags.NoMinimalRebuild and not cfg.flags.Managed then _p(4,'MinimalRebuild="%s"', bool(true)) end if cfg.flags.NoExceptions then _p(4,'ExceptionHandling="%s"', iif(_ACTION < "vs2005", "FALSE", 0)) elseif cfg.flags.SEH and _ACTION > "vs2003" then _p(4,'ExceptionHandling="2"') end if vc200x.optimization(cfg) == 0 and not cfg.flags.Managed then _p(4,'BasicRuntimeChecks="3"') end if vc200x.optimization(cfg) ~= 0 then _p(4,'StringPooling="%s"', bool(true)) end local runtime if premake.config.isdebugbuild(cfg) then runtime = iif(cfg.flags.StaticRuntime, 1, 3) else runtime = iif(cfg.flags.StaticRuntime, 0, 2) end _p(4,'RuntimeLibrary="%s"', runtime) _p(4,'EnableFunctionLevelLinking="%s"', bool(true)) if _ACTION > "vs2003" and cfg.system ~= "Xbox360" and cfg.architecture ~= "x64" then if cfg.flags.EnableSSE then _p(4,'EnableEnhancedInstructionSet="1"') elseif cfg.flags.EnableSSE2 then _p(4,'EnableEnhancedInstructionSet="2"') end end if _ACTION < "vs2005" then if cfg.flags.FloatFast then _p(4,'ImproveFloatingPointConsistency="%s"', bool(false)) elseif cfg.flags.FloatStrict then _p(4,'ImproveFloatingPointConsistency="%s"', bool(true)) end else if cfg.flags.FloatFast then _p(4,'FloatingPointModel="2"') elseif cfg.flags.FloatStrict then _p(4,'FloatingPointModel="1"') end end if _ACTION < "vs2005" and not cfg.flags.NoRTTI then _p(4,'RuntimeTypeInfo="%s"', bool(true)) elseif _ACTION > "vs2003" and cfg.flags.NoRTTI and not cfg.flags.Managed then _p(4,'RuntimeTypeInfo="%s"', bool(false)) end if cfg.flags.NativeWChar then _p(4,'TreatWChar_tAsBuiltInType="%s"', bool(true)) elseif cfg.flags.NoNativeWChar then _p(4,'TreatWChar_tAsBuiltInType="%s"', bool(false)) end if not cfg.flags.NoPCH and cfg.pchheader then _p(4,'UsePrecompiledHeader="%s"', iif(_ACTION < "vs2005", 3, 2)) _x(4,'PrecompiledHeaderThrough="%s"', path.getname(cfg.pchheader)) else _p(4,'UsePrecompiledHeader="%s"', iif(_ACTION > "vs2003" or cfg.flags.NoPCH, 0, 2)) end _p(4,'WarningLevel="%s"', iif(cfg.flags.ExtraWarnings, 4, 3)) if cfg.flags.FatalWarnings then _p(4,'WarnAsError="%s"', bool(true)) end if _ACTION < "vs2008" and not cfg.flags.Managed then _p(4,'Detect64BitPortabilityProblems="%s"', bool(not cfg.flags.No64BitChecks)) end _x(4,'ProgramDataBaseFileName="$(OutDir)\\%s.pdb"', config.gettargetinfo(cfg).basename) _p(4,'DebugInformationFormat="%s"', vc200x.symbols(cfg)) if cfg.project.language == "C" then _p(4, 'CompileAs="1"') end end function vc200x.VCCLExternalCompilerTool(cfg, toolset) local buildoptions = table.join(toolset.getcflags(cfg), toolset.getcxxflags(cfg), cfg.buildoptions) if not cfg.flags.NoPCH and cfg.pchheader then _p(4,'UsePrecompiledHeader="%s"', iif(_ACTION < "vs2005", 3, 2)) _x(4,'PrecompiledHeaderThrough="%s"', path.getname(cfg.pchheader)) table.insert(buildoptions, '--use_pch="$(IntDir)/$(TargetName).pch"') else _p(4,'UsePrecompiledHeader="%s"', iif(_ACTION > "vs2003" or cfg.flags.NoPCH, 0, 2)) end if #buildoptions > 0 then _x(4,'AdditionalOptions="%s"', table.concat(buildoptions, " ")) end vc200x.additionalIncludeDirectories(cfg, cfg.includedirs) vc200x.preprocessorDefinitions(cfg, cfg.defines) _x(4,'ProgramDataBaseFileName="$(OutDir)\\%s.pdb"', config.gettargetinfo(cfg).basename) _p(4,'DebugInformationFormat="0"') _p(4,'CompileAs="0"') end function vc200x.VCLinkerTool_ng(cfg) _p(3,'') end function vc200x.VCBuiltInLinkerTool(cfg) if cfg.kind ~= premake.STATICLIB then if cfg.flags.NoImportLib then _p(4,'IgnoreImportLibrary="%s"', bool(true)) end end if #cfg.linkoptions > 0 then _x(4,'AdditionalOptions="%s"', table.concat(cfg.linkoptions, " ")) end if #cfg.links > 0 then _x(4,'AdditionalDependencies="%s"', vc200x.links(cfg)) end _x(4,'OutputFile="$(OutDir)\\%s"', config.gettargetinfo(cfg).name) if cfg.kind ~= premake.STATICLIB then _p(4,'LinkIncremental="%s"', iif(premake.config.canincrementallink(cfg) , 2, 1)) end vc200x.additionalLibraryDirectories(cfg) if cfg.kind ~= premake.STATICLIB then local deffile = config.findfile(cfg, ".def") if deffile then _p(4,'ModuleDefinitionFile="%s"', deffile) end if cfg.flags.NoManifest then _p(4,'GenerateManifest="%s"', bool(false)) end _p(4,'GenerateDebugInformation="%s"', bool(vc200x.symbols(cfg) ~= 0)) if vc200x.symbols(cfg) >= 3 then _x(4,'ProgramDataBaseFileName="$(OutDir)\\%s.pdb"', config.gettargetinfo(cfg).basename) end _p(4,'SubSystem="%s"', iif(cfg.kind == "ConsoleApp", 1, 2)) if vc200x.optimization(cfg) ~= 0 then _p(4,'OptimizeReferences="2"') _p(4,'EnableCOMDATFolding="2"') end if (cfg.kind == "ConsoleApp" or cfg.kind == "WindowedApp") and not cfg.flags.WinMain then _p(4,'EntryPointSymbol="mainCRTStartup"') end if cfg.kind == "SharedLib" then local implibname = config.getlinkinfo(cfg).fullpath if cfg.flags.NoImportLib then local objdir = config.getuniqueobjdir(cfg) implibname = path.join(objdir, path.getname(implibname)) end _x(4,'ImportLibrary="%s"', path.translate(implibname)) end _p(4,'TargetMachine="%d"', iif(cfg.architecture == "x64", 17, 1)) end end function vc200x.VCExternalLinkerTool(cfg, toolset) local buildoptions = table.join(toolset.getldflags(cfg), cfg.linkoptions) if #buildoptions > 0 then _x(4,'AdditionalOptions="%s"', table.concat(buildoptions, " ")) end if #cfg.links > 0 then _x(4,'AdditionalDependencies="%s"', table.concat(toolset.getlinks(cfg, true), " ")) end _x(4,'OutputFile="$(OutDir)\\%s"', config.gettargetinfo(cfg).name) if cfg.kind ~= premake.STATICLIB then _p(4,'LinkIncremental="0"') end vc200x.additionalLibraryDirectories(cfg) if cfg.kind ~= premake.STATICLIB then _p(4,'GenerateManifest="%s"', bool(false)) _p(4,'ProgramDatabaseFile=""') _p(4,'RandomizedBaseAddress="1"') _p(4,'DataExecutionPrevention="0"') end end function vc200x.VCManifestTool_ng(cfg) local manifests = {} for _, fname in ipairs(cfg.files) do if path.getextension(fname) == ".manifest" then table.insert(manifests, project.getrelative(cfg.project, fname)) end end _p(3,' 0 then _x(4,'AdditionalManifestFiles="%s"', table.concat(manifests, ";")) end _p(3,'/>') end function vc200x.VCMIDLTool_ng(cfg) _p(3,'') end function vc200x.VCResourceCompilerTool_ng(cfg) _p(3,' 0 then _x(4,'AdditionalOptions="%s"', table.concat(cfg.resoptions, " ")) end vc200x.additionalIncludeDirectories(cfg, table.join(cfg.includedirs, cfg.resincludedirs)) vc200x.preprocessorDefinitions(cfg, table.join(cfg.defines, cfg.resdefines)) _p(3,'/>') end local function buildstepsblock(name, steps) _p(3,' 0 then _x(4,'CommandLine="%s"', table.implode(steps, "", "", "\r\n")) end _p(3,'/>') end function vc200x.VCPreBuildEventTool(cfg) buildstepsblock("VCPreBuildEventTool", cfg.prebuildcommands) end function vc200x.VCPreLinkEventTool(cfg) buildstepsblock("VCPreLinkEventTool", cfg.prelinkcommands) end function vc200x.VCPostBuildEventTool(cfg) buildstepsblock("VCPostBuildEventTool", cfg.postbuildcommands) end function vc200x.VCX360DeploymentTool(cfg) _p(3,' 0 then _x(4,'AdditionalOptions="%s"', table.concat(cfg.deploymentoptions, " ")) end _p(3,'/>') end function vc200x.VCX360ImageTool(cfg) _p(3,' 0 then _x(4,'AdditionalOptions="%s"', table.concat(cfg.imageoptions, " ")) end if cfg.imagepath ~= nil then _x(4,'OutputFileName="%s"', path.translate(cfg.imagepath)) end _p(3,'/>') end function vc200x.DebuggerTool(cfg) _p(3,'') end function vc200x.gettools(cfg) if _ACTION == "vs2002" then return { "VCCLCompilerTool", "VCCustomBuildTool", "VCLinkerTool", "VCMIDLTool", "VCPostBuildEventTool", "VCPreBuildEventTool", "VCPreLinkEventTool", "VCResourceCompilerTool", "VCWebServiceProxyGeneratorTool", "VCWebDeploymentTool" } end if _ACTION == "vs2003" then return { "VCCLCompilerTool", "VCCustomBuildTool", "VCLinkerTool", "VCMIDLTool", "VCPostBuildEventTool", "VCPreBuildEventTool", "VCPreLinkEventTool", "VCResourceCompilerTool", "VCWebServiceProxyGeneratorTool", "VCXMLDataGeneratorTool", "VCWebDeploymentTool", "VCManagedWrapperGeneratorTool", "VCAuxiliaryManagedWrapperGeneratorTool" } end if cfg.system == premake.XBOX360 then return { "VCPreBuildEventTool", "VCCustomBuildTool", "VCXMLDataGeneratorTool", "VCWebServiceProxyGeneratorTool", "VCMIDLTool", "VCCLCompilerTool", "VCManagedResourceCompilerTool", "VCResourceCompilerTool", "VCPreLinkEventTool", "VCLinkerTool", "VCALinkTool", "VCX360ImageTool", "VCBscMakeTool", "VCX360DeploymentTool", "VCPostBuildEventTool", "DebuggerTool", } else return { "VCPreBuildEventTool", "VCCustomBuildTool", "VCXMLDataGeneratorTool", "VCWebServiceProxyGeneratorTool", "VCMIDLTool", "VCCLCompilerTool", "VCManagedResourceCompilerTool", "VCResourceCompilerTool", "VCPreLinkEventTool", "VCLinkerTool", "VCALinkTool", "VCManifestTool", "VCXDCMakeTool", "VCBscMakeTool", "VCFxCopTool", "VCAppVerifierTool", "VCWebDeploymentTool", "VCPostBuildEventTool" } end end vc200x.toolmap = { DebuggerTool = vc200x.DebuggerTool, VCCLCompilerTool = vc200x.VCCLCompilerTool_ng, VCLinkerTool = vc200x.VCLinkerTool_ng, VCManifestTool = vc200x.VCManifestTool_ng, VCMIDLTool = vc200x.VCMIDLTool_ng, VCPostBuildEventTool = vc200x.VCPostBuildEventTool, VCPreBuildEventTool = vc200x.VCPreBuildEventTool, VCPreLinkEventTool = vc200x.VCPreLinkEventTool, VCResourceCompilerTool = vc200x.VCResourceCompilerTool_ng, VCX360DeploymentTool = vc200x.VCX360DeploymentTool, VCX360ImageTool = vc200x.VCX360ImageTool } vc200x.toolsets = { ps3 = premake.tools.snc } function vc200x.files_ng(prj) local tr = project.getsourcetree(prj) tree.traverse(tr, { onbranchenter = function(node, depth) _p(depth, '') end, onbranchexit = function(node, depth) _p(depth, '') end, onleaf = function(node, depth) _p(depth, '') vc200x.fileConfiguration(prj, node, depth + 1) _p(depth, '') end }, false, 2) end function vc200x.fileConfiguration(prj, node, depth) local compileAs if path.iscfile(node.name) ~= premake.project.iscproject(prj) then if path.iscppfile(node.name) then compileAs = iif(prj.language == premake.CPP, "C++", "C") end end for cfg in project.eachconfig(prj) do local filecfg = config.getfileconfig(cfg, node.abspath) local hasSettings = (filecfg ~= nil and filecfg.terms ~= nil) local isPchSource = (prj.pchsource == node.abspath and not cfg.flags.NoPCH) if compileAs or isPchSource or not filecfg or hasSettings then _p(depth,'') _p(depth, '') _p(depth, '') end end end function vc200x.additionalIncludeDirectories(cfg, includedirs) if #includedirs > 0 then local dirs = project.getrelative(cfg.project, includedirs) _x(4,'AdditionalIncludeDirectories="%s"', path.translate(table.concat(dirs, ";"))) end end function vc200x.additionalLibraryDirectories(cfg) if #cfg.libdirs > 0 then local dirs = table.concat(project.getrelative(cfg.project, cfg.libdirs), ";") _x(4,'AdditionalLibraryDirectories="%s"', path.translate(dirs)) end end function vc200x.compilertool(cfg) if cfg.system == premake.XBOX360 then return "VCCLX360CompilerTool" else return "VCCLCompilerTool" end end function vc200x.linkertool(cfg) if cfg.kind == premake.STATICLIB then return "VCLibrarianTool" elseif cfg.system == premake.XBOX360 then return "VCX360LinkerTool" else return "VCLinkerTool" end end function vc200x.links(cfg) local links = config.getlinks(cfg, "system", "fullpath") links = table.concat(links, " ") links = path.translate(links) return links end function vc200x.optimization(cfg) local result = 0 for _, value in ipairs(cfg.flags) do if (value == "Optimize") then result = 3 elseif (value == "OptimizeSize") then result = 1 elseif (value == "OptimizeSpeed") then result = 2 end end return result end function vc200x.preprocessorDefinitions(cfg, defines) if #defines > 0 then _x(4,'PreprocessorDefinitions="%s"', table.concat(defines, ";")) end end function vc200x.projectversion() local map = { vs2002 = '7.0', vs2003 = '7.1', vs2005 = '8.0', vs2008 = '9.0' } _p(1,'Version="%s0"', map[_ACTION]) end function vc200x.symbols(cfg) if not cfg.flags.Symbols then return 0 elseif cfg.debugformat == "c7" then return 1 else if cfg.flags.NoEditAndContinue or vc200x.optimization(cfg) ~= 0 or cfg.flags.Managed or cfg.system == "x64" or cfg.platform == "x64" -- TODO: remove this when the _ng stuff goes live then return 3 else return 4 end end end function vc200x.toolset(cfg) return premake.tools[cfg.toolset] or vc200x.toolsets[cfg.system] end function vc200x.header(element) io.eol = "\r\n" _p('') _p('<%s', element) _p(1,'ProjectType="Visual C++"') if _ACTION == "vs2002" then _p(1,'Version="7.00"') elseif _ACTION == "vs2003" then _p(1,'Version="7.10"') elseif _ACTION == "vs2005" then _p(1,'Version="8.00"') elseif _ACTION == "vs2008" then _p(1,'Version="9.00"') end end function vc200x.Configuration(name, cfg) _p(2,'') end function vc200x.Files(prj) local tr = premake.project.buildsourcetree(prj) tree.traverse(tr, { onbranchenter = function(node, depth) _p(depth, '') end, onbranchexit = function(node, depth) _p(depth, '') end, onleaf = function(node, depth) local fname = node.cfg.name _p(depth, '') depth = depth + 1 for _, cfginfo in ipairs(prj.solution.vstudio_configs) do if cfginfo.isreal then local cfg = premake.getconfig(prj, cfginfo.src_buildcfg, cfginfo.src_platform) local usePCH = (not prj.flags.NoPCH and prj.pchsource == node.cfg.name) local isSourceCode = path.iscppfile(fname) local needsCompileAs = (path.iscfile(fname) ~= premake.project.iscproject(prj)) if usePCH or (isSourceCode and needsCompileAs) then _p(depth, '') _p(depth, '\t') _p(depth, '') end end end depth = depth - 1 _p(depth, '') end, }, false, 2) end function vc200x.Platforms(prj) local used = { } _p(1,'') for _, cfg in ipairs(prj.solution.vstudio_configs) do if cfg.isreal and not table.contains(used, cfg.platform) then table.insert(used, cfg.platform) _p(2,'') end end _p(1,'') end function vc200x.VCCLCompilerTool(cfg) _p(3,' 0 then _p(4,'AdditionalOptions="%s"', table.concat(premake.esc(cfg.buildoptions), " ")) end _p(4,'Optimization="%s"', vc200x.optimization(cfg)) if cfg.flags.NoFramePointer then _p(4,'OmitFramePointers="%s"', bool(true)) end if #cfg.includedirs > 0 then _p(4,'AdditionalIncludeDirectories="%s"', premake.esc(path.translate(table.concat(cfg.includedirs, ";"), '\\'))) end if #cfg.defines > 0 then _p(4,'PreprocessorDefinitions="%s"', premake.esc(table.concat(cfg.defines, ";"))) end if premake.config.isdebugbuild(cfg) and cfg.debugformat ~= "c7" and not cfg.flags.NoMinimalRebuild and not cfg.flags.Managed then _p(4,'MinimalRebuild="%s"', bool(true)) end if cfg.flags.NoExceptions then _p(4,'ExceptionHandling="%s"', iif(_ACTION < "vs2005", "FALSE", 0)) elseif cfg.flags.SEH and _ACTION > "vs2003" then _p(4,'ExceptionHandling="2"') end if vc200x.optimization(cfg) == 0 and not cfg.flags.Managed then _p(4,'BasicRuntimeChecks="3"') end if vc200x.optimization(cfg) ~= 0 then _p(4,'StringPooling="%s"', bool(true)) end local runtime if premake.config.isdebugbuild(cfg) then runtime = iif(cfg.flags.StaticRuntime, 1, 3) else runtime = iif(cfg.flags.StaticRuntime, 0, 2) end _p(4,'RuntimeLibrary="%s"', runtime) _p(4,'EnableFunctionLevelLinking="%s"', bool(true)) if _ACTION > "vs2003" and cfg.platform ~= "Xbox360" and cfg.platform ~= "x64" then if cfg.flags.EnableSSE then _p(4,'EnableEnhancedInstructionSet="1"') elseif cfg.flags.EnableSSE2 then _p(4,'EnableEnhancedInstructionSet="2"') end end if _ACTION < "vs2005" then if cfg.flags.FloatFast then _p(4,'ImproveFloatingPointConsistency="%s"', bool(false)) elseif cfg.flags.FloatStrict then _p(4,'ImproveFloatingPointConsistency="%s"', bool(true)) end else if cfg.flags.FloatFast then _p(4,'FloatingPointModel="2"') elseif cfg.flags.FloatStrict then _p(4,'FloatingPointModel="1"') end end if _ACTION < "vs2005" and not cfg.flags.NoRTTI then _p(4,'RuntimeTypeInfo="%s"', bool(true)) elseif _ACTION > "vs2003" and cfg.flags.NoRTTI and not cfg.flags.Managed then _p(4,'RuntimeTypeInfo="%s"', bool(false)) end if cfg.flags.NativeWChar then _p(4,'TreatWChar_tAsBuiltInType="%s"', bool(true)) elseif cfg.flags.NoNativeWChar then _p(4,'TreatWChar_tAsBuiltInType="%s"', bool(false)) end if not cfg.flags.NoPCH and cfg.pchheader then _p(4,'UsePrecompiledHeader="%s"', iif(_ACTION < "vs2005", 3, 2)) _p(4,'PrecompiledHeaderThrough="%s"', path.getname(cfg.pchheader)) else _p(4,'UsePrecompiledHeader="%s"', iif(_ACTION > "vs2003" or cfg.flags.NoPCH, 0, 2)) end _p(4,'WarningLevel="%s"', iif(cfg.flags.ExtraWarnings, 4, 3)) if cfg.flags.FatalWarnings then _p(4,'WarnAsError="%s"', bool(true)) end if _ACTION < "vs2008" and not cfg.flags.Managed then _p(4,'Detect64BitPortabilityProblems="%s"', bool(not cfg.flags.No64BitChecks)) end _p(4,'ProgramDataBaseFileName="$(OutDir)\\%s.pdb"', path.getbasename(cfg.buildtarget.name)) _p(4,'DebugInformationFormat="%s"', vc200x.symbols(cfg)) if cfg.language == "C" then _p(4, 'CompileAs="1"') end _p(3,'/>') end function vc200x.VCLinkerTool(cfg) _p(3,' 0 then _p(4,'AdditionalOptions="%s"', table.concat(premake.esc(cfg.linkoptions), " ")) end if #cfg.links > 0 then _p(4,'AdditionalDependencies="%s"', table.concat(premake.getlinks(cfg, "all", "fullpath"), " ")) end _p(4,'OutputFile="$(OutDir)\\%s"', cfg.buildtarget.name) _p(4,'LinkIncremental="%s"', iif(premake.config.canincrementallink(cfg) , 2, 1)) _p(4,'AdditionalLibraryDirectories="%s"', table.concat(premake.esc(path.translate(cfg.libdirs, '\\')) , ";")) local deffile = premake.findfile(cfg, ".def") if deffile then _p(4,'ModuleDefinitionFile="%s"', deffile) end if cfg.flags.NoManifest then _p(4,'GenerateManifest="%s"', bool(false)) end _p(4,'GenerateDebugInformation="%s"', bool(vc200x.symbols(cfg) ~= 0)) if vc200x.symbols(cfg) >= 3 then _p(4,'ProgramDataBaseFileName="$(OutDir)\\%s.pdb"', path.getbasename(cfg.buildtarget.name)) end _p(4,'SubSystem="%s"', iif(cfg.kind == "ConsoleApp", 1, 2)) if vc200x.optimization(cfg) ~= 0 then _p(4,'OptimizeReferences="2"') _p(4,'EnableCOMDATFolding="2"') end if (cfg.kind == "ConsoleApp" or cfg.kind == "WindowedApp") and not cfg.flags.WinMain then _p(4,'EntryPointSymbol="mainCRTStartup"') end if cfg.kind == "SharedLib" then local implibname = config.getlinkinfo(cfg).fullpath _p(4,'ImportLibrary="%s"', iif(cfg.flags.NoImportLib, cfg.objectsdir .. "\\" .. path.getname(implibname), implibname)) end _p(4,'TargetMachine="%d"', iif(cfg.platform == "x64", 17, 1)) else _p(4,'Name="VCLibrarianTool"') if #cfg.links > 0 then _p(4,'AdditionalDependencies="%s"', table.concat(premake.getlinks(cfg, "all", "fullpath"), " ")) end _p(4,'OutputFile="$(OutDir)\\%s"', cfg.buildtarget.name) if #cfg.libdirs > 0 then _p(4,'AdditionalLibraryDirectories="%s"', premake.esc(path.translate(table.concat(cfg.libdirs , ";")))) end local addlOptions = {} if cfg.platform == "x32" then table.insert(addlOptions, "/MACHINE:X86") elseif cfg.platform == "x64" then table.insert(addlOptions, "/MACHINE:X64") end addlOptions = table.join(addlOptions, cfg.linkoptions) if #addlOptions > 0 then _p(4,'AdditionalOptions="%s"', table.concat(premake.esc(addlOptions), " ")) end end _p(3,'/>') end function vc200x.VCCLCompilerTool_PS3(cfg) _p(3,' "vs2003" or cfg.flags.NoPCH, 0, 2)) end _p(4,'AdditionalOptions="%s"', premake.esc(table.concat(buildoptions, " "))) if #cfg.includedirs > 0 then _p(4,'AdditionalIncludeDirectories="%s"', premake.esc(path.translate(table.concat(cfg.includedirs, ";"), '\\'))) end if #cfg.defines > 0 then _p(4,'PreprocessorDefinitions="%s"', table.concat(premake.esc(cfg.defines), ";")) end _p(4,'ProgramDataBaseFileName="$(OutDir)\\%s.pdb"', path.getbasename(cfg.buildtarget.name)) _p(4,'DebugInformationFormat="0"') _p(4,'CompileAs="0"') _p(3,'/>') end function vc200x.VCLinkerTool_PS3(cfg) _p(3,' 0 then _p(4,'AdditionalOptions="%s"', premake.esc(table.concat(buildoptions, " "))) end if #cfg.links > 0 then _p(4,'AdditionalDependencies="%s"', table.concat(premake.getlinks(cfg, "all", "fullpath"), " ")) end _p(4,'OutputFile="$(OutDir)\\%s"', cfg.buildtarget.name) _p(4,'LinkIncremental="0"') _p(4,'AdditionalLibraryDirectories="%s"', table.concat(premake.esc(path.translate(cfg.libdirs, '\\')) , ";")) _p(4,'GenerateManifest="%s"', bool(false)) _p(4,'ProgramDatabaseFile=""') _p(4,'RandomizedBaseAddress="1"') _p(4,'DataExecutionPrevention="0"') else _p(4,'Name="VCLibrarianTool"') local buildoptions = table.join(premake.snc.getldflags(cfg), cfg.linkoptions) if #buildoptions > 0 then _p(4,'AdditionalOptions="%s"', premake.esc(table.concat(buildoptions, " "))) end if #cfg.links > 0 then _p(4,'AdditionalDependencies="%s"', table.concat(premake.getlinks(cfg, "all", "fullpath"), " ")) end _p(4,'OutputFile="$(OutDir)\\%s"', cfg.buildtarget.name) if #cfg.libdirs > 0 then _p(4,'AdditionalLibraryDirectories="%s"', premake.esc(path.translate(table.concat(cfg.libdirs , ";")))) end end _p(3,'/>') end function vc200x.VCManifestTool(cfg) local manifests = {} for _, fname in ipairs(cfg.files) do if path.getextension(fname) == ".manifest" then table.insert(manifests, fname) end end _p(3,' 0 then _x(4,'AdditionalManifestFiles="%s"', table.concat(manifests, ";")) end _p(3,'/>') end function vc200x.VCResourceCompilerTool(cfg) _p(3,' 0 then _p(4,'AdditionalOptions="%s"', table.concat(premake.esc(cfg.resoptions), " ")) end if #cfg.defines > 0 or #cfg.resdefines > 0 then _p(4,'PreprocessorDefinitions="%s"', table.concat(premake.esc(table.join(cfg.defines, cfg.resdefines)), ";")) end if #cfg.includedirs > 0 or #cfg.resincludedirs > 0 then local dirs = table.join(cfg.includedirs, cfg.resincludedirs) _p(4,'AdditionalIncludeDirectories="%s"', premake.esc(path.translate(table.concat(dirs, ";"), '\\'))) end _p(3,'/>') end function vc200x.VCMIDLTool(cfg) _p(3,'') end local blockmap = { VCCLCompilerTool = vc200x.VCCLCompilerTool, VCCLCompilerTool_PS3 = vc200x.VCCLCompilerTool_PS3, VCLinkerTool = vc200x.VCLinkerTool, VCLinkerTool_PS3 = vc200x.VCLinkerTool_PS3, VCManifestTool = vc200x.VCManifestTool, VCMIDLTool = vc200x.VCMIDLTool, VCResourceCompilerTool = vc200x.VCResourceCompilerTool, } local function getsections(version, platform) if version == "vs2002" then return { "VCCLCompilerTool", "VCCustomBuildTool", "VCLinkerTool", "VCMIDLTool", "VCPostBuildEventTool", "VCPreBuildEventTool", "VCPreLinkEventTool", "VCResourceCompilerTool", "VCWebServiceProxyGeneratorTool", "VCWebDeploymentTool" } end if version == "vs2003" then return { "VCCLCompilerTool", "VCCustomBuildTool", "VCLinkerTool", "VCMIDLTool", "VCPostBuildEventTool", "VCPreBuildEventTool", "VCPreLinkEventTool", "VCResourceCompilerTool", "VCWebServiceProxyGeneratorTool", "VCXMLDataGeneratorTool", "VCWebDeploymentTool", "VCManagedWrapperGeneratorTool", "VCAuxiliaryManagedWrapperGeneratorTool" } end if platform == "Xbox360" then return { "VCPreBuildEventTool", "VCCustomBuildTool", "VCXMLDataGeneratorTool", "VCWebServiceProxyGeneratorTool", "VCMIDLTool", "VCCLCompilerTool", "VCManagedResourceCompilerTool", "VCResourceCompilerTool", "VCPreLinkEventTool", "VCLinkerTool", "VCALinkTool", "VCX360ImageTool", "VCBscMakeTool", "VCX360DeploymentTool", "VCPostBuildEventTool", "DebuggerTool", } end if platform == "PS3" then return { "VCPreBuildEventTool", "VCCustomBuildTool", "VCXMLDataGeneratorTool", "VCWebServiceProxyGeneratorTool", "VCMIDLTool", "VCCLCompilerTool_PS3", "VCManagedResourceCompilerTool", "VCResourceCompilerTool", "VCPreLinkEventTool", "VCLinkerTool_PS3", "VCALinkTool", "VCManifestTool", "VCXDCMakeTool", "VCBscMakeTool", "VCFxCopTool", "VCAppVerifierTool", "VCWebDeploymentTool", "VCPostBuildEventTool" } else return { "VCPreBuildEventTool", "VCCustomBuildTool", "VCXMLDataGeneratorTool", "VCWebServiceProxyGeneratorTool", "VCMIDLTool", "VCCLCompilerTool", "VCManagedResourceCompilerTool", "VCResourceCompilerTool", "VCPreLinkEventTool", "VCLinkerTool", "VCALinkTool", "VCManifestTool", "VCXDCMakeTool", "VCBscMakeTool", "VCFxCopTool", "VCAppVerifierTool", "VCWebDeploymentTool", "VCPostBuildEventTool" } end end function vc200x.generate(prj) vc200x.header('VisualStudioProject') _p(1,'Name="%s"', premake.esc(prj.name)) _p(1,'ProjectGUID="{%s}"', prj.uuid) if _ACTION > "vs2003" then _p(1,'RootNamespace="%s"', prj.name) end _p(1,'Keyword="%s"', iif(prj.flags.Managed, "ManagedCProj", "Win32Proj")) _p(1,'>') vc200x.Platforms(prj) if _ACTION > "vs2003" then _p(1,'') _p(1,'') end _p(1,'') for _, cfginfo in ipairs(prj.solution.vstudio_configs) do if cfginfo.isreal then local cfg = premake.getconfig(prj, cfginfo.src_buildcfg, cfginfo.src_platform) vc200x.Configuration(cfginfo.name, cfg) for _, block in ipairs(getsections(_ACTION, cfginfo.src_platform)) do if blockmap[block] then blockmap[block](cfg) elseif block == "VCPreBuildEventTool" then vc200x.buildstepsblock("VCPreBuildEventTool", cfg.prebuildcommands) elseif block == "VCPreLinkEventTool" then vc200x.buildstepsblock("VCPreLinkEventTool", cfg.prelinkcommands) elseif block == "VCPostBuildEventTool" then vc200x.buildstepsblock("VCPostBuildEventTool", cfg.postbuildcommands) elseif block == "VCX360DeploymentTool" then _p(3,' 0 then _p(4,'AdditionalOptions="%s"', table.concat(premake.esc(cfg.deploymentoptions), " ")) end _p(3,'/>') elseif block == "VCX360ImageTool" then _p(3,' 0 then _p(4,'AdditionalOptions="%s"', table.concat(premake.esc(cfg.imageoptions), " ")) end if cfg.imagepath ~= nil then _p(4,'OutputFileName="%s"', premake.esc(path.translate(cfg.imagepath))) end _p(3,'/>') elseif block == "DebuggerTool" then _p(3,'') else _p(3,'') end end _p(2,'') end end _p(1,'') _p(1,'') _p(1,'') _p(1,'') vc200x.Files(prj) _p(1,'') _p(1,'') _p(1,'') _p('') end local vstudio = premake.vstudio local vc200x = premake.vstudio.vc200x local project = premake5.project function vc200x.generate_user_ng(prj) io.eol = "\r\n" vc200x.xmldeclaration() _p('') _p(1,'') for cfg in project.eachconfig(prj) do vc200x.userconfiguration(cfg) vc200x.debugdir_ng(cfg) _p(2,'') end _p(1,'') _p('') end function vc200x.userconfiguration(cfg) _p(2,'') end function vc200x.debugdir_ng(cfg) _p(3,' 0 then _x(4,'CommandArguments="%s"', table.concat(cfg.debugargs, " ")) end if #cfg.debugenvs > 0 then _p(4,'Environment="%s"', table.concat(premake.esc(cfg.debugenvs), " ")) if cfg.flags.DebugEnvsDontMerge then _p(4,'EnvironmentMerge="false"') end end _p(3,'/>') end function vc200x.generate_user(prj) vc200x.header('VisualStudioUserFile') _p(1,'ShowAllFiles="false"') _p(1,'>') _p(1,'') for _, cfginfo in ipairs(prj.solution.vstudio_configs) do if cfginfo.isreal then local cfg = premake.getconfig(prj, cfginfo.src_buildcfg, cfginfo.src_platform) _p(2,'') vc200x.debugdir(cfg) _p(2,'') end end _p(1,'') _p('') end function vc200x.environmentargs(cfg) if cfg.environmentargs and #cfg.environmentargs > 0 then _p(4,'Environment="%s"', string.gsub(table.concat(cfg.environmentargs, " "),'"','"')) if cfg.flags.EnvironmentArgsDontMerge then _p(4,'EnvironmentMerge="false"') end end end function vc200x.debugdir(cfg) _p(3,' 0 then _p(4,'CommandArguments="%s"', table.concat(cfg.debugargs, " ")) end vc200x.environmentargs(cfg) _p(3,'/>') end premake.vstudio.sln2003 = { } local vstudio = premake.vstudio local sln2003 = premake.vstudio.sln2003 function sln2003.generate(sln) io.eol = '\r\n' sln.vstudio_configs = premake.vstudio.buildconfigs(sln) _p('Microsoft Visual Studio Solution File, Format Version 8.00') for prj in premake.solution.eachproject(sln) do local projpath = path.translate(path.getrelative(sln.location, vstudio.projectfile(prj))) _p('Project("{%s}") = "%s", "%s", "{%s}"', vstudio.tool(prj), prj.name, projpath, prj.uuid) local deps = premake.getdependencies(prj) if #deps > 0 then _p('\tProjectSection(ProjectDependencies) = postProject') for _, dep in ipairs(deps) do _p('\t\t{%s} = {%s}', dep.uuid, dep.uuid) end _p('\tEndProjectSection') end _p('EndProject') end _p('Global') _p('\tGlobalSection(SolutionConfiguration) = preSolution') for _, cfgname in ipairs(sln.configurations) do _p('\t\t%s = %s', cfgname, cfgname) end _p('\tEndGlobalSection') _p('\tGlobalSection(ProjectDependencies) = postSolution') _p('\tEndGlobalSection') _p('\tGlobalSection(ProjectConfiguration) = postSolution') for prj in premake.solution.eachproject(sln) do for _, cfgname in ipairs(sln.configurations) do _p('\t\t{%s}.%s.ActiveCfg = %s|%s', prj.uuid, cfgname, cfgname, vstudio.arch(prj)) _p('\t\t{%s}.%s.Build.0 = %s|%s', prj.uuid, cfgname, cfgname, vstudio.arch(prj)) end end _p('\tEndGlobalSection') _p('\tGlobalSection(ExtensibilityGlobals) = postSolution') _p('\tEndGlobalSection') _p('\tGlobalSection(ExtensibilityAddIns) = postSolution') _p('\tEndGlobalSection') _p('EndGlobal') end premake.vstudio.sln2005 = { } local vstudio = premake.vstudio local sln2005 = premake.vstudio.sln2005 local solution = premake.solution local project = premake5.project function sln2005.generate_ng(sln) io.eol = '\r\n' _p('\239\187\191') sln2005.header(sln) for prj in premake.solution.eachproject_ng(sln) do sln2005.project_ng(prj) end _p('Global') sln2005.solutionConfigurationPlatforms(sln) sln2005.projectConfigurationPlatforms(sln) sln2005.properties(sln) _p('EndGlobal') end function sln2005.header(sln) local version = { vs2005 = 9, vs2008 = 10, vs2010 = 11 } _p('Microsoft Visual Studio Solution File, Format Version %d.00', version[_ACTION]) _p('# Visual Studio %s', _ACTION:sub(3)) end function sln2005.project_ng(prj) local slnpath = premake.solution.getlocation(prj.solution) local prjpath = vstudio.projectfile_ng(prj) prjpath = path.translate(path.getrelative(slnpath, prjpath)) _x('Project("{%s}") = "%s", "%s", "{%s}"', vstudio.tool(prj), prj.name, prjpath, prj.uuid) sln2005.projectdependencies_ng(prj) _p('EndProject') end function sln2005.projectdependencies_ng(prj) local deps = project.getdependencies(prj) if #deps > 0 then _p(1,'ProjectSection(ProjectDependencies) = postProject') for _, dep in ipairs(deps) do _p(2,'{%s} = {%s}', dep.uuid, dep.uuid) end _p(1,'EndProjectSection') end end function sln2005.solutionConfigurationPlatforms(sln) _p(1,'GlobalSection(SolutionConfigurationPlatforms) = preSolution') for cfg in solution.eachconfig(sln) do local platform = vstudio.platform(cfg) _p(2,'%s|%s = %s|%s', cfg.buildcfg, platform, cfg.buildcfg, platform) end _p(1,'EndGlobalSection') end function sln2005.projectConfigurationPlatforms(sln) _p(1,'GlobalSection(ProjectConfigurationPlatforms) = postSolution') for prj in solution.eachproject_ng(sln) do for cfg in project.eachconfig(prj) do local slnplatform = vstudio.platform(cfg) local prjplatform = vstudio.projectplatform(cfg) local architecture = vstudio.architecture(cfg) _p(2,'{%s}.%s|%s.ActiveCfg = %s|%s', prj.uuid, cfg.buildcfg, slnplatform, prjplatform, architecture) _p(2,'{%s}.%s|%s.Build.0 = %s|%s', prj.uuid, cfg.buildcfg, slnplatform, prjplatform, architecture) end end _p(1,'EndGlobalSection') end function sln2005.properties(sln) _p('\tGlobalSection(SolutionProperties) = preSolution') _p('\t\tHideSolutionNode = FALSE') _p('\tEndGlobalSection') end function sln2005.generate(sln) io.eol = '\r\n' sln.vstudio_configs = premake.vstudio.buildconfigs(sln) _p('\239\187\191') sln2005.header(sln) for prj in premake.solution.eachproject(sln) do sln2005.project(prj) end _p('Global') sln2005.platforms(sln) sln2005.project_platforms(sln) sln2005.properties(sln) _p('EndGlobal') end function sln2005.project(prj) local projpath = path.translate(path.getrelative(prj.solution.location, vstudio.projectfile(prj)), "\\") _p('Project("{%s}") = "%s", "%s", "{%s}"', vstudio.tool(prj), prj.name, projpath, prj.uuid) sln2005.projectdependencies(prj) _p('EndProject') end function sln2005.projectdependencies(prj) local deps = premake.getdependencies(prj) if #deps > 0 then _p('\tProjectSection(ProjectDependencies) = postProject') for _, dep in ipairs(deps) do _p('\t\t{%s} = {%s}', dep.uuid, dep.uuid) end _p('\tEndProjectSection') end end function sln2005.platforms(sln) _p('\tGlobalSection(SolutionConfigurationPlatforms) = preSolution') for _, cfg in ipairs(sln.vstudio_configs) do _p('\t\t%s = %s', cfg.name, cfg.name) end _p('\tEndGlobalSection') end function sln2005.project_platforms(sln) _p('\tGlobalSection(ProjectConfigurationPlatforms) = postSolution') for prj in premake.solution.eachproject(sln) do for _, cfg in ipairs(sln.vstudio_configs) do local mapped if premake.isdotnetproject(prj) then mapped = "Any CPU" else if cfg.platform == "Any CPU" or cfg.platform == "Mixed Platforms" then mapped = sln.vstudio_configs[3].platform else mapped = cfg.platform end end _p('\t\t{%s}.%s.ActiveCfg = %s|%s', prj.uuid, cfg.name, cfg.buildcfg, mapped) if mapped == cfg.platform or cfg.platform == "Mixed Platforms" then _p('\t\t{%s}.%s.Build.0 = %s|%s', prj.uuid, cfg.name, cfg.buildcfg, mapped) end end end _p('\tEndGlobalSection') end premake.vstudio.cs2005 = { } local vstudio = premake.vstudio local cs2005 = premake.vstudio.cs2005 function cs2005.generate_ng(prj) print("** Warning: C# projects have not been ported yet") end local function getelements(prj, action, fname) if action == "Compile" and fname:endswith(".cs") then if fname:endswith(".Designer.cs") then local basename = fname:sub(1, -13) local testname = basename .. ".cs" if premake.findfile(prj, testname) then return "Dependency", testname end testname = basename .. ".resx" if premake.findfile(prj, testname) then return "AutoGen", testname end else local basename = fname:sub(1, -4) local testname = basename .. ".Designer.cs" if premake.findfile(prj, testname) then return "SubTypeForm" end end end if action == "EmbeddedResource" and fname:endswith(".resx") then local basename = fname:sub(1, -6) local testname = path.getname(basename .. ".cs") if premake.findfile(prj, testname) then if premake.findfile(prj, basename .. ".Designer.cs") then return "DesignerType", testname else return "Dependency", testname end else testname = path.getname(basename .. ".Designer.cs") if premake.findfile(prj, testname) then return "AutoGenerated" end end end if action == "Content" then return "CopyNewest" end return "None" end function cs2005.arch(prj) return "AnyCPU" end function cs2005.files(prj) local tr = premake.project.buildsourcetree(prj) premake.tree.traverse(tr, { onleaf = function(node) local action = premake.dotnet.getbuildaction(node.cfg) local fname = path.translate(premake.esc(node.cfg.name), "\\") local elements, dependency = getelements(prj, action, node.path) if elements == "None" then _p(' <%s Include="%s" />', action, fname) else _p(' <%s Include="%s">', action, fname) if elements == "AutoGen" then _p(' True') elseif elements == "AutoGenerated" then _p(' Designer') _p(' ResXFileCodeGenerator') _p(' %s.Designer.cs', premake.esc(path.getbasename(node.name))) elseif elements == "SubTypeDesigner" then _p(' Designer') elseif elements == "SubTypeForm" then _p(' Form') elseif elements == "PreserveNewest" then _p(' PreserveNewest') end if dependency then _p(' %s', path.translate(premake.esc(dependency), "\\")) end _p(' ', action) end end }, false) end function cs2005.projectelement(prj) local toolversion = { vs2005 = '', vs2008 = ' ToolsVersion="3.5"', vs2010 = ' ToolsVersion="4.0"', } if _ACTION > "vs2008" then _p('') end _p('', toolversion[_ACTION]) end function cs2005.projectsettings(prj) local version = { vs2005 = '8.0.50727', vs2008 = '9.0.21022', vs2010 = '8.0.30703', } _p(' ') _p(' %s', premake.esc(prj.solution.configurations[1])) _p(' %s', cs2005.arch(prj)) _p(' %s', version[_ACTION]) _p(' 2.0') _p(' {%s}', prj.uuid) _p(' %s', premake.dotnet.getkind(prj)) _p(' Properties') _p(' %s', prj.buildtarget.basename) _p(' %s', prj.buildtarget.basename) local framework = prj.framework or iif(_ACTION == "vs2010", "4.0", nil) if framework then _p(' v%s', framework) end if _ACTION == "vs2010" then _p(' Client') _p(' 512') end _p(' ') end function cs2005.propertygroup(cfg) _p(' ', premake.esc(cfg.name), cs2005.arch(cfg)) if _ACTION > "vs2008" then _p(' %s', cs2005.arch(cfg)) end end function cs2005.generate(prj) io.eol = "\r\n" cs2005.projectelement(prj) cs2005.projectsettings(prj) for cfg in premake.eachconfig(prj) do cs2005.propertygroup(cfg) if cfg.flags.Symbols then _p(' true') _p(' full') else _p(' pdbonly') end _p(' %s', iif(cfg.flags.Optimize or cfg.flags.OptimizeSize or cfg.flags.OptimizeSpeed, "true", "false")) _p(' %s', cfg.buildtarget.directory) _p(' %s', table.concat(premake.esc(cfg.defines), ";")) _p(' prompt') _p(' 4') if cfg.flags.Unsafe then _p(' true') end if cfg.flags.FatalWarnings then _p(' true') end _p(' ') end _p(' ') for _, ref in ipairs(premake.getlinks(prj, "siblings", "object")) do _p(' ', path.translate(path.getrelative(prj.location, vstudio.projectfile(ref)), "\\")) _p(' {%s}', ref.uuid) _p(' %s', premake.esc(ref.name)) _p(' ') end for _, linkname in ipairs(premake.getlinks(prj, "system", "basename")) do _p(' ', premake.esc(linkname)) end _p(' ') _p(' ') cs2005.files(prj) _p(' ') _p(' ') _p(' ') _p('') end local cs2005 = premake.vstudio.cs2005 function cs2005.generate_user_ng(prj) print("** Warning: C# projects have not been ported yet") end function cs2005.generate_user(prj) io.eol = "\r\n" _p('') _p(' ') local refpaths = table.translate(prj.libdirs, function(v) return path.getabsolute(prj.location .. "/" .. v) end) _p(' %s', path.translate(table.concat(refpaths, ";"), "\\")) _p(' ') _p('') end premake.vstudio.vc2010 = { } local vc2010 = premake.vstudio.vc2010 local vstudio = premake.vstudio local project = premake5.project local config = premake5.config local tree = premake.tree function vc2010.generate_ng(prj) io.eol = "\r\n" io.indent = " " vc2010.header_ng("Build") vc2010.projectConfigurations(prj) vc2010.globals(prj) _p(1,'') for cfg in project.eachconfig(prj) do vc2010.configurationProperties(cfg) end _p(1,'') _p(1,'') _p(1,'') for cfg in project.eachconfig(prj) do vc2010.propertySheet(cfg) end _p(1,'') for cfg in project.eachconfig(prj) do vc2010.outputProperties(cfg) end for cfg in project.eachconfig(prj) do _p(1,'', vc2010.condition(cfg)) vc2010.clCompile(cfg) vc2010.resourceCompile(cfg) vc2010.link(cfg) vc2010.buildEvents(cfg) _p(1,'') end vc2010.files_ng(prj) vc2010.projectReferences_ng(prj) _p(1,'') _p(1,'') _p(1,'') _p('') end function vc2010.header_ng(target) _p('') local defaultTargets = "" if target then defaultTargets = string.format(' DefaultTargets="%s"', target) end _p('', defaultTargets) end function vc2010.projectConfigurations(prj) _p(1,'') for cfg in project.eachconfig(prj) do _x(2,'', vstudio.configname(cfg)) _x(3,'%s', vstudio.projectplatform(cfg)) _p(3,'%s', vstudio.architecture(cfg)) _p(2,'') end _p(1,'') end function vc2010.globals(prj) _p(1,'') _p(2,'{%s}', prj.uuid) if prj.flags.Managed then _p(2,'v4.0') _p(2,'ManagedCProj') else _p(2,'Win32Proj') end _p(2,'%s', prj.name) _p(1,'') end function vc2010.configurationProperties(cfg) _p(1,'', vc2010.condition(cfg)) _p(2,'%s', vc2010.config_type(cfg)) _p(2,'%s', tostring(premake.config.isdebugbuild(cfg))) if cfg.flags.MFC then _p(2,'%s', iif(cfg.flags.StaticRuntime, "Static", "Dynamic")) end if cfg.flags.Managed then _p(2,'true') end _p(2,'%s', iif(cfg.flags.Unicode, "Unicode", "MultiByte")) _p(1,'') end function vc2010.propertySheet(cfg) _p(1,'', vc2010.condition(cfg)) _p(2,'') _p(1,'') end function vc2010.outputProperties(cfg) local target = config.gettargetinfo(cfg) _p(1,'', vc2010.condition(cfg)) if cfg.kind ~= premake.STATICLIB then _p(2,'%s', tostring(premake.config.canincrementallink(cfg))) end if cfg.kind == premake.SHAREDLIB and cfg.flags.NoImportLib then _p(2,'true'); end local outdir = path.translate(target.directory) _x(2,'%s\\', outdir) if cfg.system == premake.XBOX360 then _x(2,'$(OutDir)%s', target.name) end local objdir = path.translate(config.getuniqueobjdir(cfg)) _x(2,'%s\\', objdir) _x(2,'%s', target.basename) _x(2,'%s', target.extension) if cfg.flags.NoManifest then _p(2,'false') end _p(1,'') end function vc2010.clCompile(cfg) _p(2,'') if not cfg.flags.NoPCH and cfg.pchheader then _p(3,'Use') _x(3,'%s', path.getname(cfg.pchheader)) else _p(3,'NotUsing') end _p(3,'Level%d', iif(cfg.flags.ExtraWarnings, 4, 3)) if premake.config.isdebugbuild(cfg) and cfg.flags.ExtraWarnings then _p(3,'true') end if cfg.flags.FatalWarnings then _p(3,'true') end vc2010.preprocessorDefinitions(cfg.defines) vc2010.additionalIncludeDirectories(cfg, cfg.includedirs) vc2010.debuginfo(cfg) if cfg.flags.Symbols and cfg.debugformat ~= "c7" then local filename = config.gettargetinfo(cfg).basename _p(3,'$(OutDir)%s.pdb', filename) end _p(3,'%s', vc2010.optimization(cfg)) if premake.config.isoptimizedbuild(cfg) then _p(3,'true') _p(3,'true') end local minimalRebuild = not premake.config.isoptimizedbuild(cfg) and not cfg.flags.NoMinimalRebuild and cfg.debugformat ~= premake.C7 if not minimalRebuild then _p(3,'false') end if cfg.flags.NoFramePointer then _p(3,'true') end if premake.config.isoptimizedbuild(cfg) then _p(3,'true') end if cfg.flags.StaticRuntime then _p(3,'%s', iif(premake.config.isdebugbuild(cfg), "MultiThreadedDebug", "MultiThreaded")) end if cfg.flags.NoExceptions then _p(3,'false') elseif cfg.flags.SEH then _p(3,'Async') end if cfg.flags.NoRTTI and not cfg.flags.Managed then _p(3,'false') end if cfg.flags.NativeWChar then _p(3,'true') elseif cfg.flags.NoNativeWChar then _p(3,'false') end if cfg.flags.FloatFast then _p(3,'Fast') elseif cfg.flags.FloatStrict and not cfg.flags.Managed then _p(3,'Strict') end if cfg.flags.EnableSSE2 then _p(3,'StreamingSIMDExtensions2') elseif cfg.flags.EnableSSE then _p(3,'StreamingSIMDExtensions') end if #cfg.buildoptions > 0 then local options = table.concat(cfg.buildoptions, " ") _x(3,'%s %%(AdditionalOptions)', options) end if cfg.project.language == "C" then _p(3,'CompileAsC') end _p(2,'') end function vc2010.resourceCompile(cfg) _p(2,'') vc2010.preprocessorDefinitions(table.join(cfg.defines, cfg.resdefines)) vc2010.additionalIncludeDirectories(cfg, table.join(cfg.includedirs, cfg.resincludedirs)) _p(2,'') end function vc2010.link(cfg) _p(2,'') local subsystem = iif(cfg.kind == premake.CONSOLEAPP, "Console", "Windows") _p(3,'%s', subsystem) _p(3,'%s', tostring(cfg.flags.Symbols ~= nil)) if premake.config.isoptimizedbuild(cfg) then _p(3,'true') _p(3,'true') end if cfg.kind ~= premake.STATICLIB then vc2010.link_dynamic(cfg) end _p(2,'') if cfg.kind == premake.STATICLIB then vc2010.link_static(cfg) end end function vc2010.link_dynamic(cfg) vc2010.additionalDependencies(cfg) vc2010.additionalLibraryDirectories(cfg) if vc2010.config_type(cfg) == "Application" and not cfg.flags.WinMain and not cfg.flags.Managed then _p(3,'mainCRTStartup') end vc2010.additionalLinkOptions(cfg) end function vc2010.link_static(cfg) _p(2,'') vc2010.additionalLinkOptions(cfg) _p(2,'') end function vc2010.buildEvents(cfg) function write(group, list) if #list > 0 then _p(2,'<%s>', group) _x(3,'%s', table.implode(list, "", "", "\r\n")) _p(2,'', group) end end write("PreBuildEvent", cfg.prebuildcommands) write("PreLinkEvent", cfg.prelinkcommands) write("PostBuildEvent", cfg.postbuildcommands) end function vc2010.files_ng(prj) vc2010.simplefilesgroup_ng(prj, "ClInclude") vc2010.compilerfilesgroup_ng(prj) vc2010.simplefilesgroup_ng(prj, "None") vc2010.simplefilesgroup_ng(prj, "ResourceCompile") vc2010.customBuildFilesGroup(prj) end function vc2010.simplefilesgroup_ng(prj, group) local files = vc2010.getfilegroup_ng(prj, group) if #files > 0 then _p(1,'') for _, file in ipairs(files) do _x(2,'<%s Include=\"%s\" />', group, path.translate(file.relpath)) end _p(1,'') end end function vc2010.compilerfilesgroup_ng(prj) local files = vc2010.getfilegroup_ng(prj, "ClCompile") if #files > 0 then _p(1,'') for _, file in ipairs(files) do _x(2,'', path.translate(file.relpath)) for cfg in project.eachconfig(prj) do local filecfg = config.getfileconfig(cfg, file.abspath) if not filecfg then _p(3,'true', vc2010.condition(cfg)) end if prj.pchsource == file.abspath and not cfg.flags.NoPCH then _p(3,'Create', vc2010.condition(cfg)) end end _p(2,'') end _p(1,'') end end function vc2010.customBuildFilesGroup(prj) local files = vc2010.getfilegroup_ng(prj, "CustomBuild") if #files > 0 then _p(1,'') for _, file in ipairs(files) do _x(2,'', path.translate(file.relpath)) _p(3,'Document') for cfg in project.eachconfig(prj) do local condition = vc2010.condition(cfg) local filecfg = config.getfileconfig(cfg, file.abspath) if filecfg and filecfg.buildrule then local commands = table.concat(filecfg.buildrule.commands,'\r\n') _p(3,'%s', condition, premake.esc(commands)) local outputs = table.concat(filecfg.buildrule.outputs, ' ') _p(3,'%s', condition, premake.esc(outputs)) end end _p(2,'') end _p(1,'') end end function vc2010.getfilegroup_ng(prj, group) local groups = prj.vc2010_file_groups if not groups then groups = { ClCompile = {}, ClInclude = {}, None = {}, ResourceCompile = {}, CustomBuild = {}, } prj.vc2010_file_groups = groups local tr = project.getsourcetree(prj) tree.traverse(tr, { onleaf = function(node) local hasbuildrule = false for cfg in project.eachconfig(prj) do local filecfg = config.getfileconfig(cfg, node.abspath) if filecfg and filecfg.buildrule then hasbuildrule = true break end end if hasbuildrule then table.insert(groups.CustomBuild, node) elseif path.iscppfile(node.name) then table.insert(groups.ClCompile, node) elseif path.iscppheader(node.name) then table.insert(groups.ClInclude, node) elseif path.isresourcefile(node.name) then table.insert(groups.ResourceCompile, node) else table.insert(groups.None, node) end end }) end return groups[group] end function vc2010.projectReferences_ng(prj) local deps = project.getdependencies(prj) if #deps > 0 then local prjpath = project.getlocation(prj) _p(1,'') for _, dep in ipairs(deps) do local relpath = path.getrelative(prjpath, vstudio.projectfile_ng(dep)) _x(2,'', path.translate(relpath)) _p(3,'{%s}', dep.uuid) _p(2,'') end _p(1,'') end end function vc2010.additionalDependencies(cfg) local links local toolset = premake.vstudio.vc200x.toolset(cfg) if toolset then links = toolset.getlinks(cfg, true) else links = config.getlinks(cfg, "system", "fullpath") end if #links > 0 then links = path.translate(table.concat(links, ";")) _x(3,'%s;%%(AdditionalDependencies)', links) end end function vc2010.additionalIncludeDirectories(cfg, includedirs) if #includedirs > 0 then local dirs = project.getrelative(cfg.project, includedirs) dirs = path.translate(table.concat(dirs, ";")) _x(3,'%s;%%(AdditionalIncludeDirectories)', dirs) end end function vc2010.additionalLibraryDirectories(cfg) if #cfg.libdirs > 0 then local dirs = project.getrelative(cfg.project, cfg.libdirs) dirs = path.translate(table.concat(dirs, ";")) _x(3,'%s;%%(AdditionalLibraryDirectories)', dirs) end end function vc2010.additionalLinkOptions(cfg) if #cfg.linkoptions > 0 then local opts = table.concat(cfg.linkoptions, " ") _x(3, '%s %%(AdditionalOptions)', opts) end end function vc2010.condition(cfg) return string.format('Condition="\'$(Configuration)|$(Platform)\'==\'%s\'"', premake.esc(vstudio.configname(cfg))) end function vc2010.config_type(cfg) local map = { SharedLib = "DynamicLibrary", StaticLib = "StaticLibrary", ConsoleApp = "Application", WindowedApp = "Application" } return map[cfg.kind] end function vc2010.debuginfo(cfg) local value if cfg.flags.Symbols then if cfg.debugformat == "c7" then value = "OldStyle" elseif cfg.architecture == "x64" or cfg.flags.Managed or premake.config.isoptimizedbuild(cfg) or cfg.flags.NoEditAndContinue then value = "ProgramDatabase" else value = "EditAndContinue" end end if value then _p(3,'%s', value) end end function vc2010.optimization(cfg) local result = "Disabled" for _, flag in ipairs(cfg.flags) do if flag == "Optimize" then result = "Full" elseif flag == "OptimizeSize" then result = "MinSpace" elseif flag == "OptimizeSpeed" then result = "MaxSpeed" end end return result end function vc2010.preprocessorDefinitions(defines) if #defines > 0 then defines = table.concat(defines, ";") _x(3,'%s;%%(PreprocessorDefinitions)', defines) end end local function vs2010_config(prj) _p(1,'') for _, cfginfo in ipairs(prj.solution.vstudio_configs) do _p(2,'', premake.esc(cfginfo.name)) _p(3,'%s',cfginfo.buildcfg) _p(3,'%s',cfginfo.platform) _p(2,'') end _p(1,'') end local function vs2010_globals(prj) _p(1,'') _p(2,'{%s}',prj.uuid) _p(2,'%s',prj.name) if prj.flags and prj.flags.Managed then _p(2,'v4.0') _p(2,'ManagedCProj') else _p(2,'Win32Proj') end _p(1,'') end local function if_config_and_platform() return 'Condition="\'$(Configuration)|$(Platform)\'==\'%s\'"' end local function optimisation(cfg) local result = "Disabled" for _, value in ipairs(cfg.flags) do if (value == "Optimize") then result = "Full" elseif (value == "OptimizeSize") then result = "MinSpace" elseif (value == "OptimizeSpeed") then result = "MaxSpeed" end end return result end function vc2010.configurationPropertyGroup(cfg, cfginfo) _p(1,'' , premake.esc(cfginfo.name)) _p(2,'%s',vc2010.config_type(cfg)) _p(2,'%s', iif(optimisation(cfg) == "Disabled","true","false")) _p(2,'%s',iif(cfg.flags.Unicode,"Unicode","MultiByte")) if cfg.flags.MFC then _p(2,'%s', iif(cfg.flags.StaticRuntime, "Static", "Dynamic")) end if cfg.flags.Managed then _p(2,'true') end _p(1,'') end local function import_props(prj) for _, cfginfo in ipairs(prj.solution.vstudio_configs) do local cfg = premake.getconfig(prj, cfginfo.src_buildcfg, cfginfo.src_platform) _p(1,'' ,premake.esc(cfginfo.name)) _p(2,'') _p(1,'') end end local function incremental_link(cfg,cfginfo) if cfg.kind ~= "StaticLib" then _p(2,'%s' ,premake.esc(cfginfo.name) ,tostring(premake.config.canincrementallink(cfg))) end end local function ignore_import_lib(cfg,cfginfo) if cfg.kind == "SharedLib" then local shouldIgnore = "false" if cfg.flags.NoImportLib then shouldIgnore = "true" end _p(2,'%s' ,premake.esc(cfginfo.name),shouldIgnore) end end local function intermediate_and_out_dirs(prj) _p(1,'') _p(2,'<_ProjectFileVersion>10.0.30319.1') for _, cfginfo in ipairs(prj.solution.vstudio_configs) do local cfg = premake.getconfig(prj, cfginfo.src_buildcfg, cfginfo.src_platform) _p(2,'%s\\' , premake.esc(cfginfo.name),premake.esc(cfg.buildtarget.directory) ) _p(2,'%s\\' , premake.esc(cfginfo.name), premake.esc(cfg.objectsdir)) _p(2,'%s' ,premake.esc(cfginfo.name),path.getbasename(cfg.buildtarget.name)) ignore_import_lib(cfg,cfginfo) incremental_link(cfg,cfginfo) if cfg.flags.NoManifest then _p(2,'false' ,premake.esc(cfginfo.name)) end end _p(1,'') end local function runtime(cfg) local runtime local flags = cfg.flags if premake.config.isdebugbuild(cfg) then runtime = iif(flags.StaticRuntime and not flags.Managed, "MultiThreadedDebug", "MultiThreadedDebugDLL") else runtime = iif(flags.StaticRuntime and not flags.Managed, "MultiThreaded", "MultiThreadedDLL") end return runtime end local function precompiled_header(cfg) if not cfg.flags.NoPCH and cfg.pchheader then _p(3,'Use') _p(3,'%s', path.getname(cfg.pchheader)) else _p(3,'') end end local function preprocessor(indent,cfg) if #cfg.defines > 0 then _p(indent,'%s;%%(PreprocessorDefinitions)' ,premake.esc(table.concat(cfg.defines, ";"))) else _p(indent,'') end end local function include_dirs(indent,cfg) if #cfg.includedirs > 0 then _p(indent,'%s;%%(AdditionalIncludeDirectories)' ,premake.esc(path.translate(table.concat(cfg.includedirs, ";"), '\\'))) end end local function resource_compile(cfg) _p(2,'') preprocessor(3,cfg) include_dirs(3,cfg) _p(2,'') end local function exceptions(cfg) if cfg.flags.NoExceptions then _p(2,'false') elseif cfg.flags.SEH then _p(2,'Async') end end local function rtti(cfg) if cfg.flags.NoRTTI and not cfg.flags.Managed then _p(3,'false') end end local function wchar_t_buildin(cfg) if cfg.flags.NativeWChar then _p(3,'true') elseif cfg.flags.NoNativeWChar then _p(3,'false') end end local function sse(cfg) if cfg.flags.EnableSSE then _p(3,'StreamingSIMDExtensions') elseif cfg.flags.EnableSSE2 then _p(3,'StreamingSIMDExtensions2') end end local function floating_point(cfg) if cfg.flags.FloatFast then _p(3,'Fast') elseif cfg.flags.FloatStrict and not cfg.flags.Managed then _p(3,'Strict') end end local function debug_info(cfg) local value = '' if cfg.flags.Symbols then if cfg.debugformat == "c7" then value = "OldStyle" elseif cfg.platform == "x64" or cfg.flags.Managed or premake.config.isoptimizedbuild(cfg) or cfg.flags.NoEditAndContinue then value = "ProgramDatabase" else value = "EditAndContinue" end end _p(3,'%s', value) end local function compile_language(cfg) if cfg.language == "C" then _p(3,'CompileAsC') end end function vc2010.clcompile_old(cfg) _p(2,'') if #cfg.buildoptions > 0 then _p(3,'%s %%(AdditionalOptions)', table.concat(premake.esc(cfg.buildoptions), " ")) end _p(3,'%s',optimisation(cfg)) include_dirs(3,cfg) preprocessor(3,cfg) local value = premake.config.isdebugbuild(cfg) and not cfg.flags.NoMinimalRebuild and cfg.debugformat ~= "c7" _p(3,'%s', tostring(value)) if not premake.config.isoptimizedbuild(cfg) then if not cfg.flags.Managed then _p(3,'EnableFastChecks') end if cfg.flags.ExtraWarnings then _p(3,'true') end else _p(3,'true') end _p(3,'%s', runtime(cfg)) _p(3,'true') precompiled_header(cfg) if cfg.flags.ExtraWarnings then _p(3,'Level4') else _p(3,'Level3') end if cfg.flags.FatalWarnings then _p(3,'true') end exceptions(cfg) rtti(cfg) wchar_t_buildin(cfg) sse(cfg) floating_point(cfg) debug_info(cfg) if cfg.flags.Symbols and cfg.debugformat ~= "c7" then _p(3,'$(OutDir)%s.pdb', path.getbasename(cfg.buildtarget.name)) end if cfg.flags.NoFramePointer then _p(3,'true') end compile_language(cfg) _p(2,'') end local function event_hooks(cfg) if #cfg.postbuildcommands> 0 then _p(2,'') _p(3,'%s',premake.esc(table.implode(cfg.postbuildcommands, "", "", "\r\n"))) _p(2,'') end if #cfg.prebuildcommands> 0 then _p(2,'') _p(3,'%s',premake.esc(table.implode(cfg.prebuildcommands, "", "", "\r\n"))) _p(2,'') end if #cfg.prelinkcommands> 0 then _p(2,'') _p(3,'%s',premake.esc(table.implode(cfg.prelinkcommands, "", "", "\r\n"))) _p(2,'') end end local function additional_options(indent,cfg) if #cfg.linkoptions > 0 then _p(indent,'%s %%(AdditionalOptions)', table.concat(premake.esc(cfg.linkoptions), " ")) end end local function link_target_machine(index,cfg) local platforms = {x32 = 'MachineX86', x64 = 'MachineX64'} if platforms[cfg.platform] then _p(index,'%s', platforms[cfg.platform]) end end local function item_def_lib(cfg) if cfg.kind == 'StaticLib' then _p(1,'') _p(2,'$(OutDir)%s',cfg.buildtarget.name) additional_options(2,cfg) link_target_machine(2,cfg) _p(1,'') end end local function import_lib(cfg) if cfg.kind == "SharedLib" then local implibname = cfg.linktarget.fullpath _p(3,'%s',iif(cfg.flags.NoImportLib, cfg.objectsdir .. "\\" .. path.getname(implibname), implibname)) end end function vc2010.link_old(cfg) _p(2,'') _p(3,'%s', iif(cfg.kind == "ConsoleApp", "Console", "Windows")) _p(3,'%s', tostring(cfg.flags.Symbols ~= nil)) if premake.config.isoptimizedbuild(cfg) then _p(3,'true') _p(3,'true') end if cfg.kind ~= 'StaticLib' then vc2010.additionalDependencies_old(cfg) _p(3,'$(OutDir)%s', cfg.buildtarget.name) if #cfg.libdirs > 0 then _p(3,'%s;%%(AdditionalLibraryDirectories)', premake.esc(path.translate(table.concat(cfg.libdirs, ';'), '\\'))) end if vc2010.config_type(cfg) == 'Application' and not cfg.flags.WinMain and not cfg.flags.Managed then _p(3,'mainCRTStartup') end import_lib(cfg) link_target_machine(3,cfg) additional_options(3,cfg) end _p(2,'') end function vc2010.additionalDependencies_old(cfg) local links = premake.getlinks(cfg, "system", "fullpath") if #links > 0 then _p(3,'%s;%%(AdditionalDependencies)', table.concat(links, ";")) end end local function item_definitions(prj) for _, cfginfo in ipairs(prj.solution.vstudio_configs) do local cfg = premake.getconfig(prj, cfginfo.src_buildcfg, cfginfo.src_platform) _p(1,'' ,premake.esc(cfginfo.name)) vc2010.clcompile_old(cfg) resource_compile(cfg) item_def_lib(cfg) vc2010.link_old(cfg) event_hooks(cfg) _p(1,'') end end function vc2010.getfilegroup(prj, group) local sortedfiles = prj.vc2010sortedfiles if not sortedfiles then sortedfiles = { ClCompile = {}, ClInclude = {}, None = {}, ResourceCompile = {}, } for file in premake.project.eachfile(prj) do if path.iscppfile(file.name) then table.insert(sortedfiles.ClCompile, file) elseif path.iscppheader(file.name) then table.insert(sortedfiles.ClInclude, file) elseif path.isresourcefile(file.name) then table.insert(sortedfiles.ResourceCompile, file) else table.insert(sortedfiles.None, file) end end prj.vc2010sortedfiles = sortedfiles end return sortedfiles[group] end function vc2010.files(prj) vc2010.simplefilesgroup(prj, "ClInclude") vc2010.compilerfilesgroup(prj) vc2010.simplefilesgroup(prj, "None") vc2010.simplefilesgroup(prj, "ResourceCompile") end function vc2010.simplefilesgroup(prj, section) local files = vc2010.getfilegroup(prj, section) if #files > 0 then _p(1,'') for _, file in ipairs(files) do _p(2,'<%s Include=\"%s\" />', section, path.translate(file.name, "\\")) end _p(1,'') end end function vc2010.compilerfilesgroup(prj) local configs = prj.solution.vstudio_configs local files = vc2010.getfilegroup(prj, "ClCompile") if #files > 0 then local config_mappings = {} for _, cfginfo in ipairs(configs) do local cfg = premake.getconfig(prj, cfginfo.src_buildcfg, cfginfo.src_platform) if cfg.pchheader and cfg.pchsource and not cfg.flags.NoPCH then config_mappings[cfginfo] = path.translate(cfg.pchsource, "\\") end end _p(1,'') for _, file in ipairs(files) do local translatedpath = path.translate(file.name, "\\") _p(2,'', translatedpath) for _, cfginfo in ipairs(configs) do if config_mappings[cfginfo] and translatedpath == config_mappings[cfginfo] then _p(3,'Create', premake.esc(cfginfo.name)) config_mappings[cfginfo] = nil --only one source file per pch end end _p(2,'') end _p(1,'') end end function vc2010.header(targets) io.eol = "\r\n" _p('') local t = "" if targets then t = ' DefaultTargets="' .. targets .. '"' end _p('', t) end function premake.vs2010_vcxproj(prj) io.indent = " " vc2010.header("Build") vs2010_config(prj) vs2010_globals(prj) _p(1,'') for _, cfginfo in ipairs(prj.solution.vstudio_configs) do local cfg = premake.getconfig(prj, cfginfo.src_buildcfg, cfginfo.src_platform) vc2010.configurationPropertyGroup(cfg, cfginfo) end _p(1,'') _p(1,'') _p(1,'') import_props(prj) _p(1,'') intermediate_and_out_dirs(prj) item_definitions(prj) vc2010.files(prj) vc2010.projectReferences(prj) _p(1,'') _p(1,'') _p(1,'') _p('') end function vc2010.projectReferences(prj) local deps = premake.getdependencies(prj) if #deps > 0 then local prjpath = project.getlocation(prj) _p(1,'') for _, dep in ipairs(deps) do local deppath = path.getrelative(prjpath, vstudio.projectfile(dep)) _p(2,'', path.translate(deppath, "\\")) _p(3,'{%s}', dep.uuid) _p(2,'') end _p(1,'') end end function vc2010.debugdir(cfg) if cfg.debugdir then _p(' %s', path.translate(cfg.debugdir, '\\')) _p(' WindowsLocalDebugger') end if cfg.debugargs then _p(' %s', table.concat(cfg.debugargs, " ")) end end function vc2010.debugenvs(cfg) if cfg.debugenvs and #cfg.debugenvs > 0 then _p(2,'%s%s',table.concat(cfg.debugenvs, "\n") ,iif(cfg.flags.DebugEnvsInherit,'\n$(LocalDebuggerEnvironment)','') ) if cfg.flags.DebugEnvsDontMerge then _p(2,'false') end end end function premake.vs2010_vcxproj_user(prj) io.indent = " " vc2010.header() for _, cfginfo in ipairs(prj.solution.vstudio_configs) do local cfg = premake.getconfig(prj, cfginfo.src_buildcfg, cfginfo.src_platform) _p(' ', premake.esc(cfginfo.name)) vc2010.debugdir(cfg) vc2010.debugenvs(cfg) _p(' ') end _p('') end local vstudio = premake.vstudio local vc2010 = premake.vstudio.vc2010 local project = premake5.project function vc2010.generate_user_ng(prj) io.eol = "\r\n" io.indent = " " vc2010.header_ng() for cfg in project.eachconfig(prj) do _p(1,'', vc2010.condition(cfg)) vc2010.debugsettings(cfg) _p(1,'') end _p('') end function vc2010.debugsettings(cfg) if cfg.debugdir then local dir = project.getrelative(cfg.project, cfg.debugdir) _x(2,'%s', path.translate(dir)) _p(2,'WindowsLocalDebugger') end if #cfg.debugargs > 0 then _x(2,'%s', table.concat(cfg.debugargs, " ")) end if #cfg.debugenvs > 0 then local envs = table.concat(cfg.debugenvs, "\n") if cfg.flags.DebugEnvsInherit then envs = envs .. "\n$(LocalDebuggerEnvironment)" end _p(2,'%s', envs) if cfg.flags.DebugEnvsDontMerge then _p(2,'false') end end end local vc2010 = premake.vstudio.vc2010 local project = premake5.project local tree = premake.tree function vc2010.generate_filters_ng(prj) io.eol = "\r\n" io.indent = " " vc2010.header_ng() vc2010.filters_uniqueidentifiers(prj) vc2010.filters_filegroup(prj, "None") vc2010.filters_filegroup(prj, "ClInclude") vc2010.filters_filegroup(prj, "ClCompile") vc2010.filters_filegroup(prj, "ResourceCompile") vc2010.filters_filegroup(prj, "CustomBuild") _p('') end function vc2010.filters_uniqueidentifiers(prj) local opened = false local tr = project.getsourcetree(prj) tree.traverse(tr, { onbranch = function(node, depth) if not opened then _p(1,'') opened = true end _x(2, '', path.translate(node.path)) _p(3, '{%s}', os.uuid()) _p(2, '') end }, false) if opened then _p(1,'') end end function vc2010.filters_filegroup(prj, group) local files = vc2010.getfilegroup_ng(prj, group) if #files > 0 then _p(1,'') for _, file in ipairs(files) do if file.parent.path then _p(2,'<%s Include=\"%s\">', group, path.translate(file.relpath)) _p(3,'%s', path.translate(file.parent.path)) _p(2,'', group) else _p(2,'<%s Include=\"%s\" />', group, path.translate(file.relpath)) end end _p(1,'') end end function vc2010.filteridgroup(prj) local filters = { } local filterfound = false for file in premake.project.eachfile(prj) do local folders = string.explode(file.vpath, "/", true) local path = "" for i = 1, #folders - 1 do if not filterfound then filterfound = true _p(1,'') end path = path .. folders[i] if not filters[path] then filters[path] = true _p(2, '', path) _p(3, '{%s}', os.uuid()) _p(2, '') end path = path .. "\\" end end if filterfound then _p(1,'') end end function vc2010.filefiltergroup(prj, section) local files = vc2010.getfilegroup(prj, section) if #files > 0 then _p(1,'') for _, file in ipairs(files) do local filter if file.name ~= file.vpath then filter = path.getdirectory(file.vpath) else filter = path.getdirectory(file.name) end if filter ~= "." then _p(2,'<%s Include=\"%s\">', section, path.translate(file.name, "\\")) _p(3,'%s', path.translate(filter, "\\")) _p(2,'', section) else _p(2,'<%s Include=\"%s\" />', section, path.translate(file.name, "\\")) end end _p(1,'') end end function vc2010.generate_filters(prj) io.indent = " " vc2010.header() vc2010.filteridgroup(prj) vc2010.filefiltergroup(prj, "None") vc2010.filefiltergroup(prj, "ClInclude") vc2010.filefiltergroup(prj, "ClCompile") vc2010.filefiltergroup(prj, "ResourceCompile") _p('') end premake.xcode = { } newaction { trigger = "xcode3", shortname = "Xcode 3", description = "Generate Apple Xcode 3 project files (experimental)", os = "macosx", valid_kinds = { "ConsoleApp", "WindowedApp", "SharedLib", "StaticLib" }, valid_languages = { "C", "C++" }, valid_tools = { cc = { "gcc" }, }, valid_platforms = { Native = "Native", x32 = "Native 32-bit", x64 = "Native 64-bit", Universal32 = "32-bit Universal", Universal64 = "64-bit Universal", Universal = "Universal", iPhone = "iPhone" }, default_platform = "Universal", onsolution = function(sln) premake.xcode.preparesolution(sln) end, onproject = function(prj) premake.generate(prj, "%%.xcodeproj/project.pbxproj", premake.xcode.project) end, oncleanproject = function(prj) premake.clean.directory(prj, "%%.xcodeproj") end, oncheckproject = function(prj) local last for cfg in premake.eachconfig(prj) do if last and last ~= cfg.kind then error("Project '" .. prj.name .. "' uses more than one target kind; not supported by Xcode", 0) end last = cfg.kind end end, } newaction { trigger = "xcode4", shortname = "Xcode 4", description = "Generate Apple Xcode 4 project files (experimental)", os = "macosx", valid_kinds = { "ConsoleApp", "WindowedApp", "SharedLib", "StaticLib" }, valid_languages = { "C", "C++" }, valid_tools = { cc = { "gcc" }, }, valid_platforms = { Native = "Native", x32 = "Native 32-bit", x64 = "Native 64-bit", Universal32 = "32-bit Universal", Universal64 = "64-bit Universal", Universal = "Universal", }, default_platform = "Universal", onsolution = function(sln) premake.generate(sln, "%%.xcworkspace/contents.xcworkspacedata", premake.xcode4.workspace_generate) end, onproject = function(prj) premake.generate(prj, "%%.xcodeproj/project.pbxproj", premake.xcode.project) end, oncleanproject = function(prj) premake.clean.directory(prj, "%%.xcodeproj") premake.clean.directory(prj, "%%.xcworkspace") end, oncheckproject = function(prj) local last for cfg in premake.eachconfig(prj) do if last and last ~= cfg.kind then error("Project '" .. prj.name .. "' uses more than one target kind; not supported by Xcode", 0) end last = cfg.kind end end, } local xcode = premake.xcode local tree = premake.tree function xcode.getbuildcategory(node) local categories = { [".a"] = "Frameworks", [".c"] = "Sources", [".cc"] = "Sources", [".cpp"] = "Sources", [".cxx"] = "Sources", [".dylib"] = "Frameworks", [".framework"] = "Frameworks", [".m"] = "Sources", [".mm"] = "Sources", [".strings"] = "Resources", [".nib"] = "Resources", [".xib"] = "Resources", [".icns"] = "Resources", [".png"] = "Resources", } return categories[path.getextension(node.name)] end function xcode.getconfigname(cfg) local name = cfg.name if #cfg.project.solution.xcode.platforms > 1 then name = name .. " " .. premake.action.current().valid_platforms[cfg.platform] end return name end function xcode.getfiletype(node) local types = { [".c"] = "sourcecode.c.c", [".cc"] = "sourcecode.cpp.cpp", [".cpp"] = "sourcecode.cpp.cpp", [".css"] = "text.css", [".cxx"] = "sourcecode.cpp.cpp", [".framework"] = "wrapper.framework", [".gif"] = "image.gif", [".h"] = "sourcecode.c.h", [".html"] = "text.html", [".lua"] = "sourcecode.lua", [".m"] = "sourcecode.c.objc", [".mm"] = "sourcecode.cpp.objc", [".nib"] = "wrapper.nib", [".pch"] = "sourcecode.c.h", [".plist"] = "text.plist.xml", [".strings"] = "text.plist.strings", [".xib"] = "file.xib", [".icns"] = "image.icns", } return types[path.getextension(node.path)] or "text" end function xcode.getproducttype(node) local types = { ConsoleApp = "com.apple.product-type.tool", WindowedApp = "com.apple.product-type.application", StaticLib = "com.apple.product-type.library.static", SharedLib = "com.apple.product-type.library.dynamic", } return types[node.cfg.kind] end function xcode.gettargettype(node) local types = { ConsoleApp = "\"compiled.mach-o.executable\"", WindowedApp = "wrapper.application", StaticLib = "archive.ar", SharedLib = "\"compiled.mach-o.dylib\"", } return types[node.cfg.kind] end function xcode.getxcodeprojname(prj) local fname = premake.project.getfilename(prj, "%%.xcodeproj") return fname end function xcode.isframework(fname) return (path.getextension(fname) == ".framework") end function xcode.newid() return string.format("%04X%04X%04X%04X%04X%04X", math.random(0, 32767), math.random(0, 32767), math.random(0, 32767), math.random(0, 32767), math.random(0, 32767), math.random(0, 32767)) end function xcode.preparesolution(sln) sln.xcode = { } sln.xcode.platforms = premake.filterplatforms(sln, premake.action.current().valid_platforms, "Universal") for prj in premake.solution.eachproject(sln) do local cfg = premake.getconfig(prj, prj.configurations[1], sln.xcode.platforms[1]) local node = premake.tree.new(path.getname(cfg.buildtarget.bundlepath)) node.cfg = cfg node.id = premake.xcode.newid(node, "product") node.targetid = premake.xcode.newid(node, "target") prj.xcode = {} prj.xcode.projectnode = node end end function xcode.printlist(list, tag, cfg) if xcode.BuildSettingsExists(tag, cfg) then return -- Don't write settings end if #list > 0 then _p(4,'%s = (', tag) for _, item in ipairs(list) do _p(5, '"%s",', item) end _p(4,');') end end function xcode.BuildSettingsExists(buildsettingName, cfg) if #cfg.xcodebuildsettings > 0 then for _, item in ipairs(cfg.xcodebuildsettings) do local _, k = string.find(item, "=") local itemName = string.sub(item, 1, k - 1) itemName = string.gsub(itemName, "%s", "") end end return false end function xcodePrintUserSettings(offset, cfg) for _, item in ipairs(cfg.xcodebuildsettings) do _p(offset, item .. ';') end end function xcode.PrintBuildSetting(offset, buildsetting, cfg) if #cfg.xcodebuildsettings > 0 then local _, j = string.find(buildsetting, "=") local buildsettingName = string.sub(buildsetting, 1, j - 1) buildsettingName = string.gsub(buildsettingName, "%s", "") if xcode.BuildSettingsExists(buildsettingName, cfg) then return end end _p(offset, buildsetting) end function xcode.Header() _p('// !$*UTF8*$!') _p('{') _p(1,'archiveVersion = 1;') _p(1,'classes = {') _p(1,'};') _p(1,'objectVersion = 45;') _p(1,'objects = {') _p('') end function xcode.PBXBuildFile(tr) _p('/* Begin PBXBuildFile section */') tree.traverse(tr, { onnode = function(node) if node.buildid then _p(2,'%s /* %s in %s */ = {isa = PBXBuildFile; fileRef = %s /* %s */; };', node.buildid, node.name, xcode.getbuildcategory(node), node.id, node.name) end end }) _p('/* End PBXBuildFile section */') _p('') end function xcode.PBXContainerItemProxy(tr) if #tr.projects.children > 0 then _p('/* Begin PBXContainerItemProxy section */') for _, node in ipairs(tr.projects.children) do _p(2,'%s /* PBXContainerItemProxy */ = {', node.productproxyid) _p(3,'isa = PBXContainerItemProxy;') _p(3,'containerPortal = %s /* %s */;', node.id, path.getname(node.path)) _p(3,'proxyType = 2;') _p(3,'remoteGlobalIDString = %s;', node.project.xcode.projectnode.id) _p(3,'remoteInfo = "%s";', node.project.xcode.projectnode.name) _p(2,'};') _p(2,'%s /* PBXContainerItemProxy */ = {', node.targetproxyid) _p(3,'isa = PBXContainerItemProxy;') _p(3,'containerPortal = %s /* %s */;', node.id, path.getname(node.path)) _p(3,'proxyType = 1;') _p(3,'remoteGlobalIDString = %s;', node.project.xcode.projectnode.targetid) _p(3,'remoteInfo = "%s";', node.project.xcode.projectnode.name) _p(2,'};') end _p('/* End PBXContainerItemProxy section */') _p('') end end function xcode.PBXFileReference(tr) _p('/* Begin PBXFileReference section */') tree.traverse(tr, { onleaf = function(node) if not node.path then return end if node.kind == "product" then _p(2,'%s /* %s */ = {isa = PBXFileReference; explicitFileType = %s; includeInIndex = 0; name = "%s"; path = "%s"; sourceTree = BUILT_PRODUCTS_DIR; };', node.id, node.name, xcode.gettargettype(node), node.name, path.getname(node.cfg.buildtarget.bundlepath)) elseif node.parent.parent == tr.projects then local relpath = path.getrelative(tr.project.location, node.parent.project.location) _p(2,'%s /* %s */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "%s"; path = "%s"; sourceTree = SOURCE_ROOT; };', node.parent.id, node.parent.name, node.parent.name, path.join(relpath, node.parent.name)) else local pth, src if xcode.isframework(node.path) then if string.find(node.path,'/') then if string.find(node.path,'^%.')then error('relative paths are not currently supported for frameworks') end pth = node.path else pth = "/System/Library/Frameworks/" .. node.path end src = "absolute" else src = "group" if node.parent.isvpath then pth = node.cfg.name else pth = tree.getlocalpath(node) end end _p(2,'%s /* %s */ = {isa = PBXFileReference; lastKnownFileType = %s; name = "%s"; path = "%s"; sourceTree = "<%s>"; };', node.id, node.name, xcode.getfiletype(node), node.name, pth, src) end end }) _p('/* End PBXFileReference section */') _p('') end function xcode.PBXFrameworksBuildPhase(tr) _p('/* Begin PBXFrameworksBuildPhase section */') _p(2,'%s /* Frameworks */ = {', tr.products.children[1].fxstageid) _p(3,'isa = PBXFrameworksBuildPhase;') _p(3,'buildActionMask = 2147483647;') _p(3,'files = (') tree.traverse(tr.frameworks, { onleaf = function(node) _p(4,'%s /* %s in Frameworks */,', node.buildid, node.name) end }) tree.traverse(tr.projects, { onleaf = function(node) _p(4,'%s /* %s in Frameworks */,', node.buildid, node.name) end }) _p(3,');') _p(3,'runOnlyForDeploymentPostprocessing = 0;') _p(2,'};') _p('/* End PBXFrameworksBuildPhase section */') _p('') end function xcode.PBXGroup(tr) _p('/* Begin PBXGroup section */') tree.traverse(tr, { onnode = function(node) if (node.path and #node.children == 0) or node.kind == "vgroup" then return end if node.parent == tr.projects then _p(2,'%s /* Products */ = {', node.productgroupid) else _p(2,'%s /* %s */ = {', node.id, node.name) end _p(3,'isa = PBXGroup;') _p(3,'children = (') for _, childnode in ipairs(node.children) do _p(4,'%s /* %s */,', childnode.id, childnode.name) end _p(3,');') if node.parent == tr.projects then _p(3,'name = Products;') else _p(3,'name = "%s";', node.name) if node.path and not node.isvpath then local p = node.path if node.parent.path then p = path.getrelative(node.parent.path, node.path) end _p(3,'path = "%s";', p) end end _p(3,'sourceTree = "";') _p(2,'};') end }, true) _p('/* End PBXGroup section */') _p('') end function xcode.PBXNativeTarget(tr) _p('/* Begin PBXNativeTarget section */') for _, node in ipairs(tr.products.children) do local name = tr.project.name _p(2,'%s /* %s */ = {', node.targetid, name) _p(3,'isa = PBXNativeTarget;') _p(3,'buildConfigurationList = %s /* Build configuration list for PBXNativeTarget "%s" */;', node.cfgsection, name) _p(3,'buildPhases = (') if #tr.project.prebuildcommands > 0 then _p(4,'9607AE1010C857E500CD1376 /* Prebuild */,') end _p(4,'%s /* Resources */,', node.resstageid) _p(4,'%s /* Sources */,', node.sourcesid) if #tr.project.prelinkcommands > 0 then _p(4,'9607AE3510C85E7E00CD1376 /* Prelink */,') end _p(4,'%s /* Frameworks */,', node.fxstageid) if #tr.project.postbuildcommands > 0 then _p(4,'9607AE3710C85E8F00CD1376 /* Postbuild */,') end _p(3,');') _p(3,'buildRules = (') _p(3,');') _p(3,'dependencies = (') for _, node in ipairs(tr.projects.children) do _p(4,'%s /* PBXTargetDependency */,', node.targetdependid) end _p(3,');') _p(3,'name = "%s";', name) local p if node.cfg.kind == "ConsoleApp" then p = "$(HOME)/bin" elseif node.cfg.kind == "WindowedApp" then p = "$(HOME)/Applications" end if p then _p(3,'productInstallPath = "%s";', p) end _p(3,'productName = "%s";', name) _p(3,'productReference = %s /* %s */;', node.id, node.name) _p(3,'productType = "%s";', xcode.getproducttype(node)) _p(2,'};') end _p('/* End PBXNativeTarget section */') _p('') end function xcode.PBXProject(tr) _p('/* Begin PBXProject section */') _p(2,'08FB7793FE84155DC02AAC07 /* Project object */ = {') _p(3,'isa = PBXProject;') _p(3,'buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "%s" */;', tr.name) _p(3,'compatibilityVersion = "Xcode 3.2";') _p(3,'hasScannedForEncodings = 1;') _p(3,'mainGroup = %s /* %s */;', tr.id, tr.name) _p(3,'projectDirPath = "";') if #tr.projects.children > 0 then _p(3,'projectReferences = (') for _, node in ipairs(tr.projects.children) do _p(4,'{') _p(5,'ProductGroup = %s /* Products */;', node.productgroupid) _p(5,'ProjectRef = %s /* %s */;', node.id, path.getname(node.path)) _p(4,'},') end _p(3,');') end _p(3,'projectRoot = "";') _p(3,'targets = (') for _, node in ipairs(tr.products.children) do _p(4,'%s /* %s */,', node.targetid, node.name) end _p(3,');') _p(2,'};') _p('/* End PBXProject section */') _p('') end function xcode.PBXReferenceProxy(tr) if #tr.projects.children > 0 then _p('/* Begin PBXReferenceProxy section */') tree.traverse(tr.projects, { onleaf = function(node) _p(2,'%s /* %s */ = {', node.id, node.name) _p(3,'isa = PBXReferenceProxy;') _p(3,'fileType = %s;', xcode.gettargettype(node)) _p(3,'path = "%s";', node.path) _p(3,'remoteRef = %s /* PBXContainerItemProxy */;', node.parent.productproxyid) _p(3,'sourceTree = BUILT_PRODUCTS_DIR;') _p(2,'};') end }) _p('/* End PBXReferenceProxy section */') _p('') end end function xcode.PBXResourcesBuildPhase(tr) _p('/* Begin PBXResourcesBuildPhase section */') for _, target in ipairs(tr.products.children) do _p(2,'%s /* Resources */ = {', target.resstageid) _p(3,'isa = PBXResourcesBuildPhase;') _p(3,'buildActionMask = 2147483647;') _p(3,'files = (') tree.traverse(tr, { onnode = function(node) if xcode.getbuildcategory(node) == "Resources" then _p(4,'%s /* %s in Resources */,', node.buildid, node.name) end end }) _p(3,');') _p(3,'runOnlyForDeploymentPostprocessing = 0;') _p(2,'};') end _p('/* End PBXResourcesBuildPhase section */') _p('') end function xcode.PBXShellScriptBuildPhase(tr) local wrapperWritten = false local function doblock(id, name, which) local prjcmds = tr.project[which] local commands = table.join(prjcmds, {}) for _, cfg in ipairs(tr.configs) do local cfgcmds = cfg[which] if #cfgcmds > #prjcmds then table.insert(commands, 'if [ "${CONFIGURATION}" = "' .. xcode.getconfigname(cfg) .. '" ]; then') for i = #prjcmds + 1, #cfgcmds do table.insert(commands, cfgcmds[i]) end table.insert(commands, 'fi') end end if #commands > 0 then if not wrapperWritten then _p('/* Begin PBXShellScriptBuildPhase section */') wrapperWritten = true end _p(2,'%s /* %s */ = {', id, name) _p(3,'isa = PBXShellScriptBuildPhase;') _p(3,'buildActionMask = 2147483647;') _p(3,'files = (') _p(3,');') _p(3,'inputPaths = ('); _p(3,');'); _p(3,'name = %s;', name); _p(3,'outputPaths = ('); _p(3,');'); _p(3,'runOnlyForDeploymentPostprocessing = 0;'); _p(3,'shellPath = /bin/sh;'); _p(3,'shellScript = "%s";', table.concat(commands, "\\n"):gsub('"', '\\"')) _p(2,'};') end end doblock("9607AE1010C857E500CD1376", "Prebuild", "prebuildcommands") doblock("9607AE3510C85E7E00CD1376", "Prelink", "prelinkcommands") doblock("9607AE3710C85E8F00CD1376", "Postbuild", "postbuildcommands") if wrapperWritten then _p('/* End PBXShellScriptBuildPhase section */') end end function xcode.PBXSourcesBuildPhase(tr) _p('/* Begin PBXSourcesBuildPhase section */') for _, target in ipairs(tr.products.children) do _p(2,'%s /* Sources */ = {', target.sourcesid) _p(3,'isa = PBXSourcesBuildPhase;') _p(3,'buildActionMask = 2147483647;') _p(3,'files = (') tree.traverse(tr, { onleaf = function(node) if xcode.getbuildcategory(node) == "Sources" then _p(4,'%s /* %s in Sources */,', node.buildid, node.name) end end }) _p(3,');') _p(3,'runOnlyForDeploymentPostprocessing = 0;') _p(2,'};') end _p('/* End PBXSourcesBuildPhase section */') _p('') end function xcode.PBXVariantGroup(tr) _p('/* Begin PBXVariantGroup section */') tree.traverse(tr, { onbranch = function(node) if node.kind == "vgroup" then _p(2,'%s /* %s */ = {', node.id, node.name) _p(3,'isa = PBXVariantGroup;') _p(3,'children = (') for _, lang in ipairs(node.children) do _p(4,'%s /* %s */,', lang.id, lang.name) end _p(3,');') _p(3,'name = %s;', node.name) _p(3,'sourceTree = "";') _p(2,'};') end end }) _p('/* End PBXVariantGroup section */') _p('') end function xcode.PBXTargetDependency(tr) if #tr.projects.children > 0 then _p('/* Begin PBXTargetDependency section */') tree.traverse(tr.projects, { onleaf = function(node) _p(2,'%s /* PBXTargetDependency */ = {', node.parent.targetdependid) _p(3,'isa = PBXTargetDependency;') _p(3,'name = "%s";', node.name) _p(3,'targetProxy = %s /* PBXContainerItemProxy */;', node.parent.targetproxyid) _p(2,'};') end }) _p('/* End PBXTargetDependency section */') _p('') end end function xcode.XCBuildConfiguration_Target(tr, target, cfg) local cfgname = xcode.getconfigname(cfg) _p(2,'%s /* %s */ = {', cfg.xcode.targetid, cfgname) _p(3,'isa = XCBuildConfiguration;') _p(3,'buildSettings = {') xcodePrintUserSettings(4, cfg) xcode.PrintBuildSetting(4,'ALWAYS_SEARCH_USER_PATHS = NO;', cfg) if not cfg.flags.Symbols then xcode.PrintBuildSetting(4,'DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";', cfg) end if cfg.kind ~= "StaticLib" and cfg.buildtarget.prefix ~= "" then xcode.PrintBuildSetting(4,'EXECUTABLE_PREFIX = '.. cfg.buildtarget.prefix .. ';', cfg) end local outdir = path.getdirectory(cfg.buildtarget.bundlepath) if outdir ~= "." then xcode.PrintBuildSetting(4,'CONFIGURATION_BUILD_DIR = "' .. outdir .. '";', cfg) end xcode.PrintBuildSetting(4,'GCC_DYNAMIC_NO_PIC = NO;',cfg) xcode.PrintBuildSetting(4,'GCC_MODEL_TUNING = G5;', cfg) if tr.infoplist then xcode.PrintBuildSetting( 4,'INFOPLIST_FILE = "' .. tr.infoplist.path .. '";', cfg) end installpaths = { ConsoleApp = '/usr/local/bin', WindowedApp = '"$(HOME)/Applications"', SharedLib = '/usr/local/lib', StaticLib = '/usr/local/lib', } xcode.PrintBuildSetting(4,'INSTALL_PATH = ' .. installpaths[cfg.kind] .. ';', cfg) xcode.PrintBuildSetting(4,'PRODUCT_NAME = "' .. cfg.buildtarget.basename .. '";', cfg) _p(3,'};') _p(3,'name = "%s";', cfgname) _p(2,'};') end function xcode.XCBuildConfiguration_Project(tr, cfg) local cfgname = xcode.getconfigname(cfg) _p(2,'%s /* %s */ = {', cfg.xcode.projectid, cfgname) _p(3,'isa = XCBuildConfiguration;') _p(3,'buildSettings = {') xcodePrintUserSettings(4, cfg) local archs = { Native = "$(NATIVE_ARCH_ACTUAL)", x32 = "i386", x64 = "x86_64", Universal32 = "$(ARCHS_STANDARD_32_BIT)", Universal64 = "$(ARCHS_STANDARD_64_BIT)", Universal = "$(ARCHS_STANDARD_32_64_BIT)", iPhone = '(armv6, armv7)', } if cfg.platform:lower() == "iphone" then xcode.PrintBuildSetting(4,'SDKROOT = iphoneos;', cfg) else xcode.PrintBuildSetting(4,'SDKROOT = macosx;', cfg) end xcode.PrintBuildSetting(4,'ARCHS = "'.. archs[cfg.platform] ..'";', cfg) local targetdir = path.getdirectory(cfg.buildtarget.bundlepath) if targetdir ~= "." then xcode.PrintBuildSetting(4,'CONFIGURATION_BUILD_DIR = "$(SYMROOT)";', cfg); end xcode.PrintBuildSetting(4, 'CONFIGURATION_TEMP_DIR = "$(OBJROOT)";', cfg) if cfg.flags.Symbols then xcode.PrintBuildSetting(4,'COPY_PHASE_STRIP = NO;', cfg) end xcode.PrintBuildSetting(4,'GCC_C_LANGUAGE_STANDARD = gnu99;', cfg) if cfg.flags.NoExceptions then xcode.PrintBuildSetting(4,'GCC_ENABLE_CPP_EXCEPTIONS = NO;', cfg) end if cfg.flags.NoRTTI then xcode.PrintBuildSetting( 4,'GCC_ENABLE_CPP_RTTI = NO;', cfg) end if _ACTION ~= "xcode4" and cfg.flags.Symbols and not cfg.flags.NoEditAndContinue then xcode.PrintBuildSetting(4,'GCC_ENABLE_FIX_AND_CONTINUE = YES;', cfg) end if cfg.flags.NoExceptions then xcode.PrintBuildSetting(4,'GCC_ENABLE_OBJC_EXCEPTIONS = NO;', cfg) end if cfg.flags.Optimize or cfg.flags.OptimizeSize then xcode.PrintBuildSetting(4,'GCC_OPTIMIZATION_LEVEL = s;', cfg) elseif cfg.flags.OptimizeSpeed then xcode.PrintBuildSetting(4,'GCC_OPTIMIZATION_LEVEL = 3;', cfg) else xcode.PrintBuildSetting(4,'GCC_OPTIMIZATION_LEVEL = 0;', cfg) end if cfg.pchheader and not cfg.flags.NoPCH then xcode.PrintBuildSetting(4,'GCC_PRECOMPILE_PREFIX_HEADER = YES;', cfg) xcode.PrintBuildSetting(4,'GCC_PREFIX_HEADER = "' .. cfg.pchheader .. '";', cfg) end xcode.printlist(cfg.defines, 'GCC_PREPROCESSOR_DEFINITIONS',cfg) xcode.PrintBuildSetting(4,'GCC_SYMBOLS_PRIVATE_EXTERN = NO;', cfg) if cfg.flags.FatalWarnings then xcode.PrintBuildSetting(4,'GCC_TREAT_WARNINGS_AS_ERRORS = YES;', cfg) end xcode.PrintBuildSetting(4,'GCC_WARN_ABOUT_RETURN_TYPE = YES;', cfg) xcode.PrintBuildSetting(4,'GCC_WARN_UNUSED_VARIABLE = YES;', cfg) xcode.printlist(cfg.includedirs, 'HEADER_SEARCH_PATHS',cfg) xcode.printlist(cfg.libdirs, 'LIBRARY_SEARCH_PATHS',cfg) xcode.PrintBuildSetting(4,'OBJROOT = "' .. cfg.objectsdir .. '";', cfg) xcode.PrintBuildSetting(4,'ONLY_ACTIVE_ARCH = '.. iif(premake.config.isdebugbuild(cfg),'YES','NO') ..';', cfg) local checks = { ["-ffast-math"] = cfg.flags.FloatFast, ["-ffloat-store"] = cfg.flags.FloatStrict, ["-fomit-frame-pointer"] = cfg.flags.NoFramePointer, } local flags = { } for flag, check in pairs(checks) do if check then table.insert(flags, flag) end end xcode.printlist(table.join(flags, cfg.buildoptions), 'OTHER_CFLAGS',cfg) flags = { } for _, lib in ipairs(premake.getlinks(cfg, "system")) do if not xcode.isframework(lib) then table.insert(flags, "-l" .. lib) end end flags = table.join(flags, cfg.linkoptions) xcode.printlist(flags, 'OTHER_LDFLAGS',cfg) if cfg.flags.StaticRuntime then xcode.PrintBuildSetting(4, 'STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = static;', cfg) end if targetdir ~= "." then xcode.PrintBuildSetting(4,'SYMROOT = "' .. targetdir .. '";', cfg) end if cfg.flags.ExtraWarnings then xcode.PrintBuildSetting(4,'WARNING_CFLAGS = "-Wall";', cfg) end _p(3,'};') _p(3,'name = "%s";', cfgname) _p(2,'};') end function xcode.XCBuildConfiguration(tr) _p('/* Begin XCBuildConfiguration section */') for _, target in ipairs(tr.products.children) do for _, cfg in ipairs(tr.configs) do xcode.XCBuildConfiguration_Target(tr, target, cfg) end end for _, cfg in ipairs(tr.configs) do xcode.XCBuildConfiguration_Project(tr, cfg) end _p('/* End XCBuildConfiguration section */') _p('') end function xcode.XCBuildConfigurationList(tr) local sln = tr.project.solution _p('/* Begin XCConfigurationList section */') for _, target in ipairs(tr.products.children) do _p(2,'%s /* Build configuration list for PBXNativeTarget "%s" */ = {', target.cfgsection, target.name) _p(3,'isa = XCConfigurationList;') _p(3,'buildConfigurations = (') for _, cfg in ipairs(tr.configs) do _p(4,'%s /* %s */,', cfg.xcode.targetid, xcode.getconfigname(cfg)) end _p(3,');') _p(3,'defaultConfigurationIsVisible = 0;') _p(3,'defaultConfigurationName = "%s";', xcode.getconfigname(tr.configs[1])) _p(2,'};') end _p(2,'1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "%s" */ = {', tr.name) _p(3,'isa = XCConfigurationList;') _p(3,'buildConfigurations = (') for _, cfg in ipairs(tr.configs) do _p(4,'%s /* %s */,', cfg.xcode.projectid, xcode.getconfigname(cfg)) end _p(3,');') _p(3,'defaultConfigurationIsVisible = 0;') _p(3,'defaultConfigurationName = "%s";', xcode.getconfigname(tr.configs[1])) _p(2,'};') _p('/* End XCConfigurationList section */') _p('') end function xcode.Footer() _p(1,'};') _p('\trootObject = 08FB7793FE84155DC02AAC07 /* Project object */;') _p('}') end local xcode = premake.xcode local tree = premake.tree function xcode.buildprjtree(prj) local tr = premake.project.buildsourcetree(prj) tr.configs = {} for _, cfgname in ipairs(prj.solution.configurations) do for _, platform in ipairs(prj.solution.xcode.platforms) do local cfg = premake.getconfig(prj, cfgname, platform) cfg.xcode = {} cfg.xcode.targetid = xcode.newid(prj.xcode.projectnode, cfgname) cfg.xcode.projectid = xcode.newid(tr, cfgname) table.insert(tr.configs, cfg) end end tree.traverse(tr, { onbranch = function(node) if path.getextension(node.name) == ".lproj" then local lang = path.getbasename(node.name) -- "English", "French", etc. for _, filenode in ipairs(node.children) do local grpnode = node.parent.children[filenode.name] if not grpnode then grpnode = tree.insert(node.parent, tree.new(filenode.name)) grpnode.kind = "vgroup" end filenode.name = path.getbasename(lang) tree.insert(grpnode, filenode) end tree.remove(node) end end }) tr.frameworks = tree.new("Frameworks") for cfg in premake.eachconfig(prj) do for _, link in ipairs(premake.getlinks(cfg, "system", "fullpath")) do local name = path.getname(link) if xcode.isframework(name) and not tr.frameworks.children[name] then node = tree.insert(tr.frameworks, tree.new(name)) node.path = link end end end if #tr.frameworks.children > 0 then tree.insert(tr, tr.frameworks) end tr.products = tree.insert(tr, tree.new("Products")) tr.projects = tree.new("Projects") for _, dep in ipairs(premake.getdependencies(prj, "sibling", "object")) do local xcpath = xcode.getxcodeprojname(dep) local xcnode = tree.insert(tr.projects, tree.new(path.getname(xcpath))) xcnode.path = xcpath xcnode.project = dep xcnode.productgroupid = xcode.newid(xcnode, "prodgrp") xcnode.productproxyid = xcode.newid(xcnode, "prodprox") xcnode.targetproxyid = xcode.newid(xcnode, "targprox") xcnode.targetdependid = xcode.newid(xcnode, "targdep") local cfg = premake.getconfig(dep, prj.configurations[1]) node = tree.insert(xcnode, tree.new(cfg.linktarget.name)) node.path = cfg.linktarget.fullpath node.cfg = cfg end if #tr.projects.children > 0 then tree.insert(tr, tr.projects) end tree.traverse(tr, { onnode = function(node) node.id = xcode.newid(node) if xcode.getbuildcategory(node) then node.buildid = xcode.newid(node, "build") end if string.endswith(node.name, "Info.plist") then tr.infoplist = node end end }, true) node = tree.insert(tr.products, prj.xcode.projectnode) node.kind = "product" node.path = node.cfg.buildtarget.fullpath node.cfgsection = xcode.newid(node, "cfg") node.resstageid = xcode.newid(node, "rez") node.sourcesid = xcode.newid(node, "src") node.fxstageid = xcode.newid(node, "fxs") return tr end function premake.xcode.project(prj) local tr = xcode.buildprjtree(prj) xcode.Header(tr) xcode.PBXBuildFile(tr) xcode.PBXContainerItemProxy(tr) xcode.PBXFileReference(tr) xcode.PBXFrameworksBuildPhase(tr) xcode.PBXGroup(tr) xcode.PBXNativeTarget(tr) xcode.PBXProject(tr) xcode.PBXReferenceProxy(tr) xcode.PBXResourcesBuildPhase(tr) xcode.PBXShellScriptBuildPhase(tr) xcode.PBXSourcesBuildPhase(tr) xcode.PBXVariantGroup(tr) xcode.PBXTargetDependency(tr) xcode.XCBuildConfiguration(tr) xcode.XCBuildConfigurationList(tr) xcode.Footer(tr) end premake.xcode4 = {} local xcode4 = premake.xcode4 function xcode4.workspace_head() _p('') _p('') end function xcode4.workspace_tail() _p('') end function xcode4.workspace_file_ref(prj) local projpath = path.getrelative(prj.solution.location, prj.location) if projpath == '.' then projpath = '' else projpath = projpath ..'/' end _p(1,'',projpath .. prj.name .. '.xcodeproj') _p(1,'') end function xcode4.workspace_generate(sln) premake.xcode.preparesolution(sln) xcode4.workspace_head() for prj in premake.solution.eachproject(sln) do xcode4.workspace_file_ref(prj) end xcode4.workspace_tail() end premake.clean = { } function premake.clean.directory(obj, pattern) local fname = premake.project.getfilename(obj, pattern) os.rmdir(fname) end function premake.clean.file(obj, pattern) local fname = premake.project.getfilename(obj, pattern) os.remove(fname) end newaction { trigger = "clean", description = "Remove all binaries and generated files", onsolution = function(sln) for action in premake.action.each() do if action.oncleansolution then action.oncleansolution(sln) end end end, onproject = function(prj) for action in premake.action.each() do if action.oncleanproject then action.oncleanproject(prj) end end if (prj.objectsdir) then premake.clean.directory(prj, prj.objectsdir) end local platforms = prj.solution.platforms or { } if not table.contains(platforms, "Native") then platforms = table.join(platforms, { "Native" }) end for _, platform in ipairs(platforms) do for cfg in premake.eachconfig(prj, platform) do premake.clean.directory(prj, cfg.objectsdir) premake.clean.file(prj, premake.gettarget(cfg, "build", "posix", "windows", "windows").fullpath) premake.clean.file(prj, premake.gettarget(cfg, "build", "posix", "posix", "linux").fullpath) premake.clean.file(prj, premake.gettarget(cfg, "build", "posix", "posix", "macosx").fullpath) premake.clean.file(prj, premake.gettarget(cfg, "build", "posix", "PS3", "windows").fullpath) if cfg.kind == "WindowedApp" then premake.clean.directory(prj, premake.gettarget(cfg, "build", "posix", "posix", "linux").fullpath .. ".app") end premake.clean.file(prj, premake.gettarget(cfg, "link", "windows", "windows", "windows").fullpath) premake.clean.file(prj, premake.gettarget(cfg, "link", "posix", "posix", "linux").fullpath) local target = path.join(premake.project.getfilename(prj, cfg.buildtarget.directory), cfg.buildtarget.basename) for action in premake.action.each() do if action.oncleantarget then action.oncleantarget(target) end end end end end } local scriptfile = "premake4.lua" local shorthelp = "Type 'premake4 --help' for help" local versionhelp = "premake4 (Premake Build Script Generator) %s" _WORKING_DIR = os.getcwd() local function injectplatform(platform) if not platform then return true end platform = premake.checkvalue(platform, premake.fields.platforms.allowed) for sln in premake.solution.each() do local platforms = sln.platforms or { } if #platforms == 0 then table.insert(platforms, "Native") end if not table.contains(platforms, "Native") then return false, sln.name .. " does not target native platform\nNative platform settings are required for the --platform feature." end if not table.contains(platforms, platform) then table.insert(platforms, platform) end sln.platforms = platforms end return true end function _premake_main(scriptpath) if (scriptpath) then local scripts = dofile(scriptpath .. "/_manifest.lua") for _,v in ipairs(scripts) do dofile(scriptpath .. "/" .. v) end end premake.action.set(_ACTION) math.randomseed(os.time()) local fname = _OPTIONS["file"] or scriptfile if (os.isfile(fname)) then dofile(fname) end if (_OPTIONS["version"]) then printf(versionhelp, _PREMAKE_VERSION) return 1 end if (_OPTIONS["help"]) then premake.showhelp() return 1 end if (not _ACTION) then print(shorthelp) return 1 end if (not os.isfile(fname)) then error("No Premake script ("..scriptfile..") found!", 2) end action = premake.action.current() if (not action) then error("Error: no such action '" .. _ACTION .. "'", 0) end ok, err = premake.option.validate(_OPTIONS) if (not ok) then error("Error: " .. err, 0) end ok, err = premake.checktools() if (not ok) then error("Error: " .. err, 0) end ok, err = injectplatform(_OPTIONS["platform"]) if (not ok) then error("Error: " .. err, 0) end print("Building configurations...") if not action.isnextgen then premake.bake.buildconfigs() ok, err = premake.checkprojects() if (not ok) then error("Error: " .. err, 0) end else for sln in premake.solution.each() do premake.solution.bakeprojects(sln) end end printf("Running action '%s'...", action.trigger) premake.action.call(action.trigger) print("Done.") return 0 end $Lua: Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio $ $Authors: R. Ierusalimschy, L. H. de Figueiredo & W. Celes $ $URL: www.lua.org $ P?0C0E0C0Eh-DT! @9RFߑ?A?0C0E0C0E`qT`Pql1>>+@@AB CCDEFF^GGI,JmJ?KKLLXMNONOOORPwPyQQ2RRTSSTDU\U)V,WWXXYY@[@]^d`4aKab"ccdSekffhgcj1kFk~kkk$mmun3qvqrr sts$tu_uyy0ـă(pT؅CdԈˉZMh1̓2L1`-ݟ<EnHϨ @b6} ԳLhڶ<Hڻ8D+] Tb{VWm['wZ_`@ieSfu >rw{tUJ7 x!-l n!["e"2#$$%'U(d(./^/63e34456=[>>m?@I@@CDDEE#GG!HHQI9JJTKKNOOCPPPQfR&S$TTUUkVZ&[[[ \\aaRb=ccdreGgghimj<]ςzRx ,BAC KzRx $mAC FzRx ,+AC GzRx $cAC JzRx ,6AC MzRx $AC zRx $jVAC EzRx $3AC B$D1AC zRx ,|AC J$LACAC B$t\/AC B$cAC I$ًyAC FzRx $rAC FzRx ,DdAC JzRx $`mAC FzRx $AC IzRx ,RXAC PzRx $bjAC CzRx ,AC P,L AC NzRx ,AC JzRx $AC $DӓAC F$l.TAC $ZAC $@AC $0AAC B$ IAC $43jAC $\uAAC B$AC $,DAC B$HAC C$ߕ*AC B$$AC $Lו"AC $tѕ"AC $˕0AC $ӕ'AC $ҕAC $ɕWAC F$<gAC F$d7ZAC F$i1AC $r4AC $~&AC $|~AC F$,ҖdAC C$T$%AC $|!)AC $"AC $`AC C$hAC $YAC $DN"AC ,lHWAC G$oDAC C$AAC F$AC J$+AC F$<#AC $dAC $*AC $*AC B$_AC I$̘6AC B$,ژ7AC C,TWAC G$XAC B$@gAC B$1AC B$cAC I$$ÙqAC F,L uAC G$|QAC B$AC F$*BAC C$DAC I$ AC $D 1AC $l AC C$ LAC I$ 8AC $ # AC $ AC C$4 Ԝ AC $\ >AC B$ Ϝ{AC C$ "AC $ AC $ eAC C$$ ?LAC G$L coAC $t ~AC FzRx $AC I$DAC J$lQAC F$EbAC E,AC J,YAC G$FAC F$D6oAC C,l}AC G$Ϡ3AC C$ڠKAC F$2AC C$cAC G$<B@AC G$dZUAC F$?AC F$uAC F$oAC F$2 AC ,,bAC J,\HAC J,0'AC P$'AC ,RAC G$9'AC C$<8(AC B$d8(AC B$84AC C,DAC J$AC G$ AC F$4uAC F,\ۦAC P,^AC G$ͨeAC C$ &AC $ AC $4@AC G$\5AC B$$AC $<AC BzRx $8AC C$D(pAC C$lpAC F$&AC B$ߪZAC C$.AC B$ AC B$4 |AC C,\aAC G$dAC E$UGAC F$tHAC B$dAC C$,ЬFAC B$TSAC C$|AC C$eAC B$ AC F$eAC F$pAC C$D),AC B$l-LAC B$QNAC B$w2AC B$aAC C$ VAC G$4XAC B,\AC J$HAC B$KAC B$)XAC B$YAC F$,̱AC B$TfAC C,|ӲAC J$AC C$AAC B,ʹAC G$,olAC B$TAC I$|e3AC B$pAC CzRx $жAC $D5"AC $l/HAC G$OAC $B@AC $Z"AC $ T AC $48*AC $\:AC ,*AC J$}\AC F$>AC C$ǷAC C$,%AC ,TAC J$&AC $AC B$SAC $AC B$$ĹQAC C,LRAC M$|MAC C$4AC $$AC G$ɻAC F,AC J$L2AC C$tTAC $AC F$z!AC B$sCAC G,AC M$DAC C$lAC F,dAC J$AC ,AC G,AC G$L=AC C$tEAC C$AC $sAC I$]AC zRx $AC ,DAC P$t{AC $hAC I,(AC P,AC N$$AC $L~8AC B$tAC $uSAC B,DAC M,AC N$$R`AC B$L#AC B,tAC P$CAC C,.AC G$AC C$$AC B$LXRAC CzRx $l9AC $D} AC $l_ AC $A AC $"ZAC ,TPAC G,tAC G$D]AC F,l"AC M$-AC $AC ,AC M$(AC F,DAC M,tLAC N$4AC $*FAC I$HHAC $hAC F$D;AC B$lCAC $AAC zRx $kAC C$D[AC F$ltAC L,,AC G,~AC G$<AC ,1AC N,LAC M$|:XAC B$jAC F$DAC F$AC C$7qAC F$DAC B$lHAC C,AC M$yAC C$fAC G,AC GzRx ,mAC M,LAC M$|JAC G$YAC FzRx ,TAC G,LmAC G$|$BAC C$>AC F$/AC $AC F$/AC C$DAC C$l%AC $JAC zRx ,AC J$L%AC B,tAC J,w^AC G,AAC M$AC F,,c AC M$\TAC C$AC C$5)AC $6AC F$AC $$ AC $LMAC $t4AC C,iAC M$P=AC zRx $MNAC CzRx $[5AC B$Dh>AC C$l~CAC C$.AC B,sAC G$DAC C,AC G$D^GAC C$l}@AC B$3AC B$AC $AC F, 4xAC G$<|AC ,dpAC G$)AC B$9AC C$AC C$ I)AC B,4JAC J$dbAC F,AC M,AC N,uAC P,AC J$Lh SAC C$t ?AC C$ )AC B$ 5AC C, AC G$K ?AC B$Db .AC B$lh $AC B$d AC F$ vAC F$! $AC B$  1AC B$4& UAC BzRx ,< ^AC J$Lj xAC C,t AC K$> AC $# PAC F$K AC B$ JAC B,D ~AC M$tDAC B$8AC C,AC G$1AC F,AC G$LcaAC C,tAC GzRx $%AC B$D/AC B$l,AC B$,AC B$FAC B$,AC B$ ,AC B$4,AC B$\,AC B$/AC B$,AC B$,AC B$FAC B$$<AC B$LEAC B$t0,AC B$4,AC B$8fAC F$vfAC F$JAC E$<FAC B$d/AC B,OAC K$AC $ ,AC B$ ,AC B$4+AC B$\,AC B$,AC BzRx ,AC J,LVAC J$|AC zRx ,}AC G$L<AC B$tAC F,mJAC M,!PAC G$#AC C$$$TAC C$L:$nAC F,t$AC G,%jAC J$M&jAC C,&AC M$,`(RAC F$T(AC F$|(|AC BzRx $,).AC $D2)AC $l&)8AC $6)PAC $p)AC G,*AC M$,jAC F$<-AC ,d{-AC JzRx $F.AC $D<.CAC B,lW.AC P$0HAC C$06AC B$1AC $04AC B$<08AC C$d1JAC C$01_AC C$g1SAC G$2hAC E$2AC F$,+3uAC FzRx $`3AC L,D3AC G,t4 AC M,t>AC J$L@FAC E,j@AC J$,@zAC F,T'AjAC M,aBAC M$CSAC B$C$AC B$C_AC F$,)DAC F,TDAC M,HAC M,JAC P,yMAC M$dNDAC $<N4AC C$dNCAC C,NAC M$hO<AC C$|OmAC I, ObAC M$<PNAC F,dQ!AC M$ S;AC E$SXAC C$MSCAC , hS6AC M$<nT9AC C$dT7AC CzRx $vTAC C$DIUAC C$lU:AC C$U>AC C,U[AC G$WAC F$~XyAC C$<XtAC C$dY AC zRx ,XAC G,LYUAC J$|ZmAC FzRx $ZAC B,Dq[bAC M,t\AC P$*]AC J$]AC ,l]4AC P$$cAC $Lc[AC B,tcAC P$g/AC B,gAC N$h AC $$gAC L$LEhAC L$thAC F,[iAC N,iAC P,8lAC M,,pwAC J$\[pAC F,pvAC J$qAC F,qAC J$ q;AC ,4rAC J$dbrAC F,ptAC P$BuAC zRx ,utAC J$LXv%AC ,tUvvAC M,wAC G$wwAC F,AxAC G$,xgAC C$Ty^AC $|OyFAC $myDAC $yAC F$yxAC $TzAC F,DzAC P$tV}RAC I$}OAC I,}AC G$k~GAC BzRx $r~AC ,Dh~AC P$t;AC C,AC G$^<AC B$rAC E, AC G,LAC J$|-BAC B$GAC C,AC M$AC F$$qAC FzRx ,ƆcAC G$L5AC C$tMAC zRx $AC I,D·AC M$tAC $z`AC G$QAC B$یMAC BzRx $MAC B$D dAC I,lI1AC M$JAC C,ŽAC M$gAC F,AC J,LAC J$|AC F,<AC G,AC M,kAC J,4ɔ AC M,d< AC MzRx $ EAC B$D=?AC B$lT!AC ,MrAC J$QAC C__pr`lx̜؜ ,8DP\htȝԝ(4@LXdp|ĞОܞ $0<HT`lx̟؟ ,8DP\htȠԠ(4@LXdp|pJR"ä+̤hդzۤ2) l94)/$:@E 5'P¦QɦQѦQئ1Rݦ_Rɦ6@GçVʧ(W٧W9XXX!YoY YZ~U XZ&Z,[5[<A\C\J4]R]_^h_q`va}a05=EKPY{}}~Ɂށ J%x R)4 EpO(0"g6ģ;9e{U[lRgqrgK$P1XUux};ïȯίԯׯۯޯ,X#).3"8N<z@D JGPV\` dhm6q|u|?k*J2` u5JhsZ_envĵȵ̵еԵصܵ&/7=ELR_W `Uhmt{ X    (yQ<~=j>>>sElEEIIJJ-KKL@gChh&i+i0jt}k7=l<lҼڼģ0ڼCX %+17=BGPy St')]0-C|"'*/t@JQkѮ )KSYiH dqs|{-"mcV31C/yrmjTAjAD*""0'WgZ14&~z%)}"WDA#**_67WXg1cquB1L8  >{eLo~QbYFo3K2c@U?uo R'((4u^e&@5>p&Z.|dGHdFSeep,LN2aVXHKXAl3"H@" *\>%&SQMT!=E]8S`#CT9 ZP]- FH;CAkt~ XqHyfmYTmB/%J%^) M4 =N>C.sDG@3x)9)bS?)5?.$v$1V^x PJa/,,F,,,,/,,Fyt m [/ wv;%wg^FDROG<Bqc5N `QMMdk'E?!r 0  8 H2 pCN @W'hzݽ4ԷLlɨ#J1c?Uk{pۜ43&ų! ɱ.#@wRapzF\DȖ_` e_!`.]8ZC \Ua_Feleyf}ddeikkikwde"n1Bp?sKdVc`hnpe~eucpfBemxh7hlfgH.H>IMp=\OHk3DzUB*C@B?A BUA9>F!C4(G?ZNPK_Np@NDUCG@BIHpJ D>+.K7E?CRan|Tpg8 9;.8;!rGVrXqc s<~pxr9z} |yy  ' <7 sG OR a fs :   h  P Ԙ  g  ( 7 ' 8 '; 8( 49 9C -N :Y 9a ;p 4} E3 E Y O   h4 b 3 )) 7< + *7 ,H ;,V k,d ,t o- W9 5 ( ; : .  8 2 2 d1 f0 27 0H 00U I0e 0u 2 + #1 , 3 3 5 ,6 ) *  ; 57' X55  B (P ^ 6p '5~ ;) < 9 .. L/ - T. - //q/+)+7n(BMpO[{jve;"g"+2hz )&6lD9R4ak$z R"5'&9Zt'2=Tcmv| (/8?FLU\dkrz $,38>DMV^fmx $-5:@FO !"#$&'(,-/0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^`abcdefghijklmnopqrstuvwxyz{|}~%)*+.@_ !"#$&'(,-/0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^`abcdefghijklmnopqrstuvwxyz{|}~ _NXArgc_NXArgv___progname__mh_execute_header_builtin_scripts_do_isfile_environ_luaA_pushobject_luaC_barrierback_luaC_barrierf_luaC_callGCTM_luaC_freeall_luaC_fullgc_luaC_link_luaC_linkupval_luaC_separateudata_luaC_step_luaD_call_luaD_callhook_luaD_growstack_luaD_pcall_luaD_poscall_luaD_precall_luaD_protectedparser_luaD_rawrunprotected_luaD_reallocCI_luaD_reallocstack_luaD_seterrorobj_luaD_throw_luaE_freethread_luaE_newthread_luaF_close_luaF_findupval_luaF_freeclosure_luaF_freeproto_luaF_freeupval_luaF_getlocalname_luaF_newCclosure_luaF_newLclosure_luaF_newproto_luaF_newupval_luaG_aritherror_luaG_checkcode_luaG_checkopenop_luaG_concaterror_luaG_errormsg_luaG_ordererror_luaG_runerror_luaG_typeerror_luaH_free_luaH_get_luaH_getn_luaH_getnum_luaH_getstr_luaH_new_luaH_next_luaH_resizearray_luaH_set_luaH_setnum_luaH_setstr_luaK_checkstack_luaK_codeABC_luaK_codeABx_luaK_concat_luaK_dischargevars_luaK_exp2RK_luaK_exp2anyreg_luaK_exp2nextreg_luaK_exp2val_luaK_fixline_luaK_getlabel_luaK_goiftrue_luaK_indexed_luaK_infix_luaK_jump_luaK_nil_luaK_numberK_luaK_patchlist_luaK_patchtohere_luaK_posfix_luaK_prefix_luaK_reserveregs_luaK_ret_luaK_self_luaK_setlist_luaK_setoneret_luaK_setreturns_luaK_storevar_luaK_stringK_luaL_addlstring_luaL_addstring_luaL_addvalue_luaL_argerror_luaL_buffinit_luaL_callmeta_luaL_checkany_luaL_checkinteger_luaL_checklstring_luaL_checknumber_luaL_checkoption_luaL_checkstack_luaL_checktype_luaL_checkudata_luaL_error_luaL_findtable_luaL_getmetafield_luaL_gsub_luaL_loadbuffer_luaL_loadfile_luaL_loadstring_luaL_newmetatable_luaL_newstate_luaL_openlib_luaL_openlibs_luaL_optinteger_luaL_optlstring_luaL_optnumber_luaL_prepbuffer_luaL_pushresult_luaL_ref_luaL_register_luaL_typerror_luaL_unref_luaL_where_luaM_growaux__luaM_realloc__luaM_toobig_luaO_chunkid_luaO_fb2int_luaO_int2fb_luaO_log2_luaO_nilobject__luaO_pushfstring_luaO_pushvfstring_luaO_rawequalObj_luaO_str2d_luaP_opmodes_luaP_opnames_luaS_newlstr_luaS_newudata_luaS_resize_luaT_gettm_luaT_gettmbyobj_luaT_init_luaT_typenames_luaU_dump_luaU_header_luaU_undump_luaV_concat_luaV_equalval_luaV_execute_luaV_gettable_luaV_lessthan_luaV_settable_luaV_tonumber_luaV_tostring_luaX_init_luaX_lexerror_luaX_lookahead_luaX_newstring_luaX_next_luaX_setinput_luaX_syntaxerror_luaX_token2str_luaX_tokens_luaY_parser_luaZ_fill_luaZ_init_luaZ_lookahead_luaZ_openspace_luaZ_read_lua_atpanic_lua_call_lua_checkstack_lua_close_lua_concat_lua_cpcall_lua_createtable_lua_dump_lua_equal_lua_error_lua_gc_lua_getallocf_lua_getfenv_lua_getfield_lua_gethook_lua_gethookcount_lua_gethookmask_lua_getinfo_lua_getlocal_lua_getmetatable_lua_getstack_lua_gettable_lua_gettop_lua_getupvalue_lua_ident_lua_insert_lua_iscfunction_lua_isnumber_lua_isstring_lua_isuserdata_lua_lessthan_lua_load_lua_newstate_lua_newthread_lua_newuserdata_lua_next_lua_objlen_lua_pcall_lua_pushboolean_lua_pushcclosure_lua_pushfstring_lua_pushinteger_lua_pushlightuserdata_lua_pushlstring_lua_pushnil_lua_pushnumber_lua_pushstring_lua_pushthread_lua_pushvalue_lua_pushvfstring_lua_rawequal_lua_rawget_lua_rawgeti_lua_rawset_lua_rawseti_lua_remove_lua_replace_lua_resume_lua_setallocf_lua_setfenv_lua_setfield_lua_sethook_lua_setlevel_lua_setlocal_lua_setmetatable_lua_settable_lua_settop_lua_setupvalue_lua_status_lua_toboolean_lua_tocfunction_lua_tointeger_lua_tolstring_lua_tonumber_lua_topointer_lua_tothread_lua_touserdata_lua_type_lua_typename_lua_xmove_lua_yield_luaopen_base_luaopen_debug_luaopen_io_luaopen_math_luaopen_os_luaopen_package_luaopen_string_luaopen_table_main_os_chdir_os_copyfile_os_getcwd_os_getversion_os_is64bit_os_isdir_os_isfile_os_matchdone_os_matchisfile_os_matchname_os_matchnext_os_matchstart_os_mkdir_os_pathsearch_os_rmdir_os_stat_os_uuid_path_isabsolute_string_endswithstart_CFBundleCopyExecutableURL_CFBundleGetMainBundle_CFStringGetCString_CFURLCopyFileSystemPath_Gestalt_NSAddressOfSymbol_NSCreateObjectFileImageFromFile_NSDestroyObjectFileImage_NSLinkEditError_NSLinkModule_NSLookupSymbolInModule_NSUnLinkModule__DefaultRuneLocale___error___keymgr_dwarf2_register_sections___maskrune___stderrp___stdinp___stdoutp___tolower___toupper__cthread_init_routine__dyld_present__longjmp__setjmp_acos_asin_atan_atan2_atexit_ceil_chdir_clearerr_clock_close_closedir_cos_cosh_difftime_errno_exit_exp_fclose_feof_ferror_fflush_fgets_floor_fmod_fnmatch_fopen_fprintf_fputs_fread_free_freopen_frexp_fscanf_fseek_ftell_fwrite_getc_getcwd_getenv_gmtime_ldexp_localeconv_localtime_log_log10_mach_init_routine_malloc_memchr_memcmp_memcpy_memset_mkdir_mkstemp_mktime_modf_opendir_pclose_popen_pow_puts_rand_readdir_realloc_remove_rename_rmdir_setlocale_setvbuf_sin_sinh_sprintf_srand_stat_strcat_strchr_strcmp_strcoll_strcpy_strcspn_strerror_strftime_strlen_strncat_strncpy_strpbrk_strrchr_strstr_strtod_strtoul_system_tan_tanh_time_tmpfile_ungetc