ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/BuildFile.pm
Revision: 1.10
Committed: Sat Oct 14 17:29:05 2000 UTC (24 years, 6 months ago) by williamc
Content type: text/plain
Branch: MAIN
Changes since 1.9: +219 -26 lines
Log Message:
Added new routines for Block handling

File Contents

# Content
1 # BuildFile
2 #
3 # Interface
4 # ---------
5 # new(ConfigArea)
6 # ParseBuildFile($base,$path,$file)
7 # ParseBuildFileExport(filename)
8 # BlockParse(Block) : perform a parse to modify the block
9 # BlockClassPath() : Return the class path
10 # ignore() : return 1 if directory should be ignored 0 otherwise
11 # classname() : get/set the associated class
12 # buildfile() : get/set BuildFile location
13 # makefile() : get the generated makefile
14
15 package BuildSystem::BuildFile;
16 use ActiveDoc::SimpleDoc;
17 use BuildSystem::ToolBox;
18 require 5.004;
19
20 BEGIN {
21 $buildfile="BuildFile";
22 }
23
24 sub new {
25 my $class=shift;
26 my $self={};
27 bless $self, $class;
28 $self->{area}=shift;
29 $self->{toolbox}=$self->{area}->toolbox();
30 $self->{localtop}=$self->{area}->location();
31 # -- set RELEASTOP
32 my $rarea=$self->{area}->linkarea();
33 if ( ! defined $rarea ) {
34 $self->{releasetop}=$self->{localtop};
35 }
36 else {
37 $self->{releasetop}=$rarea->location();
38 }
39 $self->{releasetop}=$self->{area}->location();
40 $self->{Arch}=1;
41 push @{$self->{ARCHBLOCK}}, $self->{Arch};
42 return $self;
43 }
44
45 sub buildfile {
46 my $self=shift;
47 if ( @_ ) {
48 $self->{buildfile}=shift;
49 }
50 return $self->{buildfile};
51 }
52
53 sub makefile {
54 my $self=shift;
55 if ( @_ ) {
56 $self->{makefile}=shift;
57 }
58 return $self->{makefile};
59 }
60
61 sub BlockParse {
62 my $self=shift;
63 $self->{block}=shift;
64
65 # -- set up the block parse
66 my $switch=$self->_initswitcher();
67 my $parse="block";
68 $switch->newparse($parse);
69 $switch->addignoretags($parse);
70 $switch->addtag($parse,"BuildParam", \&BuildBlock_start, $self);
71
72 # -- parse away
73 $self->{switch}->parse("block");
74 }
75
76 sub Parsetofh {
77 my $self=shift;
78 my $fh=shift;
79 $self->{buildblock}=shift;
80
81 # -- set up for parse
82 @{$self->{filehandlestack}}=($fh);
83 $self->{switch}->filetoparse($self->buildfile());
84 *GNUmakefile=$fh;
85
86 # -- generate makefile
87 $self->{switch}->parse("makebuild"); # sort out supported tags
88
89 # -- Clean up
90 close GNUmakefile;
91 }
92
93 sub ignore {
94 my $self=shift;
95 return (defined $self->{ignore})?$self->{ignore}:0;
96 }
97
98 sub _initswitcher {
99 my $self=shift;
100 my $switch=ActiveDoc::SimpleDoc->new();
101 my $parse="makebuild";
102 $switch->newparse($parse);
103 $switch->addignoretags($parse);
104 $self->_commontags($switch,$parse);
105 #$switch->addtag($parse,"Build", \&Build_start, $self);
106 $switch->addtag($parse,"none",
107 \&OutToMakefile,$self,
108 \&OutToMakefile, $self,
109 "", $self);
110 $switch->addtag($parse,"Bin",
111 \&Bin_start,$self,
112 \&OutToScreen, $self,
113 "", $self);
114 $switch->addtag($parse,"ProductStore",
115 \&Store_start,$self,
116 "", $self,
117 "", $self);
118 $switch->addtag($parse,"LibType",
119 \&LibType_Start,$self,
120 \&LibType_text, $self,
121 \&LibType_end,$self);
122 $switch->addtag($parse,"ConfigurationClass",
123 \&Class_StartTag,$self,
124 \&OutToMakefile, $self,
125 "", $self);
126 $switch->addtag($parse,"ClassPath",
127 \&setBlockClassPath,$self,
128 \&OutToMakefile, $self,
129 "", $self);
130 $switch->addtag($parse,"AssociateGroup",
131 "",$self,
132 \&AssociateGroup,$self,
133 "", $self);
134 $switch->addtag($parse,"Environment",
135 \&Environment_start,$self,
136 \&OutToMakefile, $self,
137 \&Environment_end,$self);
138 $switch->addtag($parse,"Export",
139 \&export_start,$self,
140 \&OutToMakefile, $self,
141 \&export_end,$self);
142 return $switch;
143 }
144
145 sub _commontags {
146 my $self=shift;
147 my $switch=shift;
148 my $parse=shift;
149
150 $switch->grouptag("Export",$parse);
151 $switch->addtag($parse,"Use",\&Use_start,$self,
152 \&OutToMakefile, $self,
153 "", $self);
154 $switch->addtag($parse,"Group",\&Group_start,$self,
155 \&OutToMakefile, $self,
156 "", $self);
157 $switch->grouptag("Group",$parse);
158 $switch->addtag($parse,"External",
159 \&External_StartTag,$self,
160 \&OutToMakefile, $self,
161 "", $self);
162 $switch->addtag($parse,"lib",
163 \&lib_start,$self,
164 \&OutToMakefile, $self,
165 "", $self);
166 $switch->addtag($parse,"Architecture",
167 \&Arch_Start,$self,
168 \&OutToMakefile, $self,
169 \&Arch_End,$self);
170 $switch->addtag($parse,"INCLUDE_PATH",
171 \&IncludePath_Start,$self,
172 \&OutToMakefile, $self,
173 "",$self);
174 return $switch;
175 }
176
177 sub GenerateMakefile {
178 my $self=shift;
179 my $infile=shift;
180 my $outfile=shift;
181
182 $self->{switch}=$self->_initswitcher();
183 $self->{switch}->filetoparse($infile);
184
185 # open a temporary gnumakefile to store output.
186 my $fh=FileHandle->new();
187 open ( $fh, ">$outfile") or die "Unable to open $outfile for output ".
188 "$!\n";
189 @{$self->{filehandlestack}}=($fh);
190
191 # -- make an alias
192 *GNUmakefile=$fh;
193 if ( -e $ENV{LatestBuildFile} ) {
194 print GNUmakefile "include $ENV{LatestBuildFile}\n";
195 }
196 $self->{switch}->parse("makebuild"); # sort out supported tags
197 close GNUmakefile;
198 return $outfile;
199 }
200
201 sub ParseBuildFile {
202 my $self=shift;
203 my $base=shift;
204 my $path=shift;
205 my $filename=shift @_;
206 my $fullfilename;
207 if ( $filename!~/^\// ) {
208 $fullfilename="$base/$path/$filename";
209 }
210 else {
211 $fullfilename=$filename;
212 }
213 $self->{path}=$path;
214 #print "Processing $fullfilename\n";
215 $numbins=0;
216 $self->{envnum}=0;
217 $self->{envlevel}=0;
218 $self->{makefile}="$self->{localtop}/$ENV{INTwork}/$self->{path}/".
219 "BuildFile.mk";
220 $self->{currentenv}=$self->{makefile};
221 $self->{switch}=$self->_initswitcher();
222 $self->{switch}->filetoparse($fullfilename);
223
224 # $self->{switch}->{Strict_no_cr}='no';
225 #open a temporary gnumakefile to store output.
226 use Utilities::AddDir;
227 AddDir::adddir("$self->{localtop}/$ENV{INTwork}/$self->{path}");
228 $ENV{LatestBuildFile}=$self->GenerateMakefile($fullfilename,
229 $self->{localtop}."/".$ENV{INTwork}."/".$self->{path}."/BuildFile.mk");
230 }
231
232 sub classname {
233 my $self=shift;
234 if ( @_ ) {
235 $self->{classname}=shift;
236 }
237 return $self->{classname};
238 }
239
240 sub ParseBuildFile_Export {
241 my $self=shift;
242 my $filename=shift;
243 my $bf=BuildSystem::BuildFile->new($self->{area});
244 if ( defined $self->{remoteproject} ) {
245 $bf->{remoteproject}=$self->{remoteproject};
246 }
247 $bf->_parseexport($filename);
248 undef $bf;
249 }
250
251 sub _location {
252 my $self=shift;
253 use File::Basename;
254
255 return dirname($self->{switch}->filetoparse());
256 }
257
258 sub _parseexport {
259 my $self=shift;
260 my $filename=shift;
261
262 my $switchex=ActiveDoc::SimpleDoc->new();
263 $switchex->filetoparse($filename);
264 $switchex->newparse("export");
265 $switchex->addignoretags("export");
266 $switchex->addtag("export","Export",
267 \&export_start_export,$self,
268 \&OutToMakefile, $self,
269 \&export_end_export,$self);
270 $self->_commontags($switchex,"export");
271 $switchex->allowgroup("__export","export");
272 # $switchex->{Strict_no_cr}='no';
273 $self->{switch}=$switchex;
274 $switchex->parse("export"); # sort out supported tags
275 }
276
277 sub _pushremoteproject {
278 my $self=shift;
279 my $path=shift;
280
281 if ( defined $self->{remoteproject} ) {
282 push @{$self->{rpstack}}, $self->{remoteproject};
283 }
284 $self->{remoteproject}=$path;
285 }
286
287 sub _popremoteproject {
288 my $self=shift;
289 if ( $#{$self->{rpstack}} >=0 ) {
290 $self->{remoteproject}=pop @{$self->{rpstack}};
291 }
292 else {
293 undef $self->{remoteproject};
294 }
295 }
296
297 sub _toolmapper {
298 my $self=shift;
299 if ( ! defined $self->{mapper} ) {
300 require BuildSystem::ToolMapper;
301 $self->{mapper}=BuildSystem::ToolMapper->new();
302 }
303 return $self->{mapper};
304 }
305
306
307 # ---- Tag routines
308
309 #-- Override a class type with the <ConfigurationClass type=xxx> tag
310 # the type tag will pick up a pre-defined class type from project space.
311
312 sub Class_StartTag {
313 my $self=shift;
314 my $name=shift;
315 my $hashref=shift;
316
317 if ( $self->{Arch} ) {
318 if ( defined $$hashref{'type'} ) {
319 $self->classname($$hashref{'type'});
320 }
321 }
322 }
323
324 sub IncludePath_Start {
325 my $self=shift;
326 my $name=shift;
327 my $hashref=shift;
328
329 $self->{switch}->checktag( $name, $hashref, 'path');
330 if ( $self->{Arch} ) {
331 print GNUmakefile "INCLUDE+=".$self->_location()."/".
332 $$hashref{'path'}."\n";
333 }
334 }
335
336 #
337 # --- <Build class=> tag
338 #
339
340 #
341 # Parameter collection
342 #
343 sub BuildBlock_start {
344 my $self=shift;
345 my $name=shift;
346 my $hashref=shift;
347
348
349 my $blockobjid=$self->__blockobjid($hashref);
350
351 if ( $self->{Arch} ) {
352
353
354 # -- get any objects that match
355 my $inheritobj=$self->{block}->getobj($blockobjid);
356
357 # -- create an object with inherited properties
358 my $obj;
359 if ( ! defined $inheritobj ) {
360 # -- check we have a lookup for the class type
361 my $mapper=$self->_toolmapper();
362 if ( ! $mapper->exists($$hashref{'class'}) ) {
363 $self->{switch}->parseerror("Unknown class : ".
364 $$hashref{'class'});
365 }
366 $obj=BuildSystem::BuildClass->new();
367 }
368 else {
369 # -- inherit the properties from class with the same id class
370 $obj=$inheritobj->child();
371 }
372
373 # -- add changes from our tag
374 $obj->paramupdate($hashref);
375
376 # -- store the new object in the block
377 $self->{block}->setobj($obj,$blockobjid);
378 }
379 }
380
381 sub BuilderClass_buildmakefile {
382 my $self=shift;
383 my $name=shift;
384 my $hashref=shift;
385
386 my $blockobjid=$self->__blockobjid($hashref);
387
388 if ( $self->{Arch} ) {
389 # -- get the matching block object
390 my $blockobj=$self->{buildblock}->getobj($blockobjid);
391
392 # -- top level buildfile
393 my $fh=$self->{filehandlestack}[0];
394
395 # -- var initialisation
396 my @deftypes=();
397 my $buildname="";
398 my @types=$self->_toolmapper()->types($$hashref{'class'});
399
400 # -- error checking
401 if ( ! defined $blockobj->param("default") ) {
402 $self->error("No default build parameter defined for ".
403 $$hashref{'class'}." ".$$hashref{'id'});
404 }
405 if ( ! defined $blockobj->param("name") ) {
406 $self->error("\"name\" parameter defined for ".
407 $$hashref{'class'}." ".$$hashref{'id'});
408 }
409
410
411 foreach $param ( $blockobj->paramlist() ) {
412 # -- check for params that need special handling
413 if ( $param eq "default" ) {
414 @deftypes=split /,/, $param;
415 }
416 elsif ( $param eq "name" ) {
417 $buildname=$blockobj->param($param);
418 }
419 else {
420 # -- simple transfer of block object parameters to makefile
421 print $fh $param.":=".$blockobj->param($param)."\n";
422 }
423 }
424
425 # -- construct the targets in the top makefile
426 $self->_generatedefaulttargets($fh,$$hashref{'class'},@deftypes);
427 $self->_generatetypetargets($fh,$$hashref{'class'},$buildname,@types);
428
429 }
430 }
431
432 sub _blockobjid {
433 my $self=shift;
434 my $hashref=shift;
435
436 $self->{switch}->checktag($name,$hashref,'class');
437 $self->{switch}->checktag($name,$hashref,'id');
438 my $blockobjid="bc_".$$hashref{'class'},"_".$$hashref{'id'};
439
440 return $blockobjid;
441 }
442
443 sub _generatedefaulttargets {
444 my $self=shift;
445 my $fh=shift;
446 my $class=shift;
447
448 my @deftypes=shift;
449
450 print $fh "# -- Default type targets\n";
451 foreach $dtype ( @deftypes ) {
452 print $fh $class."::".$class."_".$dtype."\n";
453 }
454 print $fh "\n";
455 }
456
457 sub _generatetypetargets {
458 my $self=shift;
459 my $fh=shift;
460 my $class=shift;
461 my $name=shift;
462
463 my @types=shift;
464
465 print $fh "# -- Generic type targets\n";
466 foreach $type ( @types ) {
467 my $pattern=$class."_".$type;
468 my $dirname=$class."_".$type."_".$name;
469 my $makefile=$here."/BuildFile.mk";
470
471 # -- map to generic name for each type
472 print $fh "# ------ $pattern rules ---------------\n";
473 print $fh $class."_".$type."::".$class.
474 "_".$type."_$name\n\n";
475
476 print $fh "# -- Link Targets to $type directories\n";
477 print $fh "$dirname: make_$dirname\n";
478 print $fh "\t\@cd $here; \\\n";
479 print $fh "\t\$(MAKE) LatestBuildFile=$makefile _BuildLink_=1".
480 " workdir=$here ".
481 " -f \$(TOOL_HOME)/basics.mk datestamp \$\@; \n\n";
482
483 # -- write target to make makefile for each directory
484 print $fh "# -- Build target directories\n";
485 print $fh "make_$dirname:\n";
486 print $fh "\tif [ ! -e \"$makefile\" ]; then \\\n";
487 print $fh "\t if [ ! -d \"$here\" ]; then \\\n";
488 print $fh "\t mkdir $here; \\\n";
489 print $fh "\t fi;\\\n";
490 print $fh "\t cd $dirname; \\\n";
491 print $fh "\t echo include ".$self->{currentenv}." > ".
492 "$makefile; \\\n";
493 print $fh "\t echo VPATH+=$self->{localtop}/".$self->{path}.
494 " >> $makefile; \\\n";
495 print $fh "\t echo buildname=$name >> $makefile;\\\n";
496 print $fh "\t echo ".$dirname.":".$pattern." >> $makefile;\\\n";
497 if ( defined (my @file=$mapper->rulesfile($class)) ) {
498 foreach $f ( @file ) {
499 print $fh "\t echo -include $f >> $makefile; \\\n";
500 }
501 }
502 print $fh "\tfi\n";
503 print $fh "\n";
504
505 # -- cleaning targets
506 push @targets, "clean_$dirname";
507 print $fh "# -- cleaning targets\n";
508 print $fh "clean::clean_$dirname\n";
509 print $fh "clean_".$dirname."::\n";
510 print $fh "\t\@echo cleaning $dirname\n";
511 print $fh "\t\@if [ -d $here ]; then \\\n";
512 print $fh "\tcd $here; \\\n";
513 print $fh "\t\$(MAKE) LatestBuildFile=$makefile workdir=".
514 $here." _BuildLink_=1 -f ".
515 "\$(TOOL_HOME)/basics.mk clean; \\\n";
516 print $fh "\tfi\n\n";
517
518 }
519 print $fh "\n";
520 }
521
522 #
523 # generic build tag
524 #
525 sub Build_start {
526 my $self=shift;
527 my $name=shift;
528 my $hashref=shift;
529
530 $self->{switch}->checktag($name,$hashref,'class');
531 $self->{switch}->checktag($name,$hashref,'id');
532 if ( $self->{Arch} ) {
533
534 # -- determine the build products name
535 my $name;
536 if ( exists $$hashref{'name'} ) {
537 $name=$$hashref{'name'};
538 }
539 else {
540 $self->{switch}->parseerror("No name specified for build product");
541 #$name="\$(buildname)";
542 }
543
544 # -- check we have a lookup for the class type
545 my $mapper=$self->_toolmapper();
546 if ( ! $mapper->exists($$hashref{'class'}) ) {
547 $self->{switch}->parseerror("Unknown class : ".$$hashref{'class'});
548 }
549 else {
550 my @types=$self->_toolmapper()->types($$hashref{'class'});
551 my @deftypes=$self->_toolmapper()->defaulttypes($$hashref{'class'});
552
553 my $fh=$self->{filehandlestack}[0];
554 my @targets=();
555
556 # -- generate generic targets
557 print $fh "ifndef _BuildLink_\n";
558 $self->_generatedefaulttargets($fh,$$hashref{'class'},@deftypes);
559
560 push @targets, $$hashref{'class'};
561
562 # -- generate targets for each type
563 foreach $type ( @types ) {
564
565 # -- generic name for each type
566 my $pattern=$$hashref{'class'}."_".$type;
567 my $dirname=$$hashref{'class'}."_".$type."_".$name;
568 print $fh "# ------ $pattern rules ---------------\n";
569 print $fh $$hashref{'class'}."_".$type."::".$$hashref{'class'}.
570 "_".$type."_$name\n\n";
571
572 # -- create a new directory for each type
573 push @targets, $pattern;
574 my $dirname=$$hashref{'class'}."_".$type."_".$name;
575 my $here="$self->{localtop}/$ENV{INTwork}/".$self->{path}.
576 "/".$dirname;
577 my $makefile=$here."/BuildFile.mk";
578 # AddDir::adddir($here);
579
580 # -- create link targets to the directory
581 push @targets, $dirname;
582 print $fh "# -- Link Targets to $type directories\n";
583 print $fh "$dirname: make_$dirname\n";
584 print $fh "\t\@cd $here; \\\n";
585 print $fh "\t\$(MAKE) LatestBuildFile=$makefile _BuildLink_=1".
586 " workdir=$here ".
587 " -f \$(TOOL_HOME)/basics.mk datestamp \$\@; \n\n";
588
589 # -- write target to make makefile for each directory
590 print $fh "# -- Build target directories\n";
591 print $fh "make_$dirname:\n";
592 print $fh "\tif [ ! -e \"$makefile\" ]; then \\\n";
593 print $fh "\t if [ ! -d \"$here\" ]; then \\\n";
594 print $fh "\t mkdir $here; \\\n";
595 print $fh "\t fi;\\\n";
596 print $fh "\t cd $dirname; \\\n";
597 print $fh "\t echo include ".$self->{currentenv}." > ".
598 "$makefile; \\\n";
599 print $fh "\t echo VPATH+=$self->{localtop}/".$self->{path}.
600 " >> $makefile; \\\n";
601 print $fh "\t echo buildname=$name >> $makefile;\\\n";
602 print $fh "\t echo ".$dirname.":".$pattern." >> $makefile;\\\n";
603 if ( defined (my @file=$mapper->rulesfile($$hashref{'class'})) ) {
604 foreach $f ( @file ) {
605 print $fh "\t echo -include $f >> $makefile; \\\n";
606 }
607 }
608 print $fh "\tfi\n";
609 print $fh "\n";
610 # print $typefile "$name :\n";
611 # print $typefile "\t\$(_quietbuild_)";
612 # print $typefile $mapper->template($$hashref{'class'},$type)."\n";
613 # print $typefile "\t\$(_quietstamp_)";
614 # print $typefile "\$(SCRAMPERL) \$(SCRAM_HOME)/src/scramdatestamp \$@.ds \$@ \$^\n";
615
616 # -- cleaning targets
617 push @targets, "clean_$dirname";
618 print $fh "# -- cleaning targets\n";
619 print $fh "clean::clean_$dirname\n";
620 print $fh "clean_".$dirname."::\n";
621 print $fh "\t\@echo cleaning $dirname\n";
622 print $fh "\t\@if [ -d $here ]; then \\\n";
623 print $fh "\tcd $here; \\\n";
624 print $fh "\t\$(MAKE) LatestBuildFile=$makefile workdir=".
625 $here." _BuildLink_=1 -f ".
626 "\$(TOOL_HOME)/basics.mk clean; \\\n";
627 print $fh "\tfi\n\n";
628
629
630 }
631 # -- help targets
632 print $fh "helpheader::\n";
633 print $fh "\t\@echo Targets available:\n";
634 print $fh "\t\@echo ------------------\n\n";
635 print $fh "help::helpheader\n";
636 foreach $target ( @targets ) {
637 print $fh "help::\n";
638 print $fh "\t\@echo $target\n"
639 }
640 print $fh "endif\n";
641 } # end else
642 }
643 }
644
645 sub Bin_start {
646 my $self=shift;
647 my $name=shift;
648 my $hashref=shift;
649
650 my $fileclass;
651 my @tools;
652 my $tool;
653 my $filename;
654 my $objectname;
655
656 $self->{switch}->checktag($name,$hashref,'file');
657 if ( $self->{Arch} ) {
658 if ( ! defined $$hashref{name} ) {
659 ($$hashref{name}=$$hashref{file})=~s/\..*//;
660 }
661 ($filename=$$hashref{file})=~s/\..*//;
662
663 # Create a new directory for each binary target
664 my $dirname="bin_".$$hashref{name};
665 AddDir::adddir("$self->{localtop}/$ENV{INTwork}/".$self->{path}."/$dirname");
666 open (binGNUmakefile,
667 ">$self->{localtop}/$ENV{INTwork}/".$self->{path}."/$dirname/BuildFile.mk") or die "Unable to make $self->{localtop}/$ENV{INTwork}/$self->{path}/$dirname/".
668 "BuildFile.mk $!\n";
669
670 # Create the link targets
671 $numbins++;
672 my $fh=$self->{filehandlestack}[0];
673 print $fh <<ENDTEXT;
674
675 # Link Targets to binary directories
676 ifdef BINMODE
677 # We dont want to build a library here
678 override files:=
679 endif
680 ifndef BINMODE
681
682 define stepdown_$$hashref{'name'}
683 if [ -d "$self->{localtop}/$ENV{INTwork}/$self->{path}/$dirname" ]; then \\
684 cd $self->{localtop}/$ENV{INTwork}/$self->{path}/$dirname; \\
685 \$(MAKE) BINMODE=true LatestBuildFile=$self->{localtop}/$ENV{INTwork}/$self->{path}/$dirname/BuildFile.mk workdir=\$(workdir)/$dirname -f \$(TOOL_HOME)/basics.mk datestamp \$\@; \\
686 fi
687 endef
688
689 define stepdown2_$$hashref{'name'}
690 if [ -d "$self->{localtop}/$ENV{INTwork}/$self->{path}/$dirname" ]; then \\
691 cd $self->{localtop}/$ENV{INTwork}/$self->{path}/$dirname; \\
692 \$(MAKE) BINMODE=true LatestBuildFile=$self->{localtop}/$ENV{INTwork}/$self{path}/$dirname/BuildFile.mk workdir=\$(workdir)/$dirname -f \$(TOOL_HOME)/basics.mk datestamp \$\*; \\
693 fi
694
695 endef
696
697 bin_$$hashref{'name'}_%:: dummy
698 \@\$(stepdown2_$$hashref{'name'})
699
700 $$hashref{'name'}_%:: dummy
701 \@\$(stepdown_$$hashref{'name'})
702
703 help bin bin_debug bin_debug_local bin_insure bin_Insure clean $$hashref{'name'}:: dummy
704 \@\$(stepdown_$$hashref{'name'})
705
706 binfiles+=$$hashref{'file'}
707 locbinfiles+=$dirname/$$hashref{'file'}
708 endif
709
710
711 ENDTEXT
712
713
714 # the binary specifics makefile
715 print binGNUmakefile "include ".$self->{currentenv}."\n";
716 print binGNUmakefile "VPATH+=".$self->{localtop}."/$self{path}\n";
717
718 # alias for bin_Insure
719 print binGNUmakefile <<ENDTEXT;
720
721 bin_insure:bin_Insure
722 ifdef MAKETARGET_bin_insure
723 MAKETARGET_$$hashref{name}_Insure=1
724 endif
725
726 # debuggging target
727 $$hashref{'name'}_echo_% :: echo_%
728
729 # help targets
730 help::
731 \t\@echo Targets For $$hashref{'name'}
732 \t\@echo -------------------------------------
733 \t\@echo $$hashref{'name'} - default build
734 \t\@echo bin_$$hashref{'name'}_clean - executable specific cleaning
735 ENDTEXT
736
737 # Make generic rules for each type
738 $targettypes={
739 "bin" => 'o',
740 "bin_debug" => 'd',
741 "bin_debug_local" => 'l_d',
742 "bin_Insure" => 'Insure'
743 };
744 #
745 foreach $target ( keys %$targettypes ) {
746 print binGNUmakefile <<ENDTEXT;
747
748 # Type $target specifics
749 ifdef MAKETARGET_$target
750 MAKETARGET_$$hashref{name}_$$targettypes{$target}=1
751 endif
752 $target ::$$hashref{name}_$$targettypes{$target}
753
754 bintargets+=$$hashref{name}_$$targettypes{$target}
755 help::
756 \t\@echo $$hashref{name}_$$targettypes{$target}
757 clean::
758 \t\@if [ -f \$(binarystore)/$$hashref{name}_$$targettypes{$target} ]; then \\
759 \techo Removing \$(binarystore)/$$hashref{name}; \\
760 \trm \$(binarystore)/$$hashref{name}_$$targettypes{$target}; \\
761 \tfi
762
763 ENDTEXT
764 ($objectname=$$hashref{file})=~s/\..*/_$$targettypes{$target}\.o/;
765 ${"objectname_$$targettypes{$target}"}=$objectname;
766 print binGNUmakefile "$objectname:$$hashref{name}.dep\n";
767 } # end loop
768
769 print binGNUmakefile "$$hashref{name}_Insure.exe:.psrc\n";
770 print binGNUmakefile "$$hashref{name}_d.exe:$objectname_d\n";
771 print binGNUmakefile "\t\$(CClinkCmdDebug)\n";
772 print binGNUmakefile "\t\@\$(SCRAMPERL) \$(SCRAM_HOME)/src/scramdatestamp \$\@\.ds \$\@ \$\^\n";
773 print binGNUmakefile "$$hashref{name}_l_d.exe:$objectname_d\n";
774 print binGNUmakefile "\t\$(CClinkCmdDebugLocal)\n";
775 print binGNUmakefile "\t\@\$(SCRAMPERL) \$(SCRAM_HOME)/src/scramdatestamp \$\@\.ds \$\@ \$\^\n";
776 print binGNUmakefile "$$hashref{name}_Insure.exe:$objectname_Insure\n";
777 print binGNUmakefile "\t\$(CClinkCmdInsure)\n";
778 print binGNUmakefile "\t\@\$(SCRAMPERL) \$(SCRAM_HOME)/src/scramdatestamp \$\@\.ds \$\@ \$\^\n";
779 print binGNUmakefile "$$hashref{name}_o.exe:$objectname_o\n";
780 print binGNUmakefile "\t\$(CClinkCmd)\n";
781 print binGNUmakefile "\t\@\$(SCRAMPERL) \$(SCRAM_HOME)/src/scramdatestamp \$\@\.ds \$\@ \$\^\n";
782 print binGNUmakefile "$$hashref{name}.dep:$$hashref{file}\n";
783 print binGNUmakefile "-include $$hashref{name}.dep\n";
784 print binGNUmakefile <<ENDTEXT;
785 clean::
786 \t\@if [ -f \$(binarystore)/$$hashref{name} ]; then \\
787 \techo Removing \$(binarystore)/$$hashref{name}; \\
788 \trm \$(binarystore)/$$hashref{name}; \\
789 \tfi
790
791 $$hashref{name}_d.exe:\$(libslocal_d)
792 $$hashref{name}_o.exe:\$(libslocal)
793 ifdef MCCABE_DATA_DIR
794 $$hashref{name}_mccabe.exe: \$(libslocal_d) \$(MCCABE_DATA_DIR)/mccabeinstr/instplus.cpp
795 endif
796 $$hashref{name}_Insure.exe:\$(libslocal_I)
797 $$hashref{name}_d:$$hashref{name}_d.exe
798 \@cp $$hashref{name}_d.exe \$(binarystore)/$$hashref{name}
799 $$hashref{name}_l_d:$$hashref{name}_l_d.exe
800 \@cp $$hashref{name}_l_d.exe \$(binarystore)/$$hashref{name}
801 $$hashref{name}_Insure:$$hashref{name}_Insure.exe
802 \@cp $$hashref{name}_Insure.exe \$(binarystore)/$$hashref{name}_Insure
803 $$hashref{name}:$$hashref{name}_d.exe
804 \@mv $$hashref{name}_d.exe \$(binarystore)/$$hashref{name}
805 $$hashref{name}_o:$$hashref{name}_o.exe
806 \@mv $$hashref{name}_o.exe \$(binarystore)/$$hashref{name}
807 binfiles+=$$hashref{file}
808 ENDTEXT
809 }
810 close binGNUmakefile;
811 }
812
813 sub External_StartTag {
814 my $self=shift;
815 my $name=shift;
816 my $hashref=shift;
817
818 my $tool;
819 if ( $self->{Arch} ) {
820 $self->{switch}->checktag($name,$hashref,'ref');
821
822 # -- oo toolbox stuff
823 # - get the appropriate tool object
824 $$hashref{'ref'}=~tr[A-Z][a-z];
825 if ( ! exists $$hashref{'version'} ) {
826 $tool=$self->{toolbox}->gettool($$hashref{'ref'});
827 }
828 else {
829 $tool=$self->{toolbox}->gettool($$hashref{'ref'},$$hashref{'version'});
830 }
831 if ( ! defined $tool ) {
832 $self->{switch}->parseerror("Unknown Tool Specified ("
833 .$$hashref{'ref'}.")");
834 }
835
836 # -- old fashioned GNUmakefile stuff
837 print GNUmakefile $$hashref{'ref'};
838 if ( defined $$hashref{'version'} ) {
839 print GNUmakefile "_V_".$$hashref{'version'};
840 }
841 print GNUmakefile "=true\n";
842
843 # -- Sub system also specified?
844 if ( exists $$hashref{'use'} ) {
845 # -- look for a buildfile
846 my @paths=$tool->getfeature("INCLUDE");
847 my $file="";
848 my ($path,$testfile);
849 foreach $path ( @paths ) {
850 $testfile=$path."/".$$hashref{'use'}."/BuildFile" ;
851 if ( -f $testfile ) {
852 $file=$testfile;
853 $self->_pushremoteproject($path);
854 }
855 }
856 if ( $file eq "" ) {
857 $self->{switch}->parseerror("Unable to find SubSystem $testfile");
858 }
859 $self->ParseBuildFile_Export($file);
860 $self->_popremoteproject();
861 }
862 }
863 }
864
865 sub Group_start {
866 my $self=shift;
867 my $name=shift;
868 my $hashref=shift;
869
870 $self->{switch}->checktag($name, $hashref, 'name');
871 if ( $self->{Arch} ) {
872 print GNUmakefile "GROUP_".$$hashref{'name'};
873 if ( defined $$hashref{'version'} ) {
874 print GNUmakefile "_V_".$$hashref{'version'};
875 }
876 print GNUmakefile "=true\n";
877 }
878 }
879
880 sub Use_start {
881 my $self=shift;
882 my $name=shift;
883 my $hashref=shift;
884 my $filename;
885 use Utilities::SCRAMUtils;
886
887 $self->{switch}->checktag($name, $hashref, "name");
888 if ( $self->{Arch} ) {
889 if ( exists $$hashref{'group'} ) {
890 print GNUmakefile "GROUP_".$$hashref{'group'}."=true\n";
891 }
892 if ( ! defined $self->{remoteproject} ) {
893 $filename=SCRAMUtils::checkfile(
894 "/$ENV{INTsrc}/$$hashref{name}/BuildFile");
895 }
896 else {
897 $filename=$self->{remoteproject}."/$$hashref{name}/BuildFile";
898 print "trying $filename\n";
899 if ( ! -f $filename ) { $filename=""; };
900 }
901 if ( $filename ne "" ) {
902 $self->ParseBuildFile_Export( $filename );
903 }
904 else {
905 $self->{switch}->parseerror("Unable to detect Appropriate ".
906 "decription file for <$name name=".$$hashref{name}.">");
907 }
908 }
909 }
910
911 # List association groups between <AssociateGroup> tags
912 # seperated by newlines or spaces
913 sub AssociateGroup {
914 my $self=shift;
915 my $name=shift;
916 my $string=shift;
917 my $word;
918
919 if ( $self->{Arch} ) {
920 foreach $word ( (split /\s/, $string) ){
921 chomp $word;
922 next if /^#/;
923 if ( $word=~/none/ ) {
924 $self->{ignore}=1;
925 }
926 }
927 }
928 }
929
930 sub Arch_Start {
931 my $self=shift;
932 my $name=shift;
933 my $hashref=shift;
934
935 $self->{switch}->checktag($name, $hashref,'name');
936 ( ($ENV{SCRAM_ARCH}=~/$$hashref{name}.*/) )? ($self->{Arch}=1)
937 : ($self->{Arch}=0);
938 push @{$self->{ARCHBLOCK}}, $self->{Arch};
939 }
940
941 sub Arch_End {
942 my $self=shift;
943 my $name=shift;
944
945 pop @{$self->{ARCHBLOCK}};
946 $self->{Arch}=$self->{ARCHBLOCK}[$#{$self->{ARCHBLOCK}}];
947 }
948
949 # Split up the Class Block String into a useable array
950 sub _CutBlock {
951 my $self=shift;
952 my $string= shift @_;
953 @BlockClassA = split /\//, $string;
954 }
955
956 sub OutToMakefile {
957 my $self=shift;
958 my $name=shift;
959 my @vars=@_;
960
961 if ( $self->{Arch} ) {
962 print GNUmakefile @vars;
963 }
964 }
965
966 sub OutToScreen {
967 my $name=shift;
968 my @vars=@_;
969
970 if ( $self->{Arch} ) {
971 print @vars;
972 }
973 }
974 sub setBlockClassPath {
975 my $self=shift;
976 my $name=shift;
977 my $hashref=shift;
978
979 $self->{switch}->checktag($name, $hashref, 'path');
980 $self->{BlockClassPath}=$self->{BlockClassPath}.":".$$hashref{path};
981 $self->_CutBlock($$hashref{path});
982 }
983
984 sub BlockClassPath {
985 my $self=shift;
986 return $self->{BlockClassPath};
987 }
988
989 sub export_start_export {
990 my $self=shift;
991 my $name=shift;
992 my $hashref=shift;
993
994 $self->{switch}->opengroup("__export");
995 }
996
997 sub export_start {
998 my $self=shift;
999 my $name=shift;
1000 my $hashref=shift;
1001
1002 $self->{switch}->opengroup("__export");
1003 if ( exists $$hashref{autoexport} ) {
1004 print GNUmakefile "scram_autoexport=".$$hashref{autoexport}."\n";
1005 if ( $$hashref{autoexport}=~/true/ ) {
1006 $self->{switch}->allowgroup("__export","makebuild");
1007 }
1008 else {
1009 $self->{switch}->disallowgroup("__export","makebuild");
1010 }
1011 }
1012 # -- allow default setting from other makefiles
1013 print GNUmakefile "ifeq (\$(scram_autoexport),true)\n";
1014 }
1015
1016 sub export_end_export {
1017 my $self=shift;
1018 $self->{switch}->closegroup("__export");
1019 }
1020
1021 sub export_end {
1022 my $self=shift;
1023 $self->{switch}->closegroup("__export");
1024 print GNUmakefile "endif\n";
1025 }
1026
1027 #
1028 # Standard lib tag
1029 #
1030 sub lib_start {
1031 my $self=shift;
1032 my $name=shift;
1033 my $hashref=shift;
1034
1035 $self->{switch}->checktag($name, $hashref, 'name');
1036 if ( $self->{Arch} ) {
1037 print GNUmakefile "lib+=$$hashref{name}\n";
1038 }
1039 }
1040
1041 #
1042 # libtype specification
1043 #
1044 sub LibType_Start {
1045 my $self=shift;
1046 my $name=shift;
1047 my $hashref=shift;
1048
1049 if ( $self->{Arch} ) {
1050 if ( defined $self->{libtype_conext} ) {
1051 $self->{switch}->parseerror("<$name> tag cannot be specified".
1052 " without a </$name> tag to close previous context");
1053 }
1054 else {
1055 $self->{libtype_conext}=1;
1056 $self->{switch}->checktag($name, $hashref, 'type');
1057
1058 print GNUmakefile "# Specify Library Type\n";
1059 print GNUmakefile "DefaultLibsOff=yes\n";
1060 if ( $$hashref{'type'}=~/^archive/i ) {
1061 print GNUmakefile "LibArchive=true\n";
1062 }
1063 elsif ($$hashref{'type'}=~/debug_archive/i ) {
1064 print GNUmakefile "LibDebugArchive=true\n";
1065 }
1066 elsif ($$hashref{'type'}=~/debug_shared/i ) {
1067 print GNUmakefile "LibDebugShared=true\n";
1068 }
1069 elsif ($$hashref{'type'}=~/shared/i ) {
1070 print GNUmakefile 'LibShared=true'."\n";
1071 }
1072 print GNUmakefile "\n";
1073 }
1074 }
1075 }
1076
1077 sub LibType_text {
1078 my $self=shift;
1079 my $name=shift;
1080 my $string=shift;
1081
1082 if ( $self->{Arch} ) {
1083 $string=~s/\n/ /g;
1084 print GNUmakefile "libmsg::\n\t\@echo Library info: ";
1085 print GNUmakefile $string;
1086 print GNUmakefile "\n";
1087 }
1088 }
1089
1090 sub LibType_end {
1091 my $self=shift;
1092 my $name=shift;
1093
1094 undef $self->{libtype_conext};
1095 }
1096
1097 sub Environment_start {
1098 my $self=shift;
1099 my $name=shift;
1100 my $hashref=shift;
1101
1102 if ( $self->{Arch} ) {
1103 $self->{envnum}++;
1104
1105 # open a new Environment File
1106 my $envfile="$self->{localtop}/$ENV{INTwork}/$self->{path}/Env_".
1107 $self->{envnum}.".mk";
1108 use FileHandle;
1109 my $fh=FileHandle->new();
1110 open ($fh,">$envfile") or die "Unable to open file $envfile \n$!\n";
1111 push @{$self->{filehandlestack}}, $fh;
1112 *GNUmakefile=$fh;
1113
1114 # include the approprate environment file
1115 if ( $self->{envlevel} == 0 ) {
1116 print GNUmakefile "include $self->{localtop}/$ENV{INTwork}/".
1117 $self->{path}."/BuildFile.mk\n";
1118 }
1119 else {
1120 print GNUmakefile "include $self->{localtop}/$ENV{INTwork}/".
1121 $self->{path}."/Env_".$self->{Envlevels}[$self->{envlevel}].".mk\n";
1122 }
1123 $self->{envlevel}++;
1124 $self->{Envlevels}[$self->{envlevel}]=$self->{envnum};
1125 $self->{currentenv}="$self->{localtop}/$ENV{INTwork}/$self->{path}/Env_$self->{envnum}.mk";
1126 }
1127 }
1128
1129 sub Environment_end {
1130 my $self=shift;
1131 my $fd;
1132
1133 if ( $self->{Arch} ) {
1134 $self->{envlevel}--;
1135 if ( $self->{envlevel} < 0 ) {
1136 print "Too many </Environent> Tags on $self->{switch}->line()\n";
1137 exit 1;
1138 }
1139 close GNUmakefile;
1140 # restore the last filehandle
1141 $fd=pop @{$self->{filehandlestack}};
1142 close $fd;
1143 *GNUmakefile=$self->{filehandlestack}[$#{$self->{filehandlestack}}];
1144 if ( $self->{envlevel} < 1 ) {
1145 $self->{currentenv}="$self->{localtop}/$ENV{INTwork}/$self->{path}/".
1146 "BuildFile.mk";
1147 }
1148 else {
1149 $self->{currentenv}=
1150 $self->{localtop}."/$ENV{INTwork}/$self->{path}/Env_".
1151 $self->{Envlevels}[$self->{envlevel}];
1152 }
1153 }
1154 }
1155
1156 sub Store_start {
1157 my $self=shift;
1158 my $name=shift;
1159 my $hashref=shift;
1160
1161 if ( $self->{Arch} ) {
1162 $self->{switch}->checktag( $name, $hashref, 'name' );
1163
1164 # -- store creation
1165 my $dir=$$hashref{'name'};
1166 AddDir::adddir($self->{area}->location()."/".$dir);
1167 if ( exists $$hashref{'type'} ) {
1168 # -- architecture specific store
1169 if ( $$hashref{'type'}=~/^arch/i ) {
1170 $dir=$dir."/".$ENV{SCRAM_ARCH};
1171 AddDir::adddir($self->{area}->location()."/".$dir);
1172 }
1173 else {
1174 $self->parseerror("Unknown type in <$name> tag");
1175 }
1176 }
1177
1178 # -- set make variables for the store
1179 print GNUmakefile "SCRAMSTORENAME_".$$hashref{'name'}.":=".$dir."\n";
1180 print GNUmakefile "SCRAMSTORE_".$$hashref{'name'}.":=".
1181 $self->{localtop}."/".$dir."\n";
1182 print GNUmakefile "VPATH+=".$self->{localtop}
1183 ."/".$dir.":".$self->{releasetop}."/".$dir."\n";
1184 }
1185 }
1186
1187 sub DropDown {
1188 my $self=shift;
1189 my $name=shift;
1190 my $hashref=shift;
1191
1192 if ( $self->{Arch} ) {
1193 # - default values must always be specified
1194 $self->{switch}->checktag( $name, $hashref, 'defaults' );
1195 my @blockdirs=split /,/ , $$hashref{'defaults'};
1196 $self->{block}->defaultblocks(@blockdirs);
1197 }
1198 }