Skip to content

Commit

Permalink
[yugabyte#10920] Support build with Clang 12 and Linuxbrew
Browse files Browse the repository at this point in the history
Summary:
Support a build with Clang 12 and Linuxbrew. This is the same version of Linuxbrew that we have been using with GCC 5. The LLVM toolchain is not built for Linuxbrew but for the native OS, so we specify all libraries and include directories explicitly in order to build with Linuxbrew includes and libraries. The resulting package should have the same portability across target Linux distributions as the package we have been building with GCC 5.

This will allow us to drop support for GCC 5 and use a much newer compiler for our production release package.

Enhancing thirdparty_tool.py to allow using Linuxbrew-based packages built on a different OS, because they should not depend on the Linux distribution.

Relevant PR in yugabyte-db-thirdparty: yugabyte/yugabyte-db-thirdparty#95

Other changes:
- Removing automatic installation of Linuxbrew into `~/.linuxbrew-yb-build`. Our standard practice is to install it into a path like `/opt/yb-build/brew/linuxbrew-20181203T161736v9`.
- Remove unused constant SHARED_LINUXBREW_BUILDS_DIR.
- Do not use Ninja from the Linuxbrew directory.
- Activate the Python virtual environment early in the build-and-test.sh script used by Jenkins.
- Add a python_with_venv.sh script to simplify running Python commands with the build virtualenv.
- Simplify checking for Clang and GCC compiler families in CMake scripts (IS_CLANG and IS_GCC variables).
- Add type annotations dependency_graph.py and refactor it. Add it to codecheck.ini.
- Add a Python function arg_str_to_bool useful for creating user-friendly boolean arguments using argparse.

Test Plan:
Jenkins

Run the build in various configurations on CentOS 7, AlmaLinux 8, macOS, across x86_64 and ARM architectures.

Reviewers: steve.varnau, sergei

Reviewed By: sergei

Subscribers: ybase

Differential Revision: https://phabricator.dev.yugabyte.com/D14487
  • Loading branch information
mbautin committed Dec 30, 2021
1 parent ba8b9ea commit ce06510
Show file tree
Hide file tree
Showing 23 changed files with 1,165 additions and 754 deletions.
68 changes: 21 additions & 47 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ if("$ENV{YB_USE_PCH}" STREQUAL "1")
endif()
endif()
include(YugabyteFunctions)
yb_initialize_constants()
include(YugabyteTesting)

ADD_CXX_FLAGS("-Werror")
Expand Down Expand Up @@ -164,8 +165,6 @@ CHECK_YB_COMPILER_PATH(${CMAKE_C_COMPILER})
message("CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}")
CHECK_YB_COMPILER_PATH(${CMAKE_CXX_COMPILER})

set(BUILD_SUPPORT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/build-support)

# Provide a 'latest' symlink to this build directory if the "blessed" multi-build layout is
# detected:
#
Expand Down Expand Up @@ -227,36 +226,17 @@ endif()

INIT_COMPILER_TYPE_FROM_BUILD_ROOT()

# TODO: this is complicated by the fact that we are trying to build third-party dependencies here if
# necessary, and that the compiler is sometimes part of those third-party dependencies (e.g. Clang 7
# with the Linuxbrew-based setup). Therefore, we don't yet know the exact compiler version. If we
# know that we are not using a third-party setup where we build our own Clang, or if we are not
# planning to invoke the third-party dependency build from here, we include the CompilerInfo module
# early. We also always do that on macOS where we only use Clang.

set(INCLUDE_COMPILER_INFO_EARLY FALSE)
if(NOT "${YB_COMPILER_TYPE}" STREQUAL "clang" OR
NOT REBUILD_THIRDPARTY OR
APPLE)
set(INCLUDE_COMPILER_INFO_EARLY TRUE)
endif()
if(INCLUDE_COMPILER_INFO_EARLY)
message("Including the CompilerInfo module before determining the third-party instrumentation "
"type to use. Criteria: "
"REBUILD_THIRDPARTY=${REBUILD_THIRDPARTY}, "
"YB_COMPILER_TYPE=${YB_COMPILER_TYPE}.")
include(CompilerInfo)
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 ("${COMPILER_FAMILY}" STREQUAL "clang")
elseif (IS_CLANG)
set(THIRDPARTY_INSTRUMENTATION_TYPE "uninstrumented")
elseif ("${COMPILER_FAMILY}" STREQUAL "gcc")
elseif (IS_GCC)
set(THIRDPARTY_INSTRUMENTATION_TYPE "uninstrumented")
else()
message(FATAL_ERROR "Unknown or still undetermined compiler family: '${COMPILER_FAMILY}'.")
message(FATAL_ERROR "Unknown compiler family: '${COMPILER_FAMILY}'.")
endif()
message("THIRDPARTY_INSTRUMENTATION_TYPE=${THIRDPARTY_INSTRUMENTATION_TYPE}")

Expand Down Expand Up @@ -318,7 +298,6 @@ DETECT_BREW()

message("Using COMPILER_FAMILY=${COMPILER_FAMILY}")

# We can only use IS_CLANG after calling VALIDATE_COMPILER_TYPE.
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")
Expand Down Expand Up @@ -520,7 +499,7 @@ if (IS_CLANG)
if ("${COMPILER_VERSION}" VERSION_GREATER_EQUAL "12.0.0" AND APPLE)
ADD_CXX_FLAGS("-Wno-c++17-compat-mangling")
endif()
elseif("${COMPILER_FAMILY}" STREQUAL "gcc")
elseif(IS_GCC)
if ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64")
ADD_CXX_FLAGS("-mno-abm -mno-movbe")
endif()
Expand All @@ -530,15 +509,15 @@ endif()

set(YB_PREFIX_COMMON "${YB_THIRDPARTY_DIR}/installed/common")

# Flag to enable thread sanitizer (clang or gcc 4.8)
if ("${YB_BUILD_TYPE}" MATCHES "^(asan|tsan)$")
YB_SETUP_SANITIZER()
elseif (NOT APPLE AND IS_CLANG)
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)
include_directories(SYSTEM "${LINUXBREW_DIR}/include")
endif()

