Nuke.Unreal
Build Unreal apps in Style.
Loading...
Searching...
No Matches
WindowsHostsAndroid.cs
1using System;
2using System.Linq;
3using System.Threading.Tasks;
4using Nuke.Cola;
5using Nuke.Cola.Tooling;
6using Nuke.Common;
7using Nuke.Common.IO;
8using Nuke.Common.Tooling;
9using Nuke.Common.Utilities;
10using Serilog;
11
13
15{
16 public static string? GetJdkDownloadUrl(int jdk) => jdk switch
17 {
18 25 => "https://download.java.net/java/GA/jdk25.0.1/2fbf10d8c78e40bd87641c434705079d/8/GPL/openjdk-25.0.1_windows-x64_bin.zip",
19 24 => "https://download.java.net/java/GA/jdk24.0.2/fdc5d0102fe0414db21410ad5834341f/12/GPL/openjdk-24.0.2_windows-x64_bin.zip",
20 23 => "https://download.java.net/java/GA/jdk23.0.2/6da2a6609d6e406f85c491fcb119101b/7/GPL/openjdk-23.0.2_windows-x64_bin.zip",
21 22 => "https://download.java.net/java/GA/jdk22.0.2/c9ecb94cd31b495da20a27d4581645e8/9/GPL/openjdk-22.0.2_windows-x64_bin.zip",
22 21 => "https://download.java.net/java/GA/jdk21.0.2/f2283984656d49d69e91c558476027ac/13/GPL/openjdk-21.0.2_windows-x64_bin.zip",
23 20 => "https://download.java.net/java/GA/jdk20.0.2/6e380f22cbe7469fa75fb448bd903d8e/9/GPL/openjdk-20.0.2_windows-x64_bin.zip",
24 19 => "https://download.java.net/java/GA/jdk19.0.1/afdd2e245b014143b62ccb916125e3ce/10/GPL/openjdk-19.0.1_windows-x64_bin.zip",
25 18 => "https://download.java.net/java/GA/jdk18.0.2/f6ad4b4450fd4d298113270ec84f30ee/9/GPL/openjdk-18.0.2_windows-x64_bin.zip",
26 17 => "https://download.java.net/java/GA/jdk17.0.2/dfd4a8d0985749f896bed50d7138ee7f/8/GPL/openjdk-17.0.2_windows-x64_bin.zip",
27 _ => null
28 };
29
30 public static AbsolutePath AndroidHome
31 {
32 get
33 {
34 var androidHome = EnvironmentInfo.GetVariable("ANDROID_HOME")
35 ?? EnvironmentInfo.GetVariable("ANDROID_SDK_HOME")
36 ?? EnvironmentInfo.GetVariable("ANDROID_SDK_ROOT")
37 ?? EnvironmentInfo.SpecialFolder(SpecialFolders.LocalApplicationData)! / "Android/Sdk"
38 ;
39 Environment.SetEnvironmentVariable("ANDROID_HOME", androidHome, EnvironmentVariableTarget.Process);
40 Environment.SetEnvironmentVariable("ANDROID_SDK_HOME", androidHome, EnvironmentVariableTarget.Process);
41 return AbsolutePath.Create(androidHome);
42 }
43 }
44
45 private IPlatformSdk SelfPlatformSdk => this;
46
47 public AbsolutePath GetJdkVersionsPath(IUnrealBuild build) => SelfPlatformSdk.GetSdkVersionsPath(build) / "JDK";
48 public AbsolutePath GetCommandlineToolsPath(IUnrealBuild build) => AndroidHome / "cmdline-tools/latest";
49
50 public AbsolutePath GetSdkManagerPath(IUnrealBuild build) => GetCommandlineToolsPath(build) / "bin/sdkmanager.bat";
51
53 public override UnrealPlatform Target => UnrealPlatform.Android;
54
55 public override async Task Setup(IUnrealBuild build)
56 {
57 var sdkVersions = GetSdkVersionsChecked(build);
58 var jdkPath = GetJdkVersionsPath(build) / sdkVersions.Jdk.ToString();
59
60 Log.Information("Using JDK {0} at {1}", sdkVersions.Jdk, jdkPath);
61 if (!jdkPath.DirectoryExists())
62 {
63 var jdkDownloadPath = NukeBuild.TemporaryDirectory / $"OpenJDK-{sdkVersions.Jdk}.zip";
64 var url = GetJdkDownloadUrl(sdkVersions.Jdk);
65 Log.Debug(" Downloading JDK from {0} to {1}", url, jdkDownloadPath);
66 await HttpTasks.HttpDownloadFileAsync(url, jdkDownloadPath);
67
68 var extractTemp = NukeBuild.TemporaryDirectory / $"OpenJDK-{sdkVersions.Jdk}";
69 Log.Debug(" Extracting to {0}", extractTemp);
70
71 jdkDownloadPath.UnZipTo(extractTemp);
72 var tempJdkRoot = extractTemp.GetDirectories().First();
73 Log.Debug(" Moving");
74 tempJdkRoot.Move(jdkPath);
75 }
76 Environment.SetEnvironmentVariable("JAVA_HOME", jdkPath, EnvironmentVariableTarget.Process);
77
78 if (!SelfPlatformSdk.Exists(build))
79 {
80 var sdkManagerPath = GetSdkManagerPath(build);
81 Log.Information("Using SDK Manager at {0}", sdkVersions.Jdk, sdkManagerPath);
82 if (!sdkManagerPath.FileExists())
83 {
84 var cmdlineToolsDownloadPath = NukeBuild.TemporaryDirectory / "AndroidCommandLineTools.zip";
85 var url = "https://dl.google.com/android/repository/commandlinetools-win-13114758_latest.zip";
86 Log.Debug(" Downloading Command line tools from {0} to {1}", url, cmdlineToolsDownloadPath);
87 await HttpTasks.HttpDownloadFileAsync(url, cmdlineToolsDownloadPath);
88
89 var extractTemp = NukeBuild.TemporaryDirectory / "AndroidCommandLineTools";
90 Log.Debug(" Extracting to {0}", extractTemp);
91 cmdlineToolsDownloadPath.UnZipTo(extractTemp);
92
93 Log.Debug(" Moving");
94 (extractTemp / "cmdline-tools").Move(GetCommandlineToolsPath(build));
95 Assert.FileExists(sdkManagerPath);
96 }
97
98 var sdkManager = ToolExResolver.GetTool(sdkManagerPath);
99
100 Log.Information(
101 "Installing Android SDK {0}, Build Tools {1}, NDK {2}",
102 sdkVersions.Sdk,
103 sdkVersions.BuildTools.ToString(3),
104 sdkVersions.Ndk.ToString(3)
105 );
106 Log.Debug(" Accepting licenses");
107 sdkManager.WithInput(Enumerable.Repeat("y", 100)).CloseInput()("--licenses");
108
109 // TODO: read TargetSDKVersion from *Engine.ini
110
111 sdkManager(
112 $"""
113 "platforms;android-{sdkVersions.Sdk}"
114 "build-tools;{sdkVersions.BuildTools.ToString(3)}"
115 "ndk;{sdkVersions.Ndk.ToString(3)}"
116 "cmake;{sdkVersions.CMake.ToStringAutoFieldCount()}"
117 "platform-tools"
118 """.AsSingleLine()
119 );
120 }
121
122 Environment.SetEnvironmentVariable("NDK_ROOT", GetNdkPath(build), EnvironmentVariableTarget.Process);
123 Environment.SetEnvironmentVariable("NDKROOT", GetNdkPath(build), EnvironmentVariableTarget.Process);
124 var paths = EnvironmentInfo.Paths
125 .Append(GetPlatformToolsPath(build).ToString())
126 .Join(";")
127 ;
128 Environment.SetEnvironmentVariable("PATH", paths, EnvironmentVariableTarget.Process);
129
130 Log.Information("Using Android SDK {0} at {1}", sdkVersions.Sdk, GetSdkPath(build));
131 Log.Information("Using Android NDK toolchain {0} at {1}", sdkVersions.Ndk.ToString(3), GetToolchainPath(build));
132 }
133
134 public override bool IsValid(IUnrealBuild build) => GetSdkVersions(build) != null;
135
136 public override AbsolutePath GetSdkPath(IUnrealBuild build)
137 => AndroidHome / $"platforms/android-{GetSdkVersionsChecked(build).Sdk}";
138
139 public override AbsolutePath GetAndroidHome(IUnrealBuild build) => AndroidHome;
140
141 public override AbsolutePath GetNdkPath(IUnrealBuild build)
142 => AndroidHome / "ndk" / GetSdkVersionsChecked(build).Ndk.ToString(3);
143
144 public override AbsolutePath GetBuildToolsPath(IUnrealBuild build)
145 => AndroidHome / "build-tools" / GetSdkVersionsChecked(build).BuildTools.ToString(3);
146
147 public override ToolEx GetApkSigner(IUnrealBuild build)
148 => ToolExResolver.GetTool(GetBuildToolsPath(build) / "apksigner.bat");
149
150 public AbsolutePath GetToolchainPath(IUnrealBuild build)
151 => GetNdkPath(build) / "toolchains/llvm/prebuilt/windows-x86_64";
152
154 => new($"--ndk=\"{GetNdkPath(build)}\"");
155
156 public override AbsolutePath GetPlatformToolsPath(IUnrealBuild build) => AndroidHome / "platform-tools";
157
158 public override ToolEx GetAdb(IUnrealBuild build) => ToolExResolver.GetTool(GetPlatformToolsPath(build) / "adb.exe");
159}
Base class for managing Android SDK on any host platform.
Definition AndroidSdk.cs:35
override PlatformSdkXMakeData GetXMakeData(IUnrealBuild build)
If applicable and XMake can work with the toolchains provided by this SDK, return information for it ...
override AbsolutePath GetSdkPath(IUnrealBuild build)
The root of the currently used platform SDK in the file system, if there's one.
override bool IsValid(IUnrealBuild build)
Would this SDK be ever valid for the given Unreal project. This check is done before Setup is called....
override UnrealPlatform Target
The platform targeted by given SDK.
AbsolutePath GetToolchainPath(IUnrealBuild build)
Get the path to a C++ toolchain folder which may be used to compile external C++ code with to maintai...
override UnrealPlatform Host
The platform used for development, hosting this SDK to cross-compile target platform.
override async Task Setup(IUnrealBuild build)
High level representation of common platforms supported by Unreal Engine (NDA ones excluded) and extr...
static readonly UnrealPlatform Win64
Any platform name containing 'Windows' is also mapped to this platform.
Base interface for build components which require an UnrealBuild main class.
Base interface for implementing the automatic SDK management for a host-target platform pair.
bool Exists(IUnrealBuild build)
Whether a valid platform SDK exists locally for given project, and is ready to use without further do...
AbsolutePath GetSdkVersionsPath(IUnrealBuild build)
A shared user folder for this SDK version, owned by Nuke.Unreal. This may be a parent folder to store...
record class PlatformSdkXMakeData(string Arguments, string? Platform=null, Func< ToolEx, ToolEx >? ToolSetup=null)
A record for providing build information for XMake/XRepo when that may be requested.