1
0
mirror of https://gitlab.com/libvirt/libvirt-python.git synced 2024-10-26 07:55:06 +03:00
libvirt-python/setup.py
Michal Privoznik a6b8929083 generator.py: Drop build/ prefix from #include
When -Ibuild flag is passed to compiler then build/ can be dropped
from includes. This is safe to do, because the prefix is only on
local includes (#include "") not system ones (#include <>).

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2024-05-02 12:50:16 +00:00

285 lines
8.7 KiB
Python
Executable File

#!/usr/bin/env python3
import sys
import re
import shutil
import subprocess
import time
from pathlib import Path
from setuptools import setup, Extension
from setuptools.command.build_ext import build_ext
from setuptools.command.build_py import build_py
from setuptools.command.sdist import sdist
def getVersion():
with open("VERSION") as f:
return f.read().strip()
def check_pkgcfg():
try:
proc = subprocess.run(["pkg-config", "--version"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
if proc.returncode != 0:
print("pkg-config binary does not appear to be functional")
sys.exit(1)
except FileNotFoundError:
print("pkg-config binary is required to compile libvirt-python")
sys.exit(1)
def check_minimum_libvirt_version():
subprocess.check_call(["pkg-config",
"--print-errors",
f"--atleast-version={MIN_LIBVIRT}",
"libvirt"])
def have_libvirt_lxc():
proc = subprocess.run(["pkg-config",
f"--atleast-version={MIN_LIBVIRT_LXC}",
"libvirt"])
if proc.returncode == 0:
return True
return False
def get_pkgconfig_data(args, mod, required=True):
"""Run pkg-config to and return content associated with it"""
cmd = ["pkg-config"] + args + [mod]
output = subprocess.check_output(cmd, universal_newlines=True)
for line in output.splitlines():
if line == "":
if required:
args_str = " ".join(args)
raise Exception(f"Cannot determine '{args_str}' from "
"libvirt pkg-config file")
line = ""
return line.strip()
def get_api_xml_files():
"""Check with pkg-config that libvirt is present and extract
the API XML file paths we need from it"""
libvirt_api = get_pkgconfig_data(["--variable", "libvirt_api"], "libvirt")
offset = libvirt_api.index("-api.xml")
libvirt_qemu_api = libvirt_api[0:offset] + "-qemu-api.xml"
offset = libvirt_api.index("-api.xml")
libvirt_lxc_api = libvirt_api[0:offset] + "-lxc-api.xml"
return (libvirt_api, libvirt_qemu_api, libvirt_lxc_api)
def get_module_lists():
"""
Determine which modules we are actually building, and all their
required config
"""
c_modules = []
py_modules = []
ldflags = get_pkgconfig_data(["--libs-only-L"], "libvirt", False).split()
cflags = get_pkgconfig_data(["--cflags"], "libvirt", False).split()
cflags += ["-Ibuild"]
cflags += ["-Wp,-DPy_LIMITED_API=0x03060000"]
module = Extension("libvirtmod",
sources=[
"libvirt-override.c",
"build/libvirt.c",
"typewrappers.c",
"libvirt-utils.c"
],
libraries=["virt"],
include_dirs=["."])
module.extra_compile_args.extend(cflags)
module.extra_link_args.extend(ldflags)
c_modules.append(module)
py_modules.append("libvirt")
moduleqemu = Extension("libvirtmod_qemu",
sources=[
"libvirt-qemu-override.c",
"build/libvirt-qemu.c",
"typewrappers.c",
"libvirt-utils.c"
],
libraries=["virt-qemu", "virt"],
include_dirs=["."])
moduleqemu.extra_compile_args.extend(cflags)
moduleqemu.extra_link_args.extend(ldflags)
c_modules.append(moduleqemu)
py_modules.append("libvirt_qemu")
if have_libvirt_lxc():
modulelxc = Extension("libvirtmod_lxc",
sources=[
"libvirt-lxc-override.c",
"build/libvirt-lxc.c",
"typewrappers.c",
"libvirt-utils.c"
],
libraries=["virt-lxc", "virt"],
include_dirs=["."])
modulelxc.extra_compile_args.extend(cflags)
modulelxc.extra_link_args.extend(ldflags)
c_modules.append(modulelxc)
py_modules.append("libvirt_lxc")
py_modules.append("libvirtaio")
return c_modules, py_modules
###################
# Custom commands #
###################
class my_build_ext(build_ext):
def run(self):
check_minimum_libvirt_version()
apis = get_api_xml_files()
subprocess.check_call([sys.executable, "generator.py", "libvirt", apis[0], "c"])
subprocess.check_call([sys.executable, "generator.py", "libvirt-qemu", apis[1], "c"])
if have_libvirt_lxc():
subprocess.check_call([sys.executable, "generator.py", "libvirt-lxc", apis[2], "c"])
build_ext.run(self)
class my_build_py(build_py):
def run(self):
check_minimum_libvirt_version()
apis = get_api_xml_files()
subprocess.check_call([sys.executable, "generator.py", "libvirt", apis[0], "py"])
subprocess.check_call([sys.executable, "generator.py", "libvirt-qemu", apis[1], "py"])
if have_libvirt_lxc():
subprocess.check_call([sys.executable, "generator.py", "libvirt-lxc", apis[2], "py"])
shutil.copy("libvirtaio.py", "build")
build_py.run(self)
class my_sdist(sdist):
user_options = sdist.user_options
description = "Update libvirt-python.spec; build sdist-tarball."
def initialize_options(self):
self.snapshot = None
sdist.initialize_options(self)
def finalize_options(self):
if self.snapshot is not None:
self.snapshot = 1
sdist.finalize_options(self)
@staticmethod
def _gen_from_in(file_in, file_out, replace_pattern, replace):
with open(file_in) as f_in, open(file_out, "w") as f_out:
for line in f_in:
f_out.write(line.replace(replace_pattern, replace))
def gen_rpm_spec(self):
return self._gen_from_in("libvirt-python.spec.in",
"libvirt-python.spec",
"@VERSION@",
getVersion())
def gen_authors(self):
cmd = ["git", "log", "--pretty=format:%aN <%aE>"]
output = subprocess.check_output(cmd, universal_newlines=True)
git_authors = {line.strip() for line in output.splitlines()}
authors = sorted(git_authors, key=str.lower)
authors = [" " + author for author in authors]
self._gen_from_in("AUTHORS.in",
"AUTHORS",
"@AUTHORS@",
"\n".join(authors))
def gen_changelog(self):
cmd = ["git", "log", "--pretty=format:%H:%ct %an <%ae>%n%n%s%n%b%n"]
with open("ChangeLog", "w") as f_out:
output = subprocess.check_output(cmd, universal_newlines=True)
for line in output.splitlines():
m = re.match(r"([a-f0-9]+):(\d+)\s(.*)", line)
if m:
t = time.gmtime(int(m.group(2)))
fmt = "{: 04d}-{: 02d}-{: 02d} {}\n"
f_out.write(fmt.format(t.tm_year, t.tm_mon, t.tm_mday, m.group(3)))
else:
if re.match(r"Signed-off-by", line):
continue
f_out.write(" " + line.strip() + "\n")
def run(self):
if Path(".git").exists():
try:
self.gen_rpm_spec()
self.gen_authors()
self.gen_changelog()
sdist.run(self)
finally:
files = [
"libvirt-python.spec",
"AUTHORS",
"ChangeLog"
]
for f in files:
try:
Path(f).unlink()
except FileNotFoundError:
pass
else:
sdist.run(self)
##################
# Invoke setup() #
##################
if sys.version_info < (3, 6):
print("libvirt-python requires Python >= 3.6 to build")
sys.exit(1)
MIN_LIBVIRT = "0.9.11"
MIN_LIBVIRT_LXC = "1.0.2"
# Hack to stop "pip install" failing with error
# about missing "build" dir.
Path("build").mkdir(exist_ok=True)
check_pkgcfg()
_c_modules, _py_modules = get_module_lists()
setup(
ext_modules=_c_modules,
py_modules=_py_modules,
package_dir={
'': 'build'
},
cmdclass={
"build_ext": my_build_ext,
"build_py": my_build_py,
"sdist": my_sdist,
},
)