Starrocks BE 在Mac编译以及遇到的问题解决

背景

本文基于Starrocks 4.x

在机器 Apple M5 MacOS Tahoe 26 系统上进行编译,

对于Starrocks来说是不支持直接在 mac上进行编译的,如果你直接进行build的话,你就会遇到意想不到的问题。

所以我们转换一种思路,那就是本地下载starrocks源码,之后挂载源码到docker中,在容器中,用linux进行编译。也就是Compile StarRocks with Docker 这里所说的。

这里说到了两个linux系统,一种是Ubuntu 一种 是CentOS,分别用这两个系统来操作的话,也是会有区别的,这里我们来实操一下

基于centos

按照官网所说的,我们我们 checkout branch-4.1 分支,以及用挂载的方式去运行一个容器:

复制代码
docker run -it -v /Users/ljh/github/starrocks/.m2:/root/.m2 \
    -v /Users/ljh/github/starrocks:/root/starrocks \
    --name branch-4.1 -d starrocks/dev-env-centos7:4.1-latest

之后用docker exec -it进入容器,运行如下命令

复制代码
cd /root/starrocks
./build.sh 

运行一段时间后你会发现,你就会发现遇到类似这样的错误(由于branch和镜像的变动,问题细节可能不一样):

复制代码
 root/starrocks/be/src/util/thrift_util.cpp: In function 'void starrocks::init_thrift_logging()':
/root/starrocks/be/src/util/thrift_util.cpp:105:30: error: 'instance' is not a member of 'apache::thrift::TOutput'
  105 |     apache::thrift::TOutput::instance().setOutputFunction(thrift_output_function);
      |                              ^~~~~~~~
