Skip to content

Commit 5a1527c

Browse files
committed
Use Windows_SDK.json from UE to determine what VS components to install
1 parent d7d4092 commit 5a1527c

File tree

11 files changed

+212
-194
lines changed

11 files changed

+212
-194
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,10 @@ jobs:
3434
# All supported Ubuntu LTS with system python
3535
# Be careful when removing EOL versions so that we still test our oldest supported python at least somewhere
3636
- { os: ubuntu-22.04, python: "3.10" }
37-
- { os: ubuntu-24.04, python: "3.12" }
37+
- { os: ubuntu-24.04, python: "3.13" }
3838

39-
# All supported Visual Studio on Windows Server 2022
40-
- { os: windows-2022, python: "3.12", visual-studio: 2017 }
41-
- { os: windows-2022, python: "3.12", visual-studio: 2019 }
42-
- { os: windows-2022, python: "3.12", visual-studio: 2022 }
43-
44-
# All supported Visual Studio on Windows Server 2025
45-
- { os: windows-2025, python: "3.12", visual-studio: 2017 }
46-
- { os: windows-2025, python: "3.12", visual-studio: 2019 }
47-
- { os: windows-2025, python: "3.12", visual-studio: 2022 }
39+
- { os: windows-2022, python: "3.13" }
40+
- { os: windows-2025, python: "3.13" }
4841
runs-on: ${{ matrix.os }}
4942
steps:
5043
- name: Checkout
@@ -56,6 +49,6 @@ jobs:
5649
- name: Install
5750
run: pip install . --user
5851
- name: Build prerequisites
59-
run: ue4-docker build --target=build-prerequisites --visual-studio ${{ matrix.visual-studio || '2017' }}
52+
run: ue4-docker build --target=build-prerequisites
6053
- name: Run diagnostics
6154
run: ue4-docker diagnostics all

README.md

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,42 @@
77

88
The ue4-docker Python package contains a set of Dockerfiles and accompanying build infrastructure that allows you to build Docker images for Epic Games' [Unreal Engine](https://www.unrealengine.com/). The images also incorporate the infrastructure from [ue4cli](https://github.com/adamrehn/ue4cli), [conan-ue4cli](https://github.com/adamrehn/conan-ue4cli), and [ue4-ci-helpers](https://github.com/adamrehn/ue4-ci-helpers) to facilitate a wide variety of use cases.
99

10-
Key features include:
10+
## Key features
1111

12-
- The six most recent versions of the Unreal Engine are supported (currently Unreal Engine 4.27 and newer).
1312
- Both Windows containers and Linux containers are supported.
1413
- Building and packaging Unreal Engine projects is supported.
1514
- Running automation tests is supported.
1615
- Running built Unreal Engine projects with offscreen rendering is supported via the NVIDIA Container Toolkit under Linux.
1716

18-
Resources:
17+
## Supported engine versions
18+
19+
Unreal Engine 4.27 and five most recent versions of Unreal Engine 5 are supported.
20+
21+
### 4.27
22+
23+
No known issues.
24+
25+
### 5.2
26+
27+
You need to apply [this fix](https://forums.unrealengine.com/t/need-help-building-5-2-0-from-github/1441996/4) to your engine fork in order to build on Windows.
28+
29+
### 5.3
30+
31+
No known issues.
32+
33+
### 5.4
34+
35+
No known issues.
36+
37+
### 5.5
38+
39+
You need to apply [this patch](https://github.com/EpicGames/UnrealEngine/commit/b86e244161df5bb32030818a48ffeccd3ed310ef) to your engine fork in order to build on Windows.
40+
41+
### 5.6
42+
43+
You need to apply [this](https://github.com/EpicGames/UnrealEngine/commit/467f8b31124c89b61c00ba73c26229897cafd7bd) and [this](https://github.com/EpicGames/UnrealEngine/commit/cdda65cecacd9a1278020925c357bf4cc0b17e8c) patches to your engine fork in order to build on Windows.
44+
45+
## Resources
1946

2047
- **Documentation:** <https://adamrehn.github.io/ue4-docker>
2148
- **GitHub repository:** <https://github.com/adamrehn/ue4-docker>

docs/ue4-docker-build.adoc

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -147,14 +147,6 @@ Use Linux containers under Windows hosts (useful when testing Docker Desktop or
147147
*--random-memory*::
148148
Use a random memory limit for Windows containers
149149

150-
*--visual-studio {2017,2019,2022}*::
151-
Specify Visual Studio Build Tools version.
152-
+
153-
By default, ue4-docker uses Visual Studio Build Tools 2017 to build Unreal Engine.
154-
Starting with Unreal Engine 4.25, you may choose to use Visual Studio Build Tools 2019 instead.
155-
+
156-
Unreal Engine 5.0 adds support for VS2022 but removes support for VS2017.
157-
158150
== Environment
159151

160152
This section describes several environment variables that affect how `ue4-docker build` operates.

src/ue4docker/build.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,6 @@ def build():
200200
"Detected max image size: {:.0f}GB".format(DockerUtils.maxsize()),
201201
False,
202202
)
203-
logger.info(
204-
"Visual Studio: {}".format(config.visualStudio), False
205-
)
206203

207204
# Verify that the host OS is not a release that is blacklisted due to critical bugs
208205
if (
@@ -405,9 +402,6 @@ def build():
405402
prereqsArgs = prereqsArgs + [
406403
"--build-arg",
407404
"DLLSRCIMAGE=" + config.dllSrcImage,
408-
"--build-arg",
409-
"VISUAL_STUDIO_BUILD_NUMBER="
410-
+ config.visualStudio.build_number,
411405
]
412406

413407
custom_prerequisites_dockerfile = config.args.prerequisites_dockerfile

src/ue4docker/dockerfiles/ue4-build-prerequisites/windows/Dockerfile

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,8 @@ LABEL com.adamrehn.ue4-docker.sentinel="1"
5656
RUN reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem /v LongPathsEnabled /t REG_DWORD /d 1 /f
5757

5858
# Install Chocolatey
59-
RUN powershell -NoProfile -ExecutionPolicy Bypass -Command "$env:chocolateyVersion = '1.4.0'; Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))"
59+
RUN powershell -NoProfile -ExecutionPolicy Bypass -Command "Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))"
6060

6161
# Install the rest of our build prerequisites and clean up afterwards to minimise image size
6262
COPY install-prerequisites.ps1 C:\
63-
ARG VISUAL_STUDIO_BUILD_NUMBER
64-
RUN powershell -ExecutionPolicy Bypass -File C:\install-prerequisites.ps1 %VISUAL_STUDIO_BUILD_NUMBER%
63+
RUN powershell -ExecutionPolicy Bypass -File C:\install-prerequisites.ps1

src/ue4docker/dockerfiles/ue4-build-prerequisites/windows/install-prerequisites.ps1

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -54,69 +54,12 @@ Invoke-WebRequest -Uri "https://sdk.lunarg.com/sdk/download/1.4.304.0/windows/Vu
5454
Expand-Archive -Path "$env:TEMP\vulkan-runtime-components.zip" -DestinationPath "$env:TEMP"
5555
Copy-Item -Path "*\x64\vulkan-1.dll" -Destination C:\Windows\System32\
5656

57-
$visual_studio_build = $args[0]
58-
59-
if ($visual_studio_build -eq "15")
60-
{
61-
$windows_sdk_version = 18362
62-
}
63-
else
64-
{
65-
$windows_sdk_version = 20348
66-
}
67-
68-
# NOTE: We use the Visual Studio 2022 installer even for Visual Studio 2019 and 2017 here because the old (2017) installer now breaks
69-
Invoke-WebRequest -Uri "https://aka.ms/vs/17/release/vs_buildtools.exe" -OutFile "$env:TEMP\vs_buildtools.exe"
70-
71-
# NOTE: Microsoft.NetCore.Component.SDK only exists for VS2019+. And it is actually *needed* only for UE5
72-
# NOTE: .NET 4.5 is required for some programs even in UE5, for example https://github.com/EpicGames/UnrealEngine/blob/5.0.1-release/Engine/Source/Programs/UnrealSwarm/SwarmCoordinator/SwarmCoordinator.csproj#L26
73-
# NOTE: Microsoft.NetCore.Component.Runtime.3.1 is required by the AutomationTool tool and does not come installed with VS2022 so it needs targetting here.
74-
$vs_args = @(
75-
"--quiet",
76-
"--wait",
77-
"--norestart",
78-
"--nocache",
79-
"--installPath", "C:\BuildTools",
80-
"--channelUri", "https://aka.ms/vs/$visual_studio_build/release/channel",
81-
"--installChannelUri", "https://aka.ms/vs/$visual_studio_build/release/channel",
82-
"--channelId", "VisualStudio.$visual_studio_build.Release",
83-
"--productId", "Microsoft.VisualStudio.Product.BuildTools",
84-
"--locale", "en-US",
85-
"--add", "Microsoft.VisualStudio.Workload.VCTools",
86-
"--add", "Microsoft.VisualStudio.Workload.MSBuildTools",
87-
"--add", "Microsoft.VisualStudio.Component.NuGet",
88-
"--add", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
89-
"--add", "Microsoft.VisualStudio.Component.Windows10SDK.$windows_sdk_version",
90-
"--add", "Microsoft.Net.Component.4.5.TargetingPack",
91-
"--add", "Microsoft.Net.Component.4.6.2.TargetingPack",
92-
"--add", "Microsoft.Net.ComponentGroup.DevelopmentPrerequisites",
93-
"--add", "Microsoft.NetCore.Component.SDK",
94-
"--add", "Microsoft.NetCore.Component.Runtime.3.1"
95-
)
96-
97-
# Install the Visual Studio Build Tools workloads and components we need
98-
RunProcessChecked "$env:TEMP\vs_buildtools.exe" $vs_args
99-
100-
# NOTE: Install the .Net 4.5 Framework Pack via NuGet as it is no longer available via Visual Studio, but still needed
101-
# NOTE: some programs even in UE5, for example https://github.com/EpicGames/UnrealEngine/blob/5.0.1-release/Engine/Source/Programs/UnrealSwarm/SwarmCoordinator/SwarmCoordinator.csproj#L26
102-
Invoke-WebRequest -Uri "https://www.nuget.org/api/v2/package/Microsoft.NETFramework.ReferenceAssemblies.net45/1.0.3" -OutFile "$env:TEMP\DotNet45.zip"
103-
Expand-Archive -Path "$env:TEMP\DotNet45.zip" -DestinationPath "$env:TEMP"
104-
Copy-Item -Path "$env:TEMP\build\.NETFramework\v4.5\*" -Destination "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\" -Recurse -Force
105-
10657
# Clean up any temp files generated during prerequisite installation
10758
Remove-Item -LiteralPath "$env:TEMP" -Recurse -Force
10859
New-Item -Type directory -Path "$env:TEMP"
10960

11061
# This shaves off ~300MB as of 2021-08-31
11162
RunProcessChecked "choco-cleaner" @("--dummy")
11263

113-
# Something that gets installed in ue4-build-prerequisites creates a bogus NuGet config file
114-
# Just remove it, so a proper one will be generated on next NuGet run
115-
# See https://github.com/adamrehn/ue4-docker/issues/171#issuecomment-852136034
116-
if (Test-Path "$env:APPDATA\NuGet")
117-
{
118-
Remove-Item -LiteralPath "$env:APPDATA\NuGet" -Recurse -Force
119-
}
120-
12164
# Display a human-readable completion message
12265
Write-Output "Finished installing build prerequisites and cleaning up temporary files."

src/ue4docker/dockerfiles/ue4-source/windows/Dockerfile

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# escape=`
22
{% if combine %}
3-
FROM prerequisites as source
3+
FROM prerequisites as source-prep
44
{% else %}
55
ARG NAMESPACE
66
ARG PREREQS_TAG
7-
FROM ${NAMESPACE}/ue4-build-prerequisites:${PREREQS_TAG}
7+
FROM ${NAMESPACE}/ue4-build-prerequisites:${PREREQS_TAG} as source-prep
88
{% endif %}
99

1010
{% if source_mode == "copy" %}
@@ -51,6 +51,24 @@ RUN mkdir C:\UnrealEngine && `
5151

5252
{% endif %}
5353

54+
{% if combine %}
55+
FROM prerequisites as source
56+
{% else %}
57+
ARG NAMESPACE
58+
ARG PREREQS_TAG
59+
FROM ${NAMESPACE}/ue4-build-prerequisites:${PREREQS_TAG} as source
60+
{% endif %}
61+
62+
RUN pip install json-with-comments
63+
# TODO: Rework this. If Windows_SDK.json is missing, generate it on previous stage. So the only file that VS installation depends on is Windows_SDK.json and we don't reinstall VS when other files change
64+
# Only copy files required to determine Visual Studio version to avoid reinstalling it when minor engine changes happen
65+
COPY --from=source-prep C:\UnrealEngine\Engine\Config\Windows C:\install-vs\
66+
COPY --from=source-prep C:\UnrealEngine\Engine\Build\Build.version C:\install-vs\
67+
COPY install-vs.py C:\install-vs\
68+
RUN python C:\install-vs\install-vs.py C:\install-vs\Windows_SDK.json C:\install-vs\Build.Version
69+
70+
COPY --from=source-prep C:\UnrealEngine C:\UnrealEngine
71+
5472
{% if (not disable_all_patches) and (not disable_windows_setup_patch) %}
5573
# Since the UE4 prerequisites installer appears to break when newer versions
5674
# of the VC++ runtime are present, patch out the prereqs call in Setup.bat
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
import json
2+
import os.path
3+
import typing
4+
5+
import jsonc
6+
import subprocess
7+
import sys
8+
from typing import Any
9+
from urllib import request
10+
11+
common_components = [
12+
"Microsoft.Net.ComponentGroup.DevelopmentPrerequisites",
13+
"Microsoft.VisualStudio.Component.NuGet",
14+
"Microsoft.VisualStudio.Workload.VCTools",
15+
"Microsoft.VisualStudio.Workload.MSBuildTools",
16+
]
17+
18+
vs2022_components = common_components + [
19+
"Microsoft.NetCore.Component.SDK",
20+
]
21+
22+
ue5_vs_fallback_version = "17.8"
23+
24+
25+
def build_vs_channel_url(vs_version: str) -> str:
26+
version_major = vs_version.split(".", 1)[0]
27+
return f"https://aka.ms/vs/{version_major}/release.ltsc.{vs_version}/channel"
28+
29+
30+
class VisualStudio:
31+
def __init__(self, version: str, channel_url: str, components: typing.List[str]):
32+
self.version = version
33+
self.channel_url = channel_url
34+
self.components = sorted(set(components))
35+
36+
@staticmethod
37+
def from_json(json_config: Any):
38+
# TODO: Add option to request VS2025
39+
40+
try:
41+
vs_version = json_config["MinimumVisualStudio2022Version"]
42+
except KeyError:
43+
vs_version = ue5_vs_fallback_version
44+
45+
components = (
46+
vs2022_components
47+
+ json_config["VisualStudioSuggestedComponents"]
48+
+ json_config["VisualStudio2022SuggestedComponents"]
49+
)
50+
51+
# UE-5.4 has buggy component version
52+
if "Microsoft.VisualStudio.Component.Windows10SDK.22621" in components:
53+
components.remove("Microsoft.VisualStudio.Component.Windows10SDK.22621")
54+
components.append("Microsoft.VisualStudio.Component.Windows11SDK.22621")
55+
56+
return VisualStudio(
57+
vs_version,
58+
build_vs_channel_url(vs_version),
59+
components,
60+
)
61+
62+
def download_installer(self, installer_path: str) -> None:
63+
print(f"Downloading Visual Studio {self.version}...")
64+
# NOTE: We use the Visual Studio 2022 installer even for older Visual Studio here because the old (2017) installer now breaks
65+
request.urlretrieve(
66+
"https://aka.ms/vs/17/release/vs_buildtools.exe", installer_path
67+
)
68+
69+
def install(self, installer_path: str) -> None:
70+
argv = [
71+
installer_path,
72+
"--quiet",
73+
"--wait",
74+
"--channelUri",
75+
self.channel_url,
76+
"--productId",
77+
"Microsoft.VisualStudio.Product.BuildTools",
78+
"--norestart",
79+
"--nocache",
80+
"--installPath",
81+
"C:/BuildTools",
82+
"--locale",
83+
"en-US",
84+
]
85+
86+
print(f"Installing Visual Studio {self.version}...")
87+
print("Components:")
88+
for component in self.components:
89+
argv.append("--add")
90+
argv.append(component)
91+
print(f" * {component}")
92+
93+
sys.stdout.flush()
94+
95+
subprocess.run(argv, check=True)
96+
97+
98+
if __name__ == "__main__":
99+
windows_sdk_path = sys.argv[1]
100+
build_version_path = sys.argv[2]
101+
102+
if os.path.exists(windows_sdk_path):
103+
print(f"Using Windows_SDK.json to determine VS components")
104+
# 5.4 or newer
105+
with open(sys.argv[1]) as windows_sdk_file:
106+
windows_sdk_json = jsonc.load(windows_sdk_file)
107+
vs = VisualStudio.from_json(windows_sdk_json)
108+
else:
109+
print(f"Using fallback to determine VS components")
110+
with open(build_version_path) as build_version_file:
111+
engine_version = json.load(build_version_file)
112+
engine_major = engine_version["MajorVersion"]
113+
engine_minor = engine_version["MinorVersion"]
114+
115+
if engine_major == 5:
116+
# Assuming 5.3 or older
117+
vs = VisualStudio(
118+
ue5_vs_fallback_version,
119+
build_vs_channel_url(ue5_vs_fallback_version),
120+
vs2022_components
121+
+ [
122+
"Microsoft.Net.Component.4.6.2.TargetingPack",
123+
"Microsoft.NetCore.Component.Runtime.3.1",
124+
f"Microsoft.VisualStudio.Component.VC.14.38.{ue5_vs_fallback_version}.x86.x64",
125+
"Microsoft.VisualStudio.Component.Windows10SDK.20348",
126+
],
127+
)
128+
else:
129+
# Assuming 4.27
130+
vs = VisualStudio(
131+
"15",
132+
f"https://aka.ms/vs/15/release/channel",
133+
common_components
134+
+ [
135+
"Microsoft.Net.Component.4.5.TargetingPack",
136+
"Microsoft.Net.Component.4.6.2.TargetingPack",
137+
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64"
138+
"Microsoft.VisualStudio.Component.Windows10SDK.17763",
139+
],
140+
)
141+
142+
vs_installer_path = "C:/vs_buildtools.exe"
143+
vs.download_installer(vs_installer_path)
144+
vs.install(vs_installer_path)

0 commit comments

Comments
 (0)