#!/usr/bin/python3 # # This python script patches both the UnrealEngine and the # integration repositories. It is necessary to do this before # trying to build integration or UnrealEngine. If something # generated by this script gets overwritten, it is perfectly safe # to run this script again. # # Files generated: # # INTEGRATION/Saved/UnrealBuildTool/BuildConfiguration.xml # INTEGRATION/Integration.uproject # INTEGRATION/Integration.code-workspace # INTEGRATION/Makefile # INTEGRATION/Source/Integration/lpx-paths.hpp # # UNREALENGINE/Engine/Saved/UnrealBuildTool/BuildConfiguration.xml # UNREALENGINE/Engine/Source/Runtime/Core/Private/Logging/LogMacros.cpp # import sys, os, json 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) # # 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) Path(f"{UNREALENGINE}/Engine/Source/Runtime/Core/Private/Logging/LogMacros.cpp").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" """) # # Write LogMacros.cpp # LOGMACROS=readfile("EnginePatches/LogMacros.cpp") writefile(f"{UNREALENGINE}/Engine/Source/Runtime/Core/Private/Logging/LogMacros.cpp", LOGMACROS) # # Write Integration.uproject. # UPROJECTTEMPLATE=readfile("EnginePatches/uproject") UPROJECT=json.loads(UPROJECTTEMPLATE) with open("Integration.uproject", "w") as rewritten: json.dump(UPROJECT, rewritten, indent=4) # # Write the Makefile # writefile("Makefile", f""" all: (cd luprex ; make) dotnet {UNREALENGINE}/Engine/Binaries/DotNET/UnrealBuildTool/UnrealBuildTool.dll IntegrationEditor Linux DebugGame -project="{INTEGRATION}/Integration.uproject" -waitmutex """) # # Use UnrealBuildTool to generate a rough draft of Integration.code-workspace. # BUILDPROJECTFILES = f'{UNREALENGINE}/GenerateProjectFiles.sh -projectfiles -project="{INTEGRATION}/Integration.uproject" -game' print(BUILDPROJECTFILES) os.system(BUILDPROJECTFILES) # # 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", 'target stop-hook add --one-liner "p ::UngrabAllInputImpl()"', "breakpoint set --name UBreakPoint::OnLogError" ] 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)] # # Write Integration.code-workspace. # with open("Integration.code-workspace", "w") as rewritten: json.dump(WORKSPACE, rewritten, indent=4)