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 Project
& project
,
122 const string
& location
,
124 const XMLAttribute
* root
,
125 const string
& att_value
)
127 if ( !att_value
.size() )
128 throw XMLInvalidBuildFileException (
130 "<directory> tag has empty 'name' attribute" );
131 if ( strpbrk ( att_value
.c_str (), "/\\?*:<>|" ) )
132 throw XMLInvalidBuildFileException (
134 "<directory> tag has invalid characters in 'name' attribute" );
141 if ( root
->value
== "intermediate" )
142 path_prefix
= Environment::GetIntermediatePath() + cSep
;
143 else if ( root
->value
== "output" )
144 path_prefix
= Environment::GetOutputPath() + cSep
;
147 throw InvalidAttributeValueException (
156 return FixSeparator(path_prefix
+ path
+ cSep
+ att_value
);
160 GetExtension ( const string
& filename
)
162 size_t index
= filename
.find_last_of ( '/' );
163 if (index
== string::npos
) index
= 0;
164 string tmp
= filename
.substr( index
, filename
.size() - index
);
165 size_t ext_index
= tmp
.find_last_of( '.' );
166 if (ext_index
!= string::npos
)
167 return filename
.substr ( index
+ ext_index
, filename
.size() );
172 GetDirectory ( const string
& filename
)
174 size_t index
= filename
.find_last_of ( cSep
);
175 if ( index
== string::npos
)
178 return filename
.substr ( 0, index
);
182 GetFilename ( const string
& filename
)
184 size_t index
= filename
.find_last_of ( cSep
);
185 if ( index
== string::npos
)
188 return filename
.substr ( index
+ 1, filename
.length () - index
);
192 NormalizeFilename ( const string
& filename
)
194 if ( filename
== "" )
197 string normalizedPath
= path
.Fixup ( filename
, true );
198 string relativeNormalizedPath
= path
.RelativeFromWorkingDirectory ( normalizedPath
);
199 return FixSeparator ( relativeNormalizedPath
);
203 GetBooleanValue ( const string
& value
)
212 ToLower ( string filename
)
214 for ( size_t i
= 1; i
< filename
.length (); i
++ )
215 filename
[i
] = tolower ( filename
[i
] );
219 void IfableData::ExtractModules( std::vector
<Module
*> &modules
)
222 for ( i
= 0; i
< this->modules
.size (); i
++ )
223 modules
.push_back(this->modules
[i
]);
226 IfableData::~IfableData()
229 for ( i
= 0; i
< includes
.size (); i
++ )
231 for ( i
= 0; i
< defines
.size (); i
++ )
233 for ( i
= 0; i
< libraries
.size (); i
++ )
235 for ( i
= 0; i
< properties
.size (); i
++ )
236 delete properties
[i
];
237 for ( i
= 0; i
< compilerFlags
.size (); i
++ )
238 delete compilerFlags
[i
];
239 for ( i
= 0; i
< modules
.size(); i
++ )
241 for ( i
= 0; i
< ifs
.size (); i
++ )
243 for ( i
= 0; i
< compilationUnits
.size (); i
++ )
244 delete compilationUnits
[i
];
247 void IfableData::ProcessXML ()
250 for ( i
= 0; i
< includes
.size (); i
++ )
251 includes
[i
]->ProcessXML ();
252 for ( i
= 0; i
< defines
.size (); i
++ )
253 defines
[i
]->ProcessXML ();
254 for ( i
= 0; i
< libraries
.size (); i
++ )
255 libraries
[i
]->ProcessXML ();
256 for ( i
= 0; i
< properties
.size(); i
++ )
257 properties
[i
]->ProcessXML ();
258 for ( i
= 0; i
< compilerFlags
.size(); i
++ )
259 compilerFlags
[i
]->ProcessXML ();
260 for ( i
= 0; i
< ifs
.size (); i
++ )
261 ifs
[i
]->ProcessXML ();
262 for ( i
= 0; i
< compilationUnits
.size (); i
++ )
263 compilationUnits
[i
]->ProcessXML ();
266 Module::Module ( const Project
& project
,
267 const XMLElement
& moduleNode
,
268 const string
& modulePath
)
271 importLibrary (NULL
),
279 if ( node
.name
!= "module" )
280 throw InvalidOperationException ( __FILE__
,
282 "Module created with non-<module> node" );
284 xmlbuildFile
= Path::RelativeFromWorkingDirectory ( moduleNode
.xmlFile
->filename () );
286 path
= FixSeparator ( modulePath
);
290 const XMLAttribute
* att
= moduleNode
.GetAttribute ( "if", false );
292 enabled
= GetBooleanValue ( project
.ResolveProperties ( att
->value
) );
294 att
= moduleNode
.GetAttribute ( "ifnot", false );
296 enabled
= !GetBooleanValue ( project
.ResolveProperties ( att
->value
) );
298 att
= moduleNode
.GetAttribute ( "name", true );
302 att
= moduleNode
.GetAttribute ( "type", true );
304 type
= GetModuleType ( node
.location
, *att
);
306 att
= moduleNode
.GetAttribute ( "extension", false );
308 extension
= att
->value
;
310 extension
= GetDefaultModuleExtension ();
312 att
= moduleNode
.GetAttribute ( "unicode", false );
315 const char* p
= att
->value
.c_str();
316 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
318 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
322 throw InvalidAttributeValueException (
331 att
= moduleNode
.GetAttribute ( "stdlib", false );
334 const char* p
= att
->value
.c_str();
335 if ( !stricmp ( p
, "host" ) )
336 useHostStdlib
= true;
337 else if ( !stricmp ( p
, "default" ) )
338 useHostStdlib
= false;
341 throw InvalidAttributeValueException (
348 useHostStdlib
= false;
352 // Always define UNICODE and _UNICODE
353 Define
* pDefine
= new Define ( project
, this, "UNICODE" );
354 non_if_data
.defines
.push_back ( pDefine
);
356 pDefine
= new Define ( project
, this, "_UNICODE" );
357 non_if_data
.defines
.push_back ( pDefine
);
360 att
= moduleNode
.GetAttribute ( "entrypoint", false );
363 if ( att
->value
== "" )
365 throw InvalidAttributeValueException (
371 entrypoint
= att
->value
;
372 isDefaultEntryPoint
= false;
376 entrypoint
= GetDefaultModuleEntrypoint ();
377 isDefaultEntryPoint
= true;
380 att
= moduleNode
.GetAttribute ( "baseaddress", false );
382 baseaddress
= att
->value
;
384 baseaddress
= GetDefaultModuleBaseaddress ();
386 att
= moduleNode
.GetAttribute ( "mangledsymbols", false );
389 const char* p
= att
->value
.c_str();
390 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
391 mangledSymbols
= true;
392 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
393 mangledSymbols
= false;
396 throw InvalidAttributeValueException (
403 mangledSymbols
= false;
405 att
= moduleNode
.GetAttribute ( "underscoresymbols", false );
407 underscoreSymbols
= att
->value
== "true";
409 underscoreSymbols
= false;
411 att
= moduleNode
.GetAttribute ( "host", false );
414 const char* p
= att
->value
.c_str();
415 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
417 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
421 throw InvalidAttributeValueException (
428 att
= moduleNode
.GetAttribute ( "isstartuplib", false );
431 const char* p
= att
->value
.c_str();
432 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
434 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
435 isStartupLib
= false;
438 throw InvalidAttributeValueException (
445 isStartupLib
= false;
447 att
= moduleNode
.GetAttribute ( "prefix", false );
451 att
= moduleNode
.GetAttribute ( "installbase", false );
453 installBase
= att
->value
;
457 att
= moduleNode
.GetAttribute ( "installname", false );
459 installName
= att
->value
;
463 att
= moduleNode
.GetAttribute ( "usewrc", false );
465 useWRC
= att
->value
== "true";
469 att
= moduleNode
.GetAttribute ( "allowwarnings", false );
472 att
= moduleNode
.GetAttribute ( "warnings", false );
475 printf ( "%s: WARNING: 'warnings' attribute of <module> is deprecated, use 'allowwarnings' instead\n",
476 moduleNode
.location
.c_str() );
480 allowWarnings
= att
->value
== "true";
482 allowWarnings
= false;
484 att
= moduleNode
.GetAttribute ( "aliasof", false );
485 if ( type
== Alias
&& att
!= NULL
)
486 aliasedModuleName
= att
->value
;
488 aliasedModuleName
= "";
490 if ( type
== BootProgram
)
492 att
= moduleNode
.GetAttribute ( "payload", true );
493 payload
= att
->value
;
500 for ( i
= 0; i
< invocations
.size(); i
++ )
501 delete invocations
[i
];
502 for ( i
= 0; i
< dependencies
.size(); i
++ )
503 delete dependencies
[i
];
504 for ( i
= 0; i
< compilerFlags
.size(); i
++ )
505 delete compilerFlags
[i
];
506 for ( i
= 0; i
< linkerFlags
.size(); i
++ )
507 delete linkerFlags
[i
];
508 for ( i
= 0; i
< stubbedComponents
.size(); i
++ )
509 delete stubbedComponents
[i
];
521 if ( aliasedModuleName
== name
)
523 throw XMLInvalidBuildFileException (
525 "module '%s' cannot link against itself",
528 const Module
* m
= project
.LocateModule ( aliasedModuleName
);
531 throw XMLInvalidBuildFileException (
533 "module '%s' trying to alias non-existant module '%s'",
535 aliasedModuleName
.c_str() );
540 for ( i
= 0; i
< node
.subElements
.size(); i
++ )
542 ParseContext parseContext
;
543 ProcessXMLSubElement ( *node
.subElements
[i
], path
, parseContext
);
545 for ( i
= 0; i
< invocations
.size(); i
++ )
546 invocations
[i
]->ProcessXML ();
547 for ( i
= 0; i
< dependencies
.size(); i
++ )
548 dependencies
[i
]->ProcessXML ();
549 for ( i
= 0; i
< compilerFlags
.size(); i
++ )
550 compilerFlags
[i
]->ProcessXML();
551 for ( i
= 0; i
< linkerFlags
.size(); i
++ )
552 linkerFlags
[i
]->ProcessXML();
553 for ( i
= 0; i
< stubbedComponents
.size(); i
++ )
554 stubbedComponents
[i
]->ProcessXML();
555 non_if_data
.ProcessXML();
557 linkerScript
->ProcessXML();
561 autoRegister
->ProcessXML();
565 Module::ProcessXMLSubElement ( const XMLElement
& e
,
567 ParseContext
& parseContext
)
569 If
* pOldIf
= parseContext
.ifData
;
570 CompilationUnit
* pOldCompilationUnit
= parseContext
.compilationUnit
;
571 bool subs_invalid
= false;
572 string
subpath ( path
);
573 if ( e
.name
== "file" && e
.value
.size () > 0 )
576 const XMLAttribute
* att
= e
.GetAttribute ( "first", false );
579 if ( !stricmp ( att
->value
.c_str(), "true" ) )
581 else if ( stricmp ( att
->value
.c_str(), "false" ) )
583 throw XMLInvalidBuildFileException (
585 "attribute 'first' of <file> element can only be 'true' or 'false'" );
588 string switches
= "";
589 att
= e
.GetAttribute ( "switches", false );
591 switches
= att
->value
;
594 // check for c++ file
595 string ext
= GetExtension ( e
.value
);
596 if ( !stricmp ( ext
.c_str(), ".cpp" ) )
598 else if ( !stricmp ( ext
.c_str(), ".cc" ) )
600 else if ( !stricmp ( ext
.c_str(), ".cxx" ) )
603 File
* pFile
= new File ( FixSeparator ( path
+ cSep
+ e
.value
),
607 if ( parseContext
.compilationUnit
)
608 parseContext
.compilationUnit
->files
.push_back ( pFile
);
611 CompilationUnit
* pCompilationUnit
= new CompilationUnit ( pFile
);
612 if ( parseContext
.ifData
)
613 parseContext
.ifData
->data
.compilationUnits
.push_back ( pCompilationUnit
);
616 string ext
= GetExtension ( e
.value
);
617 if ( !stricmp ( ext
.c_str(), ".idl" ) )
618 non_if_data
.compilationUnits
.insert ( non_if_data
.compilationUnits
.begin(), pCompilationUnit
);
620 non_if_data
.compilationUnits
.push_back ( pCompilationUnit
);
623 if ( parseContext
.ifData
)
624 parseContext
.ifData
->data
.files
.push_back ( pFile
);
626 non_if_data
.files
.push_back ( pFile
);
629 else if ( e
.name
== "library" && e
.value
.size () )
631 Library
* pLibrary
= new Library ( e
, *this, e
.value
);
632 if ( parseContext
.ifData
)
633 parseContext
.ifData
->data
.libraries
.push_back ( pLibrary
);
635 non_if_data
.libraries
.push_back ( pLibrary
);
638 else if ( e
.name
== "directory" )
640 const XMLAttribute
* att
= e
.GetAttribute ( "name", true );
641 const XMLAttribute
* base
= e
.GetAttribute ( "root", false );
643 subpath
= GetSubPath ( this->project
, e
.location
, path
, base
, att
->value
);
645 else if ( e
.name
== "include" )
647 Include
* include
= new Include ( project
, this, &e
);
648 if ( parseContext
.ifData
)
649 parseContext
.ifData
->data
.includes
.push_back ( include
);
651 non_if_data
.includes
.push_back ( include
);
654 else if ( e
.name
== "define" )
656 Define
* pDefine
= new Define ( project
, this, e
);
657 if ( parseContext
.ifData
)
658 parseContext
.ifData
->data
.defines
.push_back ( pDefine
);
660 non_if_data
.defines
.push_back ( pDefine
);
663 else if ( e
.name
== "invoke" )
665 if ( parseContext
.ifData
)
667 throw XMLInvalidBuildFileException (
669 "<invoke> is not a valid sub-element of <if>" );
671 invocations
.push_back ( new Invoke ( e
, *this ) );
672 subs_invalid
= false;
674 else if ( e
.name
== "dependency" )
676 if ( parseContext
.ifData
)
678 throw XMLInvalidBuildFileException (
680 "<dependency> is not a valid sub-element of <if>" );
682 dependencies
.push_back ( new Dependency ( e
, *this ) );
685 else if ( e
.name
== "importlibrary" )
687 if ( parseContext
.ifData
)
689 throw XMLInvalidBuildFileException (
691 "<importlibrary> is not a valid sub-element of <if>" );
695 throw XMLInvalidBuildFileException (
697 "Only one <importlibrary> is valid per module" );
699 importLibrary
= new ImportLibrary ( e
, *this );
702 else if ( e
.name
== "if" )
704 parseContext
.ifData
= new If ( e
, project
, this );
706 pOldIf
->data
.ifs
.push_back ( parseContext
.ifData
);
708 non_if_data
.ifs
.push_back ( parseContext
.ifData
);
709 subs_invalid
= false;
711 else if ( e
.name
== "ifnot" )
713 parseContext
.ifData
= new If ( e
, project
, this, true );
715 pOldIf
->data
.ifs
.push_back ( parseContext
.ifData
);
717 non_if_data
.ifs
.push_back ( parseContext
.ifData
);
718 subs_invalid
= false;
720 else if ( e
.name
== "compilerflag" )
722 CompilerFlag
* pCompilerFlag
= new CompilerFlag ( project
, this, e
);
723 if ( parseContext
.ifData
)
724 parseContext
.ifData
->data
.compilerFlags
.push_back ( pCompilerFlag
);
726 non_if_data
.compilerFlags
.push_back ( pCompilerFlag
);
729 else if ( e
.name
== "linkerflag" )
731 linkerFlags
.push_back ( new LinkerFlag ( project
, this, e
) );
734 else if ( e
.name
== "linkerscript" )
738 throw XMLInvalidBuildFileException (
740 "Only one <linkerscript> is valid per module" );
742 linkerScript
= new LinkerScript ( project
, this, e
);
745 else if ( e
.name
== "component" )
747 stubbedComponents
.push_back ( new StubbedComponent ( this, e
) );
748 subs_invalid
= false;
750 else if ( e
.name
== "property" )
752 throw XMLInvalidBuildFileException (
754 "<property> is not a valid sub-element of <module>" );
756 else if ( e
.name
== "bootstrap" )
758 bootstrap
= new Bootstrap ( project
, this, e
);
761 else if ( e
.name
== "pch" )
763 if ( parseContext
.ifData
)
765 throw XMLInvalidBuildFileException (
767 "<pch> is not a valid sub-element of <if>" );
771 throw XMLInvalidBuildFileException (
773 "Only one <pch> is valid per module" );
776 e
, *this, File ( FixSeparator ( path
+ cSep
+ e
.value
), false, "", true ) );
779 else if ( e
.name
== "compilationunit" )
781 if ( project
.configuration
.CompilationUnitsEnabled
)
783 CompilationUnit
* pCompilationUnit
= new CompilationUnit ( &project
, this, &e
);
784 if ( parseContext
.ifData
)
785 parseContext
.ifData
->data
.compilationUnits
.push_back ( pCompilationUnit
);
787 non_if_data
.compilationUnits
.push_back ( pCompilationUnit
);
788 parseContext
.compilationUnit
= pCompilationUnit
;
790 subs_invalid
= false;
792 else if ( e
.name
== "autoregister" )
794 if ( autoRegister
!= NULL
)
796 throw XMLInvalidBuildFileException (
798 "there can be only one <%s> element for a module",
801 autoRegister
= new AutoRegister ( project
, this, e
);
804 if ( subs_invalid
&& e
.subElements
.size() > 0 )
806 throw XMLInvalidBuildFileException (
808 "<%s> cannot have sub-elements",
811 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
812 ProcessXMLSubElement ( *e
.subElements
[i
], subpath
, parseContext
);
813 parseContext
.ifData
= pOldIf
;
814 parseContext
.compilationUnit
= pOldCompilationUnit
;
818 Module::GetModuleType ( const string
& location
, const XMLAttribute
& attribute
)
820 if ( attribute
.value
== "buildtool" )
822 if ( attribute
.value
== "staticlibrary" )
823 return StaticLibrary
;
824 if ( attribute
.value
== "objectlibrary" )
825 return ObjectLibrary
;
826 if ( attribute
.value
== "kernel" )
828 if ( attribute
.value
== "kernelmodedll" )
829 return KernelModeDLL
;
830 if ( attribute
.value
== "kernelmodedriver" )
831 return KernelModeDriver
;
832 if ( attribute
.value
== "nativedll" )
834 if ( attribute
.value
== "nativecui" )
836 if ( attribute
.value
== "win32dll" )
838 if ( attribute
.value
== "win32ocx" )
840 if ( attribute
.value
== "win32cui" )
842 if ( attribute
.value
== "win32gui" )
844 if ( attribute
.value
== "win32scr" )
846 if ( attribute
.value
== "bootloader" )
848 if ( attribute
.value
== "bootsector" )
850 if ( attribute
.value
== "bootprogram" )
852 if ( attribute
.value
== "iso" )
854 if ( attribute
.value
== "liveiso" )
856 if ( attribute
.value
== "isoregtest" )
858 if ( attribute
.value
== "liveisoregtest" )
859 return LiveIsoRegTest
;
860 if ( attribute
.value
== "test" )
862 if ( attribute
.value
== "rpcserver" )
864 if ( attribute
.value
== "rpcclient" )
866 if ( attribute
.value
== "alias" )
868 if ( attribute
.value
== "idlheader" )
870 if ( attribute
.value
== "embeddedtypelib" )
871 return EmbeddedTypeLib
;
872 throw InvalidAttributeValueException ( location
,
878 Module::GetDefaultModuleExtension () const
902 case KernelModeDriver
:
922 case EmbeddedTypeLib
:
925 throw InvalidOperationException ( __FILE__
,
930 Module::GetDefaultModuleEntrypoint () const
935 return "NtProcessStartup";
937 case KernelModeDriver
:
938 return "DriverEntry@8";
940 return "DllMainCRTStartup@12";
942 return "NtProcessStartup@4";
949 return "wmainCRTStartup";
951 return "mainCRTStartup";
955 return "wWinMainCRTStartup";
957 return "WinMainCRTStartup";
972 case EmbeddedTypeLib
:
975 throw InvalidOperationException ( __FILE__
,
980 Module::GetDefaultModuleBaseaddress () const
998 case KernelModeDriver
:
1008 case LiveIsoRegTest
:
1014 case EmbeddedTypeLib
:
1017 throw InvalidOperationException ( __FILE__
,
1022 Module::HasImportLibrary () const
1024 return importLibrary
!= NULL
&& type
!= StaticLibrary
;
1028 Module::IsDLL () const
1037 case KernelModeDriver
:
1053 case LiveIsoRegTest
:
1058 case EmbeddedTypeLib
:
1061 throw InvalidOperationException ( __FILE__
,
1066 Module::GenerateInOutputTree () const
1075 case KernelModeDriver
:
1088 case LiveIsoRegTest
:
1089 case EmbeddedTypeLib
:
1099 throw InvalidOperationException ( __FILE__
,
1104 Module::GetTargetName () const
1106 return name
+ extension
;
1110 Module::GetDependencyPath () const
1112 if ( HasImportLibrary () )
1113 return ReplaceExtension ( GetPathWithPrefix ( "lib" ), ".a" );
1119 Module::GetBasePath () const
1125 Module::GetPath () const
1127 if ( path
.length() > 0 )
1128 return path
+ cSep
+ GetTargetName ();
1130 return GetTargetName ();
1134 Module::GetPathWithPrefix ( const string
& prefix
) const
1136 return path
+ cSep
+ prefix
+ GetTargetName ();
1140 Module::GetPathToBaseDir () const
1142 string temp_path
= path
;
1143 string result
= "..\\";
1144 while(temp_path
.find ('\\') != string::npos
)
1146 temp_path
.erase (0, temp_path
.find('\\')+1);
1153 Module::GetInvocationTarget ( const int index
) const
1155 return ssprintf ( "%s_invoke_%d",
1161 Module::GetEntryPoint(bool leadingUnderscore
) const
1164 if (entrypoint
== "0" || entrypoint
== "0x0")
1166 if (leadingUnderscore
)
1169 result
+= entrypoint
;
1174 Module::HasFileWithExtension (
1175 const IfableData
& data
,
1176 const std::string
& extension
) const
1179 for ( i
= 0; i
< data
.compilationUnits
.size (); i
++ )
1181 CompilationUnit
* compilationUnit
= data
.compilationUnits
[i
];
1182 if ( compilationUnit
->HasFileWithExtension ( extension
) )
1185 for ( i
= 0; i
< data
.ifs
.size (); i
++ )
1187 if ( HasFileWithExtension ( data
.ifs
[i
]->data
, extension
) )
1194 Module::InvokeModule () const
1196 for ( size_t i
= 0; i
< invocations
.size (); i
++ )
1198 Invoke
& invoke
= *invocations
[i
];
1199 string command
= FixSeparatorForSystemCommand(invoke
.invokeModule
->GetPath ()) + " " + invoke
.GetParameters ();
1200 printf ( "Executing '%s'\n\n", command
.c_str () );
1201 int exitcode
= system ( command
.c_str () );
1202 if ( exitcode
!= 0 )
1203 throw InvocationFailedException ( command
,
1209 File::File ( const string
& _name
, bool _first
,
1210 std::string _switches
,
1211 bool _isPreCompiledHeader
)
1214 switches(_switches
),
1215 isPreCompiledHeader(_isPreCompiledHeader
)
1225 Library::Library ( const XMLElement
& _node
,
1226 const Module
& _module
,
1227 const string
& _name
)
1231 importedModule(_module
.project
.LocateModule(_name
))
1233 if ( module
.name
== name
)
1235 throw XMLInvalidBuildFileException (
1237 "module '%s' cannot link against itself",
1240 if ( !importedModule
)
1242 throw XMLInvalidBuildFileException (
1244 "module '%s' trying to import non-existant module '%s'",
1245 module
.name
.c_str(),
1250 Library::Library ( const Module
& _module
,
1251 const string
& _name
)
1255 importedModule(_module
.project
.LocateModule(_name
))
1260 Library::ProcessXML()
1262 if ( node
&& !module
.project
.LocateModule ( name
) )
1264 throw XMLInvalidBuildFileException (
1266 "module '%s' is trying to link against non-existant module '%s'",
1267 module
.name
.c_str(),
1273 Invoke::Invoke ( const XMLElement
& _node
,
1274 const Module
& _module
)
1281 Invoke::ProcessXML()
1283 const XMLAttribute
* att
= node
.GetAttribute ( "module", false );
1285 invokeModule
= &module
;
1288 invokeModule
= module
.project
.LocateModule ( att
->value
);
1289 if ( invokeModule
== NULL
)
1291 throw XMLInvalidBuildFileException (
1293 "module '%s' is trying to invoke non-existant module '%s'",
1294 module
.name
.c_str(),
1295 att
->value
.c_str() );
1299 for ( size_t i
= 0; i
< node
.subElements
.size (); i
++ )
1300 ProcessXMLSubElement ( *node
.subElements
[i
] );
1304 Invoke::ProcessXMLSubElement ( const XMLElement
& e
)
1306 bool subs_invalid
= false;
1307 if ( e
.name
== "input" )
1309 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
1310 ProcessXMLSubElementInput ( *e
.subElements
[i
] );
1312 else if ( e
.name
== "output" )
1314 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
1315 ProcessXMLSubElementOutput ( *e
.subElements
[i
] );
1317 if ( subs_invalid
&& e
.subElements
.size() > 0 )
1319 throw XMLInvalidBuildFileException (
1321 "<%s> cannot have sub-elements",
1327 Invoke::ProcessXMLSubElementInput ( const XMLElement
& e
)
1329 bool subs_invalid
= false;
1330 if ( e
.name
== "inputfile" && e
.value
.size () > 0 )
1332 input
.push_back ( new InvokeFile (
1333 e
, FixSeparator ( module
.path
+ cSep
+ e
.value
) ) );
1334 subs_invalid
= true;
1336 if ( subs_invalid
&& e
.subElements
.size() > 0 )
1338 throw XMLInvalidBuildFileException (
1340 "<%s> cannot have sub-elements",
1346 Invoke::ProcessXMLSubElementOutput ( const XMLElement
& e
)
1348 bool subs_invalid
= false;
1349 if ( e
.name
== "outputfile" && e
.value
.size () > 0 )
1351 output
.push_back ( new InvokeFile (
1352 e
, FixSeparator ( module
.path
+ cSep
+ e
.value
) ) );
1353 subs_invalid
= true;
1355 if ( subs_invalid
&& e
.subElements
.size() > 0 )
1357 throw XMLInvalidBuildFileException (
1359 "<%s> cannot have sub-elements",
1365 Invoke::GetTargets ( string_list
& targets
) const
1367 for ( size_t i
= 0; i
< output
.size (); i
++ )
1369 InvokeFile
& file
= *output
[i
];
1370 targets
.push_back ( NormalizeFilename ( file
.name
) );
1375 Invoke::GetParameters () const
1377 string
parameters ( "" );
1379 for ( i
= 0; i
< output
.size (); i
++ )
1381 if ( parameters
.length () > 0)
1383 InvokeFile
& invokeFile
= *output
[i
];
1384 if ( invokeFile
.switches
.length () > 0 )
1386 parameters
+= invokeFile
.switches
+ " ";
1388 parameters
+= invokeFile
.name
;
1391 for ( i
= 0; i
< input
.size (); i
++ )
1393 if ( parameters
.length () > 0 )
1395 InvokeFile
& invokeFile
= *input
[i
];
1396 if ( invokeFile
.switches
.length () > 0 )
1398 parameters
+= invokeFile
.switches
;
1401 parameters
+= invokeFile
.name
;
1408 InvokeFile::InvokeFile ( const XMLElement
& _node
,
1409 const string
& _name
)
1413 const XMLAttribute
* att
= _node
.GetAttribute ( "switches", false );
1415 switches
= att
->value
;
1421 InvokeFile::ProcessXML()
1426 Dependency::Dependency ( const XMLElement
& _node
,
1427 const Module
& _module
)
1430 dependencyModule (NULL
)
1435 Dependency::ProcessXML()
1437 dependencyModule
= module
.project
.LocateModule ( node
.value
);
1438 if ( dependencyModule
== NULL
)
1440 throw XMLInvalidBuildFileException (
1442 "module '%s' depend on non-existant module '%s'",
1443 module
.name
.c_str(),
1444 node
.value
.c_str() );
1449 ImportLibrary::ImportLibrary ( const XMLElement
& _node
,
1450 const Module
& _module
)
1454 const XMLAttribute
* att
= _node
.GetAttribute ( "basename", false );
1456 basename
= att
->value
;
1458 basename
= module
.name
;
1460 att
= _node
.GetAttribute ( "dllname", false );
1462 dllname
= att
->value
;
1465 if ( _module
.type
== StaticLibrary
)
1467 throw XMLInvalidBuildFileException (
1469 "<importlibrary> dllname attribute required." );
1475 att
= _node
.GetAttribute ( "definition", true );
1477 definition
= FixSeparator(att
->value
);
1481 If::If ( const XMLElement
& node_
,
1482 const Project
& project_
,
1483 const Module
* module_
,
1484 const bool negated_
)
1485 : node(node_
), project(project_
), module(module_
), negated(negated_
)
1487 const XMLAttribute
* att
;
1489 att
= node
.GetAttribute ( "property", true );
1491 property
= att
->value
;
1493 att
= node
.GetAttribute ( "value", true );
1509 Property::Property ( const XMLElement
& node_
,
1510 const Project
& project_
,
1511 const Module
* module_
)
1512 : node(node_
), project(project_
), module(module_
)
1514 const XMLAttribute
* att
;
1516 att
= node
.GetAttribute ( "name", true );
1520 att
= node
.GetAttribute ( "value", true );
1526 Property::ProcessXML()
1532 const XMLElement
& node_
,
1533 const Module
& module_
,
1535 : node(node_
), module(module_
), file(file_
)
1540 PchFile::ProcessXML()
1545 AutoRegister::AutoRegister ( const Project
& project_
,
1546 const Module
* module_
,
1547 const XMLElement
& node_
)
1548 : project(project_
),
1555 AutoRegister::~AutoRegister ()
1560 AutoRegister::IsSupportedModuleType ( ModuleType type
)
1574 case KernelModeDriver
:
1584 case LiveIsoRegTest
:
1590 case EmbeddedTypeLib
:
1593 throw InvalidOperationException ( __FILE__
,
1598 AutoRegister::GetAutoRegisterType( string type
)
1600 if ( type
== "DllRegisterServer" )
1601 return DllRegisterServer
;
1602 if ( type
== "DllInstall" )
1604 if ( type
== "Both" )
1606 throw XMLInvalidBuildFileException (
1608 "<autoregister> type attribute must be DllRegisterServer, DllInstall or Both." );
1612 AutoRegister::Initialize ()
1614 if ( !IsSupportedModuleType ( module
->type
) )
1616 throw XMLInvalidBuildFileException (
1618 "<autoregister> is not applicable for this module type." );
1621 const XMLAttribute
* att
= node
.GetAttribute ( "infsection", true );
1622 infSection
= att
->value
;
1624 att
= node
.GetAttribute ( "type", true );
1625 type
= GetAutoRegisterType ( att
->value
);
1629 AutoRegister::ProcessXML()