mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 19:22:58 +00:00
Generate MinGW makefile in the backend.
svn path=/branches/xmlbuildsystem/; revision=12837
This commit is contained in:
parent
222bde955c
commit
1568981925
12 changed files with 127 additions and 75 deletions
|
@ -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 );
|
||||
|
|
|
@ -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 ) )
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 ())
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<project name="Project">
|
||||
<project name="Project" makefile="Makefile">
|
||||
<directory name="dir1">
|
||||
<module name="module1" type="buildtool">
|
||||
<file>file1.c</file>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<project name="Project">
|
||||
<project name="Project" makefile="Makefile">
|
||||
<directory name="dir1">
|
||||
<module name="module1" type="buildtool">
|
||||
</module>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue