欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > 解析Doris编译脚本generated-source.sh的逻辑

解析Doris编译脚本generated-source.sh的逻辑

2025/3/13 21:53:43 来源:https://blog.csdn.net/zpf_940810653842/article/details/146199184  浏览:    关键词:解析Doris编译脚本generated-source.sh的逻辑

编译脚本调用关系

build.sh
env.sh
build-thirdparty.sh
vars.sh
download-thirdparty.sh
generated-source.sh
build_help_zip.sh

以下是对该Shell脚本逻辑的详细解析:

1. 脚本基础信息

#!/usr/bin/env bash
# Licensed to the Apache Software Foundation (ASF) under one
# ... 省略许可证信息 ...

作用:
• 声明使用Bash解释器执行
• 添加Apache 2.0许可证声明,明确代码使用权限

2. 环境初始化与错误处理

set -eo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
export DORIS_HOME="${ROOT}"

关键点:
set -eo pipefail:严格错误处理,任何命令失败或管道错误立即终止脚本
ROOT:通过dirname ${BASH_SOURCE[0]}获取脚本所在绝对路径
DORIS_HOME:设置为项目根目录,供后续步骤引用

3. 加载环境配置

. "${DORIS_HOME}/env.sh"

作用:
• 加载env.sh文件,初始化编译环境变量(如JAVA_HOME、Maven路径等)
• 确保构建工具和依赖库路径正确

4. 生成代码主逻辑

echo "Build generated code"
cd "${DORIS_HOME}/gensrc"

步骤:
• 输出提示信息,标识开始生成代码
• 进入gensrc目录(生成代码专用目录)

5. 清理旧构建(条件判断)

if [[ "$#" == 0 ]]; thenecho "rm -rf ${DORIS_HOME}/gensrc/build"rm -rf "${DORIS_HOME}/gensrc/build"
fi

逻辑分支:
无参数调用:删除gensrc/build目录,确保干净构建环境
带参数调用(如通过build.sh --clean):跳过清理,由上层脚本处理
意义:避免残留旧生成文件导致冲突

6. 执行代码生成

make

关键点:
• 调用Makefile执行代码生成任务(如Thrift、Parquet等接口生成)
• 禁止并行编译(注释提示),确保生成顺序正确

7. 清理旧生成的Java代码

rm -rf "${DORIS_HOME}/fe/fe-common/src/main/java/org/apache/doris/thrift"
rm -rf "${DORIS_HOME}/fe/fe-common/src/main/java/org/apache/parquet"
rm -rf "${DORIS_HOME}/fe/fe-core/src/main/java/org/apache/doris/thrift" 
rm -rf "${DORIS_HOME}/fe/fe-core/src/main/java/org/apache/parquet"

作用:
• 删除FE模块中旧的Thrift和Parquet生成的Java代码
• 避免新旧代码混杂导致编译错误

8. 复制新生成代码到FE模块

cp -r "build/gen_java/org/apache/doris/thrift" "${DORIS_HOME}/fe/fe-common/src/main/java/org/apache/doris"
cp -r "build/gen_java/org/apache/parquet" "${DORIS_HOME}/fe/fe-common/src/main/java/org/apache/"

操作:
• 将新生成的Thrift代码复制到fe-common模块
• 将新生成的Parquet代码复制到fe-common模块
• 保持Java包结构(org.apache.doris等)

9. 收尾与输出

cd "${DORIS_HOME}/"
echo "Done"
exit 0

收尾工作:
• 返回项目根目录
• 输出完成提示
• 退出码0表示成功

附:典型使用场景

  1. 独立运行:
    ./gensrc.sh  # 清理build目录 + 生成代码
    
  2. 整合到构建流程:
    ./build.sh --clean  # 触发gensrc.sh时不清理build
    

技术亮点

条件清理机制:通过参数判断是否清理,提升与上层脚本的协作效率
严格错误处理set -eo pipefail确保任何步骤失败立即终止
路径管理:动态计算DORIS_HOME,增强脚本可移植性

潜在注意事项

依赖正确性:需确保env.sh正确配置环境变量(如Thrift编译器路径)
Makefile内容:实际生成逻辑由gensrc/Makefile定义,需与其配合
目录权限:需有权限写入fe-common等目标目录

10. 代码

