From 31e3d717ad191e966ddbd4802f85982bfb5618bd Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Thu, 3 Feb 2022 20:38:44 -0600 Subject: [PATCH 1/4] [Python] Install Python bindings with pip if available As directly invoking `python setup.py` is considered deprecated behavior by the PyPA, use `python -m pip install` to install the Python bindings if the Python interpreter has a valid version of pip associated with it. If there is a valid pip, build and install the Python bindings with `python -m pip install`. If there is no valid pip, warn the user and give them instructions on how to get pip on their machine. Attempt to still install the Python bindings by falling back on the deprecated `python setup.py build` and `python setup.py install` which will also invoke Easy Install if setuptools v0.60.0+ is used. --- bindings/python/CMakeLists.txt | 71 ++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 17 deletions(-) diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index 6fb08f51d5b..5868c9556b1 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -32,25 +32,62 @@ endif() configure_file(${SETUP_PY_IN} ${SETUP_PY}) -add_custom_command(OUTPUT ${OUTPUT} - COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} build - DEPENDS ${DEPS}) +# Check it the Python interpreter has a valid version of pip +execute_process( + COMMAND ${PYTHON_EXECUTABLE} -m pip --version + RESULT_VARIABLE VALID_PIP_EXIT_CODE + OUTPUT_QUIET +) -add_custom_target(python_target ALL DEPENDS ${OUTPUT} XrdCl) +if ( NOT ${VALID_PIP_EXIT_CODE} EQUAL 0 ) + # Attempt to still install with deprecated invocation of setup.py + message(WARNING + " ${PYTHON_EXECUTABLE} does not have a valid pip associated with it." + " It is recommended that you install a version of pip to install Python" + " packages and bindings. If you are unable to install a version of pip" + " through a package manager or with your Python build try using the PyPA's" + " get-pip.py bootstrapping script ( https://github.com/pypa/get-pip ).\n" + " The installation of the Python bindings will attempt to continue using" + " the deprecated method of `${PYTHON_EXECUTABLE} setup.py install`." + ) -# Get the distribution name on Debian families -execute_process( COMMAND grep -i ^NAME=\" /etc/os-release - OUTPUT_VARIABLE DEB_DISTRO ) -STRING(REGEX REPLACE "^NAME=\"" "" DEB_DISTRO "${DEB_DISTRO}") -STRING(REGEX REPLACE "\".*" "" DEB_DISTRO "${DEB_DISTRO}") + # https://docs.python.org/3/install/#splitting-the-job-up + add_custom_command(OUTPUT ${OUTPUT} + COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} build + DEPENDS ${DEPS}) -if( DEB_DISTRO STREQUAL "Debian" OR DEB_DISTRO STREQUAL "Ubuntu" ) - set(PYTHON_LAYOUT "unix" CACHE STRING "Python installation layout (deb or unix)") - set(DEB_INSTALL_ARGS "--install-layout ${PYTHON_LAYOUT}") -endif() + add_custom_target(python_target ALL DEPENDS ${OUTPUT} XrdCl) + + # Get the distribution name on Debian families + execute_process( COMMAND grep -i ^NAME= /etc/os-release + OUTPUT_VARIABLE DEB_DISTRO ) + STRING(REGEX REPLACE "^NAME=\"" "" DEB_DISTRO "${DEB_DISTRO}") + STRING(REGEX REPLACE "\".*" "" DEB_DISTRO "${DEB_DISTRO}") + + if( DEB_DISTRO STREQUAL "Debian" OR DEB_DISTRO STREQUAL "Ubuntu" ) + set(PYTHON_LAYOUT "unix" CACHE STRING "Python installation layout (deb or unix)") + set(DEB_INSTALL_ARGS "--install-layout ${PYTHON_LAYOUT}") + endif() -install( - CODE - "EXECUTE_PROCESS( - COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} install --prefix \$ENV{DESTDIR}/${CMAKE_INSTALL_PREFIX} ${DEB_INSTALL_ARGS} --record PYTHON_INSTALLED)" ) + install( + CODE + "EXECUTE_PROCESS( + COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} install \ + --prefix \$ENV{DESTDIR}/${CMAKE_INSTALL_PREFIX} \ + ${DEB_INSTALL_ARGS} \ + --record PYTHON_INSTALLED + )" + ) +else() + # Use --force-reinstall to ensure a clean install if a rebuild needs to happen + install( + CODE + "EXECUTE_PROCESS( + COMMAND ${PYTHON_EXECUTABLE} -m pip install \ + --force-reinstall \ + --prefix \$ENV{DESTDIR}/${CMAKE_INSTALL_PREFIX} \ + ${CMAKE_CURRENT_BINARY_DIR} + )" + ) +endif() From a6dbe2be2f611ce5ec18776b8a37f8ce3d6b4bb8 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Thu, 3 Feb 2022 20:42:40 -0600 Subject: [PATCH 2/4] [CMake] Add PYTHON_VERBOSE flag to enable --verbose pip install --- bindings/python/CMakeLists.txt | 10 +++++++++- cmake/XRootDDefaults.cmake | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index 5868c9556b1..e278b7f229e 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -32,6 +32,12 @@ endif() configure_file(${SETUP_PY_IN} ${SETUP_PY}) +if( PIP_VERBOSE ) + set(PIP_INSTALL_VERBOSE_FLAG "--verbose") +else() + set(PIP_INSTALL_VERBOSE_FLAG "") +endif() + # Check it the Python interpreter has a valid version of pip execute_process( COMMAND ${PYTHON_EXECUTABLE} -m pip --version @@ -53,7 +59,7 @@ if ( NOT ${VALID_PIP_EXIT_CODE} EQUAL 0 ) # https://docs.python.org/3/install/#splitting-the-job-up add_custom_command(OUTPUT ${OUTPUT} - COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} build + COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} ${PIP_INSTALL_VERBOSE_FLAG} build DEPENDS ${DEPS}) add_custom_target(python_target ALL DEPENDS ${OUTPUT} XrdCl) @@ -73,6 +79,7 @@ if ( NOT ${VALID_PIP_EXIT_CODE} EQUAL 0 ) CODE "EXECUTE_PROCESS( COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} install \ + ${PIP_INSTALL_VERBOSE_FLAG} \ --prefix \$ENV{DESTDIR}/${CMAKE_INSTALL_PREFIX} \ ${DEB_INSTALL_ARGS} \ --record PYTHON_INSTALLED @@ -85,6 +92,7 @@ else() CODE "EXECUTE_PROCESS( COMMAND ${PYTHON_EXECUTABLE} -m pip install \ + ${PIP_INSTALL_VERBOSE_FLAG} \ --force-reinstall \ --prefix \$ENV{DESTDIR}/${CMAKE_INSTALL_PREFIX} \ ${CMAKE_CURRENT_BINARY_DIR} diff --git a/cmake/XRootDDefaults.cmake b/cmake/XRootDDefaults.cmake index 78747b82295..a89de1985b2 100644 --- a/cmake/XRootDDefaults.cmake +++ b/cmake/XRootDDefaults.cmake @@ -18,6 +18,7 @@ option( ENABLE_XRDCL "Enable XRootD client." option( ENABLE_TESTS "Enable unit tests." FALSE ) option( ENABLE_HTTP "Enable HTTP component." TRUE ) option( ENABLE_PYTHON "Enable python bindings." TRUE ) +option( PIP_VERBOSE "Turn on --verbose flag for pip during Python bindings install." FALSE ) option( XRDCL_ONLY "Build only the client and necessary dependencies" FALSE ) option( XRDCL_LIB_ONLY "Build only the client libraries and necessary dependencies" FALSE ) option( PYPI_BUILD "The project is being built for PyPI release" FALSE ) From c6d031087c905c3488d52a684f9f9c412ca9395c Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Thu, 3 Feb 2022 20:40:28 -0600 Subject: [PATCH 3/4] [CI] Enable PIP_VERBOSE CMake option for builds in CI --- .github/workflows/build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3333060b8f7..8a88b3f726c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -63,6 +63,7 @@ jobs: -DCMAKE_INSTALL_PREFIX=/usr/local/ \ -DPYTHON_EXECUTABLE=$(command -v python3) \ -DENABLE_TESTS=ON \ + -DPIP_VERBOSE=ON \ -S xrootd \ -B build cmake3 build -LH @@ -135,6 +136,7 @@ jobs: -DCMAKE_INSTALL_PREFIX=/usr/local/ \ -DPYTHON_EXECUTABLE=$(command -v python3) \ -DENABLE_TESTS=ON \ + -DPIP_VERBOSE=ON \ -S xrootd \ -B build cmake3 build -LH @@ -202,6 +204,7 @@ jobs: -DCMAKE_INSTALL_PREFIX=/usr/ \ -DPYTHON_EXECUTABLE=$(command -v python2) \ -DENABLE_TESTS=ON \ + -DPIP_VERBOSE=ON \ -S xrootd \ -B build cmake3 build -LH From d004070148aceccc483bcc13937131e417b7965a Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Thu, 3 Feb 2022 20:44:15 -0600 Subject: [PATCH 4/4] [RPM] Add python2-pip to BuildRequires Ensure pip is available for Python 2 so that it can be attempted to be used for installation. --- packaging/rhel/xrootd.spec.in | 1 + 1 file changed, 1 insertion(+) diff --git a/packaging/rhel/xrootd.spec.in b/packaging/rhel/xrootd.spec.in index fbe9911b346..f318d804093 100644 --- a/packaging/rhel/xrootd.spec.in +++ b/packaging/rhel/xrootd.spec.in @@ -106,6 +106,7 @@ BuildRequires: libmacaroons-devel BuildRequires: json-c-devel %if %{python2only} +BuildRequires: python2-pip BuildRequires: python2-devel BuildRequires: python2-setuptools %endif