138 lines
6.0 KiB
CMake
138 lines
6.0 KiB
CMake
cmake_minimum_required(VERSION 3.14)
|
|
project(trellis2.cpp VERSION 0.1.0 LANGUAGES C CXX)
|
|
|
|
set(CMAKE_CXX_STANDARD 14)
|
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
|
|
if(NOT CMAKE_BUILD_TYPE)
|
|
set(CMAKE_BUILD_TYPE Release)
|
|
endif()
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────
|
|
# External ggml option
|
|
#
|
|
# When OFF (default): vendor ggml as a subdirectory — the upstream behavior.
|
|
# When ON : skip the bundled ggml and resolve `find_package(ggml CONFIG)`
|
|
# against an installed ggml. Lets a downstream project link multiple
|
|
# ggml-based libraries against a single shared ggml so they don't
|
|
# ship duplicate copies into the same process.
|
|
# ─────────────────────────────────────────────────────────────────────────
|
|
option(TRELLIS2_USE_EXTERNAL_GGML "Consume external ggml via find_package() instead of the bundled submodule" OFF)
|
|
|
|
# libFuzzer harnesses (clang only). The sanitizer flags apply globally — set
|
|
# BEFORE any target so the whole tree (ggml, stb decode, preprocessing,
|
|
# loaders) is instrumented. Harness targets live in fuzz/ (added at the end).
|
|
option(TRELLIS2_FUZZ "Build libFuzzer harnesses (requires clang)" OFF)
|
|
set(TRELLIS2_FUZZ_SANITIZERS "address,undefined" CACHE STRING
|
|
"Sanitizers for the fuzz build")
|
|
if(TRELLIS2_FUZZ)
|
|
add_compile_options(-fsanitize=${TRELLIS2_FUZZ_SANITIZERS} -fsanitize=fuzzer-no-link -fno-omit-frame-pointer -g -O1)
|
|
add_link_options(-fsanitize=${TRELLIS2_FUZZ_SANITIZERS})
|
|
endif()
|
|
|
|
# ggml options — enable Metal on Apple (bundled-ggml path only)
|
|
option(TRELLIS2_METAL "Enable Metal backend" ON)
|
|
if(APPLE AND TRELLIS2_METAL AND NOT TRELLIS2_USE_EXTERNAL_GGML)
|
|
set(GGML_METAL ON CACHE BOOL "" FORCE)
|
|
set(GGML_METAL_EMBED_LIBRARY ON CACHE BOOL "" FORCE)
|
|
endif()
|
|
|
|
if(TRELLIS2_USE_EXTERNAL_GGML)
|
|
find_package(ggml CONFIG REQUIRED)
|
|
set(TRELLIS2_GGML_TARGET ggml::ggml)
|
|
else()
|
|
add_subdirectory(ggml)
|
|
set(TRELLIS2_GGML_TARGET ggml)
|
|
endif()
|
|
|
|
add_library(trellis2
|
|
trellis2.cpp trellis2.h
|
|
trellis2_capi.cpp trellis2_capi.h
|
|
mesh_export.cpp mesh_export.h
|
|
print_remesh.cpp print_remesh.h
|
|
third_party/xatlas/xatlas.cpp)
|
|
target_include_directories(trellis2 PUBLIC
|
|
${CMAKE_CURRENT_SOURCE_DIR}
|
|
${CMAKE_CURRENT_SOURCE_DIR}/stb
|
|
)
|
|
# trellis2_capi.cpp reuses the example isosurface extractor for the demo path;
|
|
# mesh_export.cpp vendors xatlas for the optional chart-based UV unwrap.
|
|
target_include_directories(trellis2 PRIVATE
|
|
${CMAKE_CURRENT_SOURCE_DIR}/examples
|
|
${CMAKE_CURRENT_SOURCE_DIR}/third_party/xatlas)
|
|
|
|
find_package(Threads REQUIRED) # xatlas uses std::thread
|
|
|
|
if(TRELLIS2_USE_EXTERNAL_GGML AND DEFINED GGML_INCLUDE_DIR)
|
|
target_include_directories(trellis2 PUBLIC ${GGML_INCLUDE_DIR})
|
|
endif()
|
|
|
|
target_link_libraries(trellis2 PUBLIC ${TRELLIS2_GGML_TARGET} PRIVATE Threads::Threads)
|
|
target_compile_features(trellis2 PUBLIC cxx_std_14)
|
|
|
|
# CGAL Alpha Wrap turns arbitrary TRELLIS triangle soups into watertight,
|
|
# intersection-free 2-manifolds for printing. Auto-detect it so ordinary builds
|
|
# retain no CGAL dependency; the C API reports whether the backend is present.
|
|
option(TRELLIS2_CGAL "Enable CGAL Alpha Wrap print remeshing when available" ON)
|
|
option(TRELLIS2_FETCH_PRINT_REMESH_DEPS
|
|
"Fetch the project-pinned CGAL and Boost headers for print remeshing" OFF)
|
|
set(TRELLIS2_PRINT_REMESH_DEPS_DIR "${CMAKE_BINARY_DIR}/_deps/print-remesh" CACHE PATH
|
|
"Directory containing project-pinned CGAL and Boost headers")
|
|
if(TRELLIS2_CGAL)
|
|
if(TRELLIS2_FETCH_PRINT_REMESH_DEPS)
|
|
find_program(TRELLIS2_BASH_EXECUTABLE bash)
|
|
if(NOT TRELLIS2_BASH_EXECUTABLE)
|
|
message(FATAL_ERROR "bash is required to fetch print-remesh dependencies")
|
|
endif()
|
|
execute_process(
|
|
COMMAND "${TRELLIS2_BASH_EXECUTABLE}"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/fetch_print_remesh_deps.sh"
|
|
"${TRELLIS2_PRINT_REMESH_DEPS_DIR}"
|
|
RESULT_VARIABLE TRELLIS2_PRINT_REMESH_DEPS_RESULT)
|
|
if(NOT TRELLIS2_PRINT_REMESH_DEPS_RESULT EQUAL 0)
|
|
message(FATAL_ERROR "Failed to fetch pinned print-remesh dependencies")
|
|
endif()
|
|
set(CGAL_DIR "${TRELLIS2_PRINT_REMESH_DEPS_DIR}/cgal" CACHE PATH
|
|
"CGAL package directory" FORCE)
|
|
set(Boost_INCLUDE_DIR "${TRELLIS2_PRINT_REMESH_DEPS_DIR}/boost" CACHE PATH
|
|
"Boost header directory" FORCE)
|
|
set(Boost_DIR "${TRELLIS2_PRINT_REMESH_DEPS_DIR}/boost-cmake" CACHE PATH
|
|
"Header-only Boost CMake package directory" FORCE)
|
|
endif()
|
|
find_package(CGAL 5.5 QUIET)
|
|
if(CGAL_FOUND)
|
|
target_link_libraries(trellis2 PRIVATE CGAL::CGAL)
|
|
target_compile_definitions(trellis2 PRIVATE TRELLIS2_USE_CGAL=1)
|
|
target_compile_features(trellis2 PRIVATE cxx_std_17)
|
|
set(TRELLIS2_HAVE_CGAL ON)
|
|
message(STATUS "CGAL Alpha Wrap print remeshing: enabled")
|
|
elseif(TRELLIS2_FETCH_PRINT_REMESH_DEPS)
|
|
message(FATAL_ERROR "The project-pinned CGAL print-remesh dependencies were fetched but not found")
|
|
else()
|
|
message(STATUS "CGAL Alpha Wrap print remeshing: unavailable (CGAL >= 5.5 not found)")
|
|
endif()
|
|
endif()
|
|
|
|
set_property(TARGET trellis2 PROPERTY POSITION_INDEPENDENT_CODE ON)
|
|
|
|
if(BUILD_SHARED_LIBS)
|
|
target_compile_definitions(trellis2 PUBLIC TRELLIS2_SHARED)
|
|
target_compile_definitions(trellis2 PRIVATE TRELLIS2_BUILD)
|
|
endif()
|
|
|
|
option(TRELLIS2_BUILD_EXAMPLES "Build example executables" ON)
|
|
if(TRELLIS2_BUILD_EXAMPLES AND CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
|
add_subdirectory(examples)
|
|
endif()
|
|
|
|
option(TRELLIS2_BUILD_TESTS "Build test executables" OFF)
|
|
if(TRELLIS2_BUILD_TESTS)
|
|
enable_testing()
|
|
add_subdirectory(tests)
|
|
endif()
|
|
|
|
if(TRELLIS2_FUZZ)
|
|
add_subdirectory(fuzz)
|
|
endif()
|