#!/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.##############################################################
# This script is used to generate generated source code
##############################################################
# 命令行执行异常退出
set -eo pipefailROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"export DORIS_HOME="${ROOT}". "${DORIS_HOME}/env.sh"echo "Build generated code"
cd "${DORIS_HOME}/gensrc"# 如果从build.sh调用,则不需要清理build/目录。
# 使用`build.sh --clean`删除。
# 单独运行这个脚本会删除 build/ 目录.
if [[ "$#" == 0 ]]; thenecho "rm -rf ${DORIS_HOME}/gensrc/build"rm -rf "${DORIS_HOME}/gensrc/build"
fi# 不要使用 make(-j)并发构建 for gensrc
# make内容见下面Makefile
make
rm -rf "${DORIS_HOME}/fe/fe-common/src/main/java/org/apache/doris/thrift ${DORIS_HOME}/fe/fe-common/src/main/java/org/apache/parquet"
rm -rf "${DORIS_HOME}/fe/fe-core/src/main/java/org/apache/doris/thrift ${DORIS_HOME}/fe/fe-core/src/main/java/org/apache/parquet"cp -r "build/gen_java/org/apache/doris/thrift" "${DORIS_HOME}/fe/fe-common/src/main/java/org/apache/doris"
cp -r "build/gen_java/org/apache/parquet" "${DORIS_HOME}/fe/fe-common/src/main/java/org/apache/"
cd "${DORIS_HOME}/"
echo "Done"
exit 0

11. Makefile

# 用于生成fe和be所需要的所有文件。
# 定义构建输出目录为当前目录下的 build/ 目录,${CURDIR} 是 Make 的内置变量,表示当前目录的绝对路径
BUILD_DIR = ${CURDIR}/build/
# 执行 make 或 make all 时触发子目录构建
all: subdirs
.PHONY: all# build all subdir
SUBDIR = script proto thrift
subdirs: ${SUBDIR}
.PHONY: subdirs ${SUBDIR}
# 每个子目录目标规则:进入目录并执行 make(递归构建)
${SUBDIR}:$(MAKE) -C $@
# 声明 thrift 目录的构建依赖于 script 目录先完成
thrift: scriptclean:rm -rf ${BUILD_DIR}
.PHONY: clean

script Makefile

# generate files with python
# BUILD_DIR: 构建输出目录,位于当前目录的上级 build/ 下
BUILD_DIR = ${CURDIR}/../build/
# FE_TARGET_DIR: FE模块生成的Java代码存放路径
FE_TARGET_DIR = ${CURDIR}/../../fe/fe-core/target/generated-sources/build# Prerequisites on the right side of '|' is only order
# 默认目标 all 依赖 gen_builtins(生成内置函数)和 gen_version(生成版本信息)
all: gen_builtins gen_version
.PHONY: all
# 确保 ${BUILD_DIR}/python 目录存在
${BUILD_DIR}/python:mkdir -p $@# 在 build/python 目录下执行 gen_functions.py 生成代码
GEN_FUNC_OUTPUT = ${BUILD_DIR}/python/generated_functions.py \${BUILD_DIR}/gen_cpp/opcode/functions.cc \${BUILD_DIR}/gen_cpp/opcode/functions.h
${GEN_FUNC_OUTPUT}: gen_functions.py | ${BUILD_DIR}/pythoncd ${BUILD_DIR}/python && ${PYTHON} ${CURDIR}/gen_functions.py
gen_func: ${GEN_FUNC_OUTPUT}
.PHONY: gen_func# ScalarBuiltins.java: FE模块使用的内置函数Java类
GEN_BUILTINS_OUTPUT = ${FE_TARGET_DIR}/org/apache/doris/builtins/ScalarBuiltins.java
# 执行 gen_builtins_functions.py 生成Java代码
${GEN_BUILTINS_OUTPUT}: doris_builtins_functions.py gen_builtins_functions.py ${GEN_FUNC_OUTPUT} ${GEN_VEC_FUNC_OUTPUT}cd ${BUILD_DIR}/python && ${PYTHON} ${CURDIR}/gen_builtins_functions.py
gen_builtins: ${GEN_BUILTINS_OUTPUT}
.PHONY: gen_builtins# generate version info
gen_version:${CURDIR}/gen_build_version.sh
.PHONY: gen_version

protoc Makefile

