Release of libvirt-python-3.0.0
[libvirt-python/ericb.git] / setup.py
blobda773dacbddfa7d8cc6e41f363379d7f7923bd30
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 time
19 MIN_LIBVIRT = "0.9.11"
20 MIN_LIBVIRT_LXC = "1.0.2"
22 # Hack to stop 'pip install' failing with error
23 # about missing 'build' dir.
24 if not os.path.exists("build"):
25 os.mkdir("build")
27 _pkgcfg = -1
28 def get_pkgcfg(do_fail=True):
29 global _pkgcfg
30 if _pkgcfg == -1:
31 _pkgcfg = os.getenv('PKG_CONFIG')
32 if _pkgcfg is None:
33 _pkgcfg = distutils.spawn.find_executable("pkg-config")
34 if _pkgcfg is None and do_fail:
35 raise Exception("pkg-config binary is required to compile libvirt-python")
36 return _pkgcfg
38 def check_minimum_libvirt_version():
39 spawn([get_pkgcfg(),
40 "--print-errors",
41 "--atleast-version=%s" % MIN_LIBVIRT,
42 "libvirt"])
44 def have_libvirt_lxc():
45 try:
46 spawn([get_pkgcfg(),
47 "--atleast-version=%s" % MIN_LIBVIRT_LXC,
48 "libvirt"])
49 return True
50 except DistutilsExecError:
51 return False
53 def get_pkgconfig_data(args, mod, required=True):
54 """Run pkg-config to and return content associated with it"""
55 f = os.popen("%s %s %s" % (get_pkgcfg(), " ".join(args), mod))
57 line = f.readline()
58 if line is not None:
59 line = line.strip()
61 if line is None or line == "":
62 if required:
63 raise Exception("Cannot determine '%s' from libvirt pkg-config file" % " ".join(args))
64 else:
65 return ""
67 return line
69 def get_api_xml_files():
70 """Check with pkg-config that libvirt is present and extract
71 the API XML file paths we need from it"""
73 libvirt_api = get_pkgconfig_data(["--variable", "libvirt_api"], "libvirt")
75 offset = libvirt_api.index("-api.xml")
76 libvirt_qemu_api = libvirt_api[0:offset] + "-qemu-api.xml"
78 offset = libvirt_api.index("-api.xml")
79 libvirt_lxc_api = libvirt_api[0:offset] + "-lxc-api.xml"
81 return (libvirt_api, libvirt_qemu_api, libvirt_lxc_api)
83 def get_module_lists():
84 """
85 Determine which modules we are actually building, and all their
86 required config
87 """
88 if get_pkgcfg(do_fail=False) is None:
89 return [], []
91 c_modules = []
92 py_modules = []
93 ldflags = get_pkgconfig_data(["--libs-only-L"], "libvirt", False).split()
94 cflags = get_pkgconfig_data(["--cflags"], "libvirt", False).split()
96 module = Extension('libvirtmod',
97 sources = ['libvirt-override.c', 'build/libvirt.c', 'typewrappers.c', 'libvirt-utils.c'],
98 libraries = [ "virt" ],
99 include_dirs = [ "." ])
100 module.extra_compile_args.extend(cflags)
101 module.extra_link_args.extend(ldflags)
103 c_modules.append(module)
104 py_modules.append("libvirt")
106 moduleqemu = Extension('libvirtmod_qemu',
107 sources = ['libvirt-qemu-override.c', 'build/libvirt-qemu.c', 'typewrappers.c', 'libvirt-utils.c'],
108 libraries = [ "virt-qemu" ],
109 include_dirs = [ "." ])
110 moduleqemu.extra_compile_args.extend(cflags)
111 moduleqemu.extra_link_args.extend(ldflags)
113 c_modules.append(moduleqemu)
114 py_modules.append("libvirt_qemu")
116 if have_libvirt_lxc():
117 modulelxc = Extension('libvirtmod_lxc',
118 sources = ['libvirt-lxc-override.c', 'build/libvirt-lxc.c', 'typewrappers.c', 'libvirt-utils.c'],
119 libraries = [ "virt-lxc" ],
120 include_dirs = [ "." ])
121 modulelxc.extra_compile_args.extend(cflags)
122 modulelxc.extra_link_args.extend(ldflags)
124 c_modules.append(modulelxc)
125 py_modules.append("libvirt_lxc")
127 return c_modules, py_modules
130 ###################
131 # Custom commands #
132 ###################
134 class my_build(build):
136 def run(self):
137 check_minimum_libvirt_version()
138 apis = get_api_xml_files()
140 self.spawn([sys.executable, "generator.py", "libvirt", apis[0]])
141 self.spawn([sys.executable, "generator.py", "libvirt-qemu", apis[1]])
142 if have_libvirt_lxc():
143 self.spawn([sys.executable, "generator.py", "libvirt-lxc", apis[2]])
145 build.run(self)
147 class my_sdist(sdist):
148 user_options = sdist.user_options
150 description = "Update libvirt-python.spec; build sdist-tarball."
152 def initialize_options(self):
153 self.snapshot = None
154 sdist.initialize_options(self)
156 def finalize_options(self):
157 if self.snapshot is not None:
158 self.snapshot = 1
159 sdist.finalize_options(self)
161 def gen_rpm_spec(self):
162 f1 = open('libvirt-python.spec.in', 'r')
163 f2 = open('libvirt-python.spec', 'w')
164 for line in f1:
165 f2.write(line
166 .replace('@PY_VERSION@', self.distribution.get_version())
167 .replace('@C_VERSION@', MIN_LIBVIRT))
168 f1.close()
169 f2.close()
171 def gen_authors(self):
172 f = os.popen("git log --pretty=format:'%aN <%aE>'")
173 authors = []
174 for line in f:
175 line = " " + line.strip()
176 if line not in authors:
177 authors.append(line)
179 authors.sort(key=str.lower)
181 f1 = open('AUTHORS.in', 'r')
182 f2 = open('AUTHORS', 'w')
183 for line in f1:
184 f2.write(line.replace('@AUTHORS@', "\n".join(authors)))
185 f1.close()
186 f2.close()
189 def gen_changelog(self):
190 f1 = os.popen("git log '--pretty=format:%H:%ct %an <%ae>%n%n%s%n%b%n'")
191 f2 = open("ChangeLog", 'w')
193 for line in f1:
194 m = re.match(r'([a-f0-9]+):(\d+)\s(.*)', line)
195 if m:
196 t = time.gmtime(int(m.group(2)))
197 f2.write("%04d-%02d-%02d %s\n" % (t.tm_year, t.tm_mon, t.tm_mday, m.group(3)))
198 else:
199 if re.match(r'Signed-off-by', line):
200 continue
201 f2.write(" " + line.strip() + "\n")
203 f1.close()
204 f2.close()
207 def run(self):
208 if not os.path.exists("build"):
209 os.mkdir("build")
211 if os.path.exists(".git"):
212 try:
213 self.gen_rpm_spec()
214 self.gen_authors()
215 self.gen_changelog()
217 sdist.run(self)
219 finally:
220 files = ["libvirt-python.spec",
221 "AUTHORS",
222 "ChangeLog"]
223 for f in files:
224 if os.path.exists(f):
225 os.unlink(f)
226 else:
227 sdist.run(self)
229 class my_rpm(Command):
230 user_options = []
232 description = "Build src and noarch rpms."
234 def initialize_options(self):
235 pass
237 def finalize_options(self):
238 pass
240 def run(self):
242 Run sdist, then 'rpmbuild' the tar.gz
245 self.run_command('sdist')
246 self.spawn(["/usr/bin/rpmbuild", "-ta", "--clean",
247 "dist/libvirt-python-%s.tar.gz" % self.distribution.get_version()])
249 class my_test(Command):
250 user_options = [
251 ('build-base=', 'b',
252 "base directory for build library"),
253 ('build-platlib=', None,
254 "build directory for platform-specific distributions"),
255 ('plat-name=', 'p',
256 "platform name to build for, if supported "
257 "(default: %s)" % get_platform()),
260 description = "Run test suite."
262 def initialize_options(self):
263 self.build_base = 'build'
264 self.build_platlib = None
265 self.plat_name = None
267 def finalize_options(self):
268 if self.plat_name is None:
269 self.plat_name = get_platform()
271 plat_specifier = ".%s-%s" % (self.plat_name, sys.version[0:3])
273 if hasattr(sys, 'gettotalrefcount'):
274 plat_specifier += '-pydebug'
276 if self.build_platlib is None:
277 self.build_platlib = os.path.join(self.build_base,
278 'lib' + plat_specifier)
280 def find_nosetests_path(self):
281 paths = [
282 "/usr/bin/nosetests-%d.%d" % (sys.version_info[0],
283 sys.version_info[1]),
284 "/usr/bin/nosetests-%d" % (sys.version_info[0]),
285 "/usr/bin/nosetests",
288 for path in paths:
289 if os.path.exists(path):
290 return path
292 raise Exception("Cannot find any nosetests binary")
294 def run(self):
296 Run test suite
299 apis = get_api_xml_files()
301 if "PYTHONPATH" in os.environ:
302 os.environ["PYTHONPATH"] = self.build_platlib + ":" + os.environ["PYTHONPATH"]
303 else:
304 os.environ["PYTHONPATH"] = self.build_platlib
305 self.spawn([sys.executable, "sanitytest.py", self.build_platlib, apis[0]])
306 nose = self.find_nosetests_path()
307 self.spawn([sys.executable, nose])
310 class my_clean(clean):
311 def run(self):
312 clean.run(self)
314 if os.path.exists("build"):
315 remove_tree("build")
318 ##################
319 # Invoke setup() #
320 ##################
322 _c_modules, _py_modules = get_module_lists()
324 setup(name = 'libvirt-python',
325 version = '3.0.0',
326 url = 'http://www.libvirt.org',
327 maintainer = 'Libvirt Maintainers',
328 maintainer_email = 'libvir-list@redhat.com',
329 description = 'The libvirt virtualization API python binding',
330 long_description =
331 '''The libvirt-python package provides a module that permits applications
332 written in the Python programming language to call the interface
333 supplied by the libvirt library, to manage the virtualization capabilities
334 of recent versions of Linux (and other OSes).''',
335 license = 'LGPLv2+',
336 ext_modules = _c_modules,
337 py_modules = _py_modules,
338 package_dir = {
339 '': 'build'
341 cmdclass = {
342 'build': my_build,
343 'clean': my_clean,
344 'sdist': my_sdist,
345 'rpm': my_rpm,
346 'test': my_test
348 classifiers = [
349 "Development Status :: 5 - Production/Stable",
350 "Intended Audience :: Developers",
351 "License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)",
352 "Programming Language :: Python",
353 "Programming Language :: Python :: 2",
354 "Programming Language :: Python :: 3",