4coder/build_new/scripts/build-win32.sh

359 lines
10 KiB
Bash
Executable File

#!/bin/bash
# build-win32.sh - Windows-specific build logic using clang
# Handles Windows APIs, resource compilation, etc.
# Usage: ./build-win32.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_win32_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 (using clang with Windows target)
CXX="clang++"
CC="clang"
# Base flags for Windows
COMMON_FLAGS=(
"${CLANG_OPTS_WINDOWS[@]}"
"-I$CODE_DIR"
"-I$FOREIGN_DIR/freetype2"
)
# Architecture-specific flags
case "$arch" in
"x64")
ARCH_FLAGS=("${ARCH_FLAGS_X64[@]}")
FREETYPE_LIB="$FREETYPE_LIB_WINDOWS_X64"
;;
"x86")
ARCH_FLAGS=("${ARCH_FLAGS_X86[@]}")
FREETYPE_LIB="$FREETYPE_LIB_WINDOWS_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_WINDOWS[@]}"
"$FREETYPE_LIB"
)
# Platform includes
PLATFORM_INCLUDES=()
# Windows doesn't have additional platform includes in the original build
print_info "Windows build configuration:"
print_info " Architecture: $arch"
print_info " Configuration: $config"
print_info " Compiler: $CXX"
print_info " FreeType: $FREETYPE_LIB"
}
# =============================================================================
# Resource compilation (Windows-specific)
# =============================================================================
compile_resources() {
print_step "Compiling Windows resources"
local icon_rc="$CODE_DIR/../non-source/res/icon.rc"
local icon_res="$BUILD_DIR/icon.res"
if [[ -f "$icon_rc" ]]; then
print_info "Compiling icon resource..."
# Use windres if available, otherwise skip resources
if command -v windres &> /dev/null; then
windres "$icon_rc" -o "$icon_res"
print_success "Icon resource compiled"
echo "$icon_res" # Return the resource file path
else
print_warning "windres not found, skipping resource compilation"
echo "" # Return empty string
fi
else
print_warning "Icon resource file not found: $icon_rc"
echo "" # Return empty string
fi
}
# =============================================================================
# Build functions
# =============================================================================
build_core_engine() {
print_step "Building API Parser..."
$CUSTOM_DIR/bin/build_one_time.sh $CODE_DIR/4ed_api_parser_main.cpp $BUILD_DIR && cp $BUILD_DIR/one_time $BUILD_DIR/api_parser
print_step "Building System API..."
$CUSTOM_DIR/bin/build_one_time.sh $CODE_DIR/4ed_system_api.cpp $BUILD_DIR && $BUILD_DIR/one_time
print_step "Building API Check..."
$CUSTOM_DIR/bin/build_one_time.sh $CODE_DIR/4ed_api_check.cpp $BUILD_DIR && cp $BUILD_DIR/one_time $BUILD_DIR/api_checker
print_step "Running API Parser..."
$BUILD_DIR/api_parser $CODE_DIR/4ed_api_implementation.cpp
print_step "Building Font API..."
$CUSTOM_DIR/bin/build_one_time.sh $CODE_DIR/4ed_font_api.cpp $BUILD_DIR && $BUILD_DIR/one_time
print_step "Building Graphics API..."
$CUSTOM_DIR/bin/build_one_time.sh $CODE_DIR/4ed_graphics_api.cpp $BUILD_DIR && $BUILD_DIR/one_time
print_step "Building core engine (4ed_app.dll)"
local app_target="$CODE_DIR/4ed_app_target.cpp"
local output_lib="$BUILD_DIR/4ed_app.dll"
# Build flags for shared library
local build_flags=(
"${COMPILE_FLAGS[@]}"
"-shared"
"-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.exe)"
local platform_source="$CODE_DIR/platform_win32/win32_4ed.cpp"
local output_exe="$BUILD_DIR/4ed.exe"
# Compile resources
local resource_file
resource_file=$(compile_resources)
# Build flags for executable
local build_flags=(
"${COMPILE_FLAGS[@]}"
"${PLATFORM_INCLUDES[@]}"
"-DFRED_SUPER"
"-DFRED_INTERNAL"
)
# Add resource file if it exists
local resource_args=()
if [[ -n "$resource_file" && -f "$resource_file" ]]; then
resource_args=("$resource_file")
print_info "Including resource file: $resource_file"
fi
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 ${resource_args[*]} ${LINK_LIBS[*]}"
fi
$CXX \
"${build_flags[@]}" \
-o "$output_exe" \
"$platform_source" \
"${resource_args[@]}" \
"${LINK_LIBS[@]}"
print_success "Platform layer built successfully"
}
build_custom_layer() {
print_step "Building custom layer (custom_4coder.dll)"
local custom_target="$CUSTOM_DIR/4coder_default_bindings.cpp"
local output_lib="$BUILD_DIR/custom_4coder.dll"
local temp_dir="$BUILD_DIR/temp"
# Create temp directory
mkdir -p "$temp_dir"
# Multi-stage custom layer build process
# Stage 0: Build and Run Generators
mkdir -p "$CODE_DIR/generated"
print_step "Building CPP Lexer Gen..."
$CUSTOM_DIR/bin/build_one_time.sh $CUSTOM_DIR/languages/4coder_cpp_lexer_gen.cpp $BUILD_DIR && $BUILD_DIR/one_time
print_step "Building Generate Keycodes..."
$CUSTOM_DIR/bin/build_one_time.sh $CODE_DIR/4ed_generate_keycodes.cpp $BUILD_DIR && $BUILD_DIR/one_time
print_step "Building Docs..."
$CUSTOM_DIR/bin/build_one_time.sh $CODE_DIR/docs/4ed_doc_custom_api_main.cpp $BUILD_DIR && $BUILD_DIR/one_time
# Ensure generated directory exists
mkdir -p "$CUSTOM_DIR/generated"
# Ensure generated directory exists
mkdir -p "$CUSTOM_DIR/generated"
# Stage 2: Generate metadata
$SCRIPTS_DIR/build-metadata.sh
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"
"-I$CUSTOM_DIR"
"-I$CUSTOM_DIR/generated"
"-DFRED_SUPER"
"-DFRED_INTERNAL"
)
# Add export flags for Windows DLL
local export_flags=(
"-Wl,--export-all-symbols"
"-Wl,--out-implib,$BUILD_DIR/custom_4coder.lib"
)
if [[ "${BUILD_VERBOSE:-}" == "1" ]]; then
echo "Executing: $CXX ${build_flags[*]} ${export_flags[*]} -o $output_lib $custom_target"
fi
$CXX \
"${build_flags[@]}" \
"${export_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.exe" "4ed_app.dll" "custom_4coder.dll")
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 "Windows Build Process"
print_info "Configuration: $config"
print_info "Architecture: $arch"
# Setup platform-specific variables
setup_win32_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 "Windows build completed successfully!"
}
# Only run main if script is executed directly (not sourced)
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi