Skip to content
Permalink
Browse files

move build logic into cmake (#112)

Remove duplication of build logic and moves most of the logic into cmake. Cmake writes a
configuration file which `setup.py` takes as input to know how to compile/link the library. Apart from
that the cmake file has been overhauled to follow best practices.
  • Loading branch information...
hendrikmuhs committed Feb 18, 2019
1 parent acee11c commit 5c841677bff5c7b4951e0fa1958d3eb8a31d399d
Showing with 408 additions and 161 deletions.
  1. +1 −1 .travis.yml
  2. +123 −25 CMakeLists.txt
  3. +16 −0 cmake_modules/FindSnappy.cmake
  4. +103 −0 cmake_modules/LibFindMacros.cmake
  5. +11 −1 keyvi/flags.cmake
  6. +153 −134 python/setup.py
  7. +1 −0 rust/keyvi_core/cmake_modules
@@ -88,7 +88,7 @@ install:
- if [ "$DOCKER_IMAGE" != "" ]; then docker pull $DOCKER_IMAGE ; fi

script:
- if [ "$BUILD_TYPE" == "linux" ]; then docker run --rm -v `pwd`:/io $DOCKER_IMAGE /io/travis/build_linux.sh ; fi
- if [ "$BUILD_TYPE" == "linux" ]; then docker run --rm -v `pwd`:/io -e CONF $DOCKER_IMAGE /io/travis/build_linux.sh ; fi

- if [ "$BUILD_TYPE" == "python" ]; then
docker run --rm -v `pwd`:/io -e CONF -e PYTHON_VERSION $DOCKER_IMAGE /io/travis/build_python.sh ; fi
@@ -1,39 +1,85 @@
cmake_minimum_required(VERSION 3.0.2)
project(keyvi)

#### Build Type
if (CMAKE_BUILD_TYPE)
string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UPPER)
endif()

#### Cmake modules
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules/")

#### Compiler Flags ####

# configure C++11
if(NOT CMAKE_VERSION VERSION_LESS 3.1)
set(CMAKE_CXX_STANDARD 11)
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif()

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.2 -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DRAPIDJSON_HAS_STDSTRING")
# keyvi specific compile options, definitions and flags
set (_KEVYI_COMPILE_OPTIONS "-Wall")
set (_KEYVI_COMPILE_DEFINITIONS "RAPIDJSON_HAS_STDSTRING")

# todo: add check for SSE4.2, make it optional
set (_KEYVI_CXX_FLAGS "-msse4.2")

# OSX specifics
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set (_KEYVI_COMPILE_DEFINITIONS "${_KEYVI_COMPILE_DEFINITIONS} OS_MACOSX")
set (_KEYVI_CXX_FLAGS "${_KEYVI_CXX_FLAGS} -mmacosx-version-min=10.9")
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_PYTHON "${CMAKE_CXX_FLAGS_PYTHON} ${CMAKE_CXX_FLAGS_RELEASE}")
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 ####

# TPIE settings (todo: make optional)
set(COMPILE_TEST OFF CACHE BOOL "")
set(TPIE_PARALLEL_SORT 1 CACHE BOOL "")
add_subdirectory(keyvi/3rdparty/tpie EXCLUDE_FROM_ALL)
include_directories(keyvi/3rdparty/tpie)
include_directories(${CMAKE_BINARY_DIR}/keyvi/3rdparty/tpie)
set(_KEYVI_LINK_LIBRARIES_STATIC "${_KEYVI_LINK_LIBRARIES_STATIC} tpie")

# tiny process library
add_subdirectory(keyvi/3rdparty/tiny-process-library)
include_directories(keyvi/3rdparty/tiny-process-library/)
include_directories(${CMAKE_BINARY_DIR}/keyvi/3rdparty/tiny-process-library/)
set(_KEYVI_LINK_LIBRARIES_STATIC "${_KEYVI_LINK_LIBRARIES_STATIC} tiny-process-library")

