Skip to content

Commit aedeb20

Browse files
committed
Optionally produce "empty" embed.*.s files
Even though we might not have any content to embed, we need the symbols to be present, because they're part of the `libxamarin-app.so` ABI expected by `libmonodroid.so`
1 parent c8a844d commit aedeb20

File tree

3 files changed

+58
-32
lines changed

3 files changed

+58
-32
lines changed

src/Xamarin.Android.Build.Tasks/Tasks/CreateEmbeddedAssemblyStore.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ public override bool RunTask ()
8484
AndroidBinUtilsDirectory,
8585
inputFile,
8686
ELFEmbeddingHelper.KnownEmbedItems.AssemblyStore,
87-
AssemblySourcesDir
87+
AssemblySourcesDir,
88+
missingContentOK: false
8889
);
8990

9091
if (items.Count == 0) {

src/Xamarin.Android.Build.Tasks/Tasks/GeneratePackageManagerJava.cs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ public class GeneratePackageManagerJava : AndroidTask
6161
[Required]
6262
public bool EnablePreloadAssembliesDefault { get; set; }
6363

64-
[Required]
64+
// This property should be required but it can't, because during design time builds there's no
65+
// value to pass and MSBuild signals an error that a required property wasn't given a value.
66+
//[Required]
6567
public string AndroidBinUtilsDirectory { get; set; }
6668

6769
[Required]
@@ -343,20 +345,17 @@ void AddEnvironment ()
343345
}
344346

345347
bool haveRuntimeConfigBlob = !String.IsNullOrEmpty (RuntimeConfigBinFilePath) && File.Exists (RuntimeConfigBinFilePath);
346-
if (haveRuntimeConfigBlob) {
347-
List<ITaskItem> objectFilePaths = ELFEmbeddingHelper.EmbedBinary (
348-
Log,
349-
SupportedAbis,
350-
AndroidBinUtilsDirectory,
351-
RuntimeConfigBinFilePath,
352-
ELFEmbeddingHelper.KnownEmbedItems.RuntimeConfig,
353-
EnvironmentOutputDirectory
354-
);
355-
356-
EmbeddedObjectFiles = objectFilePaths.ToArray ();
357-
} else {
358-
EmbeddedObjectFiles = Array.Empty<ITaskItem> ();
359-
}
348+
List<ITaskItem> objectFilePaths = ELFEmbeddingHelper.EmbedBinary (
349+
Log,
350+
SupportedAbis,
351+
AndroidBinUtilsDirectory,
352+
RuntimeConfigBinFilePath,
353+
ELFEmbeddingHelper.KnownEmbedItems.RuntimeConfig,
354+
EnvironmentOutputDirectory,
355+
missingContentOK: !haveRuntimeConfigBlob
356+
);
357+
358+
EmbeddedObjectFiles = objectFilePaths.ToArray ();
360359

361360
var jniRemappingNativeCodeInfo = BuildEngine4.GetRegisteredTaskObjectAssemblyLocal<GenerateJniRemappingNativeCode.JniRemappingNativeCodeInfo> (ProjectSpecificTaskObjectKey (GenerateJniRemappingNativeCode.JniRemappingNativeCodeInfoKey), RegisteredTaskObjectLifetime.Build);
362361
var appConfigAsmGen = new ApplicationConfigNativeAssemblyGenerator (environmentVariables, systemProperties, Log) {

src/Xamarin.Android.Build.Tasks/Utilities/ELFEmbeddingHelper.cs

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,10 @@ public static List<ITaskItem> EmbedBinary (
6262
TaskLoggingHelper log,
6363
ICollection<string> supportedAbis,
6464
string androidBinUtilsDirectory,
65-
string inputFile,
65+
string? inputFile,
6666
EmbedItem embedItem,
67-
string outputDirectory)
67+
string outputDirectory,
68+
bool missingContentOK)
6869
{
6970
if (supportedAbis.Count < 1) {
7071
throw new ArgumentException ("At least one target ABI must be present", nameof (supportedAbis));
@@ -80,7 +81,8 @@ public static List<ITaskItem> EmbedBinary (
8081
abi,
8182
inputFile,
8283
outputDirectory,
83-
embedItem
84+
embedItem,
85+
missingContentOK
8486
);
8587
}
8688

@@ -91,9 +93,10 @@ public static List<ITaskItem> EmbedBinary (
9193
TaskLoggingHelper log,
9294
string abi,
9395
string androidBinUtilsDirectory,
94-
string inputFile,
96+
string? inputFile,
9597
EmbedItem embedItem,
96-
string outputDirectory)
98+
string outputDirectory,
99+
bool missingContentOK)
97100
{
98101
if (String.IsNullOrEmpty (abi)) {
99102
throw new ArgumentException ("Must be a supported ABI name", nameof (abi));
@@ -107,7 +110,8 @@ public static List<ITaskItem> EmbedBinary (
107110
abi,
108111
inputFile,
109112
outputDirectory,
110-
embedItem
113+
embedItem,
114+
missingContentOK
111115
);
112116
return ret;
113117
}
@@ -119,10 +123,11 @@ static void EmbedBinary (
119123
string abi,
120124
string inputFile,
121125
string outputDirectory,
122-
EmbedItem embedItem)
126+
EmbedItem embedItem,
127+
bool missingContentOK)
123128
{
124129
string outputFile = Path.Combine (outputDirectory, $"embed_{embedItem.BaseFileName}.{abi.ToLowerInvariant ()}.o");
125-
DoEmbed (log, MonoAndroidHelper.AbiToTargetArch (abi), llvmMcPath, inputFile, outputFile, embedItem);
130+
DoEmbed (log, MonoAndroidHelper.AbiToTargetArch (abi), llvmMcPath, inputFile, outputFile, embedItem, missingContentOK);
126131
if (!File.Exists (outputFile)) {
127132
return;
128133
}
@@ -137,33 +142,54 @@ static void DoEmbed (
137142
TaskLoggingHelper log,
138143
AndroidTargetArch arch,
139144
string llvmMcPath,
140-
string inputFile,
145+
string? inputFile,
141146
string outputFile,
142-
EmbedItem item)
147+
EmbedItem item,
148+
bool missingContentOK)
143149
{
144150
if (!llvmMcConfigs.TryGetValue (arch, out LlvmMcTargetConfig cfg)) {
145151
throw new NotSupportedException ($"Internal error: unsupported target arch '{arch}'");
146152
}
147153

148-
inputFile = Path.GetFullPath (inputFile);
154+
bool haveInputFile = !String.IsNullOrEmpty (inputFile);
155+
if (!haveInputFile) {
156+
if (!missingContentOK) {
157+
throw new InvalidOperationException ("Internal error: input file must be specified");
158+
}
159+
} else {
160+
inputFile = Path.GetFullPath (inputFile);
161+
}
149162
outputFile = Path.GetFullPath (outputFile);
150163

151-
var fi = new FileInfo (inputFile);
152-
long inputFileSize = fi.Length;
164+
long inputFileSize = 0;
165+
string? sanitizedInputFilePath = null;
166+
167+
if (haveInputFile) {
168+
var fi = new FileInfo (inputFile);
169+
if (fi.Exists) {
170+
inputFileSize = fi.Length;
171+
sanitizedInputFilePath = inputFile.Replace ("\\", "\\\\");
172+
} else if (!missingContentOK) {
173+
throw new InvalidOperationException ($"Internal error: input file '{inputFile}' does not exist");
174+
}
175+
}
176+
153177
string asmInputFile = Path.ChangeExtension (outputFile, ".s");
154-
string sanitizedInputFilePath = inputFile.Replace ("\\", "\\\\");
155178

156179
using var fs = File.Open (asmInputFile, FileMode.Create, FileAccess.Write, FileShare.Read);
157180
using var sw = new StreamWriter (fs, asmFileEncoding);
158181

159182
string symbolName = item.SymbolName;
160183
sw.WriteLine ($".section .rodata,\"a\",{cfg.AssemblerDirectivePrefix}progbits");
161-
sw.WriteLine (".p2align 3, 0x00"); // Put the data at 4k boundary
184+
sw.WriteLine (".p2align 3, 0x00"); // Put the data at the 4k boundary
162185
sw.WriteLine ();
163186
sw.WriteLine ($".global {symbolName}");
164187
sw.WriteLine ($".type {symbolName},{cfg.AssemblerDirectivePrefix}object");
165188
sw.WriteLine ($"{symbolName}:");
166-
sw.WriteLine ($"\t.incbin \"{sanitizedInputFilePath}\"");
189+
190+
if (!String.IsNullOrEmpty (sanitizedInputFilePath)) {
191+
sw.WriteLine ($"\t.incbin \"{sanitizedInputFilePath}\"");
192+
}
167193
sw.WriteLine ($"\t.size {symbolName}, {inputFileSize}");
168194
sw.WriteLine ();
169195

0 commit comments

Comments
 (0)