[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Sage in Debian status update



Le 23/02/2013 13:25, Tobias Hansen a écrit :
Am 22.02.2013 13:29, schrieb Julien Puydt:
I have scripts to (try to...) build sage against what is in debian, see
attached. Notice:
- the comments in spkg_to_dpkg are not all up to date
- feedback on them is welcome
- to use them (1) edit the sagedir variable in debian_pruner.py, then
run it from the toplevel of a freshly-untarred sage source tarball, (2)
export PYTHONHOME as the script says and finally (3) type 'make'.

One day, that will give a nice working sage (and the day after, sage
will be in debian).

I think it would be very helpful to have a Sage package that can
alternatively use the original spkg's. That means, choose at build time
to include some additional spkg's and not to use the corresponding
Debian packages. That way there always is a working Sage package
available for testing, even if there are still known problems with some
Debian packages. This would also be helpful for debugging once Sage is
in Debian, because it would allow us to quickly check whether a bug is
related to the difference between Debian and Sage with regard to a
certain dependency.

Also, would you put you Sage work into the repository?
http://anonscm.debian.org/gitweb/?p=debian-science/packages/sagemath.git;a=summary

Take spkg_to_dpkg.py, and add u'unsupported' as first element of the list in front of the spkg you want used, and the script won't use the system version, so indeed it would make what you want possible.

Here is an updated version of my files, for 5.7 and for what is available in debian.

It's still a work-in-progress.

Where do you want them in this repository? They're so experimental right now :-/

Snark on #debian-science
#!/usr/bin/python
# -*- coding: utf-8 -*-

import io,os
from apt import *
from spkg_to_dpkg import spkg_deps

do_linking = True # if False, print the colors for the dependencies dot file
verbose = False # if True, print what is done

# FIXME: I wrote code to find the version of the spkg&deb, but that
# code is not used to check we have the correct versions!
# 
# It won't be trivial to code for at least three separate reasons :
#
# - each upstream can have its own numbering scheme ;
#
# - each spkg will have its ".p314" appended, when it's not a
# prepended "cropped"... or something else ;
#
# - each deb will also have modifiers like "-314build314"... or
# - something else.
#
# Wasn't it the beatles who sang "I need love" ?

sagedir = u'/home/jpuydt/sage-5.7'
cache = Cache() # that line can take long...

def build_spkg_versions():
    result = dict()
    for filename in os.listdir(os.path.join (sagedir, u'spkg', u'standard')):
        if filename[-4:] == u'spkg': # use -4 here because there's u'deps'!
            name_and_version = filename[:-5]
            version = u'-'.join(name_and_version.split(u'-')[1:])
            name = name_and_version.split(u'-')[0]
            result[name]=version
    return result

spkg_versions = build_spkg_versions()

def spkg_version(name):
    return spkg_versions[name]

def dpkg_version(package):
    return package.installed.version

def correct_version(s_version, d_version):
    # FIXME
    return True

def remove_file(name):
    os.remove(name)

def create_directory(name):
    try:
        os.makedirs(name)
        if verbose:
            print (u'create_directory(%s)' % name)
    except:
        pass

def symlink_file(source, target):
    try:
        os.symlink(source, target)
        if verbose:
            print (u'symlink(%s, %s)' % (source, target))
    except:
        pass

def touch_file(name):
    try:
        open(name, 'a')
        if verbose:
            print(u'touch_file(%s)' % name)
    except:
        pass

def symlink_directory(source, target):
    create_directory(target)
    for name in os.listdir(source):
        next_source=os.path.join(source, name)
        next_target=os.path.join(target, name)
        if os.path.isdir(next_source):
            symlink_directory(next_source, next_target)
        else:
            symlink_file(next_source, next_target)

def polybori_workarounds():
    # This is debian bts' #702056
    directory = os.path.join (sagedir, u'local', u'share', u'polybori')
    filename = os.path.join (directory, u'flags.conf')
    create_directory (directory)
    touch_file (filename)

def python_workarounds():
    directory = os.path.join (sagedir, u'local', u'bin')
    symlink_file (os.path.join(directory, u'python2.7'), os.path.join(directory, u'python'))

    directory = os.path.join (sagedir, u'local', u'lib')
    symlink_file (os.path.join(directory, u'python2.7'), os.path.join(directory, u'python'))

    directory = os.path.join (sagedir, u'local', u'lib', u'python2.7')
    symlink_file (os.path.join(directory, u'dist-packages'), os.path.join(directory, u'site-packages'))

    directory = os.path.join (sagedir, u'local', u'lib', u'python2.7')
    symlink_directory (os.path.join(u'/usr', u'lib', u'python2.7', u'dist-packages'), os.path.join(directory, u'dist-packages'))

def setuptools_workarounds():
    directory = os.path.join (sagedir, u'local', u'bin')
    remove_file(os.path.join (directory, u'easy_install'))
    remove_file(os.path.join (directory, u'easy_install-2.7'))
    remove_file(os.path.join (directory, u'easy_install-2.6'))

workarounds = {
    u'polybori': polybori_workarounds,
    u'python2.7': python_workarounds,
    u'python-setuptools': setuptools_workarounds
}

def do_special_thing_if_needed (package):
    if workarounds.has_key(package.name):
        workarounds[package.name]()
        print ('Did something special for %s' % package.name)

def prune_spkg(name, version):
    filename = os.path.join (sagedir, u'spkg', u'installed', '%s-%s' % (name, version))
    stream = io.open(filename, 'w')
    stream.write(u'The SYSTEM package was used!\n')
    stream.close()

def stow_dpkg(package):
    if verbose:
        print ('stow_dpkg(%s)' % package.name)
    excludes = [u'', u'/.', u'/usr']
    for name in package.installed_files:
        if name not in excludes:
            target_name = os.path.join(sagedir, u'local', os.path.relpath(name, u'/usr'))
            if os.path.isdir(name):
                create_directory (target_name)
            else:
                symlink_file (name, target_name)
    do_special_thing_if_needed (package)

def loop_on_spkgs():
    create_directory (os.path.join (sagedir, u'spkg', u'installed'))
    directory = os.path.join (sagedir, u'local')
    create_directory(directory)
    symlink_file (directory, os.path.join(directory, u'local')) # that one is baffling!
    for (spkg_name, dpkg_names) in spkg_deps.items():
        prunable = True
        for dpkg_name in dpkg_names:
            try:
                dpkg = cache[dpkg_name]
                if dpkg.installed == None:
                    prunable = False
                    print ("Can't prune %s: missing package %s" % (spkg_name, dpkg_name))
            except KeyError:
                prunable = False
                if dpkg_name == u'unsupported':
                    if do_linking:
                        print ("Can't prune %s: unsupported" % spkg_name)
                    else:
                        print ("""  %s [color="red"];""" % spkg_name.upper())
                else:
                    if do_linking:
                        print ("Can't prune %s: %s not found" % (spkg_name, dpkg_name))
                    else:
                        print ("""  %s [color="orange"];""" % spkg_name.upper())
            if not prunable:
                break
        if prunable:
            for dpkg_name in dpkg_names:
                dpkg = cache[dpkg_name]
                stow_dpkg (dpkg)
            if do_linking:
                prune_spkg (spkg_name, spkg_version(spkg_name))
                print ("Pruning %s" % spkg_name)
            else:
                print ("""  %s [color="green"];""" % spkg_name.upper())

loop_on_spkgs()
#print("Don't forget to export PYTHONHOME=%s/local" % sagedir)
#!/usr/bin/python
# -*- coding: utf-8 -*-

# for each spkg name, a list of debian packages which will cover what
# it provides
#
# with an empty list if nothing is needed (!), and a u'unsupported' if
# we don't know yet what we need (or it doesn't exist... or we know
# we're really outdated)
spkg_deps = {
    u'atlas' : [u'libatlas-dev', u'libatlas-base-dev', u'libatlas3gf-base', u'libatlas3-base'],
    u'blas' : [u'libblas-dev', u'libblas3gf'],
    u'boehm_gc': [u'libgc-dev', u'libgc1c2'],
    u'boost' : [u'unsupported'],
    u'cddlib': [u'libcdd-dev', u'libcdd0d'], # experimental
    u'cephes' : [u'unsupported'],
    u'cliquer': [u'unsupported', u'libcliquer-dev', u'libcliquer1'], # patched in sage
    u'conway' : [u'unsupported'],
    u'cvxopt': [u'python-cvxopt'],
    u'cython' : [u'cython'], # experimental
    u'docutils' : [u'python-docutils'],
    u'ecl' : [u'ecl'],
    u'eclib' : [u'eclib-tools', 'libec0', 'libec-dev'],
    u'ecm' : [u'libecm-dev', u'libecm0'],
    u'elliptic_curves' : [u'unsupported'],
    u'extcode' : [u'unsupported'],
    u'fflas_ffpack' : [u'fflas-ffpack', u'fflas-ffpack-dev'],
    u'flint': [u'unsupported'],
    u'flintqs': [u'unsupported'],
    u'freetype': [u'libfreetype6-dev', u'libfreetype6'],
    u'gap' : [u'gap', u'gap-core', u'gap-dev', u'gap-libs', u'gap-prim-groups', u'gap-small-groups', u'gap-trans-groups', u'gap-character-tables', u'gap-table-of-marks'],
    u'gcc' : [u'gfortran'],
    u'gd' : [u'libgd2-xpm-dev', u'libgd2-xpm'],
    u'gdmodule' : [u'python-gd'],
    u'genus2reduction' : [u'genus2reduction'],
    u'gfan' : [u'gfan'], # experimental
    u'givaro' : [u'libgivaro-dev', u'libgivaro1'],
    u'glpk' : [u'python-glpk', u'libglpk-dev', u'libglpk0'],
    u'graphs' : [u'unsupported'],
    u'gsl': [u'libgsl0-dev', u'libgsl0ldbl'],
    u'iconv' : [], # it's in the libc
    u'iml' : [u'libiml-dev', u'libiml0'],
    u'ipython': [u'ipython'],
    u'jinja2' : [u'python-jinja2'], # debian has a newer...
    u'jmol' : [u'jmol'],
    u'lapack' : [u'liblapack-dev', u'liblapack3gf'],
    u'lcalc': [u'unsupported'], # debian doesn't have it with the headers
    u'libfplll' : [u'unsupported', u'libfplll-dev', u'libfplll0'], # personal packages, but sage is too ancient http://trac.sagemath.org/sage_trac/ticket/12835
    u'libgap' : [u'unsupported'],
    u'libm4ri' : [u'libm4ri-0.0.20120613', u'libm4ri-dev'], # experimental
    u'libm4rie' : [u'libm4rie-dev', u'libm4rie-0.0.20111203'], # experimental?
    u'libpng' : [u'libpng12-dev', u'libpng12-0'],
    u'linbox' : [u'unsupported', u'liblinbox-dev', u'liblinbox0'], # too old in debian
    u'lrcalc': [u'unsupported'],
    u'matplotlib' : [u'python-matplotlib'],
    u'maxima' : [u'maxima'],
    u'mercurial' : [u'mercurial'],
    u'mpc': [u'libmpc2', u'libmpc-dev'],
    u'mpfi' : [u'libmpfi-dev', u'libmpfi0'],
    u'mpfr' : [u'libmpfr-dev', u'libmpfr4'],
    u'mpir' : [u'unsupported'],
    u'mpmath' : [u'python-mpmath'],
    u'networkx' : [u'python-networkx'],
    u'ntl' : [u'libntl-dev', u'libntl0'],
    u'numpy': [u'python-numpy'],
    u'palp' : [u'palp'], # packaged in the debian science git
    u'pari' : [u'libpari-dev', u'pari-gp'],
    u'patch' : [u'patch'],
    u'pexpect' : [u'python-pexpect'],
    u'pil' : [u'python-imaging'],
    u'polybori' : [u'python-polybori', u'libpolybori-dev'], # experimental
    u'polytopes_db' : [u'unsupported'],
    u'ppl' : [u'libppl0.11-dev', u'libppl9'],
    u'pycrypto' : [u'python-crypto'],
    u'pygments' : [u'python-pygments'],
    u'pynac' : [u'libpynac4', 'libpynac-dev'], # personal packages
    u'python' : [u'python2.7-dev', u'python2.7', u'python2.7-minimal'],
    u'r' : [u'r-base-dev', u'r-base-core', u'r-cran-mass', u'r-cran-lattice', u'r-cran-matrix', u'r-cran-nlme', u'r-cran-survival', u'r-cran-boot', u'r-cran-cluster', u'r-cran-codetools', u'r-cran-foreign', u'r-cran-kernsmooth', u'r-cran-rpart', u'r-cran-class', u'r-cran-nnet', u'r-cran-spatial', u'r-cran-mgcv'],
    u'ratpoints' : [u'unsupported'],
    u'readline' : [u'libreadline6-dev', u'libreadline6'],
    u'rpy2' : [u'python-rpy2'],
    u'rubiks' : [u'unsupported'],
    u'sage' : [u'unsupported'],
    u'sagenb' : [u'unsupported'],
    u'sage_root' : [u'unsupported'],
    u'sage_scripts' : [u'unsupported'],
    u'sagetex' : [u'unsupported'],
    u'scipy' : [u'python-scipy'],
    u'scons' : [u'scons'],
    u'setuptools' : [u'python-setuptools', u'python-pkg-resources'],
    u'singular' : [u'unsupported'], # too old in debian
    u'sphinx' : [u'python-sphinx'],
    u'sqlalchemy' : [u'python-sqlalchemy'],
    u'sqlite' : [u'libsqlite3-dev', u'libsqlite3-0'],
    u'symmetrica' : [u'libsymmetrica-dev', u'libsymmetrica-2.0'],
    u'sympow' : [u'sympow'],
    u'sympy' : [u'python-sympy'],
    u'tachyon' : [u'tachyon'],
    u'termcap' : [], # it's unneeded
    u'zlib' : [u'zlib1g-dev', u'zlib1g'],
    u'zn_poly' : [u'libzn-poly-dev', u'libzn-poly-0.9'],
}

Reply to: