ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/BuildFile.pm
Revision: 1.3
Committed: Wed Sep 6 10:17:28 2000 UTC (24 years, 8 months ago) by williamc
Content type: text/plain
Branch: MAIN
Changes since 1.2: +4 -3 lines
Log Message:
Initiate with ConfigArea rather than toolbox

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