Have Makefile.auto depend on xml build files

svn path=/branches/xmlbuildsystem/; revision=13872
This commit is contained in:
Casper Hornstrup 2005-03-08 11:15:39 +00:00
parent 025de74d84
commit 79f349c48f
7 changed files with 155 additions and 75 deletions

View file

@ -61,7 +61,7 @@ PREAUTO := \
lib$(SEP)kernel32$(SEP)errcodes.rc lib$(SEP)kernel32$(SEP)errcodes.rc
Makefile.auto: $(RMKDIR_TARGET) $(BUILDNO_TARGET) $(NCI_SERVICE_FILES) $(WMC_TARGET) $(WRC_TARGET) \ Makefile.auto: $(RMKDIR_TARGET) $(BUILDNO_TARGET) $(NCI_SERVICE_FILES) $(WMC_TARGET) $(WRC_TARGET) \
$(RSYM_TARGET) $(CDMAKE_TARGET) $(RBUILD_TARGET) $(PREAUTO) $(RSYM_TARGET) $(CDMAKE_TARGET) $(RBUILD_TARGET) $(PREAUTO) $(XMLBUILDFILES)
tools$(SEP)rbuild$(SEP)rbuild$(EXEPOSTFIX) mingw tools$(SEP)rbuild$(SEP)rbuild$(EXEPOSTFIX) mingw

View file

