Support module_depends target
Modified: trunk/reactos/Makefile
Modified: trunk/reactos/tools/rbuild/automaticdependency.cpp
Modified: trunk/reactos/tools/rbuild/backend/mingw/mingw.cpp
Modified: trunk/reactos/tools/rbuild/backend/mingw/mingw.h
Modified: trunk/reactos/tools/rbuild/backend/mingw/modulehandler.cpp
Modified: trunk/reactos/tools/rbuild/backend/mingw/modulehandler.h
Modified: trunk/reactos/tools/rbuild/configuration.cpp
Modified: trunk/reactos/tools/rbuild/rbuild.cpp
Modified: trunk/reactos/tools/rbuild/rbuild.h
Modified: trunk/reactos/tools/rbuild/tests/sourcefiletest.cpp

Modified: trunk/reactos/Makefile
--- trunk/reactos/Makefile	2005-06-12 10:14:37 UTC (rev 15867)
+++ trunk/reactos/Makefile	2005-06-12 10:18:51 UTC (rev 15868)
@@ -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

Modified: trunk/reactos/tools/rbuild/automaticdependency.cpp
--- trunk/reactos/tools/rbuild/automaticdependency.cpp	2005-06-12 10:14:37 UTC (rev 15867)
+++ trunk/reactos/tools/rbuild/automaticdependency.cpp	2005-06-12 10:18:51 UTC (rev 15868)
@@ -281,10 +281,10 @@
 }
 
 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 @@
 }
 
 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 @@
 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++ )
+		Module& module = *project.modules[mi];
+		CheckAutomaticDependencies ( module, verbose, false );
+	}
+}
+
+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 )
 		{
-			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 );
 			}
 		}
 	}

Modified: trunk/reactos/tools/rbuild/backend/mingw/mingw.cpp
--- trunk/reactos/tools/rbuild/backend/mingw/mingw.cpp	2005-06-12 10:14:37 UTC (rev 15867)
+++ trunk/reactos/tools/rbuild/backend/mingw/mingw.cpp	2005-06-12 10:18:51 UTC (rev 15868)
@@ -293,15 +293,47 @@
 		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 ();
 	DetectPipeSupport ();
@@ -671,7 +703,6 @@
 	{
 		printf ( "Checking automatic dependencies..." );
 		AutomaticDependency automaticDependency ( ProjectNode );
-		automaticDependency.Process ();
 		automaticDependency.CheckAutomaticDependencies ( configuration.Verbose );
 		printf ( "done\n" );
 	}

Modified: trunk/reactos/tools/rbuild/backend/mingw/mingw.h
--- trunk/reactos/tools/rbuild/backend/mingw/mingw.h	2005-06-12 10:14:37 UTC (rev 15867)
+++ trunk/reactos/tools/rbuild/backend/mingw/mingw.h	2005-06-12 10:18:51 UTC (rev 15868)
@@ -94,6 +94,8 @@
 	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;

Modified: trunk/reactos/tools/rbuild/backend/mingw/modulehandler.cpp
--- trunk/reactos/tools/rbuild/backend/mingw/modulehandler.cpp	2005-06-12 10:14:37 UTC (rev 15867)
+++ trunk/reactos/tools/rbuild/backend/mingw/modulehandler.cpp	2005-06-12 10:18:51 UTC (rev 15868)
@@ -467,6 +467,22 @@
 	          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 ()
 {

Modified: trunk/reactos/tools/rbuild/backend/mingw/modulehandler.h
--- trunk/reactos/tools/rbuild/backend/mingw/modulehandler.h	2005-06-12 10:14:37 UTC (rev 15867)
+++ trunk/reactos/tools/rbuild/backend/mingw/modulehandler.h	2005-06-12 10:18:51 UTC (rev 15868)
@@ -61,6 +61,7 @@
 	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 );

Modified: trunk/reactos/tools/rbuild/configuration.cpp
--- trunk/reactos/tools/rbuild/configuration.cpp	2005-06-12 10:14:37 UTC (rev 15867)
+++ trunk/reactos/tools/rbuild/configuration.cpp	2005-06-12 10:18:51 UTC (rev 15868)
@@ -8,6 +8,7 @@
 	Verbose = false;
 	CleanAsYouGo = false;
 	AutomaticDependencies = true;
+	CheckDependenciesForModuleOnly = false;
 	MakeHandlesInstallDirectories = false;
 	GenerateProxyMakefilesInSourceTree = false;
 }

Modified: trunk/reactos/tools/rbuild/rbuild.cpp
--- trunk/reactos/tools/rbuild/rbuild.cpp	2005-06-12 10:14:37 UTC (rev 15867)
+++ trunk/reactos/tools/rbuild/rbuild.cpp	2005-06-12 10:18:51 UTC (rev 15868)
@@ -1,5 +1,3 @@
-// rbuild.cpp
-
 #include "pch.h"
 #include <typeinfo>
 
@@ -21,6 +19,32 @@
 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 )
 {
 	switch ( switchChar2 )
@@ -29,7 +53,7 @@
 			configuration.MakeHandlesInstallDirectories = true;
 			break;
 		default:
-			printf ( "Unknown switch -m%c",
+			printf ( "Unknown switch -m%c\n",
 			         switchChar2 );
 			return false;
 	}
@@ -45,7 +69,7 @@
 			configuration.GenerateProxyMakefilesInSourceTree = true;
 			break;
 		default:
-			printf ( "Unknown switch -p%c",
+			printf ( "Unknown switch -p%c\n",
 			         switchChar2 );
 			return false;
 	}
@@ -66,8 +90,8 @@
 			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 @@
 		case 'p':
 			return ParseProxyMakefileSwitch ( switchChar2 );
 		default:
-			printf ( "Unknown switch -%c",
+			printf ( "Unknown switch -%c\n",
 			         switchChar );
 			return false;
 	}
@@ -109,14 +133,18 @@
 	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" );

Modified: trunk/reactos/tools/rbuild/rbuild.h
--- trunk/reactos/tools/rbuild/rbuild.h	2005-06-12 10:14:37 UTC (rev 15867)
+++ trunk/reactos/tools/rbuild/rbuild.h	2005-06-12 10:18:51 UTC (rev 15868)
@@ -76,6 +76,8 @@
 	bool Verbose;
 	bool CleanAsYouGo;
 	bool AutomaticDependencies;
+	bool CheckDependenciesForModuleOnly;
+	std::string CheckDependenciesForModuleOnlyModule;
 	bool MakeHandlesInstallDirectories;
 	bool GenerateProxyMakefilesInSourceTree;
 };
@@ -571,7 +573,6 @@
 
 	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 @@
 	                                       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;
 };
 

Modified: trunk/reactos/tools/rbuild/tests/sourcefiletest.cpp
--- trunk/reactos/tools/rbuild/tests/sourcefiletest.cpp	2005-06-12 10:14:37 UTC (rev 15867)
+++ trunk/reactos/tools/rbuild/tests/sourcefiletest.cpp	2005-06-12 10:18:51 UTC (rev 15868)
@@ -36,7 +36,7 @@
 {
 	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 @@
 {
 	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 );