]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/rados/setup.py
import 15.2.0 Octopus source
[ceph.git] / ceph / src / pybind / rados / setup.py
1 from __future__ import print_function
2 import distutils.sysconfig
3 from distutils.errors import CompileError, LinkError
4 from distutils.ccompiler import new_compiler
5 from itertools import filterfalse, takewhile
6
7 import os
8 import pkgutil
9 import shutil
10 import subprocess
11 import sys
12 import tempfile
13 import textwrap
14
15
16 def filter_unsupported_flags(compiler, flags):
17 args = takewhile(lambda argv: not argv.startswith('-'), [compiler] + flags)
18 if any('clang' in arg for arg in args):
19 return list(filterfalse(lambda f:
20 f in ('-mcet',
21 '-fstack-clash-protection',
22 '-fno-var-tracking-assignments',
23 '-Wno-deprecated-register',
24 '-Wno-gnu-designator') or
25 f.startswith('-fcf-protection'),
26 flags))
27 else:
28 return flags
29
30
31 def monkey_with_compiler(customize):
32 def patched(compiler):
33 customize(compiler)
34 if compiler.compiler_type != 'unix':
35 return
36 compiler.compiler[1:] = \
37 filter_unsupported_flags(compiler.compiler[0],
38 compiler.compiler[1:])
39 compiler.compiler_so[1:] = \
40 filter_unsupported_flags(compiler.compiler_so[0],
41 compiler.compiler_so[1:])
42 return patched
43
44
45 distutils.sysconfig.customize_compiler = \
46 monkey_with_compiler(distutils.sysconfig.customize_compiler)
47
48 if not pkgutil.find_loader('setuptools'):
49 from distutils.core import setup
50 from distutils.extension import Extension
51 else:
52 from setuptools import setup
53 from setuptools.extension import Extension
54
55
56 distutils.sysconfig.customize_compiler = \
57 monkey_with_compiler(distutils.sysconfig.customize_compiler)
58
59 # PEP 440 versioning of the Rados package on PyPI
60 # Bump this version, after every changeset
61 __version__ = '2.0.0'
62
63
64 def get_python_flags(libs):
65 py_libs = sum((libs.split() for libs in
66 distutils.sysconfig.get_config_vars('LIBS', 'SYSLIBS')), [])
67 compiler = new_compiler()
68 distutils.sysconfig.customize_compiler(compiler)
69 return dict(
70 include_dirs=[distutils.sysconfig.get_python_inc()],
71 library_dirs=distutils.sysconfig.get_config_vars('LIBDIR', 'LIBPL'),
72 libraries=libs + [lib.replace('-l', '') for lib in py_libs],
73 extra_compile_args=filter_unsupported_flags(
74 compiler.compiler[0],
75 distutils.sysconfig.get_config_var('CFLAGS').split()),
76 extra_link_args=(distutils.sysconfig.get_config_var('LDFLAGS').split() +
77 distutils.sysconfig.get_config_var('LINKFORSHARED').split()))
78
79
80 def check_sanity():
81 """
82 Test if development headers and library for rados is available by compiling a dummy C program.
83 """
84 CEPH_SRC_DIR = os.path.join(
85 os.path.dirname(os.path.abspath(__file__)),
86 '..',
87 '..'
88 )
89
90 tmp_dir = tempfile.mkdtemp(dir=os.environ.get('TMPDIR', os.path.dirname(__file__)))
91 tmp_file = os.path.join(tmp_dir, 'rados_dummy.c')
92
93 with open(tmp_file, 'w') as fp:
94 dummy_prog = textwrap.dedent("""
95 #include <rados/librados.h>
96
97 int main(void) {
98 rados_t cluster;
99 rados_create(&cluster, NULL);
100 return 0;
101 }
102 """)
103 fp.write(dummy_prog)
104
105 compiler = new_compiler()
106 distutils.sysconfig.customize_compiler(compiler)
107
108 if 'CEPH_LIBDIR' in os.environ:
109 # The setup.py has been invoked by a top-level Ceph make.
110 # Set the appropriate CFLAGS and LDFLAGS
111 compiler.set_include_dirs([os.path.join(CEPH_SRC_DIR, 'include')])
112 compiler.set_library_dirs([os.environ.get('CEPH_LIBDIR')])
113
114 try:
115 link_objects = compiler.compile(
116 sources=[tmp_file],
117 output_dir=tmp_dir
118 )
119 compiler.link_executable(
120 objects=link_objects,
121 output_progname=os.path.join(tmp_dir, 'rados_dummy'),
122 libraries=['rados'],
123 output_dir=tmp_dir,
124 )
125
126 except CompileError:
127 print('\nCompile Error: RADOS development headers not found', file=sys.stderr)
128 return False
129 except LinkError:
130 print('\nLink Error: RADOS library not found', file=sys.stderr)
131 return False
132 else:
133 return True
134 finally:
135 shutil.rmtree(tmp_dir)
136
137
138 if 'BUILD_DOC' in os.environ.keys():
139 pass
140 elif check_sanity():
141 pass
142 else:
143 sys.exit(1)
144
145 cmdclass = {}
146 try:
147 from Cython.Build import cythonize
148 from Cython.Distutils import build_ext
149
150 cmdclass = {'build_ext': build_ext}
151 except ImportError:
152 print("WARNING: Cython is not installed.")
153
154 if not os.path.isfile('rados.c'):
155 print('ERROR: Cannot find Cythonized file rados.c', file=sys.stderr)
156 sys.exit(1)
157 else:
158 def cythonize(x, **kwargs):
159 return x
160
161 source = "rados.c"
162 else:
163 source = "rados.pyx"
164
165 # Disable cythonification if we're not really building anything
166 if (len(sys.argv) >= 2 and
167 any(i in sys.argv[1:] for i in ('--help', 'clean', 'egg_info', '--version')
168 )):
169 def cythonize(x, **kwargs):
170 return x
171
172 setup(
173 name='rados',
174 version=__version__,
175 description="Python bindings for the Ceph librados library",
176 long_description=(
177 "This package contains Python bindings for interacting with Ceph's "
178 "RADOS library. RADOS is a reliable, autonomic distributed object "
179 "storage cluster developed as part of the Ceph distributed storage "
180 "system. This is a shared library allowing applications to access "
181 "the distributed object store using a simple file-like interface."
182 ),
183 url='https://github.com/ceph/ceph/tree/master/src/pybind/rados',
184 license='LGPLv2+',
185 platforms='Linux',
186 ext_modules=cythonize(
187 [
188 Extension(
189 "rados",
190 [source],
191 **get_python_flags(['rados'])
192 )
193 ],
194 compiler_directives={'language_level': sys.version_info.major},
195 build_dir=os.environ.get("CYTHON_BUILD_DIR", None)
196 ),
197 classifiers=[
198 'Intended Audience :: Developers',
199 'Intended Audience :: System Administrators',
200 'License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)',
201 'Operating System :: POSIX :: Linux',
202 'Programming Language :: Cython',
203 'Programming Language :: Python :: 2.7',
204 'Programming Language :: Python :: 3.4',
205 'Programming Language :: Python :: 3.5'
206 ],
207 cmdclass=cmdclass,
208 )