# BOOST
set (_KEYVI_BOOST_LIBRARIES "program_options" "iostreams" "filesystem" "system" "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)
find_package(Boost REQUIRED COMPONENTS "program_options" "iostreams" "filesystem" "system" "regex" "thread" "unit_test_framework")
find_package(Boost REQUIRED COMPONENTS ${_KEYVI_BOOST_LIBRARIES} ${_KEYVI_BOOST_LIBRARIES_TEST})
if (Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
else ()
message(FATAL_ERROR "Can not find Boost")
endif ()
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(_KEYVI_LINK_LIBRARIES_STATIC "${_KEYVI_LINK_LIBRARIES_STATIC} boost_program_options boost_iostreams boost_filesystem boost_system boost_regex boost_thread-mt")
else ()
set(_KEYVI_LINK_LIBRARIES_DYNAMIC "${_KEYVI_LINK_LIBRARIES_DYNAMIC} boost_program_options boost_iostreams boost_filesystem boost_system boost_regex boost_thread")
endif ()


# Zlib
find_package(ZLIB REQUIRED)
if (ZLIB_FOUND)
IF(ZLIB_VERSION_STRING VERSION_LESS "1.2.8")
@@ -43,47 +89,99 @@ if (ZLIB_FOUND)
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
# currently reuses on tpies FindSnappy module
find_package(Snappy REQUIRED)
if(${Snappy_FOUND})
include_directories(${Snappy_INCLUDE_DIR})
else(${Snappy_FOUND})
message(FATAL_ERROR "Can not find Snappy")
endif(${Snappy_FOUND})
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
add_definitions(-DOS_MACOSX)
set(_KEYVI_LINK_LIBRARIES_STATIC "${_KEYVI_LINK_LIBRARIES_STATIC} snappy")
else ()
set(_KEYVI_LINK_LIBRARIES_DYNAMIC "${_KEYVI_LINK_LIBRARIES_DYNAMIC} snappy")
endif ()

# rapidjson
include_directories(keyvi/3rdparty/rapidjson/include)

include_directories(keyvi/include/keyvi)
include_directories(keyvi/3rdparty/tpie)
# misc
include_directories(keyvi/3rdparty/utf8)
include_directories(keyvi/3rdparty/misc)
include_directories(keyvi/3rdparty/rapidjson/include)
include_directories(keyvi/3rdparty/msgpack-c/include)
include_directories(keyvi/3rdparty/xchange/src)
include_directories(keyvi/3rdparty/tiny-process-library/)
include_directories(${CMAKE_BINARY_DIR}/keyvi/3rdparty/tpie)
include_directories(${CMAKE_BINARY_DIR}/keyvi/3rdparty/tiny-process-library/)

FILE(GLOB_RECURSE UNIT_TEST_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} keyvi/tests/keyvi/*.cpp)
add_executable(unit_test_all ${UNIT_TEST_SOURCES})
add_executable(keyvicompiler keyvi/bin/keyvicompiler/keyvicompiler.cpp)
add_executable(keyviinspector keyvi/bin/keyviinspector/keyviinspector.cpp)
add_executable(keyvimerger keyvi/bin/keyvimerger/keyvimerger.cpp)
add_library(keyvi_c SHARED keyvi/bin/keyvi_c/c_api.cpp)
# keyvi
include_directories(keyvi/include/keyvi)

target_link_libraries(unit_test_all tiny-process-library tpie ${Boost_LIBRARIES} ${ZLIB_LIBRARIES})
# 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 tpie ${Boost_LIBRARIES} ${ZLIB_LIBRARIES})
target_compile_options(keyvicompiler PRIVATE ${_KEYVI_CXX_FLAGS_LIST})
target_compile_definitions(keyvicompiler PRIVATE ${_KEYVI_COMPILE_DEFINITIONS_LIST})

install (TARGETS keyvicompiler DESTINATION bin COMPONENT applications OPTIONAL)

# keyviinspector
add_executable(keyviinspector keyvi/bin/keyviinspector/keyviinspector.cpp)
target_link_libraries(keyviinspector tpie ${Boost_LIBRARIES} ${ZLIB_LIBRARIES})
target_compile_options(keyviinspector PRIVATE ${_KEYVI_CXX_FLAGS_LIST})
target_compile_definitions(keyviinspector PRIVATE ${_KEYVI_COMPILE_DEFINITIONS_LIST})

install (TARGETS keyviinspector DESTINATION bin COMPONENT applications OPTIONAL)

# keyvimerger
add_executable(keyvimerger keyvi/bin/keyvimerger/keyvimerger.cpp)
target_link_libraries(keyvimerger tpie ${Boost_LIBRARIES} ${ZLIB_LIBRARIES})
target_compile_options(keyvimerger PRIVATE ${_KEYVI_CXX_FLAGS_LIST})
target_compile_definitions(keyvimerger PRIVATE ${_KEYVI_COMPILE_DEFINITIONS_LIST})

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 tpie ${Boost_LIBRARIES} ${ZLIB_LIBRARIES})
target_compile_options(keyvi_c PRIVATE ${_KEYVI_CXX_FLAGS_LIST})
target_compile_definitions(keyvi_c PRIVATE ${_KEYVI_COMPILE_DEFINITIONS_LIST})

# 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 tiny-process-library tpie ${Boost_LIBRARIES} ${ZLIB_LIBRARIES})
target_compile_options(unit_test_all PRIVATE ${_KEYVI_CXX_FLAGS_LIST})
target_compile_definitions(unit_test_all PRIVATE ${_KEYVI_COMPILE_DEFINITIONS_LIST})
add_dependencies(unit_test_all keyvimerger)

install (TARGETS keyvicompiler DESTINATION bin COMPONENT applications OPTIONAL)
install (TARGETS keyviinspector DESTINATION bin COMPONENT applications OPTIONAL)
install (TARGETS keyvimerger DESTINATION bin COMPONENT applications)

# bindings
add_custom_target(bindings
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:tpie> ${CMAKE_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:tiny-process-library> ${CMAKE_BINARY_DIR}
DEPENDS tpie tiny-process-library
)

configure_file(keyvi/flags.cmake keyvi/flags)
#### Configuration file for integrations and bindings ####

# expose all flags used

# includes
get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
get_directory_property(_KEYVI_INCLUDES INCLUDE_DIRECTORIES)
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++11")

configure_file(keyvi/flags.cmake keyvi/flags)
@@ -0,0 +1,16 @@
# Snappy, a fast compressor/decompressor

include(LibFindMacros)

find_path(Snappy_INCLUDE_DIR
NAMES snappy.h
)

find_library(Snappy_LIBRARY
NAMES snappy
)

set(Snappy_PROCESS_INCLUDES Snappy_INCLUDE_DIR)
set(Snappy_PROCESS_LIBS Snappy_LIBRARY)

libfind_process(Snappy)
@@ -0,0 +1,103 @@
# Version 1.0 (2013-04-12)
# Public Domain, originally written by Lasse Kärkkäinen <tronic@zi.fi>
# Published at http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries

# Works the same as find_package, but forwards the "REQUIRED" and "QUIET" arguments
# used for the current package. For this to work, the first parameter must be the
# prefix of the current package, then the prefix of the new package etc, which are
# passed to find_package.
macro (libfind_package PREFIX)
set (LIBFIND_PACKAGE_ARGS ${ARGN})
if (${PREFIX}_FIND_QUIETLY)
set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} QUIET)
endif (${PREFIX}_FIND_QUIETLY)
if (${PREFIX}_FIND_REQUIRED)
set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} REQUIRED)
endif (${PREFIX}_FIND_REQUIRED)
find_package(${LIBFIND_PACKAGE_ARGS})
endmacro (libfind_package)

# CMake developers made the UsePkgConfig system deprecated in the same release (2.6)
# where they added pkg_check_modules. Consequently I need to support both in my scripts
# to avoid those deprecated warnings. Here's a helper that does just that.
# Works identically to pkg_check_modules, except that no checks are needed prior to use.
macro (libfind_pkg_check_modules PREFIX PKGNAME)
if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
include(UsePkgConfig)
pkgconfig(${PKGNAME} ${PREFIX}_INCLUDE_DIRS ${PREFIX}_LIBRARY_DIRS ${PREFIX}_LDFLAGS ${PREFIX}_CFLAGS)
else (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(${PREFIX} ${PKGNAME})
endif (PKG_CONFIG_FOUND)
endif (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
endmacro (libfind_pkg_check_modules)

# Do the final processing once the paths have been detected.
# If include dirs are needed, ${PREFIX}_PROCESS_INCLUDES should be set to contain
# all the variables, each of which contain one include directory.
# Ditto for ${PREFIX}_PROCESS_LIBS and library files.
# Will set ${PREFIX}_FOUND, ${PREFIX}_INCLUDE_DIRS and ${PREFIX}_LIBRARIES.
# Also handles errors in case library detection was required, etc.
macro (libfind_process PREFIX)
# Skip processing if already processed during this run
if (NOT ${PREFIX}_FOUND)
# Start with the assumption that the library was found
set (${PREFIX}_FOUND TRUE)

# Process all includes and set _FOUND to false if any are missing
foreach (i ${${PREFIX}_PROCESS_INCLUDES})
if (${i})
set (${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIRS} ${${i}})
mark_as_advanced(${i})
else (${i})
set (${PREFIX}_FOUND FALSE)
endif (${i})
endforeach (i)

# Process all libraries and set _FOUND to false if any are missing
foreach (i ${${PREFIX}_PROCESS_LIBS})
if (${i})
set (${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARIES} ${${i}})
mark_as_advanced(${i})
else (${i})
set (${PREFIX}_FOUND FALSE)
endif (${i})
endforeach (i)

# Print message and/or exit on fatal error
if (${PREFIX}_FOUND)
if (NOT ${PREFIX}_FIND_QUIETLY)
message (STATUS "Found ${PREFIX} ${${PREFIX}_VERSION}")
endif (NOT ${PREFIX}_FIND_QUIETLY)
else (${PREFIX}_FOUND)
if (${PREFIX}_FIND_REQUIRED)
foreach (i ${${PREFIX}_PROCESS_INCLUDES} ${${PREFIX}_PROCESS_LIBS})
message("${i}=${${i}}")
endforeach (i)
message (FATAL_ERROR "Required library ${PREFIX} NOT FOUND.\nInstall the library (dev version) and try again. If the library is already installed, use ccmake to set the missing variables manually.")
endif (${PREFIX}_FIND_REQUIRED)
endif (${PREFIX}_FOUND)
endif (NOT ${PREFIX}_FOUND)
endmacro (libfind_process)

macro(libfind_library PREFIX basename)
set(TMP "")
if(MSVC80)
set(TMP -vc80)
endif(MSVC80)
if(MSVC90)
set(TMP -vc90)
endif(MSVC90)
set(${PREFIX}_LIBNAMES ${basename}${TMP})
if(${ARGC} GREATER 2)
set(${PREFIX}_LIBNAMES ${basename}${TMP}-${ARGV2})
string(REGEX REPLACE "\\." "_" TMP ${${PREFIX}_LIBNAMES})
set(${PREFIX}_LIBNAMES ${${PREFIX}_LIBNAMES} ${TMP})
endif(${ARGC} GREATER 2)
find_library(${PREFIX}_LIBRARY
NAMES ${${PREFIX}_LIBNAMES}
PATHS ${${PREFIX}_PKGCONF_LIBRARY_DIRS}
)
endmacro(libfind_library)

@@ -1 +1,11 @@
KEYVI_CXX_FLAGS=@CMAKE_CXX_FLAGS@
BUILD_TYPE=@CMAKE_BUILD_TYPE@
KEYVI_CXX_FLAGS_ALL=@_KEYVI_CXX_FLAGS_ALL@
BOOST_LIBRARIES=@_KEYVI_BOOST_LIBRARIES@
ZLIB_LIBRARIES=@ZLIB_LIBRARIES@
KEYVI_COMPILE_DEFINITIONS=@_KEYVI_COMPILE_DEFINITIONS@
KEYVI_COMPILE_OPTIONS=@_KEVYI_COMPILE_OPTIONS@
KEYVI_LINK_LIBRARIES_ALL=@_KEYVI_LINK_LIBRARIES_DYNAMIC@ @_KEYVI_LINK_LIBRARIES_STATIC@
KEYVI_LINK_LIBRARIES_DYNAMIC=@_KEYVI_LINK_LIBRARIES_DYNAMIC@
KEYVI_LINK_LIBRARIES_STATIC=@_KEYVI_LINK_LIBRARIES_STATIC@
KEYVI_LINK_FLAGS=@_KEYVI_LINK_FLAGS@
KEYVI_INCLUDES=@_KEYVI_INCLUDES@
Oops, something went wrong.

0 comments on commit 5c84167

Please sign in to comment.
You can’t perform that action at this time.