f156ceb73c35fb66ae9f66b5292ce0ebee5d15ce
[reactos.git] / reactos / tools / rbuild / backend / devcpp / devcpp.cpp
1 /*
2 * Dev-C++ Backend
3 * Copyright (C) 2005 Trevor McCort
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
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 "devcpp.h"
29
30 using namespace std;
31
32 static class DevCppFactory : public Backend::Factory
33 {
34 public:
35
36 DevCppFactory() : Factory("devcpp") {}
37 Backend *operator() (Project &project,
38 Configuration& configuration)
39 {
40 return new DevCppBackend(project, configuration);
41 }
42
43 } factory;
44
45
46 DevCppBackend::DevCppBackend(Project &project,
47 Configuration& configuration) : Backend(project, configuration)
48 {
49 m_unitCount = 0;
50 }
51
52 void DevCppBackend::Process()
53 {
54 string filename = ProjectNode.name + ".dev";
55
56 cout << "Creating Dev-C++ project: " << filename << endl;
57
58 ProcessModules();
59
60 m_devFile.open(filename.c_str());
61
62 if(!m_devFile.is_open())
63 {
64 cout << "Could not open file." << endl;
65 return;
66 }
67
68 m_devFile << "[Project]" << endl;
69
70 m_devFile << "FileName=" << filename << endl
71 << "Name=" << ProjectNode.name << endl
72 << "UnitCount=" << m_unitCount << endl
73 << "Type=1" << endl
74 << "Ver=1" << endl
75 << "ObjFiles=" << endl
76 << "Includes=" << endl
77 << "Libs=" << endl
78 << "PrivateResource=" << endl
79 << "ResourceIncludes=" << endl
80 << "MakeIncludes=" << endl
81 << "Compiler=" << endl
82 << "CppCompiler=" << endl
83 << "Linker=" << endl
84 << "IsCpp=1" << endl
85 << "Icon=" << endl
86 << "ExeOutput=" << endl
87 << "ObjectOutput=" << endl
88 << "OverrideOutput=0" << endl
89 << "OverrideOutputName=" << endl
90 << "HostApplication=" << endl
91 << "CommandLine=" << endl
92 << "UseCustomMakefile=1" << endl
93 << "CustomMakefile=" << ProjectNode.makefile << endl
94 << "IncludeVersionInto=0" << endl
95 << "SupportXPThemes=0" << endl
96 << "CompilerSet=0" << endl
97
98 << "CompilerSettings=0000000000000000000000" << endl;
99
100 OutputFolders();
101
102 m_devFile << endl << endl;
103
104 OutputFileUnits();
105
106 m_devFile.close();
107
108 // Dev-C++ needs a makefile, so use the MinGW backend to create one.
109
110 cout << "Creating Makefile: " << ProjectNode.makefile << endl;
111
112 Backend *backend = Backend::Factory::Create("mingw",
113 ProjectNode,
114 configuration );
115 backend->Process();
116 delete backend;
117
118 cout << "Done." << endl << endl;
119
120 cout << "You may want to disable Class browsing (see below) before you open this project in Dev-C++, as the "
121 << "parsing required for large projects can take quite awhile."
122 << endl << endl
123 << "(Tools->Editor Options->Class browsing->Enable class browsing check box)"
124 << endl << endl;
125 }
126
127 void DevCppBackend::ProcessModules()
128 {
129 for(size_t i = 0; i < ProjectNode.modules.size(); i++)
130 {
131 Module &module = *ProjectNode.modules[i];
132
133 for(size_t k = 0; k < module.non_if_data.files.size(); k++)
134 {
135 File &file = *module.non_if_data.files[k];
136
137 ProcessFile(file.name);
138 }
139 }
140 }
141
142 bool FileExists(string &filename)
143 {
144 ifstream file(filename.c_str());
145
146 if(!file.is_open())
147 return false;
148
149 file.close();
150 return true;
151 }
152
153 void DevCppBackend::ProcessFile(string &filepath)
154 {
155 // Remove the .\ at the start of the filenames
156 filepath.erase(0, 2);
157
158 if(!FileExists(filepath))
159 return;
160
161 // Change the \ to /
162 for(size_t i = 0; i < filepath.length(); i++)
163 {
164 if(filepath[i] == '\\')
165 filepath[i] = '/';
166 }
167
168 // Remove the filename from the path
169 string folder = "";
170
171 size_t pos = filepath.rfind(string("/"), filepath.length() - 1);
172
173 if(pos != string::npos)
174 {
175 folder = filepath;
176 folder.erase(pos, folder.length() - pos);
177 }
178
179 FileUnit fileUnit;
180 fileUnit.filename = filepath;
181 fileUnit.folder = folder;
182
183 m_fileUnits.push_back(fileUnit);
184
185 if(folder != "")
186 AddFolders(folder);
187
188 m_unitCount++;
189 }
190
191 bool DevCppBackend::CheckFolderAdded(string &folder)
192 {
193 for(size_t i = 0; i < m_folders.size(); i++)
194 {
195 if(m_folders[i] == folder)
196 return true;
197 }
198
199 return false;
200 }
201
202 void DevCppBackend::AddFolders(string &folder)
203 {
204 // Check if this folder was already added. true if it was, false otherwise.
205 if(CheckFolderAdded(folder))
206 return;
207
208 m_folders.push_back(folder);
209
210 size_t pos = folder.rfind(string("/"), folder.length() - 1);
211
212 if(pos == string::npos)
213 return;
214
215 folder.erase(pos, folder.length() - pos);
216 AddFolders(folder);
217 }
218
219 void DevCppBackend::OutputFolders()
220 {
221 m_devFile << "Folders=";
222
223 for(size_t i = 0; i < m_folders.size(); i++)
224 {
225 if(i > 0)
226 m_devFile << ",";
227
228 m_devFile << m_folders[i];
229 }
230 }
231
232 void DevCppBackend::OutputFileUnits()
233 {
234 for(size_t i = 0; i < m_fileUnits.size(); i++)
235 {
236 m_devFile << "[Unit" << i + 1 << "]" << endl;
237
238
239 m_devFile << "FileName=" << m_fileUnits[i].filename << endl;
240 m_devFile << "CompileCpp=1" << endl;
241 m_devFile << "Folder=" << m_fileUnits[i].folder << endl;
242 m_devFile << "Compile=1" << endl;
243 m_devFile << "Link=1" << endl;
244 m_devFile << "Priority=1000" << endl;
245 m_devFile << "OverrideBuildCmd=0" << endl;
246 m_devFile << "BuildCmd=" << endl << endl;;
247 }
248 }