You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

354 lines
11 KiB
CMake

cmake_minimum_required(VERSION 3.15)
project(Clipper2 VERSION 1.5.2 LANGUAGES C CXX)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
if(NOT DEFINED CMAKE_CXX_STANDARD OR CMAKE_CXX_STANDARD LESS 17)
set(CMAKE_CXX_STANDARD 17)
endif()
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# CLIPPER2_HI_PRECISION: See GetIntersectPoint() in clipper.core.h
option(CLIPPER2_HI_PRECISION "Caution: enabling this will compromise performance" OFF)
option(CLIPPER2_UTILS "Build utilities" ON)
option(CLIPPER2_EXAMPLES "Build examples" ON)
option(CLIPPER2_TESTS "Build tests" ON)
option(USE_EXTERNAL_GTEST "Use system-wide installed GoogleTest" OFF)
option(USE_EXTERNAL_GBENCHMARK "Use the googlebenchmark" OFF)
option(BUILD_SHARED_LIBS "Build shared libs" OFF)
set(CLIPPER2_USINGZ "ON" CACHE STRING "Build Clipper2Z, either \"ON\" or \"OFF\" or \"ONLY\"")
# CLIPPER2_MAX_DECIMAL_PRECISION: maximum decimal precision when scaling PathsD to Paths64.
# Caution: excessive scaling will increase the likelihood of integer overflow errors.
set(CLIPPER2_MAX_DECIMAL_PRECISION 8 CACHE STRING "Maximum decimal precision range")
if (APPLE)
set(CMAKE_SHARED_LIBRARY_SUFFIX ".dylib")
endif ()
include(GNUInstallDirs)
set(CLIPPER2_INC_FOLDER ${PROJECT_SOURCE_DIR}/Clipper2Lib/include/clipper2)
configure_file(clipper.version.in
${CLIPPER2_INC_FOLDER}/clipper.version.h NEWLINE_STYLE UNIX)
set(CLIPPER2_INC
${CLIPPER2_INC_FOLDER}/clipper.h
${CLIPPER2_INC_FOLDER}/clipper.version.h
${CLIPPER2_INC_FOLDER}/clipper.core.h
${CLIPPER2_INC_FOLDER}/clipper.engine.h
${CLIPPER2_INC_FOLDER}/clipper.export.h
${CLIPPER2_INC_FOLDER}/clipper.minkowski.h
${CLIPPER2_INC_FOLDER}/clipper.offset.h
${CLIPPER2_INC_FOLDER}/clipper.rectclip.h
)
set(CLIPPER2_SRC
Clipper2Lib/src/clipper.engine.cpp
Clipper2Lib/src/clipper.offset.cpp
Clipper2Lib/src/clipper.rectclip.cpp
)
set(CLIPPER2_LIBS "") # one or both of Clipper2/Clipper2Z
# primary Clipper2 library
if (NOT (CLIPPER2_USINGZ STREQUAL "ONLY"))
list(APPEND CLIPPER2_LIBS Clipper2)
add_library(Clipper2 ${CLIPPER2_INC} ${CLIPPER2_SRC})
target_compile_definitions(
Clipper2 PUBLIC
CLIPPER2_MAX_DECIMAL_PRECISION=${CLIPPER2_MAX_DECIMAL_PRECISION}
$<$<BOOL:${CLIPPER2_HI_PRECISION}>:CLIPPER2_HI_PRECISION>
)
target_include_directories(
Clipper2 PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Clipper2Lib/include>
$<INSTALL_INTERFACE:include>
)
if (MSVC)
target_compile_options(Clipper2 PRIVATE /W4 /WX)
else()
target_compile_options(Clipper2 PRIVATE -Wall -Wextra -Wpedantic -Werror -Wno-c++20-compat)
target_link_libraries(Clipper2 PUBLIC -lm)
endif()
endif()
# secondary Clipper2 library with USINGZ defined (if required)
if (NOT (CLIPPER2_USINGZ STREQUAL "OFF"))
list(APPEND CLIPPER2_LIBS Clipper2Z)
add_library(Clipper2Z ${CLIPPER2_INC} ${CLIPPER2_SRC})
target_compile_definitions(
Clipper2Z PUBLIC
USINGZ
CLIPPER2_MAX_DECIMAL_PRECISION=${CLIPPER2_MAX_DECIMAL_PRECISION}
$<$<BOOL:${CLIPPER2_HI_PRECISION}>:CLIPPER2_HI_PRECISION>
)
target_include_directories(
Clipper2Z PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Clipper2Lib/include>
$<INSTALL_INTERFACE:include>
)
if (MSVC)
target_compile_options(Clipper2Z PRIVATE /W4 /WX)
else()
target_compile_options(Clipper2Z PRIVATE -Wall -Wextra -Wpedantic -Werror -Wno-c++20-compat -Wsign-conversion)
target_link_libraries(Clipper2Z PUBLIC -lm)
endif()
endif()
set_target_properties(${CLIPPER2_LIBS} PROPERTIES FOLDER Libraries
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
PUBLIC_HEADER "${CLIPPER2_INC}"
)
if(CLIPPER2_UTILS OR CLIPPER2_TESTS OR CLIPPER2_EXAMPLES)
set(CLIPPER2_UTILS_INC
Utils/clipper.svg.h
Utils/ClipFileLoad.h
Utils/ClipFileSave.h
Utils/Timer.h
Utils/Colors.h
Utils/CommonUtils.h
)
set(CLIPPER2_UTILS_SRC
Utils/clipper.svg.cpp
Utils/ClipFileLoad.cpp
Utils/ClipFileSave.cpp
)
set(CLIPPER2_UTILS "") # one or both of Clipper2utils/Clipper2Zutils
if (NOT (CLIPPER2_USINGZ STREQUAL "ONLY"))
list(APPEND CLIPPER2_UTILS Clipper2utils)
add_library(Clipper2utils STATIC ${CLIPPER2_UTILS_INC} ${CLIPPER2_UTILS_SRC})
target_link_libraries(Clipper2utils PUBLIC Clipper2)
target_include_directories(Clipper2utils
PUBLIC Utils
)
endif()
if (NOT (CLIPPER2_USINGZ STREQUAL "OFF"))
list(APPEND CLIPPER2_UTILS Clipper2Zutils)
add_library(Clipper2Zutils STATIC ${CLIPPER2_UTILS_INC} ${CLIPPER2_UTILS_SRC})
target_link_libraries(Clipper2Zutils PUBLIC Clipper2Z)
target_include_directories(Clipper2Zutils
PUBLIC Utils
)
endif()
set_target_properties(${CLIPPER2_UTILS} PROPERTIES FOLDER Libraries)
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
foreach(lib ${CLIPPER2_UTILS})
target_compile_options(${lib} PRIVATE -Wno-unused-variable -Wno-unused-function)
endforeach()
endif()
endif()
if(CLIPPER2_EXAMPLES)
##########################################################################
##########################################################################
set(ALL_EXAMPLES "") # 2d and 3d examples (if enabled)
if (NOT (CLIPPER2_USINGZ STREQUAL "ONLY"))
set(EXAMPLES
Benchmarks
Inflate
MemLeakTest
PolygonSamples
RandomClipping
UnionClipping
RectClipping
SimpleClipping
VariableOffset
)
foreach(ex ${EXAMPLES})
add_executable(${ex} Examples/${ex}/${ex}.cpp)
target_link_libraries(${ex} PRIVATE Clipper2 Clipper2utils)
endforeach()
file(COPY Examples/Inflate/rabbit.svg DESTINATION ${CMAKE_BINARY_DIR} FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ )
list(APPEND ALL_EXAMPLES ${EXAMPLES})
endif()
if (NOT (CLIPPER2_USINGZ STREQUAL "OFF"))
set(EXAMPLESZ "UsingZ")
foreach(ex ${EXAMPLESZ})
add_executable(${ex} Examples/${ex}/${ex}.cpp)
target_link_libraries(${ex} PRIVATE Clipper2Z Clipper2Zutils)
endforeach()
list(APPEND ALL_EXAMPLES ${EXAMPLESZ})
endif()
set_target_properties(${ALL_EXAMPLES} PROPERTIES FOLDER Examples)
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
foreach(ex ${ALL_EXAMPLES})
target_compile_options(${ex} PRIVATE -Wno-unused-variable -Wno-unused-function)
endforeach()
endif()
endif()
if(CLIPPER2_TESTS)
# See: https://cliutils.gitlab.io/modern-cmake/chapters/testing/googletest.html
enable_testing()
if (WIN32)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
endif()
set(BUILD_GMOCK OFF)
if(USE_EXTERNAL_GTEST)
find_package(GTest REQUIRED)
else()
include(GoogleTest)
if(NOT EXISTS ${PROJECT_SOURCE_DIR}/Tests/googletest)
execute_process(
COMMAND "git" "clone" "https://github.com/google/googletest"
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/Tests
)
endif()
add_subdirectory("${PROJECT_SOURCE_DIR}/Tests/googletest/")
set_target_properties(gtest gtest_main PROPERTIES FOLDER GTest)
endif()
if(TARGET gtest AND TARGET gtest_main)
set(gtest_libs gtest gtest_main)
elseif(TARGET GTest::gtest AND TARGET GTest::gtest_main)
set(gtest_libs GTest::gtest GTest::gtest_main)
endif()
set(ClipperTests_SRC
Tests/TestExportHeaders.cpp
Tests/TestIsCollinear.cpp
Tests/TestLines.cpp
Tests/TestOffsets.cpp
Tests/TestOffsetOrientation.cpp
Tests/TestOrientation.cpp
Tests/TestPolygons.cpp
Tests/TestPolytreeHoles.cpp
Tests/TestPolytreeIntersection.cpp
Tests/TestPolytreeUnion.cpp
Tests/TestRandomPaths.cpp
Tests/TestRectClip.cpp
Tests/TestSimplifyPath.cpp
Tests/TestTrimCollinear.cpp
Tests/TestWindows.cpp
)
set(CLIPPER2_TESTS "") # one or both of ClipperTests/ClipperTestsZ
if (NOT (CLIPPER2_USINGZ STREQUAL "ONLY"))
list(APPEND CLIPPER2_TESTS "ClipperTests")
add_executable(ClipperTests ${ClipperTests_SRC})
target_link_libraries(ClipperTests ${gtest_libs} Clipper2 Clipper2utils)
gtest_discover_tests(ClipperTests
# set a working directory to your project root so that you can find test data via paths relative to the project root
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/../Tests
PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${PROJECT_DIR}"
)
endif()
if (NOT (CLIPPER2_USINGZ STREQUAL "OFF"))
list(APPEND CLIPPER2_TESTS "ClipperTestsZ")
add_executable(ClipperTestsZ ${ClipperTests_SRC})
target_link_libraries(ClipperTestsZ ${gtest_libs} Clipper2Z Clipper2Zutils)
gtest_discover_tests(ClipperTestsZ
# set a working directory so your project root so that you can find test data via paths relative to the project root
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/../Tests
PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${PROJECT_DIR}"
TEST_SUFFIX "_USINGZ"
)
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
foreach(ts ${CLIPPER2_TESTS})
target_compile_options(${ts} PRIVATE -Wno-unused-variable -Wno-unused-function)
endforeach()
endif()
set_target_properties(${CLIPPER2_TESTS} PROPERTIES FOLDER Tests)
file(COPY ../Tests/PolytreeHoleOwner.txt DESTINATION ${CMAKE_BINARY_DIR} FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ )
file(COPY ../Tests/PolytreeHoleOwner2.txt DESTINATION ${CMAKE_BINARY_DIR} FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ )
file(COPY ../Tests/Lines.txt DESTINATION ${CMAKE_BINARY_DIR} FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ )
file(COPY ../Tests/Polygons.txt DESTINATION ${CMAKE_BINARY_DIR} FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ )
file(COPY ../Tests/Offsets.txt DESTINATION ${CMAKE_BINARY_DIR} FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ )
endif()
if(USE_EXTERNAL_GBENCHMARK)
add_subdirectory(BenchMark)
endif()
set(CLIPPER2_PCFILES "")
foreach(lib ${CLIPPER2_LIBS})
set(pc "${CMAKE_CURRENT_BINARY_DIR}/${lib}.pc")
list(APPEND CLIPPER2_PCFILES ${pc})
if (lib STREQUAL "Clipper2Z")
set(PCFILE_LIB_SUFFIX "Z")
else()
set(PCFILE_LIB_SUFFIX "")
endif()
configure_file(Clipper2.pc.cmakein "${pc}" @ONLY)
endforeach()
install(TARGETS ${CLIPPER2_LIBS}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/clipper2
)
install(FILES ${CLIPPER2_PCFILES} DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
# create package config file
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)
write_basic_package_version_file("${PROJECT_BINARY_DIR}/Clipper2ConfigVersion.cmake" COMPATIBILITY SameMajorVersion)
configure_package_config_file(
"Clipper2Config.cmake.in"
"${PROJECT_BINARY_DIR}/Clipper2Config.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/clipper2
)
export(TARGETS ${CLIPPER2_LIBS} FILE "${PROJECT_BINARY_DIR}/Clipper2Targets.cmake")
# installation
install(TARGETS ${CLIPPER2_LIBS} EXPORT Clipper2-targets
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/clipper2
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(
FILES
${PROJECT_BINARY_DIR}/Clipper2Config.cmake
${PROJECT_BINARY_DIR}/Clipper2ConfigVersion.cmake
DESTINATION
${CMAKE_INSTALL_LIBDIR}/cmake/clipper2
)
install(
EXPORT
Clipper2-targets
NAMESPACE
Clipper2::
FILE
Clipper2Targets.cmake
DESTINATION
${CMAKE_INSTALL_LIBDIR}/cmake/clipper2
)
# disable exceptions
#string(REGEX REPLACE "/W[3|4]" "/w" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
#add_definitions(-D_HAS_EXCEPTIONS=0) # for STL