summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/generator/Visual Studio 10 2010.rst12
-rw-r--r--Help/generator/Visual Studio 10.rst9
-rw-r--r--Help/generator/Visual Studio 11 2012.rst12
-rw-r--r--Help/generator/Visual Studio 11.rst9
-rw-r--r--Help/generator/Visual Studio 12 2013.rst12
-rw-r--r--Help/generator/Visual Studio 12.rst9
-rw-r--r--Help/manual/cmake-generators.7.rst6
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmGeneratorTarget.cxx293
-rw-r--r--Source/cmGeneratorTarget.h13
-rw-r--r--Source/cmGlobalGenerator.h4
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx67
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h2
-rw-r--r--Source/cmGlobalVisualStudio11Generator.cxx80
-rw-r--r--Source/cmGlobalVisualStudio11Generator.h2
-rw-r--r--Source/cmGlobalVisualStudio12Generator.cxx67
-rw-r--r--Source/cmGlobalVisualStudio12Generator.h2
-rw-r--r--Source/cmLocalGenerator.cxx7
-rw-r--r--Source/cmLocalNinjaGenerator.cxx44
-rw-r--r--Source/cmLocalNinjaGenerator.h1
-rw-r--r--Source/cmTarget.cxx310
-rw-r--r--Source/cmTarget.h13
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx5
-rw-r--r--Source/cmake.cxx8
-rw-r--r--Tests/CMakeLists.txt11
-rw-r--r--Tests/CTestTestLaunchers/launcher_test_project/CMakeLists.txt19
-rw-r--r--Tests/CTestTestLaunchers/launcher_test_project/CTestConfig.cmake8
-rw-r--r--Tests/CTestTestLaunchers/launcher_test_project/command.cmake5
-rw-r--r--Tests/CTestTestLaunchers/test.cmake.in39
29 files changed, 654 insertions, 417 deletions
diff --git a/Help/generator/Visual Studio 10 2010.rst b/Help/generator/Visual Studio 10 2010.rst
new file mode 100644
index 0000000..000677a
--- /dev/null
+++ b/Help/generator/Visual Studio 10 2010.rst
@@ -0,0 +1,12 @@
+Visual Studio 10 2010
+---------------------
+
+Generates Visual Studio 10 (VS 2010) project files.
+
+It is possible to append a space followed by the platform name to
+create project files for a specific target platform. E.g.
+"Visual Studio 10 2010 Win64" will create project files for the
+x64 processor; "Visual Studio 10 2010 IA64" for Itanium.
+
+For compatibility with CMake versions prior to 3.0, one may specify this
+generator using the name "Visual Studio 10" without the year component.
diff --git a/Help/generator/Visual Studio 10.rst b/Help/generator/Visual Studio 10.rst
deleted file mode 100644
index 9ea7970..0000000
--- a/Help/generator/Visual Studio 10.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-Visual Studio 10
-----------------
-
-Generates Visual Studio 10 (2010) project files.
-
-It is possible to append a space followed by the platform name to
-create project files for a specific target platform. E.g. "Visual
-Studio 10 Win64" will create project files for the x64 processor;
-"Visual Studio 10 IA64" for Itanium.
diff --git a/Help/generator/Visual Studio 11 2012.rst b/Help/generator/Visual Studio 11 2012.rst
new file mode 100644
index 0000000..42f6f91
--- /dev/null
+++ b/Help/generator/Visual Studio 11 2012.rst
@@ -0,0 +1,12 @@
+Visual Studio 11 2012
+---------------------
+
+Generates Visual Studio 11 (VS 2012) project files.
+
+It is possible to append a space followed by the platform name to
+create project files for a specific target platform. E.g.
+"Visual Studio 11 2012 Win64" will create project files for the
+x64 processor; "Visual Studio 11 2012 ARM" for ARM.
+
+For compatibility with CMake versions prior to 3.0, one may specify this
+generator using the name "Visual Studio 11" without the year component.
diff --git a/Help/generator/Visual Studio 11.rst b/Help/generator/Visual Studio 11.rst
deleted file mode 100644
index 4115c8d..0000000
--- a/Help/generator/Visual Studio 11.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-Visual Studio 11
-----------------
-
-Generates Visual Studio 11 (2012) project files.
-
-It is possible to append a space followed by the platform name to
-create project files for a specific target platform. E.g. "Visual
-Studio 11 Win64" will create project files for the x64 processor;
-"Visual Studio 11 ARM" for ARM.
diff --git a/Help/generator/Visual Studio 12 2013.rst b/Help/generator/Visual Studio 12 2013.rst
new file mode 100644
index 0000000..d2f4912
--- /dev/null
+++ b/Help/generator/Visual Studio 12 2013.rst
@@ -0,0 +1,12 @@
+Visual Studio 12 2013
+---------------------
+
+Generates Visual Studio 12 (VS 2013) project files.
+
+It is possible to append a space followed by the platform name to
+create project files for a specific target platform. E.g.
+"Visual Studio 12 2013 Win64" will create project files for the
+x64 processor; "Visual Studio 12 2013 ARM" for ARM.
+
+For compatibility with CMake versions prior to 3.0, one may specify this
+generator using the name "Visual Studio 12" without the year component.
diff --git a/Help/generator/Visual Studio 12.rst b/Help/generator/Visual Studio 12.rst
deleted file mode 100644
index 51bcab7..0000000
--- a/Help/generator/Visual Studio 12.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-Visual Studio 12
-----------------
-
-Generates Visual Studio 12 (2013) project files.
-
-It is possible to append a space followed by the platform name to
-create project files for a specific target platform. E.g. "Visual
-Studio 12 Win64" will create project files for the x64 processor;
-"Visual Studio 12 ARM" for ARM.
diff --git a/Help/manual/cmake-generators.7.rst b/Help/manual/cmake-generators.7.rst
index 4f0d9c3..a290d1a 100644
--- a/Help/manual/cmake-generators.7.rst
+++ b/Help/manual/cmake-generators.7.rst
@@ -32,9 +32,9 @@ All Generators
/generator/Sublime Text 2 - NMake Makefiles
/generator/Sublime Text 2 - Unix Makefiles
/generator/Unix Makefiles
- /generator/Visual Studio 10
- /generator/Visual Studio 11
- /generator/Visual Studio 12
+ /generator/Visual Studio 10 2010
+ /generator/Visual Studio 11 2012
+ /generator/Visual Studio 12 2013
/generator/Visual Studio 6
/generator/Visual Studio 7 .NET 2003
/generator/Visual Studio 7
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 010ddc2..f2dd3bd 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -2,5 +2,5 @@
set(CMake_VERSION_MAJOR 2)
set(CMake_VERSION_MINOR 8)
set(CMake_VERSION_PATCH 12)
-set(CMake_VERSION_TWEAK 20131030)
+set(CMake_VERSION_TWEAK 20131101)
#set(CMake_VERSION_RC 1)
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 6217955..b512675 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -19,6 +19,8 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionDAGChecker.h"
+#include <queue>
+
//----------------------------------------------------------------------------
cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t)
{
@@ -46,6 +48,18 @@ const char *cmGeneratorTarget::GetProperty(const char *prop)
}
//----------------------------------------------------------------------------
+std::vector<cmSourceFile*> const*
+cmGeneratorTarget::GetSourceDepends(cmSourceFile* sf)
+{
+ SourceEntriesType::iterator i = this->SourceEntries.find(sf);
+ if(i != this->SourceEntries.end())
+ {
+ return &i->second.Depends;
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------------
bool cmGeneratorTarget::IsSystemIncludeDirectory(const char *dir,
const char *config)
{
@@ -277,6 +291,285 @@ void cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs)
}
//----------------------------------------------------------------------------
+class cmTargetTraceDependencies
+{
+public:
+ cmTargetTraceDependencies(cmGeneratorTarget* target);
+ void Trace();
+private:
+ cmTarget* Target;
+ cmGeneratorTarget* GeneratorTarget;
+ cmMakefile* Makefile;
+ cmGlobalGenerator* GlobalGenerator;
+ typedef cmGeneratorTarget::SourceEntry SourceEntry;
+ SourceEntry* CurrentEntry;
+ std::queue<cmSourceFile*> SourceQueue;
+ std::set<cmSourceFile*> SourcesQueued;
+ typedef std::map<cmStdString, cmSourceFile*> NameMapType;
+ NameMapType NameMap;
+
+ void QueueSource(cmSourceFile* sf);
+ void FollowName(std::string const& name);
+ void FollowNames(std::vector<std::string> const& names);
+ bool IsUtility(std::string const& dep);
+ void CheckCustomCommand(cmCustomCommand const& cc);
+ void CheckCustomCommands(const std::vector<cmCustomCommand>& commands);
+};
+
+//----------------------------------------------------------------------------
+cmTargetTraceDependencies
+::cmTargetTraceDependencies(cmGeneratorTarget* target):
+ Target(target->Target), GeneratorTarget(target)
+{
+ // Convenience.
+ this->Makefile = this->Target->GetMakefile();
+ this->GlobalGenerator =
+ this->Makefile->GetLocalGenerator()->GetGlobalGenerator();
+ this->CurrentEntry = 0;
+
+ // Queue all the source files already specified for the target.
+ std::vector<cmSourceFile*> const& sources = this->Target->GetSourceFiles();
+ for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
+ si != sources.end(); ++si)
+ {
+ this->QueueSource(*si);
+ }
+
+ // Queue pre-build, pre-link, and post-build rule dependencies.
+ this->CheckCustomCommands(this->Target->GetPreBuildCommands());
+ this->CheckCustomCommands(this->Target->GetPreLinkCommands());
+ this->CheckCustomCommands(this->Target->GetPostBuildCommands());
+}
+
+//----------------------------------------------------------------------------
+void cmTargetTraceDependencies::Trace()
+{
+ // Process one dependency at a time until the queue is empty.
+ while(!this->SourceQueue.empty())
+ {
+ // Get the next source from the queue.
+ cmSourceFile* sf = this->SourceQueue.front();
+ this->SourceQueue.pop();
+ this->CurrentEntry = &this->GeneratorTarget->SourceEntries[sf];
+
+ // Queue dependencies added explicitly by the user.
+ if(const char* additionalDeps = sf->GetProperty("OBJECT_DEPENDS"))
+ {
+ std::vector<std::string> objDeps;
+ cmSystemTools::ExpandListArgument(additionalDeps, objDeps);
+ this->FollowNames(objDeps);
+ }
+
+ // Queue the source needed to generate this file, if any.
+ this->FollowName(sf->GetFullPath());
+
+ // Queue dependencies added programatically by commands.
+ this->FollowNames(sf->GetDepends());
+
+ // Queue custom command dependencies.
+ if(cmCustomCommand const* cc = sf->GetCustomCommand())
+ {
+ this->CheckCustomCommand(*cc);
+ }
+ }
+ this->CurrentEntry = 0;
+}
+
+//----------------------------------------------------------------------------
+void cmTargetTraceDependencies::QueueSource(cmSourceFile* sf)
+{
+ if(this->SourcesQueued.insert(sf).second)
+ {
+ this->SourceQueue.push(sf);
+
+ // Make sure this file is in the target.
+ this->Target->AddSourceFile(sf);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmTargetTraceDependencies::FollowName(std::string const& name)
+{
+ NameMapType::iterator i = this->NameMap.find(name);
+ if(i == this->NameMap.end())
+ {
+ // Check if we know how to generate this file.
+ cmSourceFile* sf = this->Makefile->GetSourceFileWithOutput(name.c_str());
+ NameMapType::value_type entry(name, sf);
+ i = this->NameMap.insert(entry).first;
+ }
+ if(cmSourceFile* sf = i->second)
+ {
+ // Record the dependency we just followed.
+ if(this->CurrentEntry)
+ {
+ this->CurrentEntry->Depends.push_back(sf);
+ }
+
+ this->QueueSource(sf);
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmTargetTraceDependencies::FollowNames(std::vector<std::string> const& names)
+{
+ for(std::vector<std::string>::const_iterator i = names.begin();
+ i != names.end(); ++i)
+ {
+ this->FollowName(*i);
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmTargetTraceDependencies::IsUtility(std::string const& dep)
+{
+ // Dependencies on targets (utilities) are supposed to be named by
+ // just the target name. However for compatibility we support
+ // naming the output file generated by the target (assuming there is
+ // no output-name property which old code would not have set). In
+ // that case the target name will be the file basename of the
+ // dependency.
+ std::string util = cmSystemTools::GetFilenameName(dep);
+ if(cmSystemTools::GetFilenameLastExtension(util) == ".exe")
+ {
+ util = cmSystemTools::GetFilenameWithoutLastExtension(util);
+ }
+
+ // Check for a target with this name.
+ if(cmTarget* t = this->Makefile->FindTargetToUse(util.c_str()))
+ {
+ // If we find the target and the dep was given as a full path,
+ // then make sure it was not a full path to something else, and
+ // the fact that the name matched a target was just a coincidence.
+ if(cmSystemTools::FileIsFullPath(dep.c_str()))
+ {
+ if(t->GetType() >= cmTarget::EXECUTABLE &&
+ t->GetType() <= cmTarget::MODULE_LIBRARY)
+ {
+ // This is really only for compatibility so we do not need to
+ // worry about configuration names and output names.
+ std::string tLocation = t->GetLocation(0);
+ tLocation = cmSystemTools::GetFilenamePath(tLocation);
+ std::string depLocation = cmSystemTools::GetFilenamePath(dep);
+ depLocation = cmSystemTools::CollapseFullPath(depLocation.c_str());
+ tLocation = cmSystemTools::CollapseFullPath(tLocation.c_str());
+ if(depLocation == tLocation)
+ {
+ this->Target->AddUtility(util.c_str());
+ return true;
+ }
+ }
+ }
+ else
+ {
+ // The original name of the dependency was not a full path. It
+ // must name a target, so add the target-level dependency.
+ this->Target->AddUtility(util.c_str());
+ return true;
+ }
+ }
+
+ // The dependency does not name a target built in this project.
+ return false;
+}
+
+//----------------------------------------------------------------------------
+void
+cmTargetTraceDependencies
+::CheckCustomCommand(cmCustomCommand const& cc)
+{
+ // Transform command names that reference targets built in this
+ // project to corresponding target-level dependencies.
+ cmGeneratorExpression ge(cc.GetBacktrace());
+
+ // Add target-level dependencies referenced by generator expressions.
+ std::set<cmTarget*> targets;
+
+ for(cmCustomCommandLines::const_iterator cit = cc.GetCommandLines().begin();
+ cit != cc.GetCommandLines().end(); ++cit)
+ {
+ std::string const& command = *cit->begin();
+ // Check for a target with this name.
+ if(cmTarget* t = this->Makefile->FindTargetToUse(command.c_str()))
+ {
+ if(t->GetType() == cmTarget::EXECUTABLE)
+ {
+ // The command refers to an executable target built in
+ // this project. Add the target-level dependency to make
+ // sure the executable is up to date before this custom
+ // command possibly runs.
+ this->Target->AddUtility(command.c_str());
+ }
+ }
+
+ // Check for target references in generator expressions.
+ for(cmCustomCommandLine::const_iterator cli = cit->begin();
+ cli != cit->end(); ++cli)
+ {
+ const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge
+ = ge.Parse(*cli);
+ cge->Evaluate(this->Makefile, 0, true);
+ std::set<cmTarget*> geTargets = cge->GetTargets();
+ for(std::set<cmTarget*>::const_iterator it = geTargets.begin();
+ it != geTargets.end(); ++it)
+ {
+ targets.insert(*it);
+ }
+ }
+ }
+
+ for(std::set<cmTarget*>::iterator ti = targets.begin();
+ ti != targets.end(); ++ti)
+ {
+ this->Target->AddUtility((*ti)->GetName());
+ }
+
+ // Queue the custom command dependencies.
+ std::vector<std::string> const& depends = cc.GetDepends();
+ for(std::vector<std::string>::const_iterator di = depends.begin();
+ di != depends.end(); ++di)
+ {
+ std::string const& dep = *di;
+ if(!this->IsUtility(dep))
+ {
+ // The dependency does not name a target and may be a file we
+ // know how to generate. Queue it.
+ this->FollowName(dep);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmTargetTraceDependencies
+::CheckCustomCommands(const std::vector<cmCustomCommand>& commands)
+{
+ for(std::vector<cmCustomCommand>::const_iterator cli = commands.begin();
+ cli != commands.end(); ++cli)
+ {
+ this->CheckCustomCommand(*cli);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::TraceDependencies()
+{
+ // CMake-generated targets have no dependencies to trace. Normally tracing
+ // would find nothing anyway, but when building CMake itself the "install"
+ // target command ends up referencing the "cmake" target but we do not
+ // really want the dependency because "install" depend on "all" anyway.
+ if(this->GetType() == cmTarget::GLOBAL_TARGET)
+ {
+ return;
+ }
+
+ // Use a helper object to trace the dependencies.
+ cmTargetTraceDependencies tracer(this);
+ tracer.Trace();
+}
+
+//----------------------------------------------------------------------------
void cmGeneratorTarget::GetAppleArchs(const char* config,
std::vector<std::string>& archVec)
{
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 9723f72..a99f54b 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -77,9 +77,22 @@ public:
/** Add the target output files to the global generator manifest. */
void GenerateTargetManifest(const char* config);
+ /**
+ * Trace through the source files in this target and add al source files
+ * that they depend on, used by all generators
+ */
+ void TraceDependencies();
+
void ClassifySources();
void LookupObjectLibraries();
+ /** Get sources that must be built before the given source. */
+ std::vector<cmSourceFile*> const* GetSourceDepends(cmSourceFile* sf);
+
+ struct SourceEntry { std::vector<cmSourceFile*> Depends; };
+ typedef std::map<cmSourceFile*, SourceEntry> SourceEntriesType;
+ SourceEntriesType SourceEntries;
+
private:
std::map<std::string, std::vector<std::string> > SystemIncludesCache;
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index df434b3..4d6e10f 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -52,6 +52,10 @@ public:
///! Get the name for this generator
virtual const char *GetName() const { return "Generic"; };
+ /** Check whether the given name matches the current generator. */
+ virtual bool MatchesGeneratorName(const char* name) const
+ { return strcmp(this->GetName(), name) == 0; }
+
/** Set the generator-specific toolset name. Returns true if toolset
is supported and false otherwise. */
virtual bool SetGeneratorToolset(std::string const& ts);
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index 07ccc33..5e29fd7 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -18,42 +18,65 @@
#include "cmVisualStudioSlnParser.h"
#include "cmake.h"
-static const char vs10Win32generatorName[] = "Visual Studio 10";
-static const char vs10Win64generatorName[] = "Visual Studio 10 Win64";
-static const char vs10IA64generatorName[] = "Visual Studio 10 IA64";
+static const char vs10generatorName[] = "Visual Studio 10 2010";
+
+// Map generator name without year to name with year.
+static const char* cmVS10GenName(const char* name, std::string& genName)
+{
+ if(strncmp(name, vs10generatorName, sizeof(vs10generatorName)-6) != 0)
+ {
+ return 0;
+ }
+ const char* p = name + sizeof(vs10generatorName) - 6;
+ if(strncmp(p, " 2010", 5) == 0)
+ {
+ p += 5;
+ }
+ genName = std::string(vs10generatorName) + p;
+ return p;
+}
class cmGlobalVisualStudio10Generator::Factory
: public cmGlobalGeneratorFactory
{
public:
- virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const {
- if(!strcmp(name, vs10Win32generatorName))
+ virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const
+ {
+ std::string genName;
+ const char* p = cmVS10GenName(name, genName);
+ if(!p)
+ { return 0; }
+ name = genName.c_str();
+ if(strcmp(p, "") == 0)
{
return new cmGlobalVisualStudio10Generator(
name, NULL, NULL);
}
- if(!strcmp(name, vs10Win64generatorName))
+ if(strcmp(p, " Win64") == 0)
{
return new cmGlobalVisualStudio10Generator(
name, "x64", "CMAKE_FORCE_WIN64");
}
- if(!strcmp(name, vs10IA64generatorName))
+ if(strcmp(p, " IA64") == 0)
{
return new cmGlobalVisualStudio10Generator(
name, "Itanium", "CMAKE_FORCE_IA64");
}
return 0;
- }
+ }
- virtual void GetDocumentation(cmDocumentationEntry& entry) const {
- entry.Name = "Visual Studio 10";
- entry.Brief = "Generates Visual Studio 10 (2010) project files.";
- }
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const
+ {
+ entry.Name = vs10generatorName;
+ entry.Brief = "Generates Visual Studio 10 (VS 2010) project files.";
+ }
- virtual void GetGenerators(std::vector<std::string>& names) const {
- names.push_back(vs10Win32generatorName);
- names.push_back(vs10Win64generatorName);
- names.push_back(vs10IA64generatorName); }
+ virtual void GetGenerators(std::vector<std::string>& names) const
+ {
+ names.push_back(vs10generatorName);
+ names.push_back(vs10generatorName + std::string(" IA64"));
+ names.push_back(vs10generatorName + std::string(" Win64"));
+ }
};
//----------------------------------------------------------------------------
@@ -79,6 +102,18 @@ cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator(
//----------------------------------------------------------------------------
bool
+cmGlobalVisualStudio10Generator::MatchesGeneratorName(const char* name) const
+{
+ std::string genName;
+ if(cmVS10GenName(name, genName))
+ {
+ return genName == this->GetName();
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool
cmGlobalVisualStudio10Generator::SetGeneratorToolset(std::string const& ts)
{
this->PlatformToolset = ts;
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index 31e122e..e9e7cb1 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -28,6 +28,8 @@ public:
const char* platformName, const char* additionalPlatformDefinition);
static cmGlobalGeneratorFactory* NewFactory();
+ virtual bool MatchesGeneratorName(const char* name) const;
+
virtual bool SetGeneratorToolset(std::string const& ts);
virtual std::string
diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx
index 41a349e..d968c6d 100644
--- a/Source/cmGlobalVisualStudio11Generator.cxx
+++ b/Source/cmGlobalVisualStudio11Generator.cxx
@@ -13,42 +13,54 @@
#include "cmLocalVisualStudio10Generator.h"
#include "cmMakefile.h"
-static const char vs11generatorName[] = "Visual Studio 11";
+static const char vs11generatorName[] = "Visual Studio 11 2012";
+
+// Map generator name without year to name with year.
+static const char* cmVS11GenName(const char* name, std::string& genName)
+{
+ if(strncmp(name, vs11generatorName, sizeof(vs11generatorName)-6) != 0)
+ {
+ return 0;
+ }
+ const char* p = name + sizeof(vs11generatorName) - 6;
+ if(strncmp(p, " 2012", 5) == 0)
+ {
+ p += 5;
+ }
+ genName = std::string(vs11generatorName) + p;
+ return p;
+}
class cmGlobalVisualStudio11Generator::Factory
: public cmGlobalGeneratorFactory
{
public:
- virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const {
- if(strstr(name, vs11generatorName) != name)
- {
- return 0;
- }
-
- const char* p = name + sizeof(vs11generatorName) - 1;
- if(p[0] == '\0')
+ virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const
+ {
+ std::string genName;
+ const char* p = cmVS11GenName(name, genName);
+ if(!p)
+ { return 0; }
+ name = genName.c_str();
+ if(strcmp(p, "") == 0)
{
return new cmGlobalVisualStudio11Generator(
name, NULL, NULL);
}
-
- if(p[0] != ' ')
+ if(strcmp(p, " Win64") == 0)
{
- return 0;
+ return new cmGlobalVisualStudio11Generator(
+ name, "x64", "CMAKE_FORCE_WIN64");
}
-
- ++p;
-
- if(!strcmp(p, "ARM"))
+ if(strcmp(p, " ARM") == 0)
{
return new cmGlobalVisualStudio11Generator(
name, "ARM", NULL);
}
- if(!strcmp(p, "Win64"))
+ if(*p++ != ' ')
{
- return new cmGlobalVisualStudio11Generator(
- name, "x64", "CMAKE_FORCE_WIN64");
+ return 0;
}
std::set<std::string> installedSDKs =
@@ -63,14 +75,16 @@ public:
new cmGlobalVisualStudio11Generator(name, p, NULL);
ret->WindowsCEVersion = "8.00";
return ret;
- }
+ }
- virtual void GetDocumentation(cmDocumentationEntry& entry) const {
- entry.Name = "Visual Studio 11";
- entry.Brief = "Generates Visual Studio 11 (2012) project files.";
- }
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const
+ {
+ entry.Name = vs11generatorName;
+ entry.Brief = "Generates Visual Studio 11 (VS 2012) project files.";
+ }
- virtual void GetGenerators(std::vector<std::string>& names) const {
+ virtual void GetGenerators(std::vector<std::string>& names) const
+ {
names.push_back(vs11generatorName);
names.push_back(vs11generatorName + std::string(" ARM"));
names.push_back(vs11generatorName + std::string(" Win64"));
@@ -80,9 +94,9 @@ public:
for(std::set<std::string>::const_iterator i =
installedSDKs.begin(); i != installedSDKs.end(); ++i)
{
- names.push_back("Visual Studio 11 " + *i);
+ names.push_back(std::string(vs11generatorName) + " " + *i);
}
- }
+ }
};
//----------------------------------------------------------------------------
@@ -107,6 +121,18 @@ cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator(
}
//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio11Generator::MatchesGeneratorName(const char* name) const
+{
+ std::string genName;
+ if(cmVS11GenName(name, genName))
+ {
+ return genName == this->GetName();
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
void cmGlobalVisualStudio11Generator::WriteSLNHeader(std::ostream& fout)
{
fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
diff --git a/Source/cmGlobalVisualStudio11Generator.h b/Source/cmGlobalVisualStudio11Generator.h
index 7cc7e69..7ef77e7 100644
--- a/Source/cmGlobalVisualStudio11Generator.h
+++ b/Source/cmGlobalVisualStudio11Generator.h
@@ -24,6 +24,8 @@ public:
const char* platformName, const char* additionalPlatformDefinition);
static cmGlobalGeneratorFactory* NewFactory();
+ virtual bool MatchesGeneratorName(const char* name) const;
+
virtual void WriteSLNHeader(std::ostream& fout);
///! create the correct local generator
diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx
index c2cdc0b..f3806df 100644
--- a/Source/cmGlobalVisualStudio12Generator.cxx
+++ b/Source/cmGlobalVisualStudio12Generator.cxx
@@ -13,42 +13,65 @@
#include "cmLocalVisualStudio10Generator.h"
#include "cmMakefile.h"
-static const char vs12Win32generatorName[] = "Visual Studio 12";
-static const char vs12Win64generatorName[] = "Visual Studio 12 Win64";
-static const char vs12ARMgeneratorName[] = "Visual Studio 12 ARM";
+static const char vs12generatorName[] = "Visual Studio 12 2013";
+
+// Map generator name without year to name with year.
+static const char* cmVS12GenName(const char* name, std::string& genName)
+{
+ if(strncmp(name, vs12generatorName, sizeof(vs12generatorName)-6) != 0)
+ {
+ return 0;
+ }
+ const char* p = name + sizeof(vs12generatorName) - 6;
+ if(strncmp(p, " 2013", 5) == 0)
+ {
+ p += 5;
+ }
+ genName = std::string(vs12generatorName) + p;
+ return p;
+}
class cmGlobalVisualStudio12Generator::Factory
: public cmGlobalGeneratorFactory
{
public:
- virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const {
- if(!strcmp(name, vs12Win32generatorName))
+ virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const
+ {
+ std::string genName;
+ const char* p = cmVS12GenName(name, genName);
+ if(!p)
+ { return 0; }
+ name = genName.c_str();
+ if(strcmp(p, "") == 0)
{
return new cmGlobalVisualStudio12Generator(
name, NULL, NULL);
}
- if(!strcmp(name, vs12Win64generatorName))
+ if(strcmp(p, " Win64") == 0)
{
return new cmGlobalVisualStudio12Generator(
name, "x64", "CMAKE_FORCE_WIN64");
}
- if(!strcmp(name, vs12ARMgeneratorName))
+ if(strcmp(p, " ARM") == 0)
{
return new cmGlobalVisualStudio12Generator(
name, "ARM", NULL);
}
return 0;
- }
+ }
- virtual void GetDocumentation(cmDocumentationEntry& entry) const {
- entry.Name = "Visual Studio 12";
- entry.Brief = "Generates Visual Studio 12 (2013) project files.";
- }
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const
+ {
+ entry.Name = vs12generatorName;
+ entry.Brief = "Generates Visual Studio 12 (VS 2013) project files.";
+ }
- virtual void GetGenerators(std::vector<std::string>& names) const {
- names.push_back(vs12Win32generatorName);
- names.push_back(vs12Win64generatorName);
- names.push_back(vs12ARMgeneratorName); }
+ virtual void GetGenerators(std::vector<std::string>& names) const
+ {
+ names.push_back(vs12generatorName);
+ names.push_back(vs12generatorName + std::string(" ARM"));
+ names.push_back(vs12generatorName + std::string(" Win64"));
+ }
};
//----------------------------------------------------------------------------
@@ -73,6 +96,18 @@ cmGlobalVisualStudio12Generator::cmGlobalVisualStudio12Generator(
}
//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudio12Generator::MatchesGeneratorName(const char* name) const
+{
+ std::string genName;
+ if(cmVS12GenName(name, genName))
+ {
+ return genName == this->GetName();
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
void cmGlobalVisualStudio12Generator::WriteSLNHeader(std::ostream& fout)
{
fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
diff --git a/Source/cmGlobalVisualStudio12Generator.h b/Source/cmGlobalVisualStudio12Generator.h
index 8c8aeb1..5a4a78d 100644
--- a/Source/cmGlobalVisualStudio12Generator.h
+++ b/Source/cmGlobalVisualStudio12Generator.h
@@ -24,6 +24,8 @@ public:
const char* platformName, const char* additionalPlatformDefinition);
static cmGlobalGeneratorFactory* NewFactory();
+ virtual bool MatchesGeneratorName(const char* name) const;
+
virtual void WriteSLNHeader(std::ostream& fout);
///! create the correct local generator
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 2a29061..63ec576 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -257,10 +257,11 @@ void cmLocalGenerator::ConfigureFinalPass()
void cmLocalGenerator::TraceDependencies()
{
// Generate the rule files for each target.
- cmTargets& targets = this->Makefile->GetTargets();
- for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
+ cmGeneratorTargetsType targets = this->Makefile->GetGeneratorTargets();
+ for(cmGeneratorTargetsType::iterator t = targets.begin();
+ t != targets.end(); ++t)
{
- t->second.TraceDependencies();
+ t->second->TraceDependencies();
}
}
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index d95a213..f1d5e2c 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -318,9 +318,13 @@ void cmLocalNinjaGenerator::AppendCustomCommandLines(const cmCustomCommand *cc,
cdCmd << cdStr << this->ConvertToOutputFormat(wd, SHELL);
cmdLines.push_back(cdCmd.str());
}
+
+ std::string launcher = this->MakeCustomLauncher(*cc);
+
for (unsigned i = 0; i != ccg.GetNumberOfCommands(); ++i) {
- cmdLines.push_back(this->ConvertToOutputFormat(ccg.GetCommand(i).c_str(),
- SHELL));
+ cmdLines.push_back(launcher +
+ this->ConvertToOutputFormat(ccg.GetCommand(i).c_str(), SHELL));
+
std::string& cmd = cmdLines.back();
ccg.AppendArguments(i, cmd);
}
@@ -407,3 +411,39 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
this->WriteCustomCommandBuildStatement(i->first, ccTargetDeps);
}
}
+
+std::string cmLocalNinjaGenerator::MakeCustomLauncher(
+ const cmCustomCommand& cc)
+{
+ const char* property = "RULE_LAUNCH_CUSTOM";
+ const char* property_value = this->Makefile->GetProperty(property);
+
+ if(!property_value || !*property_value)
+ {
+ return std::string();
+ }
+
+ // Expand rules in the empty string. It may insert the launcher and
+ // perform replacements.
+ RuleVariables vars;
+ vars.RuleLauncher = property;
+ std::string output;
+ const std::vector<std::string>& outputs = cc.GetOutputs();
+ if(!outputs.empty())
+ {
+ RelativeRoot relative_root =
+ cc.GetWorkingDirectory() ? NONE : START_OUTPUT;
+
+ output = this->Convert(outputs[0].c_str(), relative_root, SHELL);
+ }
+ vars.Output = output.c_str();
+
+ std::string launcher;
+ this->ExpandRuleVariables(launcher, vars);
+ if(!launcher.empty())
+ {
+ launcher += " ";
+ }
+
+ return launcher;
+}
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index c450841..8eb63c5 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -121,6 +121,7 @@ private:
void WriteCustomCommandBuildStatements();
+ std::string MakeCustomLauncher(const cmCustomCommand& cc);
std::string ConfigName;
std::string HomeRelativeOutputPath;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 6d6d2d8..92eca0f 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -22,7 +22,6 @@
#include <cmsys/RegularExpression.hxx>
#include <map>
#include <set>
-#include <queue>
#include <stdlib.h> // required for atof
#include <assert.h>
@@ -84,12 +83,9 @@ public:
{
this->SourceFileFlagsConstructed = false;
}
- cmTargetInternals(cmTargetInternals const& r)
+ cmTargetInternals(cmTargetInternals const&)
{
this->SourceFileFlagsConstructed = false;
- // Only some of these entries are part of the object state.
- // Others not copied here are result caches.
- this->SourceEntries = r.SourceEntries;
}
~cmTargetInternals();
typedef cmTarget::SourceFileFlags SourceFileFlags;
@@ -125,10 +121,6 @@ public:
LinkClosureMapType;
LinkClosureMapType LinkClosureMap;
- struct SourceEntry { std::vector<cmSourceFile*> Depends; };
- typedef std::map<cmSourceFile*, SourceEntry> SourceEntriesType;
- SourceEntriesType SourceEntries;
-
struct TargetPropertyEntry {
TargetPropertyEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge,
const std::string &targetName = std::string())
@@ -493,285 +485,6 @@ bool cmTarget::IsBundleOnApple()
}
//----------------------------------------------------------------------------
-class cmTargetTraceDependencies
-{
-public:
- cmTargetTraceDependencies(cmTarget* target, cmTargetInternals* internal);
- void Trace();
-private:
- cmTarget* Target;
- cmTargetInternals* Internal;
- cmMakefile* Makefile;
- cmGlobalGenerator* GlobalGenerator;
- typedef cmTargetInternals::SourceEntry SourceEntry;
- SourceEntry* CurrentEntry;
- std::queue<cmSourceFile*> SourceQueue;
- std::set<cmSourceFile*> SourcesQueued;
- typedef std::map<cmStdString, cmSourceFile*> NameMapType;
- NameMapType NameMap;
-
- void QueueSource(cmSourceFile* sf);
- void FollowName(std::string const& name);
- void FollowNames(std::vector<std::string> const& names);
- bool IsUtility(std::string const& dep);
- void CheckCustomCommand(cmCustomCommand const& cc);
- void CheckCustomCommands(const std::vector<cmCustomCommand>& commands);
-};
-
-//----------------------------------------------------------------------------
-cmTargetTraceDependencies
-::cmTargetTraceDependencies(cmTarget* target, cmTargetInternals* internal):
- Target(target), Internal(internal)
-{
- // Convenience.
- this->Makefile = this->Target->GetMakefile();
- this->GlobalGenerator =
- this->Makefile->GetLocalGenerator()->GetGlobalGenerator();
- this->CurrentEntry = 0;
-
- // Queue all the source files already specified for the target.
- std::vector<cmSourceFile*> const& sources = this->Target->GetSourceFiles();
- for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
- si != sources.end(); ++si)
- {
- this->QueueSource(*si);
- }
-
- // Queue pre-build, pre-link, and post-build rule dependencies.
- this->CheckCustomCommands(this->Target->GetPreBuildCommands());
- this->CheckCustomCommands(this->Target->GetPreLinkCommands());
- this->CheckCustomCommands(this->Target->GetPostBuildCommands());
-}
-
-//----------------------------------------------------------------------------
-void cmTargetTraceDependencies::Trace()
-{
- // Process one dependency at a time until the queue is empty.
- while(!this->SourceQueue.empty())
- {
- // Get the next source from the queue.
- cmSourceFile* sf = this->SourceQueue.front();
- this->SourceQueue.pop();
- this->CurrentEntry = &this->Internal->SourceEntries[sf];
-
- // Queue dependencies added explicitly by the user.
- if(const char* additionalDeps = sf->GetProperty("OBJECT_DEPENDS"))
- {
- std::vector<std::string> objDeps;
- cmSystemTools::ExpandListArgument(additionalDeps, objDeps);
- this->FollowNames(objDeps);
- }
-
- // Queue the source needed to generate this file, if any.
- this->FollowName(sf->GetFullPath());
-
- // Queue dependencies added programatically by commands.
- this->FollowNames(sf->GetDepends());
-
- // Queue custom command dependencies.
- if(cmCustomCommand const* cc = sf->GetCustomCommand())
- {
- this->CheckCustomCommand(*cc);
- }
- }
- this->CurrentEntry = 0;
-}
-
-//----------------------------------------------------------------------------
-void cmTargetTraceDependencies::QueueSource(cmSourceFile* sf)
-{
- if(this->SourcesQueued.insert(sf).second)
- {
- this->SourceQueue.push(sf);
-
- // Make sure this file is in the target.
- this->Target->AddSourceFile(sf);
- }
-}
-
-//----------------------------------------------------------------------------
-void cmTargetTraceDependencies::FollowName(std::string const& name)
-{
- NameMapType::iterator i = this->NameMap.find(name);
- if(i == this->NameMap.end())
- {
- // Check if we know how to generate this file.
- cmSourceFile* sf = this->Makefile->GetSourceFileWithOutput(name.c_str());
- NameMapType::value_type entry(name, sf);
- i = this->NameMap.insert(entry).first;
- }
- if(cmSourceFile* sf = i->second)
- {
- // Record the dependency we just followed.
- if(this->CurrentEntry)
- {
- this->CurrentEntry->Depends.push_back(sf);
- }
-
- this->QueueSource(sf);
- }
-}
-
-//----------------------------------------------------------------------------
-void
-cmTargetTraceDependencies::FollowNames(std::vector<std::string> const& names)
-{
- for(std::vector<std::string>::const_iterator i = names.begin();
- i != names.end(); ++i)
- {
- this->FollowName(*i);
- }
-}
-
-//----------------------------------------------------------------------------
-bool cmTargetTraceDependencies::IsUtility(std::string const& dep)
-{
- // Dependencies on targets (utilities) are supposed to be named by
- // just the target name. However for compatibility we support
- // naming the output file generated by the target (assuming there is
- // no output-name property which old code would not have set). In
- // that case the target name will be the file basename of the
- // dependency.
- std::string util = cmSystemTools::GetFilenameName(dep);
- if(cmSystemTools::GetFilenameLastExtension(util) == ".exe")
- {
- util = cmSystemTools::GetFilenameWithoutLastExtension(util);
- }
-
- // Check for a target with this name.
- if(cmTarget* t = this->Makefile->FindTargetToUse(util.c_str()))
- {
- // If we find the target and the dep was given as a full path,
- // then make sure it was not a full path to something else, and
- // the fact that the name matched a target was just a coincidence.
- if(cmSystemTools::FileIsFullPath(dep.c_str()))
- {
- if(t->GetType() >= cmTarget::EXECUTABLE &&
- t->GetType() <= cmTarget::MODULE_LIBRARY)
- {
- // This is really only for compatibility so we do not need to
- // worry about configuration names and output names.
- std::string tLocation = t->GetLocation(0);
- tLocation = cmSystemTools::GetFilenamePath(tLocation);
- std::string depLocation = cmSystemTools::GetFilenamePath(dep);
- depLocation = cmSystemTools::CollapseFullPath(depLocation.c_str());
- tLocation = cmSystemTools::CollapseFullPath(tLocation.c_str());
- if(depLocation == tLocation)
- {
- this->Target->AddUtility(util.c_str());
- return true;
- }
- }
- }
- else
- {
- // The original name of the dependency was not a full path. It
- // must name a target, so add the target-level dependency.
- this->Target->AddUtility(util.c_str());
- return true;
- }
- }
-
- // The dependency does not name a target built in this project.
- return false;
-}
-
-//----------------------------------------------------------------------------
-void
-cmTargetTraceDependencies
-::CheckCustomCommand(cmCustomCommand const& cc)
-{
- // Transform command names that reference targets built in this
- // project to corresponding target-level dependencies.
- cmGeneratorExpression ge(cc.GetBacktrace());
-
- // Add target-level dependencies referenced by generator expressions.
- std::set<cmTarget*> targets;
-
- for(cmCustomCommandLines::const_iterator cit = cc.GetCommandLines().begin();
- cit != cc.GetCommandLines().end(); ++cit)
- {
- std::string const& command = *cit->begin();
- // Check for a target with this name.
- if(cmTarget* t = this->Makefile->FindTargetToUse(command.c_str()))
- {
- if(t->GetType() == cmTarget::EXECUTABLE)
- {
- // The command refers to an executable target built in
- // this project. Add the target-level dependency to make
- // sure the executable is up to date before this custom
- // command possibly runs.
- this->Target->AddUtility(command.c_str());
- }
- }
-
- // Check for target references in generator expressions.
- for(cmCustomCommandLine::const_iterator cli = cit->begin();
- cli != cit->end(); ++cli)
- {
- const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge
- = ge.Parse(*cli);
- cge->Evaluate(this->Makefile, 0, true);
- std::set<cmTarget*> geTargets = cge->GetTargets();
- for(std::set<cmTarget*>::const_iterator it = geTargets.begin();
- it != geTargets.end(); ++it)
- {
- targets.insert(*it);
- }
- }
- }
-
- for(std::set<cmTarget*>::iterator ti = targets.begin();
- ti != targets.end(); ++ti)
- {
- this->Target->AddUtility((*ti)->GetName());
- }
-
- // Queue the custom command dependencies.
- std::vector<std::string> const& depends = cc.GetDepends();
- for(std::vector<std::string>::const_iterator di = depends.begin();
- di != depends.end(); ++di)
- {
- std::string const& dep = *di;
- if(!this->IsUtility(dep))
- {
- // The dependency does not name a target and may be a file we
- // know how to generate. Queue it.
- this->FollowName(dep);
- }
- }
-}
-
-//----------------------------------------------------------------------------
-void
-cmTargetTraceDependencies
-::CheckCustomCommands(const std::vector<cmCustomCommand>& commands)
-{
- for(std::vector<cmCustomCommand>::const_iterator cli = commands.begin();
- cli != commands.end(); ++cli)
- {
- this->CheckCustomCommand(*cli);
- }
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::TraceDependencies()
-{
- // CMake-generated targets have no dependencies to trace. Normally tracing
- // would find nothing anyway, but when building CMake itself the "install"
- // target command ends up referencing the "cmake" target but we do not
- // really want the dependency because "install" depend on "all" anyway.
- if(this->GetType() == cmTarget::GLOBAL_TARGET)
- {
- return;
- }
-
- // Use a helper object to trace the dependencies.
- cmTargetTraceDependencies tracer(this, this->Internal.Get());
- tracer.Trace();
-}
-
-//----------------------------------------------------------------------------
bool cmTarget::FindSourceFiles()
{
for(std::vector<cmSourceFile*>::const_iterator
@@ -802,31 +515,14 @@ std::vector<cmSourceFile*> const& cmTarget::GetSourceFiles()
//----------------------------------------------------------------------------
void cmTarget::AddSourceFile(cmSourceFile* sf)
{
- typedef cmTargetInternals::SourceEntriesType SourceEntriesType;
- SourceEntriesType::iterator i = this->Internal->SourceEntries.find(sf);
- if(i == this->Internal->SourceEntries.end())
+ if (std::find(this->SourceFiles.begin(), this->SourceFiles.end(), sf)
+ == this->SourceFiles.end())
{
- typedef cmTargetInternals::SourceEntry SourceEntry;
- SourceEntriesType::value_type entry(sf, SourceEntry());
- i = this->Internal->SourceEntries.insert(entry).first;
this->SourceFiles.push_back(sf);
}
}
//----------------------------------------------------------------------------
-std::vector<cmSourceFile*> const*
-cmTarget::GetSourceDepends(cmSourceFile* sf)
-{
- typedef cmTargetInternals::SourceEntriesType SourceEntriesType;
- SourceEntriesType::iterator i = this->Internal->SourceEntries.find(sf);
- if(i != this->Internal->SourceEntries.end())
- {
- return &i->second.Depends;
- }
- return 0;
-}
-
-//----------------------------------------------------------------------------
void cmTarget::AddSources(std::vector<std::string> const& srcs)
{
for(std::vector<std::string>::const_iterator i = srcs.begin();
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 41af8ab..f3b60b0 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -34,6 +34,8 @@ class cmGlobalGenerator;
class cmComputeLinkInformation;
class cmListFileBacktrace;
class cmTarget;
+class cmGeneratorTarget;
+class cmTargetTraceDependencies;
struct cmTargetLinkInformationMap:
public std::map<std::pair<cmTarget*, std::string>, cmComputeLinkInformation*>
@@ -128,9 +130,6 @@ public:
return this->ObjectLibraries;
}
- /** Get sources that must be built before the given source. */
- std::vector<cmSourceFile*> const* GetSourceDepends(cmSourceFile* sf);
-
/**
* Flags for a given source file as used in this target. Typically assigned
* via SET_TARGET_PROPERTIES when the property is a list of source files.
@@ -347,12 +346,6 @@ public:
void GetTargetVersion(bool soversion, int& major, int& minor, int& patch);
/**
- * Trace through the source files in this target and add al source files
- * that they depend on, used by all generators
- */
- void TraceDependencies();
-
- /**
* Make sure the full path to all source files is known.
*/
bool FindSourceFiles();
@@ -732,6 +725,8 @@ private:
// Internal representation details.
friend class cmTargetInternals;
+ friend class cmGeneratorTarget;
+ friend class cmTargetTraceDependencies;
cmTargetInternalPointer Internal;
void ConstructSourceFileFlags();
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 0dbb5eb..ab97b5e 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -562,7 +562,7 @@ void cmVisualStudio10TargetGenerator::WriteCustomCommand(cmSourceFile* sf)
if(this->SourcesVisited.insert(sf).second)
{
if(std::vector<cmSourceFile*> const* depends =
- this->Target->GetSourceDepends(sf))
+ this->GeneratorTarget->GetSourceDepends(sf))
{
for(std::vector<cmSourceFile*>::const_iterator di = depends->begin();
di != depends->end(); ++di)
@@ -1049,7 +1049,8 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
si = this->GeneratorTarget->ExternalObjects.begin();
si != this->GeneratorTarget->ExternalObjects.end(); ++si)
{
- std::vector<cmSourceFile*> const* d=this->Target->GetSourceDepends(*si);
+ std::vector<cmSourceFile*> const* d =
+ this->GeneratorTarget->GetSourceDepends(*si);
this->WriteSource((d && !d->empty())? "None":"Object", *si);
}
}
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 186d4e6..f786691 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -1468,9 +1468,9 @@ int cmake::ActualConfigure()
{"7.1", "Visual Studio 7 .NET 2003"},
{"8.0", "Visual Studio 8 2005"},
{"9.0", "Visual Studio 9 2008"},
- {"10.0", "Visual Studio 10"},
- {"11.0", "Visual Studio 11"},
- {"12.0", "Visual Studio 12"},
+ {"10.0", "Visual Studio 10 2010"},
+ {"11.0", "Visual Studio 11 2012"},
+ {"12.0", "Visual Studio 12 2013"},
{0, 0}};
for(int i=0; version[i].MSVersion != 0; i++)
{
@@ -1509,7 +1509,7 @@ int cmake::ActualConfigure()
const char* genName = this->CacheManager->GetCacheValue("CMAKE_GENERATOR");
if(genName)
{
- if(strcmp(this->GlobalGenerator->GetName(), genName) != 0)
+ if(!this->GlobalGenerator->MatchesGeneratorName(genName))
{
std::string message = "Error: generator : ";
message += this->GlobalGenerator->GetName();
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 4b08c88..7c939ed 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -2344,6 +2344,17 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
--output-log "${CMake_BINARY_DIR}/Tests/CTestTest2/testOutput.log"
)
+ if("${CMAKE_TEST_GENERATOR}" MATCHES "Makefiles" OR "${CMAKE_TEST_GENERATOR}" MATCHES "Ninja")
+ configure_file("${CMake_SOURCE_DIR}/Tests/CTestTestLaunchers/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestLaunchers/test.cmake" @ONLY ESCAPE_QUOTES)
+ add_test(CTestTestLaunchers ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestLaunchers/test.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestLaunchers/testOutput.log"
+ )
+ set_tests_properties(CTestTestLaunchers PROPERTIES
+ PASS_REGULAR_EXPRESSION "CTEST_TEST_LAUNCHER_SUCCESS")
+ endif()
+
configure_file("${CMake_SOURCE_DIR}/Tests/CTestTestChecksum/test.cmake.in"
"${CMake_BINARY_DIR}/Tests/CTestTestChecksum/test.cmake" @ONLY
ESCAPE_QUOTES)
diff --git a/Tests/CTestTestLaunchers/launcher_test_project/CMakeLists.txt b/Tests/CTestTestLaunchers/launcher_test_project/CMakeLists.txt
new file mode 100644
index 0000000..06c5725
--- /dev/null
+++ b/Tests/CTestTestLaunchers/launcher_test_project/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12)
+
+project(launcher_test_project)
+
+include(CTest)
+
+add_custom_command(
+ OUTPUT test1.txt
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -DTESTID=1 -P "${CMAKE_CURRENT_SOURCE_DIR}/command.cmake"
+)
+
+add_custom_command(
+ OUTPUT test2.txt
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -DTESTID=2 -P "${CMAKE_CURRENT_SOURCE_DIR}/command.cmake"
+)
+
+add_custom_target(mytarget ALL DEPENDS test1.txt test2.txt)
diff --git a/Tests/CTestTestLaunchers/launcher_test_project/CTestConfig.cmake b/Tests/CTestTestLaunchers/launcher_test_project/CTestConfig.cmake
new file mode 100644
index 0000000..bf404ab
--- /dev/null
+++ b/Tests/CTestTestLaunchers/launcher_test_project/CTestConfig.cmake
@@ -0,0 +1,8 @@
+set(CTEST_USE_LAUNCHERS 1)
+set(CTEST_PROJECT_NAME "CTestTestLaunchers")
+set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
+set(CTEST_DART_SERVER_VERSION "2")
+set(CTEST_DROP_METHOD "http")
+set(CTEST_DROP_SITE "www.cdash.org")
+set(CTEST_DROP_LOCATION "/CDash/submit.php?project=PublicDashboard")
+set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Tests/CTestTestLaunchers/launcher_test_project/command.cmake b/Tests/CTestTestLaunchers/launcher_test_project/command.cmake
new file mode 100644
index 0000000..7f31af9
--- /dev/null
+++ b/Tests/CTestTestLaunchers/launcher_test_project/command.cmake
@@ -0,0 +1,5 @@
+if("${TESTID}" STREQUAL "1")
+ message("success")
+elseif("${TESTID}" STREQUAL "2")
+ message(FATAL_ERROR "failure")
+endif()
diff --git a/Tests/CTestTestLaunchers/test.cmake.in b/Tests/CTestTestLaunchers/test.cmake.in
new file mode 100644
index 0000000..43a6533
--- /dev/null
+++ b/Tests/CTestTestLaunchers/test.cmake.in
@@ -0,0 +1,39 @@
+cmake_minimum_required(VERSION 2.8.12)
+
+# Settings:
+set(CTEST_DASHBOARD_SOURCE "@CMake_SOURCE_DIR@/Tests/CTestTestLaunchers")
+set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTestLaunchers")
+set(CTEST_SITE "@SITE@")
+set(CTEST_BUILD_NAME "Launchers-@BUILDNAME@-CTestTestLaunchers")
+
+set(CTEST_SOURCE_DIRECTORY "${CTEST_DASHBOARD_SOURCE}/launcher_test_project")
+set(CTEST_BINARY_DIRECTORY "${CTEST_DASHBOARD_ROOT}/launcher_test_project-bin")
+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@")
+set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
+set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
+
+ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
+
+file(WRITE "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt" "
+CMAKE_CXX_FLAGS:STRING=@CMAKE_CXX_FLAGS@
+CMAKE_C_FLAGS:STRING=@CMAKE_C_FLAGS@
+CMAKE_C_COMPILER:STRING=@CMAKE_C_COMPILER@
+CMAKE_CXX_COMPILER:STRING=@CMAKE_CXX_COMPILER@
+CMAKE_C_COMPILER_ARG1:STRING=@CMAKE_C_COMPILER_ARG1@
+CMAKE_CXX_COMPILER_ARG1:STRING=@CMAKE_CXX_COMPILER_ARG1@
+")
+
+set(TEST_SUCCESS FALSE)
+
+ctest_start(Experimental)
+ctest_configure(OPTIONS "-DCTEST_USE_LAUNCHERS=1")
+ctest_build(NUMBER_ERRORS error_count)
+
+if("${error_count}" STREQUAL "1")
+ set(TEST_SUCCESS TRUE)
+endif()
+
+if(TEST_SUCCESS)
+ message("CTEST_TEST_LAUNCHER_SUCCESS")
+endif()