12 FixSeparator ( const string
& s
)
15 char* p
= strchr ( &s2
[0], CBAD_SEP
);
19 p
= strchr ( p
, CBAD_SEP
);
25 NormalizeFilename ( const string
& filename
)
28 string normalizedPath
= path
.Fixup ( filename
, true );
29 string relativeNormalizedPath
= path
.RelativeFromWorkingDirectory ( normalizedPath
);
30 return FixSeparator ( relativeNormalizedPath
);
33 Module::Module ( const Project
& project
,
34 const XMLElement
& moduleNode
,
35 const string
& modulePath
)
40 if ( node
.name
!= "module" )
41 throw Exception ( "internal tool error: Module created with non-<module> node" );
43 path
= FixSeparator ( modulePath
);
45 const XMLAttribute
* att
= moduleNode
.GetAttribute ( "name", true );
49 att
= moduleNode
.GetAttribute ( "type", true );
51 type
= GetModuleType ( node
.location
, *att
);
53 att
= moduleNode
.GetAttribute ( "extension", false );
55 extension
= att
->value
;
57 extension
= GetDefaultModuleExtension ();
63 for ( i
= 0; i
< files
.size(); i
++ )
65 for ( i
= 0; i
< libraries
.size(); i
++ )
67 for ( i
= 0; i
< includes
.size(); i
++ )
69 for ( i
= 0; i
< defines
.size(); i
++ )
71 for ( i
= 0; i
< invocations
.size(); i
++ )
72 delete invocations
[i
];
73 for ( i
= 0; i
< dependencies
.size(); i
++ )
74 delete dependencies
[i
];
75 for ( i
= 0; i
< ifs
.size(); i
++ )
77 for ( i
= 0; i
< linkerFlags
.size(); i
++ )
78 delete linkerFlags
[i
];
85 for ( i
= 0; i
< node
.subElements
.size(); i
++ )
86 ProcessXMLSubElement ( *node
.subElements
[i
], path
);
87 for ( i
= 0; i
< files
.size (); i
++ )
88 files
[i
]->ProcessXML ();
89 for ( i
= 0; i
< libraries
.size(); i
++ )
90 libraries
[i
]->ProcessXML ();
91 for ( i
= 0; i
< includes
.size(); i
++ )
92 includes
[i
]->ProcessXML ();
93 for ( i
= 0; i
< defines
.size(); i
++ )
94 defines
[i
]->ProcessXML ();
95 for ( i
= 0; i
< invocations
.size(); i
++ )
96 invocations
[i
]->ProcessXML ();
97 for ( i
= 0; i
< dependencies
.size(); i
++ )
98 dependencies
[i
]->ProcessXML ();
99 for ( i
= 0; i
< ifs
.size(); i
++ )
100 ifs
[i
]->ProcessXML();
101 for ( i
= 0; i
< linkerFlags
.size(); i
++ )
102 linkerFlags
[i
]->ProcessXML();
106 Module::ProcessXMLSubElement ( const XMLElement
& e
,
110 bool subs_invalid
= false;
111 string
subpath ( path
);
112 if ( e
.name
== "file" && e
.value
.size () > 0 )
114 const XMLAttribute
* att
= e
.GetAttribute ( "first", false );
115 File
* pFile
= new File ( FixSeparator ( path
+ CSEP
+ e
.value
),
116 att
&& atoi(att
->value
.c_str()) != 0 );
118 pIf
->files
.push_back ( pFile
);
120 files
.push_back ( pFile
);
123 else if ( e
.name
== "library" && e
.value
.size () )
126 throw InvalidBuildFileException (
128 "<library> is not a valid sub-element of <if>" );
129 libraries
.push_back ( new Library ( e
, *this, e
.value
) );
132 else if ( e
.name
== "directory" )
134 const XMLAttribute
* att
= e
.GetAttribute ( "name", true );
136 subpath
= FixSeparator ( path
+ CSEP
+ att
->value
);
138 else if ( e
.name
== "include" )
140 Include
* include
= new Include ( project
, this, e
);
142 pIf
->includes
.push_back ( include
);
144 includes
.push_back ( include
);
147 else if ( e
.name
== "define" )
149 Define
* pDefine
= new Define ( project
, this, e
);
151 pIf
->defines
.push_back ( pDefine
);
153 defines
.push_back ( pDefine
);
156 else if ( e
.name
== "invoke" )
159 throw InvalidBuildFileException (
161 "<invoke> is not a valid sub-element of <if>" );
162 invocations
.push_back ( new Invoke ( e
, *this ) );
163 subs_invalid
= false;
165 else if ( e
.name
== "dependency" )
168 throw InvalidBuildFileException (
170 "<dependency> is not a valid sub-element of <if>" );
171 dependencies
.push_back ( new Dependency ( e
, *this ) );
174 else if ( e
.name
== "importlibrary" )
177 throw InvalidBuildFileException (
179 "<importlibrary> is not a valid sub-element of <if>" );
181 throw InvalidBuildFileException (
183 "Only one <importlibrary> is valid per module" );
184 importLibrary
= new ImportLibrary ( e
, *this );
187 else if ( e
.name
== "if" )
190 pIf
= new If ( e
, project
, this );
192 pOldIf
->ifs
.push_back ( pIf
);
194 ifs
.push_back ( pIf
);
195 subs_invalid
= false;
197 else if ( e
.name
== "linkerflag" )
199 linkerFlags
.push_back ( new LinkerFlag ( project
, this, e
) );
202 else if ( e
.name
== "property" )
204 throw InvalidBuildFileException (
206 "<property> is not a valid sub-element of <module>" );
208 if ( subs_invalid
&& e
.subElements
.size() > 0 )
209 throw InvalidBuildFileException (
211 "<%s> cannot have sub-elements",
213 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
214 ProcessXMLSubElement ( *e
.subElements
[i
], subpath
, pIf
);
218 Module::GetModuleType ( const string
& location
, const XMLAttribute
& attribute
)
220 if ( attribute
.value
== "buildtool" )
222 if ( attribute
.value
== "staticlibrary" )
223 return StaticLibrary
;
224 if ( attribute
.value
== "kernel" )
226 if ( attribute
.value
== "kernelmodedll" )
227 return KernelModeDLL
;
228 if ( attribute
.value
== "kernelmodedriver" )
229 return KernelModeDriver
;
230 if ( attribute
.value
== "nativedll" )
232 if ( attribute
.value
== "win32dll" )
234 if ( attribute
.value
== "win32gui" )
236 throw InvalidAttributeValueException ( location
,
242 Module::GetDefaultModuleExtension () const
257 case KernelModeDriver
:
260 throw InvalidOperationException ( __FILE__
,
265 Module::HasImportLibrary () const
267 return importLibrary
!= NULL
;
271 Module::GetTargetName () const
273 return name
+ extension
;
277 Module::GetDependencyPath () const
279 if ( HasImportLibrary () )
281 return ssprintf ( "dk%snkm%slib%slib%s.a",
292 Module::GetBasePath () const
298 Module::GetPath () const
300 return path
+ CSEP
+ GetTargetName ();
304 Module::GetPathWithPrefix ( const string
& prefix
) const
306 return path
+ CSEP
+ prefix
+ GetTargetName ();
310 Module::GetTargets () const
312 if ( invocations
.size () > 0 )
314 string
targets ( "" );
315 for ( size_t i
= 0; i
< invocations
.size (); i
++ )
317 Invoke
& invoke
= *invocations
[i
];
318 if ( targets
.length () > 0 )
320 targets
+= invoke
.GetTargets ();
329 Module::GetInvocationTarget ( const int index
) const
331 return ssprintf ( "%s_invoke_%d",
337 File::File ( const string
& _name
, bool _first
)
338 : name(_name
), first(_first
)
348 Library::Library ( const XMLElement
& _node
,
349 const Module
& _module
,
350 const string
& _name
)
355 if ( module
.name
== name
)
356 throw InvalidBuildFileException (
358 "module '%s' cannot link against itself",
363 Library::ProcessXML()
365 if ( !module
.project
.LocateModule ( name
) )
366 throw InvalidBuildFileException (
368 "module '%s' is trying to link against non-existant module '%s'",
374 Invoke::Invoke ( const XMLElement
& _node
,
375 const Module
& _module
)
384 const XMLAttribute
* att
= node
.GetAttribute ( "module", false );
386 invokeModule
= &module
;
389 invokeModule
= module
.project
.LocateModule ( att
->value
);
390 if ( invokeModule
== NULL
)
391 throw InvalidBuildFileException (
393 "module '%s' is trying to invoke non-existant module '%s'",
395 att
->value
.c_str() );
398 for ( size_t i
= 0; i
< node
.subElements
.size (); i
++ )
399 ProcessXMLSubElement ( *node
.subElements
[i
] );
403 Invoke::ProcessXMLSubElement ( const XMLElement
& e
)
405 bool subs_invalid
= false;
406 if ( e
.name
== "input" )
408 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
409 ProcessXMLSubElementInput ( *e
.subElements
[i
] );
411 else if ( e
.name
== "output" )
413 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
414 ProcessXMLSubElementOutput ( *e
.subElements
[i
] );
416 if ( subs_invalid
&& e
.subElements
.size() > 0 )
417 throw InvalidBuildFileException ( e
.location
,
418 "<%s> cannot have sub-elements",
423 Invoke::ProcessXMLSubElementInput ( const XMLElement
& e
)
425 bool subs_invalid
= false;
426 if ( e
.name
== "inputfile" && e
.value
.size () > 0 )
428 input
.push_back ( new InvokeFile ( e
, FixSeparator ( module
.path
+ CSEP
+ e
.value
) ) );
431 if ( subs_invalid
&& e
.subElements
.size() > 0 )
432 throw InvalidBuildFileException ( e
.location
,
433 "<%s> cannot have sub-elements",
438 Invoke::ProcessXMLSubElementOutput ( const XMLElement
& e
)
440 bool subs_invalid
= false;
441 if ( e
.name
== "outputfile" && e
.value
.size () > 0 )
443 output
.push_back ( new InvokeFile ( e
, FixSeparator ( module
.path
+ CSEP
+ e
.value
) ) );
446 if ( subs_invalid
&& e
.subElements
.size() > 0 )
447 throw InvalidBuildFileException ( e
.location
,
448 "<%s> cannot have sub-elements",
453 Invoke::GetTargets () const
455 string
targets ( "" );
456 for ( size_t i
= 0; i
< output
.size (); i
++ )
458 InvokeFile
& file
= *output
[i
];
459 if ( targets
.length () > 0 )
461 targets
+= NormalizeFilename ( file
.name
);
467 InvokeFile::InvokeFile ( const XMLElement
& _node
,
468 const string
& _name
)
472 const XMLAttribute
* att
= _node
.GetAttribute ( "switches", false );
474 switches
= att
->value
;
480 InvokeFile::ProcessXML()
485 Dependency::Dependency ( const XMLElement
& _node
,
486 const Module
& _module
)
489 dependencyModule (NULL
)
494 Dependency::ProcessXML()
496 dependencyModule
= module
.project
.LocateModule ( node
.value
);
497 if ( dependencyModule
== NULL
)
498 throw InvalidBuildFileException ( node
.location
,
499 "module '%s' depend on non-existant module '%s'",
501 node
.value
.c_str() );
505 ImportLibrary::ImportLibrary ( const XMLElement
& _node
,
506 const Module
& _module
)
510 const XMLAttribute
* att
= _node
.GetAttribute ( "basename", false );
512 basename
= att
->value
;
514 basename
= module
.name
;
516 att
= _node
.GetAttribute ( "definition", true );
518 definition
= FixSeparator(att
->value
);
522 If::If ( const XMLElement
& node_
,
523 const Project
& project_
,
524 const Module
* module_
)
525 : node(node_
), project(project_
), module(module_
)
527 const XMLAttribute
* att
;
529 att
= node
.GetAttribute ( "property", true );
531 property
= att
->value
;
533 att
= node
.GetAttribute ( "value", true );
541 for ( i
= 0; i
< files
.size(); i
++ )
543 for ( i
= 0; i
< includes
.size(); i
++ )
545 for ( i
= 0; i
< defines
.size(); i
++ )
547 for ( i
= 0; i
< ifs
.size(); i
++ )
557 Property::Property ( const XMLElement
& node_
,
558 const Project
& project_
,
559 const Module
* module_
)
560 : node(node_
), project(project_
), module(module_
)
562 const XMLAttribute
* att
;
564 att
= node
.GetAttribute ( "name", true );
568 att
= node
.GetAttribute ( "value", true );
574 Property::ProcessXML()