Release of libvirt-python-3.9.0
[libvirt-python/ericb.git] / setup.py
blob3cdfcbf0bda49f605d1122d8b478d6954a838aa1
1 #!/usr/bin/python
3 from distutils.core import setup, Extension, Command
4 from distutils.command.build import build
5 from distutils.command.clean import clean
6 from distutils.command.sdist import sdist
7 from distutils.dir_util import remove_tree
8 from distutils.util import get_platform
9 from distutils.spawn import spawn
10 from distutils.errors import DistutilsExecError
11 import distutils
13 import sys
14 import os
15 import os.path
16 import re
17 import shutil
18 import time
20 MIN_LIBVIRT = "0.9.11"
21 MIN_LIBVIRT_LXC = "1.0.2"
23 # Hack to stop 'pip install' failing with error
24 # about missing 'build' dir.
25 if not os.path.exists("build"):
26 os.mkdir("build")
28 _pkgcfg = -1
29 def get_pkgcfg(do_fail=True):
30 global _pkgcfg
31 if _pkgcfg == -1:
32 _pkgcfg = os.getenv('PKG_CONFIG')
33 if _pkgcfg is None:
34 _pkgcfg = distutils.spawn.find_executable("pkg-config")
35 if _pkgcfg is None and do_fail:
36 raise Exception("pkg-config binary is required to compile libvirt-python")
37 return _pkgcfg
39 def check_minimum_libvirt_version():
40 spawn([get_pkgcfg(),
41 "--print-errors",
42 "--atleast-version=%s" % MIN_LIBVIRT,
43 "libvirt"])
45 def have_libvirt_lxc():
46 try:
47 spawn([get_pkgcfg(),
48 "--atleast-version=%s" % MIN_LIBVIRT_LXC,
49 "libvirt"])
50 return True
51 except DistutilsExecError:
52 return False
54 def have_libvirtaio():
55 # This depends on asyncio, which in turn depends on "yield from" syntax.
56 # The asyncio module itself is in standard library since 3.4, but there is
57 # an out-of-tree version compatible with 3.3.
58 return sys.version_info >= (3, 3)
60 def get_pkgconfig_data(args, mod, required=True):
61 """Run pkg-config to and return content associated with it"""
62 f = os.popen("%s %s %s" % (get_pkgcfg(), " ".join(args), mod))
64 line = f.readline()
65 if line is not None:
66 line = line.strip()
68 if line is None or line == "":
69 if required:
70 raise Exception("Cannot determine '%s' from libvirt pkg-config file" % " ".join(args))
71 else:
72 return ""
74 return line
76 def get_api_xml_files():
77 """Check with pkg-config that libvirt is present and extract
78 the API XML file paths we need from it"""
80 libvirt_api = get_pkgconfig_data(["--variable", "libvirt_api"], "libvirt")
82 offset = libvirt_api.index("-api.xml")
83 libvirt_qemu_api = libvirt_api[0:offset] + "-qemu-api.xml"
85 offset = libvirt_api.index("-api.xml")
86 libvirt_lxc_api = libvirt_api[0:offset] + "-lxc-api.xml"
88 return (libvirt_api, libvirt_qemu_api, libvirt_lxc_api)
90 def get_module_lists():
91 """
92 Determine which modules we are actually building, and all their
93 required config
94 """
95 if get_pkgcfg(do_fail=False) is None:
96 return [], []
98 c_modules = []
99 py_modules = []
100 ldflags = get_pkgconfig_data(["--libs-only-L"], "libvirt", False).split()
101 cflags = get_pkgconfig_data(["--cflags"], "libvirt", False).split()
103 module = Extension('libvirtmod',
104 sources = ['libvirt-override.c', 'build/libvirt.c', 'typewrappers.c', 'libvirt-utils.c'],
105 libraries = [ "virt" ],
106 include_dirs = [ "." ])
107 module.extra_compile_args.extend(cflags)
108 module.extra_link_args.extend(ldflags)
110 c_modules.append(module)
111 py_modules.append("libvirt")
113 moduleqemu = Extension('libvirtmod_qemu',
114 sources = ['libvirt-qemu-override.c', 'build/libvirt-qemu.c', 'typewrappers.c', 'libvirt-utils.c'],
115 libraries = [ "virt-qemu" ],
116 include_dirs = [ "." ])
117 moduleqemu.extra_compile_args.extend(cflags)
118 moduleqemu.extra_link_args.extend(ldflags)
120 c_modules.append(moduleqemu)
121 py_modules.append("libvirt_qemu")
123 if have_libvirt_lxc():
124 modulelxc = Extension('libvirtmod_lxc',
125 sources = ['libvirt-lxc-override.c', 'build/libvirt-lxc.c', 'typewrappers.c', 'libvirt-utils.c'],
126 libraries = [ "virt-lxc" ],
127 include_dirs = [ "." ])
128 modulelxc.extra_compile_args.extend(cflags)
129 modulelxc.extra_link_args.extend(ldflags)
131 c_modules.append(modulelxc)
132 py_modules.append("libvirt_lxc")
134 if have_libvirtaio():
135 py_modules.append("libvirtaio")
137 return c_modules, py_modules
140 ###################
141 # Custom commands #
142 ###################
144 class my_build(build):
146 def run(self):
147 check_minimum_libvirt_version()
148 apis = get_api_xml_files()
150 self.spawn([sys.executable, "generator.py", "libvirt", apis[0]])
151 self.spawn([sys.executable, "generator.py", "libvirt-qemu", apis[1]])
152 if have_libvirt_lxc():
153 self.spawn([sys.executable, "generator.py", "libvirt-lxc", apis[2]])
154 if have_libvirtaio():
155 shutil.copy('libvirtaio.py', 'build')
157 build.run(self)
159 class my_sdist(sdist):
160 user_options = sdist.user_options
162 description = "Update libvirt-python.spec; build sdist-tarball."
164 def initialize_options(self):
165 self.snapshot = None
166 sdist.initialize_options(self)
168 def finalize_options(self):
169 if self.snapshot is not None:
170 self.snapshot = 1
171 sdist.finalize_options(self)
173 def gen_rpm_spec(self):
174 f1 = open('libvirt-python.spec.in', 'r')
175 f2 = open('libvirt-python.spec', 'w')
176 for line in f1:
177 f2.write(line
178 .replace('@PY_VERSION@', self.distribution.get_version())
179 .replace('@C_VERSION@', MIN_LIBVIRT))
180 f1.close()
181 f2.close()
183 def gen_authors(self):
184 f = os.popen("git log --pretty=format:'%aN <%aE>'")
185 authors = []
186 for line in f:
187 line = " " + line.strip()
188 if line not in authors:
189 authors.append(line)
191 authors.sort(key=str.lower)
193 f1 = open('AUTHORS.in', 'r')
194 f2 = open('AUTHORS', 'w')
195 for line in f1:
196 f2.write(line.replace('@AUTHORS@', "\n".join(authors)))
197 f1.close()
198 f2.close()
201 def gen_changelog(self):
202 f1 = os.popen("git log '--pretty=format:%H:%ct %an <%ae>%n%n%s%n%b%n'")
203 f2 = open("ChangeLog", 'w')
205 for line in f1:
206 m = re.match(r'([a-f0-9]+):(\d+)\s(.*)', line)
207 if m:
208 t = time.gmtime(int(m.group(2)))
209 f2.write("%04d-%02d-%02d %s\n" % (t.tm_year, t.tm_mon, t.tm_mday, m.group(3)))
210 else:
211 if re.match(r'Signed-off-by', line):
212 continue
213 f2.write(" " + line.strip() + "\n")
215 f1.close()
216 f2.close()
219 def run(self):
220 if not os.path.exists("build"):
221 os.mkdir("build")
223 if os.path.exists(".git"):
224 try:
225 self.gen_rpm_spec()
226 self.gen_authors()
227 self.gen_changelog()
229 sdist.run(self)
231 finally:
232 files = ["libvirt-python.spec",
233 "AUTHORS",
234 "ChangeLog"]
235 for f in files:
236 if os.path.exists(f):
237 os.unlink(f)
238 else:
239 sdist.run(self)
241 class my_rpm(Command):
242 user_options = []
244 description = "Build src and noarch rpms."
246 def initialize_options(self):
247 pass
249 def finalize_options(self):
250 pass
252 def run(self):
254 Run sdist, then 'rpmbuild' the tar.gz
257 self.run_command('sdist')
258 self.spawn(["/usr/bin/rpmbuild", "-ta", "--clean",
259 "dist/libvirt-python-%s.tar.gz" % self.distribution.get_version()])
261 class my_test(Command):
262 user_options = [
263 ('build-base=', 'b',
264 "base directory for build library"),
265 ('build-platlib=', None,
266 "build directory for platform-specific distributions"),
267 ('plat-name=', 'p',
268 "platform name to build for, if supported "
269 "(default: %s)" % get_platform()),
272 description = "Run test suite."
274 def initialize_options(self):
275 self.build_base = 'build'
276 self.build_platlib = None
277 self.plat_name = None
279 def finalize_options(self):
280 if self.plat_name is None:
281 self.plat_name = get_platform()
283 plat_specifier = ".%s-%s" % (self.plat_name, sys.version[0:3])
285 if hasattr(sys, 'gettotalrefcount'):
286 plat_specifier += '-pydebug'
288 if self.build_platlib is None:
289 self.build_platlib = os.path.join(self.build_base,
290 'lib' + plat_specifier)
292 def find_nosetests_path(self):
293 binaries = [
294 "nosetests-%d.%d" % (sys.version_info[0],
295 sys.version_info[1]),
296 "nosetests-%d" % (sys.version_info[0]),
297 "nosetests",
300 for binary in binaries:
301 path = distutils.spawn.find_executable(binary)
302 if path is not None:
303 return path
305 raise Exception("Cannot find any nosetests binary")
307 def run(self):
309 Run test suite
312 apis = get_api_xml_files()
314 if "PYTHONPATH" in os.environ:
315 os.environ["PYTHONPATH"] = self.build_platlib + ":" + os.environ["PYTHONPATH"]
316 else:
317 os.environ["PYTHONPATH"] = self.build_platlib
318 self.spawn([sys.executable, "sanitytest.py", self.build_platlib, apis[0]])
319 nose = self.find_nosetests_path()
320 self.spawn([sys.executable, nose])
323 class my_clean(clean):
324 def run(self):
325 clean.run(self)
327 if os.path.exists("build"):
328 remove_tree("build")
331 ##################
332 # Invoke setup() #
333 ##################
335 _c_modules, _py_modules = get_module_lists()
337 setup(name = 'libvirt-python',
338 version = '3.9.0',
339 url = 'http://www.libvirt.org',
340 maintainer = 'Libvirt Maintainers',
341 maintainer_email = 'libvir-list@redhat.com',
342 description = 'The libvirt virtualization API python binding',
343 long_description =
344 '''The libvirt-python package provides a module that permits applications
345 written in the Python programming language to call the interface
346 supplied by the libvirt library, to manage the virtualization capabilities
347 of recent versions of Linux (and other OSes).''',
348 license = 'LGPLv2+',
349 ext_modules = _c_modules,
350 py_modules = _py_modules,
351 package_dir = {
352 '': 'build'
354 cmdclass = {
355 'build': my_build,
356 'clean': my_clean,
357 'sdist': my_sdist,
358 'rpm': my_rpm,
359 'test': my_test
361 classifiers = [
362 "Development Status :: 5 - Production/Stable",
363 "Intended Audience :: Developers",
364 "License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)",
365 "Programming Language :: Python",
366 "Programming Language :: Python :: 2",
367 "Programming Language :: Python :: 3",