# add ccache support find_program(CCACHE_PROGRAM ccache) if(CCACHE_PROGRAM) set(CCCACHE_EXPORTS "") set(CCACHE_OPTIONS "" CACHE STRING "options for ccache") foreach(option ${CCACHE_OPTIONS}) set(CCCACHE_EXPORTS "${CCCACHE_EXPORTS}\nexport ${option}") endforeach() set(C_LAUNCHER "${CCACHE_PROGRAM}") set(CXX_LAUNCHER "${CCACHE_PROGRAM}") configure_file("${OSMSCOUT_BASE_DIR_SOURCE}/cmake/launch-c.in" "${CMAKE_BINARY_DIR}/launch-c") configure_file("${OSMSCOUT_BASE_DIR_SOURCE}/cmake/launch-cxx.in" "${CMAKE_BINARY_DIR}/launch-cxx") execute_process(COMMAND chmod a+rx "${CMAKE_BINARY_DIR}/launch-c" "${CMAKE_BINARY_DIR}/launch-cxx" ) if(CMAKE_GENERATOR STREQUAL "Xcode") set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_BINARY_DIR}/launch-c" CACHE INTERNAL "") set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_BINARY_DIR}/launch-cxx" CACHE INTERNAL "") set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_BINARY_DIR}/launch-c" CACHE INTERNAL "") set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_BINARY_DIR}/launch-cxx" CACHE INTERNAL "") else() set(CMAKE_C_COMPILER_LAUNCHER "${CMAKE_BINARY_DIR}/launch-c" CACHE INTERNAL "") set(CMAKE_CXX_COMPILER_LAUNCHER "${CMAKE_BINARY_DIR}/launch-cxx") endif() endif() # detect available compiler features and libraries include(CheckCXXSourceCompiles) include(CheckPrototypeDefinition) include(CheckCCompilerFlag) include(CheckTypeSize) include(CheckFunctionExists) include(CheckCXXCompilerFlag) # detect 32 or 64 bits if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(OSMSCOUT_PLATFORM_X64 ON) else () set(OSMSCOUT_PLATFORM_X64 OFF) endif () # check for SSE etc. if(NOT MSVC) check_c_compiler_flag(-faltivec HAVE_ALTIVEC) check_c_compiler_flag(-mavx HAVE_AVX) check_c_compiler_flag(-mmmx HAVE_MMX) option(OSMSCOUT_ENABLE_SSE "Enable SSE support (not working on all platforms!)" OFF) if(OSMSCOUT_ENABLE_SSE) check_c_compiler_flag(-msse HAVE_SSE) check_c_compiler_flag(-msse2 HAVE_SSE2) check_c_compiler_flag(-msse3 HAVE_SSE3) check_c_compiler_flag(-msse4.1 HAVE_SSE4_1) check_c_compiler_flag(-msse4.2 HAVE_SSE4_2) check_c_compiler_flag(-mssse3 HAVE_SSSE3) endif() if(HAVE_SSE2) try_compile(SSE_OK "${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/cmake/TestSSE.c" COMPILE_DEFINITIONS "-msse2" ) if(NOT SSE_OK) message(STATUS "SSE test compilation fails") set(HAVE_SSE2 FALSE) endif() endif() if(HAVE_SSE2) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2") endif() else() set(HAVE_ALTIVEC OFF) set(HAVE_AVX ON) set(HAVE_MMX ON) set(HAVE_SSE ON) set(HAVE_SSE2 ON) set(HAVE_SSE3 OFF) set(HAVE_SSE4_1 OFF) set(HAVE_SSE4_2 OFF) set(HAVE_SSSE3 OFF) if (NOT OSMSCOUT_PLATFORM_X64) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:SSE2") endif() endif() if(CMAKE_COMPILER_IS_GNUCXX) check_cxx_compiler_flag(-fvisibility=hidden HAVE_VISIBILITY) if(HAVE_VISIBILITY) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") endif() else() set(HAVE_VISIBILITY OFF) endif() # check headers exists include(CheckIncludeFileCXX) check_include_file(dlfcn.h HAVE_DLFCN_H) check_include_file(fcntl.h HAVE_FCNTL_H) check_include_file(inttypes.h HAVE_INTTYPES_H) check_include_file(memory.h HAVE_MEMORY_H) check_include_file(stdint.h HAVE_STDINT_H) check_include_file(stdlib.h HAVE_STDLIB_H) check_include_file(strings.h HAVE_STRINGS_H) check_include_file(string.h HAVE_STRING_H) check_include_file(sys/stat.h HAVE_SYS_STAT_H) check_include_file(sys/time.h HAVE_SYS_TIME_H) check_include_file(sys/types.h HAVE_SYS_TYPES_H) check_include_file(unistd.h HAVE_UNISTD_H) check_include_file_cxx(codecvt HAVE_CODECVT) if(HAVE_STDINT_H AND HAVE_STDLIB_H AND HAVE_INTTYPES_H AND HAVE_STRING_H AND HAVE_MEMORY_H) set(STDC_HEADERS ON) else() set(STDC_HEADERS OFF) endif() # check data types exists set(CMAKE_EXTRA_INCLUDE_FILES inttypes.h) check_type_size(int16_t HAVE_INT16_T) check_type_size(int32_t HAVE_INT32_T) check_type_size(int64_t HAVE_INT64_T) check_type_size(int8_t HAVE_INT8_T) check_type_size("long long" HAVE_LONG_LONG) check_type_size(uint16_t HAVE_UINT16_T) check_type_size(uint32_t HAVE_UINT32_T) check_type_size(uint64_t HAVE_UINT64_T) check_type_size(uint8_t HAVE_UINT8_T) check_type_size("unsigned long long" HAVE_UNSIGNED_LONG_LONG) set(CMAKE_EXTRA_INCLUDE_FILES wchar.h) check_type_size(wchar_t SIZEOF_WCHAR_T) set(CMAKE_EXTRA_INCLUDE_FILES) # check functions exists check_function_exists(fseeko HAVE_FSEEKO) check_function_exists(mmap HAVE_MMAP) check_function_exists(posix_fadvise HAVE_POSIX_FADVISE) check_function_exists(posix_madvise HAVE_POSIX_MADVISE) check_function_exists(mallinfo2 HAVE_MALLINFO2) # prefer static libraries if shared are disabled if(NOT BUILD_SHARED_LIBS AND (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGXX OR CMAKE_COMPILER_IS_GNUCC)) set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) endif() # check libraries and tools macro(target_exists target var) if(TARGET ${target}) set(${var} 1) else() set(${var} 0) endif() endmacro() find_package(Catch2 3) if(NOT IOS) find_package(Marisa) endif() set(HAVE_LIB_MARISA ${MARISA_FOUND}) set(OSMSCOUT_HAVE_LIB_MARISA ${HAVE_LIB_MARISA}) set(OSMSCOUT_IMPORT_HAVE_LIB_MARISA ${MARISA_FOUND}) find_package(LibXml2) if (TARGET LibXml2::LibXml2 AND NOT BUILD_SHARED_LIBS) # seems that FindLibXml2.cmake don't handle static libraries properly # as a workaround we append PC_LIBXML_STATIC_LIBRARIES to LIBXML2_LIBRARIES set(LIBXML2_LIBRARIES ${LIBXML2_LIBRARIES} ${PC_LIBXML_STATIC_LIBRARIES}) if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGXX OR CMAKE_COMPILER_IS_GNUCC) # Libxml contains tiny http client that is using libc gethostbyname and getaddrinfo. # These functions are using dlopen in glibc, so it requires libdl dependency # and glibc libraries at runtime! Resulted binary is not fully static. list(APPEND LIBXML2_LIBRARIES "dl") endif() endif() target_exists(LibXml2::LibXml2 HAVE_LIB_XML) target_exists(LibXml2::LibXml2 OSMSCOUT_GPX_HAVE_LIB_XML) find_package(Protobuf) if (TARGET protobuf::libprotobuf AND NOT EXISTS ${PROTOBUF_PROTOC_EXECUTABLE}) message(STATUS "Protobuf library found, but protoc compiler is missing") set(HAVE_LIB_PROTOBUF FALSE) else() target_exists(protobuf::libprotobuf HAVE_LIB_PROTOBUF) endif() find_package(ZLIB) target_exists(ZLIB::ZLIB HAVE_LIB_ZLIB) find_package(LibLZMA) find_package(PNG) set(HAVE_LIB_PNG ${PNG_FOUND}) find_package(Cairo) if(CAIRO_FOUND) option(CAIRO_STATIC "Switch on if the found cairo library is static" OFF) if(CAIRO_STATIC) add_definitions(-DCAIRO_WIN32_STATIC_BUILD) endif() mark_as_advanced(CAIRO_STATIC) endif() set(HAVE_LIB_CAIRO ${CAIRO_FOUND}) find_package(LibAgg) set(HAVE_LIB_AGG ${LIBAGG_FOUND}) find_package(Freetype) set(HAVE_LIB_FREETYPE ${FREETYPE_FOUND}) find_package(Pango) set(HAVE_LIB_PANGO ${PANGO_FOUND}) set(OSMSCOUT_MAP_CAIRO_HAVE_LIB_PANGO ${PANGOCAIRO_FOUND}) set(OSMSCOUT_MAP_SVG_HAVE_LIB_PANGO ${PANGOFT2_FOUND}) find_package(harfbuzz) target_exists(harfbuzz::harfbuzz HAVE_LIB_HARFBUZZ) set(OpenGL_GL_PREFERENCE "GLVND") # Prever non-legacy OpenGL libraries find_package(OpenGL) set(HAVE_LIB_OPENGL ${OPENGL_FOUND}) find_package(GLEW) find_package(glm) if(NOT TARGET glm::glm) message(STATUS "glm NOT found") find_package(Git QUIET) if(Git_FOUND) option(OSMSCOUT_DOWNLOAD_GLM_IF_NOT_FOUND "Load GLM via Git automatically if the library was not found offline" OFF) if(OSMSCOUT_DOWNLOAD_GLM_IF_NOT_FOUND) set(GLM_ROOT_DIR ${CMAKE_BINARY_DIR}/glm) execute_process( COMMAND ${GIT_EXECUTABLE} clone https://github.com/g-truc/glm.git --recursive ${GLM_ROOT_DIR} WORKING_DIRECTORY ${CMAKE_BINARY_DIR} RESULT_VARIABLE git_result OUTPUT_VARIABLE git_output) find_package(GLM) endif() mark_as_advanced(OSMSCOUT_DOWNLOAD_GLM_IF_NOT_FOUND) endif() endif() find_package(glfw3) if (QT_VERSION_PREFERRED AND QT_VERSION_PREFERRED EQUAL 5) message(STATUS "Try loading Qt5 (explicitly preferred)...") set(QT5_TRIED 1) set(QT_DEFAULT_MAJOR_VERSION 5) find_package(Qt5 5.15 COMPONENTS Core Gui Widgets Qml Quick Svg Location Positioning Multimedia LinguistTools QUIET) if(Qt5_FOUND) message(STATUS "Choosing Qt5, since explicitly preferred") set(QT_FOUND 1) set(QT_VERSION_MAJOR 5) else () message(STATUS "Qt5 NOT found") endif() endif () if (QT_VERSION_PREFERRED AND QT_VERSION_PREFERRED EQUAL 6) message(STATUS "Try loading preferred Qt6 (explicitly preferred)...") set(QT6_TRIED 1) set(QT_DEFAULT_MAJOR_VERSION 6) find_package(Qt6 COMPONENTS Core Core5Compat Gui Widgets Qml Quick Svg Positioning Multimedia LinguistTools QUIET) if(Qt6_FOUND) message(STATUS "Choosing Qt6, since explicitly preferred") set(QT_FOUND 1) set(QT_VERSION_MAJOR 6) else () message(STATUS "Qt6 NOT found") endif() endif() if (NOT QT_FOUND AND NOT QT5_TRIED) message(STATUS "Try loading Qt5 (implicitly preferred version)...") set(QT_DEFAULT_MAJOR_VERSION 5) find_package(Qt5 5.15 COMPONENTS Core Gui Widgets Qml Quick Svg Location Positioning Multimedia LinguistTools QUIET) endif () if(NOT QT_FOUND) if (Qt5_FOUND) message(STATUS "Choosing Qt5, since implicitly preferred") set(QT_FOUND 1) set(QT_VERSION_MAJOR 5) else () message(STATUS "Qt5 NOT found") endif () endif () if (NOT QT_FOUND AND NOT QT6_TRIED) message(STATUS "Try loading Qt6 (implicitly preferred version)...") set(QT_DEFAULT_MAJOR_VERSION 6) find_package(Qt6 COMPONENTS Core Core5Compat Gui Widgets Qml Quick Svg Positioning Multimedia LinguistTools QUIET) endif() if (NOT QT_FOUND) if (Qt6_FOUND) message(STATUS "Choosing Qt6, since implicitly preferred") set(QT_FOUND 1) set(QT_VERSION_MAJOR 6) else () message(STATUS "Qt6 NOT found") endif() endif() if(QT_FOUND) message(STATUS "Qt version used: ${QT_VERSION_MAJOR}") option(QT_QML_DEBUG "Build with QML debugger support" OFF) mark_as_advanced(QT_QML_DEBUG) if (Qt5_FOUND) if (Qt5Core_FOUND AND Qt5Gui_FOUND AND Qt5Widgets_FOUND AND Qt5Svg_FOUND) message(STATUS "Qt5 map dependencies found") set(QT_MAP_DEPENDENCIES_FOUND 1) endif() if (Qt5Core_FOUND AND Qt5Gui_FOUND AND Qt5Widgets_FOUND AND Qt5Svg_FOUND AND Qt5Qml_FOUND AND Qt5Quick_FOUND AND Qt5Network_FOUND AND Qt5Location_FOUND AND Qt5Multimedia_FOUND) message(STATUS "Qt5 client dependencies found") set(QT_CLIENT_DEPENDENCIES_FOUND 1) endif() endif() if (Qt6_FOUND) if (Qt6Core_FOUND AND Qt6Gui_FOUND AND Qt6Widgets_FOUND AND Qt6Svg_FOUND) message(STATUS "Qt6 map dependencies found") set(QT_MAP_DEPENDENCIES_FOUND 1) endif() if (Qt6Core_FOUND AND Qt6Gui_FOUND AND Qt6Widgets_FOUND AND Qt6Svg_FOUND AND Qt6Qml_FOUND AND Qt6Quick_FOUND AND Qt6Network_FOUND AND Qt6Multimedia_FOUND) message(STATUS "Qt6 client dependencies found") set(QT_CLIENT_DEPENDENCIES_FOUND 1) endif() endif() if (Qt5_FOUND) set(HAVE_LIB_QT5_GUI ${Qt5Gui_FOUND}) set(HAVE_LIB_QT5_WIDGETS ${Qt5Widgets_FOUND}) else() set(HAVE_LIB_QT5_GUI ${Qt6Gui_FOUND}) set(HAVE_LIB_QT5_WIDGETS ${Qt6Widgets_FOUND}) endif() endif () find_package(OpenMP QUIET) set(OSMSCOUT_HAVE_OPENMP ${OPENMP_FOUND}) find_package(Doxygen QUIET) #find_package(SWIG QUIET) #find_package(JNI QUIET) #find_package(PythonInterp QUIET) #find_package(PythonLibs QUIET) set(Matlab_FIND_COMPONENTS MX_LIBRARY) find_package(MATLAB QUIET) find_package(Gperftools QUIET) set(HAVE_LIB_GPERFTOOLS ${GPERFTOOLS_FOUND}) if(GPERFTOOLS_FOUND) set(GPERFTOOLS_USAGE ON) else() set(GPERFTOOLS_USAGE OFF) endif() find_package(Direct2D) find_package(Threads) if(THREADS_HAVE_PTHREAD_ARG) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${THREADS_PTHREAD_ARG}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${THREADS_PTHREAD_ARG}") endif() try_compile(PTHREAD_NAME_OK "${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/cmake/TestPThreadName.cpp") if(PTHREAD_NAME_OK) set(OSMSCOUT_PTHREAD_NAME TRUE) endif() if(MSVC) set(HAVE_STD_EXECUTION 1) else() find_package(TBB QUIET) if (TBB_FOUND) try_compile(TBB_HAS_SCHEDULER_INIT "${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/cmake/TestTBBSchedulerInit.cpp" LINK_LIBRARIES TBB::tbb) endif() set(HAVE_STD_EXECUTION ${TBB_FOUND}) endif() find_program(HUGO_PATH hugo) # prepare cmake variables for configuration files set(OSMSCOUT_HAVE_INT16_T ${HAVE_INT16_T}) set(OSMSCOUT_HAVE_INT32_T ${HAVE_INT32_T}) set(OSMSCOUT_HAVE_INT64_T ${HAVE_INT64_T}) set(OSMSCOUT_HAVE_INT8_T ${HAVE_INT8_T}) set(OSMSCOUT_HAVE_LONG_LONG ${HAVE_LONG_LONG}) set(OSMSCOUT_HAVE_SSE2 ${HAVE_SSE2}) set(OSMSCOUT_HAVE_STDINT_H ${HAVE_STDINT_H}) set(OSMSCOUT_HAVE_STD_WSTRING ${HAVE_STD__WSTRING}) set(OSMSCOUT_HAVE_UINT16_T ${HAVE_UINT16_T}) set(OSMSCOUT_HAVE_UINT32_T ${HAVE_UINT32_T}) set(OSMSCOUT_HAVE_UINT64_T ${HAVE_UINT64_T}) set(OSMSCOUT_HAVE_UINT8_T ${HAVE_UINT8_T}) set(OSMSCOUT_HAVE_ULONG_LONG ${HAVE_UNSIGNED_LONG_LONG})