[linker-analyzer] intitial commit of the tool
authorRadek Doulik <rodo@xamarin.com>
Wed, 16 Sep 2015 12:59:34 +0000 (14:59 +0200)
committerRadek Doulik <rodo@xamarin.com>
Fri, 18 Sep 2015 10:45:41 +0000 (12:45 +0200)
mcs/tools/linker-analyzer/ConsoleDependencyGraph.cs [new file with mode: 0644]
mcs/tools/linker-analyzer/Info.plist [new file with mode: 0644]
mcs/tools/linker-analyzer/LinkerAnalyzer.csproj [new file with mode: 0644]
mcs/tools/linker-analyzer/LinkerAnalyzer.sln [new file with mode: 0644]
mcs/tools/linker-analyzer/LinkerAnalyzerCore/DependencyGraph.cs [new file with mode: 0644]
mcs/tools/linker-analyzer/LinkerAnalyzerCore/LinkerAnalyzerCore.csproj [new file with mode: 0644]
mcs/tools/linker-analyzer/LinkerAnalyzerCore/Properties/AssemblyInfo.cs [new file with mode: 0644]
mcs/tools/linker-analyzer/Main.cs [new file with mode: 0644]
mcs/tools/linker-analyzer/Makefile [new file with mode: 0644]
mcs/tools/linker-analyzer/linkeranalyzer.exe.sources [new file with mode: 0644]

