ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/BuildFile.pm
Revision: 1.17
Committed: Tue May 14 10:21:19 2002 UTC (22 years, 11 months ago) by sashby
Content type: text/plain
Branch: MAIN
Changes since 1.16: +29 -25 lines
Log Message:
*** empty log message ***

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