make_msvcX_install_[config] patch by Brezenbak
[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 case 'c':
111 configuration.VSConfigurationType = string (&switchStart[3]);
112 configuration.InstallFiles = true;
113 break;
114 default:
115 printf ( "Unknown switch -d%c\n",
116 switchChar2 );
117 return false;
118 }
119 return true;
120 }
121
122 bool
123 ParseMakeSwitch ( char switchChar2 )
124 {
125 switch ( switchChar2 )
126 {
127 case 'i':
128 configuration.MakeHandlesInstallDirectories = true;
129 break;
130 default:
131 printf ( "Unknown switch -m%c\n",
132 switchChar2 );
133 return false;
134 }
135 return true;
136 }
137
138 bool
139 ParseProxyMakefileSwitch ( char switchChar2 )
140 {
141 switch ( switchChar2 )
142 {
143 case 's':
144 configuration.GenerateProxyMakefilesInSourceTree = true;
145 break;
146 default:
147 printf ( "Unknown switch -p%c\n",
148 switchChar2 );
149 return false;
150 }
151 return true;
152 }
153
154 bool
155 ParseSwitch ( int argc, char** argv, int index )
156 {
157 char switchChar = strlen ( argv[index] ) > 1 ? argv[index][1] : ' ';
158 char switchChar2 = strlen ( argv[index] ) > 2 ? argv[index][2] : ' ';
159 switch ( switchChar )
160 {
161 case 'v':
162 if (switchChar2 == 's' || switchChar2 == 'c' )
163 {
164 return ParseVCProjectSwitch (
165 switchChar2,
166 argv[index] );
167 }
168 else
169 configuration.Verbose = true;
170 break;
171 case 'c':
172 configuration.CleanAsYouGo = true;
173 break;
174 case 'd':
175 return ParseAutomaticDependencySwitch (
176 switchChar2,
177 argv[index] );
178 case 'u':
179 return ParseCompilationUnitSwitch (
180 switchChar2,
181 argv[index] );
182 case 'r':
183 RootXmlFile = string(&argv[index][2]);
184 break;
185 case 'm':
186 return ParseMakeSwitch ( switchChar2 );
187 case 'p':
188 return ParseProxyMakefileSwitch ( switchChar2 );
189 default:
190 printf (
191 "Unknown switch -%c\n",
192 switchChar );
193 return false;
194 }
195 return true;
196 }
197
198 bool
199 ParseArguments ( int argc, char** argv )
200 {
201 if ( argc < 2 )
202 return false;
203
204 for ( int i = 1; i < argc; i++ )
205 {
206 if ( argv[i][0] == '-' )
207 {
208 if ( !ParseSwitch ( argc, argv, i ) )
209 return false;
210 }
211 else
212 BuildSystem = argv[i];
213 }
214
215 return true;
216 }
217
218 int
219 main ( int argc, char** argv )
220 {
221 InitializeEnvironment ();
222
223 if ( !ParseArguments ( argc, argv ) )
224 {
225 printf ( "Generates project files for buildsystems\n\n" );
226 printf ( " rbuild [switches] buildsystem\n\n" );
227 printf ( "Switches:\n" );
228 printf ( " -v Be verbose.\n" );
229 printf ( " -c Clean as you go. Delete generated files as soon as they are not\n" );
230 printf ( " needed anymore.\n" );
231 printf ( " -r{file.xml} Name of the root xml file. Default is ReactOS.xml.\n" );
232 printf ( " -dd Disable automatic dependencies.\n" );
233 printf ( " -dm{module} Check only automatic dependencies for this module.\n" );
234 printf ( " -ud Disable multiple source files per compilation unit.\n" );
235 printf ( " -mi Let make handle creation of install directories. Rbuild will\n" );
236 printf ( " not generate the directories.\n" );
237 printf ( " -ps Generate proxy makefiles in source tree instead of the output.\n" );
238 printf ( " tree.\n" );
239 printf ( " -vs{version} Version of MS VS project files. Default is %s.\n", MS_VS_DEF_VERSION );
240 printf ( "\n" );
241 printf ( " buildsystem Target build system. Can be one of:\n" );
242 printf ( " mingw MinGW\n" );
243 printf ( " devcpp DevC++\n" );
244 printf ( " msvc MS Visual Studio\n" );
245 return 1;
246 }
247 try
248 {
249 string projectFilename ( RootXmlFile );
250
251 printf ( "Reading build files..." );
252 Project project ( configuration, projectFilename );
253 printf ( "done\n" );
254
255 project.SetBackend ( Backend::Factory::Create (
256 BuildSystem,
257 project,
258 configuration ) );
259
260 project.WriteConfigurationFile ();
261 project.ExecuteInvocations ();
262 project.GetBackend().Process();
263
264 return 0;
265 }
266 catch ( Exception& ex )
267 {
268 printf ( "%s\n", (*ex).c_str () );
269 return 1;
270 }
271 catch ( XMLException& ex )
272 {
273 printf ( "%s\n", (*ex).c_str () );
274 return 1;
275 }
276 }