Back to home page

Project CMSSW displayed by LXR

 
 

    


Warning, /Utilities/ReleaseScripts/ignominy/config/IgnominySCRAM/searchPath is written in an unsupported language. File is not indexed.

0001 #!/usr/bin/env perl
0002 use File::Basename;
0003 use Storable qw(nstore retrieve);
0004 
0005 $|=1;
0006 my $release=shift;
0007 my $outdir=shift;
0008 
0009 my $whoami=`whoami`; chomp $whoami;
0010 my $CURDIR=`pwd`; chomp $CURDIR;
0011 my $SCRIPT_PATH=dirname($0);
0012 if($SCRIPT_PATH !~ /^\//){$SCRIPT_PATH="${CURDIR}/${SCRIPT_PATH}";}
0013 #current scram arch
0014 my $SCRAM_CMD="scramv1";
0015 my $SCRAM_VER="V[12]_.*";
0016 my $SCRAM_ARCH=`$SCRAM_CMD arch`; chomp $SCRAM_ARCH;
0017 my $DEPS_ARCH=`echo $SCRAM_ARCH | sed 's/[_/][_/]*/-/g' | tr '[A-Z]' '[a-z]'`;
0018 my $DEPS_DOC_RELDIR="doc/deps/$DEPS_ARCH";
0019 my $BASE_ANALYSIS_URL="http://www.cern.ch/ignominy/CMSProjects";
0020 my $PROJECT_RELEASE_BASE="/afs/cern.ch/cms/Releases";
0021 my $searchcachefile="searchcache";
0022 my $searchcache = {};
0023 my $searchcachedirty = 0;
0024 my $localtop    = "";
0025 my $CACHE;
0026 my $LOCALCACHE;
0027 my %LCG_ARCH_MAP;
0028 my $ignoreTest=0;
0029 my $LibExt="so";
0030 if ($^O=~/darwin/io){$LibExt="dylib";}
0031 
0032 my $extra_tool_info={};
0033 $extra_tool_info->{EXTRA_TOOL_INFO}{iguana}{FILES_PACKAGE_MAP}{'classlib\/.+'}="Iguana/Utilities";
0034 $extra_tool_info->{EXTRA_TOOL_INFO}{iguana}{FILES_PACKAGE_MAP}{'gl2ps.h$'}="Iguana/GL2PS";
0035 $extra_tool_info->{EXTRA_TOOL_INFO}{cmssw}{FILES_PACKAGE_MAP}{'classlib\/.+'}="Iguana/Utilities";
0036 $extra_tool_info->{EXTRA_TOOL_INFO}{cmssw}{FILES_PACKAGE_MAP}{'gl2ps.h$'}="Iguana/GL2PS";
0037 $extra_tool_info->{EXTRA_TOOL_INFO}{rootcore}{FILES_PACKAGE_MAP}{'Reflex\/'}="Rootrflx";
0038 $extra_tool_info->{EXTRA_TOOL_INFO}{rootcore}{FILES_PACKAGE_MAP}{'Math\/'}="Rootmath";
0039 $extra_tool_info->{EXTRA_TOOL_INFO}{rootcore}{FILES_PACKAGE_MAP}{'Minuit2\/'}="Rootminuit2";
0040 $extra_tool_info->{EXTRA_TOOL_INFO}{rootcore}{FILES_PACKAGE_MAP}{'Cintex\/'}="Rootcintex";
0041 $extra_tool_info->{EXTRA_TOOL_INFO}{boost}{FILES_PACKAGE_MAP}{'boost\/filesystem(\/|\.).+'}="Boost_filesystem";
0042 $extra_tool_info->{EXTRA_TOOL_INFO}{boost}{FILES_PACKAGE_MAP}{'boost\/program_options(\/|\.).+'}="Boost_program_options";
0043 $extra_tool_info->{EXTRA_TOOL_INFO}{boost}{FILES_PACKAGE_MAP}{'boost\/regex(\/|[\.\_]).+'}="Boost_regex";
0044 $extra_tool_info->{EXTRA_TOOL_INFO}{boost}{FILES_PACKAGE_MAP}{'boost\/python(\/|\.).+'}="Boost_python";
0045 $extra_tool_info->{TOOL_DONE}={};
0046 
0047 foreach my $t (keys %{$extra_tool_info->{EXTRA_TOOL_INFO}})
0048 {
0049   if(exists $extra_tool_info->{EXTRA_TOOL_INFO}{$t}{FILES_PACKAGE_MAP})
0050   {
0051     foreach my $reg (keys %{$extra_tool_info->{EXTRA_TOOL_INFO}{$t}{FILES_PACKAGE_MAP}})
0052     {
0053       my $t1=lc($extra_tool_info->{EXTRA_TOOL_INFO}{$t}{FILES_PACKAGE_MAP}{$reg});
0054       $extra_tool_info->{TOOL_ORDER}{$t1}{pretools}{$t}=1;
0055     }
0056   }
0057 }
0058 
0059 if((!defined $outdir) || ($outdir eq "")){$outdir=$CURDIR;}
0060 my $toolver="${outdir}/tool-versions.conf";
0061 my $verdep="${outdir}/versions-deps.conf";
0062 my $vers="${outdir}/versions";
0063 my $prodmap="${outdir}/products.txt";
0064 my $exclude_metrics="${outdir}/exclude-metrics";
0065 my $exclude_bins="";
0066 
0067 if(defined $release)
0068 {
0069   if(!-d $release)
0070   {
0071     print STDERR "ERROR: Release directory \"$release\" does not exist.\n"; 
0072     &exit_prog(1);
0073   }
0074   else{chdir($release); $release=`/bin/pwd`; chomp $release;}
0075 }
0076 else{$release=$CURDIR; chomp $release;}
0077 my $dir=&scram_release_top($release);
0078 if(-d "${dir}/.SCRAM"){$release=$dir;}
0079 else{print STDERR "ERROR: Can not find release directory for \"$release\".\n"; &exit_prog(1);}
0080 
0081 if(!-f "${release}/.SCRAM/Environment")
0082 {
0083   print STDERR "ERROR: ${release}/.SCRAM/Environment does not exist.\n"; 
0084   &exit_prog(1);
0085 }
0086 my $SCRAM_BASE=&getScramPath($release);
0087 unshift @INC,"${SCRAM_BASE}/src";
0088 $localtop    = $release;
0089 $CACHE->{ENVIRONMENT}={};
0090 $CACHE->{LOCALTOP}=$release;
0091 &read_Environment ();
0092 
0093 #set project name and version
0094 my $project_name= &get_scram_variable("SCRAM_PROJECTNAME",1);
0095 my $self        = lc($project_name);
0096 my $project_ver = &get_scram_variable("SCRAM_PROJECTVERSION",1);
0097 my $src_name    = &get_scram_variable("SCRAM_SOURCEDIR",1) || "src";
0098 my $src_path="${release}/${src_name}";
0099 my $config_name = &get_scram_variable("SCRAM_CONFIGDIR",1) || "config";
0100 my $releasetop  = &get_scram_variable("RELEASETOP",1);
0101 my $scram_ver   = `cat ${release}/${config_name}/scram_version`; chomp $scram_ver;
0102 if ($scram_ver!~/^$SCRAM_VER/)
0103 {
0104   print STDERR "ERROR: $project_name version $project_ver is based on SCRAM version $scram_ver,\n";
0105   print STDERR "ERROR: while this version of IGNOMINY supports SCRAM version $SCRAM_VER.\n";
0106   &exit_prog(1);
0107 }
0108 my %uniqToolLibdir = ();
0109 if($releasetop eq ""){$releasetop=$localtop;}
0110 
0111 &parse_project ();
0112 if ($searchcachedirty){&writesearchcache ($searchcache, $searchcachefile);}
0113 &scram_defaults ();
0114 
0115 sub printToFile ()
0116 {
0117   my $file=shift || return;
0118   my $msg=shift;
0119   system("echo \'$msg\' >> $file");
0120 }
0121 
0122 sub parse_project ()
0123 {
0124   my $toolcache;
0125   my $projectcache;
0126 
0127   my $APP="$project_name $project_ver";
0128   system("rm -f $toolver $verdep $vers $prodmap");
0129   system("touch $toolver $verdep $vers $prodmap");
0130   &printToFile ($verdep, "################################################################################");
0131   &printToFile ($verdep, "# Direct version dependencies");
0132   &printToFile ($verdep, "");
0133   &printToFile ($vers, "<HTML><HEAD><TITLE>$APP external tools versions</TITLE></HEAD><BODY>");
0134   &printToFile ($vers, "<CENTER><H1>$APP External Tools Versions Information</H1></CENTER>");
0135   &printToFile ($vers, "<BR><BR><CENTER><TABLE CELLPADDING=\"2\" CELLSPACING=\"2\" BORDER=\"1\"");
0136   &printToFile ($vers, "STYLE=\"WIDTH: 50%; TEXT-ALIGN: LEFT; MARGIN-LEFT: AUTO; MARGIN-RIGHT: AUTO; ");
0137   &printToFile ($vers, "BACKGROUND-COLOR: RGB(255, 255, 204);\"><TBODY>");
0138   &printToFile ($vers, "<TR><TD><B>Tool Name</B></TD><TD><B>Version Number</B></TD></TR>");
0139 
0140   $toolcache=&readcache("${releasetop}/.SCRAM/${SCRAM_ARCH}/ToolCache.db");
0141   $LOCALCACHE->{SCRAM_PROJECTS}{$self}{TOOL}=$toolcache;
0142   $projectcache=&readcache("${releasetop}/.SCRAM/${SCRAM_ARCH}/ProjectCache.db");
0143   $LOCALCACHE->{SCRAM_PROJECTS}{$self}{PROJECT}=$projectcache;
0144 
0145   print "option match pre-gen\n";
0146   
0147   &addProjectInfo ("self", $LOCALCACHE->{SCRAM_PROJECTS}{$self});
0148   if ($exclude_bins ne "")
0149   {
0150     system("touch $exclude_metrics");
0151     system("echo \"$exclude_bins\" >> $exclude_metrics");
0152   }
0153   foreach my $t (&getOrderedTools($toolcache))
0154   {
0155     if ($t eq "self"){next;}
0156     my $vlink="";
0157     my $name=&toolTag($t, $LOCALCACHE->{SCRAM_PROJECTS}{$self}, "TOOLNAME") || lc($t);
0158     my $ver=&toolTag($t, $LOCALCACHE->{SCRAM_PROJECTS}{$self}, "TOOLVERSION");
0159     $vlink=$ver;
0160     &printToFile ($toolver, "version ^$name\$:$ver");
0161     if (&isExist ("$t:SCRAM_PROJECT", $toolcache->{SETUP}) && $toolcache->{SETUP}{$t}{SCRAM_PROJECT})
0162     {
0163       my $base=&toolBase($t, $LOCALCACHE->{SCRAM_PROJECTS}{$self});
0164       my $uct=uc($t);
0165       &printToFile ($verdep, "${uct}/${uct}:");
0166       if(($base ne "") && (-d $base))
0167       {
0168         if (&isCMSProject ($t))
0169         {
0170           my $depfile="${base}/${DEPS_DOC_RELDIR}/index.html";
0171           if (-e $depfile)
0172           {
0173             $depfile=~s/^($PROJECT_RELEASE_BASE)(.+)/${BASE_ANALYSIS_URL}${2}/;
0174             $vlink="<A TARGET=_blank HREF=\"$depfile\">$ver</A>"
0175           }
0176         }
0177         my $error=0;
0178         foreach my $f ("Tool", "Project")
0179         {
0180           my $file=&cachefilename("${base}/.SCRAM/${SCRAM_ARCH}/${f}Cache.db");
0181           if (-f "$file"){$LOCALCACHE->{SCRAM_PROJECTS}{$t}{uc($f)}=&readcache("$file");}
0182           else{print STDERR "ERROR: Missing cache file $file for tool $t.\n";$error++;}
0183         }
0184         if(!$error){&addProjectInfo ($t, $LOCALCACHE->{SCRAM_PROJECTS}{$t});}
0185       }
0186       else{print STDERR "ERROR: Missing ${uct}_BASE for tool $t.\n"; }
0187     }
0188     else{
0189       &addToolInfo($t, $LOCALCACHE->{SCRAM_PROJECTS}{$self},0,1);
0190       &printToFile ($verdep, $CACHE->{SUBSYSTEMS}{$t}."/${name}:");
0191     }
0192     &printToFile ($vers, "<TR><TD>$name</TD><TD>$vlink</TD></TR>");
0193   }
0194   &printToFile ($vers, "</TBODY></TABLE></CENTER></BODY></HTML>");
0195   print "#Uniq Tool Libs\n";
0196   foreach my $libdir (keys %uniqToolLibdir)
0197   {
0198     my $from=$uniqToolLibdir{$libdir}{from};
0199     my $count=$uniqToolLibdir{$libdir}{count};
0200     if ($count>1){$from="${from}_EXTRA";}
0201     my $libdirq=quotemeta("${libdir}/");
0202     print "match ^$libdirq.+\$:'$from'\n";
0203   }
0204 }
0205 
0206 sub addProjectInfo ()
0207 {
0208   my $tool=shift || return;
0209   my $cache=shift  || return;
0210   
0211   my $func="process_$tool";
0212   if (exists &$func){return &$func($tool, $cache);}
0213   
0214   my $tool1=$tool;
0215   if($tool eq "self"){$tool1=$self;}
0216   my $uct=uc($tool1);
0217   
0218   if (&isCMSProject ($tool1))
0219   {
0220     print "#CMS/$uct\n";
0221     &addCMSProjectInfo ($tool, $cache);
0222   }
0223   elsif(&isLCGProject ($tool1))
0224   {
0225     print "#LCGAPP/$uct\n";
0226     &addLCGProjectInfo ($tool, $cache);
0227   }
0228   else{print "#Project \"$tool1\" type unknown.\n";}
0229 }
0230 
0231 
0232 sub addProductMap()
0233 {
0234   my $tool=shift;
0235   if ($tool ne "self"){return;}
0236   my $class=shift;
0237   my $type=shift;
0238   if ($class=~/(PACKAGE|SUBSYSTEM|PYTHON|DATA_INSTALL)/){return;}
0239   my $dir=shift;
0240   my $name=shift;
0241   if ($type=~/^LIBRARY$/)
0242   {
0243     my $file=shift;
0244     if ($file=~/\/plugin${name}\.${LibExt}$/){$type="PLUGINS";}
0245   }
0246   if ($class eq "CLASSLIB"){$class="LIBRARY"; $type="LIBRARY";}
0247   &printToFile ($prodmap, "$class:$type:$dir:$name");
0248 }
0249 
0250 sub addCMSProjectInfo ()
0251 {
0252   my $tool=shift || return;
0253   my $cache=shift  || return;
0254   my $cache1=$LOCALCACHE->{SCRAM_PROJECTS}{$self};
0255   
0256   my $libdirs=[];
0257   my $bindirs=[];
0258   
0259   my $base="";
0260   my $system="";
0261   my $testd="";
0262   my $found=0;
0263   if ($tool eq "self")
0264   {
0265     $system="";
0266     $base=$releasetop;
0267     if(&isExist("RUNTIME#PATH:PATH", $cache1->{TOOL}{SETUP}{$tool}, "#")){$bindirs=$cache1->{TOOL}{SETUP}{$tool}{RUNTIME}{"PATH:PATH"};}
0268     
0269     foreach my $td1 ("tests/bin", "tests", "test/bin", "test")
0270     {
0271       my $td="${base}/${td1}/${SCRAM_ARCH}";
0272       foreach my $d (@{$bindirs})
0273       {if($d=~/^$td$/){$found=1;last;}}
0274       if((!$found) && (-d $td)){push @{$bindirs}, $td;}
0275     }
0276     if (!-f "$searchcachefile" && -f "${base}/${DEPS_DOC_RELDIR}/${searchcachefile}")
0277     {system("cp ${base}/${DEPS_DOC_RELDIR}/${searchcachefile} $searchcachefile");}
0278   }
0279   else
0280   {
0281     $system=uc($tool);
0282     $base=&toolBase($tool, $cache1);
0283     if (!-f "$searchcachefile" && -f "${base}/${DEPS_DOC_RELDIR}/${searchcachefile}")
0284     {
0285       my $sc=&readsearchcache ("${base}/${DEPS_DOC_RELDIR}/${searchcachefile}");
0286       foreach my $key (keys %{$sc})
0287       {$searchcache->{$key}="${system}/".$sc->{$key};}
0288       $searchcachedirty=1;
0289     }
0290   }
0291   $testd="${base}/tests/lib/${SCRAM_ARCH}";
0292   if(&isExist("RUNTIME#PATH:LD_LIBRARY_PATH", $cache1->{TOOL}{SETUP}{$tool}, "#")){$libdirs=$cache1->{TOOL}{SETUP}{$tool}{RUNTIME}{"PATH:LD_LIBRARY_PATH"};}
0293   elsif(&isExist("LIBDIR", $cache1->{TOOL}{SETUP}{$tool})){$libdirs=$cache1->{TOOL}{SETUP}{$tool}{LIBDIR};}
0294   $found=0;
0295   foreach my $d (@{$libdirs})
0296   {if($d=~/^$testd$/){$found=1; last;}}
0297   if((!$found) && (-d $testd)){push @{$libdirs}, $testd;}
0298   
0299   my %bins=(); my %libs=();
0300   my %xdirs=();
0301   if(&isExist ("PROJECT:BUILDTREE", $cache))
0302   {
0303     foreach my $dir (keys %{$cache->{PROJECT}{BUILDTREE}})
0304     {
0305       if($dir=~/\/(CVS|.admin|doc|domain|html)(\/|)$/){next;}
0306       my $class=&getTag ("CLASS", $cache->{PROJECT}{BUILDTREE}{$dir}, "");
0307       my $name=&getTag ("NAME", $cache->{PROJECT}{BUILDTREE}{$dir}, "");
0308       my $parent=&getTag ("PARENT", $cache->{PROJECT}{BUILDTREE}{$dir}, "");
0309       if (($class=~/(LIBRARY|CLASSLIB)/i) && ($name ne "") && ($parent ne ""))
0310       {
0311         if ($scram_ver=~/^V1_0_/)
0312         {
0313           if ($class eq "CLASSLIB"){$name="classlib";}
0314           else
0315           {
0316             my $sname=&run_func("safename",$tool, $dir);
0317             if($sname){$name=$sname;}
0318           }
0319         }
0320         foreach my $libexp ('"lib".$name.".$LibExt"','"plugin".$name.".$LibExt"','$name.".iglet"')
0321         {
0322           my $libname=eval "$libexp";
0323           foreach my $d (@{$libdirs})
0324           {
0325             if(-f "${d}/${libname}")
0326             {
0327               my $libpath="${d}/${libname}";
0328               $libpath=&getActualPath ($libpath);
0329               &addProductMap($tool,$class,$class,$dir,$name,$libpath);
0330               my $libpathq=quotemeta($libpath);
0331               if ($tool eq "self"){print "scan libs $libpath\n";}
0332               if($system){print "match ^".$libpathq."\$:\'${system}/${parent}\'\n";}
0333               else{print "match ^".$libpathq."\$:\'${parent}\'\n";}
0334               $libs{$libname}=1;
0335               last;
0336             }
0337           }
0338         }
0339       }
0340       elsif (($class=~/PYTHON/i) && ($tool eq "self") && ($name ne "") && ($parent ne ""))
0341       {
0342         my $lib_prefix="Py";
0343         foreach my $d (@{$libdirs})
0344         {
0345           my $libname="$name";
0346           if (!-f "${d}/${lib_prefix}${libname}.${LibExt}")
0347           {
0348             if($parent=~/^(.+?)\/([^\/]+)$/)
0349             {$libname="$1$2";}
0350           }
0351           if(-f "${d}/${lib_prefix}${libname}.${LibExt}")
0352           {
0353             my $libpath="${d}/${lib_prefix}${libname}.${LibExt}";
0354             $libpath=&getActualPath ($libpath);
0355             &addProductMap($tool,$class,$class,$dir,$name,$libpath);
0356             my $libpathq=quotemeta($libpath);
0357             if ($tool eq "self"){print "scan libs $libpath\n";}
0358             if($system){print "match ^".$libpathq."\$:\'${system}/${parent}/python\'\n";}
0359             else{print "match ^".$libpathq."\$:\'${parent}/python\'\n";}
0360             $libs{"${lib_prefix}${libname}.${libext}"}=1;
0361             $libpathq=quotemeta("${parent}/python");
0362             print "match ^.+\\/$libpathq\\/.+\$:\'${parent}/python\'\n";
0363             last;
0364           }
0365         }
0366       }
0367       elsif ((!$ignoreTest) && ($tool eq "self") && ($class eq "TEST"))
0368       {
0369         if (&isExist ("RAWDATA:content:BUILDPRODUCTS",$cache->{PROJECT}{BUILDTREE}{$dir}))
0370         {
0371           foreach my $type (keys %{$cache->{PROJECT}{BUILDTREE}{$dir}{RAWDATA}{content}{BUILDPRODUCTS}})
0372           {
0373             my $srcdir="${base}/${src_name}/${dir}";
0374             $type=uc($type);
0375             if ($type eq "BIN")
0376             {
0377               foreach my $bp (keys %{$cache->{PROJECT}{BUILDTREE}{$dir}{RAWDATA}{content}{BUILDPRODUCTS}{$type}})
0378               {
0379                 $name=$cache->{PROJECT}{BUILDTREE}{$dir}{RAWDATA}{content}{BUILDPRODUCTS}{$type}{$bp}{NAME};
0380                 $found=0;
0381                 foreach my $d (@{$bindirs})
0382                 {
0383                   my $bin="${d}/$name";
0384                   if (-f $bin && -x $bin)
0385                   {
0386                     $found=1;
0387                     $bin=&getActualPath ($bin);
0388                     &addProductMap($tool,$class,$type,$dir,$name,$bin);
0389                     my $binq=quotemeta($bin);
0390                     print "scan bins $bin\n";
0391                     print "match ^$binq\$:\'${parent}_${name}\'\n";
0392                     $binq=quotemeta("${dir}/${name}");
0393                     print "match ^.+\\/$binq\\/.+\$:\'${parent}_${name}\'\n";
0394                     if (exists $cache->{PROJECT}{BUILDTREE}{$dir}{RAWDATA}{content}{BUILDPRODUCTS}{$type}{$bp}{FILES})
0395                     {
0396                       foreach my $binfile (@{$cache->{PROJECT}{BUILDTREE}{$dir}{RAWDATA}{content}{BUILDPRODUCTS}{$type}{$bp}{FILES}})
0397                       {
0398                         $xdirs{dirname("${dir}/${binfile}")}=1;
0399                         if($binfile=~/^(.+?\.)[^\.]+$/){$binfile=$1;}
0400                         $binfile=quotemeta("${dir}/${binfile}");
0401                         print "match ^.+\\/${binfile}.+\$:\'${parent}_${name}\'\n";
0402                       }
0403                     }
0404                     $bins{$name}=1;
0405                     my $bsrcdir=basename($srcdir);
0406                     if (($name=~/^test.+/) || ($bsrcdir eq "test") || ($bsrcdir eq "stub"))
0407                     {$exclude_bins="${exclude_bins} ${parent}_${name}";}
0408                     last;
0409                   }
0410                 }
0411                 if(!$found)
0412                 {print STDERR "Can not find \"$name\" executable in any of the binary directories.\n";}
0413               }
0414             }
0415             elsif ($type eq "LIBRARY")
0416             {
0417               foreach my $bp (keys %{$cache->{PROJECT}{BUILDTREE}{$dir}{RAWDATA}{content}{BUILDPRODUCTS}{$type}})
0418               {
0419                 $name=$cache->{PROJECT}{BUILDTREE}{$dir}{RAWDATA}{content}{BUILDPRODUCTS}{$type}{$bp}{NAME};
0420                 foreach my $libexp ('"lib".$name.".$LibExt"','"plugin".$name.".$LibExt"','$name.".iglet"')
0421                 {
0422                   my $libname=eval "$libexp";
0423                   foreach my $d (@{$libdirs})
0424                   {
0425                     my $libpath="${d}/${libname}";
0426                     if (-f "$libpath")
0427                     {
0428                       $libpath=&getActualPath ($libpath);
0429                       &addProductMap($tool,$class,$type,$dir,$name,$libpath);
0430                       my $libpathq=quotemeta($libpath);
0431                       print "scan libs $libpath\n";
0432                       if($system){print "match ^".$libpathq."\$:\'${system}/${parent}_${name}\'\n";}
0433                       else{print "match ^".$libpathq."\$:\'${parent}_${name}\'\n";}
0434                       if (exists $cache->{PROJECT}{BUILDTREE}{$dir}{RAWDATA}{content}{BUILDPRODUCTS}{$type}{$bp}{FILES})
0435                       {
0436                         foreach my $libfile (@{$cache->{PROJECT}{BUILDTREE}{$dir}{RAWDATA}{content}{BUILDPRODUCTS}{$type}{$bp}{FILES}})
0437                         {
0438                           $xdirs{dirname("${dir}/${libfile}")}=1;
0439                           if($libfile=~/^(.+?\.)[^\.]+$/){$libfile=$1;}
0440                           $libfile=quotemeta("${dir}/${libfile}");
0441                           print "match ^.+\\/${libfile}.+\$:\'${parent}_${name}\'\n";
0442                         }
0443                       }
0444                       $libs{$libname}=1;
0445                       last;
0446                     }
0447                   }
0448                 }
0449               }
0450             }
0451           }
0452         }
0453       }
0454       elsif (($tool eq "self") && ($class=~/^(BINARY|PLUGINS)$/i))
0455       {
0456         if (&isExist ("RAWDATA:content:BUILDPRODUCTS",$cache->{PROJECT}{BUILDTREE}{$dir}))
0457         {
0458           foreach my $type (keys %{$cache->{PROJECT}{BUILDTREE}{$dir}{RAWDATA}{content}{BUILDPRODUCTS}})
0459           {
0460             my $srcdir="${base}/${src_name}/${dir}";
0461             $type=uc($type);
0462             if ($type eq "BIN")
0463             {
0464               foreach my $bp (keys %{$cache->{PROJECT}{BUILDTREE}{$dir}{RAWDATA}{content}{BUILDPRODUCTS}{$type}})
0465               {
0466                 $name=$cache->{PROJECT}{BUILDTREE}{$dir}{RAWDATA}{content}{BUILDPRODUCTS}{$type}{$bp}{NAME};
0467                 $found=0;
0468                 foreach my $d (@{$bindirs})
0469                 {
0470                   my $bin="${d}/$name";
0471                   if (-f $bin && -x $bin)
0472                   {
0473                     $found=1;
0474                     $bin=&getActualPath ($bin);
0475                     &addProductMap($tool,$class,$type,$dir,$name,$bin);
0476                     my $binq=quotemeta($bin);
0477                     print "scan bins $bin\n";
0478                     print "match ^$binq\$:\'${parent}_${name}\'\n";
0479                     $binq=quotemeta("${dir}/${name}");
0480                     print "match ^.+\\/$binq\\/.+\$:\'${parent}_${name}\'\n";
0481                     if (exists $cache->{PROJECT}{BUILDTREE}{$dir}{RAWDATA}{content}{BUILDPRODUCTS}{$type}{$bp}{FILES})
0482                     {
0483                       foreach my $binfile (@{$cache->{PROJECT}{BUILDTREE}{$dir}{RAWDATA}{content}{BUILDPRODUCTS}{$type}{$bp}{FILES}})
0484                       {
0485                         $xdirs{dirname("${dir}/${binfile}")}=1;
0486                         if($binfile=~/^(.+?\.)[^\.]+$/){$binfile=$1;}
0487                         $binfile=quotemeta("${dir}/${binfile}");
0488                         print "match ^.+\\/${binfile}.+\$:\'${parent}_${name}\'\n";
0489                       }
0490                     }
0491                     $bins{$name}=1;
0492                     my $bsrcdir=basename($srcdir);
0493                     if (($name=~/^test.+/) || ($bsrcdir eq "test") || ($bsrcdir eq "stub"))
0494                     {$exclude_bins="${exclude_bins} ${parent}_${name}";}
0495                     last;
0496                   }
0497                 }
0498                 if(!$found)
0499                 {print STDERR "Can not find \"$name\" executable in any of the binary directories.\n";}
0500               }
0501             }
0502             elsif ($type eq "LIBRARY")
0503             {
0504               foreach my $bp (keys %{$cache->{PROJECT}{BUILDTREE}{$dir}{RAWDATA}{content}{BUILDPRODUCTS}{$type}})
0505               {
0506                 $name=$cache->{PROJECT}{BUILDTREE}{$dir}{RAWDATA}{content}{BUILDPRODUCTS}{$type}{$bp}{NAME};
0507                 foreach my $libexp ('"lib".$name.".$LibExt"','"plugin".$name.".$LibExt"','$name.".iglet"')
0508                 {
0509                   my $libname=eval "$libexp";
0510                   foreach my $d (@{$libdirs})
0511                   {
0512                     my $libpath="${d}/${libname}";
0513                     if (-f "$libpath")
0514                     {
0515                       $libpath=&getActualPath ($libpath);
0516                       &addProductMap($tool,$class,$type,$dir,$name,$libpath);
0517                       my $libpathq=quotemeta($libpath);
0518                       print "scan libs $libpath\n";
0519                       if($system){print "match ^".$libpathq."\$:\'${system}/${parent}_${name}\'\n";}
0520                       else{print "match ^".$libpathq."\$:\'${parent}_${name}\'\n";}
0521                       if (exists $cache->{PROJECT}{BUILDTREE}{$dir}{RAWDATA}{content}{BUILDPRODUCTS}{$type}{$bp}{FILES})
0522                       {
0523                         foreach my $libfile (@{$cache->{PROJECT}{BUILDTREE}{$dir}{RAWDATA}{content}{BUILDPRODUCTS}{$type}{$bp}{FILES}})
0524                         {
0525                           $xdirs{dirname("${dir}/${libfile}")}=1;
0526                           if($libfile=~/^(.+?\.)[^\.]+$/){$libfile=$1;}
0527                           $libfile=quotemeta("${dir}/${libfile}");
0528                           print "match ^.+\\/${libfile}.+\$:\'${parent}_${name}\'\n";
0529                         }
0530                       }
0531                       $libs{$libname}=1;
0532                       last;
0533                     }
0534                   }
0535                 }
0536               }
0537             }
0538           }
0539         }
0540       }
0541     }
0542   }
0543   my $xtool=$tool;
0544   if($xtool eq "self"){$xtool=lc($project_name);}
0545   if(&isExist ("EXTRA_TOOL_INFO:$xtool:FILES_PACKAGE_MAP",$extra_tool_info))
0546   {
0547     my $baserx=quotemeta($base);
0548     foreach my $reg (keys %{$extra_tool_info->{EXTRA_TOOL_INFO}{$xtool}{FILES_PACKAGE_MAP}})
0549     {
0550       my $t=$extra_tool_info->{EXTRA_TOOL_INFO}{$xtool}{FILES_PACKAGE_MAP}{$reg};
0551       if($system eq ""){print "match ^$baserx\\/.+?\/$reg:'${t}'\n";}
0552       else{print "match ^$baserx\\/.+?\\/$reg:'${system}/${t}'\n";}
0553     }
0554   }
0555   foreach my $x ([$bindirs , \%bins], [$libdirs , \%libs])
0556   {
0557     foreach my $d (@{$x->[0]})
0558     {
0559       if (!-d $d){next;}
0560       if($d=~/^$localtop\/external\/$SCRAM_ARCH/){next;}
0561       $d=&getActualPath ($d);
0562       opendir(DIR, "$d") || next;
0563       my $rejected="";
0564       foreach my $f (readdir(DIR))
0565       {
0566         if ((-d $f) || ($f=~/^\./)){next;}
0567         if ((!exists $x->[1]{$f}) && ($f!~/\.reg$/))
0568         {
0569           $f=quotemeta($f);
0570           if ($rejected){$rejected="$rejected|$f";}
0571           else{$rejected=$f;}
0572         }
0573       }
0574       closedir(DIR);
0575       if ($rejected)
0576       {
0577         $rejected=quotemeta($d)."\\/($rejected)";
0578         print "option define reject-binary \$filepath =~ m/^$rejected\$/\n";
0579       }
0580     }
0581   }
0582   
0583   my $src="${base}/${src_name}";
0584   my $srcq=quotemeta($src);
0585   print "search include .*:(.*):\"$src/\$1\"\n";
0586   if($system){
0587     foreach my $xd (keys %xdirs)
0588     {
0589       my $xdq=quotemeta($xd);
0590       print "match ^.+\\/$xdq(\\/.+|)\$:\"$system/$xd\"\n";
0591     }
0592     print "match ^$srcq\\/([^/]+)\\/([^/]+)\\/:\"$system/\$1/\$2\"\n";
0593   }
0594   else{
0595     foreach my $xd (sort {$b cmp $a} keys %xdirs)
0596     {
0597       my $xdq=quotemeta($xd);
0598       print "match ^.+\\/$xdq(\\/.+|)\$:\"$xd\"\n";
0599     }
0600     print "match ^$srcq\\/([^/]+)\\/([^/]+)\\/:\"\$1/\$2\"\n";
0601   }
0602 }
0603 
0604 sub addLCGProjectInfo ()
0605 {
0606   my $tool=shift || return;
0607   my $cache=shift  || return;
0608   my $cache1=$LOCALCACHE->{SCRAM_PROJECTS}{$self};
0609   my $arch=$SCRAM_ARCH;
0610   if(exists $LCG_ARCH_MAP{$arch}){$arch=$LCG_ARCH_MAP{$arch};}
0611   
0612   my $libdirs=[];
0613   if(&isExist("RUNTIME#PATH:LD_LIBRARY_PATH", $cache1->{TOOL}{SETUP}{$tool}, "#")){$libdirs=$cache1->{TOOL}{SETUP}{$tool}{RUNTIME}{"PATH:LD_LIBRARY_PATH"};}
0614   elsif(&isExist("LIBDIR", $cache1->{TOOL}{SETUP}{$tool})){$libdirs=$cache1->{TOOL}{SETUP}{$tool}{LIBDIR};}
0615   
0616   my $base=&toolBase($tool, $cache1);
0617   my $system=uc($tool);
0618   my $testd="${base}/${arch}/tests/lib";
0619   my $found=0;
0620   
0621   foreach my $d (@{$libdirs})
0622   {if($d=~/^$testd$/){$found=1; last;}}
0623   if(!$found){push @{$libdirs}, $testd;}
0624   
0625   my %libs=();
0626   if(&isExist ("PROJECT:BUILDTREE", $cache))
0627   {
0628     foreach my $dir (keys %{$cache->{PROJECT}{BUILDTREE}})
0629     {
0630       my $name=&getTag ("NAME", $cache->{PROJECT}{BUILDTREE}{$dir}, "");
0631       my $class=&getTag ("CLASS", $cache->{PROJECT}{BUILDTREE}{$dir}, "");
0632       my $parent=&getTag ("PARENT", $cache->{PROJECT}{BUILDTREE}{$dir}, "");
0633       if(&isExist ("RAWDATA:content:EXPORT:LIB", $cache->{PROJECT}{BUILDTREE}{$dir}) && ($name ne ""))
0634       {
0635         my $lib="";
0636         if ($scram_ver=~/^V1_0_/)
0637         {
0638           my $sname=&run_func("safename",$tool, $dir);
0639           if($sname){$lib=$sname;}
0640           else
0641           {
0642             foreach my $l (@{$cache->{PROJECT}{BUILDTREE}{$dir}{RAWDATA}{content}{EXPORT}{LIB}})
0643             {if(($l=~/^lcg_$name$/) || ($l=~/^$name$/)){$lib=$l; last;}}
0644           }
0645         }
0646         else{$lib=$name;}
0647         if ($lib ne "")
0648         {
0649           foreach my $d (@{$libdirs})
0650           {
0651             my $libpath="${d}/lib${lib}.${LibExt}";
0652             if (-f $libpath)
0653             {
0654               $libpath=&getActualPath ($libpath);
0655               my $libpathq=quotemeta($libpath);
0656               print "match ^".$libpathq."\$:\'${system}/${dir}\'\n";
0657               $libs{"lib${lib}.${LibExt}"}=1;
0658               last;
0659             }
0660           }
0661         }
0662       }
0663       elsif ($class=~/LIBRARY/i)
0664       {
0665         if ($scram_ver=~/^V1_0_/)
0666         {
0667           my $sname=&run_func("safename",$tool, $dir);
0668           if($sname){$name=$sname;}
0669         }
0670         foreach my $d (@{$libdirs})
0671         {
0672           my $libpath="${d}/lib${name}.${LibExt}";
0673           if (-f "$libpath")
0674           {
0675             $libpath=&getActualPath ($libpath);
0676             my $libpathq=quotemeta($libpath);
0677             print "match ^".$libpathq."\$:\'${system}/${parent}\'\n";
0678             $libs{"lib${name}.${LibExt}"}=1;
0679             last;
0680           }
0681         }
0682       }
0683     }
0684   }
0685   foreach my $x ([$libdirs , \%libs])
0686   {
0687     foreach my $d (@{$x->[0]})
0688     {
0689       if (!-d $d){next;}
0690       $d=&getActualPath ($d);
0691       opendir(DIR, "$d") || next;
0692       my $rejected="";
0693       foreach my $f (readdir(DIR))
0694       {
0695         if (-d $f){next;}
0696         if (!exists $x->[1]{$f})
0697         {
0698           $f=quotemeta($f);
0699           if ($rejected){$rejected="$rejected|$f";}
0700           else{$rejected=$f;}
0701         }
0702       }
0703       closedir(DIR);
0704       if ($rejected)
0705       {
0706         $rejected=quotemeta($d)."\\/($rejected)";
0707         print "option define reject-binary \$filepath =~ m/^$rejected\$/\n";
0708       }
0709     }
0710   }
0711 
0712   my $src="${base}/${src_name}";
0713   my $srcq=quotemeta($src);
0714   opendir(DIR, &getActualPath("$src")) || return;
0715   my @srcs=readdir(DIR); closedir(DIR);
0716   
0717   my $incdirs=[];
0718   if(&isExist("INCLUDE", $cache1->{TOOL}{SETUP}{$tool})){$incdirs=$cache1->{TOOL}{SETUP}{$tool}{INCLUDE};}
0719   if(scalar(@{$incdirs})>0)
0720   {
0721     foreach my $inc (@{$incdirs})
0722     {
0723       if ((!-e $inc) || (!-d &getActualPath("$inc"))){next;}
0724       print "search include .*:(.*):\"${inc}/\$1\"\n";
0725     }
0726     foreach my $inc (@{$incdirs})
0727     {
0728       if ((!-e $inc) || (!-d &getActualPath("$inc"))){next;}
0729       my $incq=quotemeta("$inc");
0730       opendir(DIR, &getActualPath("$inc")) || return;
0731       my @include=readdir(DIR); closedir(DIR);
0732       foreach my $d (@include)
0733       {
0734         if (($d eq ".") || ($d eq "..")){next;}
0735         foreach my $s (@srcs)
0736         {
0737           if (($s eq ".") || ($s eq "..")){next;}
0738           if (-d "${src}/${s}/${d}")
0739           {
0740             my $q="${incq}\\/".quotemeta($d);
0741             print "match ^$q\\/:\"$system/$s/$d\"\n";
0742             last;
0743           }
0744         }
0745       }
0746     }
0747   }
0748   else
0749   {
0750     foreach my $s (@srcs)
0751     {
0752       if (($s eq ".") || ($s eq "..") || ($s eq "CVS") || ($s eq "Documentation")){next;}
0753       if (!-d "${src}/${s}"){next;}
0754       opendir(DIR, &getActualPath("${src}/${s}")) || return;
0755       my @subdir = readdir(DIR); closedir(DIR);
0756       foreach my $d (@subdir)
0757       {
0758         if (($d eq ".") || ($d eq "..") || ($d eq "CVS") || ($d eq "Documentation")){next;}
0759         if (-d "${src}/${s}/${d}")
0760         {
0761           my $q="${srcq}\\/".quotemeta("$s/$d");
0762           print "match ^$q\\/:\"$system/$s/$d\"\n";
0763         }
0764       }
0765     }
0766   }
0767 }
0768 
0769 sub addToolInfo ()
0770 {
0771   my $tool=shift || return;
0772   my $cache=shift || return;
0773   my $force=shift || 0;
0774   my $add_archive=shift || 0;
0775   if(exists $extra_tool_info->{TOOL_DONE}{$tool}){return;}
0776   $extra_tool_info->{TOOL_DONE}{$tool}=1;
0777   if(&isExist("TOOL_ORDER:$tool:pretools",$extra_tool_info))
0778   {foreach my $t (keys %{$extra_tool_info->{TOOL_ORDER}{$tool}{pretools}}){&addToolInfo ($t,$cache);}}
0779 
0780   my $system=&getSystem ($tool, $cache);
0781   $CACHE->{SUBSYSTEMS}{$tool}=$system;
0782   if (!$force)
0783   {
0784     my $func="process_$tool";
0785     if (exists &$func){return &$func($tool, $cache);}
0786   }
0787   print "#$system/".ucfirst($tool)."\n";
0788   my $tool1=ucfirst ($tool);
0789   my $libdirs=[""];
0790   my $incdirs=[];
0791   if(&isExist("TOOL:SETUP:$tool:LIBDIR", $cache)){$libdirs=$cache->{TOOL}{SETUP}{$tool}{LIBDIR};}
0792   if(&isExist("TOOL:SETUP:$tool:INCLUDE", $cache)){$incdirs=$cache->{TOOL}{SETUP}{$tool}{INCLUDE};}
0793   my %missing = ();
0794   foreach my $libdir (@{$libdirs})
0795   {
0796     if(&isExist("TOOL:SETUP:$tool:LIB", $cache))
0797     {
0798       foreach my $lib (@{$cache->{TOOL}{SETUP}{$tool}{LIB}})
0799       {
0800         if(!exists $CACHE->{LIBMAP}{$lib})
0801         {$CACHE->{LIBMAP}{$lib}="${system}/${tool1}";}
0802         elsif($CACHE->{LIBMAP}{$lib} ne "${system}/${tool1}")
0803         {print "#WARNING: $lib exported from ${system}/${tool1} has already been exported by ".$CACHE->{LIBMAP}{$lib}."\n";}
0804         my $libq=quotemeta($lib);
0805         print "match \\/lib".$libq."[\\.\\-\\_].*(so|dylib|a).*\$:\'${system}/${tool1}\'\n";
0806         if ($libdir ne "")
0807         {
0808           my $libpath="${libdir}/lib${lib}.so";
0809           if (!-e $libpath){$libpath="${libdir}/lib${lib}.dylib";}
0810           if(!-e $libpath)
0811           {
0812             $libpath="${libdir}/lib${lib}.a";
0813             if (!-e $libpath)
0814             {$missing{$lib}=1;next;}
0815             if(!$add_archive){next;}
0816             print "scan libs $libpath\n";
0817           }
0818           if (exists $missing{$lib}){delete $missing{$lib};}
0819           $libpath=&getActualPath ($libpath);
0820           my $libdir1=dirname ($libpath);
0821           my $libpathq=quotemeta("${libdir1}/lib${lib}");
0822           print "match ^$libpathq\[\\.\\-\\_\].*(so|dylib|a).*\$:\'${system}/${tool1}\'\n";
0823         }
0824       }
0825     }
0826     if($libdir ne "")
0827     {
0828       $libdir=&getActualPath ($libdir);
0829       if(exists $uniqToolLibdir{$libdir}){$uniqToolLibdir{$libdir}{count}++;}
0830       else{$uniqToolLibdir{$libdir}{count}=1;$uniqToolLibdir{$libdir}{from}="${system}/${tool1}";}
0831     }
0832   }
0833   foreach my $miss (keys %missing)
0834   {
0835     print "#WARNING: Can not find library \"$miss\" in following directory/directories\n";
0836     foreach my $libdir (@{$libdirs})
0837     {
0838       if($libdir eq ""){next;}
0839       else{print "  #$libdir\n";}
0840     }
0841   }
0842   if(exists $extra_tool_info->{EXTRA_TOOL_INFO}{$tool})
0843   {
0844     foreach my $incdir (@{$incdirs})
0845     {
0846       my $incdirrx=quotemeta($incdir);
0847       foreach my $reg (keys %{$extra_tool_info->{EXTRA_TOOL_INFO}{$tool}{FILES_PACKAGE_MAP}})
0848       {
0849         my $t=$extra_tool_info->{EXTRA_TOOL_INFO}{$tool}{FILES_PACKAGE_MAP}{$reg};
0850         print "match ^$incdirrx\\/$reg:'${system}/${t}'\n";
0851       }
0852     }
0853   }
0854   foreach my $incdir (@{$incdirs})
0855   {
0856     my $incdirrx=quotemeta($incdir);
0857     print "search include .*:(.*):\"$incdir/\$1\"\n";
0858     print "match ^$incdirrx\\/:'${system}/${tool1}'\n";
0859   }
0860 }
0861 
0862 sub isCMSProject ()
0863 {
0864   my $name=shift || return 0;
0865   $name=uc($name);
0866   if ($name=~/^(IGUANA|IGUANACMS|IGNOMINY|GEOMETRY|ORCA|COBRA|OSCAR|PHYSH|CMSSW)$/){return 1;}
0867   return 0;
0868 }
0869 
0870 sub isLCGProject ()
0871 {
0872   my $name=shift || return 0;
0873   $name=uc($name);
0874   if ($name=~/^(SEAL|PI|POOL|CORAL)$/){return 1;}
0875   return 0;
0876 }
0877 
0878 sub toolBase ()
0879 {
0880   my $tool=shift || return;
0881   my $cache=shift || return;
0882   my $btag=uc($tool)."_BASE"; $btag=~tr/-/_/;
0883   return &toolTag($tool, $cache, $btag, shift);
0884 }
0885 
0886 sub toolTag ()
0887 {
0888   my $tool=shift || return;
0889   my $cache=shift || return;
0890   my $tag=shift || return;
0891   my $sep=shift || ":";
0892   return &getTag ("TOOL${sep}SETUP${sep}$tool${sep}$tag",$cache, undef, $sep);
0893 }
0894 
0895 sub getTag ()
0896 {
0897   my $tag=shift || return;
0898   my $cache=shift || return;
0899   my $default=shift;
0900   my $sep=shift || ":";
0901   if (&isExist ("$tag", $cache, $sep))
0902   {
0903     my $ref=$cache;
0904     foreach my $item (split /$sep/, $tag)
0905     {
0906       if(!exists $ref->{$item}){return $default;}
0907       $ref=$ref->{$item};
0908     }
0909     return $ref;
0910   }
0911   return $default;
0912 }
0913 
0914 sub getSystem ()
0915 {
0916   my $system="tools";
0917   my $tool=shift || return $system;
0918   my $cache=shift || return $system;
0919   if(&isExist ("TOOL:DOWNLOADED:url:$tool", $cache))
0920   {
0921     my $url=$cache->{TOOL}{DOWNLOADED}{url}{$tool};
0922     if($url=~/.*?module=SCRAMToolBox\/(.+?)\/.+?\&.*/){$system=$1;}
0923     elsif($url=~/.*?\/SCRAMToolBox\/(.+?)\/.+$/){$system=$1;}
0924   }
0925   return $system;
0926 }
0927 
0928 sub cachefilename ()
0929 {
0930   my $file=shift;
0931   if (($scram_ver=~/^V2_/) && ($file!~/\.gz$/)) {$file="${file}.gz";}
0932   return $file;
0933 }
0934 
0935 sub readcache()
0936 {
0937   require Cache::CacheUtilities;
0938   my $file=&cachefilename(shift || "${release}/.SCRAM/${SCRAM_ARCH}/ToolCache.db");
0939   return &Cache::CacheUtilities::read($file);
0940 }
0941 
0942 sub writecache()
0943 {
0944   my ($object,$file) = @_;
0945   if (($scram_ver=~/^V2/) && ($file!~/\.gz$/)){$file="${file}.gz";}
0946   &Cache::CacheUtilities::write($object,$file);
0947 }
0948 
0949 sub isExist ()
0950 {
0951   my $list=shift || return 0;
0952   my $ref=shift || return 0;
0953   my $sep=shift || ":";
0954   foreach my $item (split /$sep/, $list)
0955   {
0956     if(!exists $ref->{$item}){return 0;}
0957     $ref=$ref->{$item};
0958   }
0959   return 1;
0960 }
0961 
0962 sub exit_prog(){
0963   my $code=shift || 0;
0964   exit $code;
0965 }
0966 
0967 #return the scram base project base directory
0968 sub scram_release_top(){
0969   return &check_while_subdir_found(shift,".SCRAM");
0970 }
0971 
0972 sub check_while_subdir_found(){
0973   my $dir=shift;
0974   my $subdir=shift;
0975   while((!-d "${dir}/${subdir}") && ($dir ne "/")){$dir=dirname($dir);}
0976   if(-d "${dir}/${subdir}"){return $dir;}
0977   return "";
0978 }
0979 
0980 #this sub-routine will return a scram variable by running the
0981 #`scram build echo_<variable>` command
0982 sub _get_scram_variable(){
0983   my $var=shift;
0984   my $options=shift || "";
0985   my $value=`cd ${localtop}/${src_name}; $SCRAM_CMD build $options echo_${var} 2>&1 | grep $var`; 
0986   chomp $value;
0987   $value=~s/.+?=\s*//;
0988   if($value =~ /^\s*(.+)\s*$/){$value=$1;}
0989   else{$value="";}
0990   return $value;
0991 }
0992 
0993 sub getScramPath ()
0994 {
0995   my $rel=shift;
0996   my $sbase=`cd $rel; sh -v scram --help 2>&1 | grep SCRAMV1_ROOT=`; chomp $sbase;
0997   $sbase=~s/SCRAMV1_ROOT=["']//; $sbase=~s/['"].*//;
0998   if (!-d "${sbase}/src"){die "ERROR: Could not find SCRAM base path.\n";}
0999   return $sbase;
1000 }
1001 
1002 sub read_Environment (){
1003   foreach my $rf ("Environment","${SCRAM_ARCH}/Environment")
1004   {
1005     my $env_file="${localtop}/.SCRAM/${rf}";
1006     if (!-f $env_file){next;}
1007     foreach my $line (`cat $env_file`){
1008       chomp $line;
1009       if($line=~/^ *$/){next;}
1010       elsif($line=~/^ *#/){next;}
1011       elsif($line=~/^ *([^ ]+?) *= *(.+)$/){$CACHE->{ENVIRONMENT}{$1}=$2;}
1012     }
1013   }
1014 }
1015 
1016 sub get_scram_variable(){
1017   my $var=shift || return "";
1018   my $flag=shift;
1019   if(exists $CACHE->{ENVIRONMENT}{$var}){return $CACHE->{ENVIRONMENT}{$var};}
1020   elsif(defined $flag){return "";}
1021   else{return &_get_scram_variable($var);}
1022 }
1023 
1024 sub getActualPath ()
1025 {
1026   my $path=&_getFullPath (shift) || return "";
1027   if (-e $path)
1028   {
1029     my $pass=0;
1030     while(($pass==0) || (-l $path))
1031     {
1032       $pass++;
1033       if (-d $path){$path=&_getActualDir ($path)}
1034       else{$path=&_getActualFile ($path)};
1035     }
1036   }
1037   else{print "#ERROR: $path: Dose not exist\n";}
1038   return $path;
1039 }
1040 
1041 sub _getFullPath ()
1042 {
1043   my $f=shift || return "";
1044   if ($f!~/^\//){return "${CURDIR}/${f}";}
1045   return $f;
1046 }
1047 
1048 sub _getActualDir ()
1049 {
1050   my $dir=shift || return "";
1051   my $link=`cd $dir 2>&1; /bin/pwd`; chomp $link;
1052   return $link;
1053 }
1054 
1055 sub _getActualFile ()
1056 {
1057   my $file=shift || return "";
1058   my $link=readlink($file);
1059   if ($link eq ""){$link=$file;}
1060   elsif ($link!~/^\//)
1061   {$link=dirname($file)."/$link";}
1062   $link=&_getActualDir(dirname($link))."/".basename($link);
1063   return $link;
1064 }
1065 
1066 sub getOrderedTools (){
1067   if ($scram_ver=~/^V1_/){return &getOrderedToolsV1 (@_);}
1068   else { return &getOrderedToolsV2 (@_); }
1069 }
1070 
1071 sub getOrderedToolsV1 (){
1072   my $cache=shift;
1073   my $rev=shift || 0;
1074   my @t =();
1075   
1076   foreach my $tool (keys %{$cache->{SELECTED}})
1077   {
1078     my $index=$cache->{SELECTED}{$tool};
1079     if(&isExist ("SETUP:$tool",  $cache)){$t[$index]=$tool;}
1080     else{$t[$index]="";}
1081   }
1082   if ($rev){@t=reverse @t;}
1083   foreach my $x (@t)
1084   {if($x ne ""){push @tools, $x;}}
1085   return @tools;
1086 }
1087 
1088 sub getOrderedToolsV2 ()
1089 {
1090   require BuildSystem::ToolManager;
1091   my $cache=shift;
1092   my $rev=shift || 0;
1093   my $otools = $cache->toolsdata();
1094   my $tools  = $cache->setup();
1095   if (exists $tools->{'self'}){push @$otools,$tools->{'self'};}
1096   my @t =();
1097   my @compilertools=();
1098   foreach my $tool ( reverse @$otools )
1099   {
1100     if ($tool->scram_compiler()){push @compilertools,$tool; next;}
1101     push @t,$tool->toolname();
1102   }
1103   foreach my $tool ( @compilertools ){push @t,$tool->toolname();}
1104   if ($rev){@t=reverse @t;}
1105   return @t;
1106 }
1107 
1108 sub archive_lib_tool ()
1109 {
1110   my $tool=shift || return;
1111   my $cache=shift || return;
1112   &addToolInfo ($tool, $cache, 1, 1);
1113 }
1114 
1115 sub readsearchcache()
1116    {
1117    my ($file) = @_;
1118    my $cache = eval "retrieve(\"$file\")";
1119    die "Cache load error:$file: ",$EVAL_ERROR,"\n", if ($EVAL_ERROR);
1120    return $cache;
1121    }
1122 
1123 sub writesearchcache ()
1124 {
1125    my ($object,$file) = @_;
1126    eval {nstore($object,$file);};
1127    die "Cache write error:$file: ",$EVAL_ERROR,"\n", if ($EVAL_ERROR);
1128    return;
1129 }
1130 
1131 ###########################################################
1132 #sub process_qutexmlrpc ()
1133 #{&archive_lib_tool (shift, shift);}
1134 
1135 sub process_x11 ()
1136 {
1137   print "match ^/usr/X11:'System/X11'\n";
1138   &addToolInfo (shift, shift, 1, 1);
1139 }
1140 
1141 sub process_cxxcompiler ()
1142 {
1143   my $tool=shift || return;
1144   my $cache=shift || return;
1145   my $cxx=&toolTag($tool, $cache, "CXX");
1146   if (($cxx eq "") || (!-f $cxx) || (!-x $cxx)){return;}
1147   
1148   $cxx=~/^(\/.+)\/bin\/[^\/]+/;
1149   my $root=$1;
1150   my $dir=`$cxx -v 2>&1 | grep /specs | sed 's/.* //; s|/specs||'`; chomp $dir;
1151   my $v=`$cxx -dumpversion`; chomp $v;
1152   my $rootq=quotemeta($root);
1153   print "match ^$rootq\\/.+\$:'<Compiler>'\n";
1154   foreach my $item ("stdc++","g2c","gcc_s","supc++")
1155   {
1156     my $item1=$item;
1157     $item1=~s/\++//;
1158     print "match ^/usr/(local/|)lib/lib${item1}:'<Compiler>'\n";
1159     foreach my $d ("$root/lib", $dir)
1160     {
1161       my %cache;
1162       foreach my $lib (`ls $d/lib$item* 2>&1`)
1163       {
1164         if($?==0)
1165         {
1166           chomp $lib;
1167           $lib=&getActualPath ($lib);
1168           if (exists $cache{$lib}){next;}
1169           $cache{$lib}=1;
1170           if ($lib=~/(.+)\.a$/)
1171           {
1172             my $so="${1}.so";
1173             if(-f $so){next;}
1174             $so="${1}.dylib";
1175             if (-f $so){next;}
1176           }
1177           print "scan libs $lib\n";
1178         }
1179       }
1180     }
1181   }
1182   # Add include searchers for compiler headers.
1183   print "search include .*:(.*):\"$dir/include/\$1\"\n";  # 2.x
1184   print "search include .*:(.*):\"$root/include/c++/$v/\$1\"\n"; # 3.x
1185   print "search include .*:(.*):\"$root/include/c++/$v/backward/\$1\"\n"; # 3.x
1186   print "search include .*:(.*):\"$root/include/c++/$v/ext/\$1\"\n"; # 3.x
1187   print "search include .*:(.*):\"$root/include/g++/\$1\"\n"; # 2.x
1188 
1189   if ($v=~/^2\..*/)
1190   {
1191     print 'symbol ignore . ^__builtin',"\n";
1192     print 'symbol ignore . ^__pure_virtual',"\n";
1193     print 'symbol ignore . ^__u(div|mod)di',"\n";
1194 
1195     print 'symbol ignore . ^__eh_',"\n";
1196     print 'symbol ignore . ^__gmon_',"\n";
1197     print 'symbol ignore . ^__libc_',"\n";
1198     print 'symbol ignore . ^_IO_',"\n";
1199 
1200     print 'symbol ignore . ^__ti',"\n";         # type info
1201     print 'symbol ignore . ^__tft?\d',"\n";      # ?
1202     print 'symbol ignore . ^__vt_',"\n";         # virtual function table
1203     
1204     print 'symbol ignore . ^_\._9bad_alloc$',"\n";
1205   }
1206   elsif($v=~/^3\..*/)
1207   {
1208     print 'symbol ignore . ^__pure_virtual',"\n"; # FIXME: Temporary to disambiguate 2.95 CLHEP/GEANT4
1209     print 'symbol ignore . ^__dso_handle$',"\n";
1210 
1211     print 'symbol ignore . ^_ZTI',"\n";          # type info
1212     print 'symbol ignore . ^_ZTV',"\n";          # virtual function table
1213     print 'symbol ignore . ^_ZTT',"\n";          # ?
1214     print 'symbol ignore . ^_ZGV',"\n";          # gaurd variables
1215 
1216     print 'symbol ignore . ^_ZNSs4_Rep11_S_terminalE$',"\n";
1217     print 'symbol ignore . ^_ZNSs4_Rep11_S_max_sizeE$',"\n";
1218     print 'symbol ignore . ^_ZNSt24__default_alloc_templateILb1ELi0EE22_S_node_allocator_lockE$',"\n";
1219   }
1220 }
1221 
1222 sub scram_defaults ()
1223 {
1224   # determine whether it's a leaf or a subsystem, and automatically
1225   # generated matchers for every package.
1226   print '# SCRAM defaults',"\n";
1227   print 'option define package            $dir=~/^$root\/src\/[^\/]+$/',"\n";
1228   print 'option define package-type       grep(m|^\Q$path/|, keys %packages) ? "subsystem" : "leaf"',"\n";
1229   print 'option define package-match-rule "^(\Q$root/\E)?((\\.)?\\/)?\Q@{[&concat_path($src_root, $fullname)]}/\E"',"\n";
1230   print 'option define package-match-rule "^\Q@{[&concat_path($incdir, $src_root, $fullname)]}/\E"',"\n";
1231   print 'option define package-match-rule "^\Q@{[&concat_path($root, $build_root, $fullname)]}/\E"',"\n";
1232   print 'option define package-match-rule "^\Q@{[&concat_path($bindir, $name)]}\E\$"',"\n";
1233   print 'option define package-match-rule "^\Q$bindir/\E(example|test)_\Q$name\E(_[^/]+)?\$"',"\n";
1234   print 'option define package-match-rule "^\Q@{[&concat_path($libdir, \'lib\'.$name)]}\E(_[a-z_]+)?\.(so|dylib|a)"',"\n";
1235   print 'option define package-build-dir  &concat_path($root, $build_root, $name, $relative)',"\n";
1236 
1237   # Add standard places to look for things.
1238   #  - generated include tree
1239   #  - interface/include directory in a package
1240   #  - release src tree
1241   #  - system locations
1242   print 'search include .*:(.*):"$incdir/src/$1"',"\n";
1243   print 'search include .*:(.*):"$root/src/$name/interface/$1"',"\n";
1244   print 'search include .*:(.*):"$root/src/$name/include/$1"',"\n";
1245   print 'search include .*:(.*):"$root/src/$1"',"\n";
1246   # print 'search include .*:(.*):"$root/$build_root/$1"',"\n";
1247   print 'search include .*:(.*):"/usr/include/$1"',"\n";
1248   print 'search include .*:(.*):"/usr/local/include/$1"',"\n";
1249   print 'search include .*:^(/.*):"$1"',"\n";
1250 
1251   print '# don\'t allow standard headers from object space to confuse search',"\n";
1252   print 'reject include ^(algorithm|bitset|deque|exception|[a-z]*stream[a-z]*|functional)$',"\n";
1253   print 'reject include ^(io[a-z]+|iterator|limits|list|map|memory|new|numeric|queue|set|stack)$',"\n";
1254   print 'reject include ^(stdexcept|string|typeinfo|utility|vector)$',"\n";
1255   print 'reject include ^c[a-z]+$',"\n";
1256 
1257   # Add matchers for stuff we generally stumble across even though we
1258   # didn't really find it in configuration.  Typically comes in
1259   # through hidden dependencies not recorded in the project but that
1260   # are there (e.g. CERNLIB has parts that use Motif, but we don't
1261   # use them, but yet ignominy finds those and wants to assign them
1262   # to something; or they could be in commented-out code sections).
1263   #print 'match /include/Xm/:"System/Motif"',"\n";
1264   #print 'match /lib/libXm\.:"System/Motif"',"\n";
1265   print 'match ^/usr/local/(lib|include)/([^/]+):"ASIS/$2"',"\n";
1266   print 'match ^/usr/(lib|include)/:"<OS>"',"\n";
1267   print 'match ^/lib/:"<OS>"',"\n";
1268 
1269   # Ignore basic things we don't want to see: the compiler and system.
1270   print 'output ignore package ^<Compiler>$',"\n";
1271   print 'output ignore package ^<OS>$',"\n";
1272   #print 'output ignore binary ^/usr/',"\n";
1273 }
1274 
1275 sub run_func ()
1276 {
1277   my $func=shift || return "";
1278   my $tool=shift || return "";
1279   if($tool eq "self"){$tool=$self;}
1280   $tool=lc($tool);
1281   $func.="_${tool}";
1282   if(exists &$func){return &$func(@_);}
1283   return "";
1284 }
1285 
1286 sub safename_pool ()
1287 {return &safename_lcglevel1(shift,"lcg_");}
1288 sub safename_seal ()
1289 {return &safename_lcglevel2(shift,"lcg_");}
1290 sub safename_coral ()
1291 {return &safename_lcglevel1(shift,"lcg_");}
1292 
1293 sub safename_lcglevel1 ()
1294 {
1295   my $dir=shift;
1296   my $pre=shift;
1297   my @d=split /\/+/, $dir;
1298   if(scalar(@d)==2){return $pre.$d[0];}
1299   else{return "";}
1300 }
1301 
1302 sub safename_lcglevel2 ()
1303 {
1304   my $dir=shift;
1305   my $pre=shift;
1306   my @d=split /\/+/, $dir;
1307   if(scalar(@d)==3){return $pre.$d[1];}
1308   else{return "";}
1309 }
1310 
1311 sub safename_ignominy ()
1312 {return &safename_cms1(shift);}
1313 sub safename_iguana ()
1314 {return &safename_cms1(shift);}
1315 sub safename_cmssw ()
1316 {return &safename_cms2(shift);}
1317 
1318 sub safename_cms1 ()
1319 {
1320   my $dir=shift;
1321   my @d=split /\/+/, $dir;
1322   if(scalar(@d)==3){return $d[1];}
1323   else{return "";}
1324 }
1325 sub safename_cms2 ()
1326 {
1327   my $dir=shift;
1328   my @d=split /\/+/, $dir;
1329   if(scalar(@d)==3){return "$d[0]$d[1]";}
1330   else{return "";}
1331 }