4coder/build_new/helpers/check-toolchain.sh

438 lines
12 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
# check-toolchain.sh - Verify clang installation and build requirements
# Checks for clang, required tools, and platform-specific dependencies
set -e
# =============================================================================
# Configuration
# =============================================================================
# Minimum required versions
MIN_CLANG_VERSION_MAJOR=6
MIN_CLANG_VERSION_MINOR=0
# Required tools
REQUIRED_TOOLS=(
"clang++"
"clang"
"make"
"bash"
)
# Platform-specific tools
REQUIRED_TOOLS_LINUX=(
"pkg-config"
)
REQUIRED_TOOLS_MACOS=(
"xcrun"
)
REQUIRED_TOOLS_WIN32=(
"windres" # For resource compilation
)
# =============================================================================
# Utility Functions
# =============================================================================
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
print_success() {
echo -e "${GREEN}${NC} $1"
}
print_warning() {
echo -e "${YELLOW}${NC} $1"
}
print_error() {
echo -e "${RED}${NC} $1"
}
print_info() {
echo -e " $1"
}
# =============================================================================
# Version Checking
# =============================================================================
check_clang_version() {
local clang_version
local major minor
if ! command -v clang++ &> /dev/null; then
print_error "clang++ not found in PATH"
return 1
fi
clang_version=$(clang++ --version | head -n1)
print_info "Found: $clang_version"
# Extract version numbers (handles various clang version formats)
if [[ $clang_version =~ ([0-9]+)\.([0-9]+) ]]; then
major=${BASH_REMATCH[1]}
minor=${BASH_REMATCH[2]}
if [[ $major -gt $MIN_CLANG_VERSION_MAJOR ]] || \
[[ $major -eq $MIN_CLANG_VERSION_MAJOR && $minor -ge $MIN_CLANG_VERSION_MINOR ]]; then
print_success "clang++ version $major.$minor meets minimum requirement ($MIN_CLANG_VERSION_MAJOR.$MIN_CLANG_VERSION_MINOR)"
return 0
else
print_error "clang++ version $major.$minor is below minimum requirement ($MIN_CLANG_VERSION_MAJOR.$MIN_CLANG_VERSION_MINOR)"
return 1
fi
else
print_warning "Could not parse clang++ version, proceeding anyway"
return 0
fi
}
# =============================================================================
# Tool Checking
# =============================================================================
check_tool() {
local tool=$1
local required=${2:-true}
if command -v "$tool" &> /dev/null; then
local version_info
case "$tool" in
"clang++"|"clang")
version_info=$(command "$tool" --version 2>/dev/null | head -n1 || echo "version unknown")
;;
"make")
version_info=$(command "$tool" --version 2>/dev/null | head -n1 || echo "version unknown")
;;
"pkg-config")
version_info=$(command "$tool" --version 2>/dev/null || echo "version unknown")
;;
*)
version_info="available"
;;
esac
print_success "$tool found ($version_info)"
return 0
else
if [[ "$required" == "true" ]]; then
print_error "$tool not found in PATH"
return 1
else
print_warning "$tool not found (optional)"
return 0
fi
fi
}
check_basic_tools() {
local all_good=true
print_info "Checking basic tools..."
for tool in "${REQUIRED_TOOLS[@]}"; do
if ! check_tool "$tool"; then
all_good=false
fi
done
if [[ "$all_good" == "true" ]]; then
return 0
else
return 1
fi
}
check_platform_tools() {
local platform=$1
local all_good=true
local tools_var
case "$platform" in
"linux")
tools_var="REQUIRED_TOOLS_LINUX[@]"
;;
"macos")
tools_var="REQUIRED_TOOLS_MACOS[@]"
;;
"win32")
tools_var="REQUIRED_TOOLS_WIN32[@]"
;;
*)
print_warning "Unknown platform '$platform', skipping platform-specific tool checks"
return 0
;;
esac
print_info "Checking platform-specific tools for $platform..."
# Use indirect reference to get the array
local tools_array_name="$tools_var"
if [[ -n "${!tools_array_name:-}" ]]; then
local tools_array=("${!tools_array_name}")
for tool in "${tools_array[@]}"; do
if ! check_tool "$tool"; then
all_good=false
fi
done
fi
if [[ "$all_good" == "true" ]]; then
return 0
else
return 1
fi
}
# =============================================================================
# Platform-Specific Checks
# =============================================================================
check_macos_requirements() {
print_info "Checking macOS-specific requirements..."
# Check for Xcode command line tools
if ! xcode-select -p &> /dev/null; then
print_error "Xcode command line tools not installed"
print_info "Install with: xcode-select --install"
return 1
else
print_success "Xcode command line tools installed"
fi
# Check for macOS SDK
local sdk_path
sdk_path=$(xcrun --show-sdk-path 2>/dev/null || echo "")
if [[ -n "$sdk_path" && -d "$sdk_path" ]]; then
print_success "macOS SDK found at $sdk_path"
else
print_warning "macOS SDK not found or not accessible"
fi
# Check for required frameworks (just check if headers exist)
local frameworks=("Cocoa" "OpenGL" "Metal")
for framework in "${frameworks[@]}"; do
if [[ -d "$sdk_path/System/Library/Frameworks/$framework.framework" ]]; then
print_success "$framework framework available"
else
print_warning "$framework framework not found"
fi
done
return 0
}
check_linux_requirements() {
print_info "Checking Linux-specific requirements..."
# Check for development packages
local packages=("libx11-dev" "libgl1-mesa-dev" "libfreetype6-dev" "libfontconfig1-dev")
local missing_packages=()
for package in "${packages[@]}"; do
if dpkg -l | grep -q "$package" 2>/dev/null; then
print_success "$package installed"
elif rpm -q "$package" &>/dev/null; then
print_success "$package installed"
else
print_warning "$package not found (may be required)"
missing_packages+=("$package")
fi
done
if [[ ${#missing_packages[@]} -gt 0 ]]; then
print_info "Missing packages (Ubuntu/Debian): ${missing_packages[*]}"
print_info "Install with: sudo apt-get install ${missing_packages[*]}"
fi
return 0
}
check_win32_requirements() {
print_info "Checking Windows-specific requirements..."
# Check for Windows SDK (approximate check)
if [[ -n "${WINDOWSSDKDIR:-}" ]]; then
print_success "Windows SDK environment detected"
else
print_warning "Windows SDK environment not detected"
print_info "Make sure Visual Studio or Windows SDK is installed"
fi
return 0
}
# =============================================================================
# Library Checks
# =============================================================================
check_freetype_library() {
local platform=$1
local arch=$2
print_info "Checking FreeType library availability..."
case "$platform" in
"macos")
local freetype_lib="non-source/foreign/x64/libfreetype-mac.a"
if [[ -f "$freetype_lib" ]]; then
print_success "FreeType library found: $freetype_lib"
else
print_error "FreeType library not found: $freetype_lib"
return 1
fi
;;
"linux")
if pkg-config --exists freetype2; then
local freetype_version
freetype_version=$(pkg-config --modversion freetype2)
print_success "FreeType2 found via pkg-config (version $freetype_version)"
else
print_warning "FreeType2 not found via pkg-config"
fi
;;
"win32")
local freetype_lib="non-source/foreign/x64/freetype.lib"
if [[ -f "$freetype_lib" ]]; then
print_success "FreeType library found: $freetype_lib"
else
print_error "FreeType library not found: $freetype_lib"
return 1
fi
;;
esac
return 0
}
# =============================================================================
# Main Checking Function
# =============================================================================
check_build_environment() {
local platform
local arch
local all_good=true
echo "=== 4coder Build Environment Check ==="
echo
# Detect platform
if command -v "$(dirname "$0")/detect-platform.sh" &> /dev/null; then
platform=$($(dirname "$0")/detect-platform.sh detect)
arch=$($(dirname "$0")/detect-platform.sh arch)
print_info "Detected platform: $platform"
print_info "Detected architecture: $arch"
else
print_warning "Platform detection script not found, assuming current platform"
platform="unknown"
arch="unknown"
fi
echo
# Check clang version
if ! check_clang_version; then
all_good=false
fi
echo
# Check basic tools
if ! check_basic_tools; then
all_good=false
fi
echo
# Check platform-specific tools
if ! check_platform_tools "$platform"; then
all_good=false
fi
echo
# Check platform-specific requirements
case "$platform" in
"macos")
if ! check_macos_requirements; then
all_good=false
fi
;;
"linux")
if ! check_linux_requirements; then
all_good=false
fi
;;
"win32")
if ! check_win32_requirements; then
all_good=false
fi
;;
esac
echo
# Check libraries
if ! check_freetype_library "$platform" "$arch"; then
all_good=false
fi
echo
# Final result
if [[ "$all_good" == "true" ]]; then
print_success "Build environment check passed!"
print_info "System is ready for 4coder compilation"
return 0
else
print_error "Build environment check failed"
print_info "Some requirements are missing. Please install missing components and try again."
return 1
fi
}
# =============================================================================
# Main execution
# =============================================================================
main() {
local command="${1:-check}"
case "$command" in
"check")
check_build_environment
;;
"clang")
check_clang_version
;;
"tools")
check_basic_tools
;;
"help"|"-h"|"--help")
echo "Usage: $0 [check|clang|tools|help]"
echo ""
echo "Commands:"
echo " check - Run full build environment check (default)"
echo " clang - Check clang version only"
echo " tools - Check basic tools only"
echo " help - Show this help message"
;;
*)
echo "Error: Unknown command '$command'" >&2
echo "Run '$0 help' for usage information" >&2
return 1
;;
esac
}
# Only run main if script is executed directly (not sourced)
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi