Static library module type.
[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 ()
19 {
20 return ".";
21 }
22
23 string
24 MingwModuleHandler::ReplaceExtension ( string filename,
25 string newExtension )
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 ( Module& module )
35 {
36 return ReplaceExtension ( module.GetPath ().c_str (),
37 ".a" );
38 }
39
40 string
41 MingwModuleHandler::GetImportLibraryDependencies ( Module& module )
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 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 ( Module& module )
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 ( string sourceFilename )
76 {
77 return ReplaceExtension ( sourceFilename,
78 ".o" );
79 }
80
81 string
82 MingwModuleHandler::GetObjectFilenames ( Module& module )
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 ( vector<Define*> defines )
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 ( Module& module )
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 ( string path1,
132 string path2 )
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 ( string basePath,
144 vector<Include*> includes )
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";
153 parameters += ConcatenatePaths ( basePath,
154 include.directory );
155 }
156 return parameters;
157 }
158
159 string
160 MingwModuleHandler::GenerateGccIncludeParameters ( Module& module )
161 {
162 string parameters = GenerateGccIncludeParametersFromVector ( ".",
163 module.project->includes );
164 string s = GenerateGccIncludeParametersFromVector ( module.path,
165 module.includes );
166 if (s.length () > 0)
167 {
168 parameters += " ";
169 parameters += s;
170 }
171 return parameters;
172 }
173
174 string
175 MingwModuleHandler::GenerateGccParameters ( Module& module )
176 {
177 string parameters = GenerateGccDefineParameters ( module );
178 string s = GenerateGccIncludeParameters ( module );
179 if (s.length () > 0)
180 {
181 parameters += " ";
182 parameters += s;
183 }
184 return parameters;
185 }
186
187 void
188 MingwModuleHandler::GenerateObjectFileTargets ( Module& module )
189 {
190 if ( module.files.size () == 0 )
191 return;
192
193 for ( size_t i = 0; i < module.files.size (); i++ )
194 {
195 string sourceFilename = module.files[i]->name;
196 string objectFilename = GetObjectFilename ( sourceFilename );
197 fprintf ( fMakefile,
198 "%s: %s\n",
199 objectFilename.c_str (),
200 sourceFilename.c_str() );
201 fprintf ( fMakefile,
202 "\t${gcc} -c %s -o %s %s\n",
203 sourceFilename.c_str (),
204 objectFilename.c_str (),
205 GenerateGccParameters ( module ).c_str () );
206 }
207
208 fprintf ( fMakefile, "\n" );
209 }
210
211 void
212 MingwModuleHandler::GenerateArchiveTarget ( Module& module )
213 {
214 string archiveFilename = GetModuleArchiveFilename ( module );
215 string sourceFilenames = GetSourceFilenames ( module );
216 string objectFilenames = GetObjectFilenames ( module );
217
218 fprintf ( fMakefile,
219 "%s: %s\n",
220 archiveFilename.c_str (),
221 objectFilenames.c_str ());
222
223 fprintf ( fMakefile,
224 "\t${ar} -rc %s %s\n\n",
225 archiveFilename.c_str (),
226 objectFilenames.c_str ());
227 }
228
229
230 MingwKernelModuleHandler::MingwKernelModuleHandler ( FILE* fMakefile )
231 : MingwModuleHandler ( fMakefile )
232 {
233 }
234
235 bool
236 MingwKernelModuleHandler::CanHandleModule ( Module& module )
237 {
238 return module.type == KernelModeDLL;
239 }
240
241 void
242 MingwKernelModuleHandler::Process ( Module& module )
243 {
244 GenerateKernelModuleTarget ( module );
245 }
246
247 void
248 MingwKernelModuleHandler::GenerateKernelModuleTarget ( Module& module )
249 {
250 string workingDirectory = GetWorkingDirectory ( );
251 string archiveFilename = GetModuleArchiveFilename ( module );
252 string importLibraryDependencies = GetImportLibraryDependencies ( module );
253 fprintf ( fMakefile, "%s: %s %s\n",
254 module.GetPath ().c_str (),
255 archiveFilename.c_str (),
256 importLibraryDependencies.c_str () );
257 fprintf ( fMakefile,
258 "\t${gcc} -Wl,--base-file,%s" SSEP "base.tmp -o %s" SSEP "junk.tmp %s %s\n",
259 workingDirectory.c_str (),
260 workingDirectory.c_str (),
261 archiveFilename.c_str (),
262 importLibraryDependencies.c_str () );
263 fprintf ( fMakefile,
264 "\t${rm} %s" SSEP "junk.tmp\n",
265 workingDirectory.c_str () );
266 fprintf ( fMakefile,
267 "\t${dlltool} --dllname %s --base-file %s" SSEP "base.tmp --output-exp %s" SSEP "temp.exp --kill-at\n",
268 module.GetPath ().c_str (),
269 workingDirectory.c_str (),
270 workingDirectory.c_str ());
271 fprintf ( fMakefile,
272 "\t${rm} %s" SSEP "base.tmp\n",
273 workingDirectory.c_str () );
274 fprintf ( fMakefile,
275 "\t${ld} -Wl,%s" SSEP "temp.exp -o %s %s %s\n",
276 workingDirectory.c_str (),
277 module.GetPath ().c_str (),
278 archiveFilename.c_str (),
279 importLibraryDependencies.c_str () );
280 fprintf ( fMakefile,
281 "\t${rm} %s" SSEP "temp.exp\n",
282 workingDirectory.c_str () );
283
284 GenerateArchiveTarget ( module );
285 GenerateObjectFileTargets ( module );
286 }
287
288
289 MingwStaticLibraryModuleHandler::MingwStaticLibraryModuleHandler ( FILE* fMakefile )
290 : MingwModuleHandler ( fMakefile )
291 {
292 }
293
294 bool
295 MingwStaticLibraryModuleHandler::CanHandleModule ( Module& module )
296 {
297 return module.type == StaticLibrary;
298 }
299
300 void
301 MingwStaticLibraryModuleHandler::Process ( Module& module )
302 {
303 GenerateStaticLibraryModuleTarget ( module );
304 }
305
306 void
307 MingwStaticLibraryModuleHandler::GenerateStaticLibraryModuleTarget ( Module& module )
308 {
309 GenerateArchiveTarget ( module );
310 GenerateObjectFileTargets ( module );
311 }