| #!/bin/bash |
| set -euo pipefail |
|
|
| |
| info() { echo -e "\033[1;34m[INFO]\033[0m $*"; } |
| warn() { echo -e "\033[1;33m[WARN]\033[0m $*"; } |
| error() { echo -e "\033[1;31m[ERROR]\033[0m $*" >&2; exit 1; } |
|
|
| |
| check_requirements() { |
| local missing_tools=() |
|
|
| |
| for tool in cargo protoc npm node; do |
| if ! command -v "$tool" &>/dev/null; then |
| missing_tools+=("$tool") |
| fi |
| done |
|
|
| if [[ ${#missing_tools[@]} -gt 0 ]]; then |
| error "缺少必要工具: ${missing_tools[*]}" |
| fi |
| } |
|
|
| |
| USE_STATIC=false |
|
|
| while [[ $# -gt 0 ]]; do |
| case $1 in |
| --static) USE_STATIC=true ;; |
| --help) show_help; exit 0 ;; |
| *) error "未知参数: $1" ;; |
| esac |
| shift |
| done |
|
|
| |
| show_help() { |
| cat << EOF |
| 用法: $(basename "$0") [选项] |
| |
| 选项: |
| --static 使用静态链接(默认动态链接) |
| --help 显示此帮助信息 |
| |
| 不带参数时只编译当前平台 |
| EOF |
| } |
|
|
| |
| build_target() { |
| local target=$1 |
| local extension="" |
| local rustflags="${2:-}" |
|
|
| info "正在构建 $target..." |
|
|
| |
| [[ $target == *"windows"* ]] && extension=".exe" |
|
|
| |
| if [[ $target != "$CURRENT_TARGET" ]]; then |
| env RUSTFLAGS="$rustflags" cargo build --target "$target" --release |
| else |
| env RUSTFLAGS="$rustflags" cargo build --release |
| fi |
|
|
| |
| local binary_name="cursor-api" |
| [[ $USE_STATIC == true ]] && binary_name+="-static" |
|
|
| local binary_path |
| if [[ $target == "$CURRENT_TARGET" ]]; then |
| binary_path="target/release/cursor-api$extension" |
| else |
| binary_path="target/$target/release/cursor-api$extension" |
| fi |
|
|
| if [[ -f "$binary_path" ]]; then |
| cp "$binary_path" "release/${binary_name}-$target$extension" |
| info "完成构建 $target" |
| else |
| warn "构建产物未找到: $target" |
| warn "查找路径: $binary_path" |
| warn "当前目录内容:" |
| ls -R target/ |
| return 1 |
| fi |
| } |
|
|
| |
| ARCH=$(uname -m | sed 's/^aarch64\|arm64$/aarch64/;s/^x86_64\|x86-64\|x64\|amd64$/x86_64/') |
| OS=$(uname -s) |
|
|
| |
| get_target() { |
| local arch=$1 |
| local os=$2 |
| case "$os" in |
| "Darwin") echo "${arch}-apple-darwin" ;; |
| "Linux") |
| if [[ $USE_STATIC == true ]]; then |
| echo "${arch}-unknown-linux-musl" |
| else |
| echo "${arch}-unknown-linux-gnu" |
| fi |
| ;; |
| "MINGW"*|"MSYS"*|"CYGWIN"*|"Windows_NT") echo "${arch}-pc-windows-msvc" ;; |
| "FreeBSD") echo "${arch}-unknown-freebsd" ;; |
| *) error "不支持的系统: $os" ;; |
| esac |
| } |
|
|
| |
| CURRENT_TARGET=$(get_target "$ARCH" "$OS") |
|
|
| |
| [ -z "$CURRENT_TARGET" ] && error "无法确定当前系统的目标平台" |
|
|
| |
| get_targets() { |
| case "$1" in |
| "linux") |
| |
| echo "$CURRENT_TARGET" |
| ;; |
| "freebsd") |
| |
| echo "$CURRENT_TARGET" |
| ;; |
| "windows") |
| |
| echo "$CURRENT_TARGET" |
| ;; |
| "macos") |
| |
| echo "x86_64-apple-darwin aarch64-apple-darwin" |
| ;; |
| *) error "不支持的系统组: $1" ;; |
| esac |
| } |
|
|
| |
| check_requirements |
|
|
| |
| case "$OS" in |
| Darwin) |
| TARGETS=($(get_targets "macos")) |
| ;; |
| Linux) |
| TARGETS=($(get_targets "linux")) |
| ;; |
| FreeBSD) |
| TARGETS=($(get_targets "freebsd")) |
| ;; |
| MINGW*|MSYS*|CYGWIN*|Windows_NT) |
| TARGETS=($(get_targets "windows")) |
| ;; |
| *) error "不支持的系统: $OS" ;; |
| esac |
|
|
| |
| mkdir -p release |
|
|
| |
| RUSTFLAGS="-C link-arg=-s" |
| [[ $USE_STATIC == true ]] && RUSTFLAGS="-C target-feature=+crt-static -C link-arg=-s" |
|
|
| |
| info "开始构建..." |
| for target in "${TARGETS[@]}"; do |
| build_target "$target" "$RUSTFLAGS" & |
| done |
|
|
| |
| wait |
|
|
| |
| if [[ "$OS" == "Darwin" ]] && [[ ${#TARGETS[@]} -gt 1 ]]; then |
| binary_suffix="" |
| [[ $USE_STATIC == true ]] && binary_suffix="-static" |
|
|
| if [[ -f "release/cursor-api${binary_suffix}-x86_64-apple-darwin" ]] && \ |
| [[ -f "release/cursor-api${binary_suffix}-aarch64-apple-darwin" ]]; then |
| info "创建 macOS 通用二进制..." |
| lipo -create \ |
| "release/cursor-api${binary_suffix}-x86_64-apple-darwin" \ |
| "release/cursor-api${binary_suffix}-aarch64-apple-darwin" \ |
| -output "release/cursor-api${binary_suffix}-universal-apple-darwin" |
| fi |
| fi |
|
|
| info "构建完成!" |