ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/BuildFile.pm
Revision: 1.4
Committed: Tue Sep 12 13:01:39 2000 UTC (24 years, 7 months ago) by williamc
Content type: text/plain
Branch: MAIN
Changes since 1.3: +24 -0 lines
Log Message:
Add BuildFile basics

File Contents

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