Phase 1: Basic config and toolchain detection

This commit is contained in:
Peter Slattery 2025-07-05 13:35:22 -07:00
parent 5f35da8cb7
commit 0866aedcc9
4 changed files with 884 additions and 14 deletions

View File

@ -0,0 +1,297 @@
#!/bin/bash
# build-config.sh - Essential build configuration extracted from 4ed_build.cpp
# This file contains all the platform-specific compiler flags, linker flags, and build settings
# =============================================================================
# Directory Configuration
# =============================================================================
# Build directories
BUILD_DIR="../build"
PACK_DIR="../distributions"
SITE_DIR="../site"
# Source directories
CODE_DIR="../code"
CUSTOM_DIR="../code/custom"
FOREIGN_DIR="../non-source/foreign"
# Include directories
INCLUDES=(
"custom"
"../non-source/foreign/freetype2"
)
# =============================================================================
# Platform Detection
# =============================================================================
# Platform codes
PLATFORM_WINDOWS=0
PLATFORM_LINUX=1
PLATFORM_MAC=2
# Architecture codes
ARCH_X64=0
ARCH_X86=1
# =============================================================================
# Build Flags
# =============================================================================
# Build flag bits (matching 4ed_build.cpp)
FLAG_OPTS=$((0x1)) # Compiler warnings/options
FLAG_LIBS=$((0x2)) # Link libraries
FLAG_ICON=$((0x4)) # Windows icon resource
FLAG_SHARED_CODE=$((0x8)) # Build as shared library
FLAG_DEBUG_INFO=$((0x10)) # Debug symbols
FLAG_OPTIMIZATION=$((0x20)) # Optimization level
FLAG_SUPER=$((0x40)) # Super tier features
FLAG_INTERNAL=$((0x80)) # Internal build flags
FLAG_SHIP=$((0x100)) # Shipping build
# =============================================================================
# Compiler Options - Windows (CL equivalent using clang)
# =============================================================================
# Windows compiler options (translated from CL to clang)
CLANG_OPTS_WINDOWS=(
"-Wall" # Enable most warnings
"-Wno-unused-parameter" # Disable unused parameter warnings
"-Wno-unused-variable" # Disable unused variable warnings
"-Wno-missing-field-initializers" # Disable missing field initializer warnings
"-Wno-deprecated-declarations" # Disable deprecated declarations warnings
"-Wno-missing-braces" # Disable missing braces warnings
"-Wno-tautological-compare" # Disable tautological compare warnings
"-Wno-write-strings" # Disable write strings warnings
"-Werror" # Treat warnings as errors
"-fno-rtti" # Disable RTTI (equivalent to /GR-)
"-fno-exceptions" # Disable exceptions (equivalent to /EHa-)
"-std=c++11" # C++11 standard
"-target x86_64-pc-windows-msvc" # Target Windows with MSVC ABI
)
# Windows libraries
LIBS_WINDOWS=(
"-luser32"
"-lwinmm"
"-lgdi32"
"-lopengl32"
"-lcomdlg32"
"-luserenv"
)
# Windows FreeType libraries
FREETYPE_LIB_WINDOWS_X64="../non-source/foreign/x64/freetype.lib"
FREETYPE_LIB_WINDOWS_X86="../non-source/foreign/x86/freetype.lib"
# Windows icon resource
WINDOWS_ICON="../non-source/res/icon.res"
# =============================================================================
# Compiler Options - Linux (GCC equivalent using clang)
# =============================================================================
CLANG_OPTS_LINUX=(
"-Wno-write-strings"
"-D_GNU_SOURCE"
"-fPIC"
"-fno-threadsafe-statics"
"-pthread"
"-Wno-unused-result"
"-std=c++11"
"-target x86_64-linux-gnu" # Target Linux
)
# Linux libraries
LIBS_LINUX=(
"-lX11"
"-lpthread"
"-lm"
"-lrt"
"-lGL"
"-ldl"
"-lXfixes"
"-lfreetype"
"-lfontconfig"
)
# Linux platform includes
PLATFORM_INCLUDES_LINUX=(
"platform_all"
"platform_unix"
)
# =============================================================================
# Compiler Options - macOS (Clang native)
# =============================================================================
CLANG_OPTS_MACOS=(
"-Wno-write-strings"
"-Wno-deprecated-declarations"
"-Wno-comment"
"-Wno-switch"
"-Wno-null-dereference"
"-Wno-tautological-compare"
"-Wno-unused-result"
"-Wno-missing-declarations"
"-Wno-nullability-completeness"
"-std=c++11"
"-target x86_64-apple-macos10.12" # Target macOS 10.12+
)
# macOS frameworks (equivalent to libraries)
FRAMEWORKS_MACOS=(
"-framework Cocoa"
"-framework QuartzCore"
"-framework CoreServices"
"-framework OpenGL"
"-framework IOKit"
"-framework Metal"
"-framework MetalKit"
)
# macOS FreeType libraries
FREETYPE_LIB_MACOS_X64="../non-source/foreign/x64/libfreetype-mac.a"
FREETYPE_LIB_MACOS_X86="../non-source/foreign/x86/libfreetype-mac.a"
# macOS platform includes
PLATFORM_INCLUDES_MACOS=(
"platform_all"
"platform_unix"
)
# =============================================================================
# Architecture-specific flags
# =============================================================================
# 64-bit architecture
ARCH_FLAGS_X64=(
"-m64"
"-DFTECH_64_BIT"
)
# 32-bit architecture
ARCH_FLAGS_X86=(
"-m32"
"-DFTECH_32_BIT"
)
# =============================================================================
# Build Mode Flags
# =============================================================================
# Debug flags
DEBUG_FLAGS=(
"-g" # Debug symbols
"-O0" # No optimization
"-DDO_CRAZY_EXPENSIVE_ASSERTS" # Enable expensive assertions
)
# Release flags
RELEASE_FLAGS=(
"-O2" # Optimization level 2 (clang equivalent to -O3 for performance)
)
# =============================================================================
# File Lists (from 4ed_build.cpp)
# =============================================================================
# Platform layer files
PLATFORM_FILES_WINDOWS=("platform_win32/win32_4ed.cpp")
PLATFORM_FILES_LINUX=("platform_linux/linux_4ed.cpp")
PLATFORM_FILES_MACOS=("platform_mac/mac_4ed.mm")
# Custom layer default target
DEFAULT_CUSTOM_TARGET="../code/custom/4coder_default_bindings.cpp"
# =============================================================================
# Build Defines
# =============================================================================
# Function to get defines from flags (equivalent to get_defines_from_flags in 4ed_build.cpp)
get_defines_from_flags() {
local flags=$1
local defines=()
if (( flags & FLAG_SHIP )); then
defines+=("-DSHIP_MODE")
fi
if (( flags & FLAG_INTERNAL )); then
defines+=("-DFRED_INTERNAL")
fi
if (( flags & FLAG_SUPER )); then
defines+=("-DFRED_SUPER")
fi
echo "${defines[@]}"
}
# =============================================================================
# Build Outputs
# =============================================================================
# Main executable names
EXECUTABLE_WINDOWS="4ed.exe"
EXECUTABLE_LINUX="4ed"
EXECUTABLE_MACOS="4ed"
# Shared library names
SHARED_LIB_WINDOWS="4ed_app.dll"
SHARED_LIB_LINUX="4ed_app.so"
SHARED_LIB_MACOS="4ed_app.so"
# Custom layer library names
CUSTOM_LIB_WINDOWS="custom_4coder.dll"
CUSTOM_LIB_LINUX="custom_4coder.so"
CUSTOM_LIB_MACOS="custom_4coder.so"
# =============================================================================
# Utility Functions
# =============================================================================
# Get platform-specific settings
get_platform_settings() {
local platform=$1
case $platform in
"windows"|"win32")
echo "PLATFORM_WINDOWS"
;;
"linux")
echo "PLATFORM_LINUX"
;;
"macos"|"mac")
echo "PLATFORM_MAC"
;;
*)
echo "UNKNOWN_PLATFORM"
return 1
;;
esac
}
# Get architecture-specific settings
get_arch_settings() {
local arch=$1
case $arch in
"x64"|"x86_64")
echo "ARCH_X64"
;;
"x86"|"i386")
echo "ARCH_X86"
;;
*)
echo "UNKNOWN_ARCH"
return 1
;;
esac
}
# Check if flag is set
has_flag() {
local flags=$1
local flag=$2
(( flags & flag ))
}

