vcprojmaker.cpp

来自「一个类似windows」· C++ 代码 · 共 755 行 · 第 1/2 页

CPP
755
字号

			fprintf ( OUT, "\t\t\t\tAdditionalLibraryDirectories=\"" );
			for (i = 0; i < libraries.size (); i++)
			{
				if ( i > 0 )
					fprintf ( OUT, ";" );
 
				string libpath = libraries[i].c_str();
				libpath.replace (libpath.find("---"),
					             3,
								 cfg);
				libpath = libpath.substr (0, libpath.find_last_of ("\\") );
				fprintf ( OUT, "%s", libpath.c_str() );
			}
			fprintf ( OUT, "\"\r\n" );

			fprintf ( OUT, "\t\t\t\tOutputFile=\"$(OutDir)/%s%s\"\r\n", module.name.c_str(), module_type.c_str() );
			fprintf ( OUT, "\t\t\t\tLinkIncremental=\"%d\"\r\n", debug ? 2 : 1 );
			fprintf ( OUT, "\t\t\t\tGenerateDebugInformation=\"%s\"\r\n", speed ? "FALSE" : "TRUE" );
			fprintf ( OUT, "\t\t\t\tLinkTimeCodeGeneration=\"%d\"\r\n", release? 1: 0);	// whole program optimization

			if ( debug )
				fprintf ( OUT, "\t\t\t\tProgramDatabaseFile=\"$(OutDir)/%s.pdb\"\r\n", module.name.c_str() );

			if ( sys )
			{
				fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /ALIGN:0x20 /SECTION:INIT,D /IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096\"\r\n" );
				fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
				fprintf ( OUT, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" );
				fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 3 );
				fprintf ( OUT, "\t\t\t\tDriver=\"%d\"\r\n", 1 );
				fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module.entrypoint == "" ? "DriverEntry" : module.entrypoint.c_str ());
				fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr == "" ? "0x10000" : baseaddr.c_str ());	
			}
			else if ( exe )
			{
				if ( module.type == Kernel )
				{
					fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /SECTION:INIT,D /ALIGN:0x80\"\r\n" );
					fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
					fprintf ( OUT, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" );
					fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 3 );
					fprintf ( OUT, "\t\t\t\tDriver=\"%d\"\r\n", 1 );
					fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"KiSystemStartup\"\r\n" );
					fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr.c_str ());	
				}
				else if ( module.type == NativeCUI )
				{
					fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /ALIGN:0x20\"\r\n" );
					fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 1 );
					fprintf ( OUT, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" );
					fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
					fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"NtProcessStartup\"\r\n" );
					fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr.c_str ());	
				}
				else if ( module.type == Win32CUI || module.type == Win32GUI || module.type == Win32SCR)
				{
					fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", console ? 1 : 2 );
				}
			}
			else if ( dll )
			{
				fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module.entrypoint == "" ? "DllMain" : module.entrypoint.c_str ());
				fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr == "" ? "0x40000" : baseaddr.c_str ());
			}
			fprintf ( OUT, "\t\t\t\tTargetMachine=\"%d\"/>\r\n", 1 );
		}
		
		fprintf ( OUT, "\t\t\t<Tool\r\n" );
		fprintf ( OUT, "\t\t\t\tName=\"VCResourceCompilerTool\"\r\n" );
		fprintf ( OUT, "\t\t\t\tAdditionalIncludeDirectories=\"" );
		multiple_includes = false;
		fprintf ( OUT, "./;" );
		for ( i = 0; i < includes.size(); i++ )
		{
			const string& include = includes[i];
			if ( strcmp ( include.c_str(), "." ) )
			{
				if ( multiple_includes )
					fprintf ( OUT, ";" );
				fprintf ( OUT, "%s", include.c_str() );
				multiple_includes = true;
			}
		}
		fprintf ( OUT, "\"/>\r\n " );

		fprintf ( OUT, "\t\t\t<Tool\r\n" );
		fprintf ( OUT, "\t\t\t\tName=\"VCMIDLTool\"/>\r\n" );
		fprintf ( OUT, "\t\t\t<Tool\r\n" );
		fprintf ( OUT, "\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n" );
		fprintf ( OUT, "\t\t\t<Tool\r\n" );
		fprintf ( OUT, "\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n" );
		fprintf ( OUT, "\t\t\t<Tool\r\n" );
		fprintf ( OUT, "\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n" );
		fprintf ( OUT, "\t\t\t<Tool\r\n" );
		fprintf ( OUT, "\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n" );
		fprintf ( OUT, "\t\t\t<Tool\r\n" );
		fprintf ( OUT, "\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n" );
		fprintf ( OUT, "\t\t</Configuration>\r\n" );

		n++;
	}
	fprintf ( OUT, "\t</Configurations>\r\n" );

	fprintf ( OUT, "\t<Files>\r\n" );

	// Source files
	fprintf ( OUT, "\t\t<Filter\r\n" );
	fprintf ( OUT, "\t\t\tName=\"Source Files\"\r\n" );
	fprintf ( OUT, "\t\t\tFilter=\"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;S\">\r\n" );
	for ( size_t isrcfile = 0; isrcfile < source_files.size(); isrcfile++ )
	{
		string source_file = DosSeparator(source_files[isrcfile]);
		fprintf ( OUT, "\t\t\t<File\r\n" );
		fprintf ( OUT, "\t\t\t\tRelativePath=\"%s\">\r\n", source_file.c_str() );

		for ( size_t iconfig = 0; iconfig < cfgs.size(); iconfig++ )
		{
			std::string& config = cfgs[iconfig];

			if (( isrcfile == 0 ) && ( module.pch != NULL ))
			{
				/* little hack to speed up PCH */
				fprintf ( OUT, "\t\t\t\t<FileConfiguration\r\n" );
				fprintf ( OUT, "\t\t\t\t\tName=\"" );
				fprintf ( OUT, config.c_str() );
				fprintf ( OUT, "|Win32\">\r\n" );
				fprintf ( OUT, "\t\t\t\t\t<Tool\r\n" );
				fprintf ( OUT, "\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n" );
				fprintf ( OUT, "\t\t\t\t\t\tUsePrecompiledHeader=\"1\"/>\r\n" );
				fprintf ( OUT, "\t\t\t\t</FileConfiguration>\r\n" );
			}

			//if (configuration.VSProjectVersion < "8.00") {
				if ((source_file.find(".idl") != string::npos) || ((source_file.find(".asm") != string::npos || tolower(source_file.at(source_file.size() - 1)) == 's')))
				{
					fprintf ( OUT, "\t\t\t\t<FileConfiguration\r\n" );
					fprintf ( OUT, "\t\t\t\t\tName=\"" );
					fprintf ( OUT, config.c_str() );
					fprintf ( OUT, "|Win32\">\r\n" );
					fprintf ( OUT, "\t\t\t\t\t<Tool\r\n" );
					if (source_file.find(".idl") != string::npos)
					{
						fprintf ( OUT, "\t\t\t\t\t\tName=\"VCCustomBuildTool\"\r\n" );
						fprintf ( OUT, "\t\t\t\t\t\tOutputs=\"$(OutDir)\\$(InputName).obj\"/>\r\n" );
					}
					else if ((source_file.find(".asm") != string::npos || tolower(source_file.at(source_file.size() - 1)) == 's'))
					{
						fprintf ( OUT, "\t\t\t\t\t\tName=\"VCCustomBuildTool\"\r\n" );
						fprintf ( OUT, "\t\t\t\t\t\tCommandLine=\"cl /E &quot;$(InputPath)&quot; %s /D__ASM__ | as -o &quot;$(OutDir)\\$(InputName).obj&quot;\"\r\n",include_string.c_str() );
						fprintf ( OUT, "\t\t\t\t\t\tOutputs=\"$(OutDir)\\$(InputName).obj\"/>\r\n" );
					}
					fprintf ( OUT, "\t\t\t\t</FileConfiguration>\r\n" );
				}
			//}
		}
		fprintf ( OUT, "\t\t\t</File>\r\n" );
	}
	fprintf ( OUT, "\t\t</Filter>\r\n" );

	// Header files
	fprintf ( OUT, "\t\t<Filter\r\n" );
	fprintf ( OUT, "\t\t\tName=\"Header Files\"\r\n" );
	fprintf ( OUT, "\t\t\tFilter=\"h;hpp;hxx;hm;inl\">\r\n" );
	for ( i = 0; i < header_files.size(); i++ )
	{
		const string& header_file = header_files[i];
		fprintf ( OUT, "\t\t\t<File\r\n" );
		fprintf ( OUT, "\t\t\t\tRelativePath=\"%s\">\r\n", header_file.c_str() );
		fprintf ( OUT, "\t\t\t</File>\r\n" );
	}
	fprintf ( OUT, "\t\t</Filter>\r\n" );

	// Resource files
	fprintf ( OUT, "\t\t<Filter\r\n" );
	fprintf ( OUT, "\t\t\tName=\"Resource Files\"\r\n" );
	fprintf ( OUT, "\t\t\tFilter=\"ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\">\r\n" );
	for ( i = 0; i < resource_files.size(); i++ )
	{
		const string& resource_file = resource_files[i];
		fprintf ( OUT, "\t\t\t<File\r\n" );
		fprintf ( OUT, "\t\t\t\tRelativePath=\"%s\">\r\n", resource_file.c_str() );
		fprintf ( OUT, "\t\t\t</File>\r\n" );
	}
	fprintf ( OUT, "\t\t</Filter>\r\n" );

	fprintf ( OUT, "\t</Files>\r\n" );
	fprintf ( OUT, "\t<Globals>\r\n" );
	fprintf ( OUT, "\t</Globals>\r\n" );
	fprintf ( OUT, "</VisualStudioProject>\r\n" );
	fclose(OUT);
}

