File indexing completed on 2024-04-06 12:31:47
0001
0002 use File::Basename;
0003 use lib dirname($0);
0004 use SCRAMGenUtils;
0005 $|=1;
0006
0007 my $curdir=`/bin/pwd`; chomp $curdir;
0008 my $scriptdir=dirname($0);
0009 my $dir="";
0010 while(my $arg=shift)
0011 {
0012 if($arg eq "--help"){&usage();exit 0;}
0013 else{$dir=$arg;last;}
0014 }
0015 if($dir eq ""){$dir=$curdir;}
0016 if(!-d $dir){die "No such directory: $dir\n";}
0017
0018 if($dir=~/^[^\/]/){$dir="${curdir}/${dir}";}
0019 $dir=&SCRAMGenUtils::fixPath($dir);
0020
0021 my $release=&SCRAMGenUtils::scramReleaseTop($dir);
0022 if($release eq ""){die "\"$dir\" is not SCRAM-base project area.\n";}
0023 my $releasetop=&SCRAMGenUtils::getFromEnvironmentFile("RELEASETOP",$release) || $release;
0024 if($releasetop eq $release){die "\"$release\" is a release area. Please run this script in your developer area.\n";}
0025 &SCRAMGenUtils::init($release);
0026 my $arch=&SCRAMGenUtils::getScramArch();
0027
0028 my $headerext="\\.(h|hh|hpp)\$";
0029 my $srcext="\\.(cc|cpp|c|cxx)\$";
0030 my $lexparseext="_(lex\\.l|parse\\.y)\$";
0031 my $config=&SCRAMGenUtils::getFromEnvironmentFile("SCRAM_CONFIGDIR","$release") || "config";
0032 my $src=&SCRAMGenUtils::getFromEnvironmentFile("SCRAM_SOURCEDIR","$release") || "src";
0033 my $project=&SCRAMGenUtils::getFromEnvironmentFile("SCRAM_PROJECTNAME","$release");
0034 if($release eq $dir){$dir.="/${src}";}
0035
0036 my $packdir=$dir;
0037 if($packdir=~/^${release}\/${src}(\/.+|)$/){$packdir=$1;$packdir=~s/^\/*//;}
0038 else{die "Wrong subsystem/package directory \"$dir\".\n";}
0039 my $actualdir=$packdir;
0040 if($packdir eq ""){$packdir=".+";}
0041 else{$packdir="^$packdir(\/.+|)\$";}
0042
0043 $SCRAM_CMD=$SCRAMGenUtils::SCRAM_CMD;
0044
0045 print 'OWNHEADER=^(.+)/[^/]+/([^\\.]+)\\.(cc|CC|cpp|C|c|CPP|cxx|CXX)$:"$1/.+?/$2\\\.(h|hh|hpp|H|HH|HPP)\\$"',"\n";
0046 print 'LOCAL_HEADERS=^([^/]+/[^/]+)/.+$:"$1/.+"',"\n";
0047 print "BASE_DIR=${release}/${src}\n";
0048 my $flags="";
0049 my $cache={};
0050
0051 my $doscramb=0;
0052 my $pcf=&SCRAMGenUtils::fixCacheFileName("${release}/.SCRAM/${arch}/ProjectCache.db");
0053 if((-f "${release}/tmp/${arch}/Makefile") && (-f $pcf))
0054 {
0055 $cache->{cache}=&SCRAMGenUtils::readCache($pcf);
0056 my %dirstocheck=();
0057 if($actualdir=~/\//){$dirstocheck{$actualdir}=1;}
0058 else
0059 {
0060 if($actualdir ne ""){$actualdir.="/";}
0061 foreach my $d (&SCRAMGenUtils::readDir("${release}/${src}/${actualdir}",1))
0062 {
0063 if($d eq "CVS"){next;}
0064 $d="${actualdir}${d}";
0065 if($d!~/\//)
0066 {
0067 foreach my $d1 (&SCRAMGenUtils::readDir("${release}/${src}/${d}",1))
0068 {
0069 if($d1 eq "CVS"){next;}
0070 $dirstocheck{"${d}/${d1}"}=1;
0071 }
0072 }
0073 else{$dirstocheck{$d}=1;}
0074 }
0075 }
0076 my $dircount=scalar(keys %dirstocheck);
0077 foreach my $d (keys %{$cache->{cache}{BUILDTREE}})
0078 {
0079 if(exists $dirstocheck{$d})
0080 {
0081 delete $dirstocheck{$d};
0082 $dircount--;
0083 if($dircount == 0){last;}
0084 }
0085 }
0086 if($dircount > 0){$doscramb=1;}
0087 }
0088 else{$doscramb=1;}
0089 if($doscramb)
0090 {
0091 print "Doing \"$SCRAM_CMD b\" due to new directories:";
0092 print join("\n ",keys %dirstocheck),"\n";
0093 system("cd $release; $SCRAM_CMD b -r echo_CXX ufast >/dev/null 2>&1");
0094 $cache->{cache}=&SCRAMGenUtils::readCache($pcf);
0095 }
0096
0097 my $tmprel=$release;
0098 $cache->{tools}=&SCRAMGenUtils::readCache(&SCRAMGenUtils::fixCacheFileName("${tmprel}/.SCRAM/${arch}/ToolCache.db"));
0099
0100 my $cxx="/usr/bin/c++";
0101 my $cxx_ver="";
0102 if(exists $cache->{tools}{SETUP}{cxxcompiler}{CXX}){$cxx=$cache->{tools}{SETUP}{cxxcompiler}{CXX};}
0103 else{$cxx=&SCRAMGenUtils::getBuildVariable($tmprel,"CXX","ufast") || $cxx;}
0104 if(-x $cxx){$cxx_ver=`$cxx --version | head -1 | awk '{print \$3}'`;chomp $cxx_ver;}
0105
0106 print "COMPILER=$cxx\n";
0107 print "COMPILER_VERSION=$cxx_ver\n";
0108 print 'SKIP_INCLUDES=.+:"\\\.(cxx|cc|c|cpp|CXX|CC|C|CPP|inc|INC|icpp|ICPP|ii|II|icc|ICC|ipp|IPP)\$"',"\n";
0109 print 'SKIP_INCLUDES=^(Ig|Vis).*?/interface/config\.h$:"^classlib/sysapi/system\\\.h\$"',"\n";
0110 print 'SKIP_INCLUDES=.+:"^FWCore/ParameterSet/test/ConfigTestMain\\\.h\$"',"\n";
0111 print 'SKIP_INCLUDE_INDIRECT_ADD=.+:"^(Ig|Vis).*?/interface/config\\\.h\$"',"\n";
0112 print 'SKIP_AND_ADD_REMOVED_INCLUDES=^.*?/classes\.h$',"\n";
0113 print 'SKIP_AND_ADD_REMOVED_INCLUDES=^.*?/([^/]*)LinkDef\.h$',"\n";
0114
0115 &genConfig ($packdir,$cache);
0116 $cache->{orderedtool}=&SCRAMGenUtils::getOrderedTools($cache->{tools});
0117 my $toolcount=scalar(@{$cache->{orderedtool}});
0118 $cache->{uniqinc}={};
0119 foreach my $tool (@{$cache->{orderedtool}})
0120 {
0121 if(exists $cache->{tools}{SETUP}{$tool}{INCLUDE})
0122 {
0123 foreach my $inc (@{$cache->{tools}{SETUP}{$tool}{INCLUDE}})
0124 {
0125 if(!exists $cache->{uniqinc}{$inc})
0126 {$flags.=" -I$inc";$cache->{uniqinc}{$inc}=1;}
0127 }
0128 }
0129 }
0130
0131 foreach my $inc (split /\s+/, &SCRAMGenUtils::getBuildVariable($tmprel,"CPPDEFINES","ufast"))
0132 {$flags="$flags ".postProcessFlag ("-D$inc");}
0133 $flags="$flags ".&postProcessFlag(&SCRAMGenUtils::getBuildVariable($tmprel,"CPPFLAGS","ufast"));
0134 $flags="$flags ".&postProcessFlag(&SCRAMGenUtils::getBuildVariable($tmprel,"CXXFLAGS","ufast"));
0135 print "DEFAULT_COMPILER_FLAGS=$flags\n";
0136
0137
0138
0139 print "SOURCE_EXT=$lexparseext\n";
0140
0141 foreach my $d ("$curdir","$scriptdir")
0142 {
0143 if(-f "${d}/${project}_IncludeChecker.conf")
0144 {
0145 print "#Extra Include Checker Configuration: ${d}/${project}_IncludeChecker.conf\n";
0146 system("cat ${d}/${project}_IncludeChecker.conf");
0147 last;
0148 }
0149 }
0150 &final_exit(0);
0151
0152 sub final_exit ()
0153 {
0154 my $code=shift || 0;
0155 if(($tmprel ne "") && ($tmprel ne $release)){system("rm -rf $tmprel");}
0156 exit $code;
0157 }
0158
0159 sub genSkip ()
0160 {
0161 my $data=shift;
0162 foreach my $prod (keys %{$data->{prods}})
0163 {
0164 foreach my $f (@{$data->{prods}{$prod}{files}})
0165 {
0166
0167 if($f!~/.+?$headerext/i){next;}
0168 if($f=~/.+?FWD$headerext/i){print "SKIP_FILES=^$f\$\n";next;}
0169 if(-f "${release}/${src}/${f}")
0170 {
0171 foreach my $line (`cat ${release}/${src}/${f}`)
0172 {
0173 chomp $line;
0174 if(($def_compile_support==0) && ($line=~/^\s*\
0175 {print "SKIP_FILES=^$f\$\n";last;}
0176 if(($tmpl_compile_support==0) && ($line=~/^\s*template\s*<.+/))
0177 {print "SKIP_FILES=^$f\$\n";last;}
0178 }
0179 }
0180 }
0181 }
0182 }
0183
0184 sub genConfig ()
0185 {
0186 my $dir=shift;
0187 my $data=shift;
0188 my $cache=$data->{cache};
0189 $data->{prods}={};
0190 foreach my $d (keys %{$cache->{BUILDTREE}})
0191 {
0192 if($d!~/$dir/){next;}
0193 if((exists $cache->{BUILDTREE}{$d}{CLASS}) && (exists $cache->{BUILDTREE}{$d}{RAWDATA}{content}))
0194 {
0195 my $suffix=$cache->{BUILDTREE}{$d}{SUFFIX};
0196 if($suffix ne ""){next;}
0197 my $class=$cache->{BUILDTREE}{$d}{CLASS};
0198 my $c=$cache->{BUILDTREE}{$d}{RAWDATA}{content};
0199 if($class eq "LIBRARY"){&addPack($data,$c,dirname($d));}
0200 elsif($class=~/^(TEST|BIN|PLUGINS|BINARY)$/){&addProds($data,$c,$d);}
0201 }
0202 }
0203 &getFlags($data->{prods});
0204 foreach my $prod (sort keys %{$data->{prods}})
0205 {
0206 print "COMPILER_FLAGS=".$data->{prods}{$prod}{flags}."\n";
0207 foreach my $file (@{$data->{prods}{$prod}{files}})
0208 {
0209 print "FILES=$file\n";
0210 if($file=~/$lexparseext/){print "SKIP_AND_ADD_REMOVED_INCLUDES=^$file\$\n";}
0211 }
0212 }
0213 }
0214
0215 sub addPack()
0216 {
0217 my $data=shift;
0218 my $cache=shift;
0219 my $d=&SCRAMGenUtils::fixPath(shift);
0220 my $prod=&run_func("safename",$project,"${release}/${src}/${d}");
0221 if($prod eq ""){die "ERROR: Script is not ready for $project SCRAM-based project.\n";}
0222 $data->{prods}{$prod}{files}=[];
0223 my $pkinterface=&run_func("pkg_interface",$project,$d);
0224 my $pksrc=&run_func("pkg_src",$project,$d);
0225 foreach my $d1 ($pkinterface,$pksrc)
0226 {
0227 my $dir="${release}/${src}/${d}/${d1}";
0228 if(-d "$dir")
0229 {
0230 foreach my $f (&SCRAMGenUtils::readDir($dir,2))
0231 {if(($f=~/$headerext/i) || ($f=~/$srcext/i) || ($f=~/$lexparseext/)){push @{$data->{prods}{$prod}{files}},"${d}/${d1}/${f}";}}
0232 }
0233 }
0234 if(scalar(@{$data->{prods}{$prod}{files}})==0){delete $data->{prods}{$prod};}
0235 }
0236
0237 sub addProds ()
0238 {
0239 my $data=shift;
0240 my $cache=shift;
0241 my $d=&SCRAMGenUtils::fixPath(shift);
0242 my $bf1="${release}/src/${d}/BuildFile.xml";
0243 if(!-f $bf1){$bf1="${release}/src/${d}/BuildFile";}
0244 my $bf=undef;
0245 foreach my $t (keys %{$cache->{BUILDPRODUCTS}})
0246 {
0247 foreach my $prod (keys %{$cache->{BUILDPRODUCTS}{$t}})
0248 {
0249 if($prod=~/^\s*$/){next;}
0250 my $name=basename($prod);
0251 $data->{prods}{$name}{files}=[];
0252 my $type=lc($t);
0253 if(!defined $bf){$bf=&SCRAMGenUtils::readBuildFile($bf1);}
0254 if((exists $bf->{$type}{$name}) && (exists $bf->{$type}{$name}{file}))
0255 {
0256 foreach my $f (@{$bf->{$type}{$name}{file}})
0257 {
0258 foreach my $fx (split /\,/,$f)
0259 {
0260 foreach my $f1 (split /\s+/,$fx)
0261 {
0262 foreach my $f2 (`ls ${release}/src/${d}/$f1 2> /dev/null`)
0263 {
0264 chomp $f2;
0265 $f2=~s/^${release}\/src\///;
0266 $f2=&SCRAMGenUtils::fixPath($f2);
0267 my $fd=dirname($f2);
0268 push @{$data->{prods}{$name}{files}},$f2;
0269 }
0270 }
0271 }
0272 }
0273 }
0274 if(scalar(@{$data->{prods}{$name}{files}})==0){delete $data->{prods}{$prod};}
0275 }
0276 }
0277 }
0278
0279 sub getFlags ()
0280 {
0281 my $cache=shift;
0282 my @prods=keys %{$cache};
0283 my $s=0;
0284 my $t=scalar(@prods);
0285 my $e=$t;
0286 my $m=200;
0287 while($e>0)
0288 {
0289 if($e>$m){$e=$m;}
0290 my $rules="";
0291 my $prod="";
0292 while($e>0)
0293 {
0294 $prod=$prods[$s++];$e--;
0295 foreach my $f ("CPPFLAGS", "CXXFLAGS"){$rules="$rules echo_${prod}_${f}";}
0296 }
0297 $e=$t-$s;
0298 if($rules eq ""){next;}
0299 foreach my $output (`cd $tmprel; $SCRAM_CMD b -f $rules 2>&1`)
0300 {
0301 chomp $output;
0302 if ($output=~/^\s*((.+?)_(CPPFLAGS|CXXFLAGS))\s+=\s+(.*)/)
0303 {
0304 $prod=$2;
0305 my $val=$4;
0306 if (exists $cache->{$prod})
0307 {
0308 my $oldval=$cache->{$prod}{flags};
0309 $cache->{$prod}{flags}="$oldval ".&postProcessFlag($val);
0310 }
0311 }
0312 }
0313 }
0314 }
0315
0316 sub postProcessFlag ()
0317 {
0318 my $l=shift;
0319 my $new="";
0320 while($l=~/^(.*?\s+\-D[^\s]+=)"(.*)$/)
0321 {
0322 $new="$new $1'\"";
0323 my $rest=$2;
0324 my $esc=0;
0325 my $done=0;
0326 foreach my $ch (split //, $rest)
0327 {
0328 if($done){$l="$l$ch";}
0329 elsif($ecs){$esc=0;$new="$new$ch";}
0330 elsif($ch eq '\\'){$esc=1;$new="$new$ch";}
0331 elsif($ch eq '"'){$done=1;$new="$new$ch'";$l="";}
0332 else{$new="$new$ch";}
0333 }
0334 }
0335 return "$new $l";
0336 }
0337
0338 #####################################
0339 # Run a tool specific func
0340 ####################################
0341 sub run_func ()
0342 {
0343 my $func=shift || return "";
0344 my $tool=shift || return "";
0345 if($tool eq "self"){$tool=$project;}
0346 $tool=lc($tool);
0347 my $funcx="${func}_${tool}";
0348 if(exists &$funcx){return &$funcx(@_);}
0349 $funcx="${func}_default";
0350 if(exists &$funcx){return &$funcx($tool,@_);}
0351 return "";
0352 }
0353 #############################################
0354 # generating library safe name for a package
0355 #############################################
0356 sub safename_pool ()
0357 {return "lcg_".basename(shift);}
0358 sub safename_seal ()
0359 {return "lcg_".basename(shift);}
0360 sub safename_coral ()
0361 {return "lcg_coral_".basename(shift);}
0362
0363 sub safename_ignominy ()
0364 {return &safename_cms1(shift);}
0365 sub safename_iguana ()
0366 {return &safename_cms1(shift);}
0367 sub safename_cmssw ()
0368 {return &safename_cms2(shift);}
0369
0370 sub safename_cms1 ()
0371 {
0372 my $dir=shift;
0373 if($dir=~/^${release}\/src\/([^\/]+?)\/([^\/]+)$/){return "${2}";}
0374 else{return "";}
0375 }
0376 sub safename_cms2 ()
0377 {
0378 my $dir=shift;
0379 if($dir=~/^${release}\/src\/([^\/]+?)\/([^\/]+)$/){return "${1}${2}";}
0380 else{return "";}
0381 }
0382 #############################################
0383 # getting interface file directory name
0384 #############################################
0385 sub pkg_interface_pool ()
0386 {return basename(shift);}
0387 sub pkg_interface_seal ()
0388 {return basename(shift);}
0389 sub pkg_interface_coral ()
0390 {return basename(shift);}
0391
0392 sub pkg_interface_ignominy ()
0393 {return "interface";}
0394 sub pkg_interface_iguana ()
0395 {return "interface";}
0396 sub pkg_interface_cmssw ()
0397 {return "interface";}
0398
0399 sub pkg_src_pool ()
0400 {return "src";}
0401 sub pkg_src_seal ()
0402 {return "src";}
0403 sub pkg_src_coral ()
0404 {return "src";}
0405
0406 sub pkg_src_ignominy ()
0407 {return "src";}
0408 sub pkg_src_iguana ()
0409 {return "src";}
0410 sub pkg_src_cmssw ()
0411 {return "src";}
0412
0413 ########################################################################
0414 sub pkg_depth_cmssw ()
0415 {return 2;}
0416 sub pkg_depth_ignominy ()
0417 {return 2;}
0418 sub pkg_depth_iguana ()
0419 {return 2;}
0420
0421 sub pkg_depth_default ()
0422 {
0423 my $tool=shift;
0424 if($tool=~/^(cmssw|iguana|ignominy)$/){return 2;}
0425 if($tool=~/^(seal|pool|coral)$/){return 1;}
0426 return 1;
0427 }
0428 ########################################################################
0429
0430 sub checkTemplateCompilationSupport ()
0431 {
0432 return 0;
0433 my $dir=&SCRAMGenUtils::getTmpDir();
0434 system("echo \"template <class T>class A{A(T t){std::cout <<std::endl;}};\" > ${dir}/test.cc");
0435 my $data=`cd ${dir}; $cxx -c -fsyntax-only test.cc 2>&1`;
0436 my $tmpl=$?;
0437 system("rm -rf $dir");
0438 if($tmpl != 0){$tmpl=1;}
0439 return $tmpl;
0440 }
0441
0442 sub checkDefineCompilationSupport ()
0443 {
0444 return 0;
0445 }
0446
0447 sub usage()
0448 {
0449 print "Usage\n";
0450 print " $0 [--help] <directory>\n\n";
0451 print " --help To get this help message.\n";
0452 }