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 XMLInvalidBuildFileException (
128 "<directory> tag has empty 'name' attribute" );
129 if ( strpbrk ( att_value
.c_str (), "/\\?*:<>|" ) )
130 throw XMLInvalidBuildFileException (
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 void IfableData::ExtractModules( std::vector
<Module
*> &modules
)
201 for ( i
= 0; i
< this->modules
.size (); i
++ )
202 modules
.push_back(this->modules
[i
]);
205 IfableData::~IfableData()
208 for ( i
= 0; i
< includes
.size (); i
++ )
210 for ( i
= 0; i
< defines
.size (); i
++ )
212 for ( i
= 0; i
< libraries
.size (); i
++ )
214 for ( i
= 0; i
< properties
.size (); i
++ )
215 delete properties
[i
];
216 for ( i
= 0; i
< compilerFlags
.size (); i
++ )
217 delete compilerFlags
[i
];
218 for ( i
= 0; i
< modules
.size(); i
++ )
220 for ( i
= 0; i
< ifs
.size (); i
++ )
222 for ( i
= 0; i
< compilationUnits
.size (); i
++ )
223 delete compilationUnits
[i
];
226 void IfableData::ProcessXML ()
229 for ( i
= 0; i
< includes
.size (); i
++ )
230 includes
[i
]->ProcessXML ();
231 for ( i
= 0; i
< defines
.size (); i
++ )
232 defines
[i
]->ProcessXML ();
233 for ( i
= 0; i
< libraries
.size (); i
++ )
234 libraries
[i
]->ProcessXML ();
235 for ( i
= 0; i
< properties
.size(); i
++ )
236 properties
[i
]->ProcessXML ();
237 for ( i
= 0; i
< compilerFlags
.size(); i
++ )
238 compilerFlags
[i
]->ProcessXML ();
239 for ( i
= 0; i
< ifs
.size (); i
++ )
240 ifs
[i
]->ProcessXML ();
241 for ( i
= 0; i
< compilationUnits
.size (); i
++ )
242 compilationUnits
[i
]->ProcessXML ();
245 Module::Module ( const Project
& project
,
246 const XMLElement
& moduleNode
,
247 const string
& modulePath
)
250 importLibrary (NULL
),
258 if ( node
.name
!= "module" )
259 throw InvalidOperationException ( __FILE__
,
261 "Module created with non-<module> node" );
263 xmlbuildFile
= Path::RelativeFromWorkingDirectory ( moduleNode
.xmlFile
->filename () );
265 path
= FixSeparator ( modulePath
);
269 const XMLAttribute
* att
= moduleNode
.GetAttribute ( "if", false );
271 enabled
= GetBooleanValue ( project
.ResolveProperties ( att
->value
) );
273 att
= moduleNode
.GetAttribute ( "ifnot", false );
275 enabled
= !GetBooleanValue ( project
.ResolveProperties ( att
->value
) );
277 att
= moduleNode
.GetAttribute ( "name", true );
281 att
= moduleNode
.GetAttribute ( "type", true );
283 type
= GetModuleType ( node
.location
, *att
);
285 att
= moduleNode
.GetAttribute ( "extension", false );
287 extension
= att
->value
;
289 extension
= GetDefaultModuleExtension ();
291 att
= moduleNode
.GetAttribute ( "unicode", false );
294 const char* p
= att
->value
.c_str();
295 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
297 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
301 throw InvalidAttributeValueException (
310 att
= moduleNode
.GetAttribute ( "stdlib", false );
313 const char* p
= att
->value
.c_str();
314 if ( !stricmp ( p
, "host" ) )
315 useHostStdlib
= true;
316 else if ( !stricmp ( p
, "default" ) )
317 useHostStdlib
= false;
320 throw InvalidAttributeValueException (
327 useHostStdlib
= false;
331 // Always define UNICODE and _UNICODE
332 Define
* pDefine
= new Define ( project
, this, "UNICODE" );
333 non_if_data
.defines
.push_back ( pDefine
);
335 pDefine
= new Define ( project
, this, "_UNICODE" );
336 non_if_data
.defines
.push_back ( pDefine
);
339 att
= moduleNode
.GetAttribute ( "entrypoint", false );
342 if ( att
->value
== "" )
344 throw InvalidAttributeValueException (
350 entrypoint
= att
->value
;
351 isDefaultEntryPoint
= false;
355 entrypoint
= GetDefaultModuleEntrypoint ();
356 isDefaultEntryPoint
= true;
359 att
= moduleNode
.GetAttribute ( "baseaddress", false );
361 baseaddress
= att
->value
;
363 baseaddress
= GetDefaultModuleBaseaddress ();
365 att
= moduleNode
.GetAttribute ( "mangledsymbols", false );
368 const char* p
= att
->value
.c_str();
369 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
370 mangledSymbols
= true;
371 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
372 mangledSymbols
= false;
375 throw InvalidAttributeValueException (
382 mangledSymbols
= false;
384 att
= moduleNode
.GetAttribute ( "underscoresymbols", false );
386 underscoreSymbols
= att
->value
== "true";
388 underscoreSymbols
= false;
390 att
= moduleNode
.GetAttribute ( "host", false );
393 const char* p
= att
->value
.c_str();
394 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
396 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
400 throw InvalidAttributeValueException (
407 att
= moduleNode
.GetAttribute ( "isstartuplib", false );
410 const char* p
= att
->value
.c_str();
411 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
413 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
414 isStartupLib
= false;
417 throw InvalidAttributeValueException (
424 isStartupLib
= false;
426 att
= moduleNode
.GetAttribute ( "prefix", false );
430 att
= moduleNode
.GetAttribute ( "installbase", false );
432 installBase
= att
->value
;
436 att
= moduleNode
.GetAttribute ( "installname", false );
438 installName
= att
->value
;
442 att
= moduleNode
.GetAttribute ( "usewrc", false );
444 useWRC
= att
->value
== "true";
448 att
= moduleNode
.GetAttribute ( "allowwarnings", false );
451 att
= moduleNode
.GetAttribute ( "warnings", false );
454 printf ( "%s: WARNING: 'warnings' attribute of <module> is deprecated, use 'allowwarnings' instead\n",
455 moduleNode
.location
.c_str() );
459 allowWarnings
= att
->value
== "true";
461 allowWarnings
= false;
463 att
= moduleNode
.GetAttribute ( "aliasof", false );
464 if ( type
== Alias
&& att
!= NULL
)
465 aliasedModuleName
= att
->value
;
467 aliasedModuleName
= "";
469 if ( type
== BootProgram
)
471 att
= moduleNode
.GetAttribute ( "payload", true );
472 payload
= att
->value
;
479 for ( i
= 0; i
< invocations
.size(); i
++ )
480 delete invocations
[i
];
481 for ( i
= 0; i
< dependencies
.size(); i
++ )
482 delete dependencies
[i
];
483 for ( i
= 0; i
< compilerFlags
.size(); i
++ )
484 delete compilerFlags
[i
];
485 for ( i
= 0; i
< linkerFlags
.size(); i
++ )
486 delete linkerFlags
[i
];
487 for ( i
= 0; i
< stubbedComponents
.size(); i
++ )
488 delete stubbedComponents
[i
];
500 if ( aliasedModuleName
== name
)
502 throw XMLInvalidBuildFileException (
504 "module '%s' cannot link against itself",
507 const Module
* m
= project
.LocateModule ( aliasedModuleName
);
510 throw XMLInvalidBuildFileException (
512 "module '%s' trying to alias non-existant module '%s'",
514 aliasedModuleName
.c_str() );
519 for ( i
= 0; i
< node
.subElements
.size(); i
++ )
521 ParseContext parseContext
;
522 ProcessXMLSubElement ( *node
.subElements
[i
], path
, parseContext
);
524 for ( i
= 0; i
< invocations
.size(); i
++ )
525 invocations
[i
]->ProcessXML ();
526 for ( i
= 0; i
< dependencies
.size(); i
++ )
527 dependencies
[i
]->ProcessXML ();
528 for ( i
= 0; i
< compilerFlags
.size(); i
++ )
529 compilerFlags
[i
]->ProcessXML();
530 for ( i
= 0; i
< linkerFlags
.size(); i
++ )
531 linkerFlags
[i
]->ProcessXML();
532 for ( i
= 0; i
< stubbedComponents
.size(); i
++ )
533 stubbedComponents
[i
]->ProcessXML();
534 non_if_data
.ProcessXML();
536 linkerScript
->ProcessXML();
540 autoRegister
->ProcessXML();
544 Module::ProcessXMLSubElement ( const XMLElement
& e
,
546 ParseContext
& parseContext
)
548 If
* pOldIf
= parseContext
.ifData
;
549 CompilationUnit
* pOldCompilationUnit
= parseContext
.compilationUnit
;
550 bool subs_invalid
= false;
551 string
subpath ( path
);
552 if ( e
.name
== "file" && e
.value
.size () > 0 )
555 const XMLAttribute
* att
= e
.GetAttribute ( "first", false );
558 if ( !stricmp ( att
->value
.c_str(), "true" ) )
560 else if ( stricmp ( att
->value
.c_str(), "false" ) )
562 throw XMLInvalidBuildFileException (
564 "attribute 'first' of <file> element can only be 'true' or 'false'" );
567 string switches
= "";
568 att
= e
.GetAttribute ( "switches", false );
570 switches
= att
->value
;
573 // check for c++ file
574 string ext
= GetExtension ( e
.value
);
575 if ( !stricmp ( ext
.c_str(), ".cpp" ) )
577 else if ( !stricmp ( ext
.c_str(), ".cc" ) )
579 else if ( !stricmp ( ext
.c_str(), ".cxx" ) )
582 File
* pFile
= new File ( FixSeparator ( path
+ cSep
+ e
.value
),
586 if ( parseContext
.compilationUnit
)
587 parseContext
.compilationUnit
->files
.push_back ( pFile
);
590 CompilationUnit
* pCompilationUnit
= new CompilationUnit ( pFile
);
591 if ( parseContext
.ifData
)
592 parseContext
.ifData
->data
.compilationUnits
.push_back ( pCompilationUnit
);
595 string ext
= GetExtension ( e
.value
);
596 if ( !stricmp ( ext
.c_str(), ".idl" ) )
597 non_if_data
.compilationUnits
.insert ( non_if_data
.compilationUnits
.begin(), pCompilationUnit
);
599 non_if_data
.compilationUnits
.push_back ( pCompilationUnit
);
602 if ( parseContext
.ifData
)
603 parseContext
.ifData
->data
.files
.push_back ( pFile
);
605 non_if_data
.files
.push_back ( pFile
);
608 else if ( e
.name
== "library" && e
.value
.size () )
610 Library
* pLibrary
= new Library ( e
, *this, e
.value
);
611 if ( parseContext
.ifData
)
612 parseContext
.ifData
->data
.libraries
.push_back ( pLibrary
);
614 non_if_data
.libraries
.push_back ( pLibrary
);
617 else if ( e
.name
== "directory" )
619 const XMLAttribute
* att
= e
.GetAttribute ( "name", true );
621 subpath
= GetSubPath ( e
.location
, path
, att
->value
);
623 else if ( e
.name
== "include" )
625 Include
* include
= new Include ( project
, this, &e
);
626 if ( parseContext
.ifData
)
627 parseContext
.ifData
->data
.includes
.push_back ( include
);
629 non_if_data
.includes
.push_back ( include
);
632 else if ( e
.name
== "define" )
634 Define
* pDefine
= new Define ( project
, this, e
);
635 if ( parseContext
.ifData
)
636 parseContext
.ifData
->data
.defines
.push_back ( pDefine
);
638 non_if_data
.defines
.push_back ( pDefine
);
641 else if ( e
.name
== "invoke" )
643 if ( parseContext
.ifData
)
645 throw XMLInvalidBuildFileException (
647 "<invoke> is not a valid sub-element of <if>" );
649 invocations
.push_back ( new Invoke ( e
, *this ) );
650 subs_invalid
= false;
652 else if ( e
.name
== "dependency" )
654 if ( parseContext
.ifData
)
656 throw XMLInvalidBuildFileException (
658 "<dependency> is not a valid sub-element of <if>" );
660 dependencies
.push_back ( new Dependency ( e
, *this ) );
663 else if ( e
.name
== "importlibrary" )
665 if ( parseContext
.ifData
)
667 throw XMLInvalidBuildFileException (
669 "<importlibrary> is not a valid sub-element of <if>" );
673 throw XMLInvalidBuildFileException (
675 "Only one <importlibrary> is valid per module" );
677 importLibrary
= new ImportLibrary ( e
, *this );
680 else if ( e
.name
== "if" )
682 parseContext
.ifData
= new If ( e
, project
, this );
684 pOldIf
->data
.ifs
.push_back ( parseContext
.ifData
);
686 non_if_data
.ifs
.push_back ( parseContext
.ifData
);
687 subs_invalid
= false;
689 else if ( e
.name
== "ifnot" )
691 parseContext
.ifData
= new If ( e
, project
, this, true );
693 pOldIf
->data
.ifs
.push_back ( parseContext
.ifData
);
695 non_if_data
.ifs
.push_back ( parseContext
.ifData
);
696 subs_invalid
= false;
698 else if ( e
.name
== "compilerflag" )
700 CompilerFlag
* pCompilerFlag
= new CompilerFlag ( project
, this, e
);
701 if ( parseContext
.ifData
)
702 parseContext
.ifData
->data
.compilerFlags
.push_back ( pCompilerFlag
);
704 non_if_data
.compilerFlags
.push_back ( pCompilerFlag
);
707 else if ( e
.name
== "linkerflag" )
709 linkerFlags
.push_back ( new LinkerFlag ( project
, this, e
) );
712 else if ( e
.name
== "linkerscript" )
716 throw XMLInvalidBuildFileException (
718 "Only one <linkerscript> is valid per module" );
720 linkerScript
= new LinkerScript ( project
, this, e
);
723 else if ( e
.name
== "component" )
725 stubbedComponents
.push_back ( new StubbedComponent ( this, e
) );
726 subs_invalid
= false;
728 else if ( e
.name
== "property" )
730 throw XMLInvalidBuildFileException (
732 "<property> is not a valid sub-element of <module>" );
734 else if ( e
.name
== "bootstrap" )
736 bootstrap
= new Bootstrap ( project
, this, e
);
739 else if ( e
.name
== "pch" )
741 if ( parseContext
.ifData
)
743 throw XMLInvalidBuildFileException (
745 "<pch> is not a valid sub-element of <if>" );
749 throw XMLInvalidBuildFileException (
751 "Only one <pch> is valid per module" );
754 e
, *this, File ( FixSeparator ( path
+ cSep
+ e
.value
), false, "", true ) );
757 else if ( e
.name
== "compilationunit" )
759 if ( project
.configuration
.CompilationUnitsEnabled
)
761 CompilationUnit
* pCompilationUnit
= new CompilationUnit ( &project
, this, &e
);
762 if ( parseContext
.ifData
)
763 parseContext
.ifData
->data
.compilationUnits
.push_back ( pCompilationUnit
);
765 non_if_data
.compilationUnits
.push_back ( pCompilationUnit
);
766 parseContext
.compilationUnit
= pCompilationUnit
;
768 subs_invalid
= false;
770 else if ( e
.name
== "autoregister" )
772 if ( autoRegister
!= NULL
)
774 throw XMLInvalidBuildFileException (
776 "there can be only one <%s> element for a module",
779 autoRegister
= new AutoRegister ( project
, this, e
);
782 if ( subs_invalid
&& e
.subElements
.size() > 0 )
784 throw XMLInvalidBuildFileException (
786 "<%s> cannot have sub-elements",
789 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
790 ProcessXMLSubElement ( *e
.subElements
[i
], subpath
, parseContext
);
791 parseContext
.ifData
= pOldIf
;
792 parseContext
.compilationUnit
= pOldCompilationUnit
;
796 Module::GetModuleType ( const string
& location
, const XMLAttribute
& attribute
)
798 if ( attribute
.value
== "buildtool" )
800 if ( attribute
.value
== "staticlibrary" )
801 return StaticLibrary
;
802 if ( attribute
.value
== "objectlibrary" )
803 return ObjectLibrary
;
804 if ( attribute
.value
== "kernel" )
806 if ( attribute
.value
== "kernelmodedll" )
807 return KernelModeDLL
;
808 if ( attribute
.value
== "kernelmodedriver" )
809 return KernelModeDriver
;
810 if ( attribute
.value
== "nativedll" )
812 if ( attribute
.value
== "nativecui" )
814 if ( attribute
.value
== "win32dll" )
816 if ( attribute
.value
== "win32ocx" )
818 if ( attribute
.value
== "win32cui" )
820 if ( attribute
.value
== "win32gui" )
822 if ( attribute
.value
== "win32scr" )
824 if ( attribute
.value
== "bootloader" )
826 if ( attribute
.value
== "bootsector" )
828 if ( attribute
.value
== "bootprogram" )
830 if ( attribute
.value
== "iso" )
832 if ( attribute
.value
== "liveiso" )
834 if ( attribute
.value
== "isoregtest" )
836 if ( attribute
.value
== "liveisoregtest" )
837 return LiveIsoRegTest
;
838 if ( attribute
.value
== "test" )
840 if ( attribute
.value
== "rpcserver" )
842 if ( attribute
.value
== "rpcclient" )
844 if ( attribute
.value
== "alias" )
846 if ( attribute
.value
== "idlheader" )
848 if ( attribute
.value
== "embeddedtypelib" )
849 return EmbeddedTypeLib
;
850 throw InvalidAttributeValueException ( location
,
856 Module::GetDefaultModuleExtension () const
880 case KernelModeDriver
:
900 case EmbeddedTypeLib
:
903 throw InvalidOperationException ( __FILE__
,
908 Module::GetDefaultModuleEntrypoint () const
913 return "NtProcessStartup";
915 case KernelModeDriver
:
916 return "DriverEntry@8";
918 return "DllMainCRTStartup@12";
920 return "NtProcessStartup@4";
927 return "wmainCRTStartup";
929 return "mainCRTStartup";
933 return "wWinMainCRTStartup";
935 return "WinMainCRTStartup";
950 case EmbeddedTypeLib
:
953 throw InvalidOperationException ( __FILE__
,
958 Module::GetDefaultModuleBaseaddress () const
976 case KernelModeDriver
:
992 case EmbeddedTypeLib
:
995 throw InvalidOperationException ( __FILE__
,
1000 Module::HasImportLibrary () const
1002 return importLibrary
!= NULL
&& type
!= StaticLibrary
;
1006 Module::IsDLL () const
1015 case KernelModeDriver
:
1031 case LiveIsoRegTest
:
1036 case EmbeddedTypeLib
:
1039 throw InvalidOperationException ( __FILE__
,
1044 Module::GenerateInOutputTree () const
1053 case KernelModeDriver
:
1066 case LiveIsoRegTest
:
1067 case EmbeddedTypeLib
:
1077 throw InvalidOperationException ( __FILE__
,
1082 Module::GetTargetName () const
1084 return name
+ extension
;
1088 Module::GetDependencyPath () const
1090 if ( HasImportLibrary () )
1091 return ReplaceExtension ( GetPathWithPrefix ( "lib" ), ".a" );
1097 Module::GetBasePath () const
1103 Module::GetPath () const
1105 if ( path
.length() > 0 )
1106 return path
+ cSep
+ GetTargetName ();
1108 return GetTargetName ();
1112 Module::GetPathWithPrefix ( const string
& prefix
) const
1114 return path
+ cSep
+ prefix
+ GetTargetName ();
1118 Module::GetPathToBaseDir () const
1120 string temp_path
= path
;
1121 string result
= "..\\";
1122 while(temp_path
.find ('\\') != string::npos
)
1124 temp_path
.erase (0, temp_path
.find('\\')+1);
1131 Module::GetInvocationTarget ( const int index
) const
1133 return ssprintf ( "%s_invoke_%d",
1139 Module::GetEntryPoint(bool leadingUnderscore
) const
1142 if (entrypoint
== "0" || entrypoint
== "0x0")
1144 if (leadingUnderscore
)
1147 result
+= entrypoint
;
1152 Module::HasFileWithExtension (
1153 const IfableData
& data
,
1154 const std::string
& extension
) const
1157 for ( i
= 0; i
< data
.compilationUnits
.size (); i
++ )
1159 CompilationUnit
* compilationUnit
= data
.compilationUnits
[i
];
1160 if ( compilationUnit
->HasFileWithExtension ( extension
) )
1163 for ( i
= 0; i
< data
.ifs
.size (); i
++ )
1165 if ( HasFileWithExtension ( data
.ifs
[i
]->data
, extension
) )
1172 Module::InvokeModule () const
1174 for ( size_t i
= 0; i
< invocations
.size (); i
++ )
1176 Invoke
& invoke
= *invocations
[i
];
1177 string command
= FixSeparatorForSystemCommand(invoke
.invokeModule
->GetPath ()) + " " + invoke
.GetParameters ();
1178 printf ( "Executing '%s'\n\n", command
.c_str () );
1179 int exitcode
= system ( command
.c_str () );
1180 if ( exitcode
!= 0 )
1181 throw InvocationFailedException ( command
,
1187 File::File ( const string
& _name
, bool _first
,
1188 std::string _switches
,
1189 bool _isPreCompiledHeader
)
1192 switches(_switches
),
1193 isPreCompiledHeader(_isPreCompiledHeader
)
1203 Library::Library ( const XMLElement
& _node
,
1204 const Module
& _module
,
1205 const string
& _name
)
1209 importedModule(_module
.project
.LocateModule(_name
))
1211 if ( module
.name
== name
)
1213 throw XMLInvalidBuildFileException (
1215 "module '%s' cannot link against itself",
1218 if ( !importedModule
)
1220 throw XMLInvalidBuildFileException (
1222 "module '%s' trying to import non-existant module '%s'",
1223 module
.name
.c_str(),
1228 Library::Library ( const Module
& _module
,
1229 const string
& _name
)
1233 importedModule(_module
.project
.LocateModule(_name
))
1238 Library::ProcessXML()
1240 if ( node
&& !module
.project
.LocateModule ( name
) )
1242 throw XMLInvalidBuildFileException (
1244 "module '%s' is trying to link against non-existant module '%s'",
1245 module
.name
.c_str(),
1251 Invoke::Invoke ( const XMLElement
& _node
,
1252 const Module
& _module
)
1259 Invoke::ProcessXML()
1261 const XMLAttribute
* att
= node
.GetAttribute ( "module", false );
1263 invokeModule
= &module
;
1266 invokeModule
= module
.project
.LocateModule ( att
->value
);
1267 if ( invokeModule
== NULL
)
1269 throw XMLInvalidBuildFileException (
1271 "module '%s' is trying to invoke non-existant module '%s'",
1272 module
.name
.c_str(),
1273 att
->value
.c_str() );
1277 for ( size_t i
= 0; i
< node
.subElements
.size (); i
++ )
1278 ProcessXMLSubElement ( *node
.subElements
[i
] );
1282 Invoke::ProcessXMLSubElement ( const XMLElement
& e
)
1284 bool subs_invalid
= false;
1285 if ( e
.name
== "input" )
1287 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
1288 ProcessXMLSubElementInput ( *e
.subElements
[i
] );
1290 else if ( e
.name
== "output" )
1292 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
1293 ProcessXMLSubElementOutput ( *e
.subElements
[i
] );
1295 if ( subs_invalid
&& e
.subElements
.size() > 0 )
1297 throw XMLInvalidBuildFileException (
1299 "<%s> cannot have sub-elements",
1305 Invoke::ProcessXMLSubElementInput ( const XMLElement
& e
)
1307 bool subs_invalid
= false;
1308 if ( e
.name
== "inputfile" && e
.value
.size () > 0 )
1310 input
.push_back ( new InvokeFile (
1311 e
, FixSeparator ( module
.path
+ cSep
+ e
.value
) ) );
1312 subs_invalid
= true;
1314 if ( subs_invalid
&& e
.subElements
.size() > 0 )
1316 throw XMLInvalidBuildFileException (
1318 "<%s> cannot have sub-elements",
1324 Invoke::ProcessXMLSubElementOutput ( const XMLElement
& e
)
1326 bool subs_invalid
= false;
1327 if ( e
.name
== "outputfile" && e
.value
.size () > 0 )
1329 output
.push_back ( new InvokeFile (
1330 e
, FixSeparator ( module
.path
+ cSep
+ e
.value
) ) );
1331 subs_invalid
= true;
1333 if ( subs_invalid
&& e
.subElements
.size() > 0 )
1335 throw XMLInvalidBuildFileException (
1337 "<%s> cannot have sub-elements",
1343 Invoke::GetTargets ( string_list
& targets
) const
1345 for ( size_t i
= 0; i
< output
.size (); i
++ )
1347 InvokeFile
& file
= *output
[i
];
1348 targets
.push_back ( NormalizeFilename ( file
.name
) );
1353 Invoke::GetParameters () const
1355 string
parameters ( "" );
1357 for ( i
= 0; i
< output
.size (); i
++ )
1359 if ( parameters
.length () > 0)
1361 InvokeFile
& invokeFile
= *output
[i
];
1362 if ( invokeFile
.switches
.length () > 0 )
1364 parameters
+= invokeFile
.switches
+ " ";
1366 parameters
+= invokeFile
.name
;
1369 for ( i
= 0; i
< input
.size (); i
++ )
1371 if ( parameters
.length () > 0 )
1373 InvokeFile
& invokeFile
= *input
[i
];
1374 if ( invokeFile
.switches
.length () > 0 )
1376 parameters
+= invokeFile
.switches
;
1379 parameters
+= invokeFile
.name
;
1386 InvokeFile::InvokeFile ( const XMLElement
& _node
,
1387 const string
& _name
)
1391 const XMLAttribute
* att
= _node
.GetAttribute ( "switches", false );
1393 switches
= att
->value
;
1399 InvokeFile::ProcessXML()
1404 Dependency::Dependency ( const XMLElement
& _node
,
1405 const Module
& _module
)
1408 dependencyModule (NULL
)
1413 Dependency::ProcessXML()
1415 dependencyModule
= module
.project
.LocateModule ( node
.value
);
1416 if ( dependencyModule
== NULL
)
1418 throw XMLInvalidBuildFileException (
1420 "module '%s' depend on non-existant module '%s'",
1421 module
.name
.c_str(),
1422 node
.value
.c_str() );
1427 ImportLibrary::ImportLibrary ( const XMLElement
& _node
,
1428 const Module
& _module
)
1432 const XMLAttribute
* att
= _node
.GetAttribute ( "basename", false );
1434 basename
= att
->value
;
1436 basename
= module
.name
;
1438 att
= _node
.GetAttribute ( "dllname", false );
1440 dllname
= att
->value
;
1443 if ( _module
.type
== StaticLibrary
)
1445 throw XMLInvalidBuildFileException (
1447 "<importlibrary> dllname attribute required." );
1453 att
= _node
.GetAttribute ( "definition", true );
1455 definition
= FixSeparator(att
->value
);
1459 If::If ( const XMLElement
& node_
,
1460 const Project
& project_
,
1461 const Module
* module_
,
1462 const bool negated_
)
1463 : node(node_
), project(project_
), module(module_
), negated(negated_
)
1465 const XMLAttribute
* att
;
1467 att
= node
.GetAttribute ( "property", true );
1469 property
= att
->value
;
1471 att
= node
.GetAttribute ( "value", true );
1487 Property::Property ( const XMLElement
& node_
,
1488 const Project
& project_
,
1489 const Module
* module_
)
1490 : node(node_
), project(project_
), module(module_
)
1492 const XMLAttribute
* att
;
1494 att
= node
.GetAttribute ( "name", true );
1498 att
= node
.GetAttribute ( "value", true );
1504 Property::ProcessXML()
1510 const XMLElement
& node_
,
1511 const Module
& module_
,
1513 : node(node_
), module(module_
), file(file_
)
1518 PchFile::ProcessXML()
1523 AutoRegister::AutoRegister ( const Project
& project_
,
1524 const Module
* module_
,
1525 const XMLElement
& node_
)
1526 : project(project_
),
1533 AutoRegister::~AutoRegister ()
1538 AutoRegister::IsSupportedModuleType ( ModuleType type
)
1552 case KernelModeDriver
:
1562 case LiveIsoRegTest
:
1568 case EmbeddedTypeLib
:
1571 throw InvalidOperationException ( __FILE__
,
1576 AutoRegister::GetAutoRegisterType( string type
)
1578 if ( type
== "DllRegisterServer" )
1579 return DllRegisterServer
;
1580 if ( type
== "DllInstall" )
1582 if ( type
== "Both" )
1584 throw XMLInvalidBuildFileException (
1586 "<autoregister> type attribute must be DllRegisterServer, DllInstall or Both." );
1590 AutoRegister::Initialize ()
1592 if ( !IsSupportedModuleType ( module
->type
) )
1594 throw XMLInvalidBuildFileException (
1596 "<autoregister> is not applicable for this module type." );
1599 const XMLAttribute
* att
= node
.GetAttribute ( "infsection", true );
1600 infSection
= att
->value
;
1602 att
= node
.GetAttribute ( "type", true );
1603 type
= GetAutoRegisterType ( att
->value
);
1607 AutoRegister::ProcessXML()