std::string
MSVCBackend::_replace_str(std::string string1, const std::string &find_str, const std::string &replace_str)
{
        std::string::size_type pos = string1.find(find_str, 0);
        int intLen = find_str.length();

        while(std::string::npos != pos)
        {
                string1.replace(pos, intLen, replace_str);
                pos = string1.find(find_str, intLen + pos);
        }

        return string1;
} 

std::string
MSVCBackend::_get_solution_verion ( void ) {
    string version;

    if (configuration.VSProjectVersion.empty())
        configuration.VSProjectVersion = MS_VS_DEF_VERSION;

    if (configuration.VSProjectVersion == "7.00")
		version = "7.00";

    if (configuration.VSProjectVersion == "7.10")
		version = "8.00";

    if (configuration.VSProjectVersion == "8.00")
		version = "9.00";

	return version;
}


//void
//MSVCBackend::_generate_rules_file ( FILE* OUT )
//{
//	fprintf ( OUT, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" );
//	fprintf ( OUT, "<VisualStudioToolFile\r\n" );
//	fprintf ( OUT, "\tName=\"GCC Assembler\"\r\n" );
//	fprintf ( OUT, "\tVersion=\"%s\"\r\n", _get_solution_verion().c_str() );
//	fprintf ( OUT, "\t>\r\n" );
//	fprintf ( OUT, "\t<Rules>\r\n" );
//	fprintf ( OUT, "\t\t<CustomBuildRule\r\n" );
//	fprintf ( OUT, "\t\t\tName=\"Assembler\"\r\n" );
//	fprintf ( OUT, "\t\t\tDisplayName=\"Assembler Files\"\r\n" );
//	fprintf ( OUT, "\t\t\tCommandLine=\"cl /E &quot;$(InputPath)&quot; | as -o &quot;$(OutDir)\\$(InputName).obj&quot;\"\r\n" );
//	fprintf ( OUT, "\t\t\tOutputs=\"$(OutDir)\\$(InputName).obj\"\r\n" );	
//	fprintf ( OUT, "\t\t\tFileExtensions=\"*.S\"\r\n" );
//	fprintf ( OUT, "\t\t\tExecutionDescription=\"asm\"\r\n" );
//	fprintf ( OUT, "\t\t\t>\r\n" );
//	fprintf ( OUT, "\t\t\t<Properties>\r\n" );
//	fprintf ( OUT, "\t\t\t</Properties>\r\n" );
//	fprintf ( OUT, "\t\t</CustomBuildRule>\r\n" );
//	fprintf ( OUT, "\t</Rules>\r\n" );
//	fprintf ( OUT, "</VisualStudioToolFile>\r\n" );
//}

