Files
UnrealEngine/Engine/Source/ThirdParty/GPUReshape/SyncAndBuild.py
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

176 lines
4.8 KiB
Python

import os
import sys
import stat
import shutil
import tempfile
import threading
import subprocess
import pathlib
# Path setup
source_path = "./Source"
build_path = os.path.join(pathlib.Path.home().drive + "\\", "Temp", "GPUReshape-Build")
install_path = "../../../Binaries/ThirdParty/GPUReshape/Win64"
# All branches to pull and build
branches = [
("feature/raytracing", "Raytracing", source_path),
("feature/debug", "Debug", None),
("feature/device-commands", "DeviceCommands", None)
]
class JobContext:
lock = threading.Lock()
def __init__(self, branch_name):
# Clean log
log_name = os.path.join(f"Log{branch_name}.txt")
if os.path.exists(log_name):
os.remove(log_name)
self.branch_name = branch_name
self.log = open(log_name, "w")
def line(self, contents):
with JobContext.lock:
sys.stdout.write(f"[{self.branch_name}] {contents}\n")
sys.stdout.flush()
def clean_on_error(fn, path, e):
if not os.access(path, os.W_OK):
os.chmod(path, stat.S_IWUSR)
fn(path)
else:
raise
def remove_directory(directory):
if os.path.exists(directory):
sys.stdout.write(f"Cleaning '{directory}'... ")
shutil.rmtree(directory, ignore_errors=False, onerror=clean_on_error)
sys.stdout.write(f"OK\n")
def clean_directory(directory):
remove_directory(directory)
os.makedirs(directory, exist_ok=True)
def call(ctx, name, args):
ctx.line(name)
# Write event in log
ctx.log.write(f".call {str(args)}\n")
ctx.log.flush()
out = subprocess.run(args, stdout=ctx.log, stderr=ctx.log)
if out.returncode != 0:
ctx.line(f" Failed with {out.returncode}\n")
exit(1)
def sync_and_build(branch):
git_branch, branch_name, copy_source_path = branch
# Paths
build_dir = os.path.join(build_path, branch_name)
install_dir = os.path.join(install_path, branch_name)
# Create context
ctx = JobContext(branch_name)
# Clone the repository
call(ctx, "Cloning", [
"git",
"clone", "https://github.com/GPUOpen-Tools/GPU-Reshape",
"-b", git_branch,
build_dir
])
# Copy clean source tree if requested
if copy_source_path is not None:
shutil.copytree(build_dir, copy_source_path, dirs_exist_ok=True)
shutil.rmtree(os.path.join(copy_source_path, ".git"), ignore_errors=False, onerror=clean_on_error)
# Generate the projects
call(ctx, "Generating solution", [
"cmake",
"-G", "Visual Studio 17 2022",
"-A", "x64",
"-DCMAKE_CONFIGURATION_TYPES:STRING=RelWithDebInfo",
"-DINSTALL_THIRD_PARTY:BOOL=1",
"-S", os.path.join(build_dir),
"-B", os.path.join(build_dir, "cmake-build-vs2022"),
"-DCMAKE_VS_NUGET_PACKAGE_RESTORE=ON"
])
# Patch the solution
call(ctx, "Patching solution", [
"cmake",
"-P", os.path.join(build_dir, "Build", "Utils", "CSProjPatch.cmake"),
os.path.join(build_dir, "cmake-build-vs2022")
])
# Restore all Nuget packages
call(ctx, "Restoring solution", [
"dotnet",
"restore", os.path.join(build_dir, "cmake-build-vs2022", "GPU-Reshape.sln")
])
# Actually build the project
call(ctx, "Building", [
os.path.join(build_dir, "cmake-build-vs2022", "GRS_MSBuild.bat"),
os.path.join(build_dir, "cmake-build-vs2022", "GPU-Reshape.sln"),
"/p:Configuration=RelWithDebInfo",
"/m"
])
# Package the project
call(ctx, "Packaging", [
os.path.join(build_dir, "Build", "Scripts", "Package.bat"),
os.path.join("MSVC", "RelWithDebInfo")
])
os.mkdir(install_dir)
# Copy over executable
ctx.line("Copying executables")
shutil.copytree(
os.path.join(build_dir, "Package", "MSVC", "RelWithDebInfo"),
install_dir,
dirs_exist_ok=True
)
# Copy over symbols
ctx.line("Copying symbols")
shutil.copytree(
os.path.join(build_dir, "Package", "MSVC", "RelWithDebInfoSym"),
install_dir,
dirs_exist_ok=True
)
if __name__ == "__main__":
# Clean install
clean_directory(source_path)
clean_directory(build_path)
clean_directory(install_path)
# Print info
sys.stdout.write("Syncing and building:\n")
for branch in branches:
sys.stdout.write(f"\t '{branch[0]}' -> {branch[1]}\n")
sys.stdout.write("\n")
# Create jobs
jobs = []
for branch in branches:
job = threading.Thread(target=sync_and_build, args=(branch,))
job.start()
jobs.append(job)
# Wait for all jobs
for job in jobs:
job.join()
# Remove build files
remove_directory(build_path)