From d72d41723ccd5a383f2aa17f4b8aa768661f1fa1 Mon Sep 17 00:00:00 2001 From: Casper Hornstrup Date: Sat, 2 Apr 2005 16:46:08 +0000 Subject: [PATCH] Have rbuild create the output directories svn path=/branches/xmlbuildsystem/; revision=14449 --- reactos/tools/rbuild/backend/mingw/mingw.cpp | 136 ++++++++++++++---- reactos/tools/rbuild/backend/mingw/mingw.h | 2 +- .../rbuild/backend/mingw/modulehandler.cpp | 27 +++- .../rbuild/backend/mingw/modulehandler.h | 1 + reactos/tools/rbuild/exception.cpp | 2 +- reactos/tools/rbuild/exception.h | 2 +- 6 files changed, 136 insertions(+), 34 deletions(-) diff --git a/reactos/tools/rbuild/backend/mingw/mingw.cpp b/reactos/tools/rbuild/backend/mingw/mingw.cpp index e3ef7868a0e..b16197aca9f 100644 --- a/reactos/tools/rbuild/backend/mingw/mingw.cpp +++ b/reactos/tools/rbuild/backend/mingw/mingw.cpp @@ -3,8 +3,15 @@ #include "mingw.h" #include +#include #include "modulehandler.h" +#ifdef WIN32 +#define MKDIR(s) mkdir(s) +#else +#define MKDIR(s) mkdir(s, 0755) +#endif + using std::string; using std::vector; using std::set; @@ -20,7 +27,17 @@ public: directory_map subdirs; Directory ( const string& name ); void Add ( const char* subdir ); - void CreateRule ( FILE* f, const string& parent ); + void GenerateTree ( const string& parent ); +private: + bool mkdir_p ( const char* path ); + string ReplaceVariable ( string name, + string value, + string path ); + string GetIntermediatePath (); + string GetOutputPath (); + void ResolveVariablesInPath ( char* buf, + string path ); + bool CreateDirectory ( string path ); }; Directory::Directory ( const string& name_ ) @@ -30,6 +47,16 @@ Directory::Directory ( const string& name_ ) void Directory::Add ( const char* subdir ) { + size_t i; + string s1 = string ( subdir ); + if ( ( i = s1.find ( '$' ) ) != string::npos ) + { + throw InvalidOperationException ( __FILE__, + __LINE__, + "No environment variables can be used here. Path was %s", + subdir ); + } + const char* p = strpbrk ( subdir, "/\\" ); if ( !p ) p = subdir + strlen(subdir); @@ -40,27 +67,90 @@ void Directory::Add ( const char* subdir ) subdirs[s]->Add ( p ); } +bool +Directory::mkdir_p ( const char* path ) +{ + DIR *directory; + directory = opendir ( path ); + if ( directory != NULL ) + { + closedir ( directory ); + return false; + } + + if ( MKDIR ( path ) != 0 ) + throw AccessDeniedException ( string ( path ) ); + return true; +} + +bool +Directory::CreateDirectory ( string path ) +{ + size_t index = 0; + size_t nextIndex; + if ( isalpha ( path[0] ) && path[1] == ':' && path[2] == CSEP ) + { + nextIndex = path.find ( CSEP, 3); + } + else + nextIndex = path.find ( CSEP ); + + bool directoryWasCreated = false; + while ( nextIndex != string::npos ) + { + nextIndex = path.find ( CSEP, index + 1 ); + directoryWasCreated = mkdir_p ( path.substr ( 0, nextIndex ).c_str () ); + index = nextIndex; + } + return directoryWasCreated; +} + +string +Directory::ReplaceVariable ( string name, + string value, + string path ) +{ + size_t i = path.find ( name ); + if ( i != string::npos ) + return path.replace ( i, name.length (), value ); + else + return path; +} + +string +Directory::GetIntermediatePath () +{ + return "obj-i386"; +} + +string +Directory::GetOutputPath () +{ + return "output-i386"; +} + void -Directory::CreateRule ( FILE* f, const string& parent ) +Directory::ResolveVariablesInPath ( char* buf, + string path ) +{ + string s = ReplaceVariable ( "$(INTERMEDIATE)", GetIntermediatePath (), path ); + s = ReplaceVariable ( "$(OUTPUT)", GetOutputPath (), s ); + strcpy ( buf, s.c_str () ); +} + +void +Directory::GenerateTree ( const string& parent ) { string path; if ( parent.size() ) { - fprintf ( f, - "%s%c%s: %s\n", - parent.c_str (), - CSEP, - name.c_str (), - parent.c_str () ); - - fprintf ( f, - "\t$(ECHO_MKDIR)\n" ); - - fprintf ( f, - "\t${mkdir} $@\n" ); - + char buf[256]; + path = parent + SSEP + name; + ResolveVariablesInPath ( buf, path ); + if ( CreateDirectory ( buf ) ) + printf ( "Created %s\n", buf ); } else path = name; @@ -69,7 +159,7 @@ Directory::CreateRule ( FILE* f, const string& parent ) i != subdirs.end(); ++i ) { - i->second->CreateRule ( f, path ); + i->second->GenerateTree ( path ); } } @@ -164,7 +254,7 @@ MingwBackend::Process () delete v[i]; } - GenerateDirectoryTargets (); + GenerateDirectories (); CheckAutomaticDependencies (); CloseMakefile (); } @@ -412,16 +502,10 @@ MingwBackend::IncludeDirectoryTarget ( const string& directory ) const } void -MingwBackend::GenerateDirectoryTargets () +MingwBackend::GenerateDirectories () { - // TODO FIXME - write new directory creation - for ( int i = 0; i < 2; i++ ) - { - Directory& d = *(!i ? int_directories : out_directories); - if ( i ) fprintf ( fMakefile, "ifneq ($(INTERMEDIATE),$(OUTPUT))\n" ); - d.CreateRule ( fMakefile, "" ); - if ( i ) fprintf ( fMakefile, "endif\n" ); - } + int_directories->GenerateTree ( "" ); + out_directories->GenerateTree ( "" ); } string diff --git a/reactos/tools/rbuild/backend/mingw/mingw.h b/reactos/tools/rbuild/backend/mingw/mingw.h index 35c4f318af3..1ab974bcaac 100644 --- a/reactos/tools/rbuild/backend/mingw/mingw.h +++ b/reactos/tools/rbuild/backend/mingw/mingw.h @@ -22,7 +22,7 @@ private: void GenerateGlobalCFlagsAndProperties ( const char* op, IfableData& data ) const; std::string GenerateProjectLFLAGS () const; - void GenerateDirectoryTargets (); + void GenerateDirectories (); void GenerateGlobalVariables () const; bool IncludeInAllTarget ( const Module& module ) const; void GenerateAllTarget ( const std::vector& handlers ) const; diff --git a/reactos/tools/rbuild/backend/mingw/modulehandler.cpp b/reactos/tools/rbuild/backend/mingw/modulehandler.cpp index 8046130d0df..3fa62b07d60 100644 --- a/reactos/tools/rbuild/backend/mingw/modulehandler.cpp +++ b/reactos/tools/rbuild/backend/mingw/modulehandler.cpp @@ -100,11 +100,29 @@ MingwModuleHandler::SetUsePch ( bool b ) use_pch = b; } +/* static*/ string +MingwModuleHandler::RemoveVariables ( string path) +{ + size_t i = path.find ( '$' ); + if ( i != string::npos ) + { + size_t j = path.find ( ')', i ); + if ( j != string::npos ) + { + if ( j + 2 < path.length () && path[j + 1] == CSEP ) + return path.substr ( j + 2); + else + return path.substr ( j + 1); + } + } + return path; +} + /*static*/ string MingwModuleHandler::PassThruCacheDirectory ( const string &file, bool out ) { - string directory ( GetDirectory ( file ) ); + string directory ( GetDirectory ( RemoveVariables ( file ) ) ); string generatedFilesDirectory = backend->AddDirectoryTarget ( directory, out ); if ( directory.find ( generatedFilesDirectory ) != string::npos ) /* This path already includes the generated files directory variable */ @@ -347,10 +365,9 @@ MingwModuleHandler::GetObjectFilename ( else newExtension = ".o"; string obj_file = PassThruCacheDirectory ( - FixupTargetFilename ( - ReplaceExtension ( - sourceFilename, - newExtension ) ), + FixupTargetFilename ( ReplaceExtension ( + RemoveVariables ( sourceFilename ), + newExtension ) ), false ); if ( pclean_files ) { diff --git a/reactos/tools/rbuild/backend/mingw/modulehandler.h b/reactos/tools/rbuild/backend/mingw/modulehandler.h index b7ec56d5eb3..c5b820cc107 100644 --- a/reactos/tools/rbuild/backend/mingw/modulehandler.h +++ b/reactos/tools/rbuild/backend/mingw/modulehandler.h @@ -146,6 +146,7 @@ private: void GetInvocationDependencies ( const Module& module, string_list& dependencies ); bool IsWineModule () const; std::string GetDefinitionFilename () const; + static std::string RemoveVariables ( std::string path); public: const Module& module; string_list clean_files; diff --git a/reactos/tools/rbuild/exception.cpp b/reactos/tools/rbuild/exception.cpp index 47e0d32109c..2038a1757e4 100644 --- a/reactos/tools/rbuild/exception.cpp +++ b/reactos/tools/rbuild/exception.cpp @@ -75,7 +75,7 @@ FileNotFoundException::FileNotFoundException ( const string& filename ) AccessDeniedException::AccessDeniedException ( const string& filename) - : Exception ( "Access denied to file '%s'.", + : Exception ( "Access denied to file or directory '%s'.", filename.c_str() ) { Filename = filename; diff --git a/reactos/tools/rbuild/exception.h b/reactos/tools/rbuild/exception.h index 2adc4380eb9..3530be65a51 100644 --- a/reactos/tools/rbuild/exception.h +++ b/reactos/tools/rbuild/exception.h @@ -13,7 +13,7 @@ public: protected: Exception (); void SetMessage ( const char* message, - va_list args); + va_list args ); };