ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/BuildFile.pm
Revision: 1.1.2.11.2.2.2.3.2.2
Committed: Thu Nov 2 17:37:02 2000 UTC (24 years, 6 months ago) by williamc
Content type: text/plain
Branch: V0_16branch
CVS Tags: BuildSystemProto1, V0_18_0model, V0_18_0alpha
Changes since 1.1.2.11.2.2.2.3.2.1: +228 -68 lines
Log Message:
Import BuildSystem from dev + extra dependency checking

File Contents

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