]> git.proxmox.com Git - ceph.git/blame - ceph/src/pybind/cephfs/setup.py
import 15.2.0 Octopus source
[ceph.git] / ceph / src / pybind / cephfs / setup.py
CommitLineData
7c673cae
FG
1from __future__ import print_function
2
3import os
4import pkgutil
5import shutil
6import subprocess
7import sys
8import tempfile
9import textwrap
10from distutils.ccompiler import new_compiler
11from distutils.errors import CompileError, LinkError
9f95a23c 12from itertools import filterfalse, takewhile
11fdf7f2
TL
13import distutils.sysconfig
14
11fdf7f2 15
9f95a23c
TL
16def 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))
11fdf7f2
TL
27 else:
28 return flags
29
11fdf7f2 30
9f95a23c
TL
31def 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
45distutils.sysconfig.customize_compiler = \
46 monkey_with_compiler(distutils.sysconfig.customize_compiler)
7c673cae
FG
47
48if not pkgutil.find_loader('setuptools'):
49 from distutils.core import setup
50 from distutils.extension import Extension
51else:
52 from setuptools import setup
53 from setuptools.extension import Extension
54
55# PEP 440 versioning of the Ceph FS package on PyPI
56# Bump this version, after every changeset
57
58__version__ = '2.0.0'
59
60
9f95a23c
TL
61def get_python_flags(libs):
62 py_libs = sum((libs.split() for libs in
63 distutils.sysconfig.get_config_vars('LIBS', 'SYSLIBS')), [])
64 compiler = new_compiler()
65 distutils.sysconfig.customize_compiler(compiler)
66 return dict(
67 include_dirs=[distutils.sysconfig.get_python_inc()],
68 library_dirs=distutils.sysconfig.get_config_vars('LIBDIR', 'LIBPL'),
69 libraries=libs + [lib.replace('-l', '') for lib in py_libs],
70 extra_compile_args=filter_unsupported_flags(
71 compiler.compiler[0],
72 distutils.sysconfig.get_config_var('CFLAGS').split()),
73 extra_link_args=(distutils.sysconfig.get_config_var('LDFLAGS').split() +
74 distutils.sysconfig.get_config_var('LINKFORSHARED').split()))
7c673cae
FG
75
76
77def check_sanity():
78 """
79 Test if development headers and library for cephfs is available by compiling a dummy C program.
80 """
81 CEPH_SRC_DIR = os.path.join(
82 os.path.dirname(os.path.abspath(__file__)),
83 '..',
84 '..'
85 )
86
87 tmp_dir = tempfile.mkdtemp(dir=os.environ.get('TMPDIR', os.path.dirname(__file__)))
88 tmp_file = os.path.join(tmp_dir, 'cephfs_dummy.c')
89
90 with open(tmp_file, 'w') as fp:
91 dummy_prog = textwrap.dedent("""
92 #include <stddef.h>
93 #include "cephfs/libcephfs.h"
94
95 int main(void) {
96 struct ceph_mount_info *cmount = NULL;
97 ceph_init(cmount);
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_library_dirs([os.environ.get('CEPH_LIBDIR')])
110
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 extra_preargs=['-iquote{path}'.format(path=os.path.join(CEPH_SRC_DIR, 'include'))]
118 )
119
120 compiler.link_executable(
121 objects=link_objects,
122 output_progname=os.path.join(tmp_dir, 'cephfs_dummy'),
123 libraries=['cephfs'],
124 output_dir=tmp_dir,
125 )
126
127 except CompileError:
128 print('\nCompile Error: Ceph FS development headers not found', file=sys.stderr)
129 return False
130 except LinkError:
131 print('\nLink Error: Ceph FS library not found', file=sys.stderr)
132 return False
133 else:
134 return True
135 finally:
136 shutil.rmtree(tmp_dir)
137
138
139if 'BUILD_DOC' in os.environ.keys():
140 pass
141elif check_sanity():
142 pass
143else:
144 sys.exit(1)
145
146cmdclass = {}
147try:
148 from Cython.Build import cythonize
149 from Cython.Distutils import build_ext
150
151 cmdclass = {'build_ext': build_ext}
152except ImportError:
153 print("WARNING: Cython is not installed.")
154
155 if not os.path.isfile('cephfs.c'):
156 print('ERROR: Cannot find Cythonized file cephfs.c', file=sys.stderr)
157 sys.exit(1)
158 else:
159 def cythonize(x, **kwargs):
160 return x
161
162 source = "cephfs.c"
163else:
164 source = "cephfs.pyx"
165
166# Disable cythonification if we're not really building anything
167if (len(sys.argv) >= 2 and
168 any(i in sys.argv[1:] for i in ('--help', 'clean', 'egg_info', '--version')
169 )):
170 def cythonize(x, **kwargs):
171 return x
172
7c673cae
FG
173setup(
174 name='cephfs',
175 version=__version__,
176 description="Python bindings for the Ceph FS library",
177 long_description=(
178 "This package contains Python bindings for interacting with the "
179 "Ceph Filesystem (Ceph FS) library. Ceph FS is a POSIX-compliant "
180 "filesystem that uses a Ceph Storage Cluster to store its data. The "
181 "Ceph filesystem uses the same Ceph Storage Cluster system as "
182 "Ceph Block Devices, Ceph Object Storage with its S3 and Swift APIs, "
183 "or native bindings (librados)."
184 ),
185 url='https://github.com/ceph/ceph/tree/master/src/pybind/cephfs',
186 license='LGPLv2+',
187 platforms='Linux',
188 ext_modules=cythonize(
189 [
190 Extension(
191 "cephfs",
192 [source],
9f95a23c 193 **get_python_flags(['cephfs'])
7c673cae
FG
194 )
195 ],
9f95a23c 196 compiler_directives={'language_level': sys.version_info.major},
7c673cae
FG
197 build_dir=os.environ.get("CYTHON_BUILD_DIR", None),
198 include_path=[
199 os.path.join(os.path.dirname(__file__), "..", "rados")
200 ]
201 ),
202 classifiers=[
203 'Intended Audience :: Developers',
204 'Intended Audience :: System Administrators',
205 'License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)',
206 'Operating System :: POSIX :: Linux',
207 'Programming Language :: Cython',
208 'Programming Language :: Python :: 2.7',
209 'Programming Language :: Python :: 3.4',
210 'Programming Language :: Python :: 3.5'
211 ],
212 cmdclass=cmdclass,
213)