Skip to content
This repository has been archived by the owner on Dec 18, 2017. It is now read-only.

Commit

Permalink
Enabling loading native libs from project references CoreClr
Browse files Browse the repository at this point in the history
  • Loading branch information
moozzyk committed Oct 25, 2015
1 parent b9f0af9 commit cba17e0
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Diagnostics;
Expand All @@ -6,7 +9,6 @@
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using Microsoft.Dnx.Runtime.Servicing;
using Microsoft.Extensions.PlatformAbstractions;
Expand Down Expand Up @@ -279,7 +281,7 @@ public static void EnableLoadingNativeLibraries(IEnumerable<PackageDescription>

public static void EnableLoadingNativeLibraries(IEnumerable<ProjectDescription> projects)
{
var folderCandidates = GetFolderCandidates();
var folderCandidates = NativeLibPathUtils.GetNativeSubfolderCandidates();

var nativeLibPaths = new StringBuilder();
foreach (var projectDescription in projects)
Expand Down Expand Up @@ -323,23 +325,6 @@ private static void PreLoadNativeLib(string nativeLibFullPath)
Logger.TraceInformation("[{0}]: Preloading : {1} {2}", nameof(PackageDependencyProvider), nativeLibFullPath,
handle != IntPtr.Zero ? "succeeded" : "failed");
}

private static IEnumerable<string> GetFolderCandidates()
{
if (RuntimeEnvironmentHelper.IsWindows)
{
return PlatformServices.Default.Runtime.GetAllRuntimeIdentifiers();
}

var runtimeId = PlatformServices.Default.Runtime.GetRuntimeOsName();

return new[]
{
runtimeId,
runtimeId.Split('-')[0],
runtimeId.Split('.')[0]
};
}
#endif

#if DNX451
Expand Down
41 changes: 41 additions & 0 deletions src/Microsoft.Dnx.Runtime/Loader/ProjectAssemblyLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class ProjectAssemblyLoader : IAssemblyLoader
private readonly IAssemblyLoadContextAccessor _loadContextAccessor;
private readonly ICompilationEngine _compilationEngine;
private readonly IDictionary<string, RuntimeProject> _projects;
private readonly HashSet<string> _unloadableNativeLibs = new HashSet<string>();

public ProjectAssemblyLoader(IAssemblyLoadContextAccessor loadContextAccessor,
ICompilationEngine compilationEngine,
Expand All @@ -25,6 +26,8 @@ public ProjectAssemblyLoader(IAssemblyLoadContextAccessor loadContextAccessor,
_loadContextAccessor = loadContextAccessor;
_compilationEngine = compilationEngine;
_projects = projects.ToDictionary(p => p.Identity.Name, p => new RuntimeProject(p.Project, p.Framework));

var environment = RuntimeEnvironmentHelper.RuntimeEnvironment;
}

public Assembly Load(AssemblyName assemblyName)
Expand Down Expand Up @@ -83,7 +86,45 @@ public RuntimeProject(Project project, FrameworkName targetFramework)

public IntPtr LoadUnmanagedLibrary(string name)
{
if (_unloadableNativeLibs.Contains(name))
{
return IntPtr.Zero;
}

foreach(var projectPath in _projects.Values.Select(p => p.Project.ProjectDirectory))
{
foreach (var folder in NativeLibPathUtils.GetNativeSubfolderCandidates(RuntimeEnvironmentHelper.RuntimeEnvironment))
{
var path = NativeLibPathUtils.GetProjectNativeLibPath(projectPath, folder);
if (Directory.Exists(path))
{
var handle = LoadUnamangedLibrary(path, name);
if (handle != IntPtr.Zero)
{
return handle;
}
}
}
}

_unloadableNativeLibs.Add(name);

return IntPtr.Zero;
}

private IntPtr LoadUnamangedLibrary(string path, string name)
{
foreach (var nativeLibFullPath in Directory.EnumerateFiles(path))
{
if (NativeLibPathUtils.IsMatchingNativeLibrary(RuntimeEnvironmentHelper.RuntimeEnvironment, name, Path.GetFileName(nativeLibFullPath)))
{
return _loadContextAccessor.Default.LoadUnmanagedLibraryFromPath(nativeLibFullPath);
}
}

return IntPtr.Zero;
}

private string ExpectedExtension { get; }
}
}
56 changes: 56 additions & 0 deletions src/Microsoft.Dnx.Runtime/NativeLibPathUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.IO;

namespace Microsoft.Dnx.Runtime
{
internal class NativeLibPathUtils
{
public static IEnumerable<string> GetNativeSubfolderCandidates(IRuntimeEnvironment runtimeEnvironment)
{
if (runtimeEnvironment.OperatingSystem == RuntimeOperatingSystems.Windows)
{
return PlatformServices.Default.Runtime.GetAllRuntimeIdentifiers();
}

var runtimeId = PlatformServices.Default.Runtime.GetRuntimeOsName();

return new[]
{
runtimeId,
runtimeId.Split('-')[0],
runtimeId.Split('.')[0]
};
}

public static string GetProjectNativeLibPath(string projectPath, string nativeSubfolder)
{
return Path.Combine(projectPath, "runtimes", nativeSubfolder, "native");
}

public static bool IsMatchingNativeLibrary(IRuntimeEnvironment runtimeEnvironment, string requestedFile, string actualFile)
{
if (string.Equals(requestedFile, actualFile, StringComparison.Ordinal))
{
return true;
}

if (runtimeEnvironment.OperatingSystem == RuntimeOperatingSystems.Windows)
{
return string.Equals(requestedFile, actualFile, StringComparison.OrdinalIgnoreCase) ||
string.Equals(requestedFile + ".dll", actualFile, StringComparison.OrdinalIgnoreCase);
}

if (runtimeEnvironment.OperatingSystem == RuntimeOperatingSystems.Linux)
{
return string.Equals(requestedFile + ".so", actualFile, StringComparison.Ordinal);
}

return string.Equals(requestedFile + ".dylib", actualFile, StringComparison.Ordinal);
}

}
}
17 changes: 17 additions & 0 deletions test/Microsoft.Dnx.Runtime.Tests/NativeLibPathUitlsFacts.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.


using Xunit;

namespace Microsoft.Dnx.Runtime.Tests
{
public class NativeLibPathUitlsFacts
{
[Fact]
public void test()
{

}
}
}

0 comments on commit cba17e0

Please sign in to comment.