From 6c9c8a9001523d88f1ec9640715d01f1b9d966b0 Mon Sep 17 00:00:00 2001 From: Oliver Holworthy Date: Tue, 4 Jul 2023 22:46:17 +0100 Subject: [PATCH] Enable Installation of Python Package with System lib in a Virtual Environment (#9349) --- .github/workflows/python_tests.yml | 41 ++++++++++++++++++++++++++++ doc/build.rst | 2 +- python-package/packager/nativelib.py | 4 +-- python-package/xgboost/libpath.py | 6 ++-- 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/.github/workflows/python_tests.yml b/.github/workflows/python_tests.yml index 98dc1b468..b9e97d439 100644 --- a/.github/workflows/python_tests.yml +++ b/.github/workflows/python_tests.yml @@ -255,3 +255,44 @@ jobs: shell: bash -l {0} run: | pytest -s -v -rxXs --durations=0 ./tests/test_distributed/test_with_spark + + python-system-installation-on-ubuntu: + name: Test XGBoost Python package System Installation on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + + - name: Set up Python 3.8 + uses: actions/setup-python@v4 + with: + python-version: 3.8 + + - name: Install ninja + run: | + sudo apt-get update && sudo apt-get install -y ninja-build + + - name: Build XGBoost on Ubuntu + run: | + mkdir build + cd build + cmake .. -GNinja + ninja + + - name: Copy lib to system lib + run: | + cp lib/* "$(python -c 'import sys; print(sys.base_prefix)')/lib" + + - name: Install XGBoost in Virtual Environment + run: | + cd python-package + pip install virtualenv + virtualenv venv + source venv/bin/activate && \ + pip install -v . --config-settings use_system_libxgboost=True && \ + python -c 'import xgboost' diff --git a/doc/build.rst b/doc/build.rst index e78d2d2f4..e30d57bc8 100644 --- a/doc/build.rst +++ b/doc/build.rst @@ -259,7 +259,7 @@ There are several ways to build and install the package from source: import sys import pathlib - libpath = pathlib.Path(sys.prefix).joinpath("lib", "libxgboost.so") + libpath = pathlib.Path(sys.base_prefix).joinpath("lib", "libxgboost.so") assert libpath.exists() Then pass ``use_system_libxgboost=True`` option to ``pip install``: diff --git a/python-package/packager/nativelib.py b/python-package/packager/nativelib.py index f1708d6c5..ff38fa11d 100644 --- a/python-package/packager/nativelib.py +++ b/python-package/packager/nativelib.py @@ -132,8 +132,8 @@ def locate_or_build_libxgboost( if build_config.use_system_libxgboost: # Find libxgboost from system prefix - sys_prefix = pathlib.Path(sys.prefix).absolute().resolve() - libxgboost_sys = sys_prefix / "lib" / _lib_name() + sys_base_prefix = pathlib.Path(sys.base_prefix).absolute().resolve() + libxgboost_sys = sys_base_prefix / "lib" / _lib_name() if not libxgboost_sys.exists(): raise RuntimeError( f"use_system_libxgboost was specified but {_lib_name()} is " diff --git a/python-package/xgboost/libpath.py b/python-package/xgboost/libpath.py index be37b364e..0437f3a4c 100644 --- a/python-package/xgboost/libpath.py +++ b/python-package/xgboost/libpath.py @@ -27,7 +27,7 @@ def find_lib_path() -> List[str]: os.path.join(curr_path, os.path.pardir, os.path.pardir, "lib"), # use libxgboost from a system prefix, if available. This should be the last # option. - os.path.join(sys.prefix, "lib"), + os.path.join(sys.base_prefix, "lib"), ] if sys.platform == "win32": @@ -62,8 +62,8 @@ def find_lib_path() -> List[str]: + ("\n- ".join(dll_path)) + "\nXGBoost Python package path: " + curr_path - + "\nsys.prefix: " - + sys.prefix + + "\nsys.base_prefix: " + + sys.base_prefix + "\nSee: " + link + " for installing XGBoost."