diff options
Diffstat (limited to 'build.sh')
| -rwxr-xr-x | build.sh | 492 |
1 files changed, 492 insertions, 0 deletions
diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..37a3dba --- /dev/null +++ b/build.sh @@ -0,0 +1,492 @@ +#!/bin/bash + +# CCDJIT Build System +# A comprehensive build and development tool for the CCDJIT compiler + +set -e # Exit on any error + +# Configuration +PROJECT_NAME="ccdjit" +BINARY_NAME="bin/ccdjit" +SOURCE_DIR="src" +TEST_DIR="tests" +BUILD_DIR="bin" +RELEASE_FLAGS="-DRELEASE -O2 -Wall -Wextra" +DEBUG_FLAGS="-g -O0 -Wall -Wextra -DDEBUG" +DEV_FLAGS="-g -O1 -Wall -Wextra" +LINK_FLAGS="-lssl -lcrypto" + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +PURPLE='\033[0;35m' +CYAN='\033[0;36m' +WHITE='\033[1;37m' +GRAY='\033[0;37m' +NC='\033[0m' # No Color + +# Build status tracking +BUILD_SUCCESS=false +TEST_SUCCESS=false + +# Print colored output +print_header() { + echo -e "${CYAN}╔══════════════════════════════════════════════════════════════════════════════╗${NC}" + echo -e "${CYAN}║${WHITE} CCDJIT Build System ${CYAN}║${NC}" + echo -e "${CYAN}╚══════════════════════════════════════════════════════════════════════════════╝${NC}" + echo +} + +print_section() { + echo -e "${BLUE}┌─ ${WHITE}$1${NC}" + echo -e "${BLUE}│${NC} $2" +} + +print_success() { + echo -e "${BLUE}└─${GREEN} ✓ $1${NC}" +} + +print_error() { + echo -e "${BLUE}└─${RED} ✗ $1${NC}" +} + +print_info() { + echo -e "${BLUE}│${NC} $1" +} + +# Check dependencies +check_dependencies() { + print_section "Checking Dependencies" "Verifying required tools are available" + + local missing_deps=() + + if ! command -v cc &> /dev/null; then + missing_deps+=("cc (C compiler)") + fi + + if ! command -v make &> /dev/null; then + missing_deps+=("make") + fi + + if [ ${#missing_deps[@]} -eq 0 ]; then + print_success "All dependencies found" + return 0 + else + print_error "Missing dependencies: ${missing_deps[*]}" + echo -e "${RED}Please install the missing dependencies and try again.${NC}" + exit 1 + fi +} + +# Clean build artifacts +clean() { + print_section "Cleaning" "Removing build artifacts and temporary files" + + rm -f .cb_checksum_ccdjit + rm -f bin/ccdjit + rm -f *.o + rm -f core + rm -rf .build/ + + print_success "Clean completed" +} + +# Build the project +build() { + local build_type="$1" + local flags="$2" + local description="$3" + + print_section "Building" "$description" + + # Ensure bin directory exists + mkdir -p "$BUILD_DIR" + + # Build command + local build_cmd="cc -o $BINARY_NAME $flags $SOURCE_DIR/main.c $LINK_FLAGS" + + print_info "Command: $build_cmd" + + if eval "$build_cmd"; then + print_success "Build completed successfully" + BUILD_SUCCESS=true + + # Show binary info + if [ -f "$BINARY_NAME" ]; then + local size=$(du -h "$BINARY_NAME" | cut -f1) + print_info "Binary size: $size" + print_info "Location: $BINARY_NAME" + fi + else + print_error "Build failed" + BUILD_SUCCESS=false + exit 1 + fi +} + +# Run the binary +run() { + local args="$*" + + if [ ! -f "$BINARY_NAME" ]; then + print_error "Binary not found. Please build first." + exit 1 + fi + + print_section "Running" "Executing $BINARY_NAME" + + if [ -n "$args" ]; then + print_info "Arguments: $args" + ./"$BINARY_NAME" $args + else + ./"$BINARY_NAME" + fi +} + +# Development mode +dev_mode() { + print_header + clean + build "debug" "$DEV_FLAGS" "Development build with debugging symbols" + + if [ "$BUILD_SUCCESS" = true ]; then + echo + print_section "Development Mode" "Ready for development" + print_info "Binary: $BINARY_NAME" + print_info "Flags: $DEV_FLAGS" + print_info "Run with: $0 run [args]" + fi +} + +# Release mode +release_mode() { + print_header + clean + build "release" "$RELEASE_FLAGS" "Release build optimized for performance" + + if [ "$BUILD_SUCCESS" = true ]; then + echo + print_section "Release Mode" "Production-ready build" + print_info "Binary: $BINARY_NAME" + print_info "Flags: $RELEASE_FLAGS" + print_info "Optimized for maximum performance" + fi +} + +# Debug mode +debug_mode() { + print_header + clean + build "debug" "$DEBUG_FLAGS" "Debug build with full debugging information" + + if [ "$BUILD_SUCCESS" = true ]; then + echo + print_section "Debug Mode" "Debug build ready" + print_info "Binary: $BINARY_NAME" + print_info "Flags: $DEBUG_FLAGS" + print_info "Use with debugger: gdb $BINARY_NAME" + fi +} + +# Install the binary +install_binary() { + local install_dir="${2:-/usr/local/bin}" + + if [ ! -f "$BINARY_NAME" ]; then + print_error "Binary not found. Please build first." + exit 1 + fi + + print_section "Installing" "Installing $PROJECT_NAME to $install_dir" + + if [ ! -w "$install_dir" ]; then + print_info "Using sudo for installation" + sudo cp "$BINARY_NAME" "$install_dir/$PROJECT_NAME" + sudo chmod +x "$install_dir/$PROJECT_NAME" + else + cp "$BINARY_NAME" "$install_dir/$PROJECT_NAME" + chmod +x "$install_dir/$PROJECT_NAME" + fi + + print_success "Installed to $install_dir/$PROJECT_NAME" +} + +# Uninstall the binary +uninstall_binary() { + local install_dir="${2:-/usr/local/bin}" + local binary_path="$install_dir/$PROJECT_NAME" + + print_section "Uninstalling" "Removing $PROJECT_NAME from $install_dir" + + if [ -f "$binary_path" ]; then + if [ ! -w "$install_dir" ]; then + print_info "Using sudo for removal" + sudo rm "$binary_path" + else + rm "$binary_path" + fi + print_success "Removed $binary_path" + else + print_info "Binary not found at $binary_path" + fi +} + +# Show project information +show_info() { + print_header + + print_section "Project Information" "CCDJIT Compiler Details" + print_info "Name: $PROJECT_NAME" + print_info "Version: 1.0.0" + print_info "Description: A C-like language JIT compiler" + print_info "Source Directory: $SOURCE_DIR" + print_info "Binary Location: $BINARY_NAME" + print_info "Test Directory: $TEST_DIR" + + echo + print_section "Build Status" "Current build state" + + if [ -f "$BINARY_NAME" ]; then + local size=$(du -h "$BINARY_NAME" | cut -f1) + local date=$(stat -c %y "$BINARY_NAME" 2>/dev/null || stat -f %Sm "$BINARY_NAME" 2>/dev/null || echo "Unknown") + print_info "Binary exists: Yes" + print_info "Size: $size" + print_info "Last modified: $date" + else + print_info "Binary exists: No" + fi + + echo + print_section "Available Commands" "Build system commands" + print_info "dev - Development build with debugging" + print_info "release - Optimized release build" + print_info "debug - Full debug build" + print_info "clean - Clean build artifacts" + print_info "run [args] - Run the binary with arguments" + print_info "test - Run basic test suite" + print_info "test-adv - Run advanced test suite" + print_info "install - Install binary to system" + print_info "uninstall - Remove binary from system" + print_info "info - Show project information" + print_info "help - Show this help message" +} + +# Show help +show_help() { + print_header + + echo -e "${WHITE}Usage:${NC} $0 [COMMAND] [OPTIONS]" + echo + echo -e "${WHITE}Commands:${NC}" + echo + echo -e " ${GREEN}dev${NC} Build and prepare for development" + echo -e " ${GREEN}release${NC} Build optimized release version" + echo -e " ${GREEN}debug${NC} Build with full debugging information" + echo -e " ${GREEN}clean${NC} Clean build artifacts" + echo -e " ${GREEN}run [args]${NC} Run the binary with optional arguments" + echo -e " ${GREEN}test${NC} Run basic test suite" + echo -e " ${GREEN}test-adv [args]${NC} Run advanced test suite" + echo -e " ${GREEN}install [dir]${NC} Install binary to system (default: /usr/local/bin)" + echo -e " ${GREEN}uninstall [dir]${NC} Remove binary from system" + echo -e " ${GREEN}info${NC} Show project information" + echo -e " ${GREEN}help${NC} Show this help message" + echo + echo -e "${WHITE}Examples:${NC}" + echo + echo -e " ${GRAY}$0 dev${NC} # Development build" + echo -e " ${GRAY}$0 release${NC} # Release build" + echo -e " ${GRAY}$0 run ./tests/arithmetic.c${NC} # Run with test file" + echo -e " ${GRAY}$0 test${NC} # Run tests" + echo -e " ${GRAY}$0 test-adv all${NC} # Run all advanced tests" + echo -e " ${GRAY}$0 install${NC} # Install to /usr/local/bin" + echo -e " ${GRAY}$0 install ~/bin${NC} # Install to ~/bin" + echo + echo -e "${WHITE}Build Flags:${NC}" + echo -e " ${GRAY}Development:${NC} $DEV_FLAGS" + echo -e " ${GRAY}Release:${NC} $RELEASE_FLAGS" + echo -e " ${GRAY}Debug:${NC} $DEBUG_FLAGS" +} + +# Test configuration (global) +declare -gA test_map +test_map["./tests/add2.c"]=3 +test_map["./tests/arithmetic.c"]=28 +test_map["./tests/comparison.c"]=5 +test_map["./tests/logical.c"]=3 +test_map["./tests/if_else.c"]=12 +test_map["./tests/while_loop.c"]=10 +test_map["./tests/for_loop.c"]=6 +test_map["./tests/function_call.c"]=17 +test_map["./tests/recursive.c"]=24 +test_map["./tests/bitwise.c"]=58 +test_map["./tests/pointers.c"]=184 + test_map["./tests/arrays.c"]=150 +test_map["./tests/strings.c"]=5 +test_map["./tests/edge_cases.c"]=12 + +# Test categories +declare -gA test_categories +test_categories["./tests/add2.c"]="Basic" +test_categories["./tests/arithmetic.c"]="Arithmetic" +test_categories["./tests/comparison.c"]="Comparison" +test_categories["./tests/logical.c"]="Logical" +test_categories["./tests/if_else.c"]="Control Flow" +test_categories["./tests/while_loop.c"]="Control Flow" +test_categories["./tests/for_loop.c"]="Control Flow" +test_categories["./tests/function_call.c"]="Functions" +test_categories["./tests/recursive.c"]="Functions" +test_categories["./tests/bitwise.c"]="Bitwise" +test_categories["./tests/pointers.c"]="Pointers" +test_categories["./tests/arrays.c"]="Arrays" +test_categories["./tests/strings.c"]="Strings" +test_categories["./tests/edge_cases.c"]="Edge Cases" + +# Basic test functions (simplified version) +print_test_header() { + local test_file="$1" + local category="${test_categories[$test_file]}" + local test_name=$(basename "$test_file" .c) + echo -e "${BLUE}┌─ ${WHITE}$test_name${BLUE} (${YELLOW}$category${BLUE})${NC}" + echo -e "${BLUE}│${NC} File: $test_file" + echo -e "${BLUE}│${NC} Expected: ${test_map[$test_file]}" +} + +print_test_result() { + local test_file="$1" + local expected="$2" + local actual="$3" + local status="$4" + + if [ "$status" == "PASS" ]; then + echo -e "${BLUE}│${NC} Result: ${GREEN}✓ PASSED${NC} (got $actual)" + echo -e "${BLUE}└─${GREEN} SUCCESS${NC}" + else + echo -e "${BLUE}│${NC} Result: ${RED}✗ FAILED${NC} (expected $expected, got $actual)" + echo -e "${BLUE}└─${RED} FAILURE${NC}" + fi + echo +} + +print_test_summary() { + local passed="$1" + local failed="$2" + local total="$3" + + echo -e "${CYAN}╔══════════════════════════════════════════════════════════════════════════════╗${NC}" + echo -e "${CYAN}║${WHITE} Test Summary ${CYAN}║${NC}" + echo -e "${CYAN}╠══════════════════════════════════════════════════════════════════════════════╣${NC}" + + if [ $failed -eq 0 ]; then + echo -e "${CYAN}║${GREEN} All tests passed! ${WHITE}($passed/$total)${NC}${CYAN} ║${NC}" + else + echo -e "${CYAN}║${GREEN} Passed: $passed${NC}${CYAN} │ ${RED}Failed: $failed${NC}${CYAN} │ ${WHITE}Total: $total${NC}${CYAN} ║${NC}" + fi + + echo -e "${CYAN}╚══════════════════════════════════════════════════════════════════════════════╝${NC}" +} + +run_basic_tests() { + print_section "Testing" "Running basic test suite" + + local count=0 + local passed=0 + local failed=0 + + for key in "${!test_map[@]}"; do + print_test_header "$key" + + local output + local exit_code + local actual_result + output=$(./bin/ccdjit "$key" 2>&1) + exit_code=$? + + # Extract the actual result from "JIT returned: X" line + actual_result=$(echo "$output" | grep "JIT returned:" | sed 's/.*JIT returned: //' | tail -1) + if [ -z "$actual_result" ]; then + # If no "JIT returned:" found, use exit code + actual_result=$exit_code + fi + + if [ "${test_map[$key]}" = "$actual_result" ]; then + print_test_result "$key" "${test_map[$key]}" "$actual_result" "PASS" + passed=$((passed+1)) + else + print_test_result "$key" "${test_map[$key]}" "$actual_result" "FAIL" + failed=$((failed+1)) + fi + count=$((count+1)) + done + + print_test_summary $passed $failed $count + + if [ $failed -eq 0 ]; then + TEST_SUCCESS=true + else + TEST_SUCCESS=false + fi +} + +# Main command dispatcher +main() { + # Check dependencies first + check_dependencies + + case "${1:-help}" in + "dev"|"development") + dev_mode + ;; + "release") + release_mode + ;; + "debug") + debug_mode + ;; + "clean") + print_header + clean + ;; + "run") + shift + run "$@" + ;; + "test") + if [ ! -f "$BINARY_NAME" ]; then + print_error "Binary not found. Building first..." + build "test" "$RELEASE_FLAGS" "Test build" + fi + print_header + run_basic_tests + ;; + "test-adv"|"test-advanced") + if [ ! -f "$BINARY_NAME" ]; then + print_error "Binary not found. Building first..." + build "test" "$RELEASE_FLAGS" "Test build" + fi + shift + ./test_runner.sh "$@" + ;; + "install") + install_binary "$@" + ;; + "uninstall") + uninstall_binary "$@" + ;; + "info") + show_info + ;; + "help"|"-h"|"--help") + show_help + ;; + *) + echo -e "${RED}Error: Unknown command '$1'${NC}" + echo "Use '$0 help' for usage information" + exit 1 + ;; + esac +} + +# Run main function with all arguments +main "$@"
\ No newline at end of file |
