ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/BuildFile.pm
Revision: 1.1.2.13
Committed: Wed Jun 7 12:01:09 2000 UTC (24 years, 11 months ago) by williamc
Content type: text/plain
Branch: V0_9branch
Changes since 1.1.2.12: +1 -1 lines
Log Message:
Generalise rules for Build target to use Env variable THISDIR rather than the current bilding dir

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