Skip to content

Commit

Permalink
feat: Add support for native runtimes #419
Browse files Browse the repository at this point in the history
  • Loading branch information
robin-moss committed Oct 28, 2021
1 parent 0057044 commit 0e1c479
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 7 deletions.
92 changes: 86 additions & 6 deletions Assets/NuGet/Editor/NugetHelper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace NugetForUnity
using System.Reflection;

namespace NugetForUnity
{
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -379,10 +381,6 @@ private static void Clean(NugetPackageIdentifier package)
// For now, delete src. We may use it later...
DeleteDirectory(packageInstallDirectory + "/src");

// Since we don't automatically fix up the runtime dll platforms, remove them until we improve support
// for this newer feature of nuget packages.
DeleteDirectory(Path.Combine(packageInstallDirectory, "runtimes"));

// Delete documentation folders since they sometimes have HTML docs with JavaScript, which Unity tried to parse as "UnityScript"
DeleteDirectory(packageInstallDirectory + "/docs");

Expand Down Expand Up @@ -1281,6 +1279,81 @@ public static void LogVerbose(string format, params object[] args)
}
}

private static Dictionary<string, List<BuildTarget>> TargetRuntimes =
new Dictionary<string, List<BuildTarget>>()
{
{"win7-x64", new List<BuildTarget> {BuildTarget.StandaloneWindows64}},
{"win7-x86", new List<BuildTarget> {BuildTarget.StandaloneWindows}},
{"win-x64", new List<BuildTarget> {BuildTarget.StandaloneWindows64}},
{"win-x86", new List<BuildTarget> {BuildTarget.StandaloneWindows}},
{"linux-x64", new List<BuildTarget> {BuildTarget.StandaloneLinux64}},
{"osx-x64", new List<BuildTarget> {BuildTarget.StandaloneOSX}},
};

private static List<BuildTarget> NotObsoleteBuildTargets = typeof(BuildTarget)
.GetFields(BindingFlags.Public | BindingFlags.Static)
.Where(fieldInfo => fieldInfo.GetCustomAttribute(typeof(ObsoleteAttribute)) == null)
.Select(fieldInfo => (BuildTarget) fieldInfo.GetValue(null))
.ToList();

/// <summary>
/// Import and set compatability on native files within the runtimes folder of a NuGet package.
/// </summary>
/// <param name="package">Package to process</param>
/// <param name="runtimeDirectory">NuGet packages runtimes folder</param>
private static void HandleRuntimes(NugetPackageIdentifier package, string runtimeDirectory)
{
var runtimes = Directory.GetDirectories(runtimeDirectory);

foreach (var runtimeDir in runtimes)
{
var platform = new DirectoryInfo(runtimeDir).Name;

if (!TargetRuntimes.ContainsKey(platform))
{
LogVerbose("Runtime {0} of package {1} is not supported", platform, package);
Directory.Delete(runtimeDir, true);
continue;
}

var compatibleTargets = TargetRuntimes[platform];
var incompatibleTargets = NotObsoleteBuildTargets.Except(compatibleTargets).ToList();

var nativeFiles = Directory.GetFiles(Path.Combine(runtimeDir, "native"));
foreach (var nativeFile in nativeFiles)
{
var projectRelativePath =
nativeFile.Substring(new DirectoryInfo(Application.dataPath).Parent.FullName.Length + 1);
AssetDatabase.ImportAsset(projectRelativePath, ImportAssetOptions.ForceSynchronousImport);
PluginImporter plugin = AssetImporter.GetAtPath(projectRelativePath) as PluginImporter;

if (plugin == null)
{
Debug.LogWarning(string.Format("Native file {0} of package {1} failed to import", nativeFile,
package));
continue;
}

LogVerbose("Runtime {0} of package {1} compatability set to {2}", platform, package,
string.Join(",", compatibleTargets));
plugin.SetCompatibleWithAnyPlatform(false);
incompatibleTargets.ForEach(target => plugin.SetExcludeFromAnyPlatform(target, true));
compatibleTargets.ForEach(target => plugin.SetExcludeFromAnyPlatform(target, false));

incompatibleTargets.ForEach(target => plugin.SetCompatibleWithPlatform(target, false));
compatibleTargets.ForEach(target => plugin.SetCompatibleWithPlatform(target, true));


if (compatibleTargets.Count == 0)
{
plugin.SetExcludeEditorFromAnyPlatform(true);
}

plugin.SaveAndReimport();
}
}
}

/// <summary>
/// Installs the given package.
/// </summary>
Expand Down Expand Up @@ -1392,9 +1465,9 @@ public static bool Install(NugetPackage package, bool refreshAssets = true)
EditorUtility.DisplayProgressBar(string.Format("Installing {0} {1}", package.Id, package.Version), "Extracting Package", 0.6f);
}

string baseDirectory = Path.Combine(NugetConfigFile.RepositoryPath, string.Format("{0}.{1}", package.Id, package.Version));
if (File.Exists(cachedPackagePath))
{
string baseDirectory = Path.Combine(NugetConfigFile.RepositoryPath, string.Format("{0}.{1}", package.Id, package.Version));

// unzip the package
using (ZipArchive zip = ZipFile.OpenRead(cachedPackagePath))
Expand Down Expand Up @@ -1429,6 +1502,13 @@ public static bool Install(NugetPackage package, bool refreshAssets = true)
EditorUtility.DisplayProgressBar(string.Format("Installing {0} {1}", package.Id, package.Version), "Cleaning Package", 0.9f);
}

var runtimeDirectory = Path.Combine(baseDirectory, "runtimes");
if (Directory.Exists(runtimeDirectory))
{
LogVerbose("Package {0} has a runtime folder", package);
HandleRuntimes(package, runtimeDirectory);
}

// clean
Clean(package);

Expand Down
37 changes: 36 additions & 1 deletion Assets/Tests/Editor/NuGetTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
using NUnit.Framework;
using System;
using NUnit.Framework;
using NugetForUnity;
using System.IO;
using System.Runtime.InteropServices;
using UnityEditor;
using UnityEngine;
using Object = System.Object;

public class NuGetTests
{
Expand Down Expand Up @@ -53,6 +57,37 @@ public void InstallProtobufTest()
Assert.IsFalse(NugetHelper.IsInstalled(protobuf), "The package is STILL installed: {0} {1}", protobuf.Id, protobuf.Version);
}

[Test]
public void InstallAndRunSqlite()
{
var sqlite = new NugetPackageIdentifier("SQLite.Native", "3.12.3");
try
{
// install the package
NugetHelper.InstallIdentifier(sqlite);
Assert.IsTrue(NugetHelper.IsInstalled(sqlite), "The package was NOT installed: {0} {1}", sqlite.Id,
sqlite.Version);

// Test the runtime
var version = Marshal.PtrToStringAuto(sqlite3_libversion());
Assert.That(version, Is.EqualTo(sqlite.Version));
}
finally
{
// uninstall the package
NugetHelper.UninstallAll();
Assert.IsFalse(NugetHelper.IsInstalled(sqlite), "The packages are STILL installed: {0} {1}", sqlite.Id,
sqlite.Version);
}
}

/// <summary>
/// Call to the SQLite native file
/// </summary>
/// <returns></returns>
[DllImport("sqlite3")]
private static extern IntPtr sqlite3_libversion();

[Test]
public void InstallBootstrapCSSTest()
{
Expand Down

0 comments on commit 0e1c479

Please sign in to comment.