This fixes the small problem that generated files were being added to the Dev-C+...
[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 #include <iostream>
21 #include <fstream>
22 #include <string>
23
24 #include "devcpp.h"
25
26 using namespace std;
27
28 static class DevCppFactory : public Backend::Factory
29 {
30 public:
31
32 DevCppFactory() : Factory("devcpp") {}
33 Backend *operator() (Project &project)
34 {
35 return new DevCppBackend(project);
36 }
37
38 } factory;
39
40
41 DevCppBackend::DevCppBackend(Project &project) : Backend(project)
42 {
43 m_unitCount = 0;
44 }
45
46 void DevCppBackend::Process()
47 {
48 string filename = ProjectNode.name + ".dev";
49
50 cout << "Creating Dev-C++ project: " << filename << endl;
51
52 ProcessModules();
53
54 m_devFile.open(filename.c_str());
55
56 if(!m_devFile.is_open())
57 {
58 cout << "Could not open file." << endl;
59 return;
60 }
61
62 m_devFile << "[Project]" << endl;
63
64 m_devFile << "FileName=" << filename << endl
65 << "Name=" << ProjectNode.name << endl
66 << "UnitCount=" << m_unitCount << endl
67 << "Type=1" << endl
68 << "Ver=1" << endl
69 << "ObjFiles=" << endl
70 << "Includes=" << endl
71 << "Libs=" << endl
72 << "PrivateResource=" << endl
73 << "ResourceIncludes=" << endl
74 << "MakeIncludes=" << endl
75 << "Compiler=" << endl
76 << "CppCompiler=" << endl
77 << "Linker=" << endl
78 << "IsCpp=1" << endl
79 << "Icon=" << endl
80 << "ExeOutput=" << endl
81 << "ObjectOutput=" << endl
82 << "OverrideOutput=0" << endl
83 << "OverrideOutputName=" << endl
84 << "HostApplication=" << endl
85 << "CommandLine=" << endl
86 << "UseCustomMakefile=1" << endl
87 << "CustomMakefile=" << ProjectNode.makefile << endl
88 << "IncludeVersionInto=0" << endl
89 << "SupportXPThemes=0" << endl
90 << "CompilerSet=0" << endl
91
92 << "CompilerSettings=0000000000000000000000" << endl;
93
94 OutputFolders();
95
96 m_devFile << endl << endl;
97
98 OutputFileUnits();
99
100 m_devFile.close();
101
102 // Dev-C++ needs a makefile, so use the MinGW backend to create one.
103
104 cout << "Creating Makefile: " << ProjectNode.makefile << endl;
105
106 Backend *backend = Backend::Factory::Create("mingw", ProjectNode);
107 backend->Process();
108 delete backend;
109
110 cout << "Done." << endl << endl;
111
112 cout << "You may want to disable Class browsing (see below) before you open this project in Dev-C++, as the "
113 << "parsing required for large projects can take quite awhile."
114 << endl << endl
115 << "(Tools->Editor Options->Class browsing->Enable class browsing check box)"
116 << endl << endl;
117 }
118
119 void DevCppBackend::ProcessModules()
120 {
121 for(size_t i = 0; i < ProjectNode.modules.size(); i++)
122 {
123 Module &module = *ProjectNode.modules[i];
124
125 for(size_t k = 0; k < module.files.size(); k++)
126 {
127 File &file = *module.files[k];
128
129 ProcessFile(file.name);
130 }
131 }
132 }
133
134 bool FileExists(string &filename)
135 {
136 ifstream file(filename.c_str());
137
138 if(!file.is_open())
139 return false;
140
141 file.close();
142 return true;
143 }
144
145 void DevCppBackend::ProcessFile(string &filepath)
146 {
147 // Remove the .\ at the start of the filenames
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 DevCppBackend::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 DevCppBackend::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 DevCppBackend::OutputFolders()
212 {
213 m_devFile << "Folders=";
214
215 for(size_t i = 0; i < m_folders.size(); i++)
216 {
217 if(i > 0)
218 m_devFile << ",";
219
220 m_devFile << m_folders[i];
221 }
222 }
223
224 void DevCppBackend::OutputFileUnits()
225 {
226 for(size_t i = 0; i < m_fileUnits.size(); i++)
227 {
228 m_devFile << "[Unit" << i + 1 << "]" << endl;
229
230
231 m_devFile << "FileName=" << m_fileUnits[i].filename << endl;
232 m_devFile << "CompileCpp=1" << endl;
233 m_devFile << "Folder=" << m_fileUnits[i].folder << endl;
234 m_devFile << "Compile=1" << endl;
235 m_devFile << "Link=1" << endl;
236 m_devFile << "Priority=1000" << endl;
237 m_devFile << "OverrideBuildCmd=0" << endl;
238 m_devFile << "BuildCmd=" << endl << endl;;
239 }
240 }