View File

@ -0,0 +1,438 @@
#!/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

View File

@ -0,0 +1,128 @@
#!/bin/bash
# detect-platform.sh - Platform detection utility
# Returns: win32, linux, or macos
# Exit code: 0 for success, 1 for unknown platform
set -e
# =============================================================================
# Platform Detection
# =============================================================================
detect_platform() {
local uname_output
uname_output=$(uname -s)
case "$uname_output" in
"Darwin")
echo "macos"
return 0
;;
"Linux")
echo "linux"
return 0
;;
"CYGWIN"*|"MINGW"*|"MSYS"*)
echo "win32"
return 0
;;
*)
echo "Error: Unknown platform '$uname_output'" >&2
echo "Supported platforms: Darwin (macOS), Linux, CYGWIN/MINGW/MSYS (Windows)" >&2
return 1
;;
esac
}
# =============================================================================
# Additional Platform Information
# =============================================================================
detect_architecture() {
local uname_machine
uname_machine=$(uname -m)
case "$uname_machine" in
"x86_64"|"amd64")
echo "x64"
return 0
;;
"i386"|"i686")
echo "x86"
return 0
;;
"arm64"|"aarch64")
echo "arm64"
return 0
;;
*)
echo "Error: Unknown architecture '$uname_machine'" >&2
echo "Supported architectures: x86_64, i386, i686, arm64, aarch64" >&2
return 1
;;
esac
}
get_platform_info() {
local platform arch
platform=$(detect_platform)
if [[ $? -ne 0 ]]; then
return 1
fi
arch=$(detect_architecture)
if [[ $? -ne 0 ]]; then
return 1
fi
echo "Platform: $platform"
echo "Architecture: $arch"
echo "Full info: $(uname -a)"
return 0
}
# =============================================================================
# Main execution
# =============================================================================
main() {
local command="${1:-detect}"
case "$command" in
"detect")
detect_platform
;;
"arch")
detect_architecture
;;
"info")
get_platform_info
;;
"help"|"-h"|"--help")
echo "Usage: $0 [detect|arch|info|help]"
echo ""
echo "Commands:"
echo " detect - Detect platform (macos, linux, win32)"
echo " arch - Detect architecture (x64, x86, arm64)"
echo " info - Show detailed platform information"
echo " help - Show this help message"
echo ""
echo "Examples:"
echo " $0 detect # Returns: macos"
echo " $0 arch # Returns: x64"
echo " $0 info # Returns: Platform: macos, Architecture: x64, etc."
;;
*)
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

