Skip to content

Build from Source

NovaPhy 0.4.0 can be built as a Python package with scikit-build-core or as a standalone CMake project. Both routes configure the same top-level CMakeLists.txt; the default is a CPU-only build.

Build Methods

Python package

For normal development, let scikit-build-core own the build directory:

conda activate novaphy
export CMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake
python -m pip install -e .

Pass optional features as cache entries in CMAKE_ARGS:

CMAKE_ARGS="-DNOVAPHY_WITH_CUDA=ON -DNOVAPHY_WITH_MUJOCO_CUDA=ON -DCMAKE_CUDA_COMPILER=/path/to/nvcc" \
  python -m pip install -e .

CMake presets

The repository exposes three developer presets. The default-ci and ipc-ci variants are CI-oriented derivatives. CMakePresets.json uses schema version 3 and therefore requires CMake 3.21+.

Configure/build preset Binary directory Configuration
default build-release Release, optional GPU features off
debug build-debug Debug, optional GPU features off
ipc build-ipc Release with NOVAPHY_WITH_IPC=ON

The base preset reads the vcpkg toolchain from VCPKG_ROOT:

export VCPKG_ROOT=/path/to/vcpkg
cmake --preset default -Dpybind11_DIR="$(python -m pybind11 --cmakedir)"
cmake --build --preset default
ctest --test-dir build-release --output-on-failure

For the IPC preset, initialize libuipc and select a CUDA compiler:

git submodule update --init --recursive external/libuipc
export VCPKG_ROOT=/path/to/vcpkg
cmake --preset ipc \
  -Dpybind11_DIR="$(python -m pybind11 --cmakedir)" \
  -DCMAKE_CUDA_COMPILER=/path/to/nvcc
cmake --build --preset ipc

Use presets directly with CMake. For a pip or wheel build, pass the required -D... entries in CMAKE_ARGS so scikit-build-core retains control of its own build/{wheel_tag} directory.

Explicit standalone build

cmake -S . -B build/release \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake \
  -Dpybind11_DIR="$(python -m pybind11 --cmakedir)" \
  -DNOVAPHY_BUILD_TESTS=ON
cmake --build build/release --parallel
ctest --test-dir build/release --output-on-failure
cmake --install build/release --prefix /path/to/install

Pass --config Release to the build, test, and install commands when using a multi-configuration generator such as Visual Studio.

Build Flags

Physics and accelerator features

Cache entry Default Current behavior
NOVAPHY_WITH_CUDA OFF Compile the core CUDA DeviceArray backend. Without a compiler, CMake warns and builds the throwing stub.
NOVAPHY_WITH_COLLISION_CUDA ON (OFF by default for DLAN) Add CUDA collision kernels when core CUDA and a CUDA compiler are active. Has no effect on a CPU-only core build.
NOVAPHY_WITH_VBD_CUDA OFF Compile the NVIDIA SolverVBD GPU backend; forces core CUDA on.
NOVAPHY_WITH_VBD_DLAN OFF Compile SolverVBD through the Denglin DLAN compatibility path; forces core CUDA and COREX.
NOVAPHY_WITH_SPH_CUDA OFF Compile the only current runnable SolverSPH backend. The SPH API/module is present when this is off, but the CPU backend is not implemented and stepping is unavailable.
NOVAPHY_WITH_LBM_CUDA OFF Compile the sparse-block SolverLBM numerical backend. The LBM API/module is present when this is off, but fluid operations are unavailable.
NOVAPHY_WITH_MUJOCO_CUDA OFF Request the native SolverMuJoCo CUDA backend. Set core CUDA too; this option does not force it.
NOVAPHY_WITH_FEATHERSTONE_CUDA OFF Compile SolverFeatherstone CUDA. Requires core CUDA and a CUDA compiler at configure time.
NOVAPHY_WITH_IPC OFF Build SolverIPC and vendored libuipc. NVIDIA builds require CUDA 12.4+; CoreX uses its compatibility compiler.

GPU toolchain selection

