# Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # The following only applies to changes made to this file as part of YugaByte development. # # Portions Copyright (c) YugaByte, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except # in compliance with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software distributed under the License # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express # or implied. See the License for the specific language governing permissions and limitations # under the License. # # Require cmake that includes FindICU module (https://cmake.org/cmake/help/v3.7/release/3.7.html) cmake_minimum_required(VERSION 3.7.0) project(YugabyteDB) if("$CACHE{YB_PCH_ON}" STREQUAL "") if("$ENV{YB_USE_PCH}" STREQUAL "1") set(YB_USE_PCH ON) else() set(YB_USE_PCH OFF) endif() set(YB_PCH_ON ${YB_USE_PCH} CACHE BOOL "Whether to use precompiled headers") endif() message("-- CMAKE_SYSTEM_INFO_FILE: ${CMAKE_SYSTEM_INFO_FILE}") message("-- CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}") message("-- CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}") message("-- CMAKE_SYSTEM: ${CMAKE_SYSTEM}") message("-- CMAKE_VERSION: ${CMAKE_VERSION}") message("-- PRECOMPILED HEADERS: ${YB_PCH_ON}") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake_modules") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake_standard_modules") include(YugabyteFunctions) yb_initialize_constants() include(YugabyteTesting) ADD_CXX_FLAGS("-Werror") ADD_CXX_FLAGS("-fno-strict-aliasing -Wall") if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)$") # Certain platforms such as ARM do not use signed chars by default # which causes issues with certain bounds checks. ADD_CXX_FLAGS("-fsigned-char") # Turn off fp-contract on aarch64 to avoid multiply-add operation result difference. ADD_CXX_FLAGS("-ffp-contract=off") elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") ADD_CXX_FLAGS("-msse4.2") else() message(FATAL_ERROR "Unsupported CPU architecture: ${CMAKE_SYSTEM_PROCESSOR}") endif() if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") # Optimize for Graviton on Linux/aarch64 (not mac/arm64) ADD_CXX_FLAGS("-march=armv8.2-a+fp16+rcpc+dotprod+crypto") ADD_CXX_FLAGS("-mtune=neoverse-n1") ADD_CXX_FLAGS("-mno-outline-atomics") endif() if (NOT "$ENV{YB_TARGET_ARCH}" STREQUAL "" AND NOT "$ENV{YB_TARGET_ARCH}" STREQUAL "${CMAKE_SYSTEM_PROCESSOR}") message(FATAL_ERROR "YB_TARGET_ARCH is set to $ENV{YB_TARGET_ARCH} but CMAKE_SYSTEM_PROCESSOR " "is ${CMAKE_SYSTEM_PROCESSOR}.") endif() set(ENV{YB_TARGET_ARCH} "${CMAKE_SYSTEM_PROCESSOR}") ADD_CXX_FLAGS("-Winvalid-pch") ADD_CXX_FLAGS("-pthread -DBOOST_BIND_NO_PLACEHOLDERS") ADD_LINKER_FLAGS("-pthread") if (NOT APPLE) ADD_CXX_FLAGS("-DBOOST_UUID_RANDOM_PROVIDER_FORCE_POSIX") endif() ADD_CXX_FLAGS("-DROCKSDB_PLATFORM_POSIX") ADD_CXX_FLAGS("-DBOOST_ERROR_CODE_HEADER_ONLY") # CMake's INTERNAL type of cache variables implies FORCE, overwriting existing entries. # https://cmake.org/cmake/help/latest/command/set.html set(YB_NUM_TESTS "0" CACHE INTERNAL "Number of tests") set(YB_NUM_INCLUDED_TESTS "0" CACHE INTERNAL "Number of included tests") set(YB_NUM_EXECUTABLES "0" CACHE INTERNAL "Number of executables") set(YB_NUM_INCLUDED_EXECUTABLES "0" CACHE INTERNAL "Number of included executables") set(YB_ALL_DEPS "" CACHE INTERNAL "All dependencies") # This is used to let the add_executable wrapper know if we're adding a test. set(YB_ADDING_TEST_EXECUTABLE "FALSE" CACHE INTERNAL "") yb_disable_tests_if_necessary() parse_build_root_basename() if("${YB_BUILD_TYPE}" STREQUAL "") message(FATAL_ERROR "YB_BUILD_TYPE still not set after parse_build_root_basename") endif() message("YB_BUILD_TYPE: ${YB_BUILD_TYPE}") message("CMAKE_MAKE_PROGRAM: ${CMAKE_MAKE_PROGRAM}") # CMAKE_LINK_DEPENDS_NO_SHARED prevents prevent re-linking dependents of a shared library when it # is re-linked. Enabling the optimized behavior by default, and allowing to customize it with the # YB_CMAKE_LINK_DEPENDS_NO_SHARED environment variable. if (NOT "$ENV{YB_CMAKE_LINK_DEPENDS_NO_SHARED}" STREQUAL "") message( "Setting CMAKE_LINK_DEPENDS_NO_SHARED to '$ENV{YB_CMAKE_LINK_DEPENDS_NO_SHARED}' " "based on the YB_CMAKE_LINK_DEPENDS_NO_SHARED environment variable.") set(CMAKE_LINK_DEPENDS_NO_SHARED $ENV{YB_CMAKE_LINK_DEPENDS_NO_SHARED}) else() set(CMAKE_LINK_DEPENDS_NO_SHARED 1) endif() set(YB_FILTERING_TARGETS FALSE) if (NOT "${YB_TEST_FILTER_RE}" STREQUAL "" OR NOT "${YB_EXECUTABLE_FILTER_RE}" STREQUAL "") set(YB_FILTERING_TARGETS TRUE) endif() set(YB_SRC_ROOT "${CMAKE_CURRENT_SOURCE_DIR}") message("YB_SRC_ROOT: ${YB_SRC_ROOT}") set(YB_THIRDPARTY_DIR "$ENV{YB_THIRDPARTY_DIR}") if("${YB_THIRDPARTY_DIR}" STREQUAL "") if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/thirdparty_path.txt") file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/thirdparty_path.txt" YB_THIRDPARTY_DIR) else() set(YB_THIRDPARTY_DIR "${YB_SRC_ROOT}/thirdparty") endif() set(ENV{YB_THIRDPARTY_DIR} "${YB_THIRDPARTY_DIR}") endif() message("YB_THIRDPARTY_DIR: ${YB_THIRDPARTY_DIR}") set(YB_BUILD_ROOT "${CMAKE_CURRENT_BINARY_DIR}") set(ENV{YB_BUILD_ROOT} "${YB_BUILD_ROOT}") get_filename_component(YB_BUILD_ROOT_PARENT "${YB_BUILD_ROOT}" DIRECTORY) message("YB_BUILD_ROOT: ${YB_BUILD_ROOT}") message("YB_TARGET_ARCH: $ENV{YB_TARGET_ARCH}") DETECT_NUMBER_OF_PROCESSORS() # Detect the shared library suffix on this platform set(YB_STATIC_LIBRARY_SUFFIX ".a") if(APPLE) set(YB_SHARED_LIBRARY_SUFFIX ".dylib") else() set(YB_SHARED_LIBRARY_SUFFIX ".so") endif() message("Using shared library suffix '${YB_SHARED_LIBRARY_SUFFIX}'.") message("CMAKE_C_COMPILER=${CMAKE_C_COMPILER}") CHECK_YB_COMPILER_PATH(${CMAKE_C_COMPILER}) message("CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}") CHECK_YB_COMPILER_PATH(${CMAKE_CXX_COMPILER}) add_latest_symlink_target() add_custom_target(dummy_target ALL COMMAND cat /dev/null COMMENT "Dummy target for dependency resolution testing") include(CMakeParseArguments) # Allow "make install" to not depend on all targets. # # Must be declared in the top-level CMakeLists.txt. set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY true) # ------------------------------------------------------------------------------------------------- # Decide whether we will be rebuilding third-party dependencies. # ------------------------------------------------------------------------------------------------- set(REBUILD_THIRDPARTY TRUE) # Also allow specifying -DNO_REBUILD_THIRDPARTY, because CLion does not always pass user-specified # environment variables correctly. if ((NOT "$ENV{NO_REBUILD_THIRDPARTY}" STREQUAL "") OR ("${YB_NO_REBUILD_THIRDPARTY}" STREQUAL "1") OR (NOT "${YB_THIRDPARTY_DIR}" STREQUAL "${YB_SRC_ROOT}/thirdparty")) message("Decided that we should not rebuild third-party dependencies. Criteria: " "NO_REBUILD_THIRDPARTY env var: '$ENV{NO_REBUILD_THIRDPARTY}', " "YB_NO_REBUILD_THIRDPARTY CMake var: '${YB_NO_REBUILD_THIRDPARTY}', " "YB_THIRDPARTY_DIR: ${YB_THIRDPARTY_DIR}.") set(REBUILD_THIRDPARTY FALSE) endif() # ------------------------------------------------------------------------------------------------- include(CompilerInfo) # This helps find the right third-party build directory. if ("${YB_BUILD_TYPE}" MATCHES "^(asan|tsan)$") set(THIRDPARTY_INSTRUMENTATION_TYPE "${YB_BUILD_TYPE}") elseif (IS_CLANG) set(THIRDPARTY_INSTRUMENTATION_TYPE "uninstrumented") elseif (IS_GCC) set(THIRDPARTY_INSTRUMENTATION_TYPE "uninstrumented") else() message(FATAL_ERROR "Unknown compiler family: '${COMPILER_FAMILY}'.") endif() message("THIRDPARTY_INSTRUMENTATION_TYPE=${THIRDPARTY_INSTRUMENTATION_TYPE}") # Make sure third-party dependency is up-to-date. # TODO: do not invoke this step as part of the build. Always invoke it separately. if (REBUILD_THIRDPARTY) set(BUILD_THIRDPARTY_ARGS --build-type ${THIRDPARTY_INSTRUMENTATION_TYPE}) message("Invoking build_thirdparty.sh with these arguments: ${BUILD_THIRDPARTY_ARGS}") execute_process( COMMAND ${YB_SRC_ROOT}/build-support/invoke_thirdparty_build.sh ${BUILD_THIRDPARTY_ARGS} RESULT_VARIABLE THIRDPARTY_SCRIPT_RESULT) if (NOT (${THIRDPARTY_SCRIPT_RESULT} EQUAL 0)) message(FATAL_ERROR "Thirdparty was built unsuccessfully, terminating.") endif() else() message("Skipping the third-party build (reasons logged earlier).") endif() if(NOT INCLUDE_COMPILER_INFO_EARLY) message("Including the CompilerInfo module after we have considered building third-party " "dependencies.") include(CompilerInfo) endif() # Generate a compile_commands.json "compilation database" file. # See http://clang.llvm.org/docs/JSONCompilationDatabase.html if (CMAKE_EXPORT_COMPILE_COMMANDS) message("CMAKE_EXPORT_COMPILE_COMMANDS is already enabled, will export compile_commands.json.") elseif ("$ENV{YB_EXPORT_COMPILE_COMMANDS}" STREQUAL "1") message("The YB_EXPORT_COMPILE_COMMANDS environment variable is set to 1, will export " "compile_commands.json.") set(CMAKE_EXPORT_COMPILE_COMMANDS ON) elseif ("$ENV{YB_RUN_AFFECTED_TESTS_ONLY}" STREQUAL "1") message("YB_RUN_AFFECTED_TESTS_ONLY is set to 1, will export compile_commands.json.") set(CMAKE_EXPORT_COMPILE_COMMANDS ON) else() message("CMake will not export the compilation database") endif() # ------------------------------------------------------------------------------------------------- # Build type (debug, release, fastdebug, etc.) # ------------------------------------------------------------------------------------------------- # If no build type is specified, default to debug builds if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Debug) endif(NOT CMAKE_BUILD_TYPE) string (TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE) # Alias RELEASE as RELWITHDEBINFO and MINSIZEREL. These are common CMake # release type names and this provides compatibility with the CLion IDE. if ("${CMAKE_BUILD_TYPE}" STREQUAL "RELWITHDEBINFO" OR "${CMAKE_BUILD_TYPE}" STREQUAL "MINSIZEREL") set(CMAKE_BUILD_TYPE RELEASE) endif() VALIDATE_COMPILER_TYPE() DETECT_BREW() enable_lto_if_needed() message("Using COMPILER_FAMILY=${COMPILER_FAMILY}") if (NOT APPLE AND "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") # To enable 16-byte atomics support we should specify appropriate architecture. ADD_CXX_FLAGS("-march=ivybridge") ADD_CXX_FLAGS("-mcx16") endif() # Include compiler type and version in the compiler command line so that binaries built by different # versions of the compiler will have different keys in ccache. ADD_CXX_FLAGS("-DYB_COMPILER_TYPE=$ENV{YB_COMPILER_TYPE}") ADD_CXX_FLAGS("-DYB_COMPILER_VERSION=${COMPILER_VERSION}") ADD_CXX_FLAGS("-DROCKSDB_LIB_IO_POSIX") ADD_CXX_FLAGS("-DSNAPPY") ADD_CXX_FLAGS("-DLZ4") ADD_CXX_FLAGS("-DZLIB") ############################################################ # Compiler flags ############################################################ if(NOT APPLE AND "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") # The following flags are required to not assume the presence of too many CPU features so that the # code built can run on many platforms. For example, support building on c4.xlarge in AWS (dev # servers) and running on c3.xlarge (flash-based cluster machines). There are a couple more flags # (-mno-abm and -mno-movbe) that are not recognized by some clang versions we are using, so they # are being added in the gcc-specific section below. We have also found that these flags don't # work on Mac OS X, so we're not using them there. ADD_CXX_FLAGS("-mno-avx -mno-bmi -mno-bmi2 -mno-fma") endif() # We want access to the PRI* print format macros. ADD_CXX_FLAGS("-D__STDC_FORMAT_MACROS") # Do not warn about uses of deprecated declarations. RocksDB has a few instances of those. ADD_CXX_FLAGS("-Wno-deprecated-declarations") ADD_CXX_FLAGS("-DGFLAGS=gflags") # Don't allow virtual classes with non-virtual destructors. ADD_CXX_FLAGS("-Wnon-virtual-dtor") # Flags common to gcc and clang. ADD_CXX_FLAGS("-Werror=enum-compare") ADD_CXX_FLAGS("-Werror=reorder") ADD_CXX_FLAGS("-Werror=switch") ADD_CXX_FLAGS("-Werror=return-type") ADD_CXX_FLAGS("-Werror=non-virtual-dtor") if(IS_CLANG) ADD_CXX_FLAGS("-Werror=string-plus-int") ADD_CXX_FLAGS("-Werror=return-stack-address") ADD_CXX_FLAGS("-Werror=implicit-fallthrough") if("${COMPILER_VERSION}" VERSION_GREATER_EQUAL "11.0.0") # Clang versions earlier than 11 cannot correctly handle unique_lock with manual # locking/unlocking. ADD_CXX_FLAGS("-D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS") ADD_CXX_FLAGS("-Wthread-safety-analysis") endif() if("$ENV{YB_ENABLE_STATIC_ANALYZER}" STREQUAL "1") if(APPLE) message("YB_ENABLE_STATIC_ANALYZER is set to 1, but we are not running the static analyzer" " on macOS yet") else() message("YB_ENABLE_STATIC_ANALYZER is set to 1, enabling Clang static analyzer") include(yb_clang_analyzer) message("clang_analyzer_flags=${clang_analyzer_flags}") ADD_CXX_FLAGS("${clang_analyzer_flags}") endif() else() message("YB_ENABLE_STATIC_ANALYZER is not set to 1, not enabling Clang static analyzer") endif() ADD_CXX_FLAGS("-Wshorten-64-to-32") endif() if(USING_LINUXBREW AND IS_CLANG) # We are only using Clang with Linuxbrew. We never use Linuxbrew GCC 5 anymore, it is too old. ADD_LINKER_FLAGS("-Wl,--dynamic-linker=${LINUXBREW_LIB_DIR}/ld.so") ADD_LINKER_FLAGS("--gcc-toolchain=${LINUXBREW_DIR}") endif() if(IS_GCC) # For now code relies on fact that all libraries will be linked to binary (for using FLAGS_*) # This flag is enabled implicitly on centos but not on ubuntu # TODO: Subtitute it with '-as-needed' instead to avoid linking with unused library (issue #1495) # for reducing pocess start time ADD_LINKER_FLAGS("-Wl,-no-as-needed") if ("${COMPILER_VERSION}" MATCHES "^11[.].*$") # To silence these spurious warnings: # https://gist.githubusercontent.com/mbautin/60c7fb897a92b998a111ff38429a1158/raw # https://gist.githubusercontent.com/mbautin/56b95b7a6816ccdf77eaa60f53a7d3ef/raw ADD_CXX_FLAGS("-Wno-array-bounds") ADD_CXX_FLAGS("-Wno-stringop-overflow") ADD_CXX_FLAGS("-Wno-stringop-overread") endif() endif() if(USING_LINUXBREW) # This is needed for finding correct versions of Flex, Bison, and other tools. set(CMAKE_PREFIX_PATH "${LINUXBREW_DIR}" ${CMAKE_PREFIX_PATH}) endif() # For both RocksDB and YugaByte code, we need to set the OS flag on Mac. Some code in RocksDB also # distinguishes further into BSD vs everything else, but we probably do not care further. if(APPLE) ADD_CXX_FLAGS("-DOS_MACOSX") elseif(NOT "${YB_BUILD_TYPE}" MATCHES "^(asan|tsan)$") message("Specifying linker flags to not allow any undefined symbols") ADD_LINKER_FLAGS("-Wl,--no-undefined -Wl,--no-allow-shlib-undefined") else() message("Not specifying linker flags to not allow any undefined symbols: this is ASAN/TSAN") endif() # compiler flags for different build types (run 'cmake -DCMAKE_BUILD_TYPE=<type> .') # For all builds: # For CMAKE_BUILD_TYPE=Debug # -ggdb: Enable gdb debugging # For CMAKE_BUILD_TYPE=FastDebug # Same as DEBUG, except with some optimizations on. # For CMAKE_BUILD_TYPE=Release # -O3: Enable all compiler optimizations # -g: Enable symbols for profiler tools (TODO: remove for shipping) # -DNDEBUG: Turn off dchecks/asserts/debug only code. # -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 # For profile guided optimization (PGO) builds, in addition to the flags for release builds: # 1. Build first with CMAKE_BUILD_TYPE_PROFILE_GEN: # -fprofile-generate: Indicates compiler should insert profile guided optimization events # 2. Run the benchmarks (generates *.gcda profiling data). # 3. Build again with CMAKE_BUILD_TYPE_PROFILE_BUILD # -fprofile-use: Compiler will use the profile outputs for optimizations set(CXX_FLAGS_DEBUG "-ggdb") set(CXX_FLAGS_FASTDEBUG "-ggdb -O1 -fno-omit-frame-pointer -DFASTDEBUG") set(CXX_FLAGS_RELEASE "-O3 -g -DNDEBUG -fno-omit-frame-pointer") # Nullify CMake's predefined flags since we are handling different build types on our own. # Without this change CMake will add flags from these variables and # optimization level will be changed because in case of multiple -O flags gcc uses the last one. set(CMAKE_CXX_FLAGS_DEBUG "") set(CMAKE_CXX_FLAGS_RELEASE "") set(CXX_FLAGS_PROFILE_GEN "${CXX_FLAGS_RELEASE} -fprofile-generate") set(CXX_FLAGS_PROFILE_BUILD "${CXX_FLAGS_RELEASE} -fprofile-use") set(CLANG_GCC_TOOLCHAIN "") if(IS_CLANG AND NOT APPLE AND USING_LINUXBREW) set(CLANG_GCC_TOOLCHAIN "${LINUXBREW_DIR}") endif() # Set compile flags based on the build type. message("Configured for ${CMAKE_BUILD_TYPE} build " "(set with cmake -DCMAKE_BUILD_TYPE={release,debug,...})") if ("${CMAKE_BUILD_TYPE}" STREQUAL "DEBUG") ADD_CXX_FLAGS("${CXX_FLAGS_DEBUG}") elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "FASTDEBUG") ADD_CXX_FLAGS("${CXX_FLAGS_FASTDEBUG}") # We specify RocksDB debug level that corresponds to the -O1 optimization level, the same as # the rest of YB code in the "fastdebug" mode (used for ASAN/TSAN). elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "RELEASE") ADD_CXX_FLAGS("${CXX_FLAGS_RELEASE}") elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "PROFILE_GEN") ADD_CXX_FLAGS("${CXX_FLAGS_PROFILE_GEN}") elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "PROFILE_BUILD") ADD_CXX_FLAGS("${CXX_FLAGS_PROFILE_BUILD}") else() message(FATAL_ERROR "Unknown build type: ${CMAKE_BUILD_TYPE}") endif () if (IS_CLANG) # Using Clang with ccache causes a bunch of spurious warnings that are # purportedly fixed in the next version of ccache. See the following for details: # # http://petereisentraut.blogspot.com/2011/05/ccache-and-clang.html # http://petereisentraut.blogspot.com/2011/09/ccache-and-clang-part-2.html # Clang generates ambiguous member template warnings when calling the ev++ api. ADD_CXX_FLAGS("-Wno-ambiguous-member-template") # Emit warnings on unannotated fallthrough in switch statements. This applies to both YB and # RocksDB parts of the code. ADD_CXX_FLAGS("-Wimplicit-fallthrough") # Silence the "unused argument" warning. ADD_CXX_FLAGS("-Qunused-arguments") # Only hardcode -fcolor-diagnostics if stderr is opened on a terminal. Otherwise # the color codes show up as noisy artifacts. # # This test is imperfect because 'cmake' and 'make' can be run independently # (with different terminal options), and we're testing during the former. execute_process(COMMAND test -t 2 RESULT_VARIABLE YB_IS_TTY) if ((${YB_IS_TTY} EQUAL 0) AND (NOT ("$ENV{TERM}" STREQUAL "dumb"))) message("Running in a controlling terminal") ADD_CXX_FLAGS("-fcolor-diagnostics") else() message("Running without a controlling terminal or in a dumb terminal") endif() if ("${COMPILER_VERSION}" VERSION_GREATER_EQUAL "12.0.0" AND APPLE) ADD_CXX_FLAGS("-Wno-c++17-compat-mangling") endif() elseif(IS_GCC) if ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") ADD_CXX_FLAGS("-mno-abm -mno-movbe") endif() else() message(FATAL_ERROR "Unknown compiler family: ${COMPILER_FAMILY}") endif() set(YB_PREFIX_COMMON "${YB_THIRDPARTY_DIR}/installed/common") if(NOT APPLE AND IS_CLANG) YB_SETUP_CLANG() if ("${YB_BUILD_TYPE}" MATCHES "^(asan|tsan)$") YB_SETUP_SANITIZER() endif() endif() if (USING_LINUXBREW) include_directories(SYSTEM "${LINUXBREW_DIR}/include") endif() if (NOT IS_CLANG) ADD_LINKER_FLAGS("-latomic") endif() # Flag to enable clang undefined behavior sanitizer # We explicitly don't enable all of the sanitizer flags: # - disable 'vptr' because it currently crashes somewhere in boost::intrusive::list code # - disable 'alignment' because unaligned access is really OK on Nehalem and we do it # all over the place. if ("${YB_BUILD_TYPE}" STREQUAL "asan") if(NOT (IS_CLANG OR IS_GCC AND "${COMPILER_VERSION}" VERSION_GREATER "4.9")) message(SEND_ERROR "Cannot use UBSAN without clang or gcc >= 4.9") endif() set(CXX_NO_SANITIZE_FLAG "alignment") if(NOT APPLE) set(CXX_NO_SANITIZE_FLAG "${CXX_NO_SANITIZE_FLAG},vptr") ADD_CXX_FLAGS("-fsanitize=undefined") endif() ADD_CXX_FLAGS("-fno-sanitize-recover=all -fno-sanitize=${CXX_NO_SANITIZE_FLAG}") ADD_CXX_FLAGS("-fsanitize-recover=float-cast-overflow") endif () if ("${YB_BUILD_TYPE}" MATCHES "^(asan|tsan)$") # GCC 4.8 and 4.9 (latest as of this writing) don't allow you to specify a # sanitizer blacklist. if(IS_CLANG) # Require clang 3.4 or newer; clang 3.3 has issues with TSAN and pthread # symbol interception. if("${COMPILER_VERSION}" VERSION_LESS "3.4") message(SEND_ERROR "Must use clang 3.4 or newer to run a sanitizer build." " Try using clang from thirdparty/") endif() ADD_CXX_FLAGS("-fsanitize-blacklist=${BUILD_SUPPORT_DIR}/sanitize-blacklist.txt") else() message(WARNING "GCC does not support specifying a sanitizer blacklist. Known sanitizer " "check failures will not be suppressed.") endif() endif() set(BUILD_SHARED_LIBS ON) if ("${YB_BUILD_TYPE}" STREQUAL "prof_gen") ADD_CXX_FLAGS("-fprofile-instr-generate -DYB_PROFGEN") endif () if ("${YB_BUILD_TYPE}" STREQUAL "prof_use") if (NOT YB_PGO_DATA_PATH) message (SEND_ERROR "Pgo data path is not set.") endif() ADD_CXX_FLAGS("-fprofile-instr-use=${YB_PGO_DATA_PATH}") # Even with the fresh profile data we might get warnings like # warning: Function control flow change detected (hash mismatch) # [-Wbackend-plugin] # Silencing it for now. ADD_CXX_FLAGS("-Wno-backend-plugin") ADD_CXX_FLAGS("-Wno-profile-instr-unprofiled") ADD_CXX_FLAGS("-Wno-profile-instr-out-of-date") endif () # Position independent code is only necessary when producing shared objects. ADD_CXX_FLAGS(-fPIC) # where to put generated archives (.a files) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib") file(MAKE_DIRECTORY "${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}") # where to put generated libraries (.so files) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib") file(MAKE_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") # where to put generated binaries set(EXECUTABLE_OUTPUT_PATH "${YB_BUILD_ROOT}/bin") file(MAKE_DIRECTORY "${EXECUTABLE_OUTPUT_PATH}") # Generated sources always have higher priority than even the "ent" directory include files. include_directories(${CMAKE_CURRENT_BINARY_DIR}/src) include_directories(ent/src) include_directories(src) enable_testing() if (USING_LINUXBREW) ADD_GLOBAL_RPATH_ENTRY_AND_LIB_DIR("${YB_BUILD_ROOT}/postgres/lib") ADD_GLOBAL_RPATH_ENTRY_AND_LIB_DIR("${LINUXBREW_LIB_DIR}") endif() ############################################################ # Dependencies ############################################################ function(ADD_THIRDPARTY_LIB LIB_NAME) set(options) set(one_value_args SHARED_LIB STATIC_LIB) set(multi_value_args DEPS) cmake_parse_arguments(ARG "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN}) if(ARG_UNPARSED_ARGUMENTS) message(SEND_ERROR "Error: unrecognized arguments: ${ARG_UNPARSED_ARGUMENTS}") endif() if(NOT ARG_SHARED_LIB) if(NOT ARG_STATIC_LIB) message(FATAL_ERROR "No static or shared library provided for ${LIB_NAME}") endif() add_library(${LIB_NAME} STATIC IMPORTED) set_target_properties(${LIB_NAME} PROPERTIES IMPORTED_LOCATION "${ARG_STATIC_LIB}") message("Added static library dependency ${LIB_NAME}: ${ARG_STATIC_LIB}") else() add_library(${LIB_NAME} SHARED IMPORTED) set_target_properties(${LIB_NAME} PROPERTIES IMPORTED_LOCATION "${ARG_SHARED_LIB}") message("Added shared library dependency ${LIB_NAME}: ${ARG_SHARED_LIB}") endif() if(ARG_DEPS) set_target_properties(${LIB_NAME} PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES "${ARG_DEPS}") endif() # Set up an "exported variant" for this thirdparty library (see "Visibility" # above). It's the same as the real target, just with an "_exported" suffix. # We prefer the static archive if it exists (as it's akin to an "internal" # library), but we'll settle for the shared object if we must. # # A shared object exported variant will force any "leaf" library that # transitively depends on it to also depend on it at runtime; this is # desirable for some libraries (e.g. cyrus_sasl). set(LIB_NAME_EXPORTED ${LIB_NAME}_exported) if(ARG_STATIC_LIB) add_library(${LIB_NAME_EXPORTED} STATIC IMPORTED) set_target_properties(${LIB_NAME_EXPORTED} PROPERTIES IMPORTED_LOCATION "${ARG_STATIC_LIB}") else() add_library(${LIB_NAME_EXPORTED} SHARED IMPORTED) set_target_properties(${LIB_NAME_EXPORTED} PROPERTIES IMPORTED_LOCATION "${ARG_SHARED_LIB}") endif() if(ARG_DEPS) set_target_properties(${LIB_NAME_EXPORTED} PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES "${ARG_DEPS}") endif() endfunction() # Look in thirdparty prefix paths before anywhere else for system dependencies. set(CMAKE_PREFIX_PATH ${YB_PREFIX_COMMON} ${CMAKE_PREFIX_PATH}) ADD_LINKER_FLAGS("-L${YB_PREFIX_COMMON}/lib") set(YB_THIRDPARTY_INSTALLED_DEPS_DIR "${YB_THIRDPARTY_DIR}/installed/${THIRDPARTY_INSTRUMENTATION_TYPE}") set(CMAKE_PREFIX_PATH ${YB_THIRDPARTY_INSTALLED_DEPS_DIR} ${CMAKE_PREFIX_PATH}) ADD_LINKER_FLAGS("-L${YB_THIRDPARTY_INSTALLED_DEPS_DIR}/lib") set(YB_THIRDPARTY_INSTALLED_DIR ${YB_PREFIX_COMMON}) # See thirdparty/yb_build_thirdparty_main.py for an explanation of differences between installed and # installed-deps. ADD_GLOBAL_RPATH_ENTRY("${YB_THIRDPARTY_INSTALLED_DIR}/lib") ADD_GLOBAL_RPATH_ENTRY("${YB_THIRDPARTY_INSTALLED_DEPS_DIR}/lib") # If we are using a non-default gcc or clang compiler, we need to add its library directory to # rpath. if(IS_GCC AND NOT "$ENV{YB_GCC_PREFIX}" STREQUAL "") # TODO: this works for the gcc 6.2.0 build on Linux, might be different on other platforms. ADD_GLOBAL_RPATH_ENTRY("$ENV{YB_GCC_PREFIX}/lib64") endif() if(IS_CLANG AND NOT "$ENV{YB_CLANG_PREFIX}" STREQUAL "") # TODO: this works for the Linux binary clang 3.9 package, might be different on Mac OS X. ADD_GLOBAL_RPATH_ENTRY("$ENV{YB_CLANG_PREFIX}/lib") endif() configure_macos_sdk() # ------------------------------------------------------------------------------------------------- include(YugabyteFindThirdParty) ############################################################ # Linker setup ############################################################ set(YB_MIN_TEST_LIBS yb_test_main yb_test_util ${YB_BASE_LIBS}) set(YB_TEST_LINK_LIBS ${YB_MIN_TEST_LIBS}) ############################################################ # Subdirectories ############################################################ # TODO(dmitry): Add YB_CMAKE_CXX_EXTRA_FLAGS to CMAKE_CXX_FLAGS when all source code will be # compatible with with these flags #9279 set(YB_CMAKE_CXX_EXTRA_FLAGS "-Wextra -Wno-unused-parameter") # For any C code, use the same flags as for C++. set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS}") # C++-only flags. ADD_CXX_FLAGS("-Werror=missing-field-initializers") if ((IS_GCC) AND ("${CMAKE_CXX_COMPILER_VERSION}" VERSION_GREATER_EQUAL "7.0")) # Used with GCC 7. ADD_CXX_FLAGS("-faligned-new") endif() # -Wsign-compare is enabled for C++ only for GCC with just -Wall, and enabled for both C and C++ # for GCC and Clang with -Wextra. Remove when -Wextra is enabled for all source code (#9279). if (IS_CLANG) ADD_CXX_FLAGS("-Wsign-compare") endif() string (REPLACE "-Werror=non-virtual-dtor" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS}) string (REPLACE "-Werror=reorder" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS}) string (REPLACE "-Wnon-virtual-dtor" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS}) string (REPLACE "-Woverloaded-virtual" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS}) message("CMAKE_C_FLAGS ${CMAKE_C_FLAGS}") set(CMAKE_CXX_STANDARD 20) if (IS_GCC AND "${COMPILER_VERSION}" VERSION_GREATER_EQUAL "8.0.0") # Remove after switching to C++17 ADD_CXX_FLAGS("-Wno-aligned-new") endif() set(CMAKE_CXX_STANDARD_REQUIRED ON) message("Linker flags for executables: ${CMAKE_EXE_LINKER_FLAGS}") # Define full paths to libpq and libyb_pgbackend shared libraries. These libraries are built as part # of building PostgreSQL. We need to declare these as by-products of running the PostgreSQL build # command, as well as wrap them into CMake targets so that other libraries and executables can # depend on them. set(LIBPQ_SHARED_LIB "${YB_BUILD_ROOT}/postgres/lib/libpq${YB_SHARED_LIBRARY_SUFFIX}") set(YB_PGBACKEND_SHARED_LIB "${YB_BUILD_ROOT}/postgres/lib/libyb_pgbackend${YB_SHARED_LIBRARY_SUFFIX}") # ------------------------------------------------------------------------------------------------- # Subdirectories # ------------------------------------------------------------------------------------------------- # PostgreSQL source code is not in src/yb so that we can grep non-PostgreSQL YB code easily. add_subdirectory(src/postgres) include_directories(${YB_BUILD_ROOT}/postgres/include) add_postgres_shared_library(pq "${LIBPQ_SHARED_LIB}") add_postgres_shared_library(yb_pgbackend "${YB_PGBACKEND_SHARED_LIB}") add_subdirectory(src/yb/rocksdb) add_subdirectory(src/yb/gutil) add_subdirectory(src/yb/util) add_subdirectory(src/yb/common) add_subdirectory(src/yb/encryption) add_subdirectory(src/yb/gen_yrpc) add_subdirectory(src/yb/fs) add_subdirectory(src/yb/server) add_subdirectory(src/yb/tablet) add_subdirectory(src/yb/bfql) add_subdirectory(src/yb/bfpg) add_subdirectory(src/yb/rpc) add_subdirectory(src/yb/tserver) add_subdirectory(src/yb/consensus) add_subdirectory(src/yb/master) add_subdirectory(src/yb/client) add_subdirectory(src/yb/integration-tests) add_subdirectory(src/yb/tools) add_subdirectory(src/yb/rocksutil) add_subdirectory(src/yb/docdb) add_subdirectory(src/yb/yql) add_subdirectory(src/yb/cdc) include("${YB_SRC_ROOT}/ent/CMakeLists.txt") # ------------------------------------------------------------------------------------------------ # Utilities for collecting the dependency graph # ------------------------------------------------------------------------------------------------ # We could not accumulate multiple lines in YB_ALL_DEPS due to a CMake bug with cache variables, # but we can write multiple lines in the output file. string(REPLACE "\\n" "\n" YB_ALL_DEPS_FINAL "${YB_ALL_DEPS}") # This file wlll contains dependencies in the following form, separated by newlines: # target: dep1;dep2;..;depN # The same target can appear on the left hand side of multiple such lines. file(WRITE "${YB_BUILD_ROOT}/yb_cmake_deps.txt" "${YB_ALL_DEPS_FINAL}") math(EXPR YB_NUM_EXCLUDED_TESTS "${YB_NUM_TESTS} - ${YB_NUM_INCLUDED_TESTS}") message("Total tests: ${YB_NUM_TESTS}, " "included: ${YB_NUM_INCLUDED_TESTS}, " "excluded: ${YB_NUM_EXCLUDED_TESTS}") if(NOT ${BUILD_TESTS} AND NOT ${YB_NUM_INCLUDED_TESTS} STREQUAL "1") message( FATAL_ERROR "BUILD_TESTS is not set, but we still added ${YB_NUM_INCLUDED_TESTS} tests" " (one test would be OK because we always add create_initial_sys_catalog_snapshot).") endif() math(EXPR YB_NUM_EXCLUDED_EXECUTABLES "${YB_NUM_EXECUTABLES} - ${YB_NUM_INCLUDED_EXECUTABLES}") message("Total non-test executables: ${YB_NUM_EXECUTABLES}, " "included: ${YB_NUM_INCLUDED_EXECUTABLES}, " "excluded: ${YB_NUM_EXCLUDED_EXECUTABLES}")