[Debugger] Allow to step into Xamarin code. (#1663)

* [Debugger] Allow to step into Xamarin code.

The tool now detects the different sources and mangles the path to
ensure that the correct paths are installed in the following location:

/Library/Frameworks/Xamarin.iOS/Versions/Current/src
/Library/Frameworks/Xamarin.Mac/Versions/Current/src

The tool will detect if the path map command was used in the mdb and pub files, will point to the correct source code and will copy it to the installation dir. 

Tests have been added that will be ran both by wrench and jenkins ensuring that changes in the manglers do not change it behaviour.
This commit is contained in:
Manuel de la Pena 2017-12-05 14:13:59 +01:00 коммит произвёл GitHub
Родитель db5a49050a
Коммит 8ed3f85c07
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
20 изменённых файлов: 1234 добавлений и 70 удалений

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

@ -291,10 +291,21 @@ include $(TOP)/mk/quiet.mk
MDTOOL?="/Applications/Visual Studio.app/Contents/MacOS/vstool" $(MDTOOL_VERBOSITY)
IOS_SOURCE=$(TOP)/src
IOS_BUILD_SOURCE=$(IOS_SOURCE)/build/ios/native
IOS_COMMON_BUILD_SOURCE=$(IOS_SOURCE)/build/common
MAC_SOURCE=$(TOP)/src
MAC_FULL_BUILD_SOURCE=$(MAC_SOURCE)/build/mac/full
MAC_MODERN_BUILD_SOURCE=$(MAC_SOURCE)/build/mac/mobile
MAC_COMMON_BUILD_SOURCE=$(MAC_SOURCE)/build/common
ifneq ($(BUILD_REVISION),)
# wrench build only
IOS_MCS_FLAGS=-pathmap:$(abspath $(MONO_PATH))/=$(IOS_FRAMEWORK_DIR)/Versions/$(IOS_PACKAGE_VERSION)/src/mono/
MAC_MCS_FLAGS=-pathmap:$(abspath $(MONO_PATH))/=$(MAC_FRAMEWORK_DIR)/Versions/$(MAC_PACKAGE_VERSION)/src/mono/
IOS_MCS_FLAGS="-pathmap:$(abspath $(MONO_PATH))/=$(IOS_FRAMEWORK_DIR)/Versions/$(IOS_PACKAGE_VERSION)/src/Xamarin.iOS/"
IOS_MCS_FLAGS_XI="-pathmap:$(abspath $(IOS_COMMON_BUILD_SOURCE))/=$(IOS_FRAMEWORK_DIR)/Versions/$(IOS_PACKAGE_VERSION)/src/Xamarin.iOS/ -pathmap:$(abspath $(IOS_BUILD_SOURCE))/=$(IOS_FRAMEWORK_DIR)/Versions/$(IOS_PACKAGE_VERSION)/src/Xamarin.iOS/ -pathmap:$(abspath $(IOS_SOURCE))/=$(IOS_FRAMEWORK_DIR)/Versions/$(IOS_PACKAGE_VERSION)/src/Xamarin.iOS/"
MAC_MCS_FLAGS="-pathmap:$(abspath $(MONO_PATH))/=$(MAC_FRAMEWORK_DIR)/Versions/$(MAC_PACKAGE_VERSION)/src/Xamarin.Mac/"
MAC_MCS_FLAGS_XM="-pathmap:$(abspath $(MAC_COMMON_BUILD_SOURCE))/=$(MAC_FRAMEWORK_DIR)/Versions/$(MAC_PACKAGE_VERSION)/src/Xamarin.Mac/ -pathmap:$(abspath $(MAC_FULL_BUILD_SOURCE))/=$(MAC_FRAMEWORK_DIR)/Versions/$(MAC_PACKAGE_VERSION)/src/Xamarin.Mac/ -pathmap:$(abspath $(MAC_MODERN_BUILD_SOURCE))/=$(MAC_FRAMEWORK_DIR)/Versions/$(MAC_PACKAGE_VERSION)/src/Xamarin.Mac/ -pathmap:$(abspath $(MAC_SOURCE))/=$(MAC_FRAMEWORK_DIR)/Versions/$(MAC_PACKAGE_VERSION)/src/Xamarin.Mac/"
endif
ifdef ENABLE_XAMARIN

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

@ -264,6 +264,10 @@ MAC_DIRECTORIES += \
$$(MAC_DESTDIR)$$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/$(1)/%: $$(BUILD_DESTDIR)/bcl/$(2)/% | $$(MAC_DESTDIR)$$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/$(1)/Facades
$$(Q) install -m 0755 $$< $$@
$$(MAC_DESTDIR)$$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/$(1)/%.pdb: $$(BUILD_DESTDIR)/mac/$(2)/bcl/%.pdb | $$(MAC_DESTDIR)$$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/$(1)/Facades
$$(Q) install -m 0644 $$< $$@
endef
$(eval $(call MacInstallBclTemplate,Xamarin.Mac,xammac))

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

@ -167,6 +167,7 @@ $(IOS_BUILD_DIR)/$(1)/$(3): $$(IOS_SOURCES) $(IOS_BUILD_DIR)/$(4)/generated_sour
-r:$(IOS_LIBDIR)/Mono.Security.dll \
-keyfile:$(PRODUCT_KEY_PATH) $$(IOS_DEFINES) \
-nowarn:219,618,114,414,1635,3021,$$(IOS_WARNINGS_THAT_YOU_SHOULD_FIX) \
$(IOS_MCS_FLAGS_XI) \
$$(IOS_SOURCES) @$(IOS_BUILD_DIR)/$(4)/generated_sources
$(IOS_BUILD_DIR)/$(1)/$(3).mdb: $(IOS_BUILD_DIR)/$(1)/$(3)
@ -558,6 +559,7 @@ $(MAC_BUILD_DIR)/$(1)/$(2): $(MAC_BUILD_DIR)/$(3)/generated-sources $(MAC_SOURCE
-r:Mono.Security.dll \
-keyfile:$(SN_KEY) \
-nowarn:3021,1635,612,618,0219,0414,$(MAC_WARNINGS_TO_FIX) \
$(MAC_MCS_FLAGS_XM) \
$(4) \
@$$< $$(MAC_SOURCES)
endef

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

@ -206,6 +206,13 @@ test-ios-tasks:
@[[ -z "$$BUILD_REPOSITORY" ]] || ( xsltproc $(TOP)/tests/HtmlTransform.xslt $(NUNIT_MSBUILD_DIR)/TestResults_Xamarin.iOS.Tasks.Tests.xml > $(TOP)/tests/index.html && echo "@MonkeyWrench: AddFile: $$PWD/index.html" )
@if test -e $(NUNIT_MSBUILD_DIR)/.failed-stamp; then rm $(NUNIT_MSBUILD_DIR)/.failed-stamp; exit 1; fi
test-install-sources:
$(SYSTEM_XBUILD) $(TOP)/tools/install-source/InstallSourcesTests/InstallSourcesTests.csproj
cd $(NUNIT_MSBUILD_DIR) && $(SYSTEM_MONO) ../nunit-console.exe ../../../../tools/install-source/InstallSourcesTests/bin/Release/InstallSourcesTests.dll -xml=TestResults_InstallSourcesTests.xml -labels $(TEST_FIXTURE) || touch .failed-stamp
@[[ -z "$$BUILD_REPOSITORY" ]] || ( xsltproc $(TOP)/tests/HtmlTransform.xslt $(NUNIT_MSBUILD_DIR)/TestResults_InstallSourcesTests.xml > $(TOP)/tests/index.html && echo "@MonkeyWrench: AddFile: $$PWD/index.html" )
@if test -e $(NUNIT_MSBUILD_DIR)/.failed-stamp; then rm $(NUNIT_MSBUILD_DIR)/.failed-stamp; exit 1; fi
ifdef ENABLE_XAMARIN
ifdef INCLUDE_IOS
qa-test-dependencies.zip:

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

@ -518,6 +518,26 @@ namespace xharness
};
Tasks.Add (nunitExecutioniOSMSBuild);
var buildInstallSources = new XBuildTask ()
{
Jenkins = this,
TestProject = new TestProject (Path.GetFullPath (Path.Combine (Harness.RootDirectory, "..", "tools", "install-source", "InstallSourcesTests", "InstallSourcesTests.csproj"))),
SpecifyPlatform = false,
SpecifyConfiguration = false,
Platform = TestPlatform.iOS,
};
var nunitExecutionInstallSource = new NUnitExecuteTask (buildInstallSources)
{
TestLibrary = Path.Combine (Harness.RootDirectory, "..", "tools", "install-source", "InstallSourcesTests", "bin", "Release", "InstallSourcesTests.dll"),
TestExecutable = Path.Combine (Harness.RootDirectory, "..", "packages", "NUnit.Runners.2.6.4", "tools", "nunit-console.exe"),
WorkingDirectory = Path.Combine (Harness.RootDirectory, "..", "packages", "NUnit.Runners.2.6.4", "tools", "lib"),
Platform = TestPlatform.iOS,
TestName = "Install Sources tests",
Mode = "iOS",
Timeout = TimeSpan.FromMinutes (60),
};
Tasks.Add (nunitExecutionInstallSource);
foreach (var project in Harness.MacTestProjects) {
bool ignored = !IncludeMac;
if (!IncludeMmpTest && project.Path.Contains ("mmptest"))

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

@ -0,0 +1,24 @@
using System;
namespace InstallSources
{
/// <summary>
/// Represents a class that knows how to change paths to ensure that the correct source path is used.
/// </summary>
public interface IPathMangler
{
/// <summary>
/// Returns the real source path for the given path found in an mdb.
/// </summary>
/// <returns>The source path related to the mdb path.</returns>
/// <param name="path">The path found in the mdb file.</param>
string GetSourcePath (string path);
/// <summary>
/// Returns the target were a source path should be installed.
/// </summary>
/// <returns>The target path for the installation.</returns>
/// <param name="path">The source path to install.</param>/
string GetTargetPath (string path);
}
}

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

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{795E0F7E-5C48-4C90-8F66-518359874022}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>InstallSourcesTests</RootNamespace>
<AssemblyName>InstallSourcesTests</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="Mono.CompilerServices.SymbolWriter" />
<Reference Include="nunit.framework">
<HintPath>..\..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="Mono.Cecil">
<HintPath>Mono.Cecil.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Compile Include="MonoPathManglerTest.cs" />
<Compile Include="XamarinSourcesPathManglerTest.cs" />
<Compile Include="OpenTKManglerTest.cs" />
<Compile Include="..\IPathMangler.cs">
<Link>IPathMangler.cs</Link>
</Compile>
<Compile Include="..\MonoPathMangler.cs">
<Link>MonoPathMangler.cs</Link>
</Compile>
<Compile Include="..\OpenTKSourceMangler.cs">
<Link>OpenTKSourceMangler.cs</Link>
</Compile>
<Compile Include="..\PathManglerFactory.cs">
<Link>PathManglerFactory.cs</Link>
</Compile>
<Compile Include="..\XamarinSourcesPathMangler.cs">
<Link>XamarinSourcesPathMangler.cs</Link>
</Compile>
<Compile Include="PathManclerFactoryTests.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

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

@ -0,0 +1,48 @@
using System;
using NUnit.Framework;
using InstallSources;
namespace InstallSourcesTests
{
[TestFixture]
public class MonoPathManglerTest
{
MonoPathMangler mangler;
string monoPath;
string installDir;
string destinationDir;
[SetUp]
public void SetUp ()
{
monoPath = "/Users/test/xamarin-macios/external/mono/";
installDir = "/Users/test/xamarin-macios/_ios-build//Library/Frameworks/Xamarin.iOS.framework/Versions/git";
destinationDir = "/Users/test/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git";
mangler = new MonoPathMangler {
InstallDir = installDir,
MonoSourcePath = monoPath,
DestinationDir = destinationDir,
};
}
[TestCase ("/Users/test/xamarin-macios/external/mono/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsAsyncState.cs")]
[TestCase ("/Users/test/xamarin-macios/external/mono/mcs/class/Mono.Security/Mono.Security.X509/X509StoreManager.cs")]
[TestCase ("/Users/test/xamarin-macios/external/mono/mcs/class/dlr/Runtime/Microsoft.Scripting.Core/Actions/UpdateDelegates.Generated.cs")]
public void TestGetSourcePath (string path)
{
Assert.AreEqual (path, mangler.GetSourcePath (path), "Failed getting path for '{0}'", path);
}
[TestCase ("/Users/test/xamarin-macios/external/mono/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsAsyncState.cs")]
[TestCase ("/Users/test/xamarin-macios/external/mono/mcs/class/Mono.Security/Mono.Security.X509/X509StoreManager.cs")]
[TestCase ("/Users/test/xamarin-macios/external/mono/mcs/class/dlr/Runtime/Microsoft.Scripting.Core/Actions/UpdateDelegates.Generated.cs")]
public void TestGetTargetPath (string path)
{
var targetPath = mangler.GetTargetPath (path);
Assert.IsFalse (targetPath.StartsWith (monoPath, StringComparison.InvariantCulture), "Path starts with the mono path.");
Assert.IsTrue (targetPath.StartsWith (destinationDir, StringComparison.InvariantCulture), "Path does not start with the install dir");
Assert.IsTrue (!targetPath.Contains ("mono"), "Path does contain 'mono'");
}
}
}

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

@ -0,0 +1,46 @@
using System;
using NUnit.Framework;
using InstallSources;
namespace InstallSourcesTests
{
[TestFixture]
public class OpenTKManglerTest
{
OpenTKSourceMangler mangler;
string openTKPath;
string installDir;
string destinationDir;
[SetUp]
public void SetUp ()
{
openTKPath = "/Users/test/xamarin-macios/external/opentk/Source/";
installDir = "/Users/test/xamarin-macios/_ios-build//Library/Frameworks/Xamarin.iOS.framework/Versions/git";
destinationDir = "/Users/test/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git";
mangler = new OpenTKSourceMangler {
InstallDir = installDir,
OpenTKSourcePath = openTKPath,
DestinationDir = destinationDir,
};
}
[TestCase ("/Users/test/xamarin-macios/external/opentk/Source/OpenTK/Math/BezierCurve.cs")]
[TestCase ("/Users/test/xamarin-macios/external/opentk/Source/OpenTK/Math/BezierCurveCubic.cs")]
public void TestGetSourcePath (string path)
{
Assert.AreEqual (path, mangler.GetSourcePath (path), "Failed getting path for '{0}'", path);
}
[TestCase ("/Users/test/xamarin-macios/external/opentk/Source/OpenTK/Math/BezierCurve.cs")]
[TestCase ("/Users/test/xamarin-macios/external/opentk/Source/OpenTK/Math/BezierCurveCubic.cs")]
public void TestGetTargetPath (string path)
{
var targetPath = mangler.GetTargetPath (path);
Assert.IsFalse (targetPath.StartsWith (openTKPath, StringComparison.InvariantCulture), "Path starts with the opentk path.");
Assert.IsTrue (targetPath.StartsWith (destinationDir, StringComparison.InvariantCulture), "Path does not start with the install dir");
Assert.IsTrue (targetPath.Contains ("/src/Xamarin.iOS/"), "Path does not contain 'src'");
}
}
}

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

@ -0,0 +1,107 @@
using System.IO;
using NUnit.Framework;
using InstallSources;
namespace InstallSourcesTests
{
[TestFixture]
public class PathManclerFactoryTests
{
string tmpRoot;
string installDir;
string fakeMonoPath;
string fakeOpenTKPath;
string fakeXamarinPath;
PathManglerFactory factory;
void CreateFakeFile (string path)
{
string[] lines = { "Test", "Fake", "file" };
using (StreamWriter outputFile = new StreamWriter (path)) {
foreach (string line in lines)
outputFile.WriteLine(line);
}
}
[SetUp]
public void SetUp ()
{
installDir = Path.GetTempFileName ();
if (File.Exists (installDir))
File.Delete (installDir);
installDir = Path.Combine (installDir, "Xamarin.iOS");
Directory.CreateDirectory (installDir);
// create temp dirs that will be used to place some files
// to test their presence and decide that the correct
// mangler is used
tmpRoot = Path.GetTempFileName ();
if (File.Exists (tmpRoot))
File.Delete (tmpRoot);
Directory.CreateDirectory (tmpRoot);
// create a path for the mono paths
var monoPath = Path.Combine (tmpRoot, "external", "mono");
Directory.CreateDirectory (monoPath);
fakeMonoPath = Path.Combine (monoPath, "FakeStirng.cs");
CreateFakeFile (fakeMonoPath);
// create a path for the xamarin paths
var xamarinPath = Path.Combine (tmpRoot, "src");
Directory.CreateDirectory (xamarinPath);
fakeXamarinPath = Path.Combine (xamarinPath, "FakeObjc.cs");
CreateFakeFile (fakeXamarinPath);
var openTKPath = Path.Combine (tmpRoot, "external", "OpenTK");
Directory.CreateDirectory (Path.Combine (openTKPath));
fakeOpenTKPath = Path.Combine (openTKPath, "FakeMaths.cs");
CreateFakeFile (fakeOpenTKPath);
factory = new PathManglerFactory()
{
InstallDir = installDir,
MonoSourcePath = monoPath,
XamarinSourcePath = xamarinPath,
OpenTKSourcePath = openTKPath
};
}
[TearDown]
public void TearDown ()
{
if (Directory.Exists (tmpRoot))
Directory.Delete (tmpRoot, true);
if (Directory.Exists (installDir))
Directory.Delete (installDir);
}
[Test]
public void TestIsMonoPath ()
{
var monoPathMap = fakeMonoPath.Replace (factory.MonoSourcePath, Path.Combine (installDir, "src", "Xamarin.iOS"));
var xamarinPathMap = fakeXamarinPath.Replace(factory.XamarinSourcePath, Path.Combine (installDir, "src", "Xamarin.iOS"));
Assert.IsTrue (factory.IsMonoPath (monoPathMap), "Present mono path");
Assert.IsFalse (factory.IsMonoPath (xamarinPathMap), "Present xamarin path");
}
[Test]
public void TestIsOpenTKPath ()
{
var openTKPathMap = fakeMonoPath.Replace (factory.OpenTKSourcePath, Path.Combine (installDir, "src", "Xamarin.iOS"));
var xamarinPathMap = fakeXamarinPath.Replace(factory.XamarinSourcePath, Path.Combine (installDir, "src", "Xamarin.iOS"));
Assert.IsTrue (factory.IsMonoPath (openTKPathMap), "Present openTK path");
Assert.IsFalse (factory.IsMonoPath (xamarinPathMap), "Present xamarin path");
}
[Test]
public void TestPathIsIgnored ()
{
var pathToIgnore = Path.Combine (factory.MonoSourcePath, "mcs", "mcs", "Foo.cs");
var pathNotToIgnore = Path.Combine (factory.MonoSourcePath, "mcs", "class", "Foo.cs");
Assert.IsTrue (factory.IsIgnored (pathToIgnore), "Do ignore.");
Assert.IsFalse (factory.IsIgnored (pathNotToIgnore), "Do NOT ignore.");
}
}
}

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

@ -0,0 +1,136 @@
using System;
using NUnit.Framework;
using InstallSources;
namespace InstallSourcesTests
{
[TestFixture]
public class XamarinSourcesPathManglerTest
{
string frameworkPath;
string xamarinSourcePath;
string installDir;
string destinationDir;
XamarinSourcesPathMangler mangler;
[SetUp]
public void SetUp ()
{
frameworkPath = "Xamarin.iOS.framework";
xamarinSourcePath = "/Users/test/xamarin-macios/src/";
installDir = "/Library/Frameworks/Xamarin.iOS.framework/Versions/4.1.0.402";
destinationDir = "/Users/test/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git";
mangler = new XamarinSourcesPathMangler {
FrameworkPath = frameworkPath,
XamarinSourcePath = xamarinSourcePath,
InstallDir = installDir,
DestinationDir = destinationDir,
};
}
[TestCase ("/Library/Frameworks/Xamarin.iOS.framework/Versions/4.1.0.402/src/Xamarin.iOS/CoreData/NSEntityMapping.g.cs",
"/Users/test/xamarin-macios/src/build/ios/native/CoreData/NSEntityMapping.g.cs")]
[TestCase ("/Users/test/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/Xamarin.iOS/build/ios/native/AVFoundation/AVMutableTimedMetadataGroup.g.cs",
"/Users/test/xamarin-macios/src/build/ios/native/AVFoundation/AVMutableTimedMetadataGroup.g.cs")]
[TestCase ("/Users/test/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/Xamarin.iOS/build/ios/native/CloudKit/CKRecordZoneNotification.g.cs",
"/Users/test/xamarin-macios/src/build/ios/native/CloudKit/CKRecordZoneNotification.g.cs")]
public void TestGetSourcePathGeneratediOSCode (string path, string expectedPath)
{
var result = mangler.GetSourcePath (path);
Assert.IsTrue (result.Contains ("/build/"), "Path does not contain '/build/'");
Assert.IsTrue (result.StartsWith(xamarinSourcePath, StringComparison.InvariantCulture), "Path does not start with the XamarinPath '{0}'", xamarinSourcePath);
Assert.AreEqual (result, expectedPath);
}
[TestCase ("/Library/Frameworks/Xamarin.Mac.framework/Versions/4.1.0.402/src/Xamarin.iOS/CoreData/NSEntityMapping.g.cs",
"/Users/test/xamarin-macios/src/build/mac/full/CoreData/NSEntityMapping.g.cs")]
[TestCase ("/Users/test/xamarin-macios/_mac-build/Library/Frameworks/Xamarin.Mac.framework/Versions/git/src/Xamarin.Mac/build/mac/full/AVFoundation/AVMutableTimedMetadataGroup.g.cs",
"/Users/test/xamarin-macios/src/build/mac/full/AVFoundation/AVMutableTimedMetadataGroup.g.cs")]
[TestCase ("/Users/test/xamarin-macios/_mac-build/Library/Frameworks/Xamarin.Mac.framework/Versions/git/src/Xamarin.Mac/build/mac/full/CloudKit/CKRecordZoneNotification.g.cs",
"/Users/test/xamarin-macios/src/build/mac/full/CloudKit/CKRecordZoneNotification.g.cs")]
public void TestGetSourcePathGeneratedMacCode (string path, string expectedPath)
{
mangler.FrameworkPath = "Xamarin.Mac.framework"; // dealing with mac sources
mangler.InstallDir = "/Library/Frameworks/Xamarin.Mac.framework/Versions/4.1.0.402/";
var result = mangler.GetSourcePath (path);
Assert.IsTrue (result.Contains ("/build/"), "Path does not contain '/build/'");
Assert.IsTrue (result.StartsWith (xamarinSourcePath, StringComparison.InvariantCulture), "Path does not start with the XamarinPath '{0}'", xamarinSourcePath);
Assert.AreEqual (expectedPath, result);
}
[TestCase ("/Users/test/xamarin-macios/runtime/Delegates.generated.cs", "/Users/test/xamarin-macios/runtime/Delegates.generated.cs")]
public void TestGetSourceRuntimeCode (string path, string expectedPath)
{
var result = mangler.GetSourcePath (path);
Assert.AreEqual (result, expectedPath);
}
[TestCase ("/Library/Frameworks/Xamarin.iOS.framework/Versions/4.1.0.402/src/Xamarin.iOS/AVFoundation/AVCaptureDeviceInput.cs",
"/Users/test/xamarin-macios/src/AVFoundation/AVCaptureDeviceInput.cs")]
[TestCase ("/Users/test/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/Xamarin.iOS/CoreImage/CIImage.cs",
"/Users/test/xamarin-macios/src/CoreImage/CIImage.cs")]
[TestCase ("/Users/test/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/Xamarin.iOS/CoreData/NSAttributeDescription.cs",
"/Users/test/xamarin-macios/src/CoreData/NSAttributeDescription.cs")]
[TestCase ("/Users/test/xamarin-macios/src/CoreData/NSAttributeDescription.cs",
"/Users/test/xamarin-macios/src/CoreData/NSAttributeDescription.cs")]
public void TestGetSourcePathManualCode (string path, string expectedPath)
{
var result = mangler.GetSourcePath(path);
Assert.IsFalse (result.Contains ("/build/"), "Path contains '/build/' when it is a manual path.");
Assert.IsTrue (result.StartsWith (xamarinSourcePath, StringComparison.InvariantCulture), "Path does not start with the XamarinPath '{0}'", xamarinSourcePath);
Assert.AreEqual (result, expectedPath);
}
[TestCase ("/Library/Frameworks/Xamarin.iOS.framework/Versions/4.1.0.402/src/Xamarin.iOS/NativeTypes/NMath.cs",
"/Users/test/xamarin-macios/src/NativeTypes/NMath.cs")]
[TestCase ("/Users/test/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/Xamarin.iOS/build/common/NativeTypes/Drawing.cs",
"/Users/test/xamarin-macios/src/build/common/NativeTypes/Drawing.cs")]
[TestCase ("/Users/test/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/Xamarin.iOS/build/common/NativeTypes/Primitives.cs",
"/Users/test/xamarin-macios/src/build/common/NativeTypes/Primitives.cs")]
public void TestGetSourcePathNativeTypes (string path, string expectedPath)
{
var result = mangler.GetSourcePath(path);
Assert.IsTrue(result.StartsWith(xamarinSourcePath, StringComparison.InvariantCulture), "Path does not start with the XamarinPath '{0}'", xamarinSourcePath);
Assert.AreEqual (result, expectedPath);
}
[TestCase ("/Users/test/xamarin-macios/src/build/ios/native/AVFoundation/AVMutableMetadataItem.g.cs", "/Users/test/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/Xamarin.iOS/AVFoundation/AVMutableMetadataItem.g.cs")]
[TestCase ("/Users/test/xamarin-macios/src/AVFoundation/AVCaptureDeviceInput.cs", "/Users/test/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/Xamarin.iOS/AVFoundation/AVCaptureDeviceInput.cs")]
[TestCase ("/Users/test/xamarin-macios/src/NativeTypes/NMath.cs", "/Users/test/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/Xamarin.iOS/NativeTypes/NMath.cs")]
public void TestGetTargetPathiOS (string src, string expectedTarget)
{
var target = mangler.GetTargetPath (src);
Assert.IsTrue (target.StartsWith (destinationDir, StringComparison.InvariantCulture), "Does not contain the install dir.");
Assert.AreEqual (expectedTarget, target, "Target is not the expected one.");
}
[TestCase ("/Users/test/xamarin-macios/src/build/mac/full/AVFoundation/AVMutableMetadataItem.g.cs", "/Users/test/xamarin-macios/_mac-build/Library/Frameworks/Xamarin.Mac.framework/Versions/git/src/Xamarin.Mac/AVFoundation/AVMutableMetadataItem.g.cs")]
[TestCase ("/Users/test/xamarin-macios/src/AVFoundation/AVCaptureDeviceInput.cs", "/Users/test/xamarin-macios/_mac-build/Library/Frameworks/Xamarin.Mac.framework/Versions/git/src/Xamarin.Mac/AVFoundation/AVCaptureDeviceInput.cs")]
[TestCase ("/Users/test/xamarin-macios/src/NativeTypes/NMath.cs", "/Users/test/xamarin-macios/_mac-build/Library/Frameworks/Xamarin.Mac.framework/Versions/git/src/Xamarin.Mac/NativeTypes/NMath.cs")]
public void TestGetTargetPathMac (string src, string expectedTarget)
{
mangler.FrameworkPath = "Xamarin.Mac.framework"; // dealing with mac sources
mangler.InstallDir = "/Library/Frameworks/Xamarin.Mac.framework";
mangler.DestinationDir = "/Users/test/xamarin-macios/_mac-build/Library/Frameworks/Xamarin.Mac.framework/Versions/git";
var target = mangler.GetTargetPath (src);
Assert.IsTrue (target.StartsWith (mangler.DestinationDir, StringComparison.InvariantCulture), "Does not contain the install dir.");
Assert.AreEqual (expectedTarget, target, "Target is not the expected one.");
}
[TestCase ("/Library/Frameworks/Xamarin.iOS.framework/Versions/4.1.0.402/src/Xamarin.iOS/Delegates.generated.cs",
"/Users/test/xamarin-macios/runtime/Delegates.generated.cs")]
[TestCase ("/Users/test/xamarin-macios/src/Xamarin.iOS/runtime/Delegates.generated.cs",
"/Users/test/xamarin-macios/src/Xamarin.iOS/runtime/Delegates.generated.cs")]
public void TestGetSourcePathRuntime (string path, string expectedPath)
{
var result = mangler.GetSourcePath (path);
Assert.AreEqual (expectedPath, result);
}
}
}

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

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NUnit" version="2.6.4" targetFramework="net45" />
</packages>

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

@ -1,4 +1,5 @@
TOP=../..
SRC_PATH=$(TOP)/src
include $(TOP)/Make.config
ifdef INCLUDE_IOS
@ -8,23 +9,62 @@ ifdef INCLUDE_MAC
install-local:: install-source-mac
endif
CECIL_PATH=$(MONO_PATH)/external/cecil
CECIL_CONFIG=net_4_0_Release
MONO_CECIL_DLL=$(CECIL_PATH)/bin/$(CECIL_CONFIG)/Mono.Cecil.dll
MONO_CECIL_FILES=$(wildcard $(CECIL_PATH)/*.cs) $(wildcard $(CECIL_PATH)/*/*.cs) $(wildcard $(CECIL_PATH)/*/*/*.cs) $(wildcard $(CECIL_PATH)/*/*/*/*.cs) $(wildcard $(CECIL_PATH)/*/*/*/*/*.cs)
MONO_CECIL_PDB_FILES=$(wildcard $(CECIL_PATH)/symbols/pdb/*.cs) $(wildcard $(CECIL_PATH)/symbols/pdb/*/*.cs) $(wildcard $(CECIL_PATH)/symbols/pdb/*/*/*.cs) $(wildcard $(CECIL_PATH)/symbols/pdb/*/*/*/*.cs) $(wildcard $(CECIL_PATH)/symbols/pdb/*/*/*/*/*.cs)
Mono.Cecil.Pdb.dll: $(MONO_CECIL_PDB_FILES)
$(Q_XBUILD) cd $(CECIL_PATH)/symbols/pdb/ && $(SYSTEM_XBUILD) /p:Configuration=$(CECIL_CONFIG) Mono.Cecil.Pdb.csproj $(XBUILD_VERBOSITY)
$(Q) cp $(CECIL_PATH)/bin/$(CECIL_CONFIG)/*.dll $(dir $@)
$(MONO_CECIL_DLL): $(CECIL_PATH)/Mono.Cecil.csproj $(MONO_CECIL_FILES)
$(Q_XBUILD) cd $(CECIL_PATH) && $(SYSTEM_XBUILD) /p:Configuration=$(CECIL_CONFIG) Mono.Cecil.csproj $(XBUILD_VERBOSITY)
Mono.Cecil.dll: $(MONO_CECIL_DLL)
$(Q) cp $<* $(dir $@)
IOS_ASSEMBLIES = \
$(wildcard $(MONO_PATH)/mcs/class/lib/monotouch/*.mdb)
$(wildcard $(MONO_PATH)/mcs/class/lib/monotouch/*.pdb) \
$(IOS_DESTDIR)$(MONOTOUCH_PREFIX)/lib/64bits/Xamarin.iOS.dll.mdb
MAC_ASSEMBLIES = \
$(wildcard $(MONO_PATH)/mcs/class/lib/xammac/*.mdb)
$(wildcard $(MONO_PATH)/mcs/class/lib/xammac/*.pdb) \
$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/4.5/Xamarin.Mac.dll.mdb
IOS_MDB_FILES = \
$(IOS_DESTDIR)$(MONOTOUCH_PREFIX)/lib/64bits/Xamarin.iOS.dll \
$(IOS_DESTDIR)$(MONOTOUCH_PREFIX)/lib/32bits/Xamarin.iOS.dll
MAC_MDB_FILES = \
$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/x86_64/mobile/Xamarin.Mac.dll.mdb \
$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/i386/mobile/Xamarin.Mac.dll.mdb \
$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/reference/full/Xamarin.Mac.dll.mdb \
$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/x86_64/full/Xamarin.Mac.dll.mdb \
$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/i386/full/Xamarin.Mac.dll.mdb \
$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/XamMac.CFNetwork.dll.mdb \
$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/Xamarin.Mac/Xamarin.Mac.dll.mdb \
$(MAC_DESTDIR)$(MAC_FRAMEWORK_CURRENT_DIR)/lib/mono/4.5/Xamarin.Mac.dll.mdb
install-source-ios: install-source.exe
@echo "Installing source files for Xamarin.iOS"
$(Q) $(SYSTEM_MONO) install-source.exe $(IOS_ASSEMBLIES) --link:$(USE_SOURCE_LINKS) --mono-path=$(abspath $(MONO_PATH)) --install-dir=$(abspath $(IOS_DESTDIR))/$(abspath $(MONOTOUCH_PREFIX))
$(Q) $(SYSTEM_MONO) install-source.exe $(IOS_ASSEMBLIES) --link:$(USE_SOURCE_LINKS) -v --mono-path=$(abspath $(MONO_PATH)) --opentk-path=$(abspath $(OPENTK_PATH)/Source) --xamarin-path=$(abspath $(SRC_PATH)) --install-dir=$(IOS_FRAMEWORK_DIR)/Versions/$(IOS_PACKAGE_VERSION) --destination-dir=$(abspath $(IOS_DESTDIR))$(abspath $(MONOTOUCH_PREFIX))
install-source-mac: install-source.exe
@echo "Installing source files for Xamarin.Mac"
$(Q) $(SYSTEM_MONO) install-source.exe $(MAC_ASSEMBLIES) --link:$(USE_SOURCE_LINKS) --mono-path=$(abspath $(MONO_PATH)) --install-dir=$(abspath $(MAC_DESTDIR)/$(MAC_FRAMEWORK_CURRENT_DIR))
$(Q) $(SYSTEM_MONO) install-source.exe $(MAC_ASSEMBLIES) --link:$(USE_SOURCE_LINKS) -v --mono-path=$(abspath $(MONO_PATH)) --opentk-path=$(abspath $(OPENTK_PATH)/Source) --xamarin-path=$(abspath $(SRC_PATH)) --install-dir=$(MAC_FRAMEWORK_DIR)/Versions/$(MAC_PACKAGE_VERSION) --destination-dir=$(abspath $(MAC_DESTDIR)/$(MAC_FRAMEWORK_CURRENT_DIR))
IOS_SOURCES = \
IPathMangler.cs \
MonoPathMangler.cs \
OpenTKSourceMangler.cs \
PathManglerFactory.cs \
Program.cs \
XamarinSourcesPathMangler.cs \
$(MONO_PATH)/mcs/class/Mono.Options/Mono.Options/Options.cs
install-source.exe: $(IOS_SOURCES) Makefile install-source.csproj
install-source.exe: Mono.Cecil.dll Mono.Cecil.Pdb.dll $(IOS_SOURCES) Makefile install-source.csproj $(MONO_CECIL_DLL)
$(Q_XBUILD) $(SYSTEM_XBUILD) install-source.csproj $(XBUILD_VERBOSITY)

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

@ -0,0 +1,52 @@
using System;
using System.IO;
namespace InstallSources
{
public class MonoPathMangler : IPathMangler
{
static readonly string iOSFramework = "Xamarin.iOS/";
static readonly string MacFramework = "Xamarin.Mac/";
/// <summary>
/// Gets and sets the location of the mono sources.
/// </summary>
/// <value>The mono source path.</value>
public string MonoSourcePath { get; set; }
/// <summary>
/// Gets or sets the frame work dir.
/// </summary>
/// <value>The frame work dir.</value>
public string DestinationDir { get; set; }
/// <summary>
/// Gets or sets the install dir.
/// </summary>
/// <value>The install dir.</value>
public string InstallDir { get; set; }
public string GetSourcePath (string path)
{
bool iosFramework = true;
if (path.StartsWith(MonoSourcePath, StringComparison.Ordinal))
return path;
// we are dealing with a package build
var index = path.IndexOf (iOSFramework, StringComparison.Ordinal);
if (index < 0) {// we are dealing with mac sources
iosFramework = false;
index = path.IndexOf(MacFramework, StringComparison.Ordinal);
}
path = path.Remove (0, index + ((iosFramework)?iOSFramework.Length : MacFramework.Length)); // + length framework
return Path.Combine (MonoSourcePath, path);
}
public string GetTargetPath (string path)
{
var relativePath = path.Substring (MonoSourcePath.Length);
if (relativePath.StartsWith ("/", StringComparison.Ordinal))
relativePath = relativePath.Remove (0, 1);
var target = Path.Combine (DestinationDir, "src", (InstallDir.Contains("Xamarin.iOS")?"Xamarin.iOS":"Xamarin.Mac"), relativePath);
return target;
}
}
}

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

@ -0,0 +1,56 @@
using System;
using System.IO;
namespace InstallSources
{
/// <summary>
/// Path manipulator that knows how to deal with OpenTK paths.
/// </summary>
public class OpenTKSourceMangler : IPathMangler
{
static readonly string iOSFramework = "Xamarin.iOS/";
static readonly string MacFramework = "Xamarin.Mac/";
/// <summary>
/// Locations of the OpenTK source.
/// </summary>
/// <value>The OpenTK source path.</value>
public string OpenTKSourcePath { get; set; }
/// <summary>
/// Gets or sets the install dir.
/// </summary>
/// <value>The install dir.</value>
public string InstallDir { get; set;}
/// <summary>
/// Gets or sets the frame work dir.
/// </summary>
/// <value>The frame work dir.</value>
public string DestinationDir { get; set; }
public string GetSourcePath (string path)
{
bool iosFramework = true;
if (path.StartsWith (OpenTKSourcePath, StringComparison.Ordinal))
return path;
// we are dealing with a package build
var index = path.IndexOf (iOSFramework, StringComparison.Ordinal);
if (index < 0) {// we are dealing with mac sources
iosFramework = false;
index = path.IndexOf(MacFramework, StringComparison.Ordinal);
}
path = path.Remove (0, index + ((iosFramework)?iOSFramework.Length : MacFramework.Length)); // + length framework
return Path.Combine (OpenTKSourcePath, path);
}
public string GetTargetPath (string path)
{
var relativePath = path.Substring (OpenTKSourcePath.Length);
if (relativePath.StartsWith ("/", StringComparison.Ordinal))
relativePath = relativePath.Remove (0, 1);
var target = Path.Combine (DestinationDir, "src", (InstallDir.Contains ("Xamarin.iOS") ? "Xamarin.iOS" : "Xamarin.Mac"), relativePath);
return target;
}
}
}

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

@ -0,0 +1,131 @@
using System;
using System.IO;
namespace InstallSources
{
public class PathManglerFactory
{
public bool Verbose { get; set; }
public string InstallDir { get; set; }
public string DestinationDir { get; set; }
public string MonoSourcePath { get; set; }
public string XamarinSourcePath { get; set; }
public string FrameworkPath { get; set; }
public string OpenTKSourcePath { get; set; }
MonoPathMangler monoMangler;
OpenTKSourceMangler openTKMangler;
XamarinSourcesPathMangler xamarinPathMangler;
readonly string srcSubPath = "src";
readonly string runtimeSubPath = "runtime";
readonly string xamariniOSDir = "Xamarin.iOS";
readonly string xamarinMacDir = "Xamarin.Mac";
MonoPathMangler MonoPathMangler {
get {
if (monoMangler == null)
monoMangler = new MonoPathMangler {
InstallDir = InstallDir,
DestinationDir = DestinationDir,
MonoSourcePath = MonoSourcePath
};
return monoMangler;
}
}
OpenTKSourceMangler OpenTKSourceMangler {
get {
if (openTKMangler == null)
openTKMangler = new OpenTKSourceMangler {
InstallDir = InstallDir,
DestinationDir = DestinationDir,
OpenTKSourcePath = OpenTKSourcePath
};
return openTKMangler;
}
}
XamarinSourcesPathMangler XamarinSourcesPathMangler {
get {
if (xamarinPathMangler == null)
xamarinPathMangler = new XamarinSourcesPathMangler {
InstallDir = InstallDir,
DestinationDir = DestinationDir,
XamarinSourcePath = XamarinSourcePath,
FrameworkPath = FrameworkPath
};
return xamarinPathMangler;
}
}
public bool IsMonoPath (string path)
{
// remove the intall dir and append the mono source path
if (path.StartsWith(InstallDir, StringComparison.Ordinal)) {
// dealing with the jenkins paths
if (Verbose) {
Console.WriteLine($"Install dir is {InstallDir}");
Console.WriteLine($"Original path os {path}");
}
var srcDir = Path.Combine(InstallDir, srcSubPath,
(InstallDir.Contains(xamariniOSDir) ? xamariniOSDir : xamarinMacDir));
if (Verbose)
Console.WriteLine($"Src path to remove {srcDir}");
var relative = path.Remove(0, srcDir.Length);
if (Verbose)
Console.WriteLine($"Relative path is {relative}");
if (relative.StartsWith("/", StringComparison.Ordinal))
relative = relative.Remove(0, 1);
var monoPath = Path.Combine(MonoSourcePath, relative);
if (Verbose)
Console.WriteLine($"Mono path is {monoPath}");
return File.Exists(monoPath);
}
if (path.StartsWith (XamarinSourcePath, StringComparison.Ordinal))
return false;
var xamarinRuntimePath = XamarinSourcePath.Replace($"/{srcSubPath}/", $"/{runtimeSubPath}/");
if (path.StartsWith (xamarinRuntimePath, StringComparison.Ordinal))
return false;
return path.StartsWith (MonoSourcePath, StringComparison.Ordinal);
}
public bool IsOpenTKPath (string path)
{
if (path.StartsWith(InstallDir, StringComparison.Ordinal)) {
// dealing with the jenkins paths
var srcDir = Path.Combine (InstallDir, srcSubPath,
(InstallDir.Contains(xamariniOSDir) ? xamariniOSDir : xamarinMacDir));
var relative = path.Remove (0, srcDir.Length);
if (relative.StartsWith("/", StringComparison.Ordinal))
relative = relative.Remove (0, 1);
var openTKPath = Path.Combine (OpenTKSourcePath, relative);
return File.Exists(openTKPath);
} else {
return path.Contains(OpenTKSourcePath);
}
}
public bool IsIgnored (string path)
{
return path.Contains ("/mcs/mcs/");
}
public IPathMangler GetMangler (string path)
{
if (IsIgnored(path))
return null;
if (IsOpenTKPath (path)) {
return OpenTKSourceMangler;
}
if (IsMonoPath(path)) {
return MonoPathMangler;
}
return XamarinSourcesPathMangler;
}
}
}

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

@ -1,11 +1,19 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Mono.CompilerServices.SymbolWriter;
using Mono.Options;
using Mono.Unix;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Pdb;
using InstallSources;
public class ListSourceFiles {
static bool ParseBool (string value)
{
@ -25,87 +33,247 @@ public class ListSourceFiles {
return bool.Parse (value);
}
}
public static void Main (string[] arguments)
public static string FixPathEnding(string path)
{
if (!path.EndsWith (Path.DirectorySeparatorChar.ToString (), StringComparison.Ordinal))
return path + Path.DirectorySeparatorChar;
return path;
}
// returns a tuple with the pdb files as the first value and the mdb files as the second
public static Tuple <HashSet<String>, HashSet<String>> GetSplittedPaths (List<string> paths)
{
var splittedPaths = new Tuple<HashSet<String>, HashSet<String>> (new HashSet<string> (), new HashSet<string> ());
foreach (var p in paths) {
if (p.EndsWith (".pdb", StringComparison.Ordinal)) {
splittedPaths.Item1.Add (p);
continue;
}
if (p.EndsWith (".mdb", StringComparison.Ordinal)) {
splittedPaths.Item2.Add (p);
continue;
}
}
return splittedPaths;
}
// returns the source paths used to create an assembly that has an mdb file
public static HashSet<String> GetFilePathsFromMdb (string mdb_file)
{
var srcs = new HashSet<String> ();
MonoSymbolFile symfile;
try {
symfile = MonoSymbolFile.ReadSymbolFile(mdb_file);
srcs.UnionWith (from src in symfile.Sources select src.FileName);
} catch (IOException ioe) {
Console.WriteLine("IO error while reading msb file '{0}': {1}", mdb_file, ioe.Message);
}
return srcs;
}
// returns the source paths used to create an assembly that has a pdb file
public static HashSet<String> GetFilePathsFromPdb (string pdbFile)
{
var pdb = Path.ChangeExtension (pdbFile, ".dll");
var result = new HashSet<String> (StringComparer.OrdinalIgnoreCase);
if (!File.Exists (pdbFile))
return result;
var assemblyResolver = new DefaultAssemblyResolver ();
var assemblyLocation = Path.GetDirectoryName (pdb);
assemblyResolver.AddSearchDirectory (assemblyLocation);
var readerParameters = new ReaderParameters { AssemblyResolver = assemblyResolver };
var writerParameters = new WriterParameters ();
var symbolReaderProvider = new PortablePdbReaderProvider ();
readerParameters.SymbolReaderProvider = symbolReaderProvider;
readerParameters.ReadSymbols = true;
var assemblyDefinition = AssemblyDefinition.ReadAssembly (pdb, readerParameters);
var mainModule = assemblyDefinition.MainModule;
foreach (var type in mainModule.Types) {
foreach (var method in type.Methods) {
if (method.DebugInformation.SequencePoints.Any ()) {
var sequence_point = method.DebugInformation.SequencePoints[0];
var document = sequence_point.Document;
result.Add (document.Url);
}
}
}
return result;
}
public static int Main (string[] arguments)
{
bool link = false;
string monopath = null;
string opentkpath = null;
string xamarinpath = null;
string installDir = null;
string destinationDir = null;
bool verbose = false;
var os = new OptionSet () {
{ "link:", "If source files should be linked instead of copied. Makes the install process faster, and if you edit files when stopped in a debugger, you'll edit the right file (and not a copy).", v => link = ParseBool (v) },
{ "mono-path=", "The path of the mono checkout.", v => monopath = v },
{ "opentk-path=", "The path of the opentk checkout.", v => opentkpath = v},
{ "xamarin-path=", "The path of the xamarin source.", v => xamarinpath = v },
{ "install-dir=", "The directory to install into. The files will be put into a src subdirectory of this directory.", v => installDir = v },
{ "destination-dir=", "The path to the directory used for the -pathmap at build time.", v => destinationDir = v},
{ "v|erbose", "Enable verbose output", v => verbose = true },
};
var mdb_files = os.Parse (arguments);
var paths = os.Parse (arguments);
var files = GetSplittedPaths (paths);
var srcs = new HashSet<string> (StringComparer.OrdinalIgnoreCase);
if (!monopath.EndsWith (Path.DirectorySeparatorChar.ToString (), StringComparison.Ordinal))
monopath += Path.DirectorySeparatorChar;
monopath = FixPathEnding (monopath);
xamarinpath = FixPathEnding (xamarinpath);
opentkpath = FixPathEnding (opentkpath);
foreach (string mdb_file in mdb_files) {
if (!File.Exists (mdb_file)) {
Console.WriteLine ("File does not exist: {0}", mdb_file);
var manglerFactory = new PathManglerFactory {
Verbose = verbose,
InstallDir = installDir,
DestinationDir = destinationDir,
MonoSourcePath = monopath,
XamarinSourcePath = xamarinpath,
FrameworkPath = (installDir.Contains ("Xamarin.iOS.framework")) ? "Xamarin.iOS.framework" : "Xamarin.Mac.framework",
OpenTKSourcePath = opentkpath,
};
// add the paths from the pdb files
foreach (string pdbFile in files.Item1) {
if (!File.Exists (pdbFile)) {
Console.WriteLine ("File does not exist: {0}", pdbFile);
continue;
}
if (mdb_file.EndsWith ("monotouch.dll.mdb", StringComparison.Ordinal)) {
// don't include monotouch.dll source
continue;
} else if (mdb_file.EndsWith ("Xamarin.iOS.dll.mdb", StringComparison.Ordinal)) {
// same for Xamarin.iOS.dll
continue;
} else if (mdb_file.EndsWith ("XamMac.dll.mdb", StringComparison.Ordinal)) {
continue;
} else if (mdb_file.EndsWith ("Xamarin.Mac.dll.mdb", StringComparison.Ordinal)) {
continue;
}
MonoSymbolFile symfile;
try {
symfile = MonoSymbolFile.ReadSymbolFile (mdb_file);
} catch (IOException ioe) {
Console.WriteLine ("IO error while reading msb file '{0}': {1}", mdb_file, ioe.Message);
continue;
}
foreach (var source_file in symfile.Sources) {
var src = source_file.FileName;
if (!src.StartsWith (monopath, StringComparison.Ordinal)) {
if (verbose)
Console.WriteLine ("{0}: not a mono source file", src);
continue;
}
srcs.Add (src);
var assemblySrcs = GetFilePathsFromPdb(pdbFile);
if (verbose) {
Console.WriteLine("Pdb file sources are:");
foreach (var p in srcs)
Console.WriteLine($"\t{p}");
}
srcs.UnionWith(assemblySrcs);
}
// add the paths from the mdb files
foreach (string mdbFile in files.Item2) {
if (!File.Exists (mdbFile)) {
Console.WriteLine ("File does not exist: {0}", mdbFile);
continue;
}
var assemblySrcs = GetFilePathsFromMdb (mdbFile);
if (verbose) {
Console.WriteLine("Mdb file sources are:");
foreach (var p in srcs)
Console.WriteLine($"\t{p}");
}
srcs.UnionWith (assemblySrcs);
}
if (verbose) {
Console.WriteLine ("Build paths are:");
Console.WriteLine ($"\tMono path:{monopath}");
Console.WriteLine ($"\tXamarin path:{xamarinpath}");
Console.WriteLine ($"\tOpenTk path:{opentkpath}");
Console.WriteLine ($"\tDestination path:{destinationDir}");
}
var alreadyLinked = new List<string> ();
foreach (var src in srcs) {
var relativePath = src.Substring (monopath.Length);
var target = Path.Combine (installDir, "src", "mono", relativePath);
var mangler = manglerFactory.GetMangler (src);
if (mangler == null) { // we are ignoring this file
if (verbose)
Console.WriteLine ($"Ignoring path {src}");
continue;
}
if (verbose)
Console.WriteLine ($"Original source is {src}");
var fixedSource = mangler.GetSourcePath (src);
if (String.IsNullOrEmpty (fixedSource)) {
Console.WriteLine ($"Skip path {src}");
continue;
}
var target = mangler.GetTargetPath (fixedSource);
if (verbose) {
Console.WriteLine ($"Fixed source {fixedSource}");
Console.WriteLine ($"Target path {target}");
}
var targetDir = Path.GetDirectoryName (target);
if (!Directory.Exists (targetDir)) {
Directory.CreateDirectory (targetDir);
} else if (File.Exists (target)) {
File.Delete (target);
if (String.IsNullOrEmpty (targetDir)) {
Console.WriteLine ($"Got empty dir for {target}");
continue;
}
if (verbose)
Console.WriteLine ($"Target direcotry is {targetDir}");
if (!Directory.Exists (targetDir)) {
try {
if (verbose)
Console.WriteLine ($"Creating dir {targetDir}");
Directory.CreateDirectory(targetDir);
} catch (PathTooLongException e) {
Console.WriteLine("Could not create directory {0} because the path is too long: {1}", targetDir, e);
return 1;
}
} else if (File.Exists (target)) {
try {
File.Delete(target);
} catch (PathTooLongException e) {
Console.WriteLine("Could not delete file {0} because the path is too long: {1}", target, e);
return 1;
}
} // else
if (link) {
if (verbose)
Console.WriteLine ("ln -s {0} {1}", src, target);
new UnixFileInfo (src).CreateSymbolicLink (target);
Console.WriteLine ("ln -s {0} {1}", fixedSource, target);
try {
if (!alreadyLinked.Contains (fixedSource)) {
new UnixFileInfo (fixedSource).CreateSymbolicLink (target);
alreadyLinked.Add(fixedSource);
} else {
Console.WriteLine ("Src {0} was already linked.", src);
}
} catch (PathTooLongException e) {
Console.WriteLine("Could not link {0} to {1} because the path is too long: {2}", fixedSource, target, e);
return 1;
} catch (UnixIOException e) {
Console.WriteLine("Could not link {0} to {1}: {2}", src, target, e);
return 1;
} // try/catch
} else {
if (verbose)
Console.WriteLine ("cp {0} {1}", src, target);
File.Copy (src, target);
}
}
if (verbose) {
Console.WriteLine ("cp {0} {1}", fixedSource, target);
}
try {
File.Copy (fixedSource, target);
} catch (FileNotFoundException e) {
Console.WriteLine ("The file {0} could not be copied to {1} because the file does not exists: {2}", fixedSource, target, e);
Console.WriteLine ("Debugging info:");
Console.WriteLine ("\tSource is {0}", src);
Console.WriteLine ("\tFixed source is {0}", fixedSource);
Console.WriteLine ("\tPath mangler type is {0}", mangler.GetType().Name);
} catch (PathTooLongException e) {
Console.WriteLine ("The file {0} could not be copied to {1} because the file path is too long: {2}", fixedSource, target, e);
return 1;
}
} // else
} // foreach
return 0;
}
}
}

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

@ -0,0 +1,231 @@
using System;
using System.IO;
namespace InstallSources
{
/// <summary>
/// Path manipulator that can deal with the Xamarin sources.
/// </summary>
public class XamarinSourcesPathMangler : IPathMangler
{
static string GeneratedExtension = ".g.cs";
static string NativeTypeSubpath = "NativeTypes";
static string CommonSourceSubpath = "/build/common/";
static string RuntimeSubpath = "generated.cs";
/// <summary>
/// Gets and sets the path to the xamarin source.
/// </summary>
/// <value>The xamarin source path.</value>
public string XamarinSourcePath { get; set; }
/// <summary>
/// Gets and sets the path used as the dir name for the framework.
/// </summary>
/// <value>The framework path.</value>
public string FrameworkPath { get; set; }
/// <summary>
/// Gets or sets the install dir.
/// </summary>
/// <value>The install dir.</value>
public string InstallDir { get; set; }
/// <summary>
/// Gets or sets the frame work dir.
/// </summary>
/// <value>The frame work dir.</value>
public string DestinationDir { get; set; }
/// <summary>
/// Returns if the provided path was compiler generated or not.
/// </summary>
/// <returns><c>true</c>, if generated path was generated, <c>false</c> otherwise.</returns>
/// <param name="path">The source path to mangle.</param>
static bool IsGeneratedPath (string path)
{
return path.EndsWith (GeneratedExtension, StringComparison.InvariantCulture);
}
/// <summary>
/// Returns if the source file is part of the common source generated by the generator.
/// </summary>
/// <returns><c>true</c>, if common source was ised, <c>false</c> otherwise.</returns>
/// <param name="path">Path.</param>
public static bool IsManualSource (string path)
{
return path.EndsWith (".cs", StringComparison.CurrentCulture) && !path.Contains (CommonSourceSubpath) && !path.Contains (NativeTypeSubpath);
}
/// <summary>
/// Returns if the provided path is a NativeType.
/// </summary>
/// <returns><c>true</c>, if native type was ised, <c>false</c> otherwise.</returns>
/// <param name="path">Path.</param>
static bool IsNativeType (string path)
{
return path.Contains (NativeTypeSubpath);
}
/// <summary>
/// Returns if the pat is from the runtime generated code.
/// </summary>
/// <returns><c>true</c>, if runrime was ised, <c>false</c> otherwise.</returns>
/// <param name="path">Path.</param>
static bool IsRunrime (string path)
{
return path.Contains (RuntimeSubpath);
}
/// <summary>
/// Returns the source path for a generated file.
/// </summary>
/// <returns>The source path for native type.</returns>
/// <param name="path">Path.</param>
string GetSourcePathForGeneratedPath (string path)
{
var frameworkPrefix = FrameworkPath.Remove (FrameworkPath.IndexOf (".framework", StringComparison.Ordinal));
var installPath = Path.Combine (InstallDir, "src", frameworkPrefix);
// we might be looking at a mdb that was already gone thorugh mdb rebase, if that is the case, do find the path for the final target
if (path.StartsWith (InstallDir, StringComparison.InvariantCulture)) {
var src = path.Substring (installPath.Length + 1);
if (src.StartsWith ("/", StringComparison.Ordinal))
src = src.Remove (0, 1);
src = Path.Combine (XamarinSourcePath, (InstallDir.Contains ("Xamarin.iOS.framework")) ? "build/ios/native/" : "build/mac/full/", src);
return src;
} else {
var pos = path.IndexOf ($"/{frameworkPrefix}/", StringComparison.InvariantCulture);
var src = path.Remove (0, pos + $"/{frameworkPrefix}/".Length); // 3 for src and 1 for /
src = Path.Combine (XamarinSourcePath, src);
return src;
}
}
/// <summary>
/// Returns the source path for the native common types.
/// </summary>
/// <returns>The source path for native type.</returns>
/// <param name="path">Path.</param>
string GetSourcePathForNativeType (string path)
{
string src = "";
var pos = path.IndexOf (CommonSourceSubpath, StringComparison.InvariantCulture);
if (pos >= 0) {
src = path.Remove (0, pos + CommonSourceSubpath.Length);
src = Path.Combine (XamarinSourcePath, "build", "common", src);
} else {
pos = path.IndexOf (NativeTypeSubpath, StringComparison.InvariantCulture);
if (pos >= 0) {
src = path.Remove (0, pos);
src = Path.Combine (XamarinSourcePath, src);
} else {
Console.WriteLine ($"Ignoring path {path}");
return "";
}
}
return src;
}
/// <summary>
/// Returns the source path for the bindings that were manually done.
/// </summary>
/// <returns>The source path for manual source.</returns>
/// <param name="path">Path.</param>
string GetSourcePathForManualSource (string path)
{
var removalPath = $"/{FrameworkPath}/";
var srcFolder = Path.Combine ("src", FrameworkPath.Remove (FrameworkPath.IndexOf (".framework", StringComparison.InvariantCulture))) + Path.DirectorySeparatorChar;
var pos = path.IndexOf (removalPath, StringComparison.InvariantCulture);
var src = path.Remove (0, pos + FrameworkPath.Length + 2);
pos = src.IndexOf (srcFolder, StringComparison.InvariantCulture);
if (pos >= 0)
src = src.Remove (0, src.IndexOf (srcFolder, StringComparison.InvariantCulture) + srcFolder.Length);
else // we are dealing with a correct path (this does happen on the mac side)
src = src.Remove (0, src.IndexOf ("/src/", StringComparison.InvariantCulture) + "/src/".Length);
src = Path.Combine (XamarinSourcePath, src);
return src;
}
string GetSourcePathForRuntimeSource (string path)
{
Console.WriteLine ($"Path is {path}");
if (path.StartsWith (InstallDir, StringComparison.Ordinal)) {
var removalPath = Path.Combine (InstallDir, FrameworkPath.Replace(".framework", ""), "src");
Console.WriteLine ($"Removal path s {removalPath}");
var src = path.Remove (0, removalPath.Length);
Console.WriteLine ($"Src is {src}");
if (src.StartsWith ("/", StringComparison.Ordinal))
src = src.Remove (0, 1);
return Path.Combine (XamarinSourcePath.Replace ("src", "runtime"), src);
} return path;
}
public string GetSourcePath(string path)
{
if (IsRunrime (path)) {
return GetSourcePathForRuntimeSource (path);
}
// decide what type of path we are dealing with and return the correct source.
if (IsGeneratedPath (path)) {
return GetSourcePathForGeneratedPath (path);
}
if (IsManualSource (path))
return GetSourcePathForManualSource (path);
return GetSourcePathForNativeType (path);
}
string GetTargetPathForGeneratedPath (string path)
{
var subpath = (InstallDir.Contains ("Xamarin.iOS.framework")) ? "native" : "full";
var pos = path.IndexOf (subpath, StringComparison.InvariantCulture);
if (pos >= 0) {
var relativePath = path.Remove (0, pos + subpath.Length + 1);
return Path.Combine (DestinationDir, "src", FrameworkPath.Remove (FrameworkPath.IndexOf (".framework", StringComparison.InvariantCulture)), relativePath);
}
return null;
}
string GetTargetPathForManualSource (string path)
{
var pos = path.IndexOf (XamarinSourcePath, StringComparison.InvariantCulture);
if (pos >= 0) {
var relativePath = path.Remove (0, pos + XamarinSourcePath.Length);
return Path.Combine (DestinationDir, "src", FrameworkPath.Remove (FrameworkPath.IndexOf (".framework", StringComparison.InvariantCulture)), relativePath);
}
return null;
}
string GetTargetPathForNativeType (string path)
{
var pos = path.IndexOf (NativeTypeSubpath, StringComparison.InvariantCulture);
if (pos >= 0) {
var relativePath = path.Remove (0, pos);
return Path.Combine (DestinationDir, "src", FrameworkPath.Remove (FrameworkPath.IndexOf (".framework", StringComparison.InvariantCulture)), relativePath);
}
return null;
}
string GetTargetPathForRuntimeSource (string path)
{
var pos = path.IndexOf (RuntimeSubpath, StringComparison.InvariantCulture);
if (pos >= 0) {
var relativePath = path.Remove (0, pos + 1); // +1 is used to remove the leading / from RuntimeSubpath
var result = Path.Combine (DestinationDir, "src", FrameworkPath.Remove (FrameworkPath.IndexOf (".framework", StringComparison.InvariantCulture)), relativePath);
return result;
}
return null;
}
public string GetTargetPath (string path)
{
if (IsRunrime(path))
return GetTargetPathForRuntimeSource(path);
if (IsGeneratedPath(path))
return GetTargetPathForGeneratedPath(path);
if (IsManualSource(path))
return GetTargetPathForManualSource(path);
return GetTargetPathForNativeType (path);
}
}
}

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

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
<OutputPath>.</OutputPath>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
@ -10,26 +11,27 @@
<RootNamespace>installsource</RootNamespace>
<AssemblyName>install-source</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>.</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="Mono.Posix" />
<Reference Include="Mono.CompilerServices.SymbolWriter" />
<Reference Include="Mono.Cecil">
<HintPath>Mono.Cecil.dll</HintPath>
</Reference>
<Reference Include="Mono.Cecil.Pdb">
<HintPath>Mono.Cecil.Pdb.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="..\..\external\mono\mcs\class\Mono.Options\Mono.Options\Options.cs">
<Link>Options.cs</Link>
</Compile>
<Compile Include="IPathMangler.cs" />
<Compile Include="MonoPathMangler.cs" />
<Compile Include="OpenTKSourceMangler.cs" />
<Compile Include="PathManglerFactory.cs" />
<Compile Include="XamarinSourcesPathMangler.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

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

@ -0,0 +1,23 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "install-source", "install-source.csproj", "{B24B2169-6243-4F98-B38C-69F03655CF1B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstallSourcesTests", "InstallSourcesTests\InstallSourcesTests.csproj", "{795E0F7E-5C48-4C90-8F66-518359874022}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B24B2169-6243-4F98-B38C-69F03655CF1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B24B2169-6243-4F98-B38C-69F03655CF1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B24B2169-6243-4F98-B38C-69F03655CF1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B24B2169-6243-4F98-B38C-69F03655CF1B}.Release|Any CPU.Build.0 = Release|Any CPU
{795E0F7E-5C48-4C90-8F66-518359874022}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{795E0F7E-5C48-4C90-8F66-518359874022}.Debug|Any CPU.Build.0 = Debug|Any CPU
{795E0F7E-5C48-4C90-8F66-518359874022}.Release|Any CPU.ActiveCfg = Release|Any CPU
{795E0F7E-5C48-4C90-8F66-518359874022}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal