[XM] Fix crash in mmp when native reference path matches dllimport found

- When native_libs.Add (nr, null) was hit above and then we later matched
 we would call methods.AddRange (kvp.Value) on an empty methods
This commit is contained in:
Chris Hamons 2016-11-23 14:00:01 -06:00
Родитель c83fa8a9bb
Коммит ce464cacc3
5 изменённых файлов: 46 добавлений и 7 удалений

Просмотреть файл

@ -35,6 +35,7 @@ namespace Xamarin.MMP.Tests
public bool DiagnosticMSBuild { get; set; }
public string ProjectName { get; set; }
public string TestCode { get; set; }
public string TestDecl { get; set; }
public string CSProjConfig { get; set; }
public string References { get; set; }
public string AssemblyName { get; set; }
@ -53,6 +54,7 @@ namespace Xamarin.MMP.Tests
TmpDir = tmpDir;
ProjectName = "";
TestCode = "";
TestDecl = "";
CSProjConfig = "";
References = "";
AssemblyName = "";
@ -144,7 +146,7 @@ namespace Xamarin.MMP.Tests
public static string GenerateEXEProject (UnifiedTestConfig config)
{
WriteMainFile (config.TestCode, true, config.FSharp, Path.Combine (config.TmpDir, config.FSharp ? "Main.fs" : "Main.cs"));
WriteMainFile (config.TestDecl, config.TestCode, true, config.FSharp, Path.Combine (config.TmpDir, config.FSharp ? "Main.fs" : "Main.cs"));
string sourceDir = FindSourceDirectory ();
File.Copy (Path.Combine (sourceDir, "Info-Unified.plist"), Path.Combine (config.TmpDir, "Info.plist"), true);
@ -258,7 +260,7 @@ namespace Xamarin.MMP.Tests
public static string GenerateClassicEXEProject (string tmpDir, string projectName, string testCode, string csprojConfig = "", string references = "", string assemblyName = null)
{
WriteMainFile (testCode, false, false, Path.Combine (tmpDir, "Main.cs"));
WriteMainFile ("", testCode, false, false, Path.Combine (tmpDir, "Main.cs"));
string sourceDir = FindSourceDirectory ();
File.Copy (Path.Combine (sourceDir, "Info-Classic.plist"), Path.Combine (tmpDir, "Info.plist"), true);
@ -277,7 +279,7 @@ namespace Xamarin.MMP.Tests
public static string GenerateSystemMonoEXEProject (UnifiedTestConfig config)
{
WriteMainFile (config.TestCode, true, false, Path.Combine (config.TmpDir, "Main.cs"));
WriteMainFile (config.TestDecl, config.TestCode, true, false, Path.Combine (config.TmpDir, "Main.cs"));
string sourceDir = FindSourceDirectory ();
File.Copy (Path.Combine (sourceDir, "Info-Unified.plist"), Path.Combine (config.TmpDir, "Info.plist"), true);
@ -325,7 +327,7 @@ namespace Xamarin.MMP.Tests
}
}
static void WriteMainFile (string content, bool isUnified, bool fsharp, string location)
static void WriteMainFile (string decl, string content, bool isUnified, bool fsharp, string location)
{
const string FSharpMainTemplate = @"
namespace FSharpUnifiedExample
@ -333,6 +335,8 @@ open System
open AppKit
module main =
%DECL%
[<EntryPoint>]
let main args =
NSApplication.Init ()
@ -347,6 +351,8 @@ namespace TestCase
{
class MainClass
{
%DECL%
static void Main (string[] args)
{
NSApplication.Init ();
@ -355,7 +361,7 @@ namespace TestCase
}
}";
string currentTemplate = fsharp ? FSharpMainTemplate : MainTemplate;
string testCase = currentTemplate.Replace("%CODE%", content);
string testCase = currentTemplate.Replace ("%CODE%", content).Replace ("%DECL%", decl);
if (isUnified)
testCase = testCase.Replace ("MonoMac.", string.Empty);
using (StreamWriter s = new StreamWriter (location))

Просмотреть файл

@ -1,5 +1,7 @@
#import <Cocoa/Cocoa.h>
int GetFour ();
@interface SimpleClass : NSObject
- (int) doIt;

Просмотреть файл

@ -1,5 +1,10 @@
#import "SimpleClass.h"
int GetFour ()
{
return 4;
}
@implementation SimpleClass
- (int)doIt {

Просмотреть файл

@ -145,5 +145,25 @@ namespace Xamarin.MMP.Tests
if (libraryName != null)
Assert.IsTrue (Directory.GetFiles (xm45BundlePath).Any (x => x.Contains (libraryName) == !libraryShouldNotBeCopied), string.Format ("{0} - XM45 - We did not pull in native lib: {1}", testName, libraryName));
}
[Test]
public void NativeReference_WithDllImportOfSamePath_Builds ()
{
RunMMPTest (tmpDir =>
{
string dylibPath = Path.Combine (tmpDir, "dll/");
string filePath = Path.Combine (dylibPath, "SimpleClassDylib.dylib");
Directory.CreateDirectory (dylibPath);
File.Copy (Path.Combine (TI.AssemblyDirectory, TI.TestDirectory + "mac-binding-project/bin/SimpleClassDylib.dylib"), filePath);
// Use absolute path here and in TestDecl to trigger bug
string itemGroup = string.Format ("<ItemGroup><NativeReference Include=\"{0}\"> <IsCxx>False</IsCxx><Kind>Dynamic</Kind> </NativeReference> </ItemGroup>", filePath);
TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir) { ProjectName = "UnifiedExample.csproj", ItemGroup = itemGroup };
test.TestDecl = string.Format ("[System.Runtime.InteropServices.DllImport (\"{0}\")]public static extern int GetFour ();", filePath);
test.TestCode = "GetFour ();";
NativeReferenceTestCore (tmpDir, test, "NativeReference_WithDllImportOfSamePath_Builds", null, true, true);
});
}
}
}

Просмотреть файл

@ -612,10 +612,16 @@ namespace Xamarin.Bundler {
var linked_native_libs = Link ();
foreach (var kvp in linked_native_libs) {
List<MethodDefinition> methods;
if (native_libs.TryGetValue (kvp.Key, out methods))
if (native_libs.TryGetValue (kvp.Key, out methods)) {
if (methods == null) {
methods = new List<MethodDefinition> ();
native_libs [kvp.Key] = methods;
}
methods.AddRange (kvp.Value);
else
}
else {
native_libs.Add (kvp.Key, kvp.Value);
}
}
internalSymbols.UnionWith (BuildTarget.LinkContext.RequiredSymbols.Keys);
Watch (string.Format ("Linking (mode: '{0}')", App.LinkMode), 1);