| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
| file LICENSE.rst or https://cmake.org/licensing for details. */ | |
| #include "cmExtraCodeLiteGenerator.h" | |
| #include <cstring> | |
| #include <map> | |
| #include <memory> | |
| #include <set> | |
| #include <sstream> | |
| #include <utility> | |
| #include "cmsys/SystemInformation.hxx" | |
| #include "cmGeneratedFileStream.h" | |
| #include "cmGeneratorTarget.h" | |
| #include "cmGlobalGenerator.h" | |
| #include "cmLocalGenerator.h" | |
| #include "cmMakefile.h" | |
| #include "cmSourceFile.h" | |
| #include "cmStringAlgorithms.h" | |
| #include "cmSystemTools.h" | |
| #include "cmTargetTypes.h" | |
| #include "cmXMLWriter.h" | |
| #include "cmake.h" | |
| cmExtraCodeLiteGenerator::cmExtraCodeLiteGenerator() | |
| : ConfigName("NoConfig") | |
| { | |
| } | |
| cmExternalMakefileProjectGeneratorFactory* | |
| cmExtraCodeLiteGenerator::GetFactory() | |
| { | |
| static cmExternalMakefileProjectGeneratorSimpleFactory< | |
| cmExtraCodeLiteGenerator> | |
| factory("CodeLite", "Generates CodeLite project files (deprecated)."); | |
| if (factory.GetSupportedGlobalGenerators().empty()) { | |
| #if defined(_WIN32) | |
| factory.AddSupportedGlobalGenerator("MinGW Makefiles"); | |
| factory.AddSupportedGlobalGenerator("NMake Makefiles"); | |
| #endif | |
| factory.AddSupportedGlobalGenerator("Ninja"); | |
| factory.AddSupportedGlobalGenerator("Unix Makefiles"); | |
| } | |
| return &factory; | |
| } | |
| void cmExtraCodeLiteGenerator::Generate() | |
| { | |
| // Hold root tree information for creating the workspace | |
| std::string workspaceProjectName; | |
| std::string workspaceOutputDir; | |
| std::string workspaceFileName; | |
| std::string workspaceSourcePath; | |
| std::map<std::string, std::vector<cmLocalGenerator*>> const& projectMap = | |
| this->GlobalGenerator->GetProjectMap(); | |
| // loop projects and locate the root project. | |
| // and extract the information for creating the workspace | |
| // root makefile | |
| for (auto const& it : projectMap) { | |
| cmLocalGenerator* lg = it.second[0]; | |
| cmMakefile const* mf = lg->GetMakefile(); | |
| this->ConfigName = this->GetConfigurationName(mf); | |
| if (lg->GetCurrentBinaryDirectory() == lg->GetBinaryDirectory()) { | |
| workspaceOutputDir = lg->GetCurrentBinaryDirectory(); | |
| workspaceProjectName = lg->GetProjectName(); | |
| workspaceSourcePath = lg->GetSourceDirectory(); | |
| workspaceFileName = | |
| cmStrCat(workspaceOutputDir, '/', workspaceProjectName, ".workspace"); | |
| this->WorkspacePath = lg->GetCurrentBinaryDirectory(); | |
| break; | |
| } | |
| } | |
| cmGeneratedFileStream fout(workspaceFileName); | |
| cmXMLWriter xml(fout); | |
| xml.StartDocument("utf-8"); | |
| xml.StartElement("CodeLite_Workspace"); | |
| xml.Attribute("Name", workspaceProjectName); | |
| bool const targetsAreProjects = | |
| this->GlobalGenerator->GlobalSettingIsOn("CMAKE_CODELITE_USE_TARGETS"); | |
| std::vector<std::string> ProjectNames; | |
| if (targetsAreProjects) { | |
| ProjectNames = this->CreateProjectsByTarget(&xml); | |
| } else { | |
| ProjectNames = this->CreateProjectsByProjectMaps(&xml); | |
| } | |
| xml.StartElement("BuildMatrix"); | |
| xml.StartElement("WorkspaceConfiguration"); | |
| xml.Attribute("Name", this->ConfigName); | |
| xml.Attribute("Selected", "yes"); | |
| for (std::string const& it : ProjectNames) { | |
| xml.StartElement("Project"); | |
| xml.Attribute("Name", it); | |
| xml.Attribute("ConfigName", this->ConfigName); | |
| xml.EndElement(); | |
| } | |
| xml.EndElement(); // WorkspaceConfiguration | |
| xml.EndElement(); // BuildMatrix | |
| xml.EndElement(); // CodeLite_Workspace | |
| } | |
| // Create projects where targets are the projects | |
| std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByTarget( | |
| cmXMLWriter* xml) | |
| { | |
| std::vector<std::string> retval; | |
| // for each target in the workspace create a codelite project | |
| auto const& lgs = this->GlobalGenerator->GetLocalGenerators(); | |
| for (auto const& lg : lgs) { | |
| for (auto const& lt : lg->GetGeneratorTargets()) { | |
| cm::TargetType type = lt->GetType(); | |
| std::string const& outputDir = lg->GetCurrentBinaryDirectory(); | |
| std::string targetName = lt->GetName(); | |
| std::string filename = cmStrCat(outputDir, '/', targetName, ".project"); | |
| retval.push_back(targetName); | |
| // Make the project file relative to the workspace | |
| std::string relafilename = | |
| cmSystemTools::RelativePath(this->WorkspacePath, filename); | |
| std::string visualname = targetName; | |
| switch (type) { | |
| case cm::TargetType::SHARED_LIBRARY: | |
| case cm::TargetType::STATIC_LIBRARY: | |
| case cm::TargetType::MODULE_LIBRARY: | |
| visualname = cmStrCat("lib", std::move(visualname)); | |
| CM_FALLTHROUGH; | |
| case cm::TargetType::EXECUTABLE: | |
| xml->StartElement("Project"); | |
| xml->Attribute("Name", visualname); | |
| xml->Attribute("Path", relafilename); | |
| xml->Attribute("Active", "No"); | |
| xml->EndElement(); | |
| this->CreateNewProjectFile(lt.get(), filename); | |
| break; | |
| default: | |
| break; | |
| } | |
| } | |
| } | |
| return retval; | |
| } | |
| // The "older way of doing it. | |
| std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByProjectMaps( | |
| cmXMLWriter* xml) | |
| { | |
| std::vector<std::string> retval; | |
| // for each sub project in the workspace create a codelite project | |
| for (auto const& it : this->GlobalGenerator->GetProjectMap()) { | |
| std::string const& outputDir = it.second[0]->GetCurrentBinaryDirectory(); | |
| std::string projectName = it.second[0]->GetProjectName(); | |
| retval.push_back(projectName); | |
| std::string filename = cmStrCat(outputDir, '/', projectName, ".project"); | |
| // Make the project file relative to the workspace | |
| filename = cmSystemTools::RelativePath(this->WorkspacePath, filename); | |
| // create a project file | |
| this->CreateProjectFile(it.second); | |
| xml->StartElement("Project"); | |
| xml->Attribute("Name", projectName); | |
| xml->Attribute("Path", filename); | |
| xml->Attribute("Active", "No"); | |
| xml->EndElement(); | |
| } | |
| return retval; | |
| } | |
| /* create the project file */ | |
| void cmExtraCodeLiteGenerator::CreateProjectFile( | |
| std::vector<cmLocalGenerator*> const& lgs) | |
| { | |
| std::string const& outputDir = lgs[0]->GetCurrentBinaryDirectory(); | |
| std::string projectName = lgs[0]->GetProjectName(); | |
| std::string filename = cmStrCat(outputDir, '/', projectName, ".project"); | |
| this->CreateNewProjectFile(lgs, filename); | |
| } | |
| std::string cmExtraCodeLiteGenerator::CollectSourceFiles( | |
| cmMakefile const* makefile, cmGeneratorTarget const* gt, | |
| std::map<std::string, cmSourceFile*>& cFiles, | |
| std::set<std::string>& otherFiles) | |
| { | |
| std::string projectType; | |
| switch (gt->GetType()) { | |
| case cm::TargetType::EXECUTABLE: { | |
| projectType = "Executable"; | |
| } break; | |
| case cm::TargetType::STATIC_LIBRARY: { | |
| projectType = "Static Library"; | |
| } break; | |
| case cm::TargetType::SHARED_LIBRARY: | |
| case cm::TargetType::MODULE_LIBRARY: { | |
| projectType = "Dynamic Library"; | |
| } break; | |
| default: | |
| break; | |
| } | |
| switch (gt->GetType()) { | |
| case cm::TargetType::EXECUTABLE: | |
| case cm::TargetType::STATIC_LIBRARY: | |
| case cm::TargetType::SHARED_LIBRARY: | |
| case cm::TargetType::MODULE_LIBRARY: { | |
| cmake const* cm = makefile->GetCMakeInstance(); | |
| std::vector<cmSourceFile*> sources; | |
| gt->GetSourceFiles(sources, | |
| makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")); | |
| for (cmSourceFile* s : sources) { | |
| std::string const& fullPath = s->ResolveFullPath(); | |
| std::string const& extLower = | |
| cmSystemTools::LowerCase(s->GetExtension()); | |
| // check whether it is a source or a include file | |
| // then put it accordingly into one of the two containers | |
| if (cm->IsAKnownSourceExtension(extLower)) { | |
| cFiles[fullPath] = s; | |
| } else { | |
| otherFiles.insert(fullPath); | |
| } | |
| } | |
| } break; | |
| default: | |
| break; | |
| } | |
| return projectType; | |
| } | |
| void cmExtraCodeLiteGenerator::CreateNewProjectFile( | |
| std::vector<cmLocalGenerator*> const& lgs, std::string const& filename) | |
| { | |
| cmMakefile const* mf = lgs[0]->GetMakefile(); | |
| cmGeneratedFileStream fout(filename); | |
| if (!fout) { | |
| return; | |
| } | |
| cmXMLWriter xml(fout); | |
| //////////////////////////////////// | |
| xml.StartDocument("utf-8"); | |
| xml.StartElement("CodeLite_Project"); | |
| xml.Attribute("Name", lgs[0]->GetProjectName()); | |
| xml.Attribute("InternalType", ""); | |
| std::string projectType; | |
| // Collect all used source files in the project | |
| // Sort them into two containers, one for C/C++ implementation files | |
| // which may have an accompanying header, one for all other files | |
| std::map<std::string, cmSourceFile*> cFiles; | |
| std::set<std::string> otherFiles; | |
| for (cmLocalGenerator* lg : lgs) { | |
| cmMakefile* makefile = lg->GetMakefile(); | |
| for (auto const& target : lg->GetGeneratorTargets()) { | |
| projectType = | |
| this->CollectSourceFiles(makefile, target.get(), cFiles, otherFiles); | |
| } | |
| } | |
| // Get the project path ( we need it later to convert files to | |
| // their relative path) | |
| std::string projectPath = cmSystemTools::GetFilenamePath(filename); | |
| this->CreateProjectSourceEntries(cFiles, otherFiles, &xml, projectPath, mf, | |
| projectType, ""); | |
| xml.EndElement(); // CodeLite_Project | |
| } | |
| void cmExtraCodeLiteGenerator::FindMatchingHeaderfiles( | |
| std::map<std::string, cmSourceFile*>& cFiles, | |
| std::set<std::string>& otherFiles) | |
| { | |
| std::vector<std::string> const& headerExts = | |
| this->GlobalGenerator->GetCMakeInstance()->GetHeaderExtensions(); | |
| // 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 CodeBlocks | |
| // project generator. | |
| for (auto const& sit : cFiles) { | |
| std::string headerBasename = | |
| cmStrCat(cmSystemTools::GetFilenamePath(sit.first), '/', | |
| cmSystemTools::GetFilenameWithoutExtension(sit.first)); | |
| // check if there's a matching header around | |
| for (std::string const& ext : headerExts) { | |
| std::string hname = cmStrCat(headerBasename, '.', ext); | |
| // if it's already in the set, don't check if it exists on disk | |
| auto headerIt = otherFiles.find(hname); | |
| if (headerIt != otherFiles.end()) { | |
| break; | |
| } | |
| if (cmSystemTools::FileExists(hname)) { | |
| otherFiles.insert(hname); | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| void cmExtraCodeLiteGenerator::CreateFoldersAndFiles( | |
| std::set<std::string>& cFiles, cmXMLWriter& xml, | |
| std::string const& projectPath) | |
| { | |
| std::vector<std::string> tmp_path; | |
| std::vector<std::string> components; | |
| size_t numOfEndEl = 0; | |
| for (std::string const& cFile : cFiles) { | |
| std::string frelapath = cmSystemTools::RelativePath(projectPath, cFile); | |
| cmsys::SystemTools::SplitPath(frelapath, components, false); | |
| components.pop_back(); // erase last member -> it is file, not folder | |
| components.erase(components.begin()); // erase "root" | |
| size_t sizeOfSkip = 0; | |
| for (size_t i = 0; i < components.size(); ++i) { | |
| // skip relative path | |
| if (components[i] == ".." || components[i] == ".") { | |
| sizeOfSkip++; | |
| continue; | |
| } | |
| // same folder | |
| if (tmp_path.size() > i - sizeOfSkip && | |
| tmp_path[i - sizeOfSkip] == components[i]) { | |
| continue; | |
| } | |
| // delete "old" subfolders | |
| if (tmp_path.size() > i - sizeOfSkip) { | |
| numOfEndEl = tmp_path.size() - i + sizeOfSkip; | |
| tmp_path.erase(tmp_path.end() - numOfEndEl, tmp_path.end()); | |
| for (; numOfEndEl--;) { | |
| xml.EndElement(); | |
| } | |
| } | |
| // add folder | |
| xml.StartElement("VirtualDirectory"); | |
| xml.Attribute("Name", components[i]); | |
| tmp_path.push_back(components[i]); | |
| } | |
| // delete "old" subfolders | |
| numOfEndEl = tmp_path.size() - components.size() + sizeOfSkip; | |
| if (numOfEndEl) { | |
| tmp_path.erase(tmp_path.end() - numOfEndEl, tmp_path.end()); | |
| for (; numOfEndEl--;) { | |
| xml.EndElement(); | |
| } | |
| } | |
| // add file | |
| xml.StartElement("File"); | |
| xml.Attribute("Name", frelapath); | |
| xml.EndElement(); | |
| } | |
| // end of folders | |
| numOfEndEl = tmp_path.size(); | |
| for (; numOfEndEl--;) { | |
| xml.EndElement(); | |
| } | |
| } | |
| void cmExtraCodeLiteGenerator::CreateFoldersAndFiles( | |
| std::map<std::string, cmSourceFile*>& cFiles, cmXMLWriter& xml, | |
| std::string const& projectPath) | |
| { | |
| std::set<std::string> s; | |
| for (auto const& it : cFiles) { | |
| s.insert(it.first); | |
| } | |
| this->CreateFoldersAndFiles(s, xml, projectPath); | |
| } | |
| void cmExtraCodeLiteGenerator::CreateProjectSourceEntries( | |
| std::map<std::string, cmSourceFile*>& cFiles, | |
| std::set<std::string>& otherFiles, cmXMLWriter* _xml, | |
| std::string const& projectPath, cmMakefile const* mf, | |
| std::string const& projectType, std::string const& targetName) | |
| { | |
| cmXMLWriter& xml(*_xml); | |
| this->FindMatchingHeaderfiles(cFiles, otherFiles); | |
| // Create 2 virtual folders: src and include | |
| // and place all the implementation files into the src | |
| // folder, the rest goes to the include folder | |
| xml.StartElement("VirtualDirectory"); | |
| xml.Attribute("Name", "src"); | |
| // insert all source files in the codelite project | |
| // first the C/C++ implementation files, then all others | |
| this->CreateFoldersAndFiles(cFiles, xml, projectPath); | |
| xml.EndElement(); // VirtualDirectory | |
| xml.StartElement("VirtualDirectory"); | |
| xml.Attribute("Name", "include"); | |
| this->CreateFoldersAndFiles(otherFiles, xml, projectPath); | |
| xml.EndElement(); // VirtualDirectory | |
| // 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 codeliteCompilerName = this->GetCodeLiteCompilerName(mf); | |
| xml.StartElement("Settings"); | |
| xml.Attribute("Type", projectType); | |
| xml.StartElement("Configuration"); | |
| xml.Attribute("Name", this->ConfigName); | |
| xml.Attribute("CompilerType", this->GetCodeLiteCompilerName(mf)); | |
| xml.Attribute("DebuggerType", "GNU gdb debugger"); | |
| xml.Attribute("Type", projectType); | |
| xml.Attribute("BuildCmpWithGlobalSettings", "append"); | |
| xml.Attribute("BuildLnkWithGlobalSettings", "append"); | |
| xml.Attribute("BuildResWithGlobalSettings", "append"); | |
| xml.StartElement("Compiler"); | |
| xml.Attribute("Options", "-g"); | |
| xml.Attribute("Required", "yes"); | |
| xml.Attribute("PreCompiledHeader", ""); | |
| xml.StartElement("IncludePath"); | |
| xml.Attribute("Value", "."); | |
| xml.EndElement(); // IncludePath | |
| xml.EndElement(); // Compiler | |
| xml.StartElement("Linker"); | |
| xml.Attribute("Options", ""); | |
| xml.Attribute("Required", "yes"); | |
| xml.EndElement(); // Linker | |
| xml.StartElement("ResourceCompiler"); | |
| xml.Attribute("Options", ""); | |
| xml.Attribute("Required", "no"); | |
| xml.EndElement(); // ResourceCompiler | |
| xml.StartElement("General"); | |
| std::string outputPath = | |
| mf->GetSafeDefinition("CMAKE_RUNTIME_OUTPUT_DIRECTORY"); | |
| if (outputPath.empty()) { | |
| outputPath = mf->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH"); | |
| } | |
| std::string relapath; | |
| if (!outputPath.empty()) { | |
| relapath = cmSystemTools::RelativePath(projectPath, outputPath); | |
| xml.Attribute("OutputFile", relapath + "/$(ProjectName)"); | |
| } else { | |
| xml.Attribute("OutputFile", "$(IntermediateDirectory)/$(ProjectName)"); | |
| } | |
| xml.Attribute("IntermediateDirectory", "./"); | |
| xml.Attribute("Command", "./$(ProjectName)"); | |
| xml.Attribute("CommandArguments", ""); | |
| if (!outputPath.empty()) { | |
| xml.Attribute("WorkingDirectory", relapath); | |
| } else { | |
| xml.Attribute("WorkingDirectory", "$(IntermediateDirectory)"); | |
| } | |
| xml.Attribute("PauseExecWhenProcTerminates", "yes"); | |
| xml.EndElement(); // General | |
| xml.StartElement("Debugger"); | |
| xml.Attribute("IsRemote", "no"); | |
| xml.Attribute("RemoteHostName", ""); | |
| xml.Attribute("RemoteHostPort", ""); | |
| xml.Attribute("DebuggerPath", ""); | |
| xml.Element("PostConnectCommands"); | |
| xml.Element("StartupCommands"); | |
| xml.EndElement(); // Debugger | |
| xml.Element("PreBuild"); | |
| xml.Element("PostBuild"); | |
| xml.StartElement("CustomBuild"); | |
| xml.Attribute("Enabled", "yes"); | |
| xml.Element("RebuildCommand", this->GetRebuildCommand(mf, targetName)); | |
| xml.Element("CleanCommand", this->GetCleanCommand(mf, targetName)); | |
| xml.Element("BuildCommand", this->GetBuildCommand(mf, targetName)); | |
| xml.Element("SingleFileCommand", this->GetSingleFileBuildCommand(mf)); | |
| xml.Element("PreprocessFileCommand"); | |
| xml.Element("WorkingDirectory", "$(WorkspacePath)"); | |
| xml.EndElement(); // CustomBuild | |
| xml.StartElement("AdditionalRules"); | |
| xml.Element("CustomPostBuild"); | |
| xml.Element("CustomPreBuild"); | |
| xml.EndElement(); // AdditionalRules | |
| xml.EndElement(); // Configuration | |
| xml.StartElement("GlobalSettings"); | |
| xml.StartElement("Compiler"); | |
| xml.Attribute("Options", ""); | |
| xml.StartElement("IncludePath"); | |
| xml.Attribute("Value", "."); | |
| xml.EndElement(); // IncludePath | |
| xml.EndElement(); // Compiler | |
| xml.StartElement("Linker"); | |
| xml.Attribute("Options", ""); | |
| xml.StartElement("LibraryPath"); | |
| xml.Attribute("Value", "."); | |
| xml.EndElement(); // LibraryPath | |
| xml.EndElement(); // Linker | |
| xml.StartElement("ResourceCompiler"); | |
| xml.Attribute("Options", ""); | |
| xml.EndElement(); // ResourceCompiler | |
| xml.EndElement(); // GlobalSettings | |
| xml.EndElement(); // Settings | |
| } | |
| void cmExtraCodeLiteGenerator::CreateNewProjectFile( | |
| cmGeneratorTarget const* gt, std::string const& filename) | |
| { | |
| cmMakefile const* mf = gt->Makefile; | |
| cmGeneratedFileStream fout(filename); | |
| if (!fout) { | |
| return; | |
| } | |
| cmXMLWriter xml(fout); | |
| //////////////////////////////////// | |
| xml.StartDocument("utf-8"); | |
| xml.StartElement("CodeLite_Project"); | |
| std::string targetName = gt->GetName(); | |
| std::string visualname = targetName; | |
| switch (gt->GetType()) { | |
| case cm::TargetType::STATIC_LIBRARY: | |
| case cm::TargetType::SHARED_LIBRARY: | |
| case cm::TargetType::MODULE_LIBRARY: | |
| visualname = "lib" + targetName; | |
| break; | |
| default: | |
| break; | |
| } | |
| xml.Attribute("Name", visualname); | |
| xml.Attribute("InternalType", ""); | |
| // Collect all used source files in the project | |
| // Sort them into two containers, one for C/C++ implementation files | |
| // which may have an accompanying header, one for all other files | |
| std::string projectType; | |
| std::map<std::string, cmSourceFile*> cFiles; | |
| std::set<std::string> otherFiles; | |
| projectType = this->CollectSourceFiles(mf, gt, cFiles, otherFiles); | |
| // Get the project path ( we need it later to convert files to | |
| // their relative path) | |
| std::string projectPath = cmSystemTools::GetFilenamePath(filename); | |
| this->CreateProjectSourceEntries(cFiles, otherFiles, &xml, projectPath, mf, | |
| projectType, targetName); | |
| xml.EndElement(); // CodeLite_Project | |
| } | |
| std::string cmExtraCodeLiteGenerator::GetCodeLiteCompilerName( | |
| cmMakefile const* 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")) { | |
| compilerIdVar = "CMAKE_C_COMPILER_ID"; | |
| } | |
| std::string const& 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( | |
| cmMakefile const* 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( | |
| cmMakefile const* mf, std::string const& targetName) const | |
| { | |
| std::string const& generator = mf->GetSafeDefinition("CMAKE_GENERATOR"); | |
| std::string const& make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"); | |
| std::string buildCommand = make; // Default | |
| std::ostringstream ss; | |
| if (generator == "NMake Makefiles" || generator == "Ninja") { | |
| ss << make; | |
| } else if (generator == "MinGW Makefiles" || generator == "Unix Makefiles") { | |
| ss << make << " -f$(ProjectPath)/Makefile"; | |
| if (this->CpuCount > 0) { | |
| ss << " -j " << this->CpuCount; | |
| } | |
| } | |
| if (!targetName.empty()) { | |
| ss << " " << targetName; | |
| } | |
| buildCommand = ss.str(); | |
| return buildCommand; | |
| } | |
| std::string cmExtraCodeLiteGenerator::GetCleanCommand( | |
| cmMakefile const* mf, std::string const& targetName) const | |
| { | |
| std::string generator = mf->GetSafeDefinition("CMAKE_GENERATOR"); | |
| std::string buildcommand = this->GetBuildCommand(mf, ""); | |
| if (!targetName.empty() && generator == "Ninja") { | |
| return cmStrCat(std::move(buildcommand), " -t clean ", targetName); | |
| } | |
| return cmStrCat(std::move(buildcommand), " clean"); | |
| } | |
| std::string cmExtraCodeLiteGenerator::GetRebuildCommand( | |
| cmMakefile const* mf, std::string const& targetName) const | |
| { | |
| return cmStrCat(this->GetCleanCommand(mf, targetName), " && ", | |
| this->GetBuildCommand(mf, targetName)); | |
| } | |
| std::string cmExtraCodeLiteGenerator::GetSingleFileBuildCommand( | |
| cmMakefile const* mf) const | |
| { | |
| std::string buildCommand; | |
| std::string const& make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"); | |
| std::string const& generator = mf->GetSafeDefinition("CMAKE_GENERATOR"); | |
| if (generator == "Unix Makefiles" || generator == "MinGW Makefiles") { | |
| #if defined(_WIN32) | |
| buildCommand = cmStrCat( | |
| make, " -f$(ProjectPath)/Makefile -B $(CurrentFileFullName).obj"); | |
| #else | |
| buildCommand = | |
| cmStrCat(make, " -f$(ProjectPath)/Makefile -B $(CurrentFileFullName).o"); | |
| #endif | |
| } | |
| return buildCommand; | |
| } |