From 21501cda538d9feb4f7eb7371ac312c14168d4cf Mon Sep 17 00:00:00 2001 From: Casper Hornstrup Date: Thu, 8 Sep 2005 16:41:07 +0000 Subject: [PATCH] Christoph_vW : Binutils detection Modified to support cross-compilation Resolves #707 svn path=/trunk/; revision=17744 --- reactos/tools/rbuild/backend/mingw/mingw.cpp | 106 +++++++++++++++++++ reactos/tools/rbuild/backend/mingw/mingw.h | 6 ++ reactos/tools/rbuild/exception.cpp | 11 ++ reactos/tools/rbuild/exception.h | 10 ++ 4 files changed, 133 insertions(+) diff --git a/reactos/tools/rbuild/backend/mingw/mingw.cpp b/reactos/tools/rbuild/backend/mingw/mingw.cpp index c56e5300ebf..fc4a668cfa0 100644 --- a/reactos/tools/rbuild/backend/mingw/mingw.cpp +++ b/reactos/tools/rbuild/backend/mingw/mingw.cpp @@ -361,6 +361,7 @@ void MingwBackend::ProcessNormal () { DetectCompiler (); + DetectBinutils (); DetectNetwideAssembler (); DetectPipeSupport (); DetectPCHSupport (); @@ -813,6 +814,111 @@ MingwBackend::TryToDetectThisNetwideAssembler ( const string& assembler ) return (exitcode == 0); } +bool +MingwBackend::TryToDetectThisBinutils ( const string& binutils ) +{ + string command = ssprintf ( + "%s -v 1>%s", + binutils.c_str (), + NUL, + NUL ); + int exitcode = system ( command.c_str () ); + return (exitcode == 0); +} + +string +MingwBackend::GetBinutilsVersion ( const string& binutilsCommand ) +{ + FILE *fp; + int ch, i; + char buffer[81]; + + string versionCommand = ssprintf ( "%s -v", + binutilsCommand.c_str (), + NUL, + NUL ); + fp = popen ( versionCommand.c_str () , "r" ); + for( i = 0; ( i < 80 ) && ( feof ( fp ) == 0 ); i++ ) + { + buffer[i] = (char) ch; + ch = fgetc( fp ); + } + buffer[i] = '\0'; + pclose ( fp ); + + char separators[] = " "; + char *token; + char *prevtoken; + + token = strtok ( buffer, separators ); + while ( token != NULL ) + { + prevtoken = token; + token = strtok ( NULL, separators ); + } + string version = string ( prevtoken ); + int firstSpace = version.find_last_not_of ( " \t" ); + if ( firstSpace != -1 ) + return string ( version, 0, firstSpace - 1); + else + return version; +} + +bool +MingwBackend::IsSupportedBinutilsVersion ( const string& binutilsVersion ) +{ + if ( ( ( strcmp ( binutilsVersion.c_str (), "20040902") >= 0 ) && + ( strcmp ( binutilsVersion.c_str (), "20041008") <= 0 ) ) || + ( strcmp ( binutilsVersion.c_str (), "20031001") < 0 ) ) + return false; + else + return true; +} + +void +MingwBackend::DetectBinutils () +{ + printf ( "Detecting binutils..." ); + + bool detectedBinutils = false; + const string& ROS_PREFIXValue = Environment::GetVariable ( "ROS_PREFIX" ); + if ( ROS_PREFIXValue.length () > 0 ) + { + binutilsPrefix = ROS_PREFIXValue; + binutilsCommand = binutilsPrefix + "-ld"; + detectedBinutils = TryToDetectThisBinutils ( binutilsCommand ); + } +#if defined(WIN32) + if ( !detectedBinutils ) + { + binutilsPrefix = ""; + binutilsCommand = "ld"; + detectedBinutils = TryToDetectThisBinutils ( binutilsCommand ); + } +#endif + if ( !detectedBinutils ) + { + binutilsPrefix = "mingw32"; + binutilsCommand = binutilsPrefix + "-ld"; + detectedBinutils = TryToDetectThisBinutils ( binutilsCommand ); + } + if ( detectedBinutils ) + { + const string& binutilsVersion = GetBinutilsVersion ( binutilsCommand ); + if ( IsSupportedBinutilsVersion ( binutilsVersion ) ) + printf ( "detected (%s)\n", binutilsCommand.c_str () ); + else + { + printf ( "detected (%s), but with unsupported version (%s)\n", + binutilsCommand.c_str (), + binutilsVersion.c_str () ); + throw UnsupportedBuildToolException ( binutilsCommand, binutilsVersion ); + } + } + else + printf ( "not detected\n" ); +} + void MingwBackend::DetectNetwideAssembler () { diff --git a/reactos/tools/rbuild/backend/mingw/mingw.h b/reactos/tools/rbuild/backend/mingw/mingw.h index 532eed07f2a..27ad0812916 100644 --- a/reactos/tools/rbuild/backend/mingw/mingw.h +++ b/reactos/tools/rbuild/backend/mingw/mingw.h @@ -72,6 +72,8 @@ public: std::string compilerPrefix; std::string compilerCommand; std::string nasmCommand; + std::string binutilsPrefix; + std::string binutilsCommand; bool usePipe; Directory* intermediateDirectory; Directory* outputDirectory; @@ -108,6 +110,10 @@ private: bool TryToDetectThisCompiler ( const std::string& compiler ); void DetectCompiler (); bool TryToDetectThisNetwideAssembler ( const std::string& assembler ); + bool TryToDetectThisBinutils ( const std::string& binutils ); + std::string GetBinutilsVersion ( const std::string& binutilsCommand ); + bool IsSupportedBinutilsVersion ( const std::string& binutilsVersion ); + void DetectBinutils (); void DetectNetwideAssembler (); void DetectPipeSupport (); void DetectPCHSupport (); diff --git a/reactos/tools/rbuild/exception.cpp b/reactos/tools/rbuild/exception.cpp index 86d6a122924..7876727e3d5 100644 --- a/reactos/tools/rbuild/exception.cpp +++ b/reactos/tools/rbuild/exception.cpp @@ -187,3 +187,14 @@ InvocationFailedException::InvocationFailedException ( const std::string& comman Command = command; ExitCode = exitcode; } + + +UnsupportedBuildToolException::UnsupportedBuildToolException ( const std::string& buildTool, + const std::string& version ) + : Exception ( "Build tool '%s' with version '%s' is unsupported. Please upgrade your build tool.", + buildTool.c_str (), + version.c_str () ) +{ + BuildTool = buildTool; + Version = version; +} diff --git a/reactos/tools/rbuild/exception.h b/reactos/tools/rbuild/exception.h index a9de393c93c..0db4af59bec 100644 --- a/reactos/tools/rbuild/exception.h +++ b/reactos/tools/rbuild/exception.h @@ -139,4 +139,14 @@ public: int ExitCode; }; + +class UnsupportedBuildToolException : public Exception +{ +public: + UnsupportedBuildToolException ( const std::string& buildtool, + const std::string& version ); + std::string BuildTool; + std::string Version; +}; + #endif /* __EXCEPTION_H */ -- 2.17.1