Code::Blocks project importer / CodeLite .project format

Discussion about CodeLite development process and patches
TurboLento
CodeLite Enthusiast
Posts: 12
Joined: Mon Sep 27, 2010 2:51 am
Genuine User: Yes
IDE Question: c++
Contact:

Code::Blocks project importer / CodeLite .project format

Post by TurboLento »

Hi Eran,
I'm working on a Code::Blocks project importer, which will convert Code::Blocks' .cbp to CodeLite's .project files. So far I've got the parsing of the cbp done into my own structure (with not all but the features I use most), now i've just to implement the converting and writing to .project structure.

Do you have a specification for the ".project" format, in your computer (or elsewhere), similiar to CodeBlocks' http://wiki.codeblocks.org/index.php?title=Project_file, listing the structure of the Project file formats? That'd be most helpful!

Thanks


EDIT: update with preliminary code for the converter. It's incomplete at the moment, I'll add to it as I progress.
It uses the TinyXML library.

Code: Select all

#include "XMLUtils.h"
#include <iostream>
#include <vector>

#define TIXML_USE_STL
#include <tinyxml.h>

int main(void)
{
	// input and output files
	// VERY IMPORTANT: OUTPUT PROJECT FILE NAME MUST BE = PROJECT NAME!!!
	std::string pathToCodeBlocksProject = "Codeblocks Input Files/Utils.cbp";
	std::string filepathCodeLiteProject = "Output/Utils.project";
	
	
	// load codeblocks xml file
	TiXmlDocument* xmlElmCB_Root = new TiXmlDocument();
	xmlElmCB_Root->LoadFile(pathToCodeBlocksProject);
	//XMLUtils::dump_to_stdout(xmlElmCB_Root); // debug
	
	
	// write CodeLite output
	// create CodeLite xml file
	TiXmlDocument* xmlElmCL_Root = new TiXmlDocument();
	// add declaration
	TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "utf-8", "" );
	xmlElmCL_Root->LinkEndChild(decl);
	// add "CodeLite_Project" tag
	std::string elementName = "CodeLite_Project";
	TiXmlElement* xmlElmCL_CodeLite_Project = new TiXmlElement(elementName);
	// add "Name" attribute
	// get CodeBlocks project name
	std::string projectName = "";
	
	// search for "CodeBlocks_project_file"
	TiXmlElement* xmlElmCB_CodeBlocks_project_file = xmlElmCB_Root->FirstChildElement("CodeBlocks_project_file");
	if(xmlElmCB_CodeBlocks_project_file == 0)
	{
		std::cout << "could not find \"CodeBlocks_project_file\" below root!\n";
		return 0;
	}
	
	// find "Project" below
	TiXmlElement* xmlElmCB_Project = xmlElmCB_CodeBlocks_project_file->FirstChildElement("Project");
	if(xmlElmCB_Project == 0)
	{
		std::cout << "could not find \"Project\" below!\n";
		return 0;
	}
	
	// find an "Option" with an attribute named "title", and get that attribute value as the Project title
	for( TiXmlElement* child = xmlElmCB_Project->FirstChildElement(); child; child = child->NextSiblingElement())
	{
		if(child->ValueStr() == "Option")
			if(child->Attribute("title") != 0)
			{
				projectName = std::string(child->Attribute("title"));
				break;
			}
	}
	
	xmlElmCL_CodeLite_Project->SetAttribute("Name", projectName);
	
	// set CodeLite "InternalType" attribute
	// InternalType: Console, GUI, Library, Others, UnitTest++, User Templates
	// odd since a project can have both executable + library + others targets, which don't fall on just "Console" or "Library" categories
	// just set it to "Console" for now
	//xmlElmCL_CodeLite_Project->SetAttribute("InternalType", "Console");
	xmlElmCL_CodeLite_Project->SetAttribute("InternalType", "Library");
	
	// now that all attribute for CodeLite_Project have been added, add it to CodeLite xml file
	xmlElmCL_Root->LinkEndChild(xmlElmCL_CodeLite_Project);
	
	// add Plugins
	TiXmlElement* xmlElmPlugins = new TiXmlElement("Plugins");
	xmlElmCL_CodeLite_Project->LinkEndChild(xmlElmPlugins);
	// add Description
	TiXmlElement* xmlElmDescription = new TiXmlElement("Description");
	xmlElmCL_CodeLite_Project->LinkEndChild(xmlElmDescription);
	// add Dependencies
	TiXmlElement* xmlElmDependencies = new TiXmlElement("Dependencies");
	xmlElmCL_CodeLite_Project->LinkEndChild(xmlElmDependencies);
	
	// add files list (VirtualDirectory)
	// add list of "File" for each file in CodeBlocks project
	// get CodeBlocks files list: CodeBlocks_project_file -> Project -> Unit filename=""
	std::vector<std::string> filesList;
	for( 	TiXmlElement* xmlElmCB_Unit = xmlElmCB_Project->FirstChildElement("Unit"); 
			xmlElmCB_Unit; 
			xmlElmCB_Unit = xmlElmCB_Unit->NextSiblingElement("Unit"))
	{
		if(xmlElmCB_Unit->Attribute("filename") != 0)
		{
			std::string fileName(xmlElmCB_Unit->Attribute("filename"));
			
			// in filename, replace "\" with "/"
			for(unsigned int idxChar = 0; idxChar < fileName.size(); ++idxChar)
				if(fileName[idxChar] == '\\') fileName[idxChar] = '/';
			
			filesList.push_back(fileName);
		}
		else
		{
			std::cout << "Error: expected <Unit filename="">, did not find it\n";
		}
	}
	
	// for every file, parse directory structure and add
	for(unsigned int idxFile = 0; idxFile < filesList.size(); ++idxFile)
	{
		std::string fileName = filesList[idxFile];
		
		// parse fileName, get directory structure, and create virtual directories if necessary
		// TODO create full directory tree (right now, only creating top dir)
		std::string::size_type dirSeparator = fileName.find('/');
		std::string::size_type currentSeparatorPos = 0;
		
		//while(dirSeparator != fileName.npos)
		if(dirSeparator != fileName.npos)
		{
			std::string dirName = fileName.substr(currentSeparatorPos, dirSeparator);
			
			// check if we've added this VirtualDirectory already; 
			TiXmlElement* xmlElmCL_VirtualDir_ToAddTo = 0;
			for( 	TiXmlElement* xmlElmCL_VirtualDir = xmlElmCL_CodeLite_Project->FirstChildElement("VirtualDirectory");
					xmlElmCL_VirtualDir;
					xmlElmCL_VirtualDir = xmlElmCL_VirtualDir->NextSiblingElement("VirtualDirectory"))
			{
				if(xmlElmCL_VirtualDir->Attribute("Name") != 0)
				{
					if(std::string(xmlElmCL_VirtualDir->Attribute("Name")) == dirName) // found, add to this one
					{
						xmlElmCL_VirtualDir_ToAddTo = xmlElmCL_VirtualDir;
						break;
					}
				}
			}
			// if yes, add file to it; 
			// if not, create and add file to it
			if(xmlElmCL_VirtualDir_ToAddTo == 0)
			{
				xmlElmCL_VirtualDir_ToAddTo = new TiXmlElement("VirtualDirectory");
				xmlElmCL_CodeLite_Project->LinkEndChild(xmlElmCL_VirtualDir_ToAddTo);
				xmlElmCL_VirtualDir_ToAddTo->SetAttribute("Name", dirName);
			}
			
			// add File
			TiXmlElement* xmlElmCL_File = new TiXmlElement("File");
			xmlElmCL_File->SetAttribute("Name", fileName);
			xmlElmCL_VirtualDir_ToAddTo->LinkEndChild(xmlElmCL_File);
			
			//fileName = fileName.substr(dirSeparator+1);
		}
	}
	
	// add Settings
	TiXmlElement* xmlElmCL_Settings = new TiXmlElement("Settings");
	// set Settings Type: Static Library, Dynamic Library and Executable
	// might be irrelevant, since Settings can have several Configurations, and each can be a Static,Dynamic library or Executable,
	// independant from the Settings "Type", which makes it irrelevant
	// so setting it to Executable by default
	//xmlElmCL_Settings->SetAttribute("Type", "Executable");
	xmlElmCL_Settings->SetAttribute("Type", "Dynamic Library");
	xmlElmCL_CodeLite_Project->LinkEndChild(xmlElmCL_Settings);
	// add "Configuration" list
	// get them from CodeBlocks "Target"
	std::vector<std::string> configurationNamesList;
	TiXmlElement* xmlElmCB_Build = xmlElmCB_Project->FirstChildElement("Build");
	if(xmlElmCB_Build == 0)
	{
		std::cout << "Error: expected Project->Build in CodeBlocks file, did not find Build. exiting\n";
		return 0;
	}
	
	for( 	TiXmlElement* xmlElmCB_Target = xmlElmCB_Build->FirstChildElement("Target"); 
			xmlElmCB_Target; 
			xmlElmCB_Target = xmlElmCB_Target->NextSiblingElement("Target"))
	{
		TiXmlElement* xmlElmCL_Configuration = new TiXmlElement("Configuration");
		xmlElmCL_Settings->LinkEndChild(xmlElmCL_Configuration);
		
		// get Configuration "Name" (Target "title")
		if(xmlElmCB_Target->Attribute("title") == 0)
		{
			std::cout << "Error: expected Project->Build->Target \"title\" in CodeBlocks file, did not find \"title\". exiting\n";
			return 0;
		}
		std::string configurationName(xmlElmCB_Target->Attribute("title"));
		xmlElmCL_Configuration->SetAttribute("Name", configurationName);
		configurationNamesList.push_back(configurationName);
		
		// get configuration CompilerType
		// defaulting to CompilerType="G++ Mingw4.4.3"
		// TODO get this from elsewhere
		xmlElmCL_Configuration->SetAttribute("CompilerType", "G++ Mingw4.4.3");
		
		// get configuration DebuggerType
		// defaulting to DebuggerType="GNU gdb debugger"
		// TODO get this from elsewhere
		xmlElmCL_Configuration->SetAttribute("DebuggerType", "GNU gdb debugger");
		
		// get configuration Type ("Static Library", "Dynamic Library" or "Executable")
		// CodeBlocks: Build -> Option type=""
		// available types: 0 - GUI application (no console); 1 - Console application; 2 - Static library; 
		// 3 - Dynamic library (dll/so), 4 - Commands only (doesn't generate any output, just executes pre/post build steps), 
		// 5 - Native executable (valid only under windows where it produces a .sys file) 
		// search for Build -> Option type=""
		std::string configurationType = "";
		int outputFileType;
		for( TiXmlElement* xmlElmCB_Option = xmlElmCB_Target->FirstChildElement("Option"); 
			xmlElmCB_Option; 
			xmlElmCB_Option = xmlElmCB_Option->NextSiblingElement("Option"))
		{
			if(xmlElmCB_Option->Attribute("type") != 0)
			{
				int result = xmlElmCB_Option->QueryIntAttribute("type", &outputFileType);
				if(result == TIXML_SUCCESS)
				{
					switch(outputFileType)
					{
						case 0: // Gui application
							configurationType = "Executable";
						break;
						case 1: // console application
							configurationType = "Executable";
						break;
						case 2: // static library
							configurationType = "Static Library";
						break;
						case 3: // dynamic library
							configurationType = "Dynamic Library";
						break;
						default:
							configurationType = "Executable";
					}
					
					break;
				}
			}
		}
		xmlElmCL_Configuration->SetAttribute("Type", configurationType);
		
		// how to deal with Global Settings, default to append
		xmlElmCL_Configuration->SetAttribute("BuildCmpWithGlobalSettings", "append");
		xmlElmCL_Configuration->SetAttribute("BuildLnkWithGlobalSettings", "append");
		xmlElmCL_Configuration->SetAttribute("BuildResWithGlobalSettings", "append");
		
		// add Compiler
		TiXmlElement* xmlElmCL_Compiler = new TiXmlElement("Compiler");
		// set Compiler attribute Options
		// get from CodeBlocks Build -> Target -> Compiler
		TiXmlElement* xmlElmCB_Compiler = xmlElmCB_Target->FirstChildElement("Compiler");
		// get all compiler options
		std::vector<std::string> compilerOptions;
		std::vector<std::string> compilerIncludeDirectories;
		for( TiXmlElement* xmlElmCB_CompilerOption = xmlElmCB_Compiler->FirstChildElement("Add"); 
			xmlElmCB_CompilerOption; 
			xmlElmCB_CompilerOption = xmlElmCB_CompilerOption->NextSiblingElement("Add"))
		{
			if(xmlElmCB_CompilerOption->Attribute("option") != 0)
			{
				std::string compilerOption(xmlElmCB_CompilerOption->Attribute("option"));
				compilerOptions.push_back(compilerOption);
			}
			if(xmlElmCB_CompilerOption->Attribute("directory") != 0)
			{
				std::string compilerIncludeDirectory(xmlElmCB_CompilerOption->Attribute("directory"));
				compilerIncludeDirectories.push_back(compilerIncludeDirectory);
			}
		}
		// add all compiler options to the CodeLite compiler options, separaated by space
		std::string compilerOptionsCLString = "";
		for(unsigned int idxOption = 0; idxOption < compilerOptions.size(); ++idxOption)
		{
			compilerOptionsCLString += compilerOptions[idxOption];
			if(idxOption < compilerOptions.size() - 1)
				compilerOptionsCLString += " ";
		}
		xmlElmCL_Compiler->SetAttribute("Options", compilerOptionsCLString);
		// compiler settings:
		// Required="yes" 
		// PreCompiledHeader=""
		xmlElmCL_Compiler->SetAttribute("Required", "yes");
		xmlElmCL_Compiler->SetAttribute("PreCompiledHeader", "");
		// add Compiler -> IncludePath
		std::string compilerIncludeDirectoryCLString = "";
		for(unsigned int idxDir = 0; idxDir < compilerIncludeDirectories.size(); ++idxDir)
		{
			compilerIncludeDirectoryCLString += compilerIncludeDirectories[idxDir];
			if(idxDir < compilerIncludeDirectories.size() - 1)
				compilerIncludeDirectoryCLString += " ";
		}
		TiXmlElement* xmlElmCL_IncludePath = new TiXmlElement("IncludePath");
		xmlElmCL_IncludePath->SetAttribute("Value", compilerIncludeDirectoryCLString);
		xmlElmCL_Compiler->LinkEndChild(xmlElmCL_IncludePath);
		
		xmlElmCL_Configuration->LinkEndChild(xmlElmCL_Compiler);
		
		// add Linker options
		TiXmlElement* xmlElmCL_Linker = new TiXmlElement("Linker");
		
		// get CB Linker options
		TiXmlElement* xmlElmCB_Linker = xmlElmCB_Target->FirstChildElement("Linker");
		std::vector<std::string> linkerOptions;
		std::vector<std::string> linkerDirectories;
		std::vector<std::string> linkerLibraries;
		if(xmlElmCB_Linker != 0)
		{
			for( TiXmlElement* xmlElmCB_LinkerOption = xmlElmCB_Linker->FirstChildElement("Add"); 
				xmlElmCB_LinkerOption; 
				xmlElmCB_LinkerOption = xmlElmCB_LinkerOption->NextSiblingElement("Add"))
			{
				if(xmlElmCB_LinkerOption->Attribute("option") != 0)
				{
					std::string linkerOption(xmlElmCB_LinkerOption->Attribute("option"));
					linkerOptions.push_back(linkerOption);
				}
				if(xmlElmCB_LinkerOption->Attribute("directory") != 0)
				{
					std::string linkerIncludeDirectory(xmlElmCB_LinkerOption->Attribute("directory"));
					linkerDirectories.push_back(linkerIncludeDirectory);
				}
				if(xmlElmCB_LinkerOption->Attribute("library") != 0)
				{
					std::string linkerLibrary(xmlElmCB_LinkerOption->Attribute("library"));
					linkerLibraries.push_back(linkerLibrary);
				}
			}
		} // if(xmlElmCB_Linker != 0)
		
		/*
		CB
		<Add option="">
		Adds a linker option (e.g. "-Wl,--export-all-symbols").

		<Add directory="">
		Adds a linker search directory.

		<Add library="">
		*/
		
		// create CodeLite linker strings
		std::string linkerOptionsCL;
		for(unsigned int idxOption = 0; idxOption < linkerOptions.size(); ++idxOption)
		{
			linkerOptionsCL += linkerOptions[idxOption];
			if(idxOption < linkerOptions.size() - 1)
				linkerOptionsCL += " ";
		}
		std::string linkerDirectoriesCL;
		for(unsigned int idxDir = 0; idxDir < linkerDirectories.size(); ++idxDir)
		{
			linkerDirectoriesCL += linkerDirectories[idxDir];
			if(idxDir < linkerDirectories.size() - 1)
				linkerDirectoriesCL += ";";
		}
		std::string linkerLibrariesCL;
		for(unsigned int idxLib = 0; idxLib < linkerLibraries.size(); ++idxLib)
		{
			linkerLibrariesCL += "-l" + linkerLibraries[idxLib];
			if(idxLib < linkerLibraries.size() - 1)
				linkerLibrariesCL += " ";
		}
		
		// add to CodeLite Linker
		/*
		CL
		<Linker Options="-l" Required="yes">
			<LibraryPath Value="c:\"/>
			<Library Value="-lalleg"/>
		</Linker>
		*/ 
		xmlElmCL_Linker->SetAttribute("Options", linkerOptionsCL);
		if(linkerDirectoriesCL != "")
		{
			TiXmlElement* xmlElmCL_LibraryPath = new TiXmlElement("LibraryPath");
			xmlElmCL_LibraryPath->SetAttribute("Value", linkerDirectoriesCL);
			xmlElmCL_Linker->LinkEndChild(xmlElmCL_LibraryPath);
		}
		if(linkerLibrariesCL != "")
		{
			TiXmlElement* xmlElmCL_Library = new TiXmlElement("Library");
			xmlElmCL_Library->SetAttribute("Value", linkerLibrariesCL);
			xmlElmCL_Linker->LinkEndChild(xmlElmCL_Library);
		}
		
		// add Required attribute
		// using default Required="yes"
		xmlElmCL_Linker->SetAttribute("Required", "yes");
		
		xmlElmCL_Configuration->LinkEndChild(xmlElmCL_Linker);
		
		// add ResourceCompiler
		TiXmlElement* xmlElmCL_ResourceCompiler = new TiXmlElement("ResourceCompiler");
		xmlElmCL_ResourceCompiler->SetAttribute("Options", "");
		xmlElmCL_ResourceCompiler->SetAttribute("Required", "no");
		
		// set General options
		//<General OutputFile="./CodeLite/UtilsD.dll" IntermediateDirectory="./CodeLite/obj/Debug" Command="" CommandArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes"/>
		TiXmlElement* xmlElmCL_General = new TiXmlElement("General");
		// set OutputFile attribute
		// get output info from CodeBlocks (dependant on the following)
		// Target -> Option output="<filename path>" prefix_auto="<1 or not present>" extension_auto="<1 or not present>"
		// Target -> Option type="<filename path>"
		// Target -> Option createStaticLib="1"
		std::string outputFilePath;
		std::string outputFilePrefixAuto;
		std::string outputFileExtensionAuto;
		//std::string outputFileType; // already gotten previously in "int outputFileType"
		std::string outputFileCreateStaticLib;
		for( 	TiXmlElement* xmlElmCB_Option = xmlElmCB_Target->FirstChildElement("Option");
				xmlElmCB_Option;
				xmlElmCB_Option = xmlElmCB_Option->NextSiblingElement("Option"))
		{
			if(xmlElmCB_Option->Attribute("output") != 0)
			{
				outputFilePath = std::string(xmlElmCB_Option->Attribute("output"));
			}
			if(xmlElmCB_Option->Attribute("prefix_auto") != 0)
			{
				outputFilePrefixAuto = std::string(xmlElmCB_Option->Attribute("prefix_auto"));
			}
			if(xmlElmCB_Option->Attribute("extension_auto") != 0)
			{
				outputFileExtensionAuto = std::string(xmlElmCB_Option->Attribute("extension_auto"));
			}
			if(xmlElmCB_Option->Attribute("createStaticLib") != 0)
			{
				outputFileCreateStaticLib = std::string(xmlElmCB_Option->Attribute("createStaticLib"));
			}
		}
		
		// generate OutputFile attribute based on CodeBlocks properties
		std::string outputFileCL;
		// separate directories from output file path
		std::string outputFileCLDirectories;
		std::string outputFileCLFilename;
		// parse
		unsigned int lastSlashPos = outputFilePath.find_last_of("\\");
		if(lastSlashPos != outputFilePath.npos)
		{
			outputFileCLDirectories = outputFilePath.substr(0, lastSlashPos);
			outputFileCLFilename = outputFilePath.substr(lastSlashPos);
		}
		else
			outputFileCLFilename = outputFilePath;
		
		if(outputFilePrefixAuto == "1")
		{
			switch(outputFileType)
			{
				case 2:
					outputFileCLFilename = "lib" + outputFileCLFilename;
				break;
			}
		}
		
		if(outputFileExtensionAuto == "1")
		{
			switch(outputFileType)
			{
				// Exe's
				case 0:	// gui (no console)
				case 1: // console
					outputFileCLFilename += ".exe";
				break;
				
				// libs
				case 2: // static lib
					outputFileCLFilename += ".a";
				break;
				case 3: // dynamic lib
					outputFileCLFilename += ".dll";
				break;
				default:
				break;
			}
		}
		
		outputFileCL += outputFileCLDirectories + outputFileCLFilename;
		
		// in filename, replace "\" with "/"
		for(unsigned int idxChar = 0; idxChar < outputFileCL.size(); ++idxChar)
			if(outputFileCL[idxChar] == '\\') outputFileCL[idxChar] = '/';
		
		// set OutputFile attribute
		xmlElmCL_General->SetAttribute("OutputFile", outputFileCL);
		// set IntermediateDirectory attribute
		// based on CodeBlocks Target -> Option attribute "object_output"
		std::string CBtargetObjectOutputDir;
		for( 	TiXmlElement* xmlElmCB_Option = xmlElmCB_Target->FirstChildElement("Option");
				xmlElmCB_Option;
				xmlElmCB_Option = xmlElmCB_Option->NextSiblingElement("Option"))
		{
			if(xmlElmCB_Option->Attribute("object_output") != 0)
			{
				CBtargetObjectOutputDir = std::string(xmlElmCB_Option->Attribute("object_output"));
			}
		}
		
		// in filename, replace "\" with "/"
		for(unsigned int idxChar = 0; idxChar < CBtargetObjectOutputDir.size(); ++idxChar)
			if(CBtargetObjectOutputDir[idxChar] == '\\') CBtargetObjectOutputDir[idxChar] = '/';
		
		xmlElmCL_General->SetAttribute("IntermediateDirectory", CBtargetObjectOutputDir);
		
		// setting default parameters
		// Command="" CommandArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes"
		xmlElmCL_General->SetAttribute("Command", "");
		xmlElmCL_General->SetAttribute("CommandArguments", "");
		xmlElmCL_General->SetAttribute("WorkingDirectory", "$(IntermediateDirectory)");
		xmlElmCL_General->SetAttribute("PauseExecWhenProcTerminates", "yes");
		
		xmlElmCL_Configuration->LinkEndChild(xmlElmCL_General);
		
		//<Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="">
		//	<PostConnectCommands/>
		//	<StartupCommands/>
		//</Debugger>
		TiXmlElement* xmlElmCL_Debugger = new TiXmlElement("Debugger");
		xmlElmCL_Configuration->LinkEndChild(xmlElmCL_Debugger);
		xmlElmCL_Debugger->SetAttribute("IsRemote", "no");
		xmlElmCL_Debugger->SetAttribute("RemoteHostName", "");
		xmlElmCL_Debugger->SetAttribute("RemoteHostPort", "");
		xmlElmCL_Debugger->SetAttribute("DebuggerPath", "");
		TiXmlElement* xmlElmCL_PostConnectCommands = new TiXmlElement("PostConnectCommands");
		xmlElmCL_Debugger->LinkEndChild(xmlElmCL_PostConnectCommands);
		TiXmlElement* xmlElmCL_StartupCommands = new TiXmlElement("StartupCommands");
		xmlElmCL_Debugger->LinkEndChild(xmlElmCL_StartupCommands);
		
		//<PreBuild/>
		TiXmlElement* xmlElmCL_PreBuild = new TiXmlElement("PreBuild");
		xmlElmCL_Configuration->LinkEndChild(xmlElmCL_PreBuild);
		//<PostBuild/>
		TiXmlElement* xmlElmCL_PostBuild = new TiXmlElement("PostBuild");
		xmlElmCL_Configuration->LinkEndChild(xmlElmCL_PostBuild);
		
		// <CustomBuild Enabled="no">
		//		<RebuildCommand/>
		//		<CleanCommand/>
		//		<BuildCommand/>
        //		<PreprocessFileCommand/>
        //		<SingleFileCommand/>
        //		<MakefileGenerationCommand/>
		// 		<ThirdPartyToolName>None</ThirdPartyToolName>
        //		<WorkingDirectory/>
		// </CustomBuild>
		TiXmlElement* xmlElmCL_CustomBuild = new TiXmlElement("CustomBuild");
		xmlElmCL_Configuration->LinkEndChild(xmlElmCL_CustomBuild);
		xmlElmCL_CustomBuild->SetAttribute("Enabled", "no");
		TiXmlElement* xmlElmCL_RebuildCommand = new TiXmlElement("RebuildCommand");
		xmlElmCL_CustomBuild->LinkEndChild(xmlElmCL_RebuildCommand);
		TiXmlElement* xmlElmCL_CleanCommand = new TiXmlElement("CleanCommand");
		xmlElmCL_CustomBuild->LinkEndChild(xmlElmCL_CleanCommand);
		TiXmlElement* xmlElmCL_BuildCommand = new TiXmlElement("BuildCommand");
		xmlElmCL_CustomBuild->LinkEndChild(xmlElmCL_BuildCommand);
		TiXmlElement* xmlElmCL_PreprocessFileCommand = new TiXmlElement("PreprocessFileCommand");
		xmlElmCL_CustomBuild->LinkEndChild(xmlElmCL_PreprocessFileCommand);
		TiXmlElement* xmlElmCL_SingleFileCommand = new TiXmlElement("SingleFileCommand");
		xmlElmCL_CustomBuild->LinkEndChild(xmlElmCL_SingleFileCommand);
		TiXmlElement* xmlElmCL_MakefileGenerationCommand = new TiXmlElement("MakefileGenerationCommand");
		xmlElmCL_CustomBuild->LinkEndChild(xmlElmCL_MakefileGenerationCommand);
		TiXmlElement* xmlElmCL_ThirdPartyToolName = new TiXmlElement("ThirdPartyToolName");
		xmlElmCL_CustomBuild->LinkEndChild(xmlElmCL_ThirdPartyToolName);
		TiXmlText* xmlElmCL_ThirdPartyToolNameText = new TiXmlText("None");
		xmlElmCL_ThirdPartyToolName->LinkEndChild(xmlElmCL_ThirdPartyToolNameText);
		TiXmlElement* xmlElmCL_WorkingDirectory = new TiXmlElement("WorkingDirectory");
		xmlElmCL_CustomBuild->LinkEndChild(xmlElmCL_WorkingDirectory);
		
		//	<AdditionalRules>
        //		<CustomPostBuild/>
        //		<CustomPreBuild/>
		//	</AdditionalRules>
		TiXmlElement* xmlElmCL_AdditionalRules = new TiXmlElement("AdditionalRules");
		xmlElmCL_Configuration->LinkEndChild(xmlElmCL_AdditionalRules);
		TiXmlElement* xmlElmCL_CustomPostBuild = new TiXmlElement("CustomPostBuild");
		xmlElmCL_AdditionalRules->LinkEndChild(xmlElmCL_CustomPostBuild);
		TiXmlElement* xmlElmCL_CustomPreBuild = new TiXmlElement("CustomPreBuild");
		xmlElmCL_AdditionalRules->LinkEndChild(xmlElmCL_CustomPreBuild);
	}
	
	// add GlobalSettings
	TiXmlElement* xmlElmCL_GlobalSettings = new TiXmlElement("GlobalSettings");
	xmlElmCL_Settings->LinkEndChild(xmlElmCL_GlobalSettings);
	
	// GlobalSettings -> Compiler
	// get settings from CodeBlocks global Compiler settings (Project -> Compiler)
	TiXmlElement* xmlElmCB_Compiler = xmlElmCB_Project->FirstChildElement("Compiler");
	if(xmlElmCB_Compiler != 0)
	{
		std::vector<std::string> globalSettingsCompilerOptions;
		std::vector<std::string> globalSettingsCompilerDirectories;
		for( 	TiXmlElement* xmlElmCB_Option = xmlElmCB_Compiler->FirstChildElement("Add");
					xmlElmCB_Option;
					xmlElmCB_Option = xmlElmCB_Option->NextSiblingElement("Add"))
		{
			if(xmlElmCB_Option->Attribute("option") != 0)
			{
				globalSettingsCompilerOptions.push_back(std::string(xmlElmCB_Option->Attribute("option")));
			}
			if(xmlElmCB_Option->Attribute("directory") != 0)
			{
				globalSettingsCompilerDirectories.push_back(std::string(xmlElmCB_Option->Attribute("directory")));
			}
		}
		
		// add CB compiler options
		// Compiler Options="<add concatenated compiler options string here>"
		TiXmlElement* xmlElmCL_CompilerGlobal = new TiXmlElement("Compiler");
		xmlElmCL_GlobalSettings->LinkEndChild(xmlElmCL_CompilerGlobal);
		
		std::string compilerOptionsCL;
		for(unsigned int idxOpt = 0; idxOpt < globalSettingsCompilerOptions.size(); ++idxOpt)
		{
			compilerOptionsCL += globalSettingsCompilerOptions[idxOpt];
			if(idxOpt < globalSettingsCompilerOptions.size() - 1)
				compilerOptionsCL += " ";
		}
		xmlElmCL_CompilerGlobal->SetAttribute("Options", compilerOptionsCL);
		
		// add CB include path
		// one Compiler -> IncludePath tag for each entry
		for(unsigned int idxIncPath = 0; idxIncPath < globalSettingsCompilerDirectories.size(); ++idxIncPath)
		{
			TiXmlElement* xmlElmCL_IncludePath = new TiXmlElement("IncludePath");
			xmlElmCL_CompilerGlobal->LinkEndChild(xmlElmCL_IncludePath);
			
			// in filename, replace "\" with "/"
			for(unsigned int idxChar = 0; idxChar < globalSettingsCompilerDirectories[idxIncPath].size(); ++idxChar)
				if(globalSettingsCompilerDirectories[idxIncPath][idxChar] == '\\') globalSettingsCompilerDirectories[idxIncPath][idxChar] = '/';
			
			xmlElmCL_IncludePath->SetAttribute("Value", globalSettingsCompilerDirectories[idxIncPath]);
		}
		
	} // if(xmlElmCB_Compiler != 0)
	else
	{
		// add default compiler stuff
		/*
		<Compiler Options="">
			<IncludePath Value="."/>
		</Compiler>
		*/
		TiXmlElement* xmlElmCL_CompilerGlobal = new TiXmlElement("Compiler");
		xmlElmCL_GlobalSettings->LinkEndChild(xmlElmCL_CompilerGlobal);
		xmlElmCL_CompilerGlobal->SetAttribute("Options","");
		TiXmlElement* xmlElmCL_IncludePath = new TiXmlElement("IncludePath");
		xmlElmCL_CompilerGlobal->LinkEndChild(xmlElmCL_IncludePath);
		xmlElmCL_IncludePath->SetAttribute("Value",".");
	}
	
	// GlobalSettings -> Linker
	// get settings from CodeBlocks global Linker settings (Project -> Linker)
	TiXmlElement* xmlElmCB_Linker = xmlElmCB_Project->FirstChildElement("Linker");
	if(xmlElmCB_Linker != 0)
	{
		std::vector<std::string> globalSettingsLinkerOptions;
		std::vector<std::string> globalSettingsLinkerDirectories;
		std::vector<std::string> globalSettingsLinkerLibraries;
		for( 	TiXmlElement* xmlElmCB_Option = xmlElmCB_Linker->FirstChildElement("Add");
					xmlElmCB_Option;
					xmlElmCB_Option = xmlElmCB_Option->NextSiblingElement("Add"))
		{
			if(xmlElmCB_Option->Attribute("option") != 0)
			{
				globalSettingsLinkerOptions.push_back(std::string(xmlElmCB_Option->Attribute("option")));
			}
			if(xmlElmCB_Option->Attribute("directory") != 0)
			{
				globalSettingsLinkerDirectories.push_back(std::string(xmlElmCB_Option->Attribute("directory")));
			}
			if(xmlElmCB_Option->Attribute("library") != 0)
			{
				globalSettingsLinkerLibraries.push_back(std::string(xmlElmCB_Option->Attribute("library")));
			}
		}
		
		// add CB linker options
		TiXmlElement* xmlElmCL_LinkerGlobal = new TiXmlElement("Linker");
		xmlElmCL_GlobalSettings->LinkEndChild(xmlElmCL_LinkerGlobal);
		
		std::string linkerOptionsCL;
		for(unsigned int idxOpt = 0; idxOpt < globalSettingsLinkerOptions.size(); ++idxOpt)
		{
			linkerOptionsCL += globalSettingsLinkerOptions[idxOpt];
			if(idxOpt < globalSettingsLinkerOptions.size() - 1)
				linkerOptionsCL += " ";
		}
		xmlElmCL_LinkerGlobal->SetAttribute("Options", linkerOptionsCL);
		
		// add CB linker library path
		// one Linker -> LibraryPath tag for each entry
		for(unsigned int idxLibPath = 0; idxLibPath < globalSettingsLinkerDirectories.size(); ++idxLibPath)
		{
			TiXmlElement* xmlElmCL_LibraryPath = new TiXmlElement("LibraryPath");
			xmlElmCL_LinkerGlobal->LinkEndChild(xmlElmCL_LibraryPath);
			xmlElmCL_LibraryPath->SetAttribute("Value", globalSettingsLinkerDirectories[idxLibPath]);
		}
		
		// add CB linker libraries
		// one Linker -> Library tag for each entry
		for(unsigned int idxLib = 0; idxLib < globalSettingsLinkerLibraries.size(); ++idxLib)
		{
			TiXmlElement* xmlElmCL_Library = new TiXmlElement("Library");
			xmlElmCL_LinkerGlobal->LinkEndChild(xmlElmCL_Library);
			xmlElmCL_Library->SetAttribute("Value", globalSettingsLinkerLibraries[idxLib]);
		}
		
	} // if(xmlElmCB_Linker != 0)
	else
	{
		/*
		<Linker Options="">
			<LibraryPath Value="."/>
		</Linker>
		*/
		
		TiXmlElement* xmlElmCL_LinkerGlobal = new TiXmlElement("Linker");
		xmlElmCL_GlobalSettings->LinkEndChild(xmlElmCL_LinkerGlobal);
		xmlElmCL_LinkerGlobal->SetAttribute("Options","");
		TiXmlElement* xmlElmCL_LibraryPath = new TiXmlElement("LibraryPath");
		xmlElmCL_LinkerGlobal->LinkEndChild(xmlElmCL_LibraryPath);
		xmlElmCL_LibraryPath->SetAttribute("Value", ".");
		
	}
	
	// GlobalSettings -> ResourceCompiler
	// get settings from CodeBlocks global ResourceCompiler settings (Project -> ResourceCompiler)
	TiXmlElement* xmlElmCB_ResourceCompiler = xmlElmCB_Project->FirstChildElement("ResourceCompiler");
	if(xmlElmCB_ResourceCompiler != 0)
	{
		// TODO really get it, using default
		
		// <ResourceCompiler Options=""/>
		TiXmlElement* xmlElmCL_ResourceCompiler = new TiXmlElement("ResourceCompiler");
		xmlElmCL_GlobalSettings->LinkEndChild(xmlElmCL_ResourceCompiler);
		xmlElmCL_ResourceCompiler->SetAttribute("Options", "");
	}
	else
	{
		// <ResourceCompiler Options=""/>
		TiXmlElement* xmlElmCL_ResourceCompiler = new TiXmlElement("ResourceCompiler");
		xmlElmCL_GlobalSettings->LinkEndChild(xmlElmCL_ResourceCompiler);
		xmlElmCL_ResourceCompiler->SetAttribute("Options", "");
	}
	
	// add CodeLite Dependencies, one for each Configuration
	// use configurationNamesList
	for(unsigned int idxConfigName = 0; idxConfigName < configurationNamesList.size(); ++idxConfigName)
	{
		TiXmlElement* xmlElmCL_Dependencies = new TiXmlElement("Dependencies");
		xmlElmCL_CodeLite_Project->LinkEndChild(xmlElmCL_Dependencies);
		xmlElmCL_Dependencies->SetAttribute("Name", configurationNamesList[idxConfigName]);
	}
	
	
	XMLUtils::dump_to_stdout(xmlElmCL_Root); // debug
	
	// save CodeLite project
	xmlElmCL_Root->SaveFile(filepathCodeLiteProject);

        return 0;
}
XMLUtils.h:

