Files
doris/env.sh
T
Mingyu Chen (Rayner)andClaude Code b41856ab7e [fix](build) Move the macOS toolchain to LLVM 22 so ASAN works on macOS 26.4+ (#68595)
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache/doris-website#4180 (the macOS build guide change that
goes with this PR)

Problem Summary:

**Context.**

On macOS the only entry point for the BE unit tests is `run-be-ut.sh`,
and it defaults to `BUILD_TYPE_UT=ASAN`. Since macOS 26.4 that default
cannot start a single process: every binary linked against llvm.org's
`libclang_rt.asan_osx_dynamic` deadlocks during runtime initialisation,
before `main()`. `env.sh` selects that same toolchain on macOS
(`llvm@20`), so a developer who follows the documented setup gets a
build that hangs rather than one that fails.

How the macOS toolchain gets chosen matters for the rest of this
description:

- **Selection.** `env.sh` writes `custom_env_mac.sh`, which puts `$(brew
--prefix)/opt/<formula>/bin` on `PATH` for every formula in its
`CELLARS` list. Unless `DORIS_CLANG_HOME` is already set, `env.sh` then
takes the first `clang` on `PATH` and derives `CC`/`CXX` from it.
- **Installation.** `CELLARS` only selects; it installs nothing.
Developers install Homebrew formulae by following the macOS build guide,
and each CI workflow installs from its own `brew install` list.
- **Third-party libraries.** `thirdparty/installed` comes from one of
two places:
- the published `doris-thirdparty-prebuilt-darwin-*.tar.xz`, which
`apache/doris-thirdparty`'s `build-target.yml` builds by running
`thirdparty/build-thirdparty.sh` from apache/doris master;
- a local run of that same script. `build.sh` also starts one by itself
when `thirdparty/installed` lacks a library it checks for.

**1. The problem, and what it cost**

*The deadlock.* `sample` on the stalled process shows the whole chain:

```
__malloc_init (libsystem_malloc)                      <- early libSystem init calls malloc_default_zone()
 `- wrap_malloc_default_zone (asan runtime)
     `- AsanInitFromRtl -> AsanInitInternal -> InitializeShadowMemory
         `- MemoryRangeIsAvailable -> MemoryMappingLayout::Next -> get_dyld_hdr()
             `- dyld_shared_cache_iterate_text_swift   <- macOS 26.4 reimplemented this in Swift
                 `- _Block_copy -> malloc
                     `- __sanitizer_mz_malloc (asan's own malloc)
                         `- AsanInitFromRtl()              <- re-enters init
                             `- StaticSpinMutex::LockSlow  <- spins on the lock it already holds
```

The cause is an OS-side change, not a Doris one. It also does not mean
ASAN is broken on macOS 26: Apple's own clang sanitizer runtime runs
fine on the same host, and only llvm.org's compiler-rt is affected.
Upstream fixed it by weak-importing `_dyld_get_dyld_header` and using
it, when present, instead of walking the shared cache
(llvm/llvm-project#182943, main `2e7d07a`; backport #188913,
release/22.x `7b6514c`). **The fix shipped only in 22.1.8.** 20.1.8 is
the last 20.x release and 21.1.8 the last 21.x, so no version of
`llvm@20` can ever be made to work.

*Why it looks like a hang and not an error.*

- `be/CMakeLists.txt` reaches `storage/index/ann` unconditionally, and
that directory's `cmake-protect` target calls `add_subdirectory()` on
`contrib/openblas`.
- OpenBLAS runs an instrumented `getarch` probe from its **configure**
step (`contrib/openblas/cmake/prebuild.cmake:1513`,
`execute_process(COMMAND .../getarch 0 ...)`), and `execute_process` has
no timeout.
- So every ASAN build stops at `-- Running getarch` and never moves
again. It sits at about 90% CPU and prints no diagnostic.

`run-be-ut.sh` on macOS was therefore unusable at its default setting,
and the failure gave the developer nothing to act on.

*The second obstacle, once the toolchain is bumped.*

- clang 22 added `-Wc2y-extensions` and folds it into `-Wpedantic`.
- `__COUNTER__` only reached the C standard in C2y (WG14 N3457).
`be/src/runtime/runtime_profile.h:73-85` uses it to give two
`SCOPED_TIMER` / `SCOPED_RAW_TIMER` expansions on the same line distinct
names.
- As a result, a clang 22 build of any TU that includes that header
fails under `-Werror`. Three representative unity TUs were enough to hit
it, so the failure is not confined to one module.

