Skip to content

Commit

Permalink
[tasks] Add auto runtime initialization template to LibraryBuilder (#…
Browse files Browse the repository at this point in the history
…83050)

* [tasks] Add auto runtime initialization template to LibraryBuilder

* Grab shared library directory

* [tasks] Extend auto initialization template to account for customization

* Revert "Grab shared library directory"

This reverts commit bc86f2b.

* Remove platform specific naming

* [tasks] Move App Context setup back to autoinit.c

* Remove registering bundled modules and debugging until they can be validated

* Remove unnecessary wrapper

* Grab bundle_path later without eglib

Setting bundle_path in constructor may be too early for environment variables to be set
so grab it first thing when initializing the runtime.

Use getenv directly instead of calling into eglib with just one api

* Rename AssetsPath to AssembliesLocation

* Move assembly loading into separate function

* Remove unnecessary function

* Cleanup CMakeLists template indentation

* Add dotnet header to autoinit.c

* Default bundle_path if assemblies path environment variable not set

* Pass bundle_path to load assemblies

* Add logging and abort on failures

* Load assemblies with partial name

* Clean up targets and unneeded properties

* Rename source file

* Remove preload hook and make out of memory error more generic

* Throw when no exported symbols are found

* Remove aot data load prehook and aotdata generation

* Address feedback

* Address more feedback

* Add various fixes and make bundle_path a local variable

* Reintroduce load aot data hook in autoinit with guard

* Fix closing tag

* Include guard library-builder.h

* Fix typo
  • Loading branch information
mdh1418 authored Mar 17, 2023
1 parent b6319cd commit ea57982
Show file tree
Hide file tree
Showing 10 changed files with 328 additions and 53 deletions.
18 changes: 14 additions & 4 deletions src/mono/msbuild/android/build/AndroidApp.targets
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@
<_AOTMode Condition="'$(ForceFullAOT)' == 'true'">Full</_AOTMode>
</PropertyGroup>

<PropertyGroup Condition="'$(_IsLibraryMode)' == 'true'">
<_UsesRuntimeInitCallback>$(UsesRuntimeInitCallback)</_UsesRuntimeInitCallback>
<_UsesRuntimeInitCallback Condition="'$(_UsesRuntimeInitCallback)' == ''">true</_UsesRuntimeInitCallback>
</PropertyGroup>

<ItemGroup>
<MonoAOTCompilerDefaultAotArguments Condition="'$(TargetArchitecture)' == 'arm'" Include="mtriple=armv7-linux-gnueabi" />
<MonoAOTCompilerDefaultAotArguments Condition="'$(TargetArchitecture)' == 'arm64'" Include="mtriple=aarch64-linux-android" />
Expand All @@ -85,6 +90,8 @@
<MonoAOTCompilerDefaultAotArguments Include="static" />
<MonoAOTCompilerDefaultAotArguments Include="dwarfdebug" />
<MonoAOTCompilerDefaultAotArguments Condition="'$(_IsLibraryMode)' == 'true'" Include="direct-icalls" />
<MonoAOTCompilerDefaultAotArguments Condition="'$(_UsesRuntimeInitCallback)' == 'true' and $(CustomRuntimeInitCallback) == ''" Include="runtime-init-callback" />
<MonoAOTCompilerDefaultAotArguments Condition="'$(_UsesRuntimeInitCallback)' == 'true' and $(CustomRuntimeInitCallback) != ''" Include="runtime-init-callback=$(CustomRuntimeInitCallback)" />

<MonoAOTCompilerDefaultAotArguments Include="nimt-trampolines=2000" />
<MonoAOTCompilerDefaultAotArguments Include="ntrampolines=10000" />
Expand Down Expand Up @@ -133,6 +140,12 @@
Condition="'$(RunAOTCompilation)' == 'true'"
DependsOnTargets="_AndroidBeforeAotCompileApp">

