ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/BuildFile.pm
Revision: 1.7
Committed: Tue Sep 19 10:09:29 2000 UTC (24 years, 7 months ago) by williamc
Content type: text/plain
Branch: MAIN
Changes since 1.6: +13 -32 lines
Log Message:
Update from laptop

File Contents

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