return "";\r
}\r
\r
+string\r
+GetDirectory ( const string& filename )\r
+{\r
+ size_t index = filename.find_last_of ( CSEP );\r
+ if ( index == string::npos )\r
+ return filename;\r
+ else\r
+ return filename.substr ( 0, index );\r
+}\r
+\r
string\r
NormalizeFilename ( const string& filename )\r
{\r
return FixSeparator ( relativeNormalizedPath );\r
}\r
\r
+IfableData::~IfableData()\r
+{\r
+ size_t i;\r
+ for ( i = 0; i < files.size(); i++ )\r
+ delete files[i];\r
+ for ( i = 0; i < includes.size(); i++ )\r
+ delete includes[i];\r
+ for ( i = 0; i < defines.size(); i++ )\r
+ delete defines[i];\r
+ for ( i = 0; i < libraries.size(); i++ )\r
+ delete libraries[i];\r
+ for ( i = 0; i < properties.size(); i++ )\r
+ delete properties[i];\r
+ for ( i = 0; i < ifs.size(); i++ )\r
+ delete ifs[i];\r
+}\r
+\r
+void IfableData::ProcessXML ()\r
+{\r
+ size_t i;\r
+ for ( i = 0; i < files.size (); i++ )\r
+ files[i]->ProcessXML ();\r
+ for ( i = 0; i < includes.size (); i++ )\r
+ includes[i]->ProcessXML ();\r
+ for ( i = 0; i < defines.size (); i++ )\r
+ defines[i]->ProcessXML ();\r
+ for ( i = 0; i < libraries.size (); i++ )\r
+ libraries[i]->ProcessXML ();\r
+ for ( i = 0; i < properties.size(); i++ )\r
+ properties[i]->ProcessXML ();\r
+ for ( i = 0; i < ifs.size (); i++ )\r
+ ifs[i]->ProcessXML ();\r
+}\r
+\r
Module::Module ( const Project& project,\r
const XMLElement& moduleNode,\r
const string& modulePath )\r
: project (project),\r
node (moduleNode),\r
- importLibrary (NULL)\r
+ importLibrary (NULL),\r
+ bootstrap (NULL),\r
+ pch (NULL),\r
+ cplusplus (false)\r
{\r
if ( node.name != "module" )\r
throw Exception ( "internal tool error: Module created with non-<module> node" );\r
else\r
entrypoint = GetDefaultModuleEntrypoint ();\r
\r
+ att = moduleNode.GetAttribute ( "baseaddress", false );\r
+ if ( att != NULL )\r
+ baseaddress = att->value;\r
+ else\r
+ baseaddress = GetDefaultModuleBaseaddress ();\r
+\r
att = moduleNode.GetAttribute ( "mangledsymbols", false );\r
if ( att != NULL )\r
mangledSymbols = att->value != "false";\r
Module::~Module ()\r
{\r
size_t i;\r
- for ( i = 0; i < files.size(); i++ )\r
- delete files[i];\r
- for ( i = 0; i < libraries.size(); i++ )\r
- delete libraries[i];\r
- for ( i = 0; i < includes.size(); i++ )\r
- delete includes[i];\r
- for ( i = 0; i < defines.size(); i++ )\r
- delete defines[i];\r
for ( i = 0; i < invocations.size(); i++ )\r
delete invocations[i];\r
for ( i = 0; i < dependencies.size(); i++ )\r
delete dependencies[i];\r
- for ( i = 0; i < ifs.size(); i++ )\r
- delete ifs[i];\r
for ( i = 0; i < compilerFlags.size(); i++ )\r
delete compilerFlags[i];\r
for ( i = 0; i < linkerFlags.size(); i++ )\r
delete linkerFlags[i];\r
+ if ( pch )\r
+ delete pch;\r
}\r
\r
void\r
size_t i;\r
for ( i = 0; i < node.subElements.size(); i++ )\r
ProcessXMLSubElement ( *node.subElements[i], path );\r
- for ( i = 0; i < files.size (); i++ )\r
- files[i]->ProcessXML ();\r
- for ( i = 0; i < libraries.size(); i++ )\r
- libraries[i]->ProcessXML ();\r
- for ( i = 0; i < includes.size(); i++ )\r
- includes[i]->ProcessXML ();\r
- for ( i = 0; i < defines.size(); i++ )\r
- defines[i]->ProcessXML ();\r
for ( i = 0; i < invocations.size(); i++ )\r
invocations[i]->ProcessXML ();\r
for ( i = 0; i < dependencies.size(); i++ )\r
dependencies[i]->ProcessXML ();\r
- for ( i = 0; i < ifs.size(); i++ )\r
- ifs[i]->ProcessXML();\r
for ( i = 0; i < compilerFlags.size(); i++ )\r
compilerFlags[i]->ProcessXML();\r
for ( i = 0; i < linkerFlags.size(); i++ )\r
linkerFlags[i]->ProcessXML();\r
+ non_if_data.ProcessXML();\r
+ if ( pch )\r
+ pch->ProcessXML();\r
}\r
\r
void\r
e.location,\r
"attribute 'first' of <file> element can only be 'true' or 'false'" );\r
}\r
+ if ( !cplusplus )\r
+ {\r
+ // check for c++ file\r
+ string ext = GetExtension ( e.value );\r
+ if ( !stricmp ( ext.c_str(), ".cpp" ) )\r
+ cplusplus = true;\r
+ else if ( !stricmp ( ext.c_str(), ".cc" ) )\r
+ cplusplus = true;\r
+ else if ( !stricmp ( ext.c_str(), ".cxx" ) )\r
+ cplusplus = true;\r
+ }\r
File* pFile = new File ( FixSeparator ( path + CSEP + e.value ), first );\r
if ( pIf )\r
- pIf->files.push_back ( pFile );\r
+ pIf->data.files.push_back ( pFile );\r
else\r
- files.push_back ( pFile );\r
+ non_if_data.files.push_back ( pFile );\r
subs_invalid = true;\r
}\r
else if ( e.name == "library" && e.value.size () )\r
{\r
+ Library* pLibrary = new Library ( e, *this, e.value );\r
if ( pIf )\r
- throw InvalidBuildFileException (\r
- e.location,\r
- "<library> is not a valid sub-element of <if>" );\r
- libraries.push_back ( new Library ( e, *this, e.value ) );\r
+ pIf->data.libraries.push_back ( pLibrary );\r
+ else\r
+ non_if_data.libraries.push_back ( pLibrary );\r
subs_invalid = true;\r
}\r
else if ( e.name == "directory" )\r
{\r
Include* include = new Include ( project, this, e );\r
if ( pIf )\r
- pIf->includes.push_back ( include );\r
+ pIf->data.includes.push_back ( include );\r
else\r
- includes.push_back ( include );\r
+ non_if_data.includes.push_back ( include );\r
subs_invalid = true;\r
}\r
else if ( e.name == "define" )\r
{\r
Define* pDefine = new Define ( project, this, e );\r
if ( pIf )\r
- pIf->defines.push_back ( pDefine );\r
+ pIf->data.defines.push_back ( pDefine );\r
else\r
- defines.push_back ( pDefine );\r
+ non_if_data.defines.push_back ( pDefine );\r
subs_invalid = true;\r
}\r
else if ( e.name == "invoke" )\r
If* pOldIf = pIf;\r
pIf = new If ( e, project, this );\r
if ( pOldIf )\r
- pOldIf->ifs.push_back ( pIf );\r
+ pOldIf->data.ifs.push_back ( pIf );\r
else\r
- ifs.push_back ( pIf );\r
+ non_if_data.ifs.push_back ( pIf );\r
subs_invalid = false;\r
}\r
else if ( e.name == "compilerflag" )\r
e.location,\r
"<property> is not a valid sub-element of <module>" );\r
}\r
+ else if ( e.name == "bootstrap" )\r
+ {\r
+ bootstrap = new Bootstrap ( project, this, e );\r
+ subs_invalid = true;\r
+ }\r
+ else if ( e.name == "pch" )\r
+ {\r
+ if ( pIf )\r
+ throw InvalidBuildFileException (\r
+ e.location,\r
+ "<pch> is not a valid sub-element of <if>" );\r
+ if ( pch )\r
+ throw InvalidBuildFileException (\r
+ e.location,\r
+ "Only one <pch> is valid per module" );\r
+ pch = new PchFile (\r
+ e, *this, FixSeparator ( path + CSEP + e.value ) );\r
+ subs_invalid = true;\r
+ }\r
if ( subs_invalid && e.subElements.size() > 0 )\r
throw InvalidBuildFileException (\r
e.location,\r
__LINE__ );\r
}\r
\r
+string\r
+Module::GetDefaultModuleBaseaddress () const\r
+{\r
+ switch (type)\r
+ {\r
+ case Kernel:\r
+ return "0xc0000000";\r
+ case KernelModeDLL:\r
+ return "0x10000";\r
+ case NativeDLL:\r
+ return "0x10000";\r
+ case NativeCUI:\r
+ return "0x10000";\r
+ case Win32DLL:\r
+ return "0x10000";\r
+ case Win32CUI:\r
+ return "0x00400000";\r
+ case Win32GUI:\r
+ return "0x00400000";\r
+ case KernelModeDriver:\r
+ return "0x10000";\r
+ case BuildTool:\r
+ case StaticLibrary:\r
+ case ObjectLibrary:\r
+ case BootLoader:\r
+ case BootSector:\r
+ case Iso:\r
+ return "";\r
+ }\r
+ throw InvalidOperationException ( __FILE__,\r
+ __LINE__ );\r
+}\r
+\r
bool\r
Module::HasImportLibrary () const\r
{\r
}\r
\r
bool\r
-Module::HasFileWithExtensions ( const std::string& extension1,\r
- const std::string& extension2 ) const\r
+Module::HasFileWithExtension (\r
+ const IfableData& data,\r
+ const std::string& extension ) const\r
{\r
- for ( size_t i = 0; i < files.size (); i++ )\r
+ size_t i;\r
+ for ( i = 0; i < data.files.size (); i++ )\r
+ {\r
+ File& file = *data.files[i];\r
+ string file_ext = GetExtension ( file.name );\r
+ if ( !stricmp ( file_ext.c_str (), extension.c_str () ) )\r
+ return true;\r
+ }\r
+ for ( i = 0; i < data.ifs.size (); i++ )\r
{\r
- File& file = *files[i];\r
- string extension = GetExtension ( file.name );\r
- if ( extension == extension1 || extension == extension2 )\r
+ if ( HasFileWithExtension ( data.ifs[i]->data, extension ) )\r
return true;\r
}\r
return false;\r
}\r
\r
+void\r
+Module::InvokeModule () const\r
+{\r
+ for ( size_t i = 0; i < invocations.size (); i++ )\r
+ {\r
+ Invoke& invoke = *invocations[i];\r
+ string command = invoke.invokeModule->GetPath () + " " + invoke.GetParameters ();\r
+ printf ( "Executing '%s'\n\n", command.c_str () );\r
+ int exitcode = system ( command.c_str () );\r
+ if ( exitcode != 0 )\r
+ throw InvocationFailedException ( command,\r
+ exitcode );\r
+ }\r
+}\r
+\r
\r
File::File ( const string& _name, bool _first )\r
: name(_name), first(_first)\r
const string& _name )\r
: node(_node),\r
module(_module),\r
- name(_name)\r
+ name(_name),\r
+ imported_module(_module.project.LocateModule(_name))\r
{\r
if ( module.name == name )\r
throw InvalidBuildFileException (\r
node.location,\r
"module '%s' cannot link against itself",\r
name.c_str() );\r
+ if ( !imported_module )\r
+ throw InvalidBuildFileException (\r
+ node.location,\r
+ "module '%s' trying to import non-existant module '%s'",\r
+ module.name.c_str(),\r
+ name.c_str() );\r
}\r
\r
void\r
return targets;\r
}\r
\r
+string\r
+Invoke::GetParameters () const\r
+{\r
+ string parameters ( "" );\r
+ size_t i;\r
+ for ( i = 0; i < output.size (); i++ )\r
+ {\r
+ if ( parameters.length () > 0)\r
+ parameters += " ";\r
+ InvokeFile& invokeFile = *output[i];\r
+ if ( invokeFile.switches.length () > 0 )\r
+ {\r
+ parameters += invokeFile.switches;\r
+ parameters += " ";\r
+ }\r
+ parameters += invokeFile.name;\r
+ }\r
+\r
+ for ( i = 0; i < input.size (); i++ )\r
+ {\r
+ if ( parameters.length () > 0 )\r
+ parameters += " ";\r
+ InvokeFile& invokeFile = *input[i];\r
+ if ( invokeFile.switches.length () > 0 )\r
+ {\r
+ parameters += invokeFile.switches;\r
+ parameters += " ";\r
+ }\r
+ parameters += invokeFile.name ;\r
+ }\r
+\r
+ return parameters;\r
+}\r
+\r
\r
InvokeFile::InvokeFile ( const XMLElement& _node,\r
const string& _name )\r
\r
If::~If ()\r
{\r
- size_t i;\r
- for ( i = 0; i < files.size(); i++ )\r
- delete files[i];\r
- for ( i = 0; i < includes.size(); i++ )\r
- delete includes[i];\r
- for ( i = 0; i < defines.size(); i++ )\r
- delete defines[i];\r
- for ( i = 0; i < ifs.size(); i++ )\r
- delete ifs[i];\r
}\r
\r
void\r
Property::ProcessXML()\r
{\r
}\r
+\r
+\r
+PchFile::PchFile (\r
+ const XMLElement& node_,\r
+ const Module& module_,\r
+ const string& header_ )\r
+ : node(node_), module(module_), header(header_)\r
+{\r
+}\r
+\r
+void\r
+PchFile::ProcessXML()\r
+{\r
+}\r