ENH: add group support and fix borland error

This commit is contained in:
Bill Hoffman 2009-07-11 00:05:20 -04:00
parent 2e22b70aa2
commit 28b1912aa3
8 changed files with 164 additions and 49 deletions

View File

@ -302,6 +302,10 @@ public:
/** Construct a comment for a custom command. */
std::string ConstructComment(const cmCustomCommand& cc,
const char* default_comment = "");
// Compute object file names.
std::string GetObjectFileNameWithoutTarget(const cmSourceFile& source,
std::string const& dir_max,
bool* hasSourceExtension = 0);
protected:
/** Fill out these strings for the given target. Libraries to link,
@ -346,10 +350,6 @@ protected:
std::ostream& os, const char* config,
std::vector<std::string> const& configurationTypes);
// Compute object file names.
std::string GetObjectFileNameWithoutTarget(const cmSourceFile& source,
std::string const& dir_max,
bool* hasSourceExtension = 0);
std::string& CreateSafeUniqueObjectFileName(const char* sin,
std::string const& dir_max);

View File

@ -1958,7 +1958,7 @@ void cmMakefile::AddSourceGroup(const std::vector<std::string>& name,
// build the whole source group path
for(++i; i<=lastElement; ++i)
{
sg->AddChild(cmSourceGroup(name[i].c_str(), 0));
sg->AddChild(cmSourceGroup(name[i].c_str(), 0, sg->GetFullName()));
sg = sg->lookupChild(name[i].c_str());
}

View File

@ -23,10 +23,17 @@ public:
};
//----------------------------------------------------------------------------
cmSourceGroup::cmSourceGroup(const char* name, const char* regex): Name(name)
cmSourceGroup::cmSourceGroup(const char* name, const char* regex,
const char* parentName): Name(name)
{
this->Internal = new cmSourceGroupInternals;
this->SetGroupRegex(regex);
if(parentName)
{
this->FullName = parentName;
this->FullName += "\\";
}
this->FullName += this->Name;
}
//----------------------------------------------------------------------------
@ -39,6 +46,7 @@ cmSourceGroup::~cmSourceGroup()
cmSourceGroup::cmSourceGroup(cmSourceGroup const& r)
{
this->Name = r.Name;
this->FullName = r.FullName;
this->GroupRegex = r.GroupRegex;
this->GroupFiles = r.GroupFiles;
this->SourceFiles = r.SourceFiles;
@ -80,6 +88,12 @@ const char* cmSourceGroup::GetName() const
{
return this->Name.c_str();
}
//----------------------------------------------------------------------------
const char* cmSourceGroup::GetFullName() const
{
return this->FullName.c_str();
}
//----------------------------------------------------------------------------
bool cmSourceGroup::MatchesRegex(const char* name)

View File

@ -37,7 +37,8 @@ class cmSourceGroupInternals;
class cmSourceGroup
{
public:
cmSourceGroup(const char* name, const char* regex);
cmSourceGroup(const char* name, const char* regex,
const char* parentName=0);
cmSourceGroup(cmSourceGroup const& r);
~cmSourceGroup();
cmSourceGroup& operator=(cmSourceGroup const&);
@ -66,6 +67,11 @@ public:
* Get the name of this group.
*/
const char* GetName() const;
/**
* Get the full path name for group.
*/
const char* GetFullName() const;
/**
* Check if the given name matches this group's regex.
@ -107,6 +113,8 @@ private:
* The name of the source group.
*/
std::string Name;
// Full path to group
std::string FullName;
/**
* The regular expression matching the files in the group.

View File

@ -331,35 +331,137 @@ void cmVisualStudio10TargetGenerator::ConvertToWindowsSlash(std::string& s)
}
}
void cmVisualStudio10TargetGenerator::WriteGroups()
{
// This should create a target.vcxproj.filters file
// something like this:
{
// collect up group information
std::vector<cmSourceGroup> sourceGroups =
this->Makefile->GetSourceGroups();
std::vector<cmSourceFile*> classes = this->Target->GetSourceFiles();
/*
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<CustomBuild Include="..\CMakeLists.txt" />
</ItemGroup>
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{05072589-c7be-439a-8fd7-5db6ee5008a9}
</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\foo.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\testCCompiler.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
*/
std::set<cmSourceGroup*> groupsUsed;
std::vector<cmSourceFile*> clCompile;
std::vector<cmSourceFile*> customBuild;
std::vector<cmSourceFile*> none;
for(std::vector<cmSourceFile*>::const_iterator s = classes.begin();
s != classes.end(); s++)
{
cmSourceFile* sf = *s;
std::string const& source = sf->GetFullPath();
cmSourceGroup& sourceGroup =
this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
groupsUsed.insert(&sourceGroup);
const char* lang = sf->GetLanguage();
if(!lang)
{
lang = "None";
}
if(lang[0] == 'C')
{
clCompile.push_back(sf);
}
else if(sf->GetCustomCommand())
{
customBuild.push_back(sf);
}
else
{
none.push_back(sf);
}
}
// Write out group file
std::string path = this->Makefile->GetStartOutputDirectory();
path += "/";
path += this->Target->GetName();
path += ".vcxproj.filters";
cmGeneratedFileStream fout(path.c_str());
char magic[] = {0xEF,0xBB, 0xBF};
fout.write(magic, 3);
cmGeneratedFileStream* save = this->BuildFileStream;
this->BuildFileStream = & fout;
this->WriteString("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<Project "
"ToolsVersion=\"4.0\" "
"xmlns=\"http://schemas.microsoft.com/"
"developer/msbuild/2003\">\n",
0);
this->WriteGroupSources("ClCompile", clCompile, sourceGroups);
this->WriteGroupSources("CustomBuild", customBuild, sourceGroups);
this->WriteString("<ItemGroup>\n", 1);
for(std::set<cmSourceGroup*>::iterator g = groupsUsed.begin();
g != groupsUsed.end(); ++g)
{
cmSourceGroup* sg = *g;
const char* name = sg->GetFullName();
if(strlen(name) != 0)
{
this->WriteString("<Filter Include=\"", 2);
(*this->BuildFileStream) << name << "\">\n";
std::string guidName = "SG_Filter_";
guidName += name;
this->GlobalGenerator->CreateGUID(guidName.c_str());
this->WriteString("<UniqueIdentifier>", 3);
std::string guid
= this->GlobalGenerator->GetGUID(guidName.c_str());
(*this->BuildFileStream)
<< "{"
<< guid << "}"
<< "</UniqueIdentifier>\n";
this->WriteString("</Filter>\n", 2);
}
}
this->WriteString("</ItemGroup>\n", 1);
this->WriteGroupSources("None", none, sourceGroups);
this->WriteString("</Project>\n", 0);
// restore stream pointer
this->BuildFileStream = save;
}
void
cmVisualStudio10TargetGenerator::
WriteGroupSources(const char* name,
std::vector<cmSourceFile*> const& sources,
std::vector<cmSourceGroup>& sourceGroups)
{
this->WriteString("<ItemGroup>\n", 1);
for(std::vector<cmSourceFile*>::const_iterator s = sources.begin();
s != sources.end(); ++s)
{
cmSourceFile* sf = *s;
std::string const& source = sf->GetFullPath();
cmSourceGroup& sourceGroup =
this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
const char* filter = sourceGroup.GetFullName();
this->WriteString("<", 2);
std::string path = source;
// custom command source are done with relative paths
// so that the custom command display in the GUI
// the source groups have to EXACTLY match the string
// used in the .vcxproj file
if(sf->GetCustomCommand())
{
path = cmSystemTools::RelativePath(
this->Makefile->GetCurrentOutputDirectory(),
source.c_str());
}
this->ConvertToWindowsSlash(path);
(*this->BuildFileStream) << name << " Include=\""
<< path;
if(strlen(filter))
{
(*this->BuildFileStream) << "\">\n";
this->WriteString("<Filter>", 3);
(*this->BuildFileStream) << filter << "</Filter>\n";
this->WriteString("</", 2);
(*this->BuildFileStream) << name << ">\n";
}
else
{
(*this->BuildFileStream) << "\" />\n";
}
}
this->WriteString("</ItemGroup>\n", 1);
}
void cmVisualStudio10TargetGenerator::WriteObjSources()
{
@ -412,6 +514,7 @@ void cmVisualStudio10TargetGenerator::WriteCLSources()
if(lang && (strcmp(lang, "C") == 0 || strcmp(lang, "CXX") ==0))
{
std::string sourceFile = (*source)->GetFullPath();
this->ConvertToWindowsSlash(sourceFile);
// output the source file
this->WriteString("<ClCompile Include=\"", 2);
(*this->BuildFileStream ) << sourceFile << "\"";
@ -1025,21 +1128,6 @@ WriteMidlOptions(std::string const& /*config*/,
{
this->WriteString("<Midl>\n", 2);
this->OutputIncludes(includes);
// Need this stuff, but there is an midl.xml file...
// should we look for .idl language?, and flags?
/*
<MkTypLibCompatible>false</MkTypLibCompatible>
<TargetEnvironment>Win32</TargetEnvironment>
<GenerateStublessProxies>true</GenerateStublessProxies>
<TypeLibraryName>%(FileName).tlb</TypeLibraryName>
<OutputDirectory>$(IntDir)\</OutputDirectory>
<HeaderFileName>%(FileName).h</HeaderFileName>
<DllDataFileName>
</DllDataFileName>
<InterfaceIdentifierFileName>%(FileName)_i.c
</InterfaceIdentifierFileName>
<ProxyFileName>%(FileName)_p.c</ProxyFileName>
*/
this->WriteString("</Midl>\n", 2);
}

View File

@ -26,6 +26,7 @@ class cmSourceFile;
class cmCustomCommand;
class cmLocalVisualStudio7Generator;
class cmComputeLinkInformation;
#include "cmSourceGroup.h"
class cmVisualStudio10TargetGenerator
{
@ -74,6 +75,9 @@ private:
void WriteEvent(const char* name, std::vector<cmCustomCommand> & commands,
std::string const& configName);
void ComputeObjectNames();
void WriteGroupSources(const char* name,
std::vector<cmSourceFile*> const& sources,
std::vector<cmSourceGroup>& );
private:
std::string ModuleDefinitionFile;
std::string PathToVcxproj;

View File

@ -31,5 +31,5 @@ source_group(Base\\Sub1\\Base FILES bar.c)
source_group(EmptyGroup)
add_executable(SourceGroups main.c bar.c foo.c sub1/foo.c sub1/foobar.c baz.c)
add_executable(SourceGroups main.c bar.c foo.c sub1/foo.c sub1/foobar.c baz.c README.txt)

View File

@ -0,0 +1 @@