| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472 | 
							- /*============================================================================
 
-   CMake - Cross Platform Makefile Generator
 
-   Copyright 2004-2009 Kitware, Inc.
 
-   Copyright 2004 Alexander Neundorf ([email protected])
 
-   Copyright 2013 Eran Ifrah ([email protected])
 
-   Distributed under the OSI-approved BSD License (the "License");
 
-   see accompanying file Copyright.txt for details.
 
-   This software is distributed WITHOUT ANY WARRANTY; without even the
 
-   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
-   See the License for more information.
 
- ============================================================================*/
 
- #include "cmExtraCodeLiteGenerator.h"
 
- #include "cmGlobalUnixMakefileGenerator3.h"
 
- #include "cmLocalUnixMakefileGenerator3.h"
 
- #include "cmMakefile.h"
 
- #include "cmake.h"
 
- #include "cmSourceFile.h"
 
- #include "cmGeneratedFileStream.h"
 
- #include "cmSystemTools.h"
 
- #include <cmsys/SystemTools.hxx>
 
- #include <cmsys/SystemInformation.hxx>
 
- #include <cmsys/Directory.hxx>
 
- #include "cmStandardIncludes.h"
 
- #include "cmXMLSafe.h"
 
- //----------------------------------------------------------------------------
 
- void cmExtraCodeLiteGenerator::GetDocumentation(cmDocumentationEntry& entry,
 
-                                                 const std::string&) const
 
- {
 
-   entry.Name = this->GetName();
 
-   entry.Brief = "Generates CodeLite project files.";
 
- }
 
- cmExtraCodeLiteGenerator::cmExtraCodeLiteGenerator()
 
-   : cmExternalMakefileProjectGenerator()
 
-   , ConfigName("NoConfig")
 
-   , CpuCount(2)
 
- {
 
- #if defined(_WIN32)
 
-   this->SupportedGlobalGenerators.push_back("MinGW Makefiles");
 
-   this->SupportedGlobalGenerators.push_back("NMake Makefiles");
 
- #endif
 
-   this->SupportedGlobalGenerators.push_back("Ninja");
 
-   this->SupportedGlobalGenerators.push_back("Unix Makefiles");
 
- }
 
- void cmExtraCodeLiteGenerator::Generate()
 
- {
 
-   // Hold root tree information for creating the workspace
 
-   std::string workspaceProjectName;
 
-   std::string workspaceOutputDir;
 
-   std::string workspaceFileName;
 
-   std::string workspaceSourcePath;
 
-   std::string lprjdebug;
 
-   cmGeneratedFileStream fout;
 
-   // loop projects and locate the root project.
 
-   // and extract the information for creating the worspace
 
-   for (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
 
-        it = this->GlobalGenerator->GetProjectMap().begin();
 
-        it!= this->GlobalGenerator->GetProjectMap().end();
 
-        ++it)
 
-     {
 
-     const cmMakefile* mf =it->second[0]->GetMakefile();
 
-     this->ConfigName = GetConfigurationName( mf );
 
-     if (strcmp(it->second[0]->GetCurrentBinaryDirectory(),
 
-                it->second[0]->GetBinaryDirectory()) == 0)
 
-       {
 
-       workspaceOutputDir   = it->second[0]->GetCurrentBinaryDirectory();
 
-       workspaceProjectName = it->second[0]->GetProjectName();
 
-       workspaceSourcePath  = it->second[0]->GetSourceDirectory();
 
-       workspaceFileName    = workspaceOutputDir+"/";
 
-       workspaceFileName   += workspaceProjectName + ".workspace";
 
-       this->WorkspacePath = it->second[0]->GetCurrentBinaryDirectory();;
 
-       fout.Open(workspaceFileName.c_str(), false, false);
 
-       fout << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
 
-            "<CodeLite_Workspace Name=\"" << workspaceProjectName << "\" >\n";
 
-       }
 
-     }
 
-   // for each sub project in the workspace create a codelite project
 
-   for (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
 
-        it = this->GlobalGenerator->GetProjectMap().begin();
 
-        it!= this->GlobalGenerator->GetProjectMap().end();
 
-        ++it)
 
-     {
 
-     // retrive project information
 
-     std::string outputDir   = it->second[0]->GetCurrentBinaryDirectory();
 
-     std::string projectName = it->second[0]->GetProjectName();
 
-     std::string filename    = outputDir + "/" + projectName + ".project";
 
-     // Make the project file relative to the workspace
 
-     filename = cmSystemTools::RelativePath(this->WorkspacePath.c_str(),
 
-                                           filename.c_str());
 
-     // create a project file
 
-     this->CreateProjectFile(it->second);
 
-     fout << "  <Project Name=\"" << projectName << "\" Path=\""
 
-     << filename << "\" Active=\"No\"/>\n";
 
-     lprjdebug += "<Project Name=\"" + projectName
 
-               + "\" ConfigName=\"" + this->ConfigName + "\"/>\n";
 
-     }
 
-   fout << "  <BuildMatrix>\n"
 
-        "    <WorkspaceConfiguration Name=\""
 
-        << this->ConfigName << "\" Selected=\"yes\">\n"
 
-        "      " << lprjdebug << ""
 
-        "    </WorkspaceConfiguration>\n"
 
-        "  </BuildMatrix>\n"
 
-        "</CodeLite_Workspace>\n";
 
- }
 
- /* create the project file */
 
- void cmExtraCodeLiteGenerator::CreateProjectFile(
 
-   const std::vector<cmLocalGenerator*>& lgs)
 
- {
 
-   std::string outputDir   = lgs[0]->GetCurrentBinaryDirectory();
 
-   std::string projectName = lgs[0]->GetProjectName();
 
-   std::string filename    = outputDir + "/";
 
-   filename += projectName + ".project";
 
-   this->CreateNewProjectFile(lgs, filename);
 
- }
 
- void cmExtraCodeLiteGenerator
 
- ::CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs,
 
-                        const std::string& filename)
 
- {
 
-   const cmMakefile* mf=lgs[0]->GetMakefile();
 
-   cmGeneratedFileStream fout(filename.c_str());
 
-   if(!fout)
 
-     {
 
-     return;
 
-     }
 
-   ////////////////////////////////////
 
-   fout << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
 
-        "<CodeLite_Project Name=\"" << lgs[0]->GetProjectName()
 
-        << "\" InternalType=\"\">\n";
 
-   // Collect all used source files in the project
 
-   // Sort them into two containers, one for C/C++ implementation files
 
-   // which may have an acompanying header, one for all other files
 
-   std::string projectType;
 
-   std::map<std::string, cmSourceFile*> cFiles;
 
-   std::set<std::string> otherFiles;
 
-   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:
 
-           {
 
-           projectType = "Executable";
 
-           }
 
-         break;
 
-         case cmTarget::STATIC_LIBRARY:
 
-           {
 
-           projectType = "Static Library";
 
-           }
 
-         break;
 
-         case cmTarget::SHARED_LIBRARY:
 
-           {
 
-           projectType = "Dynamic Library";
 
-           }
 
-         break;
 
-         case cmTarget::MODULE_LIBRARY:
 
-           {
 
-           projectType = "Dynamic Library";
 
-           }
 
-         break;
 
-         default:  // intended fallthrough
 
-           break;
 
-         }
 
-       switch(ti->second.GetType())
 
