Skip to content

ue4-build-prerequisites size bloat caused by multiple VS Build Tools #133

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

Closed
slonopotamus opened this issue Mar 3, 2021 · 14 comments
Closed

Comments

@slonopotamus
Copy link
Collaborator

slonopotamus commented Mar 3, 2021

Currently, ue4-build-prerequisites uses mcr.microsoft.com/dotnet/framework/sdk as base image. If we look into its Dockerfile, we can see that it already contains VS 2019 Build Tools. On top of that, ue4-build-prerequisites installs VS 2017 Build Tools.

I either suggest:
a. Change base image to something more lightweight (mcr.microsoft.com/dotnet/framework/sdk is almost 9GB) that doesn't include VS 2019 Build Tools
b. Stop installing VS 2017 Build Tools toolchain completely and instead use VS 2019 Build Tools to build UE4 (I'd prefer going this route)

@slonopotamus
Copy link
Collaborator Author

slonopotamus commented Mar 3, 2021

Okay, the problem is that VS 2019 support was only added in UE-4.22 and ue4-docker claims to support UE >= 4.19. This makes option B impossible to do.

Though, this adds option C: only install VS 2017 Build Tools if engine version is < 4.22.

@slonopotamus
Copy link
Collaborator Author

slonopotamus commented Mar 5, 2021

Actually, option A is more interesting than I initially thought. This is described in https://adamrehn.com/articles/building-docker-images-for-unreal-engine-4/#issues-specific-to-windows-containers:

Windows Server Core does not include the DirectX or OpenGL runtime files. Although the Windows 10 SDK that is installed by the Visual Studio 2017 Build Tools installer includes the DirectX SDK, it does not include all of the runtime DLL files that are required to run applications which have been built against the SDK. Both these DLLs and a set of OpenGL runtime files would ordinarily be provided by Windows, but this is not the case for Windows Server Core.

So, possibly switch to mcr.microsoft.com/windows image as a base would improve overall usability of ue4-docker. This would involve dropping support for Windows Server 2016 because mcr.microsoft.com/windows doesn't offer image for 2016. Though this steps a bit out of scope of current issue. Also, Microsoft says that support for mcr.microsoft.com/windows:1809 will end on 5/11/2021, but mcr.microsoft.com/windows/servercore:ltsc2019 will continue to be supported until 01/09/2024.

@slonopotamus
Copy link
Collaborator Author

@adamrehn So, I suggest first discussing which path you would like to go even if you don't currently have time to work on this. Having a decision would open an opportunity for a possible contributor to pick up this issue and work on it.

@adamrehn
Copy link
Owner

a. Change base image to something more lightweight (mcr.microsoft.com/dotnet/framework/sdk is almost 9GB) that doesn't include VS 2019 Build Tools

The reason that ue4-docker uses the .NET Framework SDK image is because we need to be able to build the Unreal Engine's C# tools (AutomationTool, UnrealBuildTool, etc.) and using a base image that already includes the .NET build tools saves the need to replicate large parts of Microsoft's Dockerfile. Back when the SDK image was using the Visual Studio 2017 Build Tools there were no downsides to this convenient choice, but as you've correctly pointed out, that is no longer the case now that we have a version mismatch.

As mentioned in the Known issues for containers page of the Microsoft documentation, applications that require the .NET Framework need to use an image based on the .NET Framework runtime image, so that would be the smallest image that could feasibly be used as a starting point. I'm not sure how many of the commands from the Dockerfile for the .NET Framework SDK image would need to be replicated in order to get everything working though.

So, possibly switch to mcr.microsoft.com/windows image as a base would improve overall usability of ue4-docker.

The full Windows base image is significantly larger than the Windows Server Core base image that the .NET Framework images are built upon, so switching to the full Windows image would only increase the size of the resulting container images and defeat the purpose of this bloat-removal exercise. From what I can tell, best practice is to avoid using the full Windows base image wherever possible and to simply copy the required files into a Windows Server Core image for applications that are missing a small handful of DLL files.

So, I suggest first discussing which path you would like to go even if you don't currently have time to work on this.

My preference would be option C: only install VS 2017 Build Tools if engine version is < 4.22, since this would be the least disruptive for users building container images for newer versions of the Unreal Engine. Finding a clean way to do this is the main sticking point. In fact, one of the driving motives for the planned refactor of ue4-docker is to make it easier to produce images for different Visual Studio versions, since this is currently awkward to achieve.

@slonopotamus
Copy link
Collaborator Author

Okay, understood. I will possibly try to do something about this issue.

@TBBle
Copy link
Collaborator

TBBle commented Mar 16, 2021

I've worked on projects that are using VS2017 compiler toolchain on UE4 4.23.

I'm actually not sure if they've dropped VS2017 support in the source yet, but for the EGS-distributed Installed Builds, VS 2017 was supported up until 4.24, according to Setting Up Visual Studio for Unreal Engine. My guess would be that UE 4.25 is when they dropped VS 2017 source compatibility, as AFAIK VS2017 and VS2019 are still ABI-compatible.

I personally like option 'C', but suspect that if I want to bring more in-studio users onto ue4-docker, I'll need VS 2017 and VS 2019 build tools available. Post #48, separate images would be okay with me, as the ones using non-default VS are probably also using custom engine, so they need their own images anyway.

Perhaps the option that gives widest user coverage right now is option 'C' except "4.25" instead of "4.22"?

only install VS 2017 Build Tools if engine version is < 4.25


One team is (or was, last time I looked) using a specific MSVC toolset vesrion only, which meant all kinds of fun for new computers with the latest MSVC installed. The Visual Studio Installer makes this easy to manage on a desktop for some given known MSVC toolsets, but would I want to build ue4-docker images that contained every known MSVC 14.1X and 14.2X release for UE4 4.19 onwards?

image

That was meant to be rhetorical, but actually, I have no idea how much space that would take. Maybe that's feasible and cheap?

Hmm, 1.2 to 1.5GB each, so 13GB without MFC and friends for today's list of possible toolchains. No, thank you.


Also, ue4-docker is UE 4.20 minimum now, if it helps.

@slonopotamus
Copy link
Collaborator Author

slonopotamus commented Mar 16, 2021

While this is true that UE-4.22+ can be built with both VS2017 and VS2019, only one of them will be actually used when ue4-docker builds engine. So, the other one is just uselessly takes up disk space. And ue4-docker currently doesn't offer an option to choose what toolchain is used to build the engine. If there was such option, it would make sense to only install selected VS version in ue4-build-prerequisites, but again, not both of them.

Finally, in case user needs any additional software inside docker image, they can always build an new image that uses ue4-minimal/ue4-full as a base and add whatever they need.

So, my statement is: ue4-build-prerequisites should only contain things that are, well, build prerequisites for UE4.

@TBBle
Copy link
Collaborator

TBBle commented Mar 16, 2021

Will a VS2019-built UE4 Installed Build be compatible with a VS2017-built project? I fear not.

I'm a bit fuzzy on the ABI rules; I think that you have to build object files with VS 2017 to be able to link them to a VS2017-built binary, because the VS2017 linker doesn't understand VS2019 object files. In fact, I believe that for any compiler version, your linker has to be the no older than the newest compiler in the chain. VS2017/VS2019 is not actually the split, we're talking about toolchain versions here, of which there were 7 in VS2017 and 10 so far in VS2019, but the VS2019 Installer only offers one VS2017 toolchain (the last: 14.16).

If that's the case, then the UE4 Installed Build should be built with VS 2017 compiler as long as it's possible that the end-user will then use VS 2017 build tools (and hence the VS2017 linker) to build the final binaries. I think that's what Epic meant in their docs that their Installed Build supports VS2017/VS2019: They built with VS2017, but their headers worked with VS2019.

It's possible I'm misremembering the rule though. I know VS2017 binaries can use the VS2019 VCRT runtimes (in fact, I think VS2015 14.0x can use VS2019 runtimes), and that when running something that contains both, you have to have a runtime as new as the most-recent part (in practice, always use the latest VS2019 runtimes, it's not like pre-VS2015 where each VS release needed its own runtime package installed); but I can't remember the details more certainly than that.

The upshot I'm not totally sure that the extra 1.5GB of saved space in the extracted container is worth dropping compatibility with a compiler that upstream still supports. Maybe it is though, I'm not personally suffering from the size of the pre-req or final images, so I am not the most-affected person in this conversation.

@TBBle
Copy link
Collaborator

TBBle commented Mar 16, 2021

Actually, stepping back a notch, are you talking about the Build Tools, or the MSVC compiler toolchain? I assume it was the latter, and have been responding as-such.

However, the highlighted lines in "contains" in the original post do not appear to be installing an MSVC version, those are all C# workloads.

So unless there's another install around than the two you linked in your post, there's only one C++ compiler being installed, the VS 2017 compiler (Microsoft.VisualStudio.Workload.VCTools workload from the VisualStudio.15.Release channel by the ue4-build-prerequisites install-prerequisites.bat).

I don't have a recent ue4-docker built container image for Windows at-hand, but are you sure there's two compilers installed?

Which directories in the resulting image are actually taking up the space you're concerned about? The fix might be as simple as changing the ue4-docker script to install the VS 2017 compiler using the current release channel: Microsoft.VisualStudio.Component.VC.v141.x86.x64 is an Optional component of the Microsoft.VisualStudio.Workload.VCTools workload from the VisualStudio.16.Release channel, and unlike VisualStudio.15.Release, that workload no longer has any C++ compiler as "required", so this should be quite feasible. I've done this with Visual Studio Pro setups as far as back UE 4.19.

Edit: To be clear, my confusion came because "Build Tools" has meant both "The C++ workload in Visual Studio" (particularly in the context of side-by-side installs of different MSVC versions and even non-MSVC compilers like Clang/LLVM) and "The headless installer for getting Visual Studio workloads onto CI machines". vs_buildtools.exe is the latter usage, but I was reading the former usage before this post.

@slonopotamus
Copy link
Collaborator Author

Hmm... You've asked a good question. I need to inspect ue4-build-prerequisites image contents more carefully.

@TBBle
Copy link
Collaborator

TBBle commented Mar 16, 2021

Sorry, you replied while I was edit my response. Hopefully it went from 'good question' to 'very good question'. ^_^

@slonopotamus
Copy link
Collaborator Author

Okay, you're right. There is no VS2019 toolchain inside ue4-build-prerequisites. Though I'm still unhappy with its size. ue4-build-prerequisites on Linux is 700MB. ue4-build-prerequisites on Windows is 26GB. And all this stuff goes right into ue4-minimal image. I have some ideas what to do about it, stay tuned.

@slonopotamus
Copy link
Collaborator Author

I dunno whether to keep this issue open or not. Possibly not, because the cause of current ue4-build-prerequisites size is different. Closing.

@slonopotamus
Copy link
Collaborator Author

See #144.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants