1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
|
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from distutils.core import setup, Distribution
from distutils.command.build_py import build_py as _build_py
from distutils.command.build_ext import build_ext as _build_ext
from distutils.extension import Extension
from Cython.Build.Dependencies import cythonize
import warnings
warnings.simplefilter("always")
import os
from glob import glob
import sys
opj = os.path.join
ac_configure_flags = os.environ.get("PYSETUP_CONFIGURE_FLAGS","--without-pari")
if "--without-pari" in sys.argv:
ac_configure_flags = "--without-pari"
sys.argv.remove("--without-pari")
if "--with-pari" in sys.argv:
ac_configure_flags = "--with-pari"
sys.argv.remove("--with-pari")
env_PYBUILD_DESTDIR = os.environ.get("PYBUILD_DESTDIR")
cythonize_dir = "build/XXXX"
if "--without-pari" in ac_configure_flags:
cythonize_dir = "build/bare"
elif "--with-pari" in ac_configure_flags:
cythonize_dir = "build/pari"
kwds = dict(include_dirs=[opj("src", "cysignals"),
opj(cythonize_dir, "src"),
opj(cythonize_dir, "src", "cysignals")],
depends=glob(opj("src", "cysignals", "*.h")))
extensions = [
Extension("cysignals.signals", ["src/cysignals/signals.pyx"], **kwds),
Extension("cysignals.alarm", ["src/cysignals/alarm.pyx"], **kwds),
Extension("cysignals.pselect", ["src/cysignals/pselect.pyx"], **kwds),
Extension("cysignals.tests", ["src/cysignals/tests.pyx"], **kwds),
]
def write_if_changed(filename, text):
"""
Write ``text`` to ``filename`` but only if it differs from the
current content of ``filename``. If needed, the file and the
containing directory are created.
"""
try:
f = open(filename, "r+")
except IOError:
try:
os.makedirs(os.path.dirname(filename))
except OSError:
pass
f = open(filename, "w")
else:
if f.read() == text:
# File is up-to-date
f.close()
return
f.seek(0)
f.truncate()
print("generating {0}".format(filename))
f.write(text)
f.close()
# Run Distutils
class build_py(_build_py):
"""
Custom distutils build_py class. For every package FOO, we also
check package data for a "fake" FOO-cython package.
"""
def get_data_files(self):
"""Generate list of '(package,src_dir,build_dir,filenames)' tuples"""
data = []
if not self.packages:
return data
for package in self.packages:
for src_package in [package, package + "-cython"]:
# Locate package source directory
src_dir = self.get_package_dir(src_package)
# Compute package build directory
build_dir = os.path.join(*([self.build_lib] + package.split('.')))
# Length of path to strip from found files
plen = 0
if src_dir:
plen = len(src_dir)+1
# Strip directory from globbed filenames
filenames = [
file[plen:] for file in self.find_data_files(src_package, src_dir)
]
data.append((package, src_dir, build_dir, filenames))
return data
class build_ext(_build_ext):
def finalize_options(self):
_build_ext.finalize_options(self)
self.create_init_pxd()
ext_modules = self.distribution.ext_modules
if ext_modules:
self.distribution.ext_modules[:] = self.cythonize(ext_modules)
def cythonize(self, extensions):
return cythonize(extensions,
build_dir=cythonize_dir, include_path=["src", os.path.join(cythonize_dir, "src")])
def create_init_pxd(self):
"""
Create an ``__init__.pxd`` file in the build directory. This
file will then be installed.
The ``__init__.pxd`` file sets the correct compiler options for
packages using cysignals.
"""
dist = self.distribution
# Determine installation directory
inst = dist.get_command_obj("install")
inst.ensure_finalized()
install_dir = opj(inst.install_platlib, "cysignals")
# The variable "init_pxd" is the string which should be written to
# __init__.pxd
init_pxd = "# distutils: include_dirs = {0}\n".format(install_dir)
if env_PYBUILD_DESTDIR is None:
# Append __init__.pxd from configure
init_pxd += self.get_init_pxd()
else:
init_pxd = init_pxd.replace(env_PYBUILD_DESTDIR,"")
init_pxd_file = opj(self.build_lib, "cysignals", "__init__.pxd")
write_if_changed(init_pxd_file, init_pxd)
def get_init_pxd(self):
"""
Get the contents of ``__init__.pxd`` as generated by configure.
"""
configure_init_pxd_file = opj(cythonize_dir, "src", "cysignals", "__init__.pxd")
# Run configure if needed
try:
f = open(configure_init_pxd_file, "r")
except IOError:
import subprocess
subprocess.check_call(
"make configure && mkdir -p " + cythonize_dir +
" && " +
"{ cd " + cythonize_dir + " ; ../../configure " + ac_configure_flags + " ; }" ,
shell=True)
f = open(configure_init_pxd_file, "r")
with f:
return f.read()
setup(
name="cysignals",
author=u"Martin R. Albrecht, François Bissey, Volker Braun, Jeroen Demeyer",
author_email="sage-devel@googlegroups.com",
version=open("VERSION").read().strip(),
url="https://github.com/sagemath/cysignals",
license="GNU Lesser General Public License, version 3 or later",
description="Interrupt and signal handling for Cython",
long_description=open('README.rst').read(),
platforms=["POSIX"],
ext_modules=extensions,
packages=["cysignals","cysignals_gdb"],
package_dir={"cysignals": opj("src", "cysignals"),
"cysignals-cython": opj(cythonize_dir, "src", "cysignals"),
"cysignals_gdb": opj("src", "scripts")},
package_data={"cysignals": ["*.pxi", "*.pxd", "*.h"],
"cysignals-cython": ["*.h"],
"cysignals_gdb": ["cysignals-CSI-helper.py"]},
scripts=[opj("src", "scripts", "cysignals-CSI")],
cmdclass=dict(build_py=build_py, build_ext=build_ext),
)
|