ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/BuildFile.pm
Revision: 1.19
Committed: Tue Jul 2 14:45:29 2002 UTC (22 years, 10 months ago) by sashby
Content type: text/plain
Branch: MAIN
Changes since 1.18: +56 -33 lines
Log Message:
Rewriting BuildSystem. Using some of CW earlier modules for build logging. For tests before poss release.

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