📄 mingw.cpp
字号:
fprintf ( fMakefile, "PROJECT_WIDLFLAGS := $(PROJECT_CFLAGS)\n" );
fprintf ( fMakefile, "PROJECT_LFLAGS := %s\n",
GenerateProjectLFLAGS ().c_str () );
fprintf ( fMakefile, "PROJECT_CFLAGS += -Wall\n" );
fprintf ( fMakefile, "PROJECT_CFLAGS += -march=$(OARCH)\n" );
fprintf ( fMakefile, "PROJECT_CFLAGS += $(PROJECT_GCCOPTIONS)\n" );
fprintf ( fMakefile, "\n" );
}
bool
MingwBackend::IncludeInAllTarget ( const Module& module ) const
{
if ( MingwModuleHandler::ReferenceObjects ( module ) )
return false;
if ( module.type == BootSector )
return false;
if ( module.type == Iso )
return false;
if ( module.type == LiveIso )
return false;
if ( module.type == IsoRegTest )
return false;
if ( module.type == LiveIsoRegTest )
return false;
if ( module.type == Test )
return false;
if ( module.type == Alias )
return false;
return true;
}
void
MingwBackend::GenerateAllTarget ( const vector<MingwModuleHandler*>& handlers ) const
{
fprintf ( fMakefile, "all:" );
int wrap_count = 0;
size_t iend = handlers.size ();
for ( size_t i = 0; i < iend; i++ )
{
const Module& module = handlers[i]->module;
if ( IncludeInAllTarget ( module ) )
{
if ( wrap_count++ == 5 )
fprintf ( fMakefile, " \\\n\t\t" ), wrap_count = 0;
fprintf ( fMakefile,
" %s",
GetTargetMacro(module).c_str () );
}
}
fprintf ( fMakefile, "\n\t\n\n" );
}
string
MingwBackend::GetBuildToolDependencies () const
{
string dependencies;
for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )
{
Module& module = *ProjectNode.modules[i];
if ( !module.enabled )
continue;
if ( module.type == BuildTool )
{
if ( dependencies.length () > 0 )
dependencies += " ";
dependencies += module.GetDependencyPath ();
}
}
return dependencies;
}
void
MingwBackend::GenerateInitTarget () const
{
fprintf ( fMakefile,
"INIT = %s\n",
GetBuildToolDependencies ().c_str () );
fprintf ( fMakefile, "\n" );
}
void
MingwBackend::GenerateRegTestsRunTarget () const
{
fprintf ( fMakefile,
"REGTESTS_RUN_TARGET = regtests.dll\n" );
fprintf ( fMakefile,
"$(REGTESTS_RUN_TARGET): $(REGTESTS_TARGET)\n" );
fprintf ( fMakefile,
"\t$(cp) $(REGTESTS_TARGET) $(REGTESTS_RUN_TARGET)\n" );
fprintf ( fMakefile, "\n" );
}
void
MingwBackend::GenerateXmlBuildFilesMacro() const
{
fprintf ( fMakefile,
"XMLBUILDFILES = %s \\\n",
ProjectNode.GetProjectFilename ().c_str () );
string xmlbuildFilenames;
int numberOfExistingFiles = 0;
struct stat statbuf;
time_t SystemTime, lastWriteTime;
for ( size_t i = 0; i < ProjectNode.xmlbuildfiles.size (); i++ )
{
XMLInclude& xmlbuildfile = *ProjectNode.xmlbuildfiles[i];
if ( !xmlbuildfile.fileExists )
continue;
numberOfExistingFiles++;
if ( xmlbuildFilenames.length () > 0 )
xmlbuildFilenames += " ";
FILE* f = fopen ( xmlbuildfile.topIncludeFilename.c_str (), "rb" );
if ( !f )
throw FileNotFoundException ( NormalizeFilename ( xmlbuildfile.topIncludeFilename ) );
if ( fstat ( fileno ( f ), &statbuf ) != 0 )
{
fclose ( f );
throw AccessDeniedException ( NormalizeFilename ( xmlbuildfile.topIncludeFilename ) );
}
lastWriteTime = statbuf.st_mtime;
SystemTime = time(NULL);
if (SystemTime != -1)
{
if (difftime (lastWriteTime, SystemTime) > 0)
throw InvalidDateException ( NormalizeFilename ( xmlbuildfile.topIncludeFilename ) );
}
fclose ( f );
xmlbuildFilenames += NormalizeFilename ( xmlbuildfile.topIncludeFilename );
if ( numberOfExistingFiles % 5 == 4 || i == ProjectNode.xmlbuildfiles.size () - 1 )
{
fprintf ( fMakefile,
"\t%s",
xmlbuildFilenames.c_str ());
if ( i == ProjectNode.xmlbuildfiles.size () - 1 )
{
fprintf ( fMakefile, "\n" );
}
else
{
fprintf ( fMakefile,
" \\\n" );
}
xmlbuildFilenames.resize ( 0 );
}
numberOfExistingFiles++;
}
fprintf ( fMakefile, "\n" );
}
string
MingwBackend::GetBin2ResExecutable ()
{
return NormalizeFilename ( Environment::GetOutputPath () + sSep + "tools/bin2res/bin2res" + ExePostfix );
}
void
MingwBackend::UnpackWineResources ()
{
printf ( "Unpacking WINE resources..." );
WineResource wineResource ( ProjectNode,
GetBin2ResExecutable () );
wineResource.UnpackResources ( configuration.Verbose );
printf ( "done\n" );
}
void
MingwBackend::GenerateTestSupportCode ()
{
printf ( "Generating test support code..." );
TestSupportCode testSupportCode ( ProjectNode );
testSupportCode.GenerateTestSupportCode ( configuration.Verbose );
printf ( "done\n" );
}
void
MingwBackend::GenerateCompilationUnitSupportCode ()
{
if ( configuration.CompilationUnitsEnabled )
{
printf ( "Generating compilation unit support code..." );
CompilationUnitSupportCode compilationUnitSupportCode ( ProjectNode );
compilationUnitSupportCode.Generate ( configuration.Verbose );
printf ( "done\n" );
}
}
void
MingwBackend::GenerateSysSetup ()
{
printf ( "Generating syssetup.inf..." );
SysSetupGenerator sysSetupGenerator ( ProjectNode );
sysSetupGenerator.Generate ();
printf ( "done\n" );
}
string
MingwBackend::GetProxyMakefileTree () const
{
if ( configuration.GenerateProxyMakefilesInSourceTree )
return "";
else
return Environment::GetOutputPath ();
}
void
MingwBackend::GenerateProxyMakefiles ()
{
printf ( "Generating proxy makefiles..." );
ProxyMakefile proxyMakefile ( ProjectNode );
proxyMakefile.GenerateProxyMakefiles ( configuration.Verbose,
GetProxyMakefileTree () );
printf ( "done\n" );
}
void
MingwBackend::CheckAutomaticDependencies ()
{
if ( configuration.AutomaticDependencies )
{
printf ( "Checking automatic dependencies..." );
AutomaticDependency automaticDependency ( ProjectNode );
automaticDependency.CheckAutomaticDependencies ( configuration.Verbose );
printf ( "done\n" );
}
}
bool
MingwBackend::IncludeDirectoryTarget ( const string& directory ) const
{
if ( directory == "$(INTERMEDIATE)" + sSep + "tools")
return false;
else
return true;
}
void
MingwBackend::GenerateDirectories ()
{
printf ( "Creating directories..." );
intermediateDirectory->GenerateTree ( "", configuration.Verbose );
outputDirectory->GenerateTree ( "", configuration.Verbose );
if ( !configuration.MakeHandlesInstallDirectories )
installDirectory->GenerateTree ( "", configuration.Verbose );
printf ( "done\n" );
}
bool
MingwBackend::TryToDetectThisCompiler ( const string& compiler )
{
string command = ssprintf (
"%s -v 1>%s 2>%s",
FixSeparatorForSystemCommand(compiler).c_str (),
NUL,
NUL );
int exitcode = system ( command.c_str () );
return (bool) (exitcode == 0);
}
void
MingwBackend::DetectCompiler ()
{
printf ( "Detecting compiler..." );
bool detectedCompiler = false;
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 );
}
#endif
if ( !detectedCompiler )
{
compilerPrefix = "mingw32";
compilerCommand = compilerPrefix + "-gcc";
detectedCompiler = TryToDetectThisCompiler ( compilerCommand );
}
if ( detectedCompiler )
{
string compilerVersion = GetCompilerVersion ( compilerCommand );
if ( IsSupportedCompilerVersion ( compilerVersion ) )
printf ( "detected (%s %s)\n", compilerCommand.c_str (), compilerVersion.c_str() );
else
{
printf ( "detected (%s), but with unsupported version (%s)\n",
compilerCommand.c_str (),
compilerVersion.c_str () );
throw UnsupportedBuildToolException ( compilerCommand, compilerVersion );
}
}
else
printf ( "not detected\n" );
}
bool
MingwBackend::TryToDetectThisNetwideAssembler ( const string& assembler )
{
string command = ssprintf (
"%s -h 1>%s 2>%s",
FixSeparatorForSystemCommand(assembler).c_str (),
NUL,
NUL );
int exitcode = system ( command.c_str () );
return (bool) (exitcode == 0);
}
string
MingwBackend::GetVersionString ( const string& versionCommand )
{
FILE *fp;
int ch, i;
char buffer[81];
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;
string version;
token = strtok ( buffer, separators );
while ( token != NULL )
{
prevtoken = token;
version = string( prevtoken );
if ( version.find('.') != std::string::npos )
break;
token = strtok ( NULL, separators );
}
return version;
}
string
MingwBackend::GetNetwideAssemblerVersion ( const string& nasmCommand )
{
string versionCommand;
if ( nasmCommand.find("yasm") != std::string::npos )
{
versionCommand = ssprintf ( "%s --version",
nasmCommand.c_str (),
NUL,
NUL );
}
else
{
versionCommand = ssprintf ( "%s -v",
nasmCommand.c_str (),
NUL,
NUL );
}
return GetVersionString( versionCommand );
}
string
MingwBackend::GetCompilerVersion ( const string& compilerCommand )
{
string versionCommand = ssprintf ( "%s --version gcc",
compilerCommand.c_str (),
NUL,
NUL );
return GetVersionString( versionCommand );
}
string
MingwBackend::GetBinutilsVersion ( const string& binutilsCommand )
{
string versionCommand = ssprintf ( "%s -v",
binutilsCommand.c_str (),
NUL,
NUL );
return GetVersionString( versionCommand );
}
bool
MingwBackend::IsSupportedCompilerVersion ( const string& compilerVersion )
{
if ( strcmp ( compilerVersion.c_str (), "3.4.2") < 0 )
return false;
else
return true;
}
bool
MingwBackend::TryToDetectThisBinutils ( const string& binutils )
{
string command = ssprintf (
"%s -v 1>%s",
FixSeparatorForSystemCommand(binutils).c_str (),
NUL,
NUL );
int exitcode = system ( command.c_str () );
return (exitcode == 0);
}
string
MingwBackend::GetBinutilsVersionDate ( const string& binutilsCommand )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -