PageRenderTime 58ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/win32/build/mkdist.php

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