Strips iostream- and filesystem-using bits from the public API and tests, for freestanding/embedded consumers (e.g., wasm32-unknown-unknown via wasm-cxx-shim). Default OFF. When ON, defines MANIFOLD_NO_IOSTREAM and MANIFOLD_NO_FILESYSTEM as PUBLIC compile defs on manifold, gates iostream-using TESTs at compile time, and triggers CLIPPER2_NO_IOSTREAM=ON for the bundled Clipper2 via a carry-patch tracking AngusJohnson/Clipper2#1094 (drops once that lands and the SHA pin moves past it). Incompatible with MANIFOLD_DEBUG / MANIFOLD_TIMING (FATAL_ERROR). Discussion: https://github.com/elalish/manifold/discussions/1046 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
340 lines
10 KiB
CMake
340 lines
10 KiB
CMake
# Copyright 2020 The Manifold Authors.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# https://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
cmake_minimum_required(VERSION 3.18)
|
|
project(manifold LANGUAGES CXX)
|
|
|
|
# Use C++17
|
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
|
set(CMAKE_CXX_STANDARD 17)
|
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
|
|
set(CMAKE_VERBOSE_MAKEFILE ON)
|
|
|
|
include(CTest)
|
|
enable_testing()
|
|
include(GNUInstallDirs)
|
|
include(CMakeDependentOption)
|
|
|
|
# Define Manifold version
|
|
set(MANIFOLD_VERSION_MAJOR 3)
|
|
set(MANIFOLD_VERSION_MINOR 4)
|
|
set(MANIFOLD_VERSION_PATCH 1)
|
|
set(
|
|
MANIFOLD_VERSION
|
|
"${MANIFOLD_VERSION_MAJOR}.${MANIFOLD_VERSION_MINOR}.${MANIFOLD_VERSION_PATCH}"
|
|
)
|
|
|
|
# Primary user facing options
|
|
option(MANIFOLD_CROSS_SECTION "Build CrossSection for 2D support" ON)
|
|
option(MANIFOLD_DEBUG "Enable debug tracing/timing" OFF)
|
|
option(MANIFOLD_ASSERT "Enable assertions - requires MANIFOLD_DEBUG" OFF)
|
|
option(MANIFOLD_TIMING "Enable Boolean3 phase timing without debug overhead" OFF)
|
|
option(MANIFOLD_STRICT "Treat compile warnings as fatal build errors" OFF)
|
|
option(
|
|
MANIFOLD_NO_IOSTREAM
|
|
"Strip iostream- and filesystem-using bits from the public API and tests; useful for freestanding/embedded builds. When ON, defines both MANIFOLD_NO_IOSTREAM and MANIFOLD_NO_FILESYSTEM."
|
|
OFF
|
|
)
|
|
option(
|
|
MANIFOLD_DOWNLOADS
|
|
"Allow Manifold build to download missing dependencies"
|
|
ON
|
|
)
|
|
option(MANIFOLD_PAR "Enable Parallel backend" OFF)
|
|
option(
|
|
MANIFOLD_OPTIMIZED
|
|
"Force optimized build, even with debugging enabled"
|
|
OFF
|
|
)
|
|
option(MANIFOLD_TEST "Enable testing suite" ON)
|
|
option(MANIFOLD_PYBIND "Build python bindings" OFF)
|
|
# MANIFOLD_CBIND is only available when MANIFOLD_CROSS_SECTION is enabled
|
|
cmake_dependent_option(
|
|
MANIFOLD_CBIND
|
|
"Build C (FFI) bindings"
|
|
ON
|
|
"MANIFOLD_CROSS_SECTION"
|
|
OFF
|
|
)
|
|
# MANIFOLD_JSBIND is only available when building with Emscripten
|
|
cmake_dependent_option(
|
|
MANIFOLD_JSBIND
|
|
"Build js binding"
|
|
ON
|
|
"EMSCRIPTEN"
|
|
OFF
|
|
)
|
|
# These three options can force the build to avoid using the system version of
|
|
# the dependency
|
|
# This will either use the provided source directory via
|
|
# FETCHCONTENT_SOURCE_DIR_XXX, or fetch the source from GitHub.
|
|
# Note that the dependency will be built as static dependency to avoid dynamic
|
|
# library conflict.
|
|
# When the system package is unavailable, the option will be automatically set
|
|
# to true.
|
|
option(MANIFOLD_USE_BUILTIN_TBB "Use builtin tbb" OFF)
|
|
option(MANIFOLD_USE_BUILTIN_CLIPPER2 "Use builtin clipper2" OFF)
|
|
option(MANIFOLD_USE_BUILTIN_NANOBIND "Use builtin nanobind" OFF)
|
|
|
|
# default to Release build
|
|
option(CMAKE_BUILD_TYPE "Build type" Release)
|
|
# default to building shared library
|
|
option(BUILD_SHARED_LIBS "Build shared library" ON)
|
|
# Set some option values in the CMake cache
|
|
set(MANIFOLD_FLAGS "" CACHE STRING "Manifold compiler flags")
|
|
|
|
# Development options
|
|
option(TRACY_ENABLE "Use tracy profiling" OFF)
|
|
option(TRACY_MEMORY_USAGE "Track memory allocation with tracy (expensive)" OFF)
|
|
option(MANIFOLD_FUZZ "Enable fuzzing tests" OFF)
|
|
option(ASSIMP_ENABLE "Enable ASSIMP for utilities in extras" OFF)
|
|
mark_as_advanced(TRACY_ENABLE)
|
|
mark_as_advanced(TRACY_MEMORY_USAGE)
|
|
mark_as_advanced(MANIFOLD_FUZZ)
|
|
mark_as_advanced(ASSIMP_ENABLE)
|
|
|
|
# MANIFOLD_NO_IOSTREAM strips iostream- and filesystem-using bits
|
|
# from the public API and from the test files that use them.
|
|
# Incompatible with options that emit diagnostic output via iostream:
|
|
# MANIFOLD_DEBUG and MANIFOLD_TIMING (both use std::cout).
|
|
# MANIFOLD_TEST=ON is supported — iostream-using TEST(...) blocks
|
|
# in manifold_test/polygon_test/manifoldc_test are gated out under
|
|
# the macro; the test executable still builds and runs the rest.
|
|
if(MANIFOLD_NO_IOSTREAM AND (MANIFOLD_DEBUG OR MANIFOLD_TIMING))
|
|
message(FATAL_ERROR
|
|
"MANIFOLD_NO_IOSTREAM is incompatible with MANIFOLD_DEBUG / MANIFOLD_TIMING "
|
|
"(those options use std::cout for diagnostic output).")
|
|
endif()
|
|
|
|
# Always build position independent code for relocatability
|
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
|
|
|
# Various Compiler Flags
|
|
if(MANIFOLD_FUZZ)
|
|
# we should enable debug checks
|
|
set(MANIFOLD_DEBUG ON)
|
|
# enable fuzztest fuzzing mode
|
|
set(FUZZTEST_FUZZING_MODE ON)
|
|
# address sanitizer required
|
|
add_compile_options(-fsanitize=address)
|
|
add_link_options(-fsanitize=address)
|
|
endif()
|
|
|
|
if(TRACY_ENABLE)
|
|
option(CMAKE_BUILD_TYPE "Build type" RelWithDebInfo)
|
|
endif()
|
|
|
|
if(EMSCRIPTEN)
|
|
message("Building for Emscripten")
|
|
add_link_options(-sALLOW_MEMORY_GROWTH=1)
|
|
add_link_options(-sMAXIMUM_MEMORY=4294967296)
|
|
if(MANIFOLD_PAR)
|
|
set(CMAKE_THREAD_LIBS_INIT "-pthread")
|
|
add_compile_options(-pthread)
|
|
# mimalloc is needed for good performance
|
|
add_link_options(-sMALLOC=mimalloc)
|
|
add_link_options(-sPTHREAD_POOL_SIZE=4)
|
|
# The default stack size apparently causes problem when parallelization is
|
|
# enabled.
|
|
add_link_options(-sSTACK_SIZE=30MB)
|
|
add_link_options(-sINITIAL_MEMORY=32MB)
|
|
endif()
|
|
if(MANIFOLD_DEBUG)
|
|
list(APPEND MANIFOLD_FLAGS -fexceptions)
|
|
add_link_options(-fexceptions)
|
|
add_link_options(-sDISABLE_EXCEPTION_CATCHING=0)
|
|
endif()
|
|
set(MANIFOLD_PYBIND OFF)
|
|
set(BUILD_SHARED_LIBS OFF)
|
|
endif()
|
|
|
|
if(CMAKE_EXPORT_COMPILE_COMMANDS AND NOT EMSCRIPTEN)
|
|
# for nixos
|
|
set(
|
|
CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES
|
|
${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}
|
|
)
|
|
endif()
|
|
|
|
if(MSVC)
|
|
list(APPEND MANIFOLD_FLAGS /DNOMINMAX /bigobj /fp:precise)
|
|
else()
|
|
list(
|
|
APPEND
|
|
WARNING_FLAGS
|
|
-Wall
|
|
-Wno-unknown-warning-option
|
|
-Wno-unused
|
|
-Wno-shorten-64-to-32
|
|
-Wno-sign-compare
|
|
-Wno-alloc-size-larger-than
|
|
)
|
|
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|
list(APPEND WARNING_FLAGS -Wno-format)
|
|
endif()
|
|
elseif(PROJECT_IS_TOP_LEVEL)
|
|
# only do -Werror if we are the top level project and
|
|
# MANIFOLD_STRICT is on
|
|
if(MANIFOLD_STRICT)
|
|
list(APPEND WARNING_FLAGS -Werror)
|
|
endif()
|
|
endif()
|
|
list(APPEND MANIFOLD_FLAGS ${WARNING_FLAGS})
|
|
if(
|
|
MANIFOLD_OPTIMIZED
|
|
OR "${CMAKE_BUILD_TYPE}" STREQUAL "Release"
|
|
OR "${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo"
|
|
)
|
|
list(APPEND MANIFOLD_FLAGS -O3)
|
|
endif()
|
|
if("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo")
|
|
list(APPEND MANIFOLD_FLAGS -fno-omit-frame-pointer)
|
|
endif()
|
|
# disable fp math optimizations, e.g. FMA for supported architectures, as
|
|
# this changes floating-point results
|
|
include(CheckCXXCompilerFlag)
|
|
check_cxx_compiler_flag(-ffp-contract=off HAS_FP_CONTRACT)
|
|
check_cxx_compiler_flag(-fexcess-precision=standard HAS_FP_PRECISION)
|
|
if(HAS_FP_CONTRACT)
|
|
list(APPEND MANIFOLD_FLAGS -ffp-contract=off)
|
|
endif()
|
|
if(HAS_FP_PRECISION)
|
|
list(APPEND MANIFOLD_FLAGS -fexcess-precision=standard)
|
|
endif()
|
|
if(CODE_COVERAGE)
|
|
list(
|
|
APPEND
|
|
MANIFOLD_FLAGS
|
|
-coverage
|
|
-fno-inline-small-functions
|
|
-fkeep-inline-functions
|
|
-fkeep-static-functions
|
|
)
|
|
add_link_options(-coverage)
|
|
endif()
|
|
endif()
|
|
|
|
# RPath settings
|
|
set(CMAKE_SKIP_BUILD_RPATH FALSE)
|
|
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
|
|
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})
|
|
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
|
list(
|
|
FIND
|
|
CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES
|
|
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}
|
|
isSystemDir
|
|
)
|
|
if("${isSystemDir}" STREQUAL "-1")
|
|
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})
|
|
endif("${isSystemDir}" STREQUAL "-1")
|
|
|
|
include(${PROJECT_SOURCE_DIR}/cmake/manifoldDeps.cmake)
|
|
include(${PROJECT_SOURCE_DIR}/cmake/configHelper.cmake)
|
|
|
|
add_subdirectory(src)
|
|
add_subdirectory(bindings)
|
|
if(MANIFOLD_TEST)
|
|
add_subdirectory(samples)
|
|
add_subdirectory(test)
|
|
add_subdirectory(extras)
|
|
endif()
|
|
|
|
include(${PROJECT_SOURCE_DIR}/cmake/info.cmake)
|
|
|
|
# note that the path ${CMAKE_CURRENT_BINARY_DIR}/include is included when we
|
|
# build the manifold target (as ${PROJECT_SOURCE_DIR}/include), so users can
|
|
# include manifold/version.h without installing our library.
|
|
configure_file(
|
|
cmake/version.h.in
|
|
${CMAKE_CURRENT_BINARY_DIR}/include/manifold/version.h
|
|
@ONLY
|
|
)
|
|
set_source_files_properties(
|
|
${CMAKE_CURRENT_BINARY_DIR}/include/manifold/version.h
|
|
PROPERTIES GENERATED TRUE
|
|
)
|
|
|
|
# CMake exports
|
|
configure_file(
|
|
cmake/manifoldConfig.cmake.in
|
|
${CMAKE_CURRENT_BINARY_DIR}/manifoldConfig.cmake
|
|
@ONLY
|
|
)
|
|
include(CMakePackageConfigHelpers)
|
|
write_basic_package_version_file(
|
|
${CMAKE_CURRENT_BINARY_DIR}/cmake/manifoldConfigVersion.cmake
|
|
VERSION ${MANIFOLD_VERSION}
|
|
COMPATIBILITY SameMajorVersion
|
|
)
|
|
|
|
# Location of inputs for CMake find_package - see:
|
|
# https://cmake.org/cmake/help/latest/command/find_package.html
|
|
set(EXPORT_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake)
|
|
|
|
install(
|
|
EXPORT manifoldTargets
|
|
NAMESPACE manifold::
|
|
DESTINATION ${EXPORT_INSTALL_DIR}/manifold
|
|
)
|
|
install(
|
|
FILES
|
|
${CMAKE_CURRENT_BINARY_DIR}/cmake/manifoldConfigVersion.cmake
|
|
${CMAKE_CURRENT_BINARY_DIR}/manifoldConfig.cmake
|
|
DESTINATION ${EXPORT_INSTALL_DIR}/manifold
|
|
)
|
|
|
|
# install public headers
|
|
set(
|
|
MANIFOLD_PUBLIC_HDRS
|
|
common.h
|
|
math.h
|
|
linalg.h
|
|
manifold.h
|
|
optional_assert.h
|
|
polygon.h
|
|
vec_view.h
|
|
$<$<BOOL:${MANIFOLD_CROSS_SECTION}>:cross_section.h>
|
|
)
|
|
list(TRANSFORM MANIFOLD_PUBLIC_HDRS PREPEND include/manifold/)
|
|
list(
|
|
APPEND
|
|
MANIFOLD_PUBLIC_HDRS
|
|
${CMAKE_CURRENT_BINARY_DIR}/include/manifold/version.h
|
|
)
|
|
|
|
install(
|
|
FILES ${MANIFOLD_PUBLIC_HDRS}
|
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/manifold
|
|
)
|
|
|
|
# PkgConfig file
|
|
if(MANIFOLD_PAR)
|
|
set(TEMPLATE_OPTIONAL_TBB "tbb")
|
|
endif()
|
|
if(MANIFOLD_CROSS_SECTION)
|
|
set(TEMPLATE_OPTIONAL_CLIPPER "Clipper2")
|
|
endif()
|
|
configure_file(
|
|
cmake/manifold.pc.in
|
|
${CMAKE_CURRENT_BINARY_DIR}/manifold.pc
|
|
@ONLY
|
|
)
|
|
install(
|
|
FILES ${CMAKE_CURRENT_BINARY_DIR}/manifold.pc
|
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
|
|
)
|