Skip to content

Commit

Permalink
Apple.Core support for plug-ins without native libraries (apple#35)
Browse files Browse the repository at this point in the history
* Adding support for Apple Unity Plug-Ins which don't require native libraries and may or may not define a custom build step.
* Version bump
  • Loading branch information
jared-marsau authored and GitHub Enterprise committed Apr 10, 2024
1 parent 5dba688 commit f0911d8
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 53 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
# CHANGELOG
All notable changes to this project will be documented in this file.

## [3.1.0] - 2024-2-23
## [3.1.1] - 2024-04-08
### Added
- Adding support for tracking of Apple Unity plug-ins without native libraries.

## [3.1.0] - 2024-02-23
### Added
Support for visionOS

## [3.0.0] - 2024-2-15
## [3.0.0] - 2024-02-15
### Added
- Support for iPhone simulator and AppleTV Simulator
- Release builds now generate .dSYM files for enhanced debugging abilities
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,24 @@ public void ResolveBuildSteps()
}
}
}

/// <summary>
/// Find a build step based upon it's DisplayName property.
/// </summary>
/// <param name="displayName">A string which corresponds to a given build step's DisplayName property.</param>
/// <returns></returns>
public AppleBuildStep FindBuildStep(string displayName)
{
foreach (var buildStep in buildSteps.Values)
{
if (buildStep.DisplayName == displayName)
{
return buildStep;
}
}

return null;
}
}
}
#endif // (UNITY_EDITOR_OSX && (UNITY_IOS || UNITY_TVOS || UNITY_STANDALONE_OSX || UNITY_VISIONOS))
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ public class AppleBuildStep : ScriptableObject
/// </summary>
public virtual BuildTarget[] SupportedTargets => Array.Empty<BuildTarget>();

/// <summary>
/// Convenience property to determine if the plug-in has associated native libraries.
/// </summary>
public bool IsNativePlugIn => SupportedTargets.Length > 0;

/// <summary>
/// Returns an enumerable collection of all objects in the project which derive from AppleBuildStep
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,18 @@ private static void OnEditorUpdate()
// If this is one of the development Apple plug-in Unity projects, it needs to be handled as a special case because
// it isn't loaded/managed by the package manager; all of the assets are local under Assets/
// All Apple plug-ins will have an AppleBuildStep implementation, so check for build steps that haven't been added already
foreach (var buildStepEntry in _defaultProfile.buildSteps)
foreach (var buildStep in _defaultProfile.buildSteps.Values)
{
if (buildStepEntry.Value.SupportedTargets.Length > 0 && !_appleUnityPackages.ContainsKey(buildStepEntry.Value.DisplayName))
if (!_appleUnityPackages.ContainsKey(buildStep.DisplayName))
{
_appleUnityPackages[buildStepEntry.Value.DisplayName] = new AppleUnityPackage("Local Project", buildStepEntry.Value.DisplayName, Application.dataPath);
if (buildStep.IsNativePlugIn)
{
_appleUnityPackages[buildStep.DisplayName] = new AppleUnityPackage("Local Project", buildStep.DisplayName, Application.dataPath);
}
else
{
_appleUnityPackages[buildStep.DisplayName] = new AppleUnityPackage("Local Project", buildStep.DisplayName);
}
}
}

Expand Down Expand Up @@ -244,42 +251,30 @@ private static void ValidateLibraries()
{
foreach (var applePackage in _appleUnityPackages.Values)
{
bool isCurrentPlatformSupported = false;
bool isBuildStepEnabled = false;
foreach(var buildStep in _defaultProfile.buildSteps.Values)
AppleBuildStep buildStep = _defaultProfile.FindBuildStep(applePackage.DisplayName);
if (buildStep != null && buildStep.IsNativePlugIn)
{
if (buildStep.DisplayName == applePackage.DisplayName)
if (Array.IndexOf(buildStep.SupportedTargets, GetUnityBuildTarget(_trackedApplePlatform)) > -1)
{
isBuildStepEnabled = buildStep.IsEnabled;
BuildTarget unityBuildTarget = GetUnityBuildTarget(_trackedApplePlatform);
if (Array.IndexOf(buildStep.SupportedTargets, unityBuildTarget) > -1)
AppleNativeLibrary currLibrary = GetLibrary(applePackage.DisplayName, _trackedAppleConfig.Principal, _trackedApplePlatform);
if (!currLibrary.IsValid)
{
isCurrentPlatformSupported = true;
break;
string warningMessage = $"[Apple Unity Plug-Ins] Missing {_trackedAppleConfig.Principal} {applePackage.DisplayName} native library for {_trackedApplePlatform}\n"
+ $" {_trackedAppleConfig.Fallback} {applePackage.DisplayName} native library for {_trackedApplePlatform} will be used as a fallback.\n"
+ $" To generate the {_trackedAppleConfig.Principal} native library for {applePackage.DisplayName}, try re-building the {applePackage.DisplayName} plug-in with the following command line (assuming the working directory is the Apple Unity Plug-In project root folder):\n\n"
+ $" <b><color=orange>$> python3 ./build.py -p {applePackage.ShortName}</color></b>\n";

Debug.LogWarning(warningMessage);
}
}
}

if (isCurrentPlatformSupported)
{
AppleNativeLibrary currLibrary = GetLibrary(applePackage.DisplayName, _trackedAppleConfig.Principal, _trackedApplePlatform);
if (!currLibrary.IsValid)
else if (buildStep.IsEnabled)
{
string warningMessage = $"[Apple Unity Plug-Ins] Missing {_trackedAppleConfig.Principal} {applePackage.DisplayName} native library for {_trackedApplePlatform}\n"
+ $" {_trackedAppleConfig.Fallback} {applePackage.DisplayName} native library for {_trackedApplePlatform} will be used as a fallback.\n"
+ $" To generate the {_trackedAppleConfig.Principal} native library for {applePackage.DisplayName}, try re-building the {applePackage.DisplayName} plug-in with the following command line (assuming the working directory is the Apple Unity Plug-In project root folder):\n\n"
+ $" <b><color=orange>$> python3 ./build.py -p {applePackage.ShortName}</color></b>\n";
string warningMessage = $"[Apple Unity Plug-Ins] Targeting unsupported platform '{_trackedApplePlatform}' for Apple plug-in package {applePackage.DisplayName}.\n"
+ $" To continue building for the current platform, please disable {applePackage.DisplayName} in the Apple Build Settings window.";

Debug.LogWarning(warningMessage);
}
}
else if (isBuildStepEnabled)
{
string warningMessage = $"[Apple Unity Plug-Ins] Targeting unsupported platform '{_trackedApplePlatform}' for Apple plug-in package {applePackage.DisplayName}.\n"
+ $" To continue building for the current platform, please disable {applePackage.DisplayName} in the Apple Build Settings window.";

Debug.LogWarning(warningMessage);
}
}
}

