X-Git-Url: http://woldlab.caltech.edu/gitweb/?p=pysam.git;a=blobdiff_plain;f=setup.py;h=979b9369ae38d0aa49a7e8f98aad08dc75c43baa;hp=098cb7f47a1927736b2cbd365611a604a940cafd;hb=HEAD;hpb=aa8ecff068edbb09a03bd874fce716e93e22e53c diff --git a/setup.py b/setup.py index 098cb7f..979b936 100644 --- a/setup.py +++ b/setup.py @@ -6,34 +6,121 @@ pysam ''' -import os, sys, glob, shutil +import os, sys, glob, shutil, hashlib, re, fnmatch +import platform name = "pysam" -version = "0.2" -samtools_exclude = ( "bamtk.c", "razip.c", "bgzip.c" ) +# collect pysam version +sys.path.insert( 0, "pysam") +import version + +version = version.__version__ + +samtools_exclude = ( "bamtk.c", "razip.c", "bgzip.c", + "main.c", "calDepth.c", "bam2bed.c", + "wgsim.c", "md5fa.c", "maq2sam.c",) samtools_dest = os.path.abspath( "samtools" ) +tabix_exclude = ( "main.c", ) +tabix_dest = os.path.abspath( "tabix" ) + +def locate(pattern, root=os.curdir): + '''Locate all files matching supplied filename pattern in and below + supplied root directory.''' + for path, dirs, files in os.walk(os.path.abspath(root)): + for filename in fnmatch.filter(files, pattern): + yield os.path.join(path, filename) + +def _update_pysam_files(cf, destdir): + '''update pysam files applying redirection of ouput''' + for filename in cf: + if not filename: continue + dest = filename + ".pysam.c" + with open( filename ) as infile: + with open( dest, "w" ) as outfile: + outfile.write( '#include "pysam.h"\n\n' ) + outfile.write( re.sub( "stderr", "pysamerr", "".join(infile.readlines()) ) ) + with open( os.path.join( destdir, "pysam.h" ), "w" )as outfile: + outfile.write ("""#ifndef PYSAM_H +#define PYSAM_H +#include "stdio.h" +extern FILE * pysamerr; +#endif +""") # copy samtools source if len(sys.argv) >= 2 and sys.argv[1] == "import": if len(sys.argv) < 3: raise ValueError("missing PATH to samtools source directory") - samtools_src = os.path.abspath( sys.argv[2] ) - if not os.path.exists( samtools_src ): raise IOError( "samtools src dir `%s` does not exist." % samtools_src ) - - cfiles = glob.glob( os.path.join( samtools_src, "*.c" ) ) - hfiles = glob.glob( os.path.join( samtools_src, "*.h" ) ) - ncopied = 0 - for p in cfiles + hfiles: - f = os.path.basename(p) - if f in samtools_exclude: continue - if os.path.exists( os.path.join( samtools_dest, f )): continue - shutil.copy( p, samtools_dest ) - ncopied += 1 - print "installed latest source code from %s: %i files copied" % (samtools_src, ncopied) + if len(sys.argv) < 4: raise ValueError("missing PATH to tabix source directory") + + for destdir, srcdir, exclude in zip( + (samtools_dest, tabix_dest), + sys.argv[2:4], + (samtools_exclude, tabix_exclude)): + + srcdir = os.path.abspath( srcdir ) + if not os.path.exists( srcdir ): raise IOError( "samtools src dir `%s` does not exist." % srcdir ) + + cfiles = locate( "*.c", srcdir ) + hfiles = locate( "*.h", srcdir ) + ncopied = 0 + + def _compareAndCopy( src, srcdir, destdir, exclude ): + + d, f = os.path.split(src) + if f in exclude: return None + common_prefix = os.path.commonprefix( (d, srcdir ) ) + subdir = re.sub( common_prefix, "", d )[1:] + targetdir = os.path.join( destdir, subdir ) + if not os.path.exists( targetdir ): + os.makedirs( targetdir ) + old_file = os.path.join( targetdir, f ) + if os.path.exists( old_file ): + md5_old = hashlib.md5("".join(open(old_file,"r").readlines())).digest() + md5_new = hashlib.md5("".join(open(src,"r").readlines())).digest() + if md5_old != md5_new: + raise ValueError( "incompatible files for %s and %s" % (old_file, src )) + + shutil.copy( src, targetdir ) + return old_file + + for src_file in hfiles: + _compareAndCopy( src_file, srcdir,destdir, exclude ) + ncopied += 1 + + cf = [] + for src_file in cfiles: + cf.append( _compareAndCopy( src_file, srcdir, destdir, exclude ) ) + ncopied += 1 + + sys.stdout.write("installed latest source code from %s: %i files copied" % (srcdir, ncopied)) + # redirect stderr to pysamerr and replace bam.h with a stub. + sys.stdout.write("applying stderr redirection") + + _update_pysam_files(cf, destdir) + + sys.exit(0) -from distutils.core import setup, Extension -from Pyrex.Distutils import build_ext +if len(sys.argv) >= 2 and sys.argv[1] == "refresh": + sys.stdout.write("refreshing latest source code from .c to .pysam.c") +# redirect stderr to pysamerr and replace bam.h with a stub. + sys.stdout.write("applying stderr redirection") + for destdir in ('samtools', 'tabix'): + pysamcfiles = locate( "*.pysam.c", destdir ) + for f in pysamcfiles: os.remove(f) + cfiles = locate( "*.c", destdir ) + _update_pysam_files(cfiles, destdir) + + sys.exit(0) + + + +from distribute_setup import use_setuptools +use_setuptools() + +from setuptools import Extension, setup +from Cython.Distutils import build_ext classifiers = """ Development Status :: 2 - Alpha @@ -48,14 +135,57 @@ Topic :: Scientific/Engineering Topic :: Scientific/Engineering :: Bioinformatics """ -pysam = Extension( - "pysam/csamtools", # name of extension +if platform.system()=='Windows': + include_os = ['win32'] + os_c_files = ['win32/getopt.c'] +else: + include_os = [] + os_c_files = [] + +samtools = Extension( + "csamtools", # name of extension [ "pysam/csamtools.pyx" ] +\ - [ "pysam/%s" % x for x in ( - "pysam_util.c", )] +\ - glob.glob( os.path.join( "samtools", "*.c" ) ), + [ "pysam/%s" % x for x in ( + "pysam_util.c", )] +\ + glob.glob( os.path.join( "samtools", "*.pysam.c" )) +\ + os_c_files + \ + glob.glob( os.path.join( "samtools", "*", "*.pysam.c" ) ), library_dirs=[], - include_dirs=[ "samtools", ], + include_dirs=[ "samtools", "pysam" ] + include_os, + libraries=[ "z", ], + language="c", + define_macros = [('_FILE_OFFSET_BITS','64'), + ('_USE_KNETFILE','')], + ) + +tabix = Extension( + "ctabix", # name of extension + [ "pysam/ctabix.pyx", ] +\ + [ "pysam/%s" % x for x in ( "tabix_util.c", )] +\ + os_c_files + \ + glob.glob( os.path.join( "tabix", "*.pysam.c" ) ), + library_dirs=[], + include_dirs=[ "tabix", "pysam" ] + include_os, + libraries=[ "z", ], + language="c", + define_macros = [('_FILE_OFFSET_BITS','64'), + ('_USE_KNETFILE','')], + ) + +tabproxies = Extension( + "TabProxies", # name of extension + [ "pysam/TabProxies.pyx", ] + os_c_files, + library_dirs=[], + include_dirs= include_os, + libraries=[ "z", ], + language="c", + ) + +cvcf = Extension( + "cvcf", # name of extension + [ "pysam/cvcf.pyx", ] + os_c_files, + library_dirs=[], + include_dirs= ["tabix",] + include_os, libraries=[ "z", ], language="c", ) @@ -71,9 +201,21 @@ metadata = { 'platforms': "ALL", 'url': "http://code.google.com/p/pysam/", 'py_modules': [ - "pysam/__init__", "pysam/Pileup", "pysam/namedtuple" ], - 'ext_modules': [pysam,], - 'cmdclass' : {'build_ext': build_ext} } + "pysam/__init__", + "pysam/Pileup", + "pysam/version" ], + # cython larger that 0.16 for yield support + 'requires' : ['cython (>=0.16)'], + 'ext_modules': [samtools, tabix, tabproxies, cvcf ], + 'cmdclass' : {'build_ext': build_ext}, + 'install_requires' : ['cython>=0.12.1',], + # do not pack in order to permit linking to csamtools.so + 'zip_safe' :False, + 'use_2to3': True, + } + +if sys.version_info[0] < 3: + metadata['py_modules'].append("pysam/namedtuple") if __name__=='__main__': dist = setup(**metadata)