Merge topic 'codelite-organize-by-target'
cbe48879 CodeLite: Optionally use targets to create (sub)project files
This commit is contained in:
commit
ded15f26b8
@ -5,7 +5,11 @@ Generates CodeLite project files.
|
||||
|
||||
Project files for CodeLite will be created in the top directory and
|
||||
in every subdirectory which features a CMakeLists.txt file containing
|
||||
a PROJECT() call. The appropriate make program can build the
|
||||
a :command:`project` call.
|
||||
The :variable:`CMAKE_CODELITE_USE_TARGETS` variable may be set to ``ON``
|
||||
to change the default behaviour from projects to targets as the basis
|
||||
for project files.
|
||||
The appropriate make program can build the
|
||||
project through the default make target. A "make install" target is
|
||||
also provided.
|
||||
|
||||
|
@ -112,6 +112,7 @@ Variables that Change Behavior
|
||||
/variable/CMAKE_AUTOMOC_RELAXED_MODE
|
||||
/variable/CMAKE_BACKWARDS_COMPATIBILITY
|
||||
/variable/CMAKE_BUILD_TYPE
|
||||
/variable/CMAKE_CODELITE_USE_TARGETS
|
||||
/variable/CMAKE_COLOR_MAKEFILE
|
||||
/variable/CMAKE_CONFIGURATION_TYPES
|
||||
/variable/CMAKE_DEBUG_TARGET_PROPERTIES
|
||||
|
6
Help/release/dev/codelite-organize-by-target.rst
Normal file
6
Help/release/dev/codelite-organize-by-target.rst
Normal file
@ -0,0 +1,6 @@
|
||||
codelite-organize-by-target
|
||||
---------------------------
|
||||
|
||||
* The :generator:`CodeLite` generator gained a new
|
||||
:variable:`CMAKE_CODELITE_USE_TARGETS` option
|
||||
to change project creation from projects to targets.
|
7
Help/variable/CMAKE_CODELITE_USE_TARGETS.rst
Normal file
7
Help/variable/CMAKE_CODELITE_USE_TARGETS.rst
Normal file
@ -0,0 +1,7 @@
|
||||
CMAKE_CODELITE_USE_TARGETS
|
||||
--------------------------
|
||||
|
||||
Change the way the CodeLite generator creates projectfiles.
|
||||
|
||||
If this variable is set to ``ON`` the generator creates projectfiles
|
||||
based on targets rather than projects.
|
@ -70,6 +70,8 @@ void cmExtraCodeLiteGenerator::Generate()
|
||||
|
||||
// loop projects and locate the root project.
|
||||
// and extract the information for creating the worspace
|
||||
// root makefile
|
||||
const cmMakefile* rmf = CM_NULLPTR;
|
||||
for (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
|
||||
it = projectMap.begin();
|
||||
it != projectMap.end(); ++it) {
|
||||
@ -84,6 +86,7 @@ void cmExtraCodeLiteGenerator::Generate()
|
||||
workspaceFileName = workspaceOutputDir + "/";
|
||||
workspaceFileName += workspaceProjectName + ".workspace";
|
||||
this->WorkspacePath = it->second[0]->GetCurrentBinaryDirectory();
|
||||
rmf = it->second[0]->GetMakefile();
|
||||
;
|
||||
break;
|
||||
}
|
||||
@ -96,13 +99,90 @@ void cmExtraCodeLiteGenerator::Generate()
|
||||
xml.StartElement("CodeLite_Workspace");
|
||||
xml.Attribute("Name", workspaceProjectName);
|
||||
|
||||
bool const targetsAreProjects =
|
||||
rmf && rmf->IsOn("CMAKE_CODELITE_USE_TARGETS");
|
||||
|
||||
std::vector<std::string> ProjectNames;
|
||||
if (targetsAreProjects) {
|
||||
ProjectNames = CreateProjectsByTarget(&xml);
|
||||
} else {
|
||||
ProjectNames = CreateProjectsByProjectMaps(&xml);
|
||||
}
|
||||
|
||||
xml.StartElement("BuildMatrix");
|
||||
xml.StartElement("WorkspaceConfiguration");
|
||||
xml.Attribute("Name", this->ConfigName);
|
||||
xml.Attribute("Selected", "yes");
|
||||
|
||||
for (std::vector<std::string>::iterator it(ProjectNames.begin());
|
||||
it != ProjectNames.end(); it++) {
|
||||
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
|
||||
const std::vector<cmLocalGenerator*>& lgs =
|
||||
this->GlobalGenerator->GetLocalGenerators();
|
||||
for (std::vector<cmLocalGenerator*>::const_iterator lg(lgs.begin());
|
||||
lg != lgs.end(); lg++) {
|
||||
for (std::vector<cmGeneratorTarget*>::const_iterator lt =
|
||||
(*lg)->GetGeneratorTargets().begin();
|
||||
lt != (*lg)->GetGeneratorTargets().end(); lt++) {
|
||||
cmState::TargetType type = (*lt)->GetType();
|
||||
std::string outputDir = (*lg)->GetCurrentBinaryDirectory();
|
||||
std::string filename = outputDir + "/" + (*lt)->GetName() + ".project";
|
||||
retval.push_back((*lt)->GetName());
|
||||
// Make the project file relative to the workspace
|
||||
std::string relafilename = cmSystemTools::RelativePath(
|
||||
this->WorkspacePath.c_str(), filename.c_str());
|
||||
std::string visualname = (*lt)->GetName();
|
||||
switch (type) {
|
||||
case cmState::SHARED_LIBRARY:
|
||||
case cmState::STATIC_LIBRARY:
|
||||
case cmState::MODULE_LIBRARY:
|
||||
visualname = "lib" + visualname;
|
||||
case cmState::EXECUTABLE:
|
||||
xml->StartElement("Project");
|
||||
xml->Attribute("Name", visualname);
|
||||
xml->Attribute("Path", relafilename);
|
||||
xml->Attribute("Active", "No");
|
||||
xml->EndElement();
|
||||
|
||||
CreateNewProjectFile(*lt, 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 (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
|
||||
it = projectMap.begin();
|
||||
it != projectMap.end(); ++it) {
|
||||
// retrive project information
|
||||
it = this->GlobalGenerator->GetProjectMap().begin();
|
||||
it != this->GlobalGenerator->GetProjectMap().end(); it++) {
|
||||
|
||||
std::string outputDir = it->second[0]->GetCurrentBinaryDirectory();
|
||||
std::string projectName = it->second[0]->GetProjectName();
|
||||
retval.push_back(projectName);
|
||||
std::string filename = outputDir + "/" + projectName + ".project";
|
||||
|
||||
// Make the project file relative to the workspace
|
||||
@ -111,33 +191,13 @@ void cmExtraCodeLiteGenerator::Generate()
|
||||
|
||||
// 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();
|
||||
xml->StartElement("Project");
|
||||
xml->Attribute("Name", projectName);
|
||||
xml->Attribute("Path", filename);
|
||||
xml->Attribute("Active", "No");
|
||||
xml->EndElement();
|
||||
}
|
||||
|
||||
xml.StartElement("BuildMatrix");
|
||||
xml.StartElement("WorkspaceConfiguration");
|
||||
xml.Attribute("Name", this->ConfigName);
|
||||
xml.Attribute("Selected", "yes");
|
||||
|
||||
for (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
|
||||
it = projectMap.begin();
|
||||
it != projectMap.end(); ++it) {
|
||||
// retrive project information
|
||||
std::string projectName = it->second[0]->GetProjectName();
|
||||
|
||||
xml.StartElement("Project");
|
||||
xml.Attribute("Name", projectName);
|
||||
xml.Attribute("ConfigName", this->ConfigName);
|
||||
xml.EndElement();
|
||||
}
|
||||
|
||||
xml.EndElement(); // WorkspaceConfiguration
|
||||
xml.EndElement(); // BuildMatrix
|
||||
xml.EndElement(); // CodeLite_Workspace
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* create the project file */
|
||||
@ -152,42 +212,16 @@ void cmExtraCodeLiteGenerator::CreateProjectFile(
|
||||
this->CreateNewProjectFile(lgs, filename);
|
||||
}
|
||||
|
||||
void cmExtraCodeLiteGenerator::CreateNewProjectFile(
|
||||
const std::vector<cmLocalGenerator*>& lgs, const std::string& filename)
|
||||
std::string cmExtraCodeLiteGenerator::CollectSourceFiles(
|
||||
const cmMakefile* makefile, const cmGeneratorTarget* gt,
|
||||
std::map<std::string, cmSourceFile*>& cFiles,
|
||||
std::set<std::string>& otherFiles)
|
||||
{
|
||||
const cmMakefile* mf = lgs[0]->GetMakefile();
|
||||
cmGeneratedFileStream fout(filename.c_str());
|
||||
if (!fout) {
|
||||
return;
|
||||
}
|
||||
cmXMLWriter xml(fout);
|
||||
|
||||
////////////////////////////////////
|
||||
xml.StartDocument("utf-8");
|
||||
xml.StartElement("CodeLite_Project");
|
||||
xml.Attribute("Name", lgs[0]->GetProjectName());
|
||||
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 acompanying header, one for all other files
|
||||
std::string projectType;
|
||||
|
||||
std::vector<std::string> srcExts =
|
||||
const std::vector<std::string>& srcExts =
|
||||
this->GlobalGenerator->GetCMakeInstance()->GetSourceExtensions();
|
||||
std::vector<std::string> headerExts =
|
||||
this->GlobalGenerator->GetCMakeInstance()->GetHeaderExtensions();
|
||||
|
||||
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();
|
||||
std::vector<cmGeneratorTarget*> targets = (*lg)->GetGeneratorTargets();
|
||||
for (std::vector<cmGeneratorTarget*>::iterator ti = targets.begin();
|
||||
ti != targets.end(); ti++) {
|
||||
|
||||
switch ((*ti)->GetType()) {
|
||||
std::string projectType;
|
||||
switch (gt->GetType()) {
|
||||
case cmState::EXECUTABLE: {
|
||||
projectType = "Executable";
|
||||
} break;
|
||||
@ -204,13 +238,12 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile(
|
||||
break;
|
||||
}
|
||||
|
||||
switch ((*ti)->GetType()) {
|
||||
switch (gt->GetType()) {
|
||||
case cmState::EXECUTABLE:
|
||||
case cmState::STATIC_LIBRARY:
|
||||
case cmState::SHARED_LIBRARY:
|
||||
case cmState::MODULE_LIBRARY: {
|
||||
std::vector<cmSourceFile*> sources;
|
||||
cmGeneratorTarget* gt = *ti;
|
||||
gt->GetSourceFiles(sources,
|
||||
makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
|
||||
for (std::vector<cmSourceFile*>::const_iterator si = sources.begin();
|
||||
@ -220,8 +253,7 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile(
|
||||
std::string lang = (*si)->GetLanguage();
|
||||
if (lang == "C" || lang == "CXX") {
|
||||
std::string srcext = (*si)->GetExtension();
|
||||
for (std::vector<std::string>::const_iterator ext =
|
||||
srcExts.begin();
|
||||
for (std::vector<std::string>::const_iterator ext = srcExts.begin();
|
||||
ext != srcExts.end(); ++ext) {
|
||||
if (srcext == *ext) {
|
||||
isCFile = true;
|
||||
@ -241,9 +273,61 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile(
|
||||
default: // intended fallthrough
|
||||
break;
|
||||
}
|
||||
return projectType;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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 acompanying header, one for all other files
|
||||
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();
|
||||
std::vector<cmGeneratorTarget*> targets = (*lg)->GetGeneratorTargets();
|
||||
for (std::vector<cmGeneratorTarget*>::iterator ti = targets.begin();
|
||||
ti != targets.end(); ti++) {
|
||||
projectType = CollectSourceFiles(makefile, *ti, cFiles, otherFiles);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the project path ( we need it later to convert files to
|
||||
// their relative path)
|
||||
std::string projectPath = cmSystemTools::GetFilenamePath(filename);
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
const std::vector<std::string>& 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
|
||||
@ -275,11 +359,17 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the project path ( we need it later to convert files to
|
||||
// their relative path)
|
||||
std::string projectPath = cmSystemTools::GetFilenamePath(filename);
|
||||
void cmExtraCodeLiteGenerator::CreateProjectSourceEntries(
|
||||
std::map<std::string, cmSourceFile*>& cFiles,
|
||||
std::set<std::string>& otherFiles, cmXMLWriter* _xml,
|
||||
const std::string& projectPath, const cmMakefile* mf,
|
||||
const std::string& projectType)
|
||||
{
|
||||
|
||||
cmXMLWriter& xml(*_xml);
|
||||
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
|
||||
@ -292,8 +382,10 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile(
|
||||
cFiles.begin();
|
||||
sit != cFiles.end(); ++sit) {
|
||||
xml.StartElement("File");
|
||||
xml.Attribute("Name", cmSystemTools::RelativePath(projectPath.c_str(),
|
||||
sit->first.c_str()));
|
||||
std::string fpath(sit->first);
|
||||
std::string frelapath =
|
||||
cmSystemTools::RelativePath(projectPath.c_str(), sit->first.c_str());
|
||||
xml.Attribute("Name", frelapath);
|
||||
xml.EndElement();
|
||||
}
|
||||
xml.EndElement(); // VirtualDirectory
|
||||
@ -350,10 +442,17 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile(
|
||||
xml.EndElement(); // ResourceCompiler
|
||||
|
||||
xml.StartElement("General");
|
||||
std::string outputPath = mf->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
|
||||
if (!outputPath.empty())
|
||||
xml.Attribute("OutputFile", outputPath + "/$(ProjectName)");
|
||||
else
|
||||
xml.Attribute("OutputFile", "$(IntermediateDirectory)/$(ProjectName)");
|
||||
xml.Attribute("IntermediateDirectory", "./");
|
||||
xml.Attribute("Command", "./$(ProjectName)");
|
||||
xml.Attribute("CommandArguments", "");
|
||||
if (!outputPath.empty())
|
||||
xml.Attribute("WorkingDirectory", outputPath);
|
||||
else
|
||||
xml.Attribute("WorkingDirectory", "$(IntermediateDirectory)");
|
||||
xml.Attribute("PauseExecWhenProcTerminates", "yes");
|
||||
xml.EndElement(); // General
|
||||
@ -408,6 +507,53 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile(
|
||||
|
||||
xml.EndElement(); // GlobalSettings
|
||||
xml.EndElement(); // Settings
|
||||
}
|
||||
|
||||
void cmExtraCodeLiteGenerator::CreateNewProjectFile(
|
||||
const cmGeneratorTarget* gt, const std::string& filename)
|
||||
{
|
||||
const cmMakefile* mf = gt->Makefile;
|
||||
cmGeneratedFileStream fout(filename.c_str());
|
||||
if (!fout) {
|
||||
return;
|
||||
}
|
||||
cmXMLWriter xml(fout);
|
||||
|
||||
////////////////////////////////////
|
||||
xml.StartDocument("utf-8");
|
||||
xml.StartElement("CodeLite_Project");
|
||||
std::string visualname = gt->GetName();
|
||||
switch (gt->GetType()) {
|
||||
case cmState::STATIC_LIBRARY:
|
||||
case cmState::SHARED_LIBRARY:
|
||||
case cmState::MODULE_LIBRARY:
|
||||
visualname = "lib" + visualname;
|
||||
default: // intended fallthrough
|
||||
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 acompanying header, one for all other files
|
||||
std::string projectType;
|
||||
|
||||
std::vector<std::string> headerExts =
|
||||
this->GlobalGenerator->GetCMakeInstance()->GetHeaderExtensions();
|
||||
|
||||
std::map<std::string, cmSourceFile*> cFiles;
|
||||
std::set<std::string> otherFiles;
|
||||
|
||||
projectType = 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);
|
||||
|
||||
CreateProjectSourceEntries(cFiles, otherFiles, &xml, projectPath, mf,
|
||||
projectType);
|
||||
|
||||
xml.EndElement(); // CodeLite_Project
|
||||
}
|
||||
|
||||
|
@ -18,11 +18,16 @@
|
||||
|
||||
#include "cmExternalMakefileProjectGenerator.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class cmLocalGenerator;
|
||||
class cmMakefile;
|
||||
class cmGeneratorTarget;
|
||||
class cmXMLWriter;
|
||||
class cmSourceFile;
|
||||
|
||||
class cmExtraCodeLiteGenerator : public cmExternalMakefileProjectGenerator
|
||||
{
|
||||
@ -38,6 +43,20 @@ protected:
|
||||
std::string GetCleanCommand(const cmMakefile* mf) const;
|
||||
std::string GetRebuildCommand(const cmMakefile* mf) const;
|
||||
std::string GetSingleFileBuildCommand(const cmMakefile* mf) const;
|
||||
std::vector<std::string> CreateProjectsByTarget(cmXMLWriter* xml);
|
||||
std::vector<std::string> CreateProjectsByProjectMaps(cmXMLWriter* xml);
|
||||
std::string CollectSourceFiles(const cmMakefile* makefile,
|
||||
const cmGeneratorTarget* gt,
|
||||
std::map<std::string, cmSourceFile*>& cFiles,
|
||||
std::set<std::string>& otherFiles);
|
||||
void FindMatchingHeaderfiles(std::map<std::string, cmSourceFile*>& cFiles,
|
||||
std::set<std::string>& otherFiles);
|
||||
void CreateProjectSourceEntries(std::map<std::string, cmSourceFile*>& cFiles,
|
||||
std::set<std::string>& otherFiles,
|
||||
cmXMLWriter* xml,
|
||||
const std::string& projectPath,
|
||||
const cmMakefile* mf,
|
||||
const std::string& projectType);
|
||||
|
||||
public:
|
||||
cmExtraCodeLiteGenerator();
|
||||
@ -49,6 +68,8 @@ public:
|
||||
|
||||
void CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs,
|
||||
const std::string& filename);
|
||||
void CreateNewProjectFile(const cmGeneratorTarget* lg,
|
||||
const std::string& filename);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user