diff options
-rw-r--r-- | README | 6 | ||||
-rw-r--r-- | bootstrap.py | 91 | ||||
-rw-r--r-- | config | 51 |
3 files changed, 136 insertions, 12 deletions
@@ -244,6 +244,12 @@ bin/ there's a copy of the script we use to translate an Aegis change into a CVS checkin. +bootstrap.py + A build script for use with Aegis. This collects a current copy + of SCons from the Aegis baseline directories in a bootstrap/ + subdirectory, and then executes SCons with the supplied + command-line arguments. + build/ This doesn't exist yet if you're looking at a vanilla source tree. This is generated as part of our build process, and it's diff --git a/bootstrap.py b/bootstrap.py new file mode 100644 index 0000000..78fe091 --- /dev/null +++ b/bootstrap.py @@ -0,0 +1,91 @@ +"""bootstrap.py + +This is an Aegis-to-SCons build script that collects a copy of the +current SCons into a bootstrap/ subdirectory and then executes it with +the supplied command-line options. + +Right now, it only understands the SCons -Y option, which is the only +one currently used. It collects the repositories specified by -Y and +searches them, in order, for the pieces of SCons to copy into the local +bootstrap/ subdirectory. + +This is essentially a minimal build of SCons to bootstrap ourselves into +executing it for the full build of all the packages, as specified in our +local SConstruct file. + +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +import os +import os.path +import getopt +import string +import sys + +search = ['.'] + +opts, args = getopt.getopt(sys.argv[1:], "Y:", []) + +for o, a in opts: + if o == '-Y': + search.append(a) + +def find(file, search=search): + for dir in search: + f = os.path.join(dir, file) + if os.path.exists(f): + return os.path.normpath(f) + sys.stderr.write("could not find `%s' in search path:\n" % file) + sys.stderr.write("\t" + string.join(search, "\n\t") + "\n") + sys.exit(2) + +scons_py = os.path.join('src', 'script', 'scons.py') +src_engine = os.path.join('src', 'engine') +MANIFEST_in = find(os.path.join(src_engine, 'MANIFEST.in')) + +files = [ scons_py ] + map(lambda x: os.path.join(src_engine, x[:-1]), + open(MANIFEST_in).readlines()) + +subdir = 'bootstrap' + +for file in files: + src = find(file) + dst = os.path.join(subdir, file) + dir, _ = os.path.split(dst) + if not os.path.isdir(dir): + os.makedirs(dir) + contents = open(src, 'rb').read() + try: os.unlink(dst) + except: pass + open(dst, 'wb').write(contents) + +args = [ sys.executable, os.path.join(subdir, scons_py) ] + sys.argv[1:] + +sys.stdout.write(string.join(args, " ") + '\n') +sys.stdout.flush() + +os.environ['SCONS_LIB_DIR'] = os.path.join(subdir, src_engine) + +os.execve(sys.executable, args, os.environ) @@ -10,33 +10,60 @@ * the relevant build command. This command tells SCons where to find * the rules. * - * The ${bl}/build/scons-src/src/engine points $SCONS_LIB_DIR points - * SCons at the last-built scons-src package, which should have - * everything. This means that, under Aegis, we're really using the - * currently-checked-in baseline to build the current version. This - * implies that using a new feature in our own SConscripts is a - * two-stage process: check in the underlying feature, then check in a - * change to use it in our SConscripts. + * Our chicken-and-egg dilemma is this: we want to use the version of + * SCons under development in an Aegis change to build itself. But the + * pieces of SCons are likely only partly in this change, and partly in + * baselines. * - * The ${s src/script/scons.py} expands to a path into the baseline - * during development if the script file is not in the change. + * Python only imports things on a module-by-module basis--which is to + * say, once it finds __init__.py in a given directory, it assumes that + * all other files in that module are in the same directory. But that's + * not the way Aegis works, because if a file hasn't changed on the + * branch, it will only be in its parent's baseline directory. + * + * Aegis' mechanism for working around this sort of problem is to make + * symlinks to the proper baseline versions of each file, which makes + * it look like everything is in the local tree. That's unattractive, + * though, because we really want to eat our own dog food and use the + * SCons -Y options to pull things from the baseline repositories. + * + * So our solution (suggested by Anthony Roach) is a bootstrap.py script + * that does some Aegis-like searching through the baseline directories + * and makes a bootstrap copy of the version of SCons under development + * that we can use for building. After it makes this copy of SCons, it + * executes it with the same command-line arguments we supplied (and + * setting $SCONS_LIB_DIR to the right directory) so we can use it + * here with command-line options as if it were SCons itself. (Note, + * however, that bootstrap.py only understands the specific command-line + * options already in use here, so if you change the call below to add + * some other SCons options, you may have to modify bootstrap.py to + * recognize them. + * + * The ${Source bootstrap.py} substitution finds bootstrap.py wherever + * it may be in the Aegis baselines. + * + * The long -Y${SUBSTitute...} substitution takes the Aegis baseline + * search path and turns it into the right -Y command-line options for + * SCons. + * + * The rest of the substitutions (${DEVeloper}, etc.) should be obvious. * * Look in aesub(5) for more information about command substitutions. */ -build_command = "SCONS_LIB_DIR=src/engine python ${Source src/script/scons.py} -Y${SUBSTitute : \\ -Y $Search_Path} date='${DAte %Y/%m/%d %H:%M:%S}' developer=${DEVeloper} version=${VERsion} change=${Change}"; +build_command = "python ${Source bootstrap.py} -Y${SUBSTitute : \\ -Y $Search_Path} date='${DAte %Y/%m/%d %H:%M:%S}' developer=${DEVeloper} version=${VERsion} change=${Change}"; /* * SCons removes its targets before constructing them, which qualifies it * for the following entry in the config file. The files must be removed * first, otherwise the baseline would cease to be self-consistent. - */ link_integration_directory = true; + */ /* * This is set temporarily to allow us to build using the SCons * currently checked in to the src directory. - */ create_symlinks_before_build = true; + */ /* * aegis - project change supervisor |