diff --git a/mcs/tools/linker-analyzer/ConsoleDependencyGraph.cs b/mcs/tools/linker-analyzer/ConsoleDependencyGraph.cs
new file mode 100644 (file)
index 0000000..a778ffd
--- /dev/null
@@ -0,0 +1,146 @@
+//
+// ConsoleDependencyGraph.cs: text output related code for dependency graph
+//
+// Author:
+//   Radek Doulik (rodo@xamarin.com)
+//
+// Copyright 2015 Xamarin Inc (http://www.xamarin.com).
+//
+using System;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using LinkerAnalyzer.Core;
+
+namespace LinkerAnalyzer
+{
+       public class ConsoleDependencyGraph : DependencyGraph
+       {
+               public bool Tree = false;
+
+               public void ShowDependencies (string raw, List<VertexData> verticesList, string searchString)
+               {
+                       VertexData vertex = Vertex (raw);
+                       if (vertex == null) {
+                               Regex regex = new Regex (searchString);
+                               int count = 0;
+
+                               foreach (var v in verticesList) {
+                                       if (regex.Match (v.value) != Match.Empty) {
+                                               ShowDependencies (v);
+                                               count++;
+                                       }
+                               }
+
+                               if (count == 0)
+                                       Console.WriteLine ("\nUnable to find vertex: {0}", raw);
+                               else
+                                       Console.WriteLine ("\nFound {0} matches", count);
+                       } else
+                               ShowDependencies (vertex);
+               }
+
+               public void ShowDependencies (VertexData vertex)
+               {
+                       Header ("{0} dependencies", vertex.value);
+                       if (vertex.parentIndexes == null) {
+                               Console.WriteLine ("Root dependency");
+                       } else {
+                               int i = 0;
+                               foreach (int index in vertex.parentIndexes) {
+                                       Console.WriteLine ("Dependency #{0}", ++i);
+                                       Console.WriteLine ("\t{0}", vertex.value);
+                                       var childVertex = Vertex (index);
+                                       Console.WriteLine ("\t| {0}{1}", childVertex.value, childVertex.DepsCount);
+                                       while (childVertex.parentIndexes != null) {
+                                               childVertex = Vertex (childVertex.parentIndexes [0]);
+                                               Console.WriteLine ("\t| {0}{1}", childVertex.value, childVertex.DepsCount);
+                                       }
+                                       if (Tree)
+                                               break;
+                               }
+                       }
+               }
+
+               public void ShowAllDependencies ()
+               {
+                       Header ("All dependencies");
+                       Console.WriteLine ("Types count: {0}", vertices.Count);
+                       foreach (var vertex in vertices)
+                               ShowDependencies (vertex);
+               }
+
+               public void ShowTypesDependencies ()
+               {
+                       Header ("All types dependencies");
+                       Console.WriteLine ("Deps count: {0}", Types.Count);
+                       foreach (var type in Types)
+                               ShowDependencies (type);
+               }
+
+               string Tabs (string key)
+               {
+                       int count = Math.Max (1, 2 - key.Length / 8);
+
+                       if (count == 1)
+                               return "\t";
+                       else
+                               return "\t\t";
+               }
+
+               public void ShowStat (bool verbose = false)
+               {
+                       Header ("Statistics");
+                       if (verbose) {
+                               foreach (var key in counts.Keys)
+                                       Console.WriteLine ("Vertex type:\t{0}{1}count:{2}", key, Tabs (key), counts [key]);
+                       } else {
+                               Console.WriteLine ("Assemblies:\t{0}", counts ["Assembly"]);
+                               Console.WriteLine ("Modules:\t{0}", counts ["Module"]);
+                               Console.WriteLine ("Types:\t\t{0}", counts ["TypeDef"]);
+                               Console.WriteLine ("Fields:\t\t{0}", counts ["Field"]);
+                               Console.WriteLine ("Methods:\t{0}", counts ["Method"]);
+                       }
+
+                       Console.WriteLine ();
+                       Console.WriteLine ("Total vertices: {0}", vertices.Count);
+               }
+
+               public void ShowRoots ()
+               {
+                       Header ("Root vertices");
+
+                       int count = 0;
+                       foreach (var vertex in vertices) {
+                               if (vertex.parentIndexes == null) {
+                                       Console.WriteLine ("{0}", vertex.value);
+                                       count++;
+                               }
+                       }
+
+                       Console.WriteLine ();
+                       Console.WriteLine ("Total root vertices: {0}", count);
+               }
+
+               public void ShowRawDependencies (string raw)
+               {
+                       Header ("Raw dependencies: '{0}'", raw);
+                       ShowDependencies (raw, vertices, raw);
+               }
+
+               public void ShowTypeDependencies (string raw)
+               {
+                       Header ("Type dependencies: '{0}'", raw);
+                       ShowDependencies ("TypeDef:" + raw, Types, raw);
+               }
+
+               void Header (string header, params object[] values)
+               {
+                       string formatted = string.Format (header, values);
+                       Console.WriteLine ();
+                       Console.Write ("--- {0} ", formatted);
+                       for (int i=0; i< Math.Max (3, 64 - formatted.Length); i++)
+                               Console.Write ('-');
+                       Console.WriteLine ();
+               }
+       }
+}
diff --git a/mcs/tools/linker-analyzer/Info.plist b/mcs/tools/linker-analyzer/Info.plist
new file mode 100644 (file)
index 0000000..19517b1
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDisplayName</key>
+       <string>LinkerAnalyzer</string>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>en</string>
+       <key>CFBundleIconFile</key>
+       <string></string>
+       <key>CFBundleIdentifier</key>
+       <string>com.your-company.LinkerAnalyzer</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>LinkerAnalyzer</string>
+       <key>CFBundlePackageType</key>
+       <string>APPL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1</string>
+       <key>LSMinimumSystemVersion</key>
+       <string>10.8</string>
+       <key>NSHumanReadableCopyright</key>
+       <string>rodo</string>
+       <key>NSMainNibFile</key>
+       <string>MainMenu</string>
+       <key>NSPrincipalClass</key>
+       <string>NSApplication</string>
+</dict>
+</plist>
diff --git a/mcs/tools/linker-analyzer/LinkerAnalyzer.csproj b/mcs/tools/linker-analyzer/LinkerAnalyzer.csproj
new file mode 100644 (file)
index 0000000..bf0c453
--- /dev/null
@@ -0,0 +1,74 @@
+<?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>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectTypeGuids>{A3F8F2AB-B479-4A4A-A458-A89E7DC349F1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <ProjectGuid>{B64F51B1-2D82-479C-B8F5-8875CDF06D95}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>LinkerAnalyzer</RootNamespace>
+    <MonoMacResourcePrefix>Resources</MonoMacResourcePrefix>
+    <AssemblyName>LinkerAnalyzer</AssemblyName>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <TargetFrameworkIdentifier>Xamarin.Mac</TargetFrameworkIdentifier>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+    <UseRefCounting>true</UseRefCounting>
+    <UseSGen>true</UseSGen>
+    <IncludeMonoRuntime>false</IncludeMonoRuntime>
+    <EnablePackageSigning>false</EnablePackageSigning>
+    <CodeSigningKey>Mac Developer</CodeSigningKey>
+    <EnableCodeSigning>false</EnableCodeSigning>
+    <CreatePackage>false</CreatePackage>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>full</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+    <LinkMode>SdkOnly</LinkMode>
+    <UseRefCounting>true</UseRefCounting>
+    <UseSGen>true</UseSGen>
+    <IncludeMonoRuntime>true</IncludeMonoRuntime>
+    <CreatePackage>true</CreatePackage>
+    <CodeSigningKey>Developer ID Application</CodeSigningKey>
+    <EnableCodeSigning>true</EnableCodeSigning>
+    <EnablePackageSigning>false</EnablePackageSigning>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="Xamarin.Mac" />
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Resources\" />
+    <Folder Include="Mono.Options\" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Info.plist" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Main.cs" />
+    <Compile Include="ConsoleDependencyGraph.cs" />
+    <Compile Include="..\..\class\Mono.Options\Mono.Options\Options.cs">
+      <Link>Mono.Options\Options.cs</Link>
+    </Compile>
+  </ItemGroup>
+  <Import Project="$(MSBuildExtensionsPath)\Xamarin\Mac\Xamarin.Mac.CSharp.targets" />
+  <ItemGroup>
+    <ProjectReference Include="LinkerAnalyzerCore\LinkerAnalyzerCore.csproj">
+      <Project>{E1B8F203-5251-470E-A573-C9E79B60781B}</Project>
+      <Name>LinkerAnalyzerCore</Name>
+    </ProjectReference>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/mcs/tools/linker-analyzer/LinkerAnalyzer.sln b/mcs/tools/linker-analyzer/LinkerAnalyzer.sln
new file mode 100644 (file)
index 0000000..1debe4c
--- /dev/null
@@ -0,0 +1,23 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 12.00\r
+# Visual Studio 2012\r
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LinkerAnalyzer", "LinkerAnalyzer.csproj", "{B64F51B1-2D82-479C-B8F5-8875CDF06D95}"\r
+EndProject\r
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LinkerAnalyzerCore", "LinkerAnalyzerCore\LinkerAnalyzerCore.csproj", "{E1B8F203-5251-470E-A573-C9E79B60781B}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|Any CPU = Debug|Any CPU\r
+               Release|Any CPU = Release|Any CPU\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {B64F51B1-2D82-479C-B8F5-8875CDF06D95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r
+               {B64F51B1-2D82-479C-B8F5-8875CDF06D95}.Debug|Any CPU.Build.0 = Debug|Any CPU\r
+               {B64F51B1-2D82-479C-B8F5-8875CDF06D95}.Release|Any CPU.ActiveCfg = Release|Any CPU\r
+               {B64F51B1-2D82-479C-B8F5-8875CDF06D95}.Release|Any CPU.Build.0 = Release|Any CPU\r
+               {E1B8F203-5251-470E-A573-C9E79B60781B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r
+               {E1B8F203-5251-470E-A573-C9E79B60781B}.Debug|Any CPU.Build.0 = Debug|Any CPU\r
+               {E1B8F203-5251-470E-A573-C9E79B60781B}.Release|Any CPU.ActiveCfg = Release|Any CPU\r
+               {E1B8F203-5251-470E-A573-C9E79B60781B}.Release|Any CPU.Build.0 = Release|Any CPU\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/mcs/tools/linker-analyzer/LinkerAnalyzerCore/DependencyGraph.cs b/mcs/tools/linker-analyzer/LinkerAnalyzerCore/DependencyGraph.cs
new file mode 100644 (file)
index 0000000..e488209
--- /dev/null
@@ -0,0 +1,118 @@
+//
+// DependencyGraph.cs: linker dependencies graph
+//
+// Author:
+//   Radek Doulik (rodo@xamarin.com)
+//
+// Copyright 2015 Xamarin Inc (http://www.xamarin.com).
+//
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.IO.Compression;
+using System.Xml;
+
+namespace LinkerAnalyzer.Core
+{
+       public class VertexData {
+               public string value;
+               public List<int> parentIndexes;
+               public int index;
+
+               public string DepsCount {
+                       get {
+                               if (parentIndexes == null || parentIndexes.Count < 1)
+                                       return "";
+                               return string.Format (" [{0} deps]", parentIndexes.Count);
+                       }
+               }
+       };
+
+       public class DependencyGraph
+       {
+               protected List<VertexData> vertices = new List<VertexData> ();
+               public List<VertexData> Types = new List<VertexData> ();
+               Dictionary<string, int> indexes = new Dictionary<string, int> ();
+               protected Dictionary<string, int> counts = new Dictionary<string, int> ();
+
+               public void Load (string filename)
+               {
+                       Console.WriteLine ("Loading dependency tree from: {0}", filename);
+
+                       using (var fileStream = File.OpenRead (filename))
+                       using (var zipStream = new GZipStream (fileStream, CompressionMode.Decompress)) {
+                               try {
+                                       Load (zipStream);
+                               } catch (Exception) {
+                                       Console.WriteLine ("Unable to open and read the dependecies.");
+                                       Environment.Exit (1);
+                               }
+                       }
+               }
+
+               void Load (GZipStream zipStream) {
+                       using (XmlReader reader = XmlReader.Create (zipStream)) {
+                               while (reader.Read ()) {
+                                       switch (reader.NodeType) {
+                                       case XmlNodeType.Element:
+                                               //Console.WriteLine (reader.Name);
+                                               if (reader.Name == "edge" && reader.IsStartElement ()) {
+                                                       string b = reader.GetAttribute ("b");
+                                                       string e = reader.GetAttribute ("e");
+                                                       //Console.WriteLine ("edge value " + b + "  -->  " + e);
+
+                                                       if (e != b) {
+                                                               VertexData begin = Vertex (b, true);
+                                                               VertexData end = Vertex (e, true);
+
+                                                               if (end.parentIndexes == null)
+                                                                       end.parentIndexes = new List<int> ();
+                                                               if (!end.parentIndexes.Contains (begin.index)) {
+                                                                       end.parentIndexes.Add (begin.index);
+                                                                       //Console.WriteLine (" end parent index: {0}", end.parentIndexes);
+                                                               }
+                                                       }
+                                               }
+                                               break;
+                                       default:
+                                               //Console.WriteLine ("node: " + reader.NodeType);
+                                               break;
+                                       }
+                               }
+                       }
+               }
+
+               public VertexData Vertex (string vertexName, bool create = false)
+               {
+                       VertexData vertex;
+
+                       try {
+                               vertex = vertices [indexes [vertexName]];
+                       } catch (KeyNotFoundException) {
+                               if (create) {
+                                       int index = vertices.Count;
+                                       vertex = new VertexData () { value = vertexName, index = index };
+                                       vertices.Add (vertex);
+                                       indexes.Add (vertexName, index);
+                                       string prefix = vertexName.Substring (0, vertexName.IndexOf (':'));
+                                       if (counts.ContainsKey (prefix))
+                                               counts [prefix]++;
+                                       else
+                                               counts [prefix] = 1;
+                                       //Console.WriteLine ("prefix " + prefix + " count " + counts[prefix]);
+                                       if (prefix == "TypeDef") {
+                                               Types.Add (vertex);
+                                       }
+                               } else
+                                       return null;
+                       }
+
+                       return vertex;
+               }
+
+               public VertexData Vertex (int index)
+               {
+                       return vertices [index];
+               }
+       }
+}
diff --git a/mcs/tools/linker-analyzer/LinkerAnalyzerCore/LinkerAnalyzerCore.csproj b/mcs/tools/linker-analyzer/LinkerAnalyzerCore/LinkerAnalyzerCore.csproj
new file mode 100644 (file)
index 0000000..6427516
--- /dev/null
@@ -0,0 +1,61 @@
+<?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>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectTypeGuids>{A3F8F2AB-B479-4A4A-A458-A89E7DC349F1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <ProjectGuid>{E1B8F203-5251-470E-A573-C9E79B60781B}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>LinkerAnalyzer.Core</RootNamespace>
+    <MonoMacResourcePrefix>Resources</MonoMacResourcePrefix>
+    <AssemblyName>LinkerAnalyzerCore</AssemblyName>
+    <UseXamMacFullFramework>true</UseXamMacFullFramework>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+    <UseRefCounting>false</UseRefCounting>
+    <UseSGen>false</UseSGen>
+    <IncludeMonoRuntime>false</IncludeMonoRuntime>
+    <CreatePackage>false</CreatePackage>
+    <EnableCodeSigning>false</EnableCodeSigning>
+    <EnablePackageSigning>false</EnablePackageSigning>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>full</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+    <UseRefCounting>false</UseRefCounting>
+    <UseSGen>false</UseSGen>
+    <IncludeMonoRuntime>false</IncludeMonoRuntime>
+    <CreatePackage>false</CreatePackage>
+    <EnableCodeSigning>false</EnableCodeSigning>
+    <EnablePackageSigning>false</EnablePackageSigning>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="Xamarin.Mac" />
+    <Reference Include="System.Xml" />
+    <Reference Include="Mono.Cecil">
+      <HintPath>..\..\..\git\upstream\cecil\bin\net_4_0_Debug\Mono.Cecil.dll</HintPath>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Resources\" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="DependencyGraph.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildExtensionsPath)\Xamarin\Mac\Xamarin.Mac.CSharp.targets" />
+</Project>
\ No newline at end of file
diff --git a/mcs/tools/linker-analyzer/LinkerAnalyzerCore/Properties/AssemblyInfo.cs b/mcs/tools/linker-analyzer/LinkerAnalyzerCore/Properties/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..b78aef5
--- /dev/null
@@ -0,0 +1,27 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle ("LinkerAnalyzerCore")]
+[assembly: AssemblyDescription ("")]
+[assembly: AssemblyConfiguration ("")]
+[assembly: AssemblyCompany ("")]
+[assembly: AssemblyProduct ("")]
+[assembly: AssemblyCopyright ("rodo")]
+[assembly: AssemblyTrademark ("")]
+[assembly: AssemblyCulture ("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion ("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
diff --git a/mcs/tools/linker-analyzer/Main.cs b/mcs/tools/linker-analyzer/Main.cs
new file mode 100644 (file)
index 0000000..5c75ba5
--- /dev/null
@@ -0,0 +1,86 @@
+//
+// Main.cs: Main program file of command line utility.
+//
+// Author:
+//   Radek Doulik (rodo@xamarin.com)
+//
+// Copyright 2015 Xamarin Inc (http://www.xamarin.com).
+//
+using System;
+using Mono.Options;
+using LinkerAnalyzer.Core;
+
+namespace LinkerAnalyzer
+{
+       static class MainClass
+       {
+               static void Main (string[] args)
+               {
+                       bool showUsage = true;
+                       bool showAllDeps = false;
+                       bool showTypeDeps = false;
+                       string typeName = null;
+                       bool showRawDeps = false;
+                       string rawName = null;
+                       bool showRoots = false;
+                       bool showSpaceUsage = false;
+                       bool showStat = false;
+                       bool showTypes = false;
+                       bool reduceToTree = false;
+                       bool verbose = false;
+
+                       var optionsParser = new OptionSet () {
+                               { "a|alldeps", "show all dependencies", v => { showAllDeps = v != null; } },
+                               { "h|help", "show this message and exit.", v => showUsage = v != null },
+                               { "r|rawdeps=", "show raw vertex dependencies. Raw vertex VALUE is in the raw format written by linker to the dependency XML file. VALUE can be regular expression", v => { showRawDeps = v != null; rawName = v; } },
+                               { "roots", "show root dependencies.", v => showRoots = v != null },
+                               { "stat", "show statistic of loaded dependencies.", v => showStat = v != null },
+                               { "tree", "reduce the dependency graph to the tree.", v => reduceToTree = v != null },
+                               { "types", "show all types dependencies.", v => showTypes = v != null },
+                               { "t|typedeps=", "show type dependencies. The VALUE can be regular expression", v => { showTypeDeps = v != null; typeName = v; } },
+                               //{ "u|spaceusage", "show space analysis.", v => showSpaceUsage = v != null },
+                               { "v|verbose", "be more verbose. Enables stat and roots options.", v => verbose = v != null },
+                       };
+
+                       if (args.Length > 0) {
+                               showUsage = false;
+                               optionsParser.Parse (args);
+                       }
+
+                       if (showUsage) {
+                               Console.WriteLine ("Usage:\n\n\tlinkeranalyzer [Options] <linker-dependency-file.xml.gz>\n\nOptions:\n");
+                               optionsParser.WriteOptionDescriptions (Console.Out);
+                               Console.WriteLine ();
+                               return;
+                       }
+
+                       string dependencyFile = args [args.Length - 1];
+
+                       ConsoleDependencyGraph deps = new ConsoleDependencyGraph () { Tree = reduceToTree };
+                       deps.Load (dependencyFile);
+
+                       if (showSpaceUsage) {
+//                             SpaceAnalyzer sa = new SpaceAnalyzer (System.IO.Path.GetDirectoryName (dependencyFile));
+//                             sa.LoadAssemblies (verbose);
+                       }
+
+                       if (verbose) {
+                               showStat = true;
+                               showRoots = true;
+                       }
+
+                       if (showStat)
+                               deps.ShowStat (verbose);
+                       if (showRoots)
+                               deps.ShowRoots ();
+                       if (showRawDeps)
+                               deps.ShowRawDependencies (rawName);
+                       if (showTypeDeps)
+                               deps.ShowTypeDependencies (typeName);
+                       if (showAllDeps)
+                               deps.ShowAllDependencies ();
+                       else if (showTypes)
+                               deps.ShowTypesDependencies ();
+               }
+       }
+}
diff --git a/mcs/tools/linker-analyzer/Makefile b/mcs/tools/linker-analyzer/Makefile
new file mode 100644 (file)
index 0000000..c8fd5ff
--- /dev/null
@@ -0,0 +1,7 @@
+thisdir = tools/linker-analyzer
+SUBDIRS =
+include ../../build/rules.make
+
+PROGRAM = linkeranalyzer.exe
+
+include ../../build/executable.make
diff --git a/mcs/tools/linker-analyzer/linkeranalyzer.exe.sources b/mcs/tools/linker-analyzer/linkeranalyzer.exe.sources
new file mode 100644 (file)
index 0000000..1da8185
--- /dev/null
@@ -0,0 +1,5 @@
+ConsoleDependencyGraph.cs
+Main.cs
+
+LinkerAnalyzerCore/DependencyGraph.cs
+../../class/Mono.Options/Mono.Options/Options.cs