Code: Select all

#ifndef XMLUTILS_H
#define XMLUTILS_H

#define TIXML_USE_STL
#include <tinyxml.h>

class XMLUtils {

	public:
		// tutorial demo program
		//#include "stdafx.h"
		//#include "tinyxml.h"
		
		static const int NUM_INDENTS_PER_SPACE = 2;

		// ----------------------------------------------------------------------
		// STDOUT dump and indenting utility functions
		// ----------------------------------------------------------------------

		static const char * getIndent( unsigned int numIndents )
		{
			static const char * pINDENT="                                      + ";
			static const unsigned int LENGTH=strlen( pINDENT );
			unsigned int n=numIndents*NUM_INDENTS_PER_SPACE;
			if ( n > LENGTH ) n = LENGTH;

			return &pINDENT[ LENGTH-n ];
		}

		// same as getIndent but no "+" at the end
		static const char * getIndentAlt( unsigned int numIndents )
		{
			static const char * pINDENT="                                        ";
			static const unsigned int LENGTH=strlen( pINDENT );
			unsigned int n=numIndents*NUM_INDENTS_PER_SPACE;
			if ( n > LENGTH ) n = LENGTH;

			return &pINDENT[ LENGTH-n ];
		}

		static int dump_attribs_to_stdout(TiXmlElement* pElement, unsigned int indent)
		{
			if ( !pElement ) return 0;

			TiXmlAttribute* pAttrib=pElement->FirstAttribute();
			int i=0;
			int ival;
			double dval;
			const char* pIndent=getIndent(indent);
			printf("\n");
			while (pAttrib)
			{
				printf( "%s%s: value=[%s]", pIndent, pAttrib->Name(), pAttrib->Value());

				if (pAttrib->QueryIntValue(&ival)==TIXML_SUCCESS)    printf( " int=%d", ival);
				if (pAttrib->QueryDoubleValue(&dval)==TIXML_SUCCESS) printf( " d=%1.1f", dval);
				printf( "\n" );
				i++;
				pAttrib=pAttrib->Next();
			}
			return i;	
		}

		static void dump_to_stdout( TiXmlNode* pParent, unsigned int indent = 0 )
		{
			if ( !pParent ) return;

			TiXmlNode* pChild;
			TiXmlText* pText;
			int t = pParent->Type();
			printf( "%s", getIndent(indent));
			int num;

			switch ( t )
			{
			case TiXmlNode::DOCUMENT:
				printf( "Document" );
				break;

			case TiXmlNode::ELEMENT:
				printf( "Element [%s]", pParent->Value() );
				num=dump_attribs_to_stdout(pParent->ToElement(), indent+1);
				switch(num)
				{
					case 0:  printf( " (No attributes)"); break;
					case 1:  printf( "%s1 attribute", getIndentAlt(indent)); break;
					default: printf( "%s%d attributes", getIndentAlt(indent), num); break;
				}
				break;

			case TiXmlNode::COMMENT:
				printf( "Comment: [%s]", pParent->Value());
				break;

			case TiXmlNode::UNKNOWN:
				printf( "Unknown" );
				break;

			case TiXmlNode::TEXT:
				pText = pParent->ToText();
				printf( "Text: [%s]", pText->Value() );
				break;

			case TiXmlNode::DECLARATION:
				printf( "Declaration" );
				break;
			default:
				break;
			}
			printf( "\n" );
			for ( pChild = pParent->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) 
			{
				dump_to_stdout( pChild, indent+1 );
			}
		}

