# Building & Integration

## Dependencies

- **C++20** compiler (GCC 11+, Clang 14+, MSVC 2022+)
- **zlib** (optional) — enables deflate compression; without it, store-only is used
- **OpenMP** (optional) — enables parallel processing for large meshes; without it, serial processing is used
- **GoogleTest** (fetched automatically when tests are enabled)

## Build from Source

```bash
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . -j$(nproc)
```

Run tests:

```bash
cd build && ctest --output-on-failure
```

### CMake Options

| Option | Default | Description |
|--------|---------|-------------|
| `N3MF_BUILD_TESTS` | `ON` | Build unit tests (requires internet for GoogleTest fetch) |
| `N3MF_USE_OPENMP` | `ON` | Enable OpenMP parallel processing for large meshes |

### OpenMP Notes

OpenMP is detected automatically via `find_package(OpenMP)`. Platform-specific notes:

- **Linux (GCC)**: OpenMP is built-in, no extra setup needed.
- **Windows (MSVC)**: OpenMP is supported natively via `/openmp`. Code targets OpenMP 2.0 features for maximum MSVC compatibility (signed loop counters, manual min/max reduction).
- **macOS (Apple Clang)**: Requires `libomp` from Homebrew: `brew install libomp`. Pass the path hint to CMake: `-DOpenMP_ROOT=$(brew --prefix libomp)`.

If OpenMP is not found, the library builds and works correctly using serial processing.

## Integration

### FetchContent (recommended)

```cmake
include(FetchContent)
FetchContent_Declare(neroued_3mf
    GIT_REPOSITORY https://github.com/neroued/neroued_3mf.git
    GIT_TAG v0.1.0)
set(N3MF_BUILD_TESTS OFF CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(neroued_3mf)
target_link_libraries(your_target PRIVATE neroued::3mf)
```

### add_subdirectory

```cmake
add_subdirectory(path/to/neroued_3mf)
target_link_libraries(your_target PRIVATE neroued::3mf)
```

### find_package (after install)

```cmake
find_package(neroued_3mf 0.1 REQUIRED)
target_link_libraries(your_target PRIVATE neroued::3mf)
```

## Umbrella Header

Quick start with a single include:

```cpp
#include <neroued/3mf/neroued_3mf.h>
```

You can also include individual headers (`types.h`, `builder.h`, `writer.h`, etc.) for finer-grained control.

## Python Bindings

### Install from source

```bash
pip install .
```

This uses scikit-build-core to compile the C++ library and nanobind extension module. Requirements:

- Python 3.10+
- C++20 compiler (same as the C++ library)
- CMake 3.16+

### Development install

```bash
pip install -v --no-build-isolation -e .
```

### Run Python tests

```bash
pip install pytest
python -m pytest python/tests/
```

### Build dependencies

The Python bindings use [nanobind](https://github.com/wjakob/nanobind) (v2.12+) and [scikit-build-core](https://github.com/scikit-build/scikit-build-core) (v0.12+). These are declared in `pyproject.toml` and installed automatically by pip.

## Version Management

Python package version is derived automatically from git tags via [setuptools_scm](https://github.com/pypa/setuptools-scm). The C++ library version is also extracted from git tags at CMake configure time.

- Tag format: `v<major>.<minor>.<patch>` (e.g. `v0.2.0`)
- Pre-release tags: `v0.2.0rc1`, `v0.2.0a1`, `v0.2.0b1`
- Without a tag, development versions like `0.1.0.dev3+g1a2b3c4` are generated

To release a new version:

```bash
git tag v0.2.0
git push origin v0.2.0
```

The `wheels.yml` GitHub Actions workflow will automatically build wheels and publish to PyPI (stable tags) or TestPyPI (pre-release tags).

## Version Macros

Compile-time version info is available via `<neroued/3mf/version.h>` (generated by CMake from `version.h.in`):

```cpp
NEROUED_3MF_VERSION_MAJOR   // e.g. 0
NEROUED_3MF_VERSION_MINOR   // e.g. 1
NEROUED_3MF_VERSION_PATCH   // e.g. 0
NEROUED_3MF_VERSION_STRING  // e.g. "0.1.0"
```

## CI/CD

The project uses two GitHub Actions workflows:

- **`ci.yml`** — Runs on every PR and push to `master`. Includes clang-format checks, C++ build & test (Linux/macOS/Windows), and Python build & test (3.10–3.13 x 3 OS).
- **`wheels.yml`** — Triggered by `v*` tags. Builds wheels via cibuildwheel on all platforms, builds sdist, and publishes to PyPI/TestPyPI using OIDC Trusted Publishing.
