-// module.cpp\r
-\r
#include "pch.h"\r
#include <assert.h>\r
\r
return s2;\r
}\r
\r
+string\r
+GetExtension ( const string& filename )\r
+{\r
+ size_t index = filename.find_last_of ( '/' );\r
+ if (index == string::npos) index = 0;\r
+ string tmp = filename.substr( index, filename.size() - index );\r
+ size_t ext_index = tmp.find_last_of( '.' );\r
+ if (ext_index != string::npos) \r
+ return filename.substr ( index + ext_index, filename.size() );\r
+ 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
+ Path path;\r
+ string normalizedPath = path.Fixup ( filename, true );\r
+ string relativeNormalizedPath = path.RelativeFromWorkingDirectory ( normalizedPath );\r
+ return FixSeparator ( relativeNormalizedPath );\r
+}\r
+\r
Module::Module ( const Project& project,\r
const XMLElement& moduleNode,\r
const string& modulePath )\r
type = GetModuleType ( node.location, *att );\r
\r
att = moduleNode.GetAttribute ( "extension", false );\r
- if (att != NULL)\r
+ if ( att != NULL )\r
extension = att->value;\r
else\r
extension = GetDefaultModuleExtension ();\r
+\r
+ att = moduleNode.GetAttribute ( "entrypoint", false );\r
+ if ( att != NULL )\r
+ entrypoint = att->value;\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
+ else\r
+ mangledSymbols = false;\r
}\r
\r
Module::~Module ()\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
}\r
\r
void\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
}\r
\r
void\r
string subpath ( path );\r
if ( e.name == "file" && e.value.size () > 0 )\r
{\r
- File* pFile = new File ( FixSeparator ( path + CSEP + e.value ) );\r
+ bool first = false;\r
+ const XMLAttribute* att = e.GetAttribute ( "first", false );\r
+ if ( att )\r
+ {\r
+ if ( !stricmp ( att->value.c_str(), "true" ) )\r
+ first = true;\r
+ else if ( stricmp ( att->value.c_str(), "false" ) )\r
+ throw InvalidBuildFileException (\r
+ e.location,\r
+ "attribute 'first' of <file> element can only be 'true' or 'false'" );\r
+ }\r
+ File* pFile = new File ( FixSeparator ( path + CSEP + e.value ), first );\r
if ( pIf )\r
pIf->files.push_back ( pFile );\r
else\r
}\r
else if ( e.name == "include" )\r
{\r
+ Include* include = new Include ( project, this, e );\r
if ( pIf )\r
- throw InvalidBuildFileException (\r
- e.location,\r
- "<include> is not a valid sub-element of <if>" );\r
- includes.push_back ( new Include ( project, this, e ) );\r
+ pIf->includes.push_back ( include );\r
+ else\r
+ includes.push_back ( include );\r
subs_invalid = true;\r
}\r
else if ( e.name == "define" )\r
}\r
else if ( e.name == "if" )\r
{\r
- pIf = new If ( e, *this );\r
- ifs.push_back ( pIf );\r
+ If* pOldIf = pIf;\r
+ pIf = new If ( e, project, this );\r
+ if ( pOldIf )\r
+ pOldIf->ifs.push_back ( pIf );\r
+ else\r
+ ifs.push_back ( pIf );\r
subs_invalid = false;\r
}\r
+ else if ( e.name == "compilerflag" )\r
+ {\r
+ compilerFlags.push_back ( new CompilerFlag ( project, this, e ) );\r
+ subs_invalid = true;\r
+ }\r
+ else if ( e.name == "linkerflag" )\r
+ {\r
+ linkerFlags.push_back ( new LinkerFlag ( project, this, e ) );\r
+ subs_invalid = true;\r
+ }\r
+ else if ( e.name == "property" )\r
+ {\r
+ throw InvalidBuildFileException (\r
+ e.location,\r
+ "<property> is not a valid sub-element of <module>" );\r
+ }\r
if ( subs_invalid && e.subElements.size() > 0 )\r
throw InvalidBuildFileException (\r
e.location,\r
return BuildTool;\r
if ( attribute.value == "staticlibrary" )\r
return StaticLibrary;\r
+ if ( attribute.value == "objectlibrary" )\r
+ return ObjectLibrary;\r
if ( attribute.value == "kernel" )\r
return Kernel;\r
if ( attribute.value == "kernelmodedll" )\r
return KernelModeDLL;\r
+ if ( attribute.value == "kernelmodedriver" )\r
+ return KernelModeDriver;\r
if ( attribute.value == "nativedll" )\r
return NativeDLL;\r
+ if ( attribute.value == "nativecui" )\r
+ return NativeCUI;\r
+ if ( attribute.value == "win32dll" )\r
+ return Win32DLL;\r
+ if ( attribute.value == "win32cui" )\r
+ return Win32CUI;\r
+ if ( attribute.value == "win32gui" )\r
+ return Win32GUI;\r
+ if ( attribute.value == "bootloader" )\r
+ return BootLoader;\r
+ if ( attribute.value == "bootsector" )\r
+ return BootSector;\r
+ if ( attribute.value == "iso" )\r
+ return Iso;\r
throw InvalidAttributeValueException ( location,\r
attribute.name,\r
attribute.value );\r
return EXEPOSTFIX;\r
case StaticLibrary:\r
return ".a";\r
+ case ObjectLibrary:\r
+ return ".o";\r
case Kernel:\r
+ case NativeCUI:\r
+ case Win32CUI:\r
+ case Win32GUI:\r
return ".exe";\r
case KernelModeDLL:\r
- return ".dll";\r
case NativeDLL:\r
+ case Win32DLL:\r
return ".dll";\r
+ case KernelModeDriver:\r
+ case BootLoader:\r
+ return ".sys";\r
+ case BootSector:\r
+ return ".o";\r
+ case Iso:\r
+ return ".iso";\r
+ }\r
+ throw InvalidOperationException ( __FILE__,\r
+ __LINE__ );\r
+}\r
+\r
+string\r
+Module::GetDefaultModuleEntrypoint () const\r
+{\r
+ switch (type)\r
+ {\r
+ case Kernel:\r
+ return "_NtProcessStartup";\r
+ case KernelModeDLL:\r
+ return "_DriverEntry@8";\r
+ case NativeDLL:\r
+ return "_DllMainCRTStartup@12";\r
+ case NativeCUI:\r
+ return "_NtProcessStartup@4";\r
+ case Win32DLL:\r
+ return "_DllMain@12";\r
+ case Win32CUI:\r
+ return "_mainCRTStartup";\r
+ case Win32GUI:\r
+ return "_WinMainCRTStartup";\r
+ case KernelModeDriver:\r
+ return "_DriverEntry@8";\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
+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
+ throw InvalidOperationException ( __FILE__,\r
+ __LINE__ );\r
+}\r
+\r
+bool\r
+Module::HasImportLibrary () const\r
+{\r
+ return importLibrary != NULL;\r
}\r
\r
string\r
string\r
Module::GetDependencyPath () const\r
{\r
- switch ( type )\r
+ if ( HasImportLibrary () )\r
{\r
- case KernelModeDLL:\r
return ssprintf ( "dk%snkm%slib%slib%s.a",\r
SSEP,\r
SSEP,\r
SSEP,\r
name.c_str () );\r
- case NativeDLL:\r
- return ssprintf ( "dk%sw32%slib%slib%s.a",\r
- SSEP,\r
- SSEP,\r
- SSEP,\r
- name.c_str () );\r
- default:\r
- return GetPath();\r
}\r
+ else\r
+ return GetPath();\r
}\r
\r
string\r
index );\r
}\r
\r
+bool\r
+Module::HasFileWithExtensions ( const std::string& extension1,\r
+ const std::string& extension2 ) const\r
+{\r
+ for ( size_t i = 0; i < files.size (); i++ )\r
+ {\r
+ File& file = *files[i];\r
+ string extension = GetExtension ( file.name );\r
+ if ( extension == extension1 || extension == extension2 )\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
-File::File ( const string& _name )\r
- : name(_name)\r
+\r
+File::File ( const string& _name, bool _first )\r
+ : name(_name), first(_first)\r
{\r
}\r
\r
InvokeFile& file = *output[i];\r
if ( targets.length () > 0 )\r
targets += " ";\r
- targets += file.name;\r
+ targets += NormalizeFilename ( file.name );\r
}\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
\r
\r
-If::If ( const XMLElement& node_, const Module& module_ )\r
- : node(node_), module(module_)\r
+If::If ( const XMLElement& node_,\r
+ const Project& project_,\r
+ const Module* module_ )\r
+ : node(node_), project(project_), module(module_)\r
{\r
const XMLAttribute* att;\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
If::ProcessXML()\r
{\r
}\r
+\r
+\r
+Property::Property ( const XMLElement& node_,\r
+ const Project& project_,\r
+ const Module* module_ )\r
+ : node(node_), project(project_), module(module_)\r
+{\r
+ const XMLAttribute* att;\r
+\r
+ att = node.GetAttribute ( "name", true );\r
+ assert(att);\r
+ name = att->value;\r
+\r
+ att = node.GetAttribute ( "value", true );\r
+ assert(att);\r
+ value = att->value;\r
+}\r
+\r
+void\r
+Property::ProcessXML()\r
+{\r
+}\r