⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mingw.cpp

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	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 + -