283a91cc60
Summary: All mgp_* symbols are exported from Memgraph executable, no other symbols should be visible. The primary C API header, mg_procedure.h, is now part of the installation. Also, added a shippable query module example. Directory `query_modules` is meant to contain sources of modules we write and ship as part of the installation. Currently, there's only an example module, but there may be potentially more. Some modules could only be installed as part of the enterprise release. For Memgraph to load custom procedures, it needs to be started with a flag pointing to a directory with compiled shared libraries implementing those procedures. Reviewers: mferencevic, ipaljak, llugovic, dsantl, buda Reviewed By: mferencevic Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D2538
359 lines
15 KiB
CMake
359 lines
15 KiB
CMake
# MemGraph CMake configuration
|
|
|
|
cmake_minimum_required(VERSION 3.8)
|
|
|
|
# !! IMPORTANT !! run ./project_root/init.sh before cmake command
|
|
# to download dependencies
|
|
|
|
if(NOT UNIX)
|
|
message(FATAL_ERROR "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()
|
|
find_program(CLANG_FOUND clang)
|
|
find_program(CLANGXX_FOUND clang++)
|
|
if (CLANG_FOUND AND CLANGXX_FOUND)
|
|
set(CMAKE_C_COMPILER ${CLANG_FOUND})
|
|
set(CMAKE_CXX_COMPILER ${CLANGXX_FOUND})
|
|
else()
|
|
message(FATAL_ERROR "Couldn't find clang and/or clang++!")
|
|
endif()
|
|
|
|
# Get current commit hash.
|
|
execute_process(
|
|
OUTPUT_VARIABLE COMMIT_HASH
|
|
COMMAND git rev-parse --short HEAD
|
|
)
|
|
string(STRIP ${COMMIT_HASH} COMMIT_HASH)
|
|
|
|
# -----------------------------------------------------------------------------
|
|
|
|
project(memgraph VERSION 0.15.0)
|
|
# -----------------------------------------------------------------------------
|
|
|
|
# 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}")
|
|
# -----------------------------------------------------------------------------
|
|
|
|
# build flags -----------------------------------------------------------------
|
|
|
|
# Export the compile commands so that we can use clang-tidy. Additional benefit
|
|
# is easier debugging of compilation and linker flags.
|
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
|
|
set(CMAKE_CXX_STANDARD 17)
|
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall \
|
|
-Werror=switch -Werror=switch-bool -Werror=return-type \
|
|
-Werror=return-stack-address")
|
|
|
|
# Don't omit frame pointer in RelWithDebInfo, for additional callchain debug.
|
|
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
|
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fno-omit-frame-pointer")
|
|
|
|
# Statically link libgcc and libstdc++, the GCC allows this according to:
|
|
# https://gcc.gnu.org/onlinedocs/gcc-8.3.0/libstdc++/manual/manual/license.html
|
|
# https://www.gnu.org/licenses/gcc-exception-faq.html
|
|
# Last checked for gcc-8.3 which we are using on the build machines.
|
|
# ** If we change versions, recheck this! **
|
|
# ** Static linking is allowed only for executables! **
|
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
|
|
|
|
# Use gold linker to speedup build
|
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
|
|
|
|
# release flags
|
|
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
|
|
|
|
#debug flags
|
|
set(PREFERRED_DEBUGGER "gdb" CACHE STRING
|
|
"Tunes the debug output for your preferred debugger (gdb or lldb).")
|
|
if ("${PREFERRED_DEBUGGER}" STREQUAL "gdb" AND
|
|
"${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang|GNU")
|
|
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb")
|
|
elseif ("${PREFERRED_DEBUGGER}" STREQUAL "lldb" AND
|
|
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
|
set(CMAKE_CXX_FLAGS_DEBUG "-glldb")
|
|
else()
|
|
message(WARNING "Unable to tune for PREFERRED_DEBUGGER: "
|
|
"'${PREFERRED_DEBUGGER}' with compiler: '${CMAKE_CXX_COMPILER_ID}'")
|
|
set(CMAKE_CXX_FLAGS_DEBUG "-g")
|
|
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()
|
|
# -----------------------------------------------------------------------------
|
|
|
|
# default build type is debug
|
|
if (NOT CMAKE_BUILD_TYPE)
|
|
set(CMAKE_BUILD_TYPE "Debug")
|
|
endif()
|
|
message(STATUS "CMake build type: ${CMAKE_BUILD_TYPE}")
|
|
# -----------------------------------------------------------------------------
|
|
|
|
# setup external dependencies -------------------------------------------------
|
|
|
|
# threading
|
|
find_package(Threads REQUIRED)
|
|
|
|
# optional Ltalloc
|
|
option(USE_LTALLOC "Use Ltalloc instead of default allocator (default OFF). \
|
|
Set this to ON to link with Ltalloc." OFF)
|
|
|
|
# optional readline
|
|
option(USE_READLINE "Use GNU Readline library if available (default ON). \
|
|
Set this to OFF to prevent linking with Readline even if it is available." ON)
|
|
if (USE_READLINE)
|
|
find_package(Readline)
|
|
if (READLINE_FOUND)
|
|
add_definitions(-DHAS_READLINE)
|
|
endif()
|
|
endif()
|
|
|
|
# OpenSSL
|
|
find_package(OpenSSL REQUIRED)
|
|
|
|
set(libs_dir ${CMAKE_SOURCE_DIR}/libs)
|
|
add_subdirectory(libs EXCLUDE_FROM_ALL)
|
|
|
|
include_directories(SYSTEM ${GFLAGS_INCLUDE_DIR})
|
|
include_directories(SYSTEM ${GLOG_INCLUDE_DIR})
|
|
include_directories(SYSTEM ${FMT_INCLUDE_DIR})
|
|
include_directories(SYSTEM ${ANTLR4_INCLUDE_DIR})
|
|
include_directories(SYSTEM ${BZIP2_INCLUDE_DIR})
|
|
include_directories(SYSTEM ${ZLIB_INCLUDE_DIR})
|
|
include_directories(SYSTEM ${ROCKSDB_INCLUDE_DIR})
|
|
include_directories(SYSTEM ${LIBRDKAFKA_INCLUDE_DIR})
|
|
# -----------------------------------------------------------------------------
|
|
|
|
# openCypher parser -----------------------------------------------------------
|
|
set(opencypher_frontend ${CMAKE_SOURCE_DIR}/src/query/frontend/opencypher)
|
|
set(opencypher_generated ${opencypher_frontend}/generated)
|
|
set(opencypher_lexer_grammar ${opencypher_frontend}/grammar/MemgraphCypherLexer.g4)
|
|
set(opencypher_parser_grammar ${opencypher_frontend}/grammar/MemgraphCypher.g4)
|
|
|
|
# enumerate all files that are generated from antlr
|
|
set(antlr_opencypher_generated_src
|
|
${opencypher_generated}/MemgraphCypherLexer.cpp
|
|
${opencypher_generated}/MemgraphCypher.cpp
|
|
${opencypher_generated}/MemgraphCypherBaseVisitor.cpp
|
|
${opencypher_generated}/MemgraphCypherVisitor.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_lexer_grammar} ${opencypher_parser_grammar}
|
|
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
|
|
DEPENDS ${opencypher_lexer_grammar} ${opencypher_parser_grammar}
|
|
${opencypher_frontend}/grammar/CypherLexer.g4
|
|
${opencypher_frontend}/grammar/Cypher.g4)
|
|
|
|
# add custom target for generation
|
|
add_custom_target(generate_opencypher_parser
|
|
DEPENDS ${antlr_opencypher_generated_src})
|
|
|
|
add_library(antlr_opencypher_parser_lib STATIC ${antlr_opencypher_generated_src})
|
|
target_link_libraries(antlr_opencypher_parser_lib antlr4)
|
|
# -----------------------------------------------------------------------------
|
|
|
|
# Optional subproject configuration -------------------------------------------
|
|
option(POC "Build proof of concept binaries" OFF)
|
|
option(EXPERIMENTAL "Build experimental binaries" OFF)
|
|
option(CUSTOMERS "Build customer binaries" OFF)
|
|
option(TEST_COVERAGE "Generate coverage reports from running memgraph" OFF)
|
|
option(TOOLS "Build tools binaries" ON)
|
|
option(QUERY_MODULES "Build query modules containing custom procedures" ON)
|
|
option(MG_COMMUNITY "Build Memgraph Community Edition" OFF)
|
|
option(ASAN "Build with Address Sanitizer. To get a reasonable performance option should be used only in Release or RelWithDebInfo build " OFF)
|
|
option(TSAN "Build with Thread Sanitizer. To get a reasonable performance option should be used only in Release or RelWithDebInfo build " OFF)
|
|
option(UBSAN "Build with Undefined Behaviour Sanitizer" OFF)
|
|
option(THIN_LTO "Build with link time optimization" OFF)
|
|
|
|
if (TEST_COVERAGE)
|
|
string(TOLOWER ${CMAKE_BUILD_TYPE} lower_build_type)
|
|
if (NOT lower_build_type STREQUAL "debug")
|
|
message(FATAL_ERROR "Generating test coverage unsupported in non Debug builds. Current build type is '${CMAKE_BUILD_TYPE}'")
|
|
endif()
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping")
|
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-instr-generate -fcoverage-mapping")
|
|
endif()
|
|
|
|
if (MG_COMMUNITY)
|
|
add_definitions(-DMG_COMMUNITY)
|
|
endif()
|
|
|
|
if (ASAN)
|
|
# Enable Addres sanitizer and get nicer stack traces in error messages.
|
|
# NOTE: AddressSanitizer uses llvm-symbolizer binary from the Clang
|
|
# distribution to symbolize the stack traces (note that ideally the
|
|
# llvm-symbolizer version must match the version of ASan runtime library).
|
|
# Just make sure llvm-symbolizer is in PATH before running the binary or
|
|
# provide it in separate ASAN_SYMBOLIZER_PATH environment variable.
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
|
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
|
|
# To detect Stack-use-after-return bugs set run-time flag:
|
|
# ASAN_OPTIONS=detect_stack_use_after_return=1
|
|
# To check initialization order bugs set run-time flag:
|
|
# ASAN_OPTIONS=check_initialization_order=true
|
|
# This mode reports an error if initializer for a global variable accesses
|
|
# dynamically initialized global from another translation unit, which is
|
|
# not yet initialized
|
|
# ASAN_OPTIONS=strict_init_order=true
|
|
# This mode reports an error if initializer for a global variable accesses
|
|
# any dynamically initialized global from another translation unit.
|
|
endif()
|
|
|
|
if (TSAN)
|
|
# ThreadSanitizer generally requires all code to be compiled with -fsanitize=thread.
|
|
# If some code (e.g. dynamic libraries) is not compiled with the flag, it can
|
|
# lead to false positive race reports, false negative race reports and/or
|
|
# missed stack frames in reports depending on the nature of non-instrumented
|
|
# code. To not produce false positive reports ThreadSanitizer has to see all
|
|
# synchronization in the program, some synchronization operations (namely,
|
|
# atomic operations and thread-safe static initialization) are intercepted
|
|
# during compilation (and can only be intercepted during compilation).
|
|
# ThreadSanitizer stack trace collection also relies on compiler instrumentation
|
|
# (unwinding stack on each memory access is too expensive).
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
|
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread")
|
|
# By default ThreadSanitizer uses addr2line utility to symbolize reports.
|
|
# llvm-symbolizer is faster, consumes less memory and produces much better
|
|
# reports. To use it set runtime flag:
|
|
# TSAN_OPTIONS="extern-symbolizer-path=~/llvm-symbolizer"
|
|
# For more runtime flags see: https://github.com/google/sanitizers/wiki/ThreadSanitizerFlags
|
|
endif()
|
|
|
|
if (UBSAN)
|
|
# Compile with UBSAN but disable vptr check. This is disabled because it
|
|
# requires linking with clang++ to make sure C++ specific parts of the
|
|
# runtime library and c++ standard libraries are present.
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-omit-frame-pointer -fno-sanitize=vptr")
|
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fno-sanitize=vptr")
|
|
# Run program with environment variable UBSAN_OPTIONS=print_stacktrace=1
|
|
# Make sure llvm-symbolizer binary is in path
|
|
endif()
|
|
|
|
if (THIN_LTO)
|
|
set(CMAKE_CXX_FLAGS"${CMAKE_CXX_FLAGS} -flto=thin")
|
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto=thin")
|
|
endif()
|
|
|
|
# Add subprojects
|
|
include_directories(src)
|
|
add_subdirectory(src)
|
|
|
|
if(POC)
|
|
add_subdirectory(poc)
|
|
endif()
|
|
|
|
if(EXPERIMENTAL)
|
|
add_subdirectory(experimental)
|
|
endif()
|
|
|
|
if(CUSTOMERS)
|
|
add_subdirectory(customers)
|
|
endif()
|
|
|
|
enable_testing()
|
|
add_subdirectory(tests)
|
|
|
|
if(TOOLS)
|
|
add_subdirectory(tools)
|
|
endif()
|
|
|
|
if(QUERY_MODULES)
|
|
add_subdirectory(query_modules)
|
|
endif()
|
|
|
|
# -----------------------------------------------------------------------------
|
|
|
|
# ---- Setup CPack --------
|
|
# General setup
|
|
set(CPACK_PACKAGE_NAME memgraph)
|
|
set(CPACK_PACKAGE_VENDOR "Memgraph Ltd.")
|
|
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY
|
|
"High performance, in-memory, transactional graph database")
|
|
set(CPACK_PACKAGE_VERSION_MAJOR ${memgraph_VERSION_MAJOR})
|
|
set(CPACK_PACKAGE_VERSION_MINOR ${memgraph_VERSION_MINOR})
|
|
set(CPACK_PACKAGE_VERSION_PATCH ${memgraph_VERSION_PATCH})
|
|
set(CPACK_PACKAGE_VERSION_TWEAK ${memgraph_VERSION_TWEAK})
|
|
set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${memgraph_VERSION}-${COMMIT_HASH}${CPACK_SYSTEM_NAME})
|
|
|
|
# DEB specific
|
|
# Instead of using "name <email>" format, we use "email (name)" to prevent
|
|
# errors due to full stop, '.' at the end of "Ltd". (See: RFC 822)
|
|
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "tech@memgraph.com (Memgraph Ltd.)")
|
|
set(CPACK_DEBIAN_PACKAGE_SECTION non-free/database)
|
|
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE https://memgraph.com)
|
|
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
|
|
"${CMAKE_SOURCE_DIR}/release/debian/conffiles;"
|
|
"${CMAKE_SOURCE_DIR}/release/debian/copyright;"
|
|
"${CMAKE_SOURCE_DIR}/release/debian/prerm;"
|
|
"${CMAKE_SOURCE_DIR}/release/debian/postrm;"
|
|
"${CMAKE_SOURCE_DIR}/release/debian/postinst;")
|
|
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
|
# Description formatting is important, summary must be followed with a newline and 1 space.
|
|
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}
|
|
Contains Memgraph, the graph database. It aims to deliver developers the
|
|
speed, simplicity and scale required to build the next generation of
|
|
applications driver by real-time connected data.")
|
|
# Add `openssl` package to dependencies list. Used to generate SSL certificates.
|
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "openssl (>= 1.1.0)")
|
|
|
|
# RPM specific
|
|
set(CPACK_RPM_PACKAGE_URL https://memgraph.com)
|
|
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION
|
|
/var /var/lib /var/log /etc/logrotate.d
|
|
/lib /lib/systemd /lib/systemd/system /lib/systemd/system/memgraph.service)
|
|
set(CPACK_RPM_PACKAGE_REQUIRES_PRE "shadow-utils")
|
|
# NOTE: user specfile has a bug in cmake 3.7.2, this needs to be patched
|
|
# manually in: ~/cmake/share/cmake-3.7/Modules/CPackRPM.cmake line 2273
|
|
# Or newer cmake version used
|
|
set(CPACK_RPM_USER_BINARY_SPECFILE "${CMAKE_SOURCE_DIR}/release/rpm/memgraph.spec.in")
|
|
# Description formatting is important, no line must be greater than 80 characters.
|
|
set(CPACK_RPM_PACKAGE_DESCRIPTION "Contains Memgraph, the graph database.
|
|
It aims to deliver developers the speed, simplicity and scale required to build
|
|
the next generation of applications driver by real-time connected data.")
|
|
# Add `openssl` package to dependencies list. Used to generate SSL certificates.
|
|
set(CPACK_RPM_PACKAGE_REQUIRES "openssl >= 1.0.0, curl >= 7.29.0")
|
|
|
|
# All variables must be set before including.
|
|
include(CPack)
|
|
# ---- End Setup CPack ----
|