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. */ /** Construct a comment for a custom command. */
std::string ConstructComment(const cmCustomCommand& cc, std::string ConstructComment(const cmCustomCommand& cc,
const char* default_comment = ""); const char* default_comment = "");
// Compute object file names.
std::string GetObjectFileNameWithoutTarget(const cmSourceFile& source,
std::string const& dir_max,
bool* hasSourceExtension = 0);
protected: protected:
/** Fill out these strings for the given target. Libraries to link, /** Fill out these strings for the given target. Libraries to link,
@ -346,10 +350,6 @@ protected:
std::ostream& os, const char* config, std::ostream& os, const char* config,
std::vector<std::string> const& configurationTypes); 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& CreateSafeUniqueObjectFileName(const char* sin,
std::string const& dir_max); 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 // build the whole source group path
for(++i; i<=lastElement; ++i) 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()); 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->Internal = new cmSourceGroupInternals;
this->SetGroupRegex(regex); 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) cmSourceGroup::cmSourceGroup(cmSourceGroup const& r)
{ {
this->Name = r.Name; this->Name = r.Name;
this->FullName = r.FullName;
this->GroupRegex = r.GroupRegex; this->GroupRegex = r.GroupRegex;
this->GroupFiles = r.GroupFiles; this->GroupFiles = r.GroupFiles;
this->SourceFiles = r.SourceFiles; this->SourceFiles = r.SourceFiles;
@ -80,6 +88,12 @@ const char* cmSourceGroup::GetName() const
{ {
return this->Name.c_str(); return this->Name.c_str();
} }
//----------------------------------------------------------------------------
const char* cmSourceGroup::GetFullName() const
{
return this->FullName.c_str();
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool cmSourceGroup::MatchesRegex(const char* name) bool cmSourceGroup::MatchesRegex(const char* name)

View File

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

View File

@ -331,35 +331,137 @@ void cmVisualStudio10TargetGenerator::ConvertToWindowsSlash(std::string& s)
} }
} }
void cmVisualStudio10TargetGenerator::WriteGroups() void cmVisualStudio10TargetGenerator::WriteGroups()
{ {
// This should create a target.vcxproj.filters file // collect up group information
// something like this: std::vector<cmSourceGroup> sourceGroups =
this->Makefile->GetSourceGroups();
std::vector<cmSourceFile*> classes = this->Target->GetSourceFiles();
/* std::set<cmSourceGroup*> groupsUsed;
<?xml version="1.0" encoding="utf-8"?> std::vector<cmSourceFile*> clCompile;
<Project ToolsVersion="4.0" std::vector<cmSourceFile*> customBuild;
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> std::vector<cmSourceFile*> none;
<ItemGroup>
<CustomBuild Include="..\CMakeLists.txt" /> for(std::vector<cmSourceFile*>::const_iterator s = classes.begin();
</ItemGroup> s != classes.end(); s++)
<ItemGroup> {
<Filter Include="Source Files"> cmSourceFile* sf = *s;
<UniqueIdentifier>{05072589-c7be-439a-8fd7-5db6ee5008a9} std::string const& source = sf->GetFullPath();
</UniqueIdentifier> cmSourceGroup& sourceGroup =
</Filter> this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
</ItemGroup> groupsUsed.insert(&sourceGroup);
<ItemGroup> const char* lang = sf->GetLanguage();
<ClCompile Include="..\foo.c"> if(!lang)
<Filter>Source Files</Filter> {
</ClCompile> lang = "None";
<ClCompile Include="..\testCCompiler.c"> }
<Filter>Source Files</Filter> if(lang[0] == 'C')
</ClCompile> {
</ItemGroup> clCompile.push_back(sf);
</Project> }
*/ 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() void cmVisualStudio10TargetGenerator::WriteObjSources()
{ {
@ -412,6 +514,7 @@ void cmVisualStudio10TargetGenerator::WriteCLSources()
if(lang && (strcmp(lang, "C") == 0 || strcmp(lang, "CXX") ==0)) if(lang && (strcmp(lang, "C") == 0 || strcmp(lang, "CXX") ==0))
{ {
std::string sourceFile = (*source)->GetFullPath(); std::string sourceFile = (*source)->GetFullPath();
this->ConvertToWindowsSlash(sourceFile);
// output the source file // output the source file
this->WriteString("<ClCompile Include=\"", 2); this->WriteString("<ClCompile Include=\"", 2);
(*this->BuildFileStream ) << sourceFile << "\""; (*this->BuildFileStream ) << sourceFile << "\"";
@ -1025,21 +1128,6 @@ WriteMidlOptions(std::string const& /*config*/,
{ {
this->WriteString("<Midl>\n", 2); this->WriteString("<Midl>\n", 2);
this->OutputIncludes(includes); 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); this->WriteString("</Midl>\n", 2);
} }

View File

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

View File

@ -31,5 +31,5 @@ source_group(Base\\Sub1\\Base FILES bar.c)
source_group(EmptyGroup) 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 @@