		// load the named file and dump its structure to STDOUT
		static void dump_to_stdout(const char* pFilename)
		{
			TiXmlDocument doc(pFilename);
			bool loadOkay = doc.LoadFile();
			if (loadOkay)
			{
				printf("\n%s:\n", pFilename);
				dump_to_stdout( &doc ); // defined later in the tutorial
			}
			else
			{
				printf("Failed to load file \"%s\"\n", pFilename);
			}
		}
};

#endif // XMLUTILS_H
Last edited by TurboLento on Tue Nov 09, 2010 3:21 am, edited 3 times in total.
User avatar
eranif
CodeLite Plugin
Posts: 6372
Joined: Wed Feb 06, 2008 9:29 pm
Genuine User: Yes
IDE Question: C++
Contact:

Re: Code::Blocks project importer / CodeLite .project format

Post by eranif »

Sorry, I dont have a specifications for that.

If you have a specific question, just ask it here in this thread

Eran
Make sure you have read the HOW TO POST thread
TurboLento
CodeLite Enthusiast
Posts: 12
Joined: Mon Sep 27, 2010 2:51 am
Genuine User: Yes
IDE Question: c++
Contact:

Re: Code::Blocks project importer / CodeLite .project format

Post by TurboLento »

Thanks, I'll post when I progress further or get stuck on something.
TurboLento
CodeLite Enthusiast
Posts: 12
Joined: Mon Sep 27, 2010 2:51 am
Genuine User: Yes
IDE Question: c++
Contact:

