Big Commit

The changes affects multiple places in the repo and this one of the rare
instances where I cant be bothered writing a comprehensive commit. Look
at the diff for changes.

Signed-off-by: Ronald Caesar <github43132@proton.me>
This commit is contained in:
Ronald Caesar 2025-09-23 19:20:25 -04:00
parent 4dd8506346
commit 6bdfd6fcea
No known key found for this signature in database
GPG key ID: 04307C401999C596
10 changed files with 669 additions and 25 deletions

View file

@ -20,7 +20,7 @@ jobs:
shorthash: ${{steps.vars.outputs.shorthash}}
commit: ${{steps.vars.outputs.commit}}
steps:
- uses: actions/checkout@main
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Commit Count and Git Hash
@ -36,7 +36,7 @@ jobs:
runs-on: ubuntu-24.04
needs: get-info
steps:
- uses: actions/checkout@main
- uses: actions/checkout@v5
with:
submodules: recursive
fetch-depth: 0
@ -44,6 +44,7 @@ jobs:
- name: Install Dependencies
run: |
sudo apt update
sudo apt-get remove --purge man-db
sudo apt install -y ninja-build clang lld cmake ccache \
libx11-dev libxext-dev libxrandr-dev libxcursor-dev \
libxi-dev libxinerama-dev libwayland-dev libxkbcommon-dev \
@ -71,7 +72,7 @@ jobs:
runs-on: windows-2025
needs: get-info
steps:
- uses: actions/checkout@main
- uses: actions/checkout@v5
with:
submodules: recursive
fetch-depth: 0
@ -101,7 +102,7 @@ jobs:
runs-on: macos-13
needs: get-info
steps:
- uses: actions/checkout@main
- uses: actions/checkout@v5
with:
submodules: recursive
fetch-depth: 0
@ -143,7 +144,7 @@ jobs:
runs-on: macos-14
needs: get-info
steps:
- uses: actions/checkout@main
- uses: actions/checkout@v5
with:
submodules: recursive
fetch-depth: 0

34
3rd_Party/PINNED_DEPENDENCIES.md vendored Normal file
View file

@ -0,0 +1,34 @@
# Pinned Submodule Versions
## Overview
This document tracks all pinned third-party submodules in the Pound project. Each submodule is locked to a specific commit hash to ensure reproducible builds and prevent unexpected updates.
## Update Policy
**NEVER update submodule commits without explicit approval from the project lead.** All updates must:
1. Be tested thoroughly
2. Have documented justification
3. Update this document with the new commit hash
4. Be committed as a separate, clear change
### ImGui
- **Repository**: https://github.com/ocornut/imgui.git
- **Version Tag**: v1.92.3
- **Pinned Commit**: bf75bfec48fc00f532af8926130b70c0e26eb099:
- **License**: MIT
- **Purpose**: Provides the graphical user interface for Pound.
- **Pinning Date**: 2025-09-20
- **Pinning Reason**: Provides the UI functionality we need with no known security issues
- **Last Review**: 2025-09-20
- **Next Review**: 2026-03-20
### SDL3
- **Repository**: https://github.com/libsdl-org/SDL
- **Version Tag**: v3.2.22
- **Commit Hash**: a96677bdf6b4acb84af4ec294e5f60a4e8cbbe03
- **License**: Zlib
- **Purpose**: Provides the backend renderer for ImGui.
- **Pinning Date**: 2025-09-20
- **Pinning Reason**: Provides the UI render backend functionality we need with no known security issues
- **Last Review**: 2025-09-20
- **Next Review**: 2026-03-20

43
3rd_Party/UPDATE_PROCEDURE.md vendored Normal file
View file

@ -0,0 +1,43 @@
# Updating Git Submodules
1. **Update to New Version (Manual)**
```bash
cd 3rd_party/imgui #imgui for example
git fetch origin
git tag -l "v*" # List available versions
git checkout v1.90.0 # Or desired version
cd ../..
git add 3rd_party/imgui
git commit -m "Update ImGui to v1.90.0"
git submodule update --init --recursive
```
2. **Update to New Version (Automatated)**
`scripts/update_submodule.sh`
3. **Update Documentation**
- Update relevant information in PINNED_DEPENDENCIES.md
## For Security Updates
1. Identify the security vulnerability and the specific commit that fixes it
2. Review the changes between current pinned commit and the fix
3. Test the updated version thoroughly
4. Update the submodule to the fixing commit
5. Update this document with the new commit hash
6. Commit with clear message with `scripts/update_submodule.sh`
## For Feature Updates
1. Justify why the feature update is necessary
2. Get approval from project lead
3. Review all changes between current and new version
4. Test thoroughly including regression testing
5. Update the submodule to the new commit
6. Update this document
7. Commit with clear message with `scripts/update_submodule.sh`
## For Emergency Rollbacks
If a pinned commit introduces issues:
1. Immediately revert to the previous known-good commit
2. Document the issue and reason for rollback
3. Update this document
4. Commit with clear message with `scripts/update_submodule.sh`

