ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/BuildFile.pm
Revision: 1.11
Committed: Thu Nov 2 15:24:09 2000 UTC (24 years, 6 months ago) by williamc
Content type: text/plain
Branch: MAIN
Changes since 1.10: +3 -3 lines
Log Message:
latest mods

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 $switch->filetoparse($self->buildfile());
72
73 # -- parse away
74 $self->{switch}=$switch;
75 $switch->parse("block");
76 }
77
78 sub Parsetofh {
79 my $self=shift;
80 my $fh=shift;
81 $self->{buildblock}=shift;
82
83 # -- set up for parse
84 @{$self->{filehandlestack}}=($fh);
85 $self->{switch}->filetoparse($self->buildfile());
86 *GNUmakefile=$fh;
87
88 # -- generate makefile
89 $self->{switch}->parse("makebuild"); # sort out supported tags
90
91 # -- Clean up
92 close GNUmakefile;
93 }
94
95 sub ignore {
96 my $self=shift;
97 return (defined $self->{ignore})?$self->{ignore}:0;
98 }
99
100 sub _initswitcher {
101 my $self=shift;
102 my $switch=ActiveDoc::SimpleDoc->new();
103 my $parse="makebuild";
104 $switch->newparse($parse);
105 $switch->addignoretags($parse);
106 $self->_commontags($switch,$parse);
107 #$switch->addtag($parse,"Build", \&Build_start, $self);
108 $switch->addtag($parse,"none",
109 \&OutToMakefile,$self,
110 \&OutToMakefile, $self,
111 "", $self);
112 $switch->addtag($parse,"Bin",
113 \&Bin_start,$self,
114 \&OutToScreen, $self,
115 "", $self);
116 $switch->addtag($parse,"ProductStore",
117 \&Store_start,$self,
118 "", $self,
119 "", $self);
120 $switch->addtag($parse,"LibType",
121 \&LibType_Start,$self,
122 \&LibType_text, $self,
123 \&LibType_end,$self);
124 $switch->addtag($parse,"ConfigurationClass",
125 \&Class_StartTag,$self,
126 \&OutToMakefile, $self,
127 "", $self);
128 $switch->addtag($parse,"ClassPath",
129 \&setBlockClassPath,$self,
130 \&OutToMakefile, $self,
131 "", $self);
132 $switch->addtag($parse,"AssociateGroup",
133 "",$self,
134 \&AssociateGroup,$self,
135 "", $self);
136 $switch->addtag($parse,"Environment",
137 \&Environment_start,$self,
138 \&OutToMakefile, $self,
139 \&Environment_end,$self);
140 $switch->addtag($parse,"Export",
141 \&export_start,$self,
142 \&OutToMakefile, $self,
143 \&export_end,$self);
144 return $switch;
145 }
146
147 sub _commontags {
148 my $self=shift;
149 my $switch=shift;
150 my $parse=shift;
151
152 $switch->grouptag("Export",$parse);
153 $switch->addtag($parse,"Use",\&Use_start,$self,
154 \&OutToMakefile, $self,
155 "", $self);
156 $switch->addtag($parse,"Group",\&Group_start,$self,
157 \&OutToMakefile, $self,
158 "", $self);
159 $switch->grouptag("Group",$parse);
160 $switch->addtag($parse,"External",
161 \&External_StartTag,$self,
162 \&OutToMakefile, $self,
163 "", $self);
164 $switch->addtag($parse,"lib",
165 \&lib_start,$self,
166 \&OutToMakefile, $self,
167 "", $self);
168 $switch->addtag($parse,"Architecture",
169 \&Arch_Start,$self,
170 \&OutToMakefile, $self,
171 \&Arch_End,$self);
172 $switch->addtag($parse,"INCLUDE_PATH",
173 \&IncludePath_Start,$self,
174 \&OutToMakefile, $self,
175 "",$self);
176 return $switch;
177 }
178
179 sub GenerateMakefile {
180 my $self=shift;
181 my $infile=shift;
182 my $outfile=shift;
183
184 $self->{switch}=$self->_initswitcher();
185 $self->{switch}->filetoparse($infile);
186
187 # open a temporary gnumakefile to store output.
188 my $fh=FileHandle->new();
189 open ( $fh, ">$outfile") or die "Unable to open $outfile for output ".
190 "$!\n";
191 @{$self->{filehandlestack}}=($fh);
192
193 # -- make an alias
194 *GNUmakefile=$fh;
195 if ( -e $ENV{LatestBuildFile} ) {
196 print GNUmakefile "include $ENV{LatestBuildFile}\n";
197 }
198 $self->{switch}->parse("makebuild"); # sort out supported tags
199 close GNUmakefile;
200 return $outfile;
201 }
202
203 sub ParseBuildFile {
204 my $self=shift;
205 my $base=shift;
206 my $path=shift;
207 my $filename=shift @_;
208 my $fullfilename;
209 if ( $filename!~/^\// ) {
210 $fullfilename="$base/$path/$filename";
211 }
212 else {
213 $fullfilename=$filename;
214 }
215 $self->{path}=$path;
216 #print "Processing $fullfilename\n";
217 $numbins=0;
218 $self->{envnum}=0;
219 $self->{envlevel}=0;
220 $self->{makefile}="$self->{localtop}/$ENV{INTwork}/$self->{path}/".
221 "BuildFile.mk";
222 $self->{currentenv}=$self->{makefile};
223 $self->{switch}=$self->_initswitcher();
224 $self->{switch}->filetoparse($fullfilename);
225
226 # $self->{switch}->{Strict_no_cr}='no';
227 #open a temporary gnumakefile to store output.
228 use Utilities::AddDir;
229 AddDir::adddir("$self->{localtop}/$ENV{INTwork}/$self->{path}");
230 $ENV{LatestBuildFile}=$self->GenerateMakefile($fullfilename,
231 $self->{localtop}."/".$ENV{INTwork}."/".$self->{path}."/BuildFile.mk");
232 }
233
234 sub classname {
235 my $self=shift;
236 if ( @_ ) {
237 $self->{classname}=shift;
238 }
239 return $self->{classname};
240 }
241
242 sub ParseBuildFile_Export {
243 my $self=shift;
244 my $filename=shift;
245 my $bf=BuildSystem::BuildFile->new($self->{area});
246 if ( defined $self->{remoteproject} ) {
247 $bf->{remoteproject}=$self->{remoteproject};
248 }
249 $bf->_parseexport($filename);
250 undef $bf;
251 }
252
253 sub _location {
254 my $self=shift;
255 use File::Basename;
256
257 return dirname($self->{switch}->filetoparse());
258 }
259
260 sub _parseexport {
261 my $self=shift;
262 my $filename=shift;
263
264 my $switchex=ActiveDoc::SimpleDoc->new();
265 $switchex->filetoparse($filename);
266 $switchex->newparse("export");
267 $switchex->addignoretags("export");
268 $switchex->addtag("export","Export",
269 \&export_start_export,$self,
270 \&OutToMakefile, $self,
271 \&export_end_export,$self);
272 $self->_commontags($switchex,"export");
273 $switchex->allowgroup("__export","export");
274 # $switchex->{Strict_no_cr}='no';
275 $self->{switch}=$switchex;
276 $switchex->parse("export"); # sort out supported tags
277 }
278
279 sub _pushremoteproject {
280 my $self=shift;
281 my $path=shift;
282
283 if ( defined $self->{remoteproject} ) {
284 push @{$self->{rpstack}}, $self->{remoteproject};
285 }
286 $self->{remoteproject}=$path;
287 }
288
289 sub _popremoteproject {
290 my $self=shift;
291 if ( $#{$self->{rpstack}} >=0 ) {
292 $self->{remoteproject}=pop @{$self->{rpstack}};
293 }
294 else {
295 undef $self->{remoteproject};
296 }
297 }
298
299 sub _toolmapper {
300 my $self=shift;
301 if ( ! defined $self->{mapper} ) {
302 require BuildSystem::ToolMapper;
303 $self->{mapper}=BuildSystem::ToolMapper->new();
304 }
305 return $self->{mapper};
306 }
307
308
309 # ---- Tag routines
310
311 #-- Override a class type with the <ConfigurationClass type=xxx> tag
312 # the type tag will pick up a pre-defined class type from project space.
313
314 sub Class_StartTag {
315 my $self=shift;
316 my $name=shift;
317 my $hashref=shift;
318
319 if ( $self->{Arch} ) {
320 if ( defined $$hashref{'type'} ) {
321 $self->classname($$hashref{'type'});
322 }
323 }
324 }
325
326 sub IncludePath_Start {
327 my $self=shift;
328 my $name=shift;
329 my $hashref=shift;
330
331 $self->{switch}->checktag( $name, $hashref, 'path');
332 if ( $self->{Arch} ) {
333 print GNUmakefile "INCLUDE+=".$self->_location()."/".
334 $$hashref{'path'}."\n";
335 }
336 }
337
338 #
339 # --- <Build class=> tag
340 #
341
342 #
343 # Parameter collection
344 #
345 sub BuildBlock_start {
346 my $self=shift;
347 my $name=shift;
348 my $hashref=shift;
349
350
351 my $blockobjid=$self->__blockobjid($hashref);
352
353 if ( $self->{Arch} ) {
354
355 # -- get any objects that match
356 my $inheritobj=$self->{block}->getobj($blockobjid);
357
358 # -- create an object with inherited properties
359 my $obj;
360 if ( ! defined $inheritobj ) {
361 # -- check we have a lookup for the class type
362 my $mapper=$self->_toolmapper();
363 if ( ! $mapper->exists($$hashref{'class'}) ) {
364 $self->{switch}->parseerror("Unknown class : ".
365 $$hashref{'class'});
366 }
367 $obj=BuildSystem::BuildClass->new();
368 }
369 else {
370 # -- inherit the properties from class with the same id class
371 $obj=$inheritobj->child();
372 }
373
374 # -- add changes from our tag
375 $obj->paramupdate($hashref);
376
377 # -- store the new object in the block
378 $self->{block}->setobj($obj,$blockobjid);
379 }
380 }
381
382 sub BuilderClass_buildmakefile {
383 my $self=shift;
384 my $name=shift;
385 my $hashref=shift;
386
387 my $blockobjid=$self->__blockobjid($hashref);
388
389 if ( $self->{Arch} ) {
390 # -- get the matching block object
391 my $blockobj=$self->{buildblock}->getobj($blockobjid);
392
393 # -- top level buildfile
394 my $fh=$self->{filehandlestack}[0];
395
396 # -- var initialisation
397 my @deftypes=();
398 my $buildname="";
399 my @types=$self->_toolmapper()->types($$hashref{'class'});
400
401 # -- error checking
402 if ( ! defined $blockobj->param("default") ) {
403 $self->error("No default build parameter defined for ".
404 $$hashref{'class'}." ".$$hashref{'id'});
405 }
406 if ( ! defined $blockobj->param("name") ) {
407 $self->error("\"name\" parameter defined for ".
408 $$hashref{'class'}." ".$$hashref{'id'});
409 }
410
411
412 foreach $param ( $blockobj->paramlist() ) {
413 # -- check for params that need special handling
414 if ( $param eq "default" ) {
415 @deftypes=split /,/, $param;
416 }
417 elsif ( $param eq "name" ) {
418 $buildname=$blockobj->param($param);
419 }
420 else {
421 # -- simple transfer of block object parameters to makefile
422 print $fh $param.":=".$blockobj->param($param)."\n";
423 }
424 }
425
426 # -- construct the targets in the top makefile
427 $self->_generatedefaulttargets($fh,$$hashref{'class'},@deftypes);
428 $self->_generatetypetargets($fh,$$hashref{'class'},$buildname,@types);
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 }