Files
integration/build-everything.py

241 lines
7.0 KiB
Python
Raw Normal View History

2024-11-04 15:46:54 -05:00
#!/usr/bin/python3
#
# This python script builds integration from scratch. That includes:
#
# - Generating BuildConfiguration.xml in integration repository
# - Generating BuildConfiguration.xml in UnrealEngine repository
# - Hardwiring paths into Source/Integration/lpx-paths.hpp
# - Generating Integration.uproject
# - Generating Integration.code-workspace
# - Applies patch to Unreal Engine source.
# - Running Setup.sh in the UnrealEngine repository
# - Building luprex
# - Building ShaderCompileWorker
# - Building integration
#
# Once this is all done, everything is ready to go. It is now possible to
# start up the IDE and run luprex in the debugger.
#
# This script is mainly intended for the *initial* build.
# If you want to edit the code and recompile, it is okay to use
# this script a second time, but it's unnecessarily slow.
# It's much faster to edit and recompile using the IDE.
2024-11-04 15:46:54 -05:00
#
import sys, os, json, shutil, subprocess
2024-11-04 15:46:54 -05:00
from pathlib import Path
#
# Some handy utility functions
#
def readfile(fn):
with open(fn) as f:
return f.read()
def writefile(fn, str):
with open(fn, "w") as f:
f.write(str)
def shell(cmd):
2024-11-07 17:53:05 -05:00
print("Running:", cmd)
subprocess.run(cmd, shell=True, check=True)
2024-11-04 15:46:54 -05:00
#
# These are some directory paths that we will need.
#
USER = os.environ["USER"]
INTEGRATION = os.path.dirname(os.path.abspath(sys.argv[0]))
UNREALENGINE = os.environ["HOME"] + "/UnrealEngine"
if not os.path.isdir(f"{INTEGRATION}/Source/Integration"):
error("Could not figure out the correct path for the INTEGRATION repository.")
if not os.path.isdir(f"{UNREALENGINE}/Engine/Source"):
error("Could not figure out the correct path for the UNREALENGINE repository.")
os.chdir(INTEGRATION)
#
# Remove previously-generated files.
#
Path(f"Saved/UnrealBuildTool").mkdir(parents=True, exist_ok=True)
Path(f"Saved/UnrealBuildTool/BuildConfiguration.xml").unlink(missing_ok=True)
Path(f"Integration.uproject").unlink(missing_ok=True)
Path(f"Integration.code-workspace").unlink(missing_ok=True)
Path(f"Makefile").unlink(missing_ok=True)
Path(f"Source/Integration/lpx-paths.hpp").unlink(missing_ok=True)
Path(f"{UNREALENGINE}/Engine/Saved/UnrealBuildTool").mkdir(parents=True, exist_ok=True)
Path(f"{UNREALENGINE}/Engine/Saved/UnrealBuildTool/BuildConfiguration.xml").unlink(missing_ok=True)
#
# Write BuildConfiguration.xml
#
BUILDCONFIG=readfile("EnginePatches/BuildConfigurationLinux.xml")
writefile("Saved/UnrealBuildTool/BuildConfiguration.xml", BUILDCONFIG)
writefile(f"{UNREALENGINE}/Engine/Saved/UnrealBuildTool/BuildConfiguration.xml", BUILDCONFIG)
#
# Write lpx-paths.hpp.
#
writefile("Source/Integration/lpx-paths.hpp", f"""
#define LUPREX_DLL_PATH "{INTEGRATION}/luprex/build/linux/luprexlib.so"
#define LUPREX_ROOT_PATH "{INTEGRATION}/luprex"
""")
#
# Apply patch to the unreal engine source.
# Restore any affected sourcefiles before applying patch.
2024-11-04 15:46:54 -05:00
#
os.chdir(UNREALENGINE)
print("Applying patch to Unreal Engine...")
2024-11-07 17:53:05 -05:00
for line in readfile(f"{INTEGRATION}/EnginePatches/EnginePatch").splitlines():
if line.startswith("--- a/"):
shell(f"git checkout HEAD {line[6:]}")
shell(f"git apply {INTEGRATION}/EnginePatches/EnginePatch")
os.chdir(INTEGRATION)
2024-11-04 15:46:54 -05:00
#
# Write Integration.uproject.
#
UPROJECTTEMPLATE=readfile("EnginePatches/uproject")
UPROJECT=json.loads(UPROJECTTEMPLATE)
with open("Integration.uproject", "w") as rewritten:
json.dump(UPROJECT, rewritten, indent=4)
#
# Run Setup.sh in UNREALENGINE
2024-11-04 15:46:54 -05:00
#
os.chdir(UNREALENGINE)
shell("./Setup.sh")
os.chdir(INTEGRATION)
2024-11-04 15:46:54 -05:00
#
# Use UnrealBuildTool to generate a rough draft of Integration.code-workspace.
#
shell(f'{UNREALENGINE}/GenerateProjectFiles.sh -projectfiles -project="{INTEGRATION}/Integration.uproject" -game')
2024-11-04 15:46:54 -05:00
#
# Load the rough Integration.code-workspace into RAM, then delete the rough draft.
#
with open("Integration.code-workspace") as original:
WORKSPACE=json.load(original)
Path("Integration.code-workspace").unlink()
#
# Configure the correct build task as the default task.
#
for task in WORKSPACE["tasks"]["tasks"]:
if task["label"] == "IntegrationEditor Linux DebugGame Build":
task["group"] = { "kind": "build", "isDefault": "true" }
#
# Delete all build tasks that aren't relevant.
#
def goodtask(task):
return task["label"].startswith("IntegrationEditor Linux DebugGame")
WORKSPACE["tasks"]["tasks"] = [x for x in WORKSPACE["tasks"]["tasks"] if goodtask(x)]
#
# Add a build task for Luprex
#
LUPREXBUILDTASK={}
WORKSPACE["tasks"]["tasks"].append(LUPREXBUILDTASK)
LUPREXBUILDTASK["label"] = "Build Luprex"
LUPREXBUILDTASK["group"] = "build"
LUPREXBUILDTASK["command"] = "make"
LUPREXBUILDTASK["problemMatcher"] = "$msCompile"
LUPREXBUILDTASK["type"] = "shell"
LUPREXBUILDTASK["options"] = {}
LUPREXBUILDTASK["options"]["cwd"] = f"{INTEGRATION}/luprex"
#
# Convert all launch configurations to lldb.
#
LLDBINIT=[
f'command script import {UNREALENGINE}/Engine/Extras/LLDBDataFormatters/UEDataFormatters_2ByteChars.py',
f'settings set target.inline-breakpoint-strategy always',
f'target stop-hook add --one-liner "p ::UngrabAllInputImpl()"',
2024-11-04 15:46:54 -05:00
]
for config in WORKSPACE["launch"]["configurations"]:
config["type"] = "lldb"
config["initCommands"] = LLDBINIT
config["args"] = [ f"{INTEGRATION}/Integration.uproject", f"-userdir=User/{USER}" ]
config.pop("visualizerFile", None)
config.pop("showDisplayString", None)
#
# Delete all but the relevant launch configuration.
#
def goodconf(config):
return config["name"] == "Launch IntegrationEditor (DebugGame)"
WORKSPACE["launch"]["configurations"] = [x for x in WORKSPACE["launch"]["configurations"] if goodconf(x)]
2024-11-07 17:53:05 -05:00
#
# Add some recommended extensions.
#
EXTENSIONS=set(WORKSPACE["extensions"]["recommendations"])
EXTENSIONS.add("ms-python.python")
EXTENSIONS.add("vadimcn.vscode-lldb")
WORKSPACE["extensions"]["recommendations"] = list(EXTENSIONS)
#
# Tell vscode not to try watching all the UnrealEngine source code for modifications.
# Attempting this overruns a Linux hardwired limit on file watches.
#
WORKSPACE["settings"]["files.watcherExclude"] = {
f'{UNREALENGINE}/Engine/**' : True,
f'{UNREALENGINE}/Samples/**' : True,
f'{UNREALENGINE}/Templates/**' : True
}
2024-11-04 15:46:54 -05:00
#
# Write Integration.code-workspace.
#
with open("Integration.code-workspace", "w") as rewritten:
json.dump(WORKSPACE, rewritten, indent=4)
#
# Do an initial build of Luprex
#
os.chdir(f"{INTEGRATION}/luprex")
print("Building luprex...")
shell("make")
os.chdir(INTEGRATION)
#
# Build ShaderCompileWorker
#
os.chdir(UNREALENGINE)
print("Building ShaderCompileWorker...")
shell("Engine/Build/BatchFiles/Linux/Build.sh ShaderCompileWorker Linux Shipping -waitmutex")
Path("Engine/Binaries/Linux/ShaderCompileWorker").unlink(missing_ok=True)
shutil.copyfile("Engine/Binaries/Linux/ShaderCompileWorker-Linux-Shipping", "Engine/Binaries/Linux/ShaderCompileWorker")
os.chdir(INTEGRATION)
#
# Build Integration
#
print("Building integration...")
os.system(f'dotnet {UNREALENGINE}/Engine/Binaries/DotNET/UnrealBuildTool/UnrealBuildTool.dll IntegrationEditor Linux DebugGame -project="{INTEGRATION}/Integration.uproject" -waitmutex')