-         {
 
-         case cmTarget::EXECUTABLE:
 
-         case cmTarget::STATIC_LIBRARY:
 
-         case cmTarget::SHARED_LIBRARY:
 
-         case cmTarget::MODULE_LIBRARY:
 
-           {
 
-           std::vector<cmSourceFile*> sources;
 
-           cmGeneratorTarget* gt =
 
-               this->GlobalGenerator->GetGeneratorTarget(&ti->second);
 
-           gt->GetSourceFiles(sources,
 
-                             makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
 
-           for (std::vector<cmSourceFile*>::const_iterator si=sources.begin();
 
-                si!=sources.end(); si++)
 
-             {
 
-             // check whether it is a C/C++ implementation file
 
-             bool isCFile = false;
 
-             std::string lang = (*si)->GetLanguage();
 
-             if (lang == "C" || lang == "CXX")
 
-               {
 
-               std::string srcext = (*si)->GetExtension();
 
-               for(std::vector<std::string>::const_iterator
 
-                   ext = mf->GetSourceExtensions().begin();
 
-                   ext !=  mf->GetSourceExtensions().end();
 
-                   ++ext)
 
-                 {
 
-                 if (srcext == *ext)
 
-                   {
 
-                   isCFile = true;
 
-                   break;
 
-                   }
 
-                 }
 
-               }
 
-             // then put it accordingly into one of the two containers
 
-             if (isCFile)
 
-               {
 
-               cFiles[(*si)->GetFullPath()] = *si ;
 
-               }
 
-             else
 
-               {
 
-               otherFiles.insert((*si)->GetFullPath());
 
-               }
 
-             }
 
-           }
 
-         default:  // intended fallthrough
 
-           break;
 
-         }
 
-       }
 
-     }
 
-   // The following loop tries to add header files matching to implementation
 
-   // files to the project. It does that by iterating over all source files,
 
-   // replacing the file name extension with ".h" and checks whether such a
 
-   // file exists. If it does, it is inserted into the map of files.
 
-   // A very similar version of that code exists also in the kdevelop
 
-   // project generator.
 
-   for (std::map<std::string, cmSourceFile*>::const_iterator
 
-        sit=cFiles.begin();
 
-        sit!=cFiles.end();
 
-        ++sit)
 
-     {
 
-     std::string headerBasename=cmSystemTools::GetFilenamePath(sit->first);
 
-     headerBasename+="/";
 
-     headerBasename+=cmSystemTools::GetFilenameWithoutExtension(sit->first);
 
-     // check if there's a matching header around
 
-     for(std::vector<std::string>::const_iterator
 
-         ext = mf->GetHeaderExtensions().begin();
 
-         ext !=  mf->GetHeaderExtensions().end();
 
-         ++ext)
 
-       {
 
-       std::string hname=headerBasename;
 
-       hname += ".";
 
-       hname += *ext;
 
-       // if it's already in the set, don't check if it exists on disk
 
-       std::set<std::string>::const_iterator headerIt=otherFiles.find(hname);
 
-       if (headerIt != otherFiles.end())
 
-         {
 
-         break;
 
-         }
 
-       if(cmSystemTools::FileExists(hname.c_str()))
 
-         {
 
-         otherFiles.insert(hname);
 
-         break;
 
-         }
 
-       }
 
-     }
 
-   // Get the project path ( we need it later to convert files to
 
-   // their relative path)
 
-   std::string projectPath = cmSystemTools::GetFilenamePath(filename);
 
-   // Create 2 virtual folders: src and include
 
-   // and place all the implementation files into the src
 
-   // folder, the rest goes to the include folder
 
-   fout<< "  <VirtualDirectory Name=\"src\">\n";
 
-   // insert all source files in the codelite project
 
-   // first the C/C++ implementation files, then all others
 
-   for (std::map<std::string, cmSourceFile*>::const_iterator
 
-        sit=cFiles.begin();
 
-        sit!=cFiles.end();
 
-        ++sit)
 
-     {
 
-     std::string relativePath =
 
-       cmSystemTools::RelativePath(projectPath.c_str(), sit->first.c_str());
 
-     fout<< "    <File Name=\"" << relativePath << "\"/>\n";
 
-     }
 
-   fout<< "  </VirtualDirectory>\n";
 
-   fout<< "  <VirtualDirectory Name=\"include\">\n";
 
-   for (std::set<std::string>::const_iterator
 
-        sit=otherFiles.begin();
 
-        sit!=otherFiles.end();
 
-        ++sit)
 
