Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 10:05:52

0001 #!/usr/bin/env perl
0002 use File::Basename;
0003 use lib dirname($0);
0004 use Getopt::Long;
0005 use File::Path;
0006 use SCRAMGenUtils;
0007 
0008 if(-t STDIN){die "Please run createBuildFile.pl script. $0 is not suppose to run directly.\n";}
0009 
0010 $|=1;
0011 #get the command-line options
0012 if(&GetOptions(
0013            "--files=s",\@files,
0014            "--dir=s",\$dir,
0015            "--prodname=s",\$prodname,
0016            "--prodtype=s",\$prodtype,
0017            "--use=s",\@use,
0018            "--no-use=s",\@nuse,
0019            "--export=s",\@export,
0020            "--no-export=s",\@nexport,
0021            "--replace=s",\%replace,
0022            "--flag=s",\@flags,
0023            "--ref-bf=s",\$refbf,
0024            "--dictclasses=s",\$dictclasses,
0025            "--linkdef=s",\$linkdef,
0026            "--iglet=s",\$iglet,
0027            "--tmpdir=s",\$tmpdir,
0028            "--buildfile=s",\$buildfilename,
0029            "--config=s",\$configfile,
0030            "--jobs=i",\$jobs,
0031            "--help",\$help,
0032            "--plugin",\$plugin,
0033            "--clean",\$clean,
0034            "--xml",\$xml,
0035            "--detail",\$detail,
0036               ) eq ""){print STDERR "#Wrong arguments.\n"; &usage_msg();}
0037 
0038 my $compiler="cxxcompiler";
0039 my $srcext="cpp|cc|c|cxx|f|f77";
0040 my $hdext="h|hh|inc|ii|i|icpp|icc";
0041 my $pwd=`/bin/pwd`; chomp $pwd;
0042 my $cache={};
0043 $SCRAMGenUtils::InternalCache=$cache;
0044 $SCRAMGenUtils::CacheType=1;
0045 
0046 if(defined $help){&usage_msg();}
0047 if(defined $plugin){$plugin=1;}
0048 else{$plugin=0;}
0049 if(defined $xml){$xml="--xml";}
0050 else{$xml="";}
0051 if(defined $detail){$detail=1;}
0052 else{$detail=0;}
0053 if (! defined $jobs){$jobs=10;}
0054 $SCRAMGenUtils::DEBUG=$detail;
0055 
0056 if((!defined $prodname) || ($prodname=~/^\s*$/)){$prodname="";}
0057 else{$prodname=~s/^\s*//;$prodname=~s/\s*$//;}
0058 if((!defined $dictclasses) || ($dictclasses=~/^\s*$/)){$dictclasses='^.+?\/classes\.h$';}
0059 if((!defined $linkdef) || ($linkdef=~/^\s*$/)){$linkdef='LinkDef\.h$';}
0060 if((!defined $iglet) || ($iglet=~/^\s*$/)){$iglet='iglet\.cc$';}
0061 if((defined $prodtype) && ($prodtype!~/^(library|bin)$/)){print STDERR "Product type could only be \"library\" or \"bin\".\n"; exit 1;}
0062 
0063 if((!defined $dir) || ($dir=~/^\s$/)){print STDERR "Please use --dir <dir> for which you want to find the dependency information.\n"; exit 1;}
0064 if($dir!~/^\//){$dir="${pwd}/${dir}";}
0065 $dir=&SCRAMGenUtils::fixPath($dir);
0066 my $release=&SCRAMGenUtils::scramReleaseTop($dir);
0067 if($release eq ""){print STDERR "ERROR: Directory \"$dir\" does not exist under a SCRAM-based project area.\n";exit 1;}
0068 my $releasetop=&SCRAMGenUtils::getFromEnvironmentFile("RELEASETOP",$release);
0069 my $envcache=&SCRAMGenUtils::getEnvironmentFileCache($release);
0070 &SCRAMGenUtils::init($release);
0071 
0072 if((defined $refbf) && ($refbf!~/^\s*$/))
0073 {if(!-f $refbf){print STDERR "ERROR: Reference BuildFile \"$refbf\" does not exist.\n"; exit 1;}}
0074 else{$refbf="";}
0075 if ($refbf eq "")
0076 {
0077   my $bf="${dir}/BuildFile.xml";
0078   if(!-f $bf){$bf="${dir}/BuildFile";}
0079   if (-f $bf){$refbf=$bf;}
0080 }
0081 if ($refbf=~/\.xml$/){$xml="--xml";}
0082 
0083 if((!defined $buildfilename) || ($buildfilename=~/^\s*$/)){$buildfilename="";}
0084 elsif($buildfilename!~/^\//){$buildfilename="${pwd}/${buildfilename}";}
0085 if($buildfilename)
0086 {
0087   $buildfilename=&SCRAMGenUtils::fixPath($buildfilename);
0088   my $d=dirname($buildfilename);
0089   if(!-d $d){system("mkdir -p $d");}
0090 }
0091 
0092 my $project=&SCRAMGenUtils::getFromEnvironmentFile("SCRAM_PROJECTNAME","$release");
0093 $project=lc($project);
0094 
0095 my $pkgsrcdir=&run_func("pkg_src",$project,$dir);
0096 if ($pkgsrcdir eq ""){print STDERR "ERROR: Script not ready yet to work for \"$project\" SCRAM-based project.\n"; exit 1;}
0097 my $pkginterfacedir=&run_func("pkg_interface",$project,$dir);
0098 
0099 my $scramarch=&SCRAMGenUtils::getScramArch();
0100 if((!defined $tmpdir) || ($tmpdir=~/^\s*$/))
0101 {
0102   $tmpdir="${release}/tmp/AutoBuildFile";
0103   if($pwd!~/^$release(\/.*|)$/){$tmpdir="${pwd}/AutoBuildFile";}
0104 }
0105 
0106 my $ccfiles=0;
0107 my $isPackage=0;
0108 my $PackageName="";
0109 my $filestr="";
0110 if(scalar(@files)==0)
0111 {
0112   if(-d "${dir}/${pkgsrcdir}")
0113   {
0114     foreach my $f (&SCRAMGenUtils::readDir("${dir}/${pkgsrcdir}",2))
0115     {
0116       if($f=~/\.($srcext)$/i){push @files,"${dir}/${pkgsrcdir}/${f}";$ccfiles++;}
0117       elsif($f=~/\.($hdext)$/i){push @files,"${dir}/${pkgsrcdir}/${f}";}
0118     }
0119   }
0120   if(-d "${dir}/${pkginterfacedir}")
0121   {
0122     foreach my $f (&SCRAMGenUtils::readDir("${dir}/${pkginterfacedir}",2))
0123     {
0124       if($f=~/\.($hdext)$/i){push @files,"${dir}/${pkginterfacedir}/${f}";}
0125       elsif($f=~/\.($srcext)$/i){push @files,"${dir}/${pkginterfacedir}/${f}";}
0126     }
0127   }
0128   if(scalar(@files)==0)
0129   {
0130     if ($refbf && $buildfilename)
0131     {
0132       my $bf=basename($refbf);
0133       if ($buildfilename=~/\/$bf\.auto$/){system("cp $refbf $buildfilename");}
0134       else{&SCRAMGenUtils::convert2XMLBuildFile($refbf,$buildfilename);}
0135     }
0136     exit 0;
0137   }
0138   else
0139   {
0140     $isPackage=1;
0141     $PackageName=$dir; $PackageName=~s/^$release\/src\///;
0142     if ($prodname eq ""){$prodname=&run_func("safename",$project,$dir);}
0143   }
0144 }
0145 else
0146 {
0147   my @xf=@files;
0148   @files=();
0149   foreach my $f (@xf)
0150   {
0151     foreach my $f1 (split /\s*,\s*/,$f)
0152     {foreach my $f2 (split /\s+/,$f1){if($f2 ne ""){push @files,$f2;}}}
0153   }
0154   $filestr=join(",",@files);
0155   @xf=();
0156   foreach my $f (@files)
0157   {
0158     my @fs=();
0159     foreach my $f1 (`ls ${dir}/$f`)
0160     {
0161       chomp $f1;
0162       if(-f $f1)
0163       {
0164         $f1=&SCRAMGenUtils::fixPath($f1);
0165         push @xf,$f1;
0166         push @fs,$f1;
0167       }
0168     }
0169     if(scalar(@fs)==0)
0170     {
0171       my $found=0;
0172       if($f!~/\*/)
0173       {
0174         if($f=~/^(.+?)\.([^\.]+)$/)
0175     {
0176       my $f1=$1;
0177       my $e=$2;
0178       foreach my $x ("cc","cpp","cxx","C")
0179       {
0180         if($x eq $e){next;}
0181         if(-f "${dir}/${f1}.${x}")
0182         {
0183           $f1="${dir}/${f1}.${x}";
0184           push @xf,&SCRAMGenUtils::fixPath($f1);
0185           $found=1;
0186           print STDERR "FILE REPLACE: $f => $f1\n";
0187           last;
0188         }
0189       }
0190     }
0191       }
0192       if(!$found){print STDERR "WARNING: No such file \"$f\" under directory \"$dir\".\n";}
0193     }
0194   }
0195   @files=();
0196   @files=@xf;
0197   if(scalar(@files)>0)
0198   {
0199     foreach my $f (@files)
0200     {
0201       if($f!~/\.($srcext)$/i)
0202       {print STDERR "ERROR: Only files with extensions \"$srcext\" should be passed with --files command-line arg.\n";exit 1;}
0203     }
0204   }
0205   $ccfiles++;
0206   if ($prodname eq "")
0207   {
0208     if(scalar(@files)==1){$prodname=basename($files[0]);$prodname=~s/\.[^\.]+$//;}
0209     else{print STDERR "You should also use \"--name <product_name>\" when \"--files <file>\" command-line arguments are used.\n";exit 1;}
0210   }
0211 }
0212 
0213 my $data={};
0214 $data->{files}={};
0215 $data->{filter}=$dir;
0216 
0217 foreach my $f ("EDM_PLUGIN", "SEALPLUGIN", "SEAL_PLUGIN_NAME", "NO_LIB_CHECKING", "GENREFLEX_FAILES_ON_WARNS", "ROOTMAP", "ADD_SUBDIR", "CODEGENPATH"){$data->{sflags}{$f}=1;}
0218 foreach my $f ("CPPDEFINES"){$data->{keyflags}{$f}=1;}
0219 
0220 $data->{bfflags}=[];
0221 foreach my $f (@flags){push @{$data->{bfflags}},$f;}
0222 
0223 my $cachedir="${tmpdir}/${scramarch}";
0224 my $incdir="${cachedir}/includes";
0225 if(!-d $incdir){system("mkdir -p $incdir");}
0226 my $cachefile="${cachedir}/toolcache";
0227 my $inccache={};
0228 if((!defined $clean) && (-f "$cachefile"))
0229 {
0230   print STDERR "Reading previously save internal cache $cachefile.\n";
0231   $cache=&SCRAMGenUtils::readHashCache("$cachefile");
0232   $SCRAMGenUtils::InternalCache=$cache;
0233 }
0234 else
0235 {
0236   print STDERR "Reading project's SCRAM cache\n";
0237   &update_project_cache($cache);
0238   $cache->{IGNORE_BASETOOLS}{rootrflx}=1;
0239   $cache->{IGNORE_BASETOOLS}{boost_python}=1;
0240   &save_toolcache();
0241 }
0242 
0243 if(exists $cache->{COMPILER})
0244 {
0245   $data->{compilecmd}=$cache->{COMPILER};
0246   $data->{compileflags}=$cache->{CXXFLAGS}." ".$cache->{CXXINCLUDE};
0247 }
0248 else{print STDERR "#WARNING: No compiler found. So script is not going to parse the file for seal plugin macros.\n";}
0249 
0250 $configfile=&SCRAMGenUtils::updateConfigFileData($configfile,$data,$caahe);
0251 
0252 my $igletfile="";
0253 my $srcplugin="";
0254 my $srcedmplugin="";
0255 my $fortrancode=0;
0256 my $castor=0;
0257 my $cacherefbf=undef;
0258 my $exflags="";
0259 $data->{prodtype}=$prodtype;
0260 $data->{prodname}=$prodname;
0261 $data->{extra_include_path}={};
0262 if($refbf && (-f $refbf))
0263 {
0264   $cacherefbf=&SCRAMGenUtils::readBuildFile($refbf);
0265   my $f=&SCRAMGenUtils::findBuildFileTag($data,$cacherefbf,"flags");
0266   foreach my $a (keys %$f)
0267   {
0268     foreach my $c (@{$f->{$a}})
0269     {
0270       foreach my $f1 (keys %{$c->{flags}})
0271       {
0272         my $v=$c->{flags}{$f1};
0273     if($f1 eq "CPPDEFINES"){foreach my $fv (@$v){$exflags .=" -D".&replaceVariables($fv->{v});}}
0274     elsif($f1 eq "CXXFLAGS"){foreach my $fv (@$v){$exflags.="   ".&replaceVariables($fv->{v});}}
0275     elsif($f1 eq "CPPFLAGS"){foreach my $fv (@$v){$exflags.="   ".&replaceVariables($fv->{v});}}
0276     elsif($f1 eq "LCG_DICT_HEADER")
0277     {
0278       my $lcgreg="";
0279       foreach my $fv (@$v)
0280       {
0281         my $files=$fv->{v};
0282         $files=~s/\,/ /g;
0283         foreach my $fn (split /\s+/, $files)
0284         {
0285           if($lcgreg){$lcgreg.="|$fn";}
0286           else{$lcgreg="$fn";}
0287         }
0288       }
0289       $dictclasses="^.+?\/(".$lcgreg.")\$";
0290     }
0291       }
0292     }
0293   }
0294   $f=&SCRAMGenUtils::findBuildFileTag($data,$cacherefbf,"include_path");
0295   foreach my $a (keys %$f)
0296   {
0297     foreach my $c (@{$f->{$a}})
0298     {
0299       foreach my $f1 (keys %{$c->{include_path}})
0300       {
0301         my $f2=&replaceVariables($f1);
0302     if(($f2!~/^\s*$/) && (-d $f2)){$exflags.=" -I$f2";$data->{extra_include_path}{$f2}=1;}
0303       }
0304     }
0305   }
0306 }
0307 
0308 if($isPackage){$prodtype="";}
0309 if($isPackage || ($prodtype eq "library"))
0310 {
0311   delete $data->{PROD_TYPE_SEARCH_RULES}{main};
0312   my $d=$dir;
0313   if($isPackage){$d="${dir}/${pkgsrcdir}";}
0314   elsif(scalar(@files)>0)
0315   {
0316     my $f=$files[0];
0317     if($f=~/^(.+?)\/[^\/]+$/){$d=$1;}
0318   }
0319   if(-d $d)
0320   {
0321     foreach my $f (&SCRAMGenUtils::readDir($d,2))
0322     {
0323       $f=&SCRAMGenUtils::fixPath("${d}/${f}");
0324       if($f=~/$dictclasses/)
0325       {
0326         $plugin=-1;
0327     $data->{deps}{src}{rootrflx}=1;
0328     $ccfiles++;
0329     my $found=0;
0330     foreach my $f1 (@files){if($f1 eq $f){$found=1;last;}}
0331     if(!$found){push @files,$f;}
0332       }
0333       elsif($f=~/$linkdef/){$data->{deps}{src}{rootcintex}=1;$ccfiles++;}
0334       elsif($f=~/$iglet/){$igletfile=$f;}
0335     }
0336   }
0337 }
0338 my $fullpath=&findProductInRelease($prodname);
0339 print STDERR "Reading source files\n";
0340 my $srcfiles=[];
0341 foreach my $file (@files)
0342 {
0343   if ($file=~/\.($srcext)$/i)
0344   {
0345     if($file!~/\.(f|f77)$/i){push @$srcfiles,$file;}
0346     elsif(!$fortrancode){$fortrancode=1;print STDERR "FORTRAN FILE:$file\n";}
0347   }
0348 }
0349 if (scalar(@$srcfiles)>0)
0350 {
0351   unlink "${cachedir}/searchPreprocessedInfo";
0352   my $pid=&SCRAMGenUtils::forkProcess($jobs);
0353   if($pid==0)
0354   {
0355     &SCRAMGenUtils::searchPreprocessedFile($srcfiles,$data,$exflags);
0356     &SCRAMGenUtils::writeHashCache($data->{PROD_TYPE_SEARCH_RULES},"${cachedir}/searchPreprocessedInfo");
0357     exit 0;
0358   }
0359 }
0360 foreach my $file (@files){&process_cxx_file ($file,$data);}
0361 if(!$detail){print STDERR "\n";}
0362 my $bindeps=&getBinaryDependency($prodname,$fullpath);
0363 my $tid=&SCRAMGenUtils::startTimer ();
0364 &SCRAMGenUtils::waitForChild();
0365 if($detail){print STDERR "WAIT TIME:",&SCRAMGenUtils::stopTimer($tid),"\n";}
0366 if ((scalar(@$srcfiles)>0) && (-f "${cachedir}/searchPreprocessedInfo"))
0367 {
0368   $data->{PROD_TYPE_SEARCH_RULES}=&SCRAMGenUtils::readHashCache("${cachedir}/searchPreprocessedInfo");
0369   if((exists $data->{PROD_TYPE_SEARCH_RULES}{sealplugin}) && (exists $data->{PROD_TYPE_SEARCH_RULES}{sealplugin}{file}))
0370   {
0371     $srcplugin=$data->{PROD_TYPE_SEARCH_RULES}{sealplugin}{file};
0372     delete $data->{PROD_TYPE_SEARCH_RULES}{sealplugin};
0373   }
0374   if((exists $data->{PROD_TYPE_SEARCH_RULES}{edmplugin}) && (exists $data->{PROD_TYPE_SEARCH_RULES}{edmplugin}{file}))
0375   {
0376     $srcedmplugin=$data->{PROD_TYPE_SEARCH_RULES}{edmplugin}{file};
0377     delete $data->{PROD_TYPE_SEARCH_RULES}{edmplugin};
0378   }
0379   if((exists $data->{PROD_TYPE_SEARCH_RULES}{main}) && (exists $data->{PROD_TYPE_SEARCH_RULES}{main}{file}))
0380   {
0381     my $f=$data->{PROD_TYPE_SEARCH_RULES}{main}{file};
0382     if(($prodtype ne "") && ($prodtype ne "bin"))
0383     {print STDERR "\"$prodname\" seemed like a \"bin\" product because there is \"main()\" exists in \"f\" file.\n";}
0384     else{$prodtype="bin";}
0385     if($detail){print STDERR "Executable:$prodname:$f\n";}
0386     delete $data->{PROD_TYPE_SEARCH_RULES}{main};
0387   }
0388   if((exists $data->{PROD_TYPE_SEARCH_RULES}{castor}) && (exists $data->{PROD_TYPE_SEARCH_RULES}{castor}{file}))
0389   {
0390     my $f=$data->{PROD_TYPE_SEARCH_RULES}{castor}{file};
0391     if($detail){print STDERR "Castor Dependency:$prodname:$f\n";}
0392     $castor=1;
0393     delete $data->{PROD_TYPE_SEARCH_RULES}{castor};
0394   }
0395 }
0396 print STDERR "....\n";
0397 $data->{ccfiles}=$ccfiles;
0398 $data->{isPackage}=$isPackage;
0399 $data->{filestr}=$filestr;
0400 
0401 my $pack=$dir;
0402 $pack=~s/^$release\/src\///;
0403 if($detail && $srcplugin){print STDERR "SealPlugin:$prodname:$srcplugin\n";}
0404 if($detail && $srcedmplugin){print STDERR "EDMPlugin:$prodname:$srcedmplugin\n";}
0405 if ($fullpath && ($fullpath=~/\/plugin.+\.so$/) && (($srcedmplugin eq "") || ($srcplugin)))
0406 {
0407   $srcedmplugin="(forced to be an EDM plugin as its build as EDM plugin in release)";
0408   $srcplugin="";
0409 }
0410 
0411 if($fortrancode){foreach my $t ("pythia6","genser"){if (exists $cache->{TOOLS}{$t}){$data->{deps}{src}{$t}=1;}}}
0412 if($plugin==-1)
0413 {
0414   my $err=0;
0415   if (($srcplugin ne "") || ($srcedmplugin ne ""))
0416   {
0417     print STDERR "#WARNING: You have LCG disctionaries file(s) matching regexp \"$dictclasses\" in your package \"$pack\" and also you have SEAL/EDM PLUGIN MODULE macro defined.\n";
0418     $err=1;
0419   }
0420   if($err)
0421   {
0422     if($srcplugin ne ""){print STDERR "#WARNING: Seal Plugin File: $srcplugin\n";}
0423     if($srcedmplugin ne ""){print STDERR "#WARNING: EDM Plugin File : $srcedmplugin\n";}
0424     print STDERR "#WARNING: Packages which generate LCG disctionaries are not suppose to be seal/edm plugins. So please fix your package.\n";
0425   }
0426 }
0427 elsif(($srcplugin ne "") && ($srcedmplugin ne ""))
0428 {
0429   print STDERR "#WARNING: Your package \"$pack\" has macros for both seal and edm plugins. You are suppose to have macros for only one plugin, please fix this.\n";
0430   print STDERR "#WARNING: Seal Plugin File: $srcplugin\n";
0431   print STDERR "#WARNING: EDM Plugin File : $srcedmplugin\n";
0432   $plugin=-1;
0433 }
0434 elsif(($srcplugin ne "") || ($srcedmplugin ne "")){$plugin=1;}
0435 
0436 my $defaultplugintype=uc(&run_func("defaultplugin",$project));
0437 if(($dir=~/\/sealplugins$/) || ($dir=~/\/plugins$/))
0438 {
0439   if($plugin <= 0){push @{$data->{bfflags}},"${defaultplugintype}PLUGIN=0";}
0440   elsif($srcedmplugin ne ""){push @{$data->{bfflags}},"EDM_PLUGIN=1";}
0441   elsif($srcplugin ne ""){push @{$data->{bfflags}},"SEALPLUGIN=1";}
0442 }
0443 elsif($plugin>0)
0444 {
0445   if($srcplugin ne ""){push @{$data->{bfflags}},"SEALPLUGIN=1";}
0446   elsif($srcedmplugin ne ""){push @{$data->{bfflags}},"EDM_PLUGIN=1";}
0447 }
0448 
0449 #read ref BuildFile for extra flags
0450 &SCRAMGenUtils::updateFromRefBuildFile($cacherefbf,$data);
0451 
0452 # Extra flags
0453 foreach my $f (@{$data->{bfflags}})
0454 {
0455   my ($n,$v)=split /=/,$f,2;
0456   if(($f=~/^$n=/) && ($n!~/^\s*$/))
0457   {
0458     $v=~s/^\s*//;$v=~s/\s*$//;
0459     $n=~s/^\s*//;$n=~s/\s*$//;
0460     $n=uc($n);
0461     if(exists $data->{sflags}{$n})
0462     {
0463       if($n eq "SEAL_PLUGIN_NAME"){$n="SEALPLUGIN", $v=1;}
0464       if(($n eq "SEALPLUGIN") && ($plugin<0)){next;}
0465       if(($n eq "EDM_PLUGIN") && ($plugin<0)){next;}
0466       $data->{flags}{$n}=$v;
0467     }
0468     else
0469     {
0470       if(!exists $data->{flags}{$n}){$data->{flags}{$n}=[];}
0471       push @{$data->{flags}{$n}},$v;
0472     }
0473   }
0474 }
0475 
0476 # Extra tool/package to export
0477 foreach my $x (&commaSepDeps(\@export,$cache,"${prodname}export")){$data->{deps}{src}{$x}=1;}
0478 
0479 # Extra tool/package not to export
0480 foreach my $x (&commaSepDeps(\@nexport,$cache,"${prodname}no-export"))
0481 {
0482   if(exists $data->{deps}{src}{$x}){print STDERR "MSG:Removed dependency on \"$x\" due to no-export arguments.\n";}
0483   delete $data->{deps}{src}{$x};
0484   $data->{NO_EXPORT}{$x}=1;
0485 }
0486 
0487 # Extra tool/package to use
0488 foreach my $x (&commaSepDeps(\@use,$cache,"${prodname}use")){$data->{deps}{src}{$x}=1;}
0489 
0490 # Extra tool/package not to use
0491 foreach my $x (&commaSepDeps(\@nuse,$cache,"${prodname}no-use"))
0492 {
0493   if(exists $data->{deps}{src}{$x}){print STDERR "MSG:Removed dependency on \"$x\" due to no-use arguments.\n";}
0494   delete $data->{deps}{src}{$x};
0495    $data->{NO_USE}{$x}=1;
0496 }
0497 
0498 # Extra tool/package replacement
0499 foreach my $x (keys %replace)
0500 {
0501   my $v=$replace{$x};
0502   my $lx=lc($x); my $lv=lc($v);
0503   if(exists $cache->{TOOLS}{$lx}){$x=$lx;}
0504   if(exists $cache->{TOOLS}{$lv}){$v=$lv;}
0505   $data->{replace}{$x}=$v;
0506 }
0507 
0508 foreach my $dep (keys %{$data->{deps}{src}})
0509 {if(exists $data->{replace}{$dep}){delete $data->{deps}{src}{$dep}; $data->{deps}{src}{$data->{replace}{$dep}}=1;}}
0510 
0511 foreach my $u (keys %{$data->{deps}{src}})
0512 {
0513   my $rep=&parentCommunication("PRODUCT_INFO",$u);
0514   my $exprocess=0;
0515   if ($rep ne "NOT_EXISTS") 
0516   {
0517     if ($rep eq "PROCESS"){&parentCommunication("PLEASE_PROCESS_FIRST",$u);$exprocess=1;}
0518   }
0519   elsif((-d "${release}/src/${u}/${pkgsrcdir}") || (-d "${release}/src/${u}/${pkginterfacedir}")){&parentCommunication("PLEASE_PROCESS_FIRST",$u);$exprocess=1;}
0520   if($detail && $exprocess){print STDERR "###### Back to processing of $prodname  #######\n";}
0521   my $rep=&parentCommunication("PACKAGE_TYPE",$u);
0522   if ($rep!~/^(TOOL|PACK)$/)
0523   {
0524     delete $data->{deps}{src}{$u};
0525     if ($detail){print STDERR "Deleting dependency \"$u\" due to its type \"$rep\"\n";}
0526   }
0527 }
0528 
0529 if(exists $data->{deps}{src}{castor}){$castor=0;}
0530 &symbolCheck($bindeps);
0531 &extraProcessing($prodname,$dir);
0532 &SCRAMGenUtils::removeExtraLib ($cache,$data);
0533 &SCRAMGenUtils::printBuildFile($data, "$buildfilename");
0534 &final_exit("",0);
0535 #########################################
0536 #
0537 sub findProductInRelease ()
0538 {
0539   my $prod=shift;
0540   foreach my $dir ($release,$releasetop)
0541   {
0542     if($dir eq ""){next;}
0543     foreach my $xd (keys %{$data->{PRODUCT_SEARCH_PATHS}{PACK}})
0544     {
0545       foreach my $d ("${xd}/${scramarch}","${scramarch}/${xd}")
0546       {
0547         if (!-d "${dir}/${d}"){next;}
0548     if(-f "${dir}/${d}/lib${prod}.so"){return "${dir}/${d}/lib${prod}.so";}
0549         elsif(-f "${dir}/${d}/plugin${prod}.so"){return "${dir}/${d}/plugin${prod}.so";}
0550       }
0551     }
0552     foreach my $xd (keys %{$data->{PRODUCT_SEARCH_PATHS}{PROD}})
0553     {
0554       foreach my $d ("${xd}/${scramarch}","${scramarch}/${xd}")
0555       {
0556         if (!-d "${dir}/${d}"){next;}
0557     if(-f "${dir}/${d}/${prod}"){return "${dir}/${d}/${prod}";}
0558       }
0559     }
0560   }
0561   return "";
0562 }
0563 
0564 sub extraProcessing ()
0565 {
0566   my $p=shift;
0567   my $dir=shift;
0568   if (exists $data->{EXTRA_TOOLS}{PRODUCTS})
0569   {
0570     my $c=$data->{EXTRA_TOOLS}{PRODUCTS};
0571     foreach my $exp (keys %$c)
0572     {if ($p=~/$exp/){foreach my $t (keys %{$c->{$exp}}){if (!exists $data->{deps}{src}{$t}){$data->{deps}{src}{$t}=1;print STDERR "Added dependency(forced):$t\n";}}}}
0573   }
0574   if (exists $data->{EXTRA_TOOLS}{PATHS})
0575   {
0576     my $c=$data->{EXTRA_TOOLS}{PATHS};
0577     foreach my $exp (keys %$c)
0578     {if ($dir=~/$exp/){foreach my $t (keys %{$c->{$exp}}){if (!exists $data->{deps}{src}{$t}){$data->{deps}{src}{$t}=1;print STDERR "Added dependency(forced):$t\n";}}}}
0579   }
0580   if (exists $data->{deps}{src})
0581   {
0582     if (exists $data->{EXTRA_TOOLS}{HASDEPS})
0583     {
0584       my $c=$data->{EXTRA_TOOLS}{HASDEPS};
0585       foreach my $t (keys %$c)
0586       {
0587         if(exists $data->{deps}{src}{$t})
0588     {
0589       foreach my $d (keys %{$c->{$t}})
0590       {
0591         if((!exists $data->{deps}{src}{$d}) && (!$isPackage || ($PackageName ne $d))){$data->{deps}{src}{$d}=1;print STDERR "Added dependency(forced):$d (due to $t)\n";}
0592       }
0593     }
0594       } 
0595     }
0596     if (exists $data->{REMOVE_TOOLS}{PRODUCTS})
0597     {
0598       my $c=$data->{REMOVE_TOOLS}{PRODUCTS};
0599       foreach my $exp (keys %$c)
0600       {if ($p=~/$exp/){foreach my $t (keys %{$c->{$exp}}){if (exists $data->{deps}{src}{$t}){delete $data->{deps}{src}{$t};print STDERR "Removed dependency(forced):$t\n";}}}}
0601     }
0602     if (exists $data->{REMOVE_TOOLS}{PATHS})
0603     {
0604       my $c=$data->{REMOVE_TOOLS}{PATHS};
0605       foreach my $exp (keys %$c)
0606       {if ($dir=~/$exp/){foreach my $t (keys %{$c->{$exp}}){if (exists $data->{deps}{src}{$t}){delete $data->{deps}{src}{$t};print STDERR "Removed dependency(forced):$t\n";}}}}
0607     }
0608   }
0609   if(exists $data->{flags})
0610   {
0611     if (exists $data->{REMOVE_FLAGS}{PRODUCTS})
0612     {
0613       my $c=$data->{REMOVE_FLAGS}{PRODUCTS};
0614       foreach my $exp (keys %$c)
0615       {if ($p=~/$exp/){foreach my $f (keys %{$c->{$exp}}){if (exists $data->{flags}{$f}){delete $data->{flags}{$f};print STDERR "Removed flag(forced):$f\n";}}}}
0616     }
0617     if (exists $data->{REMOVE_FLAGS}{PATHS})
0618     {
0619       my $c=$data->{REMOVE_FLAGS}{PATHS};
0620       foreach my $exp (keys %$c)
0621       {if ($dir=~/$exp/){foreach my $f (keys %{$c->{$exp}}){if (exists $data->{flags}{$f}){delete $data->{flags}{$f};print STDERR "Removed flag(forced):$f\n";}}}}
0622     }
0623   }
0624 }
0625 
0626 sub getBinaryDependency()
0627 {
0628   my $p1=shift;
0629   my $p=shift;
0630   my $ts={};
0631   if ($p eq ""){print STDERR "WARNING: Could not find product \"$p1\". Going to seach for generated object files.\n";$p=$p1;}
0632   my $res=&parentCommunication("SYMBOL_CHECK_REQUEST",$p);
0633   if ($res ne "")
0634   {
0635     $ts=&SCRAMGenUtils::readHashCache($res);
0636     unlink $res;
0637   }
0638   return $ts;
0639 }
0640 
0641 sub processBinaryDeps ()
0642 {
0643   my $ts=shift;
0644   my $depstr=join(",",keys %{$data->{deps}{src}});
0645   my %done=();
0646   my %btools=();
0647   foreach my $s (keys %$ts)
0648   {
0649     foreach my $t (keys %{$ts->{$s}})
0650     {
0651       if (exists $done{$t}){if ($done{$t}==1){delete $ts->{$s};last;}}
0652       my $d=0;
0653       if ((exists $data->{deps}{src}{$t}) || (exists $data->{IGNORE_SYMBOL_TOOLS}{$t})){$d=1;}
0654       else
0655       {
0656         my $skip=0;
0657     if (exists $cache->{BASETOOLS}{$t})
0658     {
0659       foreach my $t1 (keys %{$cache->{BASETOOLS}{$t}})
0660       {
0661         if(exists $data->{deps}{src}{$t1}){$skip=1;$btools{$t1}=1;last;}
0662       }
0663     }
0664     if(!$skip)
0665     {
0666       my $res=&parentCommunication("HAVE_DEPS","$depstr:$t");
0667           if ($res=~/^YES:(.+)/){print "DELETING Indirectly exists via:$t ($1)\n";$d=1;}
0668     }
0669       }
0670       $done{$t}=$d;
0671       if($d){delete $ts->{$s};last;}
0672     }
0673   }
0674   foreach my $t (keys %btools){delete $data->{deps}{src}{$t};print STDERR "DELETED BASE TOOL:$t\n";}
0675   my $symcount=keys %$ts;
0676   my $tsx={};
0677   foreach my $s (keys %$ts)
0678   {
0679     my @t=keys %{$ts->{$s}};
0680     if(scalar(@t)==1)
0681     {
0682       $tsx->{$t[0]}{$s}=$ts->{$s}{$t[0]};
0683       delete $ts->{$s};
0684       $symcount--;
0685     }
0686   }
0687   if ($symcount)
0688   {
0689     foreach my $t (keys %$tsx){foreach my $s (keys %$ts){if(exists $ts->{$s}{$t}){delete $ts->{$s};$symcount--;}}}
0690     if ($symcount)
0691     {
0692       foreach my $s (keys %$ts)
0693       {
0694         foreach my $t (keys %{$data->{SAME_LIB_TOOL}})
0695     {
0696       if(exists $ts->{$s}{$t})
0697       {
0698         foreach my $t1 (keys %{$data->{SAME_LIB_TOOL}{$t}}){if(exists $ts->{$s}{$t1}){delete $ts->{$s}{$t1};}}
0699         if(scalar(keys %{$ts->{$s}})==1){$tsx->{$t}{$s}=$ts->{$s}{$t};delete $ts->{$s};$symcount--;last;}
0700       }
0701     }
0702       }
0703     }
0704     if ($symcount && (defined $cacherefbf) && (exists $cacherefbf->{use}))
0705     {
0706       foreach my $s (keys %$ts)
0707       {
0708         foreach my $t (keys %{$ts->{$s}}){if(exists $cacherefbf->{use}{$t}){$tsx->{$t}{$s}=$ts->{$s}{$t};delete $ts->{$s};$symcount--;last;}}
0709       }
0710     }
0711   }
0712   my $depstr=join(",",keys %$tsx);
0713   foreach my $t (keys %$tsx)
0714   {
0715     my $res=&parentCommunication("HAVE_DEPS","$depstr:$t");
0716     if ($res=~/^YES:(.+)/){delete $tsx->{$t};print STDERR "1:DELETING Indirectly exists via:$t ($1)\n";}
0717   }
0718   if ($symcount)
0719   {
0720     print STDERR "WARNING: Following symbols are defined in multiple tools/packages\n";
0721     foreach my $s (keys %$ts)
0722     {
0723       my $s1=&SCRAMGenUtils::cppFilt ($s);
0724       print STDERR "  Symbol:$s1\n";
0725       foreach my $t (keys %{$ts->{$s}}){print STDERR "    Tool:$t\n";}
0726     }
0727   }
0728   return $tsx;
0729 }
0730 
0731 sub symbolCheck()
0732 {
0733   my $tsx=&processBinaryDeps(shift);
0734   foreach my $t (keys %$tsx)
0735   {
0736     if($t eq "system"){next;}
0737     if (exists $data->{deps}{src}{$t}){next;}
0738     elsif(exists $data->{NO_USE}{$t}){next;}
0739     elsif(exists $data->{NO_EXPORT}{$t}){next;}
0740     $data->{deps}{src}{$t}=1;
0741     print STDERR "EXTRA TOOL due to missing symbols:$t\n";
0742     print STDERR "  SYMBOLS FOUND:\n";
0743     foreach my $s (keys %{$tsx->{$t}})
0744     {
0745       my $s1=&SCRAMGenUtils::cppFilt ($s);
0746       print STDERR "    $s1 =>$tsx->{$t}{$s}\n";
0747     }
0748   }
0749 }
0750 
0751 sub parentCommunication ()
0752 {
0753   my $req=shift;
0754   my $msg=shift;
0755   print "$req:$msg\n";
0756   $req.="_DONE";
0757   my $rep=<STDIN>;chomp $rep;
0758   if($rep=~/^$req:\s*(.*)$/){$rep=$1;}
0759   else{print STDERR "$req FAILED\n$rep\n";$rep="";}
0760   return $rep;
0761 }
0762 
0763 ##############################################################
0764 #
0765 sub process_cxx_file ()
0766 {
0767   my $file=shift;
0768   my $data=shift;
0769   if(exists $data->{files}{$file}){return;}
0770   $data->{files}{$file}={};
0771   if($detail){print STDERR "Working on $file\n";}
0772   else{print STDERR ".";}
0773   &SCRAMGenUtils::searchIncFilesCXX($file,$data->{files}{$file});
0774   if(exists $data->{files}{$file}{includes})
0775   {
0776     my $selfdir=dirname($file);
0777     my $filter=$data->{filter};
0778     foreach my $inc (keys %{$data->{files}{$file}{includes}})
0779     {
0780       my $ainc=$inc;
0781       if($inc=~/^\./)
0782       {
0783     $inc=&SCRAMGenUtils::fixPath("${selfdir}/${inc}");
0784     if($inc=~/^$release\/src\/(.+)$/){$inc=$1;}
0785       }
0786       else{$inc=&SCRAMGenUtils::fixPath($inc);}
0787       if(exists $inccache->{UNKNOWN}{$inc}){next;}
0788       elsif(-f "${selfdir}/${inc}"){&process_cxx_file ("${selfdir}/${inc}",$data);}
0789       else
0790       {
0791     my $id="";
0792     my $info = &find_inc_file_path($inc);
0793     my $fpath=$info->{fullpath};
0794     if($fpath ne "")
0795     {
0796       if ($fpath=~/^${filter}\/.+$/){&process_cxx_file ($fpath,$data);}
0797       else
0798       {
0799         foreach my $pack (keys %{$info->{pack}})
0800         {
0801           if(("$pack" ne "$project") && ("$pack" ne "self"))
0802           {
0803             if($isPackage)
0804             {
0805               if($file=~/^${filter}\/${pkginterfacedir}\//){$data->{deps}{src}{$pack}=1;}
0806               elsif($file=~/^${filter}\/${pkgsrcdir}\//){$data->{deps}{src}{$pack}=1;}
0807             }
0808             else{$data->{deps}{src}{$pack}=1;}
0809           }
0810           if($detail && ($info->{new}==1)){$info->{new}=2; print STDERR "#$ainc=>$pack\n";}
0811         }
0812       }
0813     }
0814     elsif($detail && ($info->{new}==1)){$info->{new}=2; print STDERR "#$ainc:UNKNOWN (might be from system directories)\n";}
0815       }
0816     }
0817   }
0818 }
0819 
0820 sub read_inc_cache()
0821 {
0822   my $inc=shift;
0823   if (-z "${incdir}/${inc}/.info"){$inccache->{UNKNOWN}{$inc}=1;$inccache->{INC}{$inc}={};}
0824   else
0825   {
0826     my $ref;
0827     open($ref,"${incdir}/${inc}/.info") || die "Can not open file for reading:${incdir}/${inc}/.info\n";
0828     my $line=<$ref>; chomp $line;
0829     foreach my $p (split /:/,$line){$inccache->{INC}{$inc}{pack}{$p}=1;}
0830     $line=<$ref>; chomp $line;
0831     $inccache->{INC}{$inc}{fullpath}=$line;
0832     close($ref);
0833   }
0834   return $inccache->{INC}{$inc};
0835 }
0836 
0837 sub write_inc_cache()
0838 {
0839   my $inc=shift;
0840   my $ref;
0841   open($ref,">${incdir}/${inc}/.info") || die "Can not open file for writing:${incdir}/${inc}/.info\n";
0842   if (!exists $inccache->{UNKNOWN}{$inc})
0843   {
0844     print $ref "",join(":",keys %{$inccache->{INC}{$inc}{pack}}),"\n";
0845     print $ref "",$inccache->{INC}{$inc}{fullpath},"\n";
0846   }
0847   close($ref);
0848 }
0849 
0850 sub find_inc_file_path ()
0851 {
0852   my $inc=shift;
0853   if (exists $inccache->{INC}{$inc}){return $inccache->{INC}{$inc};}
0854   elsif(-f "${incdir}/${inc}/.info"){return &read_inc_cache($inc);}
0855   $inccache->{INC}{$inc}{new}=1;
0856   my $c=$inccache->{INC}{$inc};
0857   if(exists $data->{extra_include_path})
0858   {
0859     foreach my $d (keys %{$data->{extra_include_path}})
0860     {
0861       if(-f "${d}/${inc}")
0862       {
0863     my $pack="";
0864     $c->{fullpath}="${d}/${inc}";
0865     $pack=&run_func("check_inc","self",$inc);
0866     if($pack ne ""){$c->{pack}{$pack}=1;}
0867     return $c;
0868       }
0869     }
0870   }
0871   foreach my $t (keys %{$data->{EXTRA_TOOL_INFO}})
0872   {
0873     foreach my $exp (keys %{$data->{EXTRA_TOOL_INFO}{$t}{PRETOOL_INCLUDE_SEARCH_REGEXP}})
0874     {
0875       if($inc=~/$exp/)
0876       {
0877         my @incdirs=();
0878     if (exists $data->{EXTRA_TOOL_INFO}{$t}{INCLUDE}){@incdirs=keys %{$data->{EXTRA_TOOL_INFO}{$t}{INCLUDE}};}
0879     elsif((exists $cache->{TOOLS}{$t}) &&(exists $cache->{TOOLS}{$t}{INCLUDE})){@incdirs=@{$cache->{TOOLS}{$t}{INCLUDE}};}
0880         foreach my $d (@incdirs)
0881     {
0882       if(-f "${d}/${inc}")
0883       {
0884         $c->{pack}{$t}=1;
0885         $c->{fullpath}="${d}/${inc}";
0886         return $c;
0887       }
0888     }
0889       }
0890     }
0891   }
0892   foreach my $t (@{$cache->{OTOOLS}})
0893   {
0894     my $tool=$t;
0895     if($tool eq $project){next;}
0896     foreach my $d (@{$cache->{TOOLS}{$tool}{INCLUDE}})
0897     {
0898       if(!-f "${d}/${inc}"){next;}
0899       my $pack="";
0900       $c->{fullpath}="${d}/${inc}";
0901       $pack=&run_func("check_inc",$tool,$inc);
0902       if($pack ne "")
0903       {
0904     my $base=$cache->{TOOLS}{$tool}{BASE};
0905     if($tool eq "self"){$base=$release;}
0906     if(-f "${base}/src/${pack}/${inc}"){$c->{fullpath}="${base}/src/${pack}/${inc}";}
0907         $c->{pack}{$pack}=1;
0908       }
0909       else
0910       {
0911         if(exists $cache->{BASETOOLS}{$tool})
0912         {foreach my $p (keys %{$cache->{BASETOOLS}{$tool}}){$c->{pack}{$p}=1;}}
0913         else{$c->{pack}{$tool}=1;}
0914       }
0915       return $c;
0916     }
0917   }
0918   foreach my $t (keys %{$data->{EXTRA_TOOL_INFO}})
0919   {
0920     foreach my $exp (keys %{$data->{EXTRA_TOOL_INFO}{$t}{INCLUDE_SEARCH_REGEXP}})
0921     {
0922       if($inc=~/$exp/)
0923       {
0924         my @incdirs=();
0925     if (exists $data->{EXTRA_TOOL_INFO}{$t}{INCLUDE}){@incdirs=keys %{$data->{EXTRA_TOOL_INFO}{$t}{INCLUDE}};}
0926     elsif((exists $cache->{TOOLS}{$t}) &&(exists $cache->{TOOLS}{$t}{INCLUDE})){@incdirs=@{$cache->{TOOLS}{$t}{INCLUDE}};}
0927     foreach my $d (@incdirs)
0928     {
0929       if(-f "${d}/${inc}")
0930       {
0931         $c->{pack}{$t}=1;
0932         $c->{fullpath}="${d}/${inc}";
0933         $c->{new}=1;
0934         return $c;
0935       }
0936     }
0937       }
0938     }
0939   }
0940   $inccache->{UNKNOWN}{$inc}=1;
0941   return $c;
0942 }
0943 
0944 sub final_exit()
0945 {
0946   my $msg=shift;
0947   my $code=shift || 0;
0948   &save_toolcache();
0949   print STDERR "$msg\n";
0950   exit $code;
0951 }
0952 
0953 sub save_toolcache()
0954 {
0955   my $f=$cache->{dirty};
0956   delete $cache->{dirty};
0957   if($f)
0958   {
0959     my $dir=dirname($cachefile);
0960     system("mkdir -p $dir");
0961     &SCRAMGenUtils::writeHashCache($cache,"$cachefile");
0962   }
0963   my %dirs=();
0964   my %newinc=();
0965   my $ndir=0;
0966   foreach my $inc (keys %{$inccache->{INC}})
0967   {
0968     if (exists $inccache->{INC}{$inc}{new})
0969     {
0970       $newinc{$inc}=1;
0971       my $d=\%dirs;
0972       $ndir=1;
0973       foreach my $x (split /\//,$inc)
0974       {
0975     if($x eq ""){next;}
0976     $d->{$x} ||={};
0977     $d=$d->{$x};
0978       }
0979     }
0980   }
0981   if ($ndir){mkpath(&SCRAMGenUtils::findUniqDirs(\%dirs,$incdir),0,0755);}
0982   foreach my $inc (keys %newinc){&write_inc_cache($inc);}
0983 }
0984 
0985 sub commaSepDeps ()
0986 {
0987   my $d=shift;
0988   my $c=shift;
0989   my $type=shift;
0990   my @t=();
0991   my $xd="";
0992   if(-f "${cachedir}/${type}")
0993   {
0994     open(IFILE, "${cachedir}/${type}") || die "Can not open file \"${cachedir}/${type}\" for reading.";
0995     while(my $l=<IFILE>)
0996     {
0997       $l=~s/^\s*(.+?)\s*$/$1/;
0998       if(($l=~/^\s*$/) || ($l=~/^\s*#/)){next;}
0999       $xd.="$l,";
1000     }
1001     close(IFILE);
1002   }
1003   foreach my $x1 (@$d,$xd)
1004   {
1005     if($x1=~/^\s*([^\s]+)\s*$/)
1006     {
1007       $x1=$1;
1008       foreach my $x (split /\s*,\s*/, $x1)
1009       {
1010         if($x eq ""){next;}
1011     my $lx=lc($x);
1012         if(exists $c->{TOOLS}{$lx}){$x=$lx;}
1013     push @t,$x;
1014       }
1015     }
1016   }
1017   return @t;
1018 }
1019 #####################################
1020 # Run a tool specific func
1021 ####################################
1022 sub run_func ()
1023 {
1024   my $func=shift || return "";
1025   my $tool=shift || return "";
1026   if($tool eq "self"){$tool=$project;}
1027   $tool=lc($tool);
1028   my $func1="${func}_${tool}";
1029   if(exists &$func1){return &$func1(@_);}
1030   elsif($tool ne "default"){return run_func ($func,"default",@_);}
1031   return "";
1032 }
1033 
1034 sub exists_func()
1035 {
1036   my $func=shift || return "";
1037   my $tool=shift || return "";
1038   if($tool eq "self"){$tool=$project;}
1039   $tool=lc($tool);
1040   $func.="_${tool}";
1041   if(exists &$func){return 1;}
1042   return 0;
1043 }
1044 ######################################################################
1045 # Finding packages for a header file
1046 ######################################################################
1047 sub check_inc_extra_pack_info ()
1048 {
1049   my $f=shift;
1050   my $tool=shift;
1051   if((exists $data->{EXTRA_TOOL_INFO}{$tool}) && (exists $data->{EXTRA_TOOL_INFO}{$tool}{FILES_PACKAGE_MAP}))
1052   {
1053     foreach my $exp (keys %{$data->{EXTRA_TOOL_INFO}{$tool}{FILES_PACKAGE_MAP}})
1054     {if($f=~/$exp/){return $data->{EXTRA_TOOL_INFO}{$tool}{FILES_PACKAGE_MAP}{$exp};}}
1055   }
1056   return "";
1057 }
1058 
1059 sub check_inc_seal ()
1060 {return &check_lcg2levels(shift,"seal");}
1061 
1062 sub check_inc_pool ()
1063 {return &check_lcg1level(shift,"pool");}
1064 
1065 sub check_inc_coral ()
1066 {return &check_lcg1level(shift,"coral");}
1067 
1068 sub check_lcg1level ()
1069 {
1070   my $f=shift;
1071   my $tool=shift;
1072   my $base="";
1073   my $x=&check_inc_extra_pack_info($f,$tool);
1074   if($x){return $x;}
1075   if(!exists $cache->{TOOLS}{$tool})
1076   {$tool="self";$base=$release;}
1077   else{$base=$cache->{TOOLS}{$tool}{BASE};}
1078   $base.="/src";
1079   if(!exists $cache->{TOOLS}{$tool}{PACKS})
1080   {
1081     foreach my $pack (&SCRAMGenUtils::readDir($base,1)){$cache->{TOOLS}{$tool}{PACKS}{$pack}=1;}
1082     $cache->{dirty}=1;
1083   }
1084   foreach my $pack (keys %{$cache->{TOOLS}{$tool}{PACKS}})
1085   {if(-f "${base}/${pack}/${f}"){return $pack;}}
1086   foreach my $pack (keys %{$cache->{TOOLS}{$tool}{PACKS}})
1087   {if($f=~/^$pack\/src\//){return $pack;}}
1088   return "";
1089 }
1090 
1091 sub check_lcg2levels()
1092 {
1093   my $f=shift;
1094   my $tool=shift;
1095   my $base="";
1096   my $x=&check_inc_extra_pack_info($f,$tool);
1097   if($x){return $x;}
1098   if(!exists $cache->{TOOLS}{$tool})
1099   {$tool="self";$base=$release;}
1100   else{$base=$cache->{TOOLS}{$tool}{BASE};}
1101   $base.="/src";
1102   if(!exists $cache->{TOOLS}{$tool}{PACKS})
1103   {
1104     foreach my $subsys (&SCRAMGenUtils::readDir($base,1))
1105     {
1106       if($subsys=~/^(CVS|config|src|doc|admin|html|cmt|doxygen|qmtest|scram)$/){next;}
1107       foreach my $pack (&SCRAMGenUtils::readDir("${base}/${subsys}",1))
1108       {
1109         if($pack=~/^(CVS|config|src|doc|admin|html|cmt|doxygen|qmtest|scram)$/){next;}
1110     $cache->{TOOLS}{$tool}{PACKS}{"${subsys}/${pack}"}=1;
1111       }
1112     }
1113     $cache->{dirty}=1;
1114   }
1115   foreach my $pack (keys %{$cache->{TOOLS}{$tool}{PACKS}})
1116   {if(-f "${base}/${pack}/${f}"){return $pack;}}
1117   foreach my $pack (keys %{$cache->{TOOLS}{$tool}{PACKS}})
1118   {if($f=~/^$pack\/src\//){return $pack;}}
1119   return "";
1120 }
1121 
1122 sub check_inc_self ()
1123 {return &check_cms_scram (shift,$project);}
1124 
1125 sub check_inc_iguana ()
1126 {return &check_cms_scram (shift,"iguana");}
1127 
1128 sub check_inc_ignominy ()
1129 {return &check_cms_scram (shift,"ignominy");}
1130 
1131 sub check_inc_cmssw ()
1132 {return &check_cms_scram (shift,"cmssw");}
1133 
1134 sub check_cms_scram ()
1135 {
1136   my $f=shift;
1137   my $tool=shift;
1138   my $x=&check_inc_extra_pack_info($f,$tool);
1139   if($x){return $x;}
1140   if($f=~/^(.+?)\/(interface|src)\/.+$/){return $1;}
1141   return "";
1142 }
1143 
1144 sub check_inc_rootrflx ()
1145 {return &check_inc_rootcore(shift);}
1146 sub check_inc_rootmath ()
1147 {return &check_inc_rootcore(shift);}
1148 sub check_inc_rootminuit2 ()
1149 {return &check_inc_rootcore(shift);}
1150 sub check_inc_rootcintex ()
1151 {return &check_inc_rootcore(shift);}
1152 sub check_inc_rootcore ()
1153 {
1154   my $f=shift;
1155   my $x=&check_inc_extra_pack_info($f,$project) || &check_inc_extra_pack_info($f,"rootcore") || "rootcore";
1156   return $x;
1157 }
1158 
1159 sub check_inc_boost_filesystem ()
1160 {return &check_inc_boost(shift);}
1161 sub check_inc_boost_program_options ()
1162 {return &check_inc_boost(shift);}
1163 sub check_inc_boost_regex ()
1164 {return &check_inc_boost(shift);}
1165 sub check_inc_boost_python ()
1166 {return &check_inc_boost(shift);}
1167 
1168 sub check_inc_boost ()
1169 {
1170   my $f=shift;
1171   my $x=&check_inc_extra_pack_info($f,"boost") || "boost";
1172   return $x;
1173 }
1174 #############################################
1175 # generating library safe name for a package
1176 #############################################
1177 sub safename_pool ()
1178 {return "lcg_".basename(shift);}
1179 sub safename_seal ()
1180 {return "lcg_".basename(shift);}
1181 sub safename_coral ()
1182 {return "lcg_".basename(shift);}
1183 
1184 sub safename_ignominy ()
1185 {return &safename_cms1(shift);}
1186 sub safename_iguana ()
1187 {return &safename_cms1(shift);}
1188 sub safename_cmssw ()
1189 {return &safename_cms2(shift);}
1190 sub safename_self ()
1191 {return &safename_cms2($project);}
1192 
1193 sub safename_cms1 ()
1194 {
1195   my $dir=shift;
1196   if($dir=~/^${release}\/src\/([^\/]+?)\/([^\/]+)$/){return "${2}";}
1197   else{return "";}
1198 }
1199 sub safename_cms2 ()
1200 {
1201   my $dir=shift;
1202   if($dir=~/^${release}\/src\/([^\/]+?)\/([^\/]+)$/){return "${1}${2}";}
1203   else{return "";}
1204 }
1205 
1206 sub defaultplugin_seal (){return "seal";}
1207 sub defaultplugin_pool (){return "seal";}
1208 sub defaultplugin_coral (){return "seal";}
1209 sub defaultplugin_ignominy (){return "seal";}
1210 sub defaultplugin_iguana (){return "seal";}
1211 sub defaultplugin_cmssw (){return "edm_";}
1212 sub defaultplugin_default (){return "seal";}
1213 
1214 #############################################
1215 # getting interface file directory name
1216 #############################################
1217 sub pkg_interface_pool ()
1218 {return basename(shift);}
1219 sub pkg_interface_seal ()
1220 {return basename(shift);}
1221 sub pkg_interface_coral ()
1222 {return basename(shift);}
1223 
1224 sub pkg_interface_ignominy ()
1225 {return "interface";}
1226 sub pkg_interface_iguana ()
1227 {return "interface";}
1228 sub pkg_interface_cmssw ()
1229 {return "interface";}
1230 
1231 sub pkg_src_pool ()
1232 {return "src";}
1233 sub pkg_src_seal ()
1234 {return "src";}
1235 sub pkg_src_coral ()
1236 {return "src";}
1237 
1238 sub pkg_src_ignominy ()
1239 {return "src";}
1240 sub pkg_src_iguana ()
1241 {return "src";}
1242 sub pkg_src_cmssw ()
1243 {return "src";}
1244 
1245 ##########################################################
1246 sub update_project_cache ()
1247 {
1248   my $cache=shift;
1249   my $cf=&SCRAMGenUtils::fixCacheFileName("${release}/.SCRAM/${scramarch}/ToolCache.db");
1250   if (!-f $cf){die "Can not find file for reading: $cf\n";}
1251   my $c=&SCRAMGenUtils::readCache($cf);
1252   my %allinc=();
1253   my $allincstr="";
1254   my $flags="";
1255   $cache->{OTOOLS}=[];
1256   foreach my $t (&SCRAMGenUtils::getOrderedTools($c))
1257   {
1258     push @{$cache->{OTOOLS}},$t;
1259     my $bt=uc($t)."_BASE";
1260     my $sproj=$c->{SETUP}{$t}{SCRAM_PROJECT} || 0;
1261     $cache->{TOOLS}{$t}{SCRAM_PROJECT}=$sproj;
1262     if($t eq "self"){$bt=uc($project)."_BASE";$sproj=1;$bt=$release;}
1263     elsif(exists $c->{SETUP}{$t}{$bt}){$cache->{VARS}{$bt}=$c->{SETUP}{$t}{$bt};$bt=$c->{SETUP}{$t}{$bt};$cache->{TOOLS}{$t}{BASE}=$bt;}
1264     if($t eq $compiler){if((exists $c->{SETUP}{$t}{CXX}) && (-x $c->{SETUP}{$t}{CXX})){$cache->{COMPILER}=$c->{SETUP}{$t}{CXX};}}
1265     if(exists $c->{SETUP}{$t}{FLAGS})
1266     {
1267       if(exists $c->{SETUP}{$t}{FLAGS}{CXXFLAGS}){$flags.=" ".join(" ",@{$c->{SETUP}{$t}{FLAGS}{CXXFLAGS}});}
1268       if(exists $c->{SETUP}{$t}{FLAGS}{CPPDEFINES}){$flags.=" -D".join(" -D",@{$c->{SETUP}{$t}{FLAGS}{CPPDEFINES}});}
1269     }
1270     foreach my $f ("INCLUDE", "LIBDIR", "LIB", "USE")
1271     {
1272       if(exists $c->{SETUP}{$t}{$f})
1273       {
1274         my %tmp=();
1275     foreach my $k (@{$c->{SETUP}{$t}{$f}})
1276         {
1277           if($f eq "USE"){$k=lc($k);}
1278           if(!exists $tmp{$k})
1279       {
1280         if(!exists $cache->{TOOLS}{$t}{$f}){$cache->{TOOLS}{$t}{$f}=[];}
1281         push @{$cache->{TOOLS}{$t}{$f}},$k;
1282         $tmp{$k}=1;
1283         if(($f eq "INCLUDE") && ($k!~/^\s*$/) && (!exists $allinc{$k}) && (-d $k))
1284         { 
1285           if($t eq "self")
1286           {
1287             my $sdir="${release}/src";
1288         if(!exists $allinc{$sdir}){push @{$cache->{TOOLS}{$t}{$f}},$sdir;$allinc{$sdir}=1;}
1289           }
1290           $allinc{$k}=1;$allincstr.=" -I$k";
1291         }
1292       }
1293     }
1294       }
1295     }
1296     if((exists $cache->{TOOLS}{$t}) && (exists $cache->{TOOLS}{$t}{LIB}) && (!exists $cache->{TOOLS}{$t}{LIBDIR}))
1297     {
1298       if(&exists_func("check_inc",$t)){$cache->{IGNORE_BASETOOLS}{$t}=1;}
1299       if(!exists $cache->{IGNORE_BASETOOLS}{$t})
1300       {
1301         foreach my $l (@{$cache->{TOOLS}{$t}{LIB}})
1302         {
1303           my $ts=&find_lib_tool($c,$l,$t);
1304       foreach my $t1 (keys %$ts)
1305       {
1306         my $file=&SCRAMGenUtils::findActualPath($ts->{$t1});
1307         $cache->{BASETOOLS}{$t}{$t1}=1;
1308         $cache->{XBASETOOLS}{$t1}{$t}=1;
1309       }
1310         }
1311       }
1312     }
1313   }
1314   $cache->{CXXINCLUDE}=$allincstr;
1315   $cache->{CXXFLAGS}=$flags;
1316   $cache->{dirty}=1;
1317 }
1318 
1319 sub replaceVariables {
1320   my $key=shift || return "";
1321   while($key=~/(.*)\$\(([^\$\(\)]*)\)(.*)/){
1322     my $subkey=$2;
1323     if("$subkey" ne ""){
1324       if($subkey eq "LOCALTOP"){$subkey="$release";}
1325       elsif(exists $envcache->{$subkey}){$subkey=$envcache->{$subkey};}
1326       elsif(exists $cache->{VARS}{$subkey}){$subkey=$cache->{VARS}{$subkey};}
1327       else{$subkey=$ENV{$subkey};}
1328     }
1329     $key="${1}${subkey}${3}";
1330   }
1331   return $key;
1332 }
1333 
1334 sub find_lib_tool ()
1335 {
1336   my $c=shift;
1337   my $lib=shift;
1338   my $t=shift;
1339   my $tools={};
1340   if(exists $c->{SETUP}{$t}{USE})
1341   {
1342     foreach my $t1 (@{$c->{SETUP}{$t}{USE}})
1343     {
1344       $t1=lc($t1);
1345       if(exists $c->{SETUP}{$t1}{LIBDIR})
1346       {
1347         foreach my $d (@{$c->{SETUP}{$t1}{LIBDIR}})
1348     {
1349       if(-f "${d}/lib$lib.so"){$tools->{$t1}="${d}/lib$lib.so";}
1350       elsif(-f "${d}/lib$lib.a"){$tools->{$t1}="${d}/lib$lib.a";}
1351     }
1352       }
1353     }
1354     if(scalar(keys %$tools)>0){return $tools;}
1355     foreach my $t1 (@{$c->{SETUP}{$t}{USE}})
1356     {
1357       my $t2=&find_lib_tool($c,$lib,lc($t1));
1358       if(scalar(keys %$t2)>0){return $t2;}
1359     }
1360   }
1361   return $tools;
1362 }
1363 
1364 #########################################################################
1365 # Help message
1366 #########################################################################
1367 
1368 sub usage_msg()
1369 {
1370   my $script=basename($0);
1371   print "Usage: $script --dir <path>\n";
1372   print "\t[--files <files>]      [--prodname <name>] [--prodtype <library|bin>]\n";
1373   print "\t[--use <tool/pack>]    [--no-use <tool/pack>]\n";
1374   print "\t[--export <tool/pack>] [--no-export <tool/pack>] [--flag <flags>]\n";
1375   print "\t[--replace <oldtool/oldpackage>=<newdtool/newpackage>]\n";
1376   print "\t[--ref-bf <BuildFile>] [--jobs <jobs>] [--tmpdir <dir>] [--buildfile <name>]\n";
1377   print "\t[--plugin] [--detail] [--help]\n\n";
1378   print "Where\n";
1379   print "  --dir <path>         Path of package or other product area area for which you want to\n";
1380   print "                       generate BuildFile.\n";
1381   print "  --files <files>      Comma separated list of files relative path w.t.r the dirtecoty\n";
1382   print "                       provided via --dir <path> command-line argument. Only\n";
1383   print "                       files with extensions \"$srcext\" are allowed.\n";
1384   print "                       You can add this command-line argument multiple times.\n";
1385   print "  --prodname <name>    Name of the product. By default is there is only one source file\n";
1386   print "                       provided via --files command-line argument then name will be drived\n";
1387   print "                       from that by removing the file extensions (.[$srcext]).\n";
1388   print "  --prodtype <type>    Name of the product type. Only valid values are \"library\" or \"bin\".\n";
1389   print "  --use <tool/pack>    To add an extra dependency on tool/package(for non-export section only)\n";
1390   print "                       You can add this command-line argument multiple times.\n";
1391   print "  --no-use <tool/pack> To remove dependency on tool/package(for non-export section only)\n";
1392   print "                       You can add this command-line argument multiple times.\n";
1393   print "  --export <tool/pack> To add an extra dependency on tool/package(for both export and non-export sections)\n";
1394   print "                       You can add this command-line argument multiple times.\n";
1395   print "  --no-export <tool/pack>\n";
1396   print "                       To remove dependency on tool/package(for both export and non-export sections)\n";
1397   print "                       You can add this command-line argument multiple times.\n";
1398   print "  --replace <oldtool/oldpack>=<newtool/newpack>\n";
1399   print "                       To replace a oldtool/oldpack with a newtool/newpack.\n";
1400   print "                       You can add this command-line argument multiple times.\n";
1401   print "  --ref-bf <buildfile> Provide a reference BuildFile to search for extra flags. By default is uses the\n";
1402   print "                       SubSystem/Package/BuildFile for a package directory.\n";
1403   print "  --jobs <jobs>        Number of parallel processes\n";
1404   print "  --tmpdir <path>      Path of a temporary area where this script should save its internal caches and put newly\n";
1405   print "                       generated BuildFile(s).\n";
1406   print "  --buildfile <name>   Path for auto generated BuildFile. By default it will be printed on strandard output.\n";
1407   print "  --plugin             Generate BuildFile with plugin flag in it.\n";
1408   print "                       NOTE: If package contains classes.h then this flag will not be added.\n";
1409   print "  --clean              Reset the internal tool cache and start from scratch.\n";
1410   print "  --xml                To generate XML-based BuildFiles i.e. BuildFile.xml.auto\n";
1411   print "  --detail             Run in debug mode i.e. prints more debug output.\n";
1412   print "  --help               Print this help message.\n\n";
1413   print "E.g. running something following from your project top level directory\n\n";
1414   print "  $script --dir src/FWCore/Services --flag CPPDEFINES=\"DEBUG=1\" --flag CPPDEFINES='USER=\"name\"'\n\n";
1415   print "means print a BuildFile for FWCore/Services package and add two extra flags.\n";
1416   print "NOTE: If there is already a <path>/BuildFile exists then script will read that BuildFile\n";
1417   print "and add all the flags, makefile fragments, extra libs etc. in the newly generated BuildFile too.\n";
1418   exit 0;
1419 }