Re: Code::Blocks project importer / CodeLite .project format

Post by TurboLento »

Ok, here are a few questions. I'm using this convention to indicate tag hierarchy:
<Tag> -> <Child Tag>

<CodeLite_Project> -> <Dependencies />:
1. What is the relevance of these? Must there be a Dependencies tag for each build target (<CodeLite_Project> -> <Settings> -> <Configuration Name="">)?
2. What about the order? I've seen it show up after <CodeLite_Project> -> <VirtualDirectory> and before <CodeLite_Project> -> <Settings>, or after <CodeLite_Project> -> <Settings>. Is the order irrelevant?

<CodeLite_Project> -> <Settings>:
3. what is the purpose of the "Name" attribute for the Settings element? I guess it's using the name of the type of project initially defined (I've used a test which I started as "Dynamic Library", but added a few "Static Library" configurations and this remains the same).

4. There's a <CodeLite_Project> -> <Plugins> -> <Plugin Name="qmake">, with a CDATA string like so: <![CDATA[00060001N0003All0000000000000001N0005Debug0000000000000001N0011DebugStatic0000000000000001N0012DynamicDebug0000000000000001N0014DynamicRelease0000000000000001N0007Release000000000000]]>
Is this mandatory, and if so, how is this string generated?

5. Is there a way for me to get the available CodeLite's "CompilerType" names? To be able to present to the user for him to choose the compiler for each Configuration, when converting.

