Support module_depends target
authorCasper Hornstrup <chorns@users.sourceforge.net>
Sun, 12 Jun 2005 10:18:51 +0000 (10:18 +0000)
committerCasper Hornstrup <chorns@users.sourceforge.net>
Sun, 12 Jun 2005 10:18:51 +0000 (10:18 +0000)
svn path=/trunk/; revision=15868

reactos/Makefile
reactos/tools/rbuild/automaticdependency.cpp
reactos/tools/rbuild/backend/mingw/mingw.cpp
reactos/tools/rbuild/backend/mingw/mingw.h
reactos/tools/rbuild/backend/mingw/modulehandler.cpp
reactos/tools/rbuild/backend/mingw/modulehandler.h
reactos/tools/rbuild/configuration.cpp
reactos/tools/rbuild/rbuild.cpp
reactos/tools/rbuild/rbuild.h
reactos/tools/rbuild/tests/sourcefiletest.cpp

index f19a598..f544b22 100644 (file)
 #
 #    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
index 422f4cd..8c8a360 100644 (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 );
+       }
+}
+
+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 );
                        }
                }
        }
index 9b8a970..7e9486c 100644 (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" );
        }
index 85da110..e92a1bd 100644 (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;
index b351f24..074c272 100644 (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 ()
 {
index 8161f32..a6b5b8b 100644 (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 );
index dd70744..986999b 100644 (file)
@@ -8,6 +8,7 @@ Configuration::Configuration ()
        Verbose = false;
        CleanAsYouGo = false;
        AutomaticDependencies = true;
+       CheckDependenciesForModuleOnly = false;
        MakeHandlesInstallDirectories = false;
        GenerateProxyMakefilesInSourceTree = false;
 }
index 2f44fdb..ed535de 100644 (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" );
index 7eb1a4f..bc1e14b 100644 (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;
 };
 
index a7af1a4..0b736c0 100644 (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 );