*The third obstacle: clang 22 cannot build the third-party libraries.*
The first revision of this PR moved every macOS toolchain reference to
`llvm@22`, including the third-party build. CI failed both macOS
third-party jobs (7m49s, 6m23s) on the first library that exercises a
new clang 22 error:

```
unixODBC 2.3.7  src/SQLBrowseConnectW.c:424:82:
error: incompatible pointer types passing 'SQLSMALLINT *' (aka 'short *')
       to parameter of type 'int *' [-Wincompatible-pointer-types]
```

clang 16, clang 20 and Apple clang 21 report this as a warning; clang 22
makes it an error. unixODBC is only the *first* failure: the build
aborts there, so every library after it is untested against clang 22.
The macOS third-party libraries therefore have to stay on `llvm@20`
while the BE moves to `llvm@22`.

Leaving the third-party build alone does not achieve that, because it
sources `env.sh`:

- With `CELLARS` naming `llvm@22`, a machine without `llvm@22` gets a
non-existent directory on `PATH`.
- `command -v clang` then falls through to `/usr/bin/clang` (Apple
clang), which is worse than either explicit choice.
- The job that publishes the prebuilt archive in
`apache/doris-thirdparty` is exactly such a machine: it installs only
`llvm@20` and sets no `DORIS_CLANG_HOME`.

*Two latent defects clang 22 then surfaced.* The bump is not a pure
version change. clang 22's stricter diagnostics stop the build on two
pre-existing bugs, and both are worth fixing on their own merits.

| # | Site | Diagnostic | What is actually wrong |
|---|---|---|---|
| 1 | `be/src/load/group_commit/wal/wal_dirs_info.cpp:98` |
`-Wunused-result` | `LOG(INFO) << "… err: {}", e.what();` — the `,` is
the comma operator, not an argument separator, so the statement is
`(LOG(INFO) << "…{}") , (e.what())`. The `{}` is never substituted, and
`e.what()` is evaluated and then discarded: **the error message has
never been logged**, only the literal `{}`. A repo-wide scan for the
same shape finds exactly this one site (`cloud/src/common/logging.h`
matches only inside macro definitions and is not a bug). |
| 2 | `common/cpp/sync_point.cpp:208,210` | `-Wthread-safety-analysis` |
The function holds `std::unique_lock lock(mutex_)`, then releases and
re-takes the mutex with a raw `mutex_.unlock()` / `mutex_.lock()` pair
around the callback, which bypasses the lock's ownership tracking. If
the callback throws, the re-lock is skipped while `~unique_lock` still
believes it owns the mutex, so the destructor unlocks a mutex that is
not held (UB) and `num_callbacks_running_` is never decremented.
`lock.unlock()` / `lock.lock()` still runs the callback unlocked, as
intended, and keeps the ownership state correct on every path. |

**2. What this PR does, and why it helps**

- **`env.sh`**: the macOS `CELLARS` list moves from `llvm@20` to
`llvm@22`, with a comment recording that 22.1.8 is the minimum and why.
This is the single line that decides which clang a macOS developer
builds the BE with.
- **`thirdparty/build-thirdparty.sh`**: on Darwin, right after sourcing
`env.sh` and next to the existing environment sanitization, the script
unconditionally points `DORIS_CLANG_HOME`, `CC` and `CXX` at `$(brew
--prefix llvm@20)` and puts its `bin/` first on `PATH`. If `llvm@20` is
not installed, it stops with a `brew install llvm@20` hint rather than
falling back to another compiler.
- The override has to come after `env.sh` and has to be unconditional.
`env.sh` sources `custom_env.sh`, which may export `DORIS_CLANG_HOME`
for the BE, and `build.sh` has already exported the BE's `llvm@22`
values before it starts this script.
- Every macOS third-party build runs this script: `build.sh`'s automatic
rebuild, a manual run, the pull request check in `build-thirdparty.yml`,
and the `apache/doris-thirdparty` job that publishes
`doris-thirdparty-prebuilt-darwin-*.tar.xz`. This one place therefore
keeps all of them, and the published archive, on `llvm@20`.
- `.github/workflows/build-thirdparty.yml` is unchanged: its macOS jobs
already install `llvm@20`.
- **`be/CMakeLists.txt`**: add `-Wno-c2y-extensions` for clang 19 and
newer, in its own `add_compile_options` call **after** `-Wpedantic`.
- The position matters: a later `-Wpedantic` turns the group back on.
That is also why passing the flag through `EXTRA_CXX_FLAGS` does not
work: that variable lands near the front of the command line.
- The version gate matters because the `c2y-extensions` group only
exists from clang 19 on. clang rejects an unknown `-Wno-` option like
any other unknown warning option (`-Wunknown-warning-option`, fatal
under `-Werror`), and this file accepts clang 16 and newer.
  - For clang 19 and newer the command line is exactly what it was.
