protected override string GenerateCommandLineCommands() { var prefixes = BundleResource.SplitResourcePrefixes(ResourcePrefix); var intermediate = Path.Combine(IntermediateOutputPath, ToolName); var logicalName = BundleResource.GetLogicalName(ProjectDir, prefixes, SourceFile, !string.IsNullOrEmpty(SessionId)); var path = Path.Combine(intermediate, logicalName); var args = new ProcessArgumentBuilder(); var dir = Path.GetDirectoryName(path); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } OutputFile = new TaskItem(Path.ChangeExtension(path, ".air")); OutputFile.SetMetadata("LogicalName", Path.ChangeExtension(logicalName, ".air")); args.Add("-arch", "air64"); args.Add("-emit-llvm"); args.Add("-c"); args.Add("-gline-tables-only"); args.Add("-ffast-math"); args.Add(string.Format("-std={0}-metal1.0", OperatingSystem)); args.Add("-serialize-diagnostics"); args.AddQuoted(Path.ChangeExtension(path, ".dia")); args.Add("-o"); args.AddQuoted(Path.ChangeExtension(path, ".air")); args.AddQuoted(SourceFile.ItemSpec); return(args.ToString()); }
public override bool Execute() { Log.LogTaskName("FindItemWithLogicalName"); Log.LogTaskProperty("Items", Items); Log.LogTaskProperty("LogicalName", LogicalName); Log.LogTaskProperty("ProjectDir", ProjectDir); Log.LogTaskProperty("ResourcePrefix", ResourcePrefix); if (Items != null) { var prefixes = BundleResource.SplitResourcePrefixes(ResourcePrefix); foreach (var item in Items) { var logical = BundleResource.GetLogicalName(ProjectDir, prefixes, item); if (logical == LogicalName) { Log.LogMessage(MessageImportance.Low, " {0} found at: {1}", LogicalName, item.ItemSpec); Item = item; break; } } } return(!Log.HasLoggedErrors); }
protected override string GenerateCommandLineCommands() { var prefixes = BundleResource.SplitResourcePrefixes(ResourcePrefix); var intermediate = Path.Combine(IntermediateOutputPath, ToolName); var logicalName = BundleResource.GetLogicalName(ProjectDir, prefixes, SourceFile, !string.IsNullOrEmpty(SessionId)); var path = Path.Combine(intermediate, logicalName); var args = new CommandLineArgumentBuilder(); var dir = Path.GetDirectoryName(path); string minimumDeploymentTarget; if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } if (AppManifest != null) { var plist = PDictionary.FromFile(AppManifest.ItemSpec); PString value; if (!plist.TryGetValue(MinimumDeploymentTargetKey, out value) || string.IsNullOrEmpty(value.Value)) { minimumDeploymentTarget = SdkVersion; } else { minimumDeploymentTarget = value.Value; } } else { minimumDeploymentTarget = SdkVersion; } OutputFile = new TaskItem(Path.ChangeExtension(path, ".air")); OutputFile.SetMetadata("LogicalName", Path.ChangeExtension(logicalName, ".air")); args.Add("-arch", "air64"); args.Add("-emit-llvm"); args.Add("-c"); args.Add("-gline-tables-only"); args.Add("-ffast-math"); args.Add("-serialize-diagnostics"); args.AddQuoted(Path.ChangeExtension(path, ".dia")); args.Add("-o"); args.AddQuoted(Path.ChangeExtension(path, ".air")); args.Add(string.Format("-m{0}-version-min={1}", OperatingSystem, minimumDeploymentTarget)); args.AddQuoted(SourceFile.ItemSpec); return(args.ToString()); }
protected override string GenerateCommandLineCommands() { var prefixes = BundleResource.SplitResourcePrefixes(ResourcePrefix); var intermediate = Path.Combine(IntermediateOutputPath, ToolName); var logicalName = BundleResource.GetLogicalName(ProjectDir, prefixes, SourceFile, !string.IsNullOrEmpty(SessionId)); var path = Path.Combine(intermediate, logicalName); var args = new CommandLineArgumentBuilder(); var dir = Path.GetDirectoryName(path); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } OutputFile = new TaskItem(Path.ChangeExtension(path, ".air")); OutputFile.SetMetadata("LogicalName", Path.ChangeExtension(logicalName, ".air")); args.Add("-arch", "air64"); args.Add("-emit-llvm"); args.Add("-c"); args.Add("-gline-tables-only"); args.Add("-ffast-math"); args.Add("-serialize-diagnostics"); args.AddQuoted(Path.ChangeExtension(path, ".dia")); args.Add("-o"); args.AddQuoted(Path.ChangeExtension(path, ".air")); if (Platform == ApplePlatform.MacCatalyst) { args.Add($"-target"); args.Add($"air64-apple-ios{MinimumOSVersion}-macabi"); } else { args.Add(PlatformFrameworkHelper.GetMinimumVersionArgument(TargetFrameworkMoniker, SdkIsSimulator, MinimumOSVersion)); } args.AddQuoted(SourceFile.ItemSpec); return(args.ToString()); }
public override bool Execute() { if (Items != null) { var prefixes = BundleResource.SplitResourcePrefixes(ResourcePrefix); foreach (var item in Items) { var logical = BundleResource.GetLogicalName(ProjectDir, prefixes, item, !string.IsNullOrEmpty(SessionId)); if (logical == LogicalName) { Log.LogMessage(MessageImportance.Low, " {0} found at: {1}", LogicalName, item.ItemSpec); Item = item; break; } } } return(!Log.HasLoggedErrors); }
public override bool Execute() { Log.LogTaskName("CompileSceneKitAssets"); Log.LogTaskProperty("IntermediateOutputPath", IntermediateOutputPath); Log.LogTaskProperty("ProjectDir", ProjectDir); Log.LogTaskProperty("ResourcePrefix", ResourcePrefix); Log.LogTaskProperty("SceneKitAssets", SceneKitAssets); Log.LogTaskProperty("SdkDevPath", SdkDevPath); Log.LogTaskProperty("SdkRoot", SdkRoot); Log.LogTaskProperty("SdkVersion", SdkVersion); var prefixes = BundleResource.SplitResourcePrefixes(ResourcePrefix); var intermediate = Path.Combine(IntermediateOutputPath, ToolName); var bundleResources = new List <ITaskItem> (); var modified = new HashSet <string> (); var items = new List <ITaskItem> (); string metadata; foreach (var asset in SceneKitAssets) { if (!File.Exists(asset.ItemSpec)) { continue; } // get the .scnassets directory path var scnassets = Path.GetDirectoryName(asset.ItemSpec); while (scnassets.Length > 0 && Path.GetExtension(scnassets).ToLowerInvariant() != ".scnassets") { scnassets = Path.GetDirectoryName(scnassets); } if (scnassets.Length == 0) { continue; } metadata = asset.GetMetadata("LogicalName"); if (!string.IsNullOrEmpty(metadata)) { asset.SetMetadata("LogicalName", string.Empty); } var bundleName = BundleResource.GetLogicalName(ProjectDir, prefixes, asset, !string.IsNullOrEmpty(SessionId)); var output = new TaskItem(Path.Combine(intermediate, bundleName)); if (!modified.Contains(scnassets) && (!File.Exists(output.ItemSpec) || File.GetLastWriteTimeUtc(asset.ItemSpec) > File.GetLastWriteTimeUtc(output.ItemSpec))) { var item = new TaskItem(scnassets); metadata = asset.GetMetadata("DefiningProjectFullPath"); if (!string.IsNullOrEmpty(metadata)) { item.SetMetadata("DefiningProjectFullPath", metadata); } modified.Add(scnassets); items.Add(item); } output.SetMetadata("LogicalName", bundleName); output.SetMetadata("Optimize", "false"); bundleResources.Add(output); } if (modified.Count == 0) { BundleResources = bundleResources.ToArray(); return(!Log.HasLoggedErrors); } if (!Directory.Exists(intermediate)) { Directory.CreateDirectory(intermediate); } foreach (var item in items) { var bundleDir = BundleResource.GetLogicalName(ProjectDir, prefixes, new TaskItem(item), !string.IsNullOrEmpty(SessionId)); var output = Path.Combine(intermediate, bundleDir); if (CopySceneKitAssets(item.ItemSpec, output, intermediate) == -1) { return(false); } } BundleResources = bundleResources.ToArray(); return(!Log.HasLoggedErrors); }
void RegisterFonts(PDictionary plist) { if (FontFilesToRegister == null || FontFilesToRegister.Length == 0) { return; } // https://developer.apple.com/documentation/swiftui/applying-custom-fonts-to-text // Compute the relative location in the app bundle for each font file var prefixes = BundleResource.SplitResourcePrefixes(ResourcePrefix); const string logicalNameKey = "_ComputedLogicalName_"; foreach (var item in FontFilesToRegister) { var logicalName = BundleResource.GetLogicalName(ProjectDir, prefixes, item, !string.IsNullOrEmpty(SessionId)); item.SetMetadata(logicalNameKey, logicalName); } switch (Platform) { case ApplePlatform.iOS: case ApplePlatform.TVOS: case ApplePlatform.WatchOS: case ApplePlatform.MacCatalyst: // Fonts are listed in the Info.plist in a UIAppFonts entry for iOS, tvOS, watchOS and Mac Catalyst. var uiAppFonts = plist.GetArray("UIAppFonts"); if (uiAppFonts == null) { uiAppFonts = new PArray(); plist ["UIAppFonts"] = uiAppFonts; } foreach (var item in FontFilesToRegister) { uiAppFonts.Add(new PString(item.GetMetadata(logicalNameKey))); } break; case ApplePlatform.MacOSX: // The directory where the fonts are located is in the Info.plist in the ATSApplicationFontsPath entry for macOS. // It's relative to the Resources directory. // Make sure that all the fonts are in the same directory in the app bundle var allSubdirectories = FontFilesToRegister.Select(v => Path.GetDirectoryName(v.GetMetadata(logicalNameKey))); var distinctSubdirectories = allSubdirectories.Distinct().ToArray(); if (distinctSubdirectories.Length > 1) { Log.LogError(MSBStrings.E7083 /* "All font files must be located in the same directory in the app bundle. The following font files have different target directories in the app bundle:" */, CompiledAppManifest.ItemSpec); foreach (var fonts in FontFilesToRegister) { Log.LogError(null, null, null, fonts.ItemSpec, 0, 0, 0, 0, MSBStrings.E7084 /* "The target directory is {0}" */, fonts.GetMetadata(logicalNameKey)); } } else { plist.SetIfNotPresent("ATSApplicationFontsPath", string.IsNullOrEmpty(distinctSubdirectories [0]) ? "." : distinctSubdirectories [0]); } break; default: throw new InvalidOperationException(string.Format(MSBStrings.InvalidPlatform, Platform)); } }
public override bool Execute() { var coremlcOutputDir = Path.Combine(IntermediateOutputPath, "coremlc"); var prefixes = BundleResource.SplitResourcePrefixes(ResourcePrefix); var mapping = new Dictionary <string, IDictionary> (); var bundleResources = new List <ITaskItem> (); var partialPlists = new List <ITaskItem> (); if (Models.Length > 0) { Directory.CreateDirectory(coremlcOutputDir); foreach (var model in Models) { var logicalName = BundleResource.GetLogicalName(ProjectDir, prefixes, model, !string.IsNullOrEmpty(SessionId)); var bundleName = GetPathWithoutExtension(logicalName) + ".mlmodelc"; var outputPath = Path.Combine(coremlcOutputDir, bundleName); var outputDir = Path.GetDirectoryName(outputPath); var partialPlist = GetPathWithoutExtension(outputPath) + "-partial.plist"; var log = GetPathWithoutExtension(outputPath) + ".log"; var resourceTags = model.GetMetadata("ResourceTags"); var output = new TaskItem(outputPath); output.SetMetadata("LogicalName", bundleName); output.SetMetadata("Optimize", "false"); if (EnableOnDemandResources && !string.IsNullOrEmpty(resourceTags)) { output.SetMetadata("ResourceTags", resourceTags); } var metadata = output.CloneCustomMetadata(); mapping[outputPath + "/"] = metadata; if (FileChanged(model, partialPlist)) { Directory.CreateDirectory(outputDir); if ((Compile(model, outputDir, log, partialPlist)) != 0) { return(false); } } else { Log.LogMessage(MessageImportance.Low, "Skipping `{0}' as the output file, `{1}', is newer.", model.ItemSpec, partialPlist); } } bundleResources.AddRange(GetCompiledOutput(coremlcOutputDir, mapping)); foreach (var path in Directory.EnumerateFiles(coremlcOutputDir, "*-partial.plist", SearchOption.AllDirectories)) { partialPlists.Add(new TaskItem(path)); } } BundleResources = bundleResources.ToArray(); PartialAppManifests = partialPlists.ToArray(); return(!Log.HasLoggedErrors); }
public override bool Execute() { var prefixes = BundleResource.SplitResourcePrefixes(ResourcePrefix); var intermediate = Path.Combine(IntermediateOutputPath, ToolName); var bundleResources = new List <ITaskItem> (); var modified = new HashSet <string> (); var items = new List <ITaskItem> (); string metadata; foreach (var asset in SceneKitAssets) { if (!File.Exists(asset.ItemSpec)) { continue; } // get the .scnassets directory path var scnassets = Path.GetDirectoryName(asset.ItemSpec); while (scnassets.Length > 0 && Path.GetExtension(scnassets).ToLowerInvariant() != ".scnassets") { scnassets = Path.GetDirectoryName(scnassets); } if (scnassets.Length == 0) { continue; } metadata = asset.GetMetadata("LogicalName"); if (!string.IsNullOrEmpty(metadata)) { asset.SetMetadata("LogicalName", string.Empty); } var bundleName = BundleResource.GetLogicalName(ProjectDir, prefixes, asset, !string.IsNullOrEmpty(SessionId)); var output = new TaskItem(Path.Combine(intermediate, bundleName)); if (!modified.Contains(scnassets) && (!File.Exists(output.ItemSpec) || File.GetLastWriteTimeUtc(asset.ItemSpec) > File.GetLastWriteTimeUtc(output.ItemSpec))) { // Base the new item on @asset, to get the `DefiningProject*` metadata too var scnassetsItem = new TaskItem(asset); // .. but we really want it to be for @scnassets, so set ItemSpec accordingly scnassetsItem.ItemSpec = scnassets; // .. and remove the @OriginalItemSpec which is for @asset scnassetsItem.RemoveMetadata("OriginalItemSpec"); var assetMetadata = asset.GetMetadata("DefiningProjectFullPath"); if (assetMetadata != scnassetsItem.GetMetadata("DefiningProjectFullPath")) { // xbuild doesn't set this, so we'll do it // // `DefiningProjectFullPath` is a reserved metadata for msbuild, so // setting this is not allowed anyway scnassetsItem.SetMetadata("DefiningProjectFullPath", assetMetadata); } modified.Add(scnassets); items.Add(scnassetsItem); } output.SetMetadata("LogicalName", bundleName); output.SetMetadata("Optimize", "false"); bundleResources.Add(output); } if (modified.Count == 0) { BundleResources = bundleResources.ToArray(); return(!Log.HasLoggedErrors); } if (!Directory.Exists(intermediate)) { Directory.CreateDirectory(intermediate); } foreach (var item in items) { var bundleDir = BundleResource.GetLogicalName(ProjectDir, prefixes, new TaskItem(item), !string.IsNullOrEmpty(SessionId)); var output = Path.Combine(intermediate, bundleDir); if (CopySceneKitAssets(item.ItemSpec, output, intermediate) == -1) { return(false); } } BundleResources = bundleResources.ToArray(); return(!Log.HasLoggedErrors); }
protected virtual string GetBundleRelativeOutputPath(IList <string> prefixes, ITaskItem input) { return(BundleResource.GetLogicalName(ProjectDir, prefixes, input, !string.IsNullOrEmpty(SessionId))); }
public override bool Execute() { var prefixes = BundleResource.SplitResourcePrefixes(ResourcePrefix); var bundleResources = new List <ITaskItem> (); if (BundleResources != null) { foreach (var item in BundleResources) { var logicalName = BundleResource.GetLogicalName(ProjectDir, prefixes, item, !string.IsNullOrEmpty(SessionId)); // We need a physical path here, ignore the Link element var path = item.GetMetadata("FullPath"); string illegal; if (!File.Exists(path)) { Log.LogError(" Bundle Resource '{0}' not found on disk (should be at '{1}')", logicalName, path); continue; } if (logicalName.StartsWith(".." + Path.DirectorySeparatorChar, StringComparison.Ordinal)) { Log.LogError(null, null, null, item.ItemSpec, 0, 0, 0, 0, "The path '{0}' would result in a file outside of the app bundle and cannot be used.", logicalName); continue; } if (logicalName == "Info.plist") { Log.LogWarning(null, null, null, item.ItemSpec, 0, 0, 0, 0, "Info.plist files should have a Build Action of 'None'."); continue; } if (BundleResource.IsIllegalName(logicalName, out illegal)) { Log.LogError(null, null, null, item.ItemSpec, 0, 0, 0, 0, "The name '{0}' is reserved and cannot be used.", illegal); continue; } var bundleResource = new TaskItem(item); bundleResource.SetMetadata("LogicalName", logicalName); bool optimize = false; if (CanOptimize(item.ItemSpec)) { var metadata = item.GetMetadata("Optimize"); // fall back to old metadata name if (string.IsNullOrEmpty(metadata)) { metadata = item.GetMetadata("OptimizeImage"); } if (string.IsNullOrEmpty(metadata) || !bool.TryParse(metadata, out optimize)) { switch (Path.GetExtension(item.ItemSpec).ToLowerInvariant()) { case ".plist": case ".strings": optimize = OptimizePropertyLists; break; case ".png": optimize = OptimizePNGs; break; } } } bundleResource.SetMetadata("Optimize", optimize.ToString()); bundleResources.Add(bundleResource); } } BundleResourcesWithLogicalNames = bundleResources.ToArray(); return(!Log.HasLoggedErrors); }
protected virtual string GetBundleRelativeOutputPath(IList <string> prefixes, ITaskItem input) { return(BundleResource.GetLogicalName(ProjectDir, prefixes, input)); }
public override bool Execute() { var prefixes = BundleResource.SplitResourcePrefixes(ResourcePrefix); var bundleResources = new List <ITaskItem> (); if (BundleResources != null) { foreach (var item in BundleResources) { // Skip anything with the PublishFolderType metadata, these are copied directly to the ResolvedFileToPublish item group instead. var publishFolderType = item.GetMetadata("PublishFolderType"); if (!string.IsNullOrEmpty(publishFolderType)) { continue; } var logicalName = BundleResource.GetLogicalName(ProjectDir, prefixes, item, !string.IsNullOrEmpty(SessionId)); // We need a physical path here, ignore the Link element var path = item.GetMetadata("FullPath"); string illegal; if (!File.Exists(path)) { Log.LogError(MSBStrings.E0099, logicalName, path); continue; } if (logicalName.StartsWith(".." + Path.DirectorySeparatorChar, StringComparison.Ordinal)) { Log.LogError(null, null, null, item.ItemSpec, 0, 0, 0, 0, MSBStrings.E0100, logicalName); continue; } if (logicalName == "Info.plist") { Log.LogWarning(null, null, null, item.ItemSpec, 0, 0, 0, 0, MSBStrings.E0101); continue; } if (BundleResource.IsIllegalName(logicalName, out illegal)) { Log.LogError(null, null, null, item.ItemSpec, 0, 0, 0, 0, MSBStrings.E0102, illegal); continue; } var bundleResource = new TaskItem(item); bundleResource.SetMetadata("LogicalName", logicalName); bool optimize = false; if (CanOptimize(item.ItemSpec)) { var metadata = item.GetMetadata("Optimize"); // fall back to old metadata name if (string.IsNullOrEmpty(metadata)) { metadata = item.GetMetadata("OptimizeImage"); } if (string.IsNullOrEmpty(metadata) || !bool.TryParse(metadata, out optimize)) { switch (Path.GetExtension(item.ItemSpec).ToLowerInvariant()) { case ".plist": case ".strings": optimize = OptimizePropertyLists; break; case ".png": optimize = OptimizePNGs; break; } } } bundleResource.SetMetadata("Optimize", optimize.ToString()); bundleResources.Add(bundleResource); } } BundleResourcesWithLogicalNames = bundleResources.ToArray(); return(!Log.HasLoggedErrors); }