diff options
Diffstat (limited to 'scripts/dtc/pylibfdt/setup.py')
-rwxr-xr-x | scripts/dtc/pylibfdt/setup.py | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/scripts/dtc/pylibfdt/setup.py b/scripts/dtc/pylibfdt/setup.py new file mode 100755 index 00000000000..c6fe5a6a446 --- /dev/null +++ b/scripts/dtc/pylibfdt/setup.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) + +""" +setup.py file for SWIG libfdt +Copyright (C) 2017 Google, Inc. +Written by Simon Glass <sjg@chromium.org> + +This script is modified from the upstream version, to fit in with the U-Boot +build system. + +Files to be built into the extension are provided in SOURCES +C flags to use are provided in CPPFLAGS +Object file directory is provided in OBJDIR +Version is provided in VERSION + +If these variables are not given they are parsed from the Makefiles. This +allows this script to be run stand-alone, e.g.: + + ./pylibfdt/setup.py install [--prefix=...] +""" + +from setuptools import setup, Extension +from setuptools.command.build_py import build_py as _build_py +import os +import re +import sys + +try: + from setuptools import sic +except ImportError: + pass + +srcdir = os.path.dirname(__file__) + +with open(os.path.join(srcdir, "../README"), "r") as fh: + long_description = fh.read() + +# Decodes a Makefile assignment line into key and value (and plus for +=) +RE_KEY_VALUE = re.compile(r'(?P<key>\w+) *(?P<plus>[+])?= *(?P<value>.*)$') + +def get_top_builddir(): + if '--top-builddir' in sys.argv: + index = sys.argv.index('--top-builddir') + sys.argv.pop(index) + return sys.argv.pop(index) + else: + return os.path.join(srcdir, '..') + +top_builddir = get_top_builddir() + +def ParseMakefile(fname): + """Parse a Makefile to obtain its variables. + + This collects variable assigments of the form: + + VAR = value + VAR += more + + It does not pick out := assignments, as these are not needed here. It does + handle line continuation. + + Returns a dict: + key: Variable name (e.g. 'VAR') + value: Variable value (e.g. 'value more') + """ + makevars = {} + with open(fname) as fd: + prev_text = '' # Continuation text from previous line(s) + for line in fd.read().splitlines(): + if line and line[-1] == '\\': # Deal with line continuation + prev_text += line[:-1] + continue + elif prev_text: + line = prev_text + line + prev_text = '' # Continuation is now used up + m = RE_KEY_VALUE.match(line) + if m: + value = m.group('value') or '' + key = m.group('key') + + # Appending to a variable inserts a space beforehand + if 'plus' in m.groupdict() and key in makevars: + makevars[key] += ' ' + value + else: + makevars[key] = value + return makevars + +def GetEnvFromMakefiles(): + """Scan the Makefiles to obtain the settings we need. + + This assumes that this script is being run from the top-level directory, + not the pylibfdt directory. + + Returns: + Tuple with: + List of swig options + Version string + List of files to build + List of extra C preprocessor flags needed + Object directory to use (always '') + """ + basedir = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0]))) + swig_opts = ['-I%s' % basedir] + makevars = ParseMakefile(os.path.join(basedir, 'Makefile')) + version = '%s.%s.%s' % (makevars['VERSION'], makevars['PATCHLEVEL'], + makevars['SUBLEVEL']) + makevars = ParseMakefile(os.path.join(basedir, 'libfdt', 'Makefile.libfdt')) + files = makevars['LIBFDT_SRCS'].split() + files = [os.path.join(basedir, 'libfdt', fname) for fname in files] + files.append('libfdt.i') + cflags = ['-I%s' % basedir, '-I%s/libfdt' % basedir] + objdir = '' + return swig_opts, version, files, cflags, objdir + + +progname = sys.argv[0] +files = os.environ.get('SOURCES', '').split() +cflags = os.environ.get('CPPFLAGS', '').split() +objdir = os.environ.get('OBJDIR') +try: + version = sic(os.environ.get('VERSION')) +except: + version = os.environ.get('VERSION') +swig_opts = os.environ.get('SWIG_OPTS', '').split() + +# If we were called directly rather than through our Makefile (which is often +# the case with Python module installation), read the settings from the +# Makefile. +if not all((swig_opts, version, files, cflags, objdir)): + swig_opts, version, files, cflags, objdir = GetEnvFromMakefiles() + +libfdt_module = Extension( + '_libfdt', + sources=files, + include_dirs=[os.path.join(srcdir, 'libfdt')], + library_dirs=[os.path.join(top_builddir, 'libfdt')], + swig_opts=swig_opts, +) + +class build_py(_build_py): + def run(self): + self.run_command("build_ext") + return super().run() + +setup( + name='libfdt', + version=version, + cmdclass = {'build_py' : build_py}, + author='Simon Glass', + author_email='sjg@chromium.org', + description='Python binding for libfdt', + ext_modules=[libfdt_module], + package_dir={'': objdir}, + py_modules=['libfdt'], + + long_description=long_description, + long_description_content_type="text/plain", + url="https://git.kernel.org/pub/scm/utils/dtc/dtc.git", + license="BSD", + license_files=["GPL", "BSD-2-Clause"], + + classifiers=[ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: BSD License", + "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)", + "Operating System :: OS Independent", + ], + +) |