Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[msbuild] Have XcodeCompilerToolTask use xcrun to start Apple tools #9965

Merged
merged 4 commits into from
Oct 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 32 additions & 11 deletions msbuild/Xamarin.MacDev.Tasks.Core/Tasks/XcodeCompilerToolTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Text;
using System.Diagnostics;
using System.Collections.Generic;
using System.Runtime.InteropServices;

using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
Expand Down Expand Up @@ -101,16 +102,6 @@ protected virtual IEnumerable<string> GetTargetDevices (PDictionary plist)

protected abstract void AppendCommandLineArguments (IDictionary<string, string> environment, CommandLineArgumentBuilder args, ITaskItem[] items);

string GetFullPathToTool ()
{
if (!string.IsNullOrEmpty (ToolPath))
return Path.Combine (ToolPath, ToolExe);

var path = Path.Combine (DefaultBinDir, ToolExe);

return File.Exists (path) ? path : ToolExe;
}

static ProcessStartInfo GetProcessStartInfo (IDictionary<string, string> environment, string tool, string args)
{
var startInfo = new ProcessStartInfo (tool, args);
Expand All @@ -125,6 +116,22 @@ static ProcessStartInfo GetProcessStartInfo (IDictionary<string, string> environ
return startInfo;
}

static bool? translated;

[DllImport ("/usr/lib/libSystem.dylib", SetLastError = true)]
static extern int sysctlbyname (/* const char */ [MarshalAs (UnmanagedType.LPStr)] string property, ref long oldp, ref long oldlenp, IntPtr newp, /* size_t */ long newlen);

// https://developer.apple.com/documentation/apple_silicon/about_the_rosetta_translation_environment
static bool IsTranslated ()
{
if (translated == null) {
long result = 0;
long size = sizeof (long);
translated = ((sysctlbyname ("sysctl.proc_translated", ref result, ref size, IntPtr.Zero, 0) != -1) && (result == 1));
}
return translated.Value;
}

protected int Compile (ITaskItem[] items, string output, ITaskItem manifest)
{
var environment = new Dictionary<string, string> ();
Expand All @@ -136,6 +143,20 @@ protected int Compile (ITaskItem[] items, string output, ITaskItem manifest)
if (!string.IsNullOrEmpty (SdkUsrPath))
environment.Add ("XCODE_DEVELOPER_USR_PATH", SdkUsrPath);

if (!string.IsNullOrEmpty (SdkDevPath))
environment.Add ("DEVELOPER_DIR", SdkDevPath);

// workaround for ibtool[d] bug / asserts if Intel version is loaded
string tool;
if (IsTranslated ()) {
// we force the Intel (translated) msbuild process to launch ibtool as "Apple"
tool = "arch";
args.Add ("-arch", "arm64e");
args.Add ("/usr/bin/xcrun");
} else {
tool = "/usr/bin/xcrun";
}
args.Add (ToolName);
args.Add ("--errors", "--warnings", "--notices");
args.Add ("--output-format", "xml1");

Expand All @@ -153,7 +174,7 @@ protected int Compile (ITaskItem[] items, string output, ITaskItem manifest)
foreach (var item in items)
args.AddQuoted (item.GetMetadata ("FullPath"));

var startInfo = GetProcessStartInfo (environment, GetFullPathToTool (), args.ToString ());
var startInfo = GetProcessStartInfo (environment, tool, args.ToString ());
var errors = new StringBuilder ();
int exitCode;

Expand Down
7 changes: 4 additions & 3 deletions tests/mmptest/src/MMPTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,7 @@ public void MM0144 ()
[Test]
public void BuildingSameSolutionTwice_ShouldNotRunACToolTwice ()
{
const string actool = " execution started with arguments: actool --errors --warnings --notices --output-format xml1 --output-partial-info-plist ";
RunMMPTest (tmpDir => {
TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) {
AssetIcons = true
Expand All @@ -666,15 +667,15 @@ public void BuildingSameSolutionTwice_ShouldNotRunACToolTwice ()
string project = TI.GenerateUnifiedExecutableProject (test);

string buildOutput = TI.BuildProject (project);
Assert.True (buildOutput.Contains ("actool execution started with arguments"), $"Initial build should run actool");
Assert.True (buildOutput.Contains (actool), $"Initial build should run actool");

buildOutput = TI.BuildProject (project);
Assert.False (buildOutput.Contains ("actool execution started with arguments"), $"Second build should not run actool");
Assert.False (buildOutput.Contains (actool), $"Second build should not run actool");

TI.RunAndAssert ("touch", new [] { Path.Combine (tmpDir, "Assets.xcassets/AppIcon.appiconset/[email protected]") }, "touch icon");

buildOutput = TI.BuildProject (project);
Assert.True (buildOutput.Contains ("actool execution started with arguments"), $"Build after touching icon must run actool");
Assert.True (buildOutput.Contains (actool), $"Build after touching icon must run actool");
});
}

Expand Down