5 // Jb Evain (jbevain@gmail.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 namespace Mono.Linker.Steps {
37 public class OutputStep : BaseStep {
39 protected override void Process ()
41 CheckOutputDirectory ();
42 Annotations.SaveDependencies ();
45 void CheckOutputDirectory ()
47 if (Directory.Exists (Context.OutputDirectory))
50 Directory.CreateDirectory (Context.OutputDirectory);
53 protected override void ProcessAssembly (AssemblyDefinition assembly)
55 OutputAssembly (assembly);
58 void OutputAssembly (AssemblyDefinition assembly)
60 string directory = Context.OutputDirectory;
62 CopyConfigFileIfNeeded (assembly, directory);
64 switch (Annotations.GetAction (assembly)) {
65 case AssemblyAction.Save:
66 case AssemblyAction.Link:
67 Context.Annotations.AddDependency (assembly);
68 assembly.Write (GetAssemblyFileName (assembly, directory), SaveSymbols (assembly));
70 case AssemblyAction.Copy:
71 Context.Annotations.AddDependency (assembly);
72 CloseSymbols (assembly);
73 CopyAssembly (GetOriginalAssemblyFileInfo (assembly), directory, Context.LinkSymbols);
75 case AssemblyAction.Delete:
76 CloseSymbols (assembly);
77 var target = GetAssemblyFileName (assembly, directory);
78 if (File.Exists (target)) {
80 File.Delete (target + ".mdb");
81 File.Delete (GetConfigFile (target));
85 CloseSymbols (assembly);
90 void CloseSymbols (AssemblyDefinition assembly)
92 Annotations.CloseSymbolReader (assembly);
95 WriterParameters SaveSymbols (AssemblyDefinition assembly)
97 var parameters = new WriterParameters ();
98 if (!Context.LinkSymbols)
101 if (!assembly.MainModule.HasSymbols)
104 if (Context.SymbolWriterProvider != null)
105 parameters.SymbolWriterProvider = Context.SymbolWriterProvider;
107 parameters.WriteSymbols = true;
111 static void CopyConfigFileIfNeeded (AssemblyDefinition assembly, string directory)
113 string config = GetConfigFile (GetOriginalAssemblyFileInfo (assembly).FullName);
114 if (!File.Exists (config))
117 string target = Path.GetFullPath (GetConfigFile (GetAssemblyFileName (assembly, directory)));
119 if (config == target)
122 File.Copy (config, GetConfigFile (GetAssemblyFileName (assembly, directory)), true);
125 static string GetConfigFile (string assembly)
127 return assembly + ".config";
130 static FileInfo GetOriginalAssemblyFileInfo (AssemblyDefinition assembly)
132 return new FileInfo (assembly.MainModule.FullyQualifiedName);
135 static void CopyAssembly (FileInfo fi, string directory, bool symbols)
137 string target = Path.GetFullPath (Path.Combine (directory, fi.Name));
138 string source = fi.FullName;
139 if (source == target)
142 File.Copy (source, target, true);
148 if (!File.Exists (source))
150 File.Copy (source, target + ".mdb", true);
153 static string GetAssemblyFileName (AssemblyDefinition assembly, string directory)
155 string file = assembly.Name.Name + (assembly.MainModule.Kind == ModuleKind.Dll ? ".dll" : ".exe");
156 return Path.Combine (directory, file);