d0832dd67780376b283edfea7a0de93f14451a84
[reactos.git] / reactos / tools / rbuild / backend / mingw / modulehandler.cpp
1
2 #include "../../pch.h"
3 #include <assert.h>
4
5 #include "../../rbuild.h"
6 #include "mingw.h"
7 #include "modulehandler.h"
8
9 using std::string;
10 using std::vector;
11
12 MingwModuleHandler::MingwModuleHandler ( FILE* fMakefile )
13 : fMakefile ( fMakefile )
14 {
15 }
16
17 string
18 MingwModuleHandler::GetWorkingDirectory () const
19 {
20 return ".";
21 }
22
23 string
24 MingwModuleHandler::ReplaceExtension ( const string& filename,
25 const string& newExtension ) const
26 {
27 size_t index = filename.find_last_of ( '.' );
28 if (index != string::npos)
29 return filename.substr ( 0, index ) + newExtension;
30 return filename;
31 }
32
33 string
34 MingwModuleHandler::GetModuleArchiveFilename ( const Module& module ) const
35 {
36 return ReplaceExtension ( module.GetPath ().c_str (),
37 ".a" );
38 }
39
40 string
41 MingwModuleHandler::GetImportLibraryDependencies ( const Module& module ) const
42 {
43 if ( module.libraries.size () == 0 )
44 return "";
45
46 string dependencies ( "" );
47 for ( size_t i = 0; i < module.libraries.size (); i++ )
48 {
49 if ( dependencies.size () > 0 )
50 dependencies += " ";
51 const Module* importedModule = module.project.LocateModule ( module.libraries[i]->name );
52 assert ( importedModule != NULL );
53 dependencies += importedModule->GetPath ().c_str ();
54 }
55 return dependencies;
56 }
57
58 string
59 MingwModuleHandler::GetSourceFilenames ( const Module& module ) const
60 {
61 if ( module.files.size () == 0 )
62 return "";
63
64 string sourceFilenames ( "" );
65 for ( size_t i = 0; i < module.files.size (); i++ )
66 {
67 if ( sourceFilenames.size () > 0 )
68 sourceFilenames += " ";
69 sourceFilenames += module.files[i]->name;
70 }
71 return sourceFilenames;
72 }
73
74 string
75 MingwModuleHandler::GetObjectFilename ( const string& sourceFilename ) const
76 {
77 return ReplaceExtension ( sourceFilename,
78 ".o" );
79 }
80
81 string
82 MingwModuleHandler::GetObjectFilenames ( const Module& module ) const
83 {
84 if ( module.files.size () == 0 )
85 return "";
86
87 string objectFilenames ( "" );
88 for ( size_t i = 0; i < module.files.size (); i++ )
89 {
90 if ( objectFilenames.size () > 0 )
91 objectFilenames += " ";
92 objectFilenames += GetObjectFilename ( module.files[i]->name );
93 }
94 return objectFilenames;
95 }
96
97 string
98 MingwModuleHandler::GenerateGccDefineParametersFromVector ( const vector<Define*>& defines ) const
99 {
100 string parameters;
101 for (size_t i = 0; i < defines.size (); i++)
102 {
103 Define& define = *defines[i];
104 if (parameters.length () > 0)
105 parameters += " ";
106 parameters += "-D";
107 parameters += define.name;
108 if (define.value.length () > 0)
109 {
110 parameters += "=";
111 parameters += define.value;
112 }
113 }
114 return parameters;
115 }
116
117 string
118 MingwModuleHandler::GenerateGccDefineParameters ( const Module& module ) const
119 {
120 string parameters = GenerateGccDefineParametersFromVector ( module.project.defines );
121 string s = GenerateGccDefineParametersFromVector ( module.defines );
122 if (s.length () > 0)
123 {
124 parameters += " ";
125 parameters += s;
126 }
127 return parameters;
128 }
129
130 string
131 MingwModuleHandler::ConcatenatePaths ( const string& path1,
132 const string& path2 ) const
133 {
134 if ( ( path1.length () == 0 ) || ( path1 == "." ) || ( path1 == "./" ) )
135 return path2;
136 if ( path1[path1.length ()] == CSEP )
137 return path1 + path2;
138 else
139 return path1 + CSEP + path2;
140 }
141
142 string
143 MingwModuleHandler::GenerateGccIncludeParametersFromVector ( const vector<Include*>& includes ) const
144 {
145 string parameters;
146 for (size_t i = 0; i < includes.size (); i++)
147 {
148 Include& include = *includes[i];
149 if (parameters.length () > 0)
150 parameters += " ";
151 parameters += "-I" + include.directory;
152 }
153 return parameters;
154 }
155
156 string
157 MingwModuleHandler::GenerateGccIncludeParameters ( const Module& module ) const
158 {
159 string parameters = GenerateGccIncludeParametersFromVector ( module.project.includes );
160 string s = GenerateGccIncludeParametersFromVector ( module.includes );
161 if (s.length () > 0)
162 {
163 parameters += " ";
164 parameters += s;
165 }
166 return parameters;
167 }
168
169 string
170 MingwModuleHandler::GenerateGccParameters ( const Module& module ) const
171 {
172 string parameters = GenerateGccDefineParameters ( module );
173 string s = GenerateGccIncludeParameters ( module );
174 if (s.length () > 0)
175 {
176 parameters += " ";
177 parameters += s;
178 }
179 return parameters;
180 }
181
182 void
183 MingwModuleHandler::GenerateObjectFileTargets ( const Module& module ) const
184 {
185 if ( module.files.size () == 0 )
186 return;
187
188 for ( size_t i = 0; i < module.files.size (); i++ )
189 {
190 string sourceFilename = module.files[i]->name;
191 string objectFilename = GetObjectFilename ( sourceFilename );
192 fprintf ( fMakefile,
193 "%s: %s\n",
194 objectFilename.c_str (),
195 sourceFilename.c_str() );
196 fprintf ( fMakefile,
197 "\t${gcc} -c %s -o %s %s\n",
198 sourceFilename.c_str (),
199 objectFilename.c_str (),
200 GenerateGccParameters ( module ).c_str () );
201 }
202
203 fprintf ( fMakefile, "\n" );
204 }
205
206 void
207 MingwModuleHandler::GenerateArchiveTarget ( const Module& module ) const
208 {
209 string archiveFilename = GetModuleArchiveFilename ( module );
210 string sourceFilenames = GetSourceFilenames ( module );
211 string objectFilenames = GetObjectFilenames ( module );
212
213 fprintf ( fMakefile,
214 "%s: %s\n",
215 archiveFilename.c_str (),
216 objectFilenames.c_str ());
217
218 fprintf ( fMakefile,
219 "\t${ar} -rc %s %s\n\n",
220 archiveFilename.c_str (),
221 objectFilenames.c_str ());
222 }
223
224
225 MingwKernelModuleHandler::MingwKernelModuleHandler ( FILE* fMakefile )
226 : MingwModuleHandler ( fMakefile )
227 {
228 }
229
230 bool
231 MingwKernelModuleHandler::CanHandleModule ( const Module& module ) const
232 {
233 return module.type == KernelModeDLL;
234 }
235
236 void
237 MingwKernelModuleHandler::Process ( const Module& module )
238 {
239 GenerateKernelModuleTarget ( module );
240 }
241
242 void
243 MingwKernelModuleHandler::GenerateKernelModuleTarget ( const Module& module )
244 {
245 string workingDirectory = GetWorkingDirectory ( );
246 string archiveFilename = GetModuleArchiveFilename ( module );
247 string importLibraryDependencies = GetImportLibraryDependencies ( module );
248 fprintf ( fMakefile, "%s: %s %s\n",
249 module.GetPath ().c_str (),
250 archiveFilename.c_str (),
251 importLibraryDependencies.c_str () );
252 fprintf ( fMakefile,
253 "\t${gcc} -Wl,--base-file,%s" SSEP "base.tmp -o %s" SSEP "junk.tmp %s %s\n",
254 workingDirectory.c_str (),
255 workingDirectory.c_str (),
256 archiveFilename.c_str (),
257 importLibraryDependencies.c_str () );
258 fprintf ( fMakefile,
259 "\t${rm} %s" SSEP "junk.tmp\n",
260 workingDirectory.c_str () );
261 fprintf ( fMakefile,
262 "\t${dlltool} --dllname %s --base-file %s" SSEP "base.tmp --output-exp %s" SSEP "temp.exp --kill-at\n",
263 module.GetPath ().c_str (),
264 workingDirectory.c_str (),
265 workingDirectory.c_str ());
266 fprintf ( fMakefile,
267 "\t${rm} %s" SSEP "base.tmp\n",
268 workingDirectory.c_str () );
269 fprintf ( fMakefile,
270 "\t${ld} -Wl,%s" SSEP "temp.exp -o %s %s %s\n",
271 workingDirectory.c_str (),
272 module.GetPath ().c_str (),
273 archiveFilename.c_str (),
274 importLibraryDependencies.c_str () );
275 fprintf ( fMakefile,
276 "\t${rm} %s" SSEP "temp.exp\n",
277 workingDirectory.c_str () );
278
279 GenerateArchiveTarget ( module );
280 GenerateObjectFileTargets ( module );
281 }
282
283
284 MingwStaticLibraryModuleHandler::MingwStaticLibraryModuleHandler ( FILE* fMakefile )
285 : MingwModuleHandler ( fMakefile )
286 {
287 }
288
289 bool
290 MingwStaticLibraryModuleHandler::CanHandleModule ( const Module& module ) const
291 {
292 return module.type == StaticLibrary;
293 }
294
295 void
296 MingwStaticLibraryModuleHandler::Process ( const Module& module )
297 {
298 GenerateStaticLibraryModuleTarget ( module );
299 }
300
301 void
302 MingwStaticLibraryModuleHandler::GenerateStaticLibraryModuleTarget ( const Module& module )
303 {
304 GenerateArchiveTarget ( module );
305 GenerateObjectFileTargets ( module );
306 }