ENH: add a simple CodeBlocks extra generator, early alpha stage, there seems

to be interest in it

Alex
This commit is contained in:
Alexander Neundorf 2007-07-13 00:58:43 -04:00
parent 2509e24afe
commit 378a8e99f9
4 changed files with 337 additions and 1 deletions

View File

@ -174,7 +174,8 @@ SET(SRCS
# Kdevelop only works on UNIX and not windows # Kdevelop only works on UNIX and not windows
IF(UNIX) IF(UNIX)
SET(SRCS ${SRCS} SET(SRCS ${SRCS}
cmGlobalKdevelopGenerator.cxx) cmGlobalKdevelopGenerator.cxx
cmExtraCodeBlocksGenerator.cxx)
ENDIF(UNIX) ENDIF(UNIX)
# XCode only works on apple # XCode only works on apple
IF(APPLE) IF(APPLE)

View File

@ -0,0 +1,269 @@
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
Copyright (c) 2004 Alexander Neundorf neundorf@kde.org, All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "cmExtraCodeBlocksGenerator.h"
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmake.h"
#include "cmSourceFile.h"
#include "cmGeneratedFileStream.h"
#include "cmTarget.h"
#include <cmsys/SystemTools.hxx>
//----------------------------------------------------------------------------
void cmExtraCodeBlocksGenerator
::GetDocumentation(cmDocumentationEntry& entry, const char*) const
{
entry.name = this->GetName();
entry.brief = "Generates CodeBlocks project files.";
entry.full =
"Project files for CodeBlocks will be created in the top directory "
"and in every subdirectory which features a CMakeLists.txt file "
"containing a PROJECT() call. "
"Additionally a hierarchy of UNIX makefiles is generated into the "
"build tree. Any "
"standard UNIX-style make program can build the project through the "
"default make target. A \"make install\" target is also provided.";
}
cmExtraCodeBlocksGenerator::cmExtraCodeBlocksGenerator()
:cmExternalMakefileProjectGenerator()
{
this->SupportedGlobalGenerators.push_back("Unix Makefiles");
}
void cmExtraCodeBlocksGenerator::SetGlobalGenerator(
cmGlobalGenerator* generator)
{
cmExternalMakefileProjectGenerator::SetGlobalGenerator(generator);
cmGlobalUnixMakefileGenerator3* mf = (cmGlobalUnixMakefileGenerator3*)
generator;
mf->SetToolSupportsColor(false);
mf->SetForceVerboseMakefiles(true);
}
void cmExtraCodeBlocksGenerator::Generate()
{
const cmMakefile* topLevelMakefile = this->GlobalGenerator->GetLocalGenerators()[0]->GetMakefile();
std::string workspaceName = topLevelMakefile->GetProjectName();
std::string outputDir=topLevelMakefile->GetStartOutputDirectory();
std::string workspaceFilename = outputDir;
workspaceFilename += "/";
workspaceFilename += workspaceName;
workspaceFilename += ".workspace";
cmGeneratedFileStream fout(workspaceFilename.c_str());
if(!fout)
{
return;
}
fout<<"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\n"
"<CodeBlocks_workspace_file>\n"
" <Workspace title=\""<<workspaceName<<"\">\n";
bool firstProject = true;
// for each sub project in the project create
// a kdevelop project
for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator
it = this->GlobalGenerator->GetProjectMap().begin();
it!= this->GlobalGenerator->GetProjectMap().end();
++it)
{
const cmMakefile* mf=it->second[0]->GetMakefile();
std::string filename=mf->GetStartOutputDirectory();
filename+="/";
filename+=mf->GetProjectName();
filename+=".cbp";
if (firstProject)
{
fout<<" <Project filename=\""<< filename<<"\" active=\"1\"/>\n";
}
else
{
fout<<" <Project filename=\""<< filename<<"\" />\n";
}
// create a project file
this->CreateProjectFile(it->second);
}
fout<<" </Workspace>\n"
"</CodeBlocks_workspace_file>\n";
}
/* create the project file, if it already exists, merge it with the
existing one, otherwise create a new one */
void cmExtraCodeBlocksGenerator::CreateProjectFile(const std::vector<cmLocalGenerator*>& lgs)
{
const cmMakefile* mf=lgs[0]->GetMakefile();
std::string outputDir=mf->GetStartOutputDirectory();
std::string projectDir=mf->GetHomeDirectory();
std::string projectName=mf->GetProjectName();
std::string filename=outputDir+"/";
filename+=projectName+".cbp";
std::string sessionFilename=outputDir+"/";
sessionFilename+=projectName+".layout";
/* if (cmSystemTools::FileExists(filename.c_str()))
{
this->MergeProjectFiles(outputDir, projectDir, filename,
cmakeFilePattern, sessionFilename);
}
else */
{
this->CreateNewProjectFile(lgs, filename);
}
}
void cmExtraCodeBlocksGenerator
::CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs,
const std::string& filename)
{
const cmMakefile* mf=lgs[0]->GetMakefile();
cmGeneratedFileStream fout(filename.c_str());
if(!fout)
{
return;
}
std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
fout<<"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\n"
"<CodeBlocks_project_file>\n"
" <FileVersion major=\"1\" minor=\"6\" />\n"
" <Project>\n";
fout<<" <Option title=\"" << mf->GetProjectName()<<"\" />\n"
" <Option makefile_is_custom=\"1\" />\n"
" <Option compiler=\"gcc\" />\n"
" <Build>\n";
bool installTargetCreated = false;
bool testTargetCreated = false;
bool packageTargetCreated = false;
for (std::vector<cmLocalGenerator*>::const_iterator lg=lgs.begin();
lg!=lgs.end(); lg++)
{
cmMakefile* makefile=(*lg)->GetMakefile();
cmTargets& targets=makefile->GetTargets();
for (cmTargets::iterator ti = targets.begin();
ti != targets.end(); ti++)
{
switch(ti->second.GetType())
{
case cmTarget::GLOBAL_TARGET:
if ((ti->first=="install") && (installTargetCreated==false))
{
installTargetCreated=true;
}
else if ((ti->first=="package") && (packageTargetCreated==false))
{
packageTargetCreated=true;
}
else if ((ti->first=="test") && (testTargetCreated==false))
{
testTargetCreated=true;
}
else
{
break;
}
case cmTarget::EXECUTABLE:
case cmTarget::STATIC_LIBRARY:
case cmTarget::SHARED_LIBRARY:
case cmTarget::MODULE_LIBRARY:
// case cmTarget::UTILITY:
fout<<" <Target title=\""<<ti->first<<"\">\n"
" <Option output=\""<<ti->second.GetLocation(0)<<"\" prefix_auto=\"0\" extension_auto=\"0\" />\n"
" <Option working_dir=\""<<makefile->GetStartOutputDirectory()<<"\" />\n"
" <Option type=\"0\" />\n"
" <Option compiler=\"gcc\" />\n"
" <MakeCommands>\n";
fout<<" <Build command=\""<<make<<" -f "<<makefile->GetStartOutputDirectory()<<"/Makefile "<<ti->first<<"\" />\n";
fout<<" <CompileFile command=\""<<make<<" -f "<<makefile->GetStartOutputDirectory()<<"/Makefile "<<ti->first<<"\" />\n";
fout<<" <Clean command=\""<<make<<" -f "<<makefile->GetStartOutputDirectory()<<"/Makefile clean\" />\n";
fout<<" <DistClean command=\""<<make<<" -f "<<makefile->GetStartOutputDirectory()<<"/Makefile clean\" />\n";
fout<<" </MakeCommands>\n"
" </Target>\n";
// if (ti->second.GetType()==cmTarget::UTILITY) fout<<"****** UTILITY \n";
// if (ti->second.GetType()==cmTarget::GLOBAL_TARGET) fout<<"****** GLOBAL_YESTERDAY \n";
break;
default:
break;
}
}
}
fout<<" </Build>\n";
std::map<std::string, std::string> sourceFiles;
for (std::vector<cmLocalGenerator*>::const_iterator lg=lgs.begin();
lg!=lgs.end(); lg++)
{
cmMakefile* makefile=(*lg)->GetMakefile();
cmTargets& targets=makefile->GetTargets();
for (cmTargets::iterator ti = targets.begin();
ti != targets.end(); ti++)
{
switch(ti->second.GetType())
{
case cmTarget::EXECUTABLE:
case cmTarget::STATIC_LIBRARY:
case cmTarget::SHARED_LIBRARY:
case cmTarget::MODULE_LIBRARY:
{
const std::vector<cmSourceFile*>& sources=ti->second.GetSourceFiles();
for (std::vector<cmSourceFile*>::const_iterator si=sources.begin();
si!=sources.end(); si++)
{
sourceFiles[(*si)->GetFullPath()] = ti->first;
}
}
default:
break;
}
}
}
for (std::map<std::string, std::string>::const_iterator sit=sourceFiles.begin();
sit!=sourceFiles.end();
++sit)
{
fout<<" <Unit filename=\""<<sit->first <<"\">\n";
fout<<" </Unit>\n";
}
fout<<" </Project>\n"
"</CodeBlocks_project_file>\n";
}

