341 lines
10 KiB
Bash
Executable File
341 lines
10 KiB
Bash
Executable File
#!/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
|