Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add build-with-entropy pipeline #1384

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 70 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,70 @@ jobs:
-Werror=dev
cmake --build build -- -k0

build-with-entropy:
name: 'MSVC 4.20 with entropy'
runs-on: windows-latest
strategy:
matrix:
instance: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

steps:
- uses: actions/checkout@v4

- uses: actions/checkout@v4
with:
repository: itsmattkc/msvc420
path: msvc420

- name: Setup cmake
uses: jwlawson/actions-setup-cmake@v2
with:
# Use minimum supported version
cmake-version: '3.15.x'

- name: Patch MSVC 4.2
run: |
tools/patch_c2.py msvc420/bin/C2.EXE

- name: Generate Entropy
shell: bash
run: |
# Get the first 8 characters of the SHA (enough for a decent seed)
SHA_PREFIX=$(echo "${{ github.sha }}" | cut -c 1-8)

tools/entropy.sh $((16#$SHA_PREFIX + ${{ matrix.instance }}))

- name: Build
shell: cmd
run: |
call .\msvc420\bin\VCVARS32.BAT x86
cmake -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DISLE_INCLUDE_ENTROPY=ON -G "NMake Makefiles"
cmake --build build

- name: Upload Artifact
uses: actions/upload-artifact@main
with:
name: Win32-Entropy-${{ matrix.instance }}
path: |
build/CONFIG.EXE
build/CONFIG.PDB
build/ISLE.EXE
build/ISLE.PDB
build/LEGO1.DLL
build/LEGO1.PDB

merge-entropy-artifacts:
name: 'Merge entropy artifacts'
runs-on: ubuntu-latest
needs: build-with-entropy
steps:
- name: Merge Artifacts
uses: actions/upload-artifact/merge@v4
with:
name: Win32-Entropy
pattern: Win32-Entropy-*
separate-directories: true

build:
name: 'MSVC 4.20'
runs-on: windows-latest
Expand Down Expand Up @@ -102,7 +166,7 @@ jobs:

compare:
name: Compare with master
needs: [build, fetch-deps]
needs: [build, merge-entropy-artifacts, fetch-deps]
runs-on: windows-latest
steps:
- uses: actions/checkout@main
Expand All @@ -116,6 +180,11 @@ jobs:
name: Win32
path: build

- uses: actions/download-artifact@main
with:
name: Win32-Entropy
path: build-entropy

- name: Restore cached original binaries
id: cache-original-binaries
uses: actions/cache/restore@v4
Expand Down
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ option(ISLE_DECOMP_ASSERT "Assert struct size" ${MSVC_FOR_DECOMP})
cmake_dependent_option(ISLE_USE_DX5_LIBS "Build with internal DirectX 5 SDK Libraries" ON ISLE_USE_DX5 OFF)
option(ISLE_BUILD_LEGO1 "Build LEGO1.DLL library" ON)
option(ISLE_BUILD_BETA10 "Build BETA10.DLL library" OFF)
option(ISLE_INCLUDE_ENTROPY "Build with entropy.h" OFF)

if(NOT (ISLE_BUILD_LEGO1 OR ISLE_BUILD_BETA10))
message(FATAL_ERROR "ISLE_BUILD_LEGO1 AND ISLE_BUILD_BETA10 cannot be both disabled")
Expand Down Expand Up @@ -585,6 +586,12 @@ if (MSVC_FOR_DECOMP)
set_property(TARGET isle ${lego1_targets} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()

if (ISLE_INCLUDE_ENTROPY)
foreach(tgt IN LISTS lego1_targets beta10_targets)
target_compile_options(${tgt} PRIVATE /FI${PROJECT_SOURCE_DIR}/entropy.h)
endforeach()
endif()

if(TARGET lego1)
target_link_options(lego1 PRIVATE "/OPT:REF")
# Equivalent to target_compile_options(... PRIVATE "/MT$<$<CONFIG:Debug>:d>")
Expand Down
67 changes: 67 additions & 0 deletions tools/entropy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/bin/bash

# Output file
OUTPUT_FILE="entropy.h"

# Function to generate a CamelCase string of given length
generate_name() {
local seed="$1"
local length="$2"
local char_count=0
local random_bytes=""

while [ "$char_count" -lt "$length" ]; do
random_bytes+=$(od -vAn -N4 -tu4 < /dev/urandom | tr -d '[:space:]')
char_count=$((char_count + 1))
done

# Use the provided seed for the random number generation. Crucially, re-seed bash's
# RANDOM for each name.
RANDOM="$seed"

local result=""
for ((i=0; i<length; i++)); do
# Get a pseudo-random number between 0 and 25 (inclusive)
local rand_index=$((RANDOM % 26))
# Convert to lowercase ASCII character (a=97)
local char_code=$((97 + rand_index))
# Append to the result string
result+=$(printf "\\$(printf '%o' "$char_code")")
done
echo "$result" | sed -E 's/(^|_)([a-z])/\U\2/g'
}

# Parse command-line arguments
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <seed_number>"
exit 1
fi

SEED="$1"
# Initialize the random number generator with the seed
RANDOM="$SEED"

# Generate a random number of classes (between 1 and 10)
NUM_CLASSES=$((RANDOM % 10 + 1))

> "$OUTPUT_FILE" # Clear or create the output file

echo "// Seed: $SEED" > "$OUTPUT_FILE"
echo >> "$OUTPUT_FILE"

for ((i=0; i<NUM_CLASSES; i++)); do
CLASS_NAME="Class$(generate_name "$((SEED + i * 100))" 6)"
echo "class $CLASS_NAME {" >> "$OUTPUT_FILE"

# Generate a random number of methods (between 1 and 10)
NUM_METHODS=$((RANDOM % 10 + 1))
for ((j=0; j<NUM_METHODS; j++)); do
METHOD_NAME="Function$(generate_name "$((SEED + i * 100 + j))" 8)"
echo -e "\tinline void $METHOD_NAME() {}" >> "$OUTPUT_FILE"
done

echo "};" >> "$OUTPUT_FILE"
echo >> "$OUTPUT_FILE"
done

echo "Generated $NUM_CLASSES classes in $OUTPUT_FILE using seed $SEED"