It's all I have so far, thanks for the help!
User avatar
eranif
CodeLite Plugin
Posts: 6372
Joined: Wed Feb 06, 2008 9:29 pm
Genuine User: Yes
IDE Question: C++
Contact:

Re: Code::Blocks project importer / CodeLite .project format

Post by eranif »

The order of the tags is not relevant. It is an XML file, what only matters here is that the hierarchy is set up correctly.
TurboLento wrote:<CodeLite_Project> -> <Dependencies />:
1. What is the relevance of these?
Each project can define its build order (right click a project and select 'Build Order')
TurboLento wrote:Must there be a Dependencies tag for each build target (<CodeLite_Project> -> <Settings> -> <Configuration Name="">)?
Yes, each configuration defines its own build order.
TurboLento wrote:<CodeLite_Project> -> <Settings>:
3. what is the purpose of the "Name" attribute for the Settings element? I guess it's using the name of the type of project initially defined (I've used a test which I started as "Dynamic Library", but added a few "Static Library" configurations and this remains the same).
There can be 3 different types: Static LIbrary, Dynamic Library and Executable
TurboLento wrote:4. There's a <CodeLite_Project> -> <Plugins> -> <Plugin Name="qmake">, with a CDATA string like so: <![CDATA[00060001N0003All0000000000000001N0005Debug0000000000000001N0011DebugStatic0000000000000001N0012DynamicDebug0000000000000001N0014DynamicRelease0000000000000001N0007Release000000000000]]>Is this mandatory, and if so, how is this string generated?
This information is the 'plugins' section of the project, each plugin can save information into the project file using a special API. For your matter: you can ignore this.
TurboLento wrote:5. Is there a way for me to get the available CodeLite's "CompilerType" names? To be able to present to the user for him to choose the compiler for each Configuration, when converting.
If the question is by using codelite classes? then Yes. Here is a snippet:

THIS CODE CAN NOT BE USED FROM INSIDE A PLUGIN:

Code: Select all

	
       //append list of compilers
	wxArrayString choices;
	//get list of compilers from configuration file
	BuildSettingsConfigCookie cookie;
	CompilerPtr cmp = BuildSettingsConfigST::Get()->GetFirstCompiler(cookie);
	while (cmp) {
		choices.Add(cmp->GetName());
		cmp = BuildSettingsConfigST::Get()->GetNextCompiler(cookie);
	}
USE THIS CODE CAN BE USED FROM WITHIN PLUGIN:

