ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/BuildFile.pm
Revision: 1.2
Committed: Mon Aug 28 08:23:08 2000 UTC (24 years, 8 months ago) by williamc
Content type: text/plain
Branch: MAIN
Changes since 1.1: +855 -66 lines
Log Message:
Imported from HPWbranch

File Contents

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