diff --git a/.gitignore b/.gitignore index 2ecdd4b32..9f55b20da 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .DS_Store +.vscode *.gcov *.gcda *.gcno @@ -56,3 +57,8 @@ demo/viewer/ui_layer_info.h test/standalone/*-bin test/unit/run test/visual/run +# cmake +build +.vs + +CMakeUserPresets.json diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..4c6ba296b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,452 @@ +cmake_minimum_required(VERSION 3.15) +# 3.15 is required since the Boost::XXXX targets was first added. https://cmake.org/cmake/help/latest/module/FindBoost.html#imported-targets +# 3.14 is required since SQLite3 Module was first added. https://cmake.org/cmake/help/latest/module/FindSQLite3.html#findsqlite3 + +include(cmake/GetVersion.cmake) +get_mapnik_version() + +project(mapnik + VERSION ${MAPNIK_MAJOR_VERSION}.${MAPNIK_MINOR_VERSION}.${MAPNIK_PATCH_VERSION} + HOMEPAGE_URL "https://mapnik.org/" + DESCRIPTION "Mapnik is an open source toolkit for developing mapping applications" + LANGUAGES CXX +) +message(STATUS "mapnik version: ${PROJECT_VERSION}") + +# https://cliutils.gitlab.io/modern-cmake/chapters/features/ides.html +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +include(MapnikFindPackage) +include(MapnikCopyDependencies) +include(MapnikInstall) + +set(ADDITIONAL_LIBARIES_PATHS "" CACHE STRING "only used on windows. Pass directories containing the dlls that are missing. You can ignore this, if the build (verify_app step) runs successfully") +option(COPY_LIBRARIES_FOR_EXECUTABLES "copies required shared libaries (only windows) to the executable build directory" OFF) +option(COPY_FONTS_AND_PLUGINS_FOR_EXECUTABLES "copies required plugins and fonts into the executable build directory" ON) +option(INSTALL_DEPENDENCIES "if ON, all dependencies (eg. required dlls) will be copied into CMAKE_INSTALL_PREFIX/MAPNIK_BIN_DIR." ON) + +option(BUILD_SHARED_LIBS "build mapnik dynamic(ON) or static(OFF)" ON) +option(BUILD_TEST "builds the tests" ON) +option(USE_EXTERNAL_MAPBOX_GEOMETRY "Use a external mapnik/geometry.hpp. If off, use the submodule" OFF) +option(USE_EXTERNAL_MAPBOX_POLYLABEL "Use a external mapnik/polylabel. If off, use the submodule" OFF) +option(USE_EXTERNAL_MAPBOX_PROTOZERO "Use a external mapnik/protozero. If off, use the submodule" OFF) +option(USE_EXTERNAL_MAPBOX_VARIANT "Use a external mapnik/variant. If off, use the submodule" OFF) +option(USE_JPEG "adds jpeg support" ON) +option(USE_PNG "adds png support" ON) +option(USE_TIFF "adds tiff support" ON) +option(USE_WEBP "adds webp support" ON) +option(USE_LIBXML2 "adds libxml2 support" ON) +option(USE_CAIRO "adds the cairo renderer" ON) +option(USE_PROJ "adds proj support" ON) +option(USE_GRID_RENDERER "adds grid renderer" ON) +option(USE_SVG_RENDERER "adds svg renderer" ON) +option(USE_BIGINT "uses 64 bit instead of 32" ON) +option(USE_MEMORY_MAPPED_FILE "uses file cache" ON) +option(USE_MULTITHREADED "enables the multithreaded features (threadsafe)" ON) +option(USE_NO_ATEXIT "disable atexit" OFF) +option(USE_NO_DLCLOSE "disable dlclose" OFF) +option(USE_DEBUG_OUTPUT "enables some debug messages for development" OFF) +option(USE_LOG "enables logging output. See log severity level." OFF) +# 0 = debug +# 1 = warn +# 2 = error +# 3 = none +set(USE_LOG_SEVERITY "1" CACHE STRING "sets the logging severity (only applies when USE_LOG is ON") +option(USE_STATS "Enable statistics reporting" OFF) + +option(USE_PLUGIN_INPUT_CSV "adds plugin input csv" ON) +option(USE_PLUGIN_INPUT_GDAL "adds plugin input gdal" ON) +option(USE_PLUGIN_INPUT_GEOBUF "adds plugin input geobuf" ON) +option(USE_PLUGIN_INPUT_GEOJSON "adds plugin input geojson" ON) +option(USE_PLUGIN_INPUT_OGR "adds plugin input ogr" ON) +option(USE_PLUGIN_INPUT_PGRASTER "adds plugin input pgraster" ON) +option(USE_PLUGIN_INPUT_POSTGIS "adds plugin input postgis" ON) +option(USE_PLUGIN_INPUT_RASTER "adds plugin input raster" ON) +option(USE_PLUGIN_INPUT_SHAPE "adds plugin input shape" ON) +option(USE_PLUGIN_INPUT_SQLITE "adds plugin input sqlite" ON) +option(USE_PLUGIN_INPUT_TOPOJSON "adds plugin input topojson" ON) + +option(BUILD_DEMO_VIEWER "builds the demo viewer" ON) +option(BUILD_DEMO_CPP "builds the demo c++ application" ON) + +option(BUILD_BENCHMARK "builds benchmark project" ON) + +option(BUILD_UTILITY_GEOMETRY_TO_WKB "builds the utility program geometry_to_wkb" ON) +option(BUILD_UTILITY_MAPNIK_INDEX "builds the utility program mapnik_index" ON) +option(BUILD_UTILITY_MAPNIK_RENDER "builds the utility program mapnik_render" ON) +option(BUILD_UTILITY_OGRINDEX "builds the utility program ogrindex" OFF) +option(BUILD_UTILITY_PGSQL2SQLITE "builds the utility program pgsql2sqlite" ON) +option(BUILD_UTILITY_SHAPEINDEX "builds the utility program shapeindex" ON) +option(BUILD_UTILITY_SVG2PNG "builds the utility program svg2png" ON) + +option(USE_BOOST_REGEX_ICU_WORKAROUND "if you don't use your system libraries and get double linked icu libraries set this to ON" OFF) +option(USE_GLIBC_WORKAROUND "see https://github.com/mapnik/mapnik/pull/3792 if you building with libstdc++-4.9" OFF) + +set(CMAKE_CXX_STANDARD 14 CACHE STRING "Sets the c++ standard. c++14 is minimum.") +message(STATUS "Using c++${CMAKE_CXX_STANDARD}") +# https://cmake.org/cmake/help/latest/prop_tgt/CXX_EXTENSIONS.html +set(CXX_EXTENSIONS OFF CACHE STRING "Enables the compiler specific extensions.") # Fallsback to -std=c++ if off +message(STATUS "Using c++ extensions: ${CXX_EXTENSIONS}") +# https://cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD_REQUIRED.html#prop_tgt:CXX_STANDARD_REQUIRED +set(CXX_STANDARD_REQUIRED ON) # require the specified CMAKE_CXX_STANDARD + +# add debug postfix to the libraries +set(MAPNIK_DEBUG_POSTFIX "d" CACHE STRING "sets the debug library postfix on mapnik, wkt and json") +message(STATUS "postfix for debug libraries: ${MAPNIK_DEBUG_POSTFIX}") + +if(WIN32) + set(DEFAULT_BIN_DIR bin) + set(DEFAULT_LIB_DIR lib) + set(DEFAULT_ARCHIVE_DIR lib) +else() + include(GNUInstallDirs) + set(DEFAULT_BIN_DIR ${CMAKE_INSTALL_BINDIR}) + set(DEFAULT_LIB_DIR ${CMAKE_INSTALL_LIBDIR}) + set(DEFAULT_ARCHIVE_DIR ${CMAKE_INSTALL_LIBDIR}) +endif() +# https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#runtime-output-artifacts +set(MAPNIK_BIN_DIR ${DEFAULT_BIN_DIR} CACHE STRING "Install directory for binaries") +# https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#library-output-artifacts +set(MAPNIK_LIB_DIR ${DEFAULT_LIB_DIR} CACHE STRING "Install directory for libraries") +# https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#archive-output-artifacts +set(MAPNIK_ARCHIVE_DIR ${DEFAULT_ARCHIVE_DIR} CACHE STRING "Install directory for archives") + +set(INSTALL_CMAKE_DIR ${MAPNIK_LIB_DIR}/cmake/mapnik CACHE STRING "Install directory of the cmake targets") + +if(WIN32) + set(DEFAULT_PLUGINS_INSTALL_DIR ${MAPNIK_BIN_DIR}/mapnik/input) +else() + set(DEFAULT_PLUGINS_INSTALL_DIR ${MAPNIK_LIB_DIR}/mapnik/input) +endif() +set(PLUGINS_INSTALL_DIR ${DEFAULT_PLUGINS_INSTALL_DIR} CACHE STRING "installs the plugins in the specified directory") +message(STATUS "Installing plugins to ${PLUGINS_INSTALL_DIR}") + +set(FONTS_INSTALL_DIR ${MAPNIK_BIN_DIR}/fonts CACHE STRING "installs the fonts in the specified directory") +message(STATUS "Installing fonts to ${FONTS_INSTALL_DIR}") + +set(MAPNIK_COMPILE_DEFS "") +set(MAPNIK_OPTIONAL_LIBS "") +set(MAPNIK_OPTIONAL_LIBS_INCLUDE "") + +# Begin project configuration + +# needs to be before the first call of find_boost. +if(USE_MULTITHREADED) + message(STATUS "multithreaded enabled") + set(Boost_USE_MULTITHREADED ON) + list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_THREADSAFE) +else() + set(Boost_USE_MULTITHREADED OFF) + message(STATUS "multithreaded disabled") +endif() + +find_package(PkgConfig) +mapnik_find_threads() +mapnik_find_package(ICU REQUIRED COMPONENTS uc i18n data) +mapnik_find_package(Boost 1.61 REQUIRED COMPONENTS filesystem system regex) +if(USE_BOOST_REGEX_ICU_WORKAROUND) + message(STATUS "using boost regex workaround") + set_property(TARGET Boost::regex PROPERTY INTERFACE_LINK_LIBRARIES) +endif() + +mapnik_find_package(Freetype REQUIRED) + +# try to find harfbuzz with the native configuration and fallback to our "own" FindHarfBuzz +set(HARFBUZZ_MINIMUM_VERSION 0.9.34) +mapnik_find_package(harfbuzz CONFIG QUIET) +if(harfbuzz_FOUND) + message(STATUS "Found harfbuzz native cmake") + list(APPEND MAPNIK_OPTIONAL_LIBS harfbuzz::harfbuzz) +else() + # we use our "own" FindHarfBuzz. See https://github.com/mapnik/mapnik/pull/4191#issuecomment-874728157 for more details + message(STATUS "Fallback to FindHarfBuzz") + mapnik_find_package(HarfBuzz ${HARFBUZZ_MINIMUM_VERSION} REQUIRED COMPONENTS ICU) + list(APPEND MAPNIK_OPTIONAL_LIBS HarfBuzz::HarfBuzz HarfBuzz::ICU) +endif() + +if(USE_EXTERNAL_MAPBOX_GEOMETRY) + # this is used to provide a way to specify include dirs with CACHE VARIABLES + if(NOT MAPBOX_GEOMETRY_INCLUDE_DIRS) + message(STATUS "Searching for the include dir of mapbox/geometry.hpp") + find_path(MAPBOX_GEOMETRY_INCLUDE_DIRS "mapbox/geometry.hpp" REQUIRED) + endif() +else() + set(MAPBOX_GEOMETRY_INCLUDE_DIRS + $ + $ + ) +endif() +if(NOT MAPBOX_GEOMETRY_INCLUDE_DIRS) + message(FATAL_ERROR "Set -DMAPBOX_GEOMETRY_INCLUDE_DIRS to the mapbox/geometry.hpp include dir") +endif() + +if(USE_EXTERNAL_MAPBOX_POLYLABEL) + if(NOT MAPBOX_POLYLABEL_INCLUDE_DIRS) + message(STATUS "Searching for the include dir of mapbox/polylabel") + find_path(MAPBOX_POLYLABEL_INCLUDE_DIRS "mapbox/polylabel.hpp") + endif() +else() + set(MAPBOX_POLYLABEL_INCLUDE_DIRS + $ + $ + ) +endif() +if(NOT MAPBOX_POLYLABEL_INCLUDE_DIRS) + message(FATAL_ERROR "Set MAPBOX_POLYLABEL_INCLUDE_DIRS to the mapbox/geometry include dir") +endif() + +if(USE_EXTERNAL_MAPBOX_PROTOZERO) + if(NOT MAPBOX_PROTOZERO_INCLUDE_DIRS) + message(STATUS "Searching for the include dir of mapbox/protozero") + find_path(MAPBOX_PROTOZERO_INCLUDE_DIRS "protozero/pbf_message.hpp") + endif() +else() + set(MAPBOX_PROTOZERO_INCLUDE_DIRS + $ + $ + ) +endif() +if(NOT MAPBOX_PROTOZERO_INCLUDE_DIRS) + message(FATAL_ERROR "Set MAPBOX_PROTOZERO_INCLUDE_DIRS to the mapbox/protozero include dir") +endif() + +if(USE_EXTERNAL_MAPBOX_VARIANT) + if(NOT MAPBOX_VARIANT_INCLUDE_DIRS) + message(STATUS "Searching for the include dir of mapbox/variant") + find_path(MAPBOX_VARIANT_INCLUDE_DIRS "mapbox/variant.hpp") + endif() +else() + set(MAPBOX_VARIANT_INCLUDE_DIRS + $ + $ + ) +endif() +if(NOT MAPBOX_VARIANT_INCLUDE_DIRS) + message(FATAL_ERROR "Set MAPBOX_VARIANT_INCLUDE_DIRS to the mapbox/variant include dir") +endif() + +# (used by MapnikInstall.cmake. properties are needed since "set(...)" will be out of scope +set_property(GLOBAL PROPERTY TARGETS "") +set_property(GLOBAL PROPERTY PLUGINS "") + +if(USE_GLIBC_WORKAROUND) + message("using glibc workaround") + list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_ENABLE_GLIBC_WORKAROUND) +endif() + +if(USE_BIGINT) + message(STATUS "uses BIGINT") + list(APPEND MAPNIK_COMPILE_DEFS BIGINT) +endif() + +if(USE_MEMORY_MAPPED_FILE) + message(STATUS "uses MAPNIK_MEMORY_MAPPED_FILE") + list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_MEMORY_MAPPED_FILE) +endif() + +if(USE_NO_ATEXIT) + message(STATUS "uses MAPNIK_NO_ATEXIT") + list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_NO_ATEXIT) +endif() + +if(USE_NO_DLCLOSE) + message(STATUS "uses MAPNIK_NO_DLCLOSE") + list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_NO_DLCLOSE) +endif() + +if(USE_DEBUG_OUTPUT) + message(STATUS "enabled debug outputs") + list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_DEBUG) +endif() + +if(USE_LOG) + message(STATUS "logging enabled with level ${USE_LOG_SEVERITY}") + list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_LOG MAPNIK_DEFAULT_LOG_SEVERITY=${USE_LOG_SEVERITY}) +endif() + +if(USE_STATS) + message(STATUS "adding statistics") + list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_STATS) +endif() + +if(USE_LIBXML2) + mapnik_find_package(LibXml2 REQUIRED) + list(APPEND MAPNIK_COMPILE_DEFS HAVE_LIBXML2) + list(APPEND MAPNIK_OPTIONAL_LIBS LibXml2::LibXml2) +endif() + +if(USE_PNG) + mapnik_find_package(PNG REQUIRED) + list(APPEND MAPNIK_COMPILE_DEFS HAVE_PNG) + list(APPEND MAPNIK_OPTIONAL_LIBS PNG::PNG) +endif() + +if(USE_JPEG) + mapnik_find_package(JPEG REQUIRED) + list(APPEND MAPNIK_COMPILE_DEFS HAVE_JPEG) + list(APPEND MAPNIK_OPTIONAL_LIBS JPEG::JPEG) +endif() + +if(USE_TIFF) + mapnik_find_package(TIFF REQUIRED) + list(APPEND MAPNIK_COMPILE_DEFS HAVE_TIFF) + list(APPEND MAPNIK_OPTIONAL_LIBS TIFF::TIFF) +endif() + +if(USE_WEBP) + mapnik_find_package(WebP REQUIRED) + list(APPEND MAPNIK_COMPILE_DEFS HAVE_WEBP) + list(APPEND MAPNIK_OPTIONAL_LIBS WebP::WebP) +endif() + +if(USE_CAIRO) + mapnik_find_package(Cairo REQUIRED) + list(APPEND MAPNIK_COMPILE_DEFS HAVE_CAIRO) + list(APPEND MAPNIK_OPTIONAL_LIBS Cairo::Cairo) +endif() + +if(USE_PROJ) + #https://proj.org/development/cmake.html + mapnik_find_package(PROJ QUIET) + # currently the cmake files are not installed, when installing proj via apt-get. So search via pkg-config + if(NOT PROJ_FOUND) + message(STATUS "PROJ not found via FindPROJ. Searching via pkg-config...") + pkg_check_modules(PROJ REQUIRED IMPORTED_TARGET proj) + string(REGEX MATCH "([0-9]+)\.([0-9]+)\.([0-9]+)" _dummy "${PROJ_VERSION}") + set(PROJ_VERSION_MAJOR "${CMAKE_MATCH_1}") + set(PROJ_VERSION_MINOR "${CMAKE_MATCH_2}") + set(PROJ_VERSION_PATCH "${CMAKE_MATCH_3}") + endif() + math(EXPR MAPNIK_PROJ_VERSION "${PROJ_VERSION_MAJOR}*10000 + ${PROJ_VERSION_MINOR}*100 + ${PROJ_VERSION_PATCH}" OUTPUT_FORMAT DECIMAL) + message(STATUS "Using mapnik PROJ version: ${MAPNIK_PROJ_VERSION}") + list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_USE_PROJ MAPNIK_PROJ_VERSION=${MAPNIK_PROJ_VERSION}) + list(APPEND MAPNIK_OPTIONAL_LIBS ${PROJ_LIBRARIES}) + list(APPEND MAPNIK_OPTIONAL_LIBS_INCLUDE ${PROJ_INCLUDE_DIRS}) +endif() + +if(USE_GRID_RENDERER) + message(STATUS "Using grid renderer") + list(APPEND MAPNIK_COMPILE_DEFS GRID_RENDERER) +endif() + +if(USE_SVG_RENDERER) + message(STATUS "Using svg renderer") + list(APPEND MAPNIK_COMPILE_DEFS SVG_RENDERER) +endif() + +if(NOT WIN32) + message(STATUS "Compiling with -DMAPNIK_HAS_DLCFN") + list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_HAS_DLCFN) + list(APPEND MAPNIK_OPTIONAL_LIBS ${CMAKE_DL_LIBS}) +endif() + +add_library(core INTERFACE) +add_library(mapnik::core ALIAS core) + +target_include_directories(core INTERFACE + $ + $ + $ + $ + $ + $ + $ + ${MAPNIK_OPTIONAL_LIBS_INCLUDE} +) +target_link_libraries(core INTERFACE + Threads::Threads + ICU::uc + ICU::data + ICU::i18n + Boost::headers + Boost::regex + Boost::filesystem + Freetype::Freetype + ${MAPNIK_OPTIONAL_LIBS} +) +target_compile_definitions(core INTERFACE ${MAPNIK_COMPILE_DEFS}) + +install(TARGETS core + EXPORT MapnikTargets + LIBRARY DESTINATION ${MAPNIK_LIB_DIR} + ARCHIVE DESTINATION ${MAPNIK_ARCHIVE_DIR} + RUNTIME DESTINATION ${MAPNIK_BIN_DIR} + INCLUDES DESTINATION include/ + PUBLIC_HEADER DESTINATION include/ + COMPONENT mapnik +) + +add_subdirectory(deps) +add_subdirectory(src) +add_subdirectory(plugins) +add_subdirectory(utils) +add_subdirectory(demo) +if(BUILD_BENCHMARK) + add_subdirectory(benchmark) +endif() +if(BUILD_TEST) + enable_testing() + add_subdirectory(test) +endif() + +# start package mapnik +include(CMakePackageConfigHelpers) + +# set the cmake targets install location +set(INCLUDE_INSTALL_DIR include/) +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/mapnikConfigVersion.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion +) + +list(JOIN MAPNIK_DEPENDENCIES "\n" MAPNIK_DEPENDENCIES) +configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/mapnikConfig.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/mapnikConfig.cmake" + INSTALL_DESTINATION ${INSTALL_CMAKE_DIR} + PATH_VARS INCLUDE_INSTALL_DIR PLUGINS_INSTALL_DIR FONTS_INSTALL_DIR MAPNIK_DEPENDENCIES +) + +install( + FILES + "${CMAKE_CURRENT_BINARY_DIR}/mapnikConfig.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/mapnikConfigVersion.cmake" + DESTINATION ${INSTALL_CMAKE_DIR} +) + +install( + FILES + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindCairo.cmake" + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindWebP.cmake" + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindHarfBuzz.cmake" + DESTINATION ${INSTALL_CMAKE_DIR}/Modules +) + +install(EXPORT MapnikTargets + FILE mapnikTargets.cmake + NAMESPACE mapnik:: + DESTINATION ${INSTALL_CMAKE_DIR} +) + +install(DIRECTORY include/ TYPE INCLUDE) +install(DIRECTORY deps/agg/include/ TYPE INCLUDE) +install(DIRECTORY deps/mapnik TYPE INCLUDE) +install(DIRECTORY fonts/ DESTINATION ${FONTS_INSTALL_DIR} FILES_MATCHING PATTERN "*.py" EXCLUDE PATTERN "*") + +if(NOT USE_EXTERNAL_MAPBOX_GEOMETRY) + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/deps/mapbox/geometry/include/ TYPE INCLUDE) +endif() +if(NOT USE_EXTERNAL_MAPBOX_POLYLABEL) + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/deps/mapbox/polylabel/include/ TYPE INCLUDE) +endif() +if(NOT USE_EXTERNAL_MAPBOX_PROTOZERO) + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/deps/mapbox/protozero/include/ TYPE INCLUDE) +endif() +if(NOT USE_EXTERNAL_MAPBOX_VARIANT) + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/deps/mapbox/variant/include/ TYPE INCLUDE) +endif() + +mapnik_install_targets() + +include(pack) diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 000000000..5f2a874f0 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,176 @@ +{ + "version": 2, + "cmakeMinimumRequired": { + "major": 3, + "minor": 20, + "patch": 0 + }, + "configurePresets": [ + { + "name": "use-ninja", + "hidden": true, + "generator": "Ninja" + }, + { + "name": "default-build-dir", + "hidden": true, + "binaryDir": "${sourceDir}/build/${presetName}" + }, + { + "name": "debug-build", + "hidden": true, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "USE_DEBUG_OUTPUT": "ON", + "USE_LOG": "ON", + "USE_LOG_SEVERITY": "0" + } + }, + { + "name": "release-build", + "hidden": true, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "USE_DEBUG_OUTPUT": "OFF", + "USE_LOG": "OFF" + } + }, + { + "name": "use-clang", + "hidden": true, + "inherits": [ + "default-build-dir", + "use-ninja" + ], + "cacheVariables": { + "CMAKE_C_COMPILER": "clang", + "CMAKE_CXX_COMPILER": "clang++", + "CMAKE_CXX_FLAGS": "-stdlib=libc++", + "CMAKE_EXE_LINKER_FLAGS": "-stdlib=libc++", + "CMAKE_SHARED_LINKER_FLAGS": "-stdlib=libc++" + } + }, + { + "name": "use-gcc", + "hidden": true, + "inherits": [ + "default-build-dir", + "use-ninja" + ], + "cacheVariables": { + "CMAKE_C_COMPILER": "gcc", + "CMAKE_CXX_COMPILER": "g++" + } + }, + { + "name": "use-msvc-cl", + "hidden": true, + "inherits": [ + "default-build-dir", + "use-ninja" + ], + "cacheVariables": { + "CMAKE_C_COMPILER": "cl", + "CMAKE_CXX_COMPILER": "cl" + } + }, + { + "name": "use-msvc-clang-cl", + "hidden": true, + "inherits": [ + "default-build-dir", + "use-ninja" + ], + "cacheVariables": { + "CMAKE_C_COMPILER": "clang-cl", + "CMAKE_CXX_COMPILER": "clang-cl" + } + }, + { + "name": "linux-clang-debug", + "displayName": "Linux clang debug", + "inherits": [ + "use-clang", + "debug-build" + ] + }, + { + "name": "linux-clang-release", + "displayName": "Linux clang release", + "inherits": [ + "use-clang", + "release-build" + ] + }, + { + "name": "linux-gcc-debug", + "displayName": "Linux gcc debug", + "inherits": [ + "use-gcc", + "debug-build" + ] + }, + { + "name": "linux-gcc-release", + "displayName": "Linux gcc release", + "inherits": [ + "use-gcc", + "release-build" + ] + }, + { + "name": "windows-arch-x64", + "hidden": true, + "architecture": { + "value": "x64", + "strategy": "external" + }, + "toolset": { + "value": "host=x64", + "strategy": "external" + } + }, + { + "name": "windows-default", + "displayName": "Windows x64 Debug", + "hidden": true, + "inherits": [ + "use-msvc-cl", + "windows-arch-x64" + ], + "vendor": { + "microsoft.com/VisualStudioSettings/CMake/1.0": { + "hostOS": [ + "Windows" + ] + } + } + }, + { + "name": "windows-default-debug", + "displayName": "Windows x64 Debug", + "inherits": [ + "windows-default", + "debug-build" + ] + }, + { + "name": "windows-default-release", + "displayName": "Windows x64 Release", + "inherits": [ + "windows-default", + "release-build" + ] + } + ], + "buildPresets": [ + { + "name": "windows-default", + "configurePreset": "windows-default-debug" + }, + { + "name": "linux-default", + "configurePreset": "linux-clang-debug" + } + ] +} diff --git a/INSTALL.md b/INSTALL.md index 4ef4a2124..7ee6420c0 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -2,6 +2,13 @@ Mapnik runs on Linux, OS X, Windows, and BSD systems. +## Package managers +### vcpkg +To install mapnik with vcpkg type `vcpkg install mapnik`. It will install a minimal version of mapnik and all the needed dependencies. +To install more features, type `vcpkg search mapnik` to see all available features. + +## Source build + First clone mapnik from github and initialize submodules ```bash diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt new file mode 100644 index 000000000..d67b4411f --- /dev/null +++ b/benchmark/CMakeLists.txt @@ -0,0 +1,55 @@ +project(mapnik-benchmark) + +set(BENCHMARK_SRCS + src/normalize_angle.cpp + src/test_array_allocation.cpp + src/test_expression_parse.cpp + src/test_face_ptr_creation.cpp + src/test_font_registration.cpp + src/test_getline.cpp + src/test_marker_cache.cpp + src/test_noop_rendering.cpp + src/test_numeric_cast_vs_static_cast.cpp + src/test_offset_converter.cpp + src/test_png_encoding1.cpp + src/test_png_encoding2.cpp + src/test_polygon_clipping_rendering.cpp + src/test_polygon_clipping.cpp + src/test_proj_transform1.cpp + src/test_quad_tree.cpp + src/test_rendering_shared_map.cpp + src/test_rendering.cpp + src/test_to_bool.cpp + src/test_to_double.cpp + src/test_to_int.cpp + src/test_to_string1.cpp + src/test_to_string2.cpp + src/test_utf_encoding.cpp +) +function(mapnik_create_benchmark) + get_filename_component(BENCHNAME ${ARGV0} NAME_WE) + set(TARGET_NAME "mapnik-benchmark-${BENCHNAME}") + add_executable(${TARGET_NAME} ${ARGV0}) + target_include_directories(${TARGET_NAME} PRIVATE include) + target_link_libraries(${TARGET_NAME} PRIVATE mapnik::core mapnik::agg mapnik::mapnik) + + mapnik_copy_dependencies(TARGETS ${TARGET_NAME}) +endfunction() + +foreach(benchmark ${BENCHMARK_SRCS}) + mapnik_create_benchmark(${benchmark}) +endforeach() + +# we just need one target to reference the directory correctly. mapnik-benchmark-normalize_angle is just the first in BENCHMARK_SRCS +mapnik_require_fonts(TARGET mapnik-benchmark-normalize_angle DESTINATION fonts) +# copy all plugins +mapnik_copy_plugins(TARGET mapnik-benchmark-normalize_angle + DESTINATION plugins/input + PLUGINS + input-csv input-gdal input-geobuf input-geojson input-ogr input-pgraster input-postgis input-raster input-shape input-sqlite input-topojson +) +# copy all plugin dlls. +mapnik_copy_dependencies(TARGETS mapnik-benchmark-normalize_angle + PLUGINS + input-csv input-gdal input-geobuf input-geojson input-ogr input-pgraster input-postgis input-raster input-shape input-sqlite input-topojson +) diff --git a/benchmark/include/bench_framework.hpp b/benchmark/include/bench_framework.hpp index df2a9e57b..c7729dd16 100644 --- a/benchmark/include/bench_framework.hpp +++ b/benchmark/include/bench_framework.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #include namespace benchmark { diff --git a/cmake/CopyDllsForDebug.cmake b/cmake/CopyDllsForDebug.cmake new file mode 100644 index 000000000..3c0e118a6 --- /dev/null +++ b/cmake/CopyDllsForDebug.cmake @@ -0,0 +1,38 @@ +# This is a helper script to run BundleUtilities fixup_bundle as postbuild +# for a target. The primary use case is to copy .DLLs to the build directory for +# the Windows platform. It allows generator expressions to be used to determine +# the binary location +# +# Usage : copy_dlls_for_debug TARGET LIBS DIRS +# - TARGET : A cmake target +# - See fixup_bundle for LIBS and DIRS arguments + +if(RUN_IT) +# Script ran by the add_custom_command + include(BundleUtilities) + include(InstallRequiredSystemLibraries) + string (REPLACE " " ";" TO_FIXUP_LIBS "${TO_FIXUP_LIBS}") + string (REPLACE " " ";" TO_FIXUP_DIRS "${TO_FIXUP_DIRS}") + #message(STATUS "${TO_FIXUP_FILE} ${TO_FIXUP_LIBS} ${TO_FIXUP_DIRS}") + fixup_bundle("${TO_FIXUP_FILE}" "${TO_FIXUP_LIBS}" "${TO_FIXUP_DIRS}") +# End of script ran by the add_custom_command +else() + +set(THIS_FILE ${CMAKE_CURRENT_LIST_FILE}) +function(copy_dlls_for_debug) + set(options) + set(oneValueArgs) + set(multiValueArgs TARGETS LIBS DIRS) + cmake_parse_arguments(MAPNIK_COPY_DLLS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + if(WIN32) + foreach(_target IN LISTS MAPNIK_COPY_DLLS_TARGETS) + add_custom_command( + TARGET ${_target} POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -DRUN_IT:BOOL=ON -DTO_FIXUP_FILE="$" -DTO_FIXUP_LIBS:STRING="${MAPNIK_COPY_DLLS_LIBS}" -DTO_FIXUP_DIRS="${MAPNIK_COPY_DLLS_DIRS}" -P "${THIS_FILE}" + COMMENT "Fixing up dependencies for ${_target}" + ) + endforeach() + endif(WIN32) +endfunction() + +endif() diff --git a/cmake/FindCairo.cmake b/cmake/FindCairo.cmake new file mode 100644 index 000000000..1dc42a6a0 --- /dev/null +++ b/cmake/FindCairo.cmake @@ -0,0 +1,98 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindCairo +----------- + +Find Cairo 2D graphics library. + + +Imported Targets +^^^^^^^^^^^^^^^^ +This module defines :prop_tgt:`IMPORTED` target ``Cairo::Cairo``, if +cairo has been found. + +Result variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables in your project: + +``CAIRO_FOUND`` + True if cairo headers and library were found. +``CAIRO_INCLUDE_DIRS`` + Directory where cairo headers are located. +``CAIRO_LIBRARIES`` + cairo libraries to link against. +``CAIRO_VERSION_MAJOR`` + The major version of cairo +``CAIRO_VERSION_MINOR`` + The minor version of cairo +``CAIRO_VERSION_PATCH`` + The patch version of cairo +``CAIRO_VERSION_STRING`` + version number as a string (ex: "1.16.0") +#]=======================================================================] + +if(NOT CAIRO_LIBRARY) + find_path(CAIRO_INCLUDE_DIR NAMES cairo.h HINTS ${PC_CAIRO_INCLUDEDIR} ${PC_CAIRO_INCLUDE_DIR} PATH_SUFFIXES cairo) + find_library(CAIRO_LIBRARY_RELEASE NAMES ${Cairo_NAMES} cairo HINTS ${PC_CAIRO_LIBDIR} ${PC_CAIRO_LIBRARY_DIRS}) + find_library(CAIRO_LIBRARY_DEBUG NAMES ${Cairo_NAMES} cairod HINTS ${PC_CAIRO_LIBDIR} ${PC_CAIRO_LIBRARY_DIRS}) + include(SelectLibraryConfigurations) + select_library_configurations(CAIRO) +else() + file(TO_CMAKE_PATH "${CAIRO_LIBRARY}" CAIRO_LIBRARY) +endif() + +if(CAIRO_INCLUDE_DIR AND NOT CAIRO_VERSION) + if(EXISTS "${CAIRO_INCLUDE_DIR}/cairo-version.h") + file(READ "${CAIRO_INCLUDE_DIR}/cairo-version.h" CAIRO_VERSION_CONTENT) + + string(REGEX MATCH "#define +CAIRO_VERSION_MAJOR +([0-9]+)" _dummy "${CAIRO_VERSION_CONTENT}") + set(CAIRO_VERSION_MAJOR "${CMAKE_MATCH_1}") + + string(REGEX MATCH "#define +CAIRO_VERSION_MINOR +([0-9]+)" _dummy "${CAIRO_VERSION_CONTENT}") + set(CAIRO_VERSION_MINOR "${CMAKE_MATCH_1}") + + string(REGEX MATCH "#define +CAIRO_VERSION_MICRO +([0-9]+)" _dummy "${CAIRO_VERSION_CONTENT}") + set(CAIRO_VERSION_PATCH "${CMAKE_MATCH_1}") + + set(CAIRO_VERSION "${CAIRO_VERSION_MAJOR}.${CAIRO_VERSION_MINOR}.${CAIRO_VERSION_PATCH}") + set(CAIRO_VERSION_STRING ${CAIRO_VERSION}) + endif() +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Cairo + REQUIRED_VARS + CAIRO_LIBRARY + CAIRO_INCLUDE_DIR + VERSION_VAR + CAIRO_VERSION_STRING +) +mark_as_advanced(CAIRO_INCLUDE_DIR CAIRO_LIBRARY) + +if (CAIRO_FOUND) + set(CAIRO_LIBRARIES ${CAIRO_LIBRARY}) + set(CAIRO_INCLUDE_DIRS ${CAIRO_INCLUDE_DIR}) + if(NOT TARGET Cairo::Cairo) + add_library(Cairo::Cairo UNKNOWN IMPORTED) + set_target_properties(Cairo::Cairo PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${CAIRO_INCLUDE_DIR} + IMPORTED_LINK_INTERFACE_LANGUAGES C) + + if(CAIRO_LIBRARY_RELEASE) + set_property(TARGET Cairo::Cairo APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(Cairo::Cairo PROPERTIES IMPORTED_LOCATION_RELEASE "${CAIRO_LIBRARY_RELEASE}") + endif() + + if(CAIRO_LIBRARY_DEBUG) + set_property(TARGET Cairo::Cairo APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(Cairo::Cairo PROPERTIES IMPORTED_LOCATION_DEBUG "${CAIRO_LIBRARY_DEBUG}") + endif() + + if(NOT CAIRO_LIBRARY_RELEASE AND NOT CAIRO_LIBRARY_DEBUG) + set_target_properties(Cairo::Cairo PROPERTIES IMPORTED_LOCATION "${CAIRO_LIBRARY}") + endif() + endif() +endif () diff --git a/cmake/FindHarfBuzz.cmake b/cmake/FindHarfBuzz.cmake new file mode 100644 index 000000000..a0296f321 --- /dev/null +++ b/cmake/FindHarfBuzz.cmake @@ -0,0 +1,187 @@ +# Copyright (c) 2012, Intel Corporation +# Copyright (c) 2019 Sony Interactive Entertainment Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Intel Corporation nor the names of its contributors may +# be used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# Try to find Harfbuzz include and library directories. +# +# After successful discovery, this will set for inclusion where needed: +# HarfBuzz_INCLUDE_DIRS - containg the HarfBuzz headers +# HarfBuzz_LIBRARIES - containg the HarfBuzz library + +#[=======================================================================[.rst: +FindHarfBuzz +-------------- + +Find HarfBuzz headers and libraries. + +Imported Targets +^^^^^^^^^^^^^^^^ + +``HarfBuzz::HarfBuzz`` + The HarfBuzz library, if found. + +``HarfBuzz::ICU`` + The HarfBuzz ICU library, if found. + +Result Variables +^^^^^^^^^^^^^^^^ + +This will define the following variables in your project: + +``HarfBuzz_FOUND`` + true if (the requested version of) HarfBuzz is available. +``HarfBuzz_VERSION`` + the version of HarfBuzz. +``HarfBuzz_LIBRARIES`` + the libraries to link against to use HarfBuzz. +``HarfBuzz_INCLUDE_DIRS`` + where to find the HarfBuzz headers. +``HarfBuzz_COMPILE_OPTIONS`` + this should be passed to target_compile_options(), if the + target is not used for linking + +#]=======================================================================] + +find_package(PkgConfig QUIET) +pkg_check_modules(PC_HARFBUZZ QUIET harfbuzz) +set(HarfBuzz_COMPILE_OPTIONS ${PC_HARFBUZZ_CFLAGS_OTHER}) +set(HarfBuzz_VERSION ${PC_HARFBUZZ_CFLAGS_VERSION}) + +find_path(HarfBuzz_INCLUDE_DIR + NAMES hb.h + HINTS ${PC_HARFBUZZ_INCLUDEDIR} ${PC_HARFBUZZ_INCLUDE_DIRS} + PATH_SUFFIXES harfbuzz +) + +find_library(HarfBuzz_LIBRARY + NAMES ${HarfBuzz_NAMES} harfbuzz + HINTS ${PC_HARFBUZZ_LIBDIR} ${PC_HARFBUZZ_LIBRARY_DIRS} +) + +if (HarfBuzz_INCLUDE_DIR AND NOT HarfBuzz_VERSION) + if (EXISTS "${HarfBuzz_INCLUDE_DIR}/hb-version.h") + file(READ "${HarfBuzz_INCLUDE_DIR}/hb-version.h" _harfbuzz_version_content) + + string(REGEX MATCH "#define +HB_VERSION_STRING +\"([0-9]+\.[0-9]+\.[0-9]+)\"" _dummy "${_harfbuzz_version_content}") + set(HarfBuzz_VERSION "${CMAKE_MATCH_1}") + endif () +endif () + +if ("${HarfBuzz_FIND_VERSION}" VERSION_GREATER "${HarfBuzz_VERSION}") + message(FATAL_ERROR "Required version (" ${HarfBuzz_FIND_VERSION} ") is higher than found version (" ${HarfBuzz_VERSION} ")") +endif () + +# Find components +if (HarfBuzz_INCLUDE_DIR AND HarfBuzz_LIBRARY) + set(_HarfBuzz_REQUIRED_LIBS_FOUND ON) + set(HarfBuzz_LIBS_FOUND "HarfBuzz (required): ${HarfBuzz_LIBRARY}") +else () + set(_HarfBuzz_REQUIRED_LIBS_FOUND OFF) + set(HarfBuzz_LIBS_NOT_FOUND "HarfBuzz (required)") +endif () + +if ("ICU" IN_LIST HarfBuzz_FIND_COMPONENTS) + pkg_check_modules(PC_HARFBUZZ_ICU QUIET harfbuzz-icu) + set(HarfBuzz_ICU_COMPILE_OPTIONS ${PC_HARFBUZZ_ICU_CFLAGS_OTHER}) + + find_path(HarfBuzz_ICU_INCLUDE_DIR + NAMES hb-icu.h + HINTS ${PC_HARFBUZZ_ICU_INCLUDEDIR} ${PC_HARFBUZZ_ICU_INCLUDE_DIRS} + PATH_SUFFIXES harfbuzz + ) + + find_library(HarfBuzz_ICU_LIBRARY + NAMES ${HarfBuzz_ICU_NAMES} harfbuzz-icu + HINTS ${PC_HARFBUZZ_ICU_LIBDIR} ${PC_HARFBUZZ_ICU_LIBRARY_DIRS} + ) + + if (HarfBuzz_ICU_LIBRARY) + if (HarfBuzz_FIND_REQUIRED_ICU) + list(APPEND HarfBuzz_LIBS_FOUND "ICU (required): ${HarfBuzz_ICU_LIBRARY}") + else () + list(APPEND HarfBuzz_LIBS_FOUND "ICU (optional): ${HarfBuzz_ICU_LIBRARY}") + endif () + else () + if (HarfBuzz_FIND_REQUIRED_ICU) + set(_HarfBuzz_REQUIRED_LIBS_FOUND OFF) + list(APPEND HarfBuzz_LIBS_NOT_FOUND "ICU (required)") + else () + list(APPEND HarfBuzz_LIBS_NOT_FOUND "ICU (optional)") + endif () + endif () +endif () + +if (NOT HarfBuzz_FIND_QUIETLY) + if (HarfBuzz_LIBS_FOUND) + message(STATUS "Found the following HarfBuzz libraries:") + foreach (found ${HarfBuzz_LIBS_FOUND}) + message(STATUS " ${found}") + endforeach () + endif () + if (HarfBuzz_LIBS_NOT_FOUND) + message(STATUS "The following HarfBuzz libraries were not found:") + foreach (found ${HarfBuzz_LIBS_NOT_FOUND}) + message(STATUS " ${found}") + endforeach () + endif () +endif () + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(HarfBuzz + FOUND_VAR HarfBuzz_FOUND + REQUIRED_VARS HarfBuzz_INCLUDE_DIR HarfBuzz_LIBRARY _HarfBuzz_REQUIRED_LIBS_FOUND + VERSION_VAR HarfBuzz_VERSION +) + +if (HarfBuzz_LIBRARY AND NOT TARGET HarfBuzz::HarfBuzz) + add_library(HarfBuzz::HarfBuzz UNKNOWN IMPORTED GLOBAL) + set_target_properties(HarfBuzz::HarfBuzz PROPERTIES + IMPORTED_LOCATION "${HarfBuzz_LIBRARY}" + INTERFACE_COMPILE_OPTIONS "${HarfBuzz_COMPILE_OPTIONS}" + INTERFACE_INCLUDE_DIRECTORIES "${HarfBuzz_INCLUDE_DIR}" + ) +endif () + +if (HarfBuzz_ICU_LIBRARY AND NOT TARGET HarfBuzz::ICU) + add_library(HarfBuzz::ICU UNKNOWN IMPORTED GLOBAL) + set_target_properties(HarfBuzz::ICU PROPERTIES + IMPORTED_LOCATION "${HarfBuzz_ICU_LIBRARY}" + INTERFACE_COMPILE_OPTIONS "${HarfBuzz_ICU_COMPILE_OPTIONS}" + INTERFACE_INCLUDE_DIRECTORIES "${HarfBuzz_ICU_INCLUDE_DIR}" + ) +endif () + +mark_as_advanced( + HarfBuzz_INCLUDE_DIR + HarfBuzz_ICU_INCLUDE_DIR + HarfBuzz_LIBRARY + HarfBuzz_ICU_LIBRARY +) + +if (HarfBuzz_FOUND) + set(HarfBuzz_LIBRARIES ${HarfBuzz_LIBRARY} ${HarfBuzz_ICU_LIBRARY}) + set(HarfBuzz_INCLUDE_DIRS ${HarfBuzz_INCLUDE_DIR} ${HarfBuzz_ICU_INCLUDE_DIR}) +endif () diff --git a/cmake/FindWebP.cmake b/cmake/FindWebP.cmake new file mode 100644 index 000000000..860dc3dfe --- /dev/null +++ b/cmake/FindWebP.cmake @@ -0,0 +1,97 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindWebP +------- + +Finds the WebP library. + +Imported Targets +^^^^^^^^^^^^^^^^ + +This module provides the following imported targets, if found: + +``WebP::WebP`` + The WebP library + +Result Variables +^^^^^^^^^^^^^^^^ + +This will define the following variables: + +``WebP_FOUND`` + True if the system has the WebP library. +``WebP_VERSION`` + The version of the WebP library which was found. +``WebP_INCLUDE_DIRS`` + Include directories needed to use WebP. +``WebP_LIBRARIES`` + Libraries needed to link to WebP. + +Cache Variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: + +``WebP_INCLUDE_DIR`` + The directory containing ``decode.h``. +``WebP_LIBRARY`` + The path to the Foo library. + +#]=======================================================================] + +if(NOT WebP_LIBRARY) + find_package(PkgConfig QUIET) + pkg_check_modules(PC_WebP QUIET libwebp) + set(WebP_VERSION ${PC_WebP_VERSION}) + find_path(WebP_INCLUDE_DIR NAMES decode.h HINTS ${PC_WebP_INCLUDEDIR} ${PC_WebP_INCLUDE_DIR} PATH_SUFFIXES webp) + find_library(WebP_LIBRARY_RELEASE NAMES ${WebP_NAMES} webp HINTS ${PC_WebP_LIBDIR} ${PC_WebP_LIBRARY_DIRS}) + find_library(WebP_LIBRARY_DEBUG NAMES ${WebP_NAMES} webpd HINTS ${PC_WebP_LIBDIR} ${PC_WebP_LIBRARY_DIRS}) + include(SelectLibraryConfigurations) + select_library_configurations(WebP) +else() + file(TO_CMAKE_PATH "${WebP_LIBRARY}" WebP_LIBRARY) +endif() + +if ("${WebP_FIND_VERSION}" VERSION_GREATER "${WebP_VERSION}") + if (WebP_VERSION) + message(FATAL_ERROR "Required version (" ${WebP_FIND_VERSION} ") is higher than found version (" ${PC_WebP_VERSION} ")") + else () + message(WARNING "Cannot determine WebP version without pkg-config") + endif () +endif () + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(WebP + REQUIRED_VARS + WebP_LIBRARY + WebP_INCLUDE_DIR + VERSION_VAR WebP_VERSION +) +mark_as_advanced(WebP_INCLUDE_DIR WebP_LIBRARY) + +if (WebP_FOUND) + set(WebP_LIBRARIES ${WebP_LIBRARY}) + set(WebP_INCLUDE_DIRS ${WebP_INCLUDE_DIR}) + if(NOT TARGET WebP::WebP) + add_library(WebP::WebP UNKNOWN IMPORTED) + set_target_properties(WebP::WebP PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${WebP_INCLUDE_DIR} + IMPORTED_LINK_INTERFACE_LANGUAGES C) + + if(WebP_LIBRARY_RELEASE) + set_property(TARGET WebP::WebP APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(WebP::WebP PROPERTIES IMPORTED_LOCATION_RELEASE "${WebP_LIBRARY_RELEASE}") + endif() + + if(WebP_LIBRARY_DEBUG) + set_property(TARGET WebP::WebP APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(WebP::WebP PROPERTIES IMPORTED_LOCATION_DEBUG "${WebP_LIBRARY_DEBUG}") + endif() + + if(NOT WebP_LIBRARY_RELEASE AND NOT WebP_LIBRARY_DEBUG) + set_target_properties(WebP::WebP PROPERTIES IMPORTED_LOCATION "${WebP_LIBRARY}") + endif() + endif() +endif () diff --git a/cmake/GetVersion.cmake b/cmake/GetVersion.cmake new file mode 100644 index 000000000..8c512645b --- /dev/null +++ b/cmake/GetVersion.cmake @@ -0,0 +1,12 @@ +macro(get_mapnik_version) + file(READ ${CMAKE_CURRENT_SOURCE_DIR}/include/mapnik/version.hpp VERSION_FILE) + + string(REGEX MATCH "MAPNIK_MAJOR_VERSION ([0-9]*)" _ ${VERSION_FILE}) + set(MAPNIK_MAJOR_VERSION ${CMAKE_MATCH_1}) + + string(REGEX MATCH "MAPNIK_MINOR_VERSION ([0-9]*)" _ ${VERSION_FILE}) + set(MAPNIK_MINOR_VERSION ${CMAKE_MATCH_1}) + + string(REGEX MATCH "MAPNIK_PATCH_VERSION ([0-9]*)" _ ${VERSION_FILE}) + set(MAPNIK_PATCH_VERSION ${CMAKE_MATCH_1}) +endmacro() diff --git a/cmake/MapnikCopyDependencies.cmake b/cmake/MapnikCopyDependencies.cmake new file mode 100644 index 000000000..4d14174a7 --- /dev/null +++ b/cmake/MapnikCopyDependencies.cmake @@ -0,0 +1,61 @@ +function(mapnik_find_target_location) + set(options) + set(multiValueArgs TARGETS) + cmake_parse_arguments( WIG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + +endfunction() + +function(mapnik_copy_dependencies) + if(COPY_LIBRARIES_FOR_EXECUTABLES AND WIN32) + set(options) + set(oneValueArgs) + set(multiValueArgs TARGETS PLUGINS) + cmake_parse_arguments(MAPNIK_CP_DEPS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + include(CopyDllsForDebug) + foreach(TARGET IN LISTS MAPNIK_CP_DEPS_TARGETS) + add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "$" ${CMAKE_CURRENT_BINARY_DIR}) + endforeach() + + set(LIBS "") + foreach(PLUGIN IN LISTS MAPNIK_CP_DEPS_PLUGINS) + if(TARGET ${PLUGIN}) # only copy plugins that are be build + list(APPEND LIBS "$") + endif() + endforeach() + copy_dlls_for_debug(TARGETS ${MAPNIK_CP_DEPS_TARGETS} LIBS ${LIBS} DIRS ${ADDITIONAL_LIBARIES_PATHS}) + endif() +endfunction() + +function(mapnik_copy_plugins) + if(COPY_FONTS_AND_PLUGINS_FOR_EXECUTABLES) + set(options) + set(oneValueArgs TARGET DESTINATION) + set(multiValueArgs PLUGINS) + cmake_parse_arguments(MAPNIK_CP_PLG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + # copy_if_different requires a existing directory. + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${MAPNIK_CP_PLG_DESTINATION}) + foreach(PLUGIN IN LISTS MAPNIK_CP_PLG_PLUGINS) + #message(STATUS "copying plugin ${PLUGIN} to path: ${CMAKE_CURRENT_BINARY_DIR}/${MAPNIK_CP_PLG_DESTINATION}") + if(TARGET ${PLUGIN}) + add_custom_command(TARGET ${MAPNIK_CP_PLG_TARGET} POST_BUILD COMMAND + ${CMAKE_COMMAND} -E copy_if_different "$" ${CMAKE_CURRENT_BINARY_DIR}/${MAPNIK_CP_PLG_DESTINATION}/) + else() + message(NOTICE "${MAPNIK_CP_PLG_TARGET} requires plugin ${PLUGIN} but it isn't build. Check USE_PLUGIN_INPUT_ options to enable the plugin.") + endif() + endforeach() + endif() +endfunction() + +function(mapnik_require_fonts) + if(COPY_FONTS_AND_PLUGINS_FOR_EXECUTABLES) + set(options) + set(oneValueArgs TARGET DESTINATION) + set(multiValueArgs) + cmake_parse_arguments(MAPNIK_REQUIRE_FONTS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + add_custom_command(TARGET ${MAPNIK_REQUIRE_FONTS_TARGET} POST_BUILD COMMAND + ${CMAKE_COMMAND} -E copy_directory ${mapnik_SOURCE_DIR}/fonts ${CMAKE_CURRENT_BINARY_DIR}/${MAPNIK_REQUIRE_FONTS_DESTINATION}/) + endif() +endfunction() diff --git a/cmake/MapnikFindPackage.cmake b/cmake/MapnikFindPackage.cmake new file mode 100644 index 000000000..8bcd96216 --- /dev/null +++ b/cmake/MapnikFindPackage.cmake @@ -0,0 +1,42 @@ +macro(mapnik_print_version) + string(TOUPPER ${ARGV0} TLNUP) + set(TLN ${ARGV0}) + if(${TLN}_VERSION_STRING) + message(STATUS "Using ${ARGV0} version: ${${TLN}_VERSION_STRING}") + elseif(${TLN}_VERSION) + message(STATUS "Using ${ARGV0} version: ${${TLN}_VERSION}") + elseif(${TLNUP}_VERSION_STRING) + message(STATUS "Using ${ARGV0} version: ${${TLNUP}_VERSION_STRING}") + elseif(${TLNUP}_VERSION) + message(STATUS "Using ${ARGV0} version: ${${TLNUP}_VERSION}") + else() + message(STATUS "Using ${ARGV0}") + endif() +endmacro() + +macro(mapnik_find_package) + find_package(${ARGN}) + if(${ARGV0}_FOUND) + set(MAPNIK_TMP_DEP ${ARGN}) + list(JOIN MAPNIK_TMP_DEP " " MAPNIK_TMP_DEP) + list(APPEND MAPNIK_DEPENDENCIES "find_dependency(${MAPNIK_TMP_DEP})") + mapnik_print_version(${ARGV0}) + else() + message(STATUS "not found: ${ARGV0}") + endif() +endmacro() + +macro(mapnik_find_threads) + find_package(Threads REQUIRED) + if(CMAKE_THREAD_LIBS_INIT) + message(STATUS "Using Threads (system libraries)") + elseif(CMAKE_USE_WIN32_THREADS_INIT) + message(STATUS "Using Threads (win32 threads)") + elseif(CMAKE_USE_PTHREADS_INIT) + message(STATUS "Using Threads (pthread)") + elseif(CMAKE_HP_PTHREADS_INIT) + message(STATUS "Using Threads (HP thread)") + else() + message(STATUS "Using Threads (unknown backend)") + endif() +endmacro() diff --git a/cmake/MapnikInstall.cmake b/cmake/MapnikInstall.cmake new file mode 100644 index 000000000..5e9cd1349 --- /dev/null +++ b/cmake/MapnikInstall.cmake @@ -0,0 +1,63 @@ +function(mapnik_install) + set(options ALREADY_INSTALLED IS_PLUGIN) + set(oneValueArgs TARGET) + set(multiValueArgs) + cmake_parse_arguments(MAPNIK_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT MAPNIK_INSTALL_ALREADY_INSTALLED AND NOT MAPNIK_INSTALL_IS_PLUGIN) + install(TARGETS ${MAPNIK_INSTALL_TARGET} + LIBRARY DESTINATION ${MAPNIK_LIB_DIR} + ARCHIVE DESTINATION ${MAPNIK_ARCHIVE_DIR} + RUNTIME DESTINATION ${MAPNIK_BIN_DIR} + ) + elseif(NOT MAPNIK_INSTALL_ALREADY_INSTALLED AND MAPNIK_INSTALL_IS_PLUGIN) + install(TARGETS ${MAPNIK_INSTALL_TARGET} + LIBRARY DESTINATION ${PLUGINS_INSTALL_DIR} + ARCHIVE DESTINATION ${PLUGINS_INSTALL_DIR} + RUNTIME DESTINATION ${PLUGINS_INSTALL_DIR} + ) + endif() + if(NOT MAPNIK_INSTALL_IS_PLUGIN) + message(STATUS "${MAPNIK_INSTALL_TARGET}") + get_target_property(TARGET_TYPE "${MAPNIK_INSTALL_TARGET}" TYPE) + if (TARGET_TYPE STREQUAL "EXECUTABLE") + get_property(MAPNIK_INSTALLED_TARGETS GLOBAL PROPERTY TARGETS) + list(APPEND MAPNIK_INSTALLED_TARGETS ${MAPNIK_INSTALL_TARGET}) + set_property(GLOBAL PROPERTY TARGETS ${MAPNIK_INSTALLED_TARGETS}) + endif() + else() + get_property(MAPNIK_INSTALLED_PLUGINS GLOBAL PROPERTY PLUGINS) + list(APPEND MAPNIK_INSTALLED_PLUGINS ${MAPNIK_INSTALL_TARGET}) + set_property(GLOBAL PROPERTY PLUGINS ${MAPNIK_INSTALLED_PLUGINS}) + endif() +endfunction() + + +function(mapnik_install_targets) + if(INSTALL_DEPENDENCIES AND WIN32) + # https://cmake.org/cmake/help/latest/policy/CMP0087.html + cmake_policy(SET CMP0087 NEW) + get_property(MAPNIK_INSTALLED_TARGETS GLOBAL PROPERTY TARGETS) + get_property(MAPNIK_INSTALLED_PLUGINS GLOBAL PROPERTY PLUGINS) + set(INTERNAL_TARGETS "") + set(INTERNAL_PLUGINS "") + + foreach(_target IN LISTS MAPNIK_INSTALLED_TARGETS) + list(APPEND INTERNAL_TARGETS "${CMAKE_INSTALL_PREFIX}/${MAPNIK_BIN_DIR}/$") + endforeach() + foreach(_target IN LISTS MAPNIK_INSTALLED_PLUGINS) + list(APPEND INTERNAL_PLUGINS "${CMAKE_INSTALL_PREFIX}/${PLUGINS_INSTALL_DIR}/$") + endforeach() + # all other executables get auto detected and fixed. + list(GET INTERNAL_TARGETS 0 INTERNAL_TARGETS) + + INSTALL(CODE " + message(STATUS \"${INTERNAL_TARGETS}\") + message(STATUS \"${INTERNAL_PLUGINS}\") + + include(BundleUtilities) + fixup_bundle(\"${INTERNAL_TARGETS}\" \"${INTERNAL_PLUGINS}\" \"${ADDITIONAL_LIBARIES_PATHS}\") + " COMPONENT Runtime) + endif() + +endfunction() diff --git a/cmake/mapnikConfig.cmake.in b/cmake/mapnikConfig.cmake.in new file mode 100644 index 000000000..8e724e9ff --- /dev/null +++ b/cmake/mapnikConfig.cmake.in @@ -0,0 +1,15 @@ +@PACKAGE_INIT@ + +set_and_check(MAPNIK_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@" CACHE STRING "") +set_and_check(MAPNIK_PLUGINS_DIR "@PACKAGE_PLUGINS_INSTALL_DIR@" CACHE STRING "") +set_and_check(MAPNIK_FONTS_DIR "@PACKAGE_FONTS_INSTALL_DIR@" CACHE STRING "") + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/Modules/") + +include(CMakeFindDependencyMacro) +@MAPNIK_DEPENDENCIES@ + + +include("${CMAKE_CURRENT_LIST_DIR}/mapnikTargets.cmake") + +check_required_components(mapnik) diff --git a/cmake/pack.cmake b/cmake/pack.cmake new file mode 100644 index 000000000..eb27bda41 --- /dev/null +++ b/cmake/pack.cmake @@ -0,0 +1,14 @@ +include(InstallRequiredSystemLibraries) +set(CPACK_SOURCE_GENERATOR "TGZ") +set(CPACK_GENERATOR "TGZ") +set(CPACK_SOURCE_IGNORE_FILES + \\.git/ + build/ + ".*~$" + out/ + \\.vs/ + \\.vscode/ +) +set(CPACK_VERBATIM_VARIABLES YES) + +include(CPack) diff --git a/demo/CMakeLists.txt b/demo/CMakeLists.txt new file mode 100644 index 000000000..f69a8f697 --- /dev/null +++ b/demo/CMakeLists.txt @@ -0,0 +1,9 @@ +if(BUILD_DEMO_VIEWER) + message(STATUS "Building demo viewer") + add_subdirectory(viewer) +endif() + +if(BUILD_DEMO_CPP) + message(STATUS "Building c++ demo app") + add_subdirectory(c++) +endif() diff --git a/demo/c++/CMakeLists.txt b/demo/c++/CMakeLists.txt new file mode 100644 index 000000000..7b86d37f2 --- /dev/null +++ b/demo/c++/CMakeLists.txt @@ -0,0 +1,10 @@ +project(mapnik-demo) + +add_executable(mapnik-demo rundemo.cpp) + +target_link_libraries(mapnik-demo PRIVATE mapnik::core mapnik::agg mapnik::mapnik) + +mapnik_install(TARGET mapnik-demo) +mapnik_copy_plugins(TARGET mapnik-demo DESTINATION plugins/input PLUGINS input-shape) +mapnik_require_fonts(TARGET mapnik-demo DESTINATION fonts) +mapnik_copy_dependencies(TARGETS mapnik-demo PLUGINS input-shape) diff --git a/demo/viewer/CMakeLists.txt b/demo/viewer/CMakeLists.txt new file mode 100644 index 000000000..9f866d707 --- /dev/null +++ b/demo/viewer/CMakeLists.txt @@ -0,0 +1,79 @@ +project(mapnik-viewer) + +find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets REQUIRED) + +set(PROJECT_SOURCES + about_dialog.cpp + info_dialog.cpp + layerdelegate.cpp + layerlistmodel.cpp + layerwidget.cpp + layer_info_dialog.cpp + main.cpp + mainwindow.cpp + mapwidget.cpp + styles_model.cpp + forms/about.ui + forms/info.ui + forms/layer_info.ui + mapnik_viewer.qrc +) + +if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_add_executable(mapnik-viewer + MANUAL_FINALIZATION + ${PROJECT_SOURCES} + ) +else() + if(ANDROID) + add_library(mapnik-viewer SHARED + ${PROJECT_SOURCES} + ) + else() + add_executable(mapnik-viewer + ${PROJECT_SOURCES} + ) + endif() +endif() + +set_target_properties(mapnik-viewer PROPERTIES + AUTOUIC_SEARCH_PATHS forms + AUTORCC ON + AUTOUIC ON + AUTOMOC ON +) + +target_link_libraries(mapnik-viewer PRIVATE + Qt${QT_VERSION_MAJOR}::Widgets + mapnik::core + mapnik::agg + mapnik::mapnik +) + +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/viewer.ini +"[mapnik] +plugins_dir=${PLUGINS_INSTALL_DIR} +fonts/1/dir=${FONTS_INSTALL_DIR}" +) + +if(QT_VERSION_MAJOR EQUAL 6) + qt_finalize_executable(mapnik-viewer) +endif() + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/viewer.ini DESTINATION bin) +mapnik_install(TARGET mapnik-viewer) + +mapnik_copy_dependencies( + TARGETS + mapnik-viewer + PLUGINS + input-csv input-gdal input-geobuf input-geojson input-ogr input-pgraster input-postgis input-raster input-shape input-sqlite input-topojson +) + +mapnik_copy_plugins(TARGET mapnik-viewer + DESTINATION + ${PLUGINS_INSTALL_DIR} + PLUGINS + input-csv input-gdal input-geobuf input-geojson input-ogr input-pgraster input-postgis input-raster input-shape input-sqlite input-topojson +) diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt new file mode 100644 index 000000000..603a29b69 --- /dev/null +++ b/deps/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(agg) diff --git a/deps/agg/CMakeLists.txt b/deps/agg/CMakeLists.txt new file mode 100644 index 000000000..9cd0de942 --- /dev/null +++ b/deps/agg/CMakeLists.txt @@ -0,0 +1,19 @@ +project(agg) + +add_library(agg INTERFACE) +add_library(mapnik::agg ALIAS agg) + +target_include_directories(agg INTERFACE + $ + $ +) +target_link_libraries(agg INTERFACE mapnik::core) + +install(TARGETS agg + EXPORT MapnikTargets + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + RUNTIME DESTINATION bin + PUBLIC_HEADER DESTINATION include +) +# todo install headers diff --git a/docs/cmake-usage.md b/docs/cmake-usage.md new file mode 100644 index 000000000..f3cfbcf05 --- /dev/null +++ b/docs/cmake-usage.md @@ -0,0 +1,104 @@ +# Usage with CMake +## Build +First clone mapnik from github and initialize submodules + +```bash +git clone https://github.com/mapnik/mapnik.git +cd mapnik +git submodule update --init +``` + +Make sure that all dependencies are installed. + +All available cmake options are listed at the top of [CMakeLists.txt](../CMakeLists.txt). +Pass your options while configuring e.g.: `cmake -DBUILD_DEMO_VIEWER=OFF ..` to disable the build of the demo viewer application. + +To quickstart open a console in the root mapnik dir and execute the following commands: (Pass all options and dependency dirs after `-DBUILD_TEST=OFF`) +``` +> cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_TEST=OFF +> cmake --build build --target install +``` + +## Usage + +To use Mapnik in your project add the following lines to your CMakeLists.tzt. +``` +find_package(mapnik CONFIG REQUIRED) +[...] +target_link_libraries(mytarget ... mapnik::core mapnik::mapnik) +``` + +All mapnik executables and targets are exported within `mapnikTargets.cmake`. + +The plugin dir is available in the variable `MAPNIK_PLUGINS_DIR`. +The font path is is available in the variable `MAPNIK_FONTS_DIR`. + +## Recommendations + +If you target a specific platform, it is recommended to create a toolchain file and set all the options and library path that you would normally set via cmd line options. +If you are using a recent cmake version (>=3.20), it is recommended to use a CMakePreset instead. https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html + + +## CMakePreset example + +If you are using CMakePresets and need to add vcpkg integration, just create a `CMakeUserPresets.json` file beside `CMakePresets.json. +This could look like this: +```json +{ + "version": 2, + "cmakeMinimumRequired": { + "major": 3, + "minor": 20, + "patch": 0 + }, + "configurePresets": [ + { + "name": "vcpkg-x64-win-debug", + "inherits": "windows-default-debug", + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "/scripts/buildsystems/vcpkg.cmake", + "ADDITIONAL_LIBARIES_PATHS":"/installed/x64-windows/debug/bin" + } + }, + { + "name": "vcpkg-x64-win-release", + "inherits": "windows-default-release", + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "/scripts/buildsystems/vcpkg.cmake", + "ADDITIONAL_LIBARIES_PATHS":"/installed/x64-windows/bin" + } + } + ] +} +``` + + +If your libraries are not in the global search paths, you could add a own `CMakeUserPresets.json` with + +```json +{ + "version": 2, + "cmakeMinimumRequired": { + "major": 3, + "minor": 20, + "patch": 0 + }, + "configurePresets": [ + { + "name": "linux-clang-debug-own", + "inherits": "linux-clang-debug", + "cacheVariables": { + "WebP_DIR": "/home/myuser/webp/cmake", + "USE_CAIRO": "OFF", + "CMAKE_INSTALL_PREFIX": "${sourceDir}/install" + } + } + ] +} +``` + +Build with: +``` +$ cmake --preset +$ cmake --build --preset +``` diff --git a/include/mapnik/css/css_color_grammar_x3_def.hpp b/include/mapnik/css/css_color_grammar_x3_def.hpp index e42c02470..5db0d9c92 100644 --- a/include/mapnik/css/css_color_grammar_x3_def.hpp +++ b/include/mapnik/css/css_color_grammar_x3_def.hpp @@ -430,7 +430,6 @@ auto const css_color_def = hsla_color ; -#include MAPNIK_DISABLE_WARNING_PUSH #include BOOST_SPIRIT_DEFINE( diff --git a/include/mapnik/feature_style_processor.hpp b/include/mapnik/feature_style_processor.hpp index e9d96dfa6..0a5e4c0ed 100644 --- a/include/mapnik/feature_style_processor.hpp +++ b/include/mapnik/feature_style_processor.hpp @@ -52,7 +52,7 @@ enum eAttributeCollectionPolicy }; template -class MAPNIK_DECL feature_style_processor +class feature_style_processor { public: explicit feature_style_processor(Map const& m, diff --git a/include/mapnik/geometry.hpp b/include/mapnik/geometry.hpp index 1f5b8da3b..e566c7d7f 100644 --- a/include/mapnik/geometry.hpp +++ b/include/mapnik/geometry.hpp @@ -59,7 +59,7 @@ struct geometry : geometry_base { using coordinate_type = T; -#if __cpp_inheriting_constructors >= 200802 +#if __cpp_inheriting_constructors >= 200802 && !defined (_MSC_VER) using geometry_base::geometry_base; diff --git a/include/mapnik/geometry/box2d.hpp b/include/mapnik/geometry/box2d.hpp index fe008575c..64bc467cf 100644 --- a/include/mapnik/geometry/box2d.hpp +++ b/include/mapnik/geometry/box2d.hpp @@ -33,6 +33,9 @@ MAPNIK_DISABLE_WARNING_PUSH #include MAPNIK_DISABLE_WARNING_POP +// stl +#include + // agg // forward declare so that apps using mapnik do not need agg headers namespace agg { diff --git a/include/mapnik/json/geojson_grammar_x3.hpp b/include/mapnik/json/geojson_grammar_x3.hpp index 10c63ac3e..ce2b5daf8 100644 --- a/include/mapnik/json/geojson_grammar_x3.hpp +++ b/include/mapnik/json/geojson_grammar_x3.hpp @@ -54,7 +54,7 @@ using geojson_value_base = mapnik::util::variant; struct geojson_value : geojson_value_base { -#if __cpp_inheriting_constructors >= 200802 +#if __cpp_inheriting_constructors >= 200802 && !defined (_MSC_VER) using geojson_value_base::geojson_value_base; diff --git a/include/mapnik/json/json_value.hpp b/include/mapnik/json/json_value.hpp index 5d9f34352..234d23899 100644 --- a/include/mapnik/json/json_value.hpp +++ b/include/mapnik/json/json_value.hpp @@ -46,7 +46,7 @@ using json_value_base = mapnik::util::variant; struct json_value : json_value_base { -#if __cpp_inheriting_constructors >= 200802 +#if __cpp_inheriting_constructors >= 200802 && !defined (_MSC_VER) using json_value_base::json_value_base; diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt new file mode 100644 index 000000000..76cc4ef34 --- /dev/null +++ b/plugins/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(input) diff --git a/plugins/input/CMakeLists.txt b/plugins/input/CMakeLists.txt new file mode 100644 index 000000000..d289c2a3e --- /dev/null +++ b/plugins/input/CMakeLists.txt @@ -0,0 +1,44 @@ +if(USE_PLUGIN_INPUT_CSV) + message(STATUS "using input plugin csv") + add_subdirectory(csv) +endif() +if(USE_PLUGIN_INPUT_GDAL) + message(STATUS "using input plugin gdal") + add_subdirectory(gdal) +endif() +if(USE_PLUGIN_INPUT_GEOBUF) + message(STATUS "using input plugin geobuf") + add_subdirectory(geobuf) +endif() +if(USE_PLUGIN_INPUT_GEOJSON) + message(STATUS "using input plugin geojson") + add_subdirectory(geojson) +endif() +if(USE_PLUGIN_INPUT_OGR) + message(STATUS "using input plugin ogr") + add_subdirectory(ogr) +endif() +if(USE_PLUGIN_INPUT_PGRASTER) + message(STATUS "using input plugin pgraster") + add_subdirectory(pgraster) +endif() +if(USE_PLUGIN_INPUT_POSTGIS) + message(STATUS "using input plugin postgis") + add_subdirectory(postgis) +endif() +if(USE_PLUGIN_INPUT_RASTER) + message(STATUS "using input plugin raster") + add_subdirectory(raster) +endif() +if(USE_PLUGIN_INPUT_SHAPE) + message(STATUS "using input plugin shape") + add_subdirectory(shape) +endif() +if(USE_PLUGIN_INPUT_SQLITE) + message(STATUS "using input plugin sqlite") + add_subdirectory(sqlite) +endif() +if(USE_PLUGIN_INPUT_TOPOJSON) + message(STATUS "using input plugin topojson") + add_subdirectory(topojson) +endif() diff --git a/plugins/input/csv/CMakeLists.txt b/plugins/input/csv/CMakeLists.txt new file mode 100644 index 000000000..ecf4edda6 --- /dev/null +++ b/plugins/input/csv/CMakeLists.txt @@ -0,0 +1,22 @@ +project(input-csv) + +add_library(input-csv MODULE + csv_datasource.cpp + csv_featureset.cpp + csv_index_featureset.cpp + csv_inline_featureset.cpp + csv_utils.cpp +) +add_library(mapnik::plugin::input::csv ALIAS input-csv) + +target_link_libraries(input-csv PRIVATE + mapnik::core + mapnik::mapnik + mapnik::wkt + mapnik::json +) +set_target_properties(input-csv PROPERTIES PREFIX "") +set_target_properties(input-csv PROPERTIES OUTPUT_NAME "csv") +set_target_properties(input-csv PROPERTIES SUFFIX ".input") + +mapnik_install(TARGET input-csv IS_PLUGIN) diff --git a/plugins/input/gdal/CMakeLists.txt b/plugins/input/gdal/CMakeLists.txt new file mode 100644 index 000000000..ca0cb4d6f --- /dev/null +++ b/plugins/input/gdal/CMakeLists.txt @@ -0,0 +1,21 @@ +project(input-gdal) + +find_package(GDAL REQUIRED) + +add_library(input-gdal MODULE + gdal_datasource.cpp + gdal_featureset.cpp +) +add_library(mapnik::plugin::input::gdal ALIAS input-gdal) + +target_include_directories(input-gdal PRIVATE ${GDAL_INCLUDE_DIRS}) +target_link_libraries(input-gdal PRIVATE + mapnik::core + mapnik::mapnik + ${GDAL_LIBRARIES} +) +set_target_properties(input-gdal PROPERTIES PREFIX "") +set_target_properties(input-gdal PROPERTIES OUTPUT_NAME "gdal") +set_target_properties(input-gdal PROPERTIES SUFFIX ".input") + +mapnik_install(TARGET input-gdal IS_PLUGIN) diff --git a/plugins/input/geobuf/CMakeLists.txt b/plugins/input/geobuf/CMakeLists.txt new file mode 100644 index 000000000..56a027aeb --- /dev/null +++ b/plugins/input/geobuf/CMakeLists.txt @@ -0,0 +1,17 @@ +project(input-geobuf) + +add_library(input-geobuf MODULE + geobuf_datasource.cpp + geobuf_featureset.cpp +) +add_library(mapnik::plugin::input::geobuf ALIAS input-geobuf) + +target_link_libraries(input-geobuf PRIVATE + mapnik::core + mapnik::mapnik +) +set_target_properties(input-geobuf PROPERTIES PREFIX "") +set_target_properties(input-geobuf PROPERTIES OUTPUT_NAME "geobuf") +set_target_properties(input-geobuf PROPERTIES SUFFIX ".input") + +mapnik_install(TARGET input-geobuf IS_PLUGIN) diff --git a/plugins/input/geojson/CMakeLists.txt b/plugins/input/geojson/CMakeLists.txt new file mode 100644 index 000000000..6f830e13b --- /dev/null +++ b/plugins/input/geojson/CMakeLists.txt @@ -0,0 +1,21 @@ +project(input-geojson) + +add_library(input-geojson MODULE + geojson_datasource.cpp + geojson_featureset.cpp + geojson_index_featureset.cpp + geojson_memory_index_featureset.cpp +) +add_library(mapnik::plugin::input::geojson ALIAS input-geojson) + +target_link_libraries(input-geojson PRIVATE + mapnik::core + mapnik::mapnik + mapnik::json +) + +set_target_properties(input-geojson PROPERTIES PREFIX "") +set_target_properties(input-geojson PROPERTIES OUTPUT_NAME "geojson") +set_target_properties(input-geojson PROPERTIES SUFFIX ".input") + +mapnik_install(TARGET input-geojson IS_PLUGIN) diff --git a/plugins/input/ogr/CMakeLists.txt b/plugins/input/ogr/CMakeLists.txt new file mode 100644 index 000000000..599a325a9 --- /dev/null +++ b/plugins/input/ogr/CMakeLists.txt @@ -0,0 +1,23 @@ +project(input-ogr) + +find_package(GDAL REQUIRED) + +add_library(input-ogr MODULE + ogr_converter.cpp + ogr_datasource.cpp + ogr_featureset.cpp + ogr_index_featureset.cpp +) +add_library(mapnik::plugin::input::ogr ALIAS input-ogr) + +target_include_directories(input-ogr PRIVATE ${GDAL_INCLUDE_DIRS}) +target_link_libraries(input-ogr PRIVATE + mapnik::core + mapnik::mapnik + ${GDAL_LIBRARIES} +) +set_target_properties(input-ogr PROPERTIES PREFIX "") +set_target_properties(input-ogr PROPERTIES OUTPUT_NAME "ogr") +set_target_properties(input-ogr PROPERTIES SUFFIX ".input") + +mapnik_install(TARGET input-ogr IS_PLUGIN) diff --git a/plugins/input/pgraster/CMakeLists.txt b/plugins/input/pgraster/CMakeLists.txt new file mode 100644 index 000000000..adcb6d8f6 --- /dev/null +++ b/plugins/input/pgraster/CMakeLists.txt @@ -0,0 +1,22 @@ +project(input-pgraster) + +find_package(PostgreSQL REQUIRED) + +add_library(input-pgraster MODULE + pgraster_datasource.cpp + pgraster_featureset.cpp + pgraster_wkb_reader.cpp +) +add_library(mapnik::plugin::input::pgraster ALIAS input-pgraster) + + +target_link_libraries(input-pgraster PRIVATE + mapnik::core + mapnik::mapnik + PostgreSQL::PostgreSQL +) +set_target_properties(input-pgraster PROPERTIES PREFIX "") +set_target_properties(input-pgraster PROPERTIES OUTPUT_NAME "pgraster") +set_target_properties(input-pgraster PROPERTIES SUFFIX ".input") + +mapnik_install(TARGET input-pgraster IS_PLUGIN) diff --git a/plugins/input/postgis/CMakeLists.txt b/plugins/input/postgis/CMakeLists.txt new file mode 100644 index 000000000..843786857 --- /dev/null +++ b/plugins/input/postgis/CMakeLists.txt @@ -0,0 +1,21 @@ +project(input-postgis) + +find_package(PostgreSQL REQUIRED) + +add_library(input-postgis MODULE + postgis_datasource.cpp + postgis_featureset.cpp +) +add_library(mapnik::plugin::input::postgis ALIAS input-postgis) + +target_link_libraries(input-postgis PRIVATE + mapnik::core + mapnik::mapnik + PostgreSQL::PostgreSQL +) + +set_target_properties(input-postgis PROPERTIES PREFIX "") +set_target_properties(input-postgis PROPERTIES OUTPUT_NAME "postgis") +set_target_properties(input-postgis PROPERTIES SUFFIX ".input") + +mapnik_install(TARGET input-postgis IS_PLUGIN) diff --git a/plugins/input/raster/CMakeLists.txt b/plugins/input/raster/CMakeLists.txt new file mode 100644 index 000000000..f4e2f0ef8 --- /dev/null +++ b/plugins/input/raster/CMakeLists.txt @@ -0,0 +1,19 @@ +project(input-raster) + +add_library(input-raster MODULE + raster_datasource.cpp + raster_featureset.cpp + raster_info.cpp +) +add_library(mapnik::plugin::input::raster ALIAS input-raster) + +target_link_libraries(input-raster PRIVATE + mapnik::core + mapnik::mapnik +) + +set_target_properties(input-raster PROPERTIES PREFIX "") +set_target_properties(input-raster PROPERTIES OUTPUT_NAME "raster") +set_target_properties(input-raster PROPERTIES SUFFIX ".input") + +mapnik_install(TARGET input-raster IS_PLUGIN) diff --git a/plugins/input/shape/CMakeLists.txt b/plugins/input/shape/CMakeLists.txt new file mode 100644 index 000000000..2c6ec6979 --- /dev/null +++ b/plugins/input/shape/CMakeLists.txt @@ -0,0 +1,22 @@ +project(input-shape) + +add_library(input-shape MODULE + dbfile.cpp + dbf_test.cpp + shape_datasource.cpp + shape_featureset.cpp + shape_index_featureset.cpp + shape_io.cpp shape_utils.cpp +) +add_library(mapnik::plugin::input::shape ALIAS input-shape) + +target_link_libraries(input-shape PRIVATE + mapnik::core + mapnik::mapnik +) + +set_target_properties(input-shape PROPERTIES PREFIX "") +set_target_properties(input-shape PROPERTIES OUTPUT_NAME "shape") +set_target_properties(input-shape PROPERTIES SUFFIX ".input") + +mapnik_install(TARGET input-shape IS_PLUGIN) diff --git a/plugins/input/sqlite/CMakeLists.txt b/plugins/input/sqlite/CMakeLists.txt new file mode 100644 index 000000000..89e693062 --- /dev/null +++ b/plugins/input/sqlite/CMakeLists.txt @@ -0,0 +1,21 @@ +project(input-sqlite) + +find_package(SQLite3 REQUIRED) + +add_library(input-sqlite MODULE + sqlite_datasource.cpp + sqlite_featureset.cpp +) +add_library(mapnik::plugin::input::sqlite ALIAS input-sqlite) + +target_link_libraries(input-sqlite PRIVATE + mapnik::core + mapnik::mapnik + SQLite::SQLite3 +) + +set_target_properties(input-sqlite PROPERTIES PREFIX "") +set_target_properties(input-sqlite PROPERTIES OUTPUT_NAME "sqlite") +set_target_properties(input-sqlite PROPERTIES SUFFIX ".input") + +mapnik_install(TARGET input-sqlite IS_PLUGIN) diff --git a/plugins/input/topojson/CMakeLists.txt b/plugins/input/topojson/CMakeLists.txt new file mode 100644 index 000000000..966d25b85 --- /dev/null +++ b/plugins/input/topojson/CMakeLists.txt @@ -0,0 +1,19 @@ +project(input-topojson) + +add_library(input-topojson MODULE + topojson_datasource.cpp + topojson_featureset.cpp +) +add_library(mapnik::plugin::input::topojson ALIAS input-topojson) + +target_link_libraries(input-topojson PRIVATE + mapnik::core + mapnik::mapnik + mapnik::json +) + +set_target_properties(input-topojson PROPERTIES PREFIX "") +set_target_properties(input-topojson PROPERTIES OUTPUT_NAME "topojson") +set_target_properties(input-topojson PROPERTIES SUFFIX ".input") + +mapnik_install(TARGET input-topojson IS_PLUGIN) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 000000000..c2679f065 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,318 @@ +add_subdirectory(json) +add_subdirectory(wkt) + +set(MAPNIK_SOURCES + cairo_io.cpp + color_factory.cpp + color.cpp + config_error.cpp + conversions_numeric.cpp + conversions_string.cpp + dasharray_parser.cpp + datasource_cache_static.cpp + datasource_cache.cpp + debug.cpp + expression_grammar_x3.cpp + expression_node.cpp + expression_string.cpp + expression.cpp + feature_kv_iterator.cpp + feature_style_processor.cpp + feature_type_style.cpp + font_engine_freetype.cpp + font_set.cpp + fs.cpp + function_call.cpp + generate_image_filters.cpp + gradient.cpp + image_any.cpp + image_compositing.cpp + image_copy.cpp + image_filter_grammar_x3.cpp + image_options.cpp + image_reader.cpp + image_scaling.cpp + image_util_jpeg.cpp + image_util_png.cpp + image_util_tiff.cpp + image_util_webp.cpp + image_util.cpp + image_view_any.cpp + image_view.cpp + image.cpp + layer.cpp + load_map.cpp + map.cpp + mapped_memory_cache.cpp + marker_cache.cpp + marker_helpers.cpp + memory_datasource.cpp + palette.cpp + params.cpp + parse_image_filters.cpp + parse_path.cpp + parse_transform.cpp + path_expression_grammar_x3.cpp + plugin.cpp + proj_transform_cache.cpp + proj_transform.cpp + projection.cpp + raster_colorizer.cpp + renderer_common.cpp + request.cpp + rule.cpp + save_map.cpp + scale_denominator.cpp + simplify.cpp + symbolizer_enumerations.cpp + symbolizer_keys.cpp + symbolizer.cpp + transform_expression_grammar_x3.cpp + transform_expression.cpp + twkb.cpp + unicode.cpp + value.cpp + vertex_adapters.cpp + vertex_cache.cpp + warp.cpp + well_known_srs.cpp + wkb.cpp + xml_tree.cpp +) +set(COMPILE_SRC ${MAPNIK_SOURCES}) + +if(USE_JPEG) + list(APPEND COMPILE_SRC jpeg_reader.cpp) +endif() +if(USE_PNG) + list(APPEND COMPILE_SRC png_reader.cpp) +endif() +if(USE_TIFF) + list(APPEND COMPILE_SRC tiff_reader.cpp) +endif() + +set(AGG_COMPILE_SRC + ../deps/agg/src/agg_arc.cpp + ../deps/agg/src/agg_arrowhead.cpp + ../deps/agg/src/agg_bezier_arc.cpp + ../deps/agg/src/agg_bspline.cpp + ../deps/agg/src/agg_curves.cpp + ../deps/agg/src/agg_embedded_raster_fonts.cpp + ../deps/agg/src/agg_gsv_text.cpp + ../deps/agg/src/agg_image_filters.cpp + ../deps/agg/src/agg_line_aa_basics.cpp + ../deps/agg/src/agg_line_profile_aa.cpp + ../deps/agg/src/agg_pixfmt_rgba.cpp + ../deps/agg/src/agg_rounded_rect.cpp + ../deps/agg/src/agg_sqrt_tables.cpp + ../deps/agg/src/agg_trans_affine.cpp + ../deps/agg/src/agg_trans_double_path.cpp + ../deps/agg/src/agg_trans_single_path.cpp + ../deps/agg/src/agg_trans_warp_magnifier.cpp + ../deps/agg/src/agg_vcgen_bspline.cpp + ../deps/agg/src/agg_vcgen_contour.cpp + ../deps/agg/src/agg_vcgen_dash.cpp + ../deps/agg/src/agg_vcgen_markers_term.cpp + ../deps/agg/src/agg_vcgen_stroke.cpp + ../deps/agg/src/agg_vpgen_clip_polygon.cpp + ../deps/agg/src/agg_vpgen_clip_polyline.cpp + ../deps/agg/src/agg_vpgen_segmentator.cpp +) +set(AGG_SRC + agg/agg_renderer.cpp + agg/process_building_symbolizer.cpp + agg/process_debug_symbolizer.cpp + agg/process_dot_symbolizer.cpp + agg/process_group_symbolizer.cpp + agg/process_line_pattern_symbolizer.cpp + agg/process_line_symbolizer.cpp + agg/process_markers_symbolizer.cpp + agg/process_point_symbolizer.cpp + agg/process_polygon_pattern_symbolizer.cpp + agg/process_polygon_symbolizer.cpp + agg/process_raster_symbolizer.cpp + agg/process_shield_symbolizer.cpp + agg/process_text_symbolizer.cpp + ${AGG_COMPILE_SRC} +) +list(APPEND COMPILE_SRC ${AGG_SRC}) + +if(USE_CAIRO) + message(STATUS "adding cairo renderer to compilation") + set(CAIRO_SRC + cairo/cairo_context.cpp + cairo/cairo_render_vector.cpp + cairo/cairo_renderer.cpp + cairo/process_building_symbolizer.cpp + cairo/process_debug_symbolizer.cpp + cairo/process_group_symbolizer.cpp + cairo/process_line_pattern_symbolizer.cpp + cairo/process_line_symbolizer.cpp + cairo/process_markers_symbolizer.cpp + cairo/process_point_symbolizer.cpp + cairo/process_polygon_pattern_symbolizer.cpp + cairo/process_polygon_symbolizer.cpp + cairo/process_raster_symbolizer.cpp + cairo/process_text_symbolizer.cpp + ) + list(APPEND COMPILE_SRC ${CAIRO_SRC}) +endif() + +set(CSS_SRC + css/css_color_grammar_x3.cpp + css/css_grammar_x3.cpp +) +list(APPEND COMPILE_SRC ${CSS_SRC}) + +set(GEOMETRY_SRC + geometry/box2d.cpp + geometry/closest_point.cpp + geometry/envelope.cpp + geometry/interior.cpp + geometry/polylabel.cpp + geometry/reprojection.cpp +) +list(APPEND COMPILE_SRC ${GEOMETRY_SRC}) + +if(USE_GRID_RENDERER) + message(STATUS "adding grid renderer to compilation") + set(GRID_SRC + grid/grid_renderer.cpp + grid/grid.cpp + grid/process_building_symbolizer.cpp + grid/process_group_symbolizer.cpp + grid/process_line_pattern_symbolizer.cpp + grid/process_line_symbolizer.cpp + grid/process_markers_symbolizer.cpp + grid/process_point_symbolizer.cpp + grid/process_polygon_pattern_symbolizer.cpp + grid/process_polygon_symbolizer.cpp + grid/process_raster_symbolizer.cpp + grid/process_shield_symbolizer.cpp + grid/process_text_symbolizer.cpp + ) + list(APPEND COMPILE_SRC ${GRID_SRC}) +endif() + +set(GROUP_SRC + group/group_layout_manager.cpp + group/group_rule.cpp + group/group_symbolizer_helper.cpp +) +list(APPEND COMPILE_SRC ${GROUP_SRC}) + +set(RENDERER_COMMON_SRC + renderer_common/pattern_alignment.cpp + renderer_common/render_group_symbolizer.cpp + renderer_common/render_markers_symbolizer.cpp + renderer_common/render_pattern.cpp + renderer_common/render_thunk_extractor.cpp +) +list(APPEND COMPILE_SRC ${RENDERER_COMMON_SRC}) + +set(SVG_SRC + svg/svg_parser.cpp + svg/svg_path_grammar_x3.cpp + svg/svg_path_parser.cpp + svg/svg_points_parser.cpp + svg/svg_transform_parser.cpp +) +if(USE_SVG_RENDERER) + message(STATUS "adding svg renderer to compilation") + set(SVG_RENDERER_SRC + svg/output/process_line_symbolizer.cpp + svg/output/process_polygon_symbolizer.cpp + svg/output/process_symbolizers.cpp + svg/output/svg_generator.cpp + svg/output/svg_output_attributes.cpp + svg/output/svg_output_grammars.cpp + svg/output/svg_renderer.cpp + ) + list(APPEND SVG_SRC ${SVG_RENDERER_SRC}) +endif() +list(APPEND COMPILE_SRC ${SVG_SRC}) + +set(TEXT_SRC + text/color_font_renderer.cpp + text/face.cpp + text/font_feature_settings.cpp + text/font_library.cpp + text/glyph_positions.cpp + text/itemizer.cpp + text/placement_finder.cpp + text/properties_util.cpp + text/renderer.cpp + text/scrptrun.cpp + text/symbolizer_helpers.cpp + text/text_layout.cpp + text/text_line.cpp + text/text_properties.cpp + + text/formatting/base.cpp + text/formatting/format.cpp + text/formatting/layout.cpp + text/formatting/list.cpp + text/formatting/registry.cpp + text/formatting/text.cpp + + text/placements/base.cpp + text/placements/dummy.cpp + text/placements/list.cpp + text/placements/registry.cpp + text/placements/simple.cpp +) +list(APPEND COMPILE_SRC ${TEXT_SRC}) + +set(UTIL_SRC + util/math.cpp + util/utf_conv_win.cpp +) +list(APPEND COMPILE_SRC ${UTIL_SRC}) + +if(USE_LIBXML2) + message(STATUS "adding libxml2_loader to compilation") + list(APPEND COMPILE_SRC libxml2_loader.cpp) +else() + message(STATUS "adding rapidxml_loader to compilation") + list(APPEND COMPILE_SRC rapidxml_loader.cpp) +endif() + +add_library(mapnik ${COMPILE_SRC}) +add_library(mapnik::mapnik ALIAS mapnik) + +set(COMPILE_DEFS "") +if(BUILD_SHARED_LIBS) + list(APPEND COMPILE_DEFS MAPNIK_EXPORTS) +endif() + +target_compile_definitions(mapnik PRIVATE ${COMPILE_DEFS}) +target_link_libraries(mapnik PRIVATE + mapnik::core + mapnik::agg +) + +set_target_properties(mapnik PROPERTIES + DEBUG_POSTFIX "${MAPNIK_DEBUG_POSTFIX}" + OUTPUT_NAME "mapnik" + PREFIX "lib" +) + +if(MSVC) + # disable some msvc warnings and enable bigobj + # 4068 will warn about unknown definitions. Would not be needed if https://github.com/mapbox/geometry.hpp/pull/69 is merged. + # 4661 warns about enum definitions. should be investigated at some point + # 4910 warns about extern and dllexport at the same time. should be investigated at some point + target_compile_options(mapnik PUBLIC "/bigobj" "/wd4068" "/wd4661" "/wd4910") +endif() + +install(TARGETS mapnik + EXPORT MapnikTargets + LIBRARY DESTINATION ${MAPNIK_LIB_DIR} + ARCHIVE DESTINATION ${MAPNIK_ARCHIVE_DIR} + RUNTIME DESTINATION ${MAPNIK_BIN_DIR} + INCLUDES DESTINATION include/ + PUBLIC_HEADER DESTINATION include/ + COMPONENT mapnik +) + +mapnik_install(TARGET mapnik ALREADY_INSTALLED) diff --git a/src/geometry/interior.cpp b/src/geometry/interior.cpp index 5a89e3482..9d9b218e6 100644 --- a/src/geometry/interior.cpp +++ b/src/geometry/interior.cpp @@ -232,7 +232,7 @@ bool interior(polygon const& polygon, double scale_factor, point & pt) return true; } -template +template MAPNIK_DECL bool interior(polygon const& polygon, double scale_factor, point & pt); } } diff --git a/src/geometry/polylabel.cpp b/src/geometry/polylabel.cpp index 84d3b0f14..e695b1b63 100644 --- a/src/geometry/polylabel.cpp +++ b/src/geometry/polylabel.cpp @@ -46,14 +46,14 @@ bool polylabel(polygon const& polygon, T precision, point & pt) return true; } -template -bool polylabel(polygon const& polygon, - double precision, - point & pt); +template MAPNIK_DECL +bool polylabel(polygon const& polygon, + double precision, + point & pt); -template -double polylabel_precision(polygon const& polygon, - double scale_factor); +template MAPNIK_DECL +double polylabel_precision(polygon const& polygon, +double scale_factor); } } diff --git a/src/image_util.cpp b/src/image_util.cpp index 1eabd0a13..82a79842e 100644 --- a/src/image_util.cpp +++ b/src/image_util.cpp @@ -54,7 +54,7 @@ MAPNIK_DISABLE_WARNING_POP #include #include -#if __cplusplus >= 201703L +#if __cpp_lib_execution >= 201603 #include #endif diff --git a/src/json/CMakeLists.txt b/src/json/CMakeLists.txt new file mode 100644 index 000000000..0748d2043 --- /dev/null +++ b/src/json/CMakeLists.txt @@ -0,0 +1,44 @@ +add_library(json STATIC + extract_bounding_boxes_x3.cpp + feature_from_geojson.cpp + feature_grammar_x3.cpp + generic_json_grammar_x3.cpp + geojson_grammar_x3.cpp + geometry_from_geojson.cpp + mapnik_feature_to_geojson.cpp + mapnik_geometry_to_geojson.cpp + mapnik_json_generator_grammar.cpp + parse_feature.cpp + positions_grammar_x3.cpp + topojson_grammar_x3.cpp + unicode_string_grammar_x3.cpp +) +add_library(mapnik::json ALIAS json) + +target_include_directories(json PRIVATE + ${JPEG_INCLUDE_DIR} + ${LIBXML2_INCLUDE_DIR} + ${MAPBOX_POLYLABEL_INCLUDE_DIRS} + ${MAPBOX_GEOMETRY_INCLUDE_DIRS} + ${MAPBOX_VARIANT_INCLUDE_DIRS} +) +target_link_libraries(json PRIVATE mapnik::core ${ICUU_LIB}) + +set_target_properties(json PROPERTIES + POSITION_INDEPENDENT_CODE ON + DEBUG_POSTFIX "${MAPNIK_DEBUG_POSTFIX}" + OUTPUT_NAME "json" + PREFIX "libmapnik-" +) + +install(TARGETS json + EXPORT MapnikTargets + LIBRARY DESTINATION ${MAPNIK_LIB_DIR} + ARCHIVE DESTINATION ${MAPNIK_ARCHIVE_DIR} + RUNTIME DESTINATION ${MAPNIK_BIN_DIR} + INCLUDES DESTINATION include/ + PUBLIC_HEADER DESTINATION include/ + COMPONENT mapnik +) + +mapnik_install(TARGET json) diff --git a/src/wkt/CMakeLists.txt b/src/wkt/CMakeLists.txt new file mode 100644 index 000000000..9c0934290 --- /dev/null +++ b/src/wkt/CMakeLists.txt @@ -0,0 +1,36 @@ +add_library(wkt STATIC + geometry_to_wkt.cpp + mapnik_wkt_generator_grammar.cpp + wkt_factory.cpp + wkt_grammar_x3.cpp +) +add_library(mapnik::wkt ALIAS wkt) + +target_include_directories(wkt PRIVATE + ${MAPNIK_INCLUDE_PATH} + ${JPEG_INCLUDE_DIR} + ${LIBXML2_INCLUDE_DIR} + ${MAPBOX_POLYLABEL_INCLUDE_DIRS} + ${MAPBOX_GEOMETRY_INCLUDE_DIRS} + ${MAPBOX_VARIANT_INCLUDE_DIRS} +) +target_link_libraries(wkt PRIVATE mapnik::core) + +set_target_properties(wkt PROPERTIES + POSITION_INDEPENDENT_CODE ON + DEBUG_POSTFIX "${MAPNIK_DEBUG_POSTFIX}" + OUTPUT_NAME "wkt" + PREFIX "libmapnik-" +) + +install(TARGETS wkt + EXPORT MapnikTargets + LIBRARY DESTINATION ${MAPNIK_LIB_DIR} + ARCHIVE DESTINATION ${MAPNIK_ARCHIVE_DIR} + RUNTIME DESTINATION ${MAPNIK_BIN_DIR} + INCLUDES DESTINATION include/ + PUBLIC_HEADER DESTINATION include/ + COMPONENT mapnik +) + +mapnik_install(TARGET wkt) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 000000000..a18720306 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,200 @@ +project(mapnik-test) + +find_package(Boost REQUIRED COMPONENTS program_options) +find_package(PostgreSQL REQUIRED) + +include(FetchContent) +include(CopyDllsForDebug) + +FetchContent_Declare( + Catch2 + GIT_REPOSITORY https://github.com/catchorg/Catch2.git + GIT_TAG v2.13.7) +FetchContent_MakeAvailable(Catch2) + +# Prepare "Catch" library for other executables +set(CATCH_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +add_library(Catch INTERFACE) +target_include_directories(Catch INTERFACE ${CATCH_INCLUDE_DIR}) + +if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.19.0") + # for cmake 3.19+ https://cmake.org/cmake/help/git-stage/policy/CMP0110.html + # might not be needed if catch updates its cmakes + cmake_policy(SET CMP0110 OLD) +endif() + + +add_executable(mapnik-test-unit + unit/run.cpp + unit/color/css_color.cpp + unit/core/box2d_test.cpp + unit/core/comparison_test.cpp + unit/core/conversions_test.cpp + unit/core/copy_move_test.cpp + unit/core/exceptions_test.cpp + unit/core/expressions_test.cpp + unit/core/params_test.cpp + unit/core/transform_expressions_test.cpp + unit/core/value_test.cpp + unit/datasource/csv.cpp + unit/datasource/gdal.cpp + unit/datasource/geobuf.cpp + unit/datasource/geojson.cpp + unit/datasource/memory.cpp + unit/datasource/ogr.cpp + unit/datasource/postgis.cpp + unit/datasource/shapeindex.cpp + unit/datasource/spatial_index.cpp + unit/datasource/topojson.cpp + unit/font/fontset_runtime_test.cpp + unit/geometry/centroid.cpp + unit/geometry/closest_point.cpp + unit/geometry/geometry.cpp + unit/geometry/geometry_envelope_test.cpp + unit/geometry/geometry_hit_test.cpp + unit/geometry/geometry_is_simple.cpp + unit/geometry/geometry_is_valid.cpp + unit/geometry/geometry_reprojection.cpp + unit/geometry/geometry_strategy_test.cpp + unit/geometry/geometry_test_helper.cpp + unit/geometry/grid_vertex_converter.cpp + unit/geometry/interior.cpp + unit/geometry/is_clockwise.cpp + unit/geometry/is_empty.cpp + unit/geometry/polygon_vertex_processor.cpp + unit/geometry/polylabel.cpp + unit/geometry/remove_empty.cpp + unit/imaging/image.cpp + unit/imaging/image_apply_opacity.cpp + unit/imaging/image_filter.cpp + unit/imaging/image_io_test.cpp + unit/imaging/image_is_solid.cpp + unit/imaging/image_painted_test.cpp + unit/imaging/image_premultiply.cpp + unit/imaging/image_set_pixel.cpp + unit/imaging/image_view.cpp + unit/imaging/tiff_io.cpp + unit/imaging/webp_io.cpp + unit/map/background.cpp + unit/numerics/enumeration.cpp + unit/numerics/safe_cast.cpp + unit/pixel/agg_blend_src_over_test.cpp + unit/pixel/palette.cpp + unit/projection/proj_transform.cpp + unit/renderer/buffer_size_scale_factor.cpp + unit/renderer/cairo_io.cpp + unit/renderer/feature_style_processor.cpp + unit/serialization/wkb_formats_test.cpp + unit/serialization/wkb_test.cpp + unit/serialization/xml_parser_trim.cpp + unit/sql/sql_parse.cpp + unit/svg/svg_parser_test.cpp + unit/svg/svg_path_parser_test.cpp + unit/svg/svg_renderer_test.cpp + unit/symbolizer/marker_placement_vertex_last.cpp + unit/symbolizer/markers_point_placement.cpp + unit/symbolizer/symbolizer_test.cpp + unit/text/script_runs.cpp + unit/text/shaping.cpp + unit/text/text_placements_list.cpp + unit/text/text_placements_simple.cpp + unit/util/char_array_buffer.cpp + unit/vertex_adapter/clipping_test.cpp + unit/vertex_adapter/extend_converter.cpp + unit/vertex_adapter/line_offset_test.cpp + unit/vertex_adapter/offset_converter.cpp + unit/vertex_adapter/simplify_converters_test.cpp + unit/vertex_adapter/transform_path_adapter.cpp + unit/vertex_adapter/vertex_adapter.cpp +) +target_link_libraries(mapnik-test-unit PUBLIC + Catch + mapnik::core + mapnik::agg + mapnik::mapnik + mapnik::json + mapnik::wkt + PostgreSQL::PostgreSQL +) + +add_executable(agg_rasterizer_integer_overflow_test standalone/agg_rasterizer_integer_overflow_test.cpp) +target_link_libraries(agg_rasterizer_integer_overflow_test PUBLIC + Catch + mapnik::core + mapnik::mapnik + mapnik::agg + mapnik::json +) + +add_executable(datasource_registration_test standalone/datasource_registration_test.cpp) +target_link_libraries(datasource_registration_test PUBLIC + Catch + mapnik::core + mapnik::mapnik + mapnik::agg +) + +add_executable(font_registration_test standalone/font_registration_test.cpp) +target_link_libraries(font_registration_test PUBLIC + Catch + mapnik::core + mapnik::mapnik + mapnik::agg + mapnik::json +) + +#not workable since boost::filesystem native returns a wstring and the function taskes a std::string +add_executable(map_xml_test standalone/map_xml_test.cpp) +target_link_libraries(map_xml_test PUBLIC + Catch + mapnik::core + mapnik::mapnik + mapnik::agg + mapnik::json +) + +add_executable(mapnik-test-visual + visual/parse_map_sizes.cpp + visual/report.cpp + visual/runner.cpp + visual/run.cpp +) +target_link_libraries( + mapnik-test-visual PRIVATE + Catch + Boost::program_options + Boost::filesystem + mapnik::core + mapnik::mapnik + mapnik::agg +) + +include(CTest) +include(${catch2_SOURCE_DIR}/contrib/Catch.cmake) +include(${catch2_SOURCE_DIR}/contrib/ParseAndAddCatchTests.cmake) + +# use only mapnik-test-unit since it has the same build path +mapnik_copy_plugins( + TARGET mapnik-test-unit + DESTINATION plugins/input + PLUGINS + input-csv input-gdal input-geobuf input-geojson input-ogr input-pgraster input-postgis input-raster input-shape input-sqlite input-topojson +) +mapnik_require_fonts(TARGET mapnik-test-unit DESTINATION fonts) + +mapnik_copy_dependencies( + TARGETS + mapnik-test-unit agg_rasterizer_integer_overflow_test datasource_registration_test font_registration_test map_xml_test mapnik-test-visual + PLUGINS + input-csv input-gdal input-geobuf input-geojson input-ogr input-pgraster input-postgis input-raster input-shape input-sqlite input-topojson +) + + +file(COPY data DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/test) +file(COPY data-visual DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/test) + +catch_discover_tests(mapnik-test-unit) +catch_discover_tests(agg_rasterizer_integer_overflow_test) +catch_discover_tests(datasource_registration_test) +catch_discover_tests(font_registration_test) +catch_discover_tests(map_xml_test) diff --git a/test/standalone/map_xml_test.cpp b/test/standalone/map_xml_test.cpp index b33a3f718..5f1dba900 100644 --- a/test/standalone/map_xml_test.cpp +++ b/test/standalone/map_xml_test.cpp @@ -76,17 +76,17 @@ void compare_map(bfs::path xml) { // is a normalisation step to ensure that the file is in // whatever the current version of mapnik uses as the // standard indentation, quote style, etc... - REQUIRE_NOTHROW(mapnik::load_map(m, xml.native(), false, abs_base.native())); + REQUIRE_NOTHROW(mapnik::load_map(m, xml.generic_string(), false, abs_base.generic_string())); bfs::path test_map1 = dir.path() / "mapnik-temp-map1.xml"; - REQUIRE_NOTHROW(mapnik::save_map(m, test_map1.native())); + REQUIRE_NOTHROW(mapnik::save_map(m, test_map1.generic_string())); // create a new map, load the one saved in the previous // step, and write it out again. mapnik::Map new_map(256, 256); REQUIRE(new_map.register_fonts("fonts", true)); - REQUIRE_NOTHROW(mapnik::load_map(new_map, test_map1.native(), false, abs_base.native())); + REQUIRE_NOTHROW(mapnik::load_map(new_map, test_map1.generic_string(), false, abs_base.generic_string())); bfs::path test_map2 = dir.path() / "mapnik-temp-map2.xml"; - REQUIRE_NOTHROW(mapnik::save_map(new_map, test_map2.native())); + REQUIRE_NOTHROW(mapnik::save_map(new_map, test_map2.generic_string())); // if all the information survived the load/save round-trip // then the two files ought to be identical. @@ -102,7 +102,7 @@ void add_xml_files(bfs::path dir, std::vector &xml_files) { for (auto const &entry : boost::make_iterator_range( bfs::directory_iterator(dir), bfs::directory_iterator())) { auto path = entry.path(); - if (path.extension().native() == ".xml") { + if (path.extension().generic_string() == ".xml") { xml_files.emplace_back(path); } } @@ -112,7 +112,7 @@ void load_map(mapnik::Map &m, bfs::path const &path) { try { - mapnik::load_map(m, path.native()); + mapnik::load_map(m, path.generic_string()); } catch (std::exception const &ex) { @@ -129,7 +129,7 @@ void load_map(mapnik::Map &m, bfs::path const &path) { } // anonymous namespace -const bool registered = mapnik::datasource_cache::instance().register_datasources("./plugins/input/"); +const bool registered = mapnik::datasource_cache::instance().register_datasources((bfs::path("plugins") / "input").generic_string()); TEST_CASE("map xml I/O") { // make sure plugins are loaded @@ -141,10 +141,10 @@ TEST_CASE("map xml I/O") { SECTION("good maps") { std::vector good_maps; - add_xml_files("test/data/good_maps", good_maps); + add_xml_files(bfs::path("test") / "data" / "good_maps", good_maps); for (auto const &path : good_maps) { - CAPTURE(path.native()); + CAPTURE(path.generic_string()); // check that it can load mapnik::Map m(256, 256); @@ -157,7 +157,7 @@ TEST_CASE("map xml I/O") { } // END SECTION SECTION("duplicate styles only throw in strict mode") { - std::string duplicate_stylename("test/data/broken_maps/duplicate_stylename.xml"); + std::string duplicate_stylename((bfs::path("test") / "data" / "broken_maps" / "duplicate_stylename.xml").generic_string()); CAPTURE(duplicate_stylename); mapnik::Map m(256, 256); REQUIRE(m.register_fonts("fonts", true)); @@ -169,15 +169,15 @@ TEST_CASE("map xml I/O") { SECTION("broken maps") { std::vector broken_maps; - add_xml_files("test/data/broken_maps", broken_maps); - broken_maps.emplace_back("test/data/broken_maps/does_not_exist.xml"); + add_xml_files(bfs::path("test") / "data" / "broken_maps", broken_maps); + broken_maps.emplace_back(bfs::path("test") / "data" / "broken_maps" / "does_not_exist.xml"); for (auto const &path : broken_maps) { - CAPTURE(path.native()); + CAPTURE(path.generic_string()); mapnik::Map m(256, 256); REQUIRE(m.register_fonts("fonts", true)); - REQUIRE_THROWS(mapnik::load_map(m, path.native(), true)); + REQUIRE_THROWS(mapnik::load_map(m, path.generic_string(), true)); } } // END SECTION diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt new file mode 100644 index 000000000..7aca5c8e4 --- /dev/null +++ b/utils/CMakeLists.txt @@ -0,0 +1,29 @@ +if(BUILD_UTILITY_GEOMETRY_TO_WKB) + message(STATUS "building utility geometry_to_wkb") + add_subdirectory(geometry_to_wkb) +endif() +if(BUILD_UTILITY_MAPNIK_INDEX) + message(STATUS "building utility mapnik-index") + add_subdirectory(mapnik-index) +endif() +if(BUILD_UTILITY_MAPNIK_RENDER) + message(STATUS "building utility mapnik-render") + add_subdirectory(mapnik-render) +endif() +if(BUILD_UTILITY_OGRINDEX) + message(STATUS "building utility ogrindex") + message(WARNING "can't build ogrindex currently due to some bugs") + #add_subdirectory(ogrindex) # missing include file shapeindex/quadtree.hpp +endif() +if(BUILD_UTILITY_PGSQL2SQLITE) + message(STATUS "building utility pgsql2sqlite") + add_subdirectory(pgsql2sqlite) +endif() +if(BUILD_UTILITY_SHAPEINDEX) + message(STATUS "building utility shapeindex") + add_subdirectory(shapeindex) +endif() +if(BUILD_UTILITY_SVG2PNG) + message(STATUS "building utility svg2png") + add_subdirectory(svg2png) +endif() diff --git a/utils/geometry_to_wkb/CMakeLists.txt b/utils/geometry_to_wkb/CMakeLists.txt new file mode 100644 index 000000000..8aca170fe --- /dev/null +++ b/utils/geometry_to_wkb/CMakeLists.txt @@ -0,0 +1,10 @@ +project(geometry_to_wkb) + +add_executable(geometry_to_wkb main.cpp) + +target_link_libraries(geometry_to_wkb PRIVATE + mapnik::core + mapnik::mapnik +) + +mapnik_install(TARGET geometry_to_wkb) diff --git a/utils/mapnik-index/CMakeLists.txt b/utils/mapnik-index/CMakeLists.txt new file mode 100644 index 000000000..3ec41c401 --- /dev/null +++ b/utils/mapnik-index/CMakeLists.txt @@ -0,0 +1,19 @@ +project(mapnik-index) + +find_package(Boost REQUIRED COMPONENTS program_options) + +add_executable(mapnik-index + mapnik-index.cpp + process_csv_file.cpp + process_geojson_file_x3.cpp + ../../plugins/input/csv/csv_utils.cpp # this project depends on this file +) +target_link_libraries(mapnik-index PRIVATE + mapnik::core + mapnik::mapnik + mapnik::json + mapnik::wkt + Boost::program_options +) + +mapnik_install(TARGET mapnik-index) diff --git a/utils/mapnik-render/CMakeLists.txt b/utils/mapnik-render/CMakeLists.txt new file mode 100644 index 000000000..b98ac8630 --- /dev/null +++ b/utils/mapnik-render/CMakeLists.txt @@ -0,0 +1,13 @@ +project(mapnik-render) + +find_package(Boost REQUIRED COMPONENTS program_options) + +add_executable(mapnik-render mapnik-render.cpp) + +target_link_libraries(mapnik-render PRIVATE + mapnik::core + mapnik::mapnik + Boost::program_options +) + +mapnik_install(TARGET mapnik-render) diff --git a/utils/ogrindex/CMakeLists.txt b/utils/ogrindex/CMakeLists.txt new file mode 100644 index 000000000..771b2c592 --- /dev/null +++ b/utils/ogrindex/CMakeLists.txt @@ -0,0 +1,7 @@ +project(ogrindex) + +add_executable(ogrindex ogrindex.cpp) + +target_link_libraries(ogrindex PRIVATE mapnik::core mapnik::mapnik) + +mapnik_install(TARGET ogrindex) diff --git a/utils/pgsql2sqlite/CMakeLists.txt b/utils/pgsql2sqlite/CMakeLists.txt new file mode 100644 index 000000000..19883f4a9 --- /dev/null +++ b/utils/pgsql2sqlite/CMakeLists.txt @@ -0,0 +1,20 @@ +project(pgsql2sqlite) +find_package(Boost REQUIRED COMPONENTS program_options) +find_package(SQLite3 REQUIRED) +find_package(PostgreSQL REQUIRED) + +add_executable(pgsql2sqlite + main.cpp + sqlite.cpp +) + +target_include_directories(pgsql2sqlite PRIVATE ../../plugins/input/postgis) +target_link_libraries(pgsql2sqlite PRIVATE + SQLite::SQLite3 + PostgreSQL::PostgreSQL + Boost::program_options + mapnik::core + mapnik::mapnik +) + +mapnik_install(TARGET pgsql2sqlite) diff --git a/utils/shapeindex/CMakeLists.txt b/utils/shapeindex/CMakeLists.txt new file mode 100644 index 000000000..4aae25bf1 --- /dev/null +++ b/utils/shapeindex/CMakeLists.txt @@ -0,0 +1,16 @@ +project(shapeindex) + +find_package(Boost REQUIRED COMPONENTS program_options) + +add_executable(shapeindex + shapeindex.cpp +) + +target_include_directories(shapeindex PRIVATE ../../plugins/input/shape) +target_link_libraries(shapeindex PRIVATE + Boost::program_options + mapnik::core + mapnik::mapnik +) + +mapnik_install(TARGET shapeindex) diff --git a/utils/svg2png/CMakeLists.txt b/utils/svg2png/CMakeLists.txt new file mode 100644 index 000000000..51a8baecd --- /dev/null +++ b/utils/svg2png/CMakeLists.txt @@ -0,0 +1,16 @@ +project(svg2png) + +find_package(Boost REQUIRED COMPONENTS program_options) + +add_executable(svg2png + svg2png.cpp +) + +target_link_libraries(svg2png PRIVATE + Boost::program_options + mapnik::core + mapnik::mapnik + mapnik::agg +) + +mapnik_install(TARGET svg2png)