#!/usr/bin/env bash # Copyright 2026 Safronov Grigorii # # Licensed under the CDDL, Version 1.0 (the "License"); # you may not use this file except in compliance with the License. # # You may obtain a copy of the License at # https://opensource.org/licenses/CDDL-1.0 # # Скрипт сборки futriix с использованием vendoring зависимостей # Поддерживает Linux и Illumos (OpenIndiana) # НЕ ТРЕБУЕТ GCC - использует CGO_ENABLED=0 для всех платформ set -e # Цвета для вывода if [ -t 1 ]; then RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' LIGHT_CYAN='\033[0;36m' NC='\033[0m' else RED=''; GREEN=''; YELLOW=''; LIGHT_CYAN=''; NC='' fi # Функции error_msg() { echo -e "${RED}❌ $1${NC}"; } success_msg() { echo -e "${GREEN}✅ $1${NC}"; } info_msg() { echo -e "${LIGHT_CYAN}📋 $1${NC}"; } warning_msg() { echo -e "${YELLOW}⚠️ $1${NC}"; } print_separator() { echo "================================================"; } # Проверка Go check_go() { info_msg "Checking Go installation..." if ! command -v go &> /dev/null; then error_msg "Go is not installed or not in PATH" exit 1 fi GO_VERSION=$(go version | awk '{print $3}') success_msg "Go found: $GO_VERSION" go env -w GOPROXY=https://proxy.golang.org,direct 2>/dev/null || true info_msg "Go proxy: $(go env GOPROXY)" } # Подготовка vendor с диагностикой setup_vendor() { info_msg "Checking vendor directory..." NEED_VENDOR=false if [ ! -d "vendor" ] || [ ! -f "vendor/modules.txt" ]; then warning_msg "Vendor directory not found or incomplete" NEED_VENDOR=true elif [ "go.mod" -nt "vendor/modules.txt" ]; then warning_msg "go.mod is newer than vendor directory" NEED_VENDOR=true fi if [ "$NEED_VENDOR" = true ]; then info_msg "Creating/updating vendor directory..." echo "" info_msg "Step 1/2: Downloading modules..." go mod download -x 2>&1 | grep -E "^(GET|Downloading)" | head -20 || true echo "" info_msg "Step 2/2: Creating vendor directory..." go mod vendor success_msg "Vendor dependencies ready" echo "" else info_msg "Vendor directory is up to date" fi } # Создание директории bin create_bin_dir() { mkdir -p bin info_msg "Bin directory ready" } # Сборка для указанной ОС (статическая, без CGO) build_static() { local target_os=$1 local target_arch="amd64" local output_name="futriix-${target_os}-vendor" info_msg "Building for ${target_os} (static, no CGO)..." export GOOS="${target_os}" export GOARCH="${target_arch}" export CGO_ENABLED=0 local build_tags="" if [ "${target_os}" = "illumos" ] || [ "${target_os}" = "solaris" ]; then build_tags="-tags=illumos" output_name="futriix-illumos-vendor" elif [ "${target_os}" = "linux" ]; then output_name="futriix-linux-vendor" fi local output_path="bin/${output_name}" if go build -mod=vendor ${build_tags} \ -ldflags="-s -w -X main.buildTime=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ -o "${output_path}" ./cmd/futriis; then success_msg "Build successful for ${target_os}: ${output_path}" cp "${output_path}" "./${output_name}" 2>/dev/null || true info_msg "Binary copied to: ./${output_name}" SIZE=$(ls -lh "${output_path}" | awk '{print $5}') info_msg "Binary size: $SIZE" return 0 else error_msg "Build failed for ${target_os}" return 1 fi } # Сборка для текущей ОС build_current() { local os=$(uname -s | tr '[:upper:]' '[:lower:]') info_msg "Building for current OS (${os})..." export CGO_ENABLED=0 local output_path="bin/futriix-current-vendor" if go build -mod=vendor \ -ldflags="-s -w -X main.buildTime=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ -o "${output_path}" ./cmd/futriis; then success_msg "Current OS build successful: ${output_path}" cp "${output_path}" ./futriix-current-vendor 2>/dev/null || true info_msg "Binary copied to: ./futriix-current-vendor" SIZE=$(ls -lh "${output_path}" | awk '{print $5}') info_msg "Binary size: $SIZE" return 0 else error_msg "Current OS build failed" return 1 fi } # Очистка clean() { info_msg "Cleaning binary files..." rm -f bin/futriix-*-vendor rm -f ./futriix-*-vendor success_msg "Clean completed" } clean_vendor() { info_msg "Cleaning vendor directory..." rm -rf vendor success_msg "Vendor directory removed" } # Обновление зависимостей update_deps() { info_msg "Updating dependencies..." go get -u ./... go mod tidy go mod vendor success_msg "Dependencies updated" } # Показать информацию show_deps() { info_msg "Project dependencies:" echo "" if [ -f "go.mod" ]; then echo "Direct dependencies:" go list -m all | head -20 echo "" fi if [ -d "vendor" ]; then echo "Vendor directory size:" du -sh vendor 2>/dev/null || echo "Cannot determine size" echo "" echo "Number of packages in vendor:" find vendor -name "*.go" 2>/dev/null | wc -l fi } # Справка show_help() { echo "Usage: $0 [OPTIONS]" echo "" echo "Options:" echo " -h, --help Show this help message" echo " -c, --clean Clean build artifacts" echo " -C, --clean-all Clean build artifacts and vendor directory" echo " -u, --update Update dependencies and rebuild vendor" echo " -i, --info Show dependency information" echo " -l, --linux Build only for Linux" echo " -m, --illumos Build only for Illumos" echo " -o, --only-os Build only for current OS" echo "" echo "Note: All builds use CGO_ENABLED=0 (no GCC required)" } # Основная функция main() { print_separator echo -e "${GREEN}🔨 Building futriix database with vendoring (no GCC required)${NC}" print_separator local os=$(uname -s | tr '[:upper:]' '[:lower:]') info_msg "Detected OS: $os" local BUILD_LINUX=true local BUILD_ILLUMOS=true local BUILD_CURRENT=false while [[ $# -gt 0 ]]; do case $1 in -h|--help) show_help; exit 0 ;; -c|--clean) clean; exit 0 ;; -C|--clean-all) clean; clean_vendor; exit 0 ;; -u|--update) update_deps; exit 0 ;; -i|--info) show_deps; exit 0 ;; -l|--linux) BUILD_LINUX=true; BUILD_ILLUMOS=false; BUILD_CURRENT=false; shift ;; -m|--illumos) BUILD_LINUX=false; BUILD_ILLUMOS=true; BUILD_CURRENT=false; shift ;; -o|--only-os) BUILD_LINUX=false; BUILD_ILLUMOS=false; BUILD_CURRENT=true; shift ;; *) error_msg "Unknown option: $1"; show_help; exit 1 ;; esac done check_go setup_vendor create_bin_dir print_separator local BUILD_FAILED=0 if [ "$BUILD_CURRENT" = true ]; then build_current || BUILD_FAILED=1 else if [ "$BUILD_LINUX" = true ]; then build_static "linux" || BUILD_FAILED=1 fi if [ "$BUILD_ILLUMOS" = true ]; then build_static "illumos" || BUILD_FAILED=1 fi fi print_separator if [ $BUILD_FAILED -eq 0 ]; then success_msg "All builds completed successfully!" echo "" info_msg "Generated binaries:" ls -lh bin/futriix-*-vendor 2>/dev/null || echo " No binaries in bin/" echo "" info_msg "To run the database:" echo " ./futriix-linux-vendor # On Linux" echo " ./futriix-illumos-vendor # On Illumos/OpenIndiana" echo "" info_msg "Note: All binaries are statically linked and do not require GCC" else error_msg "Some builds failed" exit 1 fi } main "$@"