<PropertyGroup Condition="'$(_IsLibraryMode)' == 'true'">
<_EnableUnmanagedCallersOnlyMethodsExport>true</_EnableUnmanagedCallersOnlyMethodsExport>
<_UseAotDataFile>$(UseAotDataFile)</_UseAotDataFile>
<_UseAotDataFile Condition="'$(_UseAotDataFile)' == ''">false</_UseAotDataFile>
</PropertyGroup>

<ItemGroup>
<ProfiledAOTProfilePaths Include="$(MibcFilePath)" />
</ItemGroup>
Expand All @@ -147,10 +160,6 @@
<DirectPInvokes Include="libSystem.Security.Cryptography.Native.Android" />
</ItemGroup>

<PropertyGroup>
<_EnableUnmanagedCallersOnlyMethodsExport Condition="'$(_IsLibraryMode)' == 'true'">true</_EnableUnmanagedCallersOnlyMethodsExport>
</PropertyGroup>

<MonoAOTCompiler
AotModulesTablePath="$(_AotModuleTablePath)"
Assemblies="@(_AotInputAssemblies)"
Expand All @@ -164,6 +173,7 @@
Mode="$(_AOTMode)"
OutputDir="$(_MobileIntermediateOutputPath)"
OutputType="AsmOnly"
UseAotDataFile="$(_UseAotDataFile)"
UseLLVM="$(MonoEnableLLVM)">
<Output TaskParameter="CompiledAssemblies" ItemName="AppAssembliesInternal" />
</MonoAOTCompiler>
Expand Down
11 changes: 9 additions & 2 deletions src/mono/msbuild/apple/build/AppleApp.targets
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,12 @@
<_AOTMode Condition="'$(UseMonoJustInterp)' == 'true'">JustInterp</_AOTMode>
</PropertyGroup>

<PropertyGroup>
<_EnableUnmanagedCallersOnlyMethodsExport Condition="'$(_IsLibraryMode)' == 'true'">true</_EnableUnmanagedCallersOnlyMethodsExport>
<PropertyGroup Condition="'$(_IsLibraryMode)' == 'true'">
<_EnableUnmanagedCallersOnlyMethodsExport>true</_EnableUnmanagedCallersOnlyMethodsExport>
<_UseAotDataFile>$(UseAotDataFile)</_UseAotDataFile>
<_UseAotDataFile Condition="'$(_UseAotDataFile)' == ''">false</_UseAotDataFile>
<_UsesRuntimeInitCallback>$(UsesRuntimeInitCallback)</_UsesRuntimeInitCallback>
<_UsesRuntimeInitCallback Condition="'$(_UsesRuntimeInitCallback)' == ''">true</_UsesRuntimeInitCallback>
</PropertyGroup>

<ItemGroup>
Expand All @@ -104,6 +108,8 @@
<MonoAOTCompilerDefaultAotArguments Include="dwarfdebug" />
<MonoAOTCompilerDefaultAotArguments Condition="'$(TargetArchitecture)' == 'arm64'" Include="mattr=+crc" /> <!-- enable System.Runtime.Intrinsics.Arm (Crc32 and ArmBase for now) -->
<MonoAOTCompilerDefaultAotArguments Include="direct-icalls" />
<MonoAOTCompilerDefaultAotArguments Condition="'$(_UsesRuntimeInitCallback)' == 'true' and $(CustomRuntimeInitCallback) == ''" Include="runtime-init-callback" />
<MonoAOTCompilerDefaultAotArguments Condition="'$(_UsesRuntimeInitCallback)' == 'true' and $(CustomRuntimeInitCallback) != ''" Include="runtime-init-callback=$(CustomRuntimeInitCallback)" />

