void BuildEntitlementFlags(GccOptions gcc) { if (SdkIsSimulator && !string.IsNullOrEmpty(CompiledEntitlements) && EntitlementsRequireLinkerFlags(CompiledEntitlements)) { gcc.Arguments.AddQuoted(new [] { "-Xlinker", "-sectcreate", "-Xlinker", "__TEXT", "-Xlinker", "__entitlements" }); gcc.Arguments.Add("-Xlinker"); gcc.Arguments.AddQuoted(Path.GetFullPath(CompiledEntitlements)); } }
protected override string GenerateCommandLineCommands() { var args = new ProcessArgumentBuilder(); TargetArchitecture architectures; bool msym; if (string.IsNullOrEmpty(Architectures) || !Enum.TryParse(Architectures, out architectures)) { architectures = TargetArchitecture.Default; } if (architectures == TargetArchitecture.ARMv6) { Log.LogError("Target architecture ARMv6 is no longer supported in Xamarin.iOS. Please select a supported architecture."); return(null); } if (IsClassic && minimumOSVersion < IPhoneSdkVersion.V3_1 && architectures.HasFlag(TargetArchitecture.ARMv7)) { Log.LogWarning(null, null, null, AppManifest.ItemSpec, 0, 0, 0, 0, "Deployment Target changed from iOS {0} to iOS 3.1 (minimum requirement for ARMv7)", minimumOSVersion); minimumOSVersion = IPhoneSdkVersion.V3_1; } if (!string.IsNullOrEmpty(IntermediateOutputPath)) { Directory.CreateDirectory(IntermediateOutputPath); args.Add("--cache"); args.AddQuoted(Path.GetFullPath(IntermediateOutputPath)); } if (IsClassic || IPhoneSdks.MonoTouch.Version < new IPhoneSdkVersion(8, 5, 0)) { args.Add("--nomanifest"); args.Add("--nosign"); } args.Add(SdkIsSimulator ? "--sim" : "--dev"); args.AddQuoted(Path.GetFullPath(AppBundleDir)); if (AppleSdkSettings.XcodeVersion.Major >= 5 && IPhoneSdks.MonoTouch.Version.CompareTo(new IPhoneSdkVersion(6, 3, 7)) < 0) { args.Add("--compiler", "clang"); } args.Add("--executable"); args.AddQuoted(ExecutableName); if (IsAppExtension) { args.Add("--extension"); } if (Debug) { if (FastDev && IPhoneSdks.MonoTouch.SupportsFastDev) { args.Add("--fastdev"); } args.Add("--debug"); } if (Profiling) { args.Add("--profiling"); } if (LinkerDumpDependencies) { args.Add("--linkerdumpdependencies"); } switch (LinkMode.ToLowerInvariant()) { case "sdkonly": args.Add("--linksdkonly"); break; case "none": args.Add("--nolink"); break; } if (!string.IsNullOrEmpty(I18n)) { args.Add("--i18n"); args.AddQuotedFormat(I18n); } args.Add("--sdkroot"); args.AddQuoted(SdkRoot); args.Add("--sdk"); args.AddQuoted(SdkVersion); if (!minimumOSVersion.IsUseDefault) { args.Add("--targetver"); args.AddQuoted(minimumOSVersion.ToString()); } if (UseFloat32 /* We want to compile 32-bit floating point code to use 32-bit floating point operations */) { args.Add("--aot-options=-O=float32"); } if (IPhoneSdks.MonoTouch.SupportsGenericValueTypeSharing) { if (!EnableGenericValueTypeSharing) { args.Add("--gsharedvt=false"); } } if (LinkDescriptions != null) { foreach (var desc in LinkDescriptions) { args.AddQuoted(string.Format("--xml={0}", desc.ItemSpec)); } } if (EnableBitcode) { switch (Framework) { case PlatformFramework.WatchOS: args.Add("--bitcode=full"); break; case PlatformFramework.TVOS: args.Add("--bitcode=asmonly"); break; default: throw new InvalidOperationException(string.Format("Bitcode is currently not supported on {0}.", Framework)); } } if (!string.IsNullOrEmpty(HttpClientHandler)) { args.Add(string.Format("--http-message-handler={0}", HttpClientHandler)); } if (!string.IsNullOrEmpty(TLSProvider)) { args.Add(string.Format("--tls-provider={0}", TLSProvider.ToLowerInvariant())); } string thumb = UseThumb && UseLlvm ? "+thumb2" : ""; string llvm = UseLlvm ? "+llvm" : ""; string abi = ""; if (SdkIsSimulator) { if (architectures.HasFlag(TargetArchitecture.i386)) { abi += (abi.Length > 0 ? "," : "") + "i386"; } if (architectures.HasFlag(TargetArchitecture.x86_64)) { abi += (abi.Length > 0 ? "," : "") + "x86_64"; } if (string.IsNullOrEmpty(abi)) { architectures = TargetArchitecture.i386; abi = "i386"; } } else { if (architectures == TargetArchitecture.Default) { architectures = TargetArchitecture.ARMv7; } if (architectures.HasFlag(TargetArchitecture.ARMv7)) { abi += (abi.Length > 0 ? "," : "") + "armv7" + llvm + thumb; } if (architectures.HasFlag(TargetArchitecture.ARMv7s)) { abi += (abi.Length > 0 ? "," : "") + "armv7s" + llvm + thumb; } if (architectures.HasFlag(TargetArchitecture.ARM64)) { // Note: ARM64 does not have thumb. abi += (abi.Length > 0 ? "," : "") + "arm64" + llvm; } if (architectures.HasFlag(TargetArchitecture.ARMv7k)) { abi += (abi.Length > 0 ? "," : "") + "armv7k" + llvm; } if (string.IsNullOrEmpty(abi)) { abi = "armv7" + llvm + thumb; } } // Output the CompiledArchitectures CompiledArchitectures = architectures.ToString(); args.Add("--abi=" + abi); // output symbols to preserve when stripping args.Add("--symbollist"); args.AddQuoted(Path.GetFullPath(SymbolsList)); // don't have mtouch generate the dsyms... args.Add("--dsym=no"); if (!string.IsNullOrEmpty(ArchiveSymbols) && bool.TryParse(ArchiveSymbols.Trim(), out msym)) { args.Add("--msym=" + (msym ? "yes" : "no")); } var gcc = new GccOptions(); if (!string.IsNullOrEmpty(ExtraArgs)) { var extraArgs = ProcessArgumentBuilder.Parse(ExtraArgs); var target = MainAssembly.ItemSpec; string projectDir; if (ProjectDir.StartsWith("~/", StringComparison.Ordinal)) { // Note: Since the Visual Studio plugin doesn't know the user's home directory on the Mac build host, // it simply uses paths relative to "~/". Expand these paths to their full path equivalents. var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); projectDir = Path.Combine(home, ProjectDir.Substring(2)); } else { projectDir = ProjectDir; } var customTags = new Dictionary <string, string> (StringComparer.OrdinalIgnoreCase) { { "projectdir", projectDir }, // Apparently msbuild doesn't propagate the solution path, so we can't get it. // { "solutiondir", proj.ParentSolution != null ? proj.ParentSolution.BaseDirectory : proj.BaseDirectory }, { "appbundledir", AppBundleDir }, { "targetpath", Path.Combine(Path.GetDirectoryName(target), Path.GetFileName(target)) }, { "targetdir", Path.GetDirectoryName(target) }, { "targetname", Path.GetFileName(target) }, { "targetext", Path.GetExtension(target) }, }; for (int i = 0; i < extraArgs.Length; i++) { if (extraArgs[i] == "-gcc_flags" || extraArgs[i] == "--gcc_flags") { // user-defined -gcc_flags argument if (i + 1 < extraArgs.Length && !string.IsNullOrEmpty(extraArgs[i + 1])) { var gccArgs = ProcessArgumentBuilder.Parse(extraArgs[i + 1]); for (int j = 0; j < gccArgs.Length; j++) { gcc.Arguments.Add(StringParserService.Parse(gccArgs[j], customTags)); } } i++; } else { // other user-defined mtouch arguments args.AddQuoted(StringParserService.Parse(extraArgs[i], customTags)); } } } BuildNativeReferenceFlags(gcc); BuildEntitlementFlags(gcc); foreach (var framework in gcc.Frameworks) { args.Add("-framework"); args.AddQuoted(framework); } foreach (var framework in gcc.WeakFrameworks) { args.Add("-weak-framework"); args.AddQuoted(framework); } if (gcc.Cxx) { args.Add("--cxx"); } if (gcc.Arguments.Length > 0) { args.Add("--gcc_flags"); args.AddQuoted(gcc.Arguments.ToString()); } foreach (var asm in References) { args.Add("-r"); if (IsFrameworkItem(asm)) { args.AddQuoted(ResolveFrameworkFile(asm.ItemSpec)); } else { args.AddQuoted(Path.GetFullPath(asm.ItemSpec)); } } foreach (var ext in AppExtensionReferences) { args.Add("--app-extension"); args.AddQuoted(Path.GetFullPath(ext.ItemSpec)); } args.Add("--target-framework"); args.Add(TargetFrameworkIdentifier + "," + TargetFrameworkVersion); args.AddQuoted(MainAssembly.ItemSpec); // We give the priority to the ExtraArgs to set the mtouch verbosity. if (string.IsNullOrEmpty(ExtraArgs) || (!string.IsNullOrEmpty(ExtraArgs) && !ExtraArgs.Contains("-q") && !ExtraArgs.Contains("-v"))) { args.Add(GetVerbosityLevel(Verbosity)); } if (!string.IsNullOrWhiteSpace(License)) { args.Add(string.Format("--license={0}", License)); } return(args.ToString()); }
protected override string GenerateCommandLineCommands() { var args = GenerateCommandLineArguments(); List <string> unescapedArgs = new List <string> (); TargetArchitecture architectures; if (string.IsNullOrEmpty(Architectures) || !Enum.TryParse(Architectures, out architectures)) { architectures = TargetArchitecture.Default; } if (architectures == TargetArchitecture.ARMv6) { Log.LogError(MSBStrings.E0053); return(null); } args.AddQuotedLine((SdkIsSimulator ? "--sim=" : "--dev=") + Path.GetFullPath(AppBundleDir)); if (AppleSdkSettings.XcodeVersion.Major >= 5 && IPhoneSdks.MonoTouch.Version.CompareTo(new IPhoneSdkVersion(6, 3, 7)) < 0) { args.AddLine("--compiler=clang"); } args.AddQuotedLine($"--executable={ExecutableName}"); if (IsAppExtension) { args.AddLine("--extension"); } if (Debug) { if (FastDev && !SdkIsSimulator) { args.AddLine("--fastdev"); } } if (LinkerDumpDependencies) { args.AddLine("--linkerdumpdependencies"); } if (!string.IsNullOrEmpty(Interpreter)) { args.AddLine($"--interpreter={Interpreter}"); } switch (LinkMode.ToLowerInvariant()) { case "sdkonly": args.AddLine("--linksdkonly"); break; case "none": args.AddLine("--nolink"); break; } args.AddQuotedLine($"--sdk={SdkVersion}"); if (!minimumOSVersion.IsUseDefault) { args.AddQuotedLine($"--targetver={minimumOSVersion.ToString ()}"); } if (UseFloat32 /* We want to compile 32-bit floating point code to use 32-bit floating point operations */) { args.AddLine("--aot-options=-O=float32"); } else { args.AddLine("--aot-options=-O=-float32"); } if (LinkDescriptions != null) { foreach (var desc in LinkDescriptions) { args.AddQuotedLine($"--xml={desc.ItemSpec}"); } } if (EnableBitcode) { switch (Platform) { case ApplePlatform.WatchOS: args.AddLine("--bitcode=full"); break; case ApplePlatform.TVOS: args.AddLine("--bitcode=asmonly"); break; default: throw new InvalidOperationException(string.Format("Bitcode is currently not supported on {0}.", Platform)); } } string thumb = UseThumb && UseLlvm ? "+thumb2" : ""; string llvm = UseLlvm ? "+llvm" : ""; string abi = ""; if (SdkIsSimulator) { if (architectures.HasFlag(TargetArchitecture.i386)) { abi += (abi.Length > 0 ? "," : "") + "i386"; } if (architectures.HasFlag(TargetArchitecture.x86_64)) { abi += (abi.Length > 0 ? "," : "") + "x86_64"; } if (string.IsNullOrEmpty(abi)) { architectures = TargetArchitecture.i386; abi = "i386"; } } else { if (architectures == TargetArchitecture.Default) { architectures = TargetArchitecture.ARMv7; } if (architectures.HasFlag(TargetArchitecture.ARMv7)) { abi += (abi.Length > 0 ? "," : "") + "armv7" + llvm + thumb; } if (architectures.HasFlag(TargetArchitecture.ARMv7s)) { abi += (abi.Length > 0 ? "," : "") + "armv7s" + llvm + thumb; } if (architectures.HasFlag(TargetArchitecture.ARM64)) { // Note: ARM64 does not have thumb. abi += (abi.Length > 0 ? "," : "") + "arm64" + llvm; } if (architectures.HasFlag(TargetArchitecture.ARMv7k)) { abi += (abi.Length > 0 ? "," : "") + "armv7k" + llvm; } if (architectures.HasFlag(TargetArchitecture.ARM64_32)) { abi += (abi.Length > 0 ? "," : "") + "arm64_32" + llvm; } if (string.IsNullOrEmpty(abi)) { abi = "armv7" + llvm + thumb; } } // Output the CompiledArchitectures CompiledArchitectures = architectures.ToString(); args.AddLine($"--abi={abi}"); // output symbols to preserve when stripping args.AddQuotedLine($"--symbollist={Path.GetFullPath (SymbolsList)}"); // don't have mtouch generate the dsyms... args.AddLine("--dsym=no"); var gcc = new GccOptions(); if (!string.IsNullOrEmpty(ExtraArgs)) { var extraArgs = CommandLineArgumentBuilder.Parse(ExtraArgs); var target = MainAssembly.ItemSpec; string projectDir; if (ProjectDir.StartsWith("~/", StringComparison.Ordinal)) { // Note: Since the Visual Studio plugin doesn't know the user's home directory on the Mac build host, // it simply uses paths relative to "~/". Expand these paths to their full path equivalents. var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); projectDir = Path.Combine(home, ProjectDir.Substring(2)); } else { projectDir = ProjectDir; } var customTags = new Dictionary <string, string> (StringComparer.OrdinalIgnoreCase) { { "projectdir", projectDir }, // Apparently msbuild doesn't propagate the solution path, so we can't get it. // { "solutiondir", proj.ParentSolution != null ? proj.ParentSolution.BaseDirectory : proj.BaseDirectory }, { "appbundledir", AppBundleDir }, { "targetpath", Path.Combine(Path.GetDirectoryName(target), Path.GetFileName(target)) }, { "targetdir", Path.GetDirectoryName(target) }, { "targetname", Path.GetFileName(target) }, { "targetext", Path.GetExtension(target) }, }; for (int i = 0; i < extraArgs.Length; i++) { var argument = extraArgs[i]; int startIndex = 0; while (argument.Length > startIndex && argument[startIndex] == '-') { startIndex++; } int endIndex = startIndex; while (endIndex < argument.Length && argument[endIndex] != '=') { endIndex++; } int length = endIndex - startIndex; if (length == 9 && string.CompareOrdinal(argument, startIndex, "gcc_flags", 0, 9) == 0) { // user-defined -gcc_flags argument string flags = null; if (endIndex < extraArgs[i].Length) { flags = Unquote(argument, endIndex + 1); } else if (i + 1 < extraArgs.Length) { flags = extraArgs[++i]; } if (!string.IsNullOrEmpty(flags)) { var gccArgs = CommandLineArgumentBuilder.Parse(flags); for (int j = 0; j < gccArgs.Length; j++) { gcc.Arguments.Add(StringParserService.Parse(gccArgs[j], customTags)); } } } else { // other user-defined mtouch arguments unescapedArgs.Add(StringParserService.Parse(argument, customTags)); } } } BuildNativeReferenceFlags(gcc); BuildEntitlementFlags(gcc); foreach (var framework in gcc.Frameworks) { args.AddQuotedLine($"--framework={framework}"); } foreach (var framework in gcc.WeakFrameworks) { args.AddQuotedLine($"--weak-framework={framework}"); } if (gcc.Cxx) { args.AddLine("--cxx"); } if (gcc.Arguments.Length > 0) { unescapedArgs.Add($"--gcc_flags={gcc.Arguments.ToString ()}"); } foreach (var asm in References) { if (IsFrameworkItem(asm)) { args.AddQuotedLine($"--reference={ResolveFrameworkFile (asm.ItemSpec)}"); } else { args.AddQuotedLine($"--reference={Path.GetFullPath (asm.ItemSpec)}"); } } foreach (var ext in AppExtensionReferences) { args.AddQuotedLine($"--app-extension={Path.GetFullPath (ext.ItemSpec)}"); } if (!string.IsNullOrWhiteSpace(License)) { args.AddLine($"--license={License}"); } return(CreateResponseFile(args, unescapedArgs)); }
void BuildNativeReferenceFlags(GccOptions gcc) { if (NativeReferences == null) { return; } foreach (var item in NativeReferences) { var value = item.GetMetadata("Kind"); NativeReferenceKind kind; bool boolean; if (string.IsNullOrEmpty(value) || !Enum.TryParse(value, out kind)) { Log.LogWarning("Unknown native reference type for '{0}'.", item.ItemSpec); continue; } if (kind == NativeReferenceKind.Static) { var libName = Path.GetFileName(item.ItemSpec); if (libName.EndsWith(".a", StringComparison.Ordinal)) { libName = libName.Substring(0, libName.Length - 2); } if (libName.StartsWith("lib", StringComparison.Ordinal)) { libName = libName.Substring(3); } if (!string.IsNullOrEmpty(Path.GetDirectoryName(item.ItemSpec))) { gcc.Arguments.AddQuoted("-L" + Path.GetDirectoryName(item.ItemSpec)); } gcc.Arguments.AddQuoted("-l" + libName); value = item.GetMetadata("ForceLoad"); if (!string.IsNullOrEmpty(value) && bool.TryParse(value, out boolean) && boolean) { gcc.Arguments.Add("-force_load"); gcc.Arguments.AddQuoted(item.ItemSpec); } value = item.GetMetadata("IsCxx"); if (!string.IsNullOrEmpty(value) && bool.TryParse(value, out boolean) && boolean) { gcc.Cxx = true; } } else if (kind == NativeReferenceKind.Framework) { gcc.Frameworks.Add(item.ItemSpec); } else { Log.LogWarning("Dynamic native references are not supported: '{0}'", item.ItemSpec); continue; } value = item.GetMetadata("NeedsGccExceptionHandling"); if (!string.IsNullOrEmpty(value) && bool.TryParse(value, out boolean) && boolean) { if (!gcc.Arguments.Contains("-lgcc_eh")) { gcc.Arguments.Add("-lgcc_eh"); } } value = item.GetMetadata("WeakFrameworks"); if (!string.IsNullOrEmpty(value)) { foreach (var framework in value.Split(' ', '\t')) { gcc.WeakFrameworks.Add(framework); } } value = item.GetMetadata("Frameworks"); if (!string.IsNullOrEmpty(value)) { foreach (var framework in value.Split(' ', '\t')) { gcc.Frameworks.Add(framework); } } // Note: these get merged into gccArgs by our caller value = item.GetMetadata("LinkerFlags"); if (!string.IsNullOrEmpty(value)) { var linkerFlags = ProcessArgumentBuilder.Parse(value); foreach (var flag in linkerFlags) { gcc.Arguments.AddQuoted(flag); } } } }
protected override string GenerateCommandLineCommands() { var args = new CommandLineArgumentBuilder(); List <string> unescapedArgs = new List <string> (); TargetArchitecture architectures; bool msym; if (string.IsNullOrEmpty(Architectures) || !Enum.TryParse(Architectures, out architectures)) { architectures = TargetArchitecture.Default; } if (architectures == TargetArchitecture.ARMv6) { Log.LogError("Target architecture ARMv6 is no longer supported in Xamarin.iOS. Please select a supported architecture."); return(null); } if (!string.IsNullOrEmpty(IntermediateOutputPath)) { Directory.CreateDirectory(IntermediateOutputPath); args.AddQuotedLine($"--cache={Path.GetFullPath (IntermediateOutputPath)}"); } args.AddQuotedLine((SdkIsSimulator ? "--sim=" : "--dev=") + Path.GetFullPath(AppBundleDir)); if (AppleSdkSettings.XcodeVersion.Major >= 5 && IPhoneSdks.MonoTouch.Version.CompareTo(new IPhoneSdkVersion(6, 3, 7)) < 0) { args.AddLine("--compiler=clang"); } args.AddQuotedLine($"--executable={ExecutableName}"); if (IsAppExtension) { args.AddLine("--extension"); } if (Debug) { if (FastDev && !SdkIsSimulator) { args.AddLine("--fastdev"); } args.AddLine("--debug"); } if (Profiling) { args.AddLine("--profiling"); } if (LinkerDumpDependencies) { args.AddLine("--linkerdumpdependencies"); } if (EnableSGenConc) { args.AddLine("--sgen-conc"); } if (!string.IsNullOrEmpty(Interpreter)) { args.Add($"--interpreter={Interpreter}"); } switch (LinkMode.ToLowerInvariant()) { case "sdkonly": args.AddLine("--linksdkonly"); break; case "none": args.AddLine("--nolink"); break; } if (!string.IsNullOrEmpty(I18n)) { args.AddQuotedLine($"--i18n={I18n}"); } args.AddQuotedLine($"--sdkroot={SdkRoot}"); args.AddQuotedLine($"--sdk={SdkVersion}"); if (!minimumOSVersion.IsUseDefault) { args.AddQuotedLine($"--targetver={minimumOSVersion.ToString ()}"); } if (UseFloat32 /* We want to compile 32-bit floating point code to use 32-bit floating point operations */) { args.AddLine("--aot-options=-O=float32"); } else { args.AddLine("--aot-options=-O=-float32"); } if (!EnableGenericValueTypeSharing) { args.AddLine("--gsharedvt=false"); } if (LinkDescriptions != null) { foreach (var desc in LinkDescriptions) { args.AddQuotedLine($"--xml={desc.ItemSpec}"); } } if (EnableBitcode) { switch (Framework) { case PlatformFramework.WatchOS: args.AddLine("--bitcode=full"); break; case PlatformFramework.TVOS: args.AddLine("--bitcode=asmonly"); break; default: throw new InvalidOperationException(string.Format("Bitcode is currently not supported on {0}.", Framework)); } } if (!string.IsNullOrEmpty(HttpClientHandler)) { args.AddLine($"--http-message-handler={HttpClientHandler}"); } string thumb = UseThumb && UseLlvm ? "+thumb2" : ""; string llvm = UseLlvm ? "+llvm" : ""; string abi = ""; if (SdkIsSimulator) { if (architectures.HasFlag(TargetArchitecture.i386)) { abi += (abi.Length > 0 ? "," : "") + "i386"; } if (architectures.HasFlag(TargetArchitecture.x86_64)) { abi += (abi.Length > 0 ? "," : "") + "x86_64"; } if (string.IsNullOrEmpty(abi)) { architectures = TargetArchitecture.i386; abi = "i386"; } } else { if (architectures == TargetArchitecture.Default) { architectures = TargetArchitecture.ARMv7; } if (architectures.HasFlag(TargetArchitecture.ARMv7)) { abi += (abi.Length > 0 ? "," : "") + "armv7" + llvm + thumb; } if (architectures.HasFlag(TargetArchitecture.ARMv7s)) { abi += (abi.Length > 0 ? "," : "") + "armv7s" + llvm + thumb; } if (architectures.HasFlag(TargetArchitecture.ARM64)) { // Note: ARM64 does not have thumb. abi += (abi.Length > 0 ? "," : "") + "arm64" + llvm; } if (architectures.HasFlag(TargetArchitecture.ARMv7k)) { abi += (abi.Length > 0 ? "," : "") + "armv7k" + llvm; } if (string.IsNullOrEmpty(abi)) { abi = "armv7" + llvm + thumb; } } // Output the CompiledArchitectures CompiledArchitectures = architectures.ToString(); args.AddLine($"--abi={abi}"); // output symbols to preserve when stripping args.AddQuotedLine($"--symbollist={Path.GetFullPath (SymbolsList)}"); // don't have mtouch generate the dsyms... args.AddLine("--dsym=no"); if (!string.IsNullOrEmpty(ArchiveSymbols) && bool.TryParse(ArchiveSymbols.Trim(), out msym)) { args.AddLine($"--msym={(msym ? "yes" : "no")}"); } var gcc = new GccOptions(); if (!string.IsNullOrEmpty(ExtraArgs)) { var extraArgs = CommandLineArgumentBuilder.Parse(ExtraArgs); var target = MainAssembly.ItemSpec; string projectDir; if (ProjectDir.StartsWith("~/", StringComparison.Ordinal)) { // Note: Since the Visual Studio plugin doesn't know the user's home directory on the Mac build host, // it simply uses paths relative to "~/". Expand these paths to their full path equivalents. var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); projectDir = Path.Combine(home, ProjectDir.Substring(2)); } else { projectDir = ProjectDir; } var customTags = new Dictionary <string, string> (StringComparer.OrdinalIgnoreCase) { { "projectdir", projectDir }, // Apparently msbuild doesn't propagate the solution path, so we can't get it. // { "solutiondir", proj.ParentSolution != null ? proj.ParentSolution.BaseDirectory : proj.BaseDirectory }, { "appbundledir", AppBundleDir }, { "targetpath", Path.Combine(Path.GetDirectoryName(target), Path.GetFileName(target)) }, { "targetdir", Path.GetDirectoryName(target) }, { "targetname", Path.GetFileName(target) }, { "targetext", Path.GetExtension(target) }, }; for (int i = 0; i < extraArgs.Length; i++) { var argument = extraArgs[i]; int startIndex = 0; while (argument.Length > startIndex && argument[startIndex] == '-') { startIndex++; } int endIndex = startIndex; while (endIndex < argument.Length && argument[endIndex] != '=') { endIndex++; } int length = endIndex - startIndex; if (length == 9 && string.CompareOrdinal(argument, startIndex, "gcc_flags", 0, 9) == 0) { // user-defined -gcc_flags argument string flags = null; if (endIndex < extraArgs[i].Length) { flags = Unquote(argument, endIndex + 1); } else if (i + 1 < extraArgs.Length) { flags = extraArgs[++i]; } if (!string.IsNullOrEmpty(flags)) { var gccArgs = CommandLineArgumentBuilder.Parse(flags); for (int j = 0; j < gccArgs.Length; j++) { gcc.Arguments.Add(StringParserService.Parse(gccArgs[j], customTags)); } } } else { // other user-defined mtouch arguments unescapedArgs.Add(StringParserService.Parse(argument, customTags)); } } } BuildNativeReferenceFlags(gcc); BuildEntitlementFlags(gcc); foreach (var framework in gcc.Frameworks) { args.AddQuotedLine($"--framework={framework}"); } foreach (var framework in gcc.WeakFrameworks) { args.AddQuotedLine($"--weak-framework={framework}"); } if (gcc.Cxx) { args.AddLine("--cxx"); } if (gcc.Arguments.Length > 0) { unescapedArgs.Add($"--gcc_flags={gcc.Arguments.ToString ()}"); } foreach (var asm in References) { if (IsFrameworkItem(asm)) { args.AddQuotedLine($"-r={ResolveFrameworkFile (asm.ItemSpec)}"); } else { args.AddQuotedLine($"-r={Path.GetFullPath (asm.ItemSpec)}"); } } foreach (var ext in AppExtensionReferences) { args.AddQuotedLine($"--app-extension={Path.GetFullPath (ext.ItemSpec)}"); } args.AddLine($"--target-framework={TargetFrameworkIdentifier},{TargetFrameworkVersion}"); args.AddQuotedLine($"--root-assembly={Path.GetFullPath (MainAssembly.ItemSpec)}"); // We give the priority to the ExtraArgs to set the mtouch verbosity. if (string.IsNullOrEmpty(ExtraArgs) || (!string.IsNullOrEmpty(ExtraArgs) && !ExtraArgs.Contains("-q") && !ExtraArgs.Contains("-v"))) { args.AddLine(GetVerbosityLevel(Verbosity)); } if (!string.IsNullOrWhiteSpace(License)) { args.AddLine($"--license={License}"); } // Generate a response file var responseFile = Path.GetFullPath(ResponseFilePath); if (File.Exists(responseFile)) { File.Delete(responseFile); } try { using (var fs = File.Create(responseFile)) { using (var writer = new StreamWriter(fs)) writer.Write(args); } } catch (Exception ex) { Log.LogWarning("Failed to create response file '{0}': {1}", responseFile, ex); } // Some arguments can not safely go in the response file and are // added separately. They must go _after_ the response file // as they may override options passed in the response file var actualArgs = new CommandLineArgumentBuilder(); actualArgs.AddQuoted($"@{responseFile}"); foreach (var arg in unescapedArgs) { actualArgs.AddQuoted(arg); } return(actualArgs.ToString()); }
void BuildNativeReferenceFlags(GccOptions gcc) { if (NativeReferences == null) return; foreach (var item in NativeReferences) { var value = item.GetMetadata ("Kind"); NativeReferenceKind kind; bool boolean; if (string.IsNullOrEmpty (value) || !Enum.TryParse (value, out kind)) { Log.LogWarning ("Unknown native reference type for '{0}'.", item.ItemSpec); continue; } if (kind == NativeReferenceKind.Static) { var libName = Path.GetFileName (item.ItemSpec); if (libName.EndsWith (".a", StringComparison.Ordinal)) libName = libName.Substring (0, libName.Length - 2); if (libName.StartsWith ("lib", StringComparison.Ordinal)) libName = libName.Substring (3); if (!string.IsNullOrEmpty (Path.GetDirectoryName (item.ItemSpec))) gcc.Arguments.AddQuoted ("-L" + Path.GetDirectoryName (item.ItemSpec)); gcc.Arguments.AddQuoted ("-l" + libName); value = item.GetMetadata ("ForceLoad"); if (!string.IsNullOrEmpty (value) && bool.TryParse (value, out boolean) && boolean) { gcc.Arguments.Add ("-force_load"); gcc.Arguments.AddQuoted (item.ItemSpec); } value = item.GetMetadata ("IsCxx"); if (!string.IsNullOrEmpty (value) && bool.TryParse (value, out boolean) && boolean) gcc.Cxx = true; } else if (kind == NativeReferenceKind.Framework) { gcc.Frameworks.Add (item.ItemSpec); } else { Log.LogWarning ("Dynamic native references are not supported: '{0}'", item.ItemSpec); continue; } value = item.GetMetadata ("NeedsGccExceptionHandling"); if (!string.IsNullOrEmpty (value) && bool.TryParse (value, out boolean) && boolean) { if (!gcc.Arguments.Contains ("-lgcc_eh")) gcc.Arguments.Add ("-lgcc_eh"); } value = item.GetMetadata ("WeakFrameworks"); if (!string.IsNullOrEmpty (value)) { foreach (var framework in value.Split (' ', '\t')) gcc.WeakFrameworks.Add (framework); } value = item.GetMetadata ("Frameworks"); if (!string.IsNullOrEmpty (value)) { foreach (var framework in value.Split (' ', '\t')) gcc.Frameworks.Add (framework); } // Note: these get merged into gccArgs by our caller value = item.GetMetadata ("LinkerFlags"); if (!string.IsNullOrEmpty (value)) { var linkerFlags = ProcessArgumentBuilder.Parse (value); foreach (var flag in linkerFlags) gcc.Arguments.AddQuoted (flag); } } }
void BuildEntitlementFlags(GccOptions gcc) { if (SdkIsSimulator && !string.IsNullOrEmpty (CompiledEntitlements) && EntitlementsRequireLinkerFlags (CompiledEntitlements)) { gcc.Arguments.AddQuoted (new [] { "-Xlinker", "-sectcreate", "-Xlinker", "__TEXT", "-Xlinker", "__entitlements" }); gcc.Arguments.Add ("-Xlinker"); gcc.Arguments.AddQuoted (Path.GetFullPath (CompiledEntitlements)); } }
protected override string GenerateCommandLineCommands() { var args = new ProcessArgumentBuilder (); TargetArchitecture architectures; if (string.IsNullOrEmpty (Architectures) || !Enum.TryParse (Architectures, out architectures)) architectures = TargetArchitecture.Default; if (architectures == TargetArchitecture.ARMv6) { Log.LogError ("Target architecture ARMv6 is no longer supported in Xamarin.iOS. Please select a supported architecture."); return null; } if (IsClassic && minimumOSVersion < IPhoneSdkVersion.V3_1 && architectures.HasFlag (TargetArchitecture.ARMv7)) { Log.LogWarning (null, null, null, AppManifest.ItemSpec, 0, 0, 0, 0, "Deployment Target changed from iOS {0} to iOS 3.1 (minimum requirement for ARMv7)", minimumOSVersion); minimumOSVersion = IPhoneSdkVersion.V3_1; } if (!string.IsNullOrEmpty (IntermediateOutputPath)) { Directory.CreateDirectory (IntermediateOutputPath); args.Add ("--cache"); args.AddQuoted (Path.GetFullPath (IntermediateOutputPath)); } if (IsClassic || IPhoneSdks.MonoTouch.Version < new IPhoneSdkVersion (8, 5, 0)) { args.Add ("--nomanifest"); args.Add ("--nosign"); } args.Add (SdkIsSimulator ? "--sim" : "--dev"); args.AddQuoted (Path.GetFullPath (AppBundleDir)); if (AppleSdkSettings.XcodeVersion.Major >= 5 && IPhoneSdks.MonoTouch.Version.CompareTo (new IPhoneSdkVersion (6, 3, 7)) < 0) args.Add ("--compiler", "clang"); args.Add ("--executable"); args.AddQuoted (ExecutableName); if (IsAppExtension) args.Add ("--extension"); if (Debug) { if (FastDev && IPhoneSdks.MonoTouch.SupportsFastDev) args.Add ("--fastdev"); args.Add ("--debug"); } if (Profiling) args.Add ("--profiling"); if (LinkerDumpDependencies) args.Add ("--linkerdumpdependencies"); switch (LinkMode.ToLowerInvariant ()) { case "sdkonly": args.Add ("--linksdkonly"); break; case "none": args.Add ("--nolink"); break; } if (!string.IsNullOrEmpty (I18n)) { args.Add ("--i18n"); args.AddQuotedFormat (I18n); } args.Add ("--sdkroot"); args.AddQuoted (SdkRoot); args.Add ("--sdk"); args.AddQuoted (SdkVersion); if (!minimumOSVersion.IsUseDefault) { args.Add ("--targetver"); args.AddQuoted (minimumOSVersion.ToString ()); } if (UseFloat32 /* We want to compile 32-bit floating point code to use 32-bit floating point operations */) args.Add ("--aot-options=-O=float32"); if (IPhoneSdks.MonoTouch.SupportsGenericValueTypeSharing) { if (!EnableGenericValueTypeSharing) args.Add ("--gsharedvt=false"); } if (LinkDescriptions != null) { foreach (var desc in LinkDescriptions) args.AddQuoted (string.Format ("--xml={0}", desc.ItemSpec)); } if (EnableBitcode) { switch (Framework) { case PlatformFramework.WatchOS: args.Add ("--bitcode=full"); break; case PlatformFramework.TVOS: args.Add ("--bitcode=asmonly"); break; default: throw new InvalidOperationException (string.Format ("Bitcode is currently not supported on {0}.", Framework)); } } if (!string.IsNullOrEmpty (HttpClientHandler)) args.Add (string.Format ("--http-message-handler={0}", HttpClientHandler)); if (!string.IsNullOrEmpty (TLSProvider)) args.Add (string.Format ("--tls-provider={0}", TLSProvider.ToLowerInvariant())); string thumb = UseThumb && UseLlvm ? "+thumb2" : ""; string llvm = UseLlvm ? "+llvm" : ""; string abi = ""; if (SdkIsSimulator) { if (architectures.HasFlag (TargetArchitecture.i386)) abi += (abi.Length > 0 ? "," : "") + "i386"; if (architectures.HasFlag (TargetArchitecture.x86_64)) abi += (abi.Length > 0 ? "," : "") + "x86_64"; if (string.IsNullOrEmpty (abi)) { architectures = TargetArchitecture.i386; abi = "i386"; } } else { if (architectures == TargetArchitecture.Default) architectures = TargetArchitecture.ARMv7; if (architectures.HasFlag (TargetArchitecture.ARMv7)) abi += (abi.Length > 0 ? "," : "") + "armv7" + llvm + thumb; if (architectures.HasFlag (TargetArchitecture.ARMv7s)) abi += (abi.Length > 0 ? "," : "") + "armv7s" + llvm + thumb; if (architectures.HasFlag (TargetArchitecture.ARM64)) { // Note: ARM64 does not have thumb. abi += (abi.Length > 0 ? "," : "") + "arm64" + llvm; } if (architectures.HasFlag (TargetArchitecture.ARMv7k)) abi += (abi.Length > 0 ? "," : "") + "armv7k"; if (string.IsNullOrEmpty (abi)) abi = "armv7" + llvm + thumb; } // Output the CompiledArchitectures CompiledArchitectures = architectures.ToString (); args.Add ("--abi=" + abi); // output symbols to preserve when stripping args.Add ("--symbollist"); args.AddQuoted (Path.GetFullPath (SymbolsList)); // don't have mtouch generate the dsyms... args.Add ("--dsym=no"); var gcc = new GccOptions (); if (!string.IsNullOrEmpty (ExtraArgs)) { var extraArgs = ProcessArgumentBuilder.Parse (ExtraArgs); var target = MainAssembly.ItemSpec; string projectDir; if (ProjectDir.StartsWith ("~/", StringComparison.Ordinal)) { // Note: Since the Visual Studio plugin doesn't know the user's home directory on the Mac build host, // it simply uses paths relative to "~/". Expand these paths to their full path equivalents. var home = Environment.GetFolderPath (Environment.SpecialFolder.UserProfile); projectDir = Path.Combine (home, ProjectDir.Substring (2)); } else { projectDir = ProjectDir; } var customTags = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase) { { "projectdir", projectDir }, // Apparently msbuild doesn't propagate the solution path, so we can't get it. // { "solutiondir", proj.ParentSolution != null ? proj.ParentSolution.BaseDirectory : proj.BaseDirectory }, { "appbundledir", AppBundleDir }, { "targetpath", Path.Combine (Path.GetDirectoryName (target), Path.GetFileName (target)) }, { "targetdir", Path.GetDirectoryName (target) }, { "targetname", Path.GetFileName (target) }, { "targetext", Path.GetExtension (target) }, }; for (int i = 0; i < extraArgs.Length; i++) { if (extraArgs[i] == "-gcc_flags" || extraArgs[i] == "--gcc_flags") { // user-defined -gcc_flags argument if (i + 1 < extraArgs.Length && !string.IsNullOrEmpty (extraArgs[i + 1])) { var gccArgs = ProcessArgumentBuilder.Parse (extraArgs[i + 1]); for (int j = 0; j < gccArgs.Length; j++) gcc.Arguments.Add (StringParserService.Parse (gccArgs[j], customTags)); } i++; } else { // other user-defined mtouch arguments args.AddQuoted (StringParserService.Parse (extraArgs[i], customTags)); } } } BuildNativeReferenceFlags (gcc); BuildEntitlementFlags (gcc); foreach (var framework in gcc.Frameworks) { args.Add ("-framework"); args.AddQuoted (framework); } foreach (var framework in gcc.WeakFrameworks) { args.Add ("-weak-framework"); args.AddQuoted (framework); } if (gcc.Cxx) args.Add ("--cxx"); if (gcc.Arguments.Length > 0) { args.Add ("--gcc_flags"); args.AddQuoted (gcc.Arguments.ToString ()); } foreach (var asm in References) { args.Add ("-r"); if (IsFrameworkItem(asm)) { args.AddQuoted (ResolveFrameworkFile(asm.ItemSpec)); } else { args.AddQuoted (Path.GetFullPath (asm.ItemSpec)); } } foreach (var ext in AppExtensionReferences) { args.Add ("--app-extension"); args.AddQuoted (Path.GetFullPath (ext.ItemSpec)); } args.Add ("--target-framework"); args.Add (TargetFrameworkIdentifier + "," + TargetFrameworkVersion); args.AddQuoted (MainAssembly.ItemSpec); // We give the priority to the ExtraArgs to set the mtouch verbosity. if (string.IsNullOrEmpty (ExtraArgs) || (!string.IsNullOrEmpty (ExtraArgs) && !ExtraArgs.Contains ("-q") && !ExtraArgs.Contains ("-v"))) args.Add (GetVerbosityLevel (Verbosity)); if (!string.IsNullOrWhiteSpace (License)) args.Add (string.Format("--license={0}", License)); return args.ToString (); }
void BuildNativeReferenceFlags(GccOptions gcc) { if (NativeReferences == null) { return; } foreach (var item in NativeReferences) { var value = item.GetMetadata("Kind"); NativeReferenceKind kind; bool boolean; if (string.IsNullOrEmpty(value) || !Enum.TryParse(value, out kind)) { Log.LogWarning(MSBStrings.W0051, item.ItemSpec); continue; } if (kind == NativeReferenceKind.Static) { var libName = Path.GetFileName(item.ItemSpec); if (libName.EndsWith(".a", StringComparison.Ordinal)) { libName = libName.Substring(0, libName.Length - 2); } if (libName.StartsWith("lib", StringComparison.Ordinal)) { libName = libName.Substring(3); } if (!string.IsNullOrEmpty(Path.GetDirectoryName(item.ItemSpec))) { gcc.Arguments.AddQuoted("-L" + Path.GetDirectoryName(item.ItemSpec)); } gcc.Arguments.AddQuoted("-l" + libName); value = item.GetMetadata("ForceLoad"); if (!string.IsNullOrEmpty(value) && bool.TryParse(value, out boolean) && boolean) { gcc.Arguments.Add("-force_load"); gcc.Arguments.AddQuoted(item.ItemSpec); } value = item.GetMetadata("IsCxx"); if (!string.IsNullOrEmpty(value) && bool.TryParse(value, out boolean) && boolean) { gcc.Cxx = true; } } else if (kind == NativeReferenceKind.Framework) { var path = item.ItemSpec; // in case the full path to the library is given (msbuild) if (Path.GetExtension(path) != ".framework") { path = Path.GetDirectoryName(path); } gcc.Frameworks.Add(path); } else { Log.LogWarning(MSBStrings.W0052, item.ItemSpec); continue; } value = item.GetMetadata("NeedsGccExceptionHandling"); if (!string.IsNullOrEmpty(value) && bool.TryParse(value, out boolean) && boolean) { if (!gcc.Arguments.Contains("-lgcc_eh")) { gcc.Arguments.Add("-lgcc_eh"); } } value = item.GetMetadata("WeakFrameworks"); if (!string.IsNullOrEmpty(value)) { foreach (var framework in value.Split(' ', '\t')) { gcc.WeakFrameworks.Add(framework); } } value = item.GetMetadata("Frameworks"); if (!string.IsNullOrEmpty(value)) { foreach (var framework in value.Split(' ', '\t')) { gcc.Frameworks.Add(framework); } } // Note: these get merged into gccArgs by our caller value = item.GetMetadata("LinkerFlags"); if (!string.IsNullOrEmpty(value)) { var linkerFlags = CommandLineArgumentBuilder.Parse(value); foreach (var flag in linkerFlags) { gcc.Arguments.AddQuoted(flag); } } } }