changeset 3430:06dd31baf953

Merge branch 'gub' of git+ssh://git.sv.gnu.org/srv/git/lilypond into gub
author Jan Nieuwenhuizen <janneke@gnu.org>
date Fri, 04 May 2007 15:21:47 +0200
parents 74517019ed26 (current diff) d03b487f0025 (diff)
children 116762651b08
files bin/gub
diffstat 15 files changed, 346 insertions(+), 282 deletions(-) [+]
line wrap: on
line diff
--- a/bin/cygwin-packager	Fri May 04 15:21:05 2007 +0200
+++ b/bin/cygwin-packager	Fri May 04 15:21:47 2007 +0200
@@ -315,6 +315,8 @@
                   action='append',
                   help='set branch for package')
 
+    p.add_option ('-v', '--verbose', action='count', dest='verbose', default=0)
+
     (options, args) = p.parse_args ()
     if len (args) != 1:
         p.print_help ()
@@ -322,9 +324,9 @@
     return (options, args)
 
 def main ():
-    (options, commands)  = parse_command_line ()
-    platform = 'cygwin'
-    settings = gub.settings.get_settings (platform)
+    (options, commands) = parse_command_line ()
+    options.platform = 'cygwin'
+    settings = gub.settings.Settins (options)
     # We want to be able to specify a build number for cygwin packages
     # that are not distributed on lp.org
     settings.build = options.build
--- a/bin/gpkg	Fri May 04 15:21:05 2007 +0200
+++ b/bin/gpkg	Fri May 04 15:21:47 2007 +0200
@@ -185,6 +185,7 @@
         platform = options.platform
         
         target_manager.read_package_headers ('uploads/%(platform)s/' % locals (), branch_dict)
+        target_manager.read_package_headers ('uploads/%(platform)s/cross/' % locals (), branch_dict)
 
     if options.command:
         commands = Command (target_manager, options)
--- a/bin/gub	Fri May 04 15:21:05 2007 +0200
+++ b/bin/gub	Fri May 04 15:21:47 2007 +0200
@@ -20,9 +20,6 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 """
 
-import os
-import re
-import string
 import sys
 sys.path.insert (0, '.')
 #
@@ -38,9 +35,8 @@
     import optparse
     p = optparse.OptionParser ()
 
-    p.usage='''gub [OPTION]... [PACKAGE]...
+    p.usage='''gub [OPTION]... [PACKAGE]...'''
 
-'''
     p.description='Grand Unified Builder.'
 
     p.add_option ('-B', '--branch', action='append',
@@ -130,222 +126,11 @@
 
     return p
 
-# FIXME: put all these functions that take manager, settings, specs, deps
-# into a 'builder' class?
-def pkg_checksum_valid (manager, spec, pkg):
-    name = pkg.name ()
-    pkg_dict = manager.package_dict (name)
-
-    valid = (spec.spec_checksum == pkg_dict['spec_checksum']
-             and spec.source_checksum () == pkg_dict['source_checksum'])
-
-    hdr = pkg.expand ('%(split_hdr)s')
-    valid = valid and os.path.exists (hdr)
-    if valid:
-        import pickle
-        hdr_dict = pickle.load (open (hdr))
-        hdr_sum = hdr_dict['spec_checksum']
-        valid = valid and hdr_sum == spec.spec_checksum
-        valid = valid and spec.source_checksum () == hdr_dict['source_checksum']
-
-    ## let's be lenient for cross pkgs.
-    ## spec.cross_checksum == manager.package_dict(name)['cross_checksum'])
-    return valid
-    
-
-def spec_checksums_valid (manager, spec):
-    valid = True
-    for pkg in spec.get_packages ():
-        valid = valid and pkg_checksum_valid (manager, spec, pkg)
-    return valid
-
-def run_one_builder (options, spec):
-    import inspect
-    available = dict (inspect.getmembers (spec, callable))
-    if options.stage:
-        (available[options.stage]) ()
-        return
-    
-    stages = ['download', 'untar', 'patch',
-              'configure', 'compile', 'install',
-              'src_package', 'package', 'clean']
-
-    if options.offline:
-        stages.remove ('download')
-
-    if not options.build_source:
-        stages.remove ('src_package')
-
-    if options.fresh:
-        try:
-            spec.os_interface.action ('Removing status filex')
-            os.unlink (spec.get_stamp_file ())
-        except OSError:
-            pass
-
-    tainted = False
-    for stage in stages:
-        if (not available.has_key (stage)):
-            continue
-
-        if spec.is_done (stage, stages.index (stage)):
-            tainted = True
-            continue
-
-        spec.os_interface.stage (' *** Stage: %s (%s)\n'
-                                 % (stage, spec.name ()))
-
-        if stage == 'package' and tainted and not options.force_package:
-            msg = spec.expand ('''Compile was continued from previous run.
-Will not package.
-Use
-
-rm %(stamp_file)s
-
-to force rebuild, or
-
---force-package
-
-to skip this check.
-''')
-            spec.os_interface.error (msg)
-            raise 'abort'
-
-
-        if (stage == 'clean'
-            and options.keep_build):
-            os.unlink (spec.get_stamp_file ())
-            continue
-
-        try:
-            (available[stage]) ()
-        except misc.SystemFailed:
-
-            ## failed patch will leave system in unpredictable state.
-            if stage == 'patch':
-                spec.system ('rm %(stamp_file)s')
-
-            raise
-
-        if stage != 'clean':
-            spec.set_done (stage, stages.index (stage))
-
-def spec_conflict_resolution (manager, spec, pkg):
-    pkg_name = pkg.name ()
-    install_candidate = pkg
-    subname = ''
-    if spec.name () != pkg_name:
-        subname = pkg_name.split ('-')[-1]
-    if spec.get_conflict_dict ().has_key (subname):
-        for c in spec.get_conflict_dict ()[subname]:
-            if manager.is_installed (c):
-                print '%(c)s conflicts with %(pkg_name)s' % locals ()
-                conflict_source = manager.source_name (c)
-                # FIXME: implicit provides: foo-* provides foo-core,
-                # should implement explicit provides
-                if conflict_source + '-core' == pkg_name:
-                    print ('  non-core %(conflict_source)s already installed'
-                           % locals ())
-                    print ('    skipping request to install %(pkg_name)s'
-                           % locals ())
-                    install_candidate = None
-                    continue
-                manager.uninstall_package (c)
-    return install_candidate
-
-def pkg_install (manager, spec, pkg):
-    if not manager.is_installed (pkg.name ()):
-        install_candidate = spec_conflict_resolution (manager, spec, pkg)
-        if install_candidate:
-            manager.unregister_package_dict (install_candidate.name ())
-            manager.register_package_dict (install_candidate.dict ())
-            manager.install_package (install_candidate.name ())
-            
-def spec_install (manager, spec):
-    for pkg in spec.get_packages ():
-        pkg_install (manager, spec, pkg)
-
-def spec_build (settings, manager, specs, spec_name):
-    spec = specs[spec_name]
-    all_installed = True
-    for p in spec.get_packages ():
-        all_installed = all_installed and manager.is_installed (p.name ())
-    if all_installed:
-        return
-
-    # ugh, dupe
-    checksum_ok = (settings.options.lax_checksums
-                   or spec_checksums_valid (manager, specs[spec_name]))
-
-    is_installable = misc.forall (manager.is_installable (p.name ())
-                                  for p in spec.get_packages ())
-
-    if (settings.options.stage
-        or not is_installable
-        or not checksum_ok):
-        settings.os_interface.stage ('building package: %s\n' % spec_name)
-        run_one_builder (settings.options, spec)
-
-    # FIXME, spec_install should be stage?
-    if settings.options.stage: # and options.stage != spec_install:
-        return
-
-    # FIXME, spec_install should be stage?
-    spec_install (manager, spec)
-
-def uninstall_outdated_specs (settings, manager, specs, deps):
-    def reverse (lst):
-        list.reverse (lst)
-        return lst
-    for spec_name in reverse (deps[:]):
-        spec = specs[spec_name]
-        # ugh, dupe
-        checksum_ok = (settings.options.lax_checksums
-                       or spec_checksums_valid (manager, specs[spec_name]))
-        for pkg in spec.get_packages ():
-            if (manager.is_installed (pkg.name ())
-                and (not manager.is_installable (pkg.name ())
-                     or not checksum_ok)):
-                manager.uninstall_package (pkg.name ())
-
-def build_source_packages (settings, specs, names):
-    try:
-        manager = gup.get_target_manager (settings)
-
-        ## Todo: have a readonly lock for local platform
-    except locker.LockedError:
-        print 'another build in progress. Skipping.'
-        if settings.options.skip_if_locked:
-            sys.exit (0)
-        raise
-
-    deps = filter (specs.has_key, names)
-
-    PATH = os.environ['PATH']
-    ## cross_prefix is also necessary for building cross packages, such as GCC
-    os.environ['PATH'] = settings.expand ('%(cross_prefix)s/bin:' + PATH,
-                                          locals ())
-
-    ## UGH -> double work, see cross.change_target_packages () ?
-    sdk_pkgs = [p for p in specs.values ()
-                if isinstance (p, gubb.SdkBuildSpec)]
-    cross_pkgs = [p for p in specs.values ()
-                  if isinstance (p, cross.CrossToolSpec)]
-
-    extra_build_deps = [p.name () for p in sdk_pkgs + cross_pkgs]
-    gup.add_packages_to_manager (manager, settings, specs)
-
-    # FIXME: what happens here, move to descriptive function?
-    if not settings.options.stage:
-        uninstall_outdated_specs (settings, manager, specs, deps)
-
-    for spec_name in deps:
-        spec_build (settings, manager, specs, spec_name)
-        
+#FIXME: move to Builder?
 def inspect (settings, files):
     (names, specs) = gup.get_source_packages (settings, files)
     pm = gup.get_target_manager (settings)
-    gup.add_packages_to_manager (pm, settings, specs)
+    gup.add_packages_to_self.manager (pm, settings, specs)
     deps = filter (specs.has_key, names)
 
     for f in files:
@@ -354,7 +139,8 @@
             open (settings.options.inspect_output, 'w').write (v)
         else:
             print v
-        
+
+#FIXME: move to Builder?
 def build (settings, files):
     (names, specs) = gup.get_source_packages (settings, files)
     def get_all_deps (name):
@@ -368,6 +154,7 @@
     deps = gup.topologically_sorted (files, {}, get_all_deps, None)
     settings.os_interface.info ('deps:' + `deps` + '\n')
 
+    import os
     PATH = os.environ['PATH']
     os.environ['PATH'] = settings.expand ('%(local_prefix)s/bin:' + PATH)
 
@@ -385,7 +172,18 @@
     if settings.options.stage:
         names = files
 
-    build_source_packages (settings, specs, names)
+    try:
+        manager = gup.get_target_manager (settings)
+        ## Todo: have a readonly lock for local platform
+    except locker.LockedError:
+        settings.os_interface.error ('another build in progress.  Skipping.')
+        if settings.options.skip_if_locked:
+            sys.exit (0)
+        raise
+
+    from gub import builder
+    b = builder.Builder (manager, settings, specs)
+    b.build_source_packages (names)
 
 def exceptional_build (settings, files):
     status = 1
--- a/bin/installer-builder	Fri May 04 15:21:05 2007 +0200
+++ b/bin/installer-builder	Fri May 04 15:21:47 2007 +0200
@@ -74,7 +74,6 @@
                   default=[],
                   dest="settings",
                   help="extra overrides for settings")
-
                   
     p.add_option ('-p', '--target-platform', action='store',
                   dest='platform',
@@ -83,6 +82,8 @@
                   help='select target platform',
                   choices=gub.settings.platforms.keys ())
 
+    p.add_option ('-v', '--verbose', action='count', dest='verbose', default=0)
+
     (options, args) = p.parse_args ()
     
     if not options.platform:
@@ -98,6 +99,8 @@
     install_manager = gup.PackageDictManager (settings.os_interface)
     install_manager.read_package_headers (settings.gub_uploads,
                                           settings.branch_dict)
+    install_manager.read_package_headers (settings.cross_gub_uploads,
+                                          settings.branch_dict)
 
     ## can't interrogate installer yet, because version is not known yet.
     file = installer.installer_checksum_file
@@ -125,6 +128,8 @@
     install_manager.include_build_deps = False
     install_manager.read_package_headers (settings.gub_uploads,
                                           settings.branch_dict)
+    install_manager.read_package_headers (settings.cross_gub_uploads,
+                                          settings.branch_dict)
 
     def get_dep (x):
         return install_manager.dependencies (x)
@@ -135,7 +140,7 @@
 
     # WTF is gcc-runtime?  Add to package dependencies, if necessary
     if not settings.is_distro:
-        package_names += ["gcc-runtime"]
+        package_names += ["cross/gcc-runtime"]
 
     for a in package_names:
         install_manager.install_package (a)
@@ -207,7 +212,7 @@
 def main ():
     (options, commands)  = parse_command_line ()
 
-    settings = gub.settings.get_settings (options.platform)
+    settings = gub.settings.Settings (options)
 
     settings.set_branches (options.branches)
     for s in options.settings:
--- a/compilers.make	Fri May 04 15:21:05 2007 +0200
+++ b/compilers.make	Fri May 04 15:21:47 2007 +0200
@@ -9,7 +9,8 @@
 #  GUB_CROSS_DISTCC_HOSTS - hosts with matching cross compilers
 #  GUB_DISTCC_ALLOW_HOSTS - which distcc daemons may connect.
 #  GUB_NATIVE_DISTCC_HOSTS - hosts with matching native compilers
-#  LOCAL_GUB_BUILDER_OPTIONS - esp.: --verbose, --keep [--force-package]
+#  LOCAL_GUB_OPTIONS - esp.: --verbose, --keep [--force-package]
+#  LOCAL_GUB_BUILDER_OPTIONS - deprecated
 
 ifeq ($(CWD),)
 $(error Must set CWD)
@@ -48,13 +49,13 @@
 		ln -s $(CWD)/gub/distcc.py target/native-distcc/bin/$(notdir $(binary)) && ) true
 
 # Find out if we need cross/gcc or glibc as topmost cross compile target
-#gcc_or_glibc = $(shell $(GUB_BUILDER) -p $(1) --inspect=version glibc > /dev/null 2>/dev/null && echo glibc || echo cross/gcc)
+#gcc_or_glibc = $(shell $(GUB) -p $(1) --inspect=version glibc > /dev/null 2>/dev/null && echo glibc || echo cross/gcc)
 
 # URG
 gcc_or_glibc = $(shell if echo $(1) | grep linux > /dev/null 2>/dev/null; then echo glibc; else echo cross/gcc; fi)
 
 cross-compilers:
-	$(foreach p, $(PLATFORMS),$(call INVOKE_GUB_BUILDER, $(p)) $(call gcc_or_glibc, $(p)) && ) true
+	$(foreach p, $(PLATFORMS),$(call INVOKE_GUB, $(p)) $(call gcc_or_glibc, $(p)) && ) true
 
 cross-distccd:
 	-$(if $(wildcard log/$@.pid),kill `cat log/$@.pid`, true)
@@ -80,12 +81,12 @@
 bootstrap: bootstrap-git download-local local cross-compilers local-cross-tools download 
 
 bootstrap-git:
-	$(GUB_BUILDER) $(LOCAL_GUB_BUILDER_OPTIONS) -p local git
+	$(GUB) $(LOCAL_GUB_OPTIONS) -p local git
 
 local-cross-tools:
 ifneq ($(filter mingw,$(PLATFORMS)),)
 ifneq ($(BUILD_PLATFORM),linux-64)
-	$(GUB_BUILDER) $(LOCAL_DRIVER_OPTIONS) -p local nsis 
+	$(GUB) $(LOCAL_GUB_OPTIONS) -p local nsis 
 endif
 endif
 
--- a/gub.make	Fri May 04 15:21:05 2007 +0200
+++ b/gub.make	Fri May 04 15:21:47 2007 +0200
@@ -6,29 +6,35 @@
 ## must always have one host.
 GUB_DISTCC_ALLOW_HOSTS=127.0.0.1
 
-GUB_BUILDER = $(PYTHON) bin/gub
-GUP_MANAGER = $(PYTHON) bin/gpkg
+GUB = $(PYTHON) bin/gub
+GPKG = $(PYTHON) bin/gpkg
 INSTALLER_BUILDER = $(PYTHON) bin/installer-builder
 CYGWIN_PACKAGER = $(PYTHON) bin/cygwin-packager
 
-INVOKE_GUB_BUILDER=$(GUB_BUILDER)\
+ifneq ($(LOCAL_GUB_BUILDER_OPTIONS),)
+$(warning LOCAL_GUB_BUILDER_OPTIONS is deprecated, use LOCAL_GUB_OPTIONS)
+LOCAL_GUB_OPTIONS += LOCAL_GUB_BUILDER_OPTIONS
+endif
+
+INVOKE_GUB=$(GUB)\
  --target-platform $(1)\
  $(GUB_ONLINE_OPTION) \
  $(foreach h,$(GUB_NATIVE_DISTCC_HOSTS), --native-distcc-host $(h))\
  $(foreach h,$(GUB_CROSS_DISTCC_HOSTS), --cross-distcc-host $(h))\
- $(GUB_BUILDER_OPTIONS)\
- $(LOCAL_GUB_BUILDER_OPTIONS)
-
+ $(GUB_OPTIONS)\
+ $(LOCAL_GUB_OPTIONS)
 
-INVOKE_GUP=$(GUP_MANAGER)\
+INVOKE_GUP=$(GPKG)\
  --platform $(1)\
- $(GUP_OPTIONS)
+ $(GPKG_OPTIONS)\
+ $(LOCAL_GPKG_OPIONS)
 
 INVOKE_INSTALLER_BUILDER=$(INSTALLER_BUILDER)\
  --target-platform $(1)\
- $(INSTALLER_BUILDER_OPTIONS)
+ $(INSTALLER_BUILDER_OPTIONS)\
+ $(LOCAL_INSTALLER_BUILDER_OPTIONS)
 
-BUILD=$(call INVOKE_GUB_BUILDER,$(1)) $(2)\
+BUILD=$(call INVOKE_GUB,$(1)) $(2)\
   && $(call INVOKE_INSTALLER_BUILDER,$(1)) build-all $(PACKAGE)
 
 BUILD_PLATFORM = $(shell $(PYTHON) bin/build-platform)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gub/builder.py	Fri May 04 15:21:47 2007 +0200
@@ -0,0 +1,242 @@
+"""
+    Copyright (c) 2005--2007
+    Jan Nieuwenhuizen <janneke@gnu.org>
+    Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+"""
+
+import os
+import sys
+sys.path.insert (0, '.')
+#
+from gub import cross
+## fixme: double use of gub name.
+from gub import gubb
+from gub import misc
+from gub import gup
+
+#FIXME: split spec_* into SpecBuiler?
+class Builder ():
+    def __init__ (self, manager, settings, specs):
+        self.manager = manager
+        self.settings = settings
+        self.specs = specs
+    
+        PATH = os.environ['PATH']
+        ## cross_prefix is also necessary for building cross packages, such as GCC
+        os.environ['PATH'] = self.settings.expand ('%(cross_prefix)s/bin:' + PATH,
+                                              locals ())
+
+        ## UGH -> double work, see cross.change_target_packages () ?
+        sdk_pkgs = [p for p in self.specs.values ()
+                    if isinstance (p, gubb.SdkBuildSpec)]
+        cross_pkgs = [p for p in self.specs.values ()
+                      if isinstance (p, cross.CrossToolSpec)]
+
+        extra_build_deps = [p.name () for p in sdk_pkgs + cross_pkgs]
+        gup.add_packages_to_manager (self.manager, self.settings, self.specs)
+
+    def pkg_checksum_valid (self, spec, pkg):
+        name = pkg.name ()
+        pkg_dict = self.manager.package_dict (name)
+
+        valid = (spec.spec_checksum == pkg_dict['spec_checksum']
+                 and spec.source_checksum () == pkg_dict['source_checksum'])
+
+        hdr = pkg.expand ('%(split_hdr)s')
+        valid = valid and os.path.exists (hdr)
+        if valid:
+            import pickle
+            hdr_dict = pickle.load (open (hdr))
+            hdr_sum = hdr_dict['spec_checksum']
+            valid = valid and hdr_sum == spec.spec_checksum
+            valid = valid and spec.source_checksum () == hdr_dict['source_checksum']
+
+        ## let's be lenient for cross pkgs.
+        ## spec.cross_checksum == self.manager.package_dict(name)['cross_checksum'])
+        return valid
+
+    def spec_checksums_valid (self, spec):
+        valid = True
+        for pkg in spec.get_packages ():
+            valid = valid and self.pkg_checksum_valid (spec, pkg)
+        return valid
+
+    def run_one_builder (self, spec):
+        import inspect
+        available = dict (inspect.getmembers (spec, callable))
+        if self.settings.options.stage:
+            (available[self.settings.options.stage]) ()
+            return
+
+        stages = ['download', 'untar', 'patch',
+                  'configure', 'compile', 'install',
+                  'src_package', 'package', 'clean']
+
+        if self.settings.options.offline:
+            stages.remove ('download')
+
+        if not self.settings.options.build_source:
+            stages.remove ('src_package')
+
+        if self.settings.options.fresh:
+            try:
+                spec_obj.os_interface.action ('Removing status filex')
+                os.unlink (spec_obj.get_stamp_file ())
+            except OSError:
+                pass
+
+        tainted = False
+        for stage in stages:
+            if (not available.has_key (stage)):
+                continue
+
+            if spec.is_done (stage, stages.index (stage)):
+                tainted = True
+                continue
+
+            spec.os_interface.stage (' *** Stage: %s (%s)\n'
+                                     % (stage, spec.name ()))
+
+            if stage == 'package' and tainted and not options.force_package:
+                msg = spec.expand ('''Compile was continued from previous run.
+Will not package.
+Use
+
+rm %(stamp_file)s
+
+to force rebuild, or
+
+--force-package
+
+to skip this check.
+''')
+                spec.os_interface.error (msg)
+                raise 'abort'
+
+
+            if (stage == 'clean'
+                and self.settings.options.keep_build):
+                os.unlink (spec.get_stamp_file ())
+                continue
+
+            try:
+                (available[stage]) ()
+            except misc.SystemFailed:
+
+                ## failed patch will leave system in unpredictable state.
+                if stage == 'patch':
+                    spec.system ('rm %(stamp_file)s')
+
+                raise
+
+            if stage != 'clean':
+                spec.set_done (stage, stages.index (stage))
+
+    def spec_conflict_resolution (self, spec, pkg):
+        pkg_name = pkg.name ()
+        install_candidate = pkg
+        subname = ''
+        if spec.name () != pkg_name:
+            subname = pkg_name.split ('-')[-1]
+        if spec.get_conflict_dict ().has_key (subname):
+            for c in spec.get_conflict_dict ()[subname]:
+                if self.manager.is_installed (c):
+                    print '%(c)s conflicts with %(pkg_name)s' % locals ()
+                    conflict_source = self.manager.source_name (c)
+                    # FIXME: implicit provides: foo-* provides foo-core,
+                    # should implement explicit provides
+                    if conflict_source + '-core' == pkg_name:
+                        print ('  non-core %(conflict_source)s already installed'
+                               % locals ())
+                        print ('    skipping request to install %(pkg_name)s'
+                               % locals ())
+                        install_candidate = None
+                        continue
+                    self.manager.uninstall_package (c)
+        return install_candidate
+
+    def pkg_install (self, spec, pkg):
+        if not self.manager.is_installed (pkg.name ()):
+            install_candidate = self.spec_conflict_resolution (spec, pkg)
+            if install_candidate:
+                self.manager.unregister_package_dict (install_candidate.name ())
+                self.manager.register_package_dict (install_candidate.dict ())
+                self.manager.install_package (install_candidate.name ())
+
+    def spec_install (self, spec):
+        for pkg in spec.get_packages ():
+            self.pkg_install (spec, pkg)
+
+    def spec_build (self, spec_name):
+        spec = self.specs[spec_name]
+        all_installed = True
+        for p in spec.get_packages ():
+            all_installed = (all_installed
+                             and self.manager.is_installed (p.name ()))
+        if all_installed:
+            return
+        # ugh, dupe
+        checksum_ok = (self.settings.options.lax_checksums
+                       or self.spec_checksums_valid (self.specs[spec_name]))
+        is_installable = misc.forall (self.manager.is_installable (p.name ())
+                                      for p in spec.get_packages ())
+        if (self.settings.options.stage
+            or not is_installable
+            or not checksum_ok):
+            self.settings.os_interface.stage ('building package: %s\n'
+                                              % spec_name)
+            self.run_one_builder (spec)
+
+        # FIXME, spec_install should be stage?
+        if self.settings.options.stage: # and options.stage != spec_install:
+            return
+
+        # FIXME, spec_install should be stage?
+        self.spec_install (spec)
+
+    def uninstall_outdated_spec (self, spec_name):
+            spec = self.specs[spec_name]
+            # ugh, dupe
+            checksum_ok = (self.settings.options.lax_checksums
+                           or self.spec_checksums_valid (self.specs[spec_name]))
+            for pkg in spec.get_packages ():
+                if (self.manager.is_installed (pkg.name ())
+                    and (not self.manager.is_installable (pkg.name ())
+                         or not checksum_ok)):
+                    self.manager.uninstall_package (pkg.name ())
+
+    def uninstall_outdated_specs (self, deps):
+        def reverse (lst):
+            list.reverse (lst)
+            return lst
+        for spec_name in reverse (deps[:]):
+            self.uninstall_outdated_spec (spec_name)
+
+    def build_source_packages (self, names):
+        deps = filter (self.specs.has_key, names)
+
+        if not self.settings.options.stage:
+            self.uninstall_outdated_specs (deps)
+
+        for spec_name in deps:
+            self.spec_build (spec_name)
+
+def main ():
+    boe
+
+if __name__ == '__main__':
+    main ()
--- a/gub/context.py	Fri May 04 15:21:05 2007 +0200
+++ b/gub/context.py	Fri May 04 15:21:47 2007 +0200
@@ -138,9 +138,12 @@
             
         return self.os_interface.file_sub (substs, self.expand (name, env), to_name, must_succeed, use_re=use_re)
     
-    def log_command (self, str, env={}):
+    def command (self, str):
+        self.os_interface.command (str)
+        
+    def log (self, str, env={}):
         str = self.expand (str, env)
-        self.os_interface.command (str)
+        self.os_interface.log (str)
         
     def read_pipe (self, cmd, env={}, ignore_errors=False):
         dict = self.get_substitution_dict (env)
--- a/gub/gup.py	Fri May 04 15:21:05 2007 +0200
+++ b/gub/gup.py	Fri May 04 15:21:47 2007 +0200
@@ -217,7 +217,7 @@
                 suffix = d['vc_branch']
                 print 'ignoring header: ' + package_hdr
                 branch = branch_dict[d['basename']]
-                print 'branch: %(branch)s, suffix: %(suffix)s' % locals ()
+                print 'branch: %(branch)s, expecting: %(suffix)s' % locals ()
                 return
         elif d['vc_branch']:
             sys.stdout.write ('No branch for package %s, ignoring header: %s\n' % (d['basename'], package_hdr))
@@ -255,7 +255,6 @@
     def read_package_headers (self, s, branch_dict):
         if os.path.isdir (s) and not s.endswith ('/'):
             s += '/'
-            
         for f in glob.glob ('%(s)s*hdr' % locals ()):
             self.register_package_header (f, branch_dict)
 
--- a/gub/installer.py	Fri May 04 15:21:05 2007 +0200
+++ b/gub/installer.py	Fri May 04 15:21:47 2007 +0200
@@ -3,7 +3,7 @@
 import time
 
 from gub import context
-from gub import darwintools
+from gub import darwin
 from gub import gup
 from gub import targetpackage
 
@@ -157,7 +157,7 @@
     def __init__ (self, settings):
         Installer.__init__ (self, settings)
         self.strip_command += ' -S '
-        self.rewirer = darwintools.Rewirer (self.settings)
+        self.rewirer = darwin.Rewirer (self.settings)
 
     def use_install_root_manager (self, package_manager):
         tarball = package_manager.package_dict ('darwin-sdk')['split_ball']
@@ -222,7 +222,7 @@
         self.system ('cd %(darwin_bundle_dir)s/../ && tar cjf %(bundle_zip)s LilyPond.app',
                      locals ())
         
-        self.log_command ("Created %(bundle_zip)s\n", locals()) 
+        self.info ("Created %(bundle_zip)s\n", locals()) 
         self.write_checksum ()
         
 class MingwRoot (Installer):
--- a/gub/settings.py	Fri May 04 15:21:05 2007 +0200
+++ b/gub/settings.py	Fri May 04 15:21:47 2007 +0200
@@ -42,18 +42,19 @@
         elif self.platform == 'mingw':
             self.target_gcc_flags = '-mwindows -mms-bitfields'
 
-        self.set_branches (options.branches)
-        self.build_source = options.build_source
-        self.cpu_count = options.cpu_count
-        self.set_distcc_hosts (options)
-        self.lilypond_versions = options.lilypond_versions
-        self.options = options ##ugh
+        try:
+            self.options = options ##ugh
+            self.set_branches (options.branches)
+            self.build_source = options.build_source
+            self.lilypond_versions = options.lilypond_versions
+            self.cpu_count = options.cpu_count
+            self.set_distcc_hosts (options)
+        except:
+            pass
 
-        #urg
         self.verbose = self.options.verbose
-    
         self.os = re.sub ('[-0-9].*', '', self.platform)
-    
+
         self.target_architecture = platforms[self.platform]
         self.cpu = self.target_architecture.split ('-')[0]
         self.build_source = False
--- a/gub/specs/guile.py	Fri May 04 15:21:05 2007 +0200
+++ b/gub/specs/guile.py	Fri May 04 15:21:47 2007 +0200
@@ -265,7 +265,11 @@
 class Guile__cygwin (Guile):
     def __init__ (self, settings):
         Guile.__init__ (self, settings)
-        self.with (version='1.8.1')
+#FIXME: barf, this breaks now that Guile uses git repo
+#        self.with (version='1.8.1')
+        from gub import mirrors
+        self.with (version='1.8.1', mirror=mirrors.gnu, format='gz')
+        self.so_version = '17'
 
     # Using gub dependencies only would be nice, but
     # we need to a lot of gup.gub_to_distro_deps ().
--- a/lilypond.make	Fri May 04 15:21:05 2007 +0200
+++ b/lilypond.make	Fri May 04 15:21:47 2007 +0200
@@ -41,10 +41,12 @@
 
 LILYPOND_LOCAL_BRANCH=$(LILYPOND_BRANCH_FILEIFIED)-git.sv.gnu.org-lilypond.git
 
-GUB_BUILDER_OPTIONS =\
+GUILE_LOCAL_BRANCH=branch_release-1-8-lilypond.org-vc-guile.git
+
+GUB_OPTIONS =\
  --branch lilypond=$(LILYPOND_BRANCH):$(LILYPOND_LOCAL_BRANCH)
 
-GUP_OPTIONS =\
+GPKG_OPTIONS =\
  --branch guile=$(GUILE_LOCAL_BRANCH) \
  --branch lilypond=$(LILYPOND_LOCAL_BRANCH)
 
@@ -76,7 +78,7 @@
 	$(PYTHON) gub/with-lock.py --skip $(LILYPOND_VERSIONS).lock $(MAKE) unlocked-update-versions
 
 download:
-	$(foreach p, $(PLATFORMS), $(call INVOKE_GUB_BUILDER,$(p)) --online --stage=download lilypond && ) true
+	$(foreach p, $(PLATFORMS), $(call INVOKE_GUB,$(p)) --online --stage=download lilypond && ) true
 	$(MAKE) downloads/genini
 	rm -f target/*/status/lilypond*
 	rm -f log/lilypond-$(LILYPOND_VERSION)*.*.test.pdf
@@ -113,7 +115,7 @@
 
 cygwin-libtool:
 	rm -f uploads/cygwin/setup.ini
-	$(call INVOKE_GUB_BUILDER,cygwin) --build-source libtool
+	$(call INVOKE_GUB,cygwin) --build-source libtool
 
 cygwin-libtool-installer:
 	$(CYGWIN_PACKAGER) libtool
@@ -122,19 +124,19 @@
 	rm -f uploads/cygwin/setup.ini
 	rm -rf target/cygwin/
 	$(call INVOKE_GUP, cygwin) install gcc
-	$(call INVOKE_GUB_BUILDER,cygwin) --build-source fontconfig
+	$(call INVOKE_GUB,cygwin) --build-source fontconfig
 
 cygwin-fontconfig-installer:
 	$(CYGWIN_PACKAGER) fontconfig
 
 cygwin-guile:
-	$(call INVOKE_GUB_BUILDER,cygwin) --build-source libtool guile
+	$(call INVOKE_GUB,cygwin) --build-source libtool guile
 
 cygwin-guile-installer:
 	$(CYGWIN_PACKAGER) guile
 
 cygwin-lilypond:
-	$(call INVOKE_GUB_BUILDER,cygwin) --build-source libtool guile fontconfig lilypond
+	$(call INVOKE_GUB,cygwin) --build-source libtool guile fontconfig lilypond
 
 cygwin-lilypond-installer:
 	$(CYGWIN_PACKAGER) --branch lilypond=$(LILYPOND_LOCAL_BRANCH) lilypond
@@ -224,13 +226,13 @@
 # -netpbm: website
 
 download-local:
-	$(GUB_BUILDER) $(LOCAL_GUB_BUILDER_OPTIONS) \
+	$(GUB) $(LOCAL_GUB_OPTIONS) \
 		-p local --stage=download \
 		$(locals)
 
 local:
 	cd librestrict && make -f GNUmakefile
-	$(GUB_BUILDER) $(LOCAL_GUB_BUILDER_OPTIONS) -p local \
+	$(GUB) $(LOCAL_GUB_OPTIONS) -p local \
 		$(locals)
 
 
@@ -279,10 +281,10 @@
 		&& touch $(call SIGNATURE_FUNCTION,$@) ; fi
 
 unlocked-doc-build:
-	$(GUP_MANAGER) -p $(BUILD_PLATFORM) remove lilypond
+	$(GPKG) -p $(BUILD_PLATFORM) remove lilypond
 
 	## force update of srcdir.
-	$(GUB_BUILDER) --branch lilypond=$(LILYPOND_BRANCH):$(LILYPOND_LOCAL_BRANCH) \
+	$(GUB) --branch lilypond=$(LILYPOND_BRANCH):$(LILYPOND_LOCAL_BRANCH) \
 		 -p $(BUILD_PLATFORM) --stage untar lilypond
 
 	unset LILYPONDPREFIX LILYPOND_DATADIR \
--- a/mingit.make	Fri May 04 15:21:05 2007 +0200
+++ b/mingit.make	Fri May 04 15:21:47 2007 +0200
@@ -12,9 +12,9 @@
 include gub.make
 include compilers.make
 
-GUP_OPTIONS=--branch git=$(MINGIT_LOCAL_BRANCH)
+GPKG_OPTIONS=--branch git=$(MINGIT_LOCAL_BRANCH)
 
-GUB_BUILDER_OPTIONS=\
+GUB_OPTIONS=\
  --branch git=$(MINGIT_BRANCH):$(MINGIT_LOCAL_BRANCH)
 
 INSTALLER_BUILDER_OPTIONS=\
@@ -24,17 +24,17 @@
 all: $(PLATFORMS)
 
 download:
-	$(foreach p, $(PLATFORMS), $(call INVOKE_GUB_BUILDER,$(p)) download git && ) true
+	$(foreach p, $(PLATFORMS), $(call INVOKE_GUB,$(p)) download git && ) true
 
 bootstrap: bootstrap-git download-local local cross-compilers local-cross-tools download 
 
 download-local:
-	$(GUB_BUILDER) $(LOCAL_GUB_BUILDER_OPTIONS) -p local\
+	$(GUB) $(LOCAL_GUB_OPTIONS) -p local\
 		--stage=download \
 		git pkg-config nsis icoutils 
 
 local:
-	$(GUB_BUILDER) $(LOCAL_GUB_BUILDER_OPTIONS) -p local git 
+	$(GUB) $(LOCAL_GUB_OPTIONS) -p local git 
 
 
 mingw:
--- a/test-lily/dist-check.py	Fri May 04 15:21:05 2007 +0200
+++ b/test-lily/dist-check.py	Fri May 04 15:21:47 2007 +0200
@@ -1,16 +1,16 @@
 #!/usr/bin/python
 
-import re
-import sys
-import os
 import glob
 import optparse
-
-sys.path.insert (0, os.path.split (sys.argv[0])[0] + '/../lib/')
+import os
+import re
+import sys
+import tempfile
 
-import repository
-import tempfile
-import misc
+sys.path.insert (0, os.path.split (sys.argv[0])[0] + '/..')
+
+from gub import repository
+from gub import misc
 
 def parse_options ():
     p = optparse.OptionParser ()