From 02bd1bc7f363a565c896aca1a0ce5a24ca107f3b Mon Sep 17 00:00:00 2001 From: Radostin Stoyanov Date: Sun, 18 Jun 2023 14:20:04 +0200 Subject: [PATCH] crit: add requirements.txt for pip>=20.1 When building with pip version 20.0.2 or older, the pip install command creates a temporary directory and copies all files from ./crit. This results in the following error message: ModuleNotFoundError: No module named 'pycriu' This error appears because the symlink 'pycriu' uses a relative path that becomes invalid '../lib/py/'. The '--no-build-isolation' option for pip install is needed to enable the use of pre-installed dependencies (e.g., protobuf) during build. The '--ignore-installed' option for pip is needed to avoid an error when crit is already installed. For example, crit is installed in the GitHub CI environment as part of the criu OBS package as a dependency for podman. Distributions such as Arch Linux have adopted an externally managed python installation in compliance with PEP 668 [1] that prevents pip from breaking the system by either installing packages to the system or locally in the home folder. The '--break-system-packages' [2] option allows pip to modify an externally managed Python installation. [1] https://peps.python.org/pep-0668/ [2] https://pip.pypa.io/en/stable/cli/pip_uninstall/ Signed-off-by: Radostin Stoyanov --- crit/pyproject.toml | 3 ++- crit/requirements.txt | 7 +++++++ lib/Makefile | 27 ++++++++++++++++++++++++--- 3 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 crit/requirements.txt diff --git a/crit/pyproject.toml b/crit/pyproject.toml index b1e1a4650a..019b0d8488 100644 --- a/crit/pyproject.toml +++ b/crit/pyproject.toml @@ -1,2 +1,3 @@ [build-system] -requires = ["setuptools"] +# Minimum requirements for the build system to execute. +requires = ["setuptools", "wheel"] # PEP 508 specifications. diff --git a/crit/requirements.txt b/crit/requirements.txt new file mode 100644 index 0000000000..c27e6d4f0b --- /dev/null +++ b/crit/requirements.txt @@ -0,0 +1,7 @@ +# We need pip version 20.1 or newer to correctly build with 'pycriu' symlink. +# - Building of local directories with pip 20.1 or newer is done in place, +# instead of a temporary location containing a copy of the directory tree. +# (https://github.com/pypa/pip/issues/7555) +pip>=20.1 +setuptools>=42.0.0 +wheel diff --git a/lib/Makefile b/lib/Makefile index 7ed73f9ab6..32d238de4d 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -4,6 +4,9 @@ UAPI_HEADERS := lib/c/criu.h images/rpc.proto images/rpc.pb-c.h criu/include/ve all-y += lib-c lib-a lib-py +PYTHON_EXTERNALLY_MANAGED := $(shell $(PYTHON) -c 'import os, sysconfig; print(int(os.path.isfile(os.path.join(sysconfig.get_path("stdlib"), "EXTERNALLY-MANAGED"))))') +PIP_BREAK_SYSTEM_PACKAGES := 0 + # # C language bindings. lib/c/Makefile: ; @@ -54,9 +57,19 @@ install: lib-c lib-a lib-py lib/c/criu.pc.in $(Q) mkdir -p $(DESTDIR)$(LIBDIR)/pkgconfig $(Q) sed -e 's,@version@,$(CRIU_VERSION),' -e 's,@libdir@,$(LIBDIR),' -e 's,@includedir@,$(dir $(INCLUDEDIR)/criu/),' lib/c/criu.pc.in > lib/c/criu.pc $(Q) install -m 644 lib/c/criu.pc $(DESTDIR)$(LIBDIR)/pkgconfig -ifeq ($(PYTHON),python3) +ifeq ($(PYTHON_EXTERNALLY_MANAGED),1) +ifeq ($(PIP_BREAK_SYSTEM_PACKAGES),0) + $(E) " SKIP INSTALL crit: Externally managed python environment (See PEP 668 for more information)" + $(E) " Consider using PIP_BREAK_SYSTEM_PACKAGES=1 make install" +else + $(E) " INSTALL " crit + $(Q) $(PYTHON) -m pip install -r ./crit/requirements.txt + $(Q) $(PYTHON) -m pip install --no-build-isolation --upgrade --ignore-installed --prefix=$(DESTDIR)$(PREFIX) ./crit +endif +else $(E) " INSTALL " crit - $(Q) $(PYTHON) -m pip install --upgrade --force-reinstall --prefix=$(DESTDIR)$(PREFIX) ./crit + $(Q) $(PYTHON) -m pip install -r ./crit/requirements.txt + $(Q) $(PYTHON) -m pip install --no-build-isolation --upgrade --ignore-installed --prefix=$(DESTDIR)$(PREFIX) ./crit endif .PHONY: install @@ -69,7 +82,15 @@ uninstall: $(Q) $(RM) $(addprefix $(DESTDIR)$(INCLUDEDIR)/criu/,$(notdir $(UAPI_HEADERS))) $(E) " UNINSTALL" pkgconfig/criu.pc $(Q) $(RM) $(addprefix $(DESTDIR)$(LIBDIR)/pkgconfig/,criu.pc) -ifeq ($(PYTHON),python3) +ifeq ($(PYTHON_EXTERNALLY_MANAGED),1) +ifeq ($(PIP_BREAK_SYSTEM_PACKAGES),0) + $(E) " SKIP UNINSTALL crit: Externally managed python environment (See PEP 668 for more information)" + $(E) " Consider using PIP_BREAK_SYSTEM_PACKAGES=1 make uninstall" +else + $(E) " UNINSTALL" crit + $(Q) $(PYTHON) ./scripts/uninstall_module.py --prefix=$(DESTDIR)$(PREFIX) crit +endif +else $(E) " UNINSTALL" crit $(Q) $(PYTHON) ./scripts/uninstall_module.py --prefix=$(DESTDIR)$(PREFIX) crit endif