void
MSVCBackend::_generate_sln_header ( FILE* OUT )
{
    fprintf ( OUT, "Microsoft Visual Studio Solution File, Format Version %s\r\n", _get_solution_verion().c_str() );
    fprintf ( OUT, "# Visual Studio 2005\r\n" );
    fprintf ( OUT, "\r\n" );
}


void
MSVCBackend::_generate_sln_project (
	FILE* OUT,
	const Module& module,
	std::string vcproj_file,
	std::string sln_guid,
	std::string vcproj_guid,
	const std::vector<Dependency*>& dependencies )
{
	//vcproj_file = DosSeparator ( std::string(".\\") + vcproj_file );

	fprintf ( OUT, "Project(\"%s\") = \"%s\", \"%s\", \"{%s}\"\r\n", sln_guid.c_str() , module.name.c_str(), vcproj_file.c_str(), vcproj_guid.c_str() );

	vector<const IfableData*> ifs_list;
	ifs_list.push_back ( &module.project.non_if_data );
	ifs_list.push_back ( &module.non_if_data );


	//FIXME: only omit ProjectDependencies in VS 2005 when there are no dependencies
	//NOTE: VS 2002 do not use ProjectSection; it uses GlobalSection instead
	if (configuration.VSProjectVersion != "7.00") {

		bool has_dependencies = false;




		while ( ifs_list.size() )
		{
			const IfableData& data = *ifs_list.back();
			ifs_list.pop_back();
			const vector<Library*>& libs = data.libraries;
			for ( unsigned i = 0; i < libs.size(); i++ )
			{
				if ( !has_dependencies ) {
					fprintf ( OUT, "\tProjectSection(ProjectDependencies) = postProject\r\n" );
					has_dependencies = true;
				}

				fprintf ( OUT, "\t\t{%s} = {%s}\r\n", libs[i]->importedModule->guid.c_str(), libs[i]->importedModule->guid.c_str());
			}
		}
		if ( has_dependencies )
			fprintf ( OUT, "\tEndProjectSection\r\n" );
	}

	fprintf ( OUT, "EndProject\r\n" );
}


