| # The MIT License (MIT) |
| # |
| # Copyright (c) 2015 Microsoft Corporation |
| # |
| # -=- Robust Distributed System Nucleus (rDSN) -=- |
| # |
| # Permission is hereby granted, free of charge, to any person obtaining a copy |
| # of this software and associated documentation files (the "Software"), to deal |
| # in the Software without restriction, including without limitation the rights |
| # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| # copies of the Software, and to permit persons to whom the Software is |
| # furnished to do so, subject to the following conditions: |
| # |
| # The above copyright notice and this permission notice shall be included in |
| # all copies or substantial portions of the Software. |
| # |
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| # THE SOFTWARE. |
| |
| # Helper function to add preprocesor definition of FILE_BASENAME |
| # to pass the filename without directory path for debugging use. |
| # |
| # Note that in header files this is not consistent with |
| # __FILE__ and __LINE__ since FILE_BASENAME will be the |
| # compilation unit source file name (.c/.cpp). |
| # |
| # Example: |
| # |
| # define_file_basename_for_sources(my_target) |
| # |
| # Will add -DFILE_BASENAME="filename" for each source file depended on |
| # by my_target, where filename is the name of the file. |
| # |
| function(define_file_basename_for_sources targetname) |
| get_target_property(source_files "${targetname}" SOURCES) |
| foreach(sourcefile ${source_files}) |
| # Add the FILE_BASENAME=filename compile definition to the list. |
| get_filename_component(basename "${sourcefile}" NAME) |
| # Set the updated compile definitions on the source file. |
| set_property( |
| SOURCE "${sourcefile}" APPEND |
| PROPERTY COMPILE_DEFINITIONS "__FILENAME__=\"${basename}\"") |
| endforeach() |
| endfunction() |
| |
| # Install this target into ${CMAKE_INSTALL_PREFIX}/lib |
| function(dsn_install_library) |
| install(TARGETS ${MY_PROJ_NAME} DESTINATION "lib") |
| endfunction() |
| |
| # Install this target into ${CMAKE_INSTALL_PREFIX}/bin/${PROJ_NAME} |
| function(dsn_install_executable) |
| set(MY_PROJ_TYPE "EXECUTABLE") |
| set(INSTALL_DIR "bin/${MY_PROJ_NAME}") |
| install(TARGETS ${MY_PROJ_NAME} DESTINATION "${INSTALL_DIR}") |
| |
| # install the extra files together with the executable |
| if(NOT (MY_BINPLACES STREQUAL "")) |
| foreach(BF ${MY_BINPLACES}) |
| install(FILES ${BF} DESTINATION "${INSTALL_DIR}") |
| endforeach() |
| endif() |
| endfunction() |
| |
| function(ms_add_project PROJ_TYPE PROJ_NAME PROJ_SRC PROJ_LIBS PROJ_BINPLACES) |
| if(NOT((PROJ_TYPE STREQUAL "STATIC") OR (PROJ_TYPE STREQUAL "SHARED") OR |
| (PROJ_TYPE STREQUAL "EXECUTABLE") OR (PROJ_TYPE STREQUAL "OBJECT"))) |
| message(FATAL_ERROR "Invalid project type.") |
| endif() |
| |
| if(PROJ_SRC STREQUAL "") |
| message(FATAL_ERROR "No source files.") |
| endif() |
| |
| if((PROJ_TYPE STREQUAL "STATIC") OR (PROJ_TYPE STREQUAL "OBJECT")) |
| add_library(${PROJ_NAME} ${PROJ_TYPE} ${PROJ_SRC}) |
| elseif(PROJ_TYPE STREQUAL "SHARED") |
| add_library(${PROJ_NAME} ${PROJ_TYPE} ${PROJ_SRC}) |
| elseif(PROJ_TYPE STREQUAL "EXECUTABLE") |
| add_executable(${PROJ_NAME} ${PROJ_SRC}) |
| endif() |
| |
| if((PROJ_TYPE STREQUAL "SHARED") OR (PROJ_TYPE STREQUAL "EXECUTABLE")) |
| if(PROJ_TYPE STREQUAL "SHARED") |
| set(LINK_MODE PRIVATE) |
| else() |
| set(LINK_MODE PUBLIC) |
| endif() |
| target_link_libraries(${PROJ_NAME} "${LINK_MODE}" ${PROJ_LIBS}) |
| endif() |
| endfunction(ms_add_project) |
| |
| |
| # Parameters: |
| # - MY_PROJ_TYPE |
| # - MY_PROJ_NAME |
| # - MY_SRC_SEARCH_MODE |
| # Search mode for source files under current project directory |
| # "GLOB_RECURSE" for recursive search |
| # "GLOB" for non-recursive search |
| # - MY_PROJ_SRC |
| # - MY_PROJ_LIBS |
| # - MY_BINPLACES |
| # Extra files that will be installed |
| # - MY_BOOST_LIBS |
| function(dsn_add_project) |
| if((NOT DEFINED MY_PROJ_TYPE) OR (MY_PROJ_TYPE STREQUAL "")) |
| message(FATAL_ERROR "MY_PROJ_TYPE is empty.") |
| endif() |
| if((NOT DEFINED MY_PROJ_NAME) OR (MY_PROJ_NAME STREQUAL "")) |
| message(FATAL_ERROR "MY_PROJ_NAME is empty.") |
| endif() |
| if(NOT DEFINED MY_SRC_SEARCH_MODE) |
| set(MY_SRC_SEARCH_MODE "GLOB") |
| endif() |
| |
| # find source files from current directory |
| if(NOT DEFINED MY_PROJ_SRC) |
| set(MY_PROJ_SRC "") |
| endif() |
| set(TEMP_SRC "") |
| # We restrict the file suffix to keep our codes consistent. |
| file(${MY_SRC_SEARCH_MODE} TEMP_SRC |
| "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp" |
| "${CMAKE_CURRENT_SOURCE_DIR}/*.c" |
| ) |
| set(MY_PROJ_SRC ${TEMP_SRC} ${MY_PROJ_SRC}) |
| |
| if(NOT DEFINED MY_PROJ_LIBS) |
| set(MY_PROJ_LIBS "") |
| endif() |
| if(NOT DEFINED MY_BINPLACES) |
| set(MY_BINPLACES "") |
| endif() |
| |
| if(NOT DEFINED MY_BOOST_LIBS) |
| set(MY_BOOST_LIBS "") |
| endif() |
| |
| if((MY_PROJ_TYPE STREQUAL "SHARED") OR (MY_PROJ_TYPE STREQUAL "EXECUTABLE")) |
| set(MY_PROJ_LIBS ${MY_PROJ_LIBS} ${DEFAULT_THIRDPARTY_LIBS} ${MY_BOOST_LIBS} ${DSN_SYSTEM_LIBS}) |
| endif() |
| ms_add_project("${MY_PROJ_TYPE}" "${MY_PROJ_NAME}" "${MY_PROJ_SRC}" "${MY_PROJ_LIBS}" "${MY_BINPLACES}") |
| define_file_basename_for_sources(${MY_PROJ_NAME}) |
| endfunction(dsn_add_project) |
| |
| function(dsn_add_static_library) |
| set(MY_PROJ_TYPE "STATIC") |
| dsn_add_project() |
| dsn_install_library() |
| endfunction(dsn_add_static_library) |
| |
| function(dsn_add_shared_library) |
| set(MY_PROJ_TYPE "SHARED") |
| dsn_add_project() |
| dsn_install_library() |
| endfunction(dsn_add_shared_library) |
| |
| function(dsn_add_executable) |
| set(MY_PROJ_TYPE "EXECUTABLE") |
| dsn_add_project() |
| endfunction(dsn_add_executable) |
| |
| function(dsn_add_object) |
| set(MY_PROJ_TYPE "OBJECT") |
| dsn_add_project() |
| endfunction(dsn_add_object) |
| |
| function(dsn_add_test) |
| if(${BUILD_TEST}) |
| add_definitions(-DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=0) |
| set(MY_EXECUTABLE_IS_TEST TRUE) |
| dsn_add_executable() |
| |
| file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/bin") |
| execute_process(COMMAND ln -sf ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BINARY_DIR}/bin/${MY_PROJ_NAME}) |
| |
| # copy the extra files together with the executable |
| if(NOT (MY_BINPLACES STREQUAL "")) |
| foreach(BF ${MY_BINPLACES}) |
| FILE(COPY ${BF} DESTINATION "${CMAKE_BINARY_DIR}/bin/${MY_PROJ_NAME}") |
| endforeach() |
| endif() |
| endif() |
| endfunction() |
| |
| function(dsn_setup_compiler_flags) |
| if(CMAKE_BUILD_TYPE STREQUAL "Debug") |
| add_definitions(-DDSN_BUILD_TYPE=Debug) |
| add_definitions(-g) |
| else() |
| add_definitions(-g) |
| add_definitions(-O2) |
| add_definitions(-DDSN_BUILD_TYPE=Release) |
| endif() |
| cmake_host_system_information(RESULT BUILD_HOSTNAME QUERY HOSTNAME) |
| add_definitions(-DDSN_BUILD_HOSTNAME=${BUILD_HOSTNAME}) |
| |
| # We want access to the PRI* print format macros. |
| add_definitions(-D__STDC_FORMAT_MACROS) |
| |
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y" CACHE STRING "" FORCE) |
| |
| # -Wall: Enable all warnings. |
| add_compile_options(-Wall) |
| add_compile_options(-Werror) |
| # -Wno-sign-compare: suppress warnings for comparison between signed and unsigned integers |
| add_compile_options(-Wno-sign-compare) |
| add_compile_options(-Wno-strict-aliasing) |
| add_compile_options(-Wuninitialized) |
| add_compile_options(-Wno-unused-result) |
| add_compile_options(-Wno-unused-variable) |
| add_compile_options(-Wno-deprecated-declarations) |
| add_compile_options(-Wno-inconsistent-missing-override) |
| add_compile_options(-Wno-attributes) |
| # -fno-omit-frame-pointer |
| # use frame pointers to allow simple stack frame walking for backtraces. |
| # This has a small perf hit but worth it for the ability to profile in production |
| add_compile_options( -fno-omit-frame-pointer) |
| # -Wno-deprecated-register |
| # kbr5.h uses the legacy 'register' keyword. |
| add_compile_options(-Wno-deprecated-register) |
| # -Wno-implicit-float-conversion |
| # Poco/Dynamic/VarHolder.h uses 'unsigned long' to 'float' conversion |
| add_compile_options(-Wno-implicit-float-conversion) |
| |
| find_program(CCACHE_FOUND ccache) |
| if(CCACHE_FOUND) |
| set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) |
| set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) |
| if ("${COMPILER_FAMILY}" STREQUAL "clang") |
| add_compile_options(-Qunused-arguments) |
| endif() |
| message(STATUS "use ccache to speed up compilation") |
| endif(CCACHE_FOUND) |
| |
| # add sanitizer check |
| if(DEFINED SANITIZER) |
| if(NOT (("${COMPILER_FAMILY}" STREQUAL "clang") OR |
| ("${COMPILER_FAMILY}" STREQUAL "gcc" AND "${COMPILER_VERSION}" VERSION_GREATER "5.4.0"))) |
| message(SEND_ERROR "Cannot use sanitizer without clang or gcc >= 5.4.0") |
| endif() |
| |
| message(STATUS "Running cmake with sanitizer=${SANITIZER}") |
| set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=${SANITIZER}" CACHE STRING "" FORCE) |
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=${SANITIZER}" CACHE STRING "" FORCE) |
| endif() |
| |
| set(CMAKE_EXE_LINKER_FLAGS |
| "${CMAKE_EXE_LINKER_FLAGS} -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free" |
| CACHE |
| STRING |
| "" |
| FORCE) |
| set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free" |
| CACHE |
| STRING |
| "" |
| FORCE) |
| endfunction(dsn_setup_compiler_flags) |
| |
| # find necessary system libs |
| function(dsn_setup_system_libs) |
| find_package(Threads REQUIRED) |
| |
| if(CMAKE_SIZEOF_VOID_P EQUAL 8) |
| set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS ON) |
| message(STATUS "FIND_LIBRARY_USE_LIB64_PATHS = ON") |
| endif() |
| |
| set(DSN_SYSTEM_LIBS "") |
| |
| if (NOT APPLE) |
| find_package(RT REQUIRED) |
| set(DSN_SYSTEM_LIBS ${DSN_SYSTEM_LIBS} ${RT_LIBRARIES}) |
| endif() |
| |
| find_package(DL REQUIRED) |
| set(DSN_SYSTEM_LIBS ${DSN_SYSTEM_LIBS} ${DL_LIBRARIES}) |
| |
| # for md5 calculation |
| find_package(OpenSSL REQUIRED) |
| set(DSN_SYSTEM_LIBS ${DSN_SYSTEM_LIBS} ${OPENSSL_CRYPTO_LIBRARY}) |
| |
| if (NOT APPLE) |
| if(ENABLE_GPERF) |
| set(DSN_SYSTEM_LIBS ${DSN_SYSTEM_LIBS} tcmalloc_and_profiler) |
| add_definitions(-DDSN_ENABLE_GPERF) |
| endif() |
| endif() |
| |
| if(USE_JEMALLOC) |
| find_package(Jemalloc REQUIRED) |
| # also use cpu profiler provided by gperftools |
| set(DSN_SYSTEM_LIBS ${DSN_SYSTEM_LIBS} JeMalloc::JeMalloc profiler) |
| add_definitions(-DDSN_USE_JEMALLOC) |
| endif() |
| |
| set(DSN_SYSTEM_LIBS |
| ${DSN_SYSTEM_LIBS} |
| ${CMAKE_THREAD_LIBS_INIT} # the thread library found by FindThreads |
| CACHE STRING "rDSN system libs" FORCE |
| ) |
| endfunction(dsn_setup_system_libs) |
| |
| function(dsn_setup_include_path)#TODO(huangwei5): remove this |
| include_directories(${THIRDPARTY_INSTALL_DIR}/include) |
| endfunction(dsn_setup_include_path) |
| |
| function(dsn_setup_thirdparty_libs) |
| set(Boost_USE_MULTITHREADED ON) |
| set(Boost_USE_STATIC_LIBS OFF) |
| set(Boost_USE_STATIC_RUNTIME OFF) |
| set(BOOST_ROOT ${THIRDPARTY_INSTALL_DIR}) |
| set(Boost_NO_SYSTEM_PATHS ON) |
| set(Boost_NO_BOOST_CMAKE ON) |
| |
| set(CMAKE_PREFIX_PATH ${THIRDPARTY_INSTALL_DIR};${CMAKE_PREFIX_PATH}) |
| message(STATUS "CMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}") |
| find_package(Boost COMPONENTS system filesystem regex REQUIRED) |
| include_directories(${Boost_INCLUDE_DIRS}) |
| |
| find_library(THRIFT_LIB NAMES libthrift.a PATHS ${THIRDPARTY_INSTALL_DIR}/lib NO_DEFAULT_PATH) |
| if(NOT THRIFT_LIB) |
| message(FATAL_ERROR "thrift library not found in ${THIRDPARTY_INSTALL_DIR}/lib") |
| endif() |
| find_package(fmt REQUIRED) |
| set(DEFAULT_THIRDPARTY_LIBS ${THRIFT_LIB} fmt::fmt CACHE STRING "default thirdparty libs" FORCE) |
| |
| # rocksdb |
| file(GLOB ROCKSDB_DEPENDS_MODULE_PATH ${THIRDPARTY_ROOT}/build/Source/rocksdb/cmake/modules) |
| if(NOT ROCKSDB_DEPENDS_MODULE_PATH) |
| message(WARNING "Cannot find RocksDB depends cmake modules path, might not find snappy, zstd, lz4") |
| endif() |
| list(APPEND CMAKE_MODULE_PATH "${ROCKSDB_DEPENDS_MODULE_PATH}") |
| find_package(snappy) |
| find_package(zstd) |
| find_package(lz4) |
| if(USE_JEMALLOC) |
| find_package(Jemalloc REQUIRED) |
| endif() |
| find_package(RocksDB REQUIRED) |
| |
| # libhdfs |
| find_package(JNI REQUIRED) |
| message (STATUS "JAVA_JVM_LIBRARY=${JAVA_JVM_LIBRARY}") |
| link_libraries(${JAVA_JVM_LIBRARY}) |
| |
| link_directories(${THIRDPARTY_INSTALL_DIR}/lib) |
| if (NOT APPLE) |
| link_directories(${THIRDPARTY_INSTALL_DIR}/lib64) |
| endif() |
| |
| if (APPLE) |
| include_directories(SYSTEM ${MACOS_OPENSSL_ROOT_DIR}/include) |
| link_directories(${MACOS_OPENSSL_ROOT_DIR}/lib) |
| message (STATUS "MACOS_OPENSSL_ROOT_DIR: ${MACOS_OPENSSL_ROOT_DIR}") |
| endif() |
| endfunction(dsn_setup_thirdparty_libs) |
| |
| function(dsn_common_setup) |
| if(NOT (UNIX)) |
| message(FATAL_ERROR "Only Unix are supported.") |
| endif() |
| |
| if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) |
| message(FATAL_ERROR "In-source builds are not allowed.") |
| endif() |
| |
| find_program(CCACHE "ccache") |
| if(CCACHE) |
| set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE}) |
| set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE}) |
| message(STATUS "CCACHE: ${CCACHE}") |
| |
| set(ENV{CCACHE_COMPRESS} "true") |
| set(ENV{CCACHE_COMPRESSLEVEL} "6") |
| set(ENV{CCACHE_MAXSIZE} "1024M") |
| endif(CCACHE) |
| |
| if(NOT DEFINED DSN_BUILD_RUNTIME) |
| set(DSN_BUILD_RUNTIME FALSE) |
| endif() |
| |
| set(BUILD_SHARED_LIBS OFF) |
| |
| include(CheckCXXCompilerFlag) |
| CHECK_CXX_COMPILER_FLAG("-std=c++1y" COMPILER_SUPPORTS_CXX1Y) |
| if(NOT ${COMPILER_SUPPORTS_CXX1Y}) |
| message(FATAL_ERROR "You need a compiler with C++1y support.") |
| endif() |
| |
| dsn_setup_system_libs() |
| dsn_setup_compiler_flags() |
| dsn_setup_include_path() |
| dsn_setup_thirdparty_libs() |
| |
| include(ThriftUtils) |
| |
| endfunction(dsn_common_setup) |