-     {
 
-     std::string relativePath =
 
-       cmSystemTools::RelativePath(projectPath.c_str(), sit->c_str());
 
-     fout << "    <File Name=\"" << relativePath << "\"/>\n";
 
-     }
 
-   fout << "  </VirtualDirectory>\n";
 
-   // Get the number of CPUs. We use this information for the make -jN
 
-   // command
 
-   cmsys::SystemInformation info;
 
-   info.RunCPUCheck();
 
-   this->CpuCount = info.GetNumberOfLogicalCPU() *
 
-                    info.GetNumberOfPhysicalCPU();
 
-   std::string cleanCommand      = GetCleanCommand(mf);
 
-   std::string buildCommand      = GetBuildCommand(mf);
 
-   std::string rebuildCommand    = GetRebuildCommand(mf);
 
-   std::string singleFileCommand = GetSingleFileBuildCommand(mf);
 
-   std::string codeliteCompilerName = this->GetCodeLiteCompilerName(mf);
 
-   fout << "\n"
 
-      "  <Settings Type=\"" << projectType << "\">\n"
 
-      "    <Configuration Name=\"" << this->ConfigName << "\" CompilerType=\""
 
-      << codeliteCompilerName << "\" DebuggerType=\"GNU gdb debugger\" "
 
-      "Type=\""
 
-      << projectType << "\" BuildCmpWithGlobalSettings=\"append\" "
 
-      "BuildLnkWithGlobalSettings=\"append\" "
 
-      "BuildResWithGlobalSettings=\"append\">\n"
 
-      "      <Compiler Options=\"-g\" "
 
-      "Required=\"yes\" PreCompiledHeader=\"\">\n"
 
-      "        <IncludePath Value=\".\"/>\n"
 
-      "      </Compiler>\n"
 
-      "      <Linker Options=\"\" Required=\"yes\"/>\n"
 
-      "      <ResourceCompiler Options=\"\" Required=\"no\"/>\n"
 
-      "      <General OutputFile=\"$(IntermediateDirectory)/$(ProjectName)\" "
 
-      "IntermediateDirectory=\"./\" Command=\"./$(ProjectName)\" "
 
-      "CommandArguments=\"\" WorkingDirectory=\"$(IntermediateDirectory)\" "
 
-      "PauseExecWhenProcTerminates=\"yes\"/>\n"
 
-      "      <Debugger IsRemote=\"no\" RemoteHostName=\"\" "
 
-      "RemoteHostPort=\"\" DebuggerPath=\"\">\n"
 
-      "        <PostConnectCommands/>\n"
 
-      "        <StartupCommands/>\n"
 
-      "      </Debugger>\n"
 
-      "      <PreBuild/>\n"
 
-      "      <PostBuild/>\n"
 
-      "      <CustomBuild Enabled=\"yes\">\n"
 
-      "        <RebuildCommand>" << rebuildCommand << "</RebuildCommand>\n"
 
-      "        <CleanCommand>" << cleanCommand << "</CleanCommand>\n"
 
-      "        <BuildCommand>" << buildCommand << "</BuildCommand>\n"
 
-      "        <SingleFileCommand>" << singleFileCommand
 
-      << "</SingleFileCommand>\n"
 
-      "        <PreprocessFileCommand/>\n"
 
-      "        <WorkingDirectory>$(WorkspacePath)</WorkingDirectory>\n"
 
-      "      </CustomBuild>\n"
 
-      "      <AdditionalRules>\n"
 
-      "        <CustomPostBuild/>\n"
 
-      "        <CustomPreBuild/>\n"
 
-      "      </AdditionalRules>\n"
 
-      "    </Configuration>\n"
 
-      "    <GlobalSettings>\n"
 
-      "      <Compiler Options=\"\">\n"
 
-      "        <IncludePath Value=\".\"/>\n"
 
-      "      </Compiler>\n"
 
-      "      <Linker Options=\"\">\n"
 
-      "        <LibraryPath Value=\".\"/>\n"
 
