Generate MinGW makefile in the backend.

svn path=/branches/xmlbuildsystem/; revision=12837
This commit is contained in:
Casper Hornstrup 2005-01-05 20:59:10 +00:00
parent 222bde955c
commit 1568981925
12 changed files with 127 additions and 75 deletions

View file

@ -7,6 +7,7 @@
#include <assert.h>
#include "XML.h"
#include "rbuild.h"
using std::string;
using std::vector;
@ -397,8 +398,8 @@ XMLElement::GetAttribute ( const string& attribute,
}
if ( required )
{
printf ( "syntax error: attribute '%s' required for <%s>\n",
attribute.c_str(), name.c_str() );
throw RequiredAttributeNotFoundException ( attribute,
name );
}
return NULL;
}
@ -416,8 +417,8 @@ XMLElement::GetAttribute ( const string& attribute,
}
if ( required )
{
printf ( "syntax error: attribute '%s' required for <%s>\n",
attribute.c_str(), name.c_str() );
throw RequiredAttributeNotFoundException ( attribute,
name );
}
return NULL;
}
@ -462,7 +463,7 @@ XMLParse(XMLFile& f,
e->attributes.push_back ( new XMLAttribute ( "top_href", top_file ) );
XMLFile fInc;
if ( !fInc.open ( file ) )
printf ( "xi:include error, couldn't find file '%s'\n", file.c_str() );
throw FileNotFoundException ( file );
else
{
Path path2 ( path, att->value );

View file

@ -6,6 +6,36 @@
using std::string;
using std::vector;
#ifdef WIN32
#define EXEPOSTFIX ".exe"
#define SEP "\\"
string FixSep ( const string& s )
{
string s2(s);
char* p = strchr ( &s2[0], '/' );
while ( p )
{
*p++ = '\\';
p = strchr ( p, '/' );
}
return s2;
}
#else
#define EXEPOSTFIX
#define SEP "/"
string FixSep ( const string& s )
{
string s2(s);
char* p = strchr ( &s2[0], '\\' );
while ( p )
{
*p++ = '/';
p = strchr ( p, '\\' );
}
return s2;
}
#endif
MingwBackend::MingwBackend ( Project& project )
: Backend ( project )
{
@ -13,18 +43,54 @@ MingwBackend::MingwBackend ( Project& project )
void MingwBackend::Process ()
{
CreateMakefile ();
GenerateHeader ();
GenerateAllTarget ();
for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )
{
Module& module = *ProjectNode.modules[i];
ProcessModule ( module );
}
CloseMakefile ();
}
void MingwBackend::CreateMakefile ()
{
fMakefile = fopen ( ProjectNode.makefile.c_str (), "w" );
if ( !fMakefile )
throw AccessDeniedException ( ProjectNode.makefile );
}
void MingwBackend::CloseMakefile ()
{
if (fMakefile)
fclose ( fMakefile );
}
void MingwBackend::GenerateHeader ()
{
fprintf ( fMakefile, "# THIS FILE IS AUTOMATICALLY GENERATED, EDIT 'ReactOS.xml' INSTEAD\n\n" );
}
void MingwBackend::GenerateAllTarget ()
{
fprintf ( fMakefile, "all: " );
for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )
{
Module& module = *ProjectNode.modules[i];
fprintf ( fMakefile,
" %s" SEP "%s" EXEPOSTFIX,
FixSep(module.path).c_str (),
module.name.c_str () );
}
fprintf ( fMakefile, "\n\n" );
}
void MingwBackend::ProcessModule ( Module& module )
{
MingwModuleHandlerList moduleHandlers;
GetModuleHandlers ( moduleHandlers );
for (size_t i = 0; i < moduleHandlers.size(); i++)
for (size_t i = 0; i < moduleHandlers.size (); i++)
{
MingwModuleHandler& moduleHandler = *moduleHandlers[i];
if (moduleHandler.CanHandleModule ( module ) )

View file

@ -25,6 +25,11 @@ public:
private:
void ProcessModule ( Module& module );
void GetModuleHandlers ( MingwModuleHandlerList& moduleHandlers );
void CreateMakefile ();
void CloseMakefile ();
void GenerateHeader ();
void GenerateAllTarget ();
FILE* fMakefile;
};
#endif /* MINGW_H */

View file

@ -40,6 +40,13 @@ FileNotFoundException::FileNotFoundException(const string& filename)
}
AccessDeniedException::AccessDeniedException(const string& filename)
: Exception ( "Access denied to file '%s'.", filename.c_str() )
{
Filename = filename;
}
InvalidBuildFileException::InvalidBuildFileException(const char* message,
...)
{
@ -48,3 +55,13 @@ InvalidBuildFileException::InvalidBuildFileException(const char* message,
SetMessage(message, args);
va_end(args);
}
RequiredAttributeNotFoundException::RequiredAttributeNotFoundException(const std::string& attributeName,
const std::string& elementName)
: InvalidBuildFileException ( "Required attribute '%s' not found on '%s'.",
attributeName.c_str (),
elementName.c_str ())
{
}

View file

@ -25,6 +25,14 @@ public:
};
class AccessDeniedException : public Exception
{
public:
AccessDeniedException(const std::string& filename);
std::string Filename;
};
class InvalidBuildFileException : public Exception
{
public:
@ -32,4 +40,12 @@ public:
...);
};
class RequiredAttributeNotFoundException : public InvalidBuildFileException
{
public:
RequiredAttributeNotFoundException(const std::string& attributeName,
const std::string& elementName);
};
#endif /* __EXCEPTION_H */