if (NOT IS_CLANG)
Expand All @@ -551,8 +530,8 @@ endif()
# - 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 ("${COMPILER_FAMILY}" STREQUAL "clang" OR
"${COMPILER_FAMILY}" STREQUAL "gcc" AND "${COMPILER_VERSION}" VERSION_GREATER "4.9"))
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")
Expand All @@ -567,7 +546,7 @@ 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("${COMPILER_FAMILY}" STREQUAL "clang")
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")
Expand Down Expand Up @@ -605,6 +584,11 @@ 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
############################################################
Expand Down Expand Up @@ -710,7 +694,7 @@ set(YB_CMAKE_CXX_EXTRA_FLAGS "-Wextra -Wno-unused-parameter")
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS}")

# C++-only flags.
if (("${COMPILER_FAMILY}" STREQUAL "gcc") AND
if ((IS_GCC) AND
("${CMAKE_CXX_COMPILER_VERSION}" VERSION_GREATER_EQUAL "7.0"))
# Used with GCC 7.
ADD_CXX_FLAGS("-faligned-new")
Expand All @@ -726,24 +710,14 @@ message("CMAKE_C_FLAGS ${CMAKE_C_FLAGS}")

set(CMAKE_CXX_STANDARD 14)

if ("${COMPILER_FAMILY}" STREQUAL "gcc" AND
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)

if (USING_LINUXBREW)
# We need to add the postgres library directory prior to /usr/lib64 specifically in order to avoid
# using the system libpq.
ADD_GLOBAL_RPATH_ENTRY_AND_LIB_DIR("${YB_BUILD_ROOT}/postgres/lib")

# Add the Linuxbrew library directory and the system library directory last.
ADD_GLOBAL_RPATH_ENTRY_AND_LIB_DIR("${LINUXBREW_LIB_DIR}")
ADD_GLOBAL_RPATH_ENTRY_AND_LIB_DIR("/usr/lib64")
endif()

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
Expand Down
94 changes: 56 additions & 38 deletions build-support/common-build-env-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#
set -euo pipefail

# shellcheck source=build-support/common-build-env.sh
. "${0%/*}/common-build-env.sh"

assert_equals() {
Expand Down Expand Up @@ -90,7 +91,7 @@ test_compiler_detection_by_jenkins_job_name() {
unset YB_COMPILER_TYPE
JOB_NAME="$jenkins_job_name"
set_compiler_type_based_on_jenkins_job_name
assert_equals "$expected_compiler_type" "$YB_COMPILER_TYPE"
assert_equals "$expected_compiler_type" "$YB_COMPILER_TYPE" "compiler type"
)
}

Expand Down Expand Up @@ -138,53 +139,70 @@ test_set_cmake_build_type_and_compiler_type() {
OSTYPE=$os_type
yb_fatal_quiet=true
set_cmake_build_type_and_compiler_type
assert_equals "$expected_cmake_build_type" "$cmake_build_type" "$test_case_details"
assert_equals "$expected_compiler_type" "$YB_COMPILER_TYPE" "$test_case_details"
assert_equals "$expected_cmake_build_type" "$cmake_build_type" "$test_case_details" \
"Note: comparing CMake build type."
assert_equals "$expected_compiler_type" "$YB_COMPILER_TYPE" "$test_case_details" \
"Note: comparing compiler type."
)
local exit_code=$?
set -e
assert_equals "$expected_exit_code" "$exit_code"
}

