Skip to content

Commit

Permalink
Add support to load native libraries from the function.deps.json file.
Browse files Browse the repository at this point in the history
This allows for probing of more locations for native libraries instead of just the "runtimes\{rid}\native" folder. For example, native assets can also live in a "runtimes\{rid}\nativeassets\{tfm}" folder.
  • Loading branch information
eerhardt committed Oct 31, 2019
1 parent 5575abf commit 9fbd4a7
Showing 1 changed file with 26 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public partial class FunctionAssemblyLoadContext : AssemblyLoadContext

private readonly List<string> _probingPaths = new List<string>();
private readonly IDictionary<string, string> _depsAssemblies;
private readonly IDictionary<string, string> _nativeLibraries;

public FunctionAssemblyLoadContext(string basePath)
{
Expand All @@ -38,7 +39,7 @@ public FunctionAssemblyLoadContext(string basePath)
throw new ArgumentNullException(nameof(basePath));
}

_depsAssemblies = InitializeDeps(basePath);
(_depsAssemblies, _nativeLibraries) = InitializeDeps(basePath);

_probingPaths.Add(basePath);
}
Expand All @@ -50,7 +51,7 @@ internal static void ResetSharedContext()
_defaultContext = new Lazy<FunctionAssemblyLoadContext>(CreateSharedContext, true);
}

internal static IDictionary<string, string> InitializeDeps(string basePath)
internal static (IDictionary<string, string> depsAssemblies, IDictionary<string, string> nativeLibraries) InitializeDeps(string basePath)
{
string depsFilePath = Path.Combine(basePath, DotNetConstants.FunctionsDepsFileName);

Expand All @@ -64,16 +65,22 @@ internal static IDictionary<string, string> InitializeDeps(string basePath)
using (Stream file = File.OpenRead(depsFilePath))
{
var depsContext = reader.Read(file);
return depsContext.RuntimeLibraries.SelectMany(l => SelectRuntimeAssemblyGroup(rids, l.RuntimeAssemblyGroups))
var depsAssemblies = depsContext.RuntimeLibraries.SelectMany(l => SelectRuntimeAssemblyGroup(rids, l.RuntimeAssemblyGroups))
.ToDictionary(path => Path.GetFileNameWithoutExtension(path));

// Note this difference here that nativeLibraries has the whole file name, including extension.
var nativeLibraries = depsContext.RuntimeLibraries.SelectMany(l => SelectRuntimeAssemblyGroup(rids, l.NativeLibraryGroups))
.ToDictionary(path => Path.GetFileName(path));

return (depsAssemblies, nativeLibraries);
}
}
catch
{
}
}

return null;
return (null, null);
}

private static IEnumerable<string> SelectRuntimeAssemblyGroup(List<string> rids, IReadOnlyList<RuntimeAssetGroup> runtimeAssemblyGroups)
Expand Down Expand Up @@ -307,9 +314,23 @@ private string GetRuntimeNativeAssetPath(string assetFileName, bool isNativeAsse

List<string> rids = DependencyHelper.GetRuntimeFallbacks();

return rids.Select(r => Path.Combine(runtimesPath, r, ridSubFolder, assetFileName))
string result = rids.Select(r => Path.Combine(runtimesPath, r, ridSubFolder, assetFileName))
.Union(_probingPaths)
.FirstOrDefault(p => File.Exists(p));

if (result == null && _nativeLibraries != null)
{
if (_nativeLibraries.TryGetValue(assetFileName, out string relativePath))
{
string nativeLibraryFullPath = Path.Combine(basePath, relativePath);
if (File.Exists(nativeLibraryFullPath))
{
result = nativeLibraryFullPath;
}
}
}

return result;
}

internal string GetUnmanagedLibraryFileName(string unmanagedLibraryName)
Expand Down

0 comments on commit 9fbd4a7

Please sign in to comment.