Commit 54d9bba6 authored by James Henstridge's avatar James Henstridge

my gnome2 build scripts (which a few others wanted to play with).

parents
all:
@echo 'Run "make install" to install.'
update:
cvs -z3 -q update -Pd .
install:
@echo "Creating $(HOME)/bin/jhbuild"
@mkdir -p $(HOME)/bin
@echo '#!/bin/sh' > $(HOME)/bin/jhbuild
@echo 'python '`pwd`'/jhbuild.py "$$@"' >> $(HOME)/bin/jhbuild
@chmod a+x $(HOME)/bin/jhbuild
@[ -f $(HOME)/.jhbuildrc ]||echo "Don't forget to create ~/.jhbuildrc"
.PHONY: all update install
Yet Another Gnome 2 Build Script
================================
This is another set of scripts for building GNOME 2. They are still a
little rough around the edges, but may still be useful to you.
They don't enforce any particular checkout, build or install
directories for your gnome2 setup. Currently, it doesn't handle
external modules that must be installed (such as gettext, libtool,
etc) -- those will need to be installed manually.
Once the dependency information is added, the script should be usable
for a stable gnome setup as well.
To install the scripts run "make install", and then copy
sample.jhbuildrc to ~/.jhbuildrc and edit to match your setup. My rc
file is provided for reference as jamesh.jhbuildrc.
Using jhbuild
-------------
To build everything, just type 'jhbuild'. Some useful options are:
--no-cvs Don't pull the sources from CVS. Useful for building
when not connected to the network.
--no-build Just update the source, don't build.
--clean Always rerun autogen and make clean before building a
module.
When an error is encountered, you will be given a chance to fix the
problem. You can choose to rerun that part of the build, start a
shell to give you a chance to fix things, give up on the module all
together, or ignore the error (useful for certain cvs errors).
If you give up on building a module, all modules that depend on it
will be skipped. If you would prefer the build not to ask questions
on errors, you can pass the --no-interact switch, which is equivalent
to always choosing give up.
Module info
-----------
Information about how to build the modules is contained in the
moduleinfo.py file. This file needs to be modified when dependencies
between modules change (usually, no change to the ~/.jhbuildrc will be
needed).
#!/bin/sh
# install -c source dest
if [ $# = 3 -a "$1" = "-c" -a ! -d "$3" -a ! "$2" = "-d" ]; then
if cmp -s $2 $3; then
: do nothing
exit 0
fi
# install source dest
elif [ $# = 2 -a ! -d "$2" -a ! "$1" = "-d" ]; then
if cmp -s $1 $2; then
: do nothing
exit 0
fi
# install -c -m perms source dest
elif [ $# = 5 -a "$1" = "-c" -a $2 = "-m" -a ! -d "$5" ]; then
if cmp -s $4 $5; then
: do nothing
exit 0
fi
# install -m perms source dest
elif [ $# = 4 -a $1 = "-m" -a ! -d "$4" ]; then
if cmp -s $3 $4; then
: do nothing
exit 0
fi
fi
exec /usr/bin/install "$@";
# -*- mode: python -*-
import os
# information about cvs server
cvsroot = ':pserver:jamesh@cvs.gnome.org:/cvs/gnome'
# modules to build (deps are also built)
moduleset = 'head'
modules = ['gtk+', 'libglade', 'bonobo-config']
# where the sources are checked out to
checkoutroot = os.path.join(os.environ['HOME'], 'cvs', 'gnome2')
# the prefix to install things to (user must have write access)
prefix = '/opt/gtk2'
# arguments to pass to autogen script
autogenargs='--disable-static --disable-gtk-doc'
installprog = '/home/james/bin/install-check'
import sys, os, string, getopt
import module
import moduleinfo
usage = 'usage: jhbuild [ -f config ] options ...'
help = '''Build a set of CVS modules (such as GNOME).
-f, --file=CONFIG specify an alternative configuration file
-c, --clean clean up modules before builds
-n, --no-cvs skip the cvs update step
-b, --no-build only perform the cvs update step
-u, --uptodate=MOD1,... assume the named modules are up to date
--no-interact do not prompt for input
'''
try:
opts, args = getopt.getopt(sys.argv[1:], 'ncbf:u:',
['no-cvs', 'clean', 'no-build', 'file=',
'uptodate=', 'no-interact', 'help'])
except getopt.error, exc:
sys.stderr.write('jhbuild: %s\n' % str(exc))
sys.stderr.write(usage + '\n')
sys.exit(1)
default_config = {
'cvsroot': ':pserver:anonymous@anoncvs.gnome.org:/cvs/gnome',
'moduleset': 'head',
'modules': 'all',
'checkoutroot': os.path.join(os.environ['HOME'], 'cvs', 'gnome2'),
'prefix': '/opt/gtk2',
'autogenargs': '',
'installprog': None,
}
cvsupdate = 1
clean = 0
nobuild = 0
interact = 1
uptodate = ()
configfile=os.path.join(os.environ['HOME'], '.jhbuildrc')
for opt, arg in opts:
if opt == '--help':
print usage
print help
sys.exit(0)
elif opt in ('-n', '--no-cvs'):
cvsupdate = 0
elif opt in ('-c', '--clean'):
clean=1
elif opt in ('-b', '--no-build'):
nobuild=1
elif opt in ('-f', '--file'):
configfile = arg
elif opt in ('-u', '--uptodate'):
uptodate = string.split(arg, ',')
elif opt == '--no-interact':
interact = 0
config = default_config.copy()
execfile(configfile, config)
module_set = getattr(moduleinfo, config['moduleset'])
if config['modules'] == 'all':
module_list = module_set.get_full_module_list()
else:
module_list = module_set.get_module_list(config['modules'])
build = module.BuildScript(cvsroot=config['cvsroot'],
modulelist=module_list,
autogenargs=config['autogenargs'],
prefix=config['prefix'],
checkoutroot=config['checkoutroot'],
installprog=config['installprog'])
build.build(cvsupdate=cvsupdate, alwaysautogen=clean, makeclean=clean,
nobuild=nobuild, skip=uptodate, interact=interact)
import os, string
_boldcode = os.popen('tput bold', 'r').read()
_normal = os.popen('tput rmso', 'r').read()
user_shell = os.environ.get('SHELL', '/bin/sh')
class Module:
def __init__(self, name, checkoutdir=None, revision=None,
autogenargs='', dependencies=[]):
self.name = name
self.checkoutdir = checkoutdir
self.revision = revision
self.autogenargs = autogenargs
self.dependencies = dependencies
def __repr__(self):
return '<cvs module %s>' % self.name
def get_checkout_dir(self, checkoutroot):
'''get the directory we will checkout to'''
if self.checkoutdir:
return os.path.join(checkoutroot, self.checkoutdir)
else:
return os.path.join(checkoutroot, self.name)
def cvs_checkout_args(self):
'''arguments to checkout the module'''
ret = 'checkout '
if self.checkoutdir:
ret = ret + '-d ' + self.checkoutdir
if self.revision:
ret = ret + '-r ' + self.revision
else:
ret = ret + '-A '
return ret + self.name
def cvs_update_args(self):
'''arguments to update the module (to be run from checkout dir)'''
ret = 'update '
if self.revision:
ret = ret + '-r ' + self.revision
else:
ret = ret + '-A '
return ret + '.'
def autogen_args(self):
'''return extra arguments to pass to autogen'''
return self.autogenargs
class ModuleSet:
def __init__(self):
self.modules = {}
def add(self, module):
'''add a Module object to this set of modules'''
self.modules[module.name] = module
def get_module_list(self, seed):
'''gets a list of module objects (in correct dependency order)
needed to build the modules in the seed list'''
module_list = map(lambda name, modules=self.modules:
modules[name], seed)
i = 0
while i < len(module_list):
# make sure dependencies are built first
depadd = []
for dep in module_list[i].dependencies:
depmod = self.modules[dep]
if depmod not in module_list[:i+1]:
depadd.append(depmod)
module_list[i:i] = depadd
if not depadd:
i = i + 1
i = 0
while i < len(module_list):
if module_list[i] in module_list[:i]:
del module_list[i]
else:
i = i + 1
return module_list
def get_full_module_list(self):
return self.get_module_list(self.modules.keys())
class BuildScript:
def __init__(self, cvsroot, modulelist, autogenargs=None, cflags=None,
prefix=None, checkoutroot=None, installprog=None):
self.cvsroot = cvsroot
self.modulelist = modulelist
self.autogenargs = autogenargs
self.cflags = cflags
self.prefix = prefix
self.checkoutroot = checkoutroot
self.installprog = installprog
if not self.autogenargs:
self.autogenargs = '--disable-static --disable-gtk-doc'
if not self.prefix:
self.prefix = '/opt/gtk2'
if not self.checkoutroot:
self.checkoutroot = os.path.join(os.environ['HOME'], 'cvs','gnome')
assert os.access(self.prefix, os.R_OK|os.W_OK|os.X_OK), \
'install prefix must be writable'
self.login()
self.setupenv()
def login(self):
'''make sure we are logged into the cvs server first'''
loggedin = 0
try:
home = os.environ['HOME']
fp = open(os.path.join(home, '.cvspass'), 'r')
for line in fp.readlines():
pos = string.find(line, ' ')
if pos > 0:
line = line[:pos]
if line == self.cvsroot:
loggedin = 1
break
except IOError:
pass
if not loggedin:
os.system('cvs -d %s login' % self.cvsroot)
def __addpath(self, envvar, path):
try:
envval = os.environ[envvar]
if string.find(envval, path) < 0:
envval = envval + ':' + path
except KeyError:
envval = path
os.environ[envvar] = envval
def setupenv(self):
'''set environment variables for using prefix'''
includedir = os.path.join(self.prefix, 'include')
self.__addpath('C_INCLUDE_PATH', includedir)
libdir = os.path.join(self.prefix, 'lib')
self.__addpath('LD_LIBRARY_PATH', libdir)
bindir = os.path.join(self.prefix, 'bin')
self.__addpath('PATH', bindir)
pkgconfigdir = os.path.join(libdir, 'pkgconfig')
self.__addpath('PKG_CONFIG_PATH', pkgconfigdir)
aclocaldir = os.path.join(self.prefix, 'share', 'aclocal')
try:
val = os.environ['ACLOCAL_FLAGS']
os.environ['ACLOCAL_FLAGS'] = '%s -I %s' % (val, aclocaldir)
except KeyError:
os.environ['ACLOCAL_FLAGS'] = '-I %s' % aclocaldir
os.environ['CERTIFIED_GNOMIE'] = 'yes'
if self.installprog:
os.environ['INSTALL'] = self.installprog
if self.cflags:
os.environ['CFLAGS'] = self.cflags
def _message(self, msg):
print '%s*** %s ***%s' % (_boldcode, msg, _normal)
def _execute(self, command):
print command
ret = os.system(command)
print
return ret
def _cvscheckout(self, module):
checkoutdir = module.get_checkout_dir(self.checkoutroot)
if os.path.exists(checkoutdir):
os.chdir(checkoutdir)
self._message('updating module %s in %s' %
(module.name, checkoutdir))
cmd = 'cvs -z3 -q %s' % module.cvs_update_args()
else:
os.chdir(self.checkoutroot)
self._message('checking out module %s into %s' %
(module.name, checkoutdir))
cmd = 'cvs -z3 -q -d %s %s' % \
(self.cvsroot, module.cvs_checkout_args())
return self._execute(cmd)
def _configure(self, module):
self._message('running autogen.sh script for %s' % module.name)
cmd = './autogen.sh --prefix %s %s %s' % \
(self.prefix, self.autogenargs, module.autogen_args())
return self._execute(cmd)
def _makeclean(self, module):
self._message('running make clean for %s' % module.name)
return self._execute('make clean')
def _make(self, module):
self._message('running make for %s' % module.name)
return self._execute('make')
def _makeinstall(self, module):
self._message('running make install for %s' % module.name)
return self._execute('make install')
ERR_RERUN = 0
ERR_CONT = 1
ERR_GIVEUP = 2
def _handle_error(self, module, stage):
'''Ask the user what to do about an error.
Returns one of ERR_RERUN, ERR_CONT or ERR_GIVEUP.'''
self._message('error during %s for module %s' % (stage, module.name))
while 1:
print
print ' [1] rerun %s' % stage
print ' [2] start shell'
print ' [3] give up on module'
print ' [4] continue (ignore error)'
val = raw_input('choice: ')
if val == '1':
return self.ERR_RERUN
elif val == '2':
print 'exit shell to continue with build'
os.system(user_shell)
elif val == '3':
return self.ERR_GIVEUP
elif val == '4':
return self.ERR_CONT
else:
print 'invalid option'
def build(self, cvsupdate=1, alwaysautogen=0, makeclean=0, nobuild=0,
skip=(), interact=1):
poison = [] # list of modules that couldn't be built
# build steps for each module ...
STATE_CHECKOUT = 0
STATE_CONFIGURE = 1
STATE_CLEAN = 2
STATE_BUILD = 3
STATE_INSTALL = 4
STATE_DONE = 5
state_names = [
'checkout', 'configure', 'clean', 'build', 'install', 'done'
]
for module in self.modulelist:
if module.name in skip: continue
# check if any dependencies have been poisoned
poisoned = 0
for dep in module.dependencies:
if dep in poison:
self._message('module %s not built due to non buildable %s'
% (module.name, dep))
poisoned = 1
if poisoned:
poison.append(module.name)
continue
state = STATE_CHECKOUT
while state != STATE_DONE:
ret = 0
next_state = STATE_DONE
if state == STATE_CHECKOUT:
checkoutdir = module.get_checkout_dir(self.checkoutroot)
if cvsupdate:
ret = self._cvscheckout(module)
if nobuild:
next_state = STATE_DONE
else:
next_state = STATE_CONFIGURE
if ret == 0:
if not os.path.exists(checkoutdir):
self._message("checkout doesn't exist :(")
poison.append(module.name)
next_state = STATE_DONE
else: # else, go on to configure check
os.chdir(checkoutdir)
elif state == STATE_CONFIGURE:
if not os.path.exists('Makefile') or alwaysautogen:
ret = self._configure(module)
next_state = STATE_CLEAN
elif state == STATE_CLEAN:
if makeclean:
ret = self._makeclean(module)
next_state = STATE_BUILD
elif state == STATE_BUILD:
ret = self._make(module)
next_state = STATE_INSTALL
elif state == STATE_INSTALL:
ret = self._makeinstall(module)
next_state = STATE_DONE
if ret == 0:
state = next_state
else:
if interact:
err = self._handle_error(module, state_names[state])
else:
self._message('giving up on %s' % module.name)
err = self.ERR_GIVEUP # non interactive
if err == self.ERR_CONT:
state = next_state
elif err == self.ERR_RERUN:
pass # redo stage
elif err == self.ERR_GIVEUP:
poison.append(module.name)
state = STATE_DONE
if len(poison) == 0:
self._message('success')
else:
self._message('the following modules were not built')
for module in poison:
print module,
print
from module import Module, ModuleSet
head = ModuleSet()
head.add(Module(name='xml-i18n-tools'))
head.add(Module(name='gnome-common'))
head.add(Module(name='gtk-doc'))
head.add(Module(name='glib',
dependencies=['gtk-doc']))
head.add(Module(name='pango', dependencies=['glib']))
head.add(Module(name='atk', dependencies=['glib']))
head.add(Module(name='gtk+',
dependencies=['pango', 'atk']))
head.add(Module(name='gnome-xml', checkoutdir='libxml2'))
head.add(Module(name='linc', dependencies=['glib']))
head.add(Module(name='libIDL', dependencies=['glib']))
head.add(Module(name='ORBit2', dependencies=['linc', 'libIDL']))
head.add(Module(name='bonobo-activation',
dependencies=['xml-i18n-tools', 'gnome-common','ORBit2','gnome-xml']))
head.add(Module(name='gconf', dependencies=['ORBit2','gnome-xml','gtk+']))
head.add(Module(name='libbonobo', dependencies=['ORBit2','bonobo-activation']))
head.add(Module(name='gnome-vfs', dependencies=['libbonobo','gconf']))
head.add(Module(name='libart_lgpl'))
head.add(Module(name='bonobo-config',
dependencies=['libbonobo', 'xml-i18n-tools']))
head.add(Module(name='libgnome',
dependencies=['libbonobo','gnome-vfs','gconf']))
head.add(Module(name='libgnomecanvas', dependencies=['gtk+', 'libart_lgpl']))
head.add(Module(name='libbonoboui',
dependencies=['libgnome', 'libbonobo', 'libgnomecanvas']))
head.add(Module(name='libgnomeui', dependencies=['libbonoboui']))
head.add(Module(name='libglade',
dependencies=['gtk+', 'gnome-xml', 'libbonoboui', 'libgnomeui']))
# -*- mode: python -*-
# edit this file to match your settings and copy it to ~/.jhbuildrc
import os
# what cvs root should be used to checkout the files?
cvsroot = ':pserver:anonymous@anoncvs.gnome.org:/cvs/gnome'
# what module set should be used? (only head supported at the moment)
moduleset = 'head'
# either a list of modules to build, or 'all' to build all
# modules in the set.
modules = 'all'
# what directory should the source be checked out to?
checkoutroot = os.environ['HOME'] + '/cvs/gnome2'
# the prefix to configure/install modules to (must have write access)
prefix = '/opt/gnome2'
# extra arguments to pass to all autogen.sh scripts
# to speed up builds of gnome2, try '--disable-static --disable-gtk-doc'
# autogenargs=''
# a alternative install program to use.
# The included install-check program won't update timestamps if the
# header hasn't changed
# installprog = '/home/james/bin/install-check'
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment