Building

How you point your own build system at EBGeometry depends on your toolchain. Pick the section below that matches your workflow: CMake, GNU make, or Direct compilation. All three methods expose the same configuration knobs — described in Configuration options.

CMake

EBGeometry can be consumed in two ways from CMake: by cloning the repository (or installing it) and using add_subdirectory, or by letting CMake fetch it automatically at configure time with FetchContent.

Local installation

If you have a local clone, point CMake at it with -DCMAKE_PREFIX_PATH or by adding a call to add_subdirectory:

# Option A — add_subdirectory
add_subdirectory(/path/to/EBGeometry EBGeometry_build)
target_link_libraries(my_program PRIVATE EBGeometry::EBGeometry)

# Option B — manually set the include path
target_include_directories(my_program PRIVATE /path/to/EBGeometry)

Enabling SIMD in CMake

Pass architecture flags via target_compile_options:

# AVX + FMA (recommended for modern x86-64)
target_compile_options(my_program PRIVATE -mavx -mfma -msse4.1)

# AVX-512F, if your target machines are guaranteed to support it
target_compile_options(my_program PRIVATE -mavx512f -mavx2 -mavx -mfma -msse4.1)

# Or for maximum portability, auto-detect via march=native:
# target_compile_options(my_program PRIVATE -march=native)

To expose the SIMD level as a CMake option:

set(EBGEOMETRY_SIMD "avx" CACHE STRING "SIMD level: avx512 | avx | sse41 | none")
set_property(CACHE EBGEOMETRY_SIMD PROPERTY STRINGS avx512 avx sse41 none)

if(EBGEOMETRY_SIMD STREQUAL "avx512")
  target_compile_options(my_program PRIVATE -mavx512f -mavx2 -mavx -mfma -msse4.1)
elseif(EBGEOMETRY_SIMD STREQUAL "avx")
  target_compile_options(my_program PRIVATE -mavx -mfma -msse4.1)
elseif(EBGEOMETRY_SIMD STREQUAL "sse41")
  target_compile_options(my_program PRIVATE -msse4.1)
endif()

This is exactly what EBGeometry’s own top-level CMakeLists.txt does for the EBGeometry::EBGeometry interface target; passing -DEBGEOMETRY_SIMD=... when configuring the top-level project (or a project that pulls it in via add_subdirectory) controls it directly. Configure and build:

cmake -B build -DEBGEOMETRY_SIMD=avx512
cmake --build build -j$(nproc)

See Configuration options for what SIMD acceleration means for EBGeometry.

Enabling assertions in CMake

option(EBGEOMETRY_ENABLE_ASSERTIONS "Enable EBGeometry runtime assertions" OFF)

if(EBGEOMETRY_ENABLE_ASSERTIONS)
  target_compile_definitions(my_program PRIVATE EBGEOMETRY_ENABLE_ASSERTIONS)
endif()

Then at configure time:

cmake -B build -DEBGEOMETRY_ENABLE_ASSERTIONS=ON -DCMAKE_BUILD_TYPE=Debug
cmake --build build

See Configuration options for assertion semantics and the recommended build-type/assertion matrix.

Tip

If you are building EBGeometry itself (rather than consuming it from another project) — for example to run its unit test suite or the bundled examples — the repository ships ready-made CMake presets that set these options for you. See Running the unit tests locally.

GNU make

A minimal Makefile

A minimal Makefile that compiles a single main.cpp against EBGeometry:

# Path to the root of the EBGeometry source tree
EBGEOMETRY_DIR := /path/to/EBGeometry

CXX      := g++
CXXFLAGS := -std=c++17 -O3 -mavx -mfma -msse4.1
CXXFLAGS += -I$(EBGEOMETRY_DIR)

# Uncomment to enable runtime assertions:
# CXXFLAGS += -DEBGEOMETRY_ENABLE_ASSERTIONS

TARGET   := my_program
SRCS     := main.cpp

$(TARGET): $(SRCS)
     $(CXX) $(CXXFLAGS) $^ -o $@

.PHONY: clean
clean:
     rm -f $(TARGET)

Because EBGeometry is header-only, there are no object files or static libraries to build; the $(TARGET) rule is the only build step required. Every example under Examples/<something> ships a GNUmakefile following this same pattern — see Overview.

Conditional SIMD selection

To choose the SIMD level at make-time rather than hard-coding it:

EBGEOMETRY_DIR := /path/to/EBGeometry

CXX      := g++
CXXFLAGS := -std=c++17 -O3 -I$(EBGEOMETRY_DIR)

# SIMD=avx (default), sse41, or none
SIMD ?= avx
ifeq ($(SIMD),avx)
  CXXFLAGS += -mavx -mfma -msse4.1
else ifeq ($(SIMD),sse41)
  CXXFLAGS += -msse4.1
endif

# Assertions: make ASSERTIONS=1 to enable
ifeq ($(ASSERTIONS),1)
  CXXFLAGS += -DEBGEOMETRY_ENABLE_ASSERTIONS
endif

TARGET := my_program
$(TARGET): main.cpp
     $(CXX) $(CXXFLAGS) $< -o $@

Invoke with, for example:

make SIMD=avx                    # AVX + FMA (default)
make SIMD=sse41 ASSERTIONS=1     # SSE4.1, assertions on
make SIMD=none                   # scalar fallback

See Configuration options for what SIMD acceleration means for EBGeometry, and for the semantics of EBGEOMETRY_ENABLE_ASSERTIONS.

Direct compilation

EBGeometry is header-only, so the simplest way to use it is to point your compiler’s include path directly at the repository and compile. There is no library to build or link against.

Minimal build

The only mandatory flag is an include path:

g++ -std=c++17 -O3 -I/path/to/EBGeometry main.cpp -o my_program

Replace g++ with clang++, icpx, or another C++17-capable compiler as needed.

Note

-O3 is strongly recommended. The innermost loops (BVH traversal, SIMD triangle evaluation, and SDF queries) contain tight if constexpr branches and inlined intrinsics that only collapse into efficient machine code with full optimisation enabled.

Enabling SIMD acceleration

EBGeometry detects the available SIMD instruction set at compile time using the standard pre-defined macros __AVX512F__, __AVX__, __SSE4_1__, and __FMA__. Pass the corresponding flags to expose the widest register set supported by your CPU:

Target ISA

GCC / Clang flag(s)

AVX-512F (recent server/HEDT CPUs)

-mavx512f -mfma

AVX + FMA (recommended on x86-64 since ~2013)

-mavx -mfma

SSE 4.1 (older or constrained targets)

-msse4.1

No SIMD (portable fallback)

(none)

A typical production build targeting a modern x86-64 workstation:

g++ -std=c++17 -O3 -mavx -mfma -msse4.1 \
    -I/path/to/EBGeometry \
    main.cpp -o my_program

The -msse4.1 flag is subsumed by -mavx on GCC but is harmless to include. On Apple Silicon (M-series) no flag is needed — the library automatically uses the scalar path, which remains correct though not SIMD-vectorised.

Tip

Use -march=native to let the compiler choose every ISA extension supported by the build machine. This gives the fastest binary but produces a non-portable executable:

g++ -std=c++17 -O3 -march=native \
    -I/path/to/EBGeometry \
    main.cpp -o my_program

See Configuration options for what SIMD acceleration means for EBGeometry.

Enabling runtime assertions

EBGeometry ships an assertion macro EBGEOMETRY_EXPECT(cond) (defined in Source/EBGeometry_Macros.hpp, included automatically through the library), disabled by default. To activate it:

g++ -std=c++17 -O0 -g \
    -DEBGEOMETRY_ENABLE_ASSERTIONS \
    -I/path/to/EBGeometry \
    main.cpp -o my_program_debug

See Configuration options for assertion semantics, the diagnostic message format, and the recommended build-type/assertion matrix.