View File

@ -23,36 +23,43 @@ Platform Script → Compile 4ed_build.cpp → Execute 4ed_build → Generate Com
Platform Script → Direct Clang Calls → Build Platform Script → Direct Clang Calls → Build
``` ```
## Phase 1: Foundation and Analysis (2-3 days) ## Phase 1: Foundation and Analysis (2-3 days) ✅ COMPLETED
### TODO 1.1: Set Up New Build Directory Structure ### TODO 1.1: Set Up New Build Directory Structure
- [ ] Create `build_new/` directory for new build scripts - [x] Create `build_new/` directory for new build scripts
- [ ] Create subdirectories: - [x] Create subdirectories:
- `build_new/scripts/` - Main build scripts - `build_new/scripts/` - Main build scripts
- `build_new/helpers/` - Helper scripts and utilities - `build_new/helpers/` - Helper scripts and utilities
- `build_new/config/` - Build configuration files - `build_new/config/` - Build configuration files
- `build_new/temp/` - Temporary files during build - `build_new/temp/` - Temporary files during build
### TODO 1.2: Extract Essential Build Parameters ### TODO 1.2: Extract Essential Build Parameters
- [ ] Analyze `4ed_build.cpp` to extract all compiler flags per platform - [x] Analyze `4ed_build.cpp` to extract all compiler flags per platform
- [ ] Document all linker flags and library dependencies - [x] Document all linker flags and library dependencies
- [ ] Create configuration file with all essential build parameters: - [x] Create configuration file with all essential build parameters:
```bash ```bash
# build_new/config/build-config.sh # build_new/config/build-config.sh
# Platform-specific compiler flags, library paths, etc. # Platform-specific compiler flags, library paths, etc.
``` ```
### TODO 1.3: Create Platform Detection Utility ### TODO 1.3: Create Platform Detection Utility
- [ ] Write `build_new/helpers/detect-platform.sh`: - [x] Write `build_new/helpers/detect-platform.sh`:
```bash ```bash
#!/bin/bash #!/bin/bash
# Returns: win32, linux, or macos # Returns: win32, linux, or macos
``` ```
### TODO 1.4: Verify Clang Installation Requirements ### TODO 1.4: Verify Clang Installation Requirements ✅
- [ ] Document clang version requirements for each platform - [x] Document clang version requirements for each platform
- [ ] Create `build_new/helpers/check-toolchain.sh` to verify clang availability - [x] Create `build_new/helpers/check-toolchain.sh` to verify clang availability
- [ ] Document any additional platform-specific setup needed - [x] Document any additional platform-specific setup needed
**Phase 1 Results:**
- ✅ Build directory structure created
- ✅ Essential build parameters extracted and documented in `build_new/config/build-config.sh`
- ✅ Platform detection utility working (`build_new/helpers/detect-platform.sh`)
- ✅ Toolchain verification script working (`build_new/helpers/check-toolchain.sh`)
- ✅ Current environment verified: macOS with clang 16.0, all dependencies available
## Phase 2: Core Build Script Development (4-5 days) ## Phase 2: Core Build Script Development (4-5 days)