Example #1
0
        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);
        }
Example #2
0
        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());
        }
Example #3
0
        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());
        }
Example #4
0
        public override bool Execute()
        {
            var prefixes        = BundleResource.SplitResourcePrefixes(ResourcePrefix);
            var intermediate    = Path.Combine(IntermediateOutputPath, ToolName);
            var bundleResources = new List <ITaskItem> ();

            foreach (var input in EnumerateInputs())
            {
                var       relative = GetBundleRelativeOutputPath(prefixes, input);
                ITaskItem output;

                if (!string.IsNullOrEmpty(relative))
                {
                    string illegal;

                    if (BundleResource.IsIllegalName(relative, out illegal))
                    {
                        Log.LogError(null, null, null, input.ItemSpec, 0, 0, 0, 0, "The name '{0}' is reserved and cannot be used.", illegal);
                        continue;
                    }

                    var rpath = Path.Combine(intermediate, relative);

                    output = new TaskItem(rpath);
                }
                else
                {
                    output = new TaskItem(intermediate);
                }

                output.SetMetadata("LogicalName", relative);

                if (NeedsBuilding(input, output))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(output.ItemSpec));

                    if (ExecuteTool(input, output) == -1)
                    {
                        return(false);
                    }
                }

                bundleResources.AddRange(GetCompiledBundleResources(input, output));
            }

            BundleResources = bundleResources.ToArray();

            return(!Log.HasLoggedErrors);
        }
Example #5
0
        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);
        }
Example #11
0
        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);
        }
Example #12
0
        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);
        }