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
)
190 IfableData::~IfableData()
193 for ( i
= 0; i
< includes
.size (); i
++ )
195 for ( i
= 0; i
< defines
.size (); i
++ )
197 for ( i
= 0; i
< libraries
.size (); i
++ )
199 for ( i
= 0; i
< properties
.size (); i
++ )
200 delete properties
[i
];
201 for ( i
= 0; i
< compilerFlags
.size (); i
++ )
202 delete compilerFlags
[i
];
203 for ( i
= 0; i
< ifs
.size (); i
++ )
205 for ( i
= 0; i
< compilationUnits
.size (); i
++ )
206 delete compilationUnits
[i
];
209 void IfableData::ProcessXML ()
212 for ( i
= 0; i
< includes
.size (); i
++ )
213 includes
[i
]->ProcessXML ();
214 for ( i
= 0; i
< defines
.size (); i
++ )
215 defines
[i
]->ProcessXML ();
216 for ( i
= 0; i
< libraries
.size (); i
++ )
217 libraries
[i
]->ProcessXML ();
218 for ( i
= 0; i
< properties
.size(); i
++ )
219 properties
[i
]->ProcessXML ();
220 for ( i
= 0; i
< compilerFlags
.size(); i
++ )
221 compilerFlags
[i
]->ProcessXML ();
222 for ( i
= 0; i
< ifs
.size (); i
++ )
223 ifs
[i
]->ProcessXML ();
224 for ( i
= 0; i
< compilationUnits
.size (); i
++ )
225 compilationUnits
[i
]->ProcessXML ();
228 Module::Module ( const Project
& project
,
229 const XMLElement
& moduleNode
,
230 const string
& modulePath
)
233 importLibrary (NULL
),
240 if ( node
.name
!= "module" )
241 throw InvalidOperationException ( __FILE__
,
243 "Module created with non-<module> node" );
245 xmlbuildFile
= Path::RelativeFromWorkingDirectory ( moduleNode
.xmlFile
->filename () );
247 path
= FixSeparator ( modulePath
);
251 const XMLAttribute
* att
= moduleNode
.GetAttribute ( "if", false );
253 enabled
= GetBooleanValue ( project
.ResolveProperties ( att
->value
) );
255 att
= moduleNode
.GetAttribute ( "ifnot", false );
257 enabled
= !GetBooleanValue ( project
.ResolveProperties ( att
->value
) );
259 att
= moduleNode
.GetAttribute ( "name", true );
263 att
= moduleNode
.GetAttribute ( "type", true );
265 type
= GetModuleType ( node
.location
, *att
);
267 att
= moduleNode
.GetAttribute ( "extension", false );
269 extension
= att
->value
;
271 extension
= GetDefaultModuleExtension ();
273 att
= moduleNode
.GetAttribute ( "unicode", false );
276 const char* p
= att
->value
.c_str();
277 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
279 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
283 throw InvalidAttributeValueException (
292 att
= moduleNode
.GetAttribute ( "entrypoint", false );
294 entrypoint
= att
->value
;
296 entrypoint
= GetDefaultModuleEntrypoint ();
298 att
= moduleNode
.GetAttribute ( "baseaddress", false );
300 baseaddress
= att
->value
;
302 baseaddress
= GetDefaultModuleBaseaddress ();
304 att
= moduleNode
.GetAttribute ( "mangledsymbols", false );
307 const char* p
= att
->value
.c_str();
308 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
309 mangledSymbols
= true;
310 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
311 mangledSymbols
= false;
314 throw InvalidAttributeValueException (
321 mangledSymbols
= false;
323 att
= moduleNode
.GetAttribute ( "host", false );
326 const char* p
= att
->value
.c_str();
327 if ( !stricmp ( p
, "true" ) || !stricmp ( p
, "yes" ) )
329 else if ( !stricmp ( p
, "false" ) || !stricmp ( p
, "no" ) )
333 throw InvalidAttributeValueException (
340 att
= moduleNode
.GetAttribute ( "prefix", false );
344 att
= moduleNode
.GetAttribute ( "installbase", false );
346 installBase
= att
->value
;
350 att
= moduleNode
.GetAttribute ( "installname", false );
352 installName
= att
->value
;
356 att
= moduleNode
.GetAttribute ( "usewrc", false );
358 useWRC
= att
->value
== "true";
362 att
= moduleNode
.GetAttribute ( "allowwarnings", false );
365 att
= moduleNode
.GetAttribute ( "warnings", false );
368 printf ( "%s: WARNING: 'warnings' attribute of <module> is deprecated, use 'allowwarnings' instead\n",
369 moduleNode
.location
.c_str() );
373 allowWarnings
= att
->value
== "true";
375 allowWarnings
= false;
377 att
= moduleNode
.GetAttribute ( "aliasof", false );
378 if ( type
== Alias
&& att
!= NULL
)
379 aliasedModuleName
= att
->value
;
381 aliasedModuleName
= "";
387 for ( i
= 0; i
< invocations
.size(); i
++ )
388 delete invocations
[i
];
389 for ( i
= 0; i
< dependencies
.size(); i
++ )
390 delete dependencies
[i
];
391 for ( i
= 0; i
< compilerFlags
.size(); i
++ )
392 delete compilerFlags
[i
];
393 for ( i
= 0; i
< linkerFlags
.size(); i
++ )
394 delete linkerFlags
[i
];
395 for ( i
= 0; i
< stubbedComponents
.size(); i
++ )
396 delete stubbedComponents
[i
];
408 if ( aliasedModuleName
== name
)
409 throw InvalidBuildFileException (
411 "module '%s' cannot link against itself",
413 const Module
* m
= project
.LocateModule ( aliasedModuleName
);
415 throw InvalidBuildFileException (
417 "module '%s' trying to alias non-existant module '%s'",
419 aliasedModuleName
.c_str() );
423 for ( i
= 0; i
< node
.subElements
.size(); i
++ )
425 ParseContext parseContext
;
426 ProcessXMLSubElement ( *node
.subElements
[i
], path
, parseContext
);
428 for ( i
= 0; i
< invocations
.size(); i
++ )
429 invocations
[i
]->ProcessXML ();
430 for ( i
= 0; i
< dependencies
.size(); i
++ )
431 dependencies
[i
]->ProcessXML ();
432 for ( i
= 0; i
< compilerFlags
.size(); i
++ )
433 compilerFlags
[i
]->ProcessXML();
434 for ( i
= 0; i
< linkerFlags
.size(); i
++ )
435 linkerFlags
[i
]->ProcessXML();
436 for ( i
= 0; i
< stubbedComponents
.size(); i
++ )
437 stubbedComponents
[i
]->ProcessXML();
438 non_if_data
.ProcessXML();
440 linkerScript
->ProcessXML();
446 Module::ProcessXMLSubElement ( const XMLElement
& e
,
448 ParseContext
& parseContext
)
450 If
* pOldIf
= parseContext
.ifData
;
451 CompilationUnit
* pOldCompilationUnit
= parseContext
.compilationUnit
;
452 bool subs_invalid
= false;
453 string
subpath ( path
);
454 if ( e
.name
== "file" && e
.value
.size () > 0 )
457 const XMLAttribute
* att
= e
.GetAttribute ( "first", false );
460 if ( !stricmp ( att
->value
.c_str(), "true" ) )
462 else if ( stricmp ( att
->value
.c_str(), "false" ) )
463 throw InvalidBuildFileException (
465 "attribute 'first' of <file> element can only be 'true' or 'false'" );
467 string switches
= "";
468 att
= e
.GetAttribute ( "switches", false );
470 switches
= att
->value
;
473 // check for c++ file
474 string ext
= GetExtension ( e
.value
);
475 if ( !stricmp ( ext
.c_str(), ".cpp" ) )
477 else if ( !stricmp ( ext
.c_str(), ".cc" ) )
479 else if ( !stricmp ( ext
.c_str(), ".cxx" ) )
482 File
* pFile
= new File ( FixSeparator ( path
+ cSep
+ e
.value
),
486 if ( parseContext
.compilationUnit
)
487 parseContext
.compilationUnit
->files
.push_back ( pFile
);
490 CompilationUnit
* pCompilationUnit
= new CompilationUnit ( pFile
);
491 if ( parseContext
.ifData
)
492 parseContext
.ifData
->data
.compilationUnits
.push_back ( pCompilationUnit
);
494 non_if_data
.compilationUnits
.push_back ( pCompilationUnit
);
496 if ( parseContext
.ifData
)
497 parseContext
.ifData
->data
.files
.push_back ( pFile
);
499 non_if_data
.files
.push_back ( pFile
);
502 else if ( e
.name
== "library" && e
.value
.size () )
504 Library
* pLibrary
= new Library ( e
, *this, e
.value
);
505 if ( parseContext
.ifData
)
506 parseContext
.ifData
->data
.libraries
.push_back ( pLibrary
);
508 non_if_data
.libraries
.push_back ( pLibrary
);
511 else if ( e
.name
== "directory" )
513 const XMLAttribute
* att
= e
.GetAttribute ( "name", true );
515 subpath
= GetSubPath ( e
.location
, path
, att
->value
);
517 else if ( e
.name
== "include" )
519 Include
* include
= new Include ( project
, this, &e
);
520 if ( parseContext
.ifData
)
521 parseContext
.ifData
->data
.includes
.push_back ( include
);
523 non_if_data
.includes
.push_back ( include
);
526 else if ( e
.name
== "define" )
528 Define
* pDefine
= new Define ( project
, this, e
);
529 if ( parseContext
.ifData
)
530 parseContext
.ifData
->data
.defines
.push_back ( pDefine
);
532 non_if_data
.defines
.push_back ( pDefine
);
535 else if ( e
.name
== "invoke" )
537 if ( parseContext
.ifData
)
538 throw InvalidBuildFileException (
540 "<invoke> is not a valid sub-element of <if>" );
541 invocations
.push_back ( new Invoke ( e
, *this ) );
542 subs_invalid
= false;
544 else if ( e
.name
== "dependency" )
546 if ( parseContext
.ifData
)
547 throw InvalidBuildFileException (
549 "<dependency> is not a valid sub-element of <if>" );
550 dependencies
.push_back ( new Dependency ( e
, *this ) );
553 else if ( e
.name
== "importlibrary" )
555 if ( parseContext
.ifData
)
556 throw InvalidBuildFileException (
558 "<importlibrary> is not a valid sub-element of <if>" );
560 throw InvalidBuildFileException (
562 "Only one <importlibrary> is valid per module" );
563 importLibrary
= new ImportLibrary ( e
, *this );
566 else if ( e
.name
== "if" )
568 parseContext
.ifData
= new If ( e
, project
, this );
570 pOldIf
->data
.ifs
.push_back ( parseContext
.ifData
);
572 non_if_data
.ifs
.push_back ( parseContext
.ifData
);
573 subs_invalid
= false;
575 else if ( e
.name
== "ifnot" )
577 parseContext
.ifData
= new If ( e
, project
, this, true );
579 pOldIf
->data
.ifs
.push_back ( parseContext
.ifData
);
581 non_if_data
.ifs
.push_back ( parseContext
.ifData
);
582 subs_invalid
= false;
584 else if ( e
.name
== "compilerflag" )
586 CompilerFlag
* pCompilerFlag
= new CompilerFlag ( project
, this, e
);
587 if ( parseContext
.ifData
)
588 parseContext
.ifData
->data
.compilerFlags
.push_back ( pCompilerFlag
);
590 non_if_data
.compilerFlags
.push_back ( pCompilerFlag
);
593 else if ( e
.name
== "linkerflag" )
595 linkerFlags
.push_back ( new LinkerFlag ( project
, this, e
) );
598 else if ( e
.name
== "linkerscript" )
601 throw InvalidBuildFileException (
603 "Only one <linkerscript> is valid per module" );
604 linkerScript
= new LinkerScript ( project
, this, e
);
607 else if ( e
.name
== "component" )
609 stubbedComponents
.push_back ( new StubbedComponent ( this, e
) );
610 subs_invalid
= false;
612 else if ( e
.name
== "property" )
614 throw InvalidBuildFileException (
616 "<property> is not a valid sub-element of <module>" );
618 else if ( e
.name
== "bootstrap" )
620 bootstrap
= new Bootstrap ( project
, this, e
);
623 else if ( e
.name
== "pch" )
625 if ( parseContext
.ifData
)
626 throw InvalidBuildFileException (
628 "<pch> is not a valid sub-element of <if>" );
630 throw InvalidBuildFileException (
632 "Only one <pch> is valid per module" );
634 e
, *this, File ( FixSeparator ( path
+ cSep
+ e
.value
), false, "", true ) );
637 else if ( e
.name
== "compilationunit" )
639 if ( project
.configuration
.CompilationUnitsEnabled
)
641 CompilationUnit
* pCompilationUnit
= new CompilationUnit ( &project
, this, &e
);
642 if ( parseContext
.ifData
)
643 parseContext
.ifData
->data
.compilationUnits
.push_back ( pCompilationUnit
);
645 non_if_data
.compilationUnits
.push_back ( pCompilationUnit
);
646 parseContext
.compilationUnit
= pCompilationUnit
;
648 subs_invalid
= false;
650 if ( subs_invalid
&& e
.subElements
.size() > 0 )
651 throw InvalidBuildFileException (
653 "<%s> cannot have sub-elements",
655 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
656 ProcessXMLSubElement ( *e
.subElements
[i
], subpath
, parseContext
);
657 parseContext
.ifData
= pOldIf
;
658 parseContext
.compilationUnit
= pOldCompilationUnit
;
662 Module::GetModuleType ( const string
& location
, const XMLAttribute
& attribute
)
664 if ( attribute
.value
== "buildtool" )
666 if ( attribute
.value
== "staticlibrary" )
667 return StaticLibrary
;
668 if ( attribute
.value
== "objectlibrary" )
669 return ObjectLibrary
;
670 if ( attribute
.value
== "kernel" )
672 if ( attribute
.value
== "kernelmodedll" )
673 return KernelModeDLL
;
674 if ( attribute
.value
== "kernelmodedriver" )
675 return KernelModeDriver
;
676 if ( attribute
.value
== "nativedll" )
678 if ( attribute
.value
== "nativecui" )
680 if ( attribute
.value
== "win32dll" )
682 if ( attribute
.value
== "win32cui" )
684 if ( attribute
.value
== "win32gui" )
686 if ( attribute
.value
== "bootloader" )
688 if ( attribute
.value
== "bootsector" )
690 if ( attribute
.value
== "iso" )
692 if ( attribute
.value
== "liveiso" )
694 if ( attribute
.value
== "test" )
696 if ( attribute
.value
== "rpcserver" )
698 if ( attribute
.value
== "rpcclient" )
700 if ( attribute
.value
== "alias" )
702 throw InvalidAttributeValueException ( location
,
708 Module::GetDefaultModuleExtension () const
727 case KernelModeDriver
:
744 throw InvalidOperationException ( __FILE__
,
749 Module::GetDefaultModuleEntrypoint () const
754 return "_NtProcessStartup";
756 return "_DriverEntry@8";
758 return "_DllMainCRTStartup@12";
760 return "_NtProcessStartup@4";
762 return "_DllMain@12";
766 return "_wmainCRTStartup";
768 return "_mainCRTStartup";
771 return "_wWinMainCRTStartup";
773 return "_WinMainCRTStartup";
774 case KernelModeDriver
:
775 return "_DriverEntry@8";
788 throw InvalidOperationException ( __FILE__
,
793 Module::GetDefaultModuleBaseaddress () const
809 case KernelModeDriver
:
823 throw InvalidOperationException ( __FILE__
,
828 Module::HasImportLibrary () const
830 return importLibrary
!= NULL
;
834 Module::IsDLL () const
842 case KernelModeDriver
:
860 throw InvalidOperationException ( __FILE__
,
865 Module::GenerateInOutputTree () const
873 case KernelModeDriver
:
891 throw InvalidOperationException ( __FILE__
,
896 Module::GetTargetName () const
898 return name
+ extension
;
902 Module::GetDependencyPath () const
904 if ( HasImportLibrary () )
905 return ReplaceExtension ( GetPathWithPrefix ( "lib" ), ".a" );
911 Module::GetBasePath () const
917 Module::GetPath () const
919 if ( path
.length() > 0 )
920 return path
+ cSep
+ GetTargetName ();
922 return GetTargetName ();
926 Module::GetPathWithPrefix ( const string
& prefix
) const
928 return path
+ cSep
+ prefix
+ GetTargetName ();
932 Module::GetInvocationTarget ( const int index
) const
934 return ssprintf ( "%s_invoke_%d",
940 Module::HasFileWithExtension (
941 const IfableData
& data
,
942 const std::string
& extension
) const
945 for ( i
= 0; i
< data
.compilationUnits
.size (); i
++ )
947 CompilationUnit
* compilationUnit
= data
.compilationUnits
[i
];
948 if ( compilationUnit
->HasFileWithExtension ( extension
) )
951 for ( i
= 0; i
< data
.ifs
.size (); i
++ )
953 if ( HasFileWithExtension ( data
.ifs
[i
]->data
, extension
) )
960 Module::InvokeModule () const
962 for ( size_t i
= 0; i
< invocations
.size (); i
++ )
964 Invoke
& invoke
= *invocations
[i
];
965 string command
= FixSeparatorForSystemCommand(invoke
.invokeModule
->GetPath ()) + " " + invoke
.GetParameters ();
966 printf ( "Executing '%s'\n\n", command
.c_str () );
967 int exitcode
= system ( command
.c_str () );
969 throw InvocationFailedException ( command
,
975 File::File ( const string
& _name
, bool _first
,
976 std::string _switches
,
977 bool _isPreCompiledHeader
)
981 isPreCompiledHeader(_isPreCompiledHeader
)
991 Library::Library ( const XMLElement
& _node
,
992 const Module
& _module
,
993 const string
& _name
)
997 importedModule(_module
.project
.LocateModule(_name
))
999 if ( module
.name
== name
)
1000 throw InvalidBuildFileException (
1002 "module '%s' cannot link against itself",
1004 if ( !importedModule
)
1005 throw InvalidBuildFileException (
1007 "module '%s' trying to import non-existant module '%s'",
1008 module
.name
.c_str(),
1013 Library::ProcessXML()
1015 if ( !module
.project
.LocateModule ( name
) )
1016 throw InvalidBuildFileException (
1018 "module '%s' is trying to link against non-existant module '%s'",
1019 module
.name
.c_str(),
1024 Invoke::Invoke ( const XMLElement
& _node
,
1025 const Module
& _module
)
1032 Invoke::ProcessXML()
1034 const XMLAttribute
* att
= node
.GetAttribute ( "module", false );
1036 invokeModule
= &module
;
1039 invokeModule
= module
.project
.LocateModule ( att
->value
);
1040 if ( invokeModule
== NULL
)
1041 throw InvalidBuildFileException (
1043 "module '%s' is trying to invoke non-existant module '%s'",
1044 module
.name
.c_str(),
1045 att
->value
.c_str() );
1048 for ( size_t i
= 0; i
< node
.subElements
.size (); i
++ )
1049 ProcessXMLSubElement ( *node
.subElements
[i
] );
1053 Invoke::ProcessXMLSubElement ( const XMLElement
& e
)
1055 bool subs_invalid
= false;
1056 if ( e
.name
== "input" )
1058 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
1059 ProcessXMLSubElementInput ( *e
.subElements
[i
] );
1061 else if ( e
.name
== "output" )
1063 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
1064 ProcessXMLSubElementOutput ( *e
.subElements
[i
] );
1066 if ( subs_invalid
&& e
.subElements
.size() > 0 )
1067 throw InvalidBuildFileException ( e
.location
,
1068 "<%s> cannot have sub-elements",
1073 Invoke::ProcessXMLSubElementInput ( const XMLElement
& e
)
1075 bool subs_invalid
= false;
1076 if ( e
.name
== "inputfile" && e
.value
.size () > 0 )
1078 input
.push_back ( new InvokeFile ( e
, FixSeparator ( module
.path
+ cSep
+ e
.value
) ) );
1079 subs_invalid
= true;
1081 if ( subs_invalid
&& e
.subElements
.size() > 0 )
1082 throw InvalidBuildFileException ( e
.location
,
1083 "<%s> cannot have sub-elements",
1088 Invoke::ProcessXMLSubElementOutput ( const XMLElement
& e
)
1090 bool subs_invalid
= false;
1091 if ( e
.name
== "outputfile" && e
.value
.size () > 0 )
1093 output
.push_back ( new InvokeFile ( e
, FixSeparator ( module
.path
+ cSep
+ e
.value
) ) );
1094 subs_invalid
= true;
1096 if ( subs_invalid
&& e
.subElements
.size() > 0 )
1097 throw InvalidBuildFileException (
1099 "<%s> cannot have sub-elements",
1104 Invoke::GetTargets ( string_list
& targets
) const
1106 for ( size_t i
= 0; i
< output
.size (); i
++ )
1108 InvokeFile
& file
= *output
[i
];
1109 targets
.push_back ( NormalizeFilename ( file
.name
) );
1114 Invoke::GetParameters () const
1116 string
parameters ( "" );
1118 for ( i
= 0; i
< output
.size (); i
++ )
1120 if ( parameters
.length () > 0)
1122 InvokeFile
& invokeFile
= *output
[i
];
1123 if ( invokeFile
.switches
.length () > 0 )
1125 parameters
+= invokeFile
.switches
+ " ";
1127 parameters
+= invokeFile
.name
;
1130 for ( i
= 0; i
< input
.size (); i
++ )
1132 if ( parameters
.length () > 0 )
1134 InvokeFile
& invokeFile
= *input
[i
];
1135 if ( invokeFile
.switches
.length () > 0 )
1137 parameters
+= invokeFile
.switches
;
1140 parameters
+= invokeFile
.name
;
1147 InvokeFile::InvokeFile ( const XMLElement
& _node
,
1148 const string
& _name
)
1152 const XMLAttribute
* att
= _node
.GetAttribute ( "switches", false );
1154 switches
= att
->value
;
1160 InvokeFile::ProcessXML()
1165 Dependency::Dependency ( const XMLElement
& _node
,
1166 const Module
& _module
)
1169 dependencyModule (NULL
)
1174 Dependency::ProcessXML()
1176 dependencyModule
= module
.project
.LocateModule ( node
.value
);
1177 if ( dependencyModule
== NULL
)
1178 throw InvalidBuildFileException ( node
.location
,
1179 "module '%s' depend on non-existant module '%s'",
1180 module
.name
.c_str(),
1181 node
.value
.c_str() );
1185 ImportLibrary::ImportLibrary ( const XMLElement
& _node
,
1186 const Module
& _module
)
1190 const XMLAttribute
* att
= _node
.GetAttribute ( "basename", false );
1192 basename
= att
->value
;
1194 basename
= module
.name
;
1196 att
= _node
.GetAttribute ( "definition", true );
1198 definition
= FixSeparator(att
->value
);
1202 If::If ( const XMLElement
& node_
,
1203 const Project
& project_
,
1204 const Module
* module_
,
1205 const bool negated_
)
1206 : node(node_
), project(project_
), module(module_
), negated(negated_
)
1208 const XMLAttribute
* att
;
1210 att
= node
.GetAttribute ( "property", true );
1212 property
= att
->value
;
1214 att
= node
.GetAttribute ( "value", true );
1229 Property::Property ( const XMLElement
& node_
,
1230 const Project
& project_
,
1231 const Module
* module_
)
1232 : node(node_
), project(project_
), module(module_
)
1234 const XMLAttribute
* att
;
1236 att
= node
.GetAttribute ( "name", true );
1240 att
= node
.GetAttribute ( "value", true );
1246 Property::ProcessXML()
1252 const XMLElement
& node_
,
1253 const Module
& module_
,
1255 : node(node_
), module(module_
), file(file_
)
1260 PchFile::ProcessXML()