arch=$( uname -m )

# Parameters: build_type OSTYPE Compiler Expected Expected
# type build_type YB_COMPILER_
# preference TYPE

test_set_cmake_build_type_and_compiler_type asan darwin auto fastdebug clang 0
test_set_cmake_build_type_and_compiler_type asan darwin clang fastdebug clang 0
test_set_cmake_build_type_and_compiler_type asan darwin gcc N/A N/A 1
test_set_cmake_build_type_and_compiler_type asan linux-gnu auto fastdebug clang7 0
test_set_cmake_build_type_and_compiler_type asan linux-gnu clang7 fastdebug clang7 0
test_set_cmake_build_type_and_compiler_type asan linux-gnu gcc N/A N/A 1
test_set_cmake_build_type_and_compiler_type asan linux-gnu gcc8 fastdebug gcc8 0
test_set_cmake_build_type_and_compiler_type asan linux-gnu gcc9 fastdebug gcc9 0
test_set_cmake_build_type_and_compiler_type tsan linux-gnu auto fastdebug clang7 0
test_set_cmake_build_type_and_compiler_type tsan linux-gnu clang7 fastdebug clang7 0
test_set_cmake_build_type_and_compiler_type tsan linux-gnu gcc N/A N/A 1
test_set_cmake_build_type_and_compiler_type tsan linux-gnu gcc8 fastdebug gcc8 0
test_set_cmake_build_type_and_compiler_type tsan linux-gnu gcc9 fastdebug gcc9 0
test_set_cmake_build_type_and_compiler_type debug darwin auto debug clang 0
test_set_cmake_build_type_and_compiler_type debug darwin clang debug clang 0
test_set_cmake_build_type_and_compiler_type debug darwin gcc N/A N/A 1
test_set_cmake_build_type_and_compiler_type debug linux-gnu auto debug gcc 0
test_set_cmake_build_type_and_compiler_type debug linux-gnu clang debug clang 0
test_set_cmake_build_type_and_compiler_type debug linux-gnu gcc debug gcc 0
test_set_cmake_build_type_and_compiler_type debug linux-gnu gcc8 debug gcc8 0
test_set_cmake_build_type_and_compiler_type debug linux-gnu gcc9 debug gcc9 0
test_set_cmake_build_type_and_compiler_type FaStDeBuG darwin auto fastdebug clang 0
test_set_cmake_build_type_and_compiler_type FaStDeBuG darwin clang fastdebug clang 0
test_set_cmake_build_type_and_compiler_type FaStDeBuG darwin gcc N/A N/A 1
test_set_cmake_build_type_and_compiler_type FaStDeBuG linux-gnu auto fastdebug gcc 0
test_set_cmake_build_type_and_compiler_type FaStDeBuG linux-gnu clang fastdebug clang 0
test_set_cmake_build_type_and_compiler_type FaStDeBuG linux-gnu gcc fastdebug gcc 0
test_set_cmake_build_type_and_compiler_type release darwin auto release clang 0
test_set_cmake_build_type_and_compiler_type release darwin clang release clang 0
test_set_cmake_build_type_and_compiler_type release darwin gcc N/A N/A 1
test_set_cmake_build_type_and_compiler_type release linux-gnu auto release gcc 0
test_set_cmake_build_type_and_compiler_type release linux-gnu clang release clang 0
test_set_cmake_build_type_and_compiler_type release linux-gnu gcc release gcc 0
test_set_cmake_build_type_and_compiler_type release linux-gnu gcc8 release gcc8 0
test_set_cmake_build_type_and_compiler_type release linux-gnu gcc9 release gcc9 0
# The last parameter is expected exit code (0 or 1).

