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