PageRenderTime 53ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/win32/build/mkdist.php

https://github.com/practicalweb/php-src
PHP | 494 lines | 339 code | 78 blank | 77 comment | 74 complexity | bd243f7d926cd99ffc90b76283caa5cf 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.24 2009/06/03 01:13:37 kalle 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. $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. if (empty($item)) {
  92. continue;
  93. } elseif (!is_file($source_dir . DIRECTORY_SEPARATOR . $item)) {
  94. echo "WARNING: $item not found\n";
  95. continue;
  96. }
  97. echo "Copying $item from $source_dir to $dest_dir\n";
  98. copy($source_dir . DIRECTORY_SEPARATOR . $item, $dest_dir . DIRECTORY_SEPARATOR . $item);
  99. if ($is_debug) {
  100. $itemdb = preg_replace("/\.(exe|dll|lib)$/i", ".pdb", $item);
  101. if (file_exists("$source_dir/$itemdb")) {
  102. copy("$source_dir/$itemdb", "$dist_dir/dev/$itemdb");
  103. }
  104. }
  105. if (preg_match("/\.(exe|dll)$/i", $item)) {
  106. get_depends($source_dir . '/' . $item);
  107. }
  108. }
  109. }
  110. function copy_text_file($source, $dest)
  111. {
  112. $text = file_get_contents($source);
  113. $text = preg_replace("/(\r\n?)|\n/", "\r\n", $text);
  114. $fp = fopen($dest, "w");
  115. fwrite($fp, $text);
  116. fclose($fp);
  117. }
  118. /* very light-weight function to extract a single named file from
  119. * a gzipped tarball. This makes assumptions about the files
  120. * based on the PEAR info set in $packages. */
  121. function extract_file_from_tarball($pkg, $filename, $dest_dir) /* {{{ */
  122. {
  123. global $packages;
  124. $name = $pkg . '-' . $packages[$pkg];
  125. $tarball = $dest_dir . "/" . $name . '.tgz';
  126. $filename = $name . '/' . $filename;
  127. $destfilename = $dest_dir . "/" . basename($filename);
  128. $fp = gzopen($tarball, 'rb');
  129. $done = false;
  130. do {
  131. /* read the header */
  132. $hdr_data = gzread($fp, 512);
  133. if (strlen($hdr_data) == 0)
  134. break;
  135. $checksum = 0;
  136. for ($i = 0; $i < 148; $i++)
  137. $checksum += ord($hdr_data{$i});
  138. for ($i = 148; $i < 156; $i++)
  139. $checksum += 32;
  140. for ($i = 156; $i < 512; $i++)
  141. $checksum += ord($hdr_data{$i});
  142. $hdr = unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor", $hdr_data);
  143. $hdr['checksum'] = octdec(trim($hdr['checksum']));
  144. if ($hdr['checksum'] != $checksum) {
  145. echo "Checksum for $tarball $hdr[filename] is invalid\n";
  146. print_r($hdr);
  147. return;
  148. }
  149. $hdr['size'] = octdec(trim($hdr['size']));
  150. echo "File: $hdr[filename] $hdr[size]\n";
  151. if ($filename == $hdr['filename']) {
  152. echo "Found the file we want\n";
  153. $dest = fopen($destfilename, 'wb');
  154. $x = stream_copy_to_stream($fp, $dest, $hdr['size']);
  155. fclose($dest);
  156. echo "Wrote $x bytes into $destfilename\n";
  157. break;
  158. }
  159. /* skip body of the file */
  160. $size = 512 * ceil((int)$hdr['size'] / 512);
  161. echo "Skipping $size bytes\n";
  162. gzseek($fp, gztell($fp) + $size);
  163. } while (!$done);
  164. } /* }}} */
  165. /* the core dll */
  166. copy("$build_dir/php.exe", "$dist_dir/php.exe");
  167. copy("$build_dir/$phpdll", "$dist_dir/$phpdll");
  168. /* and the .lib goes into dev */
  169. $phplib = str_replace(".dll", ".lib", $phpdll);
  170. copy("$build_dir/$phplib", "$dist_dir/dev/$phplib");
  171. /* debug builds; copy the symbols too */
  172. if ($is_debug) {
  173. $phppdb = str_replace(".dll", ".pdb", $phpdll);
  174. copy("$build_dir/$phppdb", "$dist_dir/dev/$phppdb");
  175. }
  176. /* copy the sapi */
  177. copy_file_list($build_dir, "$dist_dir", $sapi_targets);
  178. /* copy the extensions */
  179. copy_file_list($build_dir, "$dist_dir/ext", $ext_targets);
  180. /* pecl sapi and extensions */
  181. if(sizeof($pecl_targets)) {
  182. copy_file_list($build_dir, $pecl_dir, $pecl_targets);
  183. }
  184. /* populate reading material */
  185. $text_files = array(
  186. "LICENSE" => "license.txt",
  187. "NEWS" => "news.txt",
  188. "php.ini-development" => "php.ini-development",
  189. "php.ini-production" => "php.ini-production",
  190. "win32/install.txt" => "install.txt",
  191. "win32/pws-php5cgi.reg" => "pws-php5cgi.reg",
  192. "win32/pws-php5isapi.reg" => "pws-php5isapi.reg",
  193. );
  194. foreach ($text_files as $src => $dest) {
  195. copy_text_file($src, $dist_dir . '/' . $dest);
  196. }
  197. /* general other files */
  198. $general_files = array(
  199. "php.gif" => "php.gif",
  200. );
  201. foreach ($general_files as $src => $dest) {
  202. copy($src, $dist_dir . '/' . $dest);
  203. }
  204. /* include a snapshot identifier */
  205. $branch = "HEAD"; // TODO - determine this from CVS/Entries
  206. $fp = fopen("$dist_dir/snapshot.txt", "w");
  207. $now = date("r");
  208. $version = phpversion();
  209. fwrite($fp, <<<EOT
  210. This snapshot was automatically generated on
  211. $now
  212. Version: $version
  213. Branch: $branch
  214. Build: $build_dir
  215. EOT
  216. );
  217. /* list build-in extensions */
  218. $exts = get_loaded_extensions();
  219. fprintf($fp, "\r\nBuilt-in Extensions\r\n");
  220. fwrite($fp, "===========================\r\n");
  221. foreach ($exts as $ext) {
  222. fprintf($fp, "%s\r\n", $ext);
  223. }
  224. fwrite($fp, "\r\n\r\n");
  225. /* list dependencies */
  226. fprintf($fp, "Dependency information:\r\n");
  227. foreach ($per_module_deps as $modulename => $deps) {
  228. if (in_array($modulename, $pecl_targets))
  229. continue;
  230. fprintf($fp, "Module: %s\r\n", $modulename);
  231. fwrite($fp, "===========================\r\n");
  232. foreach ($deps as $dll) {
  233. fprintf($fp, "\t%s\r\n", basename($dll));
  234. }
  235. fwrite($fp, "\r\n");
  236. }
  237. fclose($fp);
  238. /* Now add those dependencies */
  239. foreach ($extra_dll_deps as $dll) {
  240. if (!file_exists($dll)) {
  241. /* try template dir */
  242. $tdll = $snapshot_template . "/dlls/" . basename($dll);
  243. if (!file_exists($tdll)) {
  244. $tdll = '../deps/bin/' . basename($dll);
  245. if (!file_exists($tdll)) {
  246. echo "WARNING: distro depends on $dll, but could not find it on your system\n";
  247. continue;
  248. }
  249. }
  250. $dll = $tdll;
  251. }
  252. copy($dll, "$dist_dir/" . basename($dll));
  253. }
  254. /* TODO:
  255. add sanity check and test if all required DLLs are present, per version
  256. This version works at least for 3.6, 3.8 and 4.0 (5.3-vc6, 5.3-vc9 and HEAD).
  257. */
  258. $ICU_DLLS = '../deps/bin/' . 'icu*.dll';
  259. foreach (glob($ICU_DLLS) as $filename) {
  260. copy($filename, "$dist_dir/" . basename($filename));
  261. }
  262. /* and those for pecl */
  263. foreach ($pecl_dll_deps as $dll) {
  264. if (in_array($dll, $extra_dll_deps)) {
  265. /* already in main distro */
  266. continue;
  267. }
  268. if (!file_exists($dll)) {
  269. /* try template dir */
  270. $tdll = $snapshot_template . "/dlls/" . basename($dll);
  271. if (!file_exists($tdll)) {
  272. echo "WARNING: distro depends on $dll, but could not find it on your system\n";
  273. continue;
  274. }
  275. $dll = $tdll;
  276. }
  277. copy($dll, "$pecl_dir/" . basename($dll));
  278. }
  279. function copy_dir($source, $dest)
  280. {
  281. if (!is_dir($dest)) {
  282. if (!mkdir($dest)) {
  283. return false;
  284. }
  285. }
  286. $d = opendir($source);
  287. while (($f = readdir($d)) !== false) {
  288. if ($f == '.' || $f == '..' || $f == 'CVS' || $f == '.cvsignore') {
  289. continue;
  290. }
  291. $fs = $source . '/' . $f;
  292. $fd = $dest . '/' . $f;
  293. if (is_dir($fs)) {
  294. copy_dir($fs, $fd);
  295. } else {
  296. copy($fs, $fd);
  297. }
  298. }
  299. closedir($d);
  300. }
  301. function copy_test_dir($directory, $dest)
  302. {
  303. if(substr($directory,-1) == '/') {
  304. $directory = substr($directory,0,-1);
  305. }
  306. if ($directory == 'tests') {
  307. mkdir($dest . '/tests', 0775, true);
  308. copy_dir($directory, $dest . '/tests/');
  309. return false;
  310. }
  311. if(!file_exists($directory) || !is_dir($directory)) {
  312. echo "failed... $directory\n";
  313. return FALSE;
  314. }
  315. $directory_list = opendir($directory);
  316. while (FALSE !== ($file = readdir($directory_list))) {
  317. $full_path = $directory . '/' . $file;
  318. if($file != '.' && $file != '..' && $file != 'CVS' && is_dir($full_path)) {
  319. if ($file == 'tests') {
  320. mkdir($dest . '/' . $full_path , 0775, true);
  321. copy_dir($full_path, $dest . '/' . $full_path . '/');
  322. continue;
  323. } else {
  324. copy_test_dir($full_path, $dest);
  325. }
  326. }
  327. }
  328. closedir($directory_list);
  329. }
  330. if (!is_dir($test_dir)) {
  331. mkdir($test_dir);
  332. }
  333. $dirs = array(
  334. 'ext',
  335. 'Sapi',
  336. 'Zend',
  337. 'tests'
  338. );
  339. foreach ($dirs as $dir) {
  340. copy_test_dir($dir, $test_dir);
  341. }
  342. /* change this next line to true to use good-old
  343. * hand-assembled go-pear-bundle from the snapshot template */
  344. $use_pear_template = true;
  345. if (!$use_pear_template) {
  346. /* Let's do a PEAR-less pear setup */
  347. mkdir("$dist_dir/PEAR");
  348. mkdir("$dist_dir/PEAR/go-pear-bundle");
  349. /* grab the bootstrap script */
  350. echo "Downloading go-pear\n";
  351. copy("http://pear.php.net/go-pear", "$dist_dir/PEAR/go-pear.php");
  352. /* import the package list -- sets $packages variable */
  353. include "pear/go-pear-list.php";
  354. /* download the packages into the destination */
  355. echo "Fetching packages\n";
  356. foreach ($packages as $name => $version) {
  357. $filename = "$name-$version.tgz";
  358. $destfilename = "$dist_dir/PEAR/go-pear-bundle/$filename";
  359. if (file_exists($destfilename))
  360. continue;
  361. $url = "http://pear.php.net/get/$filename";
  362. echo "Downloading $name from $url\n";
  363. flush();
  364. copy($url, $destfilename);
  365. }
  366. echo "Download complete. Extracting bootstrap files\n";
  367. /* Now, we want PEAR.php, Getopt.php (Console_Getopt) and Tar.php (Archive_Tar)
  368. * broken out of the tarballs */
  369. extract_file_from_tarball('PEAR', 'PEAR.php', "$dist_dir/PEAR/go-pear-bundle");
  370. extract_file_from_tarball('Archive_Tar', 'Archive/Tar.php', "$dist_dir/PEAR/go-pear-bundle");
  371. extract_file_from_tarball('Console_Getopt', 'Console/Getopt.php', "$dist_dir/PEAR/go-pear-bundle");
  372. }
  373. /* add extras from the template dir */
  374. if (file_exists($snapshot_template)) {
  375. $items = glob("$snapshot_template/*");
  376. print_r($items);
  377. foreach ($items as $item) {
  378. $bi = basename($item);
  379. if (is_dir($item)) {
  380. if ($bi == 'dlls' || $bi == 'symbols') {
  381. continue;
  382. } else if ($bi == 'PEAR') {
  383. if ($use_pear_template) {
  384. /* copy to top level */
  385. copy_dir($item, "$dist_dir/$bi");
  386. }
  387. } else {
  388. /* copy that dir into extras */
  389. copy_dir($item, "$dist_dir/extras/$bi");
  390. }
  391. } else {
  392. if ($bi == 'go-pear.bat') {
  393. /* copy to top level */
  394. copy($item, "$dist_dir/$bi");
  395. } else {
  396. /* copy to extras */
  397. copy($item, "$dist_dir/extras/$bi");
  398. }
  399. }
  400. }
  401. /* copy c++ runtime */
  402. $items = glob("$snapshot_template/dlls/*.CRT");
  403. foreach ($items as $item) {
  404. $bi = basename($item);
  405. if (is_dir($item)) {
  406. copy_dir($item, "$dist_dir/$bi");
  407. copy_dir($item, "$dist_dir/ext/$bi");
  408. }
  409. }
  410. } else {
  411. echo "WARNING: you don't have a snapshot template, your dist will not be complete\n";
  412. }
  413. ?>