ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/BuildFile.pm
Revision: 1.13
Committed: Wed Nov 15 14:49:22 2000 UTC (24 years, 5 months ago) by williamc
Content type: text/plain
Branch: MAIN
CVS Tags: V0_19_0, V0_18_5, V0_18_4, V_18_3_TEST, VO_18_3, V0_18_2, V0_18_1
Changes since 1.12: +68 -228 lines
Log Message:
Up and running

File Contents

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