ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/BuildFile.pm
Revision: 1.4
Committed: Tue Sep 12 13:01:39 2000 UTC (24 years, 7 months ago) by williamc
Content type: text/plain
Branch: MAIN
Changes since 1.3: +24 -0 lines
Log Message:
Add BuildFile basics

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 GenerateMakefile {
112 my $self=shift;
113 my $infile=shift;
114 my $outfile=shift;
115
116 $self->{switch}=$self->_initswitcher();
117 $self->{switch}->filetoparse($infile);
118
119 # open a temporary gnumakefile to store output.
120 my $fh=FileHandle->new();
121 open ( $fh, ">$outfile") or die "Unable to open $outfile for output ".
122 "$!\n";
123 @{$self->{filehandlestack}}=($fh);
124
125 # -- make an alias
126 *GNUmakefile=$fh;
127 if ( -e $ENV{LatestBuildFile} ) {
128 print GNUmakefile "include $ENV{LatestBuildFile}\n";
129 }
130 $ENV{LatestBuildFile}=$outfile;
131 $self->{switch}->parse("makebuild"); # sort out supported tags
132 close GNUmakefile;
133 }
134
135 sub ParseBuildFile {
136 my $self=shift;
137 my $base=shift;
138 my $path=shift;
139 my $filename=shift @_;
140 my $fullfilename;
141 if ( $filename!~/^\// ) {
142 $fullfilename="$base/$path/$filename";
143 }
144 else {
145 $fullfilename=$filename;
146 }
147 $self->{path}=$path;
148 #print "Processing $fullfilename\n";
149 $numbins=0;
150 $self->{envnum}=0;
151 $self->{envlevel}=0;
152 $self->{currentenv}="$ENV{LOCALTOP}/$ENV{INTwork}/$self->{path}/".
153 "BuildFile.mk";
154 $self->{switch}=$self->_initswitcher();
155 $self->{switch}->filetoparse($fullfilename);
156
157 # $self->{switch}->{Strict_no_cr}='no';
158 #open a temporary gnumakefile to store output.
159 use Utilities::AddDir;
160 AddDir::adddir("$ENV{LOCALTOP}/$ENV{INTwork}/$self->{path}");
161 my $fh=FileHandle->new();
162 open ( $fh, ">$ENV{LOCALTOP}/$ENV{INTwork}/".$self->{path}."/BuildFile.mk"
163 ) or die 'Unable to open /$ENV{INTwork}/".$self->{path}."/BuildFile.mk $!\n';
164 @{$self->{filehandlestack}}=($fh);
165 # make an alias
166 *GNUmakefile=$fh;
167 if ( -e $ENV{LatestBuildFile} ) {
168 print GNUmakefile "include $ENV{LatestBuildFile}\n";
169 }
170 # print "writing to :\n".
171 # "$ENV{LOCALTOP}/$ENV{INTwork}/$self->{path}/BuildFile.mk\n";
172 $ENV{LatestBuildFile}="$ENV{LOCALTOP}/$ENV{INTwork}/".$self->{path}."/BuildFile.mk";
173 $self->{switch}->parse("makebuild"); # sort out supported tags
174 if ( $numbins > 0 ) {
175 print GNUmakefile <<ENDTEXT;
176 ifndef BINMODE
177 help::
178 \t\@echo Generic Binary targets
179 \t\@echo ----------------------
180 endif
181 ENDTEXT
182 foreach $target ( keys %$targettypes ) {
183 print GNUmakefile <<ENDTEXT;
184 ifndef BINMODE
185 help::
186 \t\@echo $target
187 endif
188 ENDTEXT
189 }
190 }
191 close GNUmakefile;
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 $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="$ENV{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+=$ENV{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("$ENV{LOCALTOP}/$ENV{INTwork}/".$self->{path}."/$dirname");
436 open (binGNUmakefile,
437 ">$ENV{LOCALTOP}/$ENV{INTwork}/".$self->{path}."/$dirname/BuildFile.mk") or die "Unable to make $ENV{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 "$ENV{LOCALTOP}/$ENV{INTwork}/$self->{path}/$dirname" ]; then \\
454 cd $ENV{LOCALTOP}/$ENV{INTwork}/$self->{path}/$dirname; \\
455 \$(MAKE) BINMODE=true LatestBuildFile=$ENV{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 "$ENV{LOCALTOP}/$ENV{INTwork}/$self->{path}/$dirname" ]; then \\
461 cd $ENV{LOCALTOP}/$ENV{INTwork}/$self->{path}/$dirname; \\
462 \$(MAKE) BINMODE=true LatestBuildFile=$ENV{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+=$ENV{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 sub CheckBuildFile {
682 my $self=shift;
683 my $classdir=shift;
684 my $ClassName="";
685 my $thisfile="$classdir/$buildfile";
686
687 if ( -e $ENV{LOCALTOP}."/".$thisfile ) {
688 $DefaultBuildfile="$ENV{LOCALTOP}/$thisfile";
689 $self->ParseBuildFile($ENV{LOCALTOP}, $classdir, $buildfile);
690 }
691 elsif ( -e $ENV{RELEASETOP}."/".$thisfile ) {
692 $DefaultBuildfile="$ENV{RELEASETOP}/$thisfile";
693 $self->ParseBuildFile($ENV{RELEASETOP}, $classdir, $buildfile);
694 }
695 return $ClassName;
696 }
697
698 # List association groups between <AssociateGroup> tags
699 # seperated by newlines or spaces
700 sub AssociateGroup {
701 my $self=shift;
702 my $name=shift;
703 my $string=shift;
704 my $word;
705
706 if ( $self->{Arch} ) {
707 foreach $word ( (split /\s/, $string) ){
708 chomp $word;
709 next if /^#/;
710 if ( $word=~/none/ ) {
711 $self->{ignore}=1;
712 }
713 }
714 }
715 }
716
717 sub Arch_Start {
718 my $self=shift;
719 my $name=shift;
720 my $hashref=shift;
721
722 $self->{switch}->checktag($name, $hashref,'name');
723 ( ($ENV{SCRAM_ARCH}=~/$$hashref{name}.*/) )? ($self->{Arch}=1)
724 : ($self->{Arch}=0);
725 push @{$self->{ARCHBLOCK}}, $self->{Arch};
726 }
727
728 sub Arch_End {
729 my $self=shift;
730 my $name=shift;
731
732 pop @{$self->{ARCHBLOCK}};
733 $self->{Arch}=$self->{ARCHBLOCK}[$#{$self->{ARCHBLOCK}}];
734 }
735
736 # Split up the Class Block String into a useable array
737 sub _CutBlock {
738 my $self=shift;
739 my $string= shift @_;
740 @BlockClassA = split /\//, $string;
741 }
742
743 sub OutToMakefile {
744 my $self=shift;
745 my $name=shift;
746 my @vars=@_;
747
748 if ( $self->{Arch} ) {
749 print GNUmakefile @vars;
750 }
751 }
752
753 sub OutToScreen {
754 my $name=shift;
755 my @vars=@_;
756
757 if ( $self->{Arch} ) {
758 print @vars;
759 }
760 }
761 sub setBlockClassPath {
762 my $self=shift;
763 my $name=shift;
764 my $hashref=shift;
765
766 $self->{switch}->checktag($name, $hashref, 'path');
767 $self->{BlockClassPath}=$self->{BlockClassPath}.":".$$hashref{path};
768 $self->_CutBlock($$hashref{path});
769 }
770
771 sub BlockClassPath {
772 my $self=shift;
773 return $self->{BlockClassPath};
774 }
775
776 sub export_start_export {
777 my $self=shift;
778 my $name=shift;
779 my $hashref=shift;
780
781 $self->{switch}->opengroup("__export");
782 }
783
784 sub export_start {
785 my $self=shift;
786 my $name=shift;
787 my $hashref=shift;
788
789 $self->{switch}->opengroup("__export");
790 if ( exists $$hashref{autoexport} ) {
791 print GNUmakefile "scram_autoexport=".$$hashref{autoexport}."\n";
792 if ( $$hashref{autoexport}=~/true/ ) {
793 $self->{switch}->allowgroup("__export","makebuild");
794 }
795 else {
796 $self->{switch}->disallowgroup("__export","makebuild");
797 }
798 }
799 # -- allow default setting from other makefiles
800 print GNUmakefile "ifeq (\$(scram_autoexport),true)\n";
801 }
802
803 sub export_end_export {
804 my $self=shift;
805 $self->{switch}->closegroup("__export");
806 }
807
808 sub export_end {
809 my $self=shift;
810 $self->{switch}->closegroup("__export");
811 print GNUmakefile "endif\n";
812 }
813
814 #
815 # Standard lib tag
816 #
817 sub lib_start {
818 my $self=shift;
819 my $name=shift;
820 my $hashref=shift;
821
822 $self->{switch}->checktag($name, $hashref, 'name');
823 if ( $self->{Arch} ) {
824 print GNUmakefile "lib+=$$hashref{name}\n";
825 }
826 }
827
828 #
829 # libtype specification
830 #
831 sub LibType_Start {
832 my $self=shift;
833 my $name=shift;
834 my $hashref=shift;
835
836 if ( $self->{Arch} ) {
837 if ( defined $self->{libtype_conext} ) {
838 $self->{switch}->parseerror("<$name> tag cannot be specified".
839 " without a </$name> tag to close previous context");
840 }
841 else {
842 $self->{libtype_conext}=1;
843 $self->{switch}->checktag($name, $hashref, 'type');
844
845 print GNUmakefile "# Specify Library Type\n";
846 print GNUmakefile "DefaultLibsOff=yes\n";
847 if ( $$hashref{'type'}=~/^archive/i ) {
848 print GNUmakefile "LibArchive=true\n";
849 }
850 elsif ($$hashref{'type'}=~/debug_archive/i ) {
851 print GNUmakefile "LibDebugArchive=true\n";
852 }
853 elsif ($$hashref{'type'}=~/debug_shared/i ) {
854 print GNUmakefile "LibDebugShared=true\n";
855 }
856 elsif ($$hashref{'type'}=~/shared/i ) {
857 print GNUmakefile 'LibShared=true'."\n";
858 }
859 print GNUmakefile "\n";
860 }
861 }
862 }
863
864 sub LibType_text {
865 my $self=shift;
866 my $name=shift;
867 my $string=shift;
868
869 if ( $self->{Arch} ) {
870 $string=~s/\n/ /g;
871 print GNUmakefile "libmsg::\n\t\@echo Library info: ";
872 print GNUmakefile $string;
873 print GNUmakefile "\n";
874 }
875 }
876
877 sub LibType_end {
878 my $self=shift;
879 my $name=shift;
880
881 undef $self->{libtype_conext};
882 }
883
884 sub Environment_start {
885 my $self=shift;
886 my $name=shift;
887 my $hashref=shift;
888
889 if ( $self->{Arch} ) {
890 $self->{envnum}++;
891
892 # open a new Environment File
893 my $envfile="$ENV{LOCALTOP}/$ENV{INTwork}/$self->{path}/Env_".
894 $self->{envnum}.".mk";
895 use FileHandle;
896 my $fh=FileHandle->new();
897 open ($fh,">$envfile") or die "Unable to open file $envfile \n$!\n";
898 push @{$self->{filehandlestack}}, $fh;
899 *GNUmakefile=$fh;
900
901 # include the approprate environment file
902 if ( $self->{envlevel} == 0 ) {
903 print GNUmakefile "include $ENV{LOCALTOP}/$ENV{INTwork}/".
904 $self->{path}."/BuildFile.mk\n";
905 }
906 else {
907 print GNUmakefile "include $ENV{LOCALTOP}/$ENV{INTwork}/".
908 $self->{path}."/Env_".$self->{Envlevels}[$self->{envlevel}].".mk\n";
909 }
910 $self->{envlevel}++;
911 $self->{Envlevels}[$self->{envlevel}]=$self->{envnum};
912 $self->{currentenv}="$ENV{LOCALTOP}/$ENV{INTwork}/$self->{path}/Env_$self->{envnum}.mk";
913 }
914 }
915
916 sub Environment_end {
917 my $self=shift;
918 my $fd;
919
920 if ( $self->{Arch} ) {
921 $self->{envlevel}--;
922 if ( $self->{envlevel} < 0 ) {
923 print "Too many </Environent> Tags on $self->{switch}->line()\n";
924 exit 1;
925 }
926 close GNUmakefile;
927 # restore the last filehandle
928 $fd=pop @{$self->{filehandlestack}};
929 close $fd;
930 *GNUmakefile=$self->{filehandlestack}[$#{$self->{filehandlestack}}];
931 if ( $self->{envlevel} < 1 ) {
932 $self->{currentenv}="$ENV{LOCALTOP}/$ENV{INTwork}/$self->{path}/".
933 "BuildFile.mk";
934 }
935 else {
936 $self->{currentenv}=
937 "$ENV{LOCALTOP}/$ENV{INTwork}/$self->{path}/Env_".
938 $self->{Envlevels}[$self->{envlevel}];
939 }
940 }
941 }