5 #include "../../rbuild.h"
7 #include "modulehandler.h"
13 map
<ModuleType
,MingwModuleHandler
*>*
14 MingwModuleHandler::handler_map
= NULL
;
17 MingwModuleHandler::fMakefile
= NULL
;
19 MingwModuleHandler::MingwModuleHandler ( ModuleType moduletype
)
22 handler_map
= new map
<ModuleType
,MingwModuleHandler
*>;
23 (*handler_map
)[moduletype
] = this;
27 MingwModuleHandler::SetMakefile ( FILE* f
)
32 /*static*/ MingwModuleHandler
*
33 MingwModuleHandler::LookupHandler ( const string
& location
,
34 ModuleType moduletype
)
37 throw Exception ( "internal tool error: no registered module handlers" );
38 MingwModuleHandler
* h
= (*handler_map
)[moduletype
];
41 throw UnknownModuleTypeException ( location
, moduletype
);
48 MingwModuleHandler::GetWorkingDirectory () const
54 MingwModuleHandler::GetExtension ( const string
& filename
) const
56 size_t index
= filename
.find_last_of ( '.' );
57 if (index
!= string::npos
)
58 return filename
.substr ( index
);
63 MingwModuleHandler::ReplaceExtension ( const string
& filename
,
64 const string
& newExtension
) const
66 size_t index
= filename
.find_last_of ( '.' );
67 if (index
!= string::npos
)
68 return filename
.substr ( 0, index
) + newExtension
;
73 MingwModuleHandler::GetModuleArchiveFilename ( const Module
& module
) const
75 return ReplaceExtension ( FixupTargetFilename ( module
.GetPath () ).c_str (),
80 MingwModuleHandler::GetImportLibraryDependencies ( const Module
& module
) const
82 if ( module
.libraries
.size () == 0 )
85 string
dependencies ( "" );
86 for ( size_t i
= 0; i
< module
.libraries
.size (); i
++ )
88 if ( dependencies
.size () > 0 )
90 const Module
* importedModule
= module
.project
.LocateModule ( module
.libraries
[i
]->name
);
91 assert ( importedModule
!= NULL
);
92 dependencies
+= FixupTargetFilename ( importedModule
->GetPath () ).c_str ();
98 MingwModuleHandler::GetModuleDependencies ( const Module
& module
) const
100 if ( module
.dependencies
.size () == 0 )
103 string
dependencies ( "" );
104 for ( size_t i
= 0; i
< module
.dependencies
.size (); i
++ )
106 if ( dependencies
.size () > 0 )
108 const Dependency
* dependency
= module
.dependencies
[i
];
109 const Module
* dependencyModule
= dependency
->dependencyModule
;
110 dependencies
+= dependencyModule
->GetTargets ();
116 MingwModuleHandler::GetAllDependencies ( const Module
& module
) const
118 string dependencies
= GetImportLibraryDependencies ( module
);
119 string s
= GetModuleDependencies ( module
);
129 MingwModuleHandler::GetSourceFilenames ( const Module
& module
) const
131 if ( module
.files
.size () == 0 )
134 string
sourceFilenames ( "" );
135 for ( size_t i
= 0; i
< module
.files
.size (); i
++ )
137 if ( sourceFilenames
.size () > 0 )
138 sourceFilenames
+= " ";
139 sourceFilenames
+= module
.files
[i
]->name
;
141 return sourceFilenames
;
145 MingwModuleHandler::GetObjectFilename ( const string
& sourceFilename
) const
147 return FixupTargetFilename ( ReplaceExtension ( sourceFilename
,
152 MingwModuleHandler::GetObjectFilenames ( const Module
& module
) const
154 if ( module
.files
.size () == 0 )
157 string
objectFilenames ( "" );
158 for ( size_t i
= 0; i
< module
.files
.size (); i
++ )
160 if ( objectFilenames
.size () > 0 )
161 objectFilenames
+= " ";
162 objectFilenames
+= GetObjectFilename ( module
.files
[i
]->name
);
164 return objectFilenames
;
168 MingwModuleHandler::GenerateGccDefineParametersFromVector ( const vector
<Define
*>& defines
) const
171 for (size_t i
= 0; i
< defines
.size (); i
++)
173 Define
& define
= *defines
[i
];
174 if (parameters
.length () > 0)
177 parameters
+= define
.name
;
178 if (define
.value
.length () > 0)
181 parameters
+= define
.value
;
188 MingwModuleHandler::GenerateGccDefineParameters ( const Module
& module
) const
190 string parameters
= GenerateGccDefineParametersFromVector ( module
.project
.defines
);
191 string s
= GenerateGccDefineParametersFromVector ( module
.defines
);
201 MingwModuleHandler::ConcatenatePaths ( const string
& path1
,
202 const string
& path2
) const
204 if ( ( path1
.length () == 0 ) || ( path1
== "." ) || ( path1
== "./" ) )
206 if ( path1
[path1
.length ()] == CSEP
)
207 return path1
+ path2
;
209 return path1
+ CSEP
+ path2
;
213 MingwModuleHandler::GenerateGccIncludeParametersFromVector ( const vector
<Include
*>& includes
) const
216 for ( size_t i
= 0; i
< includes
.size (); i
++ )
218 Include
& include
= *includes
[i
];
219 if (parameters
.length () > 0)
221 parameters
+= "-I" + include
.directory
;
227 MingwModuleHandler::GenerateGccModuleIncludeVariable ( const Module
& module
) const
229 string
name ( module
.name
+ "_INCLUDES" );
233 GenerateGccIncludeParameters(module
).c_str() );
237 MingwModuleHandler::GenerateGccIncludeParameters ( const Module
& module
) const
239 string parameters
= GenerateGccIncludeParametersFromVector ( module
.includes
);
240 string s
= GenerateGccIncludeParametersFromVector ( module
.project
.includes
);
241 if ( s
.length () > 0 )
250 MingwModuleHandler::GenerateGccParameters ( const Module
& module
) const
252 string parameters
= GenerateGccDefineParameters ( module
);
253 parameters
+= ssprintf(" $(%s_INCLUDES)",module
.name
.c_str());
258 MingwModuleHandler::GenerateGccCommand ( const Module
& module
,
259 const string
& sourceFilename
,
260 const string
& cc
) const
262 string objectFilename
= GetObjectFilename ( sourceFilename
);
263 return ssprintf ( "%s -c %s -o %s %s\n",
265 sourceFilename
.c_str (),
266 objectFilename
.c_str (),
267 GenerateGccParameters ( module
).c_str () );
271 MingwModuleHandler::GenerateGccAssemblerCommand ( const Module
& module
,
272 const string
& sourceFilename
,
273 const string
& cc
) const
275 string objectFilename
= GetObjectFilename ( sourceFilename
);
276 return ssprintf ( "%s -x assembler-with-cpp -c %s -o %s -D__ASM__ %s\n",
278 sourceFilename
.c_str (),
279 objectFilename
.c_str (),
280 GenerateGccParameters ( module
).c_str () );
284 MingwModuleHandler::GenerateCommand ( const Module
& module
,
285 const string
& sourceFilename
,
286 const string
& cc
) const
288 string extension
= GetExtension ( sourceFilename
);
289 if ( extension
== ".c" || extension
== ".C" )
290 return GenerateGccCommand ( module
,
293 else if ( extension
== ".s" || extension
== ".S" )
294 return GenerateGccAssemblerCommand ( module
,
298 throw InvalidOperationException ( __FILE__
,
300 "Unsupported filename extension '%s' in file '%s'",
302 sourceFilename
.c_str () );
306 MingwModuleHandler::GenerateObjectFileTargets ( const Module
& module
,
307 const string
& cc
) const
309 if ( module
.files
.size () == 0 )
312 GenerateGccModuleIncludeVariable ( module
);
314 for ( size_t i
= 0; i
< module
.files
.size (); i
++ )
316 string sourceFilename
= module
.files
[i
]->name
;
317 string objectFilename
= GetObjectFilename ( sourceFilename
);
320 objectFilename
.c_str (),
321 sourceFilename
.c_str () );
324 GenerateCommand ( module
,
329 fprintf ( fMakefile
, "\n" );
333 MingwModuleHandler::GenerateObjectFileTargetsHost ( const Module
& module
) const
335 GenerateObjectFileTargets ( module
,
340 MingwModuleHandler::GenerateObjectFileTargetsTarget ( const Module
& module
) const
342 GenerateObjectFileTargets ( module
,
347 MingwModuleHandler::GenerateArchiveTarget ( const Module
& module
,
348 const string
& ar
) const
350 string archiveFilename
= GetModuleArchiveFilename ( module
);
351 string sourceFilenames
= GetSourceFilenames ( module
);
352 string objectFilenames
= GetObjectFilenames ( module
);
356 archiveFilename
.c_str (),
357 objectFilenames
.c_str ());
360 "\t%s -rc %s %s\n\n",
362 archiveFilename
.c_str (),
363 objectFilenames
.c_str ());
367 MingwModuleHandler::GenerateArchiveTargetHost ( const Module
& module
) const
369 GenerateArchiveTarget ( module
,
374 MingwModuleHandler::GenerateArchiveTargetTarget ( const Module
& module
) const
376 GenerateArchiveTarget ( module
,
381 MingwModuleHandler::GetInvocationDependencies ( const Module
& module
) const
384 for ( size_t i
= 0; i
< module
.invocations
.size (); i
++ )
386 Invoke
& invoke
= *module
.invocations
[i
];
387 if (invoke
.invokeModule
== &module
)
388 /* Protect against circular dependencies */
390 if ( dependencies
.length () > 0 )
392 dependencies
+= invoke
.GetTargets ();
398 MingwModuleHandler::GetInvocationParameters ( const Invoke
& invoke
) const
400 string
parameters ( "" );
402 for (i
= 0; i
< invoke
.output
.size (); i
++)
404 if (parameters
.length () > 0)
406 InvokeFile
& invokeFile
= *invoke
.output
[i
];
407 if (invokeFile
.switches
.length () > 0)
409 parameters
+= invokeFile
.switches
;
412 parameters
+= invokeFile
.name
;
415 for (i
= 0; i
< invoke
.input
.size (); i
++)
417 if (parameters
.length () > 0)
419 InvokeFile
& invokeFile
= *invoke
.input
[i
];
420 if (invokeFile
.switches
.length () > 0)
422 parameters
+= invokeFile
.switches
;
425 parameters
+= invokeFile
.name
;
432 MingwModuleHandler::GenerateInvocations ( const Module
& module
) const
434 if ( module
.invocations
.size () == 0 )
437 for ( size_t i
= 0; i
< module
.invocations
.size (); i
++ )
439 const Invoke
& invoke
= *module
.invocations
[i
];
441 if ( invoke
.invokeModule
->type
!= BuildTool
)
442 throw InvalidBuildFileException ( module
.node
.location
,
443 "Only modules of type buildtool can be invoked." );
445 string invokeTarget
= module
.GetInvocationTarget ( i
);
448 invoke
.GetTargets ().c_str (),
449 invokeTarget
.c_str () );
452 invokeTarget
.c_str (),
453 FixupTargetFilename ( invoke
.invokeModule
->GetPath () ).c_str () );
456 FixupTargetFilename ( invoke
.invokeModule
->GetPath () ).c_str (),
457 GetInvocationParameters ( invoke
).c_str () );
460 invokeTarget
.c_str () );
465 MingwModuleHandler::GetPreconditionDependenciesName ( const Module
& module
) const
467 return ssprintf ( "%s_precondition",
468 module
.name
.c_str () );
472 MingwModuleHandler::GeneratePreconditionDependencies ( const Module
& module
) const
474 string preconditionDependenciesName
= GetPreconditionDependenciesName ( module
);
475 string sourceFilenames
= GetSourceFilenames ( module
);
476 string dependencies
= GetModuleDependencies ( module
);
477 string s
= GetInvocationDependencies ( module
);
478 if ( s
.length () > 0 )
480 if ( dependencies
.length () > 0 )
487 preconditionDependenciesName
.c_str (),
488 dependencies
.c_str () );
491 sourceFilenames
.c_str (),
492 preconditionDependenciesName
.c_str ());
495 preconditionDependenciesName
.c_str () );
498 static MingwBuildToolModuleHandler buildtool_handler
;
500 MingwBuildToolModuleHandler::MingwBuildToolModuleHandler()
501 : MingwModuleHandler ( BuildTool
)
506 MingwBuildToolModuleHandler::Process ( const Module
& module
)
508 GeneratePreconditionDependencies ( module
);
509 GenerateBuildToolModuleTarget ( module
);
510 GenerateInvocations ( module
);
514 MingwBuildToolModuleHandler::GenerateBuildToolModuleTarget ( const Module
& module
)
516 string
target ( FixupTargetFilename ( module
.GetPath () ) );
517 string archiveFilename
= GetModuleArchiveFilename ( module
);
518 fprintf ( fMakefile
, "%s: %s\n",
520 archiveFilename
.c_str () );
522 "\t${host_gcc} -o %s %s\n",
524 archiveFilename
.c_str () );
525 GenerateArchiveTargetHost ( module
);
526 GenerateObjectFileTargetsHost ( module
);
529 static MingwKernelModuleHandler kernelmodule_handler
;
531 MingwKernelModuleHandler::MingwKernelModuleHandler ()
532 : MingwModuleHandler ( KernelModeDLL
)
537 MingwKernelModuleHandler::Process ( const Module
& module
)
539 GeneratePreconditionDependencies ( module
);
540 GenerateKernelModuleTarget ( module
);
541 GenerateInvocations ( module
);
545 MingwKernelModuleHandler::GenerateKernelModuleTarget ( const Module
& module
)
547 static string
ros_junk ( "$(ROS_TEMPORARY)" );
548 //static string ros_output ( "$(ROS_INTERMEDIATE)" );
549 string
target ( FixupTargetFilename(module
.GetPath()) );
550 string workingDirectory
= GetWorkingDirectory ( );
551 string archiveFilename
= GetModuleArchiveFilename ( module
);
552 string importLibraryDependencies
= GetImportLibraryDependencies ( module
);
553 string base_tmp
= ros_junk
+ module
.name
+ ".base.tmp";
554 string junk_tmp
= ros_junk
+ module
.name
+ ".junk.tmp";
555 string temp_exp
= ros_junk
+ module
.name
+ ".temp.exp";
556 fprintf ( fMakefile
, "%s: %s %s\n",
558 archiveFilename
.c_str (),
559 importLibraryDependencies
.c_str () );
561 "\t${gcc} -Wl,--entry,_NtProcessStartup -Wl,-T,%s" SSEP
"ntoskrnl.lnk -Wl,--subsystem,native -Wl,--image-base,0xC0000000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -Wl,--base-file,%s -nostartfiles -o %s %s %s\n",
562 module
.GetBasePath ().c_str (),
565 archiveFilename
.c_str (),
566 importLibraryDependencies
.c_str () );
571 "\t${dlltool} --dllname %s --base-file %s --output-exp %s --kill-at\n",
579 "\t${ld} -Wl,%s -o %s %s %s\n",
582 archiveFilename
.c_str (),
583 importLibraryDependencies
.c_str () );
588 GenerateArchiveTargetTarget ( module
);
589 GenerateObjectFileTargetsTarget ( module
);
592 static MingwStaticLibraryModuleHandler staticlibrary_handler
;
594 MingwStaticLibraryModuleHandler::MingwStaticLibraryModuleHandler ()
595 : MingwModuleHandler ( StaticLibrary
)
600 MingwStaticLibraryModuleHandler::Process ( const Module
& module
)
602 GeneratePreconditionDependencies ( module
);
603 GenerateStaticLibraryModuleTarget ( module
);
604 GenerateInvocations ( module
);
608 MingwStaticLibraryModuleHandler::GenerateStaticLibraryModuleTarget ( const Module
& module
)
610 GenerateArchiveTargetTarget ( module
);
611 GenerateObjectFileTargetsTarget ( module
);