added some verbosity
[reactos.git] / reactos / tools / rbuild / backend / msvc / msvc.cpp
1 /*
2 * Copyright (C) 2005 Trevor McCort
3 * Copyright (C) 2005 Casper S. Hornstrup
4 * Copyright (C) 2005 Steven Edwards
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20 #ifdef _MSC_VER
21 #pragma warning ( disable : 4786 )
22 #endif//_MSC_VER
23
24 #include <iostream>
25 #include <fstream>
26 #include <string>
27
28 #include "msvc.h"
29 #include "../mingw/mingw.h"
30
31 using namespace std;
32
33 char get_key(char *valid,char *prompt); //FIXME
34 bool spawn_new(const string& cmd); //FIXME
35 void gen_guid();
36
37 static class MSVCFactory : public Backend::Factory
38 {
39 public:
40
41 MSVCFactory() : Factory("MSVC") {}
42 Backend *operator() (Project &project,
43 Configuration& configuration)
44 {
45 return new MSVCBackend(project, configuration);
46 }
47
48 } factory;
49
50
51 MSVCBackend::MSVCBackend(Project &project,
52 Configuration& configuration) : Backend(project, configuration)
53 {
54 m_unitCount = 0;
55 }
56
57 void MSVCBackend::Process()
58 {
59 //bool exec = false;
60 //const char rbuild_mingw[] = "output-i386\\tools\\rbuild\\rbuild.exe mingw";
61
62 string filename = ProjectNode.name + ".dsw";
63
64 printf ( "Creating MSVC workspace: %s\n", filename.c_str() );
65
66 ProcessModules();
67
68 m_dswFile = fopen ( filename.c_str(), "w" );
69
70 if ( !m_dswFile )
71 {
72 printf ( "Could not create file '%s'.\n", filename.c_str() );
73 return;
74 }
75 _generate_wine_dsw ( m_dswFile );
76 #if 0
77 m_devFile << "Microsoft Visual Studio Solution File, Format Version 9.00" << endl;
78 m_devFile << "# Visual C++ Express 2005" << endl;
79
80 m_devFile << "# FIXME Project listings here" << endl;
81 m_devFile << "EndProject" << endl;
82 m_devFile << "Global" << endl;
83 m_devFile << " GlobalSection(SolutionConfigurationPlatforms) = preSolution" << endl;
84 m_devFile << " Debug|Win32 = Debug|Win32" << endl;
85 m_devFile << " Release|Win32 = Release|Win32" << endl;
86 m_devFile << " EndGlobalSection" << endl;
87 m_devFile << " GlobalSection(ProjectConfigurationPlatforms) = postSolution" << endl;
88 m_devFile << " #FIXME Project Listings Here" << endl;
89 m_devFile << " EndGlobalSection" << endl;
90 m_devFile << " GlobalSection(SolutionProperties) = preSolution" << endl;
91 m_devFile << " HideSolutionNode = FALSE" << endl;
92 m_devFile << " EndGlobalSection" << endl;
93 m_devFile << "EndGlobal" << endl;
94
95 m_devFile << endl << endl;
96 #endif
97 fclose ( m_dswFile );
98
99 gen_guid();
100
101 // The MSVC build still needs the mingw backend.
102 //ProcessModules();
103
104 printf ( "Done.\n" );
105
106 /*cout << "Don't expect the MSVC backend to work yet. "<< endl << endl;
107
108 if(get_key("yn","Would you like to configure for a Mingw build as well? (y/n)") == 'y')
109 {
110 exec = spawn_new(rbuild_mingw);
111 if (!exec)
112 printf("\nError invoking rbuild\n");
113 }*/
114 }
115
116 void MSVCBackend::ProcessModules()
117 {
118 for(size_t i = 0; i < ProjectNode.modules.size(); i++)
119 {
120 Module &module = *ProjectNode.modules[i];
121
122 this->_generate_dsp ( module );
123
124 /*for(size_t k = 0; k < module.non_if_data.files.size(); k++)
125 {
126 File &file = *module.non_if_data.files[k];
127
128 ProcessFile(file.name);
129 }*/
130 }
131 }
132
133 static bool FileExists(string &filename)
134 {
135 ifstream file(filename.c_str());
136
137 if(!file.is_open())
138 return false;
139
140 file.close();
141 return true;
142 }
143
144 void MSVCBackend::ProcessFile(string &filepath)
145 {
146 // Remove the .\ at the start of the filenames
147 if ( filepath[0] == '.' && strchr ( "/\\", filepath[1] ) )
148 filepath.erase(0, 2);
149
150 if(!FileExists(filepath))
151 return;
152
153 // Change the \ to /
154 for(size_t i = 0; i < filepath.length(); i++)
155 {
156 if(filepath[i] == '\\')
157 filepath[i] = '/';
158 }
159
160 // Remove the filename from the path
161 string folder = "";
162
163 size_t pos = filepath.rfind(string("/"), filepath.length() - 1);
164
165 if(pos != string::npos)
166 {
167 folder = filepath;
168 folder.erase(pos, folder.length() - pos);
169 }
170
171 FileUnit fileUnit;
172 fileUnit.filename = filepath;
173 fileUnit.folder = folder;
174
175 m_fileUnits.push_back(fileUnit);
176
177 if(folder != "")
178 AddFolders(folder);
179
180 m_unitCount++;
181 }
182
183 bool MSVCBackend::CheckFolderAdded(string &folder)
184 {
185 for(size_t i = 0; i < m_folders.size(); i++)
186 {
187 if(m_folders[i] == folder)
188 return true;
189 }
190
191 return false;
192 }
193
194 void MSVCBackend::AddFolders(string &folder)
195 {
196 // Check if this folder was already added. true if it was, false otherwise.
197 if(CheckFolderAdded(folder))
198 return;
199
200 m_folders.push_back(folder);
201
202 size_t pos = folder.rfind(string("/"), folder.length() - 1);
203
204 if(pos == string::npos)
205 return;
206
207 folder.erase(pos, folder.length() - pos);
208 AddFolders(folder);
209 }
210
211 void MSVCBackend::OutputFolders()
212 {
213 #if 0
214 m_devFile << "Folders=";
215
216 for(size_t i = 0; i < m_folders.size(); i++)
217 {
218 if(i > 0)
219 m_devFile << ",";
220
221 m_devFile << m_folders[i];
222 }
223 #endif
224 }
225
226
227 char get_key(char *valid,char *prompt)
228 {
229 int ch,okay;
230
231 while (1) {
232 if (prompt) printf("%s ",prompt);
233 fflush(stdout);
234 while (ch = getchar(), ch == ' ' || ch == '\t');
235 if (ch == EOF) exit(1);
236 if (!strchr(valid,okay = ch)) okay = 0;
237 while (ch = getchar(), ch != '\n' && ch != EOF);
238 if (ch == EOF) exit(1);
239 if (okay) return okay;
240 printf("Invalid input.\n");
241 }
242 }
243
244 bool spawn_new( const string& cmd )
245 {
246 string command = ssprintf (
247 "%s",
248 cmd.c_str (),
249 NUL,
250 NUL );
251 int exitcode = system ( command.c_str () );
252 return (exitcode == 0);
253 }
254
255 std::string
256 MSVCBackend::DspFileName ( const Module& module ) const
257 {
258 return DosSeparator(
259 ReplaceExtension ( module.GetPath(), ".dsp" )
260 );
261 }