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
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"):
29 def get_pkgcfg(do_fail
=True):
32 _pkgcfg
= os
.getenv('PKG_CONFIG')
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")
39 def check_minimum_libvirt_version():
42 "--atleast-version=%s" % MIN_LIBVIRT
,
45 def have_libvirt_lxc():
48 "--atleast-version=%s" % MIN_LIBVIRT_LXC
,
51 except DistutilsExecError
:
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
))
68 if line
is None or line
== "":
70 raise Exception("Cannot determine '%s' from libvirt pkg-config file" % " ".join(args
))
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():
92 Determine which modules we are actually building, and all their
95 if get_pkgcfg(do_fail
=False) is None:
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
144 class my_build(build
):
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')
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
):
166 sdist
.initialize_options(self
)
168 def finalize_options(self
):
169 if self
.snapshot
is not None:
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')
178 .replace('@PY_VERSION@', self
.distribution
.get_version())
179 .replace('@C_VERSION@', MIN_LIBVIRT
))
183 def gen_authors(self
):
184 f
= os
.popen("git log --pretty=format:'%aN <%aE>'")
187 line
= " " + line
.strip()
188 if line
not in authors
:
191 authors
.sort(key
=str.lower
)
193 f1
= open('AUTHORS.in', 'r')
194 f2
= open('AUTHORS', 'w')
196 f2
.write(line
.replace('@AUTHORS@', "\n".join(authors
)))
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')
206 m
= re
.match(r
'([a-f0-9]+):(\d+)\s(.*)', line
)
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)))
211 if re
.match(r
'Signed-off-by', line
):
213 f2
.write(" " + line
.strip() + "\n")
220 if not os
.path
.exists("build"):
223 if os
.path
.exists(".git"):
232 files
= ["libvirt-python.spec",
236 if os
.path
.exists(f
):
241 class my_rpm(Command
):
244 description
= "Build src and noarch rpms."
246 def initialize_options(self
):
249 def finalize_options(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
):
264 "base directory for build library"),
265 ('build-platlib=', None,
266 "build directory for platform-specific distributions"),
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
):
294 "nosetests-%d.%d" % (sys
.version_info
[0],
295 sys
.version_info
[1]),
296 "nosetests-%d" % (sys
.version_info
[0]),
300 for binary
in binaries
:
301 path
= distutils
.spawn
.find_executable(binary
)
305 raise Exception("Cannot find any nosetests binary")
312 apis
= get_api_xml_files()
314 if "PYTHONPATH" in os
.environ
:
315 os
.environ
["PYTHONPATH"] = self
.build_platlib
+ ":" + os
.environ
["PYTHONPATH"]
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
):
327 if os
.path
.exists("build"):
335 _c_modules
, _py_modules
= get_module_lists()
337 setup(name
= 'libvirt-python',
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',
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).''',
349 ext_modules
= _c_modules
,
350 py_modules
= _py_modules
,
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",