e838e86a1e486f657bf8ecd8c8dcc06a806a2f69
[reactos.git] / reactos / tools / rbuild / rbuild.cpp
1 /*
2 * Copyright (C) 2005 Casper S. Hornstrup
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18 #include "pch.h"
19 #include <typeinfo>
20
21 #include <stdio.h>
22 #ifdef WIN32
23 #include <io.h>
24 #endif
25 #include <assert.h>
26
27 #include "rbuild.h"
28 #include "backend/backend.h"
29 #include "backend/mingw/mingw.h"
30
31 using std::string;
32 using std::vector;
33
34 static string BuildSystem;
35 static string RootXmlFile = "ReactOS.xml";
36 static Configuration configuration;
37
38 bool
39 ParseAutomaticDependencySwitch (
40 char switchChar2,
41 char* switchStart )
42 {
43 switch ( switchChar2 )
44 {
45 case 'd':
46 configuration.AutomaticDependencies = false;
47 break;
48 case 'm':
49 if ( strlen ( switchStart ) <= 3 )
50 {
51 printf ( "Switch -dm requires a module name\n" );
52 return false;
53 }
54 configuration.CheckDependenciesForModuleOnly = true;
55 configuration.CheckDependenciesForModuleOnlyModule = string(&switchStart[3]);
56 break;
57 default:
58 printf ( "Unknown switch -d%c\n",
59 switchChar2 );
60 return false;
61 }
62 return true;
63 }
64
65 bool
66 ParseCompilationUnitSwitch (
67 char switchChar2,
68 char* switchStart )
69 {
70 switch ( switchChar2 )
71 {
72 case 'd':
73 configuration.CompilationUnitsEnabled = false;
74 break;
75 default:
76 printf ( "Unknown switch -u%c\n",
77 switchChar2 );
78 return false;
79 }
80 return true;
81 }
82
83 bool
84 ParseVCProjectSwitch (
85 char switchChar2,
86 char* switchStart )
87 {
88 switch ( switchChar2 )
89 {
90 case 's':
91 if ( strlen ( switchStart ) <= 3 )
92 {
93 printf ( "Switch -dm requires a module name\n" );
94 return false;
95 }
96 configuration.VSProjectVersion = string(&switchStart[3]);
97
98 if (configuration.VSProjectVersion.at(0) == '{') {
99 printf ( "Error: invalid char {\n" );
100 return false;
101 }
102
103 if (configuration.VSProjectVersion.length() == 1) //7,8
104 configuration.VSProjectVersion.append(".00");
105
106 if (configuration.VSProjectVersion.length() == 3) //7.1
107 configuration.VSProjectVersion.append("0");
108
109 break;
110 default:
111 printf ( "Unknown switch -d%c\n",
112 switchChar2 );
113 return false;
114 }
115 return true;
116 }
117
118 bool
119 ParseMakeSwitch ( char switchChar2 )
120 {
121 switch ( switchChar2 )
122 {
123 case 'i':
124 configuration.MakeHandlesInstallDirectories = true;
125 break;
126 default:
127 printf ( "Unknown switch -m%c\n",
128 switchChar2 );
129 return false;
130 }
131 return true;
132 }
133
134 bool
135 ParseProxyMakefileSwitch ( char switchChar2 )
136 {
137 switch ( switchChar2 )
138 {
139 case 's':
140 configuration.GenerateProxyMakefilesInSourceTree = true;
141 break;
142 default:
143 printf ( "Unknown switch -p%c\n",
144 switchChar2 );
145 return false;
146 }
147 return true;
148 }
149
150 bool
151 ParseSwitch ( int argc, char** argv, int index )
152 {
153 char switchChar = strlen ( argv[index] ) > 1 ? argv[index][1] : ' ';
154 char switchChar2 = strlen ( argv[index] ) > 2 ? argv[index][2] : ' ';
155 switch ( switchChar )
156 {
157 case 'v':
158 if (switchChar2 == 's')
159 {
160 return ParseVCProjectSwitch (
161 switchChar2,
162 argv[index] );
163 }
164 else
165 configuration.Verbose = true;
166 break;
167 case 'c':
168 configuration.CleanAsYouGo = true;
169 break;
170 case 'd':
171 return ParseAutomaticDependencySwitch (
172 switchChar2,
173 argv[index] );
174 case 'u':
175 return ParseCompilationUnitSwitch (
176 switchChar2,
177 argv[index] );
178 case 'r':
179 RootXmlFile = string(&argv[index][2]);
180 break;
181 case 'm':
182 return ParseMakeSwitch ( switchChar2 );
183 case 'p':
184 return ParseProxyMakefileSwitch ( switchChar2 );
185 default:
186 printf (
187 "Unknown switch -%c\n",
188 switchChar );
189 return false;
190 }
191 return true;
192 }
193
194 bool
195 ParseArguments ( int argc, char** argv )
196 {
197 if ( argc < 2 )
198 return false;
199
200 for ( int i = 1; i < argc; i++ )
201 {
202 if ( argv[i][0] == '-' )
203 {
204 if ( !ParseSwitch ( argc, argv, i ) )
205 return false;
206 }
207 else
208 BuildSystem = argv[i];
209 }
210
211 return true;
212 }
213
214 int
215 main ( int argc, char** argv )
216 {
217 InitializeEnvironment ();
218
219 if ( !ParseArguments ( argc, argv ) )
220 {
221 printf ( "Generates project files for buildsystems\n\n" );
222 printf ( " rbuild [switches] buildsystem\n\n" );
223 printf ( "Switches:\n" );
224 printf ( " -v Be verbose.\n" );
225 printf ( " -c Clean as you go. Delete generated files as soon as they are not\n" );
226 printf ( " needed anymore.\n" );
227 printf ( " -r{file.xml} Name of the root xml file. Default is ReactOS.xml.\n" );
228 printf ( " -dd Disable automatic dependencies.\n" );
229 printf ( " -dm{module} Check only automatic dependencies for this module.\n" );
230 printf ( " -ud Disable multiple source files per compilation unit.\n" );
231 printf ( " -mi Let make handle creation of install directories. Rbuild will\n" );
232 printf ( " not generate the directories.\n" );
233 printf ( " -ps Generate proxy makefiles in source tree instead of the output.\n" );
234 printf ( " tree.\n" );
235 printf ( " -vs{version} Version of MS VS project files. Default is %s.\n", MS_VS_DEF_VERSION );
236 printf ( "\n" );
237 printf ( " buildsystem Target build system. Can be one of:\n" );
238 printf ( " mingw MinGW\n" );
239 printf ( " devcpp DevC++\n" );
240 printf ( " msvc MS Visual Studio\n" );
241 return 1;
242 }
243 try
244 {
245 string projectFilename ( RootXmlFile );
246
247 printf ( "Reading build files..." );
248 Project project ( configuration, projectFilename );
249 printf ( "done\n" );
250
251 project.SetBackend ( Backend::Factory::Create (
252 BuildSystem,
253 project,
254 configuration ) );
255
256 project.WriteConfigurationFile ();
257 project.ExecuteInvocations ();
258 project.GetBackend().Process();
259
260 return 0;
261 }
262 catch ( Exception& ex )
263 {
264 printf ( "%s\n", (*ex).c_str () );
265 return 1;
266 }
267 catch ( XMLException& ex )
268 {
269 printf ( "%s\n", (*ex).c_str () );
270 return 1;
271 }
272 }