2006-02-26 Marek Sieradzki <marek.sieradzki@gmail.com>
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / Engine.cs
1 //
2 // Engine.cs: Main engine of XBuild.
3 //
4 // Author:
5 //   Marek Sieradzki (marek.sieradzki@gmail.com)
6 // 
7 // (C) 2005 Marek Sieradzki
8 //
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:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
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.
27
28 #if NET_2_0
29
30 using System;
31 using System.Collections;
32 using Microsoft.Build.Framework;
33
34 namespace Microsoft.Build.BuildEngine {
35         public class Engine {
36                 
37                 string                  binPath;
38                 bool                    buildEnabled;
39                 BuildPropertyGroup      environmentProperties;
40                 EventSource             eventSource;
41                 bool                    buildStarted;
42                 BuildPropertyGroup      globalProperties;
43                 IDictionary             importedProjects;
44                 IList                   loggers;
45                 bool                    onlyLogCriticalEvents;
46                 IDictionary             projects;
47                 BuildPropertyGroup      reservedProperties;
48
49                 // FIXME: GlobalEngine static property uses this but what about GlobalEngineAccessor?
50                 static Engine           globalEngine;
51                 static Version          version;
52
53                 static Engine ()
54                 {
55                         version = new Version("0.1");
56                 }
57                 
58                 public Engine ()
59                         : this (null)
60                 {
61                 }
62
63                 // engine should be invoked with path where binary files are
64                 // to find microsoft.build.tasks
65                 public Engine (string binPath)
66                 {
67                         this.binPath = binPath;
68                         this.projects = new Hashtable ();
69                         this.eventSource = new EventSource ();
70                         this.loggers = new ArrayList ();
71                         this.buildStarted = false;
72                         this.LoadEnvironmentProperties ();
73                         this.reservedProperties = new BuildPropertyGroup ();
74                         this.reservedProperties.AddNewProperty ("MSBuildBinPath", binPath, PropertyType.Reserved);
75                 }
76
77                 public bool BuildProject (Project project,
78                                           string[] targetNames,
79                                           IDictionary targetOutputs)
80                 {
81                         bool result;
82                         
83                         LogProjectStarted (project, targetNames);
84                                 
85                         result =  project.Build (targetNames, targetOutputs);
86                         
87                         LogProjectFinished (project, result);
88                         
89                         return result;
90                 }
91
92                 public bool BuildProjectFile (string projectFileName,
93                                           string[] targetNames,
94                                           BuildPropertyGroup globalPropertiesToUse,
95                                           IDictionary targetOutputs)
96                 {
97                         bool result;
98                         Project project;
99                         
100                         if (projects.Contains (projectFileName)) {
101                                 project = (Project) projects [projectFileName];
102                                 LogProjectStarted (project, targetNames);
103                                 result = project.Build (targetNames, targetOutputs);
104                         }
105                         else
106                                 return false;
107                         
108                         LogProjectFinished (project, result);
109                         
110                         return result;
111                 }
112
113                 public Project CreateNewProject ()
114                 {
115                         if (buildStarted == false) {
116                                 LogBuildStarted ();
117                                 buildStarted = true;
118                         }
119                         Project p = new Project (this);
120                         p.EnvironmentProperties = this.environmentProperties;
121                         p.ReservedProperties = this.reservedProperties;
122                         if (globalProperties != null) {
123                                 BuildPropertyGroup bpg = new BuildPropertyGroup ();
124                                 foreach (BuildProperty bp in globalProperties)
125                                         bpg.AddNewProperty (bp.Name, bp.Value, PropertyType.CommandLine);
126                                 p.GlobalProperties = bpg;
127                         }
128                         return p;
129                 }
130
131                 public Project GetLoadedProject (string projectFullFileName)
132                 {
133                         return (Project) projects [projectFullFileName];
134                 }
135
136                 public void RegisterLogger (ILogger logger)
137                 {
138                         if (logger == null)
139                                 throw new ArgumentNullException ("logger");
140                         logger.Initialize (eventSource);
141                         loggers.Add (logger);
142                 }
143                 
144                 [MonoTODO]
145                 public void UnloadAllProjects ()
146                 {
147                 }
148                 
149                 [MonoTODO]
150                 public void UnloadProject (Project project)
151                 {
152                 }
153
154                 public void UnregisterAllLoggers ()
155                 {
156                         // FIXME: check if build succeeded
157                         LogBuildFinished (true);
158                         foreach (ILogger i in loggers) {
159                                 i.Shutdown ();
160                         }
161                         loggers.Clear ();
162                 }
163                 
164                 private void LoadEnvironmentProperties ()
165                 {
166                         environmentProperties = new BuildPropertyGroup ();
167                         IDictionary environment = Environment.GetEnvironmentVariables ();
168                         foreach (DictionaryEntry de in environment) {
169                                 environmentProperties.AddNewProperty ((string) de.Key, (string) de.Value, PropertyType.Environment);
170                         }
171                 }
172                 
173                 private void LogProjectStarted (Project project, string[] targetNames)
174                 {
175                         ProjectStartedEventArgs psea;
176                         if (targetNames.Length == 0) {
177                                 if (project.DefaultTargets != String.Empty)
178                                         psea = new ProjectStartedEventArgs ("Project started.", null, project.FullFileName,
179                                                 project.DefaultTargets, null, null);
180                                 else
181                                         psea = new ProjectStartedEventArgs ("Project started.", null, project.FullFileName, "default", null, null);
182                         } else
183                         psea = new ProjectStartedEventArgs ("Project started.", null, project.FullFileName, String.Join (";",
184                                 targetNames), null, null);
185                         eventSource.FireProjectStarted (this, psea);
186                 }
187                 
188                 private void LogProjectFinished (Project project, bool succeeded)
189                 {
190                         ProjectFinishedEventArgs pfea;
191                         pfea = new ProjectFinishedEventArgs ("Project started.", null, project.FullFileName, succeeded);
192                         eventSource.FireProjectFinished (this, pfea);
193                 }
194                 
195                 private void LogBuildStarted ()
196                 {
197                         BuildStartedEventArgs bsea;
198                         bsea = new BuildStartedEventArgs ("Build started.", null);
199                         eventSource.FireBuildStarted (this, bsea);
200                 }
201                 
202                 private void LogBuildFinished (bool succeeded)
203                 {
204                         BuildFinishedEventArgs bfea;
205                         bfea = new BuildFinishedEventArgs ("Build finished.", null, succeeded);
206                         eventSource.FireBuildFinished (this, bfea);
207                 }
208
209                 public string BinPath {
210                         get { return binPath; }
211                         set { binPath = value; }
212                 }
213
214                 public bool BuildEnabled {
215                         get { return buildEnabled; }
216                         set { buildEnabled = value; }
217                 }
218
219                 public static Version Version {
220                         get { return version; }
221                 }
222
223                 public static Engine GlobalEngine {
224                         get { return globalEngine; }
225                 }
226
227                 public BuildPropertyGroup GlobalProperties {
228                         get { return globalProperties; }
229                         set { globalProperties = value; }
230                 }
231
232                 public bool OnlyLogCriticalEvents {
233                         get { return eventSource.OnlyLogCriticalEvents; }
234                         set { eventSource.OnlyLogCriticalEvents = value; }
235                 }
236                 
237                 internal EventSource EventSource {
238                         get { return eventSource; }
239                 }
240         }
241 }
242
243 #endif