- **`.github/workflows/be-ut-mac.yml`**: install `llvm@22` for the BE
and keep `llvm@20` next to it.
- The job builds the BE on top of the downloaded darwin-arm64 prebuilt.
When that archive lacks a library `build.sh` checks for, `build.sh`
rebuilds the third-party libraries from source, and that rebuild now
needs `llvm@20`. The archive falls behind like this whenever master
changes the set of checked libraries before the next archive is
published.
- Both formulae are keg-only, so installing both does not change which
one the BE uses.
- **`be/src/load/group_commit/wal/wal_dirs_info.cpp` and
`common/cpp/sync_point.cpp`**: the two fixes from the table above. Each
is one line, the smallest change that removes the defect rather than
suppressing the warning. No `-Wno-unused-result` /
`-Wno-thread-safety-analysis` is added, because those diagnostics point
at real bugs and should keep firing.
- **apache/doris-website#4180**: the macOS build guide installs
`llvm@22` and `llvm@20` instead of only `llvm@20`. Without it, a
developer who follows the guide after this PR has no `llvm@22`, and the
BE silently builds with Apple clang.

What this PR deliberately does not do is add `llvm@20` to `env.sh`'s
`CELLARS`:

- `CELLARS` installs nothing.
- `build-thirdparty.sh` does not use `PATH` to find `llvm@20`.
- The `CELLARS` loop prepends each entry to `PATH`. An `llvm@20` entry
after `llvm@22` would put the BE back on `llvm@20` and bring the
deadlock back.

**3. The classes, and how they call each other**

```
env.sh  CELLARS := llvm@22                                (selects a compiler; installs nothing)
  |- generates custom_env_mac.sh: $(brew --prefix)/opt/<cellar>/bin prepended to PATH
  |- DORIS_CLANG_HOME := dirname($(command -v clang))/..   -> CC / CXX / ASAN_SYMBOLIZER_PATH
  '- is sourced by:
       |- build.sh, run-be-ut.sh                           -> BE: llvm@22
       '- thirdparty/build-thirdparty.sh:55
            '- :100-110  on Darwin: DORIS_CLANG_HOME / CC / CXX := $(brew --prefix llvm@20)
                         llvm@20 missing -> exit 1, "brew install llvm@20"
                                                           -> third-party libraries: llvm@20
                 run by: build.sh (library missing from thirdparty/installed), manual runs,
                         build-thirdparty.yml (PR check), doris-thirdparty build-target.yml (publisher)

brew install lists, i.e. who installs which LLVM:
  macOS build guide (apache/doris-website#4180)   llvm@22 llvm@20
  .github/workflows/be-ut-mac.yml                 llvm@22 llvm@20
  .github/workflows/build-thirdparty.yml          llvm@20
  apache/doris-thirdparty build-target.yml        llvm@20

be/CMakeLists.txt  if (COMPILER_CLANG)
  |- add_compile_options(-Wpedantic ...)               <- enables the c2y group
  '- if (CMAKE_CXX_COMPILER_VERSION >= 19)
       add_compile_options(-Wno-c2y-extensions)        <- must stay after the line above
         |
be/src/runtime/runtime_profile.h:73-85
  '- MACRO_CONCAT(SCOPED_TIMER, __COUNTER__)           <- the only __COUNTER__ use in be/src, be/test
         |
be/src/storage/index/ann/cmake-protect/CMakeLists.txt:48
  '- add_subdirectory(contrib/openblas)
       '- cmake/prebuild.cmake:1513  execute_process(getarch)   <- where the hang surfaced
```

