diff options
author | Brad King <brad.king@kitware.com> | 2018-04-25 12:56:06 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2018-04-25 12:56:16 (GMT) |
commit | 5a6c6292898fe238f3a5105133b8904209fbedaf (patch) | |
tree | 33e003d33adddf89ac0c04e82788d63a9142670d | |
parent | e5d15848ca6cdc52ff44edcde7689518793a5eb6 (diff) | |
parent | f59c33a763ba1483129f0e721bc2394bb7442876 (diff) | |
download | CMake-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.cxx | 52 | ||||
-rw-r--r-- | Source/cmLocalVisualStudio10Generator.h | 9 | ||||
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.cxx | 10 | ||||
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.h | 5 | ||||
-rw-r--r-- | Tests/RunCMake/add_custom_command/AssigningMultipleTargets.cmake | 13 | ||||
-rw-r--r-- | Tests/RunCMake/add_custom_command/RunCMakeTest.cmake | 7 | ||||
-rw-r--r-- | Tests/RunCMake/add_custom_command/a.c | 3 | ||||
-rw-r--r-- | Tests/RunCMake/add_custom_command/generate-once.cmake | 8 |
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") |