modified tools/rbuild/backend/mingw/mingw.cpp

modified   tools/rbuild/backend/mingw/mingw.h
   From now on, the MinGW back-end will also support the Microsoft command line C/C++ compiler (cl) and incremental linker (link). Support is currently limited to detecting the tools, and invoking them with the wrong arguments. Only Windows hosts are currently supported

added      tools/rbuild/backend/mingw/mstools_detection.cpp
modified   tools/rbuild/rbuild.mak
   Auto-detection of Microsoft compiler and linker: if rbuild finds them in the path, it will use those. Otherwise, it will look for the highest version installed by any of the supported Microsoft products. Supported Microsoft products are Visual Studio 2005 and higher, Visual C++ Express and Windows DDK version 6001 and higher. Optimizing versions of the compiler will take precedence over "standard edition" compilers, regardless of version number

modified   tools/rbuild/configuration.cpp
modified   tools/rbuild/rbuild.cpp
modified   tools/rbuild/rbuild.h
   New command line options for rbuild to choose the tools set for the MinGW back-end: -Mc<compiler set>, -Ml<linker set>, -M<build tools set>. Defaults to -Mgnu, so that support for Microsoft tools has to be opted into

svn path=/trunk/; revision=41343
This commit is contained in:
KJK::Hyperion 2009-06-07 23:33:42 +00:00
parent 82a6743526
commit 4a745139c1
7 changed files with 2475 additions and 65 deletions

View file

