meson: port python bindings to build natively via meson and meson-python
We get full build parallelism and fewer confusing ancient distutils paths. The python wheels build fully standalone, including linking libfdt as a static library. For convenience, when running pip install a meson option is passed that prevents building tools or installing headers/pkgconfig files. meson-python would otherwise include them in the wheel itself, in case they are needed, but this is essentially a bit useless so don't bother. The old setuptools-based build is now redundant and goes away. Signed-off-by: Eli Schwartz <eschwartz@gentoo.org> Message-ID: <20250430152601.43554-3-eschwartz@gentoo.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>main
parent
7ebfcac852
commit
ecb21febfd
12
MANIFEST.in
12
MANIFEST.in
|
@ -1,12 +0,0 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
|
||||
|
||||
global-exclude *
|
||||
include README.md
|
||||
include GPL
|
||||
include BSD-2-Clause
|
||||
include setup.py
|
||||
include pylibfdt/libfdt.i
|
||||
include libfdt/libfdt.h
|
||||
include libfdt/fdt.h
|
||||
include libfdt/libfdt_env.h
|
||||
include VERSION.txt
|
49
Makefile
49
Makefile
|
@ -31,7 +31,6 @@ BISON = bison
|
|||
LEX = flex
|
||||
SWIG = swig
|
||||
PKG_CONFIG ?= pkg-config
|
||||
PYTHON ?= python3
|
||||
|
||||
INSTALL = install
|
||||
INSTALL_PROGRAM = $(INSTALL)
|
||||
|
@ -47,8 +46,6 @@ INCLUDEDIR = $(PREFIX)/include
|
|||
HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
|
||||
sed -e 's/\(cygwin\|msys\).*/\1/')
|
||||
|
||||
NO_PYTHON ?= 0
|
||||
|
||||
NO_VALGRIND := $(shell $(PKG_CONFIG) --exists valgrind; echo $$?)
|
||||
ifeq ($(NO_VALGRIND),1)
|
||||
CPPFLAGS += -DNO_VALGRIND
|
||||
|
@ -158,29 +155,6 @@ SCRIPTS = dtdiff
|
|||
|
||||
all: $(BIN) libfdt
|
||||
|
||||
# We need both Python and swig to build/install pylibfdt.
|
||||
# This builds the given make ${target} if those deps are found.
|
||||
check_python_deps = \
|
||||
if $(PKG_CONFIG) --cflags $(PYTHON) >/dev/null 2>&1; then \
|
||||
if which swig >/dev/null 2>&1; then \
|
||||
can_build=yes; \
|
||||
fi; \
|
||||
fi; \
|
||||
if [ "$${can_build}" = "yes" ]; then \
|
||||
$(MAKE) $${target}; \
|
||||
else \
|
||||
echo "\#\# Skipping pylibfdt (install python dev and swig to build)"; \
|
||||
fi ;
|
||||
|
||||
.PHONY: maybe_pylibfdt
|
||||
maybe_pylibfdt: FORCE
|
||||
target=pylibfdt; $(check_python_deps)
|
||||
|
||||
ifeq ($(NO_PYTHON),0)
|
||||
all: maybe_pylibfdt
|
||||
endif
|
||||
|
||||
|
||||
ifneq ($(DEPTARGETS),)
|
||||
ifneq ($(MAKECMDGOALS),libfdt)
|
||||
-include $(DTC_OBJS:%.o=%.d)
|
||||
|
@ -254,14 +228,6 @@ install-includes:
|
|||
|
||||
install: install-bin install-lib install-includes
|
||||
|
||||
.PHONY: maybe_install_pylibfdt
|
||||
maybe_install_pylibfdt: FORCE
|
||||
target=install_pylibfdt; $(check_python_deps)
|
||||
|
||||
ifeq ($(NO_PYTHON),0)
|
||||
install: maybe_install_pylibfdt
|
||||
endif
|
||||
|
||||
$(VERSION_FILE): Makefile FORCE
|
||||
$(call filechk,version)
|
||||
|
||||
|
@ -287,16 +253,6 @@ dist:
|
|||
gzip -9 > ../dtc-$(dtc_version).tar.gz
|
||||
|
||||
|
||||
#
|
||||
# Rules for pylibfdt
|
||||
#
|
||||
PYLIBFDT_dir = pylibfdt
|
||||
|
||||
include $(PYLIBFDT_dir)/Makefile.pylibfdt
|
||||
|
||||
.PHONY: pylibfdt
|
||||
pylibfdt: $(PYLIBFDT_dir)/_libfdt.so
|
||||
|
||||
#
|
||||
# Release signing and uploading
|
||||
# This is for maintainer convenience, don't try this at home.
|
||||
|
@ -330,9 +286,6 @@ TESTS_BIN += fdtput
|
|||
TESTS_BIN += fdtget
|
||||
TESTS_BIN += fdtdump
|
||||
TESTS_BIN += fdtoverlay
|
||||
ifeq ($(NO_PYTHON),0)
|
||||
TESTS_PYLIBFDT += maybe_pylibfdt
|
||||
endif
|
||||
|
||||
ifneq ($(MAKECMDGOALS),libfdt)
|
||||
include tests/Makefile.tests
|
||||
|
@ -344,7 +297,7 @@ endif
|
|||
STD_CLEANFILES = *~ *.o *.$(SHAREDLIB_EXT) *.d *.a *.i *.s core a.out vgcore.* \
|
||||
*.tab.[ch] *.lex.c *.output
|
||||
|
||||
clean: libfdt_clean pylibfdt_clean tests_clean
|
||||
clean: libfdt_clean tests_clean
|
||||
@$(VECHO) CLEAN
|
||||
rm -f $(STD_CLEANFILES)
|
||||
rm -f $(VERSION_FILE)
|
||||
|
|
|
@ -31,7 +31,7 @@ libfdt = library(
|
|||
version: meson.project_version(),
|
||||
link_args: link_args,
|
||||
link_depends: 'version.lds',
|
||||
install: true,
|
||||
install: get_option('default_library') != 'static' or not wheel_only,
|
||||
)
|
||||
|
||||
libfdt_inc = include_directories('.')
|
||||
|
@ -41,20 +41,22 @@ libfdt_dep = declare_dependency(
|
|||
link_with: libfdt,
|
||||
)
|
||||
|
||||
install_headers(
|
||||
files(
|
||||
'fdt.h',
|
||||
'libfdt.h',
|
||||
'libfdt_env.h',
|
||||
if not wheel_only
|
||||
install_headers(
|
||||
files(
|
||||
'fdt.h',
|
||||
'libfdt.h',
|
||||
'libfdt_env.h',
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
pkgconfig = import('pkgconfig')
|
||||
pkgconfig = import('pkgconfig')
|
||||
|
||||
pkgconfig.generate(
|
||||
libraries: libfdt,
|
||||
version: meson.project_version(),
|
||||
filebase: 'libfdt',
|
||||
name: 'libfdt',
|
||||
description: 'Flat Device Tree manipulation',
|
||||
)
|
||||
pkgconfig.generate(
|
||||
libraries: libfdt,
|
||||
version: meson.project_version(),
|
||||
filebase: 'libfdt',
|
||||
name: 'libfdt',
|
||||
description: 'Flat Device Tree manipulation',
|
||||
)
|
||||
endif
|
||||
|
|
|
@ -43,6 +43,7 @@ py = import('python')
|
|||
py = py.find_installation(required: get_option('python'))
|
||||
swig = find_program('swig', required: get_option('python'))
|
||||
pylibfdt_enabled = not meson.is_cross_build() and py.found() and swig.found() ? true : false
|
||||
wheel_only = get_option('wheel-only')
|
||||
|
||||
version_gen_h = vcs_tag(
|
||||
command: ['git', 'describe', '--dirty=+'],
|
||||
|
@ -59,7 +60,7 @@ util_dep = declare_dependency(
|
|||
dependencies: libfdt_dep
|
||||
)
|
||||
|
||||
if get_option('tools')
|
||||
if get_option('tools') and not wheel_only
|
||||
flex = find_program('flex', required: true)
|
||||
bison = find_program('bison', required: true)
|
||||
|
||||
|
|
|
@ -10,3 +10,5 @@ option('python', type: 'feature', value: 'auto',
|
|||
description: 'Build pylibfdt Python library')
|
||||
option('tests', type: 'boolean', value: true,
|
||||
description: 'Build tests')
|
||||
option('wheel-only', type: 'boolean', value: false,
|
||||
description: 'building from meson-python')
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
|
||||
# Makefile.pylibfdt
|
||||
#
|
||||
|
||||
PYLIBFDT_srcs = $(PYLIBFDT_dir)/libfdt.i
|
||||
PYMODULE = $(PYLIBFDT_dir)/_libfdt.so
|
||||
PYLIBFDT_CLEANFILES_L = libfdt_wrap.c libfdt.py *.pyc *.so
|
||||
PYLIBFDT_CLEANFILES = $(PYLIBFDT_CLEANFILES_L:%=$(PYLIBFDT_dir)/%)
|
||||
PYLIBFDT_CLEANDIRS_L = __pycache__ libfdt.egg-info
|
||||
PYLIBFDT_CLEANDIRS = build $(PYLIBFDT_CLEANDIRS_L:%=$(PYLIBFDT_dir)/%)
|
||||
|
||||
SETUP = ./setup.py
|
||||
|
||||
ifndef V
|
||||
SETUPFLAGS += --quiet
|
||||
endif
|
||||
|
||||
$(PYMODULE): WARNINGS = # suppress warnings from generated code
|
||||
$(PYMODULE): $(PYLIBFDT_srcs) $(LIBFDT_archive) $(SETUP)
|
||||
@$(VECHO) PYMOD $@
|
||||
CFLAGS="$(CFLAGS) -Wno-error" $(PYTHON) $(SETUP) $(SETUPFLAGS) build_ext
|
||||
|
||||
install_pylibfdt: $(PYMODULE)
|
||||
@$(VECHO) INSTALL-PYLIB
|
||||
$(PYTHON) $(SETUP) $(SETUPFLAGS) install --prefix=$(PREFIX)
|
||||
|
||||
pylibfdt_clean:
|
||||
@$(VECHO) CLEAN "(pylibfdt)"
|
||||
rm -f $(PYLIBFDT_CLEANFILES)
|
||||
rm -rf $(PYLIBFDT_CLEANDIRS)
|
|
@ -1,13 +1,21 @@
|
|||
setup_py = find_program('../setup.py')
|
||||
setup_py = [setup_py, '--quiet', '--top-builddir', meson.project_build_root()]
|
||||
|
||||
pylibfdt = custom_target(
|
||||
'pylibfdt',
|
||||
libfdt_c = custom_target(
|
||||
'swig',
|
||||
input: 'libfdt.i',
|
||||
depends: libfdt,
|
||||
output: '_libfdt.so',
|
||||
command: [setup_py, 'build_ext'],
|
||||
build_by_default: true,
|
||||
output: ['libfdt.c', 'libfdt.py'],
|
||||
install: true,
|
||||
install_dir: [false, py.get_install_dir(pure: false)],
|
||||
command: [swig, '-python', '-I'+meson.current_source_dir() / '../libfdt', '-o', '@OUTPUT0@', '@INPUT@']
|
||||
)
|
||||
|
||||
meson.add_install_script(setup_py, 'install', '--prefix=' + get_option('prefix'), '--root=$DESTDIR')
|
||||
nowarn_gen = cc.get_supported_arguments(
|
||||
'-Wno-cast-qual',
|
||||
'-Wno-missing-prototypes',
|
||||
'-Wno-redundant-decls',
|
||||
)
|
||||
pylibfdt = py.extension_module(
|
||||
'_libfdt',
|
||||
libfdt_c,
|
||||
c_args: ['-DPY_SSIZE_T_CLEAN'] + nowarn_gen,
|
||||
dependencies: [libfdt_dep, py.dependency()],
|
||||
install: true,
|
||||
)
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
[build-system]
|
||||
build-backend = 'mesonpy'
|
||||
requires = ['meson-python']
|
||||
|
||||
[project]
|
||||
name = 'libfdt'
|
||||
authors = [
|
||||
{name = 'Simon Glass', email = 'sjg@chromium.org'},
|
||||
]
|
||||
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',
|
||||
]
|
||||
description = 'Python binding for libfdt'
|
||||
readme = 'README.md'
|
||||
requires-python = '>=3.8'
|
||||
dynamic = ['version']
|
||||
|
||||
[project.urls]
|
||||
'homepage' = 'https://git.kernel.org/pub/scm/utils/dtc/dtc.git'
|
||||
|
||||
# These arguments are applied only when building a redistributable binary wheel
|
||||
# for uploading to PyPI. We don't want to install libraries (or headers /
|
||||
# pkgconfig files / executables) that clash with system C installs, so we
|
||||
# disable everything other than the python bindings themselves, and build the
|
||||
# python C-API extension using static linkage to avoid juggling "libdir" /
|
||||
# LD_LIBRARY_PATH / RPATH around. When building both the C library and the
|
||||
# python bindings for a distro, `meson setup` will still default to shared
|
||||
# libraries.
|
||||
[tool.meson-python.args]
|
||||
setup = ['-Ddefault_library=static', '-Dwheel-only=true']
|
97
setup.py
97
setup.py
|
@ -1,97 +0,0 @@
|
|||
#!/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>
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from setuptools import setup, Extension
|
||||
from setuptools.command.build_py import build_py as _build_py
|
||||
|
||||
|
||||
def scan_for_info(srcdir):
|
||||
"""Scan for the version and long_description fields
|
||||
|
||||
Args:
|
||||
srcdir (str): Source-directory path
|
||||
|
||||
Returns: tuple
|
||||
str: Full description (contents of README.md)
|
||||
str: Version string
|
||||
"""
|
||||
with open(os.path.join(srcdir, "VERSION.txt"), "r", encoding='utf-8') as fh:
|
||||
version = fh.readline().strip()
|
||||
|
||||
with open(os.path.join(srcdir, "README.md"), "r", encoding='utf-8') as fh:
|
||||
long_description = fh.read()
|
||||
|
||||
return version, long_description
|
||||
|
||||
|
||||
def get_top_builddir(srcdir):
|
||||
"""Figure out the top-level directory containing the source code
|
||||
|
||||
Args:
|
||||
srcdir (str): Source-directory path
|
||||
|
||||
Returns:
|
||||
str: Directory to build in
|
||||
"""
|
||||
if '--top-builddir' in sys.argv:
|
||||
index = sys.argv.index('--top-builddir')
|
||||
sys.argv.pop(index)
|
||||
return sys.argv.pop(index)
|
||||
return srcdir
|
||||
|
||||
|
||||
class BuildPy(_build_py):
|
||||
"""Small class to run the build_ext command"""
|
||||
def run(self):
|
||||
self.run_command("build_ext")
|
||||
return super().run()
|
||||
|
||||
|
||||
srcdir = os.path.dirname(__file__)
|
||||
version, long_description = scan_for_info(srcdir)
|
||||
|
||||
libfdt_module = Extension(
|
||||
'_libfdt',
|
||||
sources=[os.path.join(srcdir, 'pylibfdt/libfdt.i')],
|
||||
define_macros=[('PY_SSIZE_T_CLEAN', None)],
|
||||
include_dirs=[os.path.join(srcdir, 'libfdt')],
|
||||
libraries=['fdt'],
|
||||
library_dirs=[os.path.join(get_top_builddir(srcdir), 'libfdt')],
|
||||
swig_opts=['-I' + os.path.join(srcdir, 'libfdt')],
|
||||
)
|
||||
|
||||
|
||||
setup(
|
||||
name='libfdt',
|
||||
version=version,
|
||||
cmdclass = {'build_py' : BuildPy},
|
||||
author='Simon Glass',
|
||||
author_email='sjg@chromium.org',
|
||||
description='Python binding for libfdt',
|
||||
ext_modules=[libfdt_module],
|
||||
package_dir={'': os.path.join(srcdir, 'pylibfdt')},
|
||||
py_modules=['libfdt'],
|
||||
python_requires=">=3.8",
|
||||
|
||||
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",
|
||||
],
|
||||
)
|
Loading…
Reference in New Issue