#!/bin/bash
set -eo pipefail
readonly HCOM_ROOT_DIR=$(cd "$(dirname "$0")" && pwd)
readonly HCOM_LOG_TAG="[$(basename "$0")]"
readonly HCOM_INSTALL_DIR="${HCOM_ROOT_DIR}/dist/hcom"
readonly HCOM_UT_BUILD_DIR="${HCOM_ROOT_DIR}/tmp_build_dir_bazel_ut"
HCOM_SOVERSION="0"
HCOM_LIB_VERSION="0.0.1"
HCOM_COMPONENT_VERSION="${HCOM_COMPONENT_VERSION:-1.0.0}"
HCOM_BUILD_TYPE="${HCOM_BUILD_TYPE,,}"
HCOM_BUILD_TYPE="${HCOM_BUILD_TYPE:-release}"
HCOM_BUILD_HW_CRC="${HCOM_BUILD_HW_CRC:-off}"
HCOM_BUILD_UB="${HCOM_BUILD_UB:-off}"
HCOM_BUILD_SERVICE="${HCOM_BUILD_SERVICE:-on}"
HCOM_BUILD_RDMA="${HCOM_BUILD_RDMA:-on}"
HCOM_BUILD_SOCK="${HCOM_BUILD_SOCK:-on}"
HCOM_BUILD_SHM="${HCOM_BUILD_SHM:-on}"
HCOM_BUILD_MULTICAST="${HCOM_BUILD_MULTICAST:-off}"
HCOM_ENABLE_ARM_KP="${HCOM_ENABLE_ARM_KP:-off}"
HCOM_BUILD_JAVA_SDK="${HCOM_BUILD_JAVA_SDK:-off}"
HCOM_BUILD_TESTS="${HCOM_BUILD_TESTS:-off}"
HCOM_BUILD_EXAMPLE="${HCOM_BUILD_EXAMPLE:-off}"
HCOM_BUILD_RPM="${HCOM_BUILD_RPM:-off}"
HCOM_BUILD_TOOLS_PERF="${HCOM_BUILD_TOOLS_PERF:-off}"
BUILD_HCOM="${BUILD_HCOM:-ON}"
HCOM_BAZEL_CPU="${HCOM_BAZEL_CPU:-}"
HCOM_BUILD_ALLOCATOR_PROTECTION="${HCOM_BUILD_ALLOCATOR_PROTECTION:-off}"
HCOM_TEST_TOOL_PATH="${HCOM_TEST_TOOL_PATH:-${HCOM_ROOT_DIR}/dist/hcom_test_tools}"
function show_help() {
echo "Usage: $0 [COMMAND] [OPTION]"
echo "Build HCOM with Bazel."
echo "Commands: clean"
echo "Options:"
echo " -t, --type TYPE Set build type. debug/release"
}
function to_cmake_onoff() {
if [[ "${1,,}" == "on" ]]; then
echo "ON"
else
echo "OFF"
fi
}
function append_bazel_define_if() {
local option_value="${1,,}"
local expect_value="${2,,}"
local define_kv="$3"
if [[ "${option_value}" == "${expect_value}" ]]; then
BAZEL_FLAGS+=("--define=${define_kv}")
fi
}
function load_hcom_lib_version_from_cmake() {
local cmake_file="${HCOM_ROOT_DIR}/src/hcom/CMakeLists.txt"
local major=""
local minor=""
local patch=""
if [[ -f "${cmake_file}" ]]; then
local parsed=""
parsed=$(awk '
/set\(LIB_VERSION_MAJOR[[:space:]]+[0-9]+/ { major=$2; gsub(/\)/, "", major) }
/set\(LIB_VERSION_MINOR[[:space:]]+[0-9]+/ { minor=$2; gsub(/\)/, "", minor) }
/set\(LIB_VERSION_PATCH[[:space:]]+[0-9]+/ { patch=$2; gsub(/\)/, "", patch) }
END { print major " " minor " " patch }
' "${cmake_file}")
read -r major minor patch <<< "${parsed}"
fi
if [[ -z "${major}" || -z "${minor}" || -z "${patch}" ]]; then
major="0"
minor="0"
patch="1"
echo "${HCOM_LOG_TAG} warn: failed to parse lib version from CMakeLists, fallback to ${major}.${minor}.${patch}"
fi
HCOM_SOVERSION="${major}"
HCOM_LIB_VERSION="${major}.${minor}.${patch}"
}
function verify_hcom_install_layout() {
local expected=(
"${HCOM_INSTALL_DIR}/lib/libhcom.so.${HCOM_LIB_VERSION}"
"${HCOM_INSTALL_DIR}/lib/libhcom.so.${HCOM_SOVERSION}"
"${HCOM_INSTALL_DIR}/lib/libhcom.so"
"${HCOM_INSTALL_DIR}/lib/libhcom_static.a"
"${HCOM_INSTALL_DIR}/lib/libboundscheck.so"
"${HCOM_INSTALL_DIR}/include/hcom/hcom.h"
"${HCOM_INSTALL_DIR}/include/hcom/capi/hcom_c.h"
)
local miss=0
for item in "${expected[@]}"; do
if [[ ! -e "${item}" ]]; then
echo "${HCOM_LOG_TAG} error: missing install artifact: ${item}"
miss=1
fi
done
if [[ "${HCOM_BUILD_MULTICAST,,}" == "on" && ! -d "${HCOM_INSTALL_DIR}/include/hcom/multicast" ]]; then
echo "${HCOM_LOG_TAG} error: missing multicast include directory: ${HCOM_INSTALL_DIR}/include/hcom/multicast"
miss=1
fi
if [[ ${miss} -ne 0 ]]; then
exit 1
fi
}
function clean_dir() {
[[ -n "${HCOM_INSTALL_DIR}" ]] && rm -rf "${HCOM_INSTALL_DIR}"
[[ -n "${HCOM_UT_BUILD_DIR}" ]] && rm -rf "${HCOM_UT_BUILD_DIR}"
if command -v bazel >/dev/null 2>&1; then
bazel clean >/dev/null 2>&1 || true
elif command -v bazelisk >/dev/null 2>&1; then
bazelisk clean >/dev/null 2>&1 || true
fi
echo "Cleanup: ${HCOM_INSTALL_DIR}, ${HCOM_UT_BUILD_DIR} and bazel outputs"
}
function copy_if_exists() {
local src="$1"
local dst="$2"
local hint="$3"
if [[ -f "${src}" ]]; then
cp -f "${src}" "${dst}"
else
echo "${HCOM_LOG_TAG} info: ${hint} not found, skip (${src})"
fi
}
function cquery_first_file() {
local target="$1"
local regex="$2"
"${BAZEL_BIN}" cquery "${BAZEL_FLAGS[@]}" --output=files "${target}" | grep -E "${regex}" | head -n 1 || true
}
function first_existing_file() {
for candidate in "$@"; do
if [[ -n "${candidate}" && -f "${candidate}" ]]; then
echo "${candidate}"
return 0
fi
done
return 1
}
function copy_if_exists_silent() {
local src="$1"
local dst="$2"
if [[ -f "${src}" ]]; then
cp -f "${src}" "${dst}"
fi
}
function run_hcom_test_build_fallback() {
echo "${HCOM_LOG_TAG} HCOM_BUILD_TESTS=on: Bazel test targets are not available; using CMake fallback to build UT binaries."
if [[ ! -d "${HCOM_TEST_TOOL_PATH}" ]]; then
echo "${HCOM_LOG_TAG} hcom test tools are not installed, installing..."
HCOM_TEST_TOOL_PATH="${HCOM_TEST_TOOL_PATH}" bash "${HCOM_ROOT_DIR}/build/install_test_tools.sh"
fi
rm -rf "${HCOM_UT_BUILD_DIR}"
cmake -S"${HCOM_ROOT_DIR}" -B"${HCOM_UT_BUILD_DIR}" \
-DBUILD_HCOM=ON \
-DCMAKE_BUILD_TYPE=debug \
-DBUILD_TESTS=ON \
-DTEST_TOOL_INSTALL_PATH="${HCOM_TEST_TOOL_PATH}" \
-DBUILD_JAVA_SDK=OFF \
-DBUILD_WITH_HW_CRC=$(to_cmake_onoff "${HCOM_BUILD_HW_CRC}") \
-DBUILD_WITH_UB=$(to_cmake_onoff "${HCOM_BUILD_UB}") \
-DBUILD_WITH_RDMA=$(to_cmake_onoff "${HCOM_BUILD_RDMA}") \
-DBUILD_WITH_SOCK=$(to_cmake_onoff "${HCOM_BUILD_SOCK}") \
-DBUILD_WITH_SHM=$(to_cmake_onoff "${HCOM_BUILD_SHM}") \
-DBUILD_WITH_MULTICAST=$(to_cmake_onoff "${HCOM_BUILD_MULTICAST}") \
-DENABLE_ARM_KP=$(to_cmake_onoff "${HCOM_ENABLE_ARM_KP}") \
-DHCOM_COMPONENT_VERSION="${HCOM_COMPONENT_VERSION}"
cmake --build "${HCOM_UT_BUILD_DIR}" -j "$(nproc)"
echo "${HCOM_LOG_TAG} UT binaries are ready: ${HCOM_UT_BUILD_DIR}/hcom_ut, ${HCOM_UT_BUILD_DIR}/hcom_test"
echo "${HCOM_LOG_TAG} To run UT and generate xml manually:"
echo " ${HCOM_UT_BUILD_DIR}/hcom_ut --gtest_output=xml:${HCOM_UT_BUILD_DIR}/res_xml/ut_result.xml"
echo " ${HCOM_UT_BUILD_DIR}/hcom_test --gtest_output=xml:${HCOM_UT_BUILD_DIR}/res_xml/llt_result.xml"
}
while [[ "$#" -gt 0 ]]; do
case "$1" in
-t|--type) HCOM_BUILD_TYPE="${2,,}"; shift ;;
clean) clean_dir; exit 0 ;;
*) echo "Unknown parameter passed: $1"; show_help; exit 1 ;;
esac
shift
done
if [[ "${HCOM_BUILD_TYPE}" != "release" && "${HCOM_BUILD_TYPE}" != "debug" ]]; then
echo "${HCOM_LOG_TAG} invalid HCOM_BUILD_TYPE: ${HCOM_BUILD_TYPE}, expected debug/release"
exit 1
fi
BAZEL_BIN=""
if command -v bazel >/dev/null 2>&1; then
BAZEL_BIN="bazel"
elif command -v bazelisk >/dev/null 2>&1; then
BAZEL_BIN="bazelisk"
else
echo "${HCOM_LOG_TAG} bazel/bazelisk not found in PATH"
exit 1
fi
load_hcom_lib_version_from_cmake
echo "HCOM ROOT: ${HCOM_ROOT_DIR}"
echo "HCOM INSTALL DIR: ${HCOM_INSTALL_DIR}"
echo "${HCOM_LOG_TAG} using bazel command: ${BAZEL_BIN}"
echo "${HCOM_LOG_TAG} hcom build type: ${HCOM_BUILD_TYPE}"
echo "${HCOM_LOG_TAG} hcom build hw crc: ${HCOM_BUILD_HW_CRC}"
echo "${HCOM_LOG_TAG} hcom build ub: ${HCOM_BUILD_UB}"
echo "${HCOM_LOG_TAG} hcom build service: ${HCOM_BUILD_SERVICE}"
echo "${HCOM_LOG_TAG} hcom build rdma: ${HCOM_BUILD_RDMA}"
echo "${HCOM_LOG_TAG} hcom build sock: ${HCOM_BUILD_SOCK}"
echo "${HCOM_LOG_TAG} hcom build shm: ${HCOM_BUILD_SHM}"
echo "${HCOM_LOG_TAG} hcom build multicast: ${HCOM_BUILD_MULTICAST}"
echo "${HCOM_LOG_TAG} hcom enable arm kunpeng check: ${HCOM_ENABLE_ARM_KP}"
echo "${HCOM_LOG_TAG} hcom build java sdk: ${HCOM_BUILD_JAVA_SDK}"
echo "${HCOM_LOG_TAG} hcom build tests: ${HCOM_BUILD_TESTS}"
echo "${HCOM_LOG_TAG} hcom test tools path: ${HCOM_TEST_TOOL_PATH}"
echo "${HCOM_LOG_TAG} build hcom: ${BUILD_HCOM}"
echo "${HCOM_LOG_TAG} build rpm: ${HCOM_BUILD_RPM}"
echo "${HCOM_LOG_TAG} lib version (from CMake): ${HCOM_LIB_VERSION} (soversion=${HCOM_SOVERSION})"
if [[ "${HCOM_BUILD_SERVICE,,}" != "on" ]]; then
echo "${HCOM_LOG_TAG} info: BUILD_WITH_SERVICE=off currently has no source-level effect in CMake and Bazel, treated as no-op."
fi
if [[ "${HCOM_BUILD_JAVA_SDK,,}" == "on" ]]; then
echo "${HCOM_LOG_TAG} error: HCOM_BUILD_JAVA_SDK=on cannot be implemented now."
echo "${HCOM_LOG_TAG} reason: current repo has no java_sdk sources/rules (src/hcom/api/java_sdk is absent)."
echo "${HCOM_LOG_TAG} action: set HCOM_BUILD_JAVA_SDK=off; add java_sdk sources and Bazel/CMake rules first if needed."
exit 1
fi
if [[ "${BUILD_HCOM^^}" != "ON" ]]; then
echo "${HCOM_LOG_TAG} BUILD_HCOM=${BUILD_HCOM}, skip hcom bazel build."
echo "${HCOM_LOG_TAG} $0 succeeds"
exit 0
fi
[[ -n "${HCOM_INSTALL_DIR}" ]] && rm -rf "${HCOM_INSTALL_DIR}"
mkdir -p "${HCOM_INSTALL_DIR}/lib" "${HCOM_INSTALL_DIR}/include/hcom/capi"
declare -a BAZEL_FLAGS
BAZEL_FLAGS+=("--noenable_bzlmod")
if [[ "${HCOM_BUILD_TYPE}" == "release" ]]; then
BAZEL_FLAGS+=("-c" "opt")
else
BAZEL_FLAGS+=("-c" "dbg")
fi
if [[ -n "${HCOM_BAZEL_CPU}" ]]; then
BAZEL_FLAGS+=("--cpu=${HCOM_BAZEL_CPU}")
fi
append_bazel_define_if "${HCOM_BUILD_RDMA}" "off" "hcom_enable_rdma=0"
append_bazel_define_if "${HCOM_BUILD_SHM}" "off" "hcom_enable_shm=0"
append_bazel_define_if "${HCOM_BUILD_SOCK}" "off" "hcom_enable_sock=0"
append_bazel_define_if "${HCOM_BUILD_UB}" "on" "hcom_enable_ub=1"
append_bazel_define_if "${HCOM_BUILD_MULTICAST}" "on" "hcom_enable_multicast=1"
append_bazel_define_if "${HCOM_BUILD_HW_CRC}" "on" "hcom_enable_hw_crc=1"
append_bazel_define_if "${HCOM_ENABLE_ARM_KP}" "on" "hcom_enable_arm_kp=1"
append_bazel_define_if "${HCOM_BUILD_ALLOCATOR_PROTECTION}" "on" "hcom_enable_allocator_protection=1"
cd "${HCOM_ROOT_DIR}"
"${BAZEL_BIN}" build "${BAZEL_FLAGS[@]}" //src/hcom:hcom_static //src/hcom:libhcom.so //src:libboundscheck.so
SHARED_LIB_PATH=$(first_existing_file \
"${HCOM_ROOT_DIR}/bazel-bin/src/hcom/libhcom.so" \
"$(cquery_first_file //src/hcom:libhcom.so '/libhcom\.so$')" \
) || true
STATIC_LIB_PATH=$(first_existing_file \
"${HCOM_ROOT_DIR}/bazel-bin/src/hcom/libhcom_static.a" \
"${HCOM_ROOT_DIR}/bazel-bin/src/hcom/libhcom_static.pic.a" \
"$(cquery_first_file //src/hcom:hcom_static '/libhcom_static(\\.pic)?\\.(a|lo)$')" \
"$(find "${HCOM_ROOT_DIR}/bazel-bin/src/hcom" -maxdepth 2 -type f \( -name 'libhcom_static.a' -o -name 'libhcom_static.pic.a' -o -name 'libhcom_static.lo' -o -name 'libhcom_static.pic.lo' \) | head -n 1 || true)" \
) || true
BOUNDSCHECK_SO_PATH=$(first_existing_file \
"${HCOM_ROOT_DIR}/bazel-bin/src/libboundscheck.so" \
"$(cquery_first_file //src:libboundscheck.so '/libboundscheck\.so$')" \
"$(find "${HCOM_ROOT_DIR}/bazel-bin/src" -maxdepth 2 -type f -name 'libboundscheck.so' | head -n 1 || true)" \
) || true
if [[ -z "${SHARED_LIB_PATH}" || ! -f "${SHARED_LIB_PATH}" ]]; then
echo "${HCOM_LOG_TAG} failed to locate libhcom.so in bazel outputs"
exit 1
fi
if [[ -z "${STATIC_LIB_PATH}" || ! -f "${STATIC_LIB_PATH}" ]]; then
echo "${HCOM_LOG_TAG} failed to locate libhcom static archive (a/pic.a/lo/pic.lo) in bazel outputs"
"${BAZEL_BIN}" cquery "${BAZEL_FLAGS[@]}" --output=files //src/hcom:hcom_static || true
exit 1
fi
if [[ -z "${BOUNDSCHECK_SO_PATH}" || ! -f "${BOUNDSCHECK_SO_PATH}" ]]; then
echo "${HCOM_LOG_TAG} failed to locate libboundscheck.so in bazel outputs"
"${BAZEL_BIN}" cquery "${BAZEL_FLAGS[@]}" --output=files //src:libboundscheck.so || true
exit 1
fi
cp -f "${SHARED_LIB_PATH}" "${HCOM_INSTALL_DIR}/lib/libhcom.so.${HCOM_LIB_VERSION}"
ln -sfn "libhcom.so.${HCOM_LIB_VERSION}" "${HCOM_INSTALL_DIR}/lib/libhcom.so.${HCOM_SOVERSION}"
ln -sfn "libhcom.so.${HCOM_SOVERSION}" "${HCOM_INSTALL_DIR}/lib/libhcom.so"
cp -f "${STATIC_LIB_PATH}" "${HCOM_INSTALL_DIR}/lib/libhcom_static.a"
cp -f "${BOUNDSCHECK_SO_PATH}" "${HCOM_INSTALL_DIR}/lib/libboundscheck.so"
for header in "${HCOM_ROOT_DIR}"/src/hcom/hcom*.h; do
[[ -f "${header}" ]] && cp -f "${header}" "${HCOM_INSTALL_DIR}/include/hcom/"
done
declare -a HCOM_SERVICE_HEADERS=(
"${HCOM_ROOT_DIR}/src/hcom/service_v2/api/hcom_service_channel.h"
"${HCOM_ROOT_DIR}/src/hcom/service_v2/api/hcom_service_def.h"
"${HCOM_ROOT_DIR}/src/hcom/service_v2/api/hcom_service_context.h"
"${HCOM_ROOT_DIR}/src/hcom/service_v2/api/hcom_service.h"
)
declare -a HCOM_CAPI_HEADERS=(
"${HCOM_ROOT_DIR}/src/hcom/api/capi_v2/hcom_c.h"
"${HCOM_ROOT_DIR}/src/hcom/api/capi_v2/hcom_service_c.h"
)
local_header=""
for local_header in "${HCOM_SERVICE_HEADERS[@]}"; do
copy_if_exists "${local_header}" "${HCOM_INSTALL_DIR}/include/hcom/" "service header"
done
for local_header in "${HCOM_CAPI_HEADERS[@]}"; do
copy_if_exists "${local_header}" "${HCOM_INSTALL_DIR}/include/hcom/capi/" "capi header"
done
copy_if_exists_silent "${HCOM_ROOT_DIR}/src/hcom/api/capi/hcom_cgo_c.h" "${HCOM_INSTALL_DIR}/include/hcom/capi/"
if [[ "${HCOM_BUILD_MULTICAST,,}" == "on" ]]; then
mkdir -p "${HCOM_INSTALL_DIR}/include/hcom/multicast"
for header in "${HCOM_ROOT_DIR}"/src/hcom/multicast/include/multicast*.h; do
[[ -f "${header}" ]] && cp -f "${header}" "${HCOM_INSTALL_DIR}/include/hcom/multicast/"
done
fi
verify_hcom_install_layout
if [[ "${HCOM_BUILD_TESTS,,}" == "on" ]]; then
run_hcom_test_build_fallback
fi
HCOM_COMPONENT_VERSION="${HCOM_COMPONENT_VERSION}" \
HCOM_BUILD_RPM="${HCOM_BUILD_RPM}" \
HCOM_BUILD_TOOLS_PERF="${HCOM_BUILD_TOOLS_PERF}" \
HCOM_BUILD_MULTICAST="${HCOM_BUILD_MULTICAST}" \
HCOM_BUILD_JAVA_SDK="${HCOM_BUILD_JAVA_SDK}" \
HCOM_CI_WORKSPACE="${HCOM_CI_WORKSPACE}" \
bash "${HCOM_ROOT_DIR}/build/make_software_package.sh" -t "${HCOM_BUILD_TYPE}"
[[ "${HCOM_BUILD_EXAMPLE,,}" == "on" ]] && bash "${HCOM_ROOT_DIR}/build/build_example_perf.sh"
echo "${HCOM_LOG_TAG} $0 succeeds"