5 #include "../../rbuild.h"
7 #include "modulehandler.h"
13 map
<ModuleType
,MingwModuleHandler
*>*
14 MingwModuleHandler::handler_map
= NULL
;
16 MingwModuleHandler::ref
= 0;
19 MingwModuleHandler::fMakefile
= NULL
;
21 MingwModuleHandler::MingwModuleHandler ( ModuleType moduletype
)
24 handler_map
= new map
<ModuleType
,MingwModuleHandler
*>;
25 (*handler_map
)[moduletype
] = this;
28 MingwModuleHandler::~MingwModuleHandler()
38 MingwModuleHandler::SetMakefile ( FILE* f
)
43 /*static*/ MingwModuleHandler
*
44 MingwModuleHandler::LookupHandler ( const string
& location
,
45 ModuleType moduletype
)
48 throw Exception ( "internal tool error: no registered module handlers" );
49 MingwModuleHandler
* h
= (*handler_map
)[moduletype
];
52 throw UnknownModuleTypeException ( location
, moduletype
);
59 MingwModuleHandler::GetWorkingDirectory () const
65 MingwModuleHandler::GetExtension ( const string
& filename
) const
67 size_t index
= filename
.find_last_of ( '.' );
68 if (index
!= string::npos
)
69 return filename
.substr ( index
);
74 MingwModuleHandler::ReplaceExtension ( const string
& filename
,
75 const string
& newExtension
) const
77 size_t index
= filename
.find_last_of ( '.' );
78 if (index
!= string::npos
)
79 return filename
.substr ( 0, index
) + newExtension
;
84 MingwModuleHandler::GetModuleArchiveFilename ( const Module
& module
) const
86 return ReplaceExtension ( FixupTargetFilename ( module
.GetPath () ).c_str (),
91 MingwModuleHandler::GetImportLibraryDependencies ( const Module
& module
) const
93 if ( module
.libraries
.size () == 0 )
96 string
dependencies ( "" );
97 for ( size_t i
= 0; i
< module
.libraries
.size (); i
++ )
99 if ( dependencies
.size () > 0 )
101 const Module
* importedModule
= module
.project
.LocateModule ( module
.libraries
[i
]->name
);
102 assert ( importedModule
!= NULL
);
103 dependencies
+= FixupTargetFilename ( importedModule
->GetDependencyPath () ).c_str ();
109 MingwModuleHandler::GetModuleDependencies ( const Module
& module
) const
111 if ( module
.dependencies
.size () == 0 )
114 string
dependencies ( "" );
115 for ( size_t i
= 0; i
< module
.dependencies
.size (); i
++ )
117 if ( dependencies
.size () > 0 )
119 const Dependency
* dependency
= module
.dependencies
[i
];
120 const Module
* dependencyModule
= dependency
->dependencyModule
;
121 dependencies
+= dependencyModule
->GetTargets ();
127 MingwModuleHandler::GetAllDependencies ( const Module
& module
) const
129 string dependencies
= GetImportLibraryDependencies ( module
);
130 string s
= GetModuleDependencies ( module
);
140 MingwModuleHandler::GetSourceFilenames ( const Module
& module
) const
142 if ( module
.files
.size () == 0 )
145 string
sourceFilenames ( "" );
146 for ( size_t i
= 0; i
< module
.files
.size (); i
++ )
148 if ( sourceFilenames
.size () > 0 )
149 sourceFilenames
+= " ";
150 sourceFilenames
+= module
.files
[i
]->name
;
152 return sourceFilenames
;
156 MingwModuleHandler::GetObjectFilename ( const string
& sourceFilename
) const
158 return FixupTargetFilename ( ReplaceExtension ( sourceFilename
,
163 MingwModuleHandler::GetObjectFilenames ( const Module
& module
) const
165 if ( module
.files
.size () == 0 )
168 string
objectFilenames ( "" );
169 for ( size_t i
= 0; i
< module
.files
.size (); i
++ )
171 if ( objectFilenames
.size () > 0 )
172 objectFilenames
+= " ";
173 objectFilenames
+= GetObjectFilename ( module
.files
[i
]->name
);
175 return objectFilenames
;
179 MingwModuleHandler::GenerateGccDefineParametersFromVector ( const vector
<Define
*>& defines
) const
182 for (size_t i
= 0; i
< defines
.size (); i
++)
184 Define
& define
= *defines
[i
];
185 if (parameters
.length () > 0)
188 parameters
+= define
.name
;
189 if (define
.value
.length () > 0)
192 parameters
+= define
.value
;
199 MingwModuleHandler::GenerateGccDefineParameters ( const Module
& module
) const
201 string parameters
= GenerateGccDefineParametersFromVector ( module
.project
.defines
);
202 string s
= GenerateGccDefineParametersFromVector ( module
.defines
);
212 MingwModuleHandler::ConcatenatePaths ( const string
& path1
,
213 const string
& path2
) const
215 if ( ( path1
.length () == 0 ) || ( path1
== "." ) || ( path1
== "./" ) )
217 if ( path1
[path1
.length ()] == CSEP
)
218 return path1
+ path2
;
220 return path1
+ CSEP
+ path2
;
224 MingwModuleHandler::GenerateGccIncludeParametersFromVector ( const vector
<Include
*>& includes
) const
227 for ( size_t i
= 0; i
< includes
.size (); i
++ )
229 Include
& include
= *includes
[i
];
230 if (parameters
.length () > 0)
232 parameters
+= "-I" + include
.directory
;
238 MingwModuleHandler::GenerateGccModuleIncludeVariable ( const Module
& module
) const
240 string
name ( module
.name
+ "_INCLUDES" );
244 GenerateGccIncludeParameters(module
).c_str() );
248 MingwModuleHandler::GenerateGccIncludeParameters ( const Module
& module
) const
250 string parameters
= GenerateGccIncludeParametersFromVector ( module
.includes
);
251 string s
= GenerateGccIncludeParametersFromVector ( module
.project
.includes
);
252 if ( s
.length () > 0 )
261 MingwModuleHandler::GenerateGccParameters ( const Module
& module
) const
263 string parameters
= GenerateGccDefineParameters ( module
);
264 parameters
+= ssprintf(" $(%s_INCLUDES)", module
.name
.c_str());
269 MingwModuleHandler::GenerateNasmParameters ( const Module
& module
) const
275 MingwModuleHandler::GenerateGccCommand ( const Module
& module
,
276 const string
& sourceFilename
,
277 const string
& cc
) const
279 string objectFilename
= GetObjectFilename ( sourceFilename
);
280 return ssprintf ( "%s -c %s -o %s %s\n",
282 sourceFilename
.c_str (),
283 objectFilename
.c_str (),
284 GenerateGccParameters ( module
).c_str () );
288 MingwModuleHandler::GenerateGccAssemblerCommand ( const Module
& module
,
289 const string
& sourceFilename
,
290 const string
& cc
) const
292 string objectFilename
= GetObjectFilename ( sourceFilename
);
293 return ssprintf ( "%s -x assembler-with-cpp -c %s -o %s -D__ASM__ %s\n",
295 sourceFilename
.c_str (),
296 objectFilename
.c_str (),
297 GenerateGccParameters ( module
).c_str () );
301 MingwModuleHandler::GenerateNasmCommand ( const Module
& module
,
302 const string
& sourceFilename
) const
304 string objectFilename
= GetObjectFilename ( sourceFilename
);
305 return ssprintf ( "%s -f win32 %s -o %s %s\n",
307 sourceFilename
.c_str (),
308 objectFilename
.c_str (),
309 GenerateNasmParameters ( module
).c_str () );
313 MingwModuleHandler::GenerateCommand ( const Module
& module
,
314 const string
& sourceFilename
,
315 const string
& cc
) const
317 string extension
= GetExtension ( sourceFilename
);
318 if ( extension
== ".c" || extension
== ".C" )
319 return GenerateGccCommand ( module
,
322 else if ( extension
== ".s" || extension
== ".S" )
323 return GenerateGccAssemblerCommand ( module
,
326 else if ( extension
== ".asm" || extension
== ".ASM" )
327 return GenerateNasmCommand ( module
,
330 throw InvalidOperationException ( __FILE__
,
332 "Unsupported filename extension '%s' in file '%s'",
334 sourceFilename
.c_str () );
338 MingwModuleHandler::GenerateObjectFileTargets ( const Module
& module
,
339 const string
& cc
) const
341 if ( module
.files
.size () == 0 )
344 GenerateGccModuleIncludeVariable ( module
);
346 for ( size_t i
= 0; i
< module
.files
.size (); i
++ )
348 string sourceFilename
= module
.files
[i
]->name
;
349 string objectFilename
= GetObjectFilename ( sourceFilename
);
352 objectFilename
.c_str (),
353 sourceFilename
.c_str () );
356 GenerateCommand ( module
,
361 fprintf ( fMakefile
, "\n" );
365 MingwModuleHandler::GenerateObjectFileTargetsHost ( const Module
& module
) const
367 GenerateObjectFileTargets ( module
,
372 MingwModuleHandler::GenerateObjectFileTargetsTarget ( const Module
& module
) const
374 GenerateObjectFileTargets ( module
,
379 MingwModuleHandler::GenerateArchiveTarget ( const Module
& module
,
380 const string
& ar
) const
382 string archiveFilename
= GetModuleArchiveFilename ( module
);
383 string sourceFilenames
= GetSourceFilenames ( module
);
384 string objectFilenames
= GetObjectFilenames ( module
);
388 archiveFilename
.c_str (),
389 objectFilenames
.c_str ());
392 "\t%s -rc %s %s\n\n",
394 archiveFilename
.c_str (),
395 objectFilenames
.c_str ());
399 MingwModuleHandler::GenerateArchiveTargetHost ( const Module
& module
) const
401 GenerateArchiveTarget ( module
,
406 MingwModuleHandler::GenerateArchiveTargetTarget ( const Module
& module
) const
408 GenerateArchiveTarget ( module
,
413 MingwModuleHandler::GetInvocationDependencies ( const Module
& module
) const
416 for ( size_t i
= 0; i
< module
.invocations
.size (); i
++ )
418 Invoke
& invoke
= *module
.invocations
[i
];
419 if (invoke
.invokeModule
== &module
)
420 /* Protect against circular dependencies */
422 if ( dependencies
.length () > 0 )
424 dependencies
+= invoke
.GetTargets ();
430 MingwModuleHandler::GetInvocationParameters ( const Invoke
& invoke
) const
432 string
parameters ( "" );
434 for (i
= 0; i
< invoke
.output
.size (); i
++)
436 if (parameters
.length () > 0)
438 InvokeFile
& invokeFile
= *invoke
.output
[i
];
439 if (invokeFile
.switches
.length () > 0)
441 parameters
+= invokeFile
.switches
;
444 parameters
+= invokeFile
.name
;
447 for (i
= 0; i
< invoke
.input
.size (); i
++)
449 if (parameters
.length () > 0)
451 InvokeFile
& invokeFile
= *invoke
.input
[i
];
452 if (invokeFile
.switches
.length () > 0)
454 parameters
+= invokeFile
.switches
;
457 parameters
+= invokeFile
.name
;
464 MingwModuleHandler::GenerateInvocations ( const Module
& module
) const
466 if ( module
.invocations
.size () == 0 )
469 for ( size_t i
= 0; i
< module
.invocations
.size (); i
++ )
471 const Invoke
& invoke
= *module
.invocations
[i
];
473 if ( invoke
.invokeModule
->type
!= BuildTool
)
474 throw InvalidBuildFileException ( module
.node
.location
,
475 "Only modules of type buildtool can be invoked." );
477 string invokeTarget
= module
.GetInvocationTarget ( i
);
480 invoke
.GetTargets ().c_str (),
481 invokeTarget
.c_str () );
484 invokeTarget
.c_str (),
485 FixupTargetFilename ( invoke
.invokeModule
->GetPath () ).c_str () );
488 FixupTargetFilename ( invoke
.invokeModule
->GetPath () ).c_str (),
489 GetInvocationParameters ( invoke
).c_str () );
492 invokeTarget
.c_str () );
497 MingwModuleHandler::GetPreconditionDependenciesName ( const Module
& module
) const
499 return ssprintf ( "%s_precondition",
500 module
.name
.c_str () );
504 MingwModuleHandler::GeneratePreconditionDependencies ( const Module
& module
) const
506 string preconditionDependenciesName
= GetPreconditionDependenciesName ( module
);
507 string sourceFilenames
= GetSourceFilenames ( module
);
508 string dependencies
= GetModuleDependencies ( module
);
509 string s
= GetInvocationDependencies ( module
);
510 if ( s
.length () > 0 )
512 if ( dependencies
.length () > 0 )
519 preconditionDependenciesName
.c_str (),
520 dependencies
.c_str () );
523 sourceFilenames
.c_str (),
524 preconditionDependenciesName
.c_str ());
527 preconditionDependenciesName
.c_str () );
531 static MingwBuildToolModuleHandler buildtool_handler
;
533 MingwBuildToolModuleHandler::MingwBuildToolModuleHandler()
534 : MingwModuleHandler ( BuildTool
)
539 MingwBuildToolModuleHandler::Process ( const Module
& module
)
541 GeneratePreconditionDependencies ( module
);
542 GenerateBuildToolModuleTarget ( module
);
543 GenerateInvocations ( module
);
547 MingwBuildToolModuleHandler::GenerateBuildToolModuleTarget ( const Module
& module
)
549 string
target ( FixupTargetFilename ( module
.GetPath () ) );
550 string archiveFilename
= GetModuleArchiveFilename ( module
);
551 fprintf ( fMakefile
, "%s: %s\n",
553 archiveFilename
.c_str () );
555 "\t${host_gcc} -o %s %s\n",
557 archiveFilename
.c_str () );
558 GenerateArchiveTargetHost ( module
);
559 GenerateObjectFileTargetsHost ( module
);
562 static MingwKernelModuleHandler kernelmodule_handler
;
564 MingwKernelModuleHandler::MingwKernelModuleHandler ()
565 : MingwModuleHandler ( Kernel
)
570 MingwKernelModuleHandler::Process ( const Module
& module
)
572 GeneratePreconditionDependencies ( module
);
573 GenerateKernelModuleTarget ( module
);
574 GenerateInvocations ( module
);
578 MingwKernelModuleHandler::GenerateKernelModuleTarget ( const Module
& module
)
580 static string
ros_junk ( "$(ROS_TEMPORARY)" );
581 //static string ros_output ( "$(ROS_INTERMEDIATE)" );
582 string
target ( FixupTargetFilename(module
.GetPath()) );
583 string workingDirectory
= GetWorkingDirectory ( );
584 string archiveFilename
= GetModuleArchiveFilename ( module
);
585 string importLibraryDependencies
= GetImportLibraryDependencies ( module
);
586 string base_tmp
= ros_junk
+ module
.name
+ ".base.tmp";
587 string junk_tmp
= ros_junk
+ module
.name
+ ".junk.tmp";
588 string temp_exp
= ros_junk
+ module
.name
+ ".temp.exp";
589 string gccOptions
= ssprintf ("-Wl,-T,%s" SSEP
"ntoskrnl.lnk -Wl,--subsystem,native -Wl,--entry,_NtProcessStartup -Wl,--image-base,0xC0000000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll",
590 module
.GetBasePath ().c_str () );
591 fprintf ( fMakefile
, "%s: %s %s\n",
593 archiveFilename
.c_str (),
594 importLibraryDependencies
.c_str () );
596 "\t${gcc} %s -Wl,--base-file,%s -o %s %s %s\n",
600 archiveFilename
.c_str (),
601 importLibraryDependencies
.c_str () );
606 "\t${dlltool} --dllname %s --base-file %s --output-exp %s --kill-at\n",
614 "\t${gcc} %s -Wl,%s -o %s %s %s\n",
618 archiveFilename
.c_str (),
619 importLibraryDependencies
.c_str () );
624 GenerateArchiveTargetTarget ( module
);
625 GenerateObjectFileTargetsTarget ( module
);
629 static MingwStaticLibraryModuleHandler staticlibrary_handler
;
631 MingwStaticLibraryModuleHandler::MingwStaticLibraryModuleHandler ()
632 : MingwModuleHandler ( StaticLibrary
)
637 MingwStaticLibraryModuleHandler::Process ( const Module
& module
)
639 GeneratePreconditionDependencies ( module
);
640 GenerateStaticLibraryModuleTarget ( module
);
641 GenerateInvocations ( module
);
645 MingwStaticLibraryModuleHandler::GenerateStaticLibraryModuleTarget ( const Module
& module
)
647 GenerateArchiveTargetTarget ( module
);
648 GenerateObjectFileTargetsTarget ( module
);
652 static MingwKernelModeDLLModuleHandler kernelmodedll_handler
;
654 MingwKernelModeDLLModuleHandler::MingwKernelModeDLLModuleHandler ()
655 : MingwModuleHandler ( KernelModeDLL
)
660 MingwKernelModeDLLModuleHandler::Process ( const Module
& module
)
662 GeneratePreconditionDependencies ( module
);
663 GenerateKernelModeDLLModuleTarget ( module
);
664 GenerateInvocations ( module
);
668 MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget ( const Module
& module
)
670 static string
ros_junk ( "$(ROS_TEMPORARY)" );
671 string
target ( FixupTargetFilename ( module
.GetPath () ) );
672 string workingDirectory
= GetWorkingDirectory ( );
673 string archiveFilename
= GetModuleArchiveFilename ( module
);
674 string importLibraryDependencies
= GetImportLibraryDependencies ( module
);
676 if (module
.importLibrary
!= NULL
)
678 fprintf ( fMakefile
, "%s:\n",
679 module
.GetDependencyPath ().c_str () );
682 "\t${dlltool} --dllname %s --def %s --output-lib %s --kill-at\n\n",
683 module
.GetTargetName ().c_str (),
684 FixupTargetFilename ( module
.GetBasePath () + SSEP
+ module
.importLibrary
->definition
).c_str (),
685 FixupTargetFilename ( module
.GetDependencyPath () ).c_str () );
688 if (module
.files
.size () > 0)
690 fprintf ( fMakefile
, "%s: %s %s\n",
692 archiveFilename
.c_str (),
693 importLibraryDependencies
.c_str () );
696 "\t${gcc} -Wl,--subsystem,native -Wl,--entry,_DriverEntry@8 -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll -o %s %s %s\n",
698 archiveFilename
.c_str (),
699 importLibraryDependencies
.c_str () );
701 GenerateArchiveTargetTarget ( module
);
702 GenerateObjectFileTargetsTarget ( module
);
706 fprintf ( fMakefile
, "%s:\n\n",
708 fprintf ( fMakefile
, ".PHONY: %s\n\n",