memgraph/CMakeLists.txt
Teon Banek baa644e9b7 Support creating NodeFilter and CreateOp logical operators
Reviewers: mislav.bradac, buda, florijan

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D133
2017-03-16 10:06:01 +01:00

489 lines
19 KiB
CMake

# MemGraph CMake configuration
cmake_minimum_required(VERSION 3.1)
# !! IMPORTANT !! run ./project_root/init.sh before cmake command
# to download dependencies
if(NOT UNIX)
message(FATAL "Unsupported operating system.")
endif()
# Set `make clean` to ignore outputs of add_custom_command. If generated files
# need to be cleaned, set ADDITIONAL_MAKE_CLEAN_FILES property.
set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM TRUE)
# ccache setup
# ccache isn't enabled all the time because it makes some problem
# during the code coverage process
find_program(CCACHE_FOUND ccache)
option(USE_CCACHE "ccache:" ON)
message(STATUS "CCache: ${USE_CCACHE}")
if(CCACHE_FOUND AND USE_CCACHE)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
endif(CCACHE_FOUND AND USE_CCACHE)
# choose a compiler
# NOTE: must be choosen before use of project() or enable_language() ----------
set(CMAKE_C_COMPILER "clang")
set(CMAKE_CXX_COMPILER "clang++")
# -----------------------------------------------------------------------------
# set project name
# get directory name
get_filename_component(project_name ${CMAKE_SOURCE_DIR} NAME)
# replace whitespaces with underscores
string(REPLACE " " "_" project_name ${project_name})
# set project name
project(${project_name})
# -----------------------------------------------------------------------------
# setup CMake module path, defines path for include() and find_package()
# https://cmake.org/cmake/help/latest/variable/CMAKE_MODULE_PATH.html
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake)
# -----------------------------------------------------------------------------
# custom function definitions
include(functions)
# -----------------------------------------------------------------------------
# We want out of source builds, so that cmake generated files don't get mixed
# with source files. This allows for easier clean up.
disallow_in_source_build()
add_custom_target(clean_all
COMMAND ${CMAKE_COMMAND} -P ${PROJECT_SOURCE_DIR}/cmake/clean_all.cmake
COMMENT "Removing all files in ${CMAKE_BINARY_DIR}")
# threading
find_package(Threads REQUIRED)
# -----------------------------------------------------------------------------
# c++14
# TODO: set here 17 once it will be available in the cmake version (3.8)
set(cxx_standard 14)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1z -Wall")
# -----------------------------------------------------------------------------
# dir variables
set(src_dir ${CMAKE_SOURCE_DIR}/src)
set(libs_dir ${CMAKE_SOURCE_DIR}/libs)
set(tests_dir ${CMAKE_SOURCE_DIR}/tests)
set(include_dir ${CMAKE_SOURCE_DIR}/include)
set(build_include_dir ${CMAKE_BINARY_DIR}/include)
set(test_include_dir ${CMAKE_BINARY_DIR}/tests/include)
set(test_src_dir ${CMAKE_BINARY_DIR}/tests/src)
# -----------------------------------------------------------------------------
# build flags -----------------------------------------------------------------
# release flags
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG -Wno-c++1z-extensions")
#debug flags
set(CMAKE_CXX_FLAGS_DEBUG "-g -Wno-c++1z-extensions")
# compiler specific flags
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# set(CMAKE_CXX_FLAGS_DEBUG "-Wl,--export-dynamic ${CMAKE_CXX_FLAGS_DEBUG}")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# set(CMAKE_CXX_FLAGS_DEBUG "-rdynamic ${CMAKE_CXX_FLAGS_DEBUG}")
endif()
# default build type is debug
if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
set(CMAKE_BUILD_TYPE "debug")
endif()
message(STATUS "CMake build type: ${CMAKE_BUILD_TYPE}")
# -----------------------------------------------------------------------------
# setup external dependencies -------------------------------------------------
add_subdirectory(libs)
# fmt
set(fmt_source_dir ${libs_dir}/fmt)
set(fmt_static_lib ${fmt_source_dir}/fmt/libfmt.a)
# yaml-cpp
set(yaml_source_dir ${libs_dir}/yaml-cpp)
set(yaml_include_dir ${yaml_source_dir}/include)
set(yaml_static_lib ${yaml_source_dir}/libyaml-cpp.a)
# prepare template and destination folders for query engine (tests)
# and memgraph server binary
# copy query_engine template file
set(query_engine_template_file ${src_dir}/query/plan_template_cpp)
FILE(COPY ${query_engine_template_file}
DESTINATION ${CMAKE_BINARY_DIR}/tests/template)
FILE(COPY ${query_engine_template_file}
DESTINATION ${CMAKE_BINARY_DIR}/tests/integration/template)
FILE(COPY ${query_engine_template_file}
DESTINATION ${CMAKE_BINARY_DIR}/tests/manual/template)
FILE(COPY ${query_engine_template_file}
DESTINATION ${CMAKE_BINARY_DIR}/template)
# create destination folder for compiled queries
FILE(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/tests/integration/compiled)
FILE(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/tests/manual/compiled)
FILE(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/tests/compiled)
FILE(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/compiled)
# copy hardcoded queries
FILE(COPY ${tests_dir}/integration/hardcoded_query
DESTINATION ${CMAKE_BINARY_DIR}/tests/integration)
FILE(COPY ${tests_dir}/integration/stream
DESTINATION ${CMAKE_BINARY_DIR}/tests/integration)
# -----------------------------------------------------------------------------
# linter setup (clang-tidy)
# all source files for linting
FILE(GLOB_RECURSE LINTER_SRC_FILES
${src_dir}/*.cpp
${CMAKE_SOURCE_DIR}/tests/.cpp
${CMAKE_SOURCE_DIR}/poc/.cpp
)
MESSAGE(STATUS "All cpp files for linting are: ${LINTER_SRC_FILES}")
# linter target clang-tidy
find_program(CLANG_TIDY "clang-tidy")
if(CLANG_TIDY)
add_custom_target(
clang-tidy
COMMAND /usr/bin/clang-tidy
${LINTER_SRC_FILES}
-config=''
--
-std=c++1y
-I${CMAKE_SOURCE_DIR}/include -I${fmt_source_dir} -I${yaml_include_dir}
)
endif()
# -----------------------------------------------------------------------------
# logging levels --------------------------------------------------------------
option(LOG_NO_TRACE "Disable trace logging" OFF)
message(STATUS "LOG_NO_TRACE: ${LOG_NO_TRACE}")
if (LOG_NO_TRACE)
add_definitions(-DLOG_NO_TRACE)
endif()
option(LOG_NO_DEBUG "Disable debug logging" OFF)
message(STATUS "LOG_NO_DEBUG: ${LOG_NO_DEBUG}")
if (LOG_NO_DEBUG)
add_definitions(-DLOG_NO_DEBUG)
endif()
option(LOG_NO_INFO "Disable info logging" OFF)
message(STATUS "LOG_NO_INFO: ${LOG_NO_INFO}")
if (LOG_NO_INFO)
add_definitions(-DLOG_NO_INFO)
endif()
option(LOG_NO_WARN "Disable warn logging" OFF)
message(STATUS "LOG_NO_WARN: ${LOG_NO_WARN}")
if (LOG_NO_WARN)
add_definitions(-DLOG_NO_WARN)
endif()
option(LOG_NO_ERROR "Disable error logging" OFF)
message(STATUS "LOG_NO_ERROR: ${LOG_NO_ERROR}")
if (LOG_NO_ERROR)
add_definitions(-DLOG_NO_ERROR)
endif()
# -----------------------------------------------------------------------------
# logger type
# the default logger is sync logger
# on: cmake ... -DSYNC_LOGGER=OFF ... async logger is going to be used
option(SYNC_LOGGER "Sync logger" ON)
message(STATUS "SYNC_LOGGER: ${SYNC_LOGGER}")
if (SYNC_LOGGER)
add_definitions(-DSYNC_LOGGER)
endif()
# -----------------------------------------------------------------------------
# custom assert control parameters
# Debug assert, if value is OFF debug asserts will be inactive.
# Default value is ON.
option(DEBUG_ASSERT "Enable debug assertions" ON)
message(STATUS "DEBUG_ASSERT: ${DEBUG_ASSERT}")
if(DEBUG_ASSERT)
add_definitions(-DDEBUG_ASSERT_ON)
endif()
# by default on custom assert only the message, filename and line number will be
# printed on stderr, if STACKTRACE_ASSERT is ON the whole stacktrace is going to
# be printed on stderr
option(STACKTRACE_ASSERT "Dump stacktrace on custom assert" OFF)
message(STATUS "STACKTRACE_ASSERT: ${STACKTRACE_ASSERT}")
if(STACKTRACE_ASSERT)
add_definitions(-DSTACKTRACE_ASSERT_ON)
endif()
# -----------------------------------------------------------------------------
# ndebug
option(NDEBUG "No debug" OFF)
message(STATUS "NDEBUG: ${NDEBUG} (be careful CMAKE_BUILD_TYPE can also \
append this flag)")
if(NDEBUG)
add_definitions( -DNDEBUG )
endif()
# -----------------------------------------------------------------------------
# -- GLIBCXX_DEBUG ------------------------------------------------------------
# glibcxx debug (useful for gdb)
# the problem is that the query engine doesn't work as it should work if
# this flag is present (TODO: figure out why)
option(GLIBCXX_DEBUG "glibc debug" OFF)
message(STATUS "GLIBCXX_DEBUG: ${GLIBCXX_DEBUG} (solves problem with \
_M_dataplus member during a debugging process)")
if(GLIBCXX_DEBUG)
set(CMAKE_CXX_FLAGS_DEBUG "-D_GLIBCXX_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}")
endif()
# -----------------------------------------------------------------------------
# option binaries
# memgraph
option(MEMGRAPH "Build memgraph binary" ON)
message(STATUS "MEMGRAPH binary: ${MEMGRAPH}")
# proof of concept
option(POC "Build proof of concept binaries" OFF)
message(STATUS "POC binaries: ${POC}")
# tests
option(ALL_TESTS "Add all test binaries" ON)
message(STATUS "Add all test binaries: ${ALL_TESTS}")
option(BENCHMARK_TESTS "Add benchmark test binaries" OFF)
message(STATUS "Add benchmark test binaries: ${BENCHMARK_TESTS}")
option(CONCURRENT_TESTS "Add concurrent test binaries" OFF)
message(STATUS "Add concurrent test binaries: ${CONCURRENT_TESTS}")
option(INTEGRATION_TESTS "Add integration test binaries" OFF)
message(STATUS "Add integration test binaries: ${INTEGRATION_TESTS}")
option(MANUAL_TESTS "Add manual test binaries" OFF)
message(STATUS "Add manual test binaries: ${MANUAL_TESTS}")
option(UNIT_TESTS "Add unit test binaries" OFF)
message(STATUS "Add unit test binaries: ${UNIT_TESTS}")
option(TEST_COVERAGE "Generate coverage reports from unit tests" OFF)
message(STATUS "Generate coverage from unit tests: ${TEST_COVERAGE}")
# -----------------------------------------------------------------------------
# includes
include_directories(${src_dir})
include_directories(${build_include_dir})
include_directories(${fmt_source_dir})
include_directories(${yaml_include_dir})
include_directories(${GTEST_INCLUDE_DIRS} ${GMOCK_INCLUDE_DIRS})
include_directories(${CMAKE_SOURCE_DIR}/libs)
# -----------------------------------------------------------------------------
# openCypher parser -----------------------------------------------------------
set(antlr_src ${CMAKE_SOURCE_DIR}/libs/antlr4/runtime/Cpp/runtime/src)
set(opencypher_frontend ${CMAKE_SOURCE_DIR}/src/query/frontend/opencypher)
set(opencypher_generated ${opencypher_frontend}/generated)
set(opencypher_grammar ${opencypher_frontend}/grammar/Cypher.g4)
# enumerate all files that are generated from antlr
set(antlr_opencypher_generated_src
${opencypher_generated}/CypherLexer.cpp
${opencypher_generated}/CypherParser.cpp
${opencypher_generated}/CypherBaseVisitor.cpp
${opencypher_generated}/CypherVisitor.cpp
)
# Provide a command to generate sources if missing. If this were a
# custom_target, it would always run and we don't want that.
add_custom_command(OUTPUT ${antlr_opencypher_generated_src}
COMMAND
${CMAKE_COMMAND} -E make_directory ${opencypher_generated}
COMMAND
java -jar ${CMAKE_SOURCE_DIR}/libs/antlr-4.6-complete.jar -Dlanguage=Cpp -visitor -o ${opencypher_generated} -package antlropencypher ${opencypher_grammar}
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
DEPENDS ${opencypher_grammar})
# add custom target for generation
add_custom_target(generate_opencypher_parser
DEPENDS ${antlr_opencypher_generated_src})
# include antlr header files
include_directories(
${antlr_src}
${antlr_src}/misc
${antlr_src}/atn
${antlr_src}/dfa
${antlr_src}/tree
${antlr_src}/support
)
add_library(antlr_opencypher_parser_lib STATIC ${antlr_opencypher_generated_src})
target_link_libraries(antlr_opencypher_parser_lib antlr4_static)
# -----------------------------------------------------------------------------
# all memgraph src files
set(memgraph_src_files
${src_dir}/config/config.cpp
${src_dir}/dbms/dbms.cpp
# ${src_dir}/dbms/cleaner.cpp
${src_dir}/utils/string/transform.cpp
${src_dir}/utils/string/join.cpp
${src_dir}/utils/string/file.cpp
${src_dir}/utils/numerics/saturate.cpp
${src_dir}/communication/bolt/v1/transport/bolt_decoder.cpp
${src_dir}/communication/bolt/v1/transport/buffer.cpp
${src_dir}/io/network/addrinfo.cpp
${src_dir}/io/network/network_endpoint.cpp
${src_dir}/io/network/socket.cpp
${src_dir}/threading/thread.cpp
${src_dir}/mvcc/id.cpp
# ${src_dir}/snapshot/snapshot_engine.cpp
# ${src_dir}/snapshot/snapshoter.cpp
# ${src_dir}/snapshot/snapshot_encoder.cpp
# ${src_dir}/snapshot/snapshot_decoder.cpp
${src_dir}/storage/property_value.cpp
${src_dir}/storage/locking/record_lock.cpp
# ${src_dir}/storage/garbage/garbage.cpp
${src_dir}/storage/record_accessor.cpp
${src_dir}/storage/vertex_accessor.cpp
${src_dir}/storage/edge_accessor.cpp
# ${src_dir}/storage/record_accessor.cpp
${src_dir}/transactions/snapshot.cpp
${src_dir}/transactions/transaction.cpp
${src_dir}/template_engine/engine.cpp
${src_dir}/logging/streams/stdout.cpp
${src_dir}/logging/streams/stderr.cpp
${src_dir}/logging/levels.cpp
${src_dir}/logging/logs/sync_log.cpp
${src_dir}/logging/logs/async_log.cpp
${src_dir}/logging/default.cpp
${src_dir}/logging/log.cpp
${src_dir}/database/graph_db.cpp
${src_dir}/database/graph_db_accessor.cpp
${src_dir}/query/stripper.cpp
${src_dir}/query/frontend/ast/cypher_main_visitor.cpp
${src_dir}/query/context.cpp
${src_dir}/query/backend/cpp/typed_value.cpp
${src_dir}/query/frontend/logical/planner.cpp
)
# -----------------------------------------------------------------------------
# STATIC library used by memgraph executables
add_library(memgraph_lib STATIC ${memgraph_src_files})
add_dependencies(memgraph_lib generate_opencypher_parser
generate_plan_compiler_flags)
# -----------------------------------------------------------------------------
# STATIC PIC library used by query engine
add_library(memgraph_pic STATIC ${memgraph_src_files})
add_dependencies(memgraph_pic generate_opencypher_parser
generate_plan_compiler_flags)
set_property(TARGET memgraph_pic PROPERTY POSITION_INDEPENDENT_CODE TRUE)
# -----------------------------------------------------------------------------
# proof of concepts
if (POC)
add_subdirectory(poc)
endif()
# -----------------------------------------------------------------------------
# tests
if (ALL_TESTS OR BENCHMARK_TESTS OR CONCURRENT_TEST OR INTEGRATION_TEST
OR MANUAL_TESTS OR UNIT_TESTS)
add_subdirectory(tests)
endif()
# -----------------------------------------------------------------------------
execute_process(
COMMAND ./recursive_include --roots ${src_dir} ${libs_dir} --start ${src_dir}/query/plan_template_cpp --copy ${CMAKE_BINARY_DIR}/include
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/cmake
)
# memgraph build name
execute_process(
OUTPUT_VARIABLE COMMIT_BRANCH
COMMAND git rev-parse --abbrev-ref HEAD
)
execute_process(
OUTPUT_VARIABLE COMMIT_HASH
COMMAND git rev-parse --short HEAD
)
execute_process(
OUTPUT_VARIABLE COMMIT_NO
COMMAND git rev-list --count HEAD
)
string(STRIP ${COMMIT_BRANCH} COMMIT_BRANCH)
string(STRIP ${COMMIT_NO} COMMIT_NO)
string(STRIP ${COMMIT_HASH} COMMIT_HASH)
set(MEMGRAPH_BUILD_NAME
"memgraph_${COMMIT_NO}_${COMMIT_HASH}_${COMMIT_BRANCH}_${CMAKE_BUILD_TYPE}")
# -----------------------------------------------------------------------------
# memgraph main executable
if (MEMGRAPH)
add_executable(${MEMGRAPH_BUILD_NAME} ${src_dir}/memgraph_bolt.cpp)
set_property(TARGET ${MEMGRAPH_BUILD_NAME}
PROPERTY CXX_STANDARD ${cxx_standard})
target_link_libraries(${MEMGRAPH_BUILD_NAME} memgraph_lib)
target_link_libraries(${MEMGRAPH_BUILD_NAME} stdc++fs)
target_link_libraries(${MEMGRAPH_BUILD_NAME} Threads::Threads)
target_link_libraries(${MEMGRAPH_BUILD_NAME} fmt)
target_link_libraries(${MEMGRAPH_BUILD_NAME} yaml-cpp)
target_link_libraries(${MEMGRAPH_BUILD_NAME} antlr_opencypher_parser_lib)
target_link_libraries(${MEMGRAPH_BUILD_NAME} dl)
endif()
# utility target to copy hardcoded queries
# FROM: tests/integration/hardcoded_query TO: build/compiled/hardcode
add_executable(__copy_hardcoded_queries ${src_dir}/copy_hardcoded_queries.cpp)
set_property(TARGET __copy_hardcoded_queries PROPERTY CXX_STANDARD
${cxx_standard})
target_link_libraries(__copy_hardcoded_queries memgraph_lib)
target_link_libraries(__copy_hardcoded_queries stdc++fs)
target_link_libraries(__copy_hardcoded_queries fmt)
target_link_libraries(__copy_hardcoded_queries Threads::Threads)
target_link_libraries(__copy_hardcoded_queries antlr_opencypher_parser_lib)
add_custom_target(copy_hardcoded_queries ./__copy_hardcoded_queries --src
${CMAKE_SOURCE_DIR}/tests/integration/hardcoded_query --dst
${CMAKE_BINARY_DIR}/compiled/hardcode
WORKING_DIR ${CMAKE_BINARY_DIR})
# make CLion aware of all source files so we get refactoring etc
# this target won't be built
file(GLOB_RECURSE __SOURCES ${CMAKE_SOURCE_DIR}/src/*.hpp
${CMAKE_SOURCE_DIR}/src/*.cpp)
add_executable(__refactor_target ${__SOURCES})
set_target_properties(__refactor_target PROPERTIES EXCLUDE_FROM_ALL 1)
# targets to check compilability of all hardcoded query plans
# that is a first step in integration testing
# integration testing phases should be
# 1. compilation of all hardcoded query plans
# 2. query plan execution agains empty database and injected OutputStream
# 3. integration tests for all pilot/clients written in cucumber
# the following targets address only the first phase
file(GLOB __HARDCODED_SOURCES
${CMAKE_SOURCE_DIR}/tests/integration/hardcoded_query/*.cpp)
foreach(file_path ${__HARDCODED_SOURCES})
get_filename_component(file_name ${file_path} NAME_WE)
set(target_name __${file_name}_hardcoded_target)
add_executable(${target_name} ${CMAKE_SOURCE_DIR}/libs/__main.cpp
${file_path})
target_link_libraries(${target_name} memgraph_lib)
target_link_libraries(${target_name} fmt)
target_link_libraries(${target_name} Threads::Threads)
set_property(TARGET ${target_name} PROPERTY CXX_STANDARD ${cxx_standard})
set_target_properties(${target_name}
PROPERTIES RUNTIME_OUTPUT_DIRECTORY
"${CMAKE_BINARY_DIR}/__hardcoded_targets")
endforeach()
get_target_cxx_flags(memgraph_lib compile_flags)
set(plan_compiler_flags_file ${build_include_dir}/query/plan_compiler_flags.hpp)
add_custom_target(generate_plan_compiler_flags
COMMENT
"Generating ${plan_compiler_flags_file} with compile flags: ${compile_flags}"
VERBATIM
COMMAND
/bin/echo -e
"#pragma once"
"\\n// Generated from cmake. Flags are taken from current build configuration."
"\\n// Do not edit this manually!"
"\\nstatic constexpr const char compile_flags[] = \"${compile_flags}\";"
"\\nstatic constexpr const char include_dirs[] ="
"\"-I${CMAKE_BINARY_DIR}/include -I${CMAKE_SOURCE_DIR}/libs/fmt\";"
"\\nstatic constexpr const char link_dirs[] = \"-L${CMAKE_BINARY_DIR}\";"
> ${plan_compiler_flags_file}
BYPRODUCTS ${plan_compiler_flags_file}
)
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${plan_compiler_flags_file})