blob: 9abdb57595adb6b10ef5ff503eaaa06e880af3d3 [file] [log] [blame]
Simon Glass7ccca832019-10-31 07:42:59 -06001#!/usr/bin/env python3
Simon Glass85feff32022-07-30 20:57:11 -06002# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
Simon Glassa13d9022017-05-27 07:38:11 -06003
4"""
5setup.py file for SWIG libfdt
6Copyright (C) 2017 Google, Inc.
7Written by Simon Glass <sjg@chromium.org>
8
Simon Glass85feff32022-07-30 20:57:11 -06009This script is modified from the upstream version, to fit in with the U-Boot
10build system.
Simon Glassa13d9022017-05-27 07:38:11 -060011
12Files to be built into the extension are provided in SOURCES
13C flags to use are provided in CPPFLAGS
14Object file directory is provided in OBJDIR
15Version is provided in VERSION
16
17If these variables are not given they are parsed from the Makefiles. This
18allows this script to be run stand-alone, e.g.:
19
20 ./pylibfdt/setup.py install [--prefix=...]
21"""
22
Simon Glass85feff32022-07-30 20:57:11 -060023from setuptools import setup, Extension
24from setuptools.command.build_py import build_py as _build_py
Marek Vasut9675f802022-12-15 23:37:59 +010025from setuptools.extern.packaging import version
Simon Glassa13d9022017-05-27 07:38:11 -060026import os
27import re
28import sys
29
Marek Vasut9675f802022-12-15 23:37:59 +010030# Disable version normalization
31version.Version = version.LegacyVersion
32
Simon Glass85feff32022-07-30 20:57:11 -060033srcdir = os.path.dirname(__file__)
34
35with open(os.path.join(srcdir, "../README"), "r") as fh:
36 long_description = fh.read()
37
Simon Glassa13d9022017-05-27 07:38:11 -060038# Decodes a Makefile assignment line into key and value (and plus for +=)
39RE_KEY_VALUE = re.compile('(?P<key>\w+) *(?P<plus>[+])?= *(?P<value>.*)$')
40
Simon Glass85feff32022-07-30 20:57:11 -060041def get_top_builddir():
42 if '--top-builddir' in sys.argv:
43 index = sys.argv.index('--top-builddir')
44 sys.argv.pop(index)
45 return sys.argv.pop(index)
46 else:
47 return os.path.join(srcdir, '..')
48
49top_builddir = get_top_builddir()
Simon Glassa13d9022017-05-27 07:38:11 -060050
51def ParseMakefile(fname):
52 """Parse a Makefile to obtain its variables.
53
54 This collects variable assigments of the form:
55
56 VAR = value
57 VAR += more
58
59 It does not pick out := assignments, as these are not needed here. It does
60 handle line continuation.
61
62 Returns a dict:
63 key: Variable name (e.g. 'VAR')
64 value: Variable value (e.g. 'value more')
65 """
66 makevars = {}
67 with open(fname) as fd:
68 prev_text = '' # Continuation text from previous line(s)
69 for line in fd.read().splitlines():
70 if line and line[-1] == '\\': # Deal with line continuation
71 prev_text += line[:-1]
72 continue
73 elif prev_text:
74 line = prev_text + line
75 prev_text = '' # Continuation is now used up
76 m = RE_KEY_VALUE.match(line)
77 if m:
78 value = m.group('value') or ''
79 key = m.group('key')
80
81 # Appending to a variable inserts a space beforehand
82 if 'plus' in m.groupdict() and key in makevars:
83 makevars[key] += ' ' + value
84 else:
85 makevars[key] = value
86 return makevars
87
88def GetEnvFromMakefiles():
89 """Scan the Makefiles to obtain the settings we need.
90
91 This assumes that this script is being run from the top-level directory,
92 not the pylibfdt directory.
93
94 Returns:
95 Tuple with:
96 List of swig options
97 Version string
98 List of files to build
99 List of extra C preprocessor flags needed
100 Object directory to use (always '')
101 """
102 basedir = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0])))
103 swig_opts = ['-I%s' % basedir]
104 makevars = ParseMakefile(os.path.join(basedir, 'Makefile'))
105 version = '%s.%s.%s' % (makevars['VERSION'], makevars['PATCHLEVEL'],
106 makevars['SUBLEVEL'])
107 makevars = ParseMakefile(os.path.join(basedir, 'libfdt', 'Makefile.libfdt'))
108 files = makevars['LIBFDT_SRCS'].split()
109 files = [os.path.join(basedir, 'libfdt', fname) for fname in files]
Simon Glass85feff32022-07-30 20:57:11 -0600110 files.append('libfdt.i')
Simon Glassa13d9022017-05-27 07:38:11 -0600111 cflags = ['-I%s' % basedir, '-I%s/libfdt' % basedir]
112 objdir = ''
113 return swig_opts, version, files, cflags, objdir
114
115
116progname = sys.argv[0]
117files = os.environ.get('SOURCES', '').split()
118cflags = os.environ.get('CPPFLAGS', '').split()
119objdir = os.environ.get('OBJDIR')
120version = os.environ.get('VERSION')
Simon Glass3d0b9992017-05-27 07:38:16 -0600121swig_opts = os.environ.get('SWIG_OPTS', '').split()
Simon Glassa13d9022017-05-27 07:38:11 -0600122
123# If we were called directly rather than through our Makefile (which is often
124# the case with Python module installation), read the settings from the
125# Makefile.
Simon Glass3d0b9992017-05-27 07:38:16 -0600126if not all((swig_opts, version, files, cflags, objdir)):
Simon Glassa13d9022017-05-27 07:38:11 -0600127 swig_opts, version, files, cflags, objdir = GetEnvFromMakefiles()
128
129libfdt_module = Extension(
130 '_libfdt',
Simon Glass85feff32022-07-30 20:57:11 -0600131 sources=files,
132 include_dirs=[os.path.join(srcdir, 'libfdt')],
133 library_dirs=[os.path.join(top_builddir, 'libfdt')],
134 swig_opts=swig_opts,
Simon Glassa13d9022017-05-27 07:38:11 -0600135)
136
Simon Glass85feff32022-07-30 20:57:11 -0600137class build_py(_build_py):
138 def run(self):
139 self.run_command("build_ext")
140 return super().run()
141
Simon Glassa13d9022017-05-27 07:38:11 -0600142setup(
143 name='libfdt',
Simon Glass85feff32022-07-30 20:57:11 -0600144 version=version,
145 cmdclass = {'build_py' : build_py},
146 author='Simon Glass',
147 author_email='sjg@chromium.org',
Simon Glassa13d9022017-05-27 07:38:11 -0600148 description='Python binding for libfdt',
149 ext_modules=[libfdt_module],
150 package_dir={'': objdir},
Simon Glass85feff32022-07-30 20:57:11 -0600151 py_modules=['libfdt'],
152
153 long_description=long_description,
154 long_description_content_type="text/plain",
155 url="https://git.kernel.org/pub/scm/utils/dtc/dtc.git",
156 license="BSD",
157 license_files=["GPL", "BSD-2-Clause"],
158
159 classifiers=[
160 "Programming Language :: Python :: 3",
161 "License :: OSI Approved :: BSD License",
162 "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)",
163 "Operating System :: OS Independent",
164 ],
165
Simon Glassa13d9022017-05-27 07:38:11 -0600166)