### Release note

None

### Check List (For Author)

- Test: Manual test on macOS 26.5.1 (arm64, dyld-1378), plus CI.
- `clang -fsanitize=address` hello world exits 0 with llvm@22 and still
deadlocks with llvm@20 on the same host.
- `sh run-be-ut.sh` with no environment overrides now selects
`Clang-22.1.8` and clears the `-- Running getarch` point that previously
hung forever: zero FAILED targets, and `doris_be_test` links.
- `sh run-be-ut.sh --run --filter=FormatRoundTest.*` starts the ASAN
binary and passes 8 tests.
- `-Wno-c2y-extensions` gate, tested on a `__COUNTER__` TU under
`-Wpedantic -Werror`: clang 16.0.6 rejects the flag (`unknown warning
option`), which is why it is gated; clang 20.1.8 accepts it; clang
22.1.8 fails without it and passes with it.
- `build-thirdparty.sh` compiler override, checked under `bash -x` with
both `custom_env.sh` and `build.sh` exporting the `llvm@22` values: the
effective `CC`/`CXX` and the first clang on `PATH` are llvm@20. With
`llvm@20` missing, the script exits 1 with the brew hint before building
anything.
- `be-ut-mac.yml`: the "Build BE" step script passes `bash -n` on bash
3.2 and 5.3, and its `cellars` array holds both `llvm@22` and `llvm@20`.
The workflow runs only on pushes to master and on schedule, so this PR
cannot run it.
    - `build-support/check-build-hygiene.sh` passes.
- CI: `Build Third Party Libraries (macOS)`, `(macOS-arm64)` and
`(Linux)` pass at `a955357a30f` (run 36542107899), which already
contains the `build-thirdparty.sh` override. The first revision, which
moved these builds to llvm@22, failed both macOS jobs on unixODBC.
- Regression test / unit test: N/A (toolchain, flag and workflow
change).
- Behavior changed: Yes, for macOS builds only.
    - The BE builds with llvm@22 instead of llvm@20.
- The third-party libraries, including the published prebuilt, stay on
llvm@20. Building them from source now requires llvm@20 installed next
to llvm@22; without it, the build stops with a `brew install llvm@20`
hint.
- Existing macOS developers need to run `brew install llvm@22`. Without
it, `env.sh` falls back to Apple clang in `/usr/bin` for newly
configured build directories.
- Does this need documentation: Yes, apache/doris-website#4180.

---------

Co-authored-by: Claude Code <noreply@anthropic.com>
2026-09-30 21:00:34 +08:00

388 lines
12 KiB
Bash
Executable File