Code: Select all

	
       //append list of compilers
	wxArrayString choices;
	//get list of compilers from configuration file
	BuildSettingsConfigCookie cookie;
	CompilerPtr cmp = m_mgr->GetBuildSettingsConfigManager()->GetFirstCompiler(cookie);
	while (cmp) {
		choices.Add(cmp->GetName());
		cmp = m_mgr->GetBuildSettingsConfigManager()->GetNextCompiler(cookie);
	}
Eran
Make sure you have read the HOW TO POST thread
TurboLento
CodeLite Enthusiast
Posts: 12
Joined: Mon Sep 27, 2010 2:51 am
Genuine User: Yes
IDE Question: c++
Contact:

Re: Code::Blocks project importer / CodeLite .project format

Post by TurboLento »

Thanks a lot! I'll go back to work on this.
TurboLento
CodeLite Enthusiast
Posts: 12
Joined: Mon Sep 27, 2010 2:51 am
Genuine User: Yes
IDE Question: c++
Contact:

Re: Code::Blocks project importer / CodeLite .project format

Post by TurboLento »

I seem to have hit a wall here. I've written the converter, and converted a project file (still using some hardcoded values, but it should load fine).
When I do "Add an existing Project" to my workspace, with my converted project, I get the message "AddProjectToBuildMatrix was called with NULL project". What could be the cause for this? I believe my files are identical (ignoring the "Plugins" part).

Here are the two .project files. The first is one that was created normally in CodeLite, and can be added into the workspace without a problem. The second is the result of converting from the Codeblocks file, and throws the above error.

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<CodeLite_Project Name="Utils_CodeLite" InternalType="Library">
  <Plugins>
    <Plugin Name="qmake">
      <![CDATA[00060001N0003All0000000000000001N0005Debug0000000000000001N0011DebugStatic0000000000000001N0012DynamicDebug0000000000000001N0014DynamicRelease0000000000000001N0007Release000000000000]]>
    </Plugin>
  </Plugins>
  <Description/>
  <Dependencies/>
  <VirtualDirectory Name="DebugLogger">
    <File Name="DebugLogger/Logger.h"/>
    <File Name="Logger.cpp"/>
  </VirtualDirectory>
  <VirtualDirectory Name="Math">
    <File Name="Math/Math.cpp"/>
    <File Name="Math/Math.h"/>
    <File Name="Math/MathGeometry.cpp"/>
  </VirtualDirectory>
  <VirtualDirectory Name="String">
    <File Name="String/UtilsString.cpp"/>
    <File Name="String/UtilsString.h"/>
  </VirtualDirectory>
  <VirtualDirectory Name="Timer">
    <File Name="Timer/Timer.cpp"/>
    <File Name="Timer/Timer.h"/>
  </VirtualDirectory>
  <VirtualDirectory Name="Utils">
    <File Name="Utils/Containers.h"/>
  </VirtualDirectory>
  <VirtualDirectory Name="Vector">
    <File Name="Vector/Vector2.cpp"/>
    <File Name="Vector/Vector2.h"/>
  </VirtualDirectory>
  <Settings Type="Dynamic Library">
    <GlobalSettings>
      <Compiler Options="">
        <IncludePath Value="."/>
      </Compiler>
      <Linker Options="">
        <LibraryPath Value="."/>
      </Linker>
      <ResourceCompiler Options=""/>
    </GlobalSettings>
    <Configuration Name="Debug" CompilerType="G++ Mingw4.4.3" DebuggerType="GNU gdb debugger" Type="Dynamic Library" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
      <Compiler Options="-g" Required="yes" PreCompiledHeader="">
        <IncludePath Value="."/>
      </Compiler>
      <Linker Options="" Required="yes"/>
      <ResourceCompiler Options="" Required="no"/>
      <General OutputFile="./CodeLite/UtilsD.dll" IntermediateDirectory="./CodeLite/obj/Debug" Command="" CommandArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes"/>
      <Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="">
        <PostConnectCommands/>
        <StartupCommands/>
      </Debugger>
      <PreBuild/>
      <PostBuild/>
      <CustomBuild Enabled="no">
        <RebuildCommand/>
        <CleanCommand/>
        <BuildCommand/>
        <PreprocessFileCommand/>
        <SingleFileCommand/>
        <MakefileGenerationCommand/>
        <ThirdPartyToolName>None</ThirdPartyToolName>
        <WorkingDirectory/>
      </CustomBuild>
      <AdditionalRules>
        <CustomPostBuild/>
        <CustomPreBuild/>
      </AdditionalRules>
    </Configuration>
    <Configuration Name="DebugStatic" CompilerType="G++ Mingw4.4.3" DebuggerType="GNU gdb debugger" Type="Static Library" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
      <Compiler Options="-g" Required="yes" PreCompiledHeader="">
        <IncludePath Value="."/>
      </Compiler>
      <Linker Options="" Required="yes"/>
      <ResourceCompiler Options="" Required="no"/>
      <General OutputFile="./CodeLite/libUtilsD_s.a" IntermediateDirectory="./CodeLite/obj/DebugStatic" Command="" CommandArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes"/>
      <Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="">
        <PostConnectCommands/>
        <StartupCommands/>
      </Debugger>
      <PreBuild/>
      <PostBuild/>
      <CustomBuild Enabled="no">
        <RebuildCommand/>
        <CleanCommand/>
        <BuildCommand/>
        <PreprocessFileCommand/>
        <SingleFileCommand/>
        <MakefileGenerationCommand/>
        <ThirdPartyToolName>None</ThirdPartyToolName>
        <WorkingDirectory/>
      </CustomBuild>
      <AdditionalRules>
        <CustomPostBuild/>
        <CustomPreBuild/>
      </AdditionalRules>
    </Configuration>
    <Configuration Name="Release" CompilerType="G++ Mingw4.4.3" DebuggerType="GNU gdb debugger" Type="Dynamic Library" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
      <Compiler Options="" Required="yes" PreCompiledHeader="">
        <IncludePath Value="."/>
      </Compiler>
      <Linker Options="-O2" Required="yes"/>
      <ResourceCompiler Options="" Required="no"/>
      <General OutputFile="./CodeLite/Utils.dll" IntermediateDirectory="./CodeLite/obj/Release" Command="" CommandArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes"/>
      <Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="">
        <PostConnectCommands/>
        <StartupCommands/>
      </Debugger>
      <PreBuild/>
      <PostBuild/>
      <CustomBuild Enabled="no">
        <RebuildCommand/>
        <CleanCommand/>
        <BuildCommand/>
        <PreprocessFileCommand/>
        <SingleFileCommand/>
        <MakefileGenerationCommand/>
        <ThirdPartyToolName>None</ThirdPartyToolName>
        <WorkingDirectory/>
      </CustomBuild>
      <AdditionalRules>
        <CustomPostBuild/>
        <CustomPreBuild/>
      </AdditionalRules>
    </Configuration>
  </Settings>
  <Dependencies Name="Debug"/>
  <Dependencies Name="DebugStatic"/>
  <Dependencies Name="Release"/>
</CodeLite_Project>

Code: Select all

<?xml version="1.0" encoding="utf-8" ?>
<CodeLite_Project Name="Utils" InternalType="Library">
    <Plugins />
    <Description />
    <Dependencies />
    <VirtualDirectory Name="DebugLogger">
        <File Name="DebugLogger/Logger.h" />
    </VirtualDirectory>
    <VirtualDirectory Name="Math">
        <File Name="Math/Math.cpp" />
        <File Name="Math/Math.h" />
        <File Name="Math/MathGeometry.cpp" />
    </VirtualDirectory>
    <VirtualDirectory Name="String">
        <File Name="String/UtilsString.cpp" />
        <File Name="String/UtilsString.h" />
    </VirtualDirectory>
    <VirtualDirectory Name="Timer">
        <File Name="Timer/Timer.cpp" />
        <File Name="Timer/Timer.h" />
    </VirtualDirectory>
    <VirtualDirectory Name="Utils">
        <File Name="Utils/Containers.h" />
    </VirtualDirectory>
    <VirtualDirectory Name="Vector">
        <File Name="Vector/Vector2.cpp" />
        <File Name="Vector/Vector2.h" />
    </VirtualDirectory>
    <Settings Type="Dynamic Library">
        <Configuration Name="DynamicDebug" CompilerType="G++ Mingw4.4.3" DebuggerType="GNU gdb debugger" Type="Dynamic Library" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
            <Compiler Options="-g" Required="yes" PreCompiledHeader="">
                <IncludePath Value="" />
            </Compiler>
            <Linker Options="" Required="yes" />
            <General OutputFile="libs/UtilsD.dll" IntermediateDirectory="obj/DynamicDebug/" Command="" CommandArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes" />
            <Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="">
                <PostConnectCommands />
                <StartupCommands />
            </Debugger>
            <PreBuild />
            <PostBuild />
            <CustomBuild Enabled="no">
                <RebuildCommand />
                <CleanCommand />
                <BuildCommand />
                <PreprocessFileCommand />
                <SingleFileCommand />
                <MakefileGenerationCommand />
                <ThirdPartyToolName>None</ThirdPartyToolName>
                <WorkingDirectory />
            </CustomBuild>
            <AdditionalRules>
                <CustomPostBuild />
                <CustomPreBuild />
            </AdditionalRules>
        </Configuration>
        <Configuration Name="DynamicRelease" CompilerType="G++ Mingw4.4.3" DebuggerType="GNU gdb debugger" Type="Dynamic Library" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
            <Compiler Options="-O2" Required="yes" PreCompiledHeader="">
                <IncludePath Value="" />
            </Compiler>
            <Linker Options="-s" Required="yes" />
            <General OutputFile="libs/Utils.dll" IntermediateDirectory="obj/DynamicRelease/" Command="" CommandArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes" />
            <Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="">
                <PostConnectCommands />
                <StartupCommands />
            </Debugger>
            <PreBuild />
            <PostBuild />
            <CustomBuild Enabled="no">
                <RebuildCommand />
                <CleanCommand />
                <BuildCommand />
                <PreprocessFileCommand />
                <SingleFileCommand />
                <MakefileGenerationCommand />
                <ThirdPartyToolName>None</ThirdPartyToolName>
                <WorkingDirectory />
            </CustomBuild>
            <AdditionalRules>
                <CustomPostBuild />
                <CustomPreBuild />
            </AdditionalRules>
        </Configuration>
        <GlobalSettings>
            <Compiler Options="-Wall">
                <IncludePath Value="../Utils" />
            </Compiler>
            <Linker Options="">
                <LibraryPath Value="." />
            </Linker>
            <ResourceCompiler Options="" />
        </GlobalSettings>
    </Settings>
    <Dependencies Name="DynamicDebug" />
    <Dependencies Name="DynamicRelease" />
</CodeLite_Project>
Any suggestions? Thanks in advance
User avatar
eranif
CodeLite Plugin
Posts: 6372
Joined: Wed Feb 06, 2008 9:29 pm
Genuine User: Yes
IDE Question: C++
Contact:

Re: Code::Blocks project importer / CodeLite .project format

Post by eranif »

The problem is probably a mismatch with the project name and the project name that exists in the workspace.

From what I can see the C::B generated project is named Utils_CodeLite
while the one generated from codelite is simply named "Utils"

What is the name in the BuildMatrix? (open the .workspace file and search for the project name)

Also, make sure that the project name is consistent across all appearances in the .workspace file
Eran
Make sure you have read the HOW TO POST thread
TurboLento
CodeLite Enthusiast
Posts: 12
Joined: Mon Sep 27, 2010 2:51 am
Genuine User: Yes
IDE Question: c++
Contact:

Re: Code::Blocks project importer / CodeLite .project format

Post by TurboLento »

Renaming the output .project file to have the same name as defined in the project stopped the error, thanks!
However, shouldn't the file name be totally independant from the Project Name? Isn't this a bug?

There was a lot of repeated tags in the workspace file, for the project that I was trying to add and failing (probably one for every time I tried adding the project and got the error). Howeverm, inside the <BuildMatrix> -> <WorkspaceConfiguration> there was no reference to the project with the error (I'm just pointing this out in case it's something you're not aware of and it may be useful for you in tracking down errors).

There were a few things that aren't yet clear to me regarding some of the tags in a .project file, hopefully you can help me with them:

Tag "CodeLite_Project", attribute "InternalType":
from what I gather, this can be one of the following: Console, GUI, Library, Others, UnitTest++, User Templates.
But a Project can have several Configurations, and these can be of each of the types above. So, why have this attribute defined per project (isn't it both redundant and clashing with Configurations of other types? As an example, I can have a project that builds a static library, a dynamic library and a console executable, so this parameter is confusing me)

Tag "CodeLite_Project -> Settings", attribute "Type":
same question as above. Type specifies one of "Static Library, Dynamic Library and Executable", but these can be defined per Configuration, and "Settings" encompasses several Configurations. Isn't this attribute also redundant?

You provided code to accessing the CompilerTypes. Though I haven't tried it yet, what is the "m_mgr" variable?

Thanks for all the help! I'm providing the code I have in this thread's first post, and will update as I test and improve on it, hoping it might help others.
User avatar
eranif
CodeLite Plugin
Posts: 6372
Joined: Wed Feb 06, 2008 9:29 pm
Genuine User: Yes
IDE Question: C++
Contact:

Re: Code::Blocks project importer / CodeLite .project format

Post by eranif »

TurboLento wrote:However, shouldn't the file name be totally independant from the Project Name? Isn't this a bug?
the file name has no restrictions and it is NOT tied to the project name. The error you had was because the project name did not exist

the workspace was referring to a project name 'Utils' while you created a project named 'Utils_CodeLite'
TurboLento wrote:here was a lot of repeated tags in the workspace file, for the project that I was trying to add and failing (probably one for every time I tried adding the project and got the error). Howeverm, inside the <BuildMatrix> -> <WorkspaceConfiguration> there was no reference to the project with the error (I'm just pointing this out in case it's something you're not aware of and it may be useful for you in tracking down errors).
Posting the .workspace + .project will make it easier for me to see what the problem is. But I am pretty sure that that root problem is what I wrote at the start of this post.
TurboLento wrote:from what I gather, this can be one of the following: Console, GUI, Library, Others, UnitTest++, User Templates.
But a Project can have several Configurations,
There is no relation between the two attributes. The 'InternalType' is meant for display ONLY (this is how codelite knows where to place it in the 'New Project' dialog)

The 'Settings' are total different beast. The settings are the object that wraps the various configurations.
TurboLento wrote:same question as above. Type specifies one of "Static Library, Dynamic Library and Executable", but these can be defined per Configuration, and "Settings" encompasses several Configurations. Isn't this attribute also redundant?
This is the 'Global' project type, which can be overridden per build configuration. By default each build configuration will inherit the global 'Type' and then you can modify it. so you can have the same project producing different 'Types' (e.g. the same project can produce static library, dynamic library or even an executable)
TurboLento wrote:Though I haven't tried it yet, what is the "m_mgr" variable?
m_mgr is of type 'IManager' (Interface to the global manager class)
This member exits in every class that inherits from IPlugin (i.e. all plugins has it)
Has of codelite 2.8.X you can use both code snippets to access the compiler types.

General note about plugins:
Note that if you are writing a plugin and you need to add an include path so you can include one of codelite's headers it means that you are doing something wrong.
A plugin can only include files from the following projects:
  • plugin_sdk
  • CodeLite
  • wxscintilla
  • wxqlite3
  • Interfaces
Eran
Make sure you have read the HOW TO POST thread
Post Reply