Expand Down Expand Up @@ -391,10 +386,16 @@ public static AppleNativeLibrary GetLibrary(string packageDisplayName, string ap
/// <param name="packageCollection">An iterable collection of PackageInfo structs</param>
private static void AddPackagesFromCollection(IEnumerable<UnityEditor.PackageManager.PackageInfo> packageCollection, bool logPackagesAfterUpdate = true)
{
// Ensure collection of build steps is current; package names will be validated against build step names.
_defaultProfile.ResolveBuildSteps();

bool packagesAdded = false;
foreach (var unityPackage in packageCollection)
{
if (unityPackage.name.StartsWith(AppleUnityPackageNamePrefix) && unityPackage.author.name == AppleUnityPackageAuthorName && !_appleUnityPackages.ContainsKey(unityPackage.displayName))
AppleBuildStep buildStep = _defaultProfile.FindBuildStep(unityPackage.displayName);

// Apple packages with native libraries will always have a build step defined for handling those libraries, so validate here.
if (buildStep != null && buildStep.IsNativePlugIn && buildStep.DisplayName == unityPackage.displayName && unityPackage.author.name == AppleUnityPackageAuthorName && !_appleUnityPackages.ContainsKey(unityPackage.displayName))
{
AppleUnityPackage applePackage = new AppleUnityPackage(unityPackage.name, unityPackage.displayName, unityPackage.resolvedPath);
if (!applePackage.PlayModeSupportLibrary.IsValid)
Expand All @@ -407,6 +408,14 @@ private static void AddPackagesFromCollection(IEnumerable<UnityEditor.PackageMan
_appleUnityPackages[applePackage.DisplayName] = applePackage;
packagesAdded = true;
}
// If there's no build step or the build step isn't associated with a native plug-in track the library-free (C# only) package.
else if (unityPackage.name.StartsWith(AppleUnityPackageNamePrefix) && unityPackage.author.name == AppleUnityPackageAuthorName && !_appleUnityPackages.ContainsKey(unityPackage.displayName))
{
AppleUnityPackage applePackage = new AppleUnityPackage(unityPackage.name, unityPackage.displayName);
_appleUnityPackages[applePackage.DisplayName] = applePackage;
packagesAdded = true;
}

}

if (packagesAdded && logPackagesAfterUpdate)
Expand Down Expand Up @@ -471,35 +480,42 @@ private static void SyncronizePlayModeSupportLibraries()
/// </summary>
private static void LogLibrarySummary()
{
string summary = "[Apple Unity Plug-ins] Apple native plug-ins updated.\nTracking the following plug-in packages and native libraries:\n\n";
string summary = "[Apple Unity Plug-ins] Apple native plug-ins updated.\nTracking the following plug-in packages and native libraries:\n";
bool librariesFound = false;
foreach (AppleUnityPackage package in _appleUnityPackages.Values)
{
summary += $"\n<b>{package.DisplayName}</b> [{package.Name}]:\n Package Source Path: {package.SourcePath}\n";
var debugLibraries = package.GetLibraries(AppleConfigID.Debug);
if (debugLibraries.Length > 0)
if (package.IsNativePackage)
{
summary += " Debug Libraries (file name - platform):\n";
foreach (var debugLibrary in debugLibraries)
summary += $"\n<b>{package.DisplayName}</b> [{package.Name}]:\n Package Source Path: {package.SourcePath}\n";
var debugLibraries = package.GetLibraries(AppleConfigID.Debug);
if (debugLibraries.Length > 0)
{
summary += $" {debugLibrary.FileName} - {debugLibrary.Platform}\n";
summary += " Debug Libraries (file name - platform):\n";
foreach (var debugLibrary in debugLibraries)
{
summary += $" {debugLibrary.FileName} - {debugLibrary.Platform}\n";
}
librariesFound = true;
}
librariesFound = true;
}

var releaseLibraries = package.GetLibraries(AppleConfigID.Release);
if (releaseLibraries.Length > 0)
{
summary += " Release Libraries (file name - platform):\n";
foreach (var releaseLibrary in releaseLibraries)
var releaseLibraries = package.GetLibraries(AppleConfigID.Release);
if (releaseLibraries.Length > 0)
{
summary += $" {releaseLibrary.FileName} - {releaseLibrary.Platform}\n";
if (releaseLibrary.DebugSymbolsFileName != string.Empty)
summary += " Release Libraries (file name - platform):\n";
foreach (var releaseLibrary in releaseLibraries)
{
summary += $" {releaseLibrary.DebugSymbolsFileName} - {releaseLibrary.Platform}\n";
summary += $" {releaseLibrary.FileName} - {releaseLibrary.Platform}\n";
if (releaseLibrary.DebugSymbolsFileName != string.Empty)
{
summary += $" {releaseLibrary.DebugSymbolsFileName} - {releaseLibrary.Platform}\n";
}
}
librariesFound = true;
}
librariesFound = true;
}
else
{
summary += $"\n<b>{package.DisplayName}</b> [{package.Name}]:\n Non-native (C# Script or asset only) plug-in/extension.\n <b>No libraries to list.</b>\n";
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Apple.Core
{
public class AppleSecurityBuildStep : AppleBuildStep
{
public override string DisplayName => "Security";
public override string DisplayName => "Apple.Core.Security";

[Tooltip("If true, will add the com.apple.security.app-sandbox entitlement.")]
public bool AppSandboxEntitlement = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public AppleUnityPackage(string name, string displayName, string packageSystemPa
DisplayName = displayName;
PlayModeSupportLibrary = AppleNativeLibrary.Invalid;
SourcePath = packageSystemPath;
IsNativePackage = true;

_nativeLibraryCollection = new Dictionary<string, Dictionary<string, AppleNativeLibrary>>();

Expand Down Expand Up @@ -97,6 +98,22 @@ public AppleUnityPackage(string name, string displayName, string packageSystemPa
}
}

/// <summary>
/// Create a package with default values to act as a representation of a package without native libraries.
/// </summary>
/// <param name="name">Matches the 'name' field of the associated package's <c>package.json</c> file. Should be of the form <c>com.apple.unityplugin.XXX</c>.</param>
/// <param name="displayName">Matches the 'displayName' field of the associated package's <c>package.json</c> file</param>
public AppleUnityPackage(string name, string displayName)
{
Name = name;
DisplayName = displayName;
IsNativePackage = false;

PlayModeSupportLibrary = AppleNativeLibrary.Invalid;
SourcePath = string.Empty;
_nativeLibraryCollection = new Dictionary<string, Dictionary<string, AppleNativeLibrary>>();
}

/// <summary>
/// Matches the 'name' field of the associated package's <c>package.json</c> file.
/// </summary>
Expand Down Expand Up @@ -129,6 +146,11 @@ public AppleUnityPackage(string name, string displayName, string packageSystemPa
/// Records the source of the package in the local file system.
/// </summary>
public string SourcePath { get; private set; }

/// <summary>
/// True when this package references native libraries.
/// </summary>
public bool IsNativePackage { get; private set; }

/// <summary>
/// Helper will get an AppleNativeLibrary for the provided config and platform combination, returning an invalid AppleNativeLibrary if none exists.
Expand All @@ -152,6 +174,11 @@ public AppleNativeLibrary GetLibrary(string appleConfig, string applePlatform)
/// <returns>The flattened array of AppleNativeLibrary elements for this package.</returns>
public AppleNativeLibrary[] GetLibraries(string appleConfig = "")
{
if (!IsNativePackage)
{
return Array.Empty<AppleNativeLibrary>();
}

List<AppleNativeLibrary> libraries = new List<AppleNativeLibrary>();
if (appleConfig == AppleConfigID.Debug || appleConfig == AppleConfigID.Release)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Apple.Core
{
public class AppleUserManagementBuildStep : AppleBuildStep
{
public override string DisplayName => "tvOS User Management";
public override string DisplayName => "Apple.Core.UserManagementForAppleTV";

[Tooltip("The value that grants access to TVUserManager, so you can map your own profiles to users in the system.")]
public bool AllowGetCurrentUser = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "com.apple.unityplugin.core",
"displayName": "Apple.Core",
"description": "Provides project settings, post-build automation tools, and other shared functionality for Apple Unity Plug-ins.",
"version": "3.1.0",
"version": "3.1.1",
"unity": "2022.3",
"keywords": [
"apple"
Expand Down

0 comments on commit f0911d8

Please sign in to comment.