View file

@ -14,6 +14,7 @@ set(CMAKE_C_STANDARD 17)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_C_STANDARD_REQUIRED TRUE)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
#-------------------------------
# ---- Dependency Discovery ----
@ -23,14 +24,73 @@ find_package(OpenGL REQUIRED)
find_package(fmt 10.2.1 CONFIG)
find_package(SDL3 3.2.10 CONFIG)
message(STATUS "Verifying Git submodules integrity...")
# Check if submodules are properly initialized.
execute_process(
COMMAND git submodule status
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE submodule_status
RESULT_VARIABLE result
)
if(NOT result EQUAL 0)
message(FATAL_ERROR "Failed to get submodule status")
endif()
# Function to verify a specific submodule's pinned commit
function(verify_pinned_commit name path actual_commit expected_commit)
if(NOT actual_commit STREQUAL expected_commit)
message(FATAL_ERROR
"${name} submodule commit mismatch!\n"
"Path: ${path}\n"
"Expected: ${expected_commit}\n"
"Actual: ${actual_commit}\n"
"Submodule may have been updated. Please revert to pinned commit with:\n"
" cd ${path}\n"
" git checkout ${expected_commit}\n"
" cd ../..\n"
" git add ${path}\n"
" git commit -m \"Revert ${name} to pinned commit\""
)
endif()
message(STATUS "${name} commit matches pinned version: ${expected_commit}")
endfunction()
# Parse submodule status and verify each one
string(REPLACE "\n" ";" submodule_lines ${submodule_status})
foreach(line ${submodule_lines})
# Extract status character (first character)
string(SUBSTRING ${line} 0 1 status_char)
# Extract commit hash
string(REGEX REPLACE "^([ +-])([0-9a-f]+) .*" "\\2" commit_hash ${line})
# Extract path
string(REGEX REPLACE "^[ +-][0-9a-f]+ ([^ ]+).*" "\\1" submodule_path ${line})
if(status_char STREQUAL "-")
message(FATAL_ERROR "Submodule ${submodule_path} is not initialized. Please run: git submodule update --init --recursive")
elseif(status_char STREQUAL "+")
message(WARNING "Submodule ${submodule_path} has uncommitted chamges")
endif()
# Verify pinned commit for known submodules
if(submodule_path STREQUAL "3rd_Party/imgui")
verify_pinned_commit("imgui" "${submodule_path}" "${commit_hash}" "bf75bfec48fc00f532af8926130b70c0e26eb099")
elseif(submodule_path STREQUAL "3rd_Party/SDL3")
verify_pinned_commit("SDL3" "${submodule_path}" "${commit_hash}" "a96677bdf6b4acb84af4ec294e5f60a4e8cbbe03")
endif()
message(STATUS "Verified submodule: ${submodule_path} (${commit_hash})")
endforeach()
message(STATUS "All submodules verified successfully")
#-----------------------------
# ---- Target Definitions ----
#-----------------------------
if(WIN32)
add_compile_options(-DNOMINMAX -DWIN32_LEAN_AND_MEAN)
endif()
add_executable(Pound
src/main.cpp
)
@ -46,6 +106,10 @@ add_subdirectory(src/targets/switch1/hardware)
# ---- Target Configurations ----
#--------------------------------
if(WIN32)
add_compile_options(-DNOMINMAX -DWIN32_LEAN_AND_MEAN)
endif()
include(TestBigEndian)
TEST_BIG_ENDIAN(WORDS_BIGENDIAN)
@ -78,8 +142,6 @@ foreach(TARGET ${POUND_PROJECT_TARGETS})
target_compile_definitions(${TARGET} PRIVATE COMPILE_TIME_LOG_LEVEL=1)
endforeach()
# Optimizations
set_property(TARGET Pound PROPERTY CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE)
if (WIN32)

11
COMPILING.md Normal file
View file

@ -0,0 +1,11 @@
### Initial Setup
```bash
git clone https://github.com/pound-emu/pound.git
cd pound
./scripts/setup_submodules.sh
mkdir build
cd build
cmake ..
make
```

View file

@ -2,7 +2,7 @@
**Author:** GloriousTacoo, Lead Developer
**Status:** FINAL
**Version:** 1.0
**Version:** 2.0
**Date:** 2025-09-20
*Disclaimer: This document was mostly written by AI. I'm not a good technical writer.*
@ -13,11 +13,11 @@ We require a rigorous, auditable, and maintainable strategy for including third-
### **2. Glossary**
Third-party code refers to any software component not developed in-house as part of the Pound project, including libraries, frameworks, and tools that are incorporated into our build system. Vendoring is the practice of copying third-party source code directly into the project repository, creating a local snapshot that is version-controlled alongside our own code. Submodules are Git mechanisms that link to external repositories while maintaining version references within our main repository. CMake FetchContent is a modern CMake feature that downloads and configures dependencies at build time, integrating them directly into the build process without requiring separate management. Dependency pinning refers to the practice of locking to specific versions of third-party code to prevent unexpected updates from introducing instability or security vulnerabilities.
Third-party code refers to any software component not developed in-house as part of the Pound project, including libraries, frameworks, and tools that are incorporated into our build system. Git submodules are Git mechanisms that link to external repositories while maintaining version references within our main repository, allowing for the inclusion of external codebases as nested repositories. Submodule pinning refers to the practice of locking submodules to specific commits to prevent unexpected updates from introducing instability or security vulnerabilities. Cryptographic integrity verification is the process of using Git's built-in cryptographic mechanisms to ensure that submodule code has not been tampered with. Dependency manifest is a document that tracks all third-party dependencies, their versions, origins, and security status. License compatibility refers to the ability to combine software under different licenses without violating the terms of any license.
### **3. Breaking Changes**
Any transition to a new third-party inclusion strategy will require immediate and comprehensive refactoring of the existing build system. All current third-party dependencies must be evaluated against the new standard, with non-compliant components either brought into compliance or removed from the project. The CMakeLists.txt files throughout the project hierarchy will require complete rewriting to implement the chosen strategy. Continuous integration pipelines must be updated to enforce compliance. This is not a gradual transition but a complete overhaul of our dependency management philosophy that will affect every aspect of the build process.
Any transition to a new third-party inclusion strategy will require immediate and comprehensive refactoring of the existing build system. All current third-party dependencies must be converted to Git submodules, with non-compliant components either brought into compliance or removed from the project. The CMakeLists.txt files throughout the project hierarchy will require complete rewriting to build from submodule sources rather than vendored copies. Continuous integration pipelines must be updated to properly initialize and update submodules. This is not a gradual transition but a complete overhaul of our dependency management philosophy that will affect every aspect of the build process.
### **4. Success Criteria**
@ -25,23 +25,23 @@ A successful third-party inclusion strategy must provide complete auditability o
### **5. Proposed Design**
Our philosophy must be that third-party code is not trusted by default but rather treated as potentially hostile until proven otherwise through rigorous evaluation and continuous monitoring. The strategy must prioritize control over convenience, ensuring that every line of third-party code included in the project is explicitly approved, documented, and monitored throughout its lifecycle. We will implement a defense-in-depth approach where each dependency is evaluated not just for functionality but for security posture, maintenance status, and compatibility with our fail-fast philosophy. The build system must enforce strict version control and prevent automatic updates that could introduce unexpected behavior or security vulnerabilities.
Our philosophy must be that third-party code is not trusted by default but rather treated as potentially hostile until proven otherwise through rigorous evaluation and continuous monitoring. The strategy must prioritize control over convenience, ensuring that every line of third-party code included in the project is explicitly approved, documented, and monitored throughout its lifecycle. We will implement a defense-in-depth approach where each dependency is evaluated not just for functionality but for security posture, maintenance status, and compatibility with our fail-fast philosophy. Git's built-in cryptographic integrity verification will serve as our primary defense against tampering, with all submodules pinned to specific commits to prevent unexpected changes.
### **6. Technical Design**
The recommended approach is direct vendoring of all third-party code into a dedicated 3rd_Party directory with strict version control and comprehensive documentation. Each vendored dependency must reside in its own subdirectory with clear attribution, license information, and a README detailing its purpose and any modifications made. The build system will reference these local copies exclusively, eliminating any external network dependencies during the build process. All vendored code must be subjected to the same static analysis and coding standards as our own code, with automated checks ensuring compliance. A manifest file will track all dependencies, their versions, origins, and security status, with automated tools regularly checking for known vulnerabilities in the included components.
The recommended approach is to manage all third-party code as Git submodules within the repository structure. Each dependency will be added as a submodule in the 3rd_party directory, pinned to a specific commit that has been reviewed and approved for inclusion. The process begins with identifying the specific version needed for inclusion, rather than simply using "latest" which is not reproducible. For each dependency, the appropriate commit hash is identified and documented, ensuring that the exact same code is used across all builds. The submodule is added using `git submodule add` with the specific commit hash, creating a persistent reference to that exact version of the external repository. All submodules must be documented with a comprehensive README file that includes the repository URL, commit hash, license information, and purpose within the project. The build system will be configured to build directly from the submodule directories, with CMakeLists.txt files in the main project referencing these submodule paths. Automated verification scripts will run during the CMake configuration phase to ensure all submodules are properly initialized and have not been modified unexpectedly. The process for updating submodules must be clearly documented, including steps for notification, review, testing, and integration of new versions. Any custom patches or modifications to submodule code must be strictly avoided if possible, but when necessary, they must be clearly documented, tracked separately, and ideally submitted upstream for inclusion in future releases. The build system will enforce strict version control through commit pinning, preventing automatic updates that could introduce unexpected behavior or security vulnerabilities, ensuring that all builds are completely reproducible regardless of external network availability.
### **7. Components**
The strategy involves several key components working together to ensure safe dependency management. The 3rd_Party directory serves as the centralized repository for all external code, with each dependency isolated in its own version-controlled subdirectory. The build system, primarily CMake, will be configured to build exclusively from these local copies, with no external network access during compilation. A dependency manifest will maintain metadata about each included component, including version hashes, license information, and security status. Automated tooling will continuously monitor these dependencies for security vulnerabilities and compliance with our coding standards. Documentation requirements mandate that each dependency include clear attribution, modification logs, and integration notes.
The strategy involves several key components working together to ensure safe dependency management. The 3rd_party directory serves as the centralized location for all submodule references, with each dependency maintained as a separate nested repository. The Git submodule system provides the core mechanism for including external code while maintaining cryptographic integrity verification. The build system, primarily CMake, will be configured to build directly from submodule sources, with no external network access during compilation. A dependency manifest will maintain metadata about each included component, including repository URLs, commit hashes, license information, and security status. Automated tooling will continuously monitor these dependencies for security vulnerabilities and compliance with our coding standards. Documentation requirements mandate that each dependency include clear attribution, modification logs, and integration notes.
### **8. Dependencies**
This strategy depends on several critical elements to be effective. The version control system must provide robust support for large binary files and complete history tracking to maintain the integrity of vendored components. The build system must be capable of handling complex dependency graphs without requiring network access during compilation. Automated security scanning tools must be integrated into the development workflow to continuously monitor for vulnerabilities in third-party components. Developer training and enforcement mechanisms are essential to ensure compliance with the new standards. Legal review processes must be in place to verify license compatibility and ensure that all third-party inclusions meet our open-source requirements.
This strategy depends on several critical elements to be effective. The Git version control system must be available and properly configured for all developers and build environments. The build system must be capable of handling submodule initialization and updates as part of the build process. Automated security scanning tools must be integrated into the development workflow to continuously monitor for vulnerabilities in third-party components. Developer training and enforcement mechanisms are essential to ensure compliance with the new standards. Legal review processes must be in place to verify license compatibility and ensure that all third-party inclusions meet our open-source requirements. The continuous integration system must be configured to properly initialize submodules and verify their integrity before building.
### **9. Major Risks & Mitigations**
The primary risk is that vendoring large third-party components will bloat the repository size, potentially impacting clone times and storage requirements. This can be mitigated through Git LFS (Large File Storage) and careful selection of only essential components. Another significant risk is the potential for falling behind on security updates if the vendored approach makes updates more cumbersome. This will be addressed through automated monitoring tools and streamlined update processes that minimize the effort required to apply security patches.
The primary risk is that submodules may introduce complexity in dependency management, particularly for developers unfamiliar with Git submodules. This will be mitigated through comprehensive documentation, automated verification scripts, and clear procedures for submodule initialization and updates. Another significant risk is the potential for divergence between the main repository and submodule references, leading to build failures. This will be addressed through automated verification during the CMake configuration phase and clear error messages when submodules are not properly synchronized. There is also a risk that upstream repositories may disappear or become unavailable, making it impossible to clone submodules. This will be mitigated by maintaining a comprehensive dependency manifest with all necessary information and considering periodic archival of critical dependencies. The risk of license incompatibility will be addressed through thorough review of all submodule licenses before inclusion and continuous monitoring for license changes.
### **10. Out of Scope**
@ -49,8 +49,8 @@ This strategy does not address the evaluation of specific third-party libraries
### **11. Alternatives Considered**
The primary alternative to direct vendoring is the use of Git submodules, which maintain references to external repositories while keeping them logically separate from the main codebase. While this approach reduces repository bloat, it introduces significant complexity in dependency management and makes builds less reliable due to external network dependencies. Another alternative is CMake FetchContent, which downloads dependencies at build time. This approach offers convenience but sacrifices reproducibility and control, as builds become dependent on external network availability and the continued existence of remote repositories. Package managers like vcpkg or Conan were also considered but rejected due to their complexity and the additional attack surface they introduce. Each of these alternatives was ultimately deemed unsuitable for a safety-critical system where control and reproducibility are paramount.
The primary alternative to Git submodules is direct vendoring of third-party code into the repository, which involves copying source code directly into the project repository. While this approach provides complete control over dependencies and eliminates external network dependencies during builds, it significantly increases repository size and makes updates more cumbersome. Another alternative is CMake FetchContent, which downloads dependencies at build time. This approach offers convenience but sacrifices reproducibility and control, as builds become dependent on external network availability and the continued existence of remote repositories. Package managers like vcpkg or Conan were also considered but rejected due to their complexity and the additional attack surface they introduce. Each of these alternatives was ultimately deemed unsuitable for a safety-critical system where cryptographic integrity verification and reproducibility are paramount.
### **12. Recommendation**
After careful analysis of all alternatives, direct vendoring with strict version control represents the superior approach for the Pound project. While it requires more discipline and introduces repository size considerations, it provides the level of control, auditability, and reproducibility demanded by a safety-critical system. The current approach of mixed dependency management methods must be replaced entirely with this standardized vendoring strategy. The benefits of complete control, offline builds, and comprehensive auditability far outweigh the inconvenience of managing larger repositories. This approach aligns perfectly with our fail-fast philosophy and ensures that every line of code in the project, whether first-party or third-party, is subject to the same rigorous standards of safety and reliability. The transition to this approach should begin immediately with a complete inventory of all current third-party dependencies.
After careful analysis of all alternatives, Git submodules represent the superior approach for the Pound project. While they introduce some complexity in dependency management, they provide the level of cryptographic integrity verification, version control, and reproducibility demanded by a safety-critical system. The current approach of mixed dependency management methods must be replaced entirely with this standardized submodule strategy. The benefits of Git's built-in integrity verification, clear version tracking, and simplified updates far outweigh the complexity of submodule management. This approach aligns perfectly with our fail-fast philosophy and ensures that every line of code in the project, whether first-party or third-party, is subject to the same rigorous standards of safety and reliability. The transition to this approach should begin immediately with a complete inventory of all current third-party dependencies and their conversion to Git submodules.

28
scripts/log.sh Normal file
View file

@ -0,0 +1,28 @@
#!bin/bash
# Error handling function
error_handler() {
local exit_code=$?
local line_number=$1
log_critical "Script exited with code $exit_code at line $line_number"
log_critical "ABORT: Submodule setup failed - SYSTEM IN UNSTABLE STATE"
cleanup_on_failure
exit $exit_code
}
trap 'error_handler $LINENO' ERR
# Logging system
log() {
local level=$1
shift
local message="$*"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] [$level] $message"
}
log_info() { log "INFO" "$*"; }
log_warn() { log "WARN" "$*"; }
log_error() { log "ERROR" "$*"; }
log_critical() { log "CRITICAL" "$*"; }

381
scripts/setup_submodules.sh Executable file
View file

@ -0,0 +1,381 @@
#!/bin/bash
# Setup submodules with proper pinning configuration
# DISCLAIMER: This was written by AI. GLM-4.5 wrote this better than I ever could.
DIR="${BASH_SOURCE%/*}"
if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
. "$DIR/log.sh"
set -uo pipefail errtrace
IFS=$'\n\t'
# Global variables
SCRIPT_NAME="$(basename "$0")"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(git rev-parse --show-toplevel)"
# Status tracking
declare -i VALIDATION_ERRORS=0
declare -i CONFIGURATION_ERRORS=0
declare -i INITIALIZATION_ERRORS=0
# =============================================================================
# VALIDATION FUNCTIONS
# =============================================================================
validate_environment() {
log_info "Validating environment..."
# Check if we're in the correct repository
if [[ ! -f ".gitmodules" ]]; then
log_critical "Not in pound repository root or .gitmodules missing"
exit 1
fi
# Check required tools
local required_tools=("git" "bash" "mkdir" "rm" "tee")
for tool in "${required_tools[@]}"; do
if ! command -v "$tool" >/dev/null 2>&1; then
log_critical "Required tool '$tool' not found in PATH"
exit 1
fi
done
# Check git repository state
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
log_critical "Not inside a git repository"
exit 1
fi
# Check for uncommitted changes
if ! git diff-index --quiet HEAD --; then
log_warn "Uncommitted changes detected - this may affect submodule setup"
fi
# Check disk space
local available_space
available_space=$(df . | awk 'NR==2 {print $4}')
if [[ $available_space -lt 1048576 ]]; then # Less than 1GB
log_warn "Low disk space available: $available_space KB"
fi
log_info "Environment validation complete."
}
validate_submodules() {
log_info "Validating submodule configuration..."
# Check if .gitmodules exists and is readable
if [[ ! -r ".gitmodules" ]]; then
log_critical ".gitmodules file not found or not readable"
exit 1
fi
# Parse and validate submodule configurations
local submodules=()
while IFS= read -r line; do
if [[ $line =~ ^\[submodule\ \"(.*)\"\]$ ]]; then
submodules+=("${BASH_REMATCH[1]}")
fi
done < .gitmodules
if [[ ${#submodules[@]} -eq 0 ]]; then
log_critical "No submodules found in .gitmodules"
exit 1
fi
log_info "Found ${#submodules[@]} submodules: ${submodules[*]}"
# Validate each submodule configuration
for submodule in "${submodules[@]}"; do
local submodule_path
local submodule_url
submodule_path=$(git config -f .gitmodules --get submodule."$submodule".path)
submodule_url=$(git config -f .gitmodules --get submodule."$submodule".url)
if [[ -z "$submodule_path" ]]; then
log_error "Missing path configuration for submodule '$submodule'"
((VALIDATION_ERRORS++))
fi
if [[ -z "$submodule_url" ]]; then
log_error "Missing URL configuration for submodule '$submodule'"
((VALIDATION_ERRORS++))
fi
# Validate URL format
if [[ "$submodule_url" =~ ^(https?|git):// ]] || [[ "$submodule_url" =~ ^git@ ]]; then
log_info "Submodule '$submodule' URL format valid: $submodule_url"
else
log_error "Invalid URL format for submodule '$submodule': $submodule_url"
((VALIDATION_ERRORS++))
fi
done
if [[ $VALIDATION_ERRORS -gt 0 ]]; then
log_critical "Submodule configuration validation failed with $VALIDATION_ERRORS errors"
exit 1
fi
log_info "Submodule configuration validation complete."
}
# =============================================================================
# EXECUTION FUNCTIONS
# =============================================================================
initialize_submodules() {
local max_retries=3
local retry_delay=5
local success_count=0
local failure_count=0
# Get list of submodules
local submodules=()
local submodule_paths=()
# Parse .gitmodules file
while IFS= read -r line; do
if [[ $line =~ ^\[submodule\ \"(.*)\"\]$ ]]; then
local submodule_name="${BASH_REMATCH[1]}"
submodules+=("$submodule_name")
# Get the path for this submodule
local submodule_path
submodule_path=$(git config -f .gitmodules --get submodule."$submodule_name".path)
submodule_paths+=("$submodule_path")
fi
done < .gitmodules
log_info "Found ${#submodules[@]} submodules to initialize"
# Process each submodule
for i in "${!submodules[@]}"; do
local submodule="${submodules[i]}"
local submodule_path="${submodule_paths[i]}"
log_info "Submodule path: '$submodule_path'"
# Try to initialize the submodule
local submodule_initialized=false
for ((attempt=1; attempt<=max_retries; attempt++)); do
log_info "Attempt $attempt of $max_retries for submodule '$submodule'"
# Execute git command with explicit error handling
local output
output=$(git submodule update --init "$submodule_path" 2>&1)
local exit_code=$?
if [[ $exit_code -eq 0 ]]; then
log_info "Successfully initialized submodule '$submodule'"
((success_count++))
submodule_initialized=true
break
else
log_warn "Failed to initialize submodule '$submodule' (exit code: $exit_code)"
log_warn "Git output: $output"
if [[ $attempt -lt $max_retries ]]; then
log_info "Waiting $retry_delay seconds before retry..."
sleep $retry_delay
else
log_error "Failed to initialize submodule '$submodule' after $max_retries attempts"
((failure_count++))
fi
fi
done
done
log_info "Results: $success_count successful, $failure_count failed"
# Return success even if some submodules failed
# We'll handle failures in the validation phase
return 0
}
configure_submodules() {
log_info "Configuring submodules to prevent automatic updates..."
# Get all configured submodules
local submodules=()
while IFS= read -r line; do
if [[ $line =~ ^\[submodule\ \"(.*)\"\]$ ]]; then
submodules+=("${BASH_REMATCH[1]}")
fi
done < .gitmodules
local configured_count=0
local failed_count=0
for submodule in "${submodules[@]}"; do
log_info "Configuring submodule: $submodule"
if git config "submodule.$submodule.update" none; then
log_info "Successfully configured $submodule"
((configured_count++))
else
log_error "Failed to configure $submodule"
((failed_count++))
fi
done
log_info "Configuration complete: $configured_count successful, $failed_count failed"
# Return success even if some configurations failed
return 0
}
validate_setup() {
log_info "Validating submodule setup..."
local validation_errors=0
# Check each submodule
while IFS= read -r line; do
if [[ $line =~ ^\[submodule\ \"(.*)\"\]$ ]]; then
local submodule="${BASH_REMATCH[1]}"
local submodule_path
submodule_path=$(git config -f .gitmodules --get submodule."$submodule".path)
# Check if submodule directory exists
if [[ ! -d "$submodule_path" ]]; then
log_error "Submodule directory '$submodule_path' does not exist"
((validation_errors++))
continue
fi
# Check if it's a valid git repository
if [[ ! -f "$submodule_path/.git" ]]; then
log_error "Submodule '$submodule_path' is not a valid git repository"
((validation_errors++))
continue
fi
# Check if submodule is properly initialized
if ! (cd "$submodule_path" && git rev-parse --git-dir >/dev/null 2>&1); then
log_error "Submodule '$submodule_path' is not properly initialized"
((validation_errors++))
continue
fi
# Check update configuration
local update_config
update_config=$(git config submodule."$submodule".update)
if [[ "$update_config" != "none" ]]; then
log_error "Submodule '$submodule' update configuration is '$update_config', expected 'none'"
((validation_errors++))
fi
log_info "Submodule '$submodule' validation passed"
fi
done < .gitmodules
if [[ $validation_errors -gt 0 ]]; then
log_critical "Setup validation failed with $validation_errors errors"
exit 1
fi
log_info "All submodules validated successfully"
return 0
}
# =============================================================================
# CLEANUP FUNCTIONS
# =============================================================================
cleanup_on_failure() {
log_warn "Initiating cleanup due to failure..."
# Remove any partially initialized submodules
while IFS= read -r line; do
if [[ $line =~ ^\[submodule\ \"(.*)\"\]$ ]]; then
local submodule="${BASH_REMATCH[1]}"
local submodule_path
submodule_path=$(git config -f .gitmodules --get submodule."$submodule".path)
if [[ -d "$submodule_path" ]]; then
log_info "Cleaning up partially initialized submodule: $submodule_path"
rm -rf "$submodule_path"
fi
fi
done < .gitmodules
# Clean up temporary files
if [[ -d "$TEMP_DIR" ]]; then
log_info "Cleaning up temporary directory: $TEMP_DIR"
rm -rf "$TEMP_DIR"
fi
log_info "Cleanup complete"
}
# =============================================================================
# DISPLAY FUNCTIONS
# =============================================================================
display_header() {
cat << 'EOF'
===============================================================================
POUND SUBMODULE SETUP
===============================================================================
This script configures submodules with commit pinning for stability.
WARNING: This operation modifies Git configuration and affects repository state.
Result:
- Submodules will be initialized and pinned to specific commits
- Automatic updates will be disabled
===============================================================================
EOF
}
display_summary() {
cat << 'EOF'
===============================================================================
SUMMARY
===============================================================================
Submodule setup completed successfully.
SYSTEM STATUS: STABLE
SUBMODULES: PINNED
AUTOMATIC UPDATES: DISABLED
Next Steps:
1. Verify submodule configurations in .gitmodules
2. Review pinned versions in 3rd_party/PINNED_VERSIONS.md
3. Test build system with pinned submodules
===============================================================================
EOF
}
# =============================================================================
# MAIN
# =============================================================================
main() {
# Display mission header
display_header
# Change to repository root
cd "$REPO_ROOT"
# Execute phases
validate_environment
validate_submodules
initialize_submodules
configure_submodules
validate_setup
display_summary
log_info "Submodule setup successful"
exit 0
}
# Execute main function
main "$@"

85
scripts/update_submodule.sh Executable file
View file

@ -0,0 +1,85 @@
#!/bin/bash
# Controlled update of a specific submodule
set -e
if [ $# -lt 3 ]; then
echo "Usage: $0 <submodule_path> <new_commit_hash> <reason>"
echo "Example: $0 3rd_party/imgui a1b2c3d4e5f6789012345678901234567890123456 \"Security fix for CVE-2025-1234\""
exit 1
fi
SUBMODULE_PATH="$1"
NEW_COMMIT="$2"
REASON="$3"
# Get the repository root directory
REPO_ROOT=$(git rev-parse --show-toplevel)
cd "$REPO_ROOT"
# Normalize the submodule path (remove leading ../ and trailing /)
SUBMODULE_PATH=$(echo "$SUBMODULE_PATH" | sed 's:^\.\.\/::' | sed 's:/$::')
echo "Repository root: $REPO_ROOT"
echo "Updating submodule: $SUBMODULE_PATH"
echo "New commit: $NEW_COMMIT"
echo "Reason: $REASON"
echo ""
# Check if submodule exists
if [ ! -d "$SUBMODULE_PATH" ]; then
echo "Error: Submodule directory $SUBMODULE_PATH does not exist"
echo "Available submodules:"
git submodule status | awk '{print $2}'
exit 1
fi
# Check if it's actually a submodule
if [ ! -f "$SUBMODULE_PATH/.git" ]; then
echo "Error: $SUBMODULE_PATH is not a git submodule"
exit 1
fi
# Show current commit
echo "Current commit:"
cd "$SUBMODULE_PATH"
CURRENT_COMMIT=$(git rev-parse HEAD)
echo " $CURRENT_COMMIT"
git log --oneline -1
echo ""
cd "$REPO_ROOT"
# Ask for confirmation
read -p "Are you sure you want to update $SUBMODULE_PATH from $CURRENT_COMMIT to $NEW_COMMIT? (y/N): " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Update cancelled."
exit 0
fi
# Update the submodule
echo "Updating submodule..."
cd "$SUBMODULE_PATH"
git fetch origin
if ! git checkout "$NEW_COMMIT"; then
echo "Error: Failed to checkout commit $NEW_COMMIT"
echo "Available commits:"
git log --oneline -10
cd "$REPO_ROOT"
exit 1
fi
cd "$REPO_ROOT"
# Commit the change
echo "Committing the update..."
git add "$SUBMODULE_PATH"
git commit -m "Update $SUBMODULE_PATH to $NEW_COMMIT: $REASON"
echo "Update complete!"
echo ""
echo "IMPORTANT: Don't forget to:"
echo "1. Update 3rd_party/PINNED_VERSIONS.md with the new commit hash"
echo "2. Test the changes thoroughly"
echo "3. Update the CMakeLists.txt verification function if needed"

View file

@ -13,7 +13,7 @@
#elif defined(__APPLE__)
#include <libkern/OSByteOrder.h>
#define bswap_16(x) OSSwaoInt16(x)
#define bswap_16(x) OSSwapInt16(x)
#define bswap_32(x) OSSwapInt32(x)
#define bswap_64(x) OSSwapInt64(x)
@ -23,5 +23,4 @@
#endif
#endif // POUND_KVM_ENDIAN_H
#endif // POUND_KVM_ENDIAN_H