Пример #1
0
        public override bool Execute()
        {
            PDictionary plist = null;

            if (!string.IsNullOrEmpty(AppManifest?.ItemSpec))
            {
                try {
                    plist = PDictionary.FromFile(AppManifest.ItemSpec);
                } catch (Exception ex) {
                    Log.LogError(null, null, null, AppManifest, 0, 0, 0, 0, MSBStrings.E0010, AppManifest, ex.Message);
                    return(false);
                }
            }

            var minimumOSVersionInManifest = plist?.Get <PString> (PlatformFrameworkHelper.GetMinimumOSVersionKey(Platform))?.Value;

            if (string.IsNullOrEmpty(minimumOSVersionInManifest))
            {
                MinimumOSVersion = SdkVersion;
            }
            else if (!IAppleSdkVersion_Extensions.TryParse(minimumOSVersionInManifest, out var _))
            {
                Log.LogError(null, null, null, AppManifest, 0, 0, 0, 0, MSBStrings.E0011, minimumOSVersionInManifest);
                return(false);
            }
            else
            {
                MinimumOSVersion = minimumOSVersionInManifest;
            }

            return(true);
        }
Пример #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 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"));

            args.Add(PlatformFrameworkHelper.GetMinimumVersionArgument(TargetFrameworkMoniker, SdkIsSimulator, MinimumOSVersion));

            args.AddQuoted(SourceFile.ItemSpec);

            return(args.ToString());
        }
        protected string ResolveXCFramework(string xcframework)
        {
            var platformName = PlatformFrameworkHelper.GetOperatingSystem(TargetFrameworkMoniker);

            // PlatformFrameworkHelper.GetOperatingSystem returns "osx" which does not work for xcframework
            if (platformName == "osx")
            {
                platformName = "macos";
            }

            var variant = SdkIsSimulator ? "simulator" : null;

            try {
                var plist = PDictionary.FromFile(Path.Combine(xcframework, "Info.plist"));
                var dir   = ResolveXCFramework(plist, platformName, variant, Architectures);
                if (!String.IsNullOrEmpty(dir))
                {
                    return(Path.Combine(xcframework, dir));
                }

                // either the format was incorrect or we could not find a matching framework
                // note: last part is not translated since it match the (non-translated) keys inside the `Info.plist`
                var msg = (dir == null) ? MSBStrings.E0174 : MSBStrings.E0175 + $" SupportedPlatform: '{platformName}', SupportedPlatformVariant: '{variant}', SupportedArchitectures: '{Architectures}'.";
                Log.LogError(msg, xcframework);
            }
            catch (Exception) {
                Log.LogError(MSBStrings.E0174, xcframework);
            }
            return(null);
        }
Пример #4
0
        protected string?ResolveXCFramework(string xcframework)
        {
            string platformName;

            switch (Platform)
            {
            case Utils.ApplePlatform.MacCatalyst:
                platformName = "ios";
                break;

            case Utils.ApplePlatform.MacOSX:
                // PlatformFrameworkHelper.GetOperatingSystem returns "osx" which does not work for xcframework
                platformName = "macos";
                break;

            default:
                platformName = PlatformFrameworkHelper.GetOperatingSystem(TargetFrameworkMoniker);
                break;
            }

            string?variant = null;

            if (Platform == Utils.ApplePlatform.MacCatalyst)
            {
                variant = "maccatalyst";
            }
            else if (SdkIsSimulator)
            {
                variant = "simulator";
            }

            try {
                var plist = PDictionary.FromFile(Path.Combine(xcframework, "Info.plist"));
                var path  = ResolveXCFramework(plist, platformName, variant, Architectures !);
                if (!String.IsNullOrEmpty(path))
                {
                    return(Path.Combine(xcframework, path));
                }

                // either the format was incorrect or we could not find a matching framework
                // note: last part is not translated since it match the (non-translated) keys inside the `Info.plist`
                var msg = (path == null) ? MSBStrings.E0174 : MSBStrings.E0175 + $" SupportedPlatform: '{platformName}', SupportedPlatformVariant: '{variant}', SupportedArchitectures: '{Architectures}'.";
                Log.LogError(msg, xcframework);
            }
            catch (Exception) {
                Log.LogError(MSBStrings.E0174, xcframework);
            }
            return(null);
        }
Пример #5
0
        public override bool Execute()
        {
            PDictionary plist = null;

            if (!string.IsNullOrEmpty(AppManifest?.ItemSpec))
            {
                try {
                    plist = PDictionary.FromFile(AppManifest.ItemSpec);
                } catch (Exception ex) {
                    Log.LogError(null, null, null, AppManifest.ItemSpec, 0, 0, 0, 0, MSBStrings.E0010, AppManifest.ItemSpec, ex.Message);
                    return(false);
                }
            }

            var minimumOSVersionInManifest = plist?.Get <PString> (PlatformFrameworkHelper.GetMinimumOSVersionKey(Platform))?.Value;

            if (string.IsNullOrEmpty(minimumOSVersionInManifest))
            {
                MinimumOSVersion = SdkVersion;
            }
            else if (!IAppleSdkVersion_Extensions.TryParse(minimumOSVersionInManifest, out var _))
            {
                Log.LogError(null, null, null, AppManifest.ItemSpec, 0, 0, 0, 0, MSBStrings.E0011, minimumOSVersionInManifest);
                return(false);
            }
            else
            {
                MinimumOSVersion = minimumOSVersionInManifest;
            }

            if (Platform == ApplePlatform.MacCatalyst)
            {
                // Convert the min macOS version to the min iOS version, which the rest of our tooling expects.
                if (!MacCatalystSupport.TryGetiOSVersion(Sdks.GetAppleSdk(Platform).GetSdkPath(SdkVersion, false), MinimumOSVersion, out var convertedVersion))
                {
                    Log.LogError(MSBStrings.E0187, MinimumOSVersion);
                }
                MinimumOSVersion = convertedVersion;
            }

            return(true);
        }
        public override bool Execute()
        {
            PDictionary?plist = null;

            if (!string.IsNullOrEmpty(AppManifest?.ItemSpec))
            {
                try {
                    plist = PDictionary.FromFile(AppManifest !.ItemSpec);
                } catch (Exception ex) {
                    Log.LogError(null, null, null, AppManifest !.ItemSpec, 0, 0, 0, 0, MSBStrings.E0010, AppManifest.ItemSpec, ex.Message);
                    return(false);
                }
            }

            CFBundleExecutable   = plist.GetCFBundleExecutable();
            CFBundleDisplayName  = plist?.GetCFBundleDisplayName();
            CFBundleIdentifier   = plist?.GetCFBundleIdentifier();
            CFBundleVersion      = plist?.GetCFBundleVersion();
            CLKComplicationGroup = plist?.Get <PString> (ManifestKeys.CLKComplicationGroup)?.Value;

            MinimumOSVersion = plist?.Get <PString> (PlatformFrameworkHelper.GetMinimumOSVersionKey(Platform))?.Value;
            if (Platform == ApplePlatform.MacCatalyst)
            {
                // The minimum version in the Info.plist is the macOS version. However, the rest of our tooling
                // expects the iOS version, so expose that.
                if (!MacCatalystSupport.TryGetiOSVersion(Sdks.GetAppleSdk(Platform).GetSdkPath(SdkVersion, false), MinimumOSVersion !, out var convertedVersion, out var knownMacOSVersions))
                {
                    Log.LogError(MSBStrings.E0187, MinimumOSVersion, string.Join(", ", knownMacOSVersions));
                }
                MinimumOSVersion = convertedVersion;
            }

            NSExtensionPointIdentifier = plist?.GetNSExtensionPointIdentifier();
            UIDeviceFamily             = plist?.GetUIDeviceFamily().ToString();
            WKWatchKitApp       = plist?.GetWKWatchKitApp() == true;
            XSAppIconAssets     = plist?.Get <PString> (ManifestKeys.XSAppIconAssets)?.Value;
            XSLaunchImageAssets = plist?.Get <PString> (ManifestKeys.XSLaunchImageAssets)?.Value;

            return(!Log.HasLoggedErrors);
        }
Пример #7
0
        public static string GetOperatingSystem(string targetFrameworkMoniker)
        {
            var framework = PlatformFrameworkHelper.GetFramework(targetFrameworkMoniker);

            switch (framework)
            {
            case ApplePlatform.WatchOS:
                return("watchos");

            case ApplePlatform.TVOS:
                return("tvos");

            case ApplePlatform.MacOSX:
                return("osx");

            case ApplePlatform.iOS:
                return("ios");

            default:
                throw new InvalidOperationException(string.Format("Unknown target framework {0} for target framework moniker {1}.", framework, targetFrameworkMoniker));
            }
        }
        public override bool Execute()
        {
            PDictionary plist;

            try {
                plist = PDictionary.FromFile(AppManifest);
            } catch (Exception ex) {
                LogAppManifestError(MSBStrings.E0010, AppManifest, ex.Message);
                return(false);
            }

            plist.SetIfNotPresent(PlatformFrameworkHelper.GetMinimumOSVersionKey(Platform), MinimumOSVersion);

            if (!string.IsNullOrEmpty(TargetArchitectures) && !Enum.TryParse(TargetArchitectures, out architectures))
            {
                LogAppManifestError(MSBStrings.E0012, TargetArchitectures);
                return(false);
            }

            plist.SetIfNotPresent(ManifestKeys.CFBundleIdentifier, BundleIdentifier);
            plist.SetIfNotPresent(ManifestKeys.CFBundleInfoDictionaryVersion, "6.0");
            plist.SetIfNotPresent(ManifestKeys.CFBundlePackageType, IsAppExtension ? "XPC!" : "APPL");
            plist.SetIfNotPresent(ManifestKeys.CFBundleSignature, "????");
            plist.SetIfNotPresent(ManifestKeys.CFBundleVersion, "1.0");
            plist.SetIfNotPresent(ManifestKeys.CFBundleExecutable, AssemblyName);

            if (!Compile(plist))
            {
                return(false);
            }

            // Merge with any partial plists generated by the Asset Catalog compiler...
            MergePartialPlistTemplates(plist);

            CompiledAppManifest = new TaskItem(Path.Combine(AppManifestBundleDirectory, "Info.plist"));
            plist.Save(CompiledAppManifest.ItemSpec, true, true);

            return(!Log.HasLoggedErrors);
        }
Пример #9
0
        public override bool Execute()
        {
            var archiveDir = CreateArchiveDirectory();

            try {
                var plist       = PDictionary.FromFile(PlatformFrameworkHelper.GetAppManifestPath(Platform, AppBundleDir.ItemSpec));
                var productsDir = Path.Combine(archiveDir, "Products");

                // Archive the OnDemandResources...
                var resourcesDestDir = Path.Combine(productsDir, "OnDemandResources");
                var resourcesSrcDir  = Path.Combine(OutputPath, "OnDemandResources");

                if (Directory.Exists(resourcesSrcDir))
                {
                    Ditto(resourcesSrcDir, resourcesDestDir);
                }

                // Archive the Applications...
                var appDestDir = Path.Combine(productsDir, "Applications", Path.GetFileName(AppBundleDir.ItemSpec));
                Ditto(AppBundleDir.ItemSpec, appDestDir);

                // Archive the main dSYM...
                ArchiveDSym(DSYMDir, archiveDir);

                // for each `.dylib` (file) inside `MonoBundle` there could be a corresponding `.dSYM` - e.g. when using an AOT mode
                foreach (var dylib in Directory.GetFiles(UserDylibPath, "*.dylib"))
                {
                    var dsym = Path.Combine(AppBundleDir.ItemSpec, "..", Path.GetFileName(dylib) + ".dSYM");
                    ArchiveDSym(dsym, archiveDir);
                }

                // for each user framework (directory) that is bundled inside the app we must also archive their dSYMs, if available
                var fks = UserFrameworksPath;
                if (Directory.Exists(fks))
                {
                    foreach (var fx in Directory.GetDirectories(fks, "*.framework"))
                    {
                        var dsym = Path.Combine(AppBundleDir.ItemSpec, "..", Path.GetFileName(fx) + ".dSYM");
                        ArchiveDSym(dsym, archiveDir);
                    }
                }

                // Archive the mSYMs...
                ArchiveMSym(MSYMDir, archiveDir);

                // Archive the Bitcode symbol maps
                var bcSymbolMaps = Directory.GetFiles(Path.GetDirectoryName(DSYMDir), "*.bcsymbolmap");
                if (bcSymbolMaps.Length > 0)
                {
                    var bcSymbolMapsDir = Path.Combine(archiveDir, "BCSymbolMaps");

                    Directory.CreateDirectory(bcSymbolMapsDir);

                    for (int i = 0; i < bcSymbolMaps.Length; i++)
                    {
                        File.Copy(bcSymbolMaps [i], Path.Combine(bcSymbolMapsDir, Path.GetFileName(bcSymbolMaps [i])));
                    }
                }

                if (AppExtensionReferences != null)
                {
                    // Archive the dSYMs, mSYMs, etc for each of the referenced App Extensions as well...
                    for (int i = 0; i < AppExtensionReferences.Length; i++)
                    {
                        ArchiveAppExtension(AppExtensionReferences [i], archiveDir);
                    }
                }

                if (WatchAppReferences != null)
                {
                    // Archive the dSYMs, mSYMs, etc for each of the referenced WatchOS2 Apps as well...
                    for (int i = 0; i < WatchAppReferences.Length; i++)
                    {
                        ArchiveWatchApp(WatchAppReferences [i], archiveDir);
                    }
                }

                if (ITunesSourceFiles != null)
                {
                    // Archive the iTunesMetadata.plist and iTunesArtwork files...
                    var iTunesMetadataDir = Path.Combine(archiveDir, "iTunesMetadata", Path.GetFileName(AppBundleDir.ItemSpec));
                    for (int i = 0; i < ITunesSourceFiles.Length; i++)
                    {
                        var archivedMetaFile = Path.Combine(iTunesMetadataDir, Path.GetFileName(ITunesSourceFiles [i].ItemSpec));

                        Directory.CreateDirectory(iTunesMetadataDir);
                        File.Copy(ITunesSourceFiles [i].ItemSpec, archivedMetaFile, true);
                    }
                }

                // Generate an archive Info.plist
                var arInfo = new PDictionary();
                // FIXME: figure out this value
                //arInfo.Add ("AppStoreFileSize", new PNumber (65535));
                var props = new PDictionary();
                props.Add("ApplicationPath", new PString(string.Format("Applications/{0}", Path.GetFileName(AppBundleDir.ItemSpec))));
                props.Add("CFBundleIdentifier", new PString(plist.GetCFBundleIdentifier()));

                var version = plist.GetCFBundleShortVersionString();
                var build   = plist.GetCFBundleVersion();
                props.Add("CFBundleShortVersionString", new PString(version ?? (build ?? "1.0")));
                props.Add("CFBundleVersion", new PString(build ?? "1.0"));

                var iconFiles = plist.GetCFBundleIconFiles();
                var iconDict  = plist.GetCFBundleIcons();
                var icons     = new PArray();

                if (iconFiles != null)
                {
                    AddIconPaths(icons, iconFiles, Path.Combine(archiveDir, "Products"));
                }

                if (iconDict != null)
                {
                    var primary = iconDict.Get <PDictionary> (ManifestKeys.CFBundlePrimaryIcon);
                    if (primary != null && (iconFiles = primary.GetCFBundleIconFiles()) != null)
                    {
                        AddIconPaths(icons, iconFiles, Path.Combine(archiveDir, "Products"));
                    }
                }

                if (icons.Count > 0)
                {
                    props.Add("IconPaths", icons);
                }

                props.Add("SigningIdentity", SigningKey);

                arInfo.Add("ApplicationProperties", props);
                arInfo.Add("ArchiveVersion", new PNumber(2));
                arInfo.Add("CreationDate", new PDate(Now.ToUniversalTime()));
                arInfo.Add("Name", new PString(plist.GetCFBundleName() ?? plist.GetCFBundleDisplayName()));

                if (!string.IsNullOrEmpty(ProjectGuid))
                {
                    arInfo.Add("ProjectGuid", new PString(ProjectGuid));
                }

                if (!string.IsNullOrEmpty(ProjectTypeGuids))
                {
                    arInfo.Add("ProjectTypeGuids", new PString(ProjectTypeGuids));
                }

                if (!string.IsNullOrEmpty(SolutionPath))
                {
                    arInfo.Add("SolutionName", new PString(Path.GetFileNameWithoutExtension(SolutionPath)));
                    arInfo.Add("SolutionPath", new PString(SolutionPath));
                }

                if (!string.IsNullOrEmpty(InsightsApiKey))
                {
                    arInfo.Add("InsightsApiKey", new PString(InsightsApiKey));
                }

                arInfo.Save(Path.Combine(archiveDir, "Info.plist"));
                ArchiveDir = archiveDir;
            } catch (Exception ex) {
                Log.LogErrorFromException(ex);
                Directory.Delete(archiveDir, true);
            }

            return(!Log.HasLoggedErrors);
        }
Пример #10
0
        public override bool Execute()
        {
            if (!Enum.TryParse(TargetArchitectures, out architectures))
            {
                Log.LogError(12, null, MSBStrings.E0012, TargetArchitectures);
                return(false);
            }

            var abis = architectures.ToArray();

            if (abis.Count != 1)
            {
                Log.LogError(7070, null, MSBStrings.E7070, /* Invalid architecture ({0}): can't link more than one architecture at a time. */ TargetArchitectures);
                return(false);
            }
            var abi = abis [0].ToNativeArchitecture();

            var arguments = new List <string> ();

            arguments.Add("clang");

            switch (Platform)
            {
            case ApplePlatform.iOS:
            case ApplePlatform.WatchOS:
            case ApplePlatform.TVOS:
            case ApplePlatform.MacOSX:
                arguments.Add(PlatformFrameworkHelper.GetMinimumVersionArgument(TargetFrameworkMoniker, SdkIsSimulator, MinimumOSVersion));
                arguments.Add("-isysroot");
                arguments.Add(SdkRoot);

                arguments.Add("-arch");
                arguments.Add(abi);

                break;

            case ApplePlatform.MacCatalyst:
                arguments.Add($"-target");
                arguments.Add($"{abi}-apple-ios{MinimumOSVersion}-macabi");
                arguments.Add("-isysroot");
                arguments.Add(SdkRoot);
                arguments.Add("-iframework");
                arguments.Add(Path.Combine(SdkRoot, "System", "iOSSupport", "System", "Library", "Frameworks"));
                arguments.Add($"-L{Path.Combine (SdkRoot, "System", "iOSSupport", "usr", "lib")}");
                break;

            default:
                throw new InvalidOperationException(string.Format(MSBStrings.InvalidPlatform, Platform));
            }

            bool hasDylibs = false;

            if (LinkWithLibraries != null)
            {
                foreach (var libSpec in LinkWithLibraries)
                {
                    var lib          = Path.GetFullPath(libSpec.ItemSpec);
                    var libExtension = Path.GetExtension(lib).ToLowerInvariant();
                    switch (libExtension)
                    {
                    case ".a":
                    case ".o":
                        var forceLoad = string.Equals(libSpec.GetMetadata("ForceLoad"), "true", StringComparison.OrdinalIgnoreCase);
                        if (forceLoad)
                        {
                            arguments.Add("-force_load");
                        }
                        arguments.Add(lib);
                        break;

                    case ".dylib":
                        arguments.Add("-L" + Path.GetDirectoryName(lib));
                        var libName = Path.GetFileNameWithoutExtension(lib);
                        if (libName.StartsWith("lib", StringComparison.Ordinal))
                        {
                            libName = libName.Substring(3);
                        }
                        arguments.Add("-l" + libName);
                        hasDylibs = true;
                        break;

                    case ".framework":
                        arguments.Add("-F" + Path.GetDirectoryName(lib));
                        arguments.Add("-framework");
                        arguments.Add(Path.GetFileNameWithoutExtension(lib));
                        break;

                    default:
                        Log.LogError($"Unknown library extension {libExtension} to link with for {lib}.");
                        return(false);
                    }
                }
            }

            if (hasDylibs)
            {
                arguments.Add("-rpath");
                arguments.Add(DylibRPath ?? "@executable_path");
            }

            if (Frameworks != null)
            {
                foreach (var fw in Frameworks)
                {
                    var is_weak   = fw.GetMetadata("IsWeak") == "true";
                    var framework = fw.ItemSpec;
                    if (framework.EndsWith(".framework", StringComparison.Ordinal))
                    {
                        // user framework, we need to pass -F to the linker so that the linker finds the user framework.
                        arguments.Add("-F");
                        arguments.Add(Path.GetDirectoryName(Path.GetFullPath(framework)));
                        framework = Path.GetFileNameWithoutExtension(framework);
                    }
                    arguments.Add(is_weak ? "-weak_framework" : "-framework");
                    arguments.Add(framework);
                }
            }

            if (ObjectFiles != null)
            {
                foreach (var obj in ObjectFiles)
                {
                    arguments.Add(Path.GetFullPath(obj.ItemSpec));
                }
            }

            arguments.AddRange(GetEmbedEntitlementsInExecutableLinkerFlags(EntitlementsInExecutable));

            arguments.Add("-o");
            arguments.Add(Path.GetFullPath(OutputFile));

            if (LinkerFlags != null)
            {
                foreach (var flag in LinkerFlags)
                {
                    arguments.Add(flag.ItemSpec);
                }
            }

            ExecuteAsync("xcrun", arguments, sdkDevPath: SdkDevPath).Wait();

            return(!Log.HasLoggedErrors);
        }
        public override bool Execute()
        {
            var arguments = new List <string> ();

            arguments.Add("clang");

            arguments.Add(PlatformFrameworkHelper.GetMinimumVersionArgument(TargetFrameworkMoniker, SdkIsSimulator, MinimumOSVersion));

            arguments.Add("-isysroot");
            arguments.Add(SdkRoot);

            bool hasDylibs = false;

            if (LinkWithLibraries != null)
            {
                foreach (var libSpec in LinkWithLibraries)
                {
                    var lib          = Path.GetFullPath(libSpec.ItemSpec);
                    var libExtension = Path.GetExtension(lib).ToLowerInvariant();
                    switch (libExtension)
                    {
                    case ".a":
                        arguments.Add(lib);
                        break;

                    case ".dylib":
                        arguments.Add("-L" + Path.GetDirectoryName(lib));
                        var libName = Path.GetFileNameWithoutExtension(lib);
                        if (libName.StartsWith("lib", StringComparison.Ordinal))
                        {
                            libName = libName.Substring(3);
                        }
                        arguments.Add("-l" + libName);
                        hasDylibs = true;
                        break;

                    case ".framework":
                        arguments.Add("-F" + Path.GetDirectoryName(lib));
                        arguments.Add("-framework");
                        arguments.Add(Path.GetFileNameWithoutExtension(lib));
                        break;

                    default:
                        Log.LogError($"Unknown library extension {libExtension} to link with for {lib}.");
                        return(false);
                    }
                }
            }

            if (hasDylibs)
            {
                arguments.Add("-rpath");
                arguments.Add("@executable_path");
            }

            if (Frameworks != null)
            {
                foreach (var fw in Frameworks)
                {
                    var is_weak = fw.GetMetadata("IsWeak") == "true";
                    arguments.Add(is_weak ? "-weak_framework" : "-framework");
                    arguments.Add(fw.ItemSpec);
                }
            }

            if (ObjectFiles != null)
            {
                foreach (var obj in ObjectFiles)
                {
                    arguments.Add(Path.GetFullPath(obj.ItemSpec));
                }
            }

            arguments.Add("-o");
            arguments.Add(OutputFile);

            ExecuteAsync("xcrun", arguments, sdkDevPath: SdkDevPath).Wait();

            return(!Log.HasLoggedErrors);
        }
Пример #12
0
        public override bool Execute()
        {
            PDictionary plist;

            try {
                plist = PDictionary.FromFile(AppManifest);
            } catch (Exception ex) {
                LogAppManifestError(MSBStrings.E0010, AppManifest, ex.Message);
                return(false);
            }

            plist.SetIfNotPresent(PlatformFrameworkHelper.GetMinimumOSVersionKey(Platform), MinimumOSVersion);

            if (!string.IsNullOrEmpty(TargetArchitectures) && !Enum.TryParse(TargetArchitectures, out architectures))
            {
                LogAppManifestError(MSBStrings.E0012, TargetArchitectures);
                return(false);
            }

            plist.SetCFBundleIdentifier(BundleIdentifier);              // no ifs and buts, we've computed the final bundle identifier (BundleIdentifier) in DetectSigningIdentityTask.
            plist.SetIfNotPresent(ManifestKeys.CFBundleInfoDictionaryVersion, "6.0");
            plist.SetIfNotPresent(ManifestKeys.CFBundlePackageType, IsAppExtension ? "XPC!" : "APPL");
            plist.SetIfNotPresent(ManifestKeys.CFBundleSignature, "????");
            plist.SetIfNotPresent(ManifestKeys.CFBundleExecutable, AssemblyName);
            plist.SetIfNotPresent(ManifestKeys.CFBundleName, AppBundleName);

            if (GenerateApplicationManifest && !string.IsNullOrEmpty(ApplicationTitle))
            {
                plist.SetIfNotPresent(ManifestKeys.CFBundleDisplayName, ApplicationTitle);
            }

            string defaultBundleVersion = "1.0";

            if (GenerateApplicationManifest && !string.IsNullOrEmpty(ApplicationVersion))
            {
                defaultBundleVersion = ApplicationVersion;
            }
            plist.SetIfNotPresent(ManifestKeys.CFBundleVersion, defaultBundleVersion);

            string defaultBundleShortVersion = null;

            if (GenerateApplicationManifest)
            {
                if (!string.IsNullOrEmpty(AppleShortVersion))
                {
                    defaultBundleShortVersion = AppleShortVersion;
                }
                else if (!string.IsNullOrEmpty(ApplicationVersion))
                {
                    defaultBundleShortVersion = ApplicationVersion;
                }
            }
            if (string.IsNullOrEmpty(defaultBundleShortVersion))
            {
                defaultBundleShortVersion = plist.GetCFBundleVersion();
            }
            plist.SetIfNotPresent(ManifestKeys.CFBundleShortVersionString, defaultBundleShortVersion);

            if (!Compile(plist))
            {
                return(false);
            }

            // Merge with any partial plists generated by the Asset Catalog compiler...
            MergePartialPlistTemplates(plist);

            CompiledAppManifest = new TaskItem(Path.Combine(AppManifestBundleDirectory, "Info.plist"));
            plist.Save(CompiledAppManifest.ItemSpec, true, true);

            return(!Log.HasLoggedErrors);
        }
Пример #13
0
        public override bool Execute()
        {
            var processes   = new Task <Execution> [CompileInfo.Length];
            var objectFiles = new List <ITaskItem> ();

            if (ObjectFiles != null)
            {
                objectFiles.AddRange(ObjectFiles);
            }

            for (var i = 0; i < CompileInfo.Length; i++)
            {
                var info      = CompileInfo [i];
                var src       = Path.GetFullPath(info.ItemSpec);
                var arguments = new List <string> ();

                arguments.Add("clang");
                arguments.Add("-g");

                var arch = info.GetMetadata("Arch");

                switch (Platform)
                {
                case ApplePlatform.iOS:
                case ApplePlatform.WatchOS:
                case ApplePlatform.TVOS:
                case ApplePlatform.MacOSX:
                    arguments.Add(PlatformFrameworkHelper.GetMinimumVersionArgument(TargetFrameworkMoniker, SdkIsSimulator, MinimumOSVersion));
                    arguments.Add("-isysroot");
                    arguments.Add(SdkRoot);

                    if (!string.IsNullOrEmpty(arch))
                    {
                        arguments.Add("-arch");
                        arguments.Add(arch);
                    }

                    break;

                case ApplePlatform.MacCatalyst:
                    arguments.Add($"-target");
                    arguments.Add($"{arch}-apple-ios{MinimumOSVersion}-macabi");
                    arguments.Add("-isystem");
                    arguments.Add(Path.Combine(SdkRoot, "System", "iOSSupport", "usr", "include"));
                    arguments.Add("-iframework");
                    arguments.Add(Path.Combine(SdkRoot, "System", "iOSSupport", "System", "Library", "Frameworks"));
                    break;

                default:
                    throw new InvalidOperationException(string.Format(MSBStrings.InvalidPlatform, Platform));
                }

                if (IncludeDirectories != null)
                {
                    foreach (var inc in IncludeDirectories)
                    {
                        arguments.Add("-I" + Path.GetFullPath(inc.ItemSpec));
                    }
                }

                var args = info.GetMetadata("Arguments");
                if (!StringUtils.TryParseArguments(args, out var parsed_args, out var ex))
                {
                    Log.LogError("Could not parse the arguments '{0}': {1}", args, ex.Message);
                    return(false);
                }
                arguments.AddRange(parsed_args);


                var outputFile = info.GetMetadata("OutputFile");
                if (string.IsNullOrEmpty(outputFile))
                {
                    outputFile = Path.ChangeExtension(src, ".o");
                }
                outputFile = Path.GetFullPath(outputFile);
                arguments.Add("-o");
                arguments.Add(outputFile);
                objectFiles.Add(new TaskItem(outputFile));

                arguments.Add("-c");
                arguments.Add(src);

                processes [i] = ExecuteAsync("xcrun", arguments, sdkDevPath: SdkDevPath);
            }

            System.Threading.Tasks.Task.WaitAll(processes);

            ObjectFiles = objectFiles.ToArray();

            return(!Log.HasLoggedErrors);
        }
Пример #14
0
 protected string GetSdkPlatform(bool isSimulator)
 {
     return(PlatformFrameworkHelper.GetSdkPlatform(Platform, isSimulator));
 }
Пример #15
0
        public override bool Execute()
        {
            var processes   = new Task <Execution> [CompileInfo.Length];
            var objectFiles = new List <ITaskItem> ();

            if (ObjectFiles != null)
            {
                objectFiles.AddRange(ObjectFiles);
            }

            for (var i = 0; i < CompileInfo.Length; i++)
            {
                var info      = CompileInfo [i];
                var src       = Path.GetFullPath(info.ItemSpec);
                var arguments = new List <string> ();

                arguments.Add("clang");

                arguments.Add(PlatformFrameworkHelper.GetMinimumVersionArgument(TargetFrameworkMoniker, SdkIsSimulator, MinimumOSVersion));

                arguments.Add("-isysroot");
                arguments.Add(SdkRoot);

                if (IncludeDirectories != null)
                {
                    foreach (var inc in IncludeDirectories)
                    {
                        arguments.Add("-I" + Path.GetFullPath(inc.ItemSpec));
                    }
                }

                var args = info.GetMetadata("Arguments");
                if (!StringUtils.TryParseArguments(args, out var parsed_args, out var ex))
                {
                    Log.LogError("Could not parse the arguments '{0}': {1}", args, ex.Message);
                    return(false);
                }
                arguments.AddRange(parsed_args);

                var arch = info.GetMetadata("Arch");
                if (!string.IsNullOrEmpty(arch))
                {
                    arguments.Add("-arch");
                    arguments.Add(arch);
                }

                var outputFile = info.GetMetadata("OutputFile");
                if (string.IsNullOrEmpty(outputFile))
                {
                    outputFile = Path.ChangeExtension(src, ".o");
                }
                outputFile = Path.GetFullPath(outputFile);
                arguments.Add("-o");
                arguments.Add(outputFile);
                objectFiles.Add(new TaskItem(outputFile));

                arguments.Add("-c");
                arguments.Add(src);

                processes [i] = ExecuteAsync("xcrun", arguments, sdkDevPath: SdkDevPath);
            }

            System.Threading.Tasks.Task.WaitAll(processes);

            ObjectFiles = objectFiles.ToArray();

            return(!Log.HasLoggedErrors);
        }
        bool SetMinimumOSVersion(PDictionary plist)
        {
            var    minimumVersionKey          = PlatformFrameworkHelper.GetMinimumOSVersionKey(Platform);
            var    minimumOSVersionInManifest = plist?.Get <PString> (minimumVersionKey)?.Value;
            string convertedSupportedOSPlatformVersion;
            string minimumOSVersion;

            if (Platform == ApplePlatform.MacCatalyst && !string.IsNullOrEmpty(SupportedOSPlatformVersion))
            {
                // SupportedOSPlatformVersion is the iOS version for Mac Catalyst.
                // But we need to store the macOS version in the app manifest, so convert it to the macOS version here.
                if (!MacCatalystSupport.TryGetMacOSVersion(Sdks.GetAppleSdk(Platform).GetSdkPath(SdkVersion, false), SupportedOSPlatformVersion, out var convertedVersion, out var knowniOSVersions))
                {
                    Log.LogError(MSBStrings.E0188, SupportedOSPlatformVersion, string.Join(", ", knowniOSVersions));
                }
                convertedSupportedOSPlatformVersion = convertedVersion;
            }
            else
            {
                convertedSupportedOSPlatformVersion = SupportedOSPlatformVersion;
            }

            if (Platform == ApplePlatform.MacCatalyst && string.IsNullOrEmpty(minimumOSVersionInManifest))
            {
                // If there was no value for the macOS min version key, then check the iOS min version key.
                var minimumiOSVersionInManifest = plist?.Get <PString> (ManifestKeys.MinimumOSVersion)?.Value;
                if (!string.IsNullOrEmpty(minimumiOSVersionInManifest))
                {
                    // Convert to the macOS version
                    if (!MacCatalystSupport.TryGetMacOSVersion(Sdks.GetAppleSdk(Platform).GetSdkPath(SdkVersion, false), minimumiOSVersionInManifest, out var convertedVersion, out var knowniOSVersions))
                    {
                        Log.LogError(MSBStrings.E0188, minimumiOSVersionInManifest, string.Join(", ", knowniOSVersions));
                    }
                    minimumOSVersionInManifest = convertedVersion;
                }
            }

            if (string.IsNullOrEmpty(minimumOSVersionInManifest))
            {
                // Nothing is specified in the Info.plist - use SupportedOSPlatformVersion, and if that's not set, then use the sdkVersion
                if (!string.IsNullOrEmpty(convertedSupportedOSPlatformVersion))
                {
                    minimumOSVersion = convertedSupportedOSPlatformVersion;
                }
                else
                {
                    minimumOSVersion = SdkVersion;
                }
            }
            else if (!IAppleSdkVersion_Extensions.TryParse(minimumOSVersionInManifest, out var _))
            {
                LogAppManifestError(MSBStrings.E0011, minimumOSVersionInManifest);
                return(false);
            }
            else if (!string.IsNullOrEmpty(convertedSupportedOSPlatformVersion) && convertedSupportedOSPlatformVersion != minimumOSVersionInManifest)
            {
                // SupportedOSPlatformVersion and the value in the Info.plist are not the same. This is an error.
                LogAppManifestError(MSBStrings.E7082, minimumVersionKey, minimumOSVersionInManifest, SupportedOSPlatformVersion);
                return(false);
            }
            else
            {
                minimumOSVersion = minimumOSVersionInManifest;
            }

            // Write out our value
            plist [minimumVersionKey] = minimumOSVersion;

            return(true);
        }
        public override bool Execute()
        {
            var arguments = new List <string> ();

            arguments.Add("clang");

            arguments.Add(PlatformFrameworkHelper.GetMinimumVersionArgument(TargetFrameworkMoniker, SdkIsSimulator, MinimumOSVersion));

            arguments.Add("-isysroot");
            arguments.Add(SdkRoot);

            bool hasDylibs = false;

            if (LinkWithLibraries != null)
            {
                foreach (var libSpec in LinkWithLibraries)
                {
                    var lib          = Path.GetFullPath(libSpec.ItemSpec);
                    var libExtension = Path.GetExtension(lib).ToLowerInvariant();
                    switch (libExtension)
                    {
                    case ".a":
                        var forceLoad = string.Equals(libSpec.GetMetadata("ForceLoad"), "true", StringComparison.OrdinalIgnoreCase);
                        if (forceLoad)
                        {
                            arguments.Add("-force_load");
                        }
                        arguments.Add(lib);
                        break;

                    case ".dylib":
                        arguments.Add("-L" + Path.GetDirectoryName(lib));
                        var libName = Path.GetFileNameWithoutExtension(lib);
                        if (libName.StartsWith("lib", StringComparison.Ordinal))
                        {
                            libName = libName.Substring(3);
                        }
                        arguments.Add("-l" + libName);
                        hasDylibs = true;
                        break;

                    case ".framework":
                        arguments.Add("-F" + Path.GetDirectoryName(lib));
                        arguments.Add("-framework");
                        arguments.Add(Path.GetFileNameWithoutExtension(lib));
                        break;

                    default:
                        Log.LogError($"Unknown library extension {libExtension} to link with for {lib}.");
                        return(false);
                    }
                }
            }

            if (hasDylibs)
            {
                arguments.Add("-rpath");
                arguments.Add("@executable_path");
            }

            if (Frameworks != null)
            {
                foreach (var fw in Frameworks)
                {
                    var is_weak   = fw.GetMetadata("IsWeak") == "true";
                    var framework = fw.ItemSpec;
                    if (framework.EndsWith(".framework", StringComparison.Ordinal))
                    {
                        // user framework, we need to pass -F to the linker so that the linker finds the user framework.
                        arguments.Add("-F");
                        arguments.Add(Path.GetDirectoryName(Path.GetFullPath(framework)));
                        framework = Path.GetFileNameWithoutExtension(framework);
                    }
                    arguments.Add(is_weak ? "-weak_framework" : "-framework");
                    arguments.Add(framework);
                }
            }

            if (ObjectFiles != null)
            {
                foreach (var obj in ObjectFiles)
                {
                    arguments.Add(Path.GetFullPath(obj.ItemSpec));
                }
            }

            arguments.AddRange(GetEmbedEntitlementsInExecutableLinkerFlags(EntitlementsInExecutable));

            arguments.Add("-o");
            arguments.Add(Path.GetFullPath(OutputFile));

            if (LinkerFlags != null)
            {
                foreach (var flag in LinkerFlags)
                {
                    arguments.Add(flag.ItemSpec);
                }
            }

            ExecuteAsync("xcrun", arguments, sdkDevPath: SdkDevPath).Wait();

            return(!Log.HasLoggedErrors);
        }