cmake_minimum_required(VERSION 3.9) project(keyvi) #### Build Type if (CMAKE_BUILD_TYPE) string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UPPER) endif() #### Linting find_program(CLANGTIDY clang-tidy) if(CLANGTIDY) message ("-- Found clang-tidy") set(CMAKE_CXX_CLANG_TIDY clang-tidy; --extra-arg-before=-std=c++17) else() message ("-- clang-tidy not found") endif() #### Cmake modules set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules/") #### Compiler Flags #### # configure C++17 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version") # keyvi specific compile options, definitions and flags set (_KEVYI_COMPILE_OPTIONS "-Wall") set (_KEYVI_COMPILE_DEFINITIONS "RAPIDJSON_HAS_STDSTRING") if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64") set (_KEYVI_CXX_FLAGS "-msse4.2") message( STATUS "Architecture: ${CMAKE_SYSTEM_PROCESSOR} detected: added -msse4.2 compile flag") endif() set (_OS_LIBRARIES "") # OSX specifics if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set (_KEYVI_COMPILE_DEFINITIONS "${_KEYVI_COMPILE_DEFINITIONS} OS_MACOSX") endif() # build type specific settings set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb3") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -DNDEBUG") set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_DEBUG} -O0 --coverage") # link libraries set(_KEYVI_LINK_LIBRARIES_STATIC "") set(_KEYVI_LINK_LIBRARIES_DYNAMIC "") if (CMAKE_BUILD_TYPE_UPPER MATCHES COVERAGE) set(_KEYVI_LINK_LIBRARIES_DYNAMIC "${_KEYVI_LINK_LIBRARIES_DYNAMIC} gcov") set(_KEYVI_LINK_FLAGS "--coverage") endif (CMAKE_BUILD_TYPE_UPPER MATCHES COVERAGE) #### Dependencies #### # BOOST set (_KEYVI_BOOST_LIBRARIES "program_options" "iostreams" "filesystem" "regex" "thread") set (_KEYVI_BOOST_LIBRARIES_TEST "unit_test_framework") set(Boost_USE_STATIC_LIBS OFF) set(Boost_USE_MULTITHREADED ON) set(Boost_USE_STATIC_RUNTIME OFF) if(POLICY CMP0167) # Use upstream's FindBoost.cmake to find Boost libraries. cmake_policy(SET CMP0167 NEW) endif() find_package(Boost 1.80 REQUIRED COMPONENTS ${_KEYVI_BOOST_LIBRARIES} ${_KEYVI_BOOST_LIBRARIES_TEST}) if (Boost_FOUND) list(APPEND KEYVI_INCLUDES "${Boost_INCLUDE_DIRS}") else () message(FATAL_ERROR "Can not find Boost") endif () # starting with boost 1.86, boost process is not header-only anymore, so we have to add it as dependency # see https://github.com/boostorg/process/issues/390 if(Boost_VERSION VERSION_GREATER_EQUAL "1.86.0") list(APPEND _KEYVI_BOOST_LIBRARIES "process") find_package(Boost REQUIRED COMPONENTS ${_KEYVI_BOOST_LIBRARIES} ${_KEYVI_BOOST_LIBRARIES_TEST}) endif() if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(_KEYVI_LINK_LIBRARIES_STATIC "${_KEYVI_LINK_LIBRARIES_STATIC} boost_program_options boost_iostreams boost_filesystem boost_regex boost_thread") else () set(_KEYVI_LINK_LIBRARIES_DYNAMIC "${_KEYVI_LINK_LIBRARIES_DYNAMIC} boost_program_options boost_iostreams boost_filesystem boost_regex boost_thread") endif () if(Boost_VERSION VERSION_GREATER_EQUAL "1.86.0") if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(_KEYVI_LINK_LIBRARIES_STATIC "${_KEYVI_LINK_LIBRARIES_STATIC} boost_process") else () set(_KEYVI_LINK_LIBRARIES_DYNAMIC "${_KEYVI_LINK_LIBRARIES_DYNAMIC} boost_process") endif () endif () if (WIN32) # required for libboost_zlib # disable autolinking in boost add_definitions( -DBOOST_ALL_NO_LIB ) add_definitions( -DBOOST_ALL_DYN_LINK ) link_directories (${Boost_LIBRARY_DIRS}) # required for endian specific functions list(APPEND _OS_LIBRARIES "ws2_32") endif (WIN32) # Zlib find_package(ZLIB REQUIRED) if (ZLIB_FOUND) IF(ZLIB_VERSION_STRING VERSION_LESS "1.2.8") message(FATAL_ERROR "-- ZLIB version too old, please install at least v1.2.8") ENDIF(ZLIB_VERSION_STRING VERSION_LESS "1.2.8") list(APPEND KEYVI_INCLUDES "${ZLIB_INCLUDE_DIRS}") else () message(FATAL_ERROR "Can not find ZLib") endif (ZLIB_FOUND) if (ZLIB_ROOT OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(_KEYVI_LINK_LIBRARIES_STATIC "${_KEYVI_LINK_LIBRARIES_STATIC} z") else () set(_KEYVI_LINK_LIBRARIES_DYNAMIC "${_KEYVI_LINK_LIBRARIES_DYNAMIC} z") endif () # snappy find_package(Snappy REQUIRED) if(${Snappy_FOUND}) list(APPEND KEYVI_INCLUDES "${Snappy_INCLUDE_DIR}") else(${Snappy_FOUND}) message(FATAL_ERROR "Can not find Snappy") endif(${Snappy_FOUND}) if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(_KEYVI_LINK_LIBRARIES_STATIC "${_KEYVI_LINK_LIBRARIES_STATIC} snappy") else () set(_KEYVI_LINK_LIBRARIES_DYNAMIC "${_KEYVI_LINK_LIBRARIES_DYNAMIC} snappy") endif () # Zstd find_package(ZSTD REQUIRED) if (ZSTD_FOUND) list(APPEND KEYVI_INCLUDES "${ZSTD_INCLUDE_DIRS}") else () message(FATAL_ERROR "Can not find zstd") endif (ZSTD_FOUND) if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(_KEYVI_LINK_LIBRARIES_STATIC "${_KEYVI_LINK_LIBRARIES_STATIC} zstd") else () set(_KEYVI_LINK_LIBRARIES_DYNAMIC "${_KEYVI_LINK_LIBRARIES_DYNAMIC} zstd") endif () # rapidjson list(APPEND KEYVI_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/keyvi/3rdparty/rapidjson/include") # utfcpp add_subdirectory(keyvi/3rdparty/utfcpp EXCLUDE_FROM_ALL) list(APPEND KEYVI_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/keyvi/3rdparty/utfcpp/source") list(APPEND KEYVI_INCLUDES "${CMAKE_CURRENT_BINARY_DIR}/keyvi/3rdparty/utfcpp/") # misc list(APPEND KEYVI_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/keyvi/3rdparty/misc") list(APPEND KEYVI_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/keyvi/3rdparty/msgpack-c/include") list(APPEND KEYVI_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/keyvi/3rdparty/concurrentqueue") # keyvi list(APPEND KEYVI_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/keyvi/include") # target_compile_options and target_compile_definitions expect a list string(REPLACE " " ";" _KEYVI_CXX_FLAGS_LIST "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UPPER}} ${_KEVYI_COMPILE_OPTIONS} ${_KEYVI_CXX_FLAGS}") string(REPLACE " " ";" _KEYVI_COMPILE_DEFINITIONS_LIST "${_KEYVI_COMPILE_DEFINITIONS}") #### Targets #### # keyvicompiler add_executable(keyvicompiler keyvi/bin/keyvicompiler/keyvicompiler.cpp) target_link_libraries(keyvicompiler ${Boost_LIBRARIES} ${ZLIB_LIBRARIES} ${Snappy_LIBRARY} ${ZSTD_LIBRARIES} ${_OS_LIBRARIES}) target_compile_options(keyvicompiler PRIVATE ${_KEYVI_CXX_FLAGS_LIST}) target_compile_definitions(keyvicompiler PRIVATE ${_KEYVI_COMPILE_DEFINITIONS_LIST}) target_include_directories(keyvicompiler PRIVATE "$") install (TARGETS keyvicompiler DESTINATION bin COMPONENT applications OPTIONAL) # keyviinspector add_executable(keyviinspector keyvi/bin/keyviinspector/keyviinspector.cpp) target_link_libraries(keyviinspector ${Boost_LIBRARIES} ${ZLIB_LIBRARIES} ${Snappy_LIBRARY} ${ZSTD_LIBRARIES} ${_OS_LIBRARIES}) target_compile_options(keyviinspector PRIVATE ${_KEYVI_CXX_FLAGS_LIST}) target_compile_definitions(keyviinspector PRIVATE ${_KEYVI_COMPILE_DEFINITIONS_LIST}) target_include_directories(keyviinspector PRIVATE "$") install (TARGETS keyviinspector DESTINATION bin COMPONENT applications OPTIONAL) # keyvimerger add_executable(keyvimerger keyvi/bin/keyvimerger/keyvimerger.cpp) target_link_libraries(keyvimerger ${Boost_LIBRARIES} ${ZLIB_LIBRARIES} ${Snappy_LIBRARY} ${ZSTD_LIBRARIES} ${_OS_LIBRARIES}) target_compile_options(keyvimerger PRIVATE ${_KEYVI_CXX_FLAGS_LIST}) target_compile_definitions(keyvimerger PRIVATE ${_KEYVI_COMPILE_DEFINITIONS_LIST}) target_include_directories(keyvimerger PRIVATE "$") install (TARGETS keyvimerger DESTINATION bin COMPONENT applications) # keyvi_c add_library(keyvi_c SHARED keyvi/bin/keyvi_c/c_api.cpp) target_link_libraries(keyvi_c ${Boost_LIBRARIES} ${ZLIB_LIBRARIES} ${Snappy_LIBRARY} ${ZSTD_LIBRARIES} ${_OS_LIBRARIES}) target_compile_options(keyvi_c PRIVATE ${_KEYVI_CXX_FLAGS_LIST}) target_compile_definitions(keyvi_c PRIVATE ${_KEYVI_COMPILE_DEFINITIONS_LIST}) target_include_directories(keyvi_c PRIVATE "$") # unit tests FILE(GLOB_RECURSE UNIT_TEST_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} keyvi/tests/keyvi/*.cpp) add_executable(unit_test_all ${UNIT_TEST_SOURCES}) target_link_libraries(unit_test_all ${Boost_LIBRARIES} ${ZLIB_LIBRARIES} ${Snappy_LIBRARY} ${ZSTD_LIBRARIES} ${_OS_LIBRARIES}) target_compile_options(unit_test_all PRIVATE ${_KEYVI_CXX_FLAGS_LIST}) target_compile_definitions(unit_test_all PRIVATE ${_KEYVI_COMPILE_DEFINITIONS_LIST}) target_include_directories(unit_test_all PRIVATE "$") add_dependencies(unit_test_all keyvimerger) if (WIN32) message(STATUS "zlib: ${ZLIB_LIBRARY_RELEASE}") # copies the dlls required to run to the build folder foreach(LIB ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE} ${Boost_FILESYSTEM_LIBRARY_RELEASE} ${ZLIB_LIBRARY_RELEASE}) get_filename_component(UTF_BASE_NAME ${LIB} NAME_WE) get_filename_component(UTF_PATH ${LIB} PATH) if(EXISTS "${UTF_PATH}/${UTF_BASE_NAME}.dll") add_custom_command(TARGET unit_test_all POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${UTF_PATH}/${UTF_BASE_NAME}.dll" ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} ) # zlib might be stored in a different folder elseif(EXISTS "${UTF_PATH}/../bin/${UTF_BASE_NAME}.dll") add_custom_command(TARGET unit_test_all POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${UTF_PATH}/../bin/${UTF_BASE_NAME}.dll" ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} ) endif() endforeach() endif (WIN32) # bindings add_custom_target(bindings COMMAND ${CMAKE_COMMAND} ${CMAKE_BINARY_DIR} ) #### Configuration file for integrations and bindings #### # expose all flags used # includes string(REPLACE ";" " " _KEYVI_INCLUDES "${KEYVI_INCLUDES}") # compile flags set(_KEYVI_CXX_FLAGS_ALL "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UPPER}} ${_KEYVI_CXX_FLAGS} ${_KEVYI_COMPILE_OPTIONS} -std=c++17") configure_file(keyvi/flags.cmake keyvi/flags) add_library(keyvi INTERFACE) target_include_directories(keyvi INTERFACE "$") target_compile_definitions(keyvi INTERFACE ${_KEYVI_COMPILE_DEFINITIONS_LIST}) target_link_libraries(keyvi INTERFACE ${Boost_LIBRARIES} ${ZLIB_LIBRARIES} ${Snappy_LIBRARY} ${ZSTD_LIBRARIES} ${_OS_LIBRARIES}) ### docs # don't run it as part of a non-toplevel build, e.g. python if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/sphinx-docs) find_package(Doxygen) find_package(Sphinx COMPONENTS breathe) if(Doxygen_FOUND AND Sphinx_FOUND) message ("-- Found doxygen/sphinx, creating sphinx_doc target") file(GLOB_RECURSE KEYVI_PUBLIC_HEADERS keyvi/include/keyvi/*.h) set(DOXYGEN_GENERATE_LATEX NO) set(DOXYGEN_GENERATE_HTML NO) set(DOXYGEN_GENERATE_XML YES) set(DOXYGEN_INLINE_INHERITED_MEMB YES) # for scanning the python extension set(SPHINX_EXTENSIONS sphinx.ext.autodoc) set(SPHINX_CONF_IMPORT sphinx-docs/conf_extra.py) doxygen_add_docs(doxygen_keyvi ${KEYVI_PUBLIC_HEADERS}) sphinx_add_docs( sphinx_doc BREATHE_PROJECTS doxygen_keyvi BUILDER html SOURCE_DIRECTORY sphinx-docs) else() message ("-- Skip doc target, doxygen/sphinx not found") endif() endif()