📄 mingw.cpp
字号:
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 &&
( ( ch = fgetc( fp ) ) != -1 ) );
i++ )
{
buffer[i] = (char) ch;
}
buffer[i] = '\0';
pclose ( fp );
char separators[] = " ";
char *token;
char *prevtoken = NULL;
token = strtok ( buffer, separators );
while ( token != NULL )
{
prevtoken = token;
token = strtok ( NULL, separators );
}
string version = string ( prevtoken );
int lastDigit = version.find_last_not_of ( "\t\r\n" );
if ( lastDigit != -1 )
return string ( version, 0, lastDigit+1 );
else
return version;
}
bool
MingwBackend::IsSupportedBinutilsVersion ( const string& binutilsVersion )
{
if ( manualBinutilsSetting ) return true;
/* linux */
if ( binutilsVersion.find('.') != std::string::npos )
{
/* TODO: blacklist versions on version number instead of date */
return true;
}
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";
manualBinutilsSetting = true;
detectedBinutils = true;
}
#if defined(WIN32)
if ( !detectedBinutils )
{
binutilsPrefix = "";
binutilsCommand = "ld";
detectedBinutils = TryToDetectThisBinutils ( binutilsCommand );
}
#endif
if ( !detectedBinutils )
{
binutilsPrefix = "mingw32";
binutilsCommand = binutilsPrefix + "-ld";
detectedBinutils = TryToDetectThisBinutils ( binutilsCommand );
}
if ( detectedBinutils )
{
string binutilsVersion = GetBinutilsVersionDate ( binutilsCommand );
if ( IsSupportedBinutilsVersion ( binutilsVersion ) )
printf ( "detected (%s %s)\n", binutilsCommand.c_str (), GetBinutilsVersion( 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 ()
{
printf ( "Detecting netwide assembler..." );
nasmCommand = "nasm";
bool detectedNasm = TryToDetectThisNetwideAssembler ( nasmCommand );
#if defined(WIN32)
if ( !detectedNasm )
{
nasmCommand = "nasmw";
detectedNasm = TryToDetectThisNetwideAssembler ( nasmCommand );
}
#endif
if ( !detectedNasm )
{
nasmCommand = "yasm";
detectedNasm = TryToDetectThisNetwideAssembler ( nasmCommand );
}
if ( detectedNasm )
printf ( "detected (%s %s)\n", nasmCommand.c_str (), GetNetwideAssemblerVersion( nasmCommand ).c_str() );
else
printf ( "not detected\n" );
}
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 )
{
usePipe = (exitcode == 0);
fclose ( f );
unlink ( pipe_detectionObjectFilename.c_str () );
}
else
usePipe = false;
if ( usePipe )
printf ( "detected\n" );
else
printf ( "not detected\n" );
}
void
MingwBackend::DetectPCHSupport ()
{
printf ( "Detecting compiler pre-compiled header support..." );
string path = "tools" + sSep + "rbuild" + sSep + "backend" + sSep + "mingw" + sSep + "pch_detection.h";
string cmd = ssprintf (
"%s -c %s 1>%s 2>%s",
FixSeparatorForSystemCommand(compilerCommand).c_str (),
path.c_str (),
NUL,
NUL );
system ( cmd.c_str () );
path += ".gch";
FILE* f = fopen ( path.c_str (), "rb" );
if ( f )
{
use_pch = true;
fclose ( f );
unlink ( path.c_str () );
}
else
use_pch = false;
if ( use_pch )
printf ( "detected\n" );
else
printf ( "not detected\n" );
}
void
MingwBackend::GetNonModuleInstallTargetFiles (
vector<string>& out ) const
{
for ( size_t i = 0; i < ProjectNode.installfiles.size (); i++ )
{
const InstallFile& installfile = *ProjectNode.installfiles[i];
string targetFilenameNoFixup = installfile.base + sSep + installfile.newname;
string targetFilename = MingwModuleHandler::PassThruCacheDirectory (
NormalizeFilename ( targetFilenameNoFixup ),
installDirectory );
out.push_back ( targetFilename );
}
}
void
MingwBackend::GetModuleInstallTargetFiles (
vector<string>& out ) const
{
for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )
{
const Module& module = *ProjectNode.modules[i];
if ( !module.enabled )
continue;
if ( module.installName.length () > 0 )
{
string targetFilenameNoFixup;
if ( module.installBase.length () > 0 )
targetFilenameNoFixup = module.installBase + sSep + module.installName;
else
targetFilenameNoFixup = module.installName;
string targetFilename = MingwModuleHandler::PassThruCacheDirectory (
NormalizeFilename ( targetFilenameNoFixup ),
installDirectory );
out.push_back ( targetFilename );
}
}
}
void
MingwBackend::GetInstallTargetFiles (
vector<string>& out ) const
{
GetNonModuleInstallTargetFiles ( out );
GetModuleInstallTargetFiles ( out );
}
void
MingwBackend::OutputInstallTarget ( const string& sourceFilename,
const string& targetFilename,
const string& targetDirectory )
{
string fullTargetFilename;
if ( targetDirectory.length () > 0)
fullTargetFilename = targetDirectory + sSep + targetFilename;
else
fullTargetFilename = targetFilename;
string normalizedTargetFilename = MingwModuleHandler::PassThruCacheDirectory (
NormalizeFilename ( fullTargetFilename ),
installDirectory );
string normalizedTargetDirectory = MingwModuleHandler::PassThruCacheDirectory (
NormalizeFilename ( targetDirectory ),
installDirectory );
fprintf ( fMakefile,
"%s: %s | %s\n",
normalizedTargetFilename.c_str (),
sourceFilename.c_str (),
normalizedTargetDirectory.c_str () );
fprintf ( fMakefile,
"\t$(ECHO_CP)\n" );
fprintf ( fMakefile,
"\t${cp} %s %s 1>$(NUL)\n",
sourceFilename.c_str (),
normalizedTargetFilename.c_str () );
}
void
MingwBackend::OutputNonModuleInstallTargets ()
{
for ( size_t i = 0; i < ProjectNode.installfiles.size (); i++ )
{
const InstallFile& installfile = *ProjectNode.installfiles[i];
OutputInstallTarget ( installfile.GetPath (),
installfile.newname,
installfile.base );
}
}
const Module&
MingwBackend::GetAliasedModuleOrModule ( const Module& module ) const
{
if ( module.aliasedModuleName.size () > 0 )
{
const Module* aliasedModule = ProjectNode.LocateModule ( module.aliasedModuleName );
assert ( aliasedModule );
return *aliasedModule;
}
else
return module;
}
void
MingwBackend::OutputModuleInstallTargets ()
{
for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )
{
const Module& module = *ProjectNode.modules[i];
if ( !module.enabled )
continue;
if ( module.installName.length () > 0 )
{
const Module& aliasedModule = GetAliasedModuleOrModule ( module );
string sourceFilename = MingwModuleHandler::PassThruCacheDirectory (
NormalizeFilename ( aliasedModule.GetPath () ),
outputDirectory );
OutputInstallTarget ( sourceFilename,
module.installName,
module.installBase );
}
}
}
string
MingwBackend::GetRegistrySourceFiles ()
{
return "boot" + sSep + "bootdata" + sSep + "hivecls.inf "
"boot" + sSep + "bootdata" + sSep + "hivedef.inf "
"boot" + sSep + "bootdata" + sSep + "hiveinst.inf "
"boot" + sSep + "bootdata" + sSep + "hivesft.inf "
"boot" + sSep + "bootdata" + sSep + "hivesys.inf";
}
string
MingwBackend::GetRegistryTargetFiles ()
{
string system32ConfigDirectory = NormalizeFilename (
MingwModuleHandler::PassThruCacheDirectory (
"system32" + sSep + "config" + sSep,
installDirectory ) );
return system32ConfigDirectory + sSep + "default " +
system32ConfigDirectory + sSep + "sam " +
system32ConfigDirectory + sSep + "security " +
system32ConfigDirectory + sSep + "software " +
system32ConfigDirectory + sSep + "system";
}
void
MingwBackend::OutputRegistryInstallTarget ()
{
string system32ConfigDirectory = NormalizeFilename (
MingwModuleHandler::PassThruCacheDirectory (
"system32" + sSep + "config" + sSep,
installDirectory ) );
string registrySourceFiles = GetRegistrySourceFiles ();
string registryTargetFiles = GetRegistryTargetFiles ();
fprintf ( fMakefile,
"install_registry: %s\n",
registryTargetFiles.c_str () );
fprintf ( fMakefile,
"%s: %s %s $(MKHIVE_TARGET)\n",
registryTargetFiles.c_str (),
registrySourceFiles.c_str (),
system32ConfigDirectory.c_str () );
fprintf ( fMakefile,
"\t$(ECHO_MKHIVE)\n" );
fprintf ( fMakefile,
"\t$(MKHIVE_TARGET) boot%cbootdata %s boot%cbootdata%chiveinst.inf\n",
cSep, system32ConfigDirectory.c_str (),
cSep, cSep );
fprintf ( fMakefile,
"\n" );
}
void
MingwBackend::GenerateInstallTarget ()
{
vector<string> vInstallTargetFiles;
GetInstallTargetFiles ( vInstallTargetFiles );
string installTargetFiles = v2s ( vInstallTargetFiles, 5 );
string registryTargetFiles = GetRegistryTargetFiles ();
fprintf ( fMakefile,
"install: %s %s\n",
installTargetFiles.c_str (),
registryTargetFiles.c_str () );
OutputNonModuleInstallTargets ();
OutputModuleInstallTargets ();
OutputRegistryInstallTarget ();
fprintf ( fMakefile,
"\n" );
}
void
MingwBackend::GetModuleTestTargets (
vector<string>& out ) const
{
for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )
{
const Module& module = *ProjectNode.modules[i];
if ( !module.enabled )
continue;
if ( module.type == Test )
out.push_back ( module.name );
}
}
void
MingwBackend::GenerateTestTarget ()
{
vector<string> vTestTargets;
GetModuleTestTargets ( vTestTargets );
string testTargets = v2s ( vTestTargets, 5 );
fprintf ( fMakefile,
"test: %s\n",
testTargets.c_str () );
fprintf ( fMakefile,
"\n" );
}
void
MingwBackend::GenerateDirectoryTargets ()
{
intermediateDirectory->CreateRule ( fMakefile, "" );
outputDirectory->CreateRule ( fMakefile, "" );
installDirectory->CreateRule ( fMakefile, "" );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -