diff options
Diffstat (limited to 'ACE/bin/create_ace_build')
-rwxr-xr-x | ACE/bin/create_ace_build | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/ACE/bin/create_ace_build b/ACE/bin/create_ace_build new file mode 100755 index 00000000000..273342bbd50 --- /dev/null +++ b/ACE/bin/create_ace_build @@ -0,0 +1,307 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# +# Creates an ACE build tree in directory "build/<build name>" below the current +# directory, which must be an ACE "top level" directory (such as +# $ACE_ROOT). The build tree directory structure mirrors that of the ACE +# top level directory structure, except that instead of containing any plain +# files, it contains only symlinks to the files in the ACE top level structure. +# +# This program has a similar purpose to "clone", but in addition to +# only creating symlinks (clone creates hard links, by default), this +# script: +# 1) uses relative rather than absolute symlinks, +# 2) tries not to put junk files into the build tree, +# 3) only creates a new tree in a build/ directory below the current, +# top level ACE directory (it's a feature :-), but it does enforce +# consistency). +# +# This program can be re-run on a build tree at any time in order to +# update it. It will add symlinks for newly added files, and remove +# any that are no longer valid. +# +# If the <build name> starts with "build/", that part will be removed +# from it. +# +# The first three lines above let this script run without specifying the +# full path to perl, as long as it is in the user's PATH. +# Taken from perlrun man page. + +use File::Find (); +use File::Basename; +use FileHandle; + +print "You should consider using clone_build_tree.pl found with MPC\n"; + +$usage = "usage: $0 -? | [-a] [-d <directory mode>] [-v] <build name>\n"; +$directory_mode = 0777; #### Will be modified by umask, also. +$verbose = 0; + +$source='.'; +$absolute= 0; + +$perl_version = $] + 0; +if ($perl_version >= 5) { + #### Use an eval so that this script will compile with perl4. + eval <<'PERL5_CWD' + require Cwd; + sub cwd { + Cwd::getcwd (); + } +PERL5_CWD +} else { + sub cwd { + local ($pwd); + + chop ($pwd = `pwd`); + $pwd; + } +} + +my($starting_dir) = cwd (); +my(@nlinks) = (); +my($build_re) = undef; + +sub cab_link { + my($real) = shift; + my($fake) = shift; + my($uif) = ($^O eq 'MSWin32' ? 'link' : 'symlink'); + + print "$uif $real $fake\n" if $verbose; + + my($status) = 0; + if ($^O eq 'MSWin32') { + my($fixed) = $fake; + $fixed =~ s/$build_re//; + push(@nlinks, $fixed); + + chdir(dirname($fake)); + $status = link ($real, basename($fake)); + chdir($starting_dir); + } + else { + $status = symlink ($real, $fake); + } + if (!$status) { + warn "$0: $uif to $fake failed\n"; + } +} + +#### +#### Process command line args. +#### +while ($#ARGV >= 0 && $ARGV[0] =~ /^-/) { + if ($ARGV[0] eq '-v') { + $verbose = 1; + } elsif ($ARGV[0] eq '-d') { + if ($ARGV[1] =~ /^\d+$/) { + $directory_mode = eval ($ARGV[1]); shift; + } else { + warn "$0: must provide argument for -d option\n"; + die $usage; + } + } elsif ($ARGV[0] eq '-a') { + $source = &cwd (); + $absolute = 1; + } elsif ($ARGV[0] eq '-?') { + print "$usage"; + exit; + } else { + warn "$0: unknown option $ARGV[0]\n"; + die $usage; + } + shift; +} + +die $usage unless $#ARGV == 0; +$build = $ARGV[0]; +$build =~ s%^build[/\\]%%; #### remove leading "build/", if any +$build = "build/$build"; + +## Set up the build regular expression use under MSWin32 +if ($^O eq 'MSWin32') { + ## Get the original build name + $build_re = $build; + + ## Remove any trailing slashes + $build_re =~ s/[\\\/]+$//; + + ## Add a single trailing slash + $build_re .= '/'; + + ## Escape any special characters + $build_re =~ s/([\\\$\[\]\(\)\.])/\\$1/g; +} + +#### +#### Check that we're in an ACE "top level" directory. +#### +(-d 'ace' && -d 'include') || + die "$0: must be in an ACE top level (ACE_ROOT) directory!\n"; + +#### +#### Create build directories, if needed. +#### +-d 'build' || mkdir ('build', $directory_mode); +-d "$build" || mkdir ("$build", $directory_mode); + +#### +#### Get all ACE plain file and directory names. +#### +@files = (); + +sub wanted { + my ($dev,$ino,$mode,$nlink,$uid,$gid); + + /^CVS\z/s && + ($File::Find::prune = 1) + || + /^build\z/s && + ($File::Find::prune = 1) + || + /^\..*obj\z/s && + ($File::Find::prune = 1) + || + /^Templates\.DB\z/s && + ($File::Find::prune = 1) + || + /^Debug\z/s && + ($File::Find::prune = 1) + || + /^Release\z/s && + ($File::Find::prune = 1) + || + /^Static_Debug\z/s && + ($File::Find::prune = 1) + || + /^Static_Release\z/s && + ($File::Find::prune = 1) + || + ( + ($nlink || (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_))) && + ! -l $_ && + ! /^core\z/s && + ! /^.*\.state\z/s && + ! /^.*\.so\z/s && + ! /^.*\.[oa]\z/s && + ! /^.*\.dll\z/s && + ! /^.*\.lib\z/s && + ! /^.*\.obj\z/s && + ! /^.*~\z/s && + ! /^\.\z/s && + ! /^\.#.*\z/s && + ! /^.*\.log\z/s + ) && + push(@files, $File::Find::name); +} + +File::Find::find({wanted => \&wanted}, '.'); + +#### +#### Create directories and symlinks to files. +#### +foreach $file (@files) { + $file =~ s%^./%%g; #### excise leading ./ directory component + + if (-d $file) { + unless (-d "$build/$file") { + print "mkdir $build/$file, $directory_mode\n" if $verbose; + mkdir ("$build/$file", $directory_mode); + } + } else { + unless (-e "$build/$file") { + if (!$absolute) { + $up = '../..'; + while ($file =~ m%/%g) { + $up .= '/..'; + } + + cab_link("$up/$file", "$build/$file"); + } else { + $path = $source . '/' . $file; + cab_link("$path", "$build/$file"); + } + } + } +} + +#### +#### Find all the symlinks in the build directory, and remove ones +#### that are no longer actually linked to a file. +#### + +if ($^O eq 'MSWin32') { + my($lfh) = new FileHandle(); + my($txt) = "$build/create_ace_build.links"; + if (open($lfh, "$txt")) { + while(<$lfh>) { + my($line) = $_; + $line =~ s/\s+$//; + if (-e $line) { + push(@nlinks, $line); + } + else { + print "Removing $build/$line \n" if $verbose; + unlink("$build/$line") || warn "$0: unlink of $build/$line failed\n"; + } + } + close($lfh); + } + + ## Rewrite the link file. + unlink($txt); + if (open($lfh, ">$txt")) { + foreach my $file (@nlinks) { + print $lfh "$file\n"; + } + close($lfh); + } +} +else { + @lfiles = (); + + sub lcheck { + ## There's no way to know if we have hard linked back to a now + ## non-existent file. So, just do the normal -l on the file + ## which will cause no files to be pushed on Windows. + if (-l $_) { + push(@lfiles, $File::Find::name); + } + } + + File::Find::find({wanted => \&lcheck}, $build); + + foreach (@lfiles) { + local @s = stat $_; + if ($#s == -1) { + print "Removing $_ \n" if $verbose; + unlink $_ || warn "$0: unlink of $_ failed\n"; + } + } +} + +#### +#### Done: print message. +#### +print "\nCompleted creation of $build/.\n"; +my($msg) = ''; +if (! -e "$build/ace/config.h") { + $msg .= "$build/ace/config.h"; +} + +if ($^O ne 'MSWin32' && + ! -e "$build/include/makeinclude/platform_macros.GNU") { + if ($msg ne '') { + $msg .= " and\n"; + } + $msg .= "$build/include/makeinclude/platform_macros.GNU"; +} + +if ($msg ne '') { + print "Be sure to setup $msg.\n"; +} + +#### EOF |