test_set_cmake_build_type_and_compiler_type asan darwin auto fastdebug clang 0
test_set_cmake_build_type_and_compiler_type asan darwin clang fastdebug clang 0
test_set_cmake_build_type_and_compiler_type asan darwin gcc N/A N/A 1
test_set_cmake_build_type_and_compiler_type asan linux-gnu clang7 fastdebug clang7 0
test_set_cmake_build_type_and_compiler_type asan linux-gnu gcc N/A N/A 1
test_set_cmake_build_type_and_compiler_type asan linux-gnu gcc8 N/A gcc8 1
test_set_cmake_build_type_and_compiler_type asan linux-gnu gcc9 N/A gcc9 1
test_set_cmake_build_type_and_compiler_type tsan linux-gnu auto fastdebug clang7 0
test_set_cmake_build_type_and_compiler_type tsan linux-gnu clang7 fastdebug clang7 0
test_set_cmake_build_type_and_compiler_type tsan linux-gnu gcc N/A N/A 1
test_set_cmake_build_type_and_compiler_type tsan linux-gnu gcc8 N/A gcc8 1
test_set_cmake_build_type_and_compiler_type tsan linux-gnu gcc9 N/A gcc9 1
test_set_cmake_build_type_and_compiler_type debug darwin auto debug clang 0
test_set_cmake_build_type_and_compiler_type debug darwin clang debug clang 0
test_set_cmake_build_type_and_compiler_type debug darwin gcc N/A N/A 1
test_set_cmake_build_type_and_compiler_type debug linux-gnu clang debug clang 0
test_set_cmake_build_type_and_compiler_type debug linux-gnu gcc debug gcc 0
test_set_cmake_build_type_and_compiler_type debug linux-gnu gcc8 debug gcc8 0
test_set_cmake_build_type_and_compiler_type debug linux-gnu gcc9 debug gcc9 0
test_set_cmake_build_type_and_compiler_type FaStDeBuG darwin auto fastdebug clang 0
test_set_cmake_build_type_and_compiler_type FaStDeBuG darwin clang fastdebug clang 0
test_set_cmake_build_type_and_compiler_type FaStDeBuG darwin gcc N/A N/A 1
test_set_cmake_build_type_and_compiler_type FaStDeBuG linux-gnu clang fastdebug clang 0
test_set_cmake_build_type_and_compiler_type FaStDeBuG linux-gnu gcc fastdebug gcc 0
test_set_cmake_build_type_and_compiler_type release darwin auto release clang 0
test_set_cmake_build_type_and_compiler_type release darwin clang release clang 0
test_set_cmake_build_type_and_compiler_type release darwin gcc N/A N/A 1
test_set_cmake_build_type_and_compiler_type release linux-gnu clang release clang 0
test_set_cmake_build_type_and_compiler_type release linux-gnu gcc release gcc 0
test_set_cmake_build_type_and_compiler_type release linux-gnu gcc8 release gcc8 0
test_set_cmake_build_type_and_compiler_type release linux-gnu gcc9 release gcc9 0

# TODO: use Clang 12 uniformly for all achitectures, and get rid of conditional checks here.
if [[ $arch == "x86_64" && $OSTYPE == linux* ]] && is_redhat_family; then
test_set_cmake_build_type_and_compiler_type asan linux-gnu auto fastdebug clang12 0
test_set_cmake_build_type_and_compiler_type debug linux-gnu auto debug clang12 0
test_set_cmake_build_type_and_compiler_type FaStDeBuG linux-gnu auto fastdebug clang12 0
test_set_cmake_build_type_and_compiler_type release linux-gnu auto release clang12 0
fi

if [[ $arch == "aarch64" && $OSTYPE == linux* ]]; then
test_set_cmake_build_type_and_compiler_type asan linux-gnu auto fastdebug clang11 0
test_set_cmake_build_type_and_compiler_type debug linux-gnu auto debug clang11 0
test_set_cmake_build_type_and_compiler_type FaStDeBuG linux-gnu auto fastdebug clang11 0
test_set_cmake_build_type_and_compiler_type release linux-gnu auto release clang11 0
fi

# -------------------------------------------------------------------------------------------------

Expand Down
Loading

0 comments on commit ce06510

Please sign in to comment.