@ -726,32 +726,47 @@ MingwBackend::DetectCompiler ()
printf ( "Detecting compiler..." );
bool detectedCompiler = false;
const string& ROS_PREFIXValue = Environment::GetVariable ( "ROS_PREFIX" );
if ( ROS_PREFIXValue.length () > 0 )
bool supportedCompiler = false;
string compilerVersion;
if ( ProjectNode.configuration.Compiler == GnuGcc )
{
compilerPrefix = ROS_PREFIXValue;
compilerCommand = compilerPrefix + "-gcc";
detectedCompiler = TryToDetectThisCompiler ( compilerCommand );
}
const string& ROS_PREFIXValue = Environment::GetVariable ( "ROS_PREFIX" );
if ( ROS_PREFIXValue.length () > 0 )
{
compilerPrefix = ROS_PREFIXValue;
compilerCommand = compilerPrefix + "-gcc";
detectedCompiler = TryToDetectThisCompiler ( compilerCommand );
}
#if defined(WIN32)
if ( !detectedCompiler )
{
compilerPrefix = "";
compilerCommand = "gcc";
detectedCompiler = TryToDetectThisCompiler ( compilerCommand );
}
if ( !detectedCompiler )
{
compilerPrefix = "";
compilerCommand = "gcc";
detectedCompiler = TryToDetectThisCompiler ( compilerCommand );
}
#endif
if ( !detectedCompiler )
if ( !detectedCompiler )
{
compilerPrefix = "mingw32";
compilerCommand = compilerPrefix + "-gcc";
detectedCompiler = TryToDetectThisCompiler ( compilerCommand );
}
if ( detectedCompiler )
compilerVersion = GetCompilerVersion ( compilerCommand );
supportedCompiler = IsSupportedCompilerVersion ( compilerVersion );
}
else if ( ProjectNode.configuration.Compiler == MicrosoftC )
{
compilerPrefix = "mingw32";
compilerCommand = compilerPrefix + "-gcc";
detectedCompiler = TryToDetectThisCompiler ( compilerCommand );
detectedCompiler = DetectMicrosoftCompiler ( compilerVersion );
supportedCompiler = true; // TODO
}
if ( detectedCompiler )
{
string compilerVersion = GetCompilerVersion ( compilerCommand );
if ( IsSupportedCompilerVersion ( compilerVersion ) )
if ( supportedCompiler )
printf ( "detected (%s %s)\n", compilerCommand.c_str (), compilerVersion.c_str() );
else
{
@ -953,34 +968,50 @@ MingwBackend::DetectBinutils ()
printf ( "Detecting binutils..." );
bool detectedBinutils = false;
const string& ROS_PREFIXValue = Environment::GetVariable ( "ROS_PREFIX" );
bool supportedBinutils = false;
string binutilsVersion;
if ( ROS_PREFIXValue.length () > 0 )
if ( ProjectNode.configuration.Linker == GnuLd )
{
binutilsPrefix = ROS_PREFIXValue;
binutilsCommand = binutilsPrefix + "-ld";
manualBinutilsSetting = true;
detectedBinutils = true;
}
const string& ROS_PREFIXValue = Environment::GetVariable ( "ROS_PREFIX" );
if ( ROS_PREFIXValue.length () > 0 )
{
binutilsPrefix = ROS_PREFIXValue;
binutilsCommand = binutilsPrefix + "-ld";
manualBinutilsSetting = true;
detectedBinutils = true;
}
#if defined(WIN32)
if ( !detectedBinutils )
{
binutilsPrefix = "";
binutilsCommand = "ld";
detectedBinutils = TryToDetectThisBinutils ( binutilsCommand );
}
if ( !detectedBinutils )
{
binutilsPrefix = "";
binutilsCommand = "ld";
detectedBinutils = TryToDetectThisBinutils ( binutilsCommand );
}
#endif
if ( !detectedBinutils )
{
binutilsPrefix = "mingw32";
binutilsCommand = binutilsPrefix + "-ld";
detectedBinutils = TryToDetectThisBinutils ( binutilsCommand );
if ( !detectedBinutils )
{
binutilsPrefix = "mingw32";
binutilsCommand = binutilsPrefix + "-ld";
detectedBinutils = TryToDetectThisBinutils ( binutilsCommand );
}
if ( detectedBinutils )
{
binutilsVersion = GetBinutilsVersionDate ( binutilsCommand );
supportedBinutils = IsSupportedBinutilsVersion ( binutilsVersion );
}
}
else if ( ProjectNode.configuration.Linker == MicrosoftLink )
{
detectedBinutils = DetectMicrosoftLinker ( binutilsVersion );
supportedBinutils = true; // TODO
}
if ( detectedBinutils )
{
string binutilsVersion = GetBinutilsVersionDate ( binutilsCommand );
if ( IsSupportedBinutilsVersion ( binutilsVersion ) )
printf ( "detected (%s %s)\n", binutilsCommand.c_str (), GetBinutilsVersion( binutilsCommand ).c_str() );
if ( supportedBinutils )
printf ( "detected (%s %s)\n", binutilsCommand.c_str (), binutilsVersion.c_str() );
else
{
printf ( "detected (%s), but with unsupported version (%s)\n",
@ -1022,33 +1053,36 @@ MingwBackend::DetectNetwideAssembler ()
void
MingwBackend::DetectPipeSupport ()
{
printf ( "Detecting compiler -pipe support..." );
string pipe_detection = "tools" + sSep + "rbuild" + sSep + "backend" + sSep + "mingw" + sSep + "pipe_detection.c";
string pipe_detectionObjectFilename = ReplaceExtension ( pipe_detection,
".o" );
string command = ssprintf (
"%s -pipe -c %s -o %s 1>%s 2>%s",
FixSeparatorForSystemCommand(compilerCommand).c_str (),
pipe_detection.c_str (),
pipe_detectionObjectFilename.c_str (),
NUL,
NUL );
int exitcode = system ( command.c_str () );
FILE* f = fopen ( pipe_detectionObjectFilename.c_str (), "rb" );
if ( f )
if ( ProjectNode.configuration.Compiler == GnuGcc )
{
usePipe = (exitcode == 0);
fclose ( f );
unlink ( pipe_detectionObjectFilename.c_str () );
}
else
usePipe = false;
printf ( "Detecting compiler -pipe support..." );
if ( usePipe )
printf ( "detected\n" );
else
printf ( "not detected\n" );
string pipe_detection = "tools" + sSep + "rbuild" + sSep + "backend" + sSep + "mingw" + sSep + "pipe_detection.c";
string pipe_detectionObjectFilename = ReplaceExtension ( pipe_detection,
".o" );
string command = ssprintf (
"%s -pipe -c %s -o %s 1>%s 2>%s",
FixSeparatorForSystemCommand(compilerCommand).c_str (),
pipe_detection.c_str (),
pipe_detectionObjectFilename.c_str (),
NUL,
NUL );
int exitcode = system ( command.c_str () );
FILE* f = fopen ( pipe_detectionObjectFilename.c_str (), "rb" );
if ( f )
{
usePipe = (exitcode == 0);
fclose ( f );
unlink ( pipe_detectionObjectFilename.c_str () );
}
else
usePipe = false;
if ( usePipe )
printf ( "detected\n" );
else
printf ( "not detected\n" );
}
}
void
@ -1056,7 +1090,7 @@ MingwBackend::DetectPCHSupport ()
{
printf ( "Detecting compiler pre-compiled header support..." );
if ( configuration.PrecompiledHeadersEnabled )
if ( configuration.PrecompiledHeadersEnabled && ProjectNode.configuration.Compiler == GnuGcc )
{
string path = "tools" + sSep + "rbuild" + sSep + "backend" + sSep + "mingw" + sSep + "pch_detection.h";
string cmd = ssprintf (

View file

@ -45,10 +45,12 @@ public:
std::string AddDirectoryTarget ( const std::string& directory,
Directory* directoryTree );
const Module& GetAliasedModuleOrModule ( const Module& module ) const;
bool compilerNeedsHelper;
std::string compilerPrefix;
std::string compilerCommand;
std::string nasmCommand;
std::string binutilsPrefix;
bool binutilsNeedsHelper;
std::string binutilsCommand;
bool usePipe, manualBinutilsSetting;
Directory* intermediateDirectory;
@ -115,6 +117,8 @@ private:
void GenerateDirectoryTargets ();
FILE* fMakefile;
bool use_pch;
bool DetectMicrosoftCompiler ( std::string& version );
bool DetectMicrosoftLinker ( std::string& version );
};

File diff suppressed because it is too large Load diff

View file

@ -33,6 +33,8 @@ Configuration::Configuration ()
InstallFiles = false;
UseConfigurationInPath = false;
UseVSVersionInPath = false;
Compiler = GnuGcc;
Linker = GnuLd;
}
Configuration::~Configuration ()

View file

@ -160,6 +160,58 @@ ParseVCProjectSwitch (
return true;
}
bool
ParseMingwSwitch ( char* switchStart )
{
switchStart += 2;
if ( *switchStart == 'c' )
{
++ switchStart;
if ( strcmp ( switchStart, "msc" ) == 0 )
configuration.Compiler = MicrosoftC;
else if ( strcmp ( switchStart, "gcc" ) == 0 )
configuration.Compiler = GnuGcc;
else
{
printf ( "Unknown value of -Mc: %s\n", switchStart );
return false;
}
}
else if ( *switchStart == 'l' )
{
++ switchStart;
if ( strcmp ( switchStart, "mslink" ) == 0 )
configuration.Linker = MicrosoftLink;
else if ( strcmp ( switchStart, "ld" ) == 0 )
configuration.Linker = GnuLd;
else
{
printf ( "Unknown value of -Ml: %s\n", switchStart );
return false;
}
}
else if ( strcmp ( switchStart, "microsoft" ) == 0 )
{
configuration.Compiler = MicrosoftC;
configuration.Linker = MicrosoftLink;
}
else if ( strcmp ( switchStart, "gnu" ) == 0 )
{
configuration.Compiler = GnuGcc;
configuration.Linker = GnuLd;
}
else
{
printf ( "Unknown value of -M: %s\n", switchStart );
return false;
}
return true;
}
bool
ParseMakeSwitch ( char switchChar2 )
{
@ -252,6 +304,8 @@ ParseSwitch ( int argc, char** argv, int index )
break;
case 'm':
return ParseMakeSwitch ( switchChar2 );
case 'M':
return ParseMingwSwitch ( argv[index] );
case 'p':
return ParseProxyMakefileSwitch ( switchChar2 );
case 'D':
@ -309,6 +363,14 @@ main ( int argc, char** argv )
printf ( " tree.\n" );
printf ( " -vs{version} Version of MS VS project files. Default is %s.\n", MS_VS_DEF_VERSION );
printf ( " -vo{version|configuration} Adds subdirectory path to the default Intermediate-Outputdirectory.\n" );
printf ( " -Mc{compiler} Compiler to use for mingw backend. Can be one of:\n" );
printf ( " %-10s %s (default)\n", "gcc", "GNU compiler collection (gcc, g++)\n");
printf ( " %-10s %s\n", "msc", "Microsoft Visual C++ (cl)\n");
printf ( " -Ml{compiler} Linker to use for mingw backend. Can be one of:\n" );
printf ( " %-10s %s (default)\n", "ld", "GNU binutils (ld, dlltool)\n");
printf ( " %-10s %s\n", "mslink", "Microsoft Linker (link, lib)\n");
printf ( " -Mmicrosoft Same as -Mcmsc -Mlmslink\n" );
printf ( " -Mgnu Same as -Mcgcc -Mlld\n" );
printf ( " -Dvar=val Set the value of 'var' variable to 'val'.\n" );
printf ( "\n" );
printf ( " buildsystem Target build system. Can be one of:\n" );

View file

@ -155,6 +155,18 @@ enum DependenciesType
FullDependencies
};
enum CompilerSet
{
GnuGcc,
MicrosoftC
};
enum LinkerSet
{
GnuLd,
MicrosoftLink
};
class Configuration
{
public:
@ -174,6 +186,8 @@ public:
bool MakeHandlesInstallDirectories;
bool GenerateProxyMakefilesInSourceTree;
bool InstallFiles;
CompilerSet Compiler;
LinkerSet Linker;
};
class Environment

View file

@ -199,6 +199,7 @@ RBUILD_TEST_TARGET = \
RBUILD_BACKEND_MINGW_BASE_SOURCES = $(addprefix $(RBUILD_MINGW_BASE_), \
mingw.cpp \
modulehandler.cpp \
mstools_detection.cpp \
proxymakefile.cpp \
rule.cpp \
)
@ -349,6 +350,10 @@ RBUILD_HOST_CXXFLAGS = -I$(RBUILD_BASE) -I$(TOOLS_BASE) -I$(INFLIB_BASE) $(TOOLS
RBUILD_HOST_LFLAGS = $(TOOLS_LFLAGS)
ifeq ($(HOST),mingw32-windows)
RBUILD_HOST_LFLAGS += -loleaut32 -lole32 -luuid
endif
.PHONY: rbuild
rbuild: $(RBUILD_TARGET)
host_gpp += -g
@ -477,6 +482,10 @@ $(RBUILD_MINGW_INT_)modulehandler.o: $(RBUILD_MINGW_BASE_)modulehandler.cpp $(RB
$(ECHO_HOSTCC)
${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
$(RBUILD_MINGW_INT_)mstools_detection.o: $(RBUILD_MINGW_BASE_)mstools_detection.cpp $(RBUILD_HEADERS) | $(RBUILD_MINGW_INT)
$(ECHO_HOSTCC)
${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
$(RBUILD_MINGW_INT_)proxymakefile.o: $(RBUILD_MINGW_BASE_)proxymakefile.cpp $(RBUILD_HEADERS) | $(RBUILD_MINGW_INT)
$(ECHO_HOSTCC)
${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@