Skip to content

Commit

Permalink
[mmp/mtouch] Don't link with frameworks not available in the current …
Browse files Browse the repository at this point in the history
…SDK. Fixes #59636. (#2777)

We already have this logic for frameworks we detect according to the namespace
of the used types, but not for frameworks we detect from P/Invokes.

Fix this by using the same framework exclusion logic for frameworks detected
from P/Invokes: don't link with frameworks not available in the current SDK.

https://bugzilla.xamarin.com/show_bug.cgi?id=59636
  • Loading branch information
rolfbjarne authored Sep 27, 2017
1 parent ee91b95 commit a867c4f
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 12 deletions.
22 changes: 11 additions & 11 deletions tests/common/mac/ProjectTestHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ public static Version FindMonoVersion ()
return new Version (versionRegex.Match (output).Value.Split (' ')[2]);
}

public static string RunAndAssert (string exe, string args, string stepName, bool shouldFail = false, Func<string> getAdditionalFailInfo = null)
public static string RunAndAssert (string exe, string args, string stepName, bool shouldFail = false, Func<string> getAdditionalFailInfo = null, string[] environment = null)
{
StringBuilder output = new StringBuilder ();
Environment.SetEnvironmentVariable ("MONO_PATH", null);
int compileResult = Xamarin.Bundler.Driver.RunCommand (exe, args != null ? args.ToString() : string.Empty, null, output, suppressPrintOnErrors: shouldFail);
int compileResult = Xamarin.Bundler.Driver.RunCommand (exe, args != null ? args.ToString() : string.Empty, environment, output, suppressPrintOnErrors: shouldFail);
if (!shouldFail && compileResult != 0 && Xamarin.Bundler.Driver.Verbosity < 1) {
// Driver.RunCommand won't print failed output unless verbosity > 0, so let's do it ourselves.
Console.WriteLine ($"Execution failed; exit code: {compileResult}");
Expand All @@ -96,9 +96,9 @@ public static string RunAndAssert (string exe, string args, string stepName, boo
return output.ToString ();
}

public static string RunAndAssert (string exe, StringBuilder args, string stepName, bool shouldFail = false, Func<string> getAdditionalFailInfo = null)
public static string RunAndAssert (string exe, StringBuilder args, string stepName, bool shouldFail = false, Func<string> getAdditionalFailInfo = null, string[] environment = null)
{
return RunAndAssert (exe, args.ToString (), stepName, shouldFail, getAdditionalFailInfo);
return RunAndAssert (exe, args.ToString (), stepName, shouldFail, getAdditionalFailInfo, environment);
}

// In most cases we generate projects in tmp and this is not needed. But nuget and test projects can make that hard
Expand All @@ -107,7 +107,7 @@ public static void CleanUnifiedProject (string csprojTarget, bool useMSBuild = f
RunAndAssert ("/Library/Frameworks/Mono.framework/Commands/" + (useMSBuild ? "msbuild" : "xbuild"), new StringBuilder (csprojTarget + " /t:clean"), "Clean");
}

public static string BuildProject (string csprojTarget, bool isUnified, bool diagnosticMSBuild = false, bool shouldFail = false, bool useMSBuild = false, string configuration = null)
public static string BuildProject (string csprojTarget, bool isUnified, bool diagnosticMSBuild = false, bool shouldFail = false, bool useMSBuild = false, string configuration = null, string[] environment = null)
{
string rootDirectory = FindRootDirectory ();

Expand Down Expand Up @@ -140,9 +140,9 @@ public static string BuildProject (string csprojTarget, bool isUnified, bool dia
};

if (isUnified)
return RunAndAssert ("/Library/Frameworks/Mono.framework/Commands/" + (useMSBuild ? "msbuild" : "xbuild"), buildArgs, "Compile", shouldFail, getBuildProjectErrorInfo);
return RunAndAssert ("/Library/Frameworks/Mono.framework/Commands/" + (useMSBuild ? "msbuild" : "xbuild"), buildArgs, "Compile", shouldFail, getBuildProjectErrorInfo, environment);
else
return RunAndAssert ("/Applications/Visual Studio.app/Contents/MacOS/vstool", buildArgs, "Compile", shouldFail, getBuildProjectErrorInfo);
return RunAndAssert ("/Applications/Visual Studio.app/Contents/MacOS/vstool", buildArgs, "Compile", shouldFail, getBuildProjectErrorInfo, environment);
}

static string ProjectTextReplacement (UnifiedTestConfig config, string text)
Expand Down Expand Up @@ -242,10 +242,10 @@ public static string GenerateUnifiedExecutableProject (UnifiedTestConfig config)
return GenerateEXEProject (config);
}

public static string GenerateAndBuildUnifiedExecutable (UnifiedTestConfig config, bool shouldFail = false, bool useMSBuild = false, string configuration = null)
public static string GenerateAndBuildUnifiedExecutable (UnifiedTestConfig config, bool shouldFail = false, bool useMSBuild = false, string configuration = null, string[] environment = null)
{
string csprojTarget = GenerateUnifiedExecutableProject (config);
return BuildProject (csprojTarget, isUnified: true, diagnosticMSBuild: config.DiagnosticMSBuild, shouldFail: shouldFail, useMSBuild: useMSBuild, configuration: configuration);
return BuildProject (csprojTarget, isUnified: true, diagnosticMSBuild: config.DiagnosticMSBuild, shouldFail: shouldFail, useMSBuild: useMSBuild, configuration: configuration, environment: environment);
}

public static string RunGeneratedUnifiedExecutable (UnifiedTestConfig config)
Expand All @@ -255,7 +255,7 @@ public static string RunGeneratedUnifiedExecutable (UnifiedTestConfig config)
return RunEXEAndVerifyGUID (config.TmpDir, config.guid, exePath);
}

public static OutputText TestUnifiedExecutable (UnifiedTestConfig config, bool shouldFail = false, bool useMSBuild = false, string configuration = null)
public static OutputText TestUnifiedExecutable (UnifiedTestConfig config, bool shouldFail = false, bool useMSBuild = false, string configuration = null, string[] environment = null)
{
// If we've already generated guid bits for this config, don't tack on a second copy
if (config.guid == Guid.Empty)
Expand All @@ -264,7 +264,7 @@ public static OutputText TestUnifiedExecutable (UnifiedTestConfig config, bool s
config.TestCode += GenerateOutputCommand (config.TmpDir, config.guid);
}

string buildOutput = GenerateAndBuildUnifiedExecutable (config, shouldFail, useMSBuild, configuration);
string buildOutput = GenerateAndBuildUnifiedExecutable (config, shouldFail, useMSBuild, configuration, environment);
if (shouldFail)
return new OutputText (buildOutput, "");

Expand Down
16 changes: 16 additions & 0 deletions tests/mmptest/src/MMPTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -758,5 +758,21 @@ public void Unified32BitWithXMRequiringLibrary_ShouldReferenceCorrectXM_AndNotCr
TI.TestUnifiedExecutable (test);
});
}

[Test]
public void OldXcodeTest ()
{
var oldXcode = Xamarin.Tests.Configuration.GetOldXcodeRoot ();

if (string.IsNullOrEmpty (oldXcode))
Assert.Ignore ("This test needs an old Xcode.");

RunMMPTest (tmpDir => {
TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) {
CSProjConfig = "<DebugSymbols>True</DebugSymbols>", // This makes the msbuild tasks pass /debug to mmp
};
TI.TestUnifiedExecutable (test, shouldFail: false, configuration: "Debug", environment: new string [] { "MD_APPLE_SDK_ROOT", Path.GetDirectoryName (Path.GetDirectoryName (oldXcode)) });
});
}
}
}
5 changes: 4 additions & 1 deletion tools/common/Assembly.cs
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,10 @@ public void ComputeLinkerFlags ()
// detect frameworks
int f = name.IndexOf (".framework/", StringComparison.Ordinal);
if (f > 0) {
if (Frameworks.Add (file))
Framework framework;
if (Driver.GetFrameworks (App).TryGetValue (file, out framework) && framework.Version > App.SdkVersion)
Driver.Log (3, "Not linking with the framework {0} (referenced by a module reference in {1}) because it was introduced in {2} {3}, and we're using the {2} {4} SDK.", file, FileName, App.PlatformName, framework.Version, App.SdkVersion);
else if (Frameworks.Add (file))
Driver.Log (3, "Linking with the framework {0} because it's referenced by a module reference in {1}", file, FileName);
} else {
if (UnresolvedModuleReferences == null)
Expand Down
2 changes: 2 additions & 0 deletions tools/common/Target.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ public void GatherFrameworks ()
var add_to = App.DeploymentTarget >= framework.Version ? asm.Frameworks : asm.WeakFrameworks;
add_to.Add (framework.Name);
continue;
} else {
Driver.Log (3, "Not linking with the framework {0} (used by the type {1}) because it was introduced in {2} {3}, and we're using the {2} {4} SDK.", framework.Name, td.FullName, App.PlatformName, framework.Version, App.SdkVersion);
}
}
}
Expand Down

0 comments on commit a867c4f

Please sign in to comment.