ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/BuildSetup.pm
Revision: 1.1.2.7.2.2.2.1.2.5
Committed: Thu Nov 2 17:42:26 2000 UTC (24 years, 6 months ago) by williamc
Content type: text/plain
Branch: V0_16branch
Changes since 1.1.2.7.2.2.2.1.2.4: +1 -1 lines
Log Message:
call correct checker

File Contents

# User Rev Content
1 williamc 1.1.2.1 #
2     #
3     # Interface
4     # ---------
5 williamc 1.1.2.7.2.2.2.1.2.4 # new(ConfigArea) : A new BuildSetup
6     # BuildDir(directory,targets) : prepare the ground for a build and build
7 williamc 1.1.2.1 # getclass(directory) : return (Class, ClassDir, BuildFileobject)
8     # associated with directory
9 williamc 1.1.2.7.2.2.2.1.2.4 # setup(dir)
10 williamc 1.1.2.1
11     package BuildSystem::BuildSetup;
12     require 5.004;
13     use Utilities::Verbose;
14     use Utilities::SCRAMUtils;
15     use BuildSystem::BuildFile;
16 williamc 1.1.2.7.2.2.2.1.2.4 use BuildSystem::BuildRecorder;
17     use BuildSystem::DateStampRecord;
18     use BuildSystem::Block;
19 williamc 1.1.2.1 use Utilities::AddDir;
20     @ISA=qw(Utilities::Verbose);
21    
22     sub new {
23     my $class=shift;
24     my $self={};
25     bless $self,$class;
26 williamc 1.1.2.7.2.2.2.1.2.4 $self->{area}=shift;
27     $self->{toolbox}=$self->{area}->toolbox();
28     $self->{projconfigdir}=$self->{area}->configurationdir();
29     $self->{localtop}=$self->{area}->location();
30     $self->{releasearea}=$self->{area}->linkarea();
31     if ( ! defined $self->{releasearea} ) {
32     $self->{releasearea}=$self->{area};
33     }
34     $self->{releasetop}=$self->{releasearea}->location();
35     $self->{buildfilename}="BuildFile";
36     $self->verbosity(1);
37     $self->_configurationsetup();
38     # -- clean up from any previous builds
39     $self->{BuildDBfile}=$self->{localtop}."/".
40     $self->{workdir}."/BuildReporterFile";
41     if ( -f $self->{BuildDBfile} ) {
42     unlink $self->{BuildDBfile};
43     }
44 williamc 1.1.2.1 return $self;
45     }
46    
47     sub _generateexternals {
48     my $self=shift;
49     my $outfile=shift;
50    
51 williamc 1.1.2.7.2.2.2.1.2.4 # -- specify these files for dependency information
52     my $depfile=$self->{projconfigdir}."/External_Dependencies";
53 williamc 1.1.2.3
54     # -- get list of dependent files
55 williamc 1.1.2.7.2.2.2.1.2.4 my $datadir=$self->{localtop}."/.SCRAM/".$ENV{SCRAM_ARCH};
56 williamc 1.1.2.3 $fdir=FileHandle->new();
57 williamc 1.1.2.7 opendir $fdir, $datadir;
58 williamc 1.1.2.3 my @depfiles=grep !/^\.\.?$/, readdir $fdir;
59     undef $fdir;
60     for (my $i=0; $i<=$#depfiles; $i++ ) {
61     $depfiles[$i]=$datadir."/".$depfiles[$i];
62     }
63    
64 williamc 1.1.2.1 # -- do we need to rebuild?
65 williamc 1.1.2.3 if ( SCRAMUtils::dated($outfile,@depfiles) ) {
66 williamc 1.1.2.1 print "Configuring Local Area\n";
67     # -- open output file
68     my $fout=FileHandle->new();
69     $fout->open(">".$outfile) or die "Unable to open $outfile for output".
70     $!."\n";
71    
72     # -- print out tool/ version info
73     my ($tool,$toolobj,$f,$val,$version);
74 williamc 1.1.2.7.2.1 foreach $tool ( $self->{toolbox}->tools() ) {
75     $version=$self->{toolbox}->defaultversion($tool);
76 williamc 1.1.2.2 # default versions
77 williamc 1.1.2.1 print $fout "ifdef $tool\n".$tool."_V_".$version."=true\nendif\n";
78 williamc 1.1.2.7.2.1 # -- set up the different version -- externals
79     foreach $version ( $self->{toolbox}->versions($tool) ) {
80     $toolobj=$self->{toolbox}->gettool($tool,$version);
81     @deps=$toolobj->getfeature("_externals");
82     foreach $d ( @deps ) {
83 williamc 1.1.2.6 $d=~tr[A-Z][a-z];
84 williamc 1.1.2.2 print $fout "ifdef ".$tool."_V_".$version."\n $d=true\nendif\n";
85 williamc 1.1.2.7.2.1 }
86     # -- tool info
87     print $fout "ifdef ".$tool."_V_".$version."\n";
88     foreach $f ( $toolobj->features() ) {
89 williamc 1.1.2.1 foreach $val ( $toolobj->getfeature($f) ) {
90     print $fout "\t".$f." += ".$val."\n";
91     }
92 williamc 1.1.2.7.2.1 }
93     print $fout "endif\n";
94 williamc 1.1.2.1 }
95     }
96 williamc 1.1.2.7.2.2.2.1.2.4 # -- some addittional processing of specific vars
97 williamc 1.1.2.1 print $fout 'INCLUDEPATH+=$(addprefix -I,$(INCLUDE))'."\n";
98     print $fout 'LDFLAGS+=$(addprefix -L,$(LIBDIR))'."\n";
99     print $fout 'CPPFLAGS+=$(addprefix -D,$(CPPDEFINES))'."\n";
100     print $fout 'lib+=$(extralib)'."\n";
101     print $fout 'LDLIBS+=$(addprefix -l,$(lib))'."\n";
102     print $fout 'LDLIBS+=$(addprefix -l,$(REQUIRES))'."\n";
103 williamc 1.1.2.7.2.2.2.1.2.3 print $fout 'LD_LIBRARY_PATH:=$(subst $(space),:,$(LD_LIBRARY_PATH))'."\n";
104 williamc 1.1.2.1
105     undef $fout;
106 williamc 1.1.2.7.2.2.2.1.2.4 $self->verbose("End Externals Configuration Setup");
107 williamc 1.1.2.1 }
108     }
109    
110 williamc 1.1.2.7.2.2.2.1.2.4 sub classsetup {
111     my $self=shift;
112     my $THISDIR=shift;
113    
114     my $classmakefile;
115    
116     my ($Class, $ClassDir, $bf)=$self->getclass2($THISDIR);
117     $self->verbose("Class = $Class : ClassDir = $ClassDir for directory ".
118     $THISDIR);
119    
120     # -- should we ignore?
121     if ( $bf->ignore() ) {
122     print "Nothing to be done - empty group\n";
123     exit;
124     }
125 williamc 1.1.2.1
126    
127 williamc 1.1.2.7.2.2.2.1.2.4 # -- Create a makefile from the class BuildFile
128     my $classbuildfile=$self->{localtop}."/".
129     $self->{projconfigdir}."/".$Class."_BuildFile";
130     if ( -f $classbuildfile ) {
131     $classmakefile=$self->{localtop}."/".$ENV{INTwork}.
132     "/".$Class."_makefile.mk";
133     if ( SCRAMUtils::dated($classmakefile, $classbuildfile) ) {
134     # -- generate the new makefile if out of date
135     $self->verbose("Generating $classmakefile from".
136     " $classbuildfile");
137     my $classbf=BuildSystem::BuildFile->new($self->{area},$self);
138     undef $ENV{LatestBuildFile}; # gets set by BuildFile
139     $classbf->GenerateMakefile($classbuildfile, $classmakefile);
140     undef $ENV{LatestBuildFile}; # gets set by BuildFile
141     }
142     }
143     else {
144     # -- No BuildFile - maybe its old style makefile
145     $classmakefile=$self->{localtop}."/".
146     $self->{projconfigdir}."/".$Class."_makefile.mk";
147     if ( ! -f $classmakefile ) {
148     $self->error("Unable to find matching ".$Class.
149     "_BuildFile or ".$Class."_makefile.mk");
150     }
151     }
152     # -- set LatestBuildFile
153     if ( $bf->buildfile() ne "" ) {
154     $ENV{LatestBuildFile}=$bf->makefile();
155     }
156     else {
157     $ENV{LatestBuildFile}=$self->{topbf}->makefile();
158     }
159 williamc 1.1.2.1
160 williamc 1.1.2.7.2.2.2.1.2.4 return ($Class,$ClassDir,$classmakefile);
161     }
162    
163     sub _configurationsetup {
164     my $self=shift;
165    
166     # -- set working directory
167     $self->{workdir}=$ENV{INTwork};
168     $self->{fullworkdir}=$self->{localtop}."/".$self->{workdir};
169    
170     # -- make working directory
171     chdir $self->{localtop};
172     AddDir::adddir($self->{workdir});
173    
174     # -- generate tool info
175     $self->_generateexternals($self->{fullworkdir}."/clientmakefile");
176    
177     # -- process project BuildFile
178     $self->_topbuildfile();
179     }
180    
181     sub BuildDir {
182     my $self=shift;
183     my $THISDIR=shift;
184     my @Targets=@_;
185     my $DefaultBuildFile="";
186    
187     # -- Setup Class specifics
188     ($Class,$ClassDir,$classmakefile)=$self->classsetup($THISDIR);
189     $ENV{classmakefile}=$classmakefile;
190     $ENV{Class}=$Class;
191     $ENV{ClassDir}=$ClassDir;
192     $DefaultBuildFile=$ENV{classmakefile};
193     $ENV{DefaultBuildFile}=$DefaultBuildFile;
194    
195     # -- Create working directory
196     my $workdir=$self->{workdir}."/".$ClassDir;
197     chdir $self->{localtop};
198     AddDir::adddir($workdir);
199     $ENV{workdir}=$workdir;
200     my $fullworkdir=$self->{localtop}."/".$ENV{workdir};
201     chdir $fullworkdir || die "Unable to enter working directory $!";
202    
203     # -- Set up some other useful variables for the Build
204     # set variables listing directories/files available
205     my $fh=FileHandle->new();
206     opendir $fh, "$self->{localtop}/$ClassDir";
207     my @allfiles= grep !/^\.\.?$/, readdir $fh;
208     undef $fh;
209     foreach $file ( @allfiles ) {
210     if ( -d "$self->{localtop}/$ClassDir/$file" ) {
211     $ENV{SCRAM_AVAILDIRS}=$ENV{SCRAM_AVAILDIRS}." ".$file;
212     }
213     else {
214     $ENV{SCRAM_AVAILFILES}=$ENV{SCRAM_AVAILFILES}." ".$file;
215     }
216     }
217     my $targetnumber=$#Targets;
218     $ENV{"MAKETARGETS"}="";
219     foreach $word ( @Targets ) {
220     if ( $word=~/.*=.*/ ) { # if we have an assignment it cant be a target
221     $targetnumber--;
222     }
223     else {
224     # set some variables for use in makefiles
225     $ENV{"MAKETARGET_".$word}=$word;
226     if ( $ENV{"MAKETARGETS"} ne "" ) {
227     $ENV{"MAKETARGETS"}=$ENV{"MAKETARGETS"}." ".$word;
228     }
229     else {
230     $ENV{"MAKETARGETS"}=$word;
231     }
232     }
233     }
234    
235     # -- If target not specified default to the class name target
236     if ( $targetnumber == -1 ) {
237     push @Targets,$Class;
238     }
239 williamc 1.1.2.1
240     $ENV{DefaultMakefile}="$ENV{TOOL_HOME}/basics.mk";
241    
242 williamc 1.1.2.7.2.2.2.1.2.4
243     $SCRAM_GROUPSDIR=$self->{localtop}."/".$self->{projconfigdir}."/groups.mk";
244 williamc 1.1.2.1 if ( -f $SCRAM_GROUPSDIR ) {
245     $ENV{SCRAM_GROUPSDIR}=$SCRAM_GROUPSDIR;
246     }
247    
248 williamc 1.1.2.7.2.2.2.1.2.4
249     #
250     # Keep a track of what we have built this run
251     #
252     if ( ! defined $self->{BuildDB} ) {
253     my $file=$self->{BuildDBfile};
254     $self->{BuildDB}=BuildSystem::BuildRecorder->new($file);
255     }
256     my $rv=0;
257 williamc 1.1.2.7.2.2.2.1.2.5 if ( ! $self->{BuildDB}->checked($ClassDir) ) {
258 williamc 1.1.2.7.2.2.2.1.2.4 $self->{BuildDB}->checked($ClassDir,1); # Mark it as taken care of
259    
260     # Do a datestamp check so that make will build files that have changed
261     # rather than just those which are older than their dependencies
262     $self->_checkdatestampindir($ClassDir);
263    
264     # -- The main build here
265     $rv=system("gmake","--no-print-directory","-r","-k","-f",
266     "$ENV{DefaultMakefile}","-I$ENV{TOOL_HOME}", @Targets);
267     }
268 williamc 1.1.2.1 return $rv/256; # return the exit status of gmake
269 williamc 1.1.2.7.2.2.2.1.2.4
270 williamc 1.1.2.1 }
271    
272 williamc 1.1.2.7.2.2.2.1.2.4 # TODO - work in progress - replacement for BuildDir that can handle <Build> OK
273     sub BuildIt {
274     my $self=shift;
275     my $dir=shift;
276     my @Targets=@_;
277    
278    
279     # -- get the top building block
280     my $topblock=$self->_gettopblock();
281     $ENV{LatestBuildFile}=$self->_gettopbf()->makefile();
282    
283     # -- is there a class block associated with the directory?
284     my ($Class,$ClassDir)=getclass($dir);
285     $self->verbose("Using Class $Class");
286     my $classblock=$self->_getclassblock($Class,$topblock);
287    
288     # -- If target not specified default to the class name target
289     if ( $targetnumber == -1 ) {
290     push @Targets,$Class;
291     }
292    
293     # -- Create working directory
294     my $workdir=$self->{workdir}."/".$ClassDir;
295     chdir $self->{localtop};
296     AddDir::adddir($workdir);
297     $ENV{workdir}=$workdir;
298     my $fullworkdir=$self->{localtop}."/".$ENV{workdir};
299     chdir $fullworkdir || die "Unable to enter working directory $!";
300     $self->verbose("Working area setup");
301    
302     # -- Search for Blocks up to tree root
303     my @dirblocks=();
304     my @dirs=split /\//, $dir;
305     my $fulldir="";
306     my $currentblock=$classblock;
307     foreach $dire ( @dirs ) {
308     ($fulldir eq "")?$fulldir=$dire
309     :$fulldir=$fulldir."/".$dire;
310     $self->verbose("Searching $fulldir for Block");
311     my $block=$self->_getdirblock($fulldir,$currentblock);
312     if ( defined $block ) {
313     $currentblock=$block;
314     }
315     $ENV{LatestBuildFile}=$self->gettopbf()->makefile();
316     }
317    
318     # -- Create a makefile to include both BuildFile and
319     # class makefile
320    
321     my $fh=FileHandle->new();
322     my $mfile=$fullworkdir."/BuildFile.mk";
323     $self->verbose("Building makefile $mfile");
324     $fh->open(">".$mfile);
325     $fh->autoflush(1);
326     if ( -e $ENV{LatestBuildFile} ) {
327     print $fh "include $ENV{LatestBuildFile}\n";
328     }
329    
330     # -- Parse the local BuildFile
331     my $dbf=$self->_getdirbf($dir);
332     if ( defined $dbf ) {
333     $dbf->Parsetofh($fh,$currentblock);
334     }
335    
336     # -- Parse the class BuildFile
337     my $cbf=$self->_getclassbf($Class);
338     if ( defined $cbf ) {
339     $cbf->Parsetofh($fh,$currentblock);
340     }
341     $fh->close();
342     $ENV{DefaultMakefile}=$mfile;
343    
344     # -- Hack around make by checking datestamps in local working and
345     # in _class_ working directories
346     $self->_checkdatestampindir($ClassDir);
347     opendir $fh, $ClassDir;
348     my @dfiles= grep { -d $_ } readdir $fh;
349     undef $fh;
350     foreach $dir ( @dfiles ) {
351     if ( $dir=~/^_class_/ ) {
352     $self->_checkdatestampindir($ClassDir."/".$dir);
353     }
354     }
355    
356     # -- Call gmake to do the actual build
357     $rv=system("gmake","--no-print-directory","-r","-k","-f",
358     "$mfile","-I$ENV{TOOL_HOME}", @Targets);
359     return $rv/256; # return the exit status of gmake
360     }
361    
362     #
363     # -- Block generation Routines
364     #
365    
366     sub _getclassblock {
367     my $self=shift;
368     my $key=shift;
369    
370     if ( ! defined $self->{classblocks}{$key} ) {
371     $self->verbose("Initialising Class Block $key");
372     $self->{classblocks}{$key}=BuildSystem::Block->new();
373     # -- get class buildfile
374     my $bf=$self->_getclassbf($key);
375     if ( @_ ) {
376     $self->{classblocks}{$key}->parent(shift);
377     }
378     $bf->BlockParse($self->{classblocks}{$key});
379     $self->verbose("Initialisation Complete for Class Block $key");
380     }
381     return $self->{classblocks}{$key};
382    
383     }
384    
385     sub _gettopblock {
386     my $self=shift;
387    
388     if ( ! defined $self->{topblocks} ) {
389     $self->verbose("Initialising Top Block");
390     $self->{topblock}=BuildSystem::Block->new();
391     # -- get class buildfile
392     my $bf=$self->_gettopbf();
393     if ( @_ ) {
394     $self->{topblock}->parent(shift);
395     }
396     $bf->BlockParse($self->{topblock});
397     $self->verbose("Initialisation Complete for Top Block");
398     }
399     return $self->{topblock};
400     }
401    
402     sub _getdirblock {
403     my $self=shift;
404     my $dir=shift;
405     my $block=shift;
406    
407     if ( defined $dir || $dir ne "" ) {
408     if ( ! defined $self->{blocks}{$dir} ) {
409     # -- get a buildfile and do a block parse
410     $self->{blocks}{$dir}=BuildSystem::Block->new();
411     my $bf=$self->_getbuildfile($dir);
412     $self->{blocks}{$dir}->parent($block);
413     $bf->blockparse($self->{blocks}{$dir});
414     }
415     return $self->{blocks}{$dir};
416     }
417     return undef;
418     }
419    
420     #
421     # -- BuildFile generation routines
422     #
423    
424     sub _getclassbf {
425     my $self=shift;
426     my $class=shift;
427    
428     if ( ! defined $self->{classbf}{$class} ) {
429     $self->verbose("Initialising Class BuildFile $class");
430     # -- determine BuildFile or makefile
431     my $fname=$self->{localtop}."/".$self->{projconfigdir}.
432     "/".$class."_";
433     if ( -f $fname.$self->{buildfilename} ) {
434     $fname=$fname.$self->{buildfilename};
435     }
436     elsif ( -f $fname."makefile.mk" ) {
437     $fname=$fname."makefile.mk";
438     }
439     else {
440     $self->error("$fname".$self->{buildfilename}." does not exist in ".
441     $self->{projconfigdir});
442     }
443    
444     # -- create a BuildFile object
445     $self->{classbf}{$class}=BuildSystem::BuildFile->new($self->{area},$self);
446     $self->{classbf}{$class}->buildfile($fname);
447     $self->verbose("Finished Initialising Class BuildFile $class");
448     }
449     return $self->{classbf}{$class};
450     }
451    
452     sub _gettopbf {
453     my $self=shift;
454    
455     if ( ! defined $self->{topbf} ) {
456     $self->{topbf}=BuildSystem::BuildFile->new($self->{area},$self);
457     $self->{topbf}->buildfile($self->{localtop}."/".
458     $self->{projconfigdir}."/".$self->{buildfilename});
459     }
460     return $self->{topbf};
461     }
462     #
463     # Returns undef if BF does not exist at this dir level
464     #
465     sub _getdirbf {
466     my $self=shift;
467     my $dir=shift;
468    
469     if ( ! exists $self->{dirbf}{$dir} ) {
470     $self->verbose("initialising dir BuildFile $dir");
471     # -- determine if local or releasetop
472     my $fname=$self->{path}."/".$self->{buildfilename};
473     if ( -f $self->{localtop}."/".$fname ) {
474     $fname=$self->{localtop}."/".$fname;
475     }
476     elsif ( -f $self->{releasetop}."/".$fname ) {
477     $fname=$self->{releasetop}."/".$fname;
478     }
479     else {
480     $self->{dirbf}{$dir}=undef;
481     $self->verbose("initialisation complete for dir BuildFile $dir");
482     return $self->{dirbf}{$dir};
483     }
484    
485     # -- construct the bf object
486     $self->{dirbf}{$dir}=BuildSystem::BuildFile->new($self->{area},$self);
487     $self->{dirbf}{$dir}->buildfile($fname);
488    
489     $self->verbose("initialisation complete for dir BuildFile $dir");
490     }
491     return $self->{dirbf}{$dir};
492     }
493    
494     sub getclass2 {
495 williamc 1.1.2.1 my $self=shift;
496     my $dirname = shift;
497     my $Class="DEFAULT";
498     my $ClassDir="";
499    
500 williamc 1.1.2.7.2.2.2.1.2.4 #return if $dirname eq "";
501     my @DIRA=split /\//, $dirname;
502 williamc 1.1.2.1
503 williamc 1.1.2.7.2.2.2.1.2.4 my $thispath=".";
504     # -- construct all class buildfiles in the path
505 williamc 1.1.2.1 for ( $i=0; $i<=$#DIRA; $i++ ) {
506 williamc 1.1.2.7.2.2.2.1.2.4 #$thispath=(($thispath eq "")?$DIRA[$i]:$thispath."/".$DIRA[$i]);
507 williamc 1.1.2.1 $thispath=$thispath."/".$DIRA[$i];
508 williamc 1.1.2.7.2.2.2.1.2.4 if ( ! exists $self->{pathbf}{$thispath} ) {
509     $self->verbose("Initialising BuildFile in $thispath");
510     $self->{pathbf}{$thispath}=$self->_startbuildfile($thispath);
511     }
512     # -- check class overriden by BuildFile
513     if ( defined $self->{pathbf}{$thispath}->classname() ) {
514     $Class=$self->{pathbf}{$thispath}->classname();
515 williamc 1.1.2.1 $ClassDir=$thispath;
516     }
517 williamc 1.1.2.7.2.2.2.1.2.4 else {
518     # -- sort it out from classpath directives
519     foreach $BlockClassA ( @{$self->{LoBCA}} ) {
520     next if ( $#{$BlockClassA} < $i );
521     $elem=${$BlockClassA}[$i];
522     if ( $elem=~/^$DIRA[$i]\+/ ) {
523     $elem=~s/^$DIRA[$i]//;
524     }
525     #print $elem." ".$DIRA[$i]."\n";
526     if ( $elem=~/^\+/ ) {
527     ($Class=$elem)=~s/^\+//;
528 williamc 1.1.2.1 $ClassDir=$thispath;
529 williamc 1.1.2.7.2.2.2.1.2.4 }
530     #}
531     }
532     }
533     }
534     # -- default case
535     if ( $ClassDir eq "" ) {
536     if ( ! defined $self->{pathbf}{'.'}) {
537     $self->{pathbf}{'.'}=$self->_startbuildfile(".");
538     $self->verbose("DEFAULT class initialised : ".$self->{pathbf}{'.'});
539     }
540     $ClassDir=".";
541     }
542    
543     # -- returns
544     ($ClassDir_c=$ClassDir)=~s/^\.\///;
545     return ( $Class, $ClassDir_c, $self->{pathbf}{$ClassDir});
546     }
547    
548     sub getclass {
549     my $self=shift;
550     my $dirname = shift;
551    
552     my $Class="DEFAULT";
553     my $ClassDir=".";
554    
555     # return if $dirname eq "";
556     my @DIRA=split /\//, $dirname;
557    
558     my $thispath="";
559     for ( $i=0; $i<=$#DIRA; $i++ ) {
560     $thispath=(($thispath eq "")?$DIRA[$i]:$thispath."/".$DIRA[$i]);
561    
562     # -- sort it out from classpath directives
563     foreach $BlockClassA ( @{$self->{LoBCA}} ) {
564     next if ( $#{$BlockClassA} < $i );
565     $elem=${$BlockClassA}[$i];
566     if ( $elem=~/^$DIRA[$i]\+/ ) {
567     $elem=~s/^$DIRA[$i]//;
568     }
569     #print $elem." ".$DIRA[$i]."\n";
570     if ( $elem=~/^\+/ ) {
571     ($Class=$elem)=~s/^\+//;
572     $ClassDir=$thispath;
573     }
574     }
575 williamc 1.1.2.1 }
576 williamc 1.1.2.7.2.2.2.1.2.4 return ( $Class, $ClassDir );
577     }
578    
579     #
580     # Check to see if the buildfile is local or in the release area and
581     # parse appropriately
582     #
583     sub _startbuildfile {
584     my $self=shift;
585     my $classdir=shift;
586    
587     my $bf=BuildSystem::BuildFile->new($self->{area},$self);
588     my $thisfile="$classdir/$self->{buildfilename}";
589    
590     if ( -e $self->{localtop}."/".$thisfile ) {
591     $bf->buildfile($self->{localtop}."/".$thisfile);
592     $bf->ParseBuildFile($self->{localtop}, $classdir,
593     $self->{buildfilename});
594     }
595     elsif ( -e $self->{releasetop}."/".$thisfile ) {
596     $bf->buildfile($self->{releasetop}."/".$thisfile);
597     $bf->ParseBuildFile($self->{releasetop}, $classdir,
598     $self->{buildfilename});
599     }
600     return $bf;
601     }
602    
603     sub _topbuildfile {
604     my $self=shift;
605    
606     $self->verbose("Generating Top Level BuildFile");
607     # -- Analyse project buildfile if it exists
608    
609     my $topbf=$self->_gettopbf();
610    
611     # -- generate top level makefile
612     undef $ENV{LatestBuildFile};
613     $topbf->ParseBuildFile($self->{localtop},
614     $self->{projconfigdir},$self->{buildfilename});
615    
616     # -- Extract BuildStructure Information
617     my @ClassPaths=split /:/, $self->{topbf}->BlockClassPath();
618     foreach $BClassPath ( @ClassPaths ) {
619     next if ( $BClassPath eq "");
620     push @{$self->{LoBCA}}, [ split /\//, $BClassPath ];
621 williamc 1.1.2.1 }
622 williamc 1.1.2.7.2.2.2.1.2.4 $self->verbose("End top buildfile generation");
623     }
624    
625     sub _checkdatestampindir {
626     my $self=shift;
627     my $dir=shift;
628    
629     # -- get all local .ds files
630     my $fh=FileHandle->new();
631     my $ldir=$self->{localtop}."/".$self->{workdir}."/".$dir;
632     opendir $fh, $ldir;
633     my @dsfiles= grep /^.*\.ds$/, readdir $fh;
634     $fh->close();
635    
636     # -- copy across ds files from releasetop if not existing locally
637     if ( $#dsfiles < 0 ) {
638     # -- get all releasetop .ds files
639     my $rdir=$self->{releasetop}."/".$self->{workdir}."/".$dir;
640     opendir $fh, $rdir;
641     my @releasedsfiles= grep /^.*\.ds$/, readdir $fh;
642     foreach $file ( @releasedsfiles ) {
643     use File::Copy;
644     $self->verbose("Copying $file from $rdir to $ldir");
645     copy($rdir."/".$file,$ldir."/".$file);
646     }
647     $fh->close();
648     @dsfiles=@releasedsfiles;
649     }
650    
651     # -- process ds files
652     my $file;
653     foreach $datafile ( @dsfiles ) {
654     $self->verbose("Processing $ldir/$datafile\n");
655     my $ds=BuildSystem::DateStampRecord->new($ldir."/".$datafile);
656     $ds->verbosity($self->verbosity());
657     my $date;
658     my $needsupdate;
659     my $productfile=$ds->product();
660     my (%files,%moddate);
661    
662     # now get dates in our dependency list
663     my @datedfiles=$ds->dated();
664     if ( $#datedfiles >= 0 ) {
665    
666     $needsupdate=1;
667     $date=$datedfiles[0][1]-1;
668     }
669     else {
670     # -- extra checks for local replacement of files
671     foreach $file ( $ds->contents() ) {
672     # -- only check files
673     if ( -f $file ) {
674     $files{$file}=$ds->filedate($file);
675     # -- check to see if we have a new local copy
676     if ( ($file=~/\Q$self->{releasetop}\E/) &&
677     ($self->{releasetop} ne $self->{localtop}) ) {
678     ($tempfile=$file)=~s/\Q$self->{releasetop}\E/$self->{localtop}/;
679     if ( -f $tempfile ) {
680     $files{$tempfile}=$files{$file};
681     $file=$tempfile;
682     }
683     }
684     $moddate{$file}=(stat($file))[9];
685     if ( $moddate{$file} != $files{$file} ) {
686     $self->verbose($file." changed");
687     $date=$moddate{$file}-1;
688     $needsupdate=1;
689     }
690     }
691     }
692     }
693     # time stamp the product file to be older than the dependencies
694     if ( $needsupdate == 1 ) { # touch file into the past
695     my $newproductfile;
696     if ( $productfile!~/\Q$self->{localtop}\E/ ) {
697     if ( $productfile=~/\Q$self->{releasetop}\E/ ) {
698     ($newproductfile=$productfile)=~
699     s/\Q$self->{releasetop}\E/$self->{localtop}/;
700     $self->verbose("Copying $productfile to $newproductfile");
701     copy($productfile,$newproductfile);
702     }
703     else { # assume no path to worry about
704     $newproductfile=$self->{localtop}."/".$ENV{workdir}.
705     "/".$productfile;
706     # -- make a local copy of the product file if not already here
707     my $oldproductfile=$self->{releasetop}."/".$ENV{workdir}.
708     "/".$productfile;
709     if ( ! -f $newproductfile ) {
710     if ( -f $oldproductfile ) {
711     $self->verbose("Copying $oldproductfile to $newproductfile");
712     copy($oldproductfile,$newproductfile);
713     }
714     }
715     }
716     }
717     else {
718     $newproductfile=$productfile;
719     }
720     if ( -f $newproductfile ) {
721     $self->verbose("Blasting $newproductfile to the past ($date)");
722     # If the (local) productfile exists - make it older
723     utime($date,$date,$newproductfile);
724     }
725     else {
726     $self->verbose("SomeThing Wrong(?) with $newproductfile\n".
727     "RELEASETOP=".$self->{releasetop}."\n".
728     "LOCALTOP=".$self->{localtop}."\n".
729     "workdir=".$ENV{workdir});
730     }
731     }
732     else {
733     $self->verbose("No need to touch $productfile");
734     }
735     }
736     undef $fh;
737 williamc 1.1.2.1 }