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 string
& att_value
)
126 if ( !att_value
.size() )
127 throw XMLInvalidBuildFileException (
129 "<directory> tag has empty 'name' attribute" );
130 if ( strpbrk ( att_value
.c_str (), "/\\?*:<>|" ) )
131 throw XMLInvalidBuildFileException (
133 "<directory> tag has invalid characters in 'name' attribute" );
137 return FixSeparator(path
+ cSep
+ att_value
);
141 GetExtension ( const string
& filename
)
143 size_t index
= filename
.find_last_of ( '/' );
144 if (index
== string::npos
) index
= 0;
145 string tmp
= filename
.substr( index
, filename
.size() - index
);
146 size_t ext_index
= tmp
.find_last_of( '.' );
147 if (ext_index
!= string::npos
)
148 return filename
.substr ( index
+ ext_index
, filename
.size() );
153 GetDirectory ( const string
& filename
)
155 size_t index
= filename
.find_last_of ( cSep
);
156 if ( index
== string::npos
)
159 return filename
.substr ( 0, index
);
163 GetFilename ( const string
& filename
)
165 size_t index
= filename
.find_last_of ( cSep
);
166 if ( index
== string::npos
)
169 return filename
.substr ( index
+ 1, filename
.length () - index
);
173 NormalizeFilename ( const string
& filename
)
175 if ( filename
== "" )
178 string normalizedPath
= path
.Fixup ( filename
, true );
179 string relativeNormalizedPath
= path
.RelativeFromWorkingDirectory ( normalizedPath
);
180 return FixSeparator ( relativeNormalizedPath
);
184 GetBooleanValue ( const string
& value
)
193 ToLower ( string filename
)
195 for ( size_t i
= 1; i
< filename
.length (); i
++ )
196 filename
[i
] = tolower ( filename
[i
] );
200 void IfableData::ExtractModules( std::vector
<Module
*> &modules
)
203 for ( i
= 0; i
< this->modules
.size (); i
++ )
204 modules
.push_back(this->modules
[i
]);
207 IfableData::~IfableData()
210 for ( i
= 0; i
< includes
.size (); i
++ )
212 for ( i
= 0; i
< defines
.size (); i
++ )
214 for ( i
= 0; i
< libraries
.size (); i
++ )
216 for ( i
= 0; i
< properties
.size (); i
++ )
217 delete properties
[i
];
218 for ( i
= 0; i
< compilerFlags
.size (); i
++ )
219 delete compilerFlags
[i
];
220 for ( i
= 0; i
< modules
.size(); i
++ )
222 for ( i
= 0; i
< ifs
.size (); i
++ )
224 for ( i
= 0; i
< compilationUnits
.size (); i
++ )
225 delete compilationUnits
[i
];
228 void IfableData::ProcessXML ()
231 for ( i
= 0; i
< includes
.size (); i
++ )
232 includes
[i
]->ProcessXML ();
233 for ( i
= 0; i
< defines
.size (); i
++ )
234 defines
[i
]->ProcessXML ();
235 for ( i
= 0; i
< libraries
.size (); i
++ )
236 libraries
[i
]->ProcessXML ();
237 for ( i
= 0; i
< properties
.size(); i
++ )
238 properties
[i
]->ProcessXML ();
239 for ( i
= 0; i
< compilerFlags
.size(); i
++ )
240 compilerFlags
[i
]->ProcessXML ();
241 for ( i
= 0; i
< ifs
.size (); i
++ )
242 ifs
[i
]->ProcessXML ();
243 for ( i
= 0; i
< compilationUnits
.size (); i
++ )
244 compilationUnits
[i
]->ProcessXML ();
247 Module::Module ( const Project
& project
,
248 const XMLElement
& moduleNode
,
249 const string
& modulePath
)
252 importLibrary (NULL
),
261 if ( node
.name
!= "module" )
262 throw InvalidOperationException ( __FILE__
,
264 "Module created with non-<module> node" );
266 xmlbuildFile
= Path::RelativeFromWorkingDirectory ( moduleNode
.xmlFile
->filename () );
268 path
= FixSeparator ( modulePath
);
272 const XMLAttribute
* att
= moduleNode
.GetAttribute ( "if", false );
274 enabled
= GetBooleanValue ( project
.ResolveProperties ( att
->value
) );
276 att
= moduleNode
.GetAttribute ( "ifnot", false );
278 enabled
= !GetBooleanValue ( project
.ResolveProperties ( att
->value
) );
280 att
= moduleNode
.GetAttribute ( "name", true );
284 att
= moduleNode
.GetAttribute ( "type", true );
286 type
= GetModuleType ( node
.location
, *att
);
288 att
= moduleNode
.GetAttribute ( "extension", false );
290 extension
= att
->value
;
292 extension
= GetDefaultModuleExtension ();
294 att
= moduleNode
.GetAttribute ( "unicode", false );
297 const char* p
= att
->value
.c_str();
298 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
300 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
304 throw InvalidAttributeValueException (
313 att
= moduleNode
.GetAttribute ( "stdlib", false );
316 const char* p
= att
->value
.c_str();
317 if ( !stricmp ( p
, "host" ) )
318 useHostStdlib
= true;
319 else if ( !stricmp ( p
, "default" ) )
320 useHostStdlib
= false;
323 throw InvalidAttributeValueException (
330 useHostStdlib
= false;
334 // Always define UNICODE and _UNICODE
335 Define
* pDefine
= new Define ( project
, this, "UNICODE" );
336 non_if_data
.defines
.push_back ( pDefine
);
338 pDefine
= new Define ( project
, this, "_UNICODE" );
339 non_if_data
.defines
.push_back ( pDefine
);
342 att
= moduleNode
.GetAttribute ( "entrypoint", false );
345 if ( att
->value
== "" )
347 throw InvalidAttributeValueException (
353 entrypoint
= att
->value
;
354 isDefaultEntryPoint
= false;
358 entrypoint
= GetDefaultModuleEntrypoint ();
359 isDefaultEntryPoint
= true;
362 att
= moduleNode
.GetAttribute ( "baseaddress", false );
364 baseaddress
= att
->value
;
366 baseaddress
= GetDefaultModuleBaseaddress ();
368 att
= moduleNode
.GetAttribute ( "mangledsymbols", false );
371 const char* p
= att
->value
.c_str();
372 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
373 mangledSymbols
= true;
374 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
375 mangledSymbols
= false;
378 throw InvalidAttributeValueException (
385 mangledSymbols
= false;
387 att
= moduleNode
.GetAttribute ( "underscoresymbols", false );
389 underscoreSymbols
= att
->value
== "true";
391 underscoreSymbols
= false;
393 att
= moduleNode
.GetAttribute ( "host", false );
396 const char* p
= att
->value
.c_str();
397 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
399 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
403 throw InvalidAttributeValueException (
410 att
= moduleNode
.GetAttribute ( "isstartuplib", false );
413 const char* p
= att
->value
.c_str();
414 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
416 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
417 isStartupLib
= false;
420 throw InvalidAttributeValueException (
427 isStartupLib
= false;
429 att
= moduleNode
.GetAttribute ( "prefix", false );
433 att
= moduleNode
.GetAttribute ( "installbase", false );
435 installBase
= att
->value
;
439 att
= moduleNode
.GetAttribute ( "installname", false );
441 installName
= att
->value
;
445 att
= moduleNode
.GetAttribute ( "usewrc", false );
447 useWRC
= att
->value
== "true";
451 att
= moduleNode
.GetAttribute ( "allowwarnings", false );
454 att
= moduleNode
.GetAttribute ( "warnings", false );
457 printf ( "%s: WARNING: 'warnings' attribute of <module> is deprecated, use 'allowwarnings' instead\n",
458 moduleNode
.location
.c_str() );
462 allowWarnings
= att
->value
== "true";
464 allowWarnings
= false;
466 att
= moduleNode
.GetAttribute ( "aliasof", false );
467 if ( type
== Alias
&& att
!= NULL
)
468 aliasedModuleName
= att
->value
;
470 aliasedModuleName
= "";
472 if ( type
== BootProgram
)
474 att
= moduleNode
.GetAttribute ( "payload", true );
475 payload
= att
->value
;
478 if ( type
== BootProgram
|| type
== ElfExecutable
)
480 att
= moduleNode
.GetAttribute ( "buildtype", false );
483 buildtype
= att
->value
;
487 buildtype
= "BOOTPROG";
495 for ( i
= 0; i
< invocations
.size(); i
++ )
496 delete invocations
[i
];
497 for ( i
= 0; i
< dependencies
.size(); i
++ )
498 delete dependencies
[i
];
499 for ( i
= 0; i
< compilerFlags
.size(); i
++ )
500 delete compilerFlags
[i
];
501 for ( i
= 0; i
< linkerFlags
.size(); i
++ )
502 delete linkerFlags
[i
];
503 for ( i
= 0; i
< stubbedComponents
.size(); i
++ )
504 delete stubbedComponents
[i
];
516 if ( aliasedModuleName
== name
)
518 throw XMLInvalidBuildFileException (
520 "module '%s' cannot link against itself",
523 const Module
* m
= project
.LocateModule ( aliasedModuleName
);
526 throw XMLInvalidBuildFileException (
528 "module '%s' trying to alias non-existant module '%s'",
530 aliasedModuleName
.c_str() );
535 for ( i
= 0; i
< node
.subElements
.size(); i
++ )
537 ParseContext parseContext
;
538 ProcessXMLSubElement ( *node
.subElements
[i
], path
, "", parseContext
);
540 for ( i
= 0; i
< invocations
.size(); i
++ )
541 invocations
[i
]->ProcessXML ();
542 for ( i
= 0; i
< dependencies
.size(); i
++ )
543 dependencies
[i
]->ProcessXML ();
544 for ( i
= 0; i
< compilerFlags
.size(); i
++ )
545 compilerFlags
[i
]->ProcessXML();
546 for ( i
= 0; i
< linkerFlags
.size(); i
++ )
547 linkerFlags
[i
]->ProcessXML();
548 for ( i
= 0; i
< stubbedComponents
.size(); i
++ )
549 stubbedComponents
[i
]->ProcessXML();
550 non_if_data
.ProcessXML();
552 linkerScript
->ProcessXML();
556 autoRegister
->ProcessXML();
560 Module::ProcessXMLSubElement ( const XMLElement
& e
,
562 const string
& path_prefix
,
563 ParseContext
& parseContext
)
565 If
* pOldIf
= parseContext
.ifData
;
566 CompilationUnit
* pOldCompilationUnit
= parseContext
.compilationUnit
;
567 bool subs_invalid
= false;
568 string
subpath ( path
);
569 string
subpath_prefix ( "" );
570 if ( e
.name
== "file" && e
.value
.size () > 0 )
573 const XMLAttribute
* att
= e
.GetAttribute ( "first", false );
576 if ( !stricmp ( att
->value
.c_str(), "true" ) )
578 else if ( stricmp ( att
->value
.c_str(), "false" ) )
580 throw XMLInvalidBuildFileException (
582 "attribute 'first' of <file> element can only be 'true' or 'false'" );
585 string switches
= "";
586 att
= e
.GetAttribute ( "switches", false );
588 switches
= att
->value
;
591 // check for c++ file
592 string ext
= GetExtension ( e
.value
);
593 if ( !stricmp ( ext
.c_str(), ".cpp" ) )
595 else if ( !stricmp ( ext
.c_str(), ".cc" ) )
597 else if ( !stricmp ( ext
.c_str(), ".cxx" ) )
600 File
* pFile
= new File ( FixSeparator ( path
+ cSep
+ e
.value
),
605 if ( parseContext
.compilationUnit
)
606 parseContext
.compilationUnit
->files
.push_back ( pFile
);
609 CompilationUnit
* pCompilationUnit
= new CompilationUnit ( pFile
);
610 if ( parseContext
.ifData
)
611 parseContext
.ifData
->data
.compilationUnits
.push_back ( pCompilationUnit
);
614 string ext
= GetExtension ( e
.value
);
615 if ( !stricmp ( ext
.c_str(), ".idl" ) )
616 non_if_data
.compilationUnits
.insert ( non_if_data
.compilationUnits
.begin(), pCompilationUnit
);
618 non_if_data
.compilationUnits
.push_back ( pCompilationUnit
);
621 if ( parseContext
.ifData
)
622 parseContext
.ifData
->data
.files
.push_back ( pFile
);
624 non_if_data
.files
.push_back ( pFile
);
627 else if ( e
.name
== "library" && e
.value
.size () )
629 Library
* pLibrary
= new Library ( e
, *this, e
.value
);
630 if ( parseContext
.ifData
)
631 parseContext
.ifData
->data
.libraries
.push_back ( pLibrary
);
633 non_if_data
.libraries
.push_back ( pLibrary
);
636 else if ( e
.name
== "directory" )
638 const XMLAttribute
* att
= e
.GetAttribute ( "name", true );
639 const XMLAttribute
* root
= e
.GetAttribute ( "root", false );
643 if ( root
->value
== "intermediate" )
644 subpath_prefix
= "$(INTERMEDIATE)";
645 else if ( root
->value
== "output" )
646 subpath_prefix
= "$(OUTPUT)";
649 throw InvalidAttributeValueException (
655 subpath
= GetSubPath ( this->project
, e
.location
, path
, att
->value
);
657 else if ( e
.name
== "include" )
659 Include
* include
= new Include ( project
, this, &e
);
660 if ( parseContext
.ifData
)
661 parseContext
.ifData
->data
.includes
.push_back ( include
);
663 non_if_data
.includes
.push_back ( include
);
666 else if ( e
.name
== "define" )
668 Define
* pDefine
= new Define ( project
, this, e
);
669 if ( parseContext
.ifData
)
670 parseContext
.ifData
->data
.defines
.push_back ( pDefine
);
672 non_if_data
.defines
.push_back ( pDefine
);
675 else if ( e
.name
== "metadata" )
677 if ( parseContext
.ifData
)
679 throw XMLInvalidBuildFileException (
681 "<metadata> is not a valid sub-element of <if>" );
683 metadata
= new Metadata ( e
, *this );
684 subs_invalid
= false;
686 else if ( e
.name
== "invoke" )
688 if ( parseContext
.ifData
)
690 throw XMLInvalidBuildFileException (
692 "<invoke> is not a valid sub-element of <if>" );
694 invocations
.push_back ( new Invoke ( e
, *this ) );
695 subs_invalid
= false;
697 else if ( e
.name
== "dependency" )
699 if ( parseContext
.ifData
)
701 throw XMLInvalidBuildFileException (
703 "<dependency> is not a valid sub-element of <if>" );
705 dependencies
.push_back ( new Dependency ( e
, *this ) );
708 else if ( e
.name
== "importlibrary" )
710 if ( parseContext
.ifData
)
712 throw XMLInvalidBuildFileException (
714 "<importlibrary> is not a valid sub-element of <if>" );
718 throw XMLInvalidBuildFileException (
720 "Only one <importlibrary> is valid per module" );
722 importLibrary
= new ImportLibrary ( project
, e
, *this );
725 else if ( e
.name
== "if" )
727 parseContext
.ifData
= new If ( e
, project
, this );
729 pOldIf
->data
.ifs
.push_back ( parseContext
.ifData
);
731 non_if_data
.ifs
.push_back ( parseContext
.ifData
);
732 subs_invalid
= false;
734 else if ( e
.name
== "ifnot" )
736 parseContext
.ifData
= new If ( e
, project
, this, true );
738 pOldIf
->data
.ifs
.push_back ( parseContext
.ifData
);
740 non_if_data
.ifs
.push_back ( parseContext
.ifData
);
741 subs_invalid
= false;
743 else if ( e
.name
== "compilerflag" )
745 CompilerFlag
* pCompilerFlag
= new CompilerFlag ( project
, this, e
);
746 if ( parseContext
.ifData
)
747 parseContext
.ifData
->data
.compilerFlags
.push_back ( pCompilerFlag
);
749 non_if_data
.compilerFlags
.push_back ( pCompilerFlag
);
752 else if ( e
.name
== "linkerflag" )
754 linkerFlags
.push_back ( new LinkerFlag ( project
, this, e
) );
757 else if ( e
.name
== "linkerscript" )
761 throw XMLInvalidBuildFileException (
763 "Only one <linkerscript> is valid per module" );
765 linkerScript
= new LinkerScript ( project
, this, e
);
768 else if ( e
.name
== "component" )
770 stubbedComponents
.push_back ( new StubbedComponent ( this, e
) );
771 subs_invalid
= false;
773 else if ( e
.name
== "property" )
775 throw XMLInvalidBuildFileException (
777 "<property> is not a valid sub-element of <module>" );
779 else if ( e
.name
== "bootstrap" )
781 bootstrap
= new Bootstrap ( project
, this, e
);
784 else if ( e
.name
== "pch" )
786 if ( parseContext
.ifData
)
788 throw XMLInvalidBuildFileException (
790 "<pch> is not a valid sub-element of <if>" );
794 throw XMLInvalidBuildFileException (
796 "Only one <pch> is valid per module" );
798 size_t pos
= e
.value
.find_last_of ( "/\\" );
799 if ( pos
== string::npos
)
802 e
, *this, FileLocation ( SourceDirectory
, path
, e
.value
) );
806 string dir
= e
.value
.substr ( 0, pos
);
807 string name
= e
.value
.substr ( pos
+ 1);
809 e
, *this, FileLocation ( SourceDirectory
, path
+ sSep
+ dir
, name
) );
813 else if ( e
.name
== "compilationunit" )
815 if ( project
.configuration
.CompilationUnitsEnabled
)
817 CompilationUnit
* pCompilationUnit
= new CompilationUnit ( &project
, this, &e
);
818 if ( parseContext
.ifData
)
819 parseContext
.ifData
->data
.compilationUnits
.push_back ( pCompilationUnit
);
821 non_if_data
.compilationUnits
.push_back ( pCompilationUnit
);
822 parseContext
.compilationUnit
= pCompilationUnit
;
824 subs_invalid
= false;
826 else if ( e
.name
== "autoregister" )
828 if ( autoRegister
!= NULL
)
830 throw XMLInvalidBuildFileException (
832 "there can be only one <%s> element for a module",
835 autoRegister
= new AutoRegister ( project
, this, e
);
838 if ( subs_invalid
&& e
.subElements
.size() > 0 )
840 throw XMLInvalidBuildFileException (
842 "<%s> cannot have sub-elements",
845 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
846 ProcessXMLSubElement ( *e
.subElements
[i
], subpath
, subpath_prefix
, parseContext
);
847 parseContext
.ifData
= pOldIf
;
848 parseContext
.compilationUnit
= pOldCompilationUnit
;
852 Module::GetModuleType ( const string
& location
, const XMLAttribute
& attribute
)
854 if ( attribute
.value
== "buildtool" )
856 if ( attribute
.value
== "staticlibrary" )
857 return StaticLibrary
;
858 if ( attribute
.value
== "objectlibrary" )
859 return ObjectLibrary
;
860 if ( attribute
.value
== "kernel" )
862 if ( attribute
.value
== "kernelmodedll" )
863 return KernelModeDLL
;
864 if ( attribute
.value
== "kernelmodedriver" )
865 return KernelModeDriver
;
866 if ( attribute
.value
== "nativedll" )
868 if ( attribute
.value
== "nativecui" )
870 if ( attribute
.value
== "win32dll" )
872 if ( attribute
.value
== "win32ocx" )
874 if ( attribute
.value
== "win32cui" )
876 if ( attribute
.value
== "win32gui" )
878 if ( attribute
.value
== "win32scr" )
880 if ( attribute
.value
== "bootloader" )
882 if ( attribute
.value
== "bootsector" )
884 if ( attribute
.value
== "bootprogram" )
886 if ( attribute
.value
== "iso" )
888 if ( attribute
.value
== "liveiso" )
890 if ( attribute
.value
== "isoregtest" )
892 if ( attribute
.value
== "liveisoregtest" )
893 return LiveIsoRegTest
;
894 if ( attribute
.value
== "test" )
896 if ( attribute
.value
== "rpcserver" )
898 if ( attribute
.value
== "rpcclient" )
900 if ( attribute
.value
== "alias" )
902 if ( attribute
.value
== "idlheader" )
904 if ( attribute
.value
== "embeddedtypelib" )
905 return EmbeddedTypeLib
;
906 if ( attribute
.value
== "elfexecutable" )
907 return ElfExecutable
;
908 throw InvalidAttributeValueException ( location
,
914 Module::GetDefaultModuleExtension () const
939 case KernelModeDriver
:
959 case EmbeddedTypeLib
:
962 throw InvalidOperationException ( __FILE__
,
967 Module::GetDefaultModuleEntrypoint () const
972 return "NtProcessStartup";
974 case KernelModeDriver
:
975 return "DriverEntry@8";
977 return "DllMainCRTStartup@12";
979 return "NtProcessStartup@4";
986 return "wmainCRTStartup";
988 return "mainCRTStartup";
992 return "wWinMainCRTStartup";
994 return "WinMainCRTStartup";
1003 case LiveIsoRegTest
:
1010 case EmbeddedTypeLib
:
1013 throw InvalidOperationException ( __FILE__
,
1018 Module::GetDefaultModuleBaseaddress () const
1023 return "0x80800000";
1026 return "0x10000000";
1031 return "0x00400000";
1034 return "0x00400000";
1036 case KernelModeDriver
:
1037 return "0x00010000";
1048 case LiveIsoRegTest
:
1054 case EmbeddedTypeLib
:
1057 throw InvalidOperationException ( __FILE__
,
1062 Module::HasImportLibrary () const
1064 return importLibrary
!= NULL
&& type
!= StaticLibrary
;
1068 Module::IsDLL () const
1077 case KernelModeDriver
:
1093 case LiveIsoRegTest
:
1098 case EmbeddedTypeLib
:
1102 throw InvalidOperationException ( __FILE__
,
1107 Module::GenerateInOutputTree () const
1116 case KernelModeDriver
:
1129 case LiveIsoRegTest
:
1130 case EmbeddedTypeLib
:
1141 throw InvalidOperationException ( __FILE__
,
1146 Module::GetTargetName () const
1148 return name
+ extension
;
1152 Module::GetDependencyPath () const
1154 if ( HasImportLibrary () )
1155 return ReplaceExtension ( GetPathWithPrefix ( "lib" ), ".a" );
1161 Module::GetDependencyTargetName () const
1163 if ( HasImportLibrary () )
1164 return "lib" + name
+ ".a";
1166 return GetTargetName();
1170 Module::GetBasePath () const
1176 Module::GetPath () const
1178 if ( path
.length() > 0 )
1179 return path
+ cSep
+ GetTargetName ();
1181 return GetTargetName ();
1185 Module::GetPathWithPrefix ( const string
& prefix
) const
1187 return path
+ cSep
+ prefix
+ GetTargetName ();
1191 Module::GetPathToBaseDir () const
1193 string temp_path
= path
;
1194 string result
= "..\\";
1195 while(temp_path
.find ('\\') != string::npos
)
1197 temp_path
.erase (0, temp_path
.find('\\')+1);
1204 Module::GetInvocationTarget ( const int index
) const
1206 return ssprintf ( "%s_invoke_%d",
1212 Module::GetEntryPoint(bool leadingUnderscore
) const
1215 if (entrypoint
== "0" || entrypoint
== "0x0")
1217 if (leadingUnderscore
)
1220 result
+= entrypoint
;
1225 Module::HasFileWithExtension (
1226 const IfableData
& data
,
1227 const std::string
& extension
) const
1230 for ( i
= 0; i
< data
.compilationUnits
.size (); i
++ )
1232 CompilationUnit
* compilationUnit
= data
.compilationUnits
[i
];
1233 if ( compilationUnit
->HasFileWithExtension ( extension
) )
1236 for ( i
= 0; i
< data
.ifs
.size (); i
++ )
1238 if ( HasFileWithExtension ( data
.ifs
[i
]->data
, extension
) )
1245 Module::InvokeModule () const
1247 for ( size_t i
= 0; i
< invocations
.size (); i
++ )
1249 Invoke
& invoke
= *invocations
[i
];
1250 string command
= FixSeparatorForSystemCommand(invoke
.invokeModule
->GetPath ()) + " " + invoke
.GetParameters ();
1251 printf ( "Executing '%s'\n\n", command
.c_str () );
1252 int exitcode
= system ( command
.c_str () );
1253 if ( exitcode
!= 0 )
1254 throw InvocationFailedException ( command
,
1260 File::File ( const string
& _name
,
1262 std::string _switches
,
1263 bool _isPreCompiledHeader
)
1267 switches(_switches
),
1268 isPreCompiledHeader(_isPreCompiledHeader
)
1273 File::File ( const string
& _name
,
1274 const string
& _path_prefix
,
1276 std::string _switches
,
1277 bool _isPreCompiledHeader
)
1279 path_prefix(_path_prefix
),
1281 switches(_switches
),
1282 isPreCompiledHeader(_isPreCompiledHeader
)
1292 std::string
File::GetFullPath () const
1294 if ( path_prefix
.length () > 0 )
1295 return path_prefix
+ sSep
+ name
;
1301 Library::Library ( const XMLElement
& _node
,
1302 const Module
& _module
,
1303 const string
& _name
)
1307 importedModule(_module
.project
.LocateModule(_name
))
1309 if ( module
.name
== name
)
1311 throw XMLInvalidBuildFileException (
1313 "module '%s' cannot link against itself",
1316 if ( !importedModule
)
1318 throw XMLInvalidBuildFileException (
1320 "module '%s' trying to import non-existant module '%s'",
1321 module
.name
.c_str(),
1326 Library::Library ( const Module
& _module
,
1327 const string
& _name
)
1331 importedModule(_module
.project
.LocateModule(_name
))
1336 Library::ProcessXML()
1338 if ( node
&& !module
.project
.LocateModule ( name
) )
1340 throw XMLInvalidBuildFileException (
1342 "module '%s' is trying to link against non-existant module '%s'",
1343 module
.name
.c_str(),
1349 Invoke::Invoke ( const XMLElement
& _node
,
1350 const Module
& _module
)
1357 Invoke::ProcessXML()
1359 const XMLAttribute
* att
= node
.GetAttribute ( "module", false );
1361 invokeModule
= &module
;
1364 invokeModule
= module
.project
.LocateModule ( att
->value
);
1365 if ( invokeModule
== NULL
)
1367 throw XMLInvalidBuildFileException (
1369 "module '%s' is trying to invoke non-existant module '%s'",
1370 module
.name
.c_str(),
1371 att
->value
.c_str() );
1375 for ( size_t i
= 0; i
< node
.subElements
.size (); i
++ )
1376 ProcessXMLSubElement ( *node
.subElements
[i
] );
1380 Invoke::ProcessXMLSubElement ( const XMLElement
& e
)
1382 bool subs_invalid
= false;
1383 if ( e
.name
== "input" )
1385 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
1386 ProcessXMLSubElementInput ( *e
.subElements
[i
] );
1388 else if ( e
.name
== "output" )
1390 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
1391 ProcessXMLSubElementOutput ( *e
.subElements
[i
] );
1393 if ( subs_invalid
&& e
.subElements
.size() > 0 )
1395 throw XMLInvalidBuildFileException (
1397 "<%s> cannot have sub-elements",
1403 Invoke::ProcessXMLSubElementInput ( const XMLElement
& e
)
1405 bool subs_invalid
= false;
1406 if ( e
.name
== "inputfile" && e
.value
.size () > 0 )
1408 input
.push_back ( new InvokeFile (
1409 e
, FixSeparator ( module
.path
+ cSep
+ e
.value
) ) );
1410 subs_invalid
= true;
1412 if ( subs_invalid
&& e
.subElements
.size() > 0 )
1414 throw XMLInvalidBuildFileException (
1416 "<%s> cannot have sub-elements",
1422 Invoke::ProcessXMLSubElementOutput ( const XMLElement
& e
)
1424 bool subs_invalid
= false;
1425 if ( e
.name
== "outputfile" && e
.value
.size () > 0 )
1427 output
.push_back ( new InvokeFile (
1428 e
, FixSeparator ( module
.path
+ cSep
+ e
.value
) ) );
1429 subs_invalid
= true;
1431 if ( subs_invalid
&& e
.subElements
.size() > 0 )
1433 throw XMLInvalidBuildFileException (
1435 "<%s> cannot have sub-elements",
1441 Invoke::GetTargets ( string_list
& targets
) const
1443 for ( size_t i
= 0; i
< output
.size (); i
++ )
1445 InvokeFile
& file
= *output
[i
];
1446 targets
.push_back ( NormalizeFilename ( file
.name
) );
1451 Invoke::GetParameters () const
1453 string
parameters ( "" );
1455 for ( i
= 0; i
< output
.size (); i
++ )
1457 if ( parameters
.length () > 0)
1459 InvokeFile
& invokeFile
= *output
[i
];
1460 if ( invokeFile
.switches
.length () > 0 )
1462 parameters
+= invokeFile
.switches
+ " ";
1464 parameters
+= invokeFile
.name
;
1467 for ( i
= 0; i
< input
.size (); i
++ )
1469 if ( parameters
.length () > 0 )
1471 InvokeFile
& invokeFile
= *input
[i
];
1472 if ( invokeFile
.switches
.length () > 0 )
1474 parameters
+= invokeFile
.switches
;
1477 parameters
+= invokeFile
.name
;
1484 InvokeFile::InvokeFile ( const XMLElement
& _node
,
1485 const string
& _name
)
1489 const XMLAttribute
* att
= _node
.GetAttribute ( "switches", false );
1491 switches
= att
->value
;
1497 InvokeFile::ProcessXML()
1502 Dependency::Dependency ( const XMLElement
& _node
,
1503 const Module
& _module
)
1506 dependencyModule (NULL
)
1511 Dependency::ProcessXML()
1513 dependencyModule
= module
.project
.LocateModule ( node
.value
);
1514 if ( dependencyModule
== NULL
)
1516 throw XMLInvalidBuildFileException (
1518 "module '%s' depend on non-existant module '%s'",
1519 module
.name
.c_str(),
1520 node
.value
.c_str() );
1525 Metadata::Metadata ( const XMLElement
& _node
,
1526 const Module
& _module
)
1530 /* The module name */
1531 const XMLAttribute
* att
= _node
.GetAttribute ( "name", false );
1537 /* The module description */
1538 att
= _node
.GetAttribute ( "description", false );
1540 description
= att
->value
;
1544 /* The module version */
1545 att
= _node
.GetAttribute ( "version", false );
1547 version
= att
->value
;
1551 /* The module copyright */
1552 att
= _node
.GetAttribute ( "copyright", false );
1554 copyright
= att
->value
;
1558 att
= _node
.GetAttribute ( "url", false );
1564 /* When was this module updated */
1565 att
= _node
.GetAttribute ( "date", false );
1571 /* When was this module updated */
1572 att
= _node
.GetAttribute ( "owner", false );
1580 ImportLibrary::ImportLibrary ( const Project
& project
,
1581 const XMLElement
& node
,
1582 const Module
& module
)
1583 : XmlNode ( project
, node
),
1586 const XMLAttribute
* dllname
= node
.GetAttribute ( "dllname", false );
1587 const XMLAttribute
* definition
= node
.GetAttribute ( "definition", true );
1588 assert ( definition
);
1591 this->dllname
= dllname
->value
;
1592 else if ( module
.type
== StaticLibrary
)
1593 throw XMLInvalidBuildFileException (
1595 "<importlibrary> dllname attribute required." );
1597 DirectoryLocation directory
= SourceDirectory
;
1598 size_t index
= definition
->value
.rfind ( ".spec.def" );
1599 if ( index
!= string::npos
)
1600 directory
= IntermediateDirectory
;
1602 index
= definition
->value
.find_last_of ( "/\\" );
1603 if ( index
== string::npos
)
1605 source
= new FileLocation ( directory
,
1606 module
.GetBasePath (),
1607 definition
->value
);
1611 string dir
= definition
->value
.substr ( 0, index
);
1612 string name
= definition
->value
.substr ( index
+ 1);
1613 source
= new FileLocation ( directory
,
1614 NormalizeFilename ( module
.GetBasePath () + sSep
+ dir
),
1620 If::If ( const XMLElement
& node_
,
1621 const Project
& project_
,
1622 const Module
* module_
,
1623 const bool negated_
)
1624 : node(node_
), project(project_
), module(module_
), negated(negated_
)
1626 const XMLAttribute
* att
;
1628 att
= node
.GetAttribute ( "property", true );
1630 property
= att
->value
;
1632 att
= node
.GetAttribute ( "value", true );
1648 Property::Property ( const XMLElement
& node_
,
1649 const Project
& project_
,
1650 const Module
* module_
)
1651 : project(project_
), module(module_
)
1653 const XMLAttribute
* att
;
1655 att
= node_
.GetAttribute ( "name", true );
1659 att
= node_
.GetAttribute ( "value", true );
1664 Property::Property ( const Project
& project_
,
1665 const Module
* module_
,
1666 const std::string
& name_
,
1667 const std::string
& value_
)
1668 : project(project_
), module(module_
), name(name_
), value(value_
)
1673 Property::ProcessXML()
1679 const XMLElement
& node_
,
1680 const Module
& module_
,
1681 const FileLocation
& file_
)
1682 : node(node_
), module(module_
), file(file_
)
1687 PchFile::ProcessXML()