mirror of
https://git.citron-emu.org/citron/emulator
synced 2025-12-19 02:33:32 +00:00
feat: Add Profile-Guided Optimization (PGO) build support
Implements two-stage PGO build system with CMake integration and automated build scripts for Windows, Linux, and macOS. Supports MSVC, GCC, and Clang compilers. PGO enables runtime profiling-based optimizations for improved emulator performance. Includes helper scripts to streamline the build workflow and resolve platform-specific issues. Signed-off-by: Zephyron <zephyron@citron-emu.org>
This commit is contained in:
203
pgo-build.sh
Normal file
203
pgo-build.sh
Normal file
@@ -0,0 +1,203 @@
|
||||
#!/bin/bash
|
||||
# SPDX-FileCopyrightText: 2025 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# PGO Build Script for Citron (Linux/macOS)
|
||||
# This script automates the Profile-Guided Optimization build process
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
BUILD_DIR="${SCRIPT_DIR}/build"
|
||||
PGO_PROFILES_DIR="${BUILD_DIR}/pgo-profiles"
|
||||
BACKUP_PROFILES_DIR="${SCRIPT_DIR}/pgo-profiles-backup"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
print_header() {
|
||||
echo -e "${BLUE}=================================================================${NC}"
|
||||
echo -e "${BLUE}$1${NC}"
|
||||
echo -e "${BLUE}=================================================================${NC}"
|
||||
}
|
||||
|
||||
print_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
show_usage() {
|
||||
echo "Usage: $0 [STAGE]"
|
||||
echo ""
|
||||
echo "STAGE can be:"
|
||||
echo " generate - Build with PGO instrumentation (Stage 1)"
|
||||
echo " use - Build using PGO profile data (Stage 2)"
|
||||
echo " clean - Clean build directory but preserve profiles"
|
||||
echo ""
|
||||
echo "Example:"
|
||||
echo " $0 generate # Build instrumented version"
|
||||
echo " # Run citron to collect profiles"
|
||||
echo " $0 use # Build optimized version"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -j N Number of parallel jobs (default: auto-detect)"
|
||||
echo " -lto Enable Link-Time Optimization"
|
||||
echo " -h Show this help message"
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
STAGE=""
|
||||
JOBS=$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo "4")
|
||||
ENABLE_LTO="OFF"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
generate|use|clean)
|
||||
STAGE="$1"
|
||||
shift
|
||||
;;
|
||||
-j)
|
||||
JOBS="$2"
|
||||
shift 2
|
||||
;;
|
||||
-lto)
|
||||
ENABLE_LTO="ON"
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
show_usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
print_error "Unknown option: $1"
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$STAGE" ]; then
|
||||
print_error "No stage specified"
|
||||
show_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Clean stage
|
||||
if [ "$STAGE" == "clean" ]; then
|
||||
print_header "Cleaning Build Directory"
|
||||
|
||||
if [ -d "$PGO_PROFILES_DIR" ]; then
|
||||
print_info "Backing up PGO profiles..."
|
||||
mkdir -p "$BACKUP_PROFILES_DIR"
|
||||
cp -r "$PGO_PROFILES_DIR"/* "$BACKUP_PROFILES_DIR/" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
if [ -d "$BUILD_DIR" ]; then
|
||||
print_info "Removing build directory..."
|
||||
rm -rf "$BUILD_DIR"
|
||||
fi
|
||||
|
||||
if [ -d "$BACKUP_PROFILES_DIR" ]; then
|
||||
print_info "Restoring PGO profiles..."
|
||||
mkdir -p "$PGO_PROFILES_DIR"
|
||||
mv "$BACKUP_PROFILES_DIR"/* "$PGO_PROFILES_DIR/" 2>/dev/null || true
|
||||
rm -rf "$BACKUP_PROFILES_DIR"
|
||||
fi
|
||||
|
||||
print_info "Clean complete!"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Generate stage
|
||||
if [ "$STAGE" == "generate" ]; then
|
||||
print_header "PGO Stage 1: Generate Profile Data"
|
||||
|
||||
# Create build directory
|
||||
mkdir -p "$BUILD_DIR"
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
# Configure
|
||||
print_info "Configuring CMake..."
|
||||
cmake .. \
|
||||
-DCITRON_ENABLE_PGO_GENERATE=ON \
|
||||
-DCITRON_ENABLE_LTO=$ENABLE_LTO \
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
# Build
|
||||
print_info "Building instrumented Citron (this may take a while)..."
|
||||
cmake --build . -j"$JOBS"
|
||||
|
||||
print_header "Build Complete!"
|
||||
print_info "Next steps:"
|
||||
echo " 1. Run: ./bin/citron"
|
||||
echo " 2. Play games for 15-30 minutes to collect profile data"
|
||||
echo " 3. Exit citron"
|
||||
|
||||
# Clang-specific instructions
|
||||
if [ "$(cmake --system-information | grep CMAKE_CXX_COMPILER_ID | grep -i clang)" ]; then
|
||||
echo " 4. Merge profiles: llvm-profdata merge -output=$PGO_PROFILES_DIR/default.profdata $PGO_PROFILES_DIR/*.profraw"
|
||||
echo " 5. Run: $0 use"
|
||||
else
|
||||
echo " 4. Run: $0 use"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Use stage
|
||||
if [ "$STAGE" == "use" ]; then
|
||||
print_header "PGO Stage 2: Build Optimized Binary"
|
||||
|
||||
# Check if profile data exists
|
||||
if [ ! -d "$PGO_PROFILES_DIR" ] || [ -z "$(ls -A $PGO_PROFILES_DIR 2>/dev/null)" ]; then
|
||||
print_error "No profile data found in $PGO_PROFILES_DIR"
|
||||
print_info "Please run the generate stage first and collect profile data"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Backup profiles if build directory exists
|
||||
if [ -d "$BUILD_DIR" ]; then
|
||||
print_info "Backing up PGO profiles..."
|
||||
mkdir -p "$BACKUP_PROFILES_DIR"
|
||||
cp -r "$PGO_PROFILES_DIR"/* "$BACKUP_PROFILES_DIR/"
|
||||
rm -rf "$BUILD_DIR"
|
||||
fi
|
||||
|
||||
# Create build directory and restore profiles
|
||||
mkdir -p "$BUILD_DIR"
|
||||
if [ -d "$BACKUP_PROFILES_DIR" ]; then
|
||||
mkdir -p "$PGO_PROFILES_DIR"
|
||||
mv "$BACKUP_PROFILES_DIR"/* "$PGO_PROFILES_DIR/"
|
||||
rm -rf "$BACKUP_PROFILES_DIR"
|
||||
fi
|
||||
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
# Configure
|
||||
print_info "Configuring CMake..."
|
||||
cmake .. \
|
||||
-DCITRON_ENABLE_PGO_USE=ON \
|
||||
-DCITRON_ENABLE_LTO=$ENABLE_LTO \
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
# Build
|
||||
print_info "Building optimized Citron (this may take a while)..."
|
||||
cmake --build . -j"$JOBS"
|
||||
|
||||
print_header "Build Complete!"
|
||||
print_info "Your optimized Citron binary is ready!"
|
||||
print_info "Location: $BUILD_DIR/bin/citron"
|
||||
echo ""
|
||||
print_info "This build is optimized for your specific usage patterns."
|
||||
print_info "Enjoy improved performance! 🚀"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user