Christoph_vW <Christoph@ApiViewer.de>:
authorCasper Hornstrup <chorns@users.sourceforge.net>
Thu, 8 Sep 2005 16:41:07 +0000 (16:41 +0000)
committerCasper Hornstrup <chorns@users.sourceforge.net>
Thu, 8 Sep 2005 16:41:07 +0000 (16:41 +0000)
Binutils detection

Modified to support cross-compilation

Resolves #707

svn path=/trunk/; revision=17744

reactos/tools/rbuild/backend/mingw/mingw.cpp
reactos/tools/rbuild/backend/mingw/mingw.h
reactos/tools/rbuild/exception.cpp
reactos/tools/rbuild/exception.h

index c56e530..fc4a668 100644 (file)
@@ -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 ()
 {
index 532eed0..27ad081 100644 (file)
@@ -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 ();
index 86d6a12..7876727 100644 (file)
@@ -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;
+}
index a9de393..0db4af5 100644 (file)
@@ -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 */