Browse Source

VS: Fix subproject .sln dependencies on custom targets

Each project listed in a .sln must be marked (or not) as part of the
"default build" for each configuration.  For targets created by the
add_custom_target() command we add them to the default build if they
are not excluded in some way or if another target depends on them.
In the top-level .sln, a custom target is excluded if it is not
created with the ALL option to add_custom_target.  In subdirectory
.sln files, a target may also be excluded if it is not within the
directory and is brought into the solution only due to a dependency
from another target in the solution.

Fix the "IsPartOfDefaultBuild" and "IsDependedOn" methods to check
every target to be included in the .sln for a dependency on the
custom target.  Otherwise transitive dependencies through targets
not in the current subdirectory will not be considered.

Extend the SubProject test with a custom target to cover this case.

Reported-by: William Deurwaarder <[email protected]>
Reported-by: Dirk Steenpass <[email protected]>
Brad King 11 years ago
parent
commit
790e167718

+ 12 - 27
Source/cmGlobalVisualStudio7Generator.cxx

@@ -392,8 +392,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
     else
       {
       const std::set<std::string>& configsPartOfDefaultBuild =
-        this->IsPartOfDefaultBuild(root->GetMakefile()->GetProjectName(),
-                                   target);
+        this->IsPartOfDefaultBuild(projectTargets, target);
       const char *vcprojName =
         target->GetProperty("GENERATOR_FILE_NAME");
       if (vcprojName)
@@ -981,8 +980,7 @@ cmGlobalVisualStudio7Generator
 
 std::set<std::string>
 cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(
-                                                    const std::string& project,
-                                                    cmTarget const* target)
+  OrderedTargetDependSet const& projectTargets, cmTarget const* target)
 {
   std::set<std::string> activeConfigs;
   // if it is a utilitiy target then only make it part of the
@@ -992,7 +990,7 @@ cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(
     {
     return activeConfigs;
     }
-  if(type == cmTarget::UTILITY && !this->IsDependedOn(project, target))
+  if(type == cmTarget::UTILITY && !this->IsDependedOn(projectTargets, target))
     {
     return activeConfigs;
     }
@@ -1011,31 +1009,18 @@ cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(
 }
 
 bool
-cmGlobalVisualStudio7Generator::IsDependedOn(const std::string& project,
-                                             cmTarget const* targetIn)
+cmGlobalVisualStudio7Generator
+::IsDependedOn(OrderedTargetDependSet const& projectTargets,
+               cmTarget const* targetIn)
 {
-  // Get all local gens for this project
-  std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator it =
-                                              this->ProjectMap.find(project);
-  if (it == this->ProjectMap.end())
-    {
-    return false;
-    }
-
-  // loop over local gens and get the targets for each one
-  for(std::vector<cmLocalGenerator*>::const_iterator geIt = it->second.begin();
-      geIt != it->second.end(); ++geIt)
+  for (OrderedTargetDependSet::const_iterator l = projectTargets.begin();
+       l != projectTargets.end(); ++l)
     {
-    cmTargets const& targets = (*geIt)->GetMakefile()->GetTargets();
-    for (cmTargets::const_iterator l = targets.begin();
-         l != targets.end(); l++)
+    cmTarget const& target = **l;
+    TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(target);
+    if(tgtdeps.count(targetIn))
       {
-      cmTarget const& target = l->second;
-      TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(target);
-      if(tgtdeps.count(targetIn))
-        {
-        return true;
-        }
+      return true;
       }
     }
   return false;

+ 5 - 3
Source/cmGlobalVisualStudio7Generator.h

@@ -164,9 +164,11 @@ protected:
 
   std::string ConvertToSolutionPath(const char* path);
 
-  std::set<std::string> IsPartOfDefaultBuild(const std::string& project,
-                                             cmTarget const* target);
-  bool IsDependedOn(const std::string& project, cmTarget const* target);
+  std::set<std::string>
+    IsPartOfDefaultBuild(OrderedTargetDependSet const& projectTargets,
+                         cmTarget const* target);
+  bool IsDependedOn(OrderedTargetDependSet const& projectTargets,
+                    cmTarget const* target);
   std::vector<std::string> Configurations;
   std::map<std::string, std::string> GUIDMap;
 

+ 10 - 1
Tests/SubProject/CMakeLists.txt

@@ -1,6 +1,15 @@
 cmake_minimum_required (VERSION 2.6)
 project(SubProject)
-message("${CMAKE_IMPORT_LIBRARY_SUFFIX}")
+file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/gen.cxx) # require generation
+add_custom_command(
+  OUTPUT gen.cxx
+  DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/gen.cxx.in
+  COMMAND ${CMAKE_COMMAND} -E copy
+             ${CMAKE_CURRENT_SOURCE_DIR}/gen.cxx.in gen.cxx
+  )
+add_custom_target(gen DEPENDS gen.cxx)
 add_library(bar bar.cxx)
+target_include_directories(bar PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+add_dependencies(bar gen)
 add_executable(car car.cxx)
 add_subdirectory(foo)

+ 1 - 4
Tests/SubProject/bar.cxx

@@ -1,4 +1 @@
-int bar()
-{
-  return 10;
-}
+#include "gen.cxx"

+ 4 - 0
Tests/SubProject/gen.cxx.in

@@ -0,0 +1,4 @@
+int bar()
+{
+  return 10;
+}