void
MSVCBackend::_generate_sln_footer ( FILE* OUT )
{
	fprintf ( OUT, "Global\r\n" );
	fprintf ( OUT, "\tGlobalSection(SolutionConfiguration) = preSolution\r\n" );
	fprintf ( OUT, "\t\tDebug = Debug\r\n" );
	fprintf ( OUT, "\t\tRelease = Release\r\n" );
	fprintf ( OUT, "\tEndGlobalSection\r\n" );
	fprintf ( OUT, "\tGlobalSection(ProjectConfiguration) = postSolution\r\n" );
	for ( size_t i = 0; i < ProjectNode.modules.size(); i++ )
	{
		Module& module = *ProjectNode.modules[i];
		std::string guid = module.guid;
		_generate_sln_configurations ( OUT, guid.c_str() );
	} 
	fprintf ( OUT, "\tEndGlobalSection\r\n" );
	fprintf ( OUT, "\tGlobalSection(ExtensibilityGlobals) = postSolution\r\n" );
	fprintf ( OUT, "\tEndGlobalSection\r\n" );
	fprintf ( OUT, "\tGlobalSection(ExtensibilityAddIns) = postSolution\r\n" );
	fprintf ( OUT, "\tEndGlobalSection\r\n" );
	
	if (configuration.VSProjectVersion == "7.00") {
		fprintf ( OUT, "\tGlobalSection(ProjectDependencies) = postSolution\r\n" );
		//FIXME: Add dependencies for VS 2002
		fprintf ( OUT, "\tEndGlobalSection\r\n" );
	}

	if (configuration.VSProjectVersion == "8.00") {
		fprintf ( OUT, "\tGlobalSection(SolutionProperties) = preSolution\r\n" );
        	fprintf ( OUT, "\t\tHideSolutionNode = FALSE\r\n" );
		fprintf ( OUT, "\tEndGlobalSection\r\n" );
	}

	fprintf ( OUT, "EndGlobal\r\n" );
	fprintf ( OUT, "\r\n" );
}


void
MSVCBackend::_generate_sln_configurations ( FILE* OUT, std::string vcproj_guid )
{
	fprintf ( OUT, "\t\t%s.Debug.ActiveCfg = Debug|Win32\r\n", vcproj_guid.c_str() );
	fprintf ( OUT, "\t\t%s.Debug.Build.0 = Debug|Win32\r\n", vcproj_guid.c_str() );
	fprintf ( OUT, "\t\t%s.Debug.Release.ActiveCfg = Release|Win32\r\n", vcproj_guid.c_str() );
	fprintf ( OUT, "\t\t%s.Debug.Release.Build.0 = Release|Win32\r\n", vcproj_guid.c_str() );
}

void
MSVCBackend::_generate_sln ( FILE* OUT )
{
	string sln_guid = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}";
	vector<string> guids;

	_generate_sln_header(OUT);
	// TODO FIXME - is it necessary to sort them?
	for ( size_t i = 0; i < ProjectNode.modules.size(); i++ )
	{
		Module& module = *ProjectNode.modules[i];
		
		std::string vcproj_file = VcprojFileName ( module );
		_generate_sln_project ( OUT, module, vcproj_file, sln_guid, module.guid, module.dependencies );
	}
	_generate_sln_footer ( OUT );
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?