- Moved all third-party libraries (SDL, ImGui, Asar, etc.) from `src/lib/` and `third_party/` to a new `ext/` directory for better organization and clarity in dependency management. - Updated CMake configuration to reflect the new paths, ensuring all targets and includes point to the `ext/` directory. - Enhanced CMake presets to support new build options for AI and gRPC features, improving modularity and build flexibility. - Added new feature flags for agent UI and remote automation, allowing for more granular control over build configurations. - Updated documentation to reflect changes in the project structure and build options, ensuring clarity for contributors and users.
460 lines
15 KiB
Bash
Executable File
460 lines
15 KiB
Bash
Executable File
#!/bin/bash
|
||
# YAZE Build Environment Verification Script for Unix/macOS
|
||
# This script verifies the build environment is properly configured and ready to build
|
||
# Run this before building to catch common configuration issues early
|
||
|
||
set -e
|
||
|
||
# Colors for output
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
CYAN='\033[0;36m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# Flags
|
||
VERBOSE=0
|
||
FIX_ISSUES=0
|
||
CLEAN_CACHE=0
|
||
|
||
# Counters
|
||
ISSUES_FOUND=()
|
||
WARNINGS=()
|
||
SUCCESS=()
|
||
|
||
# Parse arguments
|
||
while [[ $# -gt 0 ]]; do
|
||
case $1 in
|
||
-v|--verbose)
|
||
VERBOSE=1
|
||
shift
|
||
;;
|
||
-f|--fix)
|
||
FIX_ISSUES=1
|
||
shift
|
||
;;
|
||
-c|--clean)
|
||
CLEAN_CACHE=1
|
||
shift
|
||
;;
|
||
-h|--help)
|
||
echo "Usage: $0 [OPTIONS]"
|
||
echo "Options:"
|
||
echo " -v, --verbose Verbose output"
|
||
echo " -f, --fix Automatically fix issues"
|
||
echo " -c, --clean Clean CMake cache"
|
||
echo " -h, --help Show this help message"
|
||
exit 0
|
||
;;
|
||
*)
|
||
echo "Unknown option: $1"
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
|
||
function write_status() {
|
||
local message="$1"
|
||
local type="${2:-Info}"
|
||
local timestamp=$(date +"%H:%M:%S")
|
||
|
||
case "$type" in
|
||
Success)
|
||
echo -e "[$timestamp] ${GREEN}✓${NC} $message"
|
||
;;
|
||
Error)
|
||
echo -e "[$timestamp] ${RED}✗${NC} $message"
|
||
;;
|
||
Warning)
|
||
echo -e "[$timestamp] ${YELLOW}⚠${NC} $message"
|
||
;;
|
||
Info)
|
||
echo -e "[$timestamp] ${CYAN}ℹ${NC} $message"
|
||
;;
|
||
Step)
|
||
echo -e "\n[$timestamp] ${BLUE}▶${NC} $message"
|
||
;;
|
||
esac
|
||
}
|
||
|
||
function test_command() {
|
||
command -v "$1" &> /dev/null
|
||
}
|
||
|
||
function get_cmake_version() {
|
||
if test_command cmake; then
|
||
cmake --version 2>&1 | head -n1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+'
|
||
fi
|
||
}
|
||
|
||
function test_git_submodules() {
|
||
local submodules=(
|
||
"ext/SDL"
|
||
"src/lib/abseil-cpp"
|
||
"ext/asar"
|
||
"ext/imgui"
|
||
"ext/json"
|
||
"ext/httplib"
|
||
"ext/imgui_test_engine"
|
||
"ext/nativefiledialog-extended"
|
||
)
|
||
|
||
local all_present=1
|
||
for submodule in "${submodules[@]}"; do
|
||
if [[ ! -d "$submodule" ]] || [[ -z "$(ls -A "$submodule" 2>/dev/null)" ]]; then
|
||
write_status "Submodule missing or empty: $submodule" "Error"
|
||
ISSUES_FOUND+=("Missing/empty submodule: $submodule")
|
||
all_present=0
|
||
elif [[ $VERBOSE -eq 1 ]]; then
|
||
write_status "Submodule found: $submodule" "Success"
|
||
fi
|
||
done
|
||
return $all_present
|
||
}
|
||
|
||
function test_cmake_cache() {
|
||
local build_dirs=("build" "build-test" "build-grpc-test" "build-rooms" "build-windows")
|
||
local cache_issues=0
|
||
|
||
for dir in "${build_dirs[@]}"; do
|
||
if [[ -f "$dir/CMakeCache.txt" ]]; then
|
||
local cache_age=$(($(date +%s) - $(stat -f %m "$dir/CMakeCache.txt" 2>/dev/null || stat -c %Y "$dir/CMakeCache.txt" 2>/dev/null)))
|
||
local days=$((cache_age / 86400))
|
||
if [[ $days -gt 7 ]]; then
|
||
write_status "CMake cache in '$dir' is $days days old" "Warning"
|
||
WARNINGS+=("Old CMake cache in $dir (consider cleaning)")
|
||
cache_issues=1
|
||
elif [[ $VERBOSE -eq 1 ]]; then
|
||
write_status "CMake cache in '$dir' is recent" "Success"
|
||
fi
|
||
fi
|
||
done
|
||
return $cache_issues
|
||
}
|
||
|
||
function test_agent_folder_structure() {
|
||
write_status "Verifying agent folder structure..." "Step"
|
||
|
||
local agent_files=(
|
||
"src/app/editor/agent/agent_editor.h"
|
||
"src/app/editor/agent/agent_editor.cc"
|
||
"src/app/editor/agent/agent_chat_widget.h"
|
||
"src/app/editor/agent/agent_chat_widget.cc"
|
||
"src/app/editor/agent/agent_chat_history_codec.h"
|
||
"src/app/editor/agent/agent_chat_history_codec.cc"
|
||
"src/app/editor/agent/agent_collaboration_coordinator.h"
|
||
"src/app/editor/agent/agent_collaboration_coordinator.cc"
|
||
"src/app/editor/agent/network_collaboration_coordinator.h"
|
||
"src/app/editor/agent/network_collaboration_coordinator.cc"
|
||
)
|
||
|
||
local old_system_files=(
|
||
"src/app/editor/agent/agent_chat_widget.h"
|
||
"src/app/editor/agent/agent_collaboration_coordinator.h"
|
||
)
|
||
|
||
local all_present=1
|
||
local has_old_structure=0
|
||
|
||
for file in "${agent_files[@]}"; do
|
||
if [[ ! -f "$file" ]]; then
|
||
write_status "Agent file missing: $file" "Error"
|
||
ISSUES_FOUND+=("Missing agent file: $file (may need to rebuild)")
|
||
all_present=0
|
||
elif [[ $VERBOSE -eq 1 ]]; then
|
||
write_status "Agent file found: $file" "Success"
|
||
fi
|
||
done
|
||
|
||
# Check for old structure (indicates stale cache)
|
||
for file in "${old_system_files[@]}"; do
|
||
if [[ -f "$file" ]]; then
|
||
write_status "Old agent file still present: $file" "Warning"
|
||
WARNINGS+=("Old agent structure detected (CMake cache needs cleaning)")
|
||
has_old_structure=1
|
||
fi
|
||
done
|
||
|
||
if [[ $all_present -eq 1 && $has_old_structure -eq 0 ]]; then
|
||
write_status "Agent folder structure is correct" "Success"
|
||
SUCCESS+=("Agent refactoring structure verified")
|
||
return 0
|
||
elif [[ $has_old_structure -eq 1 ]]; then
|
||
write_status "Stale agent files detected - CMake cache should be cleaned" "Warning"
|
||
return 1
|
||
fi
|
||
|
||
return $all_present
|
||
}
|
||
|
||
function clean_cmake_cache() {
|
||
write_status "Cleaning CMake cache and build directories..." "Step"
|
||
|
||
local build_dirs=("build" "build-test" "build-grpc-test" "build-rooms" "build-windows")
|
||
local cleaned=0
|
||
|
||
for dir in "${build_dirs[@]}"; do
|
||
if [[ -d "$dir" ]]; then
|
||
write_status "Removing $dir..." "Info"
|
||
if rm -rf "$dir" 2>/dev/null; then
|
||
cleaned=1
|
||
write_status " ✓ Removed $dir" "Success"
|
||
else
|
||
write_status " ✗ Failed to remove $dir" "Error"
|
||
WARNINGS+=("Could not fully clean $dir")
|
||
fi
|
||
fi
|
||
done
|
||
|
||
# Clean CMake generated files in root
|
||
local cmake_files=("CMakeCache.txt" "cmake_install.cmake" "compile_commands.json")
|
||
for file in "${cmake_files[@]}"; do
|
||
if [[ -f "$file" ]]; then
|
||
write_status "Removing root $file..." "Info"
|
||
rm -f "$file" 2>/dev/null
|
||
fi
|
||
done
|
||
|
||
if [[ $cleaned -eq 1 ]]; then
|
||
write_status "CMake cache cleaned successfully" "Success"
|
||
SUCCESS+=("Build directories cleaned - fresh build recommended")
|
||
else
|
||
write_status "No build directories found to clean" "Info"
|
||
fi
|
||
}
|
||
|
||
function sync_git_submodules() {
|
||
write_status "Syncing git submodules..." "Step"
|
||
|
||
write_status "Running: git submodule sync --recursive" "Info"
|
||
if git submodule sync --recursive &> /dev/null; then
|
||
write_status "Running: git submodule update --init --recursive" "Info"
|
||
if git submodule update --init --recursive; then
|
||
write_status "Submodules synced successfully" "Success"
|
||
return 0
|
||
fi
|
||
fi
|
||
|
||
write_status "Failed to sync submodules" "Error"
|
||
return 1
|
||
}
|
||
|
||
function test_dependency_compatibility() {
|
||
write_status "Testing dependency configuration..." "Step"
|
||
|
||
# Check httplib configuration
|
||
if [[ -f "ext/httplib/CMakeLists.txt" ]]; then
|
||
write_status "httplib found in ext/" "Success"
|
||
SUCCESS+=("httplib header-only library available")
|
||
fi
|
||
|
||
# Check json library
|
||
if [[ -d "ext/json/include" ]]; then
|
||
write_status "nlohmann/json found in ext/" "Success"
|
||
SUCCESS+=("nlohmann/json header-only library available")
|
||
fi
|
||
}
|
||
|
||
# ============================================================================
|
||
# Main Verification Process
|
||
# ============================================================================
|
||
|
||
echo ""
|
||
echo -e "${CYAN}╔════════════════════════════════════════════════════════════════╗${NC}"
|
||
echo -e "${CYAN}║ YAZE Build Environment Verification for Unix/macOS/Linux ║${NC}"
|
||
echo -e "${CYAN}╚════════════════════════════════════════════════════════════════╝${NC}"
|
||
echo ""
|
||
|
||
START_TIME=$(date +%s)
|
||
|
||
# Change to script directory
|
||
cd "$(dirname "$0")/.."
|
||
|
||
# Step 1: Check CMake
|
||
write_status "Checking CMake installation..." "Step"
|
||
if test_command cmake; then
|
||
cmake_version=$(get_cmake_version)
|
||
write_status "CMake found: version $cmake_version" "Success"
|
||
|
||
# Parse version
|
||
IFS='.' read -ra VERSION_PARTS <<< "$cmake_version"
|
||
major=${VERSION_PARTS[0]}
|
||
minor=${VERSION_PARTS[1]}
|
||
|
||
if [[ $major -lt 3 ]] || [[ $major -eq 3 && $minor -lt 16 ]]; then
|
||
write_status "CMake version too old (need 3.16+)" "Error"
|
||
ISSUES_FOUND+=("CMake version $cmake_version is below minimum 3.16")
|
||
fi
|
||
else
|
||
write_status "CMake not found in PATH" "Error"
|
||
ISSUES_FOUND+=("CMake not installed or not in PATH")
|
||
fi
|
||
|
||
# Step 2: Check Git
|
||
write_status "Checking Git installation..." "Step"
|
||
if test_command git; then
|
||
git_version=$(git --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')
|
||
write_status "Git found: version $git_version" "Success"
|
||
else
|
||
write_status "Git not found in PATH" "Error"
|
||
ISSUES_FOUND+=("Git not installed or not in PATH")
|
||
fi
|
||
|
||
# Step 3: Check Build Tools
|
||
write_status "Checking build tools..." "Step"
|
||
if test_command make; then
|
||
write_status "Make found" "Success"
|
||
elif test_command ninja; then
|
||
write_status "Ninja found" "Success"
|
||
else
|
||
write_status "No build tool found (make or ninja)" "Warning"
|
||
WARNINGS+=("Neither make nor ninja found")
|
||
fi
|
||
|
||
# Step 4: Check Compiler
|
||
if test_command clang++; then
|
||
clang_version=$(clang++ --version | head -n1)
|
||
write_status "Clang++ found: $clang_version" "Success"
|
||
elif test_command g++; then
|
||
gpp_version=$(g++ --version | head -n1)
|
||
write_status "G++ found: $gpp_version" "Success"
|
||
else
|
||
write_status "No C++ compiler found" "Error"
|
||
ISSUES_FOUND+=("No C++ compiler (clang++ or g++) found")
|
||
fi
|
||
|
||
# Step 5: Check Git Submodules
|
||
write_status "Checking git submodules..." "Step"
|
||
if test_git_submodules; then
|
||
write_status "All required submodules present" "Success"
|
||
else
|
||
write_status "Some submodules are missing or empty" "Error"
|
||
if [[ $FIX_ISSUES -eq 1 ]]; then
|
||
sync_git_submodules
|
||
test_git_submodules
|
||
else
|
||
write_status "Automatically syncing submodules..." "Info"
|
||
if sync_git_submodules; then
|
||
test_git_submodules
|
||
else
|
||
write_status "Run with --fix to try again, or manually: git submodule update --init --recursive" "Info"
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
# Step 6: Check CMake Cache
|
||
write_status "Checking CMake cache..." "Step"
|
||
if test_cmake_cache; then
|
||
write_status "CMake cache is up to date" "Success"
|
||
else
|
||
if [[ $CLEAN_CACHE -eq 1 ]]; then
|
||
clean_cmake_cache
|
||
elif [[ $FIX_ISSUES -eq 1 ]]; then
|
||
read -p "CMake cache is old. Clean it? (Y/n): " -n 1 -r
|
||
echo
|
||
if [[ $REPLY =~ ^[Yy]$ ]] || [[ -z $REPLY ]]; then
|
||
clean_cmake_cache
|
||
fi
|
||
else
|
||
write_status "Run with --clean to remove old cache files" "Info"
|
||
fi
|
||
fi
|
||
|
||
# Step 7: Check vcpkg (Windows-specific but important)
|
||
write_status "Checking vcpkg availability..." "Step"
|
||
if [[ -d "vcpkg" ]]; then
|
||
if [[ -f "vcpkg/vcpkg" ]] || [[ -f "vcpkg/vcpkg.exe" ]]; then
|
||
write_status "vcpkg found and bootstrapped" "Success"
|
||
SUCCESS+=("vcpkg available for dependency management")
|
||
|
||
# Check vcpkg version if possible
|
||
if [[ -x "vcpkg/vcpkg" ]]; then
|
||
vcpkg_version=$(./vcpkg/vcpkg version 2>/dev/null | head -n1 || echo "unknown")
|
||
write_status "vcpkg version: $vcpkg_version" "Info"
|
||
fi
|
||
else
|
||
write_status "vcpkg directory exists but not bootstrapped" "Warning"
|
||
WARNINGS+=("vcpkg not bootstrapped - run: cd vcpkg && ./bootstrap-vcpkg.sh")
|
||
fi
|
||
else
|
||
write_status "vcpkg not found (optional, required for Windows)" "Info"
|
||
write_status "To install: git clone https://github.com/microsoft/vcpkg.git && vcpkg/bootstrap-vcpkg.sh" "Info"
|
||
fi
|
||
|
||
# Step 8: Check Dependencies
|
||
test_dependency_compatibility
|
||
|
||
# Step 9: Check Agent Folder Structure
|
||
if test_agent_folder_structure; then
|
||
: # Structure is OK
|
||
else
|
||
write_status "Agent folder structure has issues" "Warning"
|
||
if [[ $CLEAN_CACHE -eq 1 ]] || [[ $FIX_ISSUES -eq 1 ]]; then
|
||
write_status "Cleaning CMake cache due to structural changes..." "Info"
|
||
clean_cmake_cache
|
||
write_status "Please rebuild the project after cache cleaning" "Info"
|
||
else
|
||
write_status "Run with --clean to fix structural issues" "Info"
|
||
fi
|
||
fi
|
||
|
||
# ============================================================================
|
||
# Summary Report
|
||
# ============================================================================
|
||
|
||
END_TIME=$(date +%s)
|
||
DURATION=$((END_TIME - START_TIME))
|
||
|
||
echo ""
|
||
echo -e "${CYAN}╔════════════════════════════════════════════════════════════════╗${NC}"
|
||
echo -e "${CYAN}║ Verification Summary ║${NC}"
|
||
echo -e "${CYAN}╚════════════════════════════════════════════════════════════════╝${NC}"
|
||
echo ""
|
||
echo "Duration: ${DURATION} seconds"
|
||
echo ""
|
||
|
||
if [[ ${#SUCCESS[@]} -gt 0 ]]; then
|
||
echo -e "${GREEN}✓ Successes (${#SUCCESS[@]}):${NC}"
|
||
for item in "${SUCCESS[@]}"; do
|
||
echo -e " ${GREEN}•${NC} $item"
|
||
done
|
||
echo ""
|
||
fi
|
||
|
||
if [[ ${#WARNINGS[@]} -gt 0 ]]; then
|
||
echo -e "${YELLOW}⚠ Warnings (${#WARNINGS[@]}):${NC}"
|
||
for item in "${WARNINGS[@]}"; do
|
||
echo -e " ${YELLOW}•${NC} $item"
|
||
done
|
||
echo ""
|
||
fi
|
||
|
||
if [[ ${#ISSUES_FOUND[@]} -gt 0 ]]; then
|
||
echo -e "${RED}✗ Issues Found (${#ISSUES_FOUND[@]}):${NC}"
|
||
for item in "${ISSUES_FOUND[@]}"; do
|
||
echo -e " ${RED}•${NC} $item"
|
||
done
|
||
echo ""
|
||
|
||
echo -e "${YELLOW}Recommended Actions:${NC}"
|
||
echo -e " ${CYAN}1. Run: ./scripts/verify-build-environment.sh --fix${NC}"
|
||
echo -e " ${CYAN}2. Install missing dependencies${NC}"
|
||
echo -e " ${CYAN}3. Check build instructions: docs/02-build-instructions.md${NC}"
|
||
echo ""
|
||
|
||
exit 1
|
||
else
|
||
echo -e "${GREEN}╔════════════════════════════════════════════════════════════════╗${NC}"
|
||
echo -e "${GREEN}║ ✓ Build Environment Ready for Development! ║${NC}"
|
||
echo -e "${GREEN}╚════════════════════════════════════════════════════════════════╝${NC}"
|
||
echo ""
|
||
|
||
echo -e "${CYAN}Next Steps:${NC}"
|
||
echo -e " ${CYAN}Command Line Workflow:${NC}"
|
||
echo -e " ${NC}cmake -B build -DCMAKE_BUILD_TYPE=Debug${NC}"
|
||
echo -e " ${NC}cmake --build build --parallel \$(nproc)${NC}"
|
||
echo ""
|
||
|
||
exit 0
|
||
fi |