2026-04-02 08:59:26 +08:00

341 lines
10 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# ============================================================================
# DetectHole 编译脚本 (Linux/macOS)
# ============================================================================
set -e # 遇到错误立即退出
# 锚定到脚本所在目录
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
cd "$SCRIPT_DIR"
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 默认参数
BUILD_TYPE="Release"
RUN_TESTS=0
CLEAN=0
ENABLE_OPENMP="OFF"
INSTALL=0
BUILD_EXAMPLES="ON"
EIGEN_HINT=""
EIGEN3_DIR_HINT=""
BUILD_DIR="" # 将根据 BUILD_TYPE 自动设置
# 交叉编译工具链
CROSS_TOOLCHAIN="/usr/gcc/linux-x86/arm/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu"
CROSS_PREFIX="${CROSS_TOOLCHAIN}/bin/aarch64-none-linux-gnu"
# 显示帮助信息
show_help() {
echo "用法: ./build.sh [选项]"
echo ""
echo "选项:"
echo " debug 使用 Debug 模式编译 (默认: Release)"
echo " release 使用 Release 模式编译"
echo " test 编译后运行测试"
echo " clean 清理构建目录后重新编译"
echo " openmp 启用 OpenMP 并行支持"
echo " example 编译示例程序 (默认开启)"
echo " no-example 不编译示例程序"
echo " install 编译后安装到系统"
echo " --eigen <path> 指定 Eigen 库路径"
echo " help 显示此帮助信息"
echo ""
echo "示例:"
echo " ./build.sh # Release 模式编译"
echo " ./build.sh debug # Debug 模式编译(使用 build-debug 目录)"
echo " ./build.sh release test # Release 模式编译并运行测试"
echo " ./build.sh clean # 清理当前构建类型的目录"
echo " ./build.sh debug clean # 清理 Debug 构建目录"
echo " ./build.sh openmp test # 启用 OpenMP 并运行测试"
echo " ./build.sh no-example # 不编译示例程序"
echo " ./build.sh install # 编译并安装到系统"
echo " ./build.sh --eigen /opt/eigen-3.4.0 # 使用自定义 Eigen 路径"
echo ""
echo "构建目录:"
echo " Release: build/"
echo " Debug: build-debug/"
echo ""
echo "Eigen 路径说明:"
echo " --eigen 参数支持以下格式:"
echo " 1. Eigen 安装根目录 (包含 share/eigen3/cmake/Eigen3Config.cmake)"
echo " 2. CMake Config 文件目录 (直接包含 Eigen3Config.cmake)"
echo " 3. lib/cmake/eigen3 目录 (包含 Eigen3Config.cmake)"
echo ""
echo " 脚本会自动在以下位置查找 Eigen3Config.cmake:"
echo " - <path>/Eigen3Config.cmake"
echo " - <path>/share/eigen3/cmake/Eigen3Config.cmake"
echo " - <path>/lib/cmake/eigen3/Eigen3Config.cmake"
echo ""
exit 0
}
# 解析命令行参数
while [[ $# -gt 0 ]]; do
case $1 in
debug)
BUILD_TYPE="Debug"
shift
;;
release)
BUILD_TYPE="Release"
shift
;;
test)
RUN_TESTS=1
shift
;;
clean)
CLEAN=1
shift
;;
openmp)
ENABLE_OPENMP="ON"
shift
;;
install)
INSTALL=1
shift
;;
example)
BUILD_EXAMPLES="ON"
shift
;;
no-example)
BUILD_EXAMPLES="OFF"
shift
;;
--eigen)
if [[ -z "$2" ]]; then
echo -e "${RED}[错误]${NC} --eigen 需要一个路径参数"
exit 1
fi
EIGEN_HINT="$2"
shift 2
;;
--eigen=*)
EIGEN_HINT="${1#*=}"
shift
;;
help|-h|--help)
show_help
;;
*)
echo -e "${RED}[错误]${NC} 未知选项: $1"
echo "使用 './build.sh help' 查看帮助"
exit 1
;;
esac
done
# 解析 Eigen3_DIR 如果用户提供了 Config package 位置/前缀
if [[ -n "$EIGEN_HINT" ]]; then
if [[ -f "$EIGEN_HINT/Eigen3Config.cmake" ]]; then
EIGEN3_DIR_HINT="$EIGEN_HINT"
elif [[ -f "$EIGEN_HINT/share/eigen3/cmake/Eigen3Config.cmake" ]]; then
EIGEN3_DIR_HINT="$EIGEN_HINT/share/eigen3/cmake"
elif [[ -f "$EIGEN_HINT/lib/cmake/eigen3/Eigen3Config.cmake" ]]; then
EIGEN3_DIR_HINT="$EIGEN_HINT/lib/cmake/eigen3"
fi
fi
# 显示标题
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}DetectHole 编译脚本${NC}"
echo -e "${BLUE}========================================${NC}"
echo ""
# 设置构建目录Debug 和 Release 使用不同目录)
if [ "$BUILD_TYPE" = "Debug" ]; then
BUILD_DIR="build-debug"
else
BUILD_DIR="build-release"
fi
# 显示配置
echo -e "${GREEN}构建类型:${NC} $BUILD_TYPE"
echo -e "${GREEN}构建目录:${NC} $BUILD_DIR"
echo -e "${GREEN}OpenMP:${NC} $ENABLE_OPENMP"
echo -e "${GREEN}编译示例:${NC} $BUILD_EXAMPLES"
echo -e "${GREEN}运行测试:${NC} $RUN_TESTS"
echo -e "${GREEN}安装:${NC} $INSTALL"
echo ""
# 检查依赖
echo -e "${YELLOW}[检查]${NC} 检查依赖..."
# 检查 CMake
if ! command -v cmake &> /dev/null; then
echo -e "${RED}[错误]${NC} 未找到 CMake"
echo "请安装 CMake 3.10 或更高版本:"
echo " Ubuntu/Debian: sudo apt-get install cmake"
echo " macOS: brew install cmake"
exit 1
fi
CMAKE_VERSION=$(cmake --version | head -n1 | awk '{print $3}')
echo -e "${GREEN}${NC} CMake $CMAKE_VERSION"
# 检查交叉编译器
if [ -x "${CROSS_PREFIX}-g++" ]; then
GCC_VERSION=$("${CROSS_PREFIX}-g++" --version | head -n1)
echo -e "${GREEN}${NC} $GCC_VERSION"
else
echo -e "${RED}[错误]${NC} 未找到交叉编译器: ${CROSS_PREFIX}-g++"
echo "请确认工具链路径正确: ${CROSS_TOOLCHAIN}"
exit 1
fi
# 检查 Eigen3
if [ -d "/usr/include/eigen3" ] || [ -d "/usr/local/include/eigen3" ] || [ -d "/opt/homebrew/include/eigen3" ]; then
echo -e "${GREEN}${NC} Eigen3"
else
echo -e "${YELLOW} ?${NC} Eigen3 (可能未安装CMake 将尝试查找)"
echo "如果编译失败,请安装 Eigen3"
echo " Ubuntu/Debian: sudo apt-get install libeigen3-dev"
echo " macOS: brew install eigen"
fi
echo ""
# 清理构建目录
if [ $CLEAN -eq 1 ]; then
echo -e "${YELLOW}[1/4]${NC} 清理构建目录..."
if [ -d "$BUILD_DIR" ]; then
rm -rf "$BUILD_DIR"
echo -e "${GREEN}${NC} 已删除 $BUILD_DIR 目录"
fi
echo ""
fi
# 创建构建目录
echo -e "${YELLOW}[1/4]${NC} 创建构建目录..."
mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"
echo ""
# 配置 CMake
echo -e "${YELLOW}[2/4]${NC} 配置 CMake..."
# 构建 CMake 参数数组(避免命令注入)
cmake_args=(.. -DCMAKE_BUILD_TYPE="$BUILD_TYPE" -DENABLE_OPENMP="$ENABLE_OPENMP"
-DBUILD_EXAMPLES="$BUILD_EXAMPLES"
-DCMAKE_C_COMPILER="${CROSS_PREFIX}-gcc"
-DCMAKE_CXX_COMPILER="${CROSS_PREFIX}-g++"
)
if [[ -n "$EIGEN3_DIR_HINT" ]]; then
echo -e "${GREEN}使用自定义 Eigen 路径:${NC} $EIGEN3_DIR_HINT"
cmake_args+=(-DEigen3_DIR="$EIGEN3_DIR_HINT")
elif [[ -n "$EIGEN_HINT" ]]; then
echo -e "${GREEN}使用自定义 Eigen 前缀:${NC} $EIGEN_HINT"
cmake_args+=(-DCMAKE_PREFIX_PATH="$EIGEN_HINT")
fi
if ! cmake "${cmake_args[@]}"; then
echo ""
echo -e "${RED}[错误]${NC} CMake 配置失败!"
echo "请检查:"
echo " 1. 是否安装了 CMake (3.10+)"
echo " 2. 是否安装了 Eigen3"
if [[ -n "$EIGEN_HINT" ]]; then
echo " 3. 指定的 Eigen 路径是否包含 Eigen3Config.cmake"
echo " 查找位置:"
echo " - $EIGEN_HINT/Eigen3Config.cmake"
echo " - $EIGEN_HINT/share/eigen3/cmake/Eigen3Config.cmake"
echo " - $EIGEN_HINT/lib/cmake/eigen3/Eigen3Config.cmake"
fi
echo " 4. 是否配置了正确的编译器"
cd ..
exit 1
fi
echo ""
# 编译项目
echo -e "${YELLOW}[3/4]${NC} 编译项目..."
NPROC=$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)
echo -e "${GREEN} 使用 $NPROC 个并行任务${NC}"
if ! cmake --build . --config $BUILD_TYPE -- -j$NPROC; then
echo ""
echo -e "${RED}[错误]${NC} 编译失败!"
cd ..
exit 1
fi
echo ""
# 运行测试
if [ $RUN_TESTS -eq 1 ]; then
echo -e "${YELLOW}[4/4]${NC} 运行测试..."
if ctest --output-on-failure -C $BUILD_TYPE; then
echo ""
echo -e "${GREEN}[成功]${NC} 所有测试通过!"
else
echo ""
echo -e "${YELLOW}[警告]${NC} 部分测试失败!"
fi
else
echo -e "${YELLOW}[4/4]${NC} 跳过测试 (使用 './build.sh test' 运行测试)"
fi
echo ""
cd ..
# 安装
if [ $INSTALL -eq 1 ]; then
echo -e "${YELLOW}[安装]${NC} 安装到系统..."
cd build
if sudo cmake --install .; then
echo -e "${GREEN}[成功]${NC} 安装完成!"
else
echo -e "${RED}[错误]${NC} 安装失败!"
cd ..
exit 1
fi
cd ..
echo ""
fi
# 显示成功信息
echo -e "${BLUE}========================================${NC}"
echo -e "${GREEN}编译成功!${NC}"
echo -e "${BLUE}========================================${NC}"
echo ""
echo "构建产物:"
echo " - $BUILD_DIR/libHoleDetectionLib.so (共享库)"
if [ "$BUILD_TYPE" = "Debug" ]; then
echo " - Export/arm/debug/libHoleDetectionLib.so* (导出的 Debug 库)"
else
echo " - Export/arm/release/libHoleDetectionLib.so* (导出的 Release 库)"
fi
echo " - Export/include/*.h (导出的头文件)"
if [ "$BUILD_EXAMPLES" = "ON" ]; then
echo " - $BUILD_DIR/examples/ (示例程序)"
fi
echo ""
if [ "$BUILD_TYPE" = "Debug" ]; then
echo "Debug 模式:"
echo " - 包含调试符号,未优化"
echo " - 适合开发和调试"
echo " - 库文件位置: Export/arm/debug/"
else
echo "Release 模式:"
echo " - 已优化(-O3无调试符号"
echo " - 适合生产环境"
echo " - 库文件位置: Export/arm/release/"
fi
echo ""
echo "注意:"
echo " 可视化功能需要 Linux 版本的 VTK 库"
echo " 当前 3rdparty/VTK-8.2.0 是 Windows 版本"
echo " 如需可视化,请安装系统 VTK: sudo apt-get install libvtk7-dev"
echo ""
exit 0