View File

@ -0,0 +1,63 @@
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
Copyright (c) 2004 Alexander Neundorf, neundorf@kde.org. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef cmExtraCodeBlocksGenerator_h
#define cmExtraCodeBlocksGenerator_h
#include "cmExternalMakefileProjectGenerator.h"
class cmLocalGenerator;
class cmMakefile;
/** \class cmExtraCodeBlocksGenerator
* \brief Write CodeBlocks project files for Makefile based projects
*
* This generator is in early alpha stage.
*/
class cmExtraCodeBlocksGenerator : public cmExternalMakefileProjectGenerator
{
public:
cmExtraCodeBlocksGenerator();
virtual void SetGlobalGenerator(cmGlobalGenerator* generator);
virtual const char* GetName() const
{ return cmExtraCodeBlocksGenerator::GetActualName();}
static const char* GetActualName() { return "CodeBlocks";}
static cmExternalMakefileProjectGenerator* New()
{ return new cmExtraCodeBlocksGenerator; }
/** Get the documentation entry for this generator. */
virtual void GetDocumentation(cmDocumentationEntry& entry,
const char* fullName) const;
virtual void Generate();
private:
/** Create the foo.kdevelop file. This one calls MergeProjectFiles()
if it already exists, otherwise createNewProjectFile() The project
files will be created in \a outputDir (in the build tree), the
kdevelop project dir will be set to \a projectDir (in the source
tree). \a cmakeFilePattern consists of a lists of all cmake
listfiles used by this CMakeLists.txt */
void CreateProjectFile(const std::vector<cmLocalGenerator*>& lgs);
///! Creates a new foo.kdevelop and a new foo.kdevses file
void CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs,
const std::string& filename);
};
#endif

View File

@ -72,6 +72,7 @@
#ifdef CMAKE_USE_KDEVELOP #ifdef CMAKE_USE_KDEVELOP
# include "cmGlobalKdevelopGenerator.h" # include "cmGlobalKdevelopGenerator.h"
# include "cmExtraCodeBlocksGenerator.h"
#endif #endif
#include <stdlib.h> // required for atoi #include <stdlib.h> // required for atoi
@ -1447,6 +1448,8 @@ void cmake::AddDefaultExtraGenerators()
#endif #endif
// e.g. eclipse ? // e.g. eclipse ?
#ifdef CMAKE_USE_KDEVELOP #ifdef CMAKE_USE_KDEVELOP
this->AddExtraGenerator(cmExtraCodeBlocksGenerator::GetActualName(),
&cmExtraCodeBlocksGenerator::New);
this->AddExtraGenerator(cmGlobalKdevelopGenerator::GetActualName(), this->AddExtraGenerator(cmGlobalKdevelopGenerator::GetActualName(),
&cmGlobalKdevelopGenerator::New); &cmGlobalKdevelopGenerator::New);
// for kdevelop also add the generator with just the name of the // for kdevelop also add the generator with just the name of the