/root/starrocks/be/src/util/thrift_util.cpp: At global scope:
/root/starrocks/be/src/util/thrift_util.cpp:100:13: warning: 'void starrocks::thrift_output_function(const char*)' defined but not used [-Wunused-function]
  100 | static void thrift_output_function(const char* output) {
      |             ^~~~~~~~~~~~~~~~~~~~~~
make[2]: *** [src/util/CMakeFiles/Util.dir/thrift_util.cpp.o] Error 1
make[1]: *** [src/util/CMakeFiles/Util.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....

这种问题的根因就是项目中的thrift 版本和 docker容器中/var/local/thirdparty/installed/thrift的版本不一样,这就导致了版本不一致导致的类不存在的问题。

这个时候,如果你能够把这些版本弄一致了(通过cherry-pick或者revert),你可以继续往下编译。

编译一段时间你就会发现,另一个问题:

复制代码
g++: fatal error: Killed signal terminated program cc1plus
compilation terminated.

这种表示,编译的时候的内存不足,这个时候就要调整容器的内存,我这里调整到了16GB。继续编译,编译到99%的时候,就差临门一脚了,你发现又一个问题出现了:

复制代码
[ 99%] Linking CXX executable /root/starrocks/be/output/lib/starrocks_be
collect2: fatal error: ld terminated with signal 9 [Killed]
compilation terminated.

这个问题,你再编译多少次,都会绕不过,所以我们这里选择参考使用lld,lld相比ld有速度和节约内存的优势。所以我们这里去下载lld,

复制代码
[root@8f94d38faa24 installed]# yum install epel-release
[root@8f94d38faa24 installed]# yum install lld
Loaded plugins: fastestmirror, ovl
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * epel: ftp.iij.ad.jp
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
No package lld available.
Error: Nothing to do

搜索以后发现centos已经已经全面停止维护(EOL),官方技术支持已于 2024年6月30日 结束。所以基于这点考虑,我们重新用Ubuntu 继续进行编译。

ubuntu编译

由于前面branch-4.1的分支和镜像的第三方包中thrift版本的不一致问题,这次我们checkout branch-4.0:

复制代码
docker run -it -v /Users/ljh/github/starrocks/.m2:/root/.m2 \
    -v /Users/ljh/github/starrocks:/root/starrocks \
    --name branch-4.0 -d starrocks/dev-env-ubuntu:4.0-latest

之后用docker exec -it进入容器,这里的thrift的版本就是0.20.0(和项目的thrift的版本一致)

而且为了避免centos编译过程中的内存不足问题,所以这里我们采用了lld链接器.而且我们用了clang来做编译:

复制代码
apt update
apt install clang

最终运行如下命令:

复制代码
cd /root/starrocks
CC=clang CXX=clang++ STARROCKS_LINKER=lld ./build.sh --clean --be

这里运行一段时间后,又会出现如下问题:

复制代码
/root/starrocks/be/src/exprs/arithmetic_expr.cpp:47:35: error: unused function 'eliminate_trivial_cast_for_decimal_mul' [-Werror,-Wunused-function]

之后我们使用export STARROCKS_CXX_COMMON_FLAGS="-Wno-unused-function"这种方式去规避,也还是不行。

这个问题出现的原因就是: Clang 把"未使用的 static 函数"当成错误(-Werror,-Wunused-function)导致的,根因是 条件编译不一致。

eliminate_trivial_cast_for_decimal_mul 只在 evaluate_decimal_fast_mul 里被调用,而后者又只在下面这段条件里被用到:

复制代码
arithmetic_expr.cpp
Lines 106-113
#if defined(__x86_64__) && defined(__GNUC__)
        if constexpr (is_mul_op<OP> && lt_is_decimal<Type>) {
            ASSIGN_OR_RETURN(auto opt_result, evaluate_decimal_fast_mul(context, ptr));
            if (opt_result != nullptr) {
                return opt_result;
            }
        }
#endif

但 函数定义本身没有包在同样的 #if 里:

复制代码
arithmetic_expr.cpp
Lines 47-64

static std::optional<LogicalType> eliminate_trivial_cast_for_decimal_mul(const Expr* e) {
    ...
}

因为我这边uname -m出来的是aarch64,因为这里的条件编译是x86_64, 所以会导致这个问题。

注意:aarch64,x86_64是两种完全不同底层的CPU架构。

最终我们修改源码去规避这个问题,修改如下:

复制代码
iff --git a/be/src/exprs/arithmetic_expr.cpp b/be/src/exprs/arithmetic_expr.cpp
index 9de00c34e1..7caf5303d2 100644
--- a/be/src/exprs/arithmetic_expr.cpp
+++ b/be/src/exprs/arithmetic_expr.cpp
@@ -44,6 +44,7 @@ namespace starrocks {
                                                       \
     virtual Expr* clone(ObjectPool* pool) const override { return pool->add(new CLASS_NAME(*this)); }

+#if defined(__x86_64__) && defined(__GNUC__)
 static std::optional<LogicalType> eliminate_trivial_cast_for_decimal_mul(const Expr* e) {
     DIAGNOSTIC_PUSH
 #if defined(__GNUC__) && !defined(__clang__)
@@ -62,12 +63,14 @@ static std::optional<LogicalType> eliminate_trivial_cast_for_decimal_mul(const E
     }
     DIAGNOSTIC_POP
 }
+#endif

 template <LogicalType Type, typename OP>
 class VectorizedArithmeticExpr final : public Expr {
 public:
     DEFINE_CLASS_CONSTRUCTOR(VectorizedArithmeticExpr);

+#if defined(__x86_64__) && defined(__GNUC__)
     StatusOr<ColumnPtr> evaluate_decimal_fast_mul(ExprContext* context, Chunk* chunk) {
         auto lhs_lt_opt = eliminate_trivial_cast_for_decimal_mul(_children[0]);
         auto rhs_lt_opt = eliminate_trivial_cast_for_decimal_mul(_children[1]);
@@ -101,6 +104,7 @@ public:
         }
         return nullptr;
     }
+#endif

     StatusOr<ColumnPtr> evaluate_checked(ExprContext* context, Chunk* ptr) override {
 #if defined(__x86_64__) && defined(__GNUC__)
diff --git a/be/src/storage/rowset/binary_plain_page.cpp b/be/src/storage/rowset/binary_plain_page.cpp
index d54669167e..615a4e3b98 100644
--- a/be/src/storage/rowset/binary_plain_page.cpp
+++ b/be/src/storage/rowset/binary_plain_page.cpp
@@ -157,9 +157,9 @@ template <LogicalType Type>
 void BinaryPlainPageDecoder<Type>::batch_string_at_index(Slice* dst, const int32_t* idx, size_t size) const {
     if (_parsed_datas.has_value()) {
         const std::vector<Slice>& parsed_data = *_parsed_datas;
+#ifdef __SSE4_2__
         const Slice* parsed_data_ptr = parsed_data.data();
         static_assert(sizeof(Slice) == sizeof(__int128));
-#ifdef __SSE4_2__
 #pragma GCC unroll 2
         for (int i = 0; i < size; ++i) {
             DCHECK_LT(idx[i], parsed_data.size());

最终保险起见,我们还是使用默认的gcc编译器:

复制代码
STARROCKS_LINKER=lld ./build.sh 

最终成功了。

总结

所以这一路下来还是挺波折的。因为BE的编译本来就消耗时间,而且中间还遇到很多的问题,前前后后花了2天时间才真正的编译成功。

相关推荐
特立独行的猫a2 小时前
Fast DDS & Fast DDS Spy Windows x64 编译安装完全指南
windows·编译·安装·fastdds·fastddsspy
带娃的IT创业者3 天前
MLX-VLM:在Mac上解锁视觉语言模型的本地推理与微调能力
人工智能·macos·语言模型·mac·视觉语言模型·mlx·本地推理
新刘海6 天前
MacBook网络已连接却上不了网
mac
周淳APP7 天前
【前端工程化原理通识:从源头到运行时的理论阐述】
前端·编译·打包·前端工程化
想ai抽7 天前
StarRocks 存储引擎设计深度调研笔记
大数据·starrocks·olap
胖胖胖胖胖虎8 天前
okhttp Stream Load 含认证请求重定向
starrocks·okhttp
涤生大数据8 天前
Doris/StarRocks 高频面试题通关指南
大数据·starrocks·数仓·数据科学·大数据开发·diris
Mininglamp_271810 天前
开源端侧 AI Agent 全栈架构解析:Mano-P 模型 + Cider 推理加速 + AFK 自动构建
人工智能·架构·开源·agent·mac·apple silicon·gui agent
StarRocks_labs12 天前
白天查数、凌晨跑批:聚水潭如何基于 StarRocks 将资源利用率提升 3x
starrocks·saas·query·存算一体·warehouse