@@ -12,7 +12,7 @@ They had "/incremental" option once in old times but lost it already.
1212Because C# compiler is really fast and C# language itself is good to
1313keep compiler run fast, implementing incremental compilation has not been
1414at 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
1616to handle this problem indirectly.
1717
1818Unity3D 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:
9999By telling changes in a project to compilation object , rolsyn can use
100100pre - 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
106104Ok . 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.
125123Compile server processes this request, return it to requester and keep
126124this intermediate object for subsequent requests.
127125
128- TODO: Depict process relationship
129-
130126To 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
161157But 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
172169because it is dependent on Assembly-CSharp. It's a natural building protocol.
173170
174171But 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
176173relatively 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
191228Roslyn emits PDB file as a debugging symbol. But Unity3D cannot understand PDB file
192229because 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
196235So 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
208251variable names, source information for IL code and etc but Visual Studio cannot
209252understand Mono assembly well enough to support debugging.
210253To 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.
214257Therefore UnityVS misses some information and cannot give enough debugging
215258information to users.
216259
217- For example,
260+ For example, let's take look at following coroutine code.
218261
219262``` csharp
220263IEnumerator 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
233277this = " Text01 (Test01)"
@@ -236,7 +280,7 @@ a = 10
236280b = (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
242286this = {Test01+<TestCoroutine>d__1}
@@ -245,15 +289,16 @@ a = 10
245289b = (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
252297private 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