ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/BuildFile.pm
Revision: 1.14
Committed: Wed Nov 7 19:49:37 2001 UTC (23 years, 6 months ago) by sashby
Content type: text/plain
Branch: MAIN
CVS Tags: V0_19_4_pre1, V0_19_3, V0_19_2, V0_19_1
Changes since 1.13: +2 -13 lines
Log Message:
ADding some changes. RELEASETOP can now be set using setroot.

File Contents

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