-      "      </Linker>\n"
 
-      "      <ResourceCompiler Options=\"\"/>\n"
 
-      "    </GlobalSettings>\n"
 
-      "  </Settings>\n"
 
-      "</CodeLite_Project>\n";
 
- }
 
- std::string
 
- cmExtraCodeLiteGenerator::GetCodeLiteCompilerName(const cmMakefile* mf) const
 
- {
 
-   // figure out which language to use
 
-   // for now care only for C and C++
 
-   std::string compilerIdVar = "CMAKE_CXX_COMPILER_ID";
 
-   if (this->GlobalGenerator->GetLanguageEnabled("CXX") == false)
 
-     {
 
-     compilerIdVar = "CMAKE_C_COMPILER_ID";
 
-     }
 
-   std::string compilerId = mf->GetSafeDefinition(compilerIdVar);
 
-   std::string compiler = "gnu g++"; // default to g++
 
-   // Since we need the compiler for parsing purposes only
 
-   // it does not matter if we use clang or clang++, same as
 
-   // "gnu gcc" vs "gnu g++"
 
-   if (compilerId == "MSVC")
 
-     {
 
-     compiler = "VC++";
 
-     }
 
-   else if (compilerId == "Clang")
 
-     {
 
-     compiler = "clang++";
 
-     }
 
-   else if (compilerId == "GNU")
 
-     {
 
-     compiler = "gnu g++";
 
-     }
 
-   return compiler;
 
- }
 
- std::string
 
- cmExtraCodeLiteGenerator::GetConfigurationName(const cmMakefile* mf) const
 
- {
 
-   std::string confName = mf->GetSafeDefinition("CMAKE_BUILD_TYPE");
 
-   // Trim the configuration name from whitespaces (left and right)
 
-   confName.erase(0, confName.find_first_not_of(" \t\r\v\n"));
 
-   confName.erase(confName.find_last_not_of(" \t\r\v\n")+1);
 
-   if ( confName.empty() )
 
-     {
 
-     confName = "NoConfig";
 
-     }
 
-   return confName;
 
- }
 
- std::string
 
- cmExtraCodeLiteGenerator::GetBuildCommand(const cmMakefile* mf) const
 
- {
 
-   std::string generator = mf->GetSafeDefinition("CMAKE_GENERATOR");
 
-   std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
 
-   std::string buildCommand = make; // Default
 
-   if ( generator == "NMake Makefiles" ||
 
-        generator == "Ninja" )
 
-     {
 
-     buildCommand = make;
 
-     }
 
-   else if ( generator == "MinGW Makefiles" ||
 
-             generator == "Unix Makefiles" )
 
-     {
 
-     std::ostringstream ss;
 
-     ss << make << " -j " << this->CpuCount;
 
-     buildCommand = ss.str();
 
-     }
 
-   return buildCommand;
 
- }
 
- std::string
 
- cmExtraCodeLiteGenerator::GetCleanCommand(const cmMakefile* mf) const
 
- {
 
-   return GetBuildCommand(mf) + " clean";
 
- }
 
- std::string
 
- cmExtraCodeLiteGenerator::GetRebuildCommand(const cmMakefile* mf) const
 
- {
 
-   return GetCleanCommand(mf) + cmXMLSafe(" && ").str() + GetBuildCommand(mf);
 
- }
 
- std::string
 
- cmExtraCodeLiteGenerator::GetSingleFileBuildCommand
 
- (const cmMakefile* mf) const
 
- {
 
-   std::string buildCommand;
 
-   std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
 
-   std::string generator = mf->GetSafeDefinition("CMAKE_GENERATOR");
 
-   if ( generator == "Unix Makefiles" || generator == "MinGW Makefiles" )
 
-     {
 
-     std::ostringstream ss;
 
-     ss << make << " -f$(ProjectPath)/Makefile $(CurrentFileName).cpp.o";
 
-     buildCommand = ss.str();
 
-     }
 
-   return buildCommand;
 
- }
 
 
  |