Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

467 lines
13 KiB

  1. # BuildComponentVC.pm
  2. #
  3. # created: 8/05/99
  4. package main;
  5. use strict 'subs';
  6. if (!$__IITBUILDPM ) { use iit::build; }
  7. sub BuildComponentVC
  8. {
  9. my($rc) = 1;
  10. my($cmdBuild) = "msdev /USEENV ";
  11. my($sTargetName) = "";
  12. my($sIniFile) = "";
  13. my($sBuildFile) = "";
  14. my($sConfig) = "";
  15. my($sMakeTemplate) = "";
  16. my($sWorkspaceName) = "";
  17. my($sBuildProc) = "";
  18. my($bDoClean) = 0;
  19. local(@lProjects) = ();
  20. local(@lBuildTypes) = ();
  21. local(@lBuildConfigs) = ();
  22. if ($DEBUG) { PrintL("BuildComponentVC(".join(", ", @_).")\n", PL_PURPLE); }
  23. # process arguments
  24. foreach $i (@_)
  25. {
  26. if ($i =~ /\.ini$/i)
  27. {
  28. $sIniFile = $i;
  29. }
  30. elsif ($i =~ /^CONFIG=/i)
  31. {
  32. $sConfig = $i;
  33. $sConfig =~ s/^CONFIG=//i;
  34. }
  35. elsif (($i =~ /^(DEBUG|RELEASE|PROFILE)$/i) || IsMemberOf($i, @lAllowedBuilds))
  36. {
  37. push(@lBuildTypes, uc($i));
  38. }
  39. elsif ($i eq PROC)
  40. {
  41. $sBuildProc = $i;
  42. }
  43. elsif ($i eq "")
  44. {
  45. }
  46. elsif ($i =~ /\.(dsp|dsw)$/)
  47. {
  48. $sBuildFile = $i;
  49. $cmdBuild .= $i." ";
  50. }
  51. elsif (lc($i) eq "rebuild")
  52. {
  53. $bDoClean = 1;
  54. }
  55. else
  56. {
  57. push(@lBuildConfigs, $i);
  58. }
  59. }
  60. if ($sIniFile)
  61. {
  62. my($sConfigDash) = (($sConfig eq "" ) ? "" : uc($sConfig)."-");
  63. UpdateProjectsInBuildIni($sIniFile, $sBuildFile);
  64. ($sWorkspaceName) = GetFieldFromBuildIni($sIniFile, $sBuildFile, $sConfigDash."NAME");
  65. ($sMakeTemplate) = GetFieldFromBuildIni($sIniFile, $sBuildFile, $sConfigDash."MAKESTRING");
  66. @lProjects = GetFieldFromBuildIni($sIniFile, $sBuildFile, $sConfigDash."MAKES");
  67. foreach $project (@lProjects)
  68. {
  69. foreach $build (GetFieldFromBuildIni($sIniFile, $sBuildFile, uc($project)."-BUILDS"))
  70. {
  71. my($config) = $sMakeTemplate;
  72. $config =~ s/\%MAKE\%/$project/i;
  73. $config =~ s/\%BUILD\%/$build/i;
  74. push(@lBuildConfigs, $config);
  75. }
  76. }
  77. }
  78. local(@lTmp) = @lBuildConfigs;
  79. @lBuildConfigs = ();
  80. foreach $config (@lTmp)
  81. {
  82. my($configGood) = 0;
  83. foreach $build (@lBuildTypes)
  84. {
  85. if (($config =~ /$build/i) && ($config =~ /$sBuildProc/i))
  86. {
  87. $configGood = 1;
  88. }
  89. #***** TODO: REMOVE (temporary fix for dsps without x86 in title)
  90. if ($config =~ /alpha/i)
  91. {
  92. $configGood = 0;
  93. }
  94. #*****
  95. }
  96. if ($configGood)
  97. {
  98. push(@lBuildConfigs, $config);
  99. }
  100. }
  101. if ($bDoClean)
  102. {
  103. PrintL("\nCleaning up ...\n\n", PL_SUBHEADER);
  104. local(@lAlreadyCleaned) = ();
  105. foreach $build (@lBuildConfigs)
  106. {
  107. if (!IsMemberOf($build, @lAlreadyCleaned))
  108. {
  109. push(@lAlreadyCleaned, $build);
  110. $_Execute = 1;
  111. Execute($cmdBuild.'/MAKE "'.$build.'" /CLEAN');
  112. my $tmp = $_Execute;
  113. undef $_Execute;
  114. PrintL($tmp);
  115. foreach $line (split("\n", $tmp))
  116. {
  117. $line =~ s/[^']*'([^']*)'.*/$1/;
  118. if ($line ne "")
  119. {
  120. push(@lAlreadyCleaned, $line);
  121. }
  122. }
  123. }
  124. else
  125. {
  126. PrintL(' - Skipping "'.$build.'" (already cleaned)'."\n", PL_BLUE);
  127. }
  128. }
  129. }
  130. foreach $build (@lBuildConfigs)
  131. {
  132. ++$nTotalBuilds;
  133. my($sMakeName) = "";
  134. if ($sWorkspaceName eq "")
  135. {
  136. $sMakeName = $sBuildFile.", ".$build;
  137. }
  138. else
  139. {
  140. $sMakeName = $sWorkspaceName.", ".$build;
  141. }
  142. my($cmdBuildProj) = $cmdBuild.'/MAKE "'.$build.'" ';
  143. PrintL("\n"."#" x (39 - ((length($sMakeName) + (length($sMakeName) % 2)) / 2)).
  144. ' '.$sMakeName.' '."#" x (39 - ((length($sMakeName) - (length($sMakeName) % 2)) / 2))."\n\n",
  145. PL_GREEN | PL_FLUSH);
  146. BEGIN_DHTML_NODE("(click to expand)");
  147. my($startTime) = time();
  148. my($strMsg) = "";
  149. PrintL($cmdBuildProj."\n");
  150. eval
  151. {
  152. open (MSDEVIN, $cmdBuildProj.' 2>&1 |');
  153. while(<MSDEVIN>)
  154. {
  155. PrintL($_);
  156. if (/: (error|fatal error|info|information|assert)(,| )/i
  157. || (/: warning(,| )/i
  158. && !/different attributes \(40000040\)/)
  159. || /\*\*\* (Error|Warning|Info): /i
  160. || (/WARNING: /i
  161. && !/Context switch during time delta calculation/) # icap stuff
  162. || /failed\./
  163. || /is not recognized/
  164. || /^error/i
  165. || /- (\d+ error\(s\), [^0]+|[^0]+ error\(s\), \d+) warning\(s\)/)
  166. {
  167. $strMsg .= "<dd>".$_;
  168. }
  169. }
  170. $bNothingDone = 0;
  171. if ($bcStatus & BC_NOTHINGDONE)
  172. {
  173. $bcStatus -= BC_NOTHINGDONE;
  174. }
  175. close(MSDEVIN);
  176. };
  177. END_DHTML_NODE();
  178. my($stopTime) = time();
  179. my($sDiff) = FmtDeltaTime($stopTime - $startTime);
  180. if ($CHILD_ERROR)
  181. {
  182. ++$nFailedBuilds;
  183. $rc = 0;
  184. PrintLTip($sMakeName." FAILED\n\n", "Build Time: ".$sDiff, PL_BIGERROR);
  185. # @faillist = (@faillist, substr $buildtype, 0, 1);
  186. }
  187. else
  188. {
  189. PrintLTip($sMakeName." Succeeded\n\n", "Build Time: ".$sDiff, PL_NOTAG | PL_MSG | PL_GREEN);
  190. }
  191. if ($strMsg ne "")
  192. {
  193. PrintMsgBlock(split(/\n/, $strMsg));
  194. }
  195. }
  196. PrintL("BuildComponentVC returns ".$rc."\n", $PL_VERBOSE);
  197. if (!$rc && IsCritical())
  198. {
  199. $bBuildFailed = 1;
  200. }
  201. return($rc);
  202. }
  203. sub GetFieldFromBuildIni
  204. {
  205. my($sIniFile, $sBuildFile, $sField) = @_;
  206. my($sBuildFileBase) = RemovePath($sBuildFile);
  207. my(@lResults) = ();
  208. my($fhIni) = OpenFile($sIniFile, "read");
  209. if (!$fhIni)
  210. {
  211. return("");
  212. }
  213. my($bFoundProj) = 0;
  214. my($bFieldPassed) = 0;
  215. my($bFieldFound) = 0;
  216. while (!$fhIni->eof() && !$bFieldPassed && !$bFieldFound)
  217. {
  218. my($text) = $fhIni->getline();
  219. if ($bFoundProj)
  220. {
  221. if ($text =~ /^\[/)
  222. {
  223. $bFoundProj = 0;
  224. $bFieldPassed = 1;
  225. }
  226. elsif ($text =~ /^$sField=/i)
  227. {
  228. $bFieldFound = 1;
  229. $text =~ s/^$sField=//i;
  230. chomp($text);
  231. if ($text =~ /,/)
  232. {
  233. @lResults = split(/\s*,\s*/, $text);
  234. }
  235. else
  236. {
  237. $lResults[0] = $text;
  238. }
  239. }
  240. }
  241. elsif ($text =~ /^\[$sBuildFileBase\]/i)
  242. {
  243. $bFoundProj = 1;
  244. }
  245. }
  246. CloseFile($fhIni);
  247. if (!$bFieldFound && ($sField =~ /-/))
  248. {
  249. my($sParentField) = $sField;
  250. $sParentField =~ s/^[^-]*-//;
  251. return(GetFieldFromBuildIni($sIniFile, $sBuildFile, $sParentField));
  252. }
  253. else
  254. {
  255. return(@lResults);
  256. }
  257. }
  258. sub UpdateProjectsInBuildIni($$)
  259. #TODO: error handling
  260. {
  261. my($sIniFile, $sBuildFile) = @_;
  262. # my($sConfigTemplate) = GetAllTextFromFile($sIniFile);
  263. # $sConfigTemplate =~ s/MAKESTRING=([^\n]*)\n.*/$1/;
  264. local(%hComponentBuilds) = ();
  265. my($fhIni) = OpenFile($sIniFile, "read");
  266. my($fhBuild) = OpenFile($sBuildFile, "read");
  267. my($rc) = 1;
  268. local(@lShipConfigs) = ();
  269. if (!$fhIni || !$fhBuild)
  270. {
  271. return(0);
  272. }
  273. PrintL(" - Checking ".$sBuildFile." for necessary updates to ".$sIniFile." ...\n");
  274. while ($fhBuild && !$fhBuild->eof())
  275. {
  276. my($text) = $fhBuild->getline();
  277. if ($text =~ /^Project: \"/)
  278. {
  279. if ($text =~ /^Project: \"all\"/)
  280. {
  281. my($bAllDone) = 0;
  282. while(!$fhBuild->eof() && !$bAllDone)
  283. {
  284. $text = $fhBuild->getline();
  285. if ($text =~ /^###############################################################################\n$/)
  286. {
  287. $bAllDone = 1;
  288. }
  289. elsif ($text =~ /Project_Dep_Name /)
  290. {
  291. $text =~ s/^\s*//g;
  292. $text =~ s/Project_Dep_Name //;
  293. chomp($text);
  294. push(@lShipConfigs, $text);
  295. }
  296. }
  297. }
  298. else
  299. {
  300. my($name) = $text;
  301. $name =~ s/^Project: \"([^\"]*)\".*/$1/;
  302. chomp($name);
  303. if ($text =~ /="/)
  304. {
  305. $text =~ s/[^=]*="([^"]*)".*/$1/;
  306. }
  307. else
  308. {
  309. $text =~ s/[^=]*=([^\s]*)\s.*/$1/;
  310. }
  311. chomp($text);
  312. my($fhProject) = OpenFile($text, "read");
  313. if ($fhProject)
  314. {
  315. while (!$fhProject->eof())
  316. {
  317. my($text) = $fhProject->getline();
  318. if ($text =~ /^# Begin Target/)
  319. {
  320. local(@lComponentBuilds) = ();
  321. while (!$fhProject->eof() && $text !~ /# End Target/)
  322. {
  323. $text = $fhProject->getline();
  324. if ($text =~ /^# Name "/)
  325. {
  326. $text =~ s/^# Name "([^"]*)".*/$1/;
  327. chomp($text);
  328. # my($tempConfig) = $sConfigTemplate;
  329. # $tempConfig =~ s/%[^%]*%//g;
  330. local(@lElems) = split(" - Win32 ", $text); #TODO: fix
  331. push(@lComponentBuilds, $lElems[1]);
  332. }
  333. }
  334. %hComponentBuilds = (%hComponentBuilds,
  335. $name => join(", ", @lComponentBuilds));
  336. }
  337. }
  338. }
  339. else
  340. {
  341. PrintL("Could not find project file: ".$text."\n", PL_BIGERROR);
  342. }
  343. }
  344. }
  345. }
  346. CloseFile($fhBuild);
  347. if (scalar(keys(%hComponentBuilds)) == 0)
  348. {
  349. return(0); #something's screwed up
  350. }
  351. my($sMakesText) = "MAKES=".join(", ", keys(%hComponentBuilds))."\n";
  352. my($sShipMakesText) = "SHIP-MAKES=".join(", ", @lShipConfigs)."\n";
  353. my($sIniText) = "";
  354. my($sBuildFileBase) = RemovePath($sBuildFile);
  355. my($bFoundProj) = 0;
  356. while (!$fhIni->eof())
  357. {
  358. my($text) = $fhIni->getline();
  359. if ($bFoundProj)
  360. {
  361. if ($text =~ /^\[/)
  362. {
  363. $bFoundProj = 0;
  364. }
  365. elsif ($text =~ /^MAKES=/i)
  366. {
  367. $text = $sMakesText;
  368. }
  369. elsif ((@lShipConfigs != ()) && ($text =~ /^SHIP-MAKES=/i))
  370. {
  371. $text = $sShipMakesText;
  372. }
  373. elsif ($text =~ /-BUILDS=/i)
  374. {
  375. my($compName) = $text;
  376. $compName =~ s/^([^-]*)-BUILDS=.*/$1/i;
  377. chomp($compName);
  378. if (GetKeyCaseInsensitive($compName, %hComponentBuilds) ne "")
  379. {
  380. $text = $compName."-BUILDS=".GetKeyCaseInsensitive($compName, %hComponentBuilds)."\n";
  381. SetKeyCaseInsensitive($compName, "", *hComponentBuilds);
  382. }
  383. }
  384. }
  385. elsif ($text =~ /^\[$sBuildFileBase\]/i)
  386. {
  387. $bFoundProj = 1;
  388. }
  389. $sIniText .= $text;
  390. }
  391. # write the new configs to the ini file
  392. foreach $config (keys(%hComponentBuilds))
  393. {
  394. if ($hComponentBuilds{$config} ne "")
  395. {
  396. $sIniText .= $config."-BUILDS=".$hComponentBuilds{$config}."\n";
  397. }
  398. }
  399. CloseFile($fhIni);
  400. unlink($sIniFile.".tmp");
  401. $fhOut = OpenFile($sIniFile.".tmp", "write");
  402. if (!$fhOut)
  403. {
  404. return(0);
  405. }
  406. $fhOut->print($sIniText);
  407. CloseFile($fhOut);
  408. if (IsReadOnly($sIniFile))
  409. {
  410. $rc = ssrepl($sIniFile.".tmp", $sIniFile);
  411. }
  412. else
  413. {
  414. $rc = EchoedCopy($sIniFile.".tmp", $sIniFile);
  415. }
  416. unlink($sIniFile.".tmp");
  417. return($rc);
  418. }
  419. $__IITBUILDCOMPONENTVCPM = 1;
  420. 1;