147 lines
3.6 KiB
Markdown
147 lines
3.6 KiB
Markdown
# Python Installation
|
||
|
||
The `uLib` Python package exposes the Core and Math C++ libraries via [pybind11](https://pybind11.readthedocs.io) bindings. There are two ways to install it: as an **end user** (pre-built wheel / pip) or as a **developer** (editable build from source).
|
||
|
||
---
|
||
|
||
## Prerequisites
|
||
|
||
`uLib` depends on native C++ libraries that must be compiled. Ensure the following are available in your environment before installing:
|
||
|
||
| Dependency | Minimum version | Notes |
|
||
|---|---|---|
|
||
| Python | 3.9 | |
|
||
| CMake | 3.12 | |
|
||
| pybind11 | 2.6.0 | |
|
||
| Conan | 2.x | for Eigen3 / Boost |
|
||
| micromamba / conda | any | recommended – provides ROOT, VTK |
|
||
|
||
### Creating the `mutom` Conda/Micromamba Environment
|
||
|
||
A ready-to-use environment definition is provided as `condaenv.yml` at the repository root.
|
||
|
||
=== "Micromamba"
|
||
```bash
|
||
micromamba env create -f condaenv.yml
|
||
micromamba activate mutom
|
||
```
|
||
|
||
=== "Conda"
|
||
```bash
|
||
conda env create -f condaenv.yml
|
||
conda activate mutom
|
||
```
|
||
|
||
The environment installs CMake, Conan, ROOT, VTK, and the compiler toolchain.
|
||
|
||
> **CUDA (optional)**
|
||
> If you want GPU-accelerated voxel filtering, you also need NVCC inside the environment:
|
||
> ```bash
|
||
> micromamba install cuda-nvcc -c conda-forge
|
||
> ```
|
||
|
||
---
|
||
|
||
## User Installation (wheel / pip)
|
||
|
||
Once the native dependencies are present in your environment, install the package with Poetry or pip:
|
||
|
||
```bash
|
||
# Activate your environment first
|
||
micromamba activate mutom
|
||
|
||
# Build and install (CUDA disabled by default)
|
||
poetry install
|
||
|
||
# Build and install with CUDA support
|
||
USE_CUDA=ON poetry install
|
||
```
|
||
|
||
After installation the module is importable from anywhere in the environment:
|
||
|
||
```python
|
||
import uLib
|
||
print(dir(uLib.Core))
|
||
print(dir(uLib.Math))
|
||
```
|
||
|
||
---
|
||
|
||
## Developer Installation (editable / in-tree build)
|
||
|
||
For development you typically want to skip the packaging layer and work directly against the CMake build tree.
|
||
|
||
### Step 1 – Install Conan dependencies
|
||
|
||
```bash
|
||
conan profile detect # first time only
|
||
conan install . --output-folder=build --build=missing
|
||
```
|
||
|
||
### Step 2 – Configure and build
|
||
|
||
```bash
|
||
# Standard release build
|
||
cmake --preset conan-release
|
||
|
||
# …or manually
|
||
cmake -B build \
|
||
-DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake \
|
||
-DCMAKE_BUILD_TYPE=Release \
|
||
-DUSE_CUDA=OFF # set to ON when a GPU is available
|
||
|
||
cmake --build build --target uLib_python -j$(nproc)
|
||
```
|
||
|
||
The shared library (`uLib_python*.so`) is written to `build/src/Python/`.
|
||
|
||
### Step 3 – Make the module importable
|
||
|
||
Point `PYTHONPATH` at the build output **and** the Python source directory (the latter carries the `uLib/__init__.py` that stitches sub-modules together):
|
||
|
||
```bash
|
||
export PYTHONPATH="$(pwd)/build/src/Python:$(pwd)/src/Python:$PYTHONPATH"
|
||
python -c "import uLib; print(uLib.__version__)"
|
||
```
|
||
|
||
Or, for a one-shot check:
|
||
|
||
```bash
|
||
PYTHONPATH="build/src/Python:src/Python" python src/Python/testing/pybind_test.py
|
||
```
|
||
|
||
### Step 4 – Run the tests
|
||
|
||
CMake registers the Python tests alongside the C++ ones; use `ctest` from the build directory:
|
||
|
||
```bash
|
||
cd build
|
||
ctest --output-on-failure -R pybind
|
||
```
|
||
|
||
Individual test scripts can also be run directly once `PYTHONPATH` is set:
|
||
|
||
```bash
|
||
python src/Python/testing/core_pybind_test.py
|
||
python src/Python/testing/math_pybind_test.py
|
||
python src/Python/testing/math_filters_test.py
|
||
```
|
||
|
||
---
|
||
|
||
## Verifying the Installation
|
||
|
||
```python
|
||
import uLib
|
||
|
||
# Core module
|
||
obj = uLib.Core.Object()
|
||
timer = uLib.Core.Timer()
|
||
timer.Start()
|
||
elapsed = timer.StopWatch() # float, seconds
|
||
|
||
# Math module
|
||
v3 = uLib.Math.Vector3f([1.0, 0.0, 0.0])
|
||
print(v3[0]) # 1.0
|
||
```
|