ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/BuildFile.pm
Revision: 1.13
Committed: Wed Nov 15 14:49:22 2000 UTC (24 years, 5 months ago) by williamc
Content type: text/plain
Branch: MAIN
CVS Tags: V0_19_0, V0_18_5, V0_18_4, V_18_3_TEST, VO_18_3, V0_18_2, V0_18_1
Changes since 1.12: +68 -228 lines
Log Message:
Up and running

File Contents

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