memgraph/cmake/functions.cmake
Teon Banek 1fd9a72e10 Generate Load functions from LCP as top level
Summary: Depends on D1596

Reviewers: mtomic, msantl

Reviewed By: msantl

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D1601
2018-09-28 10:34:20 +02:00

159 lines
7.1 KiB
CMake

# prints all included directories
function(list_includes)
get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
PROPERTY INCLUDE_DIRECTORIES)
foreach(dir ${dirs})
message(STATUS "dir='${dir}'")
endforeach()
endfunction(list_includes)
# get file names from list of file paths
function(get_file_names file_paths file_names)
set(file_names "")
foreach(file_path ${file_paths})
get_filename_component (file_name ${file_path} NAME_WE)
list(APPEND file_names ${file_name})
endforeach()
set(file_names "${file_names}" PARENT_SCOPE)
endfunction()
MACRO(SUBDIRLIST result curdir)
FILE(GLOB children RELATIVE ${curdir} ${curdir}/*)
SET(dirlist "")
FOREACH(child ${children})
IF(IS_DIRECTORY ${curdir}/${child})
LIST(APPEND dirlist ${child})
ENDIF()
ENDFOREACH()
SET(${result} ${dirlist})
ENDMACRO()
function(disallow_in_source_build)
get_filename_component(src_dir ${CMAKE_SOURCE_DIR} REALPATH)
get_filename_component(bin_dir ${CMAKE_BINARY_DIR} REALPATH)
message(STATUS "SOURCE_DIR" ${src_dir})
message(STATUS "BINARY_DIR" ${bin_dir})
# Do we maybe want to limit out-of-source builds to be only inside a
# directory which contains 'build' in name?
if("${src_dir}" STREQUAL "${bin_dir}")
# Unfortunately, we cannot remove CMakeCache.txt and CMakeFiles here
# because they are written after cmake is done.
message(FATAL_ERROR "In source build is not supported! "
"Remove CMakeCache.txt and CMakeFiles and then create a separate "
"directory, e.g. 'build' and run cmake there.")
endif()
endfunction()
# Takes a string of ';' separated VALUES and stores a new string in RESULT,
# where ';' is replaced with given SEP.
function(join values sep result)
# Match non escaped ';' and replace it with separator. This doesn't handle
# the case when backslash is escaped, e.g: "a\\\\;b" will produce "a;b".
string(REGEX REPLACE "([^\\]|^);" "\\1${sep}" tmp "${values}")
# Fix-up escapes by matching backslashes and removing them.
string(REGEX REPLACE "[\\](.)" "\\1" tmp "${tmp}")
set(${result} "${tmp}" PARENT_SCOPE)
endfunction()
# Returns a list of compile flags ready for gcc or clang.
function(get_target_cxx_flags target result)
# First set the CMAKE_CXX_FLAGS variables, then append directory and target
# options in that order. Definitions come last, directory then target.
string(TOUPPER ${CMAKE_BUILD_TYPE} build_type)
set(flags "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${build_type}}")
get_directory_property(dir_opts DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMPILE_OPTIONS)
if(dir_opts)
join("${dir_opts}" " " dir_opts)
string(APPEND flags " " ${dir_opts})
endif()
get_target_property(opts ${target} COMPILE_OPTIONS)
if(opts)
join("${opts}" " " opts)
string(APPEND flags " " ${opts})
endif()
get_directory_property(dir_defs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMPILE_DEFINITIONS)
if(dir_defs)
join("${dir_defs}" " -D" dir_defs)
string(APPEND flags " -D" ${dir_defs})
endif()
get_target_property(defs ${target} COMPILE_DEFINITIONS)
if(defs)
join("${defs}" " -D" defs)
string(APPEND flags " -D" ${defs})
endif()
set(${result} ${flags} PARENT_SCOPE)
endfunction()
# Define `add_capnp` function for registering a capnp file for generation.
#
# The `define_add_capnp` expects 2 arguments:
# * main_src_files -- variable to be updated with generated cpp files
# * generated_capnp_files -- variable to be updated with generated hpp and cpp files
#
# The `add_capnp` function expects a single argument, path to capnp file.
# Each added file is standalone and we avoid recompiling everything.
macro(define_add_capnp main_src_files generated_capnp_files)
function(add_capnp capnp_src_file)
set(cpp_file ${CMAKE_CURRENT_SOURCE_DIR}/${capnp_src_file}.c++)
set(h_file ${CMAKE_CURRENT_SOURCE_DIR}/${capnp_src_file}.h)
add_custom_command(OUTPUT ${cpp_file} ${h_file}
COMMAND ${CAPNP_EXE} compile -o${CAPNP_CXX_EXE} ${capnp_src_file} -I ${CMAKE_SOURCE_DIR}/src
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${capnp_src_file} capnproto-proj
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
# Update *global* generated_capnp_files
set(${generated_capnp_files} ${${generated_capnp_files}} ${cpp_file} ${h_file} PARENT_SCOPE)
# Update *global* main_src_files
set(${main_src_files} ${${main_src_files}} ${cpp_file} PARENT_SCOPE)
endfunction(add_capnp)
endmacro(define_add_capnp)
# Lisp C++ Preprocessing
set(lcp_exe ${CMAKE_SOURCE_DIR}/tools/lcp)
set(lcp_src_files ${CMAKE_SOURCE_DIR}/src/lisp/lcp.lisp ${lcp_exe})
# Define `add_lcp` function named `name` for registering a lcp file for generation.
#
# The `define_add_lcp` expects 3 arguments:
# * name -- name for the function, you usually want `add_lcp`
# * main_src_files -- variable to be updated with generated cpp files
# * generated_lcp_files -- variable to be updated with generated hpp, cpp and capnp files
#
# The `add_lcp` function expects at least a single argument, path to lcp file.
# Each added file is standalone and we avoid recompiling everything.
# You may pass a CAPNP_SCHEMA <id> keyword argument to generate the Cap'n Proto
# serialization code from .lcp file. You still need to add the generated capnp
# file through `add_capnp` function. To generate the <id> use `capnp id`
# invocation, and specify it here. This preserves correct id information across
# multiple schema generations. If this wasn't the case, wrong typeId
# information will break serialization between different compilations of memgraph.
macro(define_add_lcp name main_src_files generated_lcp_files)
function(${name} lcp_file)
set(one_value_kwargs CAPNP_SCHEMA)
set(multi_value_kwargs DEPENDS)
# NOTE: ${${}ARGN} syntax escapes evaluating macro's ARGN variable; see:
# https://stackoverflow.com/questions/50365544/how-to-access-enclosing-functions-arguments-from-within-a-macro
cmake_parse_arguments(KW "" "${one_value_kwargs}" "${multi_value_kwargs}" ${${}ARGN})
string(REGEX REPLACE "\.lcp$" ".hpp" h_file
"${CMAKE_CURRENT_SOURCE_DIR}/${lcp_file}")
if (KW_CAPNP_SCHEMA)
string(REGEX REPLACE "\.lcp$" ".capnp" capnp_file
"${CMAKE_CURRENT_SOURCE_DIR}/${lcp_file}")
set(capnp_id ${KW_CAPNP_SCHEMA})
set(capnp_depend capnproto-proj)
set(cpp_file ${CMAKE_CURRENT_SOURCE_DIR}/${lcp_file}.cpp)
# Update *global* main_src_files
set(${main_src_files} ${${main_src_files}} ${cpp_file} PARENT_SCOPE)
endif()
add_custom_command(OUTPUT ${h_file} ${cpp_file} ${capnp_file}
COMMAND ${lcp_exe} ${lcp_file} ${capnp_id}
VERBATIM
DEPENDS ${lcp_file} ${lcp_src_files} ${capnp_depend} ${KW_DEPENDS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
# Update *global* generated_lcp_files
set(${generated_lcp_files} ${${generated_lcp_files}} ${h_file} ${cpp_file} ${capnp_file} PARENT_SCOPE)
endfunction(${name})
endmacro(define_add_lcp)