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()))
182 def gen_authors(self
):
183 f
= os
.popen("git log --pretty=format:'%aN <%aE>'")
186 line
= " " + line
.strip()
187 if line
not in authors
:
190 authors
.sort(key
=str.lower
)
192 f1
= open('AUTHORS.in', 'r')
193 f2
= open('AUTHORS', 'w')
195 f2
.write(line
.replace('@AUTHORS@', "\n".join(authors
)))
200 def gen_changelog(self
):
201 f1
= os
.popen("git log '--pretty=format:%H:%ct %an <%ae>%n%n%s%n%b%n'")
202 f2
= open("ChangeLog", 'w')
205 m
= re
.match(r
'([a-f0-9]+):(\d+)\s(.*)', line
)
207 t
= time
.gmtime(int(m
.group(2)))
208 f2
.write("%04d-%02d-%02d %s\n" % (t
.tm_year
, t
.tm_mon
, t
.tm_mday
, m
.group(3)))
210 if re
.match(r
'Signed-off-by', line
):
212 f2
.write(" " + line
.strip() + "\n")
219 if not os
.path
.exists("build"):
222 if os
.path
.exists(".git"):
231 files
= ["libvirt-python.spec",
235 if os
.path
.exists(f
):
240 class my_rpm(Command
):
243 description
= "Build src and noarch rpms."
245 def initialize_options(self
):
248 def finalize_options(self
):
253 Run sdist, then 'rpmbuild' the tar.gz
256 self
.run_command('sdist')
257 self
.spawn(["/usr/bin/rpmbuild", "-ta", "--clean",
258 "dist/libvirt-python-%s.tar.gz" % self
.distribution
.get_version()])
260 class my_test(Command
):
263 "base directory for build library"),
264 ('build-platlib=', None,
265 "build directory for platform-specific distributions"),
267 "platform name to build for, if supported "
268 "(default: %s)" % get_platform()),
271 description
= "Run test suite."
273 def initialize_options(self
):
274 self
.build_base
= 'build'
275 self
.build_platlib
= None
276 self
.plat_name
= None
278 def finalize_options(self
):
279 if self
.plat_name
is None:
280 self
.plat_name
= get_platform()
282 plat_specifier
= ".%s-%s" % (self
.plat_name
, sys
.version
[0:3])
284 if hasattr(sys
, 'gettotalrefcount'):
285 plat_specifier
+= '-pydebug'
287 if self
.build_platlib
is None:
288 self
.build_platlib
= os
.path
.join(self
.build_base
,
289 'lib' + plat_specifier
)
291 def find_nosetests_path(self
):
293 "nosetests-%d.%d" % (sys
.version_info
[0],
294 sys
.version_info
[1]),
295 "nosetests-%d" % (sys
.version_info
[0]),
299 for binary
in binaries
:
300 path
= distutils
.spawn
.find_executable(binary
)
304 raise Exception("Cannot find any nosetests binary")
311 apis
= get_api_xml_files()
313 if "PYTHONPATH" in os
.environ
:
314 os
.environ
["PYTHONPATH"] = self
.build_platlib
+ ":" + os
.environ
["PYTHONPATH"]
316 os
.environ
["PYTHONPATH"] = self
.build_platlib
317 self
.spawn([sys
.executable
, "sanitytest.py", self
.build_platlib
, apis
[0]])
318 nose
= self
.find_nosetests_path()
319 self
.spawn([sys
.executable
, nose
])
322 class my_clean(clean
):
326 if os
.path
.exists("build"):
334 _c_modules
, _py_modules
= get_module_lists()
336 setup(name
= 'libvirt-python',
338 url
= 'http://www.libvirt.org',
339 maintainer
= 'Libvirt Maintainers',
340 maintainer_email
= 'libvir-list@redhat.com',
341 description
= 'The libvirt virtualization API python binding',
343 '''The libvirt-python package provides a module that permits applications
344 written in the Python programming language to call the interface
345 supplied by the libvirt library, to manage the virtualization capabilities
346 of recent versions of Linux (and other OSes).''',
348 ext_modules
= _c_modules
,
349 py_modules
= _py_modules
,
361 "Development Status :: 5 - Production/Stable",
362 "Intended Audience :: Developers",
363 "License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)",
364 "Programming Language :: Python",
365 "Programming Language :: Python :: 2",
366 "Programming Language :: Python :: 3",