ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/BuildFile.pm
Revision: 1.5
Committed: Wed Sep 13 14:00:33 2000 UTC (24 years, 7 months ago) by williamc
Content type: text/plain
Branch: MAIN
Changes since 1.4: +26 -25 lines
Log Message:
get rid of LOCALTOP environmental variable

File Contents

# User Rev Content
1 williamc 1.2 # BuildFile
2 williamc 1.1 #
3     # Interface
4     # ---------
5 williamc 1.3 # new(ConfigArea)
6 williamc 1.2 # ParseBuildFile($base,$path,$file)
7     # ParseBuildFileExport(filename)
8     # BlockClassPath() : Return the class path
9     # ignore() : return 1 if directory should be ignored 0 otherwise
10 williamc 1.1
11     package BuildSystem::BuildFile;
12 williamc 1.2 use ActiveDoc::SimpleDoc;
13     use BuildSystem::ToolBox;
14     require 5.004;
15    
16     BEGIN {
17     $buildfile="BuildFile";
18     }
19    
20     sub new {
21     my $class=shift;
22     my $self={};
23     bless $self, $class;
24 williamc 1.3 $self->{area}=shift;
25     $self->{toolbox}=$self->{area}->toolbox();
26 williamc 1.5 $self->{localtop}=$self->{area}->location();
27 williamc 1.2 $self->{Arch}=1;
28     push @{$self->{ARCHBLOCK}}, $self->{Arch};
29     return $self;
30     }
31    
32     sub ignore {
33     my $self=shift;
34     return (defined $self->{ignore})?$self->{ignore}:0;
35     }
36    
37     sub _initswitcher {
38     my $self=shift;
39     my $switch=ActiveDoc::SimpleDoc->new();
40     my $parse="makebuild";
41     $switch->newparse($parse);
42     $switch->addignoretags($parse);
43     $self->_commontags($switch,$parse);
44     $switch->addtag($parse,"Build", \&Build_start, $self);
45     $switch->addtag($parse,"none",
46     \&OutToMakefile,$self,
47     \&OutToMakefile, $self,
48     "", $self);
49     $switch->addtag($parse,"Bin",
50     \&Bin_start,$self,
51     \&OutToScreen, $self,
52     "", $self);
53     $switch->addtag($parse,"LibType",
54     \&LibType_Start,$self,
55     \&LibType_text, $self,
56     \&LibType_end,$self);
57     $switch->addtag($parse,"ConfigurationClass",
58     \&Class_StartTag,$self,
59     \&OutToMakefile, $self,
60     "", $self);
61     $switch->addtag($parse,"ClassPath",
62     \&setBlockClassPath,$self,
63     \&OutToMakefile, $self,
64     "", $self);
65     $switch->addtag($parse,"AssociateGroup",
66     "",$self,
67     \&AssociateGroup,$self,
68     "", $self);
69     $switch->addtag($parse,"Environment",
70     \&Environment_start,$self,
71     \&OutToMakefile, $self,
72     \&Environment_end,$self);
73     $switch->addtag($parse,"Export",
74     \&export_start,$self,
75     \&OutToMakefile, $self,
76     \&export_end,$self);
77     return $switch;
78     }
79    
80     sub _commontags {
81     my $self=shift;
82     my $switch=shift;
83     my $parse=shift;
84    
85     $switch->grouptag("Export",$parse);
86     $switch->addtag($parse,"Use",\&Use_start,$self,
87     \&OutToMakefile, $self,
88     "", $self);
89     $switch->addtag($parse,"Group",\&Group_start,$self,
90     \&OutToMakefile, $self,
91     "", $self);
92     $switch->grouptag("Group",$parse);
93     $switch->addtag($parse,"External",
94     \&External_StartTag,$self,
95     \&OutToMakefile, $self,
96     "", $self);
97     $switch->addtag($parse,"lib",
98     \&lib_start,$self,
99     \&OutToMakefile, $self,
100     "", $self);
101     $switch->addtag($parse,"Architecture",
102     \&Arch_Start,$self,
103     \&OutToMakefile, $self,
104     \&Arch_End,$self);
105     $switch->addtag($parse,"INCLUDE_PATH",
106     \&IncludePath_Start,$self,
107     \&OutToMakefile, $self,
108     "",$self);
109     return $switch;
110     }
111    
112 williamc 1.4 sub GenerateMakefile {
113     my $self=shift;
114     my $infile=shift;
115     my $outfile=shift;
116    
117     $self->{switch}=$self->_initswitcher();
118     $self->{switch}->filetoparse($infile);
119    
120     # open a temporary gnumakefile to store output.
121     my $fh=FileHandle->new();
122     open ( $fh, ">$outfile") or die "Unable to open $outfile for output ".
123     "$!\n";
124     @{$self->{filehandlestack}}=($fh);
125    
126     # -- make an alias
127     *GNUmakefile=$fh;
128     if ( -e $ENV{LatestBuildFile} ) {
129     print GNUmakefile "include $ENV{LatestBuildFile}\n";
130     }
131     $ENV{LatestBuildFile}=$outfile;
132     $self->{switch}->parse("makebuild"); # sort out supported tags
133     close GNUmakefile;
134     }
135    
136 williamc 1.2 sub ParseBuildFile {
137     my $self=shift;
138     my $base=shift;
139     my $path=shift;
140     my $filename=shift @_;
141     my $fullfilename;
142     if ( $filename!~/^\// ) {
143     $fullfilename="$base/$path/$filename";
144     }
145     else {
146     $fullfilename=$filename;
147     }
148     $self->{path}=$path;
149     #print "Processing $fullfilename\n";
150     $numbins=0;
151     $self->{envnum}=0;
152     $self->{envlevel}=0;
153 williamc 1.5 $self->{currentenv}="$self->{localtop}/$ENV{INTwork}/$self->{path}/".
154 williamc 1.2 "BuildFile.mk";
155     $self->{switch}=$self->_initswitcher();
156     $self->{switch}->filetoparse($fullfilename);
157    
158     # $self->{switch}->{Strict_no_cr}='no';
159     #open a temporary gnumakefile to store output.
160     use Utilities::AddDir;
161 williamc 1.5 AddDir::adddir("$self->{localtop}/$ENV{INTwork}/$self->{path}");
162 williamc 1.2 my $fh=FileHandle->new();
163 williamc 1.5 open ( $fh, ">$self->{localtop}/$ENV{INTwork}/".$self->{path}."/BuildFile.mk"
164 williamc 1.2 ) or die 'Unable to open /$ENV{INTwork}/".$self->{path}."/BuildFile.mk $!\n';
165     @{$self->{filehandlestack}}=($fh);
166     # make an alias
167     *GNUmakefile=$fh;
168     if ( -e $ENV{LatestBuildFile} ) {
169     print GNUmakefile "include $ENV{LatestBuildFile}\n";
170     }
171     # print "writing to :\n".
172 williamc 1.5 # "$self->{localtop}/$ENV{INTwork}/$self->{path}/BuildFile.mk\n";
173     $ENV{LatestBuildFile}="$self->{localtop}/$ENV{INTwork}/".$self->{path}."/BuildFile.mk";
174 williamc 1.2 $self->{switch}->parse("makebuild"); # sort out supported tags
175     if ( $numbins > 0 ) {
176     print GNUmakefile <<ENDTEXT;
177     ifndef BINMODE
178     help::
179     \t\@echo Generic Binary targets
180     \t\@echo ----------------------
181     endif
182     ENDTEXT
183     foreach $target ( keys %$targettypes ) {
184     print GNUmakefile <<ENDTEXT;
185     ifndef BINMODE
186     help::
187     \t\@echo $target
188     endif
189     ENDTEXT
190     }
191     }
192     close GNUmakefile;
193     }
194 williamc 1.1
195 williamc 1.2 sub ParseBuildFile_Export {
196 williamc 1.1 my $self=shift;
197 williamc 1.2 my $filename=shift;
198 williamc 1.3 my $bf=BuildSystem::BuildFile->new($self->{area});
199 williamc 1.2 if ( defined $self->{remoteproject} ) {
200     $bf->{remoteproject}=$self->{remoteproject};
201     }
202     $bf->_parseexport($filename);
203     undef $bf;
204     }
205 williamc 1.1
206 williamc 1.2 sub _location {
207     my $self=shift;
208     use File::Basename;
209 williamc 1.1
210 williamc 1.2 return dirname($self->{switch}->filetoparse());
211 williamc 1.1 }
212    
213 williamc 1.2 sub _parseexport {
214 williamc 1.1 my $self=shift;
215 williamc 1.2 my $filename=shift;
216    
217     my $switchex=ActiveDoc::SimpleDoc->new();
218     $switchex->filetoparse($filename);
219     $switchex->newparse("export");
220     $switchex->addignoretags("export");
221     $switchex->addtag("export","Export",
222     \&export_start_export,$self,
223     \&OutToMakefile, $self,
224     \&export_end_export,$self);
225     $self->_commontags($switchex,"export");
226     $switchex->allowgroup("__export","export");
227     # $switchex->{Strict_no_cr}='no';
228     $self->{switch}=$switchex;
229     $switchex->parse("export"); # sort out supported tags
230     }
231 williamc 1.1
232 williamc 1.2 sub _pushremoteproject {
233     my $self=shift;
234     my $path=shift;
235 williamc 1.1
236 williamc 1.2 if ( defined $self->{remoteproject} ) {
237     push @{$self->{rpstack}}, $self->{remoteproject};
238     }
239     $self->{remoteproject}=$path;
240 williamc 1.1 }
241    
242 williamc 1.2 sub _popremoteproject {
243     my $self=shift;
244     if ( $#{$self->{rpstack}} >=0 ) {
245     $self->{remoteproject}=pop @{$self->{rpstack}};
246     }
247     else {
248     undef $self->{remoteproject};
249     }
250     }
251 williamc 1.1
252 williamc 1.2 sub _toolmapper {
253     my $self=shift;
254     if ( ! defined $self->{mapper} ) {
255     require BuildSystem::ToolMapper;
256     $self->{mapper}=BuildSystem::ToolMapper->new();
257     }
258     return $self->{mapper};
259     }
260    
261    
262     # ---- Tag routines
263    
264     #-- Override a class type with the <ConfigurationClass type=xxx> tag
265     # the type tag will pick up a pre-defined class type from project space.
266    
267     sub Class_StartTag {
268 williamc 1.1 my $self=shift;
269     my $name=shift;
270     my $hashref=shift;
271 williamc 1.2
272     if ( $self->{Arch} ) {
273     if ( defined $$hashref{'type'} ) {
274     $ClassName=$$hashref{'type'};
275     }
276     }
277     }
278    
279     sub IncludePath_Start {
280     my $self=shift;
281     my $name=shift;
282     my $hashref=shift;
283    
284     $self->{switch}->checktag( $name, $hashref, 'path');
285     if ( $self->{Arch} ) {
286     print GNUmakefile "INCLUDE+=".$self->_location()."/".
287     $$hashref{'path'}."\n";
288     }
289     }
290    
291     #
292     # generic build tag
293     #
294     sub Build_start {
295     my $self=shift;
296     my $name=shift;
297     my $hashref=shift;
298    
299     $self->{switch}->checktag($name,$hashref,'class');
300     if ( $self->{Arch} ) {
301    
302     # -- determine the build products name
303     my $name;
304     if ( exists $$hashref{'name'} ) {
305     $name=$$hashref{'name'};
306     }
307     else {
308     $self->{switch}->parseerror("No name specified for build product");
309     #$name="\$(buildname)";
310     }
311    
312     # -- check we have a lookup for the class type
313     my $mapper=$self->_toolmapper();
314     if ( ! $mapper->exists($$hashref{'class'}) ) {
315     $self->{switch}->parseerror("Unknown class : ".$$hashref{'class'});
316     }
317     else {
318     my @types=$self->_toolmapper()->types($$hashref{'class'});
319     my @deftypes=$self->_toolmapper()->defaulttypes($$hashref{'class'});
320    
321     my $fh=$self->{filehandlestack}[0];
322     my @targets=();
323    
324     # -- generate generic targets
325     print $fh "ifndef _BuildLink_\n";
326     print $fh "# -- Generic targets\n";
327     push @targets, $$hashref{'class'};
328     foreach $dtype ( @deftypes ) {
329     print $fh $$hashref{'class'}."::".$$hashref{'class'}."_".
330     $dtype."\n";
331     }
332     print $fh "\n";
333    
334     # -- generate targets for each type
335     foreach $type ( @types ) {
336    
337     # -- generic name for each type
338     my $pattern=$$hashref{'class'}."_".$type;
339     my $dirname=$$hashref{'class'}."_".$type."_".$name;
340     print $fh "# ------ $pattern rules ---------------\n";
341     print $fh $$hashref{'class'}."_".$type."::".$$hashref{'class'}.
342     "_".$type."_$name\n\n";
343    
344     # -- create a new directory for each type
345     push @targets, $pattern;
346     my $dirname=$$hashref{'class'}."_".$type."_".$name;
347 williamc 1.5 my $here="$self->{localtop}/$ENV{INTwork}/".$self->{path}."/".$dirname;
348 williamc 1.2 my $makefile=$here."/BuildFile.mk";
349     # AddDir::adddir($here);
350    
351     # -- create link targets to the directory
352     push @targets, $dirname;
353     print $fh "# -- Link Targets to $type directories\n";
354     print $fh "$dirname: make_$dirname\n";
355     print $fh "\t\@cd $here; \\\n";
356     print $fh "\t\$(MAKE) LatestBuildFile=$makefile _BuildLink_=1".
357     " workdir=$here ".
358     " -f \$(TOOL_HOME)/basics.mk datestamp \$\@; \n\n";
359    
360     # -- write target to make makefile for each directory
361     print $fh "# -- Build target directories\n";
362     print $fh "make_$dirname:\n";
363     print $fh "\tif [ ! -e \"$makefile\" ]; then \\\n";
364     print $fh "\t if [ ! -d \"$here\" ]; then \\\n";
365     print $fh "\t mkdir $here; \\\n";
366     print $fh "\t fi;\\\n";
367     print $fh "\t cd $dirname; \\\n";
368     print $fh "\t echo include ".$self->{currentenv}." > ".
369     "$makefile; \\\n";
370 williamc 1.5 print $fh "\t echo VPATH+=$self->{localtop}/".$self->{path}.
371 williamc 1.2 " >> $makefile; \\\n";
372     print $fh "\t echo buildname=$name >> $makefile;\\\n";
373     print $fh "\t echo ".$dirname.":".$pattern." >> $makefile;\\\n";
374     if ( defined (my @file=$mapper->rulesfile($$hashref{'class'})) ) {
375     foreach $f ( @file ) {
376     print $fh "\t echo -include $f >> $makefile; \\\n";
377     }
378     }
379     print $fh "\tfi\n";
380     print $fh "\n";
381     # print $typefile "$name :\n";
382     # print $typefile "\t\$(_quietbuild_)";
383     # print $typefile $mapper->template($$hashref{'class'},$type)."\n";
384     # print $typefile "\t\$(_quietstamp_)";
385     # print $typefile "$(SCRAMPERL) $(SCRAM_HOME)/src/scramdatestamp \$@.ds \$@ \$^\n";
386    
387     # -- cleaning targets
388     push @targets, "clean_$dirname";
389     print $fh "# -- cleaning targets\n";
390     print $fh "clean::clean_$dirname\n";
391     print $fh "clean_".$dirname."::\n";
392     print $fh "\t\@echo cleaning $dirname\n";
393     print $fh "\t\@if [ -d $here ]; then \\\n";
394     print $fh "\tcd $here; \\\n";
395     print $fh "\t\$(MAKE) LatestBuildFile=$makefile workdir=".
396     $here." _BuildLink_=1 -f ".
397     "\$(TOOL_HOME)/basics.mk clean; \\\n";
398     print $fh "\tfi\n\n";
399    
400    
401     }
402     # -- help targets
403     print $fh "helpheader::\n";
404     print $fh "\t\@echo Targets available:\n";
405     print $fh "\t\@echo ------------------\n\n";
406     print $fh "help::helpheader\n";
407     foreach $target ( @targets ) {
408     print $fh "help::\n";
409     print $fh "\t\@echo $target\n"
410     }
411     print $fh "endif\n";
412     } # end else
413     }
414     }
415    
416     sub Bin_start {
417     my $self=shift;
418     my $name=shift;
419     my $hashref=shift;
420    
421     my $fileclass;
422     my @tools;
423     my $tool;
424     my $filename;
425     my $objectname;
426    
427     $self->{switch}->checktag($name,$hashref,'file');
428     if ( $self->{Arch} ) {
429     if ( ! defined $$hashref{name} ) {
430     ($$hashref{name}=$$hashref{file})=~s/\..*//;
431     }
432     ($filename=$$hashref{file})=~s/\..*//;
433    
434     # Create a new directory for each binary target
435     my $dirname="bin_".$$hashref{name};
436 williamc 1.5 AddDir::adddir("$self->{localtop}/$ENV{INTwork}/".$self->{path}."/$dirname");
437 williamc 1.2 open (binGNUmakefile,
438 williamc 1.5 ">$self->{localtop}/$ENV{INTwork}/".$self->{path}."/$dirname/BuildFile.mk") or die "Unable to make $self->{localtop}/$ENV{INTwork}/$self->{path}/$dirname/".
439 williamc 1.2 "BuildFile.mk $!\n";
440    
441     # Create the link targets
442     $numbins++;
443     my $fh=$self->{filehandlestack}[0];
444     print $fh <<ENDTEXT;
445    
446     # Link Targets to binary directories
447     ifdef BINMODE
448     # We dont want to build a library here
449     override files:=
450     endif
451     ifndef BINMODE
452    
453     define stepdown_$$hashref{'name'}
454 williamc 1.5 if [ -d "$self->{localtop}/$ENV{INTwork}/$self->{path}/$dirname" ]; then \\
455     cd $self->{localtop}/$ENV{INTwork}/$self->{path}/$dirname; \\
456     \$(MAKE) BINMODE=true LatestBuildFile=$self->{localtop}/$ENV{INTwork}/$self->{path}/$dirname/BuildFile.mk workdir=\$(workdir)/$dirname -f \$(TOOL_HOME)/basics.mk datestamp \$\@; \\
457 williamc 1.2 fi
458     endef
459    
460     define stepdown2_$$hashref{'name'}
461 williamc 1.5 if [ -d "$self->{localtop}/$ENV{INTwork}/$self->{path}/$dirname" ]; then \\
462     cd $self->{localtop}/$ENV{INTwork}/$self->{path}/$dirname; \\
463     \$(MAKE) BINMODE=true LatestBuildFile=$self->{localtop}/$ENV{INTwork}/$self{path}/$dirname/BuildFile.mk workdir=\$(workdir)/$dirname -f \$(TOOL_HOME)/basics.mk datestamp \$\*; \\
464 williamc 1.2 fi
465    
466     endef
467    
468     bin_$$hashref{'name'}_%:: dummy
469     \@\$(stepdown2_$$hashref{'name'})
470    
471     $$hashref{'name'}_%:: dummy
472     \@\$(stepdown_$$hashref{'name'})
473    
474     help bin bin_debug bin_debug_local bin_insure bin_Insure clean $$hashref{'name'}:: dummy
475     \@\$(stepdown_$$hashref{'name'})
476    
477     binfiles+=$$hashref{'file'}
478     locbinfiles+=$dirname/$$hashref{'file'}
479     endif
480    
481    
482     ENDTEXT
483    
484    
485     # the binary specifics makefile
486     print binGNUmakefile "include ".$self->{currentenv}."\n";
487 williamc 1.5 print binGNUmakefile "VPATH+=$self->{localtop}/$self{path}\n";
488 williamc 1.2
489     # alias for bin_Insure
490     print binGNUmakefile <<ENDTEXT;
491    
492     bin_insure:bin_Insure
493     ifdef MAKETARGET_bin_insure
494     MAKETARGET_$$hashref{name}_Insure=1
495     endif
496    
497     # debuggging target
498     $$hashref{'name'}_echo_% :: echo_%
499    
500     # help targets
501     help::
502     \t\@echo Targets For $$hashref{'name'}
503     \t\@echo -------------------------------------
504     \t\@echo $$hashref{'name'} - default build
505     \t\@echo bin_$$hashref{'name'}_clean - executable specific cleaning
506     ENDTEXT
507    
508     # Make generic rules for each type
509     $targettypes={
510     "bin" => 'o',
511     "bin_debug" => 'd',
512     "bin_debug_local" => 'l_d',
513     "bin_Insure" => 'Insure'
514     };
515     #
516     foreach $target ( keys %$targettypes ) {
517     print binGNUmakefile <<ENDTEXT;
518    
519     # Type $target specifics
520     ifdef MAKETARGET_$target
521     MAKETARGET_$$hashref{name}_$$targettypes{$target}=1
522     endif
523     $target ::$$hashref{name}_$$targettypes{$target}
524    
525     bintargets+=$$hashref{name}_$$targettypes{$target}
526     help::
527     \t\@echo $$hashref{name}_$$targettypes{$target}
528     clean::
529     \t\@if [ -f \$(binarystore)/$$hashref{name}_$$targettypes{$target} ]; then \\
530     \techo Removing \$(binarystore)/$$hashref{name}; \\
531     \trm \$(binarystore)/$$hashref{name}_$$targettypes{$target}; \\
532     \tfi
533    
534     ENDTEXT
535     ($objectname=$$hashref{file})=~s/\..*/_$$targettypes{$target}\.o/;
536     ${"objectname_$$targettypes{$target}"}=$objectname;
537     print binGNUmakefile "$objectname:$$hashref{name}.dep\n";
538     } # end loop
539    
540     print binGNUmakefile "$$hashref{name}_Insure.exe:.psrc\n";
541     print binGNUmakefile "$$hashref{name}_d.exe:$objectname_d\n";
542     print binGNUmakefile "\t\$(CClinkCmdDebug)\n";
543     print binGNUmakefile "\t\@\$(SCRAMPERL) $(SCRAM_HOME)/src/scramdatestamp \$\@\.ds \$\@ \$\^\n";
544     print binGNUmakefile "$$hashref{name}_l_d.exe:$objectname_d\n";
545     print binGNUmakefile "\t\$(CClinkCmdDebugLocal)\n";
546     print binGNUmakefile "\t\@\$(SCRAMPERL) $(SCRAM_HOME)/src/scramdatestamp \$\@\.ds \$\@ \$\^\n";
547     print binGNUmakefile "$$hashref{name}_Insure.exe:$objectname_Insure\n";
548     print binGNUmakefile "\t\$(CClinkCmdInsure)\n";
549     print binGNUmakefile "\t\@\$(SCRAMPERL) $(SCRAM_HOME)/src/scramdatestamp \$\@\.ds \$\@ \$\^\n";
550     print binGNUmakefile "$$hashref{name}_o.exe:$objectname_o\n";
551     print binGNUmakefile "\t\$(CClinkCmd)\n";
552     print binGNUmakefile "\t\@\$(SCRAMPERL) $(SCRAM_HOME)/src/scramdatestamp \$\@\.ds \$\@ \$\^\n";
553     print binGNUmakefile "$$hashref{name}.dep:$$hashref{file}\n";
554     print binGNUmakefile "-include $$hashref{name}.dep\n";
555     print binGNUmakefile <<ENDTEXT;
556     clean::
557     \t\@if [ -f \$(binarystore)/$$hashref{name} ]; then \\
558     \techo Removing \$(binarystore)/$$hashref{name}; \\
559     \trm \$(binarystore)/$$hashref{name}; \\
560     \tfi
561    
562     $$hashref{name}_d.exe:\$(libslocal_d)
563     $$hashref{name}_o.exe:\$(libslocal)
564     ifdef MCCABE_DATA_DIR
565     $$hashref{name}_mccabe.exe: \$(libslocal_d) \$(MCCABE_DATA_DIR)/mccabeinstr/instplus.cpp
566     endif
567     $$hashref{name}_Insure.exe:\$(libslocal_I)
568     $$hashref{name}_d:$$hashref{name}_d.exe
569     \@cp $$hashref{name}_d.exe \$(binarystore)/$$hashref{name}
570     $$hashref{name}_l_d:$$hashref{name}_l_d.exe
571     \@cp $$hashref{name}_l_d.exe \$(binarystore)/$$hashref{name}
572     $$hashref{name}_Insure:$$hashref{name}_Insure.exe
573     \@cp $$hashref{name}_Insure.exe \$(binarystore)/$$hashref{name}_Insure
574     $$hashref{name}:$$hashref{name}_d.exe
575     \@mv $$hashref{name}_d.exe \$(binarystore)/$$hashref{name}
576     $$hashref{name}_o:$$hashref{name}_o.exe
577     \@mv $$hashref{name}_o.exe \$(binarystore)/$$hashref{name}
578     binfiles+=$$hashref{file}
579     ENDTEXT
580     }
581     close binGNUmakefile;
582     }
583    
584     sub External_StartTag {
585     my $self=shift;
586     my $name=shift;
587     my $hashref=shift;
588    
589     my $tool;
590     if ( $self->{Arch} ) {
591     $self->{switch}->checktag($name,$hashref,'ref');
592    
593     # -- oo toolbox stuff
594     # - get the appropriate tool object
595     $$hashref{'ref'}=~tr[A-Z][a-z];
596     if ( ! exists $$hashref{'version'} ) {
597     $tool=$self->{toolbox}->gettool($$hashref{'ref'});
598     }
599     else {
600     $tool=$self->{toolbox}->gettool($$hashref{'ref'},$$hashref{'version'});
601     }
602     if ( ! defined $tool ) {
603     $self->{switch}->parseerror("Unknown Tool Specified ("
604     .$$hashref{'ref'}.")");
605     }
606    
607     # -- old fashioned GNUmakefile stuff
608     print GNUmakefile $$hashref{'ref'};
609     if ( defined $$hashref{'version'} ) {
610     print GNUmakefile "_V_".$$hashref{'version'};
611     }
612     print GNUmakefile "=true\n";
613    
614     # -- Sub system also specified?
615     if ( exists $$hashref{'use'} ) {
616     # -- look for a buildfile
617     my @paths=$tool->getfeature("INCLUDE");
618     my $file="";
619     my ($path,$testfile);
620     foreach $path ( @paths ) {
621     $testfile=$path."/".$$hashref{'use'}."/BuildFile" ;
622     if ( -f $testfile ) {
623     $file=$testfile;
624     $self->_pushremoteproject($path);
625     }
626     }
627     if ( $file eq "" ) {
628     $self->{switch}->parseerror("Unable to find SubSystem $testfile");
629     }
630     $self->ParseBuildFile_Export($file);
631     $self->_popremoteproject();
632     }
633     }
634     }
635    
636     sub Group_start {
637     my $self=shift;
638     my $name=shift;
639     my $hashref=shift;
640    
641     $self->{switch}->checktag($name, $hashref, 'name');
642     if ( $self->{Arch} ) {
643     print GNUmakefile "GROUP_".$$hashref{'name'};
644     if ( defined $$hashref{'version'} ) {
645     print GNUmakefile "_V_".$$hashref{'version'};
646     }
647     print GNUmakefile "=true\n";
648     }
649     }
650 williamc 1.1
651 williamc 1.2 sub Use_start {
652     my $self=shift;
653     my $name=shift;
654     my $hashref=shift;
655     my $filename;
656     use Utilities::SCRAMUtils;
657 williamc 1.1
658 williamc 1.2 $self->{switch}->checktag($name, $hashref, "name");
659     if ( $self->{Arch} ) {
660     if ( exists $$hashref{'group'} ) {
661     print GNUmakefile "GROUP_".$$hashref{'group'}."=true\n";
662     }
663     if ( ! defined $self->{remoteproject} ) {
664     $filename=SCRAMUtils::checkfile(
665     "/$ENV{INTsrc}/$$hashref{name}/BuildFile");
666     }
667     else {
668     $filename=$self->{remoteproject}."/$$hashref{name}/BuildFile";
669     print "trying $filename\n";
670     if ( ! -f $filename ) { $filename=""; };
671     }
672     if ( $filename ne "" ) {
673     $self->ParseBuildFile_Export( $filename );
674     }
675     else {
676     $self->{switch}->parseerror("Unable to detect Appropriate ".
677     "decription file for <$name name=".$$hashref{name}.">");
678     }
679     }
680     }
681    
682     sub CheckBuildFile {
683     my $self=shift;
684     my $classdir=shift;
685     my $ClassName="";
686     my $thisfile="$classdir/$buildfile";
687    
688 williamc 1.5 if ( -e $self->{localtop}."/".$thisfile ) {
689     $DefaultBuildfile="$self->{localtop}/$thisfile";
690     $self->ParseBuildFile($self->{localtop}, $classdir, $buildfile);
691 williamc 1.2 }
692     elsif ( -e $ENV{RELEASETOP}."/".$thisfile ) {
693     $DefaultBuildfile="$ENV{RELEASETOP}/$thisfile";
694     $self->ParseBuildFile($ENV{RELEASETOP}, $classdir, $buildfile);
695     }
696     return $ClassName;
697 williamc 1.1 }
698    
699 williamc 1.2 # List association groups between <AssociateGroup> tags
700     # seperated by newlines or spaces
701     sub AssociateGroup {
702     my $self=shift;
703     my $name=shift;
704     my $string=shift;
705     my $word;
706    
707     if ( $self->{Arch} ) {
708     foreach $word ( (split /\s/, $string) ){
709     chomp $word;
710     next if /^#/;
711     if ( $word=~/none/ ) {
712     $self->{ignore}=1;
713     }
714     }
715     }
716     }
717    
718     sub Arch_Start {
719     my $self=shift;
720 williamc 1.1 my $name=shift;
721     my $hashref=shift;
722    
723 williamc 1.2 $self->{switch}->checktag($name, $hashref,'name');
724     ( ($ENV{SCRAM_ARCH}=~/$$hashref{name}.*/) )? ($self->{Arch}=1)
725     : ($self->{Arch}=0);
726     push @{$self->{ARCHBLOCK}}, $self->{Arch};
727 williamc 1.1 }
728    
729 williamc 1.2 sub Arch_End {
730 williamc 1.1 my $self=shift;
731     my $name=shift;
732    
733 williamc 1.2 pop @{$self->{ARCHBLOCK}};
734     $self->{Arch}=$self->{ARCHBLOCK}[$#{$self->{ARCHBLOCK}}];
735     }
736    
737     # Split up the Class Block String into a useable array
738     sub _CutBlock {
739     my $self=shift;
740     my $string= shift @_;
741     @BlockClassA = split /\//, $string;
742     }
743    
744     sub OutToMakefile {
745     my $self=shift;
746     my $name=shift;
747     my @vars=@_;
748    
749     if ( $self->{Arch} ) {
750     print GNUmakefile @vars;
751     }
752     }
753    
754     sub OutToScreen {
755     my $name=shift;
756     my @vars=@_;
757    
758     if ( $self->{Arch} ) {
759     print @vars;
760     }
761     }
762     sub setBlockClassPath {
763     my $self=shift;
764     my $name=shift;
765     my $hashref=shift;
766    
767     $self->{switch}->checktag($name, $hashref, 'path');
768     $self->{BlockClassPath}=$self->{BlockClassPath}.":".$$hashref{path};
769     $self->_CutBlock($$hashref{path});
770     }
771    
772     sub BlockClassPath {
773     my $self=shift;
774     return $self->{BlockClassPath};
775     }
776    
777     sub export_start_export {
778     my $self=shift;
779     my $name=shift;
780     my $hashref=shift;
781    
782     $self->{switch}->opengroup("__export");
783     }
784    
785     sub export_start {
786     my $self=shift;
787     my $name=shift;
788     my $hashref=shift;
789    
790     $self->{switch}->opengroup("__export");
791     if ( exists $$hashref{autoexport} ) {
792     print GNUmakefile "scram_autoexport=".$$hashref{autoexport}."\n";
793     if ( $$hashref{autoexport}=~/true/ ) {
794     $self->{switch}->allowgroup("__export","makebuild");
795     }
796     else {
797     $self->{switch}->disallowgroup("__export","makebuild");
798     }
799     }
800     # -- allow default setting from other makefiles
801     print GNUmakefile "ifeq (\$(scram_autoexport),true)\n";
802     }
803    
804     sub export_end_export {
805     my $self=shift;
806     $self->{switch}->closegroup("__export");
807     }
808 williamc 1.1
809 williamc 1.2 sub export_end {
810     my $self=shift;
811     $self->{switch}->closegroup("__export");
812     print GNUmakefile "endif\n";
813 williamc 1.1 }
814    
815 williamc 1.2 #
816     # Standard lib tag
817     #
818     sub lib_start {
819 williamc 1.1 my $self=shift;
820     my $name=shift;
821     my $hashref=shift;
822    
823 williamc 1.2 $self->{switch}->checktag($name, $hashref, 'name');
824     if ( $self->{Arch} ) {
825     print GNUmakefile "lib+=$$hashref{name}\n";
826     }
827     }
828    
829     #
830     # libtype specification
831     #
832     sub LibType_Start {
833     my $self=shift;
834     my $name=shift;
835     my $hashref=shift;
836 williamc 1.1
837 williamc 1.2 if ( $self->{Arch} ) {
838     if ( defined $self->{libtype_conext} ) {
839     $self->{switch}->parseerror("<$name> tag cannot be specified".
840     " without a </$name> tag to close previous context");
841 williamc 1.1 }
842     else {
843 williamc 1.2 $self->{libtype_conext}=1;
844     $self->{switch}->checktag($name, $hashref, 'type');
845    
846     print GNUmakefile "# Specify Library Type\n";
847     print GNUmakefile "DefaultLibsOff=yes\n";
848     if ( $$hashref{'type'}=~/^archive/i ) {
849     print GNUmakefile "LibArchive=true\n";
850     }
851     elsif ($$hashref{'type'}=~/debug_archive/i ) {
852     print GNUmakefile "LibDebugArchive=true\n";
853     }
854     elsif ($$hashref{'type'}=~/debug_shared/i ) {
855     print GNUmakefile "LibDebugShared=true\n";
856     }
857     elsif ($$hashref{'type'}=~/shared/i ) {
858     print GNUmakefile 'LibShared=true'."\n";
859 williamc 1.1 }
860 williamc 1.2 print GNUmakefile "\n";
861     }
862     }
863     }
864 williamc 1.1
865 williamc 1.2 sub LibType_text {
866 williamc 1.1 my $self=shift;
867     my $name=shift;
868 williamc 1.2 my $string=shift;
869 williamc 1.1
870 williamc 1.2 if ( $self->{Arch} ) {
871     $string=~s/\n/ /g;
872     print GNUmakefile "libmsg::\n\t\@echo Library info: ";
873     print GNUmakefile $string;
874     print GNUmakefile "\n";
875     }
876 williamc 1.1 }
877    
878 williamc 1.2 sub LibType_end {
879 williamc 1.1 my $self=shift;
880     my $name=shift;
881    
882 williamc 1.2 undef $self->{libtype_conext};
883 williamc 1.1 }
884    
885 williamc 1.2 sub Environment_start {
886 williamc 1.1 my $self=shift;
887     my $name=shift;
888     my $hashref=shift;
889 williamc 1.2
890     if ( $self->{Arch} ) {
891     $self->{envnum}++;
892    
893     # open a new Environment File
894 williamc 1.5 my $envfile="$self->{localtop}/$ENV{INTwork}/$self->{path}/Env_".
895 williamc 1.2 $self->{envnum}.".mk";
896     use FileHandle;
897     my $fh=FileHandle->new();
898     open ($fh,">$envfile") or die "Unable to open file $envfile \n$!\n";
899     push @{$self->{filehandlestack}}, $fh;
900     *GNUmakefile=$fh;
901    
902     # include the approprate environment file
903     if ( $self->{envlevel} == 0 ) {
904 williamc 1.5 print GNUmakefile "include $self->{localtop}/$ENV{INTwork}/".
905 williamc 1.2 $self->{path}."/BuildFile.mk\n";
906     }
907     else {
908 williamc 1.5 print GNUmakefile "include $self->{localtop}/$ENV{INTwork}/".
909 williamc 1.2 $self->{path}."/Env_".$self->{Envlevels}[$self->{envlevel}].".mk\n";
910     }
911     $self->{envlevel}++;
912     $self->{Envlevels}[$self->{envlevel}]=$self->{envnum};
913 williamc 1.5 $self->{currentenv}="$self->{localtop}/$ENV{INTwork}/$self->{path}/Env_$self->{envnum}.mk";
914 williamc 1.2 }
915 williamc 1.1 }
916    
917 williamc 1.2 sub Environment_end {
918 williamc 1.1 my $self=shift;
919 williamc 1.2 my $fd;
920    
921     if ( $self->{Arch} ) {
922     $self->{envlevel}--;
923     if ( $self->{envlevel} < 0 ) {
924     print "Too many </Environent> Tags on $self->{switch}->line()\n";
925     exit 1;
926     }
927     close GNUmakefile;
928     # restore the last filehandle
929     $fd=pop @{$self->{filehandlestack}};
930     close $fd;
931     *GNUmakefile=$self->{filehandlestack}[$#{$self->{filehandlestack}}];
932     if ( $self->{envlevel} < 1 ) {
933 williamc 1.5 $self->{currentenv}="$self->{localtop}/$ENV{INTwork}/$self->{path}/".
934 williamc 1.2 "BuildFile.mk";
935     }
936     else {
937     $self->{currentenv}=
938 williamc 1.5 $self->{localtop}."/$ENV{INTwork}/$self->{path}/Env_".
939 williamc 1.2 $self->{Envlevels}[$self->{envlevel}];
940     }
941     }
942 williamc 1.1 }