|
|
#!/usr/bin/env bash
|
|
|
set -euo pipefail
|
|
|
# ============================================================
|
|
|
# 比赛平台提交脚本
|
|
|
# 将 nudt-compiler-cpp 的优化代码同步到 warning 仓库,
|
|
|
# 自动处理平台兼容性修复,然后提交并推送
|
|
|
# ============================================================
|
|
|
|
|
|
RED='\033[0;31m'
|
|
|
GREEN='\033[0;32m'
|
|
|
YELLOW='\033[1;33m'
|
|
|
NC='\033[0m'
|
|
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
|
NUDT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
|
WARNING_DIR="/home/lzk/warning"
|
|
|
|
|
|
# 死代码文件(平台 flat 编译会报错)
|
|
|
DEAD_FILES=(
|
|
|
"src/mir/LinearScanAlloc.cpp"
|
|
|
"src/mir/GreedyAlloc.cpp"
|
|
|
"src/mir/InstLiveness.cpp"
|
|
|
)
|
|
|
|
|
|
usage() {
|
|
|
echo "用法: $0 [选项]"
|
|
|
echo ""
|
|
|
echo "选项:"
|
|
|
echo " -n, --dry-run 仅显示将要做的操作,不实际执行"
|
|
|
echo " -s, --skip-build 跳过本地构建验证"
|
|
|
echo " -p, --push 同步后直接推送(需要密码)"
|
|
|
echo " -m, --msg MSG 自定义 commit message(默认自动生成)"
|
|
|
echo " -h, --help 显示帮助"
|
|
|
echo ""
|
|
|
echo "工作流程: 同步 src → 删死代码 → 修复头文件 → 提交 → [推送]"
|
|
|
exit 0
|
|
|
}
|
|
|
|
|
|
DRY_RUN=false
|
|
|
SKIP_BUILD=false
|
|
|
DO_PUSH=false
|
|
|
CUSTOM_MSG=""
|
|
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
|
case "$1" in
|
|
|
-n|--dry-run) DRY_RUN=true; shift ;;
|
|
|
-s|--skip-build) SKIP_BUILD=true; shift ;;
|
|
|
-p|--push) DO_PUSH=true; shift ;;
|
|
|
-m|--msg) CUSTOM_MSG="$2"; shift 2 ;;
|
|
|
-h|--help) usage ;;
|
|
|
*) echo -e "${RED}未知选项: $1${NC}"; usage ;;
|
|
|
esac
|
|
|
done
|
|
|
|
|
|
# ============================================================
|
|
|
# 前置检查
|
|
|
# ============================================================
|
|
|
|
|
|
echo -e "${GREEN}=== 提交前检查 ===${NC}"
|
|
|
|
|
|
if [[ ! -d "$WARNING_DIR/.git" ]]; then
|
|
|
echo -e "${RED}错误: warning 仓库不存在: $WARNING_DIR${NC}"
|
|
|
exit 1
|
|
|
fi
|
|
|
|
|
|
# 检查 warning 仓库是否干净
|
|
|
if ! git -C "$WARNING_DIR" diff-index --quiet HEAD -- 2>/dev/null; then
|
|
|
echo -e "${YELLOW}警告: warning 仓库有未提交改动${NC}"
|
|
|
git -C "$WARNING_DIR" status --short
|
|
|
echo ""
|
|
|
read -rp "继续?(未提交改动将被覆盖)[y/N] " yn
|
|
|
if [[ "$yn" != "y" && "$yn" != "Y" ]]; then
|
|
|
echo "已取消"
|
|
|
exit 0
|
|
|
fi
|
|
|
fi
|
|
|
|
|
|
# 检查 nudt 的 src/ 是否有未提交改动(核心代码)
|
|
|
if ! git -C "$NUDT_DIR" diff --quiet HEAD -- src/ 2>/dev/null; then
|
|
|
echo -e "${YELLOW}警告: nudt/src/ 有未提交改动${NC}"
|
|
|
git -C "$NUDT_DIR" diff --stat HEAD -- src/
|
|
|
echo ""
|
|
|
read -rp "继续?(确认改动已保存)[y/N] " yn
|
|
|
if [[ "$yn" != "y" && "$yn" != "Y" ]]; then
|
|
|
echo "已取消"
|
|
|
exit 0
|
|
|
fi
|
|
|
fi
|
|
|
|
|
|
# ============================================================
|
|
|
# 第1步:同步源码
|
|
|
# ============================================================
|
|
|
|
|
|
step1_sync() {
|
|
|
echo -e "${GREEN}=== 第1步: 同步源码到 warning ===${NC}"
|
|
|
|
|
|
if $DRY_RUN; then
|
|
|
echo " [dry-run] rm -rf $WARNING_DIR/src/"
|
|
|
echo " [dry-run] cp -r $NUDT_DIR/src $WARNING_DIR/"
|
|
|
return
|
|
|
fi
|
|
|
|
|
|
rm -rf "$WARNING_DIR/src/"
|
|
|
cp -r "$NUDT_DIR/src" "$WARNING_DIR/"
|
|
|
|
|
|
# 同步 .gitignore(包含 T2025* 排除)
|
|
|
cp "$NUDT_DIR/.gitignore" "$WARNING_DIR/.gitignore"
|
|
|
|
|
|
echo " 源码已同步"
|
|
|
}
|
|
|
|
|
|
# ============================================================
|
|
|
# 第2步:删除死代码
|
|
|
# ============================================================
|
|
|
|
|
|
step2_deadcode() {
|
|
|
echo -e "${GREEN}=== 第2步: 删除死代码文件 ===${NC}"
|
|
|
|
|
|
for f in "${DEAD_FILES[@]}"; do
|
|
|
local path="$WARNING_DIR/$f"
|
|
|
if [[ -f "$path" ]]; then
|
|
|
if $DRY_RUN; then
|
|
|
echo " [dry-run] rm $path"
|
|
|
else
|
|
|
rm "$path"
|
|
|
echo " 已删除: $f"
|
|
|
fi
|
|
|
else
|
|
|
echo " 跳过(不存在): $f"
|
|
|
fi
|
|
|
done
|
|
|
}
|
|
|
|
|
|
# ============================================================
|
|
|
# 第3步:修复头文件路径
|
|
|
# ============================================================
|
|
|
|
|
|
step3_headers() {
|
|
|
echo -e "${GREEN}=== 第3步: 修复头文件路径 ===${NC}"
|
|
|
|
|
|
local old_dom="$WARNING_DIR/src/ir/analysis/DominatorTree.h"
|
|
|
local new_dom="$WARNING_DIR/src/include/ir/analysis/DominatorTree.h"
|
|
|
|
|
|
if [[ -f "$old_dom" ]]; then
|
|
|
if $DRY_RUN; then
|
|
|
echo " [dry-run] mv $old_dom → $new_dom"
|
|
|
else
|
|
|
mkdir -p "$(dirname "$new_dom")"
|
|
|
cp "$old_dom" "$new_dom"
|
|
|
rm "$old_dom"
|
|
|
echo " 已移动 DominatorTree.h → src/include/ir/analysis/"
|
|
|
fi
|
|
|
elif [[ -f "$new_dom" ]]; then
|
|
|
echo " DominatorTree.h 已在正确位置"
|
|
|
else
|
|
|
echo -e " ${YELLOW}警告: DominatorTree.h 不存在${NC}"
|
|
|
fi
|
|
|
|
|
|
# 删除残留的 ANTLR 头文件(如果从 build 目录带过来)
|
|
|
local stale_headers=(
|
|
|
"$WARNING_DIR/src/include/SysYLexer.h"
|
|
|
"$WARNING_DIR/src/include/SysYParser.h"
|
|
|
"$WARNING_DIR/src/include/SysYVisitor.h"
|
|
|
"$WARNING_DIR/src/include/SysYBaseVisitor.h"
|
|
|
)
|
|
|
# 这些头文件是需要的,不删。但确保它们和 build/generated 版本一致
|
|
|
}
|
|
|
|
|
|
# ============================================================
|
|
|
# 第4步:本地构建验证(可选)
|
|
|
# ============================================================
|
|
|
|
|
|
step4_verify() {
|
|
|
if $SKIP_BUILD; then
|
|
|
echo -e "${YELLOW}=== 第4步: 跳过本地构建验证 ===${NC}"
|
|
|
return
|
|
|
fi
|
|
|
|
|
|
echo -e "${GREEN}=== 第4步: 本地构建验证 ===${NC}"
|
|
|
|
|
|
if $DRY_RUN; then
|
|
|
echo " [dry-run] cmake + make"
|
|
|
return
|
|
|
fi
|
|
|
|
|
|
# 提取 ANTLR runtime
|
|
|
local antlr_zip="$WARNING_DIR/third_party/antlr4-runtime-4.13.2.zip"
|
|
|
local antlr_dir="$WARNING_DIR/third_party/antlr4-runtime-4.13.2"
|
|
|
if [[ -f "$antlr_zip" ]] && [[ ! -d "$antlr_dir/runtime" ]]; then
|
|
|
echo " 解压 ANTLR runtime..."
|
|
|
unzip -qo "$antlr_zip" -d "$antlr_dir/" 2>/dev/null || true
|
|
|
# 修复嵌套目录
|
|
|
if [[ -d "$antlr_dir/antlr4-runtime-4.13.2/runtime" ]]; then
|
|
|
mv "$antlr_dir/antlr4-runtime-4.13.2/runtime" "$antlr_dir/" 2>/dev/null || true
|
|
|
rm -rf "$antlr_dir/antlr4-runtime-4.13.2" 2>/dev/null || true
|
|
|
fi
|
|
|
fi
|
|
|
|
|
|
local build_dir="$WARNING_DIR/build_verify"
|
|
|
mkdir -p "$build_dir/generated/antlr4"
|
|
|
|
|
|
# ANTLR 代码生成
|
|
|
java -jar "$WARNING_DIR/third_party/antlr-4.13.2-complete.jar" \
|
|
|
-Dlanguage=Cpp -visitor -no-listener -Xexact-output-dir \
|
|
|
-o "$build_dir/generated/antlr4" \
|
|
|
"$WARNING_DIR/src/antlr4/SysY.g4" 2>&1 | tail -1
|
|
|
|
|
|
# CMake 构建
|
|
|
cmake -S "$WARNING_DIR" -B "$build_dir" \
|
|
|
-DCMAKE_BUILD_TYPE=Release -DCOMPILER_PARSE_ONLY=OFF 2>&1 | tail -1
|
|
|
|
|
|
if cmake --build "$build_dir" -j "$(nproc)" 2>&1 | tail -5; then
|
|
|
echo -e " ${GREEN}构建成功${NC}"
|
|
|
|
|
|
# 快速功能验证
|
|
|
local test_file="$NUDT_DIR/2026test/functional/00_main.sy"
|
|
|
if [[ -f "$test_file" ]]; then
|
|
|
if "$build_dir/bin/compiler" "$test_file" -S -o /tmp/submit_test.s 2>/dev/null; then
|
|
|
echo -e " ${GREEN}00_main 编译通过${NC}"
|
|
|
else
|
|
|
echo -e " ${RED}00_main 编译失败!${NC}"
|
|
|
fi
|
|
|
fi
|
|
|
else
|
|
|
echo -e " ${RED}构建失败!请修复后再提交${NC}"
|
|
|
exit 1
|
|
|
fi
|
|
|
|
|
|
# 清理验证构建目录
|
|
|
rm -rf "$build_dir"
|
|
|
}
|
|
|
|
|
|
# ============================================================
|
|
|
# 第5步:提交
|
|
|
# ============================================================
|
|
|
|
|
|
step5_commit() {
|
|
|
echo -e "${GREEN}=== 第5步: 提交 ===${NC}"
|
|
|
|
|
|
if $DRY_RUN; then
|
|
|
echo " [dry-run] git add -A && git commit"
|
|
|
return
|
|
|
fi
|
|
|
|
|
|
cd "$WARNING_DIR"
|
|
|
|
|
|
# 清理可能遗留的构建目录
|
|
|
rm -rf build_teammate build_clang build_verify
|
|
|
|
|
|
git add -A
|
|
|
|
|
|
if git diff-index --quiet HEAD --; then
|
|
|
echo " 没有改动需要提交"
|
|
|
return
|
|
|
fi
|
|
|
|
|
|
local commit_msg
|
|
|
if [[ -n "$CUSTOM_MSG" ]]; then
|
|
|
commit_msg="$CUSTOM_MSG"
|
|
|
else
|
|
|
local nudt_commit=$(git -C "$NUDT_DIR" log --oneline -1)
|
|
|
commit_msg="perf: 同步优化版编译器源码
|
|
|
|
|
|
$(git -C "$NUDT_DIR" log --oneline -5 | sed 's/^/ /')
|
|
|
|
|
|
自动提交: 删除死代码 + 修复头文件路径 + 同步优化"
|
|
|
fi
|
|
|
|
|
|
git commit -m "$commit_msg"
|
|
|
echo -e " ${GREEN}已提交${NC}"
|
|
|
git log --oneline -1
|
|
|
}
|
|
|
|
|
|
# ============================================================
|
|
|
# 第6步:推送
|
|
|
# ============================================================
|
|
|
|
|
|
step6_push() {
|
|
|
if ! $DO_PUSH; then
|
|
|
echo -e "${YELLOW}=== 跳过推送(使用 -p 启用) ===${NC}"
|
|
|
echo " 手动推送: cd $WARNING_DIR && git push origin main:lzk --force"
|
|
|
return
|
|
|
fi
|
|
|
|
|
|
echo -e "${GREEN}=== 推送 ===${NC}"
|
|
|
|
|
|
if $DRY_RUN; then
|
|
|
echo " [dry-run] git push origin main:lzk --force"
|
|
|
return
|
|
|
fi
|
|
|
|
|
|
cd "$WARNING_DIR"
|
|
|
git push origin main:lzk --force
|
|
|
echo -e " ${GREEN}推送完成${NC}"
|
|
|
}
|
|
|
|
|
|
# ============================================================
|
|
|
# 执行
|
|
|
# ============================================================
|
|
|
|
|
|
echo ""
|
|
|
step1_sync
|
|
|
step2_deadcode
|
|
|
step3_headers
|
|
|
step4_verify
|
|
|
step5_commit
|
|
|
step6_push
|
|
|
|
|
|
echo ""
|
|
|
echo -e "${GREEN}=== 完成 ===${NC}"
|
|
|
echo " 平台地址: https://compiler.xtnl.org.cn/#/"
|
|
|
echo " 登录后触发功能/性能测试"
|