Generate automatic dependencies.

svn path=/branches/xmlbuildsystem/; revision=13371
This commit is contained in:
Casper Hornstrup 2005-01-31 18:25:55 +00:00
parent adeb8563b5
commit 6052ab4bd7
11 changed files with 325 additions and 83 deletions

View file

@ -1,5 +1,6 @@
<module name="freeldr_base" type="objectlibrary"> <module name="freeldr_base" type="objectlibrary">
<include base="freeldr_base">include</include> <include base="freeldr_base">include</include>
<include base="freeldr_base">cache</include>
<compilerflag>-nostdlib</compilerflag> <compilerflag>-nostdlib</compilerflag>
<compilerflag>-nostdinc</compilerflag> <compilerflag>-nostdinc</compilerflag>
<compilerflag>-ffreestanding</compilerflag> <compilerflag>-ffreestanding</compilerflag>

View file

@ -13,20 +13,42 @@
/* Read at most this amount of bytes from each file and assume that all #includes are located within this block */ /* Read at most this amount of bytes from each file and assume that all #includes are located within this block */
#define MAX_BYTES_TO_READ 4096 #define MAX_BYTES_TO_READ 4096
using std::string; using std::string;
using std::vector; using std::vector;
using std::map; using std::map;
SourceFile::SourceFile ( AutomaticDependency* automaticDependency, SourceFile::SourceFile ( AutomaticDependency* automaticDependency,
Module& module, Module& module,
const string& filename ) const string& filename,
SourceFile* parent,
bool isNonAutomaticDependency )
: automaticDependency ( automaticDependency ), : automaticDependency ( automaticDependency ),
module ( module ), module ( module ),
filename ( filename ) filename ( filename ),
isNonAutomaticDependency ( isNonAutomaticDependency )
{ {
if ( parent != NULL )
parents.push_back ( parent );
GetDirectoryAndFilenameParts ();
} }
void
SourceFile::GetDirectoryAndFilenameParts ()
{
size_t index = filename.find_last_of ( CSEP );
if ( index != string::npos )
{
directoryPart = filename.substr ( 0, index );
filenamePart = filename.substr ( index + 1, filename.length () - index );
}
else
{
directoryPart = "";
filenamePart = filename;
}
}
void void
SourceFile::Close () SourceFile::Close ()
{ {
@ -87,14 +109,65 @@ SourceFile::ReadInclude ( string& filename )
return false; return false;
} }
bool
SourceFile::IsParentOf ( const SourceFile* parent,
const SourceFile* child )
{
size_t i;
for ( i = 0; i < child->parents.size (); i++ )
{
if ( child->parents[i] != NULL )
{
if ( child->parents[i] == parent )
return true;
}
}
for ( i = 0; i < child->parents.size (); i++ )
{
if ( child->parents[i] != NULL )
{
if ( IsParentOf ( parent,
child->parents[i] ) )
return true;
}
}
return false;
}
bool
SourceFile::IsIncludedFrom ( const string& normalizedFilename )
{
if ( normalizedFilename == filename )
return true;
SourceFile* sourceFile = automaticDependency->RetrieveFromCache ( normalizedFilename );
if ( sourceFile == NULL )
return false;
return IsParentOf ( sourceFile,
this );
}
SourceFile*
SourceFile::GetParentSourceFile ()
{
if ( isNonAutomaticDependency )
return NULL;
return this;
}
SourceFile* SourceFile*
SourceFile::ParseFile ( const string& normalizedFilename ) SourceFile::ParseFile ( const string& normalizedFilename )
{ {
string extension = GetExtension ( normalizedFilename ); string extension = GetExtension ( normalizedFilename );
if ( extension == ".c" || extension == ".C" || extension == ".h" || extension == ".H") if ( extension == ".c" || extension == ".C" || extension == ".h" || extension == ".H" )
{ {
if ( IsIncludedFrom ( normalizedFilename ) )
return NULL;
SourceFile* sourceFile = automaticDependency->RetrieveFromCacheOrParse ( module, SourceFile* sourceFile = automaticDependency->RetrieveFromCacheOrParse ( module,
normalizedFilename ); normalizedFilename,
GetParentSourceFile () );
return sourceFile; return sourceFile;
} }
return NULL; return NULL;
@ -118,7 +191,8 @@ SourceFile::Parse ()
if ( locatedFile ) if ( locatedFile )
{ {
SourceFile* sourceFile = ParseFile ( resolvedFilename ); SourceFile* sourceFile = ParseFile ( resolvedFilename );
files.push_back ( sourceFile ); if ( sourceFile != NULL )
files.push_back ( sourceFile );
} }
} }
p++; p++;
@ -173,10 +247,9 @@ AutomaticDependency::ProcessFile ( Module& module,
const File& file ) const File& file )
{ {
string normalizedFilename = NormalizeFilename ( file.name ); string normalizedFilename = NormalizeFilename ( file.name );
SourceFile sourceFile = SourceFile ( this, RetrieveFromCacheOrParse ( module,
module, normalizedFilename,
normalizedFilename ); NULL );
sourceFile.Parse ();
} }
bool bool
@ -201,40 +274,54 @@ AutomaticDependency::LocateIncludedFile ( Module& module,
const string& includedFilename, const string& includedFilename,
string& resolvedFilename ) string& resolvedFilename )
{ {
for ( size_t i = 0; i < module.includes.size (); i++ ) size_t i;
for ( i = 0; i < module.includes.size (); i++ )
{ {
Include* include = module.includes[0]; Include* include = module.includes[i];
if ( LocateIncludedFile ( include->directory, if ( LocateIncludedFile ( include->directory,
includedFilename, includedFilename,
resolvedFilename ) ) resolvedFilename ) )
return true; return true;
} }
/* FIXME: Ifs */ /* FIXME: Ifs */
for ( i = 0; i < module.project.includes.size (); i++ )
{
Include* include = module.project.includes[i];
if ( LocateIncludedFile ( include->directory,
includedFilename,
resolvedFilename ) )
return true;
}
resolvedFilename = ""; resolvedFilename = "";
return false; return false;
} }
SourceFile* SourceFile*
AutomaticDependency::RetrieveFromCacheOrParse ( Module& module, AutomaticDependency::RetrieveFromCacheOrParse ( Module& module,
const string& filename ) const string& filename,
SourceFile* parentSourceFile )
{ {
SourceFile* sourceFile = sourcefile_map[filename]; SourceFile* sourceFile = sourcefile_map[filename];
if ( sourceFile == NULL ) if ( sourceFile == NULL )
{ {
sourceFile = new SourceFile ( this, sourceFile = new SourceFile ( this,
module, module,
filename ); filename,
sourceFile->Parse (); parentSourceFile,
false );
sourcefile_map[filename] = sourceFile; sourcefile_map[filename] = sourceFile;
sourceFile->Parse ();
} }
else if ( parentSourceFile != NULL )
sourceFile->parents.push_back ( parentSourceFile );
return sourceFile; return sourceFile;
} }
SourceFile* SourceFile*
AutomaticDependency::RetrieveFromCache ( Module& module, AutomaticDependency::RetrieveFromCache ( const string& filename )
const string& filename )
{ {
return sourcefile_map[filename]; return sourcefile_map[filename];
} }