@ -31,27 +31,11 @@ static const char* WSEQ = " =\t\r\n";
string working_directory; string working_directory;
class XMLInclude XMLIncludes::~XMLIncludes()
{ {
public: for ( size_t i = 0; i < this->size(); i++ )
XMLElement *e; delete (*this)[i];
Path path; }
XMLInclude ( XMLElement* e_, const Path& path_ )
: e(e_), path(path_)
{
}
};
class XMLIncludes : public vector<XMLInclude*>
{
public:
~XMLIncludes()
{
for ( size_t i = 0; i < this->size(); i++ )
delete (*this)[i];
}
};
void void
InitWorkingDirectory() InitWorkingDirectory()
@ -159,7 +143,18 @@ Path::Fixup ( const string& file, bool include_filename ) const
return tmp; return tmp;
} }
/*static*/ string string
Path::RelativeFromWorkingDirectory ()
{
string out = "";
for ( size_t i = 0; i < path.size(); i++ )
{
out += "/" + path[i];
}
return RelativeFromWorkingDirectory ( out );
}
string
Path::RelativeFromWorkingDirectory ( const string& path ) Path::RelativeFromWorkingDirectory ( const string& path )
{ {
vector<string> vwork, vpath, vout; vector<string> vwork, vpath, vout;
@ -192,7 +187,7 @@ Path::RelativeFromWorkingDirectory ( const string& path )
return out; return out;
} }
/*static*/ void void
Path::Split ( vector<string>& out, Path::Split ( vector<string>& out,
const string& path, const string& path,
bool include_last ) bool include_last )
@ -500,10 +495,10 @@ XMLElement::GetAttribute ( const string& attribute,
// it's parsed data. Keep calling this function until it returns NULL // it's parsed data. Keep calling this function until it returns NULL
// (no more data) // (no more data)
XMLElement* XMLElement*
XMLParse(XMLFile& f, XMLParse ( XMLFile& f,
XMLIncludes* includes, XMLIncludes* includes,
const Path& path, const Path& path,
bool* pend_tag = NULL ) bool* pend_tag = NULL )
{ {
string token; string token;
if ( !f.get_token(token) ) if ( !f.get_token(token) )
@ -511,23 +506,28 @@ XMLParse(XMLFile& f,
bool end_tag, is_include = false; bool end_tag, is_include = false;
while ( token[0] != '<' while ( token[0] != '<'
|| !strncmp ( token.c_str(), "<!--", 4 ) || !strncmp ( token.c_str (), "<!--", 4 )
|| !strncmp ( token.c_str(), "<?", 2 ) ) || !strncmp ( token.c_str (), "<?", 2 ) )
{ {
if ( token[0] != '<' ) if ( token[0] != '<' )
throw XMLSyntaxErrorException ( f.Location(), throw XMLSyntaxErrorException ( f.Location (),
"expecting xml tag, not '%s'", "expecting xml tag, not '%s'",
token.c_str() ); token.c_str () );
if ( !f.get_token(token) ) if ( !f.get_token(token) )
return NULL; return NULL;
} }
XMLElement* e = new XMLElement ( f.Location() ); XMLElement* e = new XMLElement ( f.Location () );
bool bNeedEnd = e->Parse ( token, end_tag ); bool bNeedEnd = e->Parse ( token, end_tag );
if ( e->name == "xi:include" && includes ) if ( e->name == "xi:include" && includes )
{ {
includes->push_back ( new XMLInclude ( e, path ) ); XMLAttribute* att;
att = e->GetAttribute ( "href", true );
assert ( att );
string includeFile ( path.Fixup ( att->value, true ) );
string topIncludeFile ( Path::RelativeFromWorkingDirectory ( includeFile ) );
includes->push_back ( new XMLInclude ( e, path, topIncludeFile ) );
is_include = true; is_include = true;
} }
@ -538,7 +538,7 @@ XMLParse(XMLFile& f,
else if ( end_tag ) else if ( end_tag )
{ {
delete e; delete e;
throw XMLSyntaxErrorException ( f.Location(), throw XMLSyntaxErrorException ( f.Location (),
"end tag '%s' not expected", "end tag '%s' not expected",
token.c_str() ); token.c_str() );
return NULL; return NULL;
@ -546,11 +546,11 @@ XMLParse(XMLFile& f,
return e; return e;
} }
bool bThisMixingErrorReported = false; bool bThisMixingErrorReported = false;
while ( f.more_tokens() ) while ( f.more_tokens () )
{ {
if ( f.next_is_text() ) if ( f.next_is_text () )
{ {
if ( !f.get_token ( token ) || !token.size() ) if ( !f.get_token ( token ) || token.size () == 0 )
{ {
throw InvalidBuildFileException ( throw InvalidBuildFileException (
f.Location(), f.Location(),
@ -559,18 +559,18 @@ XMLParse(XMLFile& f,
} }
if ( e->subElements.size() && !bThisMixingErrorReported ) if ( e->subElements.size() && !bThisMixingErrorReported )
{ {
throw XMLSyntaxErrorException ( f.Location(), throw XMLSyntaxErrorException ( f.Location (),
"mixing of inner text with sub elements" ); "mixing of inner text with sub elements" );
bThisMixingErrorReported = true; bThisMixingErrorReported = true;
} }
if ( strchr ( token.c_str(), '>' ) ) if ( strchr ( token.c_str (), '>' ) )
{ {
throw XMLSyntaxErrorException ( f.Location(), throw XMLSyntaxErrorException ( f.Location (),
"invalid symbol '>'" ); "invalid symbol '>'" );
} }
if ( e->value.size() ) if ( e->value.size() > 0 )
{ {
throw XMLSyntaxErrorException ( f.Location(), throw XMLSyntaxErrorException ( f.Location (),
"multiple instances of inner text" ); "multiple instances of inner text" );
e->value += " " + token; e->value += " " + token;
} }
@ -592,16 +592,16 @@ XMLParse(XMLFile& f,
if ( e->name != e2->name ) if ( e->name != e2->name )
{ {
delete e2; delete e2;
throw XMLSyntaxErrorException ( f.Location(), throw XMLSyntaxErrorException ( f.Location (),
"end tag name mismatch" ); "end tag name mismatch" );
break; break;
} }
delete e2; delete e2;
break; break;
} }
if ( e->value.size() && !bThisMixingErrorReported ) if ( e->value.size () > 0 && !bThisMixingErrorReported )
{ {
throw XMLSyntaxErrorException ( f.Location(), throw XMLSyntaxErrorException ( f.Location (),
"mixing of inner text with sub elements" ); "mixing of inner text with sub elements" );
bThisMixingErrorReported = true; bThisMixingErrorReported = true;
} }
@ -624,31 +624,38 @@ XMLReadFile ( XMLFile& f, XMLElement& head, XMLIncludes& includes, const Path& p
} }
XMLElement* XMLElement*
XMLLoadInclude ( XMLElement* e, const Path& path, XMLIncludes& includes ) XMLLoadInclude ( XMLInclude& include,
XMLIncludes& includes )
{ {
XMLAttribute* att; XMLAttribute* att;
att = e->GetAttribute("href",true); att = include.e->GetAttribute("href", true);
assert(att); assert(att);
string file ( path.Fixup(att->value,true) ); string file ( include.path.Fixup(att->value, true) );
string top_file ( Path::RelativeFromWorkingDirectory ( file ) ); string top_file ( Path::RelativeFromWorkingDirectory ( file ) );
e->attributes.push_back ( new XMLAttribute ( "top_href", top_file ) ); include.e->attributes.push_back ( new XMLAttribute ( "top_href", top_file ) );
XMLFile fInc; XMLFile fInc;
if ( !fInc.open ( file ) ) if ( !fInc.open ( file ) )
{ {
include.fileExists = false;
// look for xi:fallback element // look for xi:fallback element
for ( size_t i = 0; i < e->subElements.size(); i++ ) for ( size_t i = 0; i < include.e->subElements.size (); i++ )
{ {
XMLElement* e2 = e->subElements[i]; XMLElement* e2 = include.e->subElements[i];
if ( e2->name == "xi:fallback" ) if ( e2->name == "xi:fallback" )
{ {
// now look for xi:include below... // now look for xi:include below...
for ( i = 0; i < e2->subElements.size(); i++ ) for ( i = 0; i < e2->subElements.size (); i++ )
{ {
XMLElement* e3 = e2->subElements[i]; XMLElement* e3 = e2->subElements[i];
if ( e3->name == "xi:include" ) if ( e3->name == "xi:include" )
{ {
return XMLLoadInclude ( e3, path, includes ); att = e3->GetAttribute ( "href", true );
assert ( att );
string includeFile ( include.path.Fixup ( att->value, true ) );
string topIncludeFile ( Path::RelativeFromWorkingDirectory ( includeFile ) );
XMLInclude* fallbackInclude = new XMLInclude ( e3, include.path, topIncludeFile );
return XMLLoadInclude ( *fallbackInclude, includes );
} }
} }
throw InvalidBuildFileException ( throw InvalidBuildFileException (
@ -661,37 +668,39 @@ XMLLoadInclude ( XMLElement* e, const Path& path, XMLIncludes& includes )
} }
else else
{ {
XMLElement* new_e = new XMLElement ( e->location ); include.fileExists = true;
XMLElement* new_e = new XMLElement ( include.e->location );
new_e->name = "xi:included"; new_e->name = "xi:included";
Path path2 ( path, att->value ); Path path2 ( include.path, att->value );
XMLReadFile ( fInc, *new_e, includes, path2 ); XMLReadFile ( fInc, *new_e, includes, path2 );
return new_e; return new_e;
} }
} }
XMLElement* XMLElement*
XMLLoadFile ( const string& filename, const Path& path ) XMLLoadFile ( const string& filename,
const Path& path,
XMLIncludes& includes )
{ {
XMLIncludes includes;
XMLFile f; XMLFile f;
if ( !f.open ( filename ) ) if ( !f.open ( filename ) )
throw FileNotFoundException ( filename ); throw FileNotFoundException ( filename );
XMLElement* head = new XMLElement("(virtual)"); XMLElement* head = new XMLElement ( "(virtual)" );
XMLReadFile ( f, *head, includes, path ); XMLReadFile ( f, *head, includes, path );
for ( size_t i = 0; i < includes.size(); i++ ) for ( size_t i = 0; i < includes.size (); i++ )
{ {
XMLElement* e = includes[i]->e; XMLElement* e = includes[i]->e;
XMLElement* e2 = XMLLoadInclude ( includes[i]->e, includes[i]->path, includes ); XMLElement* e2 = XMLLoadInclude ( *includes[i], includes );
if ( !e2 ) if ( !e2 )
{ {
throw FileNotFoundException ( throw FileNotFoundException (
ssprintf("%s (referenced from %s)", ssprintf ( "%s (referenced from %s)",
e->GetAttribute("top_href",true)->value.c_str(), e->GetAttribute ( "top_href", true )->value.c_str (),
f.Location().c_str() ) ); f.Location ().c_str () ) );
} }
XMLElement* parent = e->parentElement; XMLElement* parent = e->parentElement;
XMLElement** parent_container = NULL; XMLElement** parent_container = NULL;
@ -701,7 +710,7 @@ XMLLoadFile ( const string& filename, const Path& path )
throw Exception ( "internal tool error: xi:include doesn't have a parent" ); throw Exception ( "internal tool error: xi:include doesn't have a parent" );
return NULL; return NULL;
} }
for ( size_t j = 0; j < parent->subElements.size(); j++ ) for ( size_t j = 0; j < parent->subElements.size (); j++ )
{ {
if ( parent->subElements[j] == e ) if ( parent->subElements[j] == e )
{ {
@ -720,7 +729,7 @@ XMLLoadFile ( const string& filename, const Path& path )
e2->name = e->name; e2->name = e->name;
e2->attributes = e->attributes; e2->attributes = e->attributes;
*parent_container = e2; *parent_container = e2;
e->attributes.resize(0); e->attributes.resize ( 0 );
delete e; delete e;
} }
return head; return head;

View file

@ -1,10 +1,10 @@
// XML.h
#ifndef XML_H #ifndef XML_H
#define XML_H #define XML_H
#include "pch.h" #include "pch.h"
class XMLElement;
void void
InitWorkingDirectory(); InitWorkingDirectory();
@ -23,6 +23,7 @@ public:
Path ( const Path& cwd, const std::string& filename ); Path ( const Path& cwd, const std::string& filename );
std::string Fixup ( const std::string& filename, bool include_filename ) const; std::string Fixup ( const std::string& filename, bool include_filename ) const;
std::string RelativeFromWorkingDirectory ();
static std::string RelativeFromWorkingDirectory ( const std::string& path ); static std::string RelativeFromWorkingDirectory ( const std::string& path );
static void Split ( std::vector<std::string>& out, static void Split ( std::vector<std::string>& out,
@ -30,6 +31,26 @@ public:
bool include_last ); bool include_last );
}; };
class XMLInclude
{
public:
XMLElement *e;
Path path;
std::string topIncludeFilename;
bool fileExists;
XMLInclude ( XMLElement* e_, const Path& path_, const std::string topIncludeFilename_ )
: e ( e_ ), path ( path_ ), topIncludeFilename ( topIncludeFilename_ )
{
}
};
class XMLIncludes : public std::vector<XMLInclude*>
{
public:
~XMLIncludes();
};
class XMLFile class XMLFile
{ {
friend class XMLElement; friend class XMLElement;
@ -86,11 +107,8 @@ public:
}; };
XMLElement* XMLElement*
XMLLoadFile ( const std::string& filename, const Path& path ); XMLLoadFile ( const std::string& filename,
const Path& path,
XMLIncludes& includes );
/*XMLElement* #endif // XML_H
XMLParse(XMLFile& f,
const Path& path,
bool* pend_tag = NULL);*/
#endif//XML_H

View file

@ -31,6 +31,7 @@ MingwBackend::Process ()
GenerateGlobalVariables (); GenerateGlobalVariables ();
GenerateAllTarget (); GenerateAllTarget ();
GenerateInitTarget (); GenerateInitTarget ();
GenerateXmlBuildFilesMacro();
for ( size_t i = 0; i < ProjectNode.modules.size (); i++ ) for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )
{ {
Module& module = *ProjectNode.modules[i]; Module& module = *ProjectNode.modules[i];
@ -258,6 +259,47 @@ MingwBackend::GenerateInitTarget () const
"\n" ); "\n" );
} }
void
MingwBackend::GenerateXmlBuildFilesMacro() const
{
fprintf ( fMakefile,
"XMLBUILDFILES = %s \\\n",
ProjectNode.GetProjectFilename ().c_str () );
string xmlbuildFilenames;
int numberOfExistingFiles = 0;
for ( size_t i = 0; i < ProjectNode.xmlbuildfiles.size (); i++ )
{
XMLInclude& xmlbuildfile = *ProjectNode.xmlbuildfiles[i];
if ( !xmlbuildfile.fileExists )
continue;
numberOfExistingFiles++;
if ( xmlbuildFilenames.length () > 0 )
xmlbuildFilenames += " ";
xmlbuildFilenames += NormalizeFilename ( xmlbuildfile.topIncludeFilename );
if ( numberOfExistingFiles % 5 == 4 || i == ProjectNode.xmlbuildfiles.size () - 1 )
{
fprintf ( fMakefile,
"\t%s",
xmlbuildFilenames.c_str ());
if ( i == ProjectNode.xmlbuildfiles.size () - 1 )
{
fprintf ( fMakefile,
"\n" );
}
else
{
fprintf ( fMakefile,
" \\\n",
xmlbuildFilenames.c_str () );
}
xmlbuildFilenames.resize ( 0 );
}
numberOfExistingFiles++;
}
fprintf ( fMakefile,
"\n" );
}
void void
MingwBackend::CheckAutomaticDependencies () MingwBackend::CheckAutomaticDependencies ()
{ {

View file

@ -30,6 +30,7 @@ private:
void GenerateAllTarget () const; void GenerateAllTarget () const;
std::string GetBuildToolDependencies () const; std::string GetBuildToolDependencies () const;
void GenerateInitTarget () const; void GenerateInitTarget () const;
void GenerateXmlBuildFilesMacro() const;
void CheckAutomaticDependencies (); void CheckAutomaticDependencies ();
FILE* fMakefile; FILE* fMakefile;
}; };

View file

@ -183,7 +183,7 @@ void
Project::ReadXml () Project::ReadXml ()
{ {
Path path; Path path;
head = XMLLoadFile ( xmlfile, path ); head = XMLLoadFile ( xmlfile, path, xmlbuildfiles );
node = NULL; node = NULL;
for ( size_t i = 0; i < head->subElements.size (); i++ ) for ( size_t i = 0; i < head->subElements.size (); i++ )
{ {
@ -344,3 +344,11 @@ Project::LocateModule ( const string& name ) const
return NULL; return NULL;
} }
std::string
Project::GetProjectFilename () const
{
return xmlfile;
}

View file

@ -63,6 +63,7 @@ class Project
public: public:
std::string name; std::string name;
std::string makefile; std::string makefile;
XMLIncludes xmlbuildfiles;
std::vector<Module*> modules; std::vector<Module*> modules;
std::vector<Include*> includes; std::vector<Include*> includes;
std::vector<Define*> defines; std::vector<Define*> defines;
@ -78,6 +79,7 @@ public:
void ProcessXML ( const std::string& path ); void ProcessXML ( const std::string& path );
Module* LocateModule ( const std::string& name ); Module* LocateModule ( const std::string& name );
const Module* LocateModule ( const std::string& name ) const; const Module* LocateModule ( const std::string& name ) const;
std::string GetProjectFilename () const;
private: private:
const Property* LookupProperty ( const std::string& name ) const; const Property* LookupProperty ( const std::string& name ) const;
void SetConfigurationOption ( char* s, void SetConfigurationOption ( char* s,