<MonoAOTCompilerDefaultAotArguments Include="nimt-trampolines=2000" />
<MonoAOTCompilerDefaultAotArguments Include="ntrampolines=40000" />
Expand Down Expand Up @@ -166,6 +172,7 @@
Mode="$(_AOTMode)"
OutputDir="$(_MobileIntermediateOutputPath)"
OutputType="AsmOnly"
UseAotDataFile="$(_UseAotDataFile)"
UseLLVM="$(MonoEnableLLVM)">
<Output TaskParameter="CompiledAssemblies" ItemName="AppAssembliesInternal" />
</MonoAOTCompiler>
Expand Down
9 changes: 7 additions & 2 deletions src/mono/msbuild/common/LibraryBuilder.targets
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
<PropertyGroup>
<_IsSharedLibrary>false</_IsSharedLibrary>
<_IsSharedLibrary Condition="'$(NativeLib)' == 'shared'">true</_IsSharedLibrary>
<_UsesCustomRuntimeInitCallback>false</_UsesCustomRuntimeInitCallback>
<_UsesCustomRuntimeInitCallback Condition="$(CustomRuntimeInitCallback) != ''">true</_UsesCustomRuntimeInitCallback>
</PropertyGroup>

<ItemGroup>
Expand All @@ -17,15 +19,18 @@

<LibraryBuilderTask
Assemblies="@(AppAssembliesInternal)"
AssembliesLocation="$(AssembliesLocation)"
ExtraLinkerArguments="@(_ExtraLinkerArgs)"
ExtraSources="@(_ExtraLibrarySources)"
IsSharedLibrary="$(_IsSharedLibrary)"
Name="$(AssemblyName)"
MonoRuntimeHeaders="$(_MonoHeaderPath)"
Name="$(AssemblyName)"
OutputDirectory="$(BundleDir)"
RuntimeIdentifier="$(RuntimeIdentifier)"
RuntimeLibraries="@(_RuntimeLibraries)"
TargetOS="$(TargetOS)">
TargetOS="$(TargetOS)"
UsesCustomRuntimeInitCallback="$(_UsesCustomRuntimeInitCallback)"
UsesRuntimeInitCallback="$(_UsesRuntimeInitCallback)">
<Output TaskParameter="OutputPath" PropertyName="LibraryOutputPath" />
</LibraryBuilderTask>
</Target>
Expand Down
96 changes: 70 additions & 26 deletions src/tasks/LibraryBuilder/LibraryBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public class LibraryBuilderTask : AppBuilderTask

private string cmakeProjectLanguages = "";
private string targetOS = "";
private bool usesAOTDataFile;
private List<string> exportedAssemblies = new List<string>();

/// <summary>
/// The name of the library being generated
Expand Down Expand Up @@ -66,6 +68,23 @@ public bool IsSharedLibrary
}
}

/// <summary>
/// Determines whether or not the mono runtime auto initialization
/// template, autoinit.c, is used.
/// </summary>
public bool UsesCustomRuntimeInitCallback { get; set; }

/// <summary>
/// Determines if there is a mono runtime init callback
/// </summary>
public bool UsesRuntimeInitCallback { get; set; }

/// <summary>
/// The environment variable name that will point to where assemblies
/// are located on the app host device.
/// </summary>
public string? AssembliesLocation { get; set; }

public bool StripDebugSymbols { get; set; }

/// <summary>
Expand Down Expand Up @@ -113,6 +132,17 @@ public override bool Execute()
GatherAotSourcesObjects(aotSources, aotObjects, extraSources, linkerArgs);
GatherLinkerArgs(linkerArgs);

File.WriteAllText(Path.Combine(OutputDirectory, "library-builder.h"),
Utils.GetEmbeddedResource("library-builder.h"));

GenerateAssembliesLoader();

if (UsesRuntimeInitCallback && !UsesCustomRuntimeInitCallback)
{
WriteAutoInitializationFromTemplate();
extraSources.AppendLine(" autoinit.c");
}

WriteCMakeFileFromTemplate(aotSources.ToString(), aotObjects.ToString(), extraSources.ToString(), linkerArgs.ToString());
OutputPath = BuildLibrary();

Expand All @@ -122,14 +152,18 @@ public override bool Execute()
private void GatherAotSourcesObjects(StringBuilder aotSources, StringBuilder aotObjects, StringBuilder extraSources, StringBuilder linkerArgs)
{
List<string> exportedSymbols = new List<string>();
List<string> exportedAssemblies = new List<string>();
bool hasExports = false;

foreach (CompiledAssembly compiledAssembly in CompiledAssemblies)
{
if (!string.IsNullOrEmpty(compiledAssembly.AssemblerFile))
{
aotSources.AppendLine(compiledAssembly.AssemblerFile);
aotSources.AppendLine($" {compiledAssembly.AssemblerFile}");
}

if (!usesAOTDataFile && !string.IsNullOrEmpty(compiledAssembly.DataFile))
{
usesAOTDataFile = true;
}

if (!string.IsNullOrEmpty(compiledAssembly.LlvmObjectFile))
Expand All @@ -145,10 +179,14 @@ private void GatherAotSourcesObjects(StringBuilder aotSources, StringBuilder aot

if (symbolsAdded > 0)
{
exportedAssemblies.Add(Path.GetFileName(compiledAssembly.Path));
exportedAssemblies.Add(Path.GetFileNameWithoutExtension(compiledAssembly.Path));
}
}
}
if (IsSharedLibrary && exportedAssemblies.Count == 0)
{
throw new LogAsErrorException($"None of the compiled assemblies contain exported symbols. Resulting shared library would be unusable.");
}

// for android, all symbols to keep go in one linker script
//
Expand All @@ -167,11 +205,9 @@ private void GatherAotSourcesObjects(StringBuilder aotSources, StringBuilder aot
WriteExportedSymbolsArg(MobileSymbolFileName, linkerArgs);
}

WriteAssembliesToLoadList(exportedAssemblies);

foreach (ITaskItem item in ExtraSources)
{
extraSources.AppendLine(item.ItemSpec);
extraSources.AppendLine($" {item.ItemSpec}");
}
}

Expand Down Expand Up @@ -226,8 +262,30 @@ private static void WriteLinkerScriptFile(string exportsFile, List<string> expor
.Replace("%GLOBAL_SYMBOLS%", globalExports));
}

private void WriteAutoInitializationFromTemplate()
{
File.WriteAllText(Path.Combine(OutputDirectory, "autoinit.c"),
Utils.GetEmbeddedResource("autoinit.c")
.Replace("%ASSEMBLIES_LOCATION%", !string.IsNullOrEmpty(AssembliesLocation) ? AssembliesLocation : "DOTNET_LIBRARY_ASSEMBLY_PATH")
.Replace("%RUNTIME_IDENTIFIER%", RuntimeIdentifier));
}

private void GenerateAssembliesLoader()
{
var assemblyPreloaders = new List<string>();
foreach (string exportedAssembly in exportedAssemblies)
{
assemblyPreloaders.Add($"preload_assembly(\"{exportedAssembly}\");");
}

File.WriteAllText(Path.Combine(OutputDirectory, "preloaded-assemblies.c"),
Utils.GetEmbeddedResource("preloaded-assemblies.c")
.Replace("%ASSEMBLIES_PRELOADER%", string.Join("\n ", assemblyPreloaders)));
}

private void WriteCMakeFileFromTemplate(string aotSources, string aotObjects, string extraSources, string linkerArgs)
{
string extraDefinitions = GenerateExtraDefinitions();
// BundleDir
File.WriteAllText(Path.Combine(OutputDirectory, "CMakeLists.txt"),
Utils.GetEmbeddedResource("CMakeLists.txt.template")
Expand All @@ -237,35 +295,21 @@ private void WriteCMakeFileFromTemplate(string aotSources, string aotObjects, st
.Replace("%MonoInclude%", MonoRuntimeHeaders)
.Replace("%AotSources%", aotSources)
.Replace("%AotObjects%", aotObjects)
.Replace("%ExtraDefinitions%", extraDefinitions)
.Replace("%ExtraSources%", extraSources)
.Replace("%LIBRARY_LINKER_ARGS%", linkerArgs));
}

private void WriteAssembliesToLoadList(List<string> assemblies)
private string GenerateExtraDefinitions()
{
string content;
var extraDefinitions = new StringBuilder();

if (assemblies.Count == 0)
{
content = " return NULL;";
}
else
if (usesAOTDataFile)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine($" char** assembly_list = (char**)malloc({assemblies.Count.ToString()} * sizeof(char*));");

for (int i = 0; i < assemblies.Count; i++)
{
sb.AppendLine($" assembly_list[{i.ToString()}] = \"{assemblies[i]}\";");
}

sb.AppendLine(" return assembly_list;");
content = sb.ToString();
extraDefinitions.AppendLine("add_definitions(-DUSES_AOT_DATA=1)");
}

File.WriteAllText(Path.Combine(OutputDirectory, "assembly_list.c"),
Utils.GetEmbeddedResource("assembly_list.c")
.Replace("%LOADABLE_ASSEMBLIES%", content));
return extraDefinitions.ToString();
}

private string BuildLibrary()
Expand Down
1 change: 1 addition & 0 deletions src/tasks/LibraryBuilder/LibraryBuilder.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<Compile Include="..\Common\Builders\AppBuilderTask.cs" />
<Compile Include="..\Common\Builders\AndroidProject.cs" />
<Compile Include="..\Common\Builders\CompiledAssembly.cs" />
<Compile Include="..\Common\LogAsErrorException.cs" />
<Compile Include="..\AppleAppBuilder\TargetOS.cs" />
<Compile Include="..\AppleAppBuilder\Xcode.cs" />
</ItemGroup>
Expand Down
25 changes: 15 additions & 10 deletions src/tasks/LibraryBuilder/Templates/CMakeLists.txt.template
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@ project(%LIBRARY_NAME%)
enable_language(%CMAKE_LANGS%)

set(DOTNET_AOT_SOURCES
%AotSources%
%AotSources%
)
set(DOTNET_AOT_OBJECTS
%AotObjects%
%AotObjects%
)
set(DOTNET_EXTRA_SOURCES
%ExtraSources%
assembly_list.c
)
library-builder.h
preloaded-assemblies.c
%ExtraSources%)

include_directories("%MonoInclude%")

add_library(
aot_library STATIC
${DOTNET_AOT_SOURCES}
${DOTNET_AOT_SOURCES}
)
target_link_libraries(
aot_library
Expand All @@ -35,9 +35,10 @@ add_library(
if(TARGETS_ANDROID)
set(MOBILE_SYSTEM_LIBS
libz.so
log
log
)
else()
add_definitions(-DHOST_ANDROID=1)
elseif(TARGETS_APPLE_MOBILE)
set(MOBILE_SYSTEM_LIBS
"-framework Foundation"
"-framework Security"
Expand All @@ -46,12 +47,16 @@ else()
"-lc++"
"-liconv"
)
add_definitions(-DHOST_APPLE_MOBILE=1)
else()
message(FATAL_ERROR "Unsupported Platform. Ensure the TargetOS is supported by the LibraryBuilder and the platform specific libs are added here.")
endif()

%ExtraDefinitions%

target_link_libraries(
%LIBRARY_NAME%
PUBLIC
aot_library
${MOBILE_SYSTEM_LIBS}
%LIBRARY_LINKER_ARGS%
)
%LIBRARY_LINKER_ARGS%)
9 changes: 0 additions & 9 deletions src/tasks/LibraryBuilder/Templates/assembly_list.c

This file was deleted.

Loading

0 comments on commit ea57982

Please sign in to comment.