1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . Diagnostics ;
4+ using System . IO ;
5+ using System . Linq ;
6+
7+ internal abstract class Compiler
8+ {
9+ protected enum ProcessRuntime
10+ {
11+ CLR40 ,
12+ CLR20 ,
13+ }
14+
15+ public abstract string Name { get ; }
16+ public virtual bool NeedsPdb2MdbConversion => false ;
17+
18+ protected readonly Logger logger ;
19+ protected readonly string compilerPath ;
20+ protected readonly string pbd2MdbPath ;
21+
22+ protected readonly List < string > outputLines = new List < string > ( ) ;
23+ protected readonly List < string > errorLines = new List < string > ( ) ;
24+
25+ protected Compiler ( Logger logger , string compilerPath , string pbd2MdbPath = null )
26+ {
27+ this . logger = logger ;
28+ this . compilerPath = compilerPath ;
29+ this . pbd2MdbPath = pbd2MdbPath ;
30+ }
31+
32+ public int Compile ( Platform platform , string unityEditorDataDir , string responseFile )
33+ {
34+ var process = CreateCompilerProcess ( platform , unityEditorDataDir , responseFile ) ;
35+ process . OutputDataReceived += ( sender , e ) => outputLines . Add ( e . Data ) ;
36+ process . ErrorDataReceived += ( sender , e ) => errorLines . Add ( e . Data ) ;
37+
38+ logger ? . Append ( $ "Process: { process . StartInfo . FileName } ") ;
39+ logger ? . Append ( $ "Arguments: { process . StartInfo . Arguments } ") ;
40+
41+ process . Start ( ) ;
42+ process . BeginOutputReadLine ( ) ;
43+ process . BeginErrorReadLine ( ) ;
44+ process . WaitForExit ( ) ;
45+ logger ? . Append ( $ "Exit code: { process . ExitCode } ") ;
46+
47+ return process . ExitCode ;
48+ }
49+
50+ public virtual void PrintCompilerOutputAndErrors ( )
51+ {
52+ var lines = ( from line in outputLines
53+ let trimmedLine = line ? . Trim ( )
54+ where string . IsNullOrEmpty ( trimmedLine ) == false
55+ select trimmedLine ) . ToList ( ) ;
56+
57+ logger ? . Append ( $ "- Compiler output ({ lines . Count } { ( lines . Count == 1 ? "line" : "lines" ) } ):") ;
58+
59+ for ( int i = 0 ; i < lines . Count ; i ++ )
60+ {
61+ Console . Out . WriteLine ( lines [ i ] ) ;
62+ logger ? . Append ( $ "{ i } : { lines [ i ] } ") ;
63+ }
64+
65+ lines = ( from line in errorLines
66+ let trimmedLine = line ? . Trim ( )
67+ where string . IsNullOrEmpty ( trimmedLine ) == false
68+ select trimmedLine ) . ToList ( ) ;
69+
70+ logger ? . Append ( "" ) ;
71+ logger ? . Append ( $ "- Compiler errors ({ lines . Count } { ( lines . Count == 1 ? "line" : "lines" ) } ):") ;
72+
73+ for ( int i = 0 ; i < lines . Count ; i ++ )
74+ {
75+ Console . Error . WriteLine ( lines [ i ] ) ;
76+ logger ? . Append ( $ "{ i } : { lines [ i ] } ") ;
77+ }
78+ }
79+
80+ protected abstract Process CreateCompilerProcess ( Platform platform , string unityEditorDataDir , string responseFile ) ;
81+
82+ public virtual void ConvertDebugSymbols ( Platform platform , string libraryPath , string unityEditorDataDir ) { }
83+
84+ protected static ProcessStartInfo CreateOSDependentStartInfo ( Platform platform , ProcessRuntime processRuntime , string processPath , string processArguments ,
85+ string unityEditorDataDir )
86+ {
87+ ProcessStartInfo startInfo ;
88+
89+ if ( platform == Platform . Windows )
90+ {
91+ switch ( processRuntime )
92+ {
93+ case ProcessRuntime . CLR20 :
94+ var runtimePath = Path . Combine ( unityEditorDataDir , @"Mono/bin/mono.exe" ) ;
95+ startInfo = new ProcessStartInfo ( runtimePath , $ "\" { processPath } \" { processArguments } ") ;
96+ break ;
97+
98+ case ProcessRuntime . CLR40 :
99+ startInfo = new ProcessStartInfo ( processPath , processArguments ) ;
100+ break ;
101+
102+ default :
103+ throw new ArgumentOutOfRangeException ( nameof ( processRuntime ) , processRuntime , null ) ;
104+ }
105+ }
106+ else
107+ {
108+ string runtimePath ;
109+ switch ( processRuntime )
110+ {
111+ case ProcessRuntime . CLR40 :
112+ if ( File . Exists ( "/usr/local/bin/mono" ) )
113+ {
114+ runtimePath = "/usr/local/bin/mono" ;
115+ }
116+ else
117+ {
118+ runtimePath = Path . Combine ( unityEditorDataDir , "MonoBleedingEdge/bin/mono" ) ;
119+ }
120+ break ;
121+
122+ case ProcessRuntime . CLR20 :
123+ runtimePath = Path . Combine ( unityEditorDataDir , @"Mono/bin/mono" ) ;
124+ break ;
125+
126+ default :
127+ throw new ArgumentOutOfRangeException ( nameof ( processRuntime ) , processRuntime , null ) ;
128+ }
129+
130+ startInfo = new ProcessStartInfo ( runtimePath , $ "\" { processPath } \" { processArguments } ") ;
131+
132+ if ( processRuntime != ProcessRuntime . CLR20 )
133+ {
134+ // Since we already are running under old mono runtime, we need to remove
135+ // these variables before launching the different version of the runtime.
136+ var vars = startInfo . EnvironmentVariables ;
137+ vars . Remove ( "MONO_PATH" ) ;
138+ vars . Remove ( "MONO_CFG_DIR" ) ;
139+ }
140+ }
141+
142+ startInfo . RedirectStandardError = true ;
143+ startInfo . RedirectStandardOutput = true ;
144+ startInfo . UseShellExecute = false ;
145+
146+ return startInfo ;
147+ }
148+
149+ public virtual void PrintPdb2MdbOutputAndErrors ( )
150+ {
151+ throw new NotSupportedException ( ) ;
152+ }
153+ }
0 commit comments