#
# 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
}
void
-AutomaticDependency::Process ()
+AutomaticDependency::ParseFiles ()
{
for ( size_t i = 0; i < project.modules.size (); i++ )
- ProcessModule ( *project.modules[i] );
+ ParseFiles ( *project.modules[i] );
}
void
}
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,
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 );
+ }
+}
+
+void
+AutomaticDependency::CheckAutomaticDependencies ( Module& module,
+ bool verbose )
+{
+ CheckAutomaticDependencies ( module, verbose, true );
+}
- SourceFile* sourceFile = RetrieveFromCache ( normalizedFilename );
- if ( sourceFile != NULL )
+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 );
}
}
}
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 ();
{
printf ( "Checking automatic dependencies..." );
AutomaticDependency automaticDependency ( ProjectNode );
- automaticDependency.Process ();
automaticDependency.CheckAutomaticDependencies ( configuration.Verbose );
printf ( "done\n" );
}
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;
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 ()
{
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 );
Verbose = false;
CleanAsYouGo = false;
AutomaticDependencies = true;
+ CheckDependenciesForModuleOnly = false;
MakeHandlesInstallDirectories = false;
GenerateProxyMakefilesInSourceTree = false;
}
-// rbuild.cpp
-
#include "pch.h"
#include <typeinfo>
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 )
{
configuration.MakeHandlesInstallDirectories = true;
break;
default:
- printf ( "Unknown switch -m%c",
+ printf ( "Unknown switch -m%c\n",
switchChar2 );
return false;
}
configuration.GenerateProxyMakefilesInSourceTree = true;
break;
default:
- printf ( "Unknown switch -p%c",
+ printf ( "Unknown switch -p%c\n",
switchChar2 );
return false;
}
configuration.CleanAsYouGo = true;
break;
case 'd':
- configuration.AutomaticDependencies = false;
- break;
+ return ParseAutomaticDependencySwitch ( switchChar2,
+ argv[index] );
case 'r':
RootXmlFile = string(&argv[index][2]);
break;
case 'p':
return ParseProxyMakefileSwitch ( switchChar2 );
default:
- printf ( "Unknown switch -%c",
+ printf ( "Unknown switch -%c\n",
switchChar );
return false;
}
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" );
bool Verbose;
bool CleanAsYouGo;
bool AutomaticDependencies;
+ bool CheckDependenciesForModuleOnly;
+ std::string CheckDependenciesForModuleOnlyModule;
bool MakeHandlesInstallDirectories;
bool GenerateProxyMakefilesInSourceTree;
};
AutomaticDependency ( const Project& project );
~AutomaticDependency ();
- void Process ();
std::string GetFilename ( const std::string& filename );
bool LocateIncludedFile ( const std::string& directory,
const std::string& includedFilename,
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;
};
{
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 );
{
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 );