PageRenderTime 61ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/php5/win32/build/mkdist.php

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