View file

@ -19,7 +19,8 @@ public:
MingwBackend::MingwBackend ( Project& project ) MingwBackend::MingwBackend ( Project& project )
: Backend ( project ) : Backend ( project ),
automaticDependencyUniqueIdCounter ( 0 )
{ {
} }
@ -240,12 +241,19 @@ MingwBackend::GenerateAllTarget () const
fprintf ( fMakefile, "\n\t\n\n" ); fprintf ( fMakefile, "\n\t\n\n" );
} }
string*
MingwBackend::GenerateAutomaticDependencyUniqueId ()
{
automaticDependencyUniqueIdCounter++;
return new string ( ssprintf ( "d%d",
automaticDependencyUniqueIdCounter ) );
}
void void
MingwBackend::GenerateAutomaticDependencies () const MingwBackend::GenerateAutomaticDependencies ()
{ {
AutomaticDependency automaticDependency ( ProjectNode ); AutomaticDependency automaticDependency ( ProjectNode );
automaticDependency.Process (); automaticDependency.Process ();
for ( size_t mi = 0; mi < ProjectNode.modules.size (); mi++ ) for ( size_t mi = 0; mi < ProjectNode.modules.size (); mi++ )
{ {
Module& module = *ProjectNode.modules[mi]; Module& module = *ProjectNode.modules[mi];
@ -253,34 +261,110 @@ MingwBackend::GenerateAutomaticDependencies () const
{ {
File& file = *module.files[fi]; File& file = *module.files[fi];
string normalizedFilename = NormalizeFilename ( file.name ); string normalizedFilename = NormalizeFilename ( file.name );
SourceFile* sourceFile = automaticDependency.RetrieveFromCache ( module,
normalizedFilename ); SourceFile* sourceFile = automaticDependency.RetrieveFromCache ( normalizedFilename );
if ( sourceFile != NULL ) if ( sourceFile != NULL )
{ {
string dependencies ( "" ); string dependencies ( "" );
GenerateAutomaticDependenciesForFile ( sourceFile, GenerateAutomaticDependenciesForFileCached ( sourceFile,
dependencies ); dependencies );
fprintf ( fMakefile, if ( dependencies.size () > 0 )
"%s:: %s", {
normalizedFilename.c_str (), const string& objectFilename = MingwModuleHandler::GetObjectFilename ( normalizedFilename );
dependencies.c_str () ); string* uniqueId = automaticDependencyMap[dependencies];
if ( uniqueId == NULL )
{
uniqueId = GenerateAutomaticDependencyUniqueId ();
automaticDependencyMap[dependencies] = uniqueId;
fprintf ( fMakefile,
"%s = %s\n",
uniqueId->c_str (),
dependencies.c_str () );
}
fprintf ( fMakefile,
"%s: $(%s)\n",
objectFilename.c_str (),
uniqueId->c_str () );
}
} }
} }
} }
} }
void string
MingwBackend::GenerateAutomaticDependenciesForFile ( SourceFile* sourceFile, MingwBackend::GetFilename ( const string& filename ) const
string& dependencies ) const
{ {
if ( dependencies.size () > 0 ) size_t index = filename.find_last_of ( CSEP );
dependencies += " "; if ( index == string::npos )
dependencies += sourceFile->filename; return filename;
else
return filename.substr ( index + 1, filename.length () - index );
}
void
MingwBackend::GenerateAutomaticDependenciesForFileCached ( SourceFile* sourceFile,
string& dependencies )
{
for ( size_t i = 0; i < sourceFile->files.size (); i++) for ( size_t i = 0; i < sourceFile->files.size (); i++)
{ {
SourceFile* childSourceFile = sourceFile->files[0]; SourceFile* childSourceFile = sourceFile->files[i];
string* uniqueId = automaticDependencyDirectoryMap[childSourceFile->directoryPart];
if ( uniqueId == NULL )
{
uniqueId = GenerateAutomaticDependencyUniqueId ();
automaticDependencyDirectoryMap[childSourceFile->directoryPart] = uniqueId;
fprintf ( fMakefile,
"%s = %s\n",
uniqueId->c_str (),
childSourceFile->directoryPart.c_str () );
}
dependencies += ssprintf ( "${%s}%s%s",
uniqueId->c_str (),
SSEP,
childSourceFile->filenamePart.c_str () );
string childDependencies;
if ( childSourceFile->cachedDependencies.length () > 0 )
childDependencies = childSourceFile->cachedDependencies;
else
{
GenerateAutomaticDependenciesForFile ( childSourceFile,
childDependencies );
if ( childDependencies.length () > 200 )
{
childSourceFile->cachedDependencies = childDependencies;
}
}
dependencies += " " + childDependencies;
}
}
void
MingwBackend::GenerateAutomaticDependenciesForFile ( SourceFile* sourceFile,
string& dependencies )
{
for ( size_t i = 0; i < sourceFile->files.size (); i++ )
{
SourceFile* childSourceFile = sourceFile->files[i];
if ( dependencies.length () > 0 )
dependencies += " ";
string* uniqueId = automaticDependencyDirectoryMap[childSourceFile->directoryPart];
if ( uniqueId == NULL )
{
uniqueId = GenerateAutomaticDependencyUniqueId ();
automaticDependencyDirectoryMap[childSourceFile->directoryPart] = uniqueId;
fprintf ( fMakefile,
"%s = %s\n",
uniqueId->c_str (),
childSourceFile->directoryPart.c_str () );
}
dependencies += ssprintf ( "${%s}%s%s",
uniqueId->c_str (),
SSEP,
childSourceFile->filenamePart.c_str () );
GenerateAutomaticDependenciesForFile ( childSourceFile, GenerateAutomaticDependenciesForFile ( childSourceFile,
dependencies ); dependencies );
} }

View file

@ -8,6 +8,7 @@ class MingwBackend : public Backend
{ {
public: public:
MingwBackend ( Project& project ); MingwBackend ( Project& project );
virtual ~MingwBackend () { };
virtual void Process (); virtual void Process ();
private: private:
void ProcessModule ( Module& module ) const; void ProcessModule ( Module& module ) const;
@ -27,10 +28,19 @@ private:
void GenerateGlobalVariables () const; void GenerateGlobalVariables () const;
bool IncludeInAllTarget ( const Module& module ) const; bool IncludeInAllTarget ( const Module& module ) const;
void GenerateAllTarget () const; void GenerateAllTarget () const;
void GenerateAutomaticDependencies () const; std::string* GenerateAutomaticDependencyUniqueId ();
void GenerateAutomaticDependencies ();
bool IsAutomaticDependencyGenerated ( SourceFile* sourceFile );
void OutputAutomaticDependenciesForFile ( SourceFile* sourceFile );
std::string GetFilename ( const std::string& filename ) const;
void GenerateAutomaticDependenciesForFileCached ( SourceFile* sourceFile,
std::string& dependencies );
void GenerateAutomaticDependenciesForFile ( SourceFile* sourceFile, void GenerateAutomaticDependenciesForFile ( SourceFile* sourceFile,
std::string& dependencies ) const; std::string& dependencies );
FILE* fMakefile; FILE* fMakefile;
int automaticDependencyUniqueIdCounter;
std::map<std::string, std::string*> automaticDependencyMap;
std::map<std::string, std::string*> automaticDependencyDirectoryMap;
}; };
std::string FixupTargetFilename ( const std::string& targetFilename ); std::string FixupTargetFilename ( const std::string& targetFilename );

View file

@ -22,6 +22,20 @@ MingwModuleHandler::ref = 0;
FILE* FILE*
MingwModuleHandler::fMakefile = NULL; MingwModuleHandler::fMakefile = NULL;
string
ReplaceExtension ( const string& filename,
const string& newExtension )
{
size_t index = filename.find_last_of ( '/' );
if (index == string::npos) index = 0;
string tmp = filename.substr( index, filename.size() - index );
size_t ext_index = tmp.find_last_of( '.' );
if (ext_index != string::npos)
return filename.substr ( 0, index + ext_index ) + newExtension;
return filename + newExtension;
}
MingwModuleHandler::MingwModuleHandler ( ModuleType moduletype ) MingwModuleHandler::MingwModuleHandler ( ModuleType moduletype )
{ {
if ( !ref++ ) if ( !ref++ )
@ -72,10 +86,10 @@ MingwModuleHandler::GetWorkingDirectory () const
return "."; return ".";
} }
string string
MingwModuleHandler::GetDirectory ( const string& filename ) const MingwModuleHandler::GetDirectory ( const string& filename )
{ {
size_t index = filename.find_last_of ( '/' ); size_t index = filename.find_last_of ( CSEP );
if (index == string::npos) if (index == string::npos)
return "."; return ".";
else else
@ -91,19 +105,6 @@ MingwModuleHandler::GetBasename ( const string& filename ) const
return ""; return "";
} }
string
MingwModuleHandler::ReplaceExtension ( const string& filename,
const string& newExtension ) const
{
size_t index = filename.find_last_of ( '/' );
if (index == string::npos) index = 0;
string tmp = filename.substr( index, filename.size() - index );
size_t ext_index = tmp.find_last_of( '.' );
if (ext_index != string::npos)
return filename.substr ( 0, index + ext_index ) + newExtension;
return filename + newExtension;
}
string string
MingwModuleHandler::GetActualSourceFilename ( const string& filename ) const MingwModuleHandler::GetActualSourceFilename ( const string& filename ) const
{ {
@ -237,7 +238,7 @@ MingwModuleHandler::GetSourceFilenamesWithoutGeneratedFiles ( const Module& modu
} }
string string
MingwModuleHandler::GetObjectFilename ( const string& sourceFilename ) const MingwModuleHandler::GetObjectFilename ( const string& sourceFilename )
{ {
string newExtension; string newExtension;
string extension = GetExtension ( sourceFilename ); string extension = GetExtension ( sourceFilename );
@ -247,9 +248,8 @@ MingwModuleHandler::GetObjectFilename ( const string& sourceFilename ) const
newExtension = ".stubs.o"; newExtension = ".stubs.o";
else else
newExtension = ".o"; newExtension = ".o";
return PassThruCacheDirectory ( return FixupTargetFilename (
FixupTargetFilename ( ReplaceExtension ( sourceFilename, newExtension ) );
ReplaceExtension ( sourceFilename, newExtension ) ) );
} }
string string
@ -263,7 +263,7 @@ MingwModuleHandler::GetObjectFilenames ( const Module& module ) const
{ {
if ( objectFilenames.size () > 0 ) if ( objectFilenames.size () > 0 )
objectFilenames += " "; objectFilenames += " ";
objectFilenames += GetObjectFilename ( module.files[i]->name ); objectFilenames += PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( module.files[i]->name ) );
} }
return objectFilenames; return objectFilenames;
} }
@ -510,7 +510,7 @@ MingwModuleHandler::GenerateMacros (
fprintf ( fMakefile, fprintf ( fMakefile,
"%s := %s $(%s)\n", "%s := %s $(%s)\n",
objs_macro.c_str(), objs_macro.c_str(),
GetObjectFilename(files[i]->name).c_str(), PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( files[i]->name ) ).c_str (),
objs_macro.c_str() ); objs_macro.c_str() );
} }
} }
@ -530,7 +530,7 @@ MingwModuleHandler::GenerateMacros (
fMakefile, fMakefile,
"%s%s", "%s%s",
( i%10 == 9 ? "\\\n\t" : " " ), ( i%10 == 9 ? "\\\n\t" : " " ),
GetObjectFilename(files[i]->name).c_str() ); PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( files[i]->name ) ).c_str () );
} }
} }
fprintf ( fMakefile, "\n" ); fprintf ( fMakefile, "\n" );
@ -612,7 +612,7 @@ MingwModuleHandler::GenerateGccCommand ( const Module& module,
const string& cc, const string& cc,
const string& cflagsMacro ) const const string& cflagsMacro ) const
{ {
string objectFilename = GetObjectFilename ( sourceFilename ); string objectFilename = PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( sourceFilename ) );
fprintf ( fMakefile, fprintf ( fMakefile,
"%s: %s\n", "%s: %s\n",
objectFilename.c_str (), objectFilename.c_str (),
@ -631,7 +631,7 @@ MingwModuleHandler::GenerateGccAssemblerCommand ( const Module& module,
const string& cc, const string& cc,
const string& cflagsMacro ) const const string& cflagsMacro ) const
{ {
string objectFilename = GetObjectFilename ( sourceFilename ); string objectFilename = PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( sourceFilename ) );
fprintf ( fMakefile, fprintf ( fMakefile,
"%s: %s\n", "%s: %s\n",
objectFilename.c_str (), objectFilename.c_str (),
@ -649,7 +649,7 @@ MingwModuleHandler::GenerateNasmCommand ( const Module& module,
const string& sourceFilename, const string& sourceFilename,
const string& nasmflagsMacro ) const const string& nasmflagsMacro ) const
{ {
string objectFilename = GetObjectFilename ( sourceFilename ); string objectFilename = PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( sourceFilename ) );
fprintf ( fMakefile, fprintf ( fMakefile,
"%s: %s\n", "%s: %s\n",
objectFilename.c_str (), objectFilename.c_str (),
@ -667,7 +667,7 @@ MingwModuleHandler::GenerateWindresCommand ( const Module& module,
const string& sourceFilename, const string& sourceFilename,
const string& windresflagsMacro ) const const string& windresflagsMacro ) const
{ {
string objectFilename = GetObjectFilename ( sourceFilename ); string objectFilename = PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( sourceFilename ) );
fprintf ( fMakefile, fprintf ( fMakefile,
"%s: %s\n", "%s: %s\n",
objectFilename.c_str (), objectFilename.c_str (),
@ -908,7 +908,7 @@ MingwModuleHandler::GetCleanTargets ( vector<string>& out,
size_t i; size_t i;
for ( i = 0; i < files.size(); i++ ) for ( i = 0; i < files.size(); i++ )
out.push_back ( GetObjectFilename(files[i]->name) ); out.push_back ( PassThruCacheDirectory ( MingwModuleHandler::GetObjectFilename ( files[i]->name ) ) );
for ( i = 0; i < ifs.size(); i++ ) for ( i = 0; i < ifs.size(); i++ )
GetCleanTargets ( out, ifs[i]->files, ifs[i]->ifs ); GetCleanTargets ( out, ifs[i]->files, ifs[i]->ifs );

View file

@ -3,6 +3,11 @@
#include "../backend.h" #include "../backend.h"
extern std::string
ReplaceExtension ( const std::string& filename,
const std::string& newExtension );
class MingwModuleHandler class MingwModuleHandler
{ {
public: public:
@ -16,15 +21,13 @@ public:
static MingwModuleHandler* LookupHandler ( const std::string& location, static MingwModuleHandler* LookupHandler ( const std::string& location,
ModuleType moduletype_ ); ModuleType moduletype_ );
virtual void Process ( const Module& module ) = 0; virtual void Process ( const Module& module ) = 0;
void GenerateDirectoryTargets () const; void GenerateDirectoryTargets () const;
static std::string GetObjectFilename ( const std::string& sourceFilename );
static std::string GetDirectory ( const std::string& filename );
protected: protected:
const std::string &PassThruCacheDirectory ( const std::string &f ) const; const std::string &PassThruCacheDirectory ( const std::string &f ) const;
std::string GetWorkingDirectory () const; std::string GetWorkingDirectory () const;
std::string GetDirectory (const std::string& filename ) const;
std::string GetBasename ( const std::string& filename ) const; std::string GetBasename ( const std::string& filename ) const;
std::string ReplaceExtension ( const std::string& filename,
const std::string& newExtension ) const;
std::string GetActualSourceFilename ( const std::string& filename ) const; std::string GetActualSourceFilename ( const std::string& filename ) const;
std::string GetModuleArchiveFilename ( const Module& module ) const; std::string GetModuleArchiveFilename ( const Module& module ) const;
bool IsGeneratedFile ( const File& file ) const; bool IsGeneratedFile ( const File& file ) const;
@ -37,7 +40,6 @@ protected:
std::string GetSourceFilenames ( const Module& module ) const; std::string GetSourceFilenames ( const Module& module ) const;
std::string GetSourceFilenamesWithoutGeneratedFiles ( const Module& module ) const; std::string GetSourceFilenamesWithoutGeneratedFiles ( const Module& module ) const;
std::string GetObjectFilename ( const std::string& sourceFilename ) const;
std::string GetObjectFilenames ( const Module& module ) const; std::string GetObjectFilenames ( const Module& module ) const;
void GenerateMacrosAndTargetsHost ( const Module& module ) const; void GenerateMacrosAndTargetsHost ( const Module& module ) const;
void GenerateMacrosAndTargetsTarget ( const Module& module ) const; void GenerateMacrosAndTargetsTarget ( const Module& module ) const;
@ -47,6 +49,8 @@ protected:
std::string GetInvocationDependencies ( const Module& module ) const; std::string GetInvocationDependencies ( const Module& module ) const;
std::string GetInvocationParameters ( const Invoke& invoke ) const; std::string GetInvocationParameters ( const Invoke& invoke ) const;
void GenerateInvocations ( const Module& module ) const; void GenerateInvocations ( const Module& module ) const;
std::string GetPreconditionDependenciesName ( const Module& module ) const;
void GeneratePreconditionDependencies ( const Module& module ) const; void GeneratePreconditionDependencies ( const Module& module ) const;
std::string GetCFlagsMacro ( const Module& module ) const; std::string GetCFlagsMacro ( const Module& module ) const;
std::string GetObjectsMacro ( const Module& module ) const; std::string GetObjectsMacro ( const Module& module ) const;
@ -144,7 +148,6 @@ private:
const std::string& ar, const std::string& ar,
const std::string* clags, const std::string* clags,
const std::string* nasmflags ) const; const std::string* nasmflags ) const;
std::string GetPreconditionDependenciesName ( const Module& module ) const;
std::string GetSpecObjectDependencies ( const std::string& filename ) const; std::string GetSpecObjectDependencies ( const std::string& filename ) const;
}; };

View file

@ -352,7 +352,9 @@ class SourceFile
public: public:
SourceFile ( AutomaticDependency* automaticDependency, SourceFile ( AutomaticDependency* automaticDependency,
Module& module, Module& module,
const std::string& filename ); const std::string& filename,
SourceFile* parent,
bool isNonAutomaticDependency );
SourceFile* ParseFile ( const std::string& normalizedFilename ); SourceFile* ParseFile ( const std::string& normalizedFilename );
void Parse (); void Parse ();
std::string Location () const; std::string Location () const;
@ -360,11 +362,21 @@ public:
AutomaticDependency* automaticDependency; AutomaticDependency* automaticDependency;
Module& module; Module& module;
std::string filename; std::string filename;
std::string filenamePart;
std::string directoryPart;
std::vector<SourceFile*> parents; /* List of files, this file is included from */
bool isNonAutomaticDependency;
std::string cachedDependencies;
private: private:
void GetDirectoryAndFilenameParts ();
void Close (); void Close ();
void Open (); void Open ();
void SkipWhitespace (); void SkipWhitespace ();
bool ReadInclude ( std::string& filename ); bool ReadInclude ( std::string& filename );
bool IsIncludedFrom ( const std::string& normalizedFilename );
SourceFile* GetParentSourceFile ();
bool IsParentOf ( const SourceFile* parent,
const SourceFile* child );
std::string buf; std::string buf;
const char *p; const char *p;
const char *end; const char *end;
@ -387,9 +399,9 @@ public:
const std::string& includedFilename, const std::string& includedFilename,
std::string& resolvedFilename ); std::string& resolvedFilename );
SourceFile* RetrieveFromCacheOrParse ( Module& module, SourceFile* RetrieveFromCacheOrParse ( Module& module,
const std::string& filename ); const std::string& filename,
SourceFile* RetrieveFromCache ( Module& module, SourceFile* parentSourceFile );
const std::string& filename ); SourceFile* RetrieveFromCache ( const std::string& filename );
private: private:
void ProcessModule ( Module& module ); void ProcessModule ( Module& module );
void ProcessFile ( Module& module, void ProcessFile ( Module& module,

View file

@ -108,6 +108,10 @@ class SourceFileTest : public BaseTest
{ {
public: public:
void Run(); void Run();
private:
bool IsParentOf ( const SourceFile* parent,
const SourceFile* child );
}; };
#endif /* __TEST_H */ #endif /* __TEST_H */

View file

@ -1,2 +1,3 @@
#include <sourcefile1/sourcefile1_header3.h> #include "sourcefile1/sourcefile1_header3.h"
#include <sourcefile2/sourcefile1_dontexist.h> #include <sourcefile2/sourcefile1_dontexist.h>
#include <sourcefile1_recurse.h>

View file

@ -0,0 +1,2 @@
#include <sourcefile1_recurse.h>
#include <sourcefile1_header1.h>

View file

@ -2,10 +2,48 @@
using std::string; using std::string;
void SourceFileTest::Run() bool
SourceFileTest::IsParentOf ( const SourceFile* parent,
const SourceFile* child )
{
size_t i;
for ( i = 0; i < child->parents.size (); i++ )
{
if ( child->parents[i] != NULL )
{
if ( child->parents[i] == parent )
{
return true;
}
}
}
for ( i = 0; i < child->parents.size (); i++ )
{
if ( child->parents[i] != NULL )
{
if ( IsParentOf ( parent,
child->parents[i] ) )
{
return true;
}
}
}
return false;
}
void
SourceFileTest::Run ()
{ {
const Project project ( "tests/data/automaticdependency.xml" ); const Project project ( "tests/data/automaticdependency.xml" );
AutomaticDependency automaticDependency ( project ); AutomaticDependency automaticDependency ( project );
automaticDependency.Process (); automaticDependency.Process ();
ARE_EQUAL(3, automaticDependency.sourcefile_map.size()); ARE_EQUAL( 5, automaticDependency.sourcefile_map.size () );
const SourceFile* header1 = automaticDependency.RetrieveFromCache ( "tests" SSEP "data" SSEP "sourcefile1_header1.h" );
IS_NOT_NULL( header1 );
const SourceFile* recurse = automaticDependency.RetrieveFromCache ( "tests" SSEP "data" SSEP "sourcefile1_recurse.h" );
IS_NOT_NULL( recurse );
IS_TRUE( IsParentOf ( header1,
recurse ) );
IS_FALSE( IsParentOf ( recurse,
header1 ) );
} }