Cache entry Default Current behavior
NOVAPHY_GPU_PLATFORM NVIDIA Accepts NVIDIA or COREX (case-insensitive, stored uppercase). DLAN forces COREX. This selector alone enables no backend.
NOVAPHY_CUDA_ARCHITECTURES native (NVIDIA), ivcore11 (CoreX), 70 (DLAN) Architecture list applied to NovaPhy CUDA targets and copied into CMAKE_CUDA_ARCHITECTURES.
NOVAPHY_CUDA_SEPARABLE_COMPILATION ON on NVIDIA; forced OFF on CoreX/DLAN Cache marker for the common CUDA policy. CoreX/DLAN also force CMAKE_CUDA_SEPARABLE_COMPILATION=OFF; current targets do not generally consume the NovaPhy marker directly.
CMAKE_CUDA_COMPILER auto-probed when a CUDA feature is requested Explicit path to nvcc or the selected compatibility wrapper. CPU builds do not probe CUDA.
CMAKE_TOOLCHAIN_FILE unset Path to the vcpkg toolchain file. The presets derive it from VCPKG_ROOT.

Set NOVAPHY_CUDA_ARCHITECTURES, not only CMAKE_CUDA_ARCHITECTURES: the top-level configuration copies the former into the latter with FORCE.

For DLAN runtime discovery, set the DLAN_SDK_ROOT or DLGPU_ROOT cache entry/environment variable. NOVAPHY_DLAN_CURT_LIBRARY can point directly to libcurt.so when automatic lookup is not suitable.

General build controls

Cache entry Default Current behavior
NOVAPHY_BUILD_TESTS ON at the repository root; OFF as a subproject Build native tests when GoogleTest is found.
NOVAPHY_BUNDLE_DEPENDENCIES ON under scikit-build; OFF otherwise Bundle eligible runtime dependencies into the Python package.

NOVAPHY_WITH_SPH is deprecated. If supplied, CMake warns; a true value is translated to NOVAPHY_WITH_SPH_CUDA=ON.

Feature Relationships

Requested feature Implied / required settings Incompatible or independent settings
Core CUDA NOVAPHY_WITH_CUDA=ON and a CUDA compiler for a real backend Does not enable any solver-specific CUDA backend
Collision CUDA Core CUDA + NOVAPHY_WITH_COLLISION_CUDA=ON No separate Python has_collision_cuda() check
VBD CUDA Forces core CUDA; requires a CUDA compiler; collision CUDA therefore builds by default Mutually exclusive with VBD DLAN
VBD DLAN Forces core CUDA and COREX; requires a compiler wrapper and libcurt.so Mutually exclusive with VBD CUDA; collision CUDA defaults off
SPH CUDA A real backend requires a CUDA compiler; otherwise CMake leaves the interface-only module Does not force core CUDA; CUDA is the only current runnable SolverSPH backend
LBM CUDA Requires a CUDA compiler at configure time Does not force core CUDA; CUDA is the only current SolverLBM numerical backend
MuJoCo CUDA Core CUDA + MuJoCo CUDA + a CUDA compiler MuJoCo flag alone compiles the stub
Featherstone CUDA Core CUDA + Featherstone CUDA + a CUDA compiler Missing core CUDA or compiler is a configure error
IPC on NVIDIA IPC flag, libuipc submodule, CUDA 12.4+ Core CUDA is independent
IPC on CoreX IPC flag, libuipc submodule, COREX, compatibility wrapper Core CUDA is independent

Enabling any CUDA-backed module starts CUDA compiler detection. A successful configuration request is not the same as a usable runtime backend: check the loaded Python extension and then exercise the target device.

Common Configurations

# Core CUDA and collision CUDA (collision is ON by default)
CMAKE_ARGS="-DNOVAPHY_WITH_CUDA=ON -DCMAKE_CUDA_COMPILER=/path/to/nvcc" \
  python -m pip install -e .

# VBD CUDA (also forces core CUDA)
CMAKE_ARGS="-DNOVAPHY_WITH_VBD_CUDA=ON -DCMAKE_CUDA_COMPILER=/path/to/nvcc" \
  python -m pip install -e .

# SPH CUDA without core CUDA buffers
CMAKE_ARGS="-DNOVAPHY_WITH_SPH_CUDA=ON -DCMAKE_CUDA_COMPILER=/path/to/nvcc" \
  python -m pip install -e .

# LBM CUDA without core CUDA buffers
CMAKE_ARGS="-DNOVAPHY_WITH_LBM_CUDA=ON -DCMAKE_CUDA_COMPILER=/path/to/nvcc" \
  python -m pip install -e .

# Core CUDA plus both native articulated solver backends
CMAKE_ARGS="-DNOVAPHY_WITH_CUDA=ON -DNOVAPHY_WITH_MUJOCO_CUDA=ON -DNOVAPHY_WITH_FEATHERSTONE_CUDA=ON -DCMAKE_CUDA_COMPILER=/path/to/nvcc" \
  python -m pip install -e .

For DLAN, use the Denglin DLAN guide. For libuipc requirements and solver limitations, use the IPC guide.

Verify the Built Extension

The Python binding exports six compiled-feature checks:

import novaphy

assert novaphy.version() == "0.4.0"
print("IPC              ", novaphy.has_ipc())
print("SPH CUDA         ", novaphy.has_sph_cuda())
print("MuJoCo CUDA      ", novaphy.has_mujoco_cuda())
print("Featherstone CUDA", novaphy.has_featherstone_cuda())
print("VBD CUDA         ", novaphy.has_vbd_cuda())
print("VBD DLAN         ", novaphy.has_vbd_dlan())

model = novaphy.ModelBuilder().finalize()
lbm = novaphy.solvers.SolverLBM(model)
print("LBM CUDA         ", lbm.has_cuda_backend)

There is no current top-level feature check for core CUDA or collision CUDA. LBM likewise uses the model-bound solver property shown above rather than a top-level function. The configure log distinguishes the real core/collision sources from their stubs. The six top-level booleans and the LBM property report what was compiled into the extension that Python actually loaded; they do not probe driver health. VBD DLAN builds define both the shared CUDA-source availability macro and the DLAN-specific macro, so both has_vbd_cuda() and has_vbd_dlan() return true in that variant.

C++ Integration

add_subdirectory

Set feature options before adding NovaPhy:

set(NOVAPHY_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(NOVAPHY_WITH_IPC OFF CACHE BOOL "" FORCE)
add_subdirectory(/path/to/NovaPhy)

target_link_libraries(your_target PRIVATE novaphy::core)

Additional build-tree targets include novaphy::vbd, novaphy::sph, and novaphy::lbm. novaphy::ipc exists only in IPC builds and is not yet exported by the installed CMake package. Link only the modules your C++ target uses.

Installed package

After cmake --install, a consumer can use:

find_package(tinyxml2 CONFIG REQUIRED)
find_package(novaphy CONFIG REQUIRED)
target_link_libraries(your_target PRIVATE novaphy::core)

The explicit tinyxml2 lookup reflects the current package-config limitation: novaphy::core links it publicly, but the installed NovaPhy config does not forward-find it yet.

Runnable integration projects live under cmake/cmake_project/.

Compiler and Platform Coverage

The CPU build requires C++20. The current CI covers the default CPU configuration on ubuntu-latest and windows-latest with Python 3.11, plus a self-hosted Linux IPC build using CUDA 12.8. Other compiler, CUDA, CoreX, and DLAN combinations are not all continuously tested, so treat the following as constraints rather than a universal compatibility promise:

  • The NVIDIA IPC path is rejected below CUDA 12.4.
  • The selected CUDA toolkit determines which host compiler versions and GPU architectures it accepts.
  • CoreX and DLAN require their compatibility wrappers and runtime libraries; selecting NOVAPHY_GPU_PLATFORM=COREX does not install them.
  • For a GPU architecture other than the local default, pass an explicit NOVAPHY_CUDA_ARCHITECTURES supported by the selected compiler.

Packaging

Build a default CPU wheel:

python -m pip install build
python -m build

Build a feature variant by passing the same cache entries used for editable installs:

CMAKE_ARGS="-DNOVAPHY_WITH_CUDA=ON -DNOVAPHY_WITH_MUJOCO_CUDA=ON -DCMAKE_CUDA_COMPILER=/path/to/nvcc" \
  python -m build

NOVAPHY_BUNDLE_DEPENDENCIES defaults to on for scikit-build wheel builds. Demo modules are included unless NOVAPHY_EXCLUDE_DEMOS=true is set.

Troubleshooting

pybind11 version conflict

Use python -m pip install pybind11 and, for standalone CMake, pass -Dpybind11_DIR="$(python -m pybind11 --cmakedir)". A vcpkg pybind11 can bind against a different Python environment.

A feature check stays false after rebuilding

Print novaphy.__file__ and confirm Python is loading the extension from the build you just configured. Uninstall duplicate editable/wheel installs before rebuilding. On Windows, merged source and site-packages paths are a common cause of loading an older _core*.pyd.

CUDA was requested but the core uses stubs

NOVAPHY_WITH_CUDA=ON deliberately remains configurable without a detected compiler and emits a warning. Pass CMAKE_CUDA_COMPILER explicitly and confirm the configure summary says the core CUDA backend is enabled.

Changing GPU platform or architecture

Do not reuse a build tree configured for another CUDA compiler or platform. Create a new build directory, or remove the stale CMake cache before switching between NVIDIA, CoreX, and DLAN.