#!/usr/bin/env bash
# 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.
# Explicitly set to prevent ccache misses caused by terminal differences
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
export LC_CTYPE=en_US.UTF-8
export LC_MESSAGES=en_US.UTF-8
# check DORIS_HOME
if [[ -z "${DORIS_HOME}" ]]; then
echo "Error: DORIS_HOME is not set"
exit 1
fi
TARGET_SYSTEM="$(uname -s)"
TARGET_ARCH="$(uname -m)"
echo "Target system: ${TARGET_SYSTEM}; Target arch: ${TARGET_ARCH}"
# check OS type
if [[ -n "${OSTYPE}" ]]; then
if [[ "${OSTYPE}" != "linux-gnu" ]] && [[ "${OSTYPE:0:6}" != "darwin" ]]; then
echo "Error: Unsupported OS type: ${OSTYPE}"
exit 1
fi
fi
if [[ "$(uname -s)" == 'Darwin' ]]; then
if ! command -v brew &>/dev/null; then
echo "Error: Homebrew is missing. Please install it first due to we use Homebrew to manage the tools which are needed to build the project."
exit 1
fi
cat >"${DORIS_HOME}/custom_env_mac.sh" <<EOF
# This file is generated automatically. PLEASE DO NOT MODIFY IT.
HOMEBREW_REPO_PREFIX="$(brew --prefix)"
CELLARS=(
automake
autoconf
libtool
pkg-config
texinfo
coreutils
gnu-getopt
python@3
cmake
ninja
ccache
bison
byacc
gettext
wget
pcre
maven
# 22.1.8 is the first compiler-rt whose ASAN runtime survives macOS 26.4+:
# dyld reimplemented dyld_shared_cache_iterate_text in Swift there and its
# _Block_copy allocation re-enters ASAN init, so every -fsanitize=address
# binary built with llvm@20 deadlocks before main() (llvm/llvm-project#182943,
# fixed in 22.1.8; no 20.x or 21.x backport exists). That is the BE's compiler:
# thirdparty/build-thirdparty.sh keeps the third-party libraries on llvm@20.
llvm@22
m4
)
for cellar in "\${CELLARS[@]}"; do
EXPORT_CELLARS="\${HOMEBREW_REPO_PREFIX}/opt/\${cellar}/bin:\${EXPORT_CELLARS}"
done
export PATH="\${EXPORT_CELLARS}:/usr/bin:\${PATH}"
export DORIS_BUILD_PYTHON_VERSION='python3'
export NODE_OPTIONS='--openssl-legacy-provider'
EOF
DORIS_HOME_ABSOLUATE_PATH="$(
set -e
cd "${DORIS_HOME}"
pwd
)"
SOURCE_MAC_ENV_CONTENT="source '${DORIS_HOME_ABSOLUATE_PATH}/custom_env_mac.sh'"
if [[ ! -f "${DORIS_HOME}/custom_env.sh" ]] ||
! grep "${SOURCE_MAC_ENV_CONTENT}" "${DORIS_HOME}/custom_env.sh" &>/dev/null; then
echo "${SOURCE_MAC_ENV_CONTENT}" >>"${DORIS_HOME}/custom_env.sh"
fi
fi
# include custom environment variables
if [[ -f "${DORIS_HOME}/custom_env.sh" ]]; then
# shellcheck disable=1091
. "${DORIS_HOME}/custom_env.sh"
fi
# set DORIS_THIRDPARTY
if [[ -z "${DORIS_THIRDPARTY}" ]]; then
export DORIS_THIRDPARTY="${DORIS_HOME}/thirdparty"
fi
# set DISABLE_BUILD_AZURE
# Azure is built on every platform now. It used to be skipped on aarch64 and macOS
# because the third-party recipe was x86_64-Linux-only; that is fixed in build_azure.
if [[ -z "${DISABLE_BUILD_AZURE}" ]]; then
export DISABLE_BUILD_AZURE='OFF'
fi
# check python
if [[ -z "${DORIS_BUILD_PYTHON_VERSION}" ]]; then
DORIS_BUILD_PYTHON_VERSION="python"
fi
export PYTHON="${DORIS_BUILD_PYTHON_VERSION}"
if ! ${PYTHON} --version; then
echo "Error: ${PYTHON} is not found, maybe you should set DORIS_BUILD_PYTHON_VERSION."
exit 1
fi
if [[ -z "${DORIS_TOOLCHAIN}" ]]; then
if [[ "$(uname -s)" == 'Darwin' ]]; then
DORIS_TOOLCHAIN=clang
else
DORIS_TOOLCHAIN=clang
fi
fi
if [[ "${DORIS_TOOLCHAIN}" == "gcc" ]]; then
# set GCC HOME
if [[ -z "${DORIS_GCC_HOME}" ]]; then
DORIS_GCC_HOME="$(dirname "$(command -v gcc)")"/..
export DORIS_GCC_HOME
fi
export CC="${DORIS_GCC_HOME}/bin/gcc"
export CXX="${DORIS_GCC_HOME}/bin/g++"
if test -x "${DORIS_GCC_HOME}/bin/ld"; then
export DORIS_BIN_UTILS="${DORIS_GCC_HOME}/bin/"
fi
ENABLE_PCH='OFF'
elif [[ "${DORIS_TOOLCHAIN}" == "clang" ]]; then
# set CLANG HOME
if [[ -z "${DORIS_CLANG_HOME}" ]]; then
DORIS_CLANG_HOME="$(dirname "$(command -v clang)")"/..
export DORIS_CLANG_HOME
fi
export CC="${DORIS_CLANG_HOME}/bin/clang"
export CXX="${DORIS_CLANG_HOME}/bin/clang++"
if test -x "${DORIS_CLANG_HOME}/bin/ld.lld"; then
export DORIS_BIN_UTILS="${DORIS_CLANG_HOME}/bin/"
fi
if [[ -f "${DORIS_CLANG_HOME}/bin/llvm-symbolizer" ]]; then
export ASAN_SYMBOLIZER_PATH="${DORIS_CLANG_HOME}/bin/llvm-symbolizer"
fi
covs=()
while IFS='' read -r line; do covs+=("${line}"); done <<<"$(find "${DORIS_CLANG_HOME}" -name "llvm-cov*")"
if [[ ${#covs[@]} -ge 1 ]]; then
LLVM_COV="${covs[0]}"
else
LLVM_COV="$(command -v llvm-cov)"
fi
export LLVM_COV
profdatas=()
while IFS='' read -r line; do profdatas+=("${line}"); done <<<"$(find "${DORIS_CLANG_HOME}" -name "llvm-profdata*")"
if [[ ${#profdatas[@]} -ge 1 ]]; then
LLVM_PROFDATA="${profdatas[0]}"
else
LLVM_PROFDATA="$(command -v llvm-profdata)"
fi
export LLVM_PROFDATA
if [[ -z "${ENABLE_PCH}" ]]; then
ENABLE_PCH='ON'
fi
else
echo "Error: unknown DORIS_TOOLCHAIN=${DORIS_TOOLCHAIN}, currently only 'gcc' and 'clang' are supported"
exit 1
fi
export CCACHE_COMPILERCHECK=content
if [[ "${ENABLE_PCH}" == "ON" ]]; then
export CCACHE_PCH_EXTSUM=true
export CCACHE_SLOPPINESS="pch_defines,time_macros"
else
export CCACHE_NOPCH_EXTSUM=true
export CCACHE_SLOPPINESS="default"
fi
if [[ -z "${DORIS_BIN_UTILS}" ]]; then
export DORIS_BIN_UTILS='/usr/bin/'
fi
if [[ -z "${DORIS_GCC_HOME}" ]]; then
DORIS_GCC_HOME="$(dirname "$(command -v gcc)")/.."
export DORIS_GCC_HOME
fi
if [[ ! -f "${DORIS_GCC_HOME}/bin/gcc" ]]; then
echo "Error: wrong directory DORIS_GCC_HOME=${DORIS_GCC_HOME}"
exit 1
fi
# export CLANG COMPATIBLE FLAGS
CLANG_COMPATIBLE_FLAGS="$(echo | "${DORIS_GCC_HOME}/bin/gcc" -Wp,-v -xc++ - -fsyntax-only 2>&1 |
grep -E '^\s+/' | awk '{print "-I" $1}' | tr '\n' ' ')"
export CLANG_COMPATIBLE_FLAGS
# get jdk version, return version as an Integer.
# 1.8 => 8, 13.0 => 13
function jdk_version() {
local java_cmd="${1}"
local result
local IFS=$'\n'
if [[ -z "${java_cmd}" ]]; then
result=no_java
return 1
else
local version
# remove \r for Cygwin
version="$("${java_cmd}" -Xms32M -Xmx32M -version 2>&1 | tr '\r' '\n' | grep version | awk '{print $3}')"
version="${version//\"/}"
if [[ "${version}" =~ ^1\. ]]; then
result="$(echo "${version}" | awk -F '.' '{print $2}')"
else
result="$(echo "${version}" | awk -F '.' '{print $1}')"
fi
fi
echo "${result}"
return 0
}
# check java version
# must use jdk_17
function check_jdk_version() {
if [[ ! -x "${JAVA}" ]]; then
echo "The JAVA_HOME environment variable is not defined correctly"
echo "This environment variable is needed to run this program"
echo "NB: JAVA_HOME should point to a JDK not a JRE"
exit 1
fi
echo "Check JAVA version"
java_version="$(
set -e
jdk_version "${JAVA}"
)"
if [[ "${java_version}" -ne 17 ]]; then
echo "ERROR: The JAVA version is ${java_version}, it must be JDK-17."
exit 1
fi
return 0
}
# if is called from build-thirdparty.sh, no need to check these tools
if test -z "${DO_NOT_CHECK_JAVA_ENV:-}"; then
# register keyword is forbidden to use in C++17
# the C++ code generated by flex that remove register keyword after version 2.6.0
# so we need check flex version here to avoid compilation failed
flex_ver="$(flex --version | awk '{print $2}')"
required_ver="2.6.0"
if [[ ! "$(printf '%s\n' "${required_ver}" "${flex_ver}" | sort -V | head -n1)" = "${required_ver}" ]]; then
echo "Error: flex version (${flex_ver}) must be greater than or equal to ${required_ver}"
exit 1
fi
# check java home
if [[ -z "${JAVA_HOME}" ]]; then
if [[ -n "${JDK_17}" ]]; then
echo "Use JDK_17 = ${JDK_17}"
JAVA="${JDK_17}/bin/java"
JAVAP="${JDK_17}/bin/javap"
export JAVA_HOME="${JDK_17}"
else
JAVA="$(command -v java)"
JAVAP="$(command -v javap)"
fi
check_jdk_version
else
JAVA="${JAVA_HOME}/bin/java"
JAVAP="${JAVA_HOME}/bin/javap"
echo "Check JAVA_HOME version"
java_version="$(
set -e
jdk_version "${JAVA}"
)"
if [[ "${java_version}" -ne 17 ]]; then
echo "JAVA_HOME=${JAVA_HOME}. It does not point to JDK-17."
if [[ -n "${JDK_17}" ]]; then
echo "Use JDK_17=${JDK_17}."
JAVA="${JDK_17}/bin/java"
JAVAP="${JDK_17}/bin/javap"
export JAVA_HOME="${JDK_17}"
check_jdk_version
else
echo "The 'JDK_17' environment variable is not set."
echo "ERROR: The JAVA version is ${java_version}, it must be JDK-17."
exit 1
fi
fi
fi
export JAVA
JAVA_VER="$("${JAVAP}" -verbose java.lang.String | grep "major version" | cut -d " " -f5)"
if [[ "${JAVA_VER}" -lt 52 ]]; then
echo "Error: require JAVA with JDK version at least 1.8"
exit 1
fi
# check maven
MVN_CMD='mvn'
if [[ -n "${CUSTOM_MVN}" ]]; then
MVN_CMD="${CUSTOM_MVN}"
fi
if ! "${MVN_CMD}" --version; then
echo "Error: mvn is not found"
exit 1
fi
export MVN_CMD
fi
if [[ "$(uname -s)" == 'Darwin' ]]; then
if ! command -v libtoolize &>/dev/null && command -v glibtoolize &>/dev/null; then
shopt -s expand_aliases
alias libtoolize='glibtoolize'
fi
fi
CMAKE_CMD='cmake'
if [[ -n "${CUSTOM_CMAKE}" ]]; then
CMAKE_CMD="${CUSTOM_CMAKE}"
fi
if ! "${CMAKE_CMD}" --version; then
echo "Error: cmake is not found"
exit 1
fi
export CMAKE_CMD
GENERATOR="Unix Makefiles"
BUILD_SYSTEM="make"
if NINJA_VERSION="$(ninja --version 2>/dev/null)"; then
echo "ninja ${NINJA_VERSION}"
GENERATOR="Ninja"
BUILD_SYSTEM="ninja"
fi
# for worktree build, use ubsan_ignorelist.txt from main branch to avoid ccache miss.
if [[ -z "${UBSAN_IGNORELIST}" ]]; then
export UBSAN_IGNORELIST="${DORIS_HOME}/conf/ubsan_ignorelist.txt"
fi
if CCACHE_VERSION="$(ccache --version 2>/dev/null)"; then
echo "${CCACHE_VERSION}" | head -n 1
# shellcheck disable=2034
CMAKE_USE_CCACHE_CXX="-DCMAKE_CXX_COMPILER_LAUNCHER=ccache"
CMAKE_USE_CCACHE_C="-DCMAKE_C_COMPILER_LAUNCHER=ccache"
export CCACHE_BASEDIR=${DORIS_HOME}
export CCACHE_NOHASHDIR=1
export CCACHE_COMPRESS=1
export CCACHE_IGNOREOPTIONS='-ffile-prefix-map=*' # we remap path in different repo to one. the item itself could be ignore.
# for debug. when debug enabled, will generate text fingerprint file *.ccache-input-text
# export CCACHE_LOGFILE=
# export CCACHE_DEBUG=1
fi
export GENERATOR
export BUILD_SYSTEM
export PKG_CONFIG_PATH="${DORIS_HOME}/thirdparty/installed/lib64/pkgconfig:${PKG_CONFIG_PATH}"