drgn/setup.py
Omar Sandoval 6a13d74c0c libdrgn: build with bundled elfutils
Now that we have the bundled version of elfutils, build it from libdrgn
and link to it. We can also get rid of the elfutils version checks from
the libdrgn code.
2019-09-19 11:07:12 -07:00

112 lines
3.6 KiB
Python
Executable File

#!/usr/bin/env python3
import contextlib
import re
import os.path
from distutils.dir_util import mkpath
from distutils.file_util import copy_file
from setuptools import setup, find_packages
from setuptools.extension import Extension
from setuptools.command.build_ext import build_ext
import subprocess
import sys
class my_build_ext(build_ext):
user_options = [
('inplace', 'i', 'put compiled extension into the source directory'),
('parallel=', 'j', 'number of parallel build jobs'),
]
boolean_options = ['inplace']
help_options = []
def _run_autoreconf(self, dir):
makefile_in = os.path.join(dir, 'Makefile.in')
if not os.path.exists(makefile_in):
try:
subprocess.check_call(['autoreconf', '-i', dir])
except Exception:
with contextlib.suppress(FileNotFoundError):
os.remove(makefile_in)
raise
def _run_configure(self):
mkpath(self.build_temp)
makefile = os.path.join(self.build_temp, 'Makefile')
if not os.path.exists(makefile):
args = [
os.path.relpath('libdrgn/configure', self.build_temp),
'--disable-static', '--with-python=' + sys.executable,
]
try:
subprocess.check_call(args, cwd=self.build_temp)
except Exception:
with contextlib.suppress(FileNotFoundError):
os.remove(makefile)
raise
def _run_make(self):
args = ['make', '-C', self.build_temp]
if self.parallel:
args.append(f'-j{self.parallel}')
subprocess.check_call(args)
def run(self):
self._run_autoreconf('libdrgn')
self._run_autoreconf('libdrgn/elfutils')
self._run_configure()
self._run_make()
so = os.path.join(self.build_temp, '.libs/_drgn.so')
if self.inplace:
copy_file(so, self.get_ext_fullpath('_drgn'))
self.inplace = 0
build_path = self.get_ext_fullpath('_drgn')
mkpath(os.path.dirname(build_path))
copy_file(so, build_path)
def get_source_files(self):
if os.path.exists('.git'):
args = ['git', 'ls-files', '-z', 'libdrgn']
return [
os.fsdecode(path) for path in
subprocess.check_output(args).split(b'\0') if path
]
else:
# If this is a source distribution, then setuptools will get the
# list of sources that was included in the tarball.
return []
with open('libdrgn/drgn.h', 'r') as f:
drgn_h = f.read()
version_major = re.search('^#define DRGN_VERSION_MAJOR ([0-9])+$', drgn_h,
re.MULTILINE).group(1)
version_minor = re.search('^#define DRGN_VERSION_MINOR ([0-9])+$', drgn_h,
re.MULTILINE).group(1)
version_patch = re.search('^#define DRGN_VERSION_PATCH ([0-9])+$', drgn_h,
re.MULTILINE).group(1)
version = f'{version_major}.{version_minor}.{version_patch}'
setup(
name='drgn',
version=version,
packages=find_packages(exclude=['examples', 'scripts', 'tests']),
# This is here so that setuptools knows that we have an extension; it's
# actually built using autotools/make.
ext_modules=[Extension(name='_drgn', sources=[])],
cmdclass={
'build_ext': my_build_ext,
},
entry_points={
'console_scripts': ['drgn=drgn.internal.cli:main'],
},
author='Omar Sandoval',
author_email='osandov@osandov.com',
description='Scriptable debugger library',
license='GPL-3.0+',
url='https://github.com/osandov/drgn',
)