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