/*
* Copyright (C) 2005 Casper S. Hornstrup
+ * Copyright (C) 2008 Hervé Poussineau
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
delete compilerFlags[i];
for ( i = 0; i < modules.size(); i++ )
delete modules[i];
- for ( i = 0; i < ifs.size (); i++ )
- delete ifs[i];
for ( i = 0; i < compilationUnits.size (); i++ )
delete compilationUnits[i];
}
properties[i]->ProcessXML ();
for ( i = 0; i < compilerFlags.size(); i++ )
compilerFlags[i]->ProcessXML ();
- for ( i = 0; i < ifs.size (); i++ )
- ifs[i]->ProcessXML ();
for ( i = 0; i < compilationUnits.size (); i++ )
compilationUnits[i]->ProcessXML ();
}
node (moduleNode),
importLibrary (NULL),
metadata (NULL),
+ bootSector (NULL),
bootstrap (NULL),
autoRegister(NULL),
linkerScript (NULL),
pch (NULL),
cplusplus (false),
- host (HostDefault)
+ host (HostDefault),
+ output (NULL),
+ install (NULL)
{
if ( node.name != "module" )
throw InvalidOperationException ( __FILE__,
att->value,
&moduleNode );
}
- else
+
+ att = moduleNode.GetAttribute ( "output", false );
+ if ( att != NULL )
+ {
+ if (output != NULL)
+ {
+ printf ( "%s: WARNING: 'installname' overrides 'output' also defined for this module.\n",
+ moduleNode.location.c_str() );
+ }
+ else
+ {
+ output = new FileLocation ( GetTargetDirectoryTree (),
+ modulePath,
+ att->value,
+ &moduleNode );
+ }
+ }
+
+ /* If no one has set the output file for this module set it automatically */
+ if (output == NULL)
{
- install = NULL;
output = new FileLocation ( GetTargetDirectoryTree (),
- modulePath,
- name + extension,
- &moduleNode );
+ modulePath,
+ name + extension,
+ &moduleNode );
}
att = moduleNode.GetAttribute ( "allowwarnings", false );
}
}
+ att = moduleNode.GetAttribute ( "description", false );
+ if (att != NULL )
+ {
+ description = project.ResolveProperties(att->value);
+ }
+ else
+ description = "";
+
+ att = moduleNode.GetAttribute ( "lcid", false );
+ if (type == KeyboardLayout && att != NULL )
+ lcid = att->value;
+ else
+ lcid = "";
+
+ att = moduleNode.GetAttribute ( "layoutid", false );
+ if (type == KeyboardLayout && att != NULL )
+ layoutId = att->value;
+ else
+ layoutId = "";
+
+ att = moduleNode.GetAttribute ( "layoutnameresid", false );
+ if (type == KeyboardLayout && att != NULL )
+ layoutNameResId = att->value;
+ else
+ layoutNameResId = "";
+
SetImportLibrary ( NULL );
}
delete pch;
if ( install )
delete install;
+ if ( metadata )
+ delete metadata;
+ if ( bootstrap )
+ delete bootstrap;
+ if ( importLibrary )
+ delete importLibrary;
+ if ( bootSector )
+ delete bootSector;
+ if ( dependency )
+ delete dependency;
+ if ( autoRegister )
+ delete autoRegister;
if ( output )
- delete output;
+ delete output;
}
void
const string& relative_path,
ParseContext& parseContext )
{
- If* pOldIf = parseContext.ifData;
CompilationUnit* pOldCompilationUnit = parseContext.compilationUnit;
bool subs_invalid = false;
string subpath ( relative_path );
else
{
CompilationUnit* pCompilationUnit = new CompilationUnit ( pFile );
- if ( parseContext.ifData )
- parseContext.ifData->data.compilationUnits.push_back ( pCompilationUnit );
+ string ext = ToLower ( GetExtension ( e.value ) );
+ if ( ext == ".idl" )
+ {
+ // put .idl files at the start of the module
+ non_if_data.compilationUnits.insert (
+ non_if_data.compilationUnits.begin(),
+ pCompilationUnit );
+ }
+ else if ( ext == ".asm" || ext == ".s" )
+ {
+ // put .asm files at the end of the module
+ non_if_data.compilationUnits.push_back ( pCompilationUnit );
+ non_if_data.asmFiles++;
+ }
else
{
- string ext = ToLower ( GetExtension ( e.value ) );
- if ( ext == ".idl" )
- {
- // put .idl files at the start of the module
- non_if_data.compilationUnits.insert (
- non_if_data.compilationUnits.begin(),
- pCompilationUnit );
- }
- else if ( ext == ".asm" || ext == ".s" )
- {
- // put .asm files at the end of the module
- non_if_data.compilationUnits.push_back ( pCompilationUnit );
- non_if_data.asmFiles++;
- }
- else
- {
- // put other files in the middle
- non_if_data.compilationUnits.insert (
- non_if_data.compilationUnits.end() - non_if_data.asmFiles,
- pCompilationUnit );
- }
+ // put other files in the middle
+ non_if_data.compilationUnits.insert (
+ non_if_data.compilationUnits.end() - non_if_data.asmFiles,
+ pCompilationUnit );
}
}
- if ( parseContext.ifData )
- parseContext.ifData->data.files.push_back ( pFile );
- else
- non_if_data.files.push_back ( pFile );
+ non_if_data.files.push_back ( pFile );
subs_invalid = true;
}
else if ( e.name == "library" && e.value.size () )
{
Library* pLibrary = new Library ( e, *this, e.value );
- if ( parseContext.ifData )
- parseContext.ifData->data.libraries.push_back ( pLibrary );
- else
- non_if_data.libraries.push_back ( pLibrary );
+ non_if_data.libraries.push_back ( pLibrary );
subs_invalid = true;
}
else if ( e.name == "directory" )
else if ( e.name == "include" )
{
Include* include = new Include ( project, &e, this );
- if ( parseContext.ifData )
- parseContext.ifData->data.includes.push_back ( include );
- else
- non_if_data.includes.push_back ( include );
+ non_if_data.includes.push_back ( include );
subs_invalid = true;
}
else if ( e.name == "define" )
{
Define* pDefine = new Define ( project, this, e );
- if ( parseContext.ifData )
- parseContext.ifData->data.defines.push_back ( pDefine );
- else
- non_if_data.defines.push_back ( pDefine );
+ non_if_data.defines.push_back ( pDefine );
subs_invalid = true;
}
else if ( e.name == "metadata" )
{
- if ( parseContext.ifData )
- {
- throw XMLInvalidBuildFileException (
- e.location,
- "<metadata> is not a valid sub-element of <if>" );
- }
metadata = new Metadata ( e, *this );
subs_invalid = false;
}
else if ( e.name == "invoke" )
{
- if ( parseContext.ifData )
- {
- throw XMLInvalidBuildFileException (
- e.location,
- "<invoke> is not a valid sub-element of <if>" );
- }
invocations.push_back ( new Invoke ( e, *this ) );
subs_invalid = false;
}
else if ( e.name == "dependency" )
{
- if ( parseContext.ifData )
- {
- throw XMLInvalidBuildFileException (
- e.location,
- "<dependency> is not a valid sub-element of <if>" );
- }
dependencies.push_back ( new Dependency ( e, *this ) );
subs_invalid = true;
}
+ else if ( e.name == "bootsector" )
+ {
+ bootSector = new Bootsector ( e, this );
+ subs_invalid = true;
+ }
else if ( e.name == "importlibrary" )
{
- if ( parseContext.ifData )
- {
- throw XMLInvalidBuildFileException (
- e.location,
- "<importlibrary> is not a valid sub-element of <if>" );
- }
if ( importLibrary )
{
throw XMLInvalidBuildFileException (
e.location,
"Only one <importlibrary> is valid per module" );
}
- SetImportLibrary ( new ImportLibrary ( project, e, *this ) );
+ SetImportLibrary ( new ImportLibrary ( project, e, this ) );
subs_invalid = true;
}
- else if ( e.name == "if" )
+ else if ( e.name == "if" || e.name == "ifnot" )
{
- parseContext.ifData = new If ( e, project, this );
- if ( pOldIf )
- pOldIf->data.ifs.push_back ( parseContext.ifData );
- else
- non_if_data.ifs.push_back ( parseContext.ifData );
- subs_invalid = false;
- }
- else if ( e.name == "ifnot" )
- {
- parseContext.ifData = new If ( e, project, this, true );
- if ( pOldIf )
- pOldIf->data.ifs.push_back ( parseContext.ifData );
- else
- non_if_data.ifs.push_back ( parseContext.ifData );
+ const XMLAttribute* name;
+ name = e.GetAttribute ( "property", true );
+ assert( name );
+ const Property *property = project.LookupProperty( name->value );
+ if ( !property )
+ {
+ // Property not found
+ throw InvalidOperationException ( __FILE__,
+ __LINE__,
+ "Test on unknown property '%s' at %s",
+ name->value.c_str (), e.location.c_str () );
+ }
+
+ const XMLAttribute* value;
+ value = e.GetAttribute ( "value", true );
+ assert( value );
+
+ bool negate = ( e.name == "ifnot" );
+ bool equality = ( property->value == value->value );
+ if ( equality == negate )
+ {
+ // Failed, skip this element
+ if ( project.configuration.Verbose )
+ printf("Skipping 'If' at %s\n", e.location.c_str () );
+ return;
+ }
subs_invalid = false;
}
else if ( e.name == "compilerflag" )
{
CompilerFlag* pCompilerFlag = new CompilerFlag ( project, this, e );
- if ( parseContext.ifData )
- parseContext.ifData->data.compilerFlags.push_back ( pCompilerFlag );
- else
- non_if_data.compilerFlags.push_back ( pCompilerFlag );
+ non_if_data.compilerFlags.push_back ( pCompilerFlag );
subs_invalid = true;
}
else if ( e.name == "linkerflag" )
}
else if ( e.name == "linkerscript" )
{
- if ( parseContext.ifData )
- {
- throw XMLInvalidBuildFileException (
- e.location,
- "<linkerscript> is not a valid sub-element of <if>" );
- }
if ( linkerScript )
{
throw XMLInvalidBuildFileException (
if ( pos == string::npos )
{
linkerScript = new LinkerScript (
- e, *this, FileLocation ( SourceDirectory, relative_path, e.value, &e ) );
+ e, *this, new FileLocation ( SourceDirectory, relative_path, e.value, &e ) );
}
else
{
string dir = e.value.substr ( 0, pos );
string name = e.value.substr ( pos + 1);
linkerScript = new LinkerScript (
- e, *this, FileLocation ( SourceDirectory, relative_path + sSep + dir, name, &e ) );
+ e, *this, new FileLocation ( SourceDirectory, relative_path + sSep + dir, name, &e ) );
}
subs_invalid = true;
}
}
else if ( e.name == "pch" )
{
- if ( parseContext.ifData )
- {
- throw XMLInvalidBuildFileException (
- e.location,
- "<pch> is not a valid sub-element of <if>" );
- }
if ( pch )
{
throw XMLInvalidBuildFileException (
if ( pos == string::npos )
{
pch = new PchFile (
- e, *this, FileLocation ( SourceDirectory, relative_path, e.value, &e ) );
+ e, *this, new FileLocation ( SourceDirectory, relative_path, e.value, &e ) );
}
else
{
string dir = e.value.substr ( 0, pos );
string name = e.value.substr ( pos + 1);
pch = new PchFile (
- e, *this, FileLocation ( SourceDirectory, relative_path + sSep + dir, name, &e ) );
+ e, *this, new FileLocation ( SourceDirectory, relative_path + sSep + dir, name, &e ) );
}
subs_invalid = true;
}
if ( project.configuration.CompilationUnitsEnabled )
{
CompilationUnit* pCompilationUnit = new CompilationUnit ( &project, this, &e );
- if ( parseContext.ifData )
- parseContext.ifData->data.compilationUnits.push_back ( pCompilationUnit );
- else
- non_if_data.compilationUnits.push_back ( pCompilationUnit );
+ non_if_data.compilationUnits.push_back ( pCompilationUnit );
parseContext.compilationUnit = pCompilationUnit;
}
subs_invalid = false;
}
for ( size_t i = 0; i < e.subElements.size (); i++ )
ProcessXMLSubElement ( *e.subElements[i], subdirectory, subpath, parseContext );
- parseContext.ifData = pOldIf;
parseContext.compilationUnit = pOldCompilationUnit;
}
return BuildTool;
if ( attribute.value == "staticlibrary" )
return StaticLibrary;
+ if ( attribute.value == "hoststaticlibrary" )
+ return HostStaticLibrary;
if ( attribute.value == "objectlibrary" )
return ObjectLibrary;
if ( attribute.value == "kernel" )
return NativeDLL;
if ( attribute.value == "nativecui" )
return NativeCUI;
+ if ( attribute.value == "keyboardlayout" )
+ return KeyboardLayout;
if ( attribute.value == "win32dll" )
return Win32DLL;
if ( attribute.value == "win32ocx" )
return EmbeddedTypeLib;
if ( attribute.value == "elfexecutable" )
return ElfExecutable;
+ if ( attribute.value == "cabinet" )
+ return Cabinet;
+ if ( attribute.value == "messageheader" )
+ return MessageHeader;
throw InvalidAttributeValueException ( location,
attribute.name,
attribute.value );
{
case Kernel:
case KernelModeDLL:
+ case KeyboardLayout:
case NativeDLL:
case Win32DLL:
case Win32OCX:
case LiveIso:
case IsoRegTest:
case LiveIsoRegTest:
- case EmbeddedTypeLib:
case ElfExecutable:
+ case Cabinet:
return OutputDirectory;
+ case EmbeddedTypeLib:
case StaticLibrary:
+ case HostStaticLibrary:
case ObjectLibrary:
case RpcServer:
case RpcClient:
case RpcProxy:
case Alias:
case IdlHeader:
+ case MessageHeader:
return IntermediateDirectory;
case TypeDontCare:
break;
return ExePostfix;
case BootProgram:
case StaticLibrary:
+ case HostStaticLibrary:
return ".a";
case ObjectLibrary:
return ".o";
case KernelModeDLL:
case NativeDLL:
+ case KeyboardLayout:
case Win32DLL:
return ".dll";
case Win32OCX:
case KernelModeDriver:
case BootLoader:
return ".sys";
+ case Cabinet:
+ return ".cab";
case BootSector:
return ".o";
case Iso:
case Alias:
case ElfExecutable:
case IdlHeader:
+ case MessageHeader:
return "";
case EmbeddedTypeLib:
return ".tlb";
{
case Kernel:
return "KiSystemStartup";
+ case KeyboardLayout:
case KernelModeDLL:
case KernelModeDriver:
+ if (Environment::GetArch() == "arm") return "DriverEntry";
return "DriverEntry@8";
case NativeDLL:
- return "DllMainCRTStartup@12";
+ if (Environment::GetArch() == "arm") return "DllMainCRTStartup";
+ return "DllMainCRTStartup@12";
case NativeCUI:
- return "NtProcessStartup@4";
+ if (Environment::GetArch() == "arm") return "NtProcessStartup";
+ return "NtProcessStartup@4";
case Win32DLL:
case Win32OCX:
+ if (Environment::GetArch() == "arm") return "DllMain";
return "DllMain@12";
case Win32CUI:
case Test:
return "WinMainCRTStartup";
case BuildTool:
case StaticLibrary:
+ case HostStaticLibrary:
case ObjectLibrary:
case BootLoader:
case BootSector:
case Alias:
case BootProgram:
case IdlHeader:
+ case MessageHeader:
case ElfExecutable:
case EmbeddedTypeLib:
+ case Cabinet:
return "";
case TypeDontCare:
break;
case Win32SCR:
case Win32GUI:
return "0x00400000";
+ case KeyboardLayout:
case KernelModeDLL:
case KernelModeDriver:
return "0x00010000";
return "0xe00000";
case BuildTool:
case StaticLibrary:
+ case HostStaticLibrary:
case ObjectLibrary:
case BootLoader:
case BootSector:
case Alias:
case BootProgram:
case IdlHeader:
+ case MessageHeader:
case EmbeddedTypeLib:
+ case Cabinet:
return "";
case TypeDontCare:
break;
bool
Module::HasImportLibrary () const
{
- return importLibrary != NULL && type != StaticLibrary;
+ return importLibrary != NULL && type != StaticLibrary && type != HostStaticLibrary;
}
bool
case Kernel:
case KernelModeDLL:
case NativeDLL:
+ case KeyboardLayout:
case Win32DLL:
case Win32OCX:
case KernelModeDriver:
case Win32GUI:
case BuildTool:
case StaticLibrary:
+ case HostStaticLibrary:
case ObjectLibrary:
case BootLoader:
case BootSector:
case RpcProxy:
case Alias:
case IdlHeader:
+ case MessageHeader:
case EmbeddedTypeLib:
case ElfExecutable:
+ case Cabinet:
return false;
case TypeDontCare:
break;
result = "_";
result += entrypoint;
+
+ if (Environment::GetArch() == "amd64")
+ {
+ size_t at_index = result.find_last_of( '@' );
+ if ( at_index != result.npos )
+ return result.substr (0, at_index );
+ }
+
return result;
}
if ( compilationUnit->HasFileWithExtension ( extension ) )
return true;
}
- for ( i = 0; i < data.ifs.size (); i++ )
- {
- if ( HasFileWithExtension ( data.ifs[i]->data, extension ) )
- return true;
- }
return false;
}
}
}
+Bootsector::Bootsector ( const XMLElement& _node,
+ const Module* _module )
+ : node (_node),
+ module (_module),
+ bootSectorModule (NULL)
+{
+ if ( !IsSupportedModuleType ( module->type ) )
+ {
+ throw XMLInvalidBuildFileException (
+ node.location,
+ "<bootsector> is not applicable for this module type." );
+ }
+
+ bootSectorModule = module->project.LocateModule ( node.value );
+ if ( bootSectorModule == NULL )
+ {
+ throw XMLInvalidBuildFileException (
+ node.location,
+ "module '%s' depend on non-existant module '%s'",
+ module->name.c_str(),
+ node.value.c_str() );
+ }
+
+ if (bootSectorModule->type != BootSector)
+ {
+ throw XMLInvalidBuildFileException (
+ node.location,
+ "module '%s' is referencing non BootSector module '%s'",
+ module->name.c_str(),
+ node.value.c_str() );
+ }
+}
+
+void
+Bootsector::ProcessXML()
+{
+}
+
+bool
+Bootsector::IsSupportedModuleType ( ModuleType type )
+{
+ if ( type == Iso ||
+ type == LiveIso ||
+ type == IsoRegTest ||
+ type == LiveIsoRegTest )
+ {
+ return true;
+ }
+
+ return false;
+}
Metadata::Metadata ( const XMLElement& _node,
const Module& _module )
}
+ImportLibrary::~ImportLibrary ()
+{
+ delete source;
+}
+
+
ImportLibrary::ImportLibrary ( const Project& project,
const XMLElement& node,
- const Module& module )
+ const Module* module )
: XmlNode ( project, node ),
module (module)
{
+ DirectoryLocation directory = SourceDirectory;
+ const Module* base = module;
const XMLAttribute* dllname = node.GetAttribute ( "dllname", false );
const XMLAttribute* definition = node.GetAttribute ( "definition", true );
assert ( definition );
+ string relative_path;
+ const XMLAttribute* att = node.GetAttribute ( "base", false );
+ if ( att )
+ {
+ base = project.LocateModule ( att->value );
+ if ( !base )
+ throw XMLInvalidBuildFileException (
+ node.location,
+ "<importlibrary> attribute 'base' references non-existant module '%s'",
+ att->value.c_str() );
+
+ }
+
+ if ( base )
+ {
+ relative_path = base->output->relative_path;
+ if ( node.value.length () > 0 && node.value != "." )
+ relative_path += sSep + node.value;
+ }
+ else
+ relative_path = node.value;
+
+ att = node.GetAttribute ( "root", false );
+ if ( att )
+ {
+ if ( att->value == "intermediate" )
+ directory = IntermediateDirectory;
+ else
+ throw InvalidAttributeValueException ( node.location,
+ "root",
+ att->value );
+ }
+ else
+ {
+ size_t index = definition->value.rfind ( ".spec.def" );
+ if ( index != string::npos )
+ directory = IntermediateDirectory;
+ }
+
if ( dllname )
this->dllname = dllname->value;
- else if ( module.type == StaticLibrary )
+ else if ( module->type == StaticLibrary || module->type == HostStaticLibrary )
throw XMLInvalidBuildFileException (
node.location,
"<importlibrary> dllname attribute required." );
- DirectoryLocation directory = SourceDirectory;
- size_t index = definition->value.rfind ( ".spec.def" );
- if ( index != string::npos )
- directory = IntermediateDirectory;
-
- index = definition->value.find_last_of ( "/\\" );
+ size_t index = definition->value.find_last_of ( "/\\" );
if ( index == string::npos )
{
source = new FileLocation ( directory,
- module.output->relative_path,
+ base->output->relative_path,
definition->value,
&node );
}
string dir = definition->value.substr ( 0, index );
string name = definition->value.substr ( index + 1);
source = new FileLocation ( directory,
- NormalizeFilename ( module.output->relative_path + sSep + dir ),
+ NormalizeFilename ( base->output->relative_path + sSep + dir ),
name,
&node );
}
}
-If::If ( const XMLElement& node_,
- const Project& project_,
- const Module* module_,
- const bool negated_ )
- : node(node_), project(project_), module(module_), negated(negated_)
-{
- const XMLAttribute* att;
-
- att = node.GetAttribute ( "property", true );
- assert(att);
- property = att->value;
-
- att = node.GetAttribute ( "value", true );
- assert(att);
- value = att->value;
-}
-
-If::~If ()
-{
-}
-
-void
-If::ProcessXML()
-{
-
-}
-
-
Property::Property ( const XMLElement& node_,
const Project& project_,
const Module* module_ )
att = node_.GetAttribute ( "value", true );
assert(att);
value = att->value;
+
+ att = node_.GetAttribute ( "internal", false );
+ if ( att != NULL )
+ {
+ const char* p = att->value.c_str();
+ if ( !stricmp ( p, "true" ) || !stricmp ( p, "yes" ) )
+ isInternal = true;
+ else if ( !stricmp ( p, "false" ) || !stricmp ( p, "no" ) )
+ isInternal = false;
+ else
+ {
+ throw InvalidAttributeValueException (
+ node_.location,
+ "internal",
+ att->value );
+ }
+ }
+ else
+ isInternal = false;
}
Property::Property ( const Project& project_,
PchFile::PchFile (
const XMLElement& node_,
const Module& module_,
- const FileLocation& file_ )
+ const FileLocation *file_ )
: node(node_), module(module_), file(file_)
{
}
+PchFile::~PchFile()
+{
+ delete file;
+}
+
void
PchFile::ProcessXML()
{