PageRenderTime 55ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/win32/build/mkdist.php

https://github.com/ifeghali/php-src
PHP | 486 lines | 331 code | 77 blank | 78 comment | 72 complexity | c1b991ea7aef60b430e165050ba2f174 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, BSD-3-Clause
  1. <?php # $Id$
  2. /* piece together a windows binary distro */
  3. $build_dir = $argv[1];
  4. $phpdll = $argv[2];
  5. $sapi_targets = explode(" ", $argv[3]);
  6. $ext_targets = explode(" ", $argv[4]);
  7. $pecl_targets = explode(" ", $argv[5]);
  8. $snapshot_template = $argv[6];
  9. $is_debug = preg_match("/^debug/i", $build_dir);
  10. echo "Making dist for $build_dir\n";
  11. $dist_dir = $build_dir . "/php-" . phpversion();
  12. $test_dir = $build_dir . "/php-test-pack-" . phpversion();
  13. $pecl_dir = $build_dir . "/pecl-" . phpversion();
  14. @mkdir($dist_dir);
  15. @mkdir("$dist_dir/ext");
  16. @mkdir("$dist_dir/dev");
  17. @mkdir("$dist_dir/extras");
  18. @mkdir($pecl_dir);
  19. /* figure out additional DLL's that are required */
  20. $extra_dll_deps = array();
  21. $per_module_deps = array();
  22. $pecl_dll_deps = array();
  23. function get_depends($module)
  24. {
  25. static $no_dist = array(
  26. /* windows system dlls that should not be bundled */
  27. 'advapi32.dll', 'comdlg32.dll', 'crypt32.dll', 'gdi32.dll', 'kernel32.dll', 'ntdll.dll',
  28. 'odbc32.dll', 'ole32.dll', 'oleaut32.dll', 'rpcrt4.dll',
  29. 'shell32.dll', 'shlwapi.dll', 'user32.dll', 'ws2_32.dll', 'ws2help.dll',
  30. 'comctl32.dll', 'winmm.dll', 'wsock32.dll', 'winspool.drv', 'msasn1.dll',
  31. 'secur32.dll', 'netapi32.dll',
  32. /* apache */
  33. 'apachecore.dll',
  34. /* apache 2 */
  35. 'libhttpd.dll', 'libapr.dll', 'libaprutil.dll','libapr-1.dll', 'libaprutil-1.dll',
  36. /* pi3web */
  37. 'piapi.dll', 'pi3api.dll',
  38. /* nsapi */
  39. 'ns-httpd30.dll', 'ns-httpd35.dll', 'ns-httpd36.dll', 'ns-httpd40.dll',
  40. /* oracle */
  41. 'oci.dll', 'ociw32.dll',
  42. /* sybase */
  43. 'libcs.dll', 'libct.dll',
  44. /* visual C++; mscvrt.dll is present on everyones system,
  45. * but the debug version (msvcrtd.dll) and those from visual studio.net
  46. * (msvcrt7x.dll) are not */
  47. 'msvcrt.dll',
  48. );
  49. global $build_dir, $extra_dll_deps, $ext_targets, $sapi_targets, $pecl_targets, $phpdll, $per_module_deps, $pecl_dll_deps;
  50. $bd = strtolower(realpath($build_dir));
  51. $is_pecl = in_array($module, $pecl_targets);
  52. $cmd = "$GLOBALS[build_dir]\\deplister.exe \"$module\" \"$GLOBALS[build_dir]\"";
  53. $proc = proc_open($cmd,
  54. array(1 => array("pipe", "w")),
  55. $pipes);
  56. $n = 0;
  57. while (($line = fgetcsv($pipes[1]))) {
  58. $n++;
  59. $dep = strtolower($line[0]);
  60. $depbase = basename($dep);
  61. /* ignore stuff in our build dir, but only if it is
  62. * one of our targets */
  63. if (((in_array($depbase, $sapi_targets) ||
  64. in_array($depbase, $ext_targets) || in_array($depbase, $pecl_targets)) ||
  65. $depbase == $phpdll) && file_exists($GLOBALS['build_dir'] . "/$depbase")) {
  66. continue;
  67. }
  68. /* ignore some well-known system dlls */
  69. if (in_array(basename($dep), $no_dist)) {
  70. continue;
  71. }
  72. if ($is_pecl) {
  73. if (!in_array($dep, $pecl_dll_deps)) {
  74. $pecl_dll_deps[] = $dep;
  75. }
  76. } else {
  77. if (!in_array($dep, $extra_dll_deps)) {
  78. $extra_dll_deps[] = $dep;
  79. }
  80. }
  81. $per_module_deps[basename($module)][] = $dep;
  82. }
  83. fclose($pipes[1]);
  84. proc_close($proc);
  85. //echo "Module $module [$n lines]\n";
  86. }
  87. function copy_file_list($source_dir, $dest_dir, $list)
  88. {
  89. global $is_debug, $dist_dir;
  90. foreach ($list as $item) {
  91. echo "Copying $item from $source_dir to $dest_dir\n";
  92. copy($source_dir . DIRECTORY_SEPARATOR . $item, $dest_dir . DIRECTORY_SEPARATOR . $item);
  93. if ($is_debug) {
  94. $itemdb = preg_replace("/\.(exe|dll|lib)$/i", ".pdb", $item);
  95. if (file_exists("$source_dir/$itemdb")) {
  96. copy("$source_dir/$itemdb", "$dist_dir/dev/$itemdb");
  97. }
  98. }
  99. if (preg_match("/\.(exe|dll)$/i", $item)) {
  100. get_depends($source_dir . '/' . $item);
  101. }
  102. }
  103. }
  104. function copy_text_file($source, $dest)
  105. {
  106. $text = file_get_contents($source);
  107. $text = preg_replace("/(\r\n?)|\n/", "\r\n", $text);
  108. $fp = fopen($dest, "w");
  109. fwrite($fp, $text);
  110. fclose($fp);
  111. }
  112. /* very light-weight function to extract a single named file from
  113. * a gzipped tarball. This makes assumptions about the files
  114. * based on the PEAR info set in $packages. */
  115. function extract_file_from_tarball($pkg, $filename, $dest_dir) /* {{{ */
  116. {
  117. global $packages;
  118. $name = $pkg . '-' . $packages[$pkg];
  119. $tarball = $dest_dir . "/" . $name . '.tgz';
  120. $filename = $name . '/' . $filename;
  121. $destfilename = $dest_dir . "/" . basename($filename);
  122. $fp = gzopen($tarball, 'rb');
  123. $done = false;
  124. do {
  125. /* read the header */
  126. $hdr_data = gzread($fp, 512);
  127. if (strlen($hdr_data) == 0)
  128. break;
  129. $checksum = 0;
  130. for ($i = 0; $i < 148; $i++)
  131. $checksum += ord($hdr_data{$i});
  132. for ($i = 148; $i < 156; $i++)
  133. $checksum += 32;
  134. for ($i = 156; $i < 512; $i++)
  135. $checksum += ord($hdr_data{$i});
  136. $hdr = unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor", $hdr_data);
  137. $hdr['checksum'] = octdec(trim($hdr['checksum']));
  138. if ($hdr['checksum'] != $checksum) {
  139. echo "Checksum for $tarball $hdr[filename] is invalid\n";
  140. print_r($hdr);
  141. return;
  142. }
  143. $hdr['size'] = octdec(trim($hdr['size']));
  144. echo "File: $hdr[filename] $hdr[size]\n";
  145. if ($filename == $hdr['filename']) {
  146. echo "Found the file we want\n";
  147. $dest = fopen($destfilename, 'wb');
  148. $x = stream_copy_to_stream($fp, $dest, $hdr['size']);
  149. fclose($dest);
  150. echo "Wrote $x bytes into $destfilename\n";
  151. break;
  152. }
  153. /* skip body of the file */
  154. $size = 512 * ceil((int)$hdr['size'] / 512);
  155. echo "Skipping $size bytes\n";
  156. gzseek($fp, gztell($fp) + $size);
  157. } while (!$done);
  158. } /* }}} */
  159. /* the core dll */
  160. copy("$build_dir/php.exe", "$dist_dir/php.exe");
  161. copy("$build_dir/$phpdll", "$dist_dir/$phpdll");
  162. /* and the .lib goes into dev */
  163. $phplib = str_replace(".dll", ".lib", $phpdll);
  164. copy("$build_dir/$phplib", "$dist_dir/dev/$phplib");
  165. /* debug builds; copy the symbols too */
  166. if ($is_debug) {
  167. $phppdb = str_replace(".dll", ".pdb", $phpdll);
  168. copy("$build_dir/$phppdb", "$dist_dir/dev/$phppdb");
  169. }
  170. /* copy the sapi */
  171. copy_file_list($build_dir, "$dist_dir", $sapi_targets);
  172. /* copy the extensions */
  173. copy_file_list($build_dir, "$dist_dir/ext", $ext_targets);
  174. /* pecl sapi and extensions */
  175. copy_file_list($build_dir, $pecl_dir, $pecl_targets);
  176. /* populate reading material */
  177. $text_files = array(
  178. "LICENSE" => "license.txt",
  179. "NEWS" => "news.txt",
  180. "php.ini-dist" => "php.ini-dist",
  181. "php.ini-recommended" => "php.ini-recommended",
  182. "win32/install.txt" => "install.txt",
  183. "win32/pws-php5cgi.reg" => "pws-php5cgi.reg",
  184. "win32/pws-php5isapi.reg" => "pws-php5isapi.reg",
  185. );
  186. foreach ($text_files as $src => $dest) {
  187. copy_text_file($src, $dist_dir . '/' . $dest);
  188. }
  189. /* general other files */
  190. $general_files = array(
  191. "php.gif" => "php.gif",
  192. );
  193. foreach ($general_files as $src => $dest) {
  194. copy($src, $dist_dir . '/' . $dest);
  195. }
  196. /* include a snapshot identifier */
  197. $branch = "HEAD"; // TODO - determine this from CVS/Entries
  198. $fp = fopen("$dist_dir/snapshot.txt", "w");
  199. $now = date("r");
  200. $version = phpversion();
  201. fwrite($fp, <<<EOT
  202. This snapshot was automatically generated on
  203. $now
  204. Version: $version
  205. Branch: $branch
  206. Build: $build_dir
  207. EOT
  208. );
  209. /* list build-in extensions */
  210. $exts = get_loaded_extensions();
  211. fprintf($fp, "\r\nBuilt-in Extensions\r\n");
  212. fwrite($fp, "===========================\r\n");
  213. foreach ($exts as $ext) {
  214. fprintf($fp, "%s\r\n", $ext);
  215. }
  216. fwrite($fp, "\r\n\r\n");
  217. /* list dependencies */
  218. fprintf($fp, "Dependency information:\r\n");
  219. foreach ($per_module_deps as $modulename => $deps) {
  220. if (in_array($modulename, $pecl_targets))
  221. continue;
  222. fprintf($fp, "Module: %s\r\n", $modulename);
  223. fwrite($fp, "===========================\r\n");
  224. foreach ($deps as $dll) {
  225. fprintf($fp, "\t%s\r\n", basename($dll));
  226. }
  227. fwrite($fp, "\r\n");
  228. }
  229. fclose($fp);
  230. /* Now add those dependencies */
  231. foreach ($extra_dll_deps as $dll) {
  232. if (!file_exists($dll)) {
  233. /* try template dir */
  234. $tdll = $snapshot_template . "/dlls/" . basename($dll);
  235. if (!file_exists($tdll)) {
  236. $tdll = '../deps/bin/' . basename($dll);
  237. if (!file_exists($tdll)) {
  238. echo "WARNING: distro depends on $dll, but could not find it on your system\n";
  239. continue;
  240. }
  241. }
  242. $dll = $tdll;
  243. }
  244. copy($dll, "$dist_dir/" . basename($dll));
  245. }
  246. /* TODO:
  247. add sanity check and test if all required DLLs are present, per version
  248. This version works at least for 3.6, 3.8 and 4.0 (5.3-vc6, 5.3-vc9 and HEAD).
  249. */
  250. $ICU_DLLS = '../deps/bin/' . 'icu*.dll';
  251. foreach (glob($ICU_DLLS) as $filename) {
  252. copy($filename, "$dist_dir/" . basename($filename));
  253. }
  254. /* and those for pecl */
  255. foreach ($pecl_dll_deps as $dll) {
  256. if (in_array($dll, $extra_dll_deps)) {
  257. /* already in main distro */
  258. continue;
  259. }
  260. if (!file_exists($dll)) {
  261. /* try template dir */
  262. $tdll = $snapshot_template . "/dlls/" . basename($dll);
  263. if (!file_exists($tdll)) {
  264. echo "WARNING: distro depends on $dll, but could not find it on your system\n";
  265. continue;
  266. }
  267. $dll = $tdll;
  268. }
  269. copy($dll, "$pecl_dir/" . basename($dll));
  270. }
  271. function copy_dir($source, $dest)
  272. {
  273. if (!is_dir($dest)) {
  274. if (!mkdir($dest)) {
  275. return false;
  276. }
  277. }
  278. $d = opendir($source);
  279. while (($f = readdir($d)) !== false) {
  280. if ($f == '.' || $f == '..' || $f == 'CVS' || $f == '.cvsignore') {
  281. continue;
  282. }
  283. $fs = $source . '/' . $f;
  284. $fd = $dest . '/' . $f;
  285. if (is_dir($fs)) {
  286. copy_dir($fs, $fd);
  287. } else {
  288. copy($fs, $fd);
  289. }
  290. }
  291. closedir($d);
  292. }
  293. function copy_test_dir($directory, $dest)
  294. {
  295. if(substr($directory,-1) == '/') {
  296. $directory = substr($directory,0,-1);
  297. }
  298. if ($directory == 'tests') {
  299. mkdir($dest . '/tests', 0775, true);
  300. copy_dir($directory, $dest . '/tests/');
  301. return false;
  302. }
  303. if(!file_exists($directory) || !is_dir($directory)) {
  304. echo "failed... $directory\n";
  305. return FALSE;
  306. }
  307. $directory_list = opendir($directory);
  308. while (FALSE !== ($file = readdir($directory_list))) {
  309. $full_path = $directory . '/' . $file;
  310. if($file != '.' && $file != '..' && $file != 'CVS' && is_dir($full_path)) {
  311. if ($file == 'tests') {
  312. mkdir($dest . '/' . $full_path , 0775, true);
  313. copy_dir($full_path, $dest . '/' . $full_path . '/');
  314. continue;
  315. } else {
  316. copy_test_dir($full_path, $dest);
  317. }
  318. }
  319. }
  320. closedir($directory_list);
  321. }
  322. if (!is_dir($test_dir)) {
  323. mkdir($test_dir);
  324. }
  325. $dirs = array(
  326. 'ext',
  327. 'Sapi',
  328. 'Zend',
  329. 'tests'
  330. );
  331. foreach ($dirs as $dir) {
  332. copy_test_dir($dir, $test_dir);
  333. }
  334. /* change this next line to true to use good-old
  335. * hand-assembled go-pear-bundle from the snapshot template */
  336. $use_pear_template = true;
  337. if (!$use_pear_template) {
  338. /* Let's do a PEAR-less pear setup */
  339. mkdir("$dist_dir/PEAR");
  340. mkdir("$dist_dir/PEAR/go-pear-bundle");
  341. /* grab the bootstrap script */
  342. echo "Downloading go-pear\n";
  343. copy("http://pear.php.net/go-pear", "$dist_dir/PEAR/go-pear.php");
  344. /* import the package list -- sets $packages variable */
  345. include "pear/go-pear-list.php";
  346. /* download the packages into the destination */
  347. echo "Fetching packages\n";
  348. foreach ($packages as $name => $version) {
  349. $filename = "$name-$version.tgz";
  350. $destfilename = "$dist_dir/PEAR/go-pear-bundle/$filename";
  351. if (file_exists($destfilename))
  352. continue;
  353. $url = "http://pear.php.net/get/$filename";
  354. echo "Downloading $name from $url\n";
  355. flush();
  356. copy($url, $destfilename);
  357. }
  358. echo "Download complete. Extracting bootstrap files\n";
  359. /* Now, we want PEAR.php, Getopt.php (Console_Getopt) and Tar.php (Archive_Tar)
  360. * broken out of the tarballs */
  361. extract_file_from_tarball('PEAR', 'PEAR.php', "$dist_dir/PEAR/go-pear-bundle");
  362. extract_file_from_tarball('Archive_Tar', 'Archive/Tar.php', "$dist_dir/PEAR/go-pear-bundle");
  363. extract_file_from_tarball('Console_Getopt', 'Console/Getopt.php', "$dist_dir/PEAR/go-pear-bundle");
  364. }
  365. /* add extras from the template dir */
  366. if (file_exists($snapshot_template)) {
  367. $items = glob("$snapshot_template/*");
  368. print_r($items);
  369. foreach ($items as $item) {
  370. $bi = basename($item);
  371. if (is_dir($item)) {
  372. if ($bi == 'dlls' || $bi == 'symbols') {
  373. continue;
  374. } else if ($bi == 'PEAR') {
  375. if ($use_pear_template) {
  376. /* copy to top level */
  377. copy_dir($item, "$dist_dir/$bi");
  378. }
  379. } else {
  380. /* copy that dir into extras */
  381. copy_dir($item, "$dist_dir/extras/$bi");
  382. }
  383. } else {
  384. if ($bi == 'go-pear.bat') {
  385. /* copy to top level */
  386. copy($item, "$dist_dir/$bi");
  387. } else {
  388. /* copy to extras */
  389. copy($item, "$dist_dir/extras/$bi");
  390. }
  391. }
  392. }
  393. /* copy c++ runtime */
  394. $items = glob("$snapshot_template/dlls/*.CRT");
  395. foreach ($items as $item) {
  396. $bi = basename($item);
  397. if (is_dir($item)) {
  398. copy_dir($item, "$dist_dir/$bi");
  399. copy_dir($item, "$dist_dir/ext/$bi");
  400. }
  401. }
  402. } else {
  403. echo "WARNING: you don't have a snapshot template\n";
  404. echo " your dist will not be complete\n";
  405. }
  406. ?>