#!/bin/bash # build-linux.sh - Linux-specific build logic using clang # Handles X11, pthread, fontconfig, etc. # Usage: ./build-linux.sh [debug|release] [x64|x86] set -e # Exit on error # ============================================================================= # Configuration # ============================================================================= SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" CONFIG_DIR="$SCRIPT_DIR/../config" # Source configuration files source "$CONFIG_DIR/build-config.sh" source "$HELPERS_DIR/print-routines.sh" source "$HELPERS_DIR/copy-resources.sh" # ============================================================================= # Platform-specific settings # ============================================================================= setup_linux_vars() { local config=$1 local arch=$2 # Base directories (relative to project root) BUILD_DIR="${BUILD_ROOT:-../build}" CODE_DIR="${CODE_DIR:-../code}" CUSTOM_DIR="${CUSTOM_DIR:-../code/custom}" FOREIGN_DIR="${FOREIGN_DIR:-../non-source/foreign}" # Compiler CXX="clang++" CC="clang" # Base flags for Linux COMMON_FLAGS=( "${CLANG_OPTS_LINUX[@]}" "-I$CODE_DIR" "-I$FOREIGN_DIR/freetype2" ) # Architecture-specific flags case "$arch" in "x64") ARCH_FLAGS=("${ARCH_FLAGS_X64[@]}") ;; "x86") ARCH_FLAGS=("${ARCH_FLAGS_X86[@]}") ;; *) echo "Error: Unsupported architecture: $arch" >&2 return 1 ;; esac # Configuration-specific flags case "$config" in "debug") CONFIG_FLAGS=("${DEBUG_FLAGS[@]}") ;; "release") CONFIG_FLAGS=("${RELEASE_FLAGS[@]}") ;; *) echo "Error: Unsupported config: $config" >&2 return 1 ;; esac # Combine all flags COMPILE_FLAGS=( "${COMMON_FLAGS[@]}" "${ARCH_FLAGS[@]}" "${CONFIG_FLAGS[@]}" ) # Libraries LINK_LIBS=("${LIBS_LINUX[@]}") # Platform includes PLATFORM_INCLUDES=() for inc in "${PLATFORM_INCLUDES_LINUX[@]}"; do PLATFORM_INCLUDES+=("-I$CODE_DIR/$inc") done print_info "Linux build configuration:" print_info " Architecture: $arch" print_info " Configuration: $config" print_info " Compiler: $CXX" } # ============================================================================= # Build functions # ============================================================================= build_core_engine() { print_step "Building core engine (4ed_app.so)" local app_target="$CODE_DIR/4ed_app_target.cpp" local output_lib="$BUILD_DIR/4ed_app.so" # Build flags for shared library local build_flags=( "${COMPILE_FLAGS[@]}" "-shared" "-fPIC" "-DFRED_SUPER" "-DFRED_INTERNAL" ) # Include directories for custom layer local include_flags=( "-I$CUSTOM_DIR" "-I$CUSTOM_DIR/generated" ) print_info "Compiling core application library..." print_info "Input: $app_target" print_info "Output: $output_lib" # Compile core application shared library if [[ "${BUILD_VERBOSE:-}" == "1" ]]; then echo "Executing: $CXX ${build_flags[*]} ${include_flags[*]} -o $output_lib $app_target ${LINK_LIBS[*]}" fi $CXX \ "${build_flags[@]}" \ "${include_flags[@]}" \ -o "$output_lib" \ "$app_target" \ "${LINK_LIBS[@]}" print_success "Core engine built successfully" } build_platform_layer() { print_step "Building platform layer (4ed executable)" local platform_source="$CODE_DIR/platform_linux/linux_4ed.cpp" local output_exe="$BUILD_DIR/4ed" # Build flags for executable local build_flags=( "${COMPILE_FLAGS[@]}" "${PLATFORM_INCLUDES[@]}" "-DFRED_SUPER" "-DFRED_INTERNAL" ) print_info "Compiling platform layer executable..." print_info "Input: $platform_source" print_info "Output: $output_exe" # Compile platform layer executable if [[ "${BUILD_VERBOSE:-}" == "1" ]]; then echo "Executing: $CXX ${build_flags[*]} -o $output_exe $platform_source ${LINK_LIBS[*]}" fi $CXX \ "${build_flags[@]}" \ -o "$output_exe" \ "$platform_source" \ "${LINK_LIBS[@]}" print_success "Platform layer built successfully" } build_custom_layer() { print_step "Building custom layer (custom_4coder.so)" local custom_target="$CUSTOM_DIR/4coder_default_bindings.cpp" local output_lib="$BUILD_DIR/custom_4coder.so" local temp_dir="$BUILD_DIR/temp" # Create temp directory mkdir -p "$temp_dir" # Multi-stage custom layer build process # Stage 1: Preprocess with meta macros print_info "Stage 1: Preprocessing with meta macros..." local preprocessed_file="$temp_dir/4coder_default_bindings.i" $CXX \ -I"$CODE_DIR" \ -I"$CUSTOM_DIR" \ -I"$CUSTOM_DIR/generated" \ -DMETA_PASS \ -E \ "$custom_target" \ -o "$preprocessed_file" print_success "Preprocessing completed" # Stage 2: Build metadata generator print_info "Stage 2: Building metadata generator..." local metadata_generator="$temp_dir/metadata_generator" local metadata_source="$CUSTOM_DIR/4coder_metadata_generator.cpp" $CXX \ "${COMPILE_FLAGS[@]}" \ -I"$CODE_DIR" \ -I"$CUSTOM_DIR" \ -I"$CUSTOM_DIR/generated" \ -o "$metadata_generator" \ "$metadata_source" print_success "Metadata generator built" # Stage 3: Generate metadata print_info "Stage 3: Generating metadata files..." # Ensure generated directory exists mkdir -p "$CUSTOM_DIR/generated" # Run metadata generator "$metadata_generator" \ -R "$CUSTOM_DIR/generated/" \ "$preprocessed_file" print_success "Metadata generated" # Stage 4: Compile custom layer shared library print_info "Stage 4: Compiling custom layer shared library..." local build_flags=( "${COMPILE_FLAGS[@]}" "-shared" "-fPIC" "-I$CUSTOM_DIR" "-I$CUSTOM_DIR/generated" "-DFRED_SUPER" "-DFRED_INTERNAL" ) if [[ "${BUILD_VERBOSE:-}" == "1" ]]; then echo "Executing: $CXX ${build_flags[*]} -o $output_lib $custom_target" fi $CXX \ "${build_flags[@]}" \ -o "$output_lib" \ "$custom_target" print_success "Custom layer built successfully" # Clean up temporary files print_info "Cleaning up temporary files..." rm -f "$preprocessed_file" "$metadata_generator" } validate_build() { print_step "Validating build outputs" local all_good=true local expected_files=("4ed" "4ed_app.so" "custom_4coder.so") for file in "${expected_files[@]}"; do if [[ -f "$BUILD_DIR/$file" ]]; then local file_size file_size=$(stat -c%s "$BUILD_DIR/$file" 2>/dev/null || echo "unknown") print_success "$file (${file_size} bytes)" else echo -e "${RED}✗${NC} Missing: $file" all_good=false fi done if [[ "$all_good" == "true" ]]; then print_success "All build outputs validated" return 0 else echo -e "${RED}✗${NC} Build validation failed" return 1 fi } # ============================================================================= # Main execution # ============================================================================= main() { local config="${1:-debug}" local arch="${2:-x64}" print_step "Linux Build Process" print_info "Configuration: $config" print_info "Architecture: $arch" # Setup platform-specific variables setup_linux_vars "$config" "$arch" # Create build directory mkdir -p "$BUILD_DIR" # Execute build steps build_custom_layer build_core_engine build_platform_layer copy_resources validate_build print_success "Linux build completed successfully!" } # Only run main if script is executed directly (not sourced) if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then main "$@" fi