]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/rbd/setup.py
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / pybind / rbd / setup.py
1 from __future__ import print_function
2
3 import os
4 import pkgutil
5 import shutil
6 import subprocess
7 import sys
8 import tempfile
9 import textwrap
10 from distutils.ccompiler import new_compiler
11 from distutils.errors import CompileError, LinkError
12 from distutils.sysconfig import customize_compiler
13
14 if not pkgutil.find_loader('setuptools'):
15 from distutils.core import setup
16 from distutils.extension import Extension
17 else:
18 from setuptools import setup
19 from setuptools.extension import Extension
20
21 # PEP 440 versioning of the RBD package on PyPI
22 # Bump this version, after every changeset
23
24 __version__ = '2.0.0'
25
26
27 def get_python_flags():
28 cflags = {'I': [], 'extras': []}
29 ldflags = {'l': [], 'L': [], 'extras': []}
30
31 if os.environ.get('VIRTUAL_ENV', None):
32 python = "python"
33 else:
34 python = 'python' + str(sys.version_info.major) + '.' + str(sys.version_info.minor)
35
36 python_config = python + '-config'
37
38 for cflag in subprocess.check_output(
39 [python_config, "--cflags"]
40 ).strip().decode('utf-8').split():
41 if cflag.startswith('-I'):
42 cflags['I'].append(cflag.replace('-I', ''))
43 else:
44 cflags['extras'].append(cflag)
45
46 for ldflag in subprocess.check_output(
47 [python_config, "--ldflags"]
48 ).strip().decode('utf-8').split():
49 if ldflag.startswith('-l'):
50 ldflags['l'].append(ldflag.replace('-l', ''))
51 if ldflag.startswith('-L'):
52 ldflags['L'].append(ldflag.replace('-L', ''))
53 else:
54 ldflags['extras'].append(ldflag)
55
56 return {
57 'cflags': cflags,
58 'ldflags': ldflags
59 }
60
61
62 def check_sanity():
63 """
64 Test if development headers and library for rbd is available by compiling a dummy C program.
65 """
66 CEPH_SRC_DIR = os.path.join(
67 os.path.dirname(os.path.abspath(__file__)),
68 '..',
69 '..'
70 )
71
72 tmp_dir = tempfile.mkdtemp(dir=os.environ.get('TMPDIR', os.path.dirname(__file__)))
73 tmp_file = os.path.join(tmp_dir, 'rbd_dummy.c')
74
75 with open(tmp_file, 'w') as fp:
76 dummy_prog = textwrap.dedent("""
77 #include <stddef.h>
78 #include <rbd/librbd.h>
79 int main(void) {
80 rados_t cluster;
81 rados_create(&cluster, NULL);
82 return 0;
83 }
84 """)
85 fp.write(dummy_prog)
86
87 compiler = new_compiler()
88 customize_compiler(compiler)
89
90 if {'MAKEFLAGS', 'MFLAGS', 'MAKELEVEL'}.issubset(set(os.environ.keys())):
91 # The setup.py has been invoked by a top-level Ceph make.
92 # Set the appropriate CFLAGS and LDFLAGS
93
94 compiler.set_include_dirs([os.path.join(CEPH_SRC_DIR, 'include')])
95 compiler.set_library_dirs([os.environ.get('CEPH_LIBDIR')])
96
97 try:
98 compiler.define_macro('_FILE_OFFSET_BITS', '64')
99
100 link_objects = compiler.compile(
101 sources=[tmp_file],
102 output_dir=tmp_dir
103 )
104
105 compiler.link_executable(
106 objects=link_objects,
107 output_progname=os.path.join(tmp_dir, 'rbd_dummy'),
108 libraries=['rbd', 'rados'],
109 output_dir=tmp_dir,
110 )
111
112 except CompileError:
113 print('\nCompile Error: RBD development headers not found', file=sys.stderr)
114 return False
115 except LinkError:
116 print('\nLink Error: RBD library not found', file=sys.stderr)
117 return False
118 else:
119 return True
120 finally:
121 shutil.rmtree(tmp_dir)
122
123
124 if 'BUILD_DOC' in os.environ.keys():
125 pass
126 elif check_sanity():
127 pass
128 else:
129 sys.exit(1)
130
131 cmdclass = {}
132 try:
133 from Cython.Build import cythonize
134 from Cython.Distutils import build_ext
135
136 cmdclass = {'build_ext': build_ext}
137 except ImportError:
138 print("WARNING: Cython is not installed.")
139
140 if not os.path.isfile('rbd.c'):
141 print('ERROR: Cannot find Cythonized file rbd.c', file=sys.stderr)
142 sys.exit(1)
143 else:
144 def cythonize(x, **kwargs):
145 return x
146
147 source = "rbd.c"
148 else:
149 source = "rbd.pyx"
150
151 # Disable cythonification if we're not really building anything
152 if (len(sys.argv) >= 2 and
153 any(i in sys.argv[1:] for i in ('--help', 'clean', 'egg_info', '--version')
154 )):
155 def cythonize(x, **kwargs):
156 return x
157
158 flags = get_python_flags()
159
160 setup(
161 name='rbd',
162 version=__version__,
163 description="Python bindings for the RBD library",
164 long_description=(
165 "This package contains Python bindings for interacting with the "
166 "RADOS Block Device (RBD) library. rbd is a utility for manipulating "
167 "rados block device images, used by the Linux rbd driver and the rbd "
168 "storage driver for QEMU/KVM. RBD images are simple block devices that "
169 "are striped over objects and stored in a RADOS object store. The size "
170 "of the objects the image is striped over must be a power of two."
171 ),
172 url='https://github.com/ceph/ceph/tree/master/src/pybind/rbd',
173 license='LGPLv2+',
174 platforms='Linux',
175 ext_modules=cythonize(
176 [
177 Extension(
178 "rbd",
179 [source],
180 include_dirs=flags['cflags']['I'],
181 library_dirs=flags['ldflags']['L'],
182 libraries=['rbd', 'rados'] + flags['ldflags']['l'],
183 extra_compile_args=flags['cflags']['extras'] + flags['ldflags']['extras'],
184 )
185 ],
186 build_dir=os.environ.get("CYTHON_BUILD_DIR", None),
187 include_path=[
188 os.path.join(os.path.dirname(__file__), "..", "rados")
189 ]
190 ),
191 classifiers=[
192 'Intended Audience :: Developers',
193 'Intended Audience :: System Administrators',
194 'License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)',
195 'Operating System :: POSIX :: Linux',
196 'Programming Language :: Cython',
197 'Programming Language :: Python :: 2.7',
198 'Programming Language :: Python :: 3.4',
199 'Programming Language :: Python :: 3.5'
200 ],
201 cmdclass=cmdclass,
202 )