Merge pull request #2216 from jwillemsen/jwi-cxxversionchecks
[ACE_TAO.git] / ACE / bin / auto_compile
blobc4ab9fae6246907c343b61bc6b39f0bb04789473
1 eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
2     & eval 'exec perl -S $0 $argv:q'
3     if 0;
5 # -*- perl -*-
6 # This script checkouts ACE from CVS, updates the "clone" directory,
7 # compiles $ACE_ROOT/ace and $ACE_ROOT/tests and finally runs
8 # $ACE_ROOT/tests/run_tests.sh.
10 # If it detects any problem it send email.
12 # DO NOT invoke this script from your crontab, use
13 # auto_compile_wrapper for that.
15 # This script requires Perl5.
17 # TODO: Modify the script or split it in such a way that the main copy
18 # can be obtained either using cvs or downloading the latest beta
19 # from the WWW.
22 # The first three lines above let this script run without specifying the
23 # full path to perl, as long as it is in the user's PATH.
24 # Taken from perlrun man page.
26 use File::Basename;
27 use File::Copy;
28 use FileHandle;
29 require POSIX;
31 # This are the sub-directories (in the module) we really compile.
33 # Find out the command name.
34 $CMD = basename($0);
36 $dont_update = 0;
37 # $copy_logs = 1;
38 # $LOG_DESTINATION = $ENV{'HOME'}.'/.www-docs/auto_compile';
40 $copy_logs = 0;
41 $LOG_DESTINATION='bugzilla'.'@cs.wustl.edu';
43 $dont_build_tao = 0;
44 $dont_run = 0;
45 $makefile_suffix = "";
46 $pre_realclean = 0;
47 $post_realclean = 0;
48 $report_success = 0;
49 $debug = 0;
50 $sandbox = '';
51 $sandbox_timeout = 600;
52 $sendreport = 0;
53 @BUILD_LIST= ();
54 @CONFIGURATION_OPTIONS = ();
56 @ARGS = ();
57 while ($#ARGV >= 0) {
58   if (!($ARGV[0] =~ m/^-/)) {
59     push @ARGS, $ARGV[0];
60   } elsif ($ARGV[0] eq "-single_threaded") {
61     print STDERR "$CMD: obsolete option $ARGV[0], "
62       ."please use -config instead\n";
63     push @CONFIGURATION_OPTIONS, 'ST';
64   } elsif ($ARGV[0] eq "-minimum_corba") {
65     print STDERR "$CMD: obsolete option $ARGV[0], "
66       ."please use -config instead\n";
67     push @CONFIGURATION_OPTIONS, 'MINIMUM';
68   } elsif ($ARGV[0] eq "-ami") {
69     print STDERR "$CMD: obsolete option $ARGV[0], "
70       ."please use -config instead\n";
71     push @CONFIGURATION_OPTIONS, 'AMI';
72   } elsif ($ARGV[0] eq "-smart_proxies") {
73     print STDERR "$CMD: obsolete option $ARGV[0], "
74       ."please use -config instead\n";
75     push @CONFIGURATION_OPTIONS, 'SMART_PROXIES';
76   } elsif ($ARGV[0] eq "-static") {
77     print STDERR "$CMD: obsolete option $ARGV[0], "
78       ."please use -config instead\n";
79     push @CONFIGURATION_OPTIONS, 'STATIC';
80   } elsif ($ARGV[0] eq "-config") {
81     shift;
82     push @CONFIGURATION_OPTIONS, $ARGV[0];
83   } elsif ($ARGV[0] eq "-build_list") {
84     shift;
85     @BUILD_LIST = split (/,/, $ARGV[0]);
86   } elsif ($ARGV[0] eq "-dont_update") {
87     $dont_update = 1;
88   } elsif ($ARGV[0] eq "-copy_logs") {
89     shift;
90     $copy_logs = 1;
91     $LOG_DESTINATION = $ARGV[0];
92   } elsif ($ARGV[0] eq "-sandbox") {
93     shift;
94     $sandbox = $ARGV[0];
95   } elsif ($ARGV[0] eq "-sandbox_timeout") {
96     shift;
97     $sandbox_timeout = $ARGV[0];
98   } elsif ($ARGV[0] eq "-dont_run") {
99     $dont_run = 1;
100   } elsif ($ARGV[0] eq "-pre_realclean") {
101     $pre_realclean = 1;
102   } elsif ($ARGV[0] eq "-post_realclean") {
103     $post_realclean = 1;
104   } elsif ($ARGV[0] eq "-report_success") {
105     $report_success = 1;
106   } elsif ($ARGV[0] eq "-debug") {
107     $debug = 1;
108   } elsif ($ARGV[0] eq "-sendreport") {
109     $sendreport = 1;
110   } elsif ($ARGV[0] eq "-notao") {
111     $dont_build_tao = 1;
112   } elsif ($ARGV[0] eq "-make_type") {
113     shift;
114     $makefile_suffix = $ARGV[0];
115   } else {
116     print "Ignoring option $ARGV[0]\n";
117   }
118   shift;
121 # Extract configuration information from command line.
122   # TODO: Some validation and checking should be done here.
123 $CHECKOUT = $ARGS[0];
124 $BUILD    = $ARGS[1];
125 $LOGDIR   = $ARGS[2];
126 $ADMIN    = $ARGS[3];
127 $MAIL     = "mail";
128 if ($#ARGS >= 4) {
129   $MAIL     = $ARGS[4];
131 $LOG_URL  = "http://ace.cs.wustl.edu/~bugzilla/auto_compile_logs/";
132 if ($#ARGS >= 5) {
133   $LOG_URL = $ARGS[5];
135 # This is the module we will checkout unless a different one is on the
136 # command line.
137 $MODULE='ACE_wrappers';
138 if ($#ARGS >= 6) {
139   $MODULE = $ARGS[6];
142 $ENV{'ACE_ROOT'} = $CHECKOUT . '/' . $MODULE . '/build/' . $BUILD;
143 $ENV{'TAO_ROOT'} = $CHECKOUT . '/' . $MODULE . '/build/' . $BUILD . '/TAO';
145 # We obtain our revision to report errors.
146 $REVISION='$Revision$ ';
148 # When an error is found we try to die gracefully and send some email
149 # to ADMIN.
151 $disable_file = $LOGDIR . '/.disable';
152 $histfile = $LOGDIR . '/history';
153 $LOGBASE = POSIX::strftime("%Y_%m_%d_%H_%M", localtime);
154 $LOGFILE = $LOGDIR . '/' . $LOGBASE . '.txt';
155 $HOST = `hostname`;
156 chop $HOST;
157 $LOG_NAME =  $HOST . '_' . $BUILD . '/' . $LOGBASE . '.txt';
158 $STATUS = "OK";
160 if ($debug) {
161   print "CHECKOUT = $CHECKOUT\n";
162   print "BUILD = $BUILD\n";
163   print "LOGDIR = $LOGDIR\n";
164   print "ADMIN = $ADMIN\n";
165   print "MAIL = $MAIL\n";
166   print "ACE_ROOT = $ENV{ACE_ROOT}\n";
167   print "TAO_ROOT = $ENV{TAO_ROOT}\n";
168   print "CONFIGURATION_OPTIONS = ", @CONFIGURATION_OPTIONS, "\n";
171 push @INC, $CHECKOUT . '/' . $MODULE . '/bin';
173 require PerlACE::ConfigList;
175 $config_list = new PerlACE::ConfigList;
177 $config_list->my_config_list (@CONFIGURATION_OPTIONS);
179 if ($#BUILD_LIST == -1) {
180   if ($dont_build_tao) {
181     @BUILD_LIST=('ace', 'netsvcs', 'tests');
182   }
183   else {
184     @BUILD_LIST=('.', 'TAO');
185   }
188 sub mydie {
189   my $DEST_DIR = $LOG_DESTINATION.'/'.$HOST.'_'.$BUILD;
190   mkdir $DEST_DIR,0755 if (!-d $DEST_DIR);
191   if (open(STATUS, '>'.$DEST_DIR.'/status.txt')) {
192     print STATUS "SCOREBOARD_STATUS: Inactive\n";
193     close STATUS;
194   }
195   unlink $disable_file;
196   die $_ . "\n";
199 @RUN_LIST = ();
201 if ($debug) {
203   @BUILD_LIST = ('ace');
204   @RUN_LIST = ('TAO/tests/OctetSeq/run_test.pl');
205   $ADMIN = $ENV{'LOGNAME'};
207 } else {
208   $config_list->load ($CHECKOUT . '/' . $MODULE . '/' . 'build/' . $BUILD . '/bin/auto_run_tests.lst');
210   @RUN_LIST = $config_list->valid_entries ();
213 sub mail_logs {
214   open (MAIL, "|".$MAIL.' -s AUTO_COMPILE_LOG='.$LOG_NAME.' '.$LOG_DESTINATION)
215     || mydie "Cannot open mail pipe for: $LOG_NAME\n";
217   print MAIL 'This is the log for: ', "\n";
218   print MAIL $CMD, ' [', $REVISION, "] for $HOST/$BUILD\n";
220   print MAIL "\n================================================================\n";
222  if (open (THELOG, "$LOGFILE"))
223     {
224       while (<THELOG>) {
225         print MAIL $_;
226       }
227       close (THELOG);
228     }
229   close (MAIL); # Ignore errors....
232 sub copy_logs {
233   local $DEST_DIR = $LOG_DESTINATION.'/'.$HOST.'_'.$BUILD;
234   mkdir $DEST_DIR,0755 if (!-d $DEST_DIR);
236   copy($LOGFILE, $DEST_DIR.'/'.$LOGBASE.'.txt');
238   local $MAKE_PRETTY="$CHECKOUT/$MODULE/bin/make_pretty.pl";
239   system ("perl $MAKE_PRETTY -b -i $LOGFILE >$DEST_DIR/$LOGBASE"."_brief.html");
240   system ("perl $MAKE_PRETTY    -i $LOGFILE >$DEST_DIR/$LOGBASE".".html");
242   chmod 0644, $DEST_DIR.'/'.$LOGBASE.'.txt'
243             , $DEST_DIR.'/'.$LOGBASE.'_brief.html'
244             , $DEST_DIR.'/'.$LOGBASE.'.html' ;
247 sub report_errors {
249   # First clear the lock, so the next execution works...
250   unlink $disable_file; # Ignore errors!
252   if ($sendreport) {
253         # Now send a summary of the errors to the ADMIN account, if there are any.
255         if ($#_ >= 0) {
256           local $to = $ADMIN;
258           open (MAIL, "|".$MAIL.' -s "[AUTO_COMPILE] '.$HOST.' '.$BUILD.'" '.$to)
259             || mydie "Cannot open mail pipe for: $_\n";
261           print MAIL 'The following message is brought to you by: ', "\n";
262           print MAIL $CMD, ' [', $REVISION, "] for $BUILD on $HOST\n\n";
264           print MAIL "\nPlease check the following log for more info:\n\n";
265           print MAIL $LOG_URL, '?', $HOST, '_', $BUILD, "\n\n";
267           local $m;
268           foreach $m (@_) {
269             print MAIL $m, "\n";
270           }
271           close (MAIL); # Ignore errors....
272         }
273   }
275   # Now send the complete log to bugzilla...
276   if ($copy_logs) {
277     copy_logs ();
278   } else {
279     mail_logs ();
280   }
283 ### MAIN FUNCTION
285 if (-f $disable_file) {
286   print 'The following message is brought to you by: ', "\n";
287   print $CMD, ' [', $REVISION, "] for $BUILD on $CHECKOUT\n";
289   print "DISABLED\n";
291   exit 0;
294 open (DISABLE, '>' . $disable_file)
295     || die "cannot open disable file <$disable_file>\n";
296 print DISABLE "auto_compile <$date> is running\n";
297 close (DISABLE)
298     || die "cannot close disable file";
300 open(HIST, '>>' . $histfile)
301     # Do not use 'mydie' to report the problem, it tries to remove the
302     # disable file
303     || mydie "cannot open history file \"$histfile\"\n";
305 $date = localtime;
307 print HIST $CMD, ': running at ', $date, ' ';
309 open(LOG, '>' . $LOGFILE)
310     || mydie "cannot open log file";
312 LOG->autoflush ();
314 # The following lines are useful when debugging the script or wrapper.
315 # print LOG $CHECKOUT, " ", $BUILD, " ", $LOGDIR, " ", $ADMIN, "\n";
316 #while (($key,$value) = each %ENV) {
317 #  print LOG $key, " = ", $value, "\n";
320 print LOG "#################### CVS\n";
321 my $DEST_DIR = $LOG_DESTINATION.'/'.$HOST.'_'.$BUILD;
322 mkdir $DEST_DIR,0755 if !-d $DEST_DIR;
323 if (open(STATUS, '>'.$DEST_DIR.'/status.txt')) {
324   print STATUS "SCOREBOARD_STATUS: CVS\n";
325   close STATUS;
328 chdir($CHECKOUT)
329     || mydie "Cannot chdir to $CHECKOUT";
331 if ($dont_update == 0) {
332   $date = localtime;
333   print LOG "$CMD: starting checkout at ", $date, "\n";
334   open(CVS, "cvs -q checkout -P $MODULE 2>&1 |")
335     || mydie "cannot start checkout of $MODULE";
337   $conflicts = 0;
338   while (<CVS>) {
339     if (m/^C /) {
340       ($unused, $entry) = split('/');
341       if (($entry ne "ChangeLog\n") && ($entry ne "THANKS\n")) {
342         $conflicts = 1;
343       }
344     }
345     print LOG $_;
346   }
347   close(CVS);
348 #    || mydie "error while checking out $MODULE";
349   $date = localtime;
350   print LOG "$CMD: checkout finished at ", $date, "\n";
352   if ($conflicts != 0) {
353     mydie "conflicts on checkout";
354   }
357 chdir($MODULE)
358     || mydie "cannot chdir to $MODULE";
360 $date = localtime;
361 print LOG "$CMD: starting clone at ", $date, "\n";
362 open(CLONE, "perl bin/create_ace_build -a -v $BUILD 2>&1 |")
363     || mydie "cannot clone directory";
364 while(<CLONE>) {
365     print LOG $_;
367 close(CLONE)
368     || mydie "error while cloning ACE_ROOT";
369 $date = localtime;
370 print LOG "$CMD: clone finished at ", $date, "\n";
372 chdir('build/' . $BUILD)
373     || mydie "cannot chdir to $BUILD";
375 @failures = ();
377 if ($makefile_suffix ne "") {
378   $MAKEFLAGS = "-f Makefile.$makefile_suffix";
381 print LOG "#################### Compiler\n";
382 if (open(STATUS, '>'.$DEST_DIR.'/status.txt')) {
383   print STATUS "SCOREBOARD_STATUS: Compile\n";
384   close STATUS;
387 if ($pre_realclean) {
388   foreach $i (reverse(@BUILD_LIST)) {
389     $date = localtime;
390     print LOG "$CMD: =============================================\n";
391     print LOG "$CMD: make realclean in $i started at ", $date, "\n";
392     open(MAKE, "make -k $MAKEFLAGS -C $i realclean 2>&1 |")
393       || mydie "cannot start make in $i";
395     while (<MAKE>) {
396       # Ignore errors....
397     }
398     if (close(MAKE) == 0) {
399         push @failures, "errors while cleaning $i";
400     }
401     $date = localtime;
402     print LOG "$CMD: make realclean in $i finished at ", $date, "\n";
403     print LOG "$CMD: =============================================\n\n";
404   }
407 $MAKEFLAGS .= "";
408 foreach $i (@BUILD_LIST) {
409     $date = localtime;
410     print LOG "$CMD: =============================================\n";
411     print LOG "$CMD: make for $i started at ", $date, "\n";
412     open(MAKE, "make -k $MAKEFLAGS -C $i 2>&1 |")
413         || mydie "cannot start make for $i";
415     local $current_dir = $i;
416     local $last_error = "";
417     local $this_error = 0;
418     local $this_warning = 0;
419     while (<MAKE>) {
420         chop;
421         $this_error = $this_warning = 0;
422         if ($^O eq 'hpux'
423             && m/^Warning:[ \t]+[0-9]+ future errors were detected/) {
424             next;
425         }
426         print LOG $_, "\n";
428         if (m/^make(\[[0-9]+\])?: Entering directory /) {
429             s/^make(\[[0-9]+\])?: Entering directory //;
430             s%^$ENV{'ACE_ROOT'}/%%;
431             $current_dir = $_;
432         }
433         if (m/error:/i || m/error /i
434             || m/^make(\[[0-9]+\])?: \*\*\*/) {
435             $this_error = 1;
436         }
437         if ($^O eq 'aix'
438             && m/\d+-\d+ \([SI]\)/) {
439             $this_error = 1;
440         }
441         if ($this_error) {
442             if ($last_error ne $current_dir
443                 || STATUS eq "COMPILATION WARNING") {
444               $STATUS = "COMPILATION ERROR";
445               push @failures, "Error while compiling in $current_dir \n";
446               $last_error = $current_dir;
447             }
448         }
449         if (m/warning:/i
450             || m/warning /i
451             || m/Info: /i) {
452             $this_warning = 1;
453             if ($^O eq 'aix'
454                 && m/^ld: \d+-\d+ WARNING: Duplicate symbol: .*ACE.*/) {
455                 $this_warning = 0;
456             }
457         }
458         if ($^O eq 'aix'
459             && m/\d+-\d+ \(W\)/) {
460             $this_warning = 1;
461         }
462         if ($this_warning) {
463           if ($last_error ne $current_dir) {
464             if ($STATUS eq "OK") {
465               $STATUS = "COMPILATION WARNING";
466             }
467             push @failures, "Warning while compiling in $current_dir\n";
468             $last_error = $current_dir;
469           }
470         }
471     }
472     if (close(MAKE) == 0) {
473         push @failures, "errors while running make in $i";
474     }
475     $date = localtime;
476     print LOG "$CMD: make for $i finished at ", $date, "\n";
477     print LOG "$CMD: =============================================\n\n";
480 print LOG "#################### Tests\n";
481 if (open(STATUS, '>'.$DEST_DIR.'/status.txt')) {
482   print STATUS "SCOREBOARD_STATUS: Tests\n";
483   close STATUS;
486 if ($dont_run == 0) {
487   my $config_params;
488   if ($#CONFIGURATION_OPTIONS != -1) {
489     $config_params = ' -Config ';
490   }
491   $config_params .= join ' -Config ', @CONFIGURATION_OPTIONS;
493   foreach my $i (@RUN_LIST) {
495     local $directory = '.';
496     local $program = $i;
498     if ($i =~ /(.*)\/([^\/]*)$/) {
499         $directory = $1;
500         $program = $2;
501     }
503     $date = localtime;
504     print LOG "\n\n$CMD: ================  $date ================\n";
505     print LOG "auto_run_tests: $i\n";
506     local $subdir =
507         $CHECKOUT .'/'. $MODULE .'/build/'. $BUILD .'/'. $directory;
508     chdir ($subdir)
509         || mydie "cannot chdir to $subdir";
511     $run_error = 0;
512     my $prefix = '';
513     if ($sandbox ne "") {
514       $prefix = $sandbox.' '.$sandbox_timeout.' ';
515     }
516     if (open(RUN, $prefix."perl $program $config_params 2>&1 |") == 0) {
517         push @failures, "cannot run $program in $directory";
518         next;
519     }
520     while (<RUN>) {
521         print LOG $_;
522         if (m/Error/
523             || m/ERROR/
524             || m/FAILED/
525             || m/EXCEPTION/
526             || m/pure virtual /i) {
527           if ($STATUS eq "OK") {
528             $STATUS = "RUNTIME ERROR";
529           }
530           $run_error = 1;
531         }
532     }
533     if (close(RUN) == 0) {
534       if ($STATUS eq "OK") {
535         $STATUS = "RUNTIME ERROR";
536       }
537       print LOG "ERROR, non-zero status returned by test script\n";
538       push @failures, "Error when closing pipe for $program in $directory";
539       next;
540     }
541     $date = localtime;
542     print LOG "$CMD: $program finished ", $date, "\n";
544     if ($run_error != 0) {
545       push @failures,
546       "errors detected while running $program in $directory";
547     }
548   }
551 if ($post_realclean) {
552   foreach $i (reverse(@BUILD_LIST)) {
553     $date = localtime;
554     print LOG "$CMD: =============================================\n";
555     print LOG "$CMD: make realclean in $i started at ", $date, "\n";
556     open(MAKE, "make -k $MAKEFLAGS -C $i realclean 2>&1 |");
558     while (<MAKE>) {
559       # Ignore errors....
560     }
561     if (close(MAKE) == 0) {
562         push @failures, "errors while cleaning $i";
563     }
564     $date = localtime;
565     print LOG "$CMD: make realclean in $i finished at ", $date, "\n";
566     print LOG "$CMD: =============================================\n\n";
567   }
570 print LOG "#################### Config\n";
572 chdir($CHECKOUT . "/" . $MODULE . "/build/" . $BUILD)
573   || mydie "Cannot chdir to $CHECKOUT/$MODULE/build/$BUILD";
575 open (CONFIG, "perl bin/nightlybuilds/print_config.pl $CHECKOUT/$MODULE/build/$BUILD 2>&1 |")
576   || mydie "Cannot run print_config.pl script";
577 while (<CONFIG>) {
578   print LOG $_;
580 close (CONFIG)
581   || mydie "Error while running print_config.pl script";
583 report_errors @failures;
585 print LOG "#################### End\n";
586 if (open(STATUS, '>'.$DEST_DIR.'/status.txt')) {
587   print STATUS "SCOREBOARD_STATUS: Inactive\n";
588   close STATUS;
591 close(LOG)
592     || mydie "cannot close LOGFILE";
594 print HIST "$STATUS\n";
595 close(HIST)
596     || mydie "cannot close history file";
598 unlink $disable_file
599     || die "cannot unlink disable file";
601 if ($report_success && $STATUS eq "OK") {
602   report_errors "Congratulations: No errors or warnings detected\n";
605 exit 0;