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.6
Committed: Thu Nov 2 17:47:17 2000 UTC (24 years, 6 months ago) by williamc
Content type: text/plain
Branch: V0_16branch
CVS Tags: BuildSystemProto1, V0_18_0model, V0_18_0alpha
Changes since 1.1.2.7.2.2.2.1.2.5: +3 -1 lines
Log Message:
Only mark checked if its the default build

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 williamc 1.1.2.7.2.2.2.1.2.6 $self->{workdir}."/BuildRecorderFile";
41 williamc 1.1.2.7.2.2.2.1.2.4 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.6 if ( $Targets[0] eq $Class ) {
259 williamc 1.1.2.7.2.2.2.1.2.4 $self->{BuildDB}->checked($ClassDir,1); # Mark it as taken care of
260 williamc 1.1.2.7.2.2.2.1.2.6 }
261 williamc 1.1.2.7.2.2.2.1.2.4
262     # Do a datestamp check so that make will build files that have changed
263     # rather than just those which are older than their dependencies
264     $self->_checkdatestampindir($ClassDir);
265    
266     # -- The main build here
267     $rv=system("gmake","--no-print-directory","-r","-k","-f",
268     "$ENV{DefaultMakefile}","-I$ENV{TOOL_HOME}", @Targets);
269     }
270 williamc 1.1.2.1 return $rv/256; # return the exit status of gmake
271 williamc 1.1.2.7.2.2.2.1.2.4
272 williamc 1.1.2.1 }
273    
274 williamc 1.1.2.7.2.2.2.1.2.4 # TODO - work in progress - replacement for BuildDir that can handle <Build> OK
275     sub BuildIt {
276     my $self=shift;
277     my $dir=shift;
278     my @Targets=@_;
279    
280    
281     # -- get the top building block
282     my $topblock=$self->_gettopblock();
283     $ENV{LatestBuildFile}=$self->_gettopbf()->makefile();
284    
285     # -- is there a class block associated with the directory?
286     my ($Class,$ClassDir)=getclass($dir);
287     $self->verbose("Using Class $Class");
288     my $classblock=$self->_getclassblock($Class,$topblock);
289    
290     # -- If target not specified default to the class name target
291     if ( $targetnumber == -1 ) {
292     push @Targets,$Class;
293     }
294    
295     # -- Create working directory
296     my $workdir=$self->{workdir}."/".$ClassDir;
297     chdir $self->{localtop};
298     AddDir::adddir($workdir);
299     $ENV{workdir}=$workdir;
300     my $fullworkdir=$self->{localtop}."/".$ENV{workdir};
301     chdir $fullworkdir || die "Unable to enter working directory $!";
302     $self->verbose("Working area setup");
303    
304     # -- Search for Blocks up to tree root
305     my @dirblocks=();
306     my @dirs=split /\//, $dir;
307     my $fulldir="";
308     my $currentblock=$classblock;
309     foreach $dire ( @dirs ) {
310     ($fulldir eq "")?$fulldir=$dire
311     :$fulldir=$fulldir."/".$dire;
312     $self->verbose("Searching $fulldir for Block");
313     my $block=$self->_getdirblock($fulldir,$currentblock);
314     if ( defined $block ) {
315     $currentblock=$block;
316     }
317     $ENV{LatestBuildFile}=$self->gettopbf()->makefile();
318     }
319    
320     # -- Create a makefile to include both BuildFile and
321     # class makefile
322    
323     my $fh=FileHandle->new();
324     my $mfile=$fullworkdir."/BuildFile.mk";
325     $self->verbose("Building makefile $mfile");
326     $fh->open(">".$mfile);
327     $fh->autoflush(1);
328     if ( -e $ENV{LatestBuildFile} ) {
329     print $fh "include $ENV{LatestBuildFile}\n";
330     }
331    
332     # -- Parse the local BuildFile
333     my $dbf=$self->_getdirbf($dir);
334     if ( defined $dbf ) {
335     $dbf->Parsetofh($fh,$currentblock);
336     }
337    
338     # -- Parse the class BuildFile
339     my $cbf=$self->_getclassbf($Class);
340     if ( defined $cbf ) {
341     $cbf->Parsetofh($fh,$currentblock);
342     }
343     $fh->close();
344     $ENV{DefaultMakefile}=$mfile;
345    
346     # -- Hack around make by checking datestamps in local working and
347     # in _class_ working directories
348     $self->_checkdatestampindir($ClassDir);
349     opendir $fh, $ClassDir;
350     my @dfiles= grep { -d $_ } readdir $fh;
351     undef $fh;
352     foreach $dir ( @dfiles ) {
353     if ( $dir=~/^_class_/ ) {
354     $self->_checkdatestampindir($ClassDir."/".$dir);
355     }
356     }
357    
358     # -- Call gmake to do the actual build
359     $rv=system("gmake","--no-print-directory","-r","-k","-f",
360     "$mfile","-I$ENV{TOOL_HOME}", @Targets);
361     return $rv/256; # return the exit status of gmake
362     }
363    
364     #
365     # -- Block generation Routines
366     #
367    
368     sub _getclassblock {
369     my $self=shift;
370     my $key=shift;
371    
372     if ( ! defined $self->{classblocks}{$key} ) {
373     $self->verbose("Initialising Class Block $key");
374     $self->{classblocks}{$key}=BuildSystem::Block->new();
375     # -- get class buildfile
376     my $bf=$self->_getclassbf($key);
377     if ( @_ ) {
378     $self->{classblocks}{$key}->parent(shift);
379     }
380     $bf->BlockParse($self->{classblocks}{$key});
381     $self->verbose("Initialisation Complete for Class Block $key");
382     }
383     return $self->{classblocks}{$key};
384    
385     }
386    
387     sub _gettopblock {
388     my $self=shift;
389    
390     if ( ! defined $self->{topblocks} ) {
391     $self->verbose("Initialising Top Block");
392     $self->{topblock}=BuildSystem::Block->new();
393     # -- get class buildfile
394     my $bf=$self->_gettopbf();
395     if ( @_ ) {
396     $self->{topblock}->parent(shift);
397     }
398     $bf->BlockParse($self->{topblock});
399     $self->verbose("Initialisation Complete for Top Block");
400     }
401     return $self->{topblock};
402     }
403    
404     sub _getdirblock {
405     my $self=shift;
406     my $dir=shift;
407     my $block=shift;
408    
409     if ( defined $dir || $dir ne "" ) {
410     if ( ! defined $self->{blocks}{$dir} ) {
411     # -- get a buildfile and do a block parse
412     $self->{blocks}{$dir}=BuildSystem::Block->new();
413     my $bf=$self->_getbuildfile($dir);
414     $self->{blocks}{$dir}->parent($block);
415     $bf->blockparse($self->{blocks}{$dir});
416     }
417     return $self->{blocks}{$dir};
418     }
419     return undef;
420     }
421    
422     #
423     # -- BuildFile generation routines
424     #
425    
426     sub _getclassbf {
427     my $self=shift;
428     my $class=shift;
429    
430     if ( ! defined $self->{classbf}{$class} ) {
431     $self->verbose("Initialising Class BuildFile $class");
432     # -- determine BuildFile or makefile
433     my $fname=$self->{localtop}."/".$self->{projconfigdir}.
434     "/".$class."_";
435     if ( -f $fname.$self->{buildfilename} ) {
436     $fname=$fname.$self->{buildfilename};
437     }
438     elsif ( -f $fname."makefile.mk" ) {
439     $fname=$fname."makefile.mk";
440     }
441     else {
442     $self->error("$fname".$self->{buildfilename}." does not exist in ".
443     $self->{projconfigdir});
444     }
445    
446     # -- create a BuildFile object
447     $self->{classbf}{$class}=BuildSystem::BuildFile->new($self->{area},$self);
448     $self->{classbf}{$class}->buildfile($fname);
449     $self->verbose("Finished Initialising Class BuildFile $class");
450     }
451     return $self->{classbf}{$class};
452     }
453    
454     sub _gettopbf {
455     my $self=shift;
456    
457     if ( ! defined $self->{topbf} ) {
458     $self->{topbf}=BuildSystem::BuildFile->new($self->{area},$self);
459     $self->{topbf}->buildfile($self->{localtop}."/".
460     $self->{projconfigdir}."/".$self->{buildfilename});
461     }
462     return $self->{topbf};
463     }
464     #
465     # Returns undef if BF does not exist at this dir level
466     #
467     sub _getdirbf {
468     my $self=shift;
469     my $dir=shift;
470    
471     if ( ! exists $self->{dirbf}{$dir} ) {
472     $self->verbose("initialising dir BuildFile $dir");
473     # -- determine if local or releasetop
474     my $fname=$self->{path}."/".$self->{buildfilename};
475     if ( -f $self->{localtop}."/".$fname ) {
476     $fname=$self->{localtop}."/".$fname;
477     }
478     elsif ( -f $self->{releasetop}."/".$fname ) {
479     $fname=$self->{releasetop}."/".$fname;
480     }
481     else {
482     $self->{dirbf}{$dir}=undef;
483     $self->verbose("initialisation complete for dir BuildFile $dir");
484     return $self->{dirbf}{$dir};
485     }
486    
487     # -- construct the bf object
488     $self->{dirbf}{$dir}=BuildSystem::BuildFile->new($self->{area},$self);
489     $self->{dirbf}{$dir}->buildfile($fname);
490    
491     $self->verbose("initialisation complete for dir BuildFile $dir");
492     }
493     return $self->{dirbf}{$dir};
494     }
495    
496     sub getclass2 {
497 williamc 1.1.2.1 my $self=shift;
498     my $dirname = shift;
499     my $Class="DEFAULT";
500     my $ClassDir="";
501    
502 williamc 1.1.2.7.2.2.2.1.2.4 #return if $dirname eq "";
503     my @DIRA=split /\//, $dirname;
504 williamc 1.1.2.1
505 williamc 1.1.2.7.2.2.2.1.2.4 my $thispath=".";
506     # -- construct all class buildfiles in the path
507 williamc 1.1.2.1 for ( $i=0; $i<=$#DIRA; $i++ ) {
508 williamc 1.1.2.7.2.2.2.1.2.4 #$thispath=(($thispath eq "")?$DIRA[$i]:$thispath."/".$DIRA[$i]);
509 williamc 1.1.2.1 $thispath=$thispath."/".$DIRA[$i];
510 williamc 1.1.2.7.2.2.2.1.2.4 if ( ! exists $self->{pathbf}{$thispath} ) {
511     $self->verbose("Initialising BuildFile in $thispath");
512     $self->{pathbf}{$thispath}=$self->_startbuildfile($thispath);
513     }
514     # -- check class overriden by BuildFile
515     if ( defined $self->{pathbf}{$thispath}->classname() ) {
516     $Class=$self->{pathbf}{$thispath}->classname();
517 williamc 1.1.2.1 $ClassDir=$thispath;
518     }
519 williamc 1.1.2.7.2.2.2.1.2.4 else {
520     # -- sort it out from classpath directives
521     foreach $BlockClassA ( @{$self->{LoBCA}} ) {
522     next if ( $#{$BlockClassA} < $i );
523     $elem=${$BlockClassA}[$i];
524     if ( $elem=~/^$DIRA[$i]\+/ ) {
525     $elem=~s/^$DIRA[$i]//;
526     }
527     #print $elem." ".$DIRA[$i]."\n";
528     if ( $elem=~/^\+/ ) {
529     ($Class=$elem)=~s/^\+//;
530 williamc 1.1.2.1 $ClassDir=$thispath;
531 williamc 1.1.2.7.2.2.2.1.2.4 }
532     #}
533     }
534     }
535     }
536     # -- default case
537     if ( $ClassDir eq "" ) {
538     if ( ! defined $self->{pathbf}{'.'}) {
539     $self->{pathbf}{'.'}=$self->_startbuildfile(".");
540     $self->verbose("DEFAULT class initialised : ".$self->{pathbf}{'.'});
541     }
542     $ClassDir=".";
543     }
544    
545     # -- returns
546     ($ClassDir_c=$ClassDir)=~s/^\.\///;
547     return ( $Class, $ClassDir_c, $self->{pathbf}{$ClassDir});
548     }
549    
550     sub getclass {
551     my $self=shift;
552     my $dirname = shift;
553    
554     my $Class="DEFAULT";
555     my $ClassDir=".";
556    
557     # return if $dirname eq "";
558     my @DIRA=split /\//, $dirname;
559    
560     my $thispath="";
561     for ( $i=0; $i<=$#DIRA; $i++ ) {
562     $thispath=(($thispath eq "")?$DIRA[$i]:$thispath."/".$DIRA[$i]);
563    
564     # -- sort it out from classpath directives
565     foreach $BlockClassA ( @{$self->{LoBCA}} ) {
566     next if ( $#{$BlockClassA} < $i );
567     $elem=${$BlockClassA}[$i];
568     if ( $elem=~/^$DIRA[$i]\+/ ) {
569     $elem=~s/^$DIRA[$i]//;
570     }
571     #print $elem." ".$DIRA[$i]."\n";
572     if ( $elem=~/^\+/ ) {
573     ($Class=$elem)=~s/^\+//;
574     $ClassDir=$thispath;
575     }
576     }
577 williamc 1.1.2.1 }
578 williamc 1.1.2.7.2.2.2.1.2.4 return ( $Class, $ClassDir );
579     }
580    
581     #
582     # Check to see if the buildfile is local or in the release area and
583     # parse appropriately
584     #
585     sub _startbuildfile {
586     my $self=shift;
587     my $classdir=shift;
588    
589     my $bf=BuildSystem::BuildFile->new($self->{area},$self);
590     my $thisfile="$classdir/$self->{buildfilename}";
591    
592     if ( -e $self->{localtop}."/".$thisfile ) {
593     $bf->buildfile($self->{localtop}."/".$thisfile);
594     $bf->ParseBuildFile($self->{localtop}, $classdir,
595     $self->{buildfilename});
596     }
597     elsif ( -e $self->{releasetop}."/".$thisfile ) {
598     $bf->buildfile($self->{releasetop}."/".$thisfile);
599     $bf->ParseBuildFile($self->{releasetop}, $classdir,
600     $self->{buildfilename});
601     }
602     return $bf;
603     }
604    
605     sub _topbuildfile {
606     my $self=shift;
607    
608     $self->verbose("Generating Top Level BuildFile");
609     # -- Analyse project buildfile if it exists
610    
611     my $topbf=$self->_gettopbf();
612    
613     # -- generate top level makefile
614     undef $ENV{LatestBuildFile};
615     $topbf->ParseBuildFile($self->{localtop},
616     $self->{projconfigdir},$self->{buildfilename});
617    
618     # -- Extract BuildStructure Information
619     my @ClassPaths=split /:/, $self->{topbf}->BlockClassPath();
620     foreach $BClassPath ( @ClassPaths ) {
621     next if ( $BClassPath eq "");
622     push @{$self->{LoBCA}}, [ split /\//, $BClassPath ];
623 williamc 1.1.2.1 }
624 williamc 1.1.2.7.2.2.2.1.2.4 $self->verbose("End top buildfile generation");
625     }
626    
627     sub _checkdatestampindir {
628     my $self=shift;
629     my $dir=shift;
630    
631     # -- get all local .ds files
632     my $fh=FileHandle->new();
633     my $ldir=$self->{localtop}."/".$self->{workdir}."/".$dir;
634     opendir $fh, $ldir;
635     my @dsfiles= grep /^.*\.ds$/, readdir $fh;
636     $fh->close();
637    
638     # -- copy across ds files from releasetop if not existing locally
639     if ( $#dsfiles < 0 ) {
640     # -- get all releasetop .ds files
641     my $rdir=$self->{releasetop}."/".$self->{workdir}."/".$dir;
642     opendir $fh, $rdir;
643     my @releasedsfiles= grep /^.*\.ds$/, readdir $fh;
644     foreach $file ( @releasedsfiles ) {
645     use File::Copy;
646     $self->verbose("Copying $file from $rdir to $ldir");
647     copy($rdir."/".$file,$ldir."/".$file);
648     }
649     $fh->close();
650     @dsfiles=@releasedsfiles;
651     }
652    
653     # -- process ds files
654     my $file;
655     foreach $datafile ( @dsfiles ) {
656     $self->verbose("Processing $ldir/$datafile\n");
657     my $ds=BuildSystem::DateStampRecord->new($ldir."/".$datafile);
658     $ds->verbosity($self->verbosity());
659     my $date;
660     my $needsupdate;
661     my $productfile=$ds->product();
662     my (%files,%moddate);
663    
664     # now get dates in our dependency list
665     my @datedfiles=$ds->dated();
666     if ( $#datedfiles >= 0 ) {
667    
668     $needsupdate=1;
669     $date=$datedfiles[0][1]-1;
670     }
671     else {
672     # -- extra checks for local replacement of files
673     foreach $file ( $ds->contents() ) {
674     # -- only check files
675     if ( -f $file ) {
676     $files{$file}=$ds->filedate($file);
677     # -- check to see if we have a new local copy
678     if ( ($file=~/\Q$self->{releasetop}\E/) &&
679     ($self->{releasetop} ne $self->{localtop}) ) {
680     ($tempfile=$file)=~s/\Q$self->{releasetop}\E/$self->{localtop}/;
681     if ( -f $tempfile ) {
682     $files{$tempfile}=$files{$file};
683     $file=$tempfile;
684     }
685     }
686     $moddate{$file}=(stat($file))[9];
687     if ( $moddate{$file} != $files{$file} ) {
688     $self->verbose($file." changed");
689     $date=$moddate{$file}-1;
690     $needsupdate=1;
691     }
692     }
693     }
694     }
695     # time stamp the product file to be older than the dependencies
696     if ( $needsupdate == 1 ) { # touch file into the past
697     my $newproductfile;
698     if ( $productfile!~/\Q$self->{localtop}\E/ ) {
699     if ( $productfile=~/\Q$self->{releasetop}\E/ ) {
700     ($newproductfile=$productfile)=~
701     s/\Q$self->{releasetop}\E/$self->{localtop}/;
702     $self->verbose("Copying $productfile to $newproductfile");
703     copy($productfile,$newproductfile);
704     }
705     else { # assume no path to worry about
706     $newproductfile=$self->{localtop}."/".$ENV{workdir}.
707     "/".$productfile;
708     # -- make a local copy of the product file if not already here
709     my $oldproductfile=$self->{releasetop}."/".$ENV{workdir}.
710     "/".$productfile;
711     if ( ! -f $newproductfile ) {
712     if ( -f $oldproductfile ) {
713     $self->verbose("Copying $oldproductfile to $newproductfile");
714     copy($oldproductfile,$newproductfile);
715     }
716     }
717     }
718     }
719     else {
720     $newproductfile=$productfile;
721     }
722     if ( -f $newproductfile ) {
723     $self->verbose("Blasting $newproductfile to the past ($date)");
724     # If the (local) productfile exists - make it older
725     utime($date,$date,$newproductfile);
726     }
727     else {
728     $self->verbose("SomeThing Wrong(?) with $newproductfile\n".
729     "RELEASETOP=".$self->{releasetop}."\n".
730     "LOCALTOP=".$self->{localtop}."\n".
731     "workdir=".$ENV{workdir});
732     }
733     }
734     else {
735     $self->verbose("No need to touch $productfile");
736     }
737     }
738     undef $fh;
739 williamc 1.1.2.1 }