Skip to content

Commit 4da13c3

Browse files
committed
More docs
1 parent 111b391 commit 4da13c3

File tree

1 file changed

+74
-28
lines changed

1 file changed

+74
-28
lines changed

docs/UnderTheHood.md

Lines changed: 74 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ They had "/incremental" option once in old times but lost it already.
1212
Because C# compiler is really fast and C# language itself is good to
1313
keep compiler run fast, implementing incremental compilation has not been
1414
at the first priority.
15-
Also community keep there project small and like to separate big project into smaller ones
15+
Also community keep their project small and like to separate big project into smaller ones
1616
to handle this problem indirectly.
1717

1818
Unity3D uses mono C# infrastructure. It seems hard to make compiler work faster
@@ -99,8 +99,6 @@ incremental compiler is written in a simple way like:
9999
By telling changes in a project to compilation object, rolsyn can use
100100
pre-parsed syntax trees and some informations that I wish.
101101

102-
TODO: Check information that roslyn uses for next build
103-
104102
### Compile server
105103

106104
Ok. Keeping compilation object and reusing can make an incremental compiler.
@@ -125,8 +123,6 @@ Compiler forwards a compilation request to this serdver and waits for results.
125123
Compile server processes this request, return it to requester and keep
126124
this intermediate object for subsequent requests.
127125

128-
TODO: Depict process relationship
129-
130126
To communicate between compile client and server,
131127
[WCF on Named pipe](https://msdn.microsoft.com/en-us/library/ms733769%28v=vs.110%29.aspx) is used
132128
to make this tool quickly even Mono doesn't support it.
@@ -161,9 +157,10 @@ It is an internal feature for Unity3D and cannot be accessed from external user
161157
But to make it, he renamed plugin DLL to one of internal friend DLL names,
162158
`Unity.PureCSharpTests`.
163159

164-
## Modification for Unity3D/Mono
160+
## Modification for Unity3D & Mono
165161

166-
TODO: Intro
162+
After implementing a general incremental compiler, there are some works left to
163+
go well with Unity3D and Mono.
167164

168165
### Reuse prebuilt DLLs
169166

@@ -172,33 +169,79 @@ But at the same time Unity3D also build Assembly-CSharp-Editor
172169
because it is dependent on Assembly-CSharp. It's a natural building protocol.
173170

174171
But most of time it is not useful.
175-
If there is no changed in sources of Assembly-CSharp-Editor, it is considered
172+
If there is no change in sources of Assembly-CSharp-Editor, it is considered
176173
relatively safe to skip rebuilding Assembly-CSharp-Editor.
177174

178-
TODO: TEST & SHOW ERROR CASE
179-
TODO: DETAILED DESCRIPTION OF OPTION
180-
181-
PrebuiltOutputReuse in IncrementalCompiler.xml
175+
So two options are provided to handle this.
182176

183177
- WhenNoChange :
184178
When nothing changed in sources and references, reuse prebuilt results.
179+
This is safe and common.
185180
- WhenNoSourceChange :
186181
When nothing changed in sources and references (except update of some references),
187182
reuse prebuilt results.
183+
This is almost safe and not common. If Assembly-CSharp-Editor is not affected by
184+
updated referenced DLL, this will be ok.
185+
186+
But with WhenNoSourceChange, a following case will be errornous.
187+
188+
```csharp
189+
// Assets/Scripts/NormalTest.cs (will be at Assembly-CSharp)
190+
public static class NormalTest {
191+
public static void Test(int a) {
192+
Debug.Log("Log:" + a);
193+
}
194+
}
195+
196+
// Assets/Editor/EditorTest.cs (will be at Assembly-CSharp-Editor)
197+
public static class EditorTest {
198+
[MenuItem("Assets/Call Test")]
199+
public static void Test() {
200+
NormalTest.Test(1);
201+
}
202+
}
203+
```
204+
205+
After build & run, change the signature of method `Test` called by EditorTest.
206+
207+
```csharp
208+
public static class NormalTest {
209+
public static void Test(int a, string b) { // "string b" added
210+
Debug.Log("Log:" + a);
211+
}
212+
}
213+
```
214+
215+
With WhenNoChange, Assembly-CSharp-Editor will be built because of change of NormalTest.
216+
But with WhenNoSourceChange, Assembly-CSharp-Editor won't be built because there is no change in their sources and
217+
you might get MissingMethodException like this:
218+
219+
```csharp
220+
MissingMethodException: Method not found: 'NormalTest.Test'.
221+
```
222+
223+
When this exception is thrown, just recompiling `Assembly-CSharp-Editor` can solve the problem.
224+
So this can be a good option for making build fast on the price of rare exception.
188225

189226
### MDB instead of PDB
190227

191228
Roslyn emits PDB file as a debugging symbol. But Unity3D cannot understand PDB file
192229
because it's based on mono compiler. To make unity3D get proper debugging information,
193-
MDB file should be constructed and they already provided a tool to convert pdb to mdb and
194-
jbevain update support output of visual studio 2015 [pdb2mdb](https://gist.github.com/jbevain/ba23149da8369e4a966f)
230+
MDB file should be constructed.
231+
Fortunately they already provided a tool to convert pdb to mdb.
232+
Jb Evain also released [new one](https://gist.github.com/jbevain/ba23149da8369e4a966f)
233+
to support output of visual studio 2015.
195234

196235
So simple process supporting unity3d is
197-
- Emit pdb via Roslyn
198-
- Convert pdb to mdb with pdb2mdb tool
236+
1. Emit pdb with Roslyn
237+
1. Convert pdb to mdb with pdb2mdb tool
199238

200-
But how about emitting mdb from Roslyn directly? it can save time for generating and converting pdb?
201-
A guy at Xamarain already tried it but it is not updated now. So I grab his work and update it to work latest Roslyn.
239+
But how about emitting mdb from Roslyn directly?
240+
It could save time for generating and converting pdb.
241+
Good thing is that a guy at Xamarain already tried [it](https://github.com/mono/roslyn/pull/4).
242+
But bad thing is that it is not being maintained now.
243+
So I grab his work and [update it](https://github.com/SaladbowlCreative/Unity3D.IncrementalCompiler/blob/master/core/RoslynMdbWriter/README.md)
244+
to work with latest Roslyn.
202245

203246
### Renaming symbol for UnityVS debugging
204247

@@ -208,13 +251,13 @@ does a lot of hard works to support Unity3D application debugging in Visual Stud
208251
variable names, source information for IL code and etc but Visual Studio cannot
209252
understand Mono assembly well enough to support debugging.
210253
To deal with this problem, UnityVS examines assemblies carefully
211-
and making use of common pattern of mono DLLs by itself.
254+
and makes use of common pattern of mono DLLs by itself.
212255

213256
.NET assembly built with Roslyn, however, is different with one with Mono.
214257
Therefore UnityVS misses some information and cannot give enough debugging
215258
information to users.
216259

217-
For example,
260+
For example, let's take look at following coroutine code.
218261

219262
```csharp
220263
IEnumerator TestCoroutine(int a, Func<int, string> b) {
@@ -227,7 +270,8 @@ IEnumerator TestCoroutine(int a, Func<int, string> b) {
227270
}
228271
```
229272

230-
UnityVS can show variable v in watch for DLL from Mono3.
273+
Set breakpoint at a commented line in coroutine and watch local variable `v` in debugging windows.
274+
UnityVS can show variable `v` in watch window for DLL built from Mono3.
231275

232276
```csharp
233277
this = "Text01 (Test01)"
@@ -236,7 +280,7 @@ a = 10
236280
b = (trimmed)
237281
```
238282

239-
UnityVS cannot show variable v in watch for DLL from Roslyn.
283+
Howevery, UnityVS cannot show variable v in watch window for DLL built from Roslyn.
240284

241285
```csharp
242286
this = {Test01+<TestCoroutine>d__1}
@@ -245,15 +289,16 @@ a = 10
245289
b = (trimmed)
246290
```
247291

248-
There is a difference between Mono and Roslyn for making name of local variables in iterator class.
292+
This is caused because there is a difference between Mono and Roslyn
293+
for making name of local variables in iterator class.
249294

250295
```csharp
251296
// Mono3
252297
private sealed class <TestCoroutine>c__Iterator0 : IEnumerator<object>, IEnumerator, IDisposable {
253-
internal int a;
254-
internal int <v>__0;
255-
internal Func<int, string> b;
256-
internal Test01 <>f__this;
298+
internal int a;
299+
internal int <v>__0;
300+
internal Func<int, string> b;
301+
internal Test01 <>f__this;
257302
// trimmed
258303
259304
// Roslyn
@@ -345,4 +390,5 @@ with detailed comments.
345390

346391
## Conclusion
347392

348-
...
393+
Done! During this journey implementing an incremental compiler,
394+
I found many interesting works that people has been working and got inspired.

0 commit comments

Comments
 (0)