* format cmake files * update format.sh * fix linker flags for emscripten * update readme * use gersemi * actual format * should be public instead of interface * make test work without download * simplification * format
444 lines
13 KiB
CMake
444 lines
13 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)
|
|
|
|
# Define Manifold version
|
|
set(MANIFOLD_VERSION_MAJOR 2)
|
|
set(MANIFOLD_VERSION_MINOR 5)
|
|
set(MANIFOLD_VERSION_PATCH 1)
|
|
set(
|
|
MANIFOLD_VERSION
|
|
"${MANIFOLD_VERSION_MAJOR}.${MANIFOLD_VERSION_MINOR}.${MANIFOLD_VERSION_PATCH}"
|
|
)
|
|
|
|
# Correct MANIFOLD_PAR values to on/off (previous NONE/TBB values should still
|
|
# work this way)
|
|
if(DEFINED MANIFOLD_PAR)
|
|
if(
|
|
"${MANIFOLD_PAR}" STREQUAL ""
|
|
OR "${MANIFOLD_PAR}" STREQUAL "NONE"
|
|
OR "${MANIFOLD_PAR}" STREQUAL "OFF"
|
|
)
|
|
set(MANIFOLD_PAR OFF)
|
|
else()
|
|
set(MANIFOLD_PAR ON)
|
|
endif()
|
|
endif()
|
|
|
|
# Primary user facing options
|
|
option(MANIFOLD_CROSS_SECTION "Build CrossSection for 2D support" ON)
|
|
option(MANIFOLD_DEBUG "Enable debug tracing/timing" OFF)
|
|
option(
|
|
MANIFOLD_DOWNLOADS
|
|
"Allow Manifold build to download missing dependencies"
|
|
ON
|
|
)
|
|
option(MANIFOLD_EXCEPTIONS "Build manifold with exception enabled" ON)
|
|
option(MANIFOLD_EXPORT "Build mesh export (via assimp) utility library" OFF)
|
|
option(MANIFOLD_PAR "Enable Parallel backend" OFF)
|
|
option(MANIFOLD_TEST "Enable testing suite" ON)
|
|
option(BUILD_SHARED_LIBS "Build shared library" ON)
|
|
include(CMakeDependentOption)
|
|
cmake_dependent_option(
|
|
MANIFOLD_CBIND
|
|
"Build C (FFI) bindings"
|
|
ON
|
|
"MANIFOLD_CROSS_SECTION"
|
|
OFF
|
|
)
|
|
option(MANIFOLD_PYBIND "Build python bindings" OFF)
|
|
cmake_dependent_option(
|
|
MANIFOLD_JSBIND
|
|
"Build js binding"
|
|
ON
|
|
"EMSCRIPTEN"
|
|
OFF
|
|
)
|
|
|
|
# Set some option values in the CMake cache
|
|
if(NOT MANIFOLD_FLAGS)
|
|
set(MANIFOLD_FLAGS "")
|
|
endif()
|
|
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(BUILD_TEST_CGAL "Build CGAL performance comparisons" OFF)
|
|
mark_as_advanced(TRACY_ENABLE)
|
|
mark_as_advanced(TRACY_MEMORY_USAGE)
|
|
mark_as_advanced(BUILD_TEST_CGAL)
|
|
|
|
# fuzztest is a rather large dependency
|
|
option(MANIFOLD_FUZZ "Enable fuzzing tests" OFF)
|
|
mark_as_advanced(MANIFOLD_FUZZ)
|
|
|
|
# Define some paths for CMake
|
|
include(GNUInstallDirs)
|
|
|
|
# Always build position independent code for relocatability
|
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
|
|
|
# Various Compiler Flags
|
|
if(MANIFOLD_FUZZ)
|
|
if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
|
message(FATAL_ERROR "fuzztest only supports clang")
|
|
endif()
|
|
# we should enable debug checks
|
|
set(MANIFOLD_DEBUG ON)
|
|
# enable fuzztest fuzzing mode
|
|
set(FUZZTEST_FUZZING_MODE ON)
|
|
# address sanitizer required
|
|
list(APPEND CMAKE_CXX_FLAGS -fsanitize=address)
|
|
endif()
|
|
|
|
if(TRACY_ENABLE)
|
|
option(CMAKE_BUILD_TYPE "Build type" RelWithDebInfo)
|
|
if(TRACY_MEMORY_USAGE)
|
|
list(APPEND MANIFOLD_FLAGS -DTRACY_MEMORY_USAGE)
|
|
endif()
|
|
if(NOT MSVC)
|
|
list(APPEND CMAKE_CXX_FLAGS -fno-omit-frame-pointer)
|
|
endif()
|
|
else()
|
|
option(CMAKE_BUILD_TYPE "Build type" Release)
|
|
endif()
|
|
|
|
if(EMSCRIPTEN)
|
|
message("Building for Emscripten")
|
|
if(MANIFOLD_EXCEPTIONS)
|
|
list(APPEND MANIFOLD_FLAGS -fexceptions)
|
|
string(
|
|
APPEND
|
|
CMAKE_EXE_LINKER_FLAGS
|
|
"-sALLOW_MEMORY_GROWTH=1 -fexceptions -sDISABLE_EXCEPTION_CATCHING=0 "
|
|
)
|
|
else()
|
|
string(APPEND CMAKE_EXE_LINKER_FLAGS "-sALLOW_MEMORY_GROWTH=1 ")
|
|
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)
|
|
else()
|
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|
list(
|
|
APPEND
|
|
WARNING_FLAGS
|
|
-Wall
|
|
-Wno-unused
|
|
-Wno-array-bounds
|
|
-Wno-stringop-overflow
|
|
-Wno-alloc-size-larger-than
|
|
)
|
|
else()
|
|
list(APPEND WARNING_FLAGS -Wall -Wno-unused -Wno-shorten-64-to-32)
|
|
endif()
|
|
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|
list(APPEND WARNING_FLAGS -Wno-format)
|
|
endif()
|
|
else()
|
|
list(APPEND WARNING_FLAGS -Werror)
|
|
endif()
|
|
list(APPEND MANIFOLD_FLAGS ${WARNING_FLAGS})
|
|
endif()
|
|
|
|
if(CODE_COVERAGE AND NOT MSVC)
|
|
list(
|
|
APPEND
|
|
COVERAGE_FLAGS
|
|
-coverage
|
|
-fno-inline-small-functions
|
|
-fkeep-inline-functions
|
|
-fkeep-static-functions
|
|
)
|
|
list(APPEND MANIFOLD_FLAGS ${COVERAGE_FLAGS})
|
|
add_link_options("-coverage")
|
|
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")
|
|
|
|
# Dependencies
|
|
include(FetchContent)
|
|
|
|
function(logmissingdep PKG)
|
|
if(NOT MANIFOLD_DOWNLOADS)
|
|
if(ARGC EQUAL 3)
|
|
set(MSG "${ARGV2} enabled, but ${PKG} was not found ")
|
|
string(APPEND MSG "and dependency downloading is disabled. ")
|
|
else()
|
|
set(MSG "${PKG} not found, and dependency downloading disabled. ")
|
|
endif()
|
|
string(APPEND MSG "Please install ${PKG} and reconfigure.\n")
|
|
message(FATAL_ERROR ${MSG})
|
|
endif()
|
|
endfunction()
|
|
|
|
# GLM is required in all configurations.
|
|
find_package(glm QUIET)
|
|
if(NOT glm_FOUND)
|
|
logmissingdep("glm")
|
|
message(STATUS "glm not found, downloading from source")
|
|
set(GLM_BUILD_INSTALL "ON" CACHE STRING "")
|
|
FetchContent_Declare(
|
|
glm
|
|
GIT_REPOSITORY https://github.com/g-truc/glm.git
|
|
GIT_TAG 1.0.1
|
|
GIT_PROGRESS TRUE
|
|
)
|
|
FetchContent_MakeAvailable(glm)
|
|
if(NOT EMSCRIPTEN)
|
|
install(TARGETS glm)
|
|
endif()
|
|
endif()
|
|
|
|
# If we're building parallel, we need the requisite libraries
|
|
if(MANIFOLD_PAR)
|
|
find_package(Threads REQUIRED)
|
|
find_package(TBB QUIET)
|
|
find_package(PkgConfig QUIET)
|
|
if(NOT TBB_FOUND AND PKG_CONFIG_FOUND)
|
|
pkg_check_modules(TBB tbb)
|
|
endif()
|
|
if(NOT TBB_FOUND)
|
|
logmissingdep("TBB" , "Parallel mode")
|
|
# TODO - this isn't recommended by the TBB upstream - should we be
|
|
# doing it?
|
|
message(STATUS "TBB not found, downloading from source")
|
|
set(TBB_TEST OFF CACHE INTERNAL "" FORCE)
|
|
set(TBB_STRICT OFF CACHE INTERNAL "" FORCE)
|
|
FetchContent_Declare(
|
|
TBB
|
|
GIT_REPOSITORY https://github.com/oneapi-src/oneTBB.git
|
|
GIT_TAG v2021.11.0
|
|
GIT_PROGRESS TRUE
|
|
)
|
|
FetchContent_MakeAvailable(TBB)
|
|
set_property(DIRECTORY ${tbb_SOURCE_DIR} PROPERTY EXCLUDE_FROM_ALL YES)
|
|
# note: we do want to install tbb to the user machine when built from
|
|
# source
|
|
if(NOT EMSCRIPTEN)
|
|
install(TARGETS tbb)
|
|
endif()
|
|
endif()
|
|
endif()
|
|
|
|
# If we're building cross_section, we need Clipper2
|
|
if(MANIFOLD_CROSS_SECTION)
|
|
find_package(Clipper2 QUIET)
|
|
if(NOT Clipper2_FOUND AND PKG_CONFIG_FOUND)
|
|
pkg_check_modules(Clipper2 Clipper2)
|
|
endif()
|
|
if(Clipper2_FOUND)
|
|
add_library(Clipper2 SHARED IMPORTED)
|
|
set_property(
|
|
TARGET Clipper2
|
|
PROPERTY IMPORTED_LOCATION ${Clipper2_LINK_LIBRARIES}
|
|
)
|
|
if(WIN32)
|
|
set_property(
|
|
TARGET Clipper2
|
|
PROPERTY IMPORTED_IMPLIB ${Clipper2_LINK_LIBRARIES}
|
|
)
|
|
endif()
|
|
target_include_directories(Clipper2 INTERFACE ${Clipper2_INCLUDE_DIRS})
|
|
else()
|
|
logmissingdep("Clipper2" , "cross_section")
|
|
message(STATUS "clipper2 not found, downloading from source")
|
|
set(CLIPPER2_UTILS OFF)
|
|
set(CLIPPER2_EXAMPLES OFF)
|
|
set(CLIPPER2_TESTS OFF)
|
|
set(
|
|
CLIPPER2_USINGZ
|
|
"OFF"
|
|
CACHE STRING
|
|
"Preempt cache default of USINGZ (we only use 2d)"
|
|
)
|
|
FetchContent_Declare(
|
|
Clipper2
|
|
GIT_REPOSITORY https://github.com/AngusJohnson/Clipper2.git
|
|
GIT_TAG ff378668baae3570e9d8070aa9eb339bdd5a6aba
|
|
GIT_PROGRESS TRUE
|
|
SOURCE_SUBDIR CPP
|
|
)
|
|
FetchContent_MakeAvailable(Clipper2)
|
|
if(NOT EMSCRIPTEN)
|
|
install(TARGETS Clipper2)
|
|
endif()
|
|
endif()
|
|
endif()
|
|
|
|
# If we're supporting mesh I/O, we need assimp
|
|
if(MANIFOLD_EXPORT)
|
|
find_package(assimp REQUIRED)
|
|
endif()
|
|
|
|
add_subdirectory(src)
|
|
add_subdirectory(bindings)
|
|
add_subdirectory(samples)
|
|
add_subdirectory(test)
|
|
add_subdirectory(extras)
|
|
|
|
# configuration summary, idea from openscad
|
|
# https://github.com/openscad/openscad/blob/master/cmake/Modules/info.cmake
|
|
message(STATUS "====================================")
|
|
message(STATUS "Manifold Build Configuration Summary")
|
|
message(STATUS "====================================")
|
|
message(STATUS " ")
|
|
if(MXECROSS)
|
|
message(STATUS "Environment: MXE")
|
|
elseif(APPLE)
|
|
message(STATUS "Environment: macOS")
|
|
elseif(WIN32)
|
|
if(MINGW)
|
|
message(STATUS "Environment: msys2")
|
|
else()
|
|
message(STATUS "Environment: Windows")
|
|
endif()
|
|
elseif(LINUX)
|
|
message(STATUS "Environment: Linux")
|
|
elseif(UNIX)
|
|
message(STATUS "Environment: Unknown Unix")
|
|
else()
|
|
message(STATUS "Environment: Unknown")
|
|
endif()
|
|
message(STATUS " ")
|
|
message(STATUS "CMAKE_VERSION: ${CMAKE_VERSION}")
|
|
message(STATUS "CMAKE_TOOLCHAIN_FILE: ${CMAKE_TOOLCHAIN_FILE}")
|
|
message(STATUS "CMAKE_GENERATOR: ${CMAKE_GENERATOR}")
|
|
message(STATUS "CPACK_CMAKE_GENERATOR: ${CPACK_CMAKE_GENERATOR}")
|
|
message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
|
|
message(STATUS "CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}")
|
|
message(STATUS "CMAKE_CXX_COMPILER_ID: ${CMAKE_CXX_COMPILER_ID}")
|
|
message(STATUS "CMAKE_CXX_COMPILER_VERSION: ${CMAKE_CXX_COMPILER_VERSION}")
|
|
if(APPLE)
|
|
message(STATUS "CMAKE_OSX_DEPLOYMENT_TARGET: ${CMAKE_OSX_DEPLOYMENT_TARGET}")
|
|
message(STATUS "CMAKE_OSX_ARCHITECTURES: ${CMAKE_OSX_ARCHITECTURES}")
|
|
endif()
|
|
message(STATUS "BUILD_SHARED_LIBS: ${BUILD_SHARED_LIBS}")
|
|
message(STATUS " ")
|
|
message(STATUS "MANIFOLD_PAR: ${MANIFOLD_PAR}")
|
|
message(STATUS "MANIFOLD_FLAGS: ${MANIFOLD_FLAGS}")
|
|
message(STATUS "MANIFOLD_EXPORT: ${MANIFOLD_EXPORT}")
|
|
message(STATUS "MANIFOLD_TEST: ${MANIFOLD_TEST}")
|
|
message(STATUS "MANIFOLD_FUZZ: ${MANIFOLD_FUZZ}")
|
|
message(STATUS "MANIFOLD_DEBUG: ${MANIFOLD_DEBUG}")
|
|
message(STATUS "MANIFOLD_CBIND: ${MANIFOLD_CBIND}")
|
|
message(STATUS "MANIFOLD_PYBIND: ${MANIFOLD_PYBIND}")
|
|
message(STATUS "MANIFOLD_JSBIND: ${MANIFOLD_JSBIND}")
|
|
message(STATUS "MANIFOLD_EXCEPTIONS: ${MANIFOLD_EXCEPTIONS}")
|
|
message(STATUS " ")
|
|
|
|
# If it's an EMSCRIPTEN build, we're done
|
|
if(EMSCRIPTEN)
|
|
return()
|
|
endif()
|
|
|
|
# CMake exports
|
|
configure_file(
|
|
manifoldConfig.cmake.in
|
|
${CMAKE_CURRENT_BINARY_DIR}/manifoldConfig.cmake
|
|
@ONLY
|
|
)
|
|
include(CMakePackageConfigHelpers)
|
|
write_basic_package_version_file(
|
|
${CMAKE_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
|
|
include/manifold/common.h
|
|
include/manifold/iters.h
|
|
include/manifold/manifold.h
|
|
include/manifold/optional_assert.h
|
|
include/manifold/parallel.h
|
|
include/manifold/polygon.h
|
|
include/manifold/vec_view.h
|
|
)
|
|
|
|
if(MANIFOLD_CROSS_SECTION)
|
|
list(APPEND MANIFOLD_PUBLIC_HDRS include/manifold/cross_section.h)
|
|
endif()
|
|
|
|
if(MANIFOLD_EXPORT)
|
|
list(APPEND MANIFOLD_PUBLIC_HDRS include/manifold/meshIO.h)
|
|
endif()
|
|
|
|
install(
|
|
FILES ${MANIFOLD_PUBLIC_HDRS}
|
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/manifold
|
|
)
|
|
|
|
# PkgConfig file
|
|
if(MANIFOLD_CROSS_SECTION)
|
|
set(TEMPLATE_OPTIONAL_CLIPPER "Clipper2")
|
|
endif()
|
|
configure_file(manifold.pc.in ${CMAKE_CURRENT_BINARY_DIR}/manifold.pc @ONLY)
|
|
install(
|
|
FILES ${CMAKE_CURRENT_BINARY_DIR}/manifold.pc
|
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
|
|
)
|