2 * Copyright (C) 2005 Casper S. Hornstrup
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 Right ( const string
& s
, size_t n
)
31 return string ( &s
[s
.size()-n
] );
35 Replace ( const string
& s
, const string
& find
, const string
& with
)
38 const char* p
= s
.c_str();
41 const char* p2
= strstr ( p
, find
.c_str() );
45 ret
+= string ( p
, p2
-p
);
55 ChangeSeparator ( const string
& s
,
56 const char fromSeparator
,
57 const char toSeparator
)
60 char* p
= strchr ( &s2
[0], fromSeparator
);
64 p
= strchr ( p
, fromSeparator
);
70 FixSeparator ( const string
& s
)
72 return ChangeSeparator ( s
, cBadSep
, cSep
);
76 FixSeparatorForSystemCommand ( const string
& s
)
79 char* p
= strchr ( &s2
[0], DEF_CBAD_SEP
);
83 p
= strchr ( p
, DEF_CBAD_SEP
);
89 DosSeparator ( const string
& s
)
92 char* p
= strchr ( &s2
[0], '/' );
96 p
= strchr ( p
, '/' );
103 const string
& filename
,
104 const string
& newExtension
)
106 size_t index
= filename
.find_last_of ( '/' );
107 if ( index
== string::npos
)
109 size_t index2
= filename
.find_last_of ( '\\' );
110 if ( index2
!= string::npos
&& index2
> index
)
112 string tmp
= filename
.substr( index
/*, filename.size() - index*/ );
113 size_t ext_index
= tmp
.find_last_of( '.' );
114 if ( ext_index
!= string::npos
)
115 return filename
.substr ( 0, index
+ ext_index
) + newExtension
;
116 return filename
+ newExtension
;
121 const string
& location
,
123 const string
& att_value
)
125 if ( !att_value
.size() )
126 throw InvalidBuildFileException (
128 "<directory> tag has empty 'name' attribute" );
129 if ( strpbrk ( att_value
.c_str (), "/\\?*:<>|" ) )
130 throw InvalidBuildFileException (
132 "<directory> tag has invalid characters in 'name' attribute" );
135 return FixSeparator(path
+ cSep
+ att_value
);
139 GetExtension ( const string
& filename
)
141 size_t index
= filename
.find_last_of ( '/' );
142 if (index
== string::npos
) index
= 0;
143 string tmp
= filename
.substr( index
, filename
.size() - index
);
144 size_t ext_index
= tmp
.find_last_of( '.' );
145 if (ext_index
!= string::npos
)
146 return filename
.substr ( index
+ ext_index
, filename
.size() );
151 GetDirectory ( const string
& filename
)
153 size_t index
= filename
.find_last_of ( cSep
);
154 if ( index
== string::npos
)
157 return filename
.substr ( 0, index
);
161 GetFilename ( const string
& filename
)
163 size_t index
= filename
.find_last_of ( cSep
);
164 if ( index
== string::npos
)
167 return filename
.substr ( index
+ 1, filename
.length () - index
);
171 NormalizeFilename ( const string
& filename
)
173 if ( filename
== "" )
176 string normalizedPath
= path
.Fixup ( filename
, true );
177 string relativeNormalizedPath
= path
.RelativeFromWorkingDirectory ( normalizedPath
);
178 return FixSeparator ( relativeNormalizedPath
);
182 GetBooleanValue ( const string
& value
)
191 ToLower ( string filename
)
193 for ( size_t i
= 1; i
< filename
.length (); i
++ )
194 filename
[i
] = tolower ( filename
[i
] );
198 IfableData::~IfableData()
201 for ( i
= 0; i
< includes
.size (); i
++ )
203 for ( i
= 0; i
< defines
.size (); i
++ )
205 for ( i
= 0; i
< libraries
.size (); i
++ )
207 for ( i
= 0; i
< properties
.size (); i
++ )
208 delete properties
[i
];
209 for ( i
= 0; i
< compilerFlags
.size (); i
++ )
210 delete compilerFlags
[i
];
211 for ( i
= 0; i
< ifs
.size (); i
++ )
213 for ( i
= 0; i
< compilationUnits
.size (); i
++ )
214 delete compilationUnits
[i
];
217 void IfableData::ProcessXML ()
220 for ( i
= 0; i
< includes
.size (); i
++ )
221 includes
[i
]->ProcessXML ();
222 for ( i
= 0; i
< defines
.size (); i
++ )
223 defines
[i
]->ProcessXML ();
224 for ( i
= 0; i
< libraries
.size (); i
++ )
225 libraries
[i
]->ProcessXML ();
226 for ( i
= 0; i
< properties
.size(); i
++ )
227 properties
[i
]->ProcessXML ();
228 for ( i
= 0; i
< compilerFlags
.size(); i
++ )
229 compilerFlags
[i
]->ProcessXML ();
230 for ( i
= 0; i
< ifs
.size (); i
++ )
231 ifs
[i
]->ProcessXML ();
232 for ( i
= 0; i
< compilationUnits
.size (); i
++ )
233 compilationUnits
[i
]->ProcessXML ();
236 Module::Module ( const Project
& project
,
237 const XMLElement
& moduleNode
,
238 const string
& modulePath
)
241 importLibrary (NULL
),
249 if ( node
.name
!= "module" )
250 throw InvalidOperationException ( __FILE__
,
252 "Module created with non-<module> node" );
254 xmlbuildFile
= Path::RelativeFromWorkingDirectory ( moduleNode
.xmlFile
->filename () );
256 path
= FixSeparator ( modulePath
);
260 const XMLAttribute
* att
= moduleNode
.GetAttribute ( "if", false );
262 enabled
= GetBooleanValue ( project
.ResolveProperties ( att
->value
) );
264 att
= moduleNode
.GetAttribute ( "ifnot", false );
266 enabled
= !GetBooleanValue ( project
.ResolveProperties ( att
->value
) );
268 att
= moduleNode
.GetAttribute ( "name", true );
272 att
= moduleNode
.GetAttribute ( "type", true );
274 type
= GetModuleType ( node
.location
, *att
);
276 att
= moduleNode
.GetAttribute ( "extension", false );
278 extension
= att
->value
;
280 extension
= GetDefaultModuleExtension ();
282 att
= moduleNode
.GetAttribute ( "unicode", false );
285 const char* p
= att
->value
.c_str();
286 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
288 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
292 throw InvalidAttributeValueException (
301 att
= moduleNode
.GetAttribute ( "entrypoint", false );
303 entrypoint
= att
->value
;
305 entrypoint
= GetDefaultModuleEntrypoint ();
307 att
= moduleNode
.GetAttribute ( "baseaddress", false );
309 baseaddress
= att
->value
;
311 baseaddress
= GetDefaultModuleBaseaddress ();
313 att
= moduleNode
.GetAttribute ( "mangledsymbols", false );
316 const char* p
= att
->value
.c_str();
317 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
318 mangledSymbols
= true;
319 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
320 mangledSymbols
= false;
323 throw InvalidAttributeValueException (
330 mangledSymbols
= false;
332 att
= moduleNode
.GetAttribute ( "host", false );
335 const char* p
= att
->value
.c_str();
336 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
338 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
342 throw InvalidAttributeValueException (
349 att
= moduleNode
.GetAttribute ( "prefix", false );
353 att
= moduleNode
.GetAttribute ( "installbase", false );
355 installBase
= att
->value
;
359 att
= moduleNode
.GetAttribute ( "installname", false );
361 installName
= att
->value
;
365 att
= moduleNode
.GetAttribute ( "usewrc", false );
367 useWRC
= att
->value
== "true";
371 att
= moduleNode
.GetAttribute ( "allowwarnings", false );
374 att
= moduleNode
.GetAttribute ( "warnings", false );
377 printf ( "%s: WARNING: 'warnings' attribute of <module> is deprecated, use 'allowwarnings' instead\n",
378 moduleNode
.location
.c_str() );
382 allowWarnings
= att
->value
== "true";
384 allowWarnings
= false;
386 att
= moduleNode
.GetAttribute ( "aliasof", false );
387 if ( type
== Alias
&& att
!= NULL
)
388 aliasedModuleName
= att
->value
;
390 aliasedModuleName
= "";
396 for ( i
= 0; i
< invocations
.size(); i
++ )
397 delete invocations
[i
];
398 for ( i
= 0; i
< dependencies
.size(); i
++ )
399 delete dependencies
[i
];
400 for ( i
= 0; i
< compilerFlags
.size(); i
++ )
401 delete compilerFlags
[i
];
402 for ( i
= 0; i
< linkerFlags
.size(); i
++ )
403 delete linkerFlags
[i
];
404 for ( i
= 0; i
< stubbedComponents
.size(); i
++ )
405 delete stubbedComponents
[i
];
417 if ( aliasedModuleName
== name
)
418 throw InvalidBuildFileException (
420 "module '%s' cannot link against itself",
422 const Module
* m
= project
.LocateModule ( aliasedModuleName
);
424 throw InvalidBuildFileException (
426 "module '%s' trying to alias non-existant module '%s'",
428 aliasedModuleName
.c_str() );
432 for ( i
= 0; i
< node
.subElements
.size(); i
++ )
434 ParseContext parseContext
;
435 ProcessXMLSubElement ( *node
.subElements
[i
], path
, parseContext
);
437 for ( i
= 0; i
< invocations
.size(); i
++ )
438 invocations
[i
]->ProcessXML ();
439 for ( i
= 0; i
< dependencies
.size(); i
++ )
440 dependencies
[i
]->ProcessXML ();
441 for ( i
= 0; i
< compilerFlags
.size(); i
++ )
442 compilerFlags
[i
]->ProcessXML();
443 for ( i
= 0; i
< linkerFlags
.size(); i
++ )
444 linkerFlags
[i
]->ProcessXML();
445 for ( i
= 0; i
< stubbedComponents
.size(); i
++ )
446 stubbedComponents
[i
]->ProcessXML();
447 non_if_data
.ProcessXML();
449 linkerScript
->ProcessXML();
453 autoRegister
->ProcessXML();
457 Module::ProcessXMLSubElement ( const XMLElement
& e
,
459 ParseContext
& parseContext
)
461 If
* pOldIf
= parseContext
.ifData
;
462 CompilationUnit
* pOldCompilationUnit
= parseContext
.compilationUnit
;
463 bool subs_invalid
= false;
464 string
subpath ( path
);
465 if ( e
.name
== "file" && e
.value
.size () > 0 )
468 const XMLAttribute
* att
= e
.GetAttribute ( "first", false );
471 if ( !stricmp ( att
->value
.c_str(), "true" ) )
473 else if ( stricmp ( att
->value
.c_str(), "false" ) )
474 throw InvalidBuildFileException (
476 "attribute 'first' of <file> element can only be 'true' or 'false'" );
478 string switches
= "";
479 att
= e
.GetAttribute ( "switches", false );
481 switches
= att
->value
;
484 // check for c++ file
485 string ext
= GetExtension ( e
.value
);
486 if ( !stricmp ( ext
.c_str(), ".cpp" ) )
488 else if ( !stricmp ( ext
.c_str(), ".cc" ) )
490 else if ( !stricmp ( ext
.c_str(), ".cxx" ) )
493 File
* pFile
= new File ( FixSeparator ( path
+ cSep
+ e
.value
),
497 if ( parseContext
.compilationUnit
)
498 parseContext
.compilationUnit
->files
.push_back ( pFile
);
501 CompilationUnit
* pCompilationUnit
= new CompilationUnit ( pFile
);
502 if ( parseContext
.ifData
)
503 parseContext
.ifData
->data
.compilationUnits
.push_back ( pCompilationUnit
);
505 non_if_data
.compilationUnits
.push_back ( pCompilationUnit
);
507 if ( parseContext
.ifData
)
508 parseContext
.ifData
->data
.files
.push_back ( pFile
);
510 non_if_data
.files
.push_back ( pFile
);
513 else if ( e
.name
== "library" && e
.value
.size () )
515 Library
* pLibrary
= new Library ( e
, *this, e
.value
);
516 if ( parseContext
.ifData
)
517 parseContext
.ifData
->data
.libraries
.push_back ( pLibrary
);
519 non_if_data
.libraries
.push_back ( pLibrary
);
522 else if ( e
.name
== "directory" )
524 const XMLAttribute
* att
= e
.GetAttribute ( "name", true );
526 subpath
= GetSubPath ( e
.location
, path
, att
->value
);
528 else if ( e
.name
== "include" )
530 Include
* include
= new Include ( project
, this, &e
);
531 if ( parseContext
.ifData
)
532 parseContext
.ifData
->data
.includes
.push_back ( include
);
534 non_if_data
.includes
.push_back ( include
);
537 else if ( e
.name
== "define" )
539 Define
* pDefine
= new Define ( project
, this, e
);
540 if ( parseContext
.ifData
)
541 parseContext
.ifData
->data
.defines
.push_back ( pDefine
);
543 non_if_data
.defines
.push_back ( pDefine
);
546 else if ( e
.name
== "invoke" )
548 if ( parseContext
.ifData
)
549 throw InvalidBuildFileException (
551 "<invoke> is not a valid sub-element of <if>" );
552 invocations
.push_back ( new Invoke ( e
, *this ) );
553 subs_invalid
= false;
555 else if ( e
.name
== "dependency" )
557 if ( parseContext
.ifData
)
558 throw InvalidBuildFileException (
560 "<dependency> is not a valid sub-element of <if>" );
561 dependencies
.push_back ( new Dependency ( e
, *this ) );
564 else if ( e
.name
== "importlibrary" )
566 if ( parseContext
.ifData
)
567 throw InvalidBuildFileException (
569 "<importlibrary> is not a valid sub-element of <if>" );
571 throw InvalidBuildFileException (
573 "Only one <importlibrary> is valid per module" );
574 importLibrary
= new ImportLibrary ( e
, *this );
577 else if ( e
.name
== "if" )
579 parseContext
.ifData
= new If ( e
, project
, this );
581 pOldIf
->data
.ifs
.push_back ( parseContext
.ifData
);
583 non_if_data
.ifs
.push_back ( parseContext
.ifData
);
584 subs_invalid
= false;
586 else if ( e
.name
== "ifnot" )
588 parseContext
.ifData
= new If ( e
, project
, this, true );
590 pOldIf
->data
.ifs
.push_back ( parseContext
.ifData
);
592 non_if_data
.ifs
.push_back ( parseContext
.ifData
);
593 subs_invalid
= false;
595 else if ( e
.name
== "compilerflag" )
597 CompilerFlag
* pCompilerFlag
= new CompilerFlag ( project
, this, e
);
598 if ( parseContext
.ifData
)
599 parseContext
.ifData
->data
.compilerFlags
.push_back ( pCompilerFlag
);
601 non_if_data
.compilerFlags
.push_back ( pCompilerFlag
);
604 else if ( e
.name
== "linkerflag" )
606 linkerFlags
.push_back ( new LinkerFlag ( project
, this, e
) );
609 else if ( e
.name
== "linkerscript" )
612 throw InvalidBuildFileException (
614 "Only one <linkerscript> is valid per module" );
615 linkerScript
= new LinkerScript ( project
, this, e
);
618 else if ( e
.name
== "component" )
620 stubbedComponents
.push_back ( new StubbedComponent ( this, e
) );
621 subs_invalid
= false;
623 else if ( e
.name
== "property" )
625 throw InvalidBuildFileException (
627 "<property> is not a valid sub-element of <module>" );
629 else if ( e
.name
== "bootstrap" )
631 bootstrap
= new Bootstrap ( project
, this, e
);
634 else if ( e
.name
== "pch" )
636 if ( parseContext
.ifData
)
637 throw InvalidBuildFileException (
639 "<pch> is not a valid sub-element of <if>" );
641 throw InvalidBuildFileException (
643 "Only one <pch> is valid per module" );
645 e
, *this, File ( FixSeparator ( path
+ cSep
+ e
.value
), false, "", true ) );
648 else if ( e
.name
== "compilationunit" )
650 if ( project
.configuration
.CompilationUnitsEnabled
)
652 CompilationUnit
* pCompilationUnit
= new CompilationUnit ( &project
, this, &e
);
653 if ( parseContext
.ifData
)
654 parseContext
.ifData
->data
.compilationUnits
.push_back ( pCompilationUnit
);
656 non_if_data
.compilationUnits
.push_back ( pCompilationUnit
);
657 parseContext
.compilationUnit
= pCompilationUnit
;
659 subs_invalid
= false;
661 else if ( e
.name
== "autoregister" )
663 if ( autoRegister
!= NULL
)
665 throw InvalidBuildFileException ( e
.location
,
666 "there can be only one <%s> element for a module",
669 autoRegister
= new AutoRegister ( project
, this, e
);
672 if ( subs_invalid
&& e
.subElements
.size() > 0 )
673 throw InvalidBuildFileException (
675 "<%s> cannot have sub-elements",
677 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
678 ProcessXMLSubElement ( *e
.subElements
[i
], subpath
, parseContext
);
679 parseContext
.ifData
= pOldIf
;
680 parseContext
.compilationUnit
= pOldCompilationUnit
;
684 Module::GetModuleType ( const string
& location
, const XMLAttribute
& attribute
)
686 if ( attribute
.value
== "buildtool" )
688 if ( attribute
.value
== "staticlibrary" )
689 return StaticLibrary
;
690 if ( attribute
.value
== "objectlibrary" )
691 return ObjectLibrary
;
692 if ( attribute
.value
== "kernel" )
694 if ( attribute
.value
== "kernelmodedll" )
695 return KernelModeDLL
;
696 if ( attribute
.value
== "kernelmodedriver" )
697 return KernelModeDriver
;
698 if ( attribute
.value
== "nativedll" )
700 if ( attribute
.value
== "nativecui" )
702 if ( attribute
.value
== "win32dll" )
704 if ( attribute
.value
== "win32cui" )
706 if ( attribute
.value
== "win32gui" )
708 if ( attribute
.value
== "bootloader" )
710 if ( attribute
.value
== "bootsector" )
712 if ( attribute
.value
== "iso" )
714 if ( attribute
.value
== "liveiso" )
716 if ( attribute
.value
== "test" )
718 if ( attribute
.value
== "rpcserver" )
720 if ( attribute
.value
== "rpcclient" )
722 if ( attribute
.value
== "alias" )
724 throw InvalidAttributeValueException ( location
,
730 Module::GetDefaultModuleExtension () const
749 case KernelModeDriver
:
766 throw InvalidOperationException ( __FILE__
,
771 Module::GetDefaultModuleEntrypoint () const
776 return "_NtProcessStartup";
778 return "_DriverEntry@8";
780 return "_DllMainCRTStartup@12";
782 return "_NtProcessStartup@4";
784 return "_DllMain@12";
788 return "_wmainCRTStartup";
790 return "_mainCRTStartup";
793 return "_wWinMainCRTStartup";
795 return "_WinMainCRTStartup";
796 case KernelModeDriver
:
797 return "_DriverEntry@8";
810 throw InvalidOperationException ( __FILE__
,
815 Module::GetDefaultModuleBaseaddress () const
831 case KernelModeDriver
:
845 throw InvalidOperationException ( __FILE__
,
850 Module::HasImportLibrary () const
852 return importLibrary
!= NULL
;
856 Module::IsDLL () const
864 case KernelModeDriver
:
882 throw InvalidOperationException ( __FILE__
,
887 Module::GenerateInOutputTree () const
895 case KernelModeDriver
:
913 throw InvalidOperationException ( __FILE__
,
918 Module::GetTargetName () const
920 return name
+ extension
;
924 Module::GetDependencyPath () const
926 if ( HasImportLibrary () )
927 return ReplaceExtension ( GetPathWithPrefix ( "lib" ), ".a" );
933 Module::GetBasePath () const
939 Module::GetPath () const
941 if ( path
.length() > 0 )
942 return path
+ cSep
+ GetTargetName ();
944 return GetTargetName ();
948 Module::GetPathWithPrefix ( const string
& prefix
) const
950 return path
+ cSep
+ prefix
+ GetTargetName ();
954 Module::GetInvocationTarget ( const int index
) const
956 return ssprintf ( "%s_invoke_%d",
962 Module::HasFileWithExtension (
963 const IfableData
& data
,
964 const std::string
& extension
) const
967 for ( i
= 0; i
< data
.compilationUnits
.size (); i
++ )
969 CompilationUnit
* compilationUnit
= data
.compilationUnits
[i
];
970 if ( compilationUnit
->HasFileWithExtension ( extension
) )
973 for ( i
= 0; i
< data
.ifs
.size (); i
++ )
975 if ( HasFileWithExtension ( data
.ifs
[i
]->data
, extension
) )
982 Module::InvokeModule () const
984 for ( size_t i
= 0; i
< invocations
.size (); i
++ )
986 Invoke
& invoke
= *invocations
[i
];
987 string command
= FixSeparatorForSystemCommand(invoke
.invokeModule
->GetPath ()) + " " + invoke
.GetParameters ();
988 printf ( "Executing '%s'\n\n", command
.c_str () );
989 int exitcode
= system ( command
.c_str () );
991 throw InvocationFailedException ( command
,
997 File::File ( const string
& _name
, bool _first
,
998 std::string _switches
,
999 bool _isPreCompiledHeader
)
1002 switches(_switches
),
1003 isPreCompiledHeader(_isPreCompiledHeader
)
1013 Library::Library ( const XMLElement
& _node
,
1014 const Module
& _module
,
1015 const string
& _name
)
1019 importedModule(_module
.project
.LocateModule(_name
))
1021 if ( module
.name
== name
)
1022 throw InvalidBuildFileException (
1024 "module '%s' cannot link against itself",
1026 if ( !importedModule
)
1027 throw InvalidBuildFileException (
1029 "module '%s' trying to import non-existant module '%s'",
1030 module
.name
.c_str(),
1035 Library::ProcessXML()
1037 if ( !module
.project
.LocateModule ( name
) )
1038 throw InvalidBuildFileException (
1040 "module '%s' is trying to link against non-existant module '%s'",
1041 module
.name
.c_str(),
1046 Invoke::Invoke ( const XMLElement
& _node
,
1047 const Module
& _module
)
1054 Invoke::ProcessXML()
1056 const XMLAttribute
* att
= node
.GetAttribute ( "module", false );
1058 invokeModule
= &module
;
1061 invokeModule
= module
.project
.LocateModule ( att
->value
);
1062 if ( invokeModule
== NULL
)
1063 throw InvalidBuildFileException (
1065 "module '%s' is trying to invoke non-existant module '%s'",
1066 module
.name
.c_str(),
1067 att
->value
.c_str() );
1070 for ( size_t i
= 0; i
< node
.subElements
.size (); i
++ )
1071 ProcessXMLSubElement ( *node
.subElements
[i
] );
1075 Invoke::ProcessXMLSubElement ( const XMLElement
& e
)
1077 bool subs_invalid
= false;
1078 if ( e
.name
== "input" )
1080 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
1081 ProcessXMLSubElementInput ( *e
.subElements
[i
] );
1083 else if ( e
.name
== "output" )
1085 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
1086 ProcessXMLSubElementOutput ( *e
.subElements
[i
] );
1088 if ( subs_invalid
&& e
.subElements
.size() > 0 )
1089 throw InvalidBuildFileException ( e
.location
,
1090 "<%s> cannot have sub-elements",
1095 Invoke::ProcessXMLSubElementInput ( const XMLElement
& e
)
1097 bool subs_invalid
= false;
1098 if ( e
.name
== "inputfile" && e
.value
.size () > 0 )
1100 input
.push_back ( new InvokeFile ( e
, FixSeparator ( module
.path
+ cSep
+ e
.value
) ) );
1101 subs_invalid
= true;
1103 if ( subs_invalid
&& e
.subElements
.size() > 0 )
1104 throw InvalidBuildFileException ( e
.location
,
1105 "<%s> cannot have sub-elements",
1110 Invoke::ProcessXMLSubElementOutput ( const XMLElement
& e
)
1112 bool subs_invalid
= false;
1113 if ( e
.name
== "outputfile" && e
.value
.size () > 0 )
1115 output
.push_back ( new InvokeFile ( e
, FixSeparator ( module
.path
+ cSep
+ e
.value
) ) );
1116 subs_invalid
= true;
1118 if ( subs_invalid
&& e
.subElements
.size() > 0 )
1119 throw InvalidBuildFileException (
1121 "<%s> cannot have sub-elements",
1126 Invoke::GetTargets ( string_list
& targets
) const
1128 for ( size_t i
= 0; i
< output
.size (); i
++ )
1130 InvokeFile
& file
= *output
[i
];
1131 targets
.push_back ( NormalizeFilename ( file
.name
) );
1136 Invoke::GetParameters () const
1138 string
parameters ( "" );
1140 for ( i
= 0; i
< output
.size (); i
++ )
1142 if ( parameters
.length () > 0)
1144 InvokeFile
& invokeFile
= *output
[i
];
1145 if ( invokeFile
.switches
.length () > 0 )
1147 parameters
+= invokeFile
.switches
+ " ";
1149 parameters
+= invokeFile
.name
;
1152 for ( i
= 0; i
< input
.size (); i
++ )
1154 if ( parameters
.length () > 0 )
1156 InvokeFile
& invokeFile
= *input
[i
];
1157 if ( invokeFile
.switches
.length () > 0 )
1159 parameters
+= invokeFile
.switches
;
1162 parameters
+= invokeFile
.name
;
1169 InvokeFile::InvokeFile ( const XMLElement
& _node
,
1170 const string
& _name
)
1174 const XMLAttribute
* att
= _node
.GetAttribute ( "switches", false );
1176 switches
= att
->value
;
1182 InvokeFile::ProcessXML()
1187 Dependency::Dependency ( const XMLElement
& _node
,
1188 const Module
& _module
)
1191 dependencyModule (NULL
)
1196 Dependency::ProcessXML()
1198 dependencyModule
= module
.project
.LocateModule ( node
.value
);
1199 if ( dependencyModule
== NULL
)
1200 throw InvalidBuildFileException ( node
.location
,
1201 "module '%s' depend on non-existant module '%s'",
1202 module
.name
.c_str(),
1203 node
.value
.c_str() );
1207 ImportLibrary::ImportLibrary ( const XMLElement
& _node
,
1208 const Module
& _module
)
1212 const XMLAttribute
* att
= _node
.GetAttribute ( "basename", false );
1214 basename
= att
->value
;
1216 basename
= module
.name
;
1218 att
= _node
.GetAttribute ( "definition", true );
1220 definition
= FixSeparator(att
->value
);
1224 If::If ( const XMLElement
& node_
,
1225 const Project
& project_
,
1226 const Module
* module_
,
1227 const bool negated_
)
1228 : node(node_
), project(project_
), module(module_
), negated(negated_
)
1230 const XMLAttribute
* att
;
1232 att
= node
.GetAttribute ( "property", true );
1234 property
= att
->value
;
1236 att
= node
.GetAttribute ( "value", true );
1251 Property::Property ( const XMLElement
& node_
,
1252 const Project
& project_
,
1253 const Module
* module_
)
1254 : node(node_
), project(project_
), module(module_
)
1256 const XMLAttribute
* att
;
1258 att
= node
.GetAttribute ( "name", true );
1262 att
= node
.GetAttribute ( "value", true );
1268 Property::ProcessXML()
1274 const XMLElement
& node_
,
1275 const Module
& module_
,
1277 : node(node_
), module(module_
), file(file_
)
1282 PchFile::ProcessXML()
1287 AutoRegister::AutoRegister ( const Project
& project_
,
1288 const Module
* module_
,
1289 const XMLElement
& node_
)
1290 : project(project_
),
1297 AutoRegister::~AutoRegister ()
1302 AutoRegister::IsSupportedModuleType ( ModuleType type
)
1314 case KernelModeDriver
:
1328 throw InvalidOperationException ( __FILE__
,
1333 AutoRegister::GetAutoRegisterType( string type
)
1335 if ( type
== "DllRegisterServer" )
1336 return DllRegisterServer
;
1337 if ( type
== "DllInstall" )
1339 if ( type
== "Both" )
1341 throw InvalidBuildFileException (
1343 "<autoregister> type attribute must be DllRegisterServer, DllInstall or Both." );
1347 AutoRegister::Initialize ()
1349 if ( !IsSupportedModuleType ( module
->type
) )
1351 throw InvalidBuildFileException (
1353 "<autoregister> is not applicable for this module type." );
1356 const XMLAttribute
* att
= node
.GetAttribute ( "infsection", true );
1357 infSection
= att
->value
;
1359 att
= node
.GetAttribute ( "type", true );
1360 type
= GetAutoRegisterType ( att
->value
);
1364 AutoRegister::ProcessXML()