use ROS_TEMPORARY and ROS_INTERMEDIATE to allow builder to override locations for...
[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 ( FixupTargetFilename(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 += FixupTargetFilename(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
78 FixupTargetFilename ( ReplaceExtension ( sourceFilename,
79 ".o" ) );
80 }
81
82 string
83 MingwModuleHandler::GetObjectFilenames ( const Module& module ) const
84 {
85 if ( module.files.size () == 0 )
86 return "";
87
88 string objectFilenames ( "" );
89 for ( size_t i = 0; i < module.files.size (); i++ )
90 {
91 if ( objectFilenames.size () > 0 )
92 objectFilenames += " ";
93 objectFilenames += GetObjectFilename ( module.files[i]->name );
94 }
95 return objectFilenames;
96 }
97
98 string
99 MingwModuleHandler::GenerateGccDefineParametersFromVector ( const vector<Define*>& defines ) const
100 {
101 string parameters;
102 for (size_t i = 0; i < defines.size (); i++)
103 {
104 Define& define = *defines[i];
105 if (parameters.length () > 0)
106 parameters += " ";
107 parameters += "-D";
108 parameters += define.name;
109 if (define.value.length () > 0)
110 {
111 parameters += "=";
112 parameters += define.value;
113 }
114 }
115 return parameters;
116 }
117
118 string
119 MingwModuleHandler::GenerateGccDefineParameters ( const Module& module ) const
120 {
121 string parameters = GenerateGccDefineParametersFromVector ( module.project.defines );
122 string s = GenerateGccDefineParametersFromVector ( module.defines );
123 if (s.length () > 0)
124 {
125 parameters += " ";
126 parameters += s;
127 }
128 return parameters;
129 }
130
131 string
132 MingwModuleHandler::ConcatenatePaths ( const string& path1,
133 const string& path2 ) const
134 {
135 if ( ( path1.length () == 0 ) || ( path1 == "." ) || ( path1 == "./" ) )
136 return path2;
137 if ( path1[path1.length ()] == CSEP )
138 return path1 + path2;
139 else
140 return path1 + CSEP + path2;
141 }
142
143 string
144 MingwModuleHandler::GenerateGccIncludeParametersFromVector ( const vector<Include*>& includes ) const
145 {
146 string parameters;
147 for (size_t i = 0; i < includes.size (); i++)
148 {
149 Include& include = *includes[i];
150 if (parameters.length () > 0)
151 parameters += " ";
152 parameters += "-I" + include.directory;
153 }
154 return parameters;
155 }
156
157 string
158 MingwModuleHandler::GenerateGccIncludeParameters ( const Module& module ) const
159 {
160 string parameters = GenerateGccIncludeParametersFromVector ( module.project.includes );
161 string s = GenerateGccIncludeParametersFromVector ( module.includes );
162 if (s.length () > 0)
163 {
164 parameters += " ";
165 parameters += s;
166 }
167 return parameters;
168 }
169
170 string
171 MingwModuleHandler::GenerateGccParameters ( const Module& module ) const
172 {
173 string parameters = GenerateGccDefineParameters ( module );
174 string s = GenerateGccIncludeParameters ( module );
175 if (s.length () > 0)
176 {
177 parameters += " ";
178 parameters += s;
179 }
180 return parameters;
181 }
182
183 void
184 MingwModuleHandler::GenerateObjectFileTargets ( const Module& module ) const
185 {
186 if ( module.files.size () == 0 )
187 return;
188
189 for ( size_t i = 0; i < module.files.size (); i++ )
190 {
191 string sourceFilename = module.files[i]->name;
192 string objectFilename = GetObjectFilename ( sourceFilename );
193 fprintf ( fMakefile,
194 "%s: %s\n",
195 objectFilename.c_str (),
196 sourceFilename.c_str() );
197 fprintf ( fMakefile,
198 "\t${gcc} -c %s -o %s %s\n",
199 sourceFilename.c_str (),
200 objectFilename.c_str (),
201 GenerateGccParameters ( module ).c_str () );
202 }
203
204 fprintf ( fMakefile, "\n" );
205 }
206
207 void
208 MingwModuleHandler::GenerateArchiveTarget ( const Module& module ) const
209 {
210 string archiveFilename = GetModuleArchiveFilename ( module );
211 string sourceFilenames = GetSourceFilenames ( module );
212 string objectFilenames = GetObjectFilenames ( module );
213
214 fprintf ( fMakefile,
215 "%s: %s\n",
216 archiveFilename.c_str (),
217 objectFilenames.c_str ());
218
219 fprintf ( fMakefile,
220 "\t${ar} -rc %s %s\n\n",
221 archiveFilename.c_str (),
222 objectFilenames.c_str ());
223 }
224
225
226 MingwKernelModuleHandler::MingwKernelModuleHandler ( FILE* fMakefile )
227 : MingwModuleHandler ( fMakefile )
228 {
229 }
230
231 bool
232 MingwKernelModuleHandler::CanHandleModule ( const Module& module ) const
233 {
234 return module.type == KernelModeDLL;
235 }
236
237 void
238 MingwKernelModuleHandler::Process ( const Module& module )
239 {
240 GenerateKernelModuleTarget ( module );
241 }
242
243 void
244 MingwKernelModuleHandler::GenerateKernelModuleTarget ( const Module& module )
245 {
246 static string ros_junk ( "$(ROS_TEMPORARY)" );
247 //static string ros_output ( "$(ROS_INTERMEDIATE)" );
248 string target ( FixupTargetFilename(module.GetPath()) );
249 string workingDirectory = GetWorkingDirectory ( );
250 string archiveFilename = GetModuleArchiveFilename ( module );
251 string importLibraryDependencies = GetImportLibraryDependencies ( module );
252 string base_tmp = ros_junk + module.name + ".base.tmp";
253 string junk_tmp = ros_junk + module.name + ".junk.tmp";
254 string temp_exp = ros_junk + module.name + ".temp.exp";
255 fprintf ( fMakefile, "%s: %s %s\n",
256 target.c_str (),
257 archiveFilename.c_str (),
258 importLibraryDependencies.c_str () );
259 fprintf ( fMakefile,
260 "\t${gcc} -Wl,--base-file,%s -o %s %s %s\n",
261 base_tmp.c_str (),
262 junk_tmp.c_str (),
263 archiveFilename.c_str (),
264 importLibraryDependencies.c_str () );
265 fprintf ( fMakefile,
266 "\t${rm} %s\n",
267 junk_tmp.c_str () );
268 fprintf ( fMakefile,
269 "\t${dlltool} --dllname %s --base-file %s --output-exp %s --kill-at\n",
270 target.c_str (),
271 base_tmp.c_str (),
272 temp_exp.c_str ());
273 fprintf ( fMakefile,
274 "\t${rm} %s\n",
275 base_tmp.c_str () );
276 fprintf ( fMakefile,
277 "\t${ld} -Wl,%s -o %s %s %s\n",
278 temp_exp.c_str (),
279 target.c_str (),
280 archiveFilename.c_str (),
281 importLibraryDependencies.c_str () );
282 fprintf ( fMakefile,
283 "\t${rm} %s\n",
284 temp_exp.c_str () );
285
286 GenerateArchiveTarget ( module );
287 GenerateObjectFileTargets ( module );
288 }
289
290
291 MingwStaticLibraryModuleHandler::MingwStaticLibraryModuleHandler ( FILE* fMakefile )
292 : MingwModuleHandler ( fMakefile )
293 {
294 }
295
296 bool
297 MingwStaticLibraryModuleHandler::CanHandleModule ( const Module& module ) const
298 {
299 return module.type == StaticLibrary;
300 }
301
302 void
303 MingwStaticLibraryModuleHandler::Process ( const Module& module )
304 {
305 GenerateStaticLibraryModuleTarget ( module );
306 }
307
308 void
309 MingwStaticLibraryModuleHandler::GenerateStaticLibraryModuleTarget ( const Module& module )
310 {
311 GenerateArchiveTarget ( module );
312 GenerateObjectFileTargets ( module );
313 }