ENH: Fully implemented SOURCE_GROUP command.
This commit is contained in:
parent
e093bdade0
commit
48aedb2ba3
|
@ -252,7 +252,7 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
|
||||||
std::string source = (*i)->GetFullPath();
|
std::string source = (*i)->GetFullPath();
|
||||||
cmSourceGroup& sourceGroup = m_Makefile->FindSourceGroup(source.c_str(),
|
cmSourceGroup& sourceGroup = m_Makefile->FindSourceGroup(source.c_str(),
|
||||||
sourceGroups);
|
sourceGroups);
|
||||||
sourceGroup.AddSource(source.c_str(), *i);
|
sourceGroup.AssignSource(*i);
|
||||||
// while we are at it, if it is a .rule file then for visual studio 6 we
|
// while we are at it, if it is a .rule file then for visual studio 6 we
|
||||||
// must generate it
|
// must generate it
|
||||||
if ((*i)->GetSourceExtension() == "rule")
|
if ((*i)->GetSourceExtension() == "rule")
|
||||||
|
|
|
@ -695,7 +695,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
|
||||||
}
|
}
|
||||||
cmSourceGroup& sourceGroup =
|
cmSourceGroup& sourceGroup =
|
||||||
m_Makefile->FindSourceGroup(source.c_str(), sourceGroups);
|
m_Makefile->FindSourceGroup(source.c_str(), sourceGroups);
|
||||||
sourceGroup.AddSource(source.c_str(), *i);
|
sourceGroup.AssignSource(*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// open the project
|
// open the project
|
||||||
|
|
|
@ -1535,17 +1535,21 @@ cmSourceGroup&
|
||||||
cmMakefile::FindSourceGroup(const char* source,
|
cmMakefile::FindSourceGroup(const char* source,
|
||||||
std::vector<cmSourceGroup> &groups)
|
std::vector<cmSourceGroup> &groups)
|
||||||
{
|
{
|
||||||
std::string file = source;
|
// First search for a group that lists the file explicitly.
|
||||||
std::string::size_type pos = file.rfind('/');
|
|
||||||
if(pos != std::string::npos)
|
|
||||||
{
|
|
||||||
file = file.substr(pos+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
|
for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
|
||||||
sg != groups.rend(); ++sg)
|
sg != groups.rend(); ++sg)
|
||||||
{
|
{
|
||||||
if(sg->Matches(file.c_str()))
|
if(sg->MatchesFiles(source))
|
||||||
|
{
|
||||||
|
return *sg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now search for a group whose regex matches the file.
|
||||||
|
for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
|
||||||
|
sg != groups.rend(); ++sg)
|
||||||
|
{
|
||||||
|
if(sg->MatchesRegex(source))
|
||||||
{
|
{
|
||||||
return *sg;
|
return *sg;
|
||||||
}
|
}
|
||||||
|
@ -1840,7 +1844,6 @@ cmSourceFile* cmMakefile::GetOrCreateSource(const char* sourceName,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cmSourceFile* cmMakefile::AddSource(cmSourceFile const&sf)
|
cmSourceFile* cmMakefile::AddSource(cmSourceFile const&sf)
|
||||||
{
|
{
|
||||||
// check to see if it exists
|
// check to see if it exists
|
||||||
|
|
|
@ -16,42 +16,68 @@
|
||||||
=========================================================================*/
|
=========================================================================*/
|
||||||
#include "cmSourceGroup.h"
|
#include "cmSourceGroup.h"
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
/**
|
cmSourceGroup::cmSourceGroup(const char* name, const char* regex): m_Name(name)
|
||||||
* The constructor initializes the group's regular expression.
|
|
||||||
*/
|
|
||||||
cmSourceGroup::cmSourceGroup(const char* name, const char* regex):
|
|
||||||
m_Name(name),
|
|
||||||
m_GroupRegex(regex)
|
|
||||||
{
|
{
|
||||||
|
this->SetGroupRegex(regex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
/**
|
void cmSourceGroup::SetGroupRegex(const char* regex)
|
||||||
* Copy constructor.
|
|
||||||
*/
|
|
||||||
cmSourceGroup::cmSourceGroup(const cmSourceGroup& r):
|
|
||||||
m_Name(r.m_Name),
|
|
||||||
m_GroupRegex(r.m_GroupRegex),
|
|
||||||
m_SourceFiles(r.m_SourceFiles)
|
|
||||||
{
|
{
|
||||||
|
if(regex)
|
||||||
|
{
|
||||||
|
m_GroupRegex.compile(regex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_GroupRegex.compile("^$");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
/**
|
void cmSourceGroup::AddGroupFile(const char* name)
|
||||||
* Returns whether the given name matches the group's regular expression.
|
{
|
||||||
*/
|
m_GroupFiles.insert(name);
|
||||||
bool cmSourceGroup::Matches(const char* name)
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
const char* cmSourceGroup::GetName() const
|
||||||
|
{
|
||||||
|
return m_Name.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmSourceGroup::MatchesRegex(const char* name)
|
||||||
{
|
{
|
||||||
return m_GroupRegex.find(name);
|
return m_GroupRegex.find(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmSourceGroup::MatchesFiles(const char* name)
|
||||||
|
{
|
||||||
|
std::set<cmStdString>::const_iterator i = m_GroupFiles.find(name);
|
||||||
|
if(i != m_GroupFiles.end())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
//----------------------------------------------------------------------------
|
||||||
* Add a source to the group that the compiler will know how to build.
|
void cmSourceGroup::AssignSource(const cmSourceFile* sf)
|
||||||
*/
|
|
||||||
void cmSourceGroup::AddSource(const char* /* name */, const cmSourceFile* sf)
|
|
||||||
{
|
{
|
||||||
m_SourceFiles.push_back(sf);
|
m_SourceFiles.push_back(sf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
const std::vector<const cmSourceFile*>& cmSourceGroup::GetSourceFiles() const
|
||||||
|
{
|
||||||
|
return m_SourceFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
std::vector<const cmSourceFile*>& cmSourceGroup::GetSourceFiles()
|
||||||
|
{
|
||||||
|
return m_SourceFiles;
|
||||||
|
}
|
||||||
|
|
|
@ -25,29 +25,56 @@ class cmSourceFile;
|
||||||
/** \class cmSourceGroup
|
/** \class cmSourceGroup
|
||||||
* \brief Hold a group of sources as specified by a SOURCE_GROUP command.
|
* \brief Hold a group of sources as specified by a SOURCE_GROUP command.
|
||||||
*
|
*
|
||||||
* cmSourceGroup holds all the source files and corresponding commands
|
* cmSourceGroup holds a regular expression and a list of files. When
|
||||||
* for files matching the regular expression specified for the group.
|
* local generators are about to generate the rules for a target's
|
||||||
|
* files, the set of source groups is consulted to group files
|
||||||
|
* together. A file is placed into the last source group that lists
|
||||||
|
* the file by name. If no group lists the file, it is placed into
|
||||||
|
* the last group whose regex matches it.
|
||||||
*/
|
*/
|
||||||
class cmSourceGroup
|
class cmSourceGroup
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cmSourceGroup(const char* name, const char* regex);
|
cmSourceGroup(const char* name, const char* regex);
|
||||||
cmSourceGroup(const cmSourceGroup&);
|
|
||||||
~cmSourceGroup() {}
|
~cmSourceGroup() {}
|
||||||
|
|
||||||
void SetGroupRegex(const char* regex)
|
/**
|
||||||
{ m_GroupRegex.compile(regex); }
|
* Set the regular expression for this group.
|
||||||
void AddSource(const char* name, const cmSourceFile*);
|
*/
|
||||||
const char* GetName() const
|
void SetGroupRegex(const char* regex);
|
||||||
{ return m_Name.c_str(); }
|
|
||||||
bool Matches(const char *);
|
/**
|
||||||
|
* Add a file name to the explicit list of files for this group.
|
||||||
|
*/
|
||||||
|
void AddGroupFile(const char* name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of this group.
|
||||||
|
*/
|
||||||
|
const char* GetName() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the given name matches this group's regex.
|
||||||
|
*/
|
||||||
|
bool MatchesRegex(const char* name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the given name matches this group's explicit file list.
|
||||||
|
*/
|
||||||
|
bool MatchesFiles(const char* name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign the given source file to this group. Used only by
|
||||||
|
* generators.
|
||||||
|
*/
|
||||||
|
void AssignSource(const cmSourceFile* sf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of the source files used by this target
|
* Get the list of the source files that have been assigned to this
|
||||||
|
* source group.
|
||||||
*/
|
*/
|
||||||
const std::vector<const cmSourceFile*> &GetSourceFiles() const
|
const std::vector<const cmSourceFile*>& GetSourceFiles() const;
|
||||||
{return m_SourceFiles;}
|
std::vector<const cmSourceFile*>& GetSourceFiles();
|
||||||
std::vector<const cmSourceFile*> &GetSourceFiles() {return m_SourceFiles;}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
@ -61,7 +88,13 @@ private:
|
||||||
cmsys::RegularExpression m_GroupRegex;
|
cmsys::RegularExpression m_GroupRegex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vector of all source files in this source group
|
* Set of file names explicitly added to this group.
|
||||||
|
*/
|
||||||
|
std::set<cmStdString> m_GroupFiles;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vector of all source files that have been assigned to
|
||||||
|
* this group.
|
||||||
*/
|
*/
|
||||||
std::vector<const cmSourceFile*> m_SourceFiles;
|
std::vector<const cmSourceFile*> m_SourceFiles;
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,37 +24,60 @@ bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args)
|
||||||
this->SetError("called with incorrect number of arguments");
|
this->SetError("called with incorrect number of arguments");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( args[1] == "REGULAR_EXPRESSION" && args.size() == 3 )
|
|
||||||
{
|
|
||||||
m_Makefile->AddSourceGroup(args[0].c_str(), args[2].c_str());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( args[1] == "FILES" )
|
// Get the source group with the given name.
|
||||||
|
cmSourceGroup* sg = m_Makefile->GetSourceGroup(args[0].c_str());
|
||||||
|
if(!sg)
|
||||||
{
|
{
|
||||||
cmSourceGroup* sg = m_Makefile->GetSourceGroup(args[0].c_str());
|
m_Makefile->AddSourceGroup(args[0].c_str(), 0);
|
||||||
if ( !sg )
|
sg = m_Makefile->GetSourceGroup(args[0].c_str());
|
||||||
{
|
|
||||||
m_Makefile->AddSourceGroup(args[0].c_str(), 0);
|
|
||||||
sg = m_Makefile->GetSourceGroup(args[0].c_str());
|
|
||||||
}
|
|
||||||
unsigned int cc;
|
|
||||||
for ( cc = 2; cc < args.size(); cc ++ )
|
|
||||||
{
|
|
||||||
sg->AddSource(args[cc].c_str(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( args.size() == 2 )
|
// Process arguments.
|
||||||
|
bool doingFiles = false;
|
||||||
|
for(unsigned int i=1; i < args.size(); ++i)
|
||||||
{
|
{
|
||||||
m_Makefile->AddSourceGroup(args[0].c_str(), args[1].c_str());
|
if(args[i] == "REGULAR_EXPRESSION")
|
||||||
return true;
|
{
|
||||||
|
// Next argument must specify the regex.
|
||||||
|
if(i+1 < args.size())
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
sg->SetGroupRegex(args[i].c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->SetError("REGULAR_EXPRESSION argument given without a regex.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
doingFiles = false;
|
||||||
|
}
|
||||||
|
else if(args[i] == "FILES")
|
||||||
|
{
|
||||||
|
// Next arguments will specify files.
|
||||||
|
doingFiles = true;
|
||||||
|
}
|
||||||
|
else if(doingFiles)
|
||||||
|
{
|
||||||
|
// Convert name to full path and add to the group's list.
|
||||||
|
std::string src = args[i].c_str();
|
||||||
|
if(!cmSystemTools::FileIsFullPath(src.c_str()))
|
||||||
|
{
|
||||||
|
src = m_Makefile->GetCurrentDirectory();
|
||||||
|
src += "/";
|
||||||
|
src += args[i];
|
||||||
|
}
|
||||||
|
sg->AddGroupFile(src.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmOStringStream err;
|
||||||
|
err << "Unknown argument \"" << args[i].c_str() << "\". "
|
||||||
|
<< "Perhaps the FILES keyword is missing.\n";
|
||||||
|
this->SetError(err.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->SetError("called with incorrect number of arguments");
|
return true;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,10 +71,14 @@ public:
|
||||||
virtual const char* GetFullDocumentation()
|
virtual const char* GetFullDocumentation()
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
" SOURCE_GROUP(name regex)\n"
|
" SOURCE_GROUP(name [REGULAR_EXPRESSION regex] [FILES src1 src2 ...])\n"
|
||||||
"Defines a new source group. Any file whose name matches the regular "
|
"Defines a group into which sources will be placed in project files. "
|
||||||
"expression will be placed in this group. The LAST regular expression "
|
"This is mainly used to setup file tabs in Visual Studio. "
|
||||||
"of all defined SOURCE_GROUPs that matches the file will be selected.";
|
"Any file whose name is listed or matches the regular expression will "
|
||||||
|
"be placed in this group. If a file matches multiple groups, the LAST "
|
||||||
|
"group that explicitly lists the file will be favored, if any. If no "
|
||||||
|
"group explicitly lists the file, the LAST group whose regular "
|
||||||
|
"expression matches the file will be favored.";
|
||||||
}
|
}
|
||||||
|
|
||||||
cmTypeMacro(cmSourceGroupCommand, cmCommand);
|
cmTypeMacro(cmSourceGroupCommand, cmCommand);
|
||||||
|
|
Loading…
Reference in New Issue