summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2018-04-25 12:56:06 (GMT)
committerKitware Robot <kwrobot@kitware.com>2018-04-25 12:56:16 (GMT)
commit5a6c6292898fe238f3a5105133b8904209fbedaf (patch)
tree33e003d33adddf89ac0c04e82788d63a9142670d
parente5d15848ca6cdc52ff44edcde7689518793a5eb6 (diff)
parentf59c33a763ba1483129f0e721bc2394bb7442876 (diff)
downloadCMake-5a6c6292898fe238f3a5105133b8904209fbedaf.zip
CMake-5a6c6292898fe238f3a5105133b8904209fbedaf.tar.gz
CMake-5a6c6292898fe238f3a5105133b8904209fbedaf.tar.bz2
Merge topic 'vs-dedup-custom-commands'
f59c33a763 VS: Generate a custom command only in the least dependent target d58d4daa6b cmVisualStudio10TargetGenerator: Use cmLocalVisualStudio10Generator Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !1889
-rw-r--r--Source/cmLocalVisualStudio10Generator.cxx52
-rw-r--r--Source/cmLocalVisualStudio10Generator.h9
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx10
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h5
-rw-r--r--Tests/RunCMake/add_custom_command/AssigningMultipleTargets.cmake13
-rw-r--r--Tests/RunCMake/add_custom_command/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/add_custom_command/a.c3
-rw-r--r--Tests/RunCMake/add_custom_command/generate-once.cmake8
8 files changed, 87 insertions, 20 deletions
diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx
index 2803d4a..5b6e781 100644
--- a/Source/cmLocalVisualStudio10Generator.cxx
+++ b/Source/cmLocalVisualStudio10Generator.cxx
@@ -62,21 +62,47 @@ cmLocalVisualStudio10Generator::~cmLocalVisualStudio10Generator()
{
}
+void cmLocalVisualStudio10Generator::GenerateTargetsDepthFirst(
+ cmGeneratorTarget* target, std::vector<cmGeneratorTarget*>& remaining)
+{
+ if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+ return;
+ }
+ // Find this target in the list of remaining targets.
+ auto it = std::find(remaining.begin(), remaining.end(), target);
+ if (it == remaining.end()) {
+ // This target was already handled.
+ return;
+ }
+ // Remove this target from the list of remaining targets because
+ // we are handling it now.
+ *it = nullptr;
+ auto& deps = this->GlobalGenerator->GetTargetDirectDepends(target);
+ for (auto& d : deps) {
+ // FIXME: Revise CreateSingleVCProj so we do not have to drop `const` here.
+ auto dependee = const_cast<cmGeneratorTarget*>(&*d);
+ GenerateTargetsDepthFirst(dependee, remaining);
+ // Take the union of visited source files of custom commands
+ auto visited = GetSourcesVisited(dependee);
+ GetSourcesVisited(target).insert(visited.begin(), visited.end());
+ }
+ if (static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator)
+ ->TargetIsFortranOnly(target)) {
+ this->CreateSingleVCProj(target->GetName(), target);
+ } else {
+ cmVisualStudio10TargetGenerator tg(
+ target, static_cast<cmGlobalVisualStudio10Generator*>(
+ this->GetGlobalGenerator()));
+ tg.Generate();
+ }
+}
+
void cmLocalVisualStudio10Generator::Generate()
{
- const std::vector<cmGeneratorTarget*>& tgts = this->GetGeneratorTargets();
- for (cmGeneratorTarget* l : tgts) {
- if (l->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
- continue;
- }
- if (static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator)
- ->TargetIsFortranOnly(l)) {
- this->CreateSingleVCProj(l->GetName(), l);
- } else {
- cmVisualStudio10TargetGenerator tg(
- l, static_cast<cmGlobalVisualStudio10Generator*>(
- this->GetGlobalGenerator()));
- tg.Generate();
+ std::vector<cmGeneratorTarget*> remaining = this->GetGeneratorTargets();
+ for (auto& t : remaining) {
+ if (t) {
+ GenerateTargetsDepthFirst(t, remaining);
}
}
this->WriteStampFiles();
diff --git a/Source/cmLocalVisualStudio10Generator.h b/Source/cmLocalVisualStudio10Generator.h
index bcdc307..a4150b9 100644
--- a/Source/cmLocalVisualStudio10Generator.h
+++ b/Source/cmLocalVisualStudio10Generator.h
@@ -33,10 +33,19 @@ public:
void ReadAndStoreExternalGUID(const std::string& name,
const char* path) override;
+ std::set<cmSourceFile const*>& GetSourcesVisited(cmGeneratorTarget* target)
+ {
+ return SourcesVisited[target];
+ };
+
protected:
const char* ReportErrorLabel() const override;
bool CustomCommandUseLocal() const override { return true; }
private:
+ void GenerateTargetsDepthFirst(cmGeneratorTarget* target,
+ std::vector<cmGeneratorTarget*>& remaining);
+
+ std::map<cmGeneratorTarget*, std::set<cmSourceFile const*>> SourcesVisited;
};
#endif
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 1a618a0..50b7d52 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -8,7 +8,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalVisualStudio10Generator.h"
-#include "cmLocalVisualStudio7Generator.h"
+#include "cmLocalVisualStudio10Generator.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmSystemTools.h"
@@ -204,7 +204,8 @@ cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator(
, Name(target->GetName())
, GUID(gg->GetGUID(this->Name))
, GlobalGenerator(gg)
- , LocalGenerator((cmLocalVisualStudio7Generator*)target->GetLocalGenerator())
+ , LocalGenerator(
+ (cmLocalVisualStudio10Generator*)target->GetLocalGenerator())
{
this->Makefile->GetConfigurations(this->Configurations);
this->NsightTegra = gg->IsNsightTegra();
@@ -1177,7 +1178,6 @@ void cmVisualStudio10TargetGenerator::WriteNsightTegraConfigurationValues(
void cmVisualStudio10TargetGenerator::WriteCustomCommands()
{
- this->SourcesVisited.clear();
this->CSharpCustomCommandNames.clear();
std::vector<cmSourceFile const*> customCommands;
this->GeneratorTarget->GetCustomCommands(customCommands, "");
@@ -1198,7 +1198,9 @@ void cmVisualStudio10TargetGenerator::WriteCustomCommands()
void cmVisualStudio10TargetGenerator::WriteCustomCommand(
cmSourceFile const* sf)
{
- if (this->SourcesVisited.insert(sf).second) {
+ if (this->LocalGenerator->GetSourcesVisited(this->GeneratorTarget)
+ .insert(sf)
+ .second) {
if (std::vector<cmSourceFile*> const* depends =
this->GeneratorTarget->GetSourceDepends(sf)) {
for (cmSourceFile const* di : *depends) {
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 3c53d1b..bbe3f7f 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -17,7 +17,7 @@ class cmCustomCommand;
class cmGeneratedFileStream;
class cmGeneratorTarget;
class cmGlobalVisualStudio10Generator;
-class cmLocalVisualStudio7Generator;
+class cmLocalVisualStudio10Generator;
class cmMakefile;
class cmSourceFile;
class cmSourceGroup;
@@ -208,8 +208,7 @@ private:
bool TargetCompileAsWinRT;
cmGlobalVisualStudio10Generator* const GlobalGenerator;
cmGeneratedFileStream* BuildFileStream;
- cmLocalVisualStudio7Generator* const LocalGenerator;
- std::set<cmSourceFile const*> SourcesVisited;
+ cmLocalVisualStudio10Generator* const LocalGenerator;
std::set<std::string> CSharpCustomCommandNames;
bool IsMissingFiles;
std::vector<std::string> AddedFiles;
diff --git a/Tests/RunCMake/add_custom_command/AssigningMultipleTargets.cmake b/Tests/RunCMake/add_custom_command/AssigningMultipleTargets.cmake
new file mode 100644
index 0000000..fe1cceb
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/AssigningMultipleTargets.cmake
@@ -0,0 +1,13 @@
+enable_language(CXX)
+
+add_custom_command(OUTPUT generated.cpp
+ MAIN_DEPENDENCY a.c
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/generate-once.cmake ${CMAKE_CURRENT_BINARY_DIR}/generated.cpp
+ VERBATIM)
+
+add_executable(exe1 ${CMAKE_CURRENT_BINARY_DIR}/generated.cpp)
+add_executable(exe2 ${CMAKE_CURRENT_BINARY_DIR}/generated.cpp)
+add_executable(exe3 ${CMAKE_CURRENT_BINARY_DIR}/generated.cpp)
+
+add_dependencies(exe1 exe2)
+add_dependencies(exe3 exe1)
diff --git a/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake b/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake
index c12e5aa..0387dbb 100644
--- a/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake
+++ b/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake
@@ -14,3 +14,10 @@ run_cmake(TargetNotInDir)
if(${RunCMake_GENERATOR} MATCHES "Visual Studio ([^89]|[89][0-9])")
run_cmake(RemoveEmptyCommands)
endif()
+
+run_cmake(AssigningMultipleTargets)
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AssigningMultipleTargets-build)
+set(RunCMake_TEST_NO_CLEAN 1)
+run_cmake_command(AssigningMultipleTargets-build ${CMAKE_COMMAND} --build .)
+unset(RunCMake_TEST_BINARY_DIR)
+unset(RunCMake_TEST_NO_CLEAN)
diff --git a/Tests/RunCMake/add_custom_command/a.c b/Tests/RunCMake/add_custom_command/a.c
new file mode 100644
index 0000000..707c1c3
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/a.c
@@ -0,0 +1,3 @@
+void a()
+{
+}
diff --git a/Tests/RunCMake/add_custom_command/generate-once.cmake b/Tests/RunCMake/add_custom_command/generate-once.cmake
new file mode 100644
index 0000000..2a8e843
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/generate-once.cmake
@@ -0,0 +1,8 @@
+if (${CMAKE_ARGC} LESS 4)
+ message(FATAL_ERROR "Too few arguments")
+endif()
+set(output "${CMAKE_ARGV3}")
+if(EXISTS ${output})
+ message(FATAL_ERROR "${output} already exists")
+endif()
+file(WRITE ${output} "int main() { return 0; }\n")