confutils.js 99 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710
  1. // Utils for configure script
  2. /*
  3. +----------------------------------------------------------------------+
  4. | PHP Version 7 |
  5. +----------------------------------------------------------------------+
  6. | Copyright (c) 1997-2018 The PHP Group |
  7. +----------------------------------------------------------------------+
  8. | This source file is subject to version 3.01 of the PHP license, |
  9. | that is bundled with this package in the file LICENSE, and is |
  10. | available through the world-wide-web at the following url: |
  11. | http://www.php.net/license/3_01.txt |
  12. | If you did not receive a copy of the PHP license and are unable to |
  13. | obtain it through the world-wide-web, please send a note to |
  14. | license@php.net so we can mail you a copy immediately. |
  15. +----------------------------------------------------------------------+
  16. | Author: Wez Furlong <wez@thebrainroom.com> |
  17. +----------------------------------------------------------------------+
  18. */
  19. var STDOUT = WScript.StdOut;
  20. var STDERR = WScript.StdErr;
  21. var WshShell = WScript.CreateObject("WScript.Shell");
  22. var FSO = WScript.CreateObject("Scripting.FileSystemObject");
  23. var MFO = null;
  24. var SYSTEM_DRIVE = WshShell.Environment("Process").Item("SystemDrive");
  25. var PROGRAM_FILES = WshShell.Environment("Process").Item("ProgramFiles");
  26. var PROGRAM_FILESx86 = WshShell.Environment("Process").Item("ProgramFiles(x86)");
  27. var VCINSTALLDIR = WshShell.Environment("Process").Item("VCINSTALLDIR");
  28. var PHP_SRC_DIR=FSO.GetParentFolderName(WScript.ScriptFullName);
  29. var VS_TOOLSET = true;
  30. var CLANG_TOOLSET = false;
  31. var ICC_TOOLSET = false;
  32. var VCVERS = -1;
  33. var CLANGVERS = -1;
  34. var INTELVERS = -1;
  35. var COMPILER_NUMERIC_VERSION = -1;
  36. var COMPILER_NAME = "unknown";
  37. var PHP_OBJECT_OUT_DIR = "";
  38. var PHP_CONFIG_PROFILE = "no";
  39. var PHP_SANITIZER = "no";
  40. var VERBOSITY = 0;
  41. var CMD_MOD1 = "@";
  42. var CMD_MOD2 = "@";
  43. var PHP_TEST_INI_PATH = "";
  44. var PHP_TEST_INI = "";
  45. var PHP_TEST_INI_EXT_EXCLUDE = "";
  46. var PHP_MAKEFILE_FRAGMENTS = PHP_SRC_DIR + "\\Makefile.fragments.w32";
  47. /* Care also about NTDDI_VERSION and _WIN32_WINNT in config.w32.h.in
  48. and manifest. */
  49. var WINVER = "0x0601"; /* 7/2008r2 */
  50. // There's a minimum requirement for bison.
  51. var MINBISON = "3.0.0";
  52. // There's a minimum requirement for re2c..
  53. var MINRE2C = "0.13.4";
  54. /* Store the enabled extensions (summary + QA check) */
  55. var extensions_enabled = new Array();
  56. /* Store the SAPI enabled (summary + QA check) */
  57. var sapi_enabled = new Array();
  58. /* Store the headers to install */
  59. var headers_install = new Array();
  60. /* Store unknown configure options */
  61. var INVALID_CONFIG_ARGS = new Array();
  62. /* Mapping CL version > human readable name */
  63. var VC_VERSIONS = new Array();
  64. VC_VERSIONS[1700] = 'MSVC11 (Visual C++ 2012)';
  65. VC_VERSIONS[1800] = 'MSVC12 (Visual C++ 2013)';
  66. VC_VERSIONS[1900] = 'MSVC14 (Visual C++ 2015)';
  67. VC_VERSIONS[1910] = 'MSVC15 (Visual C++ 2017)';
  68. VC_VERSIONS[1911] = 'MSVC15 (Visual C++ 2017)';
  69. VC_VERSIONS[1912] = 'MSVC15 (Visual C++ 2017)';
  70. VC_VERSIONS[1913] = 'MSVC15 (Visual C++ 2017)';
  71. VC_VERSIONS[1914] = 'MSVC15 (Visual C++ 2017)';
  72. VC_VERSIONS[1915] = 'MSVC15 (Visual C++ 2017)';
  73. VC_VERSIONS[1916] = 'MSVC15 (Visual C++ 2017)';
  74. var VC_VERSIONS_SHORT = new Array();
  75. VC_VERSIONS_SHORT[1700] = 'VC11';
  76. VC_VERSIONS_SHORT[1800] = 'VC12';
  77. VC_VERSIONS_SHORT[1900] = 'VC14';
  78. VC_VERSIONS_SHORT[1910] = 'VC15';
  79. VC_VERSIONS_SHORT[1911] = 'VC15';
  80. VC_VERSIONS_SHORT[1912] = 'VC15';
  81. VC_VERSIONS_SHORT[1913] = 'VC15';
  82. VC_VERSIONS_SHORT[1914] = 'VC15';
  83. VC_VERSIONS_SHORT[1915] = 'VC15';
  84. VC_VERSIONS_SHORT[1916] = 'VC15';
  85. if (PROGRAM_FILES == null) {
  86. PROGRAM_FILES = "C:\\Program Files";
  87. }
  88. if (MODE_PHPIZE) {
  89. if (!FSO.FileExists("config.w32")) {
  90. STDERR.WriteLine("Must be run from the root of the extension source");
  91. WScript.Quit(10);
  92. }
  93. } else {
  94. if (!FSO.FileExists("README.GIT-RULES")) {
  95. STDERR.WriteLine("Must be run from the root of the php source");
  96. WScript.Quit(10);
  97. }
  98. }
  99. var CWD = WshShell.CurrentDirectory;
  100. if (typeof(CWD) == "undefined") {
  101. CWD = FSO.GetParentFolderName(FSO.GetAbsolutePathName("README.GIT-RULES"));
  102. }
  103. /* defaults; we pick up the precise versions from configure.ac */
  104. var PHP_VERSION = 7;
  105. var PHP_MINOR_VERSION = 3;
  106. var PHP_RELEASE_VERSION = 0;
  107. var PHP_EXTRA_VERSION = "";
  108. var PHP_VERSION_STRING = "7.3.0";
  109. /* Get version numbers and DEFINE as a string */
  110. function get_version_numbers()
  111. {
  112. var cin = file_get_contents("configure.ac");
  113. if (cin.match(new RegExp("PHP_MAJOR_VERSION=(\\d+)"))) {
  114. PHP_VERSION = RegExp.$1;
  115. }
  116. if (cin.match(new RegExp("PHP_MINOR_VERSION=(\\d+)"))) {
  117. PHP_MINOR_VERSION = RegExp.$1;
  118. }
  119. if (cin.match(new RegExp("PHP_RELEASE_VERSION=(\\d+)"))) {
  120. PHP_RELEASE_VERSION = RegExp.$1;
  121. }
  122. PHP_VERSION_STRING = PHP_VERSION + "." + PHP_MINOR_VERSION + "." + PHP_RELEASE_VERSION;
  123. if (cin.match(new RegExp("PHP_EXTRA_VERSION=\"([^\"]+)\""))) {
  124. PHP_EXTRA_VERSION = RegExp.$1;
  125. if (PHP_EXTRA_VERSION.length) {
  126. PHP_VERSION_STRING += PHP_EXTRA_VERSION;
  127. }
  128. }
  129. DEFINE('PHP_VERSION_STRING', PHP_VERSION_STRING);
  130. }
  131. configure_args = new Array();
  132. configure_subst = WScript.CreateObject("Scripting.Dictionary");
  133. configure_hdr = WScript.CreateObject("Scripting.Dictionary");
  134. build_dirs = new Array();
  135. extension_include_code = "";
  136. extension_module_ptrs = "";
  137. if (!MODE_PHPIZE) {
  138. get_version_numbers();
  139. }
  140. /* execute a command and return the output as a string */
  141. function execute(command_line)
  142. {
  143. var e = WshShell.Exec(command_line);
  144. var ret = "";
  145. ret = e.StdOut.ReadAll();
  146. //STDOUT.WriteLine("command " + command_line);
  147. //STDOUT.WriteLine(ret);
  148. return ret;
  149. }
  150. function probe_binary(EXE, what)
  151. {
  152. // tricky escapes to get stderr redirection to work
  153. var command = 'cmd /c ""' + EXE;
  154. if (what == "version") {
  155. command = command + '" -v"';
  156. } else if (what == "longversion") {
  157. command = command + '" --version"';
  158. }
  159. var version = execute(command + '" 2>&1"');
  160. if (what == "64") {
  161. if (version.match(/x64/)) {
  162. return 1;
  163. }
  164. } else {
  165. if (version.match(/(\d+\.\d+(\.\d+)?(\.\d+)?)/)) {
  166. return RegExp.$1;
  167. }
  168. }
  169. return 0;
  170. }
  171. function condense_path(path)
  172. {
  173. path = FSO.GetAbsolutePathName(path);
  174. if (path.substr(0, CWD.length).toLowerCase()
  175. == CWD.toLowerCase() &&
  176. (path.charCodeAt(CWD.length) == 92 || path.charCodeAt(CWD.length) == 47)) {
  177. return path.substr(CWD.length + 1);
  178. }
  179. var a = CWD.split("\\");
  180. var b = path.split("\\");
  181. var i, j;
  182. for (i = 0; i < b.length; i++) {
  183. if (a[i].toLowerCase() == b[i].toLowerCase())
  184. continue;
  185. if (i > 0) {
  186. /* first difference found */
  187. path = "";
  188. for (j = 0; j < a.length - i; j++) {
  189. path += "..\\";
  190. }
  191. for (j = i; j < b.length; j++) {
  192. path += b[j];
  193. if (j < b.length - 1)
  194. path += "\\";
  195. }
  196. return path;
  197. }
  198. /* on a different drive */
  199. break;
  200. }
  201. return path;
  202. }
  203. function ConfigureArg(type, optname, helptext, defval)
  204. {
  205. var opptype = type == "enable" ? "disable" : "without";
  206. if (defval == "yes" || defval == "yes,shared") {
  207. this.arg = "--" + opptype + "-" + optname;
  208. this.imparg = "--" + type + "-" + optname;
  209. } else {
  210. this.arg = "--" + type + "-" + optname;
  211. this.imparg = "--" + opptype + "-" + optname;
  212. }
  213. this.optname = optname;
  214. this.helptext = helptext;
  215. this.defval = defval;
  216. this.symval = optname.toUpperCase().replace(new RegExp("-", "g"), "_");
  217. this.seen = false;
  218. this.argval = defval;
  219. }
  220. function ARG_WITH(optname, helptext, defval)
  221. {
  222. configure_args[configure_args.length] = new ConfigureArg("with", optname, helptext, defval);
  223. }
  224. function ARG_ENABLE(optname, helptext, defval)
  225. {
  226. configure_args[configure_args.length] = new ConfigureArg("enable", optname, helptext, defval);
  227. }
  228. function analyze_arg(argval)
  229. {
  230. var ret = new Array();
  231. var shared = false;
  232. if (argval == "shared") {
  233. shared = true;
  234. argval = "yes";
  235. } else if (argval == null) {
  236. /* nothing */
  237. } else if (arg_match = argval.match(new RegExp("^shared,(.*)"))) {
  238. shared = true;
  239. argval = arg_match[1];
  240. } else if (arg_match = argval.match(new RegExp("^(.*),shared$"))) {
  241. shared = true;
  242. argval = arg_match[1];
  243. }
  244. ret[0] = shared;
  245. ret[1] = argval;
  246. return ret;
  247. }
  248. function word_wrap_and_indent(indent, text, line_suffix, indent_char)
  249. {
  250. if (text == null) {
  251. return "";
  252. }
  253. var words = text.split(new RegExp("\\s+", "g"));
  254. var i = 0;
  255. var ret_text = "";
  256. var this_line = "";
  257. var t;
  258. var space = "";
  259. var lines = 0;
  260. if (line_suffix == null) {
  261. line_suffix = "";
  262. }
  263. if (indent_char == null) {
  264. indent_char = " ";
  265. }
  266. for (i = 0; i < indent; i++) {
  267. space += indent_char;
  268. }
  269. for (i = 0; i < words.length; i++) {
  270. if (this_line.length) {
  271. t = this_line + " " + words[i];
  272. } else {
  273. t = words[i];
  274. }
  275. if (t.length + indent > 78) {
  276. if (lines++) {
  277. ret_text += space;
  278. }
  279. ret_text += this_line + line_suffix + "\r\n";
  280. this_line = "";
  281. }
  282. if (this_line.length) {
  283. this_line += " " + words[i];
  284. } else {
  285. this_line = words[i];
  286. }
  287. }
  288. if (this_line.length) {
  289. if (lines)
  290. ret_text += space;
  291. ret_text += this_line;
  292. }
  293. return ret_text;
  294. }
  295. function conf_process_args()
  296. {
  297. var i, j;
  298. var configure_help_mode = false;
  299. var analyzed = false;
  300. var nice = "cscript /nologo /e:jscript configure.js ";
  301. var disable_all = false;
  302. args = WScript.Arguments;
  303. for (i = 0; i < args.length; i++) {
  304. arg = args(i);
  305. nice += ' "' + arg + '"';
  306. if (arg == "--help") {
  307. configure_help_mode = true;
  308. break;
  309. }
  310. if (arg == "--disable-all") {
  311. disable_all = true;
  312. continue;
  313. }
  314. // If it is --foo=bar, split on the equals sign
  315. arg = arg.split("=", 2);
  316. argname = arg[0];
  317. if (arg.length > 1) {
  318. argval = arg[1];
  319. } else {
  320. argval = null;
  321. }
  322. // Find the arg
  323. found = false;
  324. for (j = 0; j < configure_args.length; j++) {
  325. if (argname == configure_args[j].imparg || argname == configure_args[j].arg) {
  326. found = true;
  327. arg = configure_args[j];
  328. arg.seen = true;
  329. analyzed = analyze_arg(argval);
  330. /* Force shared when called after phpize */
  331. if (MODE_PHPIZE) {
  332. shared = "shared";
  333. } else {
  334. shared = analyzed[0];
  335. }
  336. argval = analyzed[1];
  337. if (argname == arg.imparg) {
  338. /* we matched the implicit, or default arg */
  339. if (argval == null) {
  340. argval = arg.defval;
  341. }
  342. } else {
  343. /* we matched the non-default arg */
  344. if (argval == null) {
  345. if (arg.defval == "no") {
  346. argval = "yes";
  347. } else if (arg.defval == "no,shared") {
  348. argval = "yes,shared";
  349. shared = true;
  350. } else {
  351. argval = "no";
  352. }
  353. }
  354. }
  355. arg.argval = argval;
  356. eval("PHP_" + arg.symval + " = argval;");
  357. eval("PHP_" + arg.symval + "_SHARED = shared;");
  358. break;
  359. }
  360. }
  361. if (!found) {
  362. INVALID_CONFIG_ARGS[INVALID_CONFIG_ARGS.length] = argname;
  363. }
  364. }
  365. if (PHP_SNAPSHOT_BUILD != 'no' && INVALID_CONFIG_ARGS.length) {
  366. STDERR.WriteLine('Unknown option ' + INVALID_CONFIG_ARGS[0] + '; please try configure.js --help for a list of valid options');
  367. WScript.Quit(2);
  368. }
  369. if (configure_help_mode) {
  370. STDOUT.WriteLine(word_wrap_and_indent(0,
  371. "Options that enable extensions and SAPI will accept \
  372. 'yes' or 'no' as a parameter. They also accept 'shared' \
  373. as a synonym for 'yes' and request a shared build of that \
  374. module. Not all modules can be built as shared modules; \
  375. configure will display [shared] after the module name if \
  376. can be built that way. \
  377. "
  378. ));
  379. STDOUT.WriteBlankLines(1);
  380. // Measure width to pretty-print the output
  381. max_width = 0;
  382. for (i = 0; i < configure_args.length; i++) {
  383. arg = configure_args[i];
  384. if (arg.arg.length > max_width)
  385. max_width = arg.arg.length;
  386. }
  387. for (i = 0; i < configure_args.length; i++) {
  388. arg = configure_args[i];
  389. n = max_width - arg.arg.length;
  390. pad = " ";
  391. for (j = 0; j < n; j++) {
  392. pad += " ";
  393. }
  394. STDOUT.WriteLine(" " + arg.arg + pad + word_wrap_and_indent(max_width + 5, arg.helptext));
  395. }
  396. WScript.Quit(1);
  397. }
  398. var snapshot_build_exclusions = new Array(
  399. 'debug', 'crt-debug', 'lzf-better-compression',
  400. 'php-build', 'snapshot-template', 'ereg',
  401. 'pcre-regex', 'fastcgi', 'force-cgi-redirect',
  402. 'path-info-check', 'zts', 'ipv6', 'memory-limit',
  403. 'zend-multibyte', 'fd-setsize', 'memory-manager',
  404. 'pgi', 'pgo', 'all-shared', 'config-profile'
  405. );
  406. var force;
  407. // Now set any defaults we might have missed out earlier
  408. for (i = 0; i < configure_args.length; i++) {
  409. arg = configure_args[i];
  410. if (arg.seen)
  411. continue;
  412. analyzed = analyze_arg(arg.defval);
  413. shared = analyzed[0];
  414. argval = analyzed[1];
  415. // Don't trust a default "yes" answer for a non-core module
  416. // in a snapshot build
  417. if (PHP_SNAPSHOT_BUILD != "no" && argval == "yes" && !shared) {
  418. force = true;
  419. for (j = 0; j < snapshot_build_exclusions.length; j++) {
  420. if (snapshot_build_exclusions[j] == arg.optname) {
  421. force = false;
  422. break;
  423. }
  424. }
  425. if (force) {
  426. /* now check if it is a core module */
  427. force = false;
  428. for (j = 0; j < core_module_list.length; j++) {
  429. if (core_module_list[j] == arg.optname) {
  430. force = true;
  431. break;
  432. }
  433. }
  434. if (!force) {
  435. STDOUT.WriteLine("snapshot: forcing " + arg.arg + " shared");
  436. shared = true;
  437. }
  438. }
  439. }
  440. if (PHP_SNAPSHOT_BUILD != "no" && argval == "no") {
  441. force = true;
  442. for (j = 0; j < snapshot_build_exclusions.length; j++) {
  443. if (snapshot_build_exclusions[j] == arg.optname) {
  444. force = false;
  445. break;
  446. }
  447. }
  448. if (force) {
  449. STDOUT.WriteLine("snapshot: forcing " + arg.optname + " on");
  450. argval = "yes";
  451. shared = true;
  452. }
  453. }
  454. if (disable_all) {
  455. force = true;
  456. for (j = 0; j < snapshot_build_exclusions.length; j++) {
  457. if (snapshot_build_exclusions[j] == arg.optname) {
  458. force = false;
  459. break;
  460. }
  461. }
  462. if (force) {
  463. if (arg.defval == '') {
  464. argval = '';
  465. } else {
  466. argval = "no";
  467. }
  468. shared = false;
  469. }
  470. }
  471. eval("PHP_" + arg.symval + " = argval;");
  472. eval("PHP_" + arg.symval + "_SHARED = shared;");
  473. }
  474. MFO = FSO.CreateTextFile("Makefile.objects", true);
  475. var profile = false;
  476. if (PHP_CONFIG_PROFILE != 'no') {
  477. if (PHP_CONFIG_PROFILE.toLowerCase() == 'nice') {
  478. WARNING('Config profile name cannot be named \'nice\'');
  479. } else {
  480. var config_profile = FSO.CreateTextFile('config.' + PHP_CONFIG_PROFILE + '.bat', true);
  481. config_profile.WriteLine('@echo off');
  482. config_profile.WriteLine(nice + ' %*');
  483. config_profile.Close();
  484. profile = true;
  485. }
  486. }
  487. // Only generate an updated config.nice.bat file if a profile was not used
  488. if (!profile) {
  489. STDOUT.WriteLine("Saving configure options to config.nice.bat");
  490. var nicefile = FSO.CreateTextFile("config.nice.bat", true);
  491. nicefile.WriteLine('@echo off');
  492. nicefile.WriteLine(nice + " %*");
  493. nicefile.Close();
  494. }
  495. AC_DEFINE('CONFIGURE_COMMAND', nice, "Configure line");
  496. }
  497. function DEFINE(name, value)
  498. {
  499. if (configure_subst.Exists(name)) {
  500. configure_subst.Remove(name);
  501. }
  502. configure_subst.Add(name, value);
  503. }
  504. function verbalize_deps_path(path)
  505. {
  506. var absolute_path = FSO.GetAbsolutePathName(path);
  507. if (absolute_path.indexOf(PHP_PHP_BUILD) == 0) {
  508. absolute_path = absolute_path.substring(PHP_PHP_BUILD.length).split('\\');
  509. if (absolute_path[1] == 'include' || absolute_path[1] == 'lib') {
  510. return "<in deps path> " + absolute_path.join('\\');
  511. }
  512. }
  513. return path;
  514. }
  515. // Searches a set of paths for a file;
  516. // returns the dir in which the file was found,
  517. // true if it was found in the default env path,
  518. // or false if it was not found at all.
  519. // env_name is the optional name of an env var
  520. // specifying the default path to search
  521. function search_paths(thing_to_find, explicit_path, env_name)
  522. {
  523. var i, found = false, place = false, file, env;
  524. STDOUT.Write("Checking for " + thing_to_find + " ... ");
  525. thing_to_find = thing_to_find.replace(new RegExp("/", "g"), "\\");
  526. if (explicit_path != null) {
  527. if (typeof(explicit_path) == "string") {
  528. explicit_path = explicit_path.split(";");
  529. }
  530. for (i = 0; i < explicit_path.length; i++) {
  531. file = glob(explicit_path[i] + "\\" + thing_to_find);
  532. if (file) {
  533. found = true;
  534. place = file[0];
  535. place = place.substr(0, place.length - thing_to_find.length - 1);
  536. break;
  537. }
  538. }
  539. }
  540. if (!found && env_name != null) {
  541. env = WshShell.Environment("Process").Item(env_name);
  542. env = env.split(";");
  543. for (i = 0; i < env.length; i++) {
  544. file = glob(env[i] + "\\" + thing_to_find);
  545. if (file) {
  546. found = true;
  547. place = true;
  548. break;
  549. }
  550. }
  551. }
  552. if (found && place == true) {
  553. STDOUT.WriteLine(" <in default path>");
  554. } else if (found) {
  555. STDOUT.WriteLine(" " + verbalize_deps_path(place));
  556. } else {
  557. STDOUT.WriteLine(" <not found>");
  558. }
  559. return place;
  560. }
  561. function PATH_PROG(progname, additional_paths, symbol)
  562. {
  563. var exe;
  564. var place;
  565. var cyg_path = PHP_CYGWIN + "\\bin;" + PHP_CYGWIN + "\\usr\\local\\bin";
  566. var php_build_bin_path = PHP_PHP_BUILD + "\\bin"
  567. exe = progname + ".exe";
  568. if (additional_paths == null) {
  569. additional_paths = cyg_path;
  570. } else {
  571. additional_paths += ";" + cyg_path;
  572. }
  573. additional_paths = additional_paths + ";" + php_build_bin_path;
  574. place = search_paths(exe, additional_paths, "PATH");
  575. if (place == true) {
  576. place = exe;
  577. } else if (place != false) {
  578. place = place + "\\" + exe;
  579. }
  580. if (place) {
  581. if (symbol == null) {
  582. symbol = progname.toUpperCase();
  583. }
  584. DEFINE(symbol, place);
  585. }
  586. return place;
  587. }
  588. function find_pattern_in_path(pattern, path)
  589. {
  590. if (path == null) {
  591. return false;
  592. }
  593. var dirs = path.split(';');
  594. var i;
  595. var items;
  596. for (i = 0; i < dirs.length; i++) {
  597. items = glob(dirs[i] + "\\" + pattern);
  598. if (items) {
  599. return condense_path(items[0]);
  600. }
  601. }
  602. return false;
  603. }
  604. function copy_dep_pdb_into_build_dir(libpath)
  605. {
  606. var candidate;
  607. var build_dir = get_define("BUILD_DIR");
  608. var libdir = FSO.GetParentFolderName(libpath);
  609. var bindir = FSO.GetAbsolutePathName(libdir + "\\..\\bin");
  610. var names = [];
  611. var libname = FSO.GetFileName(libpath);
  612. /* Within same .lib, everything should be bound to the same .pdb. No check
  613. for every single object in the static libs. */
  614. var _tmp = execute("dumpbin /section:.debug$T /rawdata:1,256 " + libpath);
  615. if (!_tmp.match("LNK4039")) {
  616. if (_tmp.match(/\d{2,}:\s+([a-z0-9\s]+)/i)) {
  617. var m = RegExp.$1;
  618. var a = m.split(/ /);
  619. var s = "";
  620. for (var i in a) {
  621. s = s + String.fromCharCode(parseInt("0x" + a[i]));
  622. }
  623. if (s.match(/([^\\]+\.pdb)/i)) {
  624. if (RegExp.$1 != names[0]) {
  625. names.push(RegExp.$1);
  626. }
  627. }
  628. }
  629. }
  630. /* This is rather a fallback, if the bin has no debug section or
  631. something went wrong with parsing. */
  632. names.push(libname.replace(new RegExp("\\.lib$"), ".pdb"));
  633. for (var k = 0; k < names.length; k++) {
  634. var pdbname = names[k];
  635. candidate = bindir + "\\" + pdbname;
  636. if (FSO.FileExists(candidate)) {
  637. FSO.CopyFile(candidate, build_dir + "\\" + pdbname, true);
  638. return true;
  639. }
  640. candidate = libdir + "\\" + pdbname;
  641. if (FSO.FileExists(candidate)) {
  642. FSO.CopyFile(candidate, build_dir + "\\" + pdbname, true);
  643. return true;
  644. }
  645. }
  646. return false;
  647. }
  648. function CHECK_LIB(libnames, target, path_to_check, common_name)
  649. {
  650. STDOUT.Write("Checking for library " + libnames + " ... ");
  651. if (common_name == null && target != null) {
  652. common_name = target;
  653. }
  654. if (path_to_check == null) {
  655. path_to_check = "";
  656. }
  657. // if they specified a common name for the package that contains
  658. // the library, tag some useful defaults on to the end of the
  659. // path to be searched
  660. if (common_name != null) {
  661. path_to_check += ";" + PHP_PHP_BUILD + "\\" + common_name + "*";
  662. path_to_check += ";" + PHP_PHP_BUILD + "\\lib\\" + common_name + "*";
  663. path_to_check += ";..\\" + common_name + "*";
  664. }
  665. // Determine target for build flags
  666. if (target == null) {
  667. target = "";
  668. } else {
  669. target = "_" + target.toUpperCase();
  670. }
  671. // Expand path to include general dirs
  672. path_to_check += ";" + php_usual_lib_suspects;
  673. // It is common practice to put libs under one of these dir names
  674. var subdirs = new Array(PHP_DEBUG == "yes" ? "Debug" : (PHP_DEBUG_PACK == "yes"?"Release_Dbg":"Release"), "lib", "libs", "libexec");
  675. // libnames can be ; separated list of accepted library names
  676. libnames = libnames.split(';');
  677. // for debug builds, lib may have _debug appended, we want that first
  678. if (PHP_DEBUG == "yes") {
  679. var length = libnames.length;
  680. for (var i = 0; i < length; i++) {
  681. var name = new String(libnames[i]);
  682. rExp = /.lib$/i;
  683. name = name.replace(rExp,"_debug.lib");
  684. libnames.unshift(name);
  685. }
  686. }
  687. var i, j, k, libname;
  688. var location = false;
  689. var path = path_to_check.split(';');
  690. for (i = 0; i < libnames.length; i++) {
  691. libname = libnames[i];
  692. for (k = 0; k < path.length; k++) {
  693. location = glob(path[k] + "\\" + libname);
  694. if (location) {
  695. location = location[0];
  696. break;
  697. }
  698. for (j = 0; j < subdirs.length; j++) {
  699. location = glob(path[k] + "\\" + subdirs[j] + "\\" + libname);
  700. if (location) {
  701. location = location[0];
  702. break;
  703. }
  704. }
  705. if (location)
  706. break;
  707. }
  708. if (location) {
  709. location = condense_path(location);
  710. var libdir = FSO.GetParentFolderName(location);
  711. libname = FSO.GetFileName(location);
  712. ADD_FLAG("LDFLAGS" + target, '/libpath:"' + libdir + '" ');
  713. ADD_FLAG("ARFLAGS" + target, '/libpath:"' + libdir + '" ');
  714. ADD_FLAG("LIBS" + target, libname);
  715. STDOUT.WriteLine(verbalize_deps_path(location));
  716. copy_dep_pdb_into_build_dir(location);
  717. return location;
  718. }
  719. // Check in their standard lib path
  720. location = find_pattern_in_path(libname, WshShell.Environment("Process").Item("LIB"));
  721. if (location) {
  722. location = condense_path(location);
  723. libname = FSO.GetFileName(location);
  724. ADD_FLAG("LIBS" + target, libname);
  725. STDOUT.WriteLine("<in LIB path> " + libname);
  726. return location;
  727. }
  728. // Check in their general extra libs path
  729. location = find_pattern_in_path(libname, PHP_EXTRA_LIBS);
  730. if (location) {
  731. location = condense_path(location);
  732. libname = FSO.GetFileName(location);
  733. ADD_FLAG("LIBS" + target, libname);
  734. STDOUT.WriteLine("<in extra libs path>");
  735. copy_dep_pdb_into_build_dir(location);
  736. return location;
  737. }
  738. }
  739. STDOUT.WriteLine("<not found>");
  740. return false;
  741. }
  742. function OLD_CHECK_LIB(libnames, target, path_to_check)
  743. {
  744. if (target == null) {
  745. target = "";
  746. } else {
  747. target = "_" + target.toUpperCase();
  748. }
  749. if (path_to_check == null) {
  750. path_to_check = php_usual_lib_suspects;
  751. } else {
  752. path_to_check += ";" + php_usual_lib_suspects;
  753. }
  754. var have = 0;
  755. var p;
  756. var i;
  757. var libname;
  758. var subdir = PHP_DEBUG == "yes" ? "Debug" : (PHP_DEBUG_PACK == "yes"?"Release_Dbg":"Release");
  759. libnames = libnames.split(';');
  760. for (i = 0; i < libnames.length; i++) {
  761. libname = libnames[i];
  762. p = search_paths(libname, path_to_check, "LIB");
  763. if (!p) {
  764. p = search_paths(subdir + "\\" + libname, path_to_check, "LIB");
  765. if (p) {
  766. p += "\\" + subdir;
  767. }
  768. }
  769. if (typeof(p) == "string") {
  770. ADD_FLAG("LDFLAGS" + target, '/libpath:"' + p + '" ');
  771. ADD_FLAG("ARFLAGS" + target, '/libpath:"' + p + '" ');
  772. ADD_FLAG("LIBS" + target, libname);
  773. have = 1;
  774. } else if (p == true) {
  775. ADD_FLAG("LIBS" + target, libname);
  776. have = 1;
  777. } else {
  778. /* not found in the defaults or the explicit paths,
  779. * so check the general extra libs; if we find
  780. * it here, no need to add another /libpath: for it as we
  781. * already have it covered, but we need to add the lib
  782. * to LIBS_XXX */
  783. if (false != search_paths(libname, PHP_EXTRA_LIBS, null)) {
  784. ADD_FLAG("LIBS" + target, libname);
  785. have = 1;
  786. }
  787. }
  788. if (have) {
  789. break;
  790. }
  791. }
  792. // AC_DEFINE("HAVE_" + header_name.toUpperCase().replace(new RegExp("/\\\\-\.", "g"), "_"), have);
  793. return have;
  794. }
  795. function CHECK_FUNC_IN_HEADER(header_name, func_name, path_to_check, add_to_flag)
  796. {
  797. var c = false;
  798. var sym;
  799. STDOUT.Write("Checking for " + func_name + " in " + header_name + " ... ");
  800. c = GREP_HEADER(header_name, func_name, path_to_check);
  801. sym = func_name.toUpperCase();
  802. sym = sym.replace(new RegExp("[\\\\/\.-]", "g"), "_");
  803. if (typeof(add_to_flag) == "undefined") {
  804. AC_DEFINE("HAVE_" + sym, c ? 1 : 0);
  805. } else {
  806. ADD_FLAG(add_to_flag, "/DHAVE_" + sym + "=" + (c ? "1" : "0"));
  807. }
  808. if (c) {
  809. STDOUT.WriteLine("OK");
  810. return c;
  811. }
  812. STDOUT.WriteLine("No");
  813. return false;
  814. }
  815. function GREP_HEADER(header_name, regex, path_to_check)
  816. {
  817. var c = false;
  818. if (FSO.FileExists(path_to_check + "\\" + header_name)) {
  819. c = file_get_contents(path_to_check + "\\" + header_name);
  820. }
  821. if (!c) {
  822. /* look in the include path */
  823. var p = search_paths(header_name, path_to_check, "INCLUDE");
  824. if (typeof(p) == "string") {
  825. c = file_get_contents(p);
  826. } else if (p == false) {
  827. p = search_paths(header_name, PHP_EXTRA_INCLUDES, null);
  828. if (typeof(p) == "string") {
  829. c = file_get_contents(p);
  830. }
  831. }
  832. if (!c) {
  833. return false;
  834. }
  835. }
  836. if (typeof(regex) == "string") {
  837. regex = new RegExp(regex);
  838. }
  839. if (c.match(regex)) {
  840. /* caller can now use RegExp.$1 etc. to get at patterns */
  841. return true;
  842. }
  843. return false;
  844. }
  845. function CHECK_HEADER_ADD_INCLUDE(header_name, flag_name, path_to_check, use_env, add_dir_part, add_to_flag_only)
  846. {
  847. var dir_part_to_add = "";
  848. if (use_env == null) {
  849. use_env = true;
  850. }
  851. // if true, add the dir part of the header_name to the include path
  852. if (add_dir_part == null) {
  853. add_dir_part = false;
  854. } else if (add_dir_part) {
  855. var basename = FSO.GetFileName(header_name);
  856. dir_part_to_add = "\\" + header_name.substr(0, header_name.length - basename.length - 1);
  857. }
  858. if (path_to_check == null) {
  859. path_to_check = php_usual_include_suspects;
  860. } else {
  861. path_to_check += ";" + php_usual_include_suspects;
  862. }
  863. var p = search_paths(header_name, path_to_check, use_env ? "INCLUDE" : null);
  864. var have = 0;
  865. var sym;
  866. if (typeof(p) == "string") {
  867. ADD_FLAG(flag_name, '/I "' + p + dir_part_to_add + '" ');
  868. } else if (p == false) {
  869. /* Not found in the defaults or the explicit paths,
  870. * so check the general extra includes; if we find
  871. * it here, no need to add another /I for it as we
  872. * already have it covered, unless we are adding
  873. * the dir part.... */
  874. p = search_paths(header_name, PHP_EXTRA_INCLUDES, null);
  875. if (typeof(p) == "string" && add_dir_part) {
  876. ADD_FLAG(flag_name, '/I "' + p + dir_part_to_add + '" ');
  877. }
  878. }
  879. have = p ? 1 : 0
  880. sym = header_name.toUpperCase();
  881. sym = sym.replace(new RegExp("[\\\\/\.-]", "g"), "_");
  882. if (typeof(add_to_flag_only) == "undefined" &&
  883. flag_name.match(new RegExp("^CFLAGS_(.*)$"))) {
  884. add_to_flag_only = true;
  885. }
  886. if (typeof(add_to_flag_only) != "undefined") {
  887. ADD_FLAG(flag_name, "/DHAVE_" + sym + "=" + have);
  888. } else if (!configure_hdr.Exists('HAVE_' + sym)) {
  889. AC_DEFINE("HAVE_" + sym, have, "have the " + header_name + " header file");
  890. }
  891. return p;
  892. }
  893. /* XXX check whether some manifest was originally supplied, otherwise keep using the default. */
  894. function generate_version_info_manifest(makefiletarget)
  895. {
  896. var manifest_name = makefiletarget + ".manifest";
  897. if (MODE_PHPIZE) {
  898. MFO.WriteLine("$(BUILD_DIR)\\" + manifest_name + ": " + PHP_DIR + "\\build\\default.manifest");
  899. MFO.WriteLine("\t" + CMD_MOD2 + "copy " + PHP_DIR + "\\build\\default.manifest $(BUILD_DIR)\\" + makefiletarget + ".manifest >nul");
  900. } else {
  901. MFO.WriteLine("$(BUILD_DIR)\\" + manifest_name + ": win32\\build\\default.manifest");
  902. MFO.WriteLine("\t" + CMD_MOD2 + "copy $(PHP_SRC_DIR)\\win32\\build\\default.manifest $(BUILD_DIR)\\" + makefiletarget + ".manifest >nul");
  903. }
  904. return manifest_name;
  905. }
  906. /* Emits rule to generate version info for a SAPI
  907. * or extension. Returns the name of the .res file
  908. * that will be generated */
  909. function generate_version_info_resource(makefiletarget, basename, creditspath, sapi)
  910. {
  911. var resname = makefiletarget + ".res";
  912. var res_desc = makefiletarget;
  913. var res_prod_name = "PHP " + makefiletarget;
  914. var credits;
  915. var thanks = "";
  916. var logo = "";
  917. var debug = "";
  918. var project_url = "http://www.php.net";
  919. var project_header = creditspath + "/php_" + basename + ".h";
  920. var versioning = "";
  921. if (sapi) {
  922. var internal_name = basename.toUpperCase() + " SAPI";
  923. } else {
  924. var internal_name = basename.toUpperCase() + " extension";
  925. }
  926. if (FSO.FileExists(creditspath + '/CREDITS')) {
  927. credits = FSO.OpenTextFile(creditspath + '/CREDITS', 1);
  928. res_desc = credits.ReadLine();
  929. try {
  930. thanks = credits.ReadLine();
  931. } catch (e) {
  932. thanks = null;
  933. }
  934. if (thanks == null) {
  935. thanks = "";
  936. } else {
  937. thanks = "Thanks to " + thanks;
  938. }
  939. credits.Close();
  940. }
  941. if (creditspath.match(new RegExp("pecl"))) {
  942. /* PECL project url - this will eventually work correctly for all */
  943. project_url = "http://pecl.php.net/" + basename;
  944. /* keep independent versioning PECL-specific for now */
  945. if (FSO.FileExists(project_header)) {
  946. if (header = FSO.OpenTextFile(project_header, 1)) {
  947. contents = header.ReadAll();
  948. /* allowed: x.x.x[a|b|-alpha|-beta][RCx][-dev] */
  949. if (contents.match(new RegExp('PHP_' + basename.toUpperCase() + '_VERSION(\\s+)"((\\d+\.\\d+(\.\\d+)?)((a|b)(\\d)?|\-[a-z]{3,5})?(RC\\d+)?(\-dev)?)'))) {
  950. project_version = RegExp.$2;
  951. file_version = RegExp.$3.split('.');
  952. if (!file_version[2]) {
  953. file_version[2] = 0;
  954. }
  955. versioning = '\\"" /d EXT_FILE_VERSION=' + file_version[0] + ',' + file_version[1] + ',' + file_version[2] + ' /d EXT_VERSION="\\"' + project_version;
  956. }
  957. header.Close();
  958. }
  959. }
  960. }
  961. if (makefiletarget.match(new RegExp("\\.exe$"))) {
  962. logo = " /d WANT_LOGO ";
  963. }
  964. if (PHP_DEBUG != "no") {
  965. debug = " /d _DEBUG";
  966. }
  967. /**
  968. * Use user supplied template.rc if it exists
  969. */
  970. if (FSO.FileExists(creditspath + '\\template.rc')) {
  971. MFO.WriteLine("$(BUILD_DIR)\\" + resname + ": " + creditspath + "\\template.rc");
  972. MFO.WriteLine("\t" + CMD_MOD1 + "$(RC) /nologo $(BASE_INCLUDES) /fo $(BUILD_DIR)\\" + resname + logo + debug +
  973. ' /d FILE_DESCRIPTION="\\"' + res_desc + '\\"" /d FILE_NAME="\\"' +
  974. makefiletarget + '\\"" /d PRODUCT_NAME="\\"' + res_prod_name +
  975. versioning + '\\"" /d THANKS_GUYS="\\"' + thanks + '\\"" ' +
  976. creditspath + '\\template.rc');
  977. return resname;
  978. }
  979. if (MODE_PHPIZE) {
  980. MFO.WriteLine("$(BUILD_DIR)\\" + resname + ": $(PHP_DIR)\\build\\template.rc");
  981. MFO.WriteLine("\t" + CMD_MOD1 + "$(RC) /nologo $(BASE_INCLUDES) /I $(PHP_DIR)/include /n /fo $(BUILD_DIR)\\" + resname + logo + debug +
  982. ' /d FILE_DESCRIPTION="\\"' + res_desc + '\\"" /d FILE_NAME="\\"'
  983. + makefiletarget + '\\"" /d URL="\\"' + project_url +
  984. '\\"" /d INTERNAL_NAME="\\"' + internal_name + versioning +
  985. '\\"" /d THANKS_GUYS="\\"' + thanks + '\\"" $(PHP_DIR)\\build\\template.rc');
  986. } else {
  987. MFO.WriteLine("$(BUILD_DIR)\\" + resname + ": win32\\build\\template.rc");
  988. MFO.WriteLine("\t" + CMD_MOD1 + "$(RC) /nologo $(BASE_INCLUDES) /n /fo $(BUILD_DIR)\\" + resname + logo + debug +
  989. ' /d FILE_DESCRIPTION="\\"' + res_desc + '\\"" /d FILE_NAME="\\"'
  990. + makefiletarget + '\\"" /d URL="\\"' + project_url +
  991. '\\"" /d INTERNAL_NAME="\\"' + internal_name + versioning +
  992. '\\"" /d THANKS_GUYS="\\"' + thanks + '\\"" win32\\build\\template.rc');
  993. }
  994. MFO.WriteBlankLines(1);
  995. return resname;
  996. }
  997. /* Check if PGO is enabled for given module. To disable PGO for a particular module,
  998. define a global variable by the following name scheme before SAPI() or EXTENSION() call
  999. var PHP_MYMODULE_PGO = false; */
  1000. function is_pgo_desired(mod)
  1001. {
  1002. var varname = "PHP_" + mod.toUpperCase() + "_PGO";
  1003. /* XXX enable PGO in phpize mode */
  1004. if (MODE_PHPIZE) {
  1005. return false;
  1006. }
  1007. /* don't disable if there's no mention of the varname */
  1008. if (eval("typeof " + varname + " == 'undefined'")) {
  1009. return true;
  1010. }
  1011. return eval("!!" + varname);
  1012. }
  1013. function SAPI(sapiname, file_list, makefiletarget, cflags, obj_dir)
  1014. {
  1015. var SAPI = sapiname.toUpperCase();
  1016. var ldflags;
  1017. var resname;
  1018. var ld;
  1019. var manifest;
  1020. if (typeof(obj_dir) == "undefined") {
  1021. sapiname_for_printing = configure_module_dirname;
  1022. } else {
  1023. sapiname_for_printing = configure_module_dirname + " (via " + obj_dir + ")";
  1024. }
  1025. STDOUT.WriteLine("Enabling SAPI " + sapiname_for_printing);
  1026. MFO.WriteBlankLines(1);
  1027. MFO.WriteLine("# objects for SAPI " + sapiname);
  1028. MFO.WriteBlankLines(1);
  1029. if (cflags) {
  1030. ADD_FLAG('CFLAGS_' + SAPI, cflags);
  1031. }
  1032. ADD_SOURCES(configure_module_dirname, file_list, sapiname, obj_dir);
  1033. MFO.WriteBlankLines(1);
  1034. MFO.WriteLine("# SAPI " + sapiname);
  1035. MFO.WriteBlankLines(1);
  1036. /* generate a .res file containing version information */
  1037. resname = generate_version_info_resource(makefiletarget, sapiname, configure_module_dirname, true);
  1038. manifest_name = generate_version_info_manifest(makefiletarget);
  1039. MFO.WriteLine(makefiletarget + ": $(BUILD_DIR)\\" + makefiletarget);
  1040. MFO.WriteLine("\t" + CMD_MOD2 + "echo SAPI " + sapiname_for_printing + " build complete");
  1041. if (MODE_PHPIZE) {
  1042. MFO.WriteLine("$(BUILD_DIR)\\" + makefiletarget + ": $(DEPS_" + SAPI + ") $(" + SAPI + "_GLOBAL_OBJS) $(PHPLIB) $(BUILD_DIR)\\" + resname + " $(BUILD_DIR)\\" + manifest_name);
  1043. } else {
  1044. MFO.WriteLine("$(BUILD_DIR)\\" + makefiletarget + ": $(DEPS_" + SAPI + ") $(" + SAPI + "_GLOBAL_OBJS) $(BUILD_DIR)\\$(PHPLIB) $(BUILD_DIR)\\" + resname + " $(BUILD_DIR)\\" + manifest_name);
  1045. }
  1046. var is_lib = makefiletarget.match(new RegExp("\\.lib$"));
  1047. if (makefiletarget.match(new RegExp("\\.dll$"))) {
  1048. ldflags = "/dll $(LDFLAGS)";
  1049. manifest = "-" + CMD_MOD2 + "$(_VC_MANIFEST_EMBED_DLL)";
  1050. } else if (is_lib) {
  1051. ldflags = "$(ARFLAGS)";
  1052. ld = CMD_MOD1 + "$(MAKE_LIB)";
  1053. } else {
  1054. ldflags = "$(LDFLAGS)";
  1055. manifest = "-" + CMD_MOD2 + "$(_VC_MANIFEST_EMBED_EXE)";
  1056. }
  1057. if (PHP_SANITIZER == "yes") {
  1058. if (CLANG_TOOLSET) {
  1059. add_asan_opts("CFLAGS_" + SAPI, "LIBS_" + SAPI, (is_lib ? "ARFLAGS_" : "LDFLAGS_") + SAPI);
  1060. }
  1061. }
  1062. if(is_pgo_desired(sapiname) && (PHP_PGI == "yes" || PHP_PGO != "no")) {
  1063. // Add compiler and link flags if PGO options are selected
  1064. if (PHP_DEBUG != "yes" && PHP_PGI == "yes") {
  1065. ADD_FLAG('CFLAGS_' + SAPI, "/GL /O2");
  1066. ADD_FLAG('LDFLAGS_' + SAPI, "/LTCG /GENPROFILE");
  1067. }
  1068. else if (PHP_DEBUG != "yes" && PHP_PGO != "no") {
  1069. ADD_FLAG('CFLAGS_' + SAPI, "/GL /O2");
  1070. ADD_FLAG('LDFLAGS_' + SAPI, "/LTCG /USEPROFILE");
  1071. }
  1072. ldflags += " /PGD:$(PGOPGD_DIR)\\" + makefiletarget.substring(0, makefiletarget.indexOf(".")) + ".pgd";
  1073. }
  1074. if (MODE_PHPIZE) {
  1075. if (ld) {
  1076. MFO.WriteLine("\t" + ld + " /nologo /out:$(BUILD_DIR)\\" + makefiletarget + " " + ldflags + " $(" + SAPI + "_GLOBAL_OBJS_RESP) $(PHPLIB) $(ARFLAGS_" + SAPI + ") $(LIBS_" + SAPI + ") $(BUILD_DIR)\\" + resname);
  1077. } else {
  1078. ld = CMD_MOD1 + '"$(LINK)"';
  1079. MFO.WriteLine("\t" + ld + " /nologo " + " $(" + SAPI + "_GLOBAL_OBJS_RESP) $(PHPLIB) $(LIBS_" + SAPI + ") $(BUILD_DIR)\\" + resname + " /out:$(BUILD_DIR)\\" + makefiletarget + " " + ldflags + " $(LDFLAGS_" + SAPI + ")");
  1080. }
  1081. } else {
  1082. if (ld) {
  1083. MFO.WriteLine("\t" + ld + " /nologo /out:$(BUILD_DIR)\\" + makefiletarget + " " + ldflags + " $(" + SAPI + "_GLOBAL_OBJS_RESP) $(BUILD_DIR)\\$(PHPLIB) $(ARFLAGS_" + SAPI + ") $(LIBS_" + SAPI + ") $(BUILD_DIR)\\" + resname);
  1084. } else {
  1085. ld = CMD_MOD1 + '"$(LINK)"';
  1086. MFO.WriteLine("\t" + ld + " /nologo " + " $(" + SAPI + "_GLOBAL_OBJS_RESP) $(BUILD_DIR)\\$(PHPLIB) $(LIBS_" + SAPI + ") $(BUILD_DIR)\\" + resname + " /out:$(BUILD_DIR)\\" + makefiletarget + " " + ldflags + " $(LDFLAGS_" + SAPI + ")");
  1087. }
  1088. }
  1089. if (manifest) {
  1090. MFO.WriteLine("\t" + manifest);
  1091. }
  1092. DEFINE('CFLAGS_' + SAPI + '_OBJ', '$(CFLAGS_' + SAPI + ')');
  1093. if (configure_module_dirname.match("pecl")) {
  1094. ADD_FLAG("PECL_TARGETS", makefiletarget);
  1095. } else {
  1096. ADD_FLAG("SAPI_TARGETS", makefiletarget);
  1097. }
  1098. MFO.WriteBlankLines(1);
  1099. sapi_enabled[sapi_enabled.length] = [sapiname];
  1100. }
  1101. function ADD_DIST_FILE(filename)
  1102. {
  1103. if (configure_module_dirname.match("pecl")) {
  1104. ADD_FLAG("PECL_EXTRA_DIST_FILES", filename);
  1105. } else {
  1106. ADD_FLAG("PHP_EXTRA_DIST_FILES", filename);
  1107. }
  1108. }
  1109. function file_get_contents(filename)
  1110. {
  1111. var f, c;
  1112. try {
  1113. f = FSO.OpenTextFile(filename, 1);
  1114. c = f.ReadAll();
  1115. f.Close();
  1116. return c;
  1117. } catch (e) {
  1118. STDOUT.WriteLine("Problem reading " + filename);
  1119. return false;
  1120. }
  1121. }
  1122. // Add a dependency on another extension, so that
  1123. // the dependencies are built before extname
  1124. function ADD_EXTENSION_DEP(extname, dependson, optional)
  1125. {
  1126. var EXT = extname.toUpperCase();
  1127. var DEP = dependson.toUpperCase();
  1128. var dep_present = false;
  1129. var dep_shared = false;
  1130. try {
  1131. dep_present = eval("PHP_" + DEP);
  1132. if (dep_present != "no") {
  1133. try {
  1134. dep_shared = eval("PHP_" + DEP + "_SHARED");
  1135. } catch (e) {
  1136. dep_shared = false;
  1137. }
  1138. }
  1139. } catch (e) {
  1140. dep_present = "no";
  1141. }
  1142. if (optional) {
  1143. if (dep_present == "no") {
  1144. MESSAGE("\t" + dependson + " not found: " + dependson + " support in " + extname + " disabled");
  1145. return false;
  1146. }
  1147. }
  1148. var ext_shared = eval("PHP_" + EXT + "_SHARED");
  1149. if (dep_shared) {
  1150. if (!ext_shared) {
  1151. if (optional) {
  1152. MESSAGE("\tstatic " + extname + " cannot depend on shared " + dependson + ": " + dependson + "support disabled");
  1153. return false;
  1154. }
  1155. ERROR("static " + extname + " cannot depend on shared " + dependson);
  1156. }
  1157. ADD_FLAG("LIBS_" + EXT, "php_" + dependson + ".lib");
  1158. if (MODE_PHPIZE) {
  1159. ADD_FLAG("LDFLAGS_" + EXT, "/libpath:$(BUILD_DIR_DEV)\\lib");
  1160. ADD_FLAG("DEPS_" + EXT, "$(BUILD_DIR_DEV)\\lib\\php_" + dependson + ".lib");
  1161. } else {
  1162. ADD_FLAG("LDFLAGS_" + EXT, "/libpath:$(BUILD_DIR)");
  1163. ADD_FLAG("DEPS_" + EXT, "$(BUILD_DIR)\\php_" + dependson + ".lib");
  1164. }
  1165. } else {
  1166. if (dep_present == "no") {
  1167. if (ext_shared) {
  1168. WARNING(extname + " cannot be built: missing dependency, " + dependson + " not found");
  1169. var dllname = ' php_' + extname + '.dll';
  1170. if (!REMOVE_TARGET(dllname, 'EXT_TARGETS')) {
  1171. REMOVE_TARGET(dllname, 'PECL_TARGETS');
  1172. }
  1173. return false;
  1174. }
  1175. ERROR("Cannot build " + extname + "; " + dependson + " not enabled");
  1176. return false;
  1177. }
  1178. } // dependency is statically built-in to PHP
  1179. return true;
  1180. }
  1181. var static_pgo_enabled = false;
  1182. function ZEND_EXTENSION(extname, file_list, shared, cflags, dllname, obj_dir)
  1183. {
  1184. EXTENSION(extname, file_list, shared, cflags, dllname, obj_dir);
  1185. extensions_enabled[extensions_enabled.length - 1][2] = true;
  1186. }
  1187. function EXTENSION(extname, file_list, shared, cflags, dllname, obj_dir)
  1188. {
  1189. var objs = null;
  1190. var EXT = extname.toUpperCase();
  1191. var extname_for_printing;
  1192. var ldflags;
  1193. if (shared == null) {
  1194. if (force_all_shared()) {
  1195. shared = true;
  1196. eval("PHP_" + EXT + "_SHARED = true;");
  1197. } else {
  1198. eval("shared = PHP_" + EXT + "_SHARED;");
  1199. }
  1200. } else {
  1201. eval("PHP_" + EXT + "_SHARED = shared;");
  1202. }
  1203. if (cflags == null) {
  1204. cflags = "";
  1205. }
  1206. if (typeof(obj_dir) == "undefined") {
  1207. extname_for_printing = configure_module_dirname;
  1208. } else {
  1209. extname_for_printing = configure_module_dirname + " (via " + obj_dir + ")";
  1210. }
  1211. if (shared) {
  1212. STDOUT.WriteLine("Enabling extension " + extname_for_printing + " [shared]");
  1213. cflags = "/D COMPILE_DL_" + EXT + " /D " + EXT + "_EXPORTS=1 " + cflags;
  1214. ADD_FLAG("CFLAGS_PHP", "/D COMPILE_DL_" + EXT);
  1215. } else {
  1216. STDOUT.WriteLine("Enabling extension " + extname_for_printing);
  1217. }
  1218. MFO.WriteBlankLines(1);
  1219. MFO.WriteLine("# objects for EXT " + extname);
  1220. MFO.WriteBlankLines(1);
  1221. ADD_SOURCES(configure_module_dirname, file_list, extname, obj_dir);
  1222. MFO.WriteBlankLines(1);
  1223. if (shared) {
  1224. if (dllname == null) {
  1225. dllname = "php_" + extname + ".dll";
  1226. }
  1227. var libname = dllname.substring(0, dllname.length-4) + ".lib";
  1228. var resname = generate_version_info_resource(dllname, extname, configure_module_dirname, false);
  1229. var ld = CMD_MOD1 + '"$(LINK)"';
  1230. var manifest_name = generate_version_info_manifest(dllname);
  1231. ldflags = "";
  1232. if (is_pgo_desired(extname) && (PHP_PGI == "yes" || PHP_PGO != "no")) {
  1233. // Add compiler and link flags if PGO options are selected
  1234. if (PHP_DEBUG != "yes" && PHP_PGI == "yes") {
  1235. ADD_FLAG('LDFLAGS_' + EXT, "/LTCG /GENPROFILE");
  1236. }
  1237. else if (PHP_DEBUG != "yes" && PHP_PGO != "no") {
  1238. ADD_FLAG('LDFLAGS_' + EXT, "/LTCG /USEPROFILE");
  1239. }
  1240. ADD_FLAG('CFLAGS_' + EXT, "/GL /O2");
  1241. ldflags = " /PGD:$(PGOPGD_DIR)\\" + dllname.substring(0, dllname.indexOf(".")) + ".pgd";
  1242. }
  1243. MFO.WriteLine("$(BUILD_DIR)\\" + libname + ": $(BUILD_DIR)\\" + dllname);
  1244. MFO.WriteBlankLines(1);
  1245. if (MODE_PHPIZE) {
  1246. MFO.WriteLine("$(BUILD_DIR)\\" + dllname + ": $(DEPS_" + EXT + ") $(" + EXT + "_GLOBAL_OBJS) $(PHPLIB) $(BUILD_DIR)\\" + resname + " $(BUILD_DIR)\\" + manifest_name);
  1247. MFO.WriteLine("\t" + ld + " $(" + EXT + "_GLOBAL_OBJS_RESP) $(PHPLIB) $(LIBS_" + EXT + ") $(LIBS) $(BUILD_DIR)\\" + resname + " /out:$(BUILD_DIR)\\" + dllname + " $(DLL_LDFLAGS) $(LDFLAGS) $(LDFLAGS_" + EXT + ")");
  1248. } else {
  1249. MFO.WriteLine("$(BUILD_DIR)\\" + dllname + ": $(DEPS_" + EXT + ") $(" + EXT + "_GLOBAL_OBJS) $(BUILD_DIR)\\$(PHPLIB) $(BUILD_DIR)\\" + resname + " $(BUILD_DIR)\\" + manifest_name);
  1250. MFO.WriteLine("\t" + ld + " $(" + EXT + "_GLOBAL_OBJS_RESP) $(BUILD_DIR)\\$(PHPLIB) $(LIBS_" + EXT + ") $(LIBS) $(BUILD_DIR)\\" + resname + " /out:$(BUILD_DIR)\\" + dllname + ldflags + " $(DLL_LDFLAGS) $(LDFLAGS) $(LDFLAGS_" + EXT + ")");
  1251. }
  1252. MFO.WriteLine("\t-" + CMD_MOD2 + "$(_VC_MANIFEST_EMBED_DLL)");
  1253. MFO.WriteBlankLines(1);
  1254. if (configure_module_dirname.match("pecl")) {
  1255. ADD_FLAG("PECL_TARGETS", dllname);
  1256. } else {
  1257. ADD_FLAG("EXT_TARGETS", dllname);
  1258. }
  1259. MFO.WriteLine(dllname + ": $(BUILD_DIR)\\" + dllname);
  1260. MFO.WriteLine("\t" + CMD_MOD2 + "echo EXT " + extname + " build complete");
  1261. MFO.WriteBlankLines(1);
  1262. DEFINE('CFLAGS_' + EXT + '_OBJ', '$(CFLAGS_' + EXT + ')');
  1263. } else {
  1264. ADD_FLAG("STATIC_EXT_OBJS", "$(" + EXT + "_GLOBAL_OBJS)");
  1265. ADD_FLAG("STATIC_EXT_OBJS_RESP", "$(" + EXT + "_GLOBAL_OBJS_RESP)");
  1266. ADD_FLAG("STATIC_EXT_LIBS", "$(LIBS_" + EXT + ")");
  1267. ADD_FLAG("STATIC_EXT_LDFLAGS", "$(LDFLAGS_" + EXT + ")");
  1268. ADD_FLAG("STATIC_EXT_CFLAGS", "$(CFLAGS_" + EXT + ")");
  1269. if (is_pgo_desired(extname) && (PHP_PGI == "yes" || PHP_PGO != "no")) {
  1270. if (!static_pgo_enabled) {
  1271. if (PHP_DEBUG != "yes" && PHP_PGI == "yes") {
  1272. ADD_FLAG('STATIC_EXT_LDFLAGS', "/LTCG:PGINSTRUMENT");
  1273. }
  1274. else if (PHP_DEBUG != "yes" && PHP_PGO != "no") {
  1275. ADD_FLAG('STATIC_EXT_LDFLAGS', "/LTCG:PGUPDATE");
  1276. }
  1277. ADD_FLAG("STATIC_EXT_CFLAGS", "/GL /O2");
  1278. static_pgo_enabled = true;
  1279. }
  1280. }
  1281. /* find the header that declares the module pointer,
  1282. * so we can include it in internal_functions.c */
  1283. var ext_dir = FSO.GetFolder(configure_module_dirname);
  1284. var fc = new Enumerator(ext_dir.Files);
  1285. var re = /\.h$/;
  1286. var s, c;
  1287. for (; !fc.atEnd(); fc.moveNext()) {
  1288. s = fc.item() + "";
  1289. if (s.match(re)) {
  1290. c = file_get_contents(s);
  1291. if (c.match("phpext_")) {
  1292. extension_include_code += '#include "' + configure_module_dirname + '/' + FSO.GetFileName(s) + '"\r\n';
  1293. }
  1294. }
  1295. }
  1296. extension_module_ptrs += '\tphpext_' + extname + '_ptr,\r\n';
  1297. DEFINE('CFLAGS_' + EXT + '_OBJ', '$(CFLAGS_PHP) $(CFLAGS_' + EXT + ')');
  1298. }
  1299. if (MODE_PHPIZE) {
  1300. if (!FSO.FileExists(PHP_DIR + "/include/main/config.pickle.h")) {
  1301. var _tmp = FSO.CreateTextFile(PHP_DIR + "/include/main/config.pickle.h", true);
  1302. _tmp.Close();
  1303. }
  1304. cflags = "/FI main/config.pickle.h " + cflags;
  1305. }
  1306. ADD_FLAG("CFLAGS_" + EXT, cflags);
  1307. // [extname, shared, zend]
  1308. extensions_enabled[extensions_enabled.length] = [extname, shared ? 'shared' : 'static', false];
  1309. }
  1310. function ADD_SOURCES(dir, file_list, target, obj_dir)
  1311. {
  1312. var i;
  1313. var tv;
  1314. var src, obj, sym, flags;
  1315. if (target == null) {
  1316. target = "php";
  1317. }
  1318. sym = target.toUpperCase() + "_GLOBAL_OBJS";
  1319. flags = "CFLAGS_" + target.toUpperCase() + '_OBJ';
  1320. var bd = get_define('BUILD_DIR');
  1321. var respd = bd + '\\resp';
  1322. if (!FSO.FolderExists(respd)) {
  1323. FSO.CreateFolder(respd);
  1324. }
  1325. var obj_lst_fn = respd + '\\' + sym + '.txt';
  1326. var resp = "";
  1327. if (configure_subst.Exists(sym)) {
  1328. tv = configure_subst.Item(sym);
  1329. } else {
  1330. if (FSO.FileExists(obj_lst_fn)) {
  1331. FSO.DeleteFile(obj_lst_fn, true);
  1332. }
  1333. tv = "";
  1334. }
  1335. file_list = file_list.split(new RegExp("\\s+"));
  1336. file_list.sort();
  1337. var re = new RegExp("\.[a-z0-9A-Z]+$");
  1338. dir = dir.replace(new RegExp("/", "g"), "\\");
  1339. var objs_line = "";
  1340. var srcs_line = "";
  1341. var sub_build = "$(BUILD_DIR)\\";
  1342. var srcs_by_dir = {};
  1343. /* Parse the file list to create an aggregated structure based on the subdirs passed. */
  1344. for (i in file_list) {
  1345. src = file_list[i];
  1346. var _tmp = src.split("\\");
  1347. var filename = _tmp.pop();
  1348. // build the obj out dir and use it as a key
  1349. var dirname = _tmp.join("\\");
  1350. //WARNING("dir: " + dir + " dirname: " + dirname + " filename: " + filename);
  1351. /* if module dir is not a child of the main source dir,
  1352. * we need to tweak it; we should have detected such a
  1353. * case in condense_path and rewritten the path to
  1354. * be relative.
  1355. * This probably breaks for non-sibling dirs, but that
  1356. * is not a problem as buildconf only checks for pecl
  1357. * as either a child or a sibling */
  1358. if (obj_dir == null) {
  1359. if (MODE_PHPIZE) {
  1360. /* In the phpize mode, the subdirs are always relative to BUID_DIR.
  1361. No need to differentiate by extension, only one gets built. */
  1362. var build_dir = (dirname ? dirname : "").replace(new RegExp("^..\\\\"), "");
  1363. } else {
  1364. var build_dir = (dirname ? (dir + "\\" + dirname) : dir).replace(new RegExp("^..\\\\"), "");
  1365. }
  1366. }
  1367. else {
  1368. var build_dir = (dirname ? obj_dir + "\\" + dirname : obj_dir).replace(new RegExp("^..\\\\"), "");
  1369. }
  1370. obj = sub_build + build_dir + "\\" + filename.replace(re, ".obj");
  1371. if (i > 0) {
  1372. srcs_line += " " + dir + "\\" + src;
  1373. objs_line += " " + obj
  1374. } else {
  1375. srcs_line = dir + "\\" + src;
  1376. objs_line = obj;
  1377. }
  1378. resp += " " + obj.replace('$(BUILD_DIR)', bd);
  1379. tv += " " + obj;
  1380. if (!srcs_by_dir.hasOwnProperty(build_dir)) {
  1381. srcs_by_dir[build_dir] = [];
  1382. }
  1383. /* storing the index from the file_list */
  1384. srcs_by_dir[build_dir].push(i);
  1385. }
  1386. /* Create makefile build targets and dependencies. */
  1387. MFO.WriteLine(objs_line + ": " + srcs_line);
  1388. /* Create target subdirs if any and produce the compiler calls, /mp is respected if enabled. */
  1389. for (var k in srcs_by_dir) {
  1390. var dirs = k.split("\\");
  1391. var i, d = "";
  1392. for (i = 0; i < dirs.length; i++) {
  1393. d += dirs[i];
  1394. build_dirs[build_dirs.length] = d;
  1395. d += "\\";
  1396. }
  1397. var mangle_dir = k.replace(new RegExp("[\\\\/.-]", "g"), "_");
  1398. var bd_flags_name = "CFLAGS_BD_" + mangle_dir.toUpperCase();
  1399. DEFINE(bd_flags_name, "/Fp" + sub_build + d + " /FR" + sub_build + d + " ");
  1400. if (VS_TOOLSET) {
  1401. ADD_FLAG(bd_flags_name, "/Fd" + sub_build + d);
  1402. }
  1403. if (PHP_ANALYZER == "clang") {
  1404. var analyzer_base_args = X64 ? "-m64" : "-m32";
  1405. var analyzer_base_flags = "";
  1406. analyzer_base_args += " --analyze";
  1407. var vc_ver;
  1408. if (VS_TOOLSET) {
  1409. vc_ver = VCVERS;
  1410. } else {
  1411. vc_ver = probe_binary(PATH_PROG('cl', null));
  1412. }
  1413. analyzer_base_args += " -fms-compatibility -fms-compatibility-version=" + vc_ver + " -fms-extensions -Xclang -analyzer-output=text -Xclang -fmodules";
  1414. } else if (PHP_ANALYZER == "cppcheck") {
  1415. var analyzer_base_args = "";
  1416. var analyzer_base_flags = "";
  1417. if (VS_TOOLSET) {
  1418. analyzer_base_flags += " -D _MSC_VER=" + VCVERS;
  1419. } else {
  1420. analyzer_base_flags += " -D _MSC_VER=" + probe_binary(PATH_PROG('cl', null));
  1421. }
  1422. if (X64) {
  1423. analyzer_base_flags += " -D _M_X64 -D _WIN64";
  1424. } else {
  1425. analyzer_base_flags += " -D _M_IX86 ";
  1426. }
  1427. analyzer_base_flags += " -D _WIN32 -D WIN32 -D _WINDOWS";
  1428. var vc_incs = WshShell.Environment("Process").Item("INCLUDE").split(";")
  1429. for (i in vc_incs) {
  1430. if (!vc_incs[i].length) {
  1431. continue;
  1432. }
  1433. analyzer_base_flags += " -I " + "\"" + vc_incs[i] + "\"";
  1434. }
  1435. var cppcheck_platform = X64 ? "win64" : "win32A";
  1436. var cppcheck_lib = "win32\\build\\cppcheck_" + (X64 ? "x64" : "x86") + ".cfg";
  1437. analyzer_base_args += "--enable=warning,performance,portability,information,missingInclude " +
  1438. "--platform=" + cppcheck_platform + " " +
  1439. "--library=windows.cfg --library=microsoft_sal.cfg " +
  1440. "--library=win32\\build\\cppcheck.cfg " +
  1441. "--library=" + cppcheck_lib + " " +
  1442. /* "--rule-file=win32\build\cppcheck_rules.xml " + */
  1443. " --std=c89 --std=c++11 " +
  1444. "--quiet --inconclusive --template=vs -j 4 " +
  1445. "--suppress=unmatchedSuppression " +
  1446. "--suppressions-list=win32\\build\\cppcheck_suppress.txt ";
  1447. var cppcheck_build_dir = get_define("CPPCHECK_BUILD_DIR");
  1448. if (!!cppcheck_build_dir) {
  1449. analyzer_base_args += "--cppcheck-build-dir=$(CPPCHECK_BUILD_DIR)";
  1450. }
  1451. }
  1452. if (PHP_MP_DISABLED) {
  1453. for (var j in srcs_by_dir[k]) {
  1454. src = file_list[srcs_by_dir[k][j]];
  1455. var _tmp = src.split("\\");
  1456. var filename = _tmp.pop();
  1457. obj = filename.replace(re, ".obj");
  1458. MFO.WriteLine("\t" + CMD_MOD1 + "$(CC) $(" + flags + ") $(CFLAGS) $(" + bd_flags_name + ") /c " + dir + "\\" + src + " /Fo" + sub_build + d + obj);
  1459. if ("clang" == PHP_ANALYZER) {
  1460. MFO.WriteLine("\t" + CMD_MOD1 + "\"$(CLANG_CL)\" " + analyzer_base_args + " $(" + flags + "_ANALYZER) $(CFLAGS_ANALYZER) $(" + bd_flags_name + "_ANALYZER) " + dir + "\\" + src);
  1461. } else if ("cppcheck" == PHP_ANALYZER) {
  1462. MFO.WriteLine("\t\"" + CMD_MOD1 + "$(CPPCHECK)\" " + analyzer_base_args + " $(" + flags + "_ANALYZER) $(CFLAGS_ANALYZER) $(" + bd_flags_name + "_ANALYZER) " + analyzer_base_flags + " " + dir + "\\" + src);
  1463. }else if (PHP_ANALYZER == "pvs") {
  1464. MFO.WriteLine("\t" + CMD_MOD1 + "\"$(PVS_STUDIO)\" --cl-params $(" + flags + ") $(CFLAGS) $(" + bd_flags_name + ") /c " + dir + "\\" + src + " --source-file " + dir + "\\" + src
  1465. + " --cfg PVS-Studio.conf --errors-off \"V122 V117 V111\" ");
  1466. }
  1467. }
  1468. } else {
  1469. /* TODO create a response file at least for the source files to work around the cmd line length limit. */
  1470. var src_line = "";
  1471. for (var j in srcs_by_dir[k]) {
  1472. src_line += dir + "\\" + file_list[srcs_by_dir[k][j]] + " ";
  1473. }
  1474. MFO.WriteLine("\t" + CMD_MOD1 + "$(CC) $(" + flags + ") $(CFLAGS) /Fo" + sub_build + d + " $(" + bd_flags_name + ") /c " + src_line);
  1475. if ("clang" == PHP_ANALYZER) {
  1476. MFO.WriteLine("\t\"$(CLANG_CL)\" " + analyzer_base_args + " $(" + flags + "_ANALYZER) $(CFLAGS_ANALYZER) $(" + bd_flags_name + "_ANALYZER) " + src_line);
  1477. } else if ("cppcheck" == PHP_ANALYZER) {
  1478. MFO.WriteLine("\t\"$(CPPCHECK)\" " + analyzer_base_args + " $(" + flags + "_ANALYZER) $(CFLAGS_ANALYZER) $(" + bd_flags_name + "_ANALYZER) " + analyzer_base_flags + " " + src_line);
  1479. }
  1480. }
  1481. }
  1482. DEFINE(sym, tv);
  1483. /* Generate the object response file and define it to the Makefile. This can be
  1484. useful when getting the "command line too long" linker errors.
  1485. TODO pack this into a function when response files are used for other kinds of info. */
  1486. var obj_lst_fh = null;
  1487. if (!FSO.FileExists(obj_lst_fn)) {
  1488. obj_lst_fh = FSO.CreateTextFile(obj_lst_fn);
  1489. } else {
  1490. obj_lst_fh = FSO.OpenTextFile(obj_lst_fn, 8);
  1491. }
  1492. obj_lst_fh.Write(" " + resp);
  1493. obj_lst_fh.Close();
  1494. DEFINE(sym + "_RESP", '@"' + obj_lst_fn + '"');
  1495. }
  1496. function REMOVE_TARGET(dllname, flag)
  1497. {
  1498. var dllname = dllname.replace(/\s/g, "");
  1499. var EXT = dllname.replace(/php_(\S+)\.dll/, "$1").toUpperCase();
  1500. var php_flags = configure_subst.Item("CFLAGS_PHP");
  1501. if (configure_subst.Exists(flag)) {
  1502. var targets = configure_subst.Item(flag);
  1503. if (targets.match(dllname)) {
  1504. configure_subst.Remove(flag);
  1505. targets = targets.replace(dllname, "");
  1506. targets = targets.replace(/\s+/, " ");
  1507. targets = targets.replace(/\s$/, "");
  1508. configure_subst.Add(flag, targets);
  1509. configure_hdr.Add("HAVE_" + EXT, new Array(0, ""));
  1510. configure_subst.Item("CFLAGS_PHP") = php_flags.replace(" /D COMPILE_DL_" + EXT, "");
  1511. extensions_enabled.pop();
  1512. return true;
  1513. }
  1514. }
  1515. return false;
  1516. }
  1517. function generate_internal_functions()
  1518. {
  1519. var infile, outfile;
  1520. var indata;
  1521. STDOUT.WriteLine("Generating main/internal_functions.c");
  1522. infile = FSO.OpenTextFile("main/internal_functions.c.in", 1);
  1523. indata = infile.ReadAll();
  1524. infile.Close();
  1525. indata = indata.replace("@EXT_INCLUDE_CODE@", extension_include_code);
  1526. indata = indata.replace("@EXT_MODULE_PTRS@", extension_module_ptrs);
  1527. if (FSO.FileExists("main/internal_functions.c")) {
  1528. var origdata = file_get_contents("main/internal_functions.c");
  1529. if (origdata == indata) {
  1530. STDOUT.WriteLine("\t[content unchanged; skipping]");
  1531. return;
  1532. }
  1533. }
  1534. outfile = FSO.CreateTextFile("main/internal_functions.c", true);
  1535. outfile.Write(indata);
  1536. outfile.Close();
  1537. }
  1538. function output_as_table(header, ar_out)
  1539. {
  1540. var l = header.length;
  1541. var cols = 80;
  1542. var fixedlength = "";
  1543. var t = 0;
  1544. var i,j,k,m;
  1545. var out = "| ";
  1546. var min = new Array(l);
  1547. var max = new Array(l);
  1548. if (!!ar_out[0] && l != ar_out[0].length) {
  1549. STDOUT.WriteLine("Invalid header argument, can't output the table " + l + " " + ar_out[0].length );
  1550. return;
  1551. }
  1552. for (j=0; j < l; j++) {
  1553. var tmax, tmin;
  1554. /* Figure out the max length per column */
  1555. tmin = 0;
  1556. tmax = 0;
  1557. for (k = 0; k < ar_out.length; k++) {
  1558. if(typeof ar_out[k][j] != 'undefined') {
  1559. var t = ar_out[k][j].length;
  1560. if (t > tmax) tmax = t;
  1561. else if (t < tmin) tmin = t;
  1562. }
  1563. }
  1564. if (tmax > header[j].length) {
  1565. max[j] = tmax;
  1566. } else {
  1567. max[j] = header[j].length;
  1568. }
  1569. if (tmin < header[j].length) {
  1570. min[j] = header[j].length;
  1571. }
  1572. }
  1573. sep = "";
  1574. k = 0;
  1575. for (i = 0; i < l; i++) {
  1576. k += max[i] + 3;
  1577. }
  1578. k++;
  1579. for (j=0; j < k; j++) {
  1580. sep += "-";
  1581. }
  1582. STDOUT.WriteLine(sep);
  1583. out = "|";
  1584. for (j=0; j < l; j++) {
  1585. out += " " + header[j];
  1586. for (var i = 0; i < (max[j] - header[j].length); i++){
  1587. out += " ";
  1588. }
  1589. out += " |";
  1590. }
  1591. STDOUT.WriteLine(out);
  1592. STDOUT.WriteLine(sep);
  1593. out = "|";
  1594. for (i=0; i < ar_out.length; i++) {
  1595. line = ar_out[i];
  1596. for (j=0; j < l; j++) {
  1597. out += " " + line[j];
  1598. if(typeof line[j] != 'undefined') {
  1599. for (var k = 0; k < (max[j] - line[j].length); k++){
  1600. out += " ";
  1601. }
  1602. }
  1603. out += " |";
  1604. }
  1605. STDOUT.WriteLine(out);
  1606. out = "|";
  1607. }
  1608. STDOUT.WriteLine(sep);
  1609. }
  1610. function write_extensions_summary()
  1611. {
  1612. var exts = new Array();
  1613. var zend_exts = new Array();
  1614. for(var x = 0; x < extensions_enabled.length; ++x)
  1615. {
  1616. var l = extensions_enabled[x];
  1617. if(l[2])
  1618. {
  1619. zend_exts.push([l[0], l[1]]);
  1620. }
  1621. else
  1622. {
  1623. exts.push([l[0], l[1]]);
  1624. }
  1625. }
  1626. STDOUT.WriteLine('Enabled extensions:');
  1627. output_as_table(['Extension', 'Mode'], exts.sort());
  1628. if(zend_exts.length)
  1629. {
  1630. STDOUT.WriteBlankLines(2);
  1631. STDOUT.WriteLine('Enabled Zend extensions:');
  1632. output_as_table(['Extension', 'Mode'], zend_exts.sort());
  1633. }
  1634. }
  1635. function write_summary()
  1636. {
  1637. var ar = new Array();
  1638. var k = 0;
  1639. STDOUT.WriteBlankLines(2);
  1640. write_extensions_summary();
  1641. STDOUT.WriteBlankLines(2);
  1642. if (!MODE_PHPIZE) {
  1643. STDOUT.WriteLine("Enabled SAPI:");
  1644. output_as_table(["Sapi Name"], sapi_enabled);
  1645. STDOUT.WriteBlankLines(2);
  1646. }
  1647. ar[k++] = ['Build type', PHP_DEBUG == "yes" ? "Debug" : "Release"];
  1648. ar[k++] = ['Thread Safety', PHP_ZTS == "yes" ? "Yes" : "No"];
  1649. ar[k++] = ['Compiler', COMPILER_NAME];
  1650. ar[k++] = ['Architecture', X64 ? 'x64' : 'x86'];
  1651. if (PHP_PGO == "yes") {
  1652. ar[k++] = ['Optimization', "PGO"];
  1653. } else if (PHP_PGI == "yes") {
  1654. ar[k++] = ['Optimization', "PGI"];
  1655. } else {
  1656. ar[k++] = ['Optimization', PHP_DEBUG == "yes" ? "disabled" : "PGO disabled"];
  1657. }
  1658. var simd = configure_subst.Item("PHP_SIMD_SCALE");
  1659. if (!!simd) {
  1660. ar[k++] = ["Native intrinsics", simd];
  1661. }
  1662. if (PHP_ANALYZER == "vs") {
  1663. ar[k++] = ['Static analyzer', 'Visual Studio'];
  1664. } else if (PHP_ANALYZER == "clang") {
  1665. ar[k++] = ['Static analyzer', 'clang'];
  1666. } else if (PHP_ANALYZER == "cppcheck") {
  1667. ar[k++] = ['Static analyzer', 'Cppcheck'];
  1668. } else if (PHP_ANALYZER == "pvs") {
  1669. ar[k++] = ['Static analyzer', 'PVS-Studio'];
  1670. } else {
  1671. ar[k++] = ['Static analyzer', 'disabled'];
  1672. }
  1673. output_as_table(["",""], ar);
  1674. STDOUT.WriteBlankLines(2);
  1675. }
  1676. function is_on_exclude_list_for_test_ini(list, name)
  1677. {
  1678. for (var i in list) {
  1679. if (name == list[i]) {
  1680. return true;
  1681. }
  1682. }
  1683. return false;
  1684. }
  1685. function generate_tmp_php_ini()
  1686. {
  1687. if ("no" == PHP_TEST_INI) {
  1688. /* Test ini generation is disabled. */
  1689. return;
  1690. }
  1691. var ini_dir = PHP_OBJECT_OUT_DIR + ("yes" == PHP_DEBUG ? "Debug" : "Release") + ("yes" == PHP_ZTS ? "_TS" : "");
  1692. PHP_TEST_INI_PATH = ini_dir + "\\tmp-php.ini";
  1693. if (FSO.FileExists(PHP_TEST_INI_PATH)) {
  1694. STDOUT.WriteLine("Generating " + PHP_TEST_INI_PATH + " ...");
  1695. var INI = FSO.OpenTextFile(PHP_TEST_INI_PATH, 2);
  1696. } else {
  1697. STDOUT.WriteLine("Regenerating " + PHP_TEST_INI_PATH + " ...");
  1698. var INI = FSO.CreateTextFile(PHP_TEST_INI_PATH, true);
  1699. }
  1700. var ext_list = PHP_TEST_INI_EXT_EXCLUDE.split(",");
  1701. INI.WriteLine("extension_dir=" + ini_dir);
  1702. for (var i in extensions_enabled) {
  1703. if ("shared" != extensions_enabled[i][1]) {
  1704. continue;
  1705. }
  1706. var directive = (extensions_enabled[i][2] ? 'zend_extension' : 'extension');
  1707. var ext_name = extensions_enabled[i][0];
  1708. if ("gd" == ext_name) {
  1709. ext_name = "gd2";
  1710. }
  1711. if (!is_on_exclude_list_for_test_ini(ext_list, ext_name)) {
  1712. INI.WriteLine(directive + "=php_" + ext_name + ".dll");
  1713. }
  1714. }
  1715. INI.Close();
  1716. }
  1717. function generate_files()
  1718. {
  1719. var i, dir, bd, last;
  1720. STDOUT.WriteBlankLines(1);
  1721. STDOUT.WriteLine("Creating build dirs...");
  1722. dir = get_define("BUILD_DIR");
  1723. build_dirs.sort();
  1724. last = null;
  1725. if (!FSO.FolderExists(dir)) {
  1726. FSO.CreateFolder(dir);
  1727. }
  1728. for (i = 0; i < build_dirs.length; i++) {
  1729. bd = FSO.BuildPath(dir, build_dirs[i]);
  1730. if (bd == last) {
  1731. continue;
  1732. }
  1733. last = bd;
  1734. build_dir = get_define('BUILD_DIR');
  1735. build_dir = build_dir.replace(new RegExp("\\\\", "g"), "\\\\");
  1736. if (build_dir.substr(build_dir.Length - 2, 2) != '\\\\') {
  1737. build_dir += '\\\\';
  1738. }
  1739. ADD_FLAG("BUILD_DIRS_SUB", bd.replace(new RegExp(build_dir), ''));
  1740. if (!FSO.FolderExists(bd)) {
  1741. FSO.CreateFolder(bd);
  1742. }
  1743. }
  1744. STDOUT.WriteLine("Generating files...");
  1745. if (!MODE_PHPIZE) {
  1746. generate_tmp_php_ini();
  1747. }
  1748. generate_makefile();
  1749. if (!MODE_PHPIZE) {
  1750. generate_internal_functions();
  1751. generate_config_h();
  1752. generate_phpize();
  1753. } else {
  1754. generate_config_pickle_h();
  1755. generate_ext_pickle();
  1756. }
  1757. STDOUT.WriteLine("Done.");
  1758. STDOUT.WriteBlankLines(1);
  1759. write_summary();
  1760. if (INVALID_CONFIG_ARGS.length) {
  1761. STDOUT.WriteLine('WARNING');
  1762. STDOUT.WriteLine('The following arguments is invalid, and therefore ignored:');
  1763. for (var i = 0; i < INVALID_CONFIG_ARGS.length; ++i) {
  1764. STDOUT.WriteLine(' ' + INVALID_CONFIG_ARGS[i]);
  1765. }
  1766. STDOUT.WriteBlankLines(2);
  1767. }
  1768. if (PHP_SNAPSHOT_BUILD != "no") {
  1769. STDOUT.WriteLine("Type 'nmake snap' to build a PHP snapshot");
  1770. } else {
  1771. STDOUT.WriteLine("Type 'nmake' to build PHP");
  1772. }
  1773. }
  1774. function generate_ext_pickle()
  1775. {
  1776. var content;
  1777. var DEPS = null;
  1778. var dest;
  1779. var deps_lines = new Array();
  1780. var build_var_name = function(name) {
  1781. return "PHP_" + name.toUpperCase();
  1782. }
  1783. STDOUT.WriteLine("Generating pickle deps");
  1784. dest = PHP_DIR + "/script/";
  1785. if (!FSO.FolderExists(dest)) {
  1786. FSO.CreateFolder(dest);
  1787. }
  1788. if (FSO.FileExists(dest + "/ext_pickle.js")) {
  1789. DEPS = FSO.OpenTextFile(dest + "/ext_pickle.js", 1);
  1790. while (!DEPS.AtEndOfStream) {
  1791. var ln = DEPS.ReadLine();
  1792. var found = false;
  1793. for (var i in extensions_enabled) {
  1794. var reg0 = new RegExp(build_var_name(extensions_enabled[i][0]) + "\s*=.+", "g");
  1795. var reg1 = new RegExp(build_var_name(extensions_enabled[i][0]) + "_SHARED" + "\s*=.+", "g");
  1796. if (ln.match(reg1) || ln.match(reg0)) {
  1797. found = true;
  1798. break;
  1799. }
  1800. }
  1801. if (!found) {
  1802. deps_lines.push(ln);
  1803. }
  1804. }
  1805. }
  1806. for (var i in extensions_enabled) {
  1807. deps_lines.push(build_var_name(extensions_enabled[i][0]) + "=true;");
  1808. deps_lines.push(build_var_name(extensions_enabled[i][0]) + "_SHARED=" + (extensions_enabled[i][1] == 'shared' ? 'true' : 'false') + ";");
  1809. }
  1810. if (!!DEPS) {
  1811. DEPS.Close();
  1812. DEPS = null;
  1813. }
  1814. /* Replace the ext_pickle.js with the new content */
  1815. DEPS = FSO.CreateTextFile(dest + "/ext_pickle.js", true);
  1816. for (var j in deps_lines) {
  1817. DEPS.WriteLine(deps_lines[j]);
  1818. }
  1819. DEPS.Close();
  1820. }
  1821. function generate_config_pickle_h()
  1822. {
  1823. var outfile = null;
  1824. var lines = new Array();
  1825. var keys = (new VBArray(configure_hdr.Keys())).toArray();
  1826. dest = PHP_DIR + "/include/main";
  1827. var ignore_key = function(key) {
  1828. var ignores = [ "CONFIGURE_COMMAND", "PHP_COMPILER_ID", "COMPILER", "ARCHITECTURE", "HAVE_STRNLEN", "PHP_DIR" ];
  1829. for (var k in ignores) {
  1830. if (ignores[k] == key) {
  1831. return true;
  1832. }
  1833. }
  1834. return false;
  1835. }
  1836. STDOUT.WriteLine("Generating main/config.pickle.h");
  1837. if (FSO.FileExists(dest + "/config.pickle.h")) {
  1838. outfile = FSO.OpenTextFile(dest + "/config.pickle.h", 1);
  1839. while (!outfile.AtEndOfStream) {
  1840. var found = false;
  1841. var ln = outfile.ReadLine();
  1842. for (var i in keys) {
  1843. var reg = new RegExp("#define[\s ]+" + keys[i] + "[\s ]*.*", "g");
  1844. if (ln.match(reg)) {
  1845. found = true;
  1846. break;
  1847. }
  1848. }
  1849. if (!found) {
  1850. lines.push(ln);
  1851. }
  1852. }
  1853. }
  1854. for (var i in keys) {
  1855. var item = configure_hdr.Item(keys[i]);
  1856. if (ignore_key(keys[i])) {
  1857. continue;
  1858. }
  1859. /* XXX fix comment handling */
  1860. /*if (!lines[j].match(/^#define.+/g)) {
  1861. continue;
  1862. }*/
  1863. lines.push("#define " + keys[i] + " " + item[0]);
  1864. }
  1865. if (outfile) {
  1866. outfile.Close();
  1867. outfile = null;
  1868. }
  1869. outfile = FSO.CreateTextFile(dest + "/config.pickle.h", true);
  1870. for (var k in lines) {
  1871. outfile.WriteLine(lines[k]);
  1872. }
  1873. outfile.Close();
  1874. }
  1875. function generate_config_h()
  1876. {
  1877. var infile, outfile;
  1878. var indata;
  1879. var prefix;
  1880. prefix = PHP_PREFIX.replace(new RegExp("\\\\", "g"), "\\\\");
  1881. STDOUT.WriteLine("Generating main/config.w32.h");
  1882. infile = FSO.OpenTextFile("win32/build/config.w32.h.in", 1);
  1883. indata = infile.ReadAll();
  1884. infile.Close();
  1885. outfile = FSO.CreateTextFile("main/config.w32.h", true);
  1886. indata = indata.replace(new RegExp("@PREFIX@", "g"), prefix);
  1887. outfile.Write(indata);
  1888. var keys = (new VBArray(configure_hdr.Keys())).toArray();
  1889. var i, j;
  1890. var item;
  1891. var pieces, stuff_to_crack, chunk;
  1892. outfile.WriteBlankLines(1);
  1893. outfile.WriteLine("/* values determined by configure.js */");
  1894. for (i in keys) {
  1895. item = configure_hdr.Item(keys[i]);
  1896. outfile.WriteBlankLines(1);
  1897. pieces = item[0];
  1898. if (item[1] != undefined) {
  1899. outfile.WriteLine("/* " + item[1] + " */");
  1900. }
  1901. if (typeof(pieces) == "string" && pieces.charCodeAt(0) == 34) {
  1902. /* quoted string have a maximal length of 2k under vc.
  1903. * solution is to crack them and let the compiler concat
  1904. * them implicitly */
  1905. stuff_to_crack = pieces;
  1906. pieces = "";
  1907. while (stuff_to_crack.length) {
  1908. j = 65;
  1909. while (stuff_to_crack.charCodeAt(j) != 32 && j < stuff_to_crack.length)
  1910. j++;
  1911. chunk = stuff_to_crack.substr(0, j);
  1912. pieces += chunk;
  1913. stuff_to_crack = stuff_to_crack.substr(chunk.length);
  1914. if (stuff_to_crack.length)
  1915. pieces += '" "';
  1916. }
  1917. }
  1918. outfile.WriteLine("#define " + keys[i] + " " + pieces);
  1919. }
  1920. if (VS_TOOLSET) {
  1921. if (VCVERS >= 1800) {
  1922. outfile.WriteLine("");
  1923. outfile.WriteLine("#define HAVE_ACOSH 1");
  1924. outfile.WriteLine("#define HAVE_ASINH 1");
  1925. outfile.WriteLine("#define HAVE_ATANH 1");
  1926. }
  1927. if (VCVERS >= 1900) {
  1928. outfile.WriteLine("#define HAVE_LOG1P 1");
  1929. }
  1930. }
  1931. outfile.Close();
  1932. }
  1933. /* Generate phpize */
  1934. function generate_phpize()
  1935. {
  1936. STDOUT.WriteLine("Generating phpize");
  1937. dest = get_define("BUILD_DIR") + '/devel';
  1938. if (!FSO.FolderExists(dest)) {
  1939. FSO.CreateFolder(dest);
  1940. }
  1941. var MF = FSO.CreateTextFile(dest + "/phpize.js", true);
  1942. var DEPS = FSO.CreateTextFile(dest + "/ext_deps.js", true);
  1943. prefix = get_define("PHP_PREFIX");
  1944. prefix = prefix.replace(new RegExp("/", "g"), "\\");
  1945. prefix = prefix.replace(new RegExp("\\\\", "g"), "\\\\");
  1946. MF.WriteLine("var PHP_PREFIX=" + '"' + prefix + '"');
  1947. MF.WriteLine("var PHP_ZTS=" + '"' + (PHP_ZTS.toLowerCase() == "yes" ? "Yes" : "No") + '"');
  1948. MF.WriteLine("var VC_VERSION=" + VCVERS);
  1949. MF.WriteLine("var PHP_VERSION=" + PHP_VERSION);
  1950. MF.WriteLine("var PHP_MINOR_VERSION=" + PHP_MINOR_VERSION);
  1951. MF.WriteLine("var PHP_RELEASE_VERSION=" + PHP_RELEASE_VERSION);
  1952. MF.WriteBlankLines(1);
  1953. MF.WriteLine("/* Genereted extensions list with mode (static/shared) */");
  1954. var count = extensions_enabled.length;
  1955. for (i in extensions_enabled) {
  1956. out = "PHP_" + extensions_enabled[i][0].toUpperCase() + "_SHARED=" + (extensions_enabled[i][1] == 'shared' ? 'true' : 'false') + ";";
  1957. DEPS.WriteLine("PHP_" + extensions_enabled[i][0].toUpperCase() + "=true;");
  1958. DEPS.WriteLine(out);
  1959. MF.WriteLine(out);
  1960. }
  1961. MF.WriteBlankLines(2);
  1962. MF.WriteLine("/* Genereted win32/build/phpize.js.in */");
  1963. MF.WriteBlankLines(1);
  1964. MF.Write(file_get_contents("win32/build/phpize.js.in"));
  1965. MF.Close();
  1966. DEPS.Close();
  1967. /* Generate flags file */
  1968. /* spit out variable definitions */
  1969. CJ = FSO.CreateTextFile(dest + "/config.phpize.js");
  1970. CJ.WriteLine("var PHP_ZTS =" + '"' + PHP_ZTS + '"');
  1971. CJ.WriteLine("var PHP_DEBUG=" + '"' + PHP_DEBUG + '"');
  1972. CJ.WriteLine("var PHP_DLL_LIB =" + '"' + get_define('PHPLIB') + '"');
  1973. CJ.WriteLine("var PHP_DLL =" + '"' + get_define('PHPDLL') + '"');
  1974. CJ.WriteLine("var PHP_SECURITY_FLAGS =" + '"' + PHP_SECURITY_FLAGS + '"');
  1975. /* The corresponding configure options aren't enabled through phpize,
  1976. thus these dummy declarations are required. */
  1977. CJ.WriteLine("var PHP_ANALYZER =" + '"no"');
  1978. CJ.WriteLine("var PHP_PGO =" + '"no"');
  1979. CJ.WriteLine("var PHP_PGI =" + '"no"');
  1980. CJ.WriteLine("var PHP_ALL_SHARED =" + '"no"');
  1981. CJ.WriteBlankLines(1);
  1982. CJ.Close();
  1983. }
  1984. function extract_convert_style_line(val, match_sw, to_sw, keep_mkfile_vars)
  1985. {
  1986. var ret = "";
  1987. /*var re = new RegExp(match_sw + "(.*)", "g");
  1988. var r;
  1989. while (r = re.execute(val)) {
  1990. WARNING(r);
  1991. }
  1992. return ret;*/
  1993. var cf = val.replace(/\s+/g, " ").split(" ");
  1994. var i_val = false;
  1995. for (var i in cf) {
  1996. var r;
  1997. if (keep_mkfile_vars) {
  1998. r = cf[i].match(/^\$\((.*)\)/);
  1999. if (!!r) {
  2000. ret += " " + r[0];
  2001. continue;
  2002. }
  2003. }
  2004. if (i_val && !!cf[i]) {
  2005. i_val = false;
  2006. ret += " " + to_sw + " " + cf[i];
  2007. continue;
  2008. }
  2009. var re;
  2010. re = new RegExp(match_sw + "(.*)");
  2011. r = cf[i].match(re);
  2012. if (!!r && r.length > 1 && !!r[1]) {
  2013. /* The value is not ws separated from the switch. */
  2014. ret += " " + to_sw + " " + r[1];
  2015. continue;
  2016. }
  2017. r = cf[i].match(match_sw);
  2018. if (!!r) {
  2019. //WARNING(cf[i]);
  2020. /* Value is going to be added in the next iteration. */
  2021. i_val = true;
  2022. }
  2023. }
  2024. return ret;
  2025. }
  2026. function handle_analyzer_makefile_flags(fd, key, val)
  2027. {
  2028. var relevant = false;
  2029. /* VS integrates /analyze with the bulid process,
  2030. no further action is required. */
  2031. if ("no" == PHP_ANALYZER || "vs" == PHP_ANALYZER) {
  2032. return;
  2033. }
  2034. if (key.match("CFLAGS")) {
  2035. var new_val = val;
  2036. var reg = /\$\(([^\)]+)\)/g;
  2037. var r;
  2038. while (r = reg.exec(val)) {
  2039. var repl = "$(" + r[1] + "_ANALYZER)"
  2040. new_val = new_val.replace(r[0], repl);
  2041. }
  2042. val = new_val;
  2043. if ("clang" == PHP_ANALYZER) {
  2044. val = val.replace(/\/FD /, "")
  2045. .replace(/\/Fp.+? /, "")
  2046. .replace(/\/Fo.+? /, "")
  2047. .replace(/\/Fd.+? /, "")
  2048. //.replace(/\/Fd.+?/, " ")
  2049. .replace(/\/FR.+? /, "")
  2050. .replace("/guard:cf ", "")
  2051. .replace(/\/MP \d+ /, "")
  2052. .replace(/\/MP /, "")
  2053. .replace("/LD ", "")
  2054. .replace("/Qspectre ", "");
  2055. } else if ("cppcheck" == PHP_ANALYZER) {
  2056. new_val = "";
  2057. new_val += extract_convert_style_line(val, "/I", "-I", true);
  2058. new_val += extract_convert_style_line(val, "/D", "-D", false);
  2059. val = new_val;
  2060. }
  2061. relevant = true;
  2062. } else if (key.match("BASE_INCLUDES")) {
  2063. if ("cppcheck" == PHP_ANALYZER) {
  2064. new_val = "";
  2065. new_val += extract_convert_style_line(val, "/I", "-I", true);
  2066. new_val += extract_convert_style_line(val, "/D", "-D", false);
  2067. val = new_val;
  2068. }
  2069. relevant = true;
  2070. }
  2071. if (!relevant) {
  2072. return;
  2073. }
  2074. key += "_ANALYZER";
  2075. //WARNING("KEY: " + key + " VAL: " + val);
  2076. fd.WriteLine(key + "=" + val + " ");
  2077. fd.WriteBlankLines(1);
  2078. }
  2079. /* Generate the Makefile */
  2080. function generate_makefile()
  2081. {
  2082. STDOUT.WriteLine("Generating Makefile");
  2083. var MF = FSO.CreateTextFile("Makefile", true);
  2084. MF.WriteLine("# Generated by configure.js");
  2085. /* spit out variable definitions */
  2086. var keys = (new VBArray(configure_subst.Keys())).toArray();
  2087. var i;
  2088. MF.WriteLine("PHP_SRC_DIR =" + PHP_SRC_DIR);
  2089. for (i in keys) {
  2090. // The trailing space is needed to prevent the trailing backslash
  2091. // that is part of the build dir flags (CFLAGS_BD_XXX) from being
  2092. // seen as a line continuation character
  2093. /* \s+\/ eliminates extra whitespace caused when using \ for string continuation,
  2094. whereby \/ is the start of the next compiler switch */
  2095. var val = trim(configure_subst.Item(keys[i])).replace(/\s+\//gm, " /");
  2096. MF.WriteLine(keys[i] + "=" + val + " ");
  2097. MF.WriteBlankLines(1);
  2098. /* If static analyze is enabled, add analyzer specific stuff to the Makefile. */
  2099. handle_analyzer_makefile_flags(MF, keys[i], val);
  2100. }
  2101. if (!MODE_PHPIZE) {
  2102. var val = "yes" == PHP_TEST_INI ? PHP_TEST_INI_PATH : "";
  2103. /* Be sure it's done after generate_tmp_php_ini(). */
  2104. MF.WriteLine("PHP_TEST_INI_PATH=\"" + val + "\"");
  2105. }
  2106. MF.WriteBlankLines(1);
  2107. if (MODE_PHPIZE) {
  2108. var TF = FSO.OpenTextFile(PHP_DIR + "/script/Makefile.phpize", 1);
  2109. } else {
  2110. var TF = FSO.OpenTextFile("win32/build/Makefile", 1);
  2111. }
  2112. MF.Write(TF.ReadAll());
  2113. MF.WriteLine("build-headers:");
  2114. MF.WriteLine(" " + CMD_MOD2 + "if not exist $(BUILD_DIR_DEV)\\include mkdir $(BUILD_DIR_DEV)\\include >nul");
  2115. MF.WriteLine(" " + CMD_MOD2 + "for %D in ($(INSTALL_HEADERS_DIR)) do " + CMD_MOD2 + "if not exist $(BUILD_DIR_DEV)\\include\\%D mkdir $(BUILD_DIR_DEV)\\include\\%D >nul");
  2116. for (i in headers_install) {
  2117. if (headers_install[i][2] != "") {
  2118. MF.WriteLine(" " + CMD_MOD2 + "if not exist $(BUILD_DIR_DEV)\\include\\" + headers_install[i][2] + " mkdir $(BUILD_DIR_DEV)\\include\\" +
  2119. headers_install[i][2] + ">nul");
  2120. MF.WriteLine(" " + CMD_MOD2 + "copy " + headers_install[i][0] + " " + "$(BUILD_DIR_DEV)\\include\\" + headers_install[i][2] + " /y >nul");
  2121. }
  2122. }
  2123. MF.WriteLine(" " + CMD_MOD2 + "for %D in ($(INSTALL_HEADERS_DIR)) do " + CMD_MOD2 + "copy %D*.h $(BUILD_DIR_DEV)\\include\\%D /y >nul");
  2124. if (MODE_PHPIZE) {
  2125. MF.WriteBlankLines(1);
  2126. MF.WriteLine("build-bins:");
  2127. for (var i in extensions_enabled) {
  2128. var lib = "php_" + extensions_enabled[i][0] + ".lib";
  2129. var dll = "php_" + extensions_enabled[i][0] + ".dll";
  2130. MF.WriteLine(" " + CMD_MOD2 + "copy $(BUILD_DIR)\\" + lib + " $(BUILD_DIR_DEV)\\lib");
  2131. MF.WriteLine(" " + CMD_MOD2 + "if not exist $(PHP_PREFIX) mkdir $(PHP_PREFIX) >nul");
  2132. MF.WriteLine(" " + CMD_MOD2 + "if not exist $(PHP_PREFIX)\\ext mkdir $(PHP_PREFIX)\\ext >nul");
  2133. MF.WriteLine(" " + CMD_MOD2 + "copy $(BUILD_DIR)\\" + dll + " $(PHP_PREFIX)\\ext");
  2134. }
  2135. } else {
  2136. MF.WriteBlankLines(1);
  2137. MF.WriteLine("build-ext-libs:");
  2138. MF.WriteLine(" " + CMD_MOD2 + "if not exist $(BUILD_DIR_DEV)\\lib mkdir $(BUILD_DIR_DEV)\\lib >nul");
  2139. for (var i in extensions_enabled) {
  2140. var lib;
  2141. lib = "php_" + extensions_enabled[i][0] + "*.lib";
  2142. if ('shared' == extensions_enabled[i][1]) {
  2143. MF.WriteLine(" " + CMD_MOD2 + "if exist $(BUILD_DIR)\\" + lib + " copy $(BUILD_DIR)\\" + lib + " $(BUILD_DIR_DEV)\\lib");
  2144. }
  2145. }
  2146. }
  2147. TF.Close();
  2148. MF.WriteBlankLines(1);
  2149. var extra_path = "$(PHP_BUILD)\\bin";
  2150. if (PHP_EXTRA_LIBS.length) {
  2151. path = PHP_EXTRA_LIBS.split(';');
  2152. for (i = 0; i < path.length; i++) {
  2153. f = FSO.GetAbsolutePathName(path[i] + "\\..\\bin");
  2154. if (FSO.FolderExists(f)) {
  2155. extra_path = extra_path + ";" + f;
  2156. }
  2157. }
  2158. }
  2159. if (PHP_SANITIZER == "yes") {
  2160. if (CLANG_TOOLSET) {
  2161. extra_path = extra_path + ";" + get_clang_lib_dir() + "\\windows";
  2162. }
  2163. }
  2164. MF.WriteLine("set-tmp-env:");
  2165. MF.WriteLine(" " + CMD_MOD2 + "set PATH=" + extra_path + ";$(PATH)");
  2166. MF.WriteBlankLines(2);
  2167. MF.WriteLine("dump-tmp-env: set-tmp-env");
  2168. MF.WriteLine(" " + CMD_MOD2 + "set");
  2169. MF.WriteBlankLines(2);
  2170. MFO.Close();
  2171. TF = FSO.OpenTextFile("Makefile.objects", 1);
  2172. if (!TF.AtEndOfStream) {
  2173. MF.Write(TF.ReadAll());
  2174. }
  2175. TF.Close();
  2176. MF.WriteBlankLines(2);
  2177. if (FSO.FileExists(PHP_MAKEFILE_FRAGMENTS)) {
  2178. TF = FSO.OpenTextFile(PHP_MAKEFILE_FRAGMENTS, 1);
  2179. if (!TF.AtEndOfStream) {
  2180. MF.Write(TF.ReadAll());
  2181. }
  2182. TF.Close();
  2183. MF.WriteBlankLines(2);
  2184. FSO.DeleteFile(PHP_MAKEFILE_FRAGMENTS, true);
  2185. }
  2186. MF.Close();
  2187. }
  2188. function ADD_FLAG(name, flags, target)
  2189. {
  2190. if (target != null) {
  2191. name = target.toUpperCase() + "_" + name;
  2192. }
  2193. flags = trim(flags);
  2194. if (configure_subst.Exists(name)) {
  2195. var curr_flags = configure_subst.Item(name);
  2196. /* Prefix with a space, thus making sure the
  2197. current flag is not a substring of some
  2198. other. It's still not a complete check if
  2199. some flags with spaces got added.
  2200. TODO rework to use an array, so direct
  2201. match can be done. This will also
  2202. help to normalize flags and to not
  2203. to insert duplicates. */
  2204. if (curr_flags.indexOf(" " + flags) >= 0 || curr_flags.indexOf(flags + " ") >= 0) {
  2205. return;
  2206. }
  2207. flags = curr_flags + " " + flags;
  2208. configure_subst.Remove(name);
  2209. }
  2210. configure_subst.Add(name, flags);
  2211. }
  2212. function get_define(name)
  2213. {
  2214. if (configure_subst.Exists(name)) {
  2215. return configure_subst.Item(name);
  2216. }
  2217. return "";
  2218. }
  2219. // Add a .def to the core to export symbols
  2220. function ADD_DEF_FILE(name)
  2221. {
  2222. if (!configure_subst.Exists("PHPDEF")) {
  2223. DEFINE("PHPDEF", "$(BUILD_DIR)\\$(PHPDLL).def");
  2224. ADD_FLAG("PHP_LDFLAGS", "/def:$(PHPDEF)");
  2225. }
  2226. ADD_FLAG("PHP_DLL_DEF_SOURCES", name);
  2227. }
  2228. function AC_DEFINE(name, value, comment, quote)
  2229. {
  2230. if (quote == null) {
  2231. quote = true;
  2232. }
  2233. if (quote && typeof(value) == "string") {
  2234. value = '"' + value.replace(new RegExp('(["\\\\])', "g"), '\\$1') + '"';
  2235. } else if (typeof(value) != "undefined" && value.length == 0) {
  2236. value = '""';
  2237. }
  2238. var item = new Array(value, comment);
  2239. if (configure_hdr.Exists(name)) {
  2240. var orig_item = configure_hdr.Item(name);
  2241. STDOUT.WriteLine("AC_DEFINE[" + name + "]=" + value + ": is already defined to " + orig_item[0]);
  2242. } else {
  2243. configure_hdr.Add(name, item);
  2244. }
  2245. }
  2246. function MESSAGE(msg)
  2247. {
  2248. STDOUT.WriteLine("" + msg);
  2249. }
  2250. function ERROR(msg)
  2251. {
  2252. STDERR.WriteLine("ERROR: " + msg);
  2253. WScript.Quit(3);
  2254. }
  2255. function WARNING(msg)
  2256. {
  2257. STDERR.WriteLine("WARNING: " + msg);
  2258. STDERR.WriteBlankLines(1);
  2259. }
  2260. function copy_and_subst(srcname, destname, subst_array)
  2261. {
  2262. if (!FSO.FileExists(srcname)) {
  2263. srcname = configure_module_dirname + "\\" + srcname;
  2264. destname = configure_module_dirname + "\\" + destname;
  2265. }
  2266. var content = file_get_contents(srcname);
  2267. var i;
  2268. for (i = 0; i < subst_array.length; i+=2) {
  2269. var re = subst_array[i];
  2270. var rep = subst_array[i+1];
  2271. content = content.replace(re, rep);
  2272. }
  2273. var f = FSO.CreateTextFile(destname, true);
  2274. f.Write(content);
  2275. f.Close();
  2276. }
  2277. // glob using simple filename wildcards
  2278. // returns an array of matches that are found
  2279. // in the filesystem
  2280. function glob(path_pattern)
  2281. {
  2282. var path_parts = path_pattern.replace(new RegExp("/", "g"), "\\").split("\\");
  2283. var p;
  2284. var base = "";
  2285. var is_pat_re = /\*/;
  2286. //STDOUT.WriteLine("glob: " + path_pattern);
  2287. if (FSO.FileExists(path_pattern)) {
  2288. return new Array(path_pattern);
  2289. }
  2290. // first, build as much as possible that doesn't have a pattern
  2291. for (p = 0; p < path_parts.length; p++) {
  2292. if (path_parts[p].match(is_pat_re))
  2293. break;
  2294. if (p)
  2295. base += "\\";
  2296. base += path_parts[p];
  2297. }
  2298. return _inner_glob(base, p, path_parts);
  2299. }
  2300. function _inner_glob(base, p, parts)
  2301. {
  2302. var pat = parts[p];
  2303. var full_name = base + "\\" + pat;
  2304. var re = null;
  2305. var items = null;
  2306. if (p == parts.length) {
  2307. return false;
  2308. }
  2309. //STDOUT.WriteLine("inner: base=" + base + " p=" + p + " pat=" + pat);
  2310. if (FSO.FileExists(full_name)) {
  2311. if (p < parts.length - 1) {
  2312. // we didn't reach the full extent of the pattern
  2313. return false;
  2314. }
  2315. return new Array(full_name);
  2316. }
  2317. if (FSO.FolderExists(full_name) && p == parts.length - 1) {
  2318. // we have reached the end of the pattern; no need to recurse
  2319. return new Array(full_name);
  2320. }
  2321. // Convert the pattern into a regexp
  2322. re = new RegExp("^" + pat.replace(/\./g, '\\.').replace(/\*/g, '.*').replace(/\?/g, '.') + "$", "i");
  2323. items = new Array();
  2324. if (!FSO.FolderExists(base)) {
  2325. return false;
  2326. }
  2327. var folder = FSO.GetFolder(base);
  2328. var fc = null;
  2329. var subitems = null;
  2330. var item_name = null;
  2331. var j;
  2332. fc = new Enumerator(folder.SubFolders);
  2333. for (; !fc.atEnd(); fc.moveNext()) {
  2334. item_name = FSO.GetFileName(fc.item());
  2335. if (item_name.match(re)) {
  2336. // got a match; if we are at the end of the pattern, just add these
  2337. // things to the items array
  2338. if (p == parts.length - 1) {
  2339. items[items.length] = fc.item();
  2340. } else {
  2341. // we should recurse and do more matches
  2342. subitems = _inner_glob(base + "\\" + item_name, p + 1, parts);
  2343. if (subitems) {
  2344. for (j = 0; j < subitems.length; j++) {
  2345. items[items.length] = subitems[j];
  2346. }
  2347. }
  2348. }
  2349. }
  2350. }
  2351. // if we are at the end of the pattern, we should match
  2352. // files too
  2353. if (p == parts.length - 1) {
  2354. fc = new Enumerator(folder.Files);
  2355. for (; !fc.atEnd(); fc.moveNext()) {
  2356. item_name = FSO.GetFileName(fc.item());
  2357. if (item_name.match(re)) {
  2358. items[items.length] = fc.item();
  2359. }
  2360. }
  2361. }
  2362. if (items.length == 0)
  2363. return false;
  2364. return items;
  2365. }
  2366. /* Install Headers */
  2367. function PHP_INSTALL_HEADERS(dir, headers_list)
  2368. {
  2369. headers_list = headers_list.split(new RegExp("\\s+"));
  2370. headers_list.sort();
  2371. if (dir.length > 0 && dir.substr(dir.length - 1) != '/' && dir.substr(dir.length - 1) != '\\') {
  2372. dir += '/';
  2373. }
  2374. dir = dir.replace(new RegExp("/", "g"), "\\");
  2375. for (i in headers_list) {
  2376. found = false;
  2377. src = headers_list[i];
  2378. src = src.replace(new RegExp("/", "g"), "\\");
  2379. isdir = FSO.FolderExists(dir + src);
  2380. isfile = FSO.FileExists(dir + src);
  2381. if (isdir) {
  2382. if (src.length > 0 && src.substr(src.length - 1) != '/' && src.substr(src.length - 1) != '\\') {
  2383. src += '\\';
  2384. }
  2385. headers_install[headers_install.length] = [dir + src, 'dir',''];
  2386. ADD_FLAG("INSTALL_HEADERS_DIR", dir + src);
  2387. found = true;
  2388. } else if (isfile) {
  2389. dirname = FSO.GetParentFolderName(dir + src);
  2390. headers_install[headers_install.length] = [dir + src, 'file', dirname];
  2391. ADD_FLAG("INSTALL_HEADERS", dir + src);
  2392. found = true;
  2393. } else {
  2394. path = configure_module_dirname + "\\"+ src;
  2395. isdir = FSO.FolderExists(path);
  2396. isfile = FSO.FileExists(path);
  2397. if (isdir) {
  2398. if (src.length > 0 && src.substr(src.length - 1) != '/' && src.substr(src.length - 1) != '\\') {
  2399. src += '\\';
  2400. }
  2401. headers_install[headers_install.length] = [path, 'dir',''];
  2402. ADD_FLAG("INSTALL_HEADERS_DIR", path);
  2403. } else if (isfile) {
  2404. dirname = FSO.GetParentFolderName(path);
  2405. headers_install[headers_install.length] = [path, 'file', dir];
  2406. ADD_FLAG("INSTALL_HEADERS", dir + src);
  2407. found = true;
  2408. }
  2409. }
  2410. if (found == false) {
  2411. STDOUT.WriteLine(headers_list);
  2412. ERROR("Cannot find header " + dir + src);
  2413. }
  2414. }
  2415. }
  2416. // For snapshot builders, this option will attempt to enable everything
  2417. // and you can then build everything, ignoring fatal errors within a module
  2418. // by running "nmake snap"
  2419. PHP_SNAPSHOT_BUILD = "no";
  2420. if (!MODE_PHPIZE) {
  2421. ARG_ENABLE('snapshot-build', 'Build a snapshot; turns on everything it can and ignores build errors', 'no');
  2422. }
  2423. function toolset_option_handle()
  2424. {
  2425. if ("clang" == PHP_TOOLSET) {
  2426. VS_TOOLSET = false;
  2427. CLANG_TOOLSET = true;
  2428. ICC_TOOLSET = false;
  2429. } else if ("icc" == PHP_TOOLSET) {
  2430. VS_TOOLSET = false;
  2431. CLANG_TOOLSET = false;
  2432. ICC_TOOLSET = true;
  2433. } else {
  2434. /* Visual Studio is the default toolset. */
  2435. PHP_TOOLSET = "no" == PHP_TOOLSET ? "vs" : PHP_TOOLSET;
  2436. if (!!PHP_TOOLSET && "vs" != PHP_TOOLSET) {
  2437. ERROR("Unsupported toolset '" + PHP_TOOLSET + "'");
  2438. }
  2439. VS_TOOLSET = true;
  2440. CLANG_TOOLSET = false;
  2441. ICC_TOOLSET = false;
  2442. }
  2443. }
  2444. function toolset_setup_compiler()
  2445. {
  2446. PHP_CL = toolset_get_compiler();
  2447. if (!PHP_CL) {
  2448. ERROR("Compiler not found");
  2449. }
  2450. COMPILER_NUMERIC_VERSION = toolset_get_compiler_version();
  2451. COMPILER_NAME = toolset_get_compiler_name();
  2452. if (VS_TOOLSET) {
  2453. /* For the record here: */
  2454. // 1200 is VC6
  2455. // 1300 is vs.net 2002
  2456. // 1310 is vs.net 2003
  2457. // 1400 is vs.net 2005
  2458. // 1500 is vs.net 2008
  2459. // 1600 is vs.net 2010
  2460. // 1700 is vs.net 2011
  2461. // 1800 is vs.net 2012
  2462. // 1900 is vs.net 2015
  2463. // 1910 is vs.net 2017
  2464. // Which version of the compiler do we have?
  2465. VCVERS = COMPILER_NUMERIC_VERSION;
  2466. if (VCVERS < 1700) {
  2467. ERROR("Unsupported MS C++ Compiler, VC11 (2011) minimum is required");
  2468. }
  2469. if (undefined == COMPILER_NAME) {
  2470. var tmp = probe_binary(PHP_CL);
  2471. COMPILER_NAME = "MSVC " + tmp + ", untested";
  2472. WARNING("Using unknown MSVC version " + tmp);
  2473. AC_DEFINE('COMPILER', COMPILER_NAME, "Detected compiler version");
  2474. DEFINE("PHP_COMPILER_SHORT", tmp);
  2475. AC_DEFINE('PHP_COMPILER_ID', tmp, "Compiler compatibility ID");
  2476. } else {
  2477. AC_DEFINE('COMPILER', COMPILER_NAME, "Detected compiler version");
  2478. DEFINE("PHP_COMPILER_SHORT", VC_VERSIONS_SHORT[VCVERS]);
  2479. AC_DEFINE('PHP_COMPILER_ID', VC_VERSIONS_SHORT[VCVERS], "Compiler compatibility ID");
  2480. }
  2481. } else if (CLANG_TOOLSET) {
  2482. CLANGVERS = COMPILER_NUMERIC_VERSION;
  2483. AC_DEFINE('COMPILER', COMPILER_NAME, "Detected compiler version");
  2484. DEFINE("PHP_COMPILER_SHORT", "clang");
  2485. AC_DEFINE('PHP_COMPILER_ID', "clang"); /* XXX something better were to write here */
  2486. } else if (ICC_TOOLSET) {
  2487. INTELVERS = COMPILER_NUMERIC_VERSION;
  2488. AC_DEFINE('COMPILER', COMPILER_NAME, "Detected compiler version");
  2489. DEFINE("PHP_COMPILER_SHORT", "icc");
  2490. AC_DEFINE('PHP_COMPILER_ID', "icc"); /* XXX something better were to write here */
  2491. }
  2492. STDOUT.WriteLine(" Detected compiler " + COMPILER_NAME);
  2493. }
  2494. function toolset_setup_project_tools()
  2495. {
  2496. PATH_PROG('nmake');
  2497. // we don't want to define LIB, as that will override the default library path
  2498. // that is set in that env var
  2499. PATH_PROG('lib', null, 'MAKE_LIB');
  2500. var BISON = PATH_PROG('bison');
  2501. if (BISON) {
  2502. var BISONVERS = probe_binary(BISON, "longversion");
  2503. STDOUT.WriteLine(' Detected bison version ' + BISONVERS);
  2504. if (BISONVERS.match(/^\d+.\d+$/)) {
  2505. BISONVERS += ".0";
  2506. }
  2507. var hm = BISONVERS.match(/(\d+)\.(\d+)\.(\d+)/);
  2508. var nm = MINBISON.match(/(\d+)\.(\d+)\.(\d+)/);
  2509. var intvers = (hm[1]-0)*10000 + (hm[2]-0)*100 + (hm[3]-0);
  2510. var intmin = (nm[1]-0)*10000 + (nm[2]-0)*100 + (nm[3]-0);
  2511. if (intvers < intmin) {
  2512. ERROR('The minimum bison version requirement is ' + MINBISON);
  2513. }
  2514. } else {
  2515. ERROR('bison is required')
  2516. }
  2517. if (!PATH_PROG('sed')) {
  2518. ERROR('sed is required')
  2519. }
  2520. RE2C = PATH_PROG('re2c');
  2521. if (RE2C) {
  2522. var RE2CVERS = probe_binary(RE2C, "version");
  2523. STDOUT.WriteLine(' Detected re2c version ' + RE2CVERS);
  2524. if (RE2CVERS.match(/^\d+.\d+$/)) {
  2525. RE2CVERS += ".0";
  2526. }
  2527. var hm = RE2CVERS.match(/(\d+)\.(\d+)\.(\d+)/);
  2528. var nm = MINRE2C.match(/(\d+)\.(\d+)\.(\d+)/);
  2529. var intvers = (hm[1]-0)*10000 + (hm[2]-0)*100 + (hm[3]-0);
  2530. var intmin = (nm[1]-0)*10000 + (nm[2]-0)*100 + (nm[3]-0);
  2531. if (intvers < intmin) {
  2532. ERROR('The minimum RE2C version requirement is ' + MINRE2C);
  2533. }
  2534. } else {
  2535. ERROR('re2c is required')
  2536. }
  2537. PATH_PROG('zip');
  2538. PATH_PROG('lemon');
  2539. PATH_PROG('7za');
  2540. // avoid picking up midnight commander from cygwin
  2541. if (!PATH_PROG('mc', WshShell.Environment("Process").Item("PATH"))) {
  2542. ERROR('mc is required')
  2543. }
  2544. // Try locating the manifest tool
  2545. if (VS_TOOLSET) {
  2546. if (!PATH_PROG('mt', WshShell.Environment("Process").Item("PATH"))) {
  2547. ERROR('mt is required')
  2548. }
  2549. }
  2550. }
  2551. /* Get compiler if the toolset is supported */
  2552. function toolset_get_compiler()
  2553. {
  2554. if (VS_TOOLSET) {
  2555. return PATH_PROG('cl', null, 'PHP_CL')
  2556. } else if (CLANG_TOOLSET) {
  2557. return PATH_PROG('clang-cl', null, 'PHP_CL')
  2558. } else if (ICC_TOOLSET) {
  2559. return PATH_PROG('icl', null, 'PHP_CL')
  2560. }
  2561. ERROR("Unsupported toolset");
  2562. }
  2563. /* Get compiler version if the toolset is supported */
  2564. function toolset_get_compiler_version()
  2565. {
  2566. var version;
  2567. if (VS_TOOLSET) {
  2568. version = probe_binary(PHP_CL).substr(0, 5).replace('.', '');
  2569. return version;
  2570. } else if (CLANG_TOOLSET) {
  2571. var command = 'cmd /c ""' + PHP_CL + '" -v"';
  2572. var full = execute(command + '" 2>&1"');
  2573. if (full.match(/clang version ([\d\.]+) \((.*)\)/)) {
  2574. version = RegExp.$1;
  2575. version = version.replace(/\./g, '');
  2576. version = version/100 < 1 ? version*10 : version;
  2577. return version;
  2578. }
  2579. } else if (ICC_TOOLSET) {
  2580. var command = 'cmd /c ""' + PHP_CL + '" -v"';
  2581. var full = execute(command + '" 2>&1"');
  2582. if (full.match(/Version (\d+\.\d+\.\d+)/)) {
  2583. version = RegExp.$1;
  2584. version = version.replace(/\./g, '');
  2585. version = version/100 < 1 ? version*10 : version;
  2586. return version;
  2587. }
  2588. }
  2589. ERROR("Failed to parse compiler version or unsupported toolset");
  2590. }
  2591. /* Get compiler name if the toolset is supported */
  2592. function toolset_get_compiler_name()
  2593. {
  2594. var version;
  2595. if (VS_TOOLSET) {
  2596. var name = undefined;
  2597. version = probe_binary(PHP_CL).substr(0, 5).replace('.', '');
  2598. if (undefined != VC_VERSIONS[version]) {
  2599. name = VC_VERSIONS[version];
  2600. }
  2601. return name;
  2602. } else if (CLANG_TOOLSET || ICC_TOOLSET) {
  2603. var command = 'cmd /c ""' + PHP_CL + '" -v"';
  2604. var full = execute(command + '" 2>&1"');
  2605. return full.split(/\n/)[0].replace(/\s/g, ' ');
  2606. }
  2607. WARNING("Unsupported toolset");
  2608. }
  2609. function toolset_is_64()
  2610. {
  2611. if (VS_TOOLSET) {
  2612. return probe_binary(PHP_CL, 64);
  2613. } else if (CLANG_TOOLSET) {
  2614. /*var command = 'cmd /c ""' + PHP_CL + '" -v"';
  2615. var full = execute(command + '" 2>&1"');
  2616. return null != full.match(/x86_64/);*/
  2617. /* Even executed within an environment setup with vcvars32.bat,
  2618. clang-cl doesn't recognize the arch toolset. But as it needs
  2619. the VS environment, checking the arch of cl.exe is correct. */
  2620. return probe_binary(PATH_PROG('cl', null), 64);
  2621. } else if (ICC_TOOLSET) {
  2622. var command = 'cmd /c ""' + PHP_CL + '" -v"';
  2623. var full = execute(command + '" 2>&1"');
  2624. return null != full.match(/Intel\(R\) 64/);
  2625. }
  2626. ERROR("Unsupported toolset");
  2627. }
  2628. function toolset_setup_arch()
  2629. {
  2630. if (X64) {
  2631. STDOUT.WriteLine(" Detected 64-bit compiler");
  2632. } else {
  2633. STDOUT.WriteLine(" Detected 32-bit compiler");
  2634. }
  2635. AC_DEFINE('ARCHITECTURE', X64 ? 'x64' : 'x86', "Detected compiler architecture");
  2636. DEFINE("PHP_ARCHITECTURE", X64 ? 'x64' : 'x86');
  2637. }
  2638. function toolset_setup_codegen_arch()
  2639. {
  2640. if("no" == PHP_CODEGEN_ARCH || "yes" == PHP_CODEGEN_ARCH) {
  2641. return;
  2642. }
  2643. if (VS_TOOLSET) {
  2644. var arc = PHP_CODEGEN_ARCH.toUpperCase();
  2645. if ("IA32" != arc) {
  2646. ERROR("Only IA32 arch is supported by --with-codegen-arch, got '" + arc + "'");
  2647. } else if (X64) {
  2648. ERROR("IA32 arch is only supported with 32-bit build");
  2649. }
  2650. ADD_FLAG("CFLAGS", "/arch:" + arc);
  2651. PHP_NATIVE_INTRINSICS = "disabled";
  2652. }
  2653. }
  2654. function toolset_setup_linker()
  2655. {
  2656. if (VS_TOOLSET) {
  2657. return PATH_PROG('link', null);
  2658. } else if (CLANG_TOOLSET) {
  2659. //return PATH_PROG('lld', WshShell.Environment("Process").Item("PATH"), "LINK");
  2660. return PATH_PROG('link', WshShell.Environment("Process").Item("PATH"));
  2661. } else if (ICC_TOOLSET) {
  2662. return PATH_PROG('xilink', WshShell.Environment("Process").Item("PATH"), "LINK");
  2663. }
  2664. ERROR("Unsupported toolset");
  2665. }
  2666. function toolset_setup_common_cflags()
  2667. {
  2668. // CFLAGS for building the PHP dll
  2669. DEFINE("CFLAGS_PHP", "/D _USRDLL /D PHP7DLLTS_EXPORTS /D PHP_EXPORTS \
  2670. /D LIBZEND_EXPORTS /D TSRM_EXPORTS /D SAPI_EXPORTS /D WINVER=" + WINVER);
  2671. DEFINE('CFLAGS_PHP_OBJ', '$(CFLAGS_PHP) $(STATIC_EXT_CFLAGS)');
  2672. // General CFLAGS for building objects
  2673. DEFINE("CFLAGS", "/nologo $(BASE_INCLUDES) /D _WINDOWS /D WINDOWS=1 \
  2674. /D ZEND_WIN32=1 /D PHP_WIN32=1 /D WIN32 /D _MBCS /W3 \
  2675. /D _USE_MATH_DEFINES");
  2676. if (VS_TOOLSET) {
  2677. ADD_FLAG("CFLAGS", " /FD ");
  2678. // fun stuff: MS deprecated ANSI stdio and similar functions
  2679. // disable annoying warnings. In addition, time_t defaults
  2680. // to 64-bit. Ask for 32-bit.
  2681. if (X64) {
  2682. ADD_FLAG('CFLAGS', ' /wd4996 ');
  2683. } else {
  2684. ADD_FLAG('CFLAGS', ' /wd4996 /D_USE_32BIT_TIME_T=1 ');
  2685. }
  2686. if (PHP_DEBUG == "yes") {
  2687. // Set some debug/release specific options
  2688. ADD_FLAG('CFLAGS', ' /RTC1 ');
  2689. } else {
  2690. if (PHP_DEBUG == "no" && PHP_SECURITY_FLAGS == "yes") {
  2691. /* Mitigations for CVE-2017-5753.
  2692. TODO backport for all supported VS versions when they release it. */
  2693. if (VCVERS >= 1912) {
  2694. var subver1912 = probe_binary(PHP_CL).substr(6);
  2695. if (VCVERS >= 1913 || 1912 == VCVERS && subver1912 >= 25835) {
  2696. ADD_FLAG('CFLAGS', "/Qspectre");
  2697. } else {
  2698. /* Undocumented. */
  2699. ADD_FLAG('CFLAGS', "/d2guardspecload");
  2700. }
  2701. } else if (1900 == VCVERS) {
  2702. var subver1900 = probe_binary(PHP_CL).substr(6);
  2703. if (subver1900 >= 24241) {
  2704. ADD_FLAG('CFLAGS', "/Qspectre");
  2705. }
  2706. }
  2707. }
  2708. if (VCVERS >= 1900) {
  2709. if (PHP_SECURITY_FLAGS == "yes") {
  2710. ADD_FLAG('CFLAGS', "/guard:cf");
  2711. }
  2712. }
  2713. if (VCVERS >= 1800) {
  2714. if (PHP_PGI != "yes" && PHP_PGO != "yes") {
  2715. ADD_FLAG('CFLAGS', "/Zc:inline");
  2716. }
  2717. /* We enable /opt:icf only with the debug pack, so /Gw only makes sense there, too. */
  2718. if (PHP_DEBUG_PACK == "yes") {
  2719. ADD_FLAG('CFLAGS', "/Gw");
  2720. }
  2721. }
  2722. }
  2723. if (VCVERS >= 1914) {
  2724. /* This is only in effect for CXX sources, __cplusplus is not defined in C sources. */
  2725. ADD_FLAG("CFLAGS", "/Zc:__cplusplus");
  2726. }
  2727. } else if (CLANG_TOOLSET) {
  2728. if (X64) {
  2729. ADD_FLAG('CFLAGS', '-m64');
  2730. } else {
  2731. ADD_FLAG('CFLAGS', '-m32');
  2732. }
  2733. ADD_FLAG("CFLAGS", " /fallback ");
  2734. ADD_FLAG("CFLAGS", "-Xclang -fmodules");
  2735. var vc_ver = probe_binary(PATH_PROG('cl', null));
  2736. ADD_FLAG("CFLAGS"," -fms-compatibility -fms-compatibility-version=" + vc_ver + " -fms-extensions");
  2737. }
  2738. }
  2739. function toolset_setup_intrinsic_cflags()
  2740. {
  2741. var default_enabled = "sse2";
  2742. /* XXX AVX and above needs to be reflected in /arch, for now SSE4.2 is
  2743. the best possible optimization.*/
  2744. var avail = WScript.CreateObject("Scripting.Dictionary");
  2745. avail.Add("sse", "__SSE__");
  2746. avail.Add("sse2", "__SSE2__");
  2747. avail.Add("sse3", "__SSE3__");
  2748. avail.Add("ssse3", "__SSSE3__");
  2749. avail.Add("sse4.1", "__SSE4_1__");
  2750. avail.Add("sse4.2", "__SSE4_2__");
  2751. /* From oldest to newest. */
  2752. var scale = new Array("sse", "sse2", "sse3", "ssse3", "sse4.1", "sse4.2", "avx", "avx2");
  2753. if (VS_TOOLSET) {
  2754. if ("disabled" == PHP_NATIVE_INTRINSICS) {
  2755. ERROR("Can't enable intrinsics, --with-codegen-arch passed with an incompatible option. ")
  2756. }
  2757. if ("no" == PHP_NATIVE_INTRINSICS || "yes" == PHP_NATIVE_INTRINSICS) {
  2758. PHP_NATIVE_INTRINSICS = default_enabled;
  2759. }
  2760. if ("all" == PHP_NATIVE_INTRINSICS) {
  2761. var list = (new VBArray(avail.Keys())).toArray();
  2762. for (var i in list) {
  2763. AC_DEFINE(avail.Item(list[i]), 1);
  2764. }
  2765. /* All means all. __AVX__ and __AVX2__ are defined by compiler. */
  2766. ADD_FLAG("CFLAGS","/arch:AVX2");
  2767. configure_subst.Add("PHP_SIMD_SCALE", "AVX2");
  2768. } else {
  2769. var list = PHP_NATIVE_INTRINSICS.split(",");
  2770. var j = 0;
  2771. for (var k = 0; k < scale.length; k++) {
  2772. for (var i = 0; i < list.length; i++) {
  2773. var it = list[i].toLowerCase();
  2774. if (scale[k] == it) {
  2775. j = k > j ? k : j;
  2776. } else if (!avail.Exists(it) && "avx2" != it && "avx" != it) {
  2777. WARNING("Unknown intrinsic name '" + it + "' ignored");
  2778. }
  2779. }
  2780. }
  2781. if (!X64) {
  2782. /* SSE2 is currently the default on 32-bit. It could change later,
  2783. for now no need to pass it. But, if SSE only was chosen,
  2784. /arch:SSE is required. */
  2785. if ("sse" == scale[j]) {
  2786. ADD_FLAG("CFLAGS","/arch:SSE");
  2787. }
  2788. }
  2789. configure_subst.Add("PHP_SIMD_SCALE", scale[j].toUpperCase());
  2790. /* There is no explicit way to enable intrinsics between SSE3 and SSE4.2.
  2791. The declared macros therefore won't affect the code generation,
  2792. but will enable the guarded code parts. */
  2793. if ("avx2" == scale[j]) {
  2794. ADD_FLAG("CFLAGS","/arch:AVX2");
  2795. j -= 2;
  2796. } else if ("avx" == scale[j]) {
  2797. ADD_FLAG("CFLAGS","/arch:AVX");
  2798. j -= 1;
  2799. }
  2800. for (var i = 0; i <= j; i++) {
  2801. var it = scale[i];
  2802. AC_DEFINE(avail.Item(it), 1);
  2803. }
  2804. }
  2805. }
  2806. }
  2807. function toolset_setup_common_ldlags()
  2808. {
  2809. // General DLL link flags
  2810. DEFINE("DLL_LDFLAGS", "/dll ");
  2811. // PHP DLL link flags
  2812. DEFINE("PHP_LDFLAGS", "$(DLL_LDFLAGS)");
  2813. DEFINE("LDFLAGS", "/nologo ");
  2814. // we want msvcrt in the PHP DLL
  2815. ADD_FLAG("PHP_LDFLAGS", "/nodefaultlib:libcmt");
  2816. if (VS_TOOLSET) {
  2817. if (VCVERS >= 1900) {
  2818. if (PHP_SECURITY_FLAGS == "yes") {
  2819. ADD_FLAG('LDFLAGS', "/GUARD:CF");
  2820. }
  2821. }
  2822. }
  2823. }
  2824. function toolset_setup_common_libs()
  2825. {
  2826. // urlmon.lib ole32.lib oleaut32.lib uuid.lib gdi32.lib winspool.lib comdlg32.lib
  2827. DEFINE("LIBS", "kernel32.lib ole32.lib user32.lib advapi32.lib shell32.lib ws2_32.lib Dnsapi.lib psapi.lib bcrypt.lib");
  2828. }
  2829. function toolset_setup_build_mode()
  2830. {
  2831. if (PHP_DEBUG == "yes") {
  2832. ADD_FLAG("CFLAGS", "/LDd /MDd /W3 /Od /D _DEBUG /D ZEND_DEBUG=1 " +
  2833. (X64?"/Zi":"/ZI"));
  2834. ADD_FLAG("LDFLAGS", "/debug");
  2835. // Avoid problems when linking to release libraries that use the release
  2836. // version of the libc
  2837. ADD_FLAG("PHP_LDFLAGS", "/nodefaultlib:msvcrt");
  2838. } else {
  2839. // Generate external debug files when --enable-debug-pack is specified
  2840. if (PHP_DEBUG_PACK == "yes") {
  2841. ADD_FLAG("CFLAGS", "/Zi");
  2842. ADD_FLAG("LDFLAGS", "/incremental:no /debug /opt:ref,icf");
  2843. }
  2844. // Equivalent to Release_TSInline build -> best optimization
  2845. ADD_FLAG("CFLAGS", "/LD /MD /W3 /Ox /D NDebug /D NDEBUG /D ZEND_WIN32_FORCE_INLINE /GF /D ZEND_DEBUG=0");
  2846. // if you have VS.Net /GS hardens the binary against buffer overruns
  2847. // ADD_FLAG("CFLAGS", "/GS");
  2848. }
  2849. }
  2850. function object_out_dir_option_handle()
  2851. {
  2852. if (PHP_OBJECT_OUT_DIR.length) {
  2853. PHP_OBJECT_OUT_DIR = FSO.GetAbsolutePathName(PHP_OBJECT_OUT_DIR);
  2854. if (!FSO.FolderExists(PHP_OBJECT_OUT_DIR)) {
  2855. ERROR('chosen output directory ' + PHP_OBJECT_OUT_DIR + ' does not exist');
  2856. }
  2857. PHP_OBJECT_OUT_DIR += '\\';
  2858. } else {
  2859. PHP_OBJECT_OUT_DIR = FSO.GetAbsolutePathName(".") + '\\';
  2860. if (X64) {
  2861. PHP_OBJECT_OUT_DIR += 'x64\\';
  2862. if (!FSO.FolderExists(PHP_OBJECT_OUT_DIR)) {
  2863. FSO.CreateFolder(PHP_OBJECT_OUT_DIR);
  2864. }
  2865. }
  2866. }
  2867. }
  2868. function setup_zts_stuff()
  2869. {
  2870. if (PHP_ZTS == "yes") {
  2871. ADD_FLAG("CFLAGS", "/D ZTS=1");
  2872. ADD_FLAG("ZTS", "1");
  2873. } else {
  2874. ADD_FLAG("ZTS", "0");
  2875. }
  2876. DEFINE("PHP_ZTS_ARCHIVE_POSTFIX", PHP_ZTS == "yes" ? '' : "-nts");
  2877. // set up the build dir and DLL name
  2878. if (PHP_DEBUG == "yes" && PHP_ZTS == "yes") {
  2879. DEFINE("BUILD_DIR", PHP_OBJECT_OUT_DIR + "Debug_TS");
  2880. if (!MODE_PHPIZE) {
  2881. DEFINE("PHPDLL", "php" + PHP_VERSION + "ts_debug.dll");
  2882. DEFINE("PHPLIB", "php" + PHP_VERSION + "ts_debug.lib");
  2883. }
  2884. } else if (PHP_DEBUG == "yes" && PHP_ZTS == "no") {
  2885. DEFINE("BUILD_DIR", PHP_OBJECT_OUT_DIR + "Debug");
  2886. if (!MODE_PHPIZE) {
  2887. DEFINE("PHPDLL", "php" + PHP_VERSION + "_debug.dll");
  2888. DEFINE("PHPLIB", "php" + PHP_VERSION + "_debug.lib");
  2889. }
  2890. } else if (PHP_DEBUG == "no" && PHP_ZTS == "yes") {
  2891. DEFINE("BUILD_DIR", PHP_OBJECT_OUT_DIR + "Release_TS");
  2892. if (!MODE_PHPIZE) {
  2893. DEFINE("PHPDLL", "php" + PHP_VERSION + "ts.dll");
  2894. DEFINE("PHPLIB", "php" + PHP_VERSION + "ts.lib");
  2895. }
  2896. } else if (PHP_DEBUG == "no" && PHP_ZTS == "no") {
  2897. DEFINE("BUILD_DIR", PHP_OBJECT_OUT_DIR + "Release");
  2898. if (!MODE_PHPIZE) {
  2899. DEFINE("PHPDLL", "php" + PHP_VERSION + ".dll");
  2900. DEFINE("PHPLIB", "php" + PHP_VERSION + ".lib");
  2901. }
  2902. }
  2903. if (!FSO.FolderExists(get_define('BUILD_DIR'))) {
  2904. FSO.CreateFolder(get_define('BUILD_DIR'));
  2905. }
  2906. }
  2907. function php_build_option_handle()
  2908. {
  2909. if (PHP_PHP_BUILD == 'no') {
  2910. if (FSO.FolderExists("..\\deps")) {
  2911. PHP_PHP_BUILD = "..\\deps";
  2912. } else {
  2913. if (FSO.FolderExists("..\\php_build")) {
  2914. PHP_PHP_BUILD = "..\\php_build";
  2915. } else {
  2916. if (X64) {
  2917. if (FSO.FolderExists("..\\win64build")) {
  2918. PHP_PHP_BUILD = "..\\win64build";
  2919. } else if (FSO.FolderExists("..\\php-win64-dev\\php_build")) {
  2920. PHP_PHP_BUILD = "..\\php-win64-dev\\php_build";
  2921. }
  2922. } else {
  2923. if (FSO.FolderExists("..\\win32build")) {
  2924. PHP_PHP_BUILD = "..\\win32build";
  2925. } else if (FSO.FolderExists("..\\php-win32-dev\\php_build")) {
  2926. PHP_PHP_BUILD = "..\\php-win32-dev\\php_build";
  2927. }
  2928. }
  2929. }
  2930. }
  2931. PHP_PHP_BUILD = FSO.GetAbsolutePathName(PHP_PHP_BUILD);
  2932. }
  2933. DEFINE("PHP_BUILD", PHP_PHP_BUILD);
  2934. }
  2935. // Poke around for some headers
  2936. function probe_basic_headers()
  2937. {
  2938. var p;
  2939. if (PHP_PHP_BUILD != "no") {
  2940. php_usual_include_suspects += ";" + PHP_PHP_BUILD + "\\include";
  2941. php_usual_lib_suspects += ";" + PHP_PHP_BUILD + "\\lib";
  2942. }
  2943. }
  2944. function add_extra_dirs()
  2945. {
  2946. var path, i, f;
  2947. if (PHP_EXTRA_INCLUDES.length) {
  2948. path = PHP_EXTRA_INCLUDES.split(';');
  2949. for (i = 0; i < path.length; i++) {
  2950. f = FSO.GetAbsolutePathName(path[i]);
  2951. if (FSO.FolderExists(f)) {
  2952. ADD_FLAG("CFLAGS", '/I "' + f + '" ');
  2953. }
  2954. }
  2955. }
  2956. if (PHP_EXTRA_LIBS.length) {
  2957. path = PHP_EXTRA_LIBS.split(';');
  2958. for (i = 0; i < path.length; i++) {
  2959. f = FSO.GetAbsolutePathName(path[i]);
  2960. if (FSO.FolderExists(f)) {
  2961. if (VS_TOOLSET && VCVERS <= 1200 && f.indexOf(" ") >= 0) {
  2962. ADD_FLAG("LDFLAGS", '/libpath:"\\"' + f + '\\"" ');
  2963. ADD_FLAG("ARFLAGS", '/libpath:"\\"' + f + '\\"" ');
  2964. } else {
  2965. ADD_FLAG("LDFLAGS", '/libpath:"' + f + '" ');
  2966. ADD_FLAG("ARFLAGS", '/libpath:"' + f + '" ');
  2967. }
  2968. }
  2969. }
  2970. }
  2971. }
  2972. function trim(s)
  2973. {
  2974. return s.replace(/^\s+/, "").replace(/\s+$/, "");
  2975. }
  2976. function force_all_shared()
  2977. {
  2978. return !!PHP_ALL_SHARED && "yes" == PHP_ALL_SHARED;
  2979. }
  2980. function ADD_MAKEFILE_FRAGMENT(src_file)
  2981. {
  2982. var fn_in;
  2983. if ("undefined" == typeof(src_file)) {
  2984. fn_in = configure_module_dirname + "\\Makefile.frag.w32";
  2985. } else {
  2986. fn_in = src_file;
  2987. }
  2988. if (FSO.FileExists(fn_in)) {
  2989. var h_in, h_out;
  2990. var create_out_fl = !FSO.FileExists(PHP_MAKEFILE_FRAGMENTS);
  2991. var open_flags = create_out_fl ? 2 : 8;
  2992. h_in = FSO.OpenTextFile(fn_in, 1);
  2993. h_out = FSO.OpenTextFile(PHP_MAKEFILE_FRAGMENTS, open_flags, create_out_fl);
  2994. if (!h_in.AtEndOfStream) {
  2995. h_out.Write(h_in.ReadAll());
  2996. h_out.WriteBlankLines(1);
  2997. }
  2998. h_in.Close();
  2999. h_out.Close();
  3000. }
  3001. }
  3002. function SETUP_OPENSSL(target, path_to_check, common_name, use_env, add_dir_part, add_to_flag_only)
  3003. {
  3004. var ret = 0;
  3005. var cflags_var = "CFLAGS_" + target.toUpperCase();
  3006. if (CHECK_LIB("libcrypto.lib", target, path_to_check) &&
  3007. CHECK_LIB("libssl.lib", target, path_to_check) &&
  3008. CHECK_LIB("crypt32.lib", target, path_to_check, common_name) &&
  3009. CHECK_HEADER_ADD_INCLUDE("openssl/ssl.h", cflags_var, path_to_check, use_env, add_dir_part, add_to_flag_only)) {
  3010. /* Openssl 1.1.x */
  3011. return 2;
  3012. } else if (CHECK_LIB("ssleay32.lib", target, path_to_check, common_name) &&
  3013. CHECK_LIB("libeay32.lib", target, path_to_check, common_name) &&
  3014. CHECK_LIB("crypt32.lib", target, path_to_check, common_name) &&
  3015. CHECK_HEADER_ADD_INCLUDE("openssl/ssl.h", cflags_var, path_to_check, use_env, add_dir_part, add_to_flag_only)) {
  3016. /* Openssl 1.0.x and lower */
  3017. return 1;
  3018. }
  3019. return ret;
  3020. }
  3021. function check_binary_tools_sdk()
  3022. {
  3023. var BIN_TOOLS_SDK_VER_MAJOR = 0;
  3024. var BIN_TOOLS_SDK_VER_MINOR = 0;
  3025. var BIN_TOOLS_SDK_VER_PATCH = 0;
  3026. var out = execute("cmd /c phpsdk_version");
  3027. if (out.match(/PHP SDK (\d+)\.(\d+)\.(\d+).*/)) {
  3028. BIN_TOOLS_SDK_VER_MAJOR = parseInt(RegExp.$1);
  3029. BIN_TOOLS_SDK_VER_MINOR = parseInt(RegExp.$2);
  3030. BIN_TOOLS_SDK_VER_PATCH = parseInt(RegExp.$3);
  3031. }
  3032. /* Basic test, extend by need. */
  3033. if (BIN_TOOLS_SDK_VER_MAJOR < 2) {
  3034. ERROR("Incompatible binary tools version. Please consult\r\nhttps://wiki.php.net/internals/windows/stepbystepbuild_sdk_2");
  3035. }
  3036. }
  3037. function get_clang_lib_dir()
  3038. {
  3039. var ret = null;
  3040. var ver = null;
  3041. if (COMPILER_NAME.match(/clang version ([\d\.]+) \((.*)\)/)) {
  3042. ver = RegExp.$1;
  3043. } else {
  3044. ERROR("Faled to determine clang lib path");
  3045. }
  3046. if (X64) {
  3047. ret = PROGRAM_FILES + "\\LLVM\\lib\\clang\\" + ver + "\\lib";
  3048. if (!FSO.FolderExists(ret)) {
  3049. ret = null;
  3050. }
  3051. } else {
  3052. ret = PROGRAM_FILESx86 + "\\LLVM\\lib\\clang\\" + ver + "\\lib";
  3053. if (!FSO.FolderExists(ret)) {
  3054. ret = PROGRAM_FILES + "\\LLVM\\lib\\clang\\" + ver + "\\lib";
  3055. if (!FSO.FolderExists(ret)) {
  3056. ret = null;
  3057. }
  3058. }
  3059. }
  3060. if (null == ret) {
  3061. ERROR("Invalid clang lib path encountered");
  3062. }
  3063. return ret;
  3064. }
  3065. function add_asan_opts(cflags_name, libs_name, ldflags_name)
  3066. {
  3067. var ver = null;
  3068. if (COMPILER_NAME.match(/clang version ([\d\.]+) \((.*)\)/)) {
  3069. ver = RegExp.$1;
  3070. } else {
  3071. ERROR("Faled to determine clang lib path");
  3072. }
  3073. if (!!cflags_name) {
  3074. ADD_FLAG(cflags_name, "-fsanitize=address");
  3075. ADD_FLAG(cflags_name, "-fsanitize-address-use-after-scope");
  3076. }
  3077. if (!!libs_name) {
  3078. if (X64) {
  3079. ADD_FLAG(libs_name, "clang_rt.asan_dynamic-x86_64.lib clang_rt.asan_dynamic_runtime_thunk-x86_64.lib");
  3080. } else {
  3081. ADD_FLAG(libs_name, "clang_rt.asan_dynamic-i386.lib clang_rt.asan_dynamic_runtime_thunk-i386.lib");
  3082. }
  3083. }
  3084. if (!!ldflags_name) {
  3085. ADD_FLAG(ldflags_name, "/libpath:\"" + get_clang_lib_dir() + "\\windows\"");
  3086. }
  3087. }
  3088. function setup_verbosity()
  3089. {
  3090. if ("no" != PHP_VERBOSITY) {
  3091. if ("yes" == PHP_VERBOSITY) {
  3092. VERBOSITY = 1;
  3093. if (1 == VERBOSITY) {
  3094. CMD_MOD1 = "";
  3095. }
  3096. } else {
  3097. var _tmp = parseInt(PHP_VERBOSITY);
  3098. if (0 != _tmp && 1 != _tmp && 2 != _tmp) {
  3099. ERROR("Unsupported verbosity level '" + PHP_VERBOSITY + "'");
  3100. }
  3101. VERBOSITY = _tmp;
  3102. if (1 == VERBOSITY) {
  3103. CMD_MOD1 = "";
  3104. }
  3105. if (2 == VERBOSITY) {
  3106. CMD_MOD1 = "";
  3107. CMD_MOD2 = "";
  3108. }
  3109. }
  3110. } else {
  3111. VERBOSITY = 0;
  3112. CMD_MOD1 = "@";
  3113. CMD_MOD2 = "@";
  3114. }
  3115. }