95b8a92d38d3c7046aa9f8ad98b66d21f1238651
[mono.git] / mcs / tools / linker / README
1 monolinker
2 ====
3
4 monolinker is the Mono CIL Linker.
5
6 The linker is a tool one can use to only ship the minimal possible set of
7 functions that a set of programs might require to run as opposed to the full
8 libraries.
9
10 * How does the linker work?
11
12 The linker analyses the intermediate code (CIL) produced by every compiler
13 targeting the Mono platform like mcs, gmcs, vbnc, booc or others. It will walk
14 through all the code that it is given to it, and basically, perform a mark and
15 sweep operations on all the code that it is referenced, to only keep what is
16 necessary for the source program to run.
17
18 * Usage
19
20 1) Linking from a source assembly
21
22 The command:
23
24 monolinker -a Program.exe
25
26 will use the assembly Program.exe as a source. That means that the linker will
27 walk through all the methods of Program.exe to generate only what is necessary
28 for this assembly to run.
29
30 2) Linking from an xml descriptor
31
32 The command:
33
34 monolinker -x desc.xml
35
36 will use the XML descriptor as a source. That means that the linker will
37 use this file to decide what to link in a set of assemblies. The format of the
38 descriptors is described further on in this document.
39
40 3) Linking from an api info file
41
42 The command:
43
44 monolinker -i assembly.info
45
46 will use a file produced by mono-api-info as a source. The linker will use
47 this file to link only what is necessary to match the public API defined in
48 the info file.
49
50 4) Actions on the assemblies
51
52 You can specify what the linker should do exactly per assembly.
53
54 The linker can do 3 things:
55
56         - skip them, and do nothing with them,
57         - copy them to the output directory,
58         - link them, to reduce their size.
59
60 You can specify an action per assembly like this:
61
62 monolinker -p link Foo
63
64 or
65
66 monolinker -p skip System.Windows.Forms
67
68 Or you can specify what to do for the core assemblies.
69
70 Core assemblies are the assemblies that belongs to the base class library,
71 like mscorlib.dll, System.dll or System.Windows.Forms.dll.
72
73 You can specify what action to do on the core assemblies with the option:
74
75 -c skip|copy|link
76
77 5) The output directory
78
79 By default, the linker will create an `output' directory in the current
80 directory where it will emit the linked files, to avoid erasing source
81 assemblies. You can specify the output directory with the option:
82
83 -o output_directory
84
85 If you specify the directory `.', please ensure that you won't write over
86 important assemblies of yours.
87
88 * Syntax of a xml descriptor
89
90 Here is an example that shows all the possibilities of this format:
91
92 ---
93 <linker>
94         <assembly fullname="Library">
95                 <type fullname="Foo" />
96                 <type fullname="Bar" preserve="nothing" required="false" />
97                 <type fullname="Baz" preserve="fields" required="false" />
98                 <type fullname="Gazonk">
99                         <method signature="System.Void .ctor(System.String)" />
100                         <field signature="System.String _blah" />
101                 </type>
102         </assembly>
103 </linker>
104 ---
105
106 In this example, the linker will link the types Foo, Bar, Baz and Gazonk.
107
108 The fullname attribute specifies the fullname of the type in the format
109 specified by ECMA-335. This is in Mono and certain cases not the same
110 as the one reported by Type.FullName (nested classes e.g.).
111
112 The preserve attribute ensures that all the fields of the type Baz will be
113 always be linked, not matter if they are used or not, but that neither the
114 fields or the methods of Bar will be linked if they are not used. Not
115 specifying a preserve attribute implies that we are preserving everything in
116 the specified type.
117
118 The required attribute specifies that if the type is not marked, during the
119 mark operation, it will not be linked.
120
121 The type Gazonk will be linked, as well as its constructor taking a string as a
122 parameter, and it's _blah field.
123
124 You can have multiple assembly nodes.
125
126 6) The i18n Assemblies
127
128 Mono have a few assemblies which contains everything region specific:
129
130     I18N.CJK.dll
131     I18N.MidEast.dll
132     I18N.Other.dll
133     I18N.Rare.dll
134     I18N.West.dll
135
136 By default, they will all be copied to the output directory. But you can
137 specify which one you want using the command:
138
139 monolinker -l choice
140
141 Where choice can either be: none, all, cjk, mideast, other, rare or west. You can
142 combine the values with a comma.
143
144 Example:
145
146 monolinker -a assembly -l mideast,cjk
147
148 7) Specifying directories where the linker should look for assemblies
149
150 By default, the linker will first look for assemblies in the directories `.'
151 and `bin'. You can specify
152
153 Example:
154
155 monolinker -d ../../libs -a program.exe
156
157 8) Adding custom steps to the linker.
158
159 You can write custom steps for the linker and tell the linker to use them.
160 Let's take a simple example:
161
162 using System;
163
164 using Mono.Linker;
165 using Mono.Linker.Steps;
166
167 namespace Foo {
168
169         public class FooStep : IStep {
170
171                 public void Process (LinkContext context)
172                 {
173                         foreach (IStep step in context.Pipeline.GetSteps ()) {
174                                 Console.WriteLine (step.GetType ().Name);
175                         }
176                 }
177         }
178 }
179
180
181 That is compiled against the linker to a Foo.dll assembly.
182
183 You can ask the linker to add it at the end of the pipeline:
184
185 monolinker -s Foo.FooStep,Foo -a program.exe
186
187 Or you can ask the linker to add it after a specific step:
188
189 monolinker -s MarkStep:Foo.FooStep,Foo -a program.exe
190
191 Or before a specific step:
192
193 monolinker -s Foo.FooStep,Foo:MarkStep
194
195 * Inside the linker
196
197 The linker is a quite small piece of code, and it pretty simple to address.
198 Its only dependency is Mono.Cecil, that is used to read, modify and write back
199 the assemblies.
200
201 Everything is located in the namespace Mono.Linker, or in sub namespaces.
202 Being a command line utility, its entry point function is in the class Driver.
203
204 This class is in charge of analyzing the command line, and to instantiate two
205 important objects, a LinkContext, and a Pipeline.
206
207 The LinkContext contains all the informations that will be used during the
208 linking process, such as the assemblies involved, the output directory and
209 probably other useful stuff.
210
211 The Pipeline is simply a queue of actions (steps), to be applied to the current
212 context. The whole process of linking is split into those differents steps
213 that are all located in the Mono.Linker.Steps namespace.
214
215 Here are the current steps that are implemented, in the order they are used:
216
217 1) ResolveFromAssembly or ResolveFromXml
218
219 Those steps are used to initialize the context, and pre-mark the root code
220 that will be used as a source for the linker.
221
222 Resolving from an assembly or resolving from a xml descriptor is a decision
223 taken in the command line parsing.
224
225 2) LoadReferences
226
227 This step will load all the references of all the assemblies involved in the
228 current context.
229
230 3) Blacklist
231
232 This step is used if and only if you have specified that the core should be
233 linked. It will load a bunch of resources from the assemblies, that are
234 actually a few XML descriptors, that will ensure that some types and methods
235 that are used from inside the runtime are properly linked and not removed.
236
237 It is doing so by inserting a ResolveFromXml step per blacklist in the
238 pipeline.
239
240 4) Mark
241
242 This is the most complex step. The linker will get from the context the list
243 of types, fields and methods that have been pre-marked in the resolve steps,
244 and walk through all of them. For every method, it will analyse the CIL stream,
245 to find references to other fields, types, or methods.
246
247 When it encounters such a reference, it will resolve the original definition of
248 this reference, and add this to the queue of items to be processed. For
249 instance, if have in a source assembly a call to Console.WriteLine, the linker
250 will resolve the appropriate method WriteLine in the Console type from the
251 mscorlib assembly, and add it to the queue. When this WriteLine method will be
252 dequeued, and processed, the linker will go through everything that is used in
253 it, and add it to the queue, if they have not been processed already.
254
255 To know if something have been marked to be linked, or processed, the linker
256 is using a functionality of Cecil called annotations. Almost everything in
257 Cecil can be annotated. Concretely, it means that almost everything own an
258 Hashtable in which you can add what you want, using the keys and the values you
259 want.
260
261 So the linker will annotate assemblies, types, methods and fields to know
262 what should be linked or not, and what have been processed, and how it should
263 process them.
264
265 This is really useful as we don't have to recreate a full hierarchy of classes
266 to encapsulate the different Cecil types to add the few informations we want.
267
268 5) Sweep
269
270 This simple step will walk through all the elements of an assembly, and based
271 on their annotations, remove them or keep them.
272
273 6) Clean
274
275 This step will clean parts of the assemblies, like properties. If a proprety
276 used to have a getter and a setter, and that after the mark & sweep steps,
277 only the getter is linked, it will update the property to reflect that.
278
279 There is a few things to keep clean like properties has we've seen, events,
280 nested classes, and probably a few others.
281
282 7) Output
283
284 For each assembly in the context, this step will act on the action associated
285 to the assembly. If the assembly is marked as skip, it won't do anything,
286 if it's marked as copy, it will copy the assembly to the output directory,
287 and if it's link, it will save the modified assembly to the output directory.
288
289 * Reporting a bug
290
291 If you face a bug in the linker, please report it to:
292
293 http://bugzilla.ximian.com
294
295 Product: Mono tools, Component: linker.
296
297 * Mailing lists
298
299 You can ask questions about the linker of the cecil Google Group:
300
301 http://groups.google.com/group/mono-cecil
302
303 --
304 Jb Evain <jbevain@novell.com>