| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 | /*=========================================================================  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 [email protected], 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 "cmSystemTools.h"#include <cmsys/SystemTools.hxx>/* Some useful URLs:Homepage: http://www.codeblocks.orgFile format docs:http://wiki.codeblocks.org/index.php?title=File_formats_descriptionhttp://wiki.codeblocks.org/index.php?title=Workspace_filehttp://wiki.codeblocks.org/index.php?title=Project_fileDiscussion:http://forums.codeblocks.org/index.php/topic,6789.0.html*///----------------------------------------------------------------------------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 makefiles is generated into the "    "build tree.  The appropriate make program can build the project through "    "the default make target.  A \"make install\" target is also provided.";}cmExtraCodeBlocksGenerator::cmExtraCodeBlocksGenerator():cmExternalMakefileProjectGenerator(){#if defined(_WIN32)  this->SupportedGlobalGenerators.push_back("MinGW Makefiles");// disable until somebody actually tests it://  this->SupportedGlobalGenerators.push_back("NMake Makefiles");//  this->SupportedGlobalGenerators.push_back("MSYS Makefiles");#endif  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(){  // for each sub project in the project create a codeblocks project  for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator       it = this->GlobalGenerator->GetProjectMap().begin();      it!= this->GlobalGenerator->GetProjectMap().end();      ++it)    {    // create a project file    this->CreateProjectFile(it->second);    }}/* create the project file, if it already exists, merge it with theexisting 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;    }  // figure out the compiler  std::string compiler = this->GetCBCompilerId(mf);  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"        "      <Option title=\"" << mf->GetProjectName()<<"\" />\n"        "      <Option makefile_is_custom=\"1\" />\n"        "      <Option compiler=\"" << compiler << "\" />\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:            {            int cbTargetType = this->GetCBTargetType(&ti->second);            std::string makefileName = makefile->GetStartOutputDirectory();            makefileName += "/Makefile";            makefileName = cmSystemTools::ConvertToOutputPath(                                                         makefileName.c_str());  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=\"" << cbTargetType << "\" />\n"        "         <Option compiler=\"" << compiler << "\" />\n"        "         <Compiler>\n";            // the include directories for this target            const std::vector<std::string>& incDirs =                              ti->second.GetMakefile()->GetIncludeDirectories();            for(std::vector<std::string>::const_iterator dirIt=incDirs.begin();                dirIt != incDirs.end();                ++dirIt)              {  fout <<"            <Add directory=\"" << dirIt->c_str() << "\" />\n";              }  fout<<"         </Compiler>\n"        "         <MakeCommands>\n"        "            <Build command=\"" << this->BuildMakeCommand(make, makefileName.c_str(), ti->first.c_str()) << "\" />\n"        "            <CompileFile command=\"" << this->BuildMakeCommand(make, makefileName.c_str(), ""$file"") << "\" />\n"        "            <Clean command=\"" << this->BuildMakeCommand(make, makefileName.c_str(), "clean") << "\" />\n"        "            <DistClean command=\"" << this->BuildMakeCommand(make, makefileName.c_str(), "clean") << "\" />\n"        "         </MakeCommands>\n"        "      </Target>\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:  // intended fallthrough          break;        }      }    }  for (std::map<std::string, std::string>::const_iterator        sit=sourceFiles.begin();       sit!=sourceFiles.end();       ++sit)  {  fout<<"      <Unit filename=\""<<sit->first <<"\">\n"        "      </Unit>\n";  }  fout<<"   </Project>\n"        "</CodeBlocks_project_file>\n";}std::string cmExtraCodeBlocksGenerator::GetCBCompilerId(const cmMakefile* mf){  // figure out which language to use  // for now care only for C and C++  std::string compilerIdVar = "CMAKE_CXX_COMPILER_ID";  cmGlobalGenerator* gg=const_cast<cmGlobalGenerator*>(this->GlobalGenerator);  if (gg->GetLanguageEnabled("CXX") == false)    {    compilerIdVar = "CMAKE_C_COMPILER_ID";    }  std::string hostSystemName = mf->GetSafeDefinition("CMAKE_HOST_SYSTEM_NAME");  std::string systemName = mf->GetSafeDefinition("CMAKE_SYSTEM_NAME");  std::string compilerId = mf->GetRequiredDefinition(compilerIdVar.c_str());  std::string compiler = "gcc";  if (compilerId == "MSVC")    {    compiler = "msvc";    }  else if (compilerId == "Borland")    {    compiler = "bcc";    }  else if (compilerId == "SDCC")    {    compiler = "sdcc";    }  else if (compilerId == "Intel")    {    compiler = "icc";    }  else if (compilerId == "Watcom")    {    compiler = "ow";    }  else if (compilerId == "GNU")    {    compiler = "gcc";    }  return compiler;}int cmExtraCodeBlocksGenerator::GetCBTargetType(cmTarget* target){  if ( target->GetType()==cmTarget::EXECUTABLE)    {    if ((target->GetPropertyAsBool("WIN32_EXECUTABLE"))        || (target->GetPropertyAsBool("MACOSX_BUNDLE")))      {      return 0;      }    else      {      return 1;      }    }  else if ( target->GetType()==cmTarget::STATIC_LIBRARY)    {    return 2;    }  else if ((target->GetType()==cmTarget::SHARED_LIBRARY)      || (target->GetType()==cmTarget::MODULE_LIBRARY))    {    return 3;    }  return 4;}std::string cmExtraCodeBlocksGenerator::BuildMakeCommand(             const std::string& make, const char* makefile, const char* target){  std::string command = make;  if (strcmp(this->GlobalGenerator->GetName(), "NMake Makefiles")==0)    {    command += " /NOLOGO /f "";    command += makefile;    command += "" ";    command += target;    }  else    {    command += " -f "";    command += makefile;    command += "" ";    command += target;    }  return command;}
 |