Support module_depends target

svn path=/trunk/; revision=15868
This commit is contained in:
Casper Hornstrup 2005-06-12 10:18:51 +00:00
parent 639193ca53
commit 321c3545d8
10 changed files with 162 additions and 55 deletions

View file

@ -50,11 +50,12 @@
#
# ROS_RBUILDFLAGS
# Pass parameters to rbuild.
# -v Be verbose.
# -c Clean as you go. Delete generated files as soon as they are not needed anymore.
# -d Disable automatic dependencies.
# -mi Let make handle creation of install directories. Rbuild will not generate the directories.
# -ps Generate proxy makefiles in source tree instead of the output tree.
# -v Be verbose.
# -c Clean as you go. Delete generated files as soon as they are not needed anymore.
# -dd Disable automatic dependencies.
# -dm{module} Check only automatic dependencies for this module.
# -mi Let make handle creation of install directories. Rbuild will not generate the directories.
# -ps Generate proxy makefiles in source tree instead of the output tree.
.PHONY: all
.PHONY: clean

View file

@ -281,10 +281,10 @@ AutomaticDependency::~AutomaticDependency ()
}
void
AutomaticDependency::Process ()
AutomaticDependency::ParseFiles ()
{
for ( size_t i = 0; i < project.modules.size (); i++ )
ProcessModule ( *project.modules[i] );
ParseFiles ( *project.modules[i] );
}
void
@ -301,17 +301,17 @@ AutomaticDependency::GetModuleFiles ( Module& module,
}
void
AutomaticDependency::ProcessModule ( Module& module )
AutomaticDependency::ParseFiles ( Module& module )
{
vector<File*> files;
GetModuleFiles ( module, files );
for ( size_t i = 0; i < files.size (); i++ )
ProcessFile ( module, *files[i] );
ParseFile ( module, *files[i] );
}
void
AutomaticDependency::ProcessFile ( Module& module,
const File& file )
AutomaticDependency::ParseFile ( Module& module,
const File& file )
{
string normalizedFilename = NormalizeFilename ( file.name );
RetrieveFromCacheOrParse ( module,
@ -412,34 +412,54 @@ AutomaticDependency::RetrieveFromCache ( const string& filename )
void
AutomaticDependency::CheckAutomaticDependencies ( bool verbose )
{
struct utimbuf timebuf;
ParseFiles ();
for ( size_t mi = 0; mi < project.modules.size (); mi++ )
{
vector<File*> files;
GetModuleFiles ( *project.modules[mi], files );
for ( size_t fi = 0; fi < files.size (); fi++ )
{
File& file = *files[fi];
string normalizedFilename = NormalizeFilename ( file.name );
Module& module = *project.modules[mi];
CheckAutomaticDependencies ( module, verbose, false );
}
}
SourceFile* sourceFile = RetrieveFromCache ( normalizedFilename );
if ( sourceFile != NULL )
void
AutomaticDependency::CheckAutomaticDependencies ( Module& module,
bool verbose )
{
CheckAutomaticDependencies ( module, verbose, true );
}
void
AutomaticDependency::CheckAutomaticDependencies ( Module& module,
bool verbose,
bool parseFiles )
{
if ( parseFiles )
ParseFiles ( module );
struct utimbuf timebuf;
vector<File*> files;
GetModuleFiles ( module, files );
for ( size_t fi = 0; fi < files.size (); fi++ )
{
File& file = *files[fi];
string normalizedFilename = NormalizeFilename ( file.name );
SourceFile* sourceFile = RetrieveFromCache ( normalizedFilename );
if ( sourceFile != NULL )
{
CheckAutomaticDependenciesForFile ( sourceFile );
assert ( sourceFile->youngestLastWriteTime != 0 );
if ( sourceFile->youngestLastWriteTime > sourceFile->lastWriteTime )
{
CheckAutomaticDependenciesForFile ( sourceFile );
assert ( sourceFile->youngestLastWriteTime != 0 );
if ( sourceFile->youngestLastWriteTime > sourceFile->lastWriteTime )
if ( verbose )
{
if ( verbose )
{
printf ( "Marking %s for rebuild due to younger file %s\n",
sourceFile->filename.c_str (),
sourceFile->youngestFile->filename.c_str () );
}
timebuf.actime = sourceFile->youngestLastWriteTime;
timebuf.modtime = sourceFile->youngestLastWriteTime;
utime ( sourceFile->filename.c_str (),
&timebuf );
printf ( "Marking %s for rebuild due to younger file %s\n",
sourceFile->filename.c_str (),
sourceFile->youngestFile->filename.c_str () );
}
timebuf.actime = sourceFile->youngestLastWriteTime;
timebuf.modtime = sourceFile->youngestLastWriteTime;
utime ( sourceFile->filename.c_str (),
&timebuf );
}
}
}

View file

@ -293,14 +293,46 @@ MingwBackend::ProcessModules ()
h.GenerateInvocations ();
h.GenerateCleanTarget ();
h.GenerateInstallTarget ();
h.GenerateDependsTarget ();
delete v[i];
}
printf ( "done\n" );
}
void
MingwBackend::Process ()
{
if ( configuration.CheckDependenciesForModuleOnly )
CheckAutomaticDependenciesForModuleOnly ();
else
ProcessNormal ();
}
void
MingwBackend::CheckAutomaticDependenciesForModuleOnly ()
{
if ( configuration.AutomaticDependencies )
{
Module* module = ProjectNode.LocateModule ( configuration.CheckDependenciesForModuleOnlyModule );
if ( module == NULL )
{
printf ( "Module '%s' does not exist\n",
configuration.CheckDependenciesForModuleOnlyModule.c_str () );
return;
}
printf ( "Checking automatic dependencies for module '%s'...",
module->name.c_str () );
AutomaticDependency automaticDependency ( ProjectNode );
automaticDependency.CheckAutomaticDependencies ( *module,
configuration.Verbose );
printf ( "done\n" );
}
}
void
MingwBackend::ProcessNormal ()
{
DetectCompiler ();
DetectNetwideAssembler ();
@ -671,7 +703,6 @@ MingwBackend::CheckAutomaticDependencies ()
{
printf ( "Checking automatic dependencies..." );
AutomaticDependency automaticDependency ( ProjectNode );
automaticDependency.Process ();
automaticDependency.CheckAutomaticDependencies ( configuration.Verbose );
printf ( "done\n" );
}

View file

@ -94,6 +94,8 @@ private:
void DetectPipeSupport ();
void DetectPCHSupport ();
void ProcessModules ();
void CheckAutomaticDependenciesForModuleOnly ();
void ProcessNormal ();
std::string GetNonModuleInstallDirectories ( const std::string& installDirectory );
std::string GetInstallDirectories ( const std::string& installDirectory );
void GetNonModuleInstallFiles ( std::vector<std::string>& out ) const;

View file

@ -467,6 +467,22 @@ MingwModuleHandler::GenerateInstallTarget () const
normalizedTargetFilename.c_str() );
}
void
MingwModuleHandler::GenerateDependsTarget () const
{
fprintf ( fMakefile,
".PHONY: %s_depends\n",
module.name.c_str() );
fprintf ( fMakefile,
"%s_depends: $(RBUILD_TARGET)\n",
module.name.c_str () );
fprintf ( fMakefile,
"\t$(ECHO_RBUILD)\n" );
fprintf ( fMakefile,
"\t$(Q)$(RBUILD_TARGET) -dm%s mingw\n",
module.name.c_str () );
}
string
MingwModuleHandler::GetObjectFilenames ()
{

View file

@ -61,6 +61,7 @@ public:
void GenerateInvocations () const;
void GenerateCleanTarget () const;
void GenerateInstallTarget () const;
void GenerateDependsTarget () const;
static bool ReferenceObjects ( const Module& module );
protected:
virtual void GetModuleSpecificSourceFiles ( std::vector<File*>& sourceFiles );

View file

@ -8,6 +8,7 @@ Configuration::Configuration ()
Verbose = false;
CleanAsYouGo = false;
AutomaticDependencies = true;
CheckDependenciesForModuleOnly = false;
MakeHandlesInstallDirectories = false;
GenerateProxyMakefilesInSourceTree = false;
}

View file

@ -1,5 +1,3 @@
// rbuild.cpp
#include "pch.h"
#include <typeinfo>
@ -20,6 +18,32 @@ static string BuildSystem;
static string RootXmlFile = "ReactOS.xml";
static Configuration configuration;
bool
ParseAutomaticDependencySwitch ( char switchChar2,
char* switchStart )
{
switch ( switchChar2 )
{
case 'd':
configuration.AutomaticDependencies = false;
break;
case 'm':
if ( strlen ( switchStart ) <= 3 )
{
printf ( "Switch -dm requires a module name\n" );
return false;
}
configuration.CheckDependenciesForModuleOnly = true;
configuration.CheckDependenciesForModuleOnlyModule = string(&switchStart[3]);
break;
default:
printf ( "Unknown switch -d%c\n",
switchChar2 );
return false;
}
return true;
}
bool
ParseMakeSwitch ( char switchChar2 )
{
@ -29,7 +53,7 @@ ParseMakeSwitch ( char switchChar2 )
configuration.MakeHandlesInstallDirectories = true;
break;
default:
printf ( "Unknown switch -m%c",
printf ( "Unknown switch -m%c\n",
switchChar2 );
return false;
}
@ -45,7 +69,7 @@ ParseProxyMakefileSwitch ( char switchChar2 )
configuration.GenerateProxyMakefilesInSourceTree = true;
break;
default:
printf ( "Unknown switch -p%c",
printf ( "Unknown switch -p%c\n",
switchChar2 );
return false;
}
@ -66,8 +90,8 @@ ParseSwitch ( int argc, char** argv, int index )
configuration.CleanAsYouGo = true;
break;
case 'd':
configuration.AutomaticDependencies = false;
break;
return ParseAutomaticDependencySwitch ( switchChar2,
argv[index] );
case 'r':
RootXmlFile = string(&argv[index][2]);
break;
@ -76,7 +100,7 @@ ParseSwitch ( int argc, char** argv, int index )
case 'p':
return ParseProxyMakefileSwitch ( switchChar2 );
default:
printf ( "Unknown switch -%c",
printf ( "Unknown switch -%c\n",
switchChar );
return false;
}
@ -109,14 +133,18 @@ main ( int argc, char** argv )
if ( !ParseArguments ( argc, argv ) )
{
printf ( "Generates project files for buildsystems\n\n" );
printf ( " rbuild [switches] buildsystem\n\n" );
printf ( " rbuild [switches] buildsystem\n" );
printf ( "Switches:\n" );
printf ( " -v Be verbose.\n" );
printf ( " -c Clean as you go. Delete generated files as soon as they are not needed anymore.\n" );
printf ( " -d Disable automatic dependencies.\n" );
printf ( " -rfile.xml Name of the root xml file. Default is ReactOS.xml.\n" );
printf ( " -mi Let make handle creation of install directories. Rbuild will not generate the directories.\n" );
printf ( " -ps Generate proxy makefiles in source tree instead of the output tree.\n" );
printf ( " -v Be verbose.\n" );
printf ( " -c Clean as you go. Delete generated files as soon as they are not\n" );
printf ( " needed anymore.\n" );
printf ( " -dd Disable automatic dependencies.\n" );
printf ( " -dm{module} Check only automatic dependencies for this module.\n" );
printf ( " -r{file.xml} Name of the root xml file. Default is ReactOS.xml.\n" );
printf ( " -mi Let make handle creation of install directories. Rbuild will\n" );
printf ( " not generate the directories.\n" );
printf ( " -ps Generate proxy makefiles in source tree instead of the output.\n" );
printf ( " tree.\n" );
printf ( "\n" );
printf ( " buildsystem Target build system. Can be one of:\n" );
printf ( " mingw MinGW\n" );

View file

@ -76,6 +76,8 @@ public:
bool Verbose;
bool CleanAsYouGo;
bool AutomaticDependencies;
bool CheckDependenciesForModuleOnly;
std::string CheckDependenciesForModuleOnlyModule;
bool MakeHandlesInstallDirectories;
bool GenerateProxyMakefilesInSourceTree;
};
@ -571,7 +573,6 @@ public:
AutomaticDependency ( const Project& project );
~AutomaticDependency ();
void Process ();
std::string GetFilename ( const std::string& filename );
bool LocateIncludedFile ( const std::string& directory,
const std::string& includedFilename,
@ -586,13 +587,19 @@ public:
SourceFile* parentSourceFile );
SourceFile* RetrieveFromCache ( const std::string& filename );
void CheckAutomaticDependencies ( bool verbose );
void CheckAutomaticDependencies ( Module& module,
bool verbose );
void CheckAutomaticDependencies ( Module& module,
bool verbose,
bool parseFiles );
void CheckAutomaticDependenciesForFile ( SourceFile* sourceFile );
private:
void GetModuleFiles ( Module& module,
std::vector<File*>& files ) const;
void ProcessModule ( Module& module );
void ProcessFile ( Module& module,
const File& file );
void ParseFiles ();
void ParseFiles ( Module& module );
void ParseFile ( Module& module,
const File& file );
std::map<std::string, SourceFile*> sourcefile_map;
};

View file

@ -36,7 +36,7 @@ SourceFileTest::IncludeTest ()
{
const Project project ( RBUILD_BASE "tests" SSEP "data" SSEP "automaticdependency_include.xml" );
AutomaticDependency automaticDependency ( project );
automaticDependency.Process ();
automaticDependency.ParseFiles ();
ARE_EQUAL( 4, automaticDependency.sourcefile_map.size () );
const SourceFile* include = automaticDependency.RetrieveFromCache ( RBUILD_BASE "tests" SSEP "data" SSEP "sourcefile_include.h" );
IS_NOT_NULL( include );
@ -49,7 +49,7 @@ SourceFileTest::FullParseTest ()
{
const Project project ( RBUILD_BASE "tests" SSEP "data" SSEP "automaticdependency.xml" );
AutomaticDependency automaticDependency ( project );
automaticDependency.Process ();
automaticDependency.ParseFiles ();
ARE_EQUAL( 5, automaticDependency.sourcefile_map.size () );
const SourceFile* header1 = automaticDependency.RetrieveFromCache ( RBUILD_BASE "tests" SSEP "data" SSEP "sourcefile1_header1.h" );
IS_NOT_NULL( header1 );