# This file compile all protobuf files.
# BUILD_DIR: 构建输出目录,位于当前目录的上级 build/ 下
BUILD_DIR = ${CURDIR}/../build/
# PROTOC: Protobuf 编译器路径,依赖 Doris 第三方库中的 protoc 工具
PROTOC = ${DORIS_THIRDPARTY}/installed/bin/protoc
# SOURCES: 查找当前目录及子目录中所有 .proto 文件
SOURCES = $(shell find ${CURDIR} -name "*.proto")
# OBJECTS: 将 .proto 路径转换为 build/gen_cpp/xxx.pb.cc 路径
OBJECTS = $(patsubst ${CURDIR}/%.proto, ${BUILD_DIR}/gen_cpp/%.pb.cc, ${SOURCES})
# HEADERS: 生成对应的头文件路径 xxx.pb.h
HEADERS = $(patsubst ${CURDIR}/%.proto, ${BUILD_DIR}/gen_cpp/%.pb.h, ${SOURCES})
# JAVA_OBJECTS: 类似逻辑生成 Java 文件路径
JAVA_OBJECTS = $(patsubst ${CURDIR}/%.proto, ${BUILD_DIR}/java/org/apache/doris/proto/%.java, ${SOURCES})#all: ${JAVA_OBJECTS} ${OBJECTS} ${HEADERS}
all: ${JAVA_OBJECTS} ${OBJECTS} ${HEADERS}
.PHONY: all
# 调用 protoc 生成 C++ 代码到指定目录# --proto_path: 指定 .proto 文件的根目录# --cpp_out: 指定 C++ 输出目录# $<: 表示依赖的第一个文件(即 .proto 文件)
${BUILD_DIR}/gen_cpp/%.pb.h ${BUILD_DIR}/gen_cpp/%.pb.cc: ${CURDIR}/%.proto | ${BUILD_DIR}/gen_cpp${PROTOC} --proto_path=${CURDIR} --cpp_out=${BUILD_DIR}/gen_cpp $<
# 生成 Java 代码到 build/java 目录
${BUILD_DIR}/java/org/apache/doris/proto/%.java: ${CURDIR}/%.proto | ${BUILD_DIR}/java${PROTOC} --proto_path=${CURDIR} --java_out=${BUILD_DIR}/java/ $<${BUILD_DIR}/gen_cpp:mkdir -p $@#${BUILD_DIR}/java:
#	mkdir -p $@

thrift Makefile

# BUILD_DIR: 构建输出目录(上级目录的 build/)
BUILD_DIR = ${CURDIR}/../build/
# THRIFT: Thrift 编译器路径(来自 Doris 第三方依赖)
THRIFT = ${DORIS_THIRDPARTY}/installed/bin/thrift
# 手工编写的 Thrift 文件
SOURCES = $(shell find ${CURDIR} -name "*.thrift")
OBJECTS = $(patsubst ${CURDIR}/%.thrift, ${BUILD_DIR}/gen_cpp/%_types.cpp, ${SOURCES})
# 生成的 Thrift 文件(注释中存在错误,应为 ${BUILD_DIR}/thrift 目录),等下试试
GEN_SOURCES = $(shell find ${THRIFT} -name "*.thrift")
GEN_OBJECTS = $(patsubst ${BUILD_DIR}/thrift/%.thrift, ${BUILD_DIR}/gen_cpp/%_types.cpp, ${GEN_SOURCES})
# all 目标依赖手工编写和生成的 Thrift 文件编译结果
all: ${GEN_OBJECTS} ${OBJECTS}
.PHONY: all
# 解析阶段直接创建 Java 代码目录(无论目标是否需要)
$(shell mkdir -p ${BUILD_DIR}/gen_java)
# 参数解析:# -I: 添加 Thrift 文件搜索路径(当前目录 + 生成目录)# --gen cpp/java: 生成对应语言代码# -out: 输出目录# fullcamel: Java 类名使用驼峰命名# -strict: 严格模式(警告视为错误)
THRIFT_CPP_ARGS = -I ${CURDIR} -I ${BUILD_DIR}/thrift/ --gen cpp -out ${BUILD_DIR}/gen_cpp --allow-64bit-consts -strict
THRIFT_JAVA_ARGS = -I ${CURDIR} -I ${BUILD_DIR}/thrift/ --gen java:fullcamel -out ${BUILD_DIR}/gen_java --allow-64bit-consts -strict
# 目录创建规则
${BUILD_DIR}/gen_cpp:mkdir -p $@
# 手工编写的 Thrift 文件编译规则
${BUILD_DIR}/gen_cpp/%_types.cpp: ${CURDIR}/%.thrift | ${BUILD_DIR}/gen_cpp${THRIFT} ${THRIFT_CPP_ARGS} $<${THRIFT} ${THRIFT_JAVA_ARGS} $<# 生成的 Thrift 文件编译规则(需修复 GEN_SOURCES 路径)
${BUILD_DIR}/gen_cpp/%_types.cpp: ${BUILD_DIR}/thrift/%.thrift | ${BUILD_DIR}/gen_cpp${THRIFT} ${THRIFT_CPP_ARGS} $<${THRIFT} ${THRIFT_JAVA_ARGS} $<

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词