View file

@ -6,36 +6,6 @@
using std::string;
using std::vector;
#ifdef WIN32
#define EXEPOSTFIX ".exe"
#define SEP "\\"
string FixSep ( const string& s )
{
string s2(s);
char* p = strchr ( &s2[0], '/' );
while ( p )
{
*p++ = '\\';
p = strchr ( p, '/' );
}
return s2;
}
#else
#define EXEPOSTFIX
#define SEP "/"
string FixSep ( const string& s )
{
string s2(s);
char* p = strchr ( &s2[0], '\\' );
while ( p )
{
*p++ = '/';
p = strchr ( p, '\\' );
}
return s2;
}
#endif
Project::Project()
{
}
@ -83,6 +53,9 @@ Project::ProcessXML ( const XMLElement& e, const string& path )
name = "Unnamed";
else
name = att->value;
att = e.GetAttribute ( "makefile", true );
makefile = att->value;
}
else if ( e.name == "module" )
{
@ -105,32 +78,3 @@ Project::ProcessXML ( const XMLElement& e, const string& path )
for ( size_t i = 0; i < e.subElements.size (); i++ )
ProcessXML ( *e.subElements[i], subpath );
}
bool
Project::GenerateOutput()
{
const XMLAttribute* att;
size_t i;
att = head->GetAttribute ( "makefile", true );
if ( !att )
return false;
FILE* f = fopen ( att->value.c_str(), "w" );
if ( !f )
{
throw Exception ( "Unable to open '%s' for output", att->value.c_str() );
return false;
}
fprintf ( f, "# THIS FILE IS AUTOMATICALLY GENERATED, EDIT 'ReactOS.xml' INSTEAD\n\n" );
// generate module list:
fprintf ( f, "all: " );
for ( i = 0; i < modules.size(); i++ )
{
Module& m = *modules[i];
fprintf ( f, " %s" SEP "%s" EXEPOSTFIX, FixSep(m.path).c_str(), m.name.c_str() );
}
fprintf ( f, "\n\n" );
return true;
}

View file

@ -20,9 +20,10 @@ main ( int argc, char** argv )
try
{
string projectFilename ( "ReactOS.xml" );
Project project = Project ( projectFilename );
Project project ( projectFilename );
Backend* backend = new MingwBackend ( project );
backend->Process ();
delete backend;
// REM TODO FIXME actually do something with Project object...
#if 0

View file

@ -15,6 +15,7 @@ class Project
{
public:
std::string name;
std::string makefile;
std::vector<Module*> modules;
Project ();
@ -22,13 +23,13 @@ public:
~Project ();
void ProcessXML ( const XMLElement& e,
const std::string& path );
bool GenerateOutput();
private:
void ReadXml ();
XMLFile xmlfile;
XMLElement* head;
};
class Module
{
public:
@ -46,6 +47,7 @@ public:
void ProcessXML ( const XMLElement& e, const std::string& path );
};
class File
{
public:

View file

@ -1,4 +1,4 @@
<project name="Project">
<project name="Project" makefile="Makefile">
<directory name="dir1">
<module name="module1" type="buildtool">
<file>file1.c</file>

View file

@ -1,4 +1,4 @@
<project name="Project">
<project name="Project" makefile="Makefile">
<directory name="dir1">
<module name="module1" type="buildtool">
</module>

View file

@ -5,15 +5,15 @@ using std::string;
void ModuleTest::Run()
{
string projectFilename ( "tests/data/module.xml" );
Project* project = new Project( projectFilename );
ARE_EQUAL(2, project->modules.size());
Project project ( projectFilename );
ARE_EQUAL(2, project.modules.size());
Module& module1 = *project->modules[0];
Module& module1 = *project.modules[0];
ARE_EQUAL(2, module1.files.size());
ARE_EQUAL("./dir1/file1.c", module1.files[0]->name);
ARE_EQUAL("./dir1/file2.c", module1.files[1]->name);
Module& module2 = *project->modules[1];
Module& module2 = *project.modules[1];
ARE_EQUAL(2, module2.files.size());
ARE_EQUAL("./dir2/file3.c", module2.files[0]->name);
ARE_EQUAL("./dir2/file4.c", module2.files[1]->name);

View file

@ -5,6 +5,6 @@ using std::string;
void ProjectTest::Run()
{
string projectFilename ( "tests/data/project.xml" );
Project* project = new Project( projectFilename );
ARE_EQUAL(2, project->modules.size());
Project project( projectFilename );
ARE_EQUAL(2, project.modules.size());
}