#!/usr/bin/python """ Copyright (c) 2005--2007 Jan Nieuwenhuizen Han-Wen Nienhuys 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. """ def argv0_relocation (): import os, sys bindir = os.path.dirname (sys.argv[0]) prefix = os.path.dirname (bindir) sys.path.insert (0, prefix) argv0_relocation () import optparse import os import sys import pickle # from gub import gup from gub import installer import gub.settings from gub import locker from gub import versiondb def parse_command_line (): p = optparse.OptionParser () p.usage='''installer-builder.py [OPTION]... COMMAND [PACKAGE] Commands: build - build installer root strip - strip installer root package - package installer binary build-all - build, strip, package ''' p.description='Grand Unified Builder - collect in platform dependent package format' p.add_option ('-B', '--branch', dest='branches', default=[], action='append', help='set branch for package') p.add_option ('-l', '--skip-if-locked', default=False, dest="skip_if_locked", action="store_true", help="Return successfully if another build is already running") p.add_option ('--version-db', action='store', default='uploads/lilypond.versions', dest='version_db') p.add_option ("--no-strip", action="store_false", default=True, dest="do_strip", help="don't perform strip stage") p.add_option ("--setting", '-s', action="append", default=[], dest="settings", help="extra overrides for settings") p.add_option ('-p', '--platform', action='store', dest='platform', type='choice', default=None, 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: raise Exception ('error: no platform specified') cli_parser.print_help () sys.exit (2) return (options, args) def check_installer (installer, options, args): settings = installer.settings install_manager = gup.PackageDictManager (settings.os_interface) install_manager.read_package_headers (settings.packages, settings.branch_dict) install_manager.read_package_headers (settings.cross_packages, settings.branch_dict) ## can't interrogate installer yet, because version is not known yet. file = installer.installer_checksum_file if not os.path.exists (file): return False checksum = pickle.loads (open (file).read ()) ok = True print 'FIXME: serialization checksum' return True # FIXME: why this weird logic, always doing a full loop? Try: # loop: # if false: # return false # return True for (p, source_hash, spec_hash) in checksum: dict = install_manager.package_dict (p) ok = (ok and source_hash == dict['source_checksum'] and spec_hash == dict['spec_checksum']) return ok def build_installer (installer, args, options): settings = installer.settings install_manager = gup.DependencyManager (installer.installer_root, settings.os_interface, dbdir=installer.installer_db, clean=True) install_manager.include_build_deps = False install_manager.read_package_headers (settings.packages, settings.branch_dict) install_manager.read_package_headers (settings.cross_packages, settings.branch_dict) def get_dep (x): return install_manager.dependencies (x) package_names = gup.topologically_sorted (args, {}, get_dep, None) # WTF is gcc-runtime? Add to package dependencies, if necessary if not settings.is_distro and not settings.platform == 'linux-arm-vfp': package_names += ["cross/gcc-runtime"] for a in package_names: install_manager.install_package (a) version = install_manager.package_dict (args[0])['version'] try: version_tup = tuple (map (int, version.split ('.'))) db = versiondb.VersionDataBase (options.version_db) buildnumber = '%d' % db.get_next_build_number (version_tup) except: version = '0.0' buildnumber = '0' settings.installer_version = version settings.installer_build = buildnumber installer.use_install_root_manager (install_manager) checksum_list = [] print 'FIXME: serialization checksum' for p in (): ## install_manager.installed_packages (): dict = install_manager.package_dict (p) checksum_list.append ((p, dict['source_checksum'], dict['spec_checksum'])) installer.checksum = pickle.dumps (checksum_list) def strip_installer (obj): obj.command (' ** Stage: %s (%s installer)\n' % ('strip', obj.name)) obj.strip () def package_installer (installer): installer.create () def run_installer_commands (commands, settings, args, options): name = args[0] installer_obj = installer.get_installer (settings, name) if check_installer (installer_obj, options, args): settings.os_interface.info ('installer is up to date\n') return for c in commands: settings.os_interface.stage (' *** IStage: %s (%s)\n' % (c, installer_obj.name)) if c == ('build'): build_installer (installer_obj, args, options) elif c == ('strip'): strip_installer (installer_obj) elif c == ('package'): package_installer (installer_obj) else: raise Exception ('unknown installer command', c) def main (): (options, commands) = parse_command_line () settings = gub.settings.Settings (options) for s in options.settings: (k, v) = tuple (s.split ('=')) if settings.__dict__.has_key (k): settings.os_interface.warn ('overwriting %s = %s with %s\n' % (k, settings.__dict__[k], v)) settings.__dict__[k] = v c = commands.pop (0) cs = [c] if c == 'build-all': cs = ['build', 'strip', 'package'] if not options.do_strip: cs.remove ('strip') try: run_installer_commands (cs, settings, commands, options) except locker.LockedError, e: if options.skip_if_locked: settings.os_interface.error ('skipping build; install_root is locked\n') sys.exit (0) raise e settings.os_interface.stage ('done\n') settings.os_interface.error ('build log written to: ' + settings.os_interface.log_file_name + '\n') if __name__ == '__main__': main ()