Skip to content
Snippets Groups Projects
setup.py.in 9.37 KiB
Newer Older
Franck Pérignon's avatar
Franck Pérignon committed
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
setup.py file for @PYPACKAGE_NAME@

"""
from numpy.distutils.core import setup, Extension
from numpy.distutils.misc_util import Configuration
# tools to deal with fortran dependencies.
import sys
sys.path.append('@CMAKE_SOURCE_DIR@/')
import sort_f90

def parseCmakeVar(var):
    if var != "":
        return var.split(';')
    else:
        return None
def create_fortran_extension(name, pyf_file=None, src_dirs=None, sources=None,
                             libdir=None, libs=None, debug_mode=0):
    """Create a new f2py module from fortran files
    """
    if sources is None:
        sources = []
        assert src_dirs is not None

    for sdir in src_dirs:
        sources += glob.glob(os.path.join(sdir, '*.f95'))
        sources += glob.glob(os.path.join(sdir, '*.f90'))
    f2py_options = ['--no-lower', '--no-wrap-functions']
    options = []
    # Reorder source list with fortran modules
    # dependencies. It seems that this is not taken into
    # account in f2py or distutils.
    if pyf_file is not None:
        sources.append(pyf_file)
    sources = sort_f90.sort(sources)
    if debug_mode == 0:
        options.append(('F2PY_REPORT_ON_ARRAY_COPY', '1'))
        if os.uname()[0] == 'Linux':
            options.append(('F2PY_REPORT_ATEXIT', '1'))
    inc_dir = '@MPI_Fortran_INCLUDE_PATH@'.split(';')
    #  To avoid -I -I in compiler call, which results in a bug:
    while inc_dir.count('') > 0:
        inc_dir.remove('')
    inc_dir.append('@CMAKE_BINARY_DIR@/Modules')
    fortran_flags = ['@Fortran_FLAGS@']
    ext_fort = Extension(name=name,
                         sources=sources,
                         f2py_options=f2py_options,
                         include_dirs=inc_dir,
                         define_macros=options,
                         library_dirs=libdir,
                         libraries=libs,
                         extra_f90_compile_args=fortran_flags
                         )
    return ext_fort

def create_swig_extension(name, inc_dirs, src_dirs=None, sources=None):
    """Create a python module from C++ files, using swig
    """
    swig_dir  = os.path.join('@CMAKE_SOURCE_DIR@', 'swig')
    swig_config_file = os.path.join(swig_dir, name+'.i')

    include_dirs = set(inc_dirs)
    if sources is None:
        sources = []
        if(src_dirs == None):
            assert(inc_dirs != None)
            for idir in inc_dirs:
                #sources += glob.glob(os.path.join(idir, '**/*.cpp'), recursive=True)
                for root, dirnames, filenames in os.walk(idir):
                    for filename in fnmatch.filter(filenames, '*.cpp'):
                        sources.append(os.path.join(root, filename))
        else:
            for sdir in src_dirs:
                sources += glob.glob(os.path.join(sdir, '*.cpp'))
    #else:
        #for f in sources:
            #include_dirs.add(os.path.dirname(f))

    sources.insert(0,swig_config_file)
    include_dirs = list(include_dirs)

    name = 'hysop._' + name
    swig_opts = ['-I' + swig_dir,
                 '-c++', '-modern']
                 #-outdir', '/Users/Franck/toto',
    
    extern_includes = parseCmakeVar("@CXX_EXT_INCLUDES@")
    if(extern_includes != None):
        for exti in extern_includes:
            include_dirs.append(exti)

    libraries = parseCmakeVar("@CXX_EXT_LIBS@")
    library_dirs = parseCmakeVar("@CXX_EXT_LIB_DIRS@")
    extra_compile_args = parseCmakeVar("@CXX_FLAGS@")
    extra_link_args = parseCmakeVar("@CXX_LINKER_FLAGS@")
    define_macros = parseCmakeVar("@CXX_EXTRA_DEFINES@")

    #print "INCLUDE_DIRS=",include_dirs
    #print "LIBRARIES=",libraries
    #print "LIBRARY_DIRS=",library_dirs
    #print "EXTRA_COMPILE_ARGS=",extra_compile_args
    #print "EXTRA_LINK_ARGS=",extra_link_args
    #print "DEFINE_MACROS=",define_macros
    #  To avoid -I -I in compiler call, which results in a bug:
    #while inc_dir.count('') > 0:
    #    inc_dir.remove('')
    #inc_dir.append('@CMAKE_BINARY_DIR@/Modules')
    swig_ext = Extension(name, sources=sources, language='c++',
                         swig_opts=swig_opts,
                         include_dirs=include_dirs,
                         library_dirs=library_dirs,
                         libraries=libraries,
                         define_macros=define_macros,
                         extra_compile_args=extra_compile_args,
                         extra_link_args=extra_link_args)
# ------------ Set list of packages required to build the module -------------
Franck Pérignon's avatar
Franck Pérignon committed
# Full package name
name = '@PYPACKAGE_NAME@'
# List of modules (directories) to be included
Franck Pérignon's avatar
Franck Pérignon committed
packages = ['hysop',
            'hysop.domain',
            'hysop.fields',
            'hysop.operator',
            'hysop.operator.discrete',
            'hysop.problem',
            'hysop.tools',
            'hysop.numerics',
            'hysop.numerics.integrators',
Franck Pérignon's avatar
Franck Pérignon committed
packages_for_tests = ['hysop.domain.tests',
                      'hysop.fields.tests',
                      'hysop.operator.tests',
                      'hysop.numerics.tests',
                      'hysop.tools.tests',
                      'hysop.problem.tests',
                      'hysop.numerics.tests',
Franck Pérignon's avatar
Franck Pérignon committed
    packages.append('hysop.mpi')
    packages_for_tests.append('hysop.mpi.tests')
Franck Pérignon's avatar
Franck Pérignon committed
    packages.append('hysop.gpu')
    packages_for_tests.append('hysop.gpu.tests')
    packages = packages + packages_for_tests
Franck Pérignon's avatar
Franck Pérignon committed
# Enable this to get debug info
# ------------ Extensions (f2py, cython, ...) setup ------------

# Check if fortran interface is enabled
enable_fortran = "@WITH_LIB_FORTRAN@"
    fortran_root = \
        '@CMAKE_SOURCE_DIR@/hysop'
Franck Pérignon's avatar
Franck Pérignon committed
    hysop_libdir = ['@CMAKE_BINARY_DIR@/src']
    hysoplib = ['@HYSOP_LIBRARY_NAME@']
    f2py_options = ['--no-lower']
    fortran_src = set([])
    # -- fftw fortran sources --
    withfftw = "@WITH_FFTW@"
        fortran_src.add('f2py/parameters.f90')
        fortran_src.add('f2py/fftw2py.f90')
        hysoplib.append('fftw3')
        hysoplib.append('fftw3_mpi')
Franck Pérignon's avatar
Franck Pérignon committed
        hysop_libdir.append(fftwdir)
Franck Pérignon's avatar
Franck Pérignon committed
        packages.append('hysop.fakef2py')
        packages.append('hysop.fakef2py.fftw2py')
    # -- scales sources --
    withscales = '@WITH_SCALES@'
        fortran_src.add('f2py/parameters.f90')
        fortran_src.add('f2py/scales2py.f90')
Franck Pérignon's avatar
Franck Pérignon committed
        packages.append('hysop.fakef2py')
        packages.append('hysop.fakef2py.scales2py')
    # -- set full path to fortran sources --
    fortran_src = list(fortran_src)
    for i in xrange(len(fortran_src)):
        fortran_src[i] = os.path.join(fortran_root, fortran_src[i])

    # === Draft for future implementation of fortran interface ===
    # -- f2py signature file --
    pyf_file = os.path.join(fortran_root, 'f2hysop.pyf')
    # -- list of directories which contains fortran sources --
    # those dirs must be in hysop package directory
    subdirs = ['fortran',
               ]
    num_dirs = []
    for sd in subdirs:
        num_dirs.append(os.path.join(fortran_root, sd))

    # create python interface to fortran sources
    # For the moment, it includes the 'old' interface
    # to scales and fftw (in sources) and the new
    # interface, in src_dirs
    ext['f2hysop'] = create_fortran_extension(
        name='hysop.f2hysop',
        sources=fortran_src,
        libdir=hysop_libdir,
        libs=hysoplib,
        pyf_file=pyf_file,
        src_dirs=num_dirs)

    for ex in ext:
        ext_modules.append(ext[ex])
Franck Pérignon's avatar
Franck Pérignon committed
    packages.append('hysop.fakef2py')
    packages.append('hysop.fakef2py.scales2py')
    packages.append('hysop.fakef2py.fftw2py')
# --- C++ files and swig interface --
if enable_cpp:
    # path to .i files
    swig_include_dirs = [os.path.join('@CMAKE_SOURCE_DIR@','swig')]
    cpp_include_dirs = ['src/fftw','src/hysop++/src']
    for id in cpp_include_dirs:
        swig_include_dirs.append(os.path.join('@CMAKE_SOURCE_DIR@', id))
    cpp2hysop = "@CPP_2_HYSOP@"
    ext[cpp2hysop] = create_swig_extension(name=cpp2hysop, inc_dirs=swig_include_dirs)
    for ex in ext:
        ext_modules.append(ext[ex])
    cl_src_dirs = ["cl_src", "cl_src/kernels",
                   "cl_src/advection", "cl_src/remeshing"]
    for cl_dir in cl_src_dirs:
Franck Pérignon's avatar
Franck Pérignon committed
            ('./hysop/gpu/' + cl_dir,
             ['@CMAKE_SOURCE_DIR@/hysop/gpu/' + cl_dir + '/'
Franck Pérignon's avatar
Franck Pérignon committed
                  '@CMAKE_SOURCE_DIR@/hysop/gpu/' + cl_dir + '/')
              if cl_file[0] != '.' and cl_file[0] != '#' and cl_file[-3:] == '.cl']))

descr = 'Hybrid Computation with Particles.'
authors = 'G.H Cottet, J.M Etancelin, J.B Keck, C.Mimeau, F.Pérignon, C. Picard'
Franck Pérignon's avatar
Franck Pérignon committed
# authors = 'HySoP development team'
config = Configuration(
    name=name,
    version='@PYPACKAGE_VERSION@',
    description=descr,
    author=authors,
    author_email='hysop-members@lists.forge.imag.fr',
    url='https://forge.imag.fr/projects/hysop/',
    license='GNU public license',
    package_dir={'': '@CMAKE_SOURCE_DIR@'},
    ext_modules=ext_modules,
    packages=packages,
    data_files=data_files,
Franck Pérignon's avatar
Franck Pérignon committed
)

setup(**config.todict())