Browse Source

Merge topic 'per-config-EXCLUDE_FROM_DEFAULT_BUILD' into vs-global-sections

Conflicts:
	Source/cmGlobalVisualStudio7Generator.h
Brad King 13 years ago
parent
commit
45d4f81fde

+ 7 - 4
Source/cmGlobalVisualStudio71Generator.cxx

@@ -276,9 +276,10 @@ void cmGlobalVisualStudio71Generator
 // Write a dsp file into the SLN file, Note, that dependencies from
 // executables to the libraries it uses are also done here
 void cmGlobalVisualStudio71Generator
-::WriteProjectConfigurations(std::ostream& fout, const char* name,
-                             bool partOfDefaultBuild,
-                             const char* platformMapping)
+::WriteProjectConfigurations(
+  std::ostream& fout, const char* name,
+  const std::set<std::string>& configsPartOfDefaultBuild,
+  const char* platformMapping)
 {
   std::string guid = this->GetGUID(name);
   for(std::vector<std::string>::iterator i = this->Configurations.begin();
@@ -287,7 +288,9 @@ void cmGlobalVisualStudio71Generator
     fout << "\t\t{" << guid << "}." << *i
          << ".ActiveCfg = " << *i << "|"
          << (platformMapping ? platformMapping : "Win32") << std::endl;
-    if(partOfDefaultBuild)
+    std::set<std::string>::const_iterator
+      ci = configsPartOfDefaultBuild.find(*i);
+    if(!(ci == configsPartOfDefaultBuild.end()))
       {
       fout << "\t\t{" << guid << "}." << *i
            << ".Build.0 = " << *i << "|"

+ 4 - 4
Source/cmGlobalVisualStudio71Generator.h

@@ -61,10 +61,10 @@ protected:
                             const char* name, const char* path, cmTarget &t);
   virtual void WriteProjectDepends(std::ostream& fout,
                            const char* name, const char* path, cmTarget &t);
-  virtual void WriteProjectConfigurations(std::ostream& fout,
-                                          const char* name,
-                                          bool partOfDefaultBuild,
-                                          const char* platformMapping = NULL);
+  virtual void WriteProjectConfigurations(
+    std::ostream& fout, const char* name,
+    const std::set<std::string>& configsPartOfDefaultBuild,
+    const char* platformMapping = NULL);
   virtual void WriteExternalProject(std::ostream& fout,
                                     const char* name,
                                     const char* path,

+ 34 - 19
Source/cmGlobalVisualStudio7Generator.cxx

@@ -10,6 +10,7 @@
   See the License for more information.
 ============================================================================*/
 #include "windows.h" // this must be first to define GetCurrentDirectory
+#include <assert.h>
 #include "cmGlobalVisualStudio7Generator.h"
 #include "cmGeneratedFileStream.h"
 #include "cmLocalVisualStudio7Generator.h"
@@ -243,20 +244,23 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
     const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
     if(expath)
       {
+      std::set<std::string> allConfigurations(this->Configurations.begin(),
+                                              this->Configurations.end());
       this->WriteProjectConfigurations(
         fout, target->GetName(),
-        true, target->GetProperty("VS_PLATFORM_MAPPING"));
+        allConfigurations, target->GetProperty("VS_PLATFORM_MAPPING"));
       }
     else
       {
-      bool partOfDefaultBuild = this->IsPartOfDefaultBuild(
-        root->GetMakefile()->GetProjectName(), target);
+      const std::set<std::string>& configsPartOfDefaultBuild =
+        this->IsPartOfDefaultBuild(root->GetMakefile()->GetProjectName(),
+                                   target);
       const char *vcprojName =
         target->GetProperty("GENERATOR_FILE_NAME");
       if (vcprojName)
         {
         this->WriteProjectConfigurations(fout, vcprojName,
-                                         partOfDefaultBuild);
+                                         configsPartOfDefaultBuild);
         }
       }
     }
@@ -582,9 +586,10 @@ cmGlobalVisualStudio7Generator
 // Write a dsp file into the SLN file, Note, that dependencies from
 // executables to the libraries it uses are also done here
 void cmGlobalVisualStudio7Generator
-::WriteProjectConfigurations(std::ostream& fout, const char* name,
-                             bool partOfDefaultBuild,
-                             const char* platformMapping)
+::WriteProjectConfigurations(
+  std::ostream& fout, const char* name,
+  const std::set<std::string>& configsPartOfDefaultBuild,
+  const char* platformMapping)
 {
   std::string guid = this->GetGUID(name);
   for(std::vector<std::string>::iterator i = this->Configurations.begin();
@@ -593,7 +598,9 @@ void cmGlobalVisualStudio7Generator
     fout << "\t\t{" << guid << "}." << *i
          << ".ActiveCfg = " << *i << "|"
          << (platformMapping ? platformMapping : "Win32") << "\n";
-    if(partOfDefaultBuild)
+      std::set<std::string>::const_iterator
+        ci = configsPartOfDefaultBuild.find(*i);
+      if(!(ci == configsPartOfDefaultBuild.end()))
       {
       fout << "\t\t{" << guid << "}." << *i
            << ".Build.0 = " << *i << "|"
@@ -825,26 +832,34 @@ cmGlobalVisualStudio7Generator
     }
 }
 
-bool cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(const char* project,
-                                                          cmTarget* target)
+std::set<std::string>
+cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(const char* project,
+                                                     cmTarget* target)
 {
-  if(target->GetPropertyAsBool("EXCLUDE_FROM_DEFAULT_BUILD"))
-    {
-    return false;
-    }
+  std::set<std::string> activeConfigs;
   // if it is a utilitiy target then only make it part of the
   // default build if another target depends on it
   int type = target->GetType();
   if (type == cmTarget::GLOBAL_TARGET)
     {
-    return false;
+    return activeConfigs;
+    }
+  if(type == cmTarget::UTILITY && !this->IsDependedOn(project, target))
+    {
+    return activeConfigs;
     }
-  if(type == cmTarget::UTILITY)
+  // inspect EXCLUDE_FROM_DEFAULT_BUILD[_<CONFIG>] properties
+  for(std::vector<std::string>::iterator i = this->Configurations.begin();
+      i != this->Configurations.end(); ++i)
     {
-    return this->IsDependedOn(project, target);
+    const char* propertyValue =
+      target->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i->c_str());
+    if(cmSystemTools::IsOff(propertyValue))
+      {
+      activeConfigs.insert(*i);
+      }
     }
-  // default is to be part of the build
-  return true;
+  return activeConfigs;
 }
 
 //----------------------------------------------------------------------------

+ 6 - 6
Source/cmGlobalVisualStudio7Generator.h

@@ -105,10 +105,10 @@ protected:
                             const char* name, const char* path, cmTarget &t);
   virtual void WriteProjectDepends(std::ostream& fout,
                            const char* name, const char* path, cmTarget &t);
-  virtual void WriteProjectConfigurations(std::ostream& fout,
-                                          const char* name,
-                                          bool partOfDefaultBuild,
-                                          const char* platformMapping = NULL);
+  virtual void WriteProjectConfigurations(
+    std::ostream& fout, const char* name,
+    const std::set<std::string>& configsPartOfDefaultBuild,
+    const char* platformMapping = NULL);
   virtual void WriteSLNGlobalSections(std::ostream& fout,
                                       cmLocalGenerator* root);
   virtual void WriteSLNFooter(std::ostream& fout);
@@ -138,8 +138,8 @@ protected:
 
   std::string ConvertToSolutionPath(const char* path);
 
-  bool IsPartOfDefaultBuild(const char* project,
-                            cmTarget* target);
+  std::set<std::string> IsPartOfDefaultBuild(const char* project,
+                                             cmTarget* target);
   std::vector<std::string> Configurations;
   std::map<cmStdString, cmStdString> GUIDMap;
 

+ 7 - 4
Source/cmGlobalVisualStudio8Generator.cxx

@@ -257,9 +257,10 @@ cmGlobalVisualStudio8Generator
 //----------------------------------------------------------------------------
 void
 cmGlobalVisualStudio8Generator
-::WriteProjectConfigurations(std::ostream& fout, const char* name,
-                             bool partOfDefaultBuild,
-                             const char* platformMapping)
+::WriteProjectConfigurations(
+  std::ostream& fout, const char* name,
+  const std::set<std::string>& configsPartOfDefaultBuild,
+  const char* platformMapping)
 {
   std::string guid = this->GetGUID(name);
   for(std::vector<std::string>::iterator i = this->Configurations.begin();
@@ -269,7 +270,9 @@ cmGlobalVisualStudio8Generator
          << "|" << this->GetPlatformName() << ".ActiveCfg = " << *i << "|"
          << (platformMapping ? platformMapping : this->GetPlatformName())
          << "\n";
-    if(partOfDefaultBuild)
+      std::set<std::string>::const_iterator
+        ci = configsPartOfDefaultBuild.find(*i);
+      if(!(ci == configsPartOfDefaultBuild.end()))
       {
       fout << "\t\t{" << guid << "}." << *i
            << "|" << this->GetPlatformName() << ".Build.0 = " << *i << "|"

+ 4 - 4
Source/cmGlobalVisualStudio8Generator.h

@@ -74,10 +74,10 @@ protected:
   static cmIDEFlagTable const* GetExtraFlagTableVS8();
   virtual void WriteSLNHeader(std::ostream& fout);
   virtual void WriteSolutionConfigurations(std::ostream& fout);
-  virtual void WriteProjectConfigurations(std::ostream& fout,
-                                          const char* name,
-                                          bool partOfDefaultBuild,
-                                          const char* platformMapping = NULL);
+  virtual void WriteProjectConfigurations(
+    std::ostream& fout, const char* name,
+    const std::set<std::string>& configsPartOfDefaultBuild,
+    const char* platformMapping = NULL);
   virtual bool ComputeTargetDepends();
   virtual void WriteProjectDepends(std::ostream& fout, const char* name,
                                    const char* path, cmTarget &t);

+ 3 - 1
Source/cmSetTargetPropertiesCommand.h

@@ -156,7 +156,9 @@ public:
         "\n"
         "The EXCLUDE_FROM_DEFAULT_BUILD property is used by the visual "
         "studio generators.  If it is set to 1 the target will not be "
-        "part of the default build when you select \"Build Solution\"."
+        "part of the default build when you select \"Build Solution\". "
+        "This can also be set on a per-configuration basis using "
+        "EXCLUDE_FROM_DEFAULT_BUILD_<CONFIG>."
         ;
     }
 

+ 15 - 0
Source/cmTarget.cxx

@@ -265,6 +265,21 @@ void cmTarget::DefineProperties(cmake *cm)
      "whatever file extension is required by the host app for your "
      "bundle.");
 
+  cm->DefineProperty
+    ("EXCLUDE_FROM_DEFAULT_BUILD", cmProperty::TARGET,
+     "Exclude target from \"Build Solution\".",
+     "This property is only used by Visual Studio generators 7 and above. "
+     "When set to TRUE, the target will not be built when you press "
+     "\"Build Solution\".");
+
+  cm->DefineProperty
+    ("EXCLUDE_FROM_DEFAULT_BUILD_<CONFIG>", cmProperty::TARGET,
+     "Per-configuration version of target exclusion from \"Build Solution\". ",
+     "This is the configuration-specific version of "
+     "EXCLUDE_FROM_DEFAULT_BUILD. If the generic EXCLUDE_FROM_DEFAULT_BUILD "
+     "is also set on a target, EXCLUDE_FROM_DEFAULT_BUILD_<CONFIG> takes "
+     "precedence in configurations for which it has a value.");
+
   cm->DefineProperty
     ("FRAMEWORK", cmProperty::TARGET,
      "This target is a framework on the Mac.",

+ 29 - 0
Tests/CMakeLists.txt

@@ -1442,6 +1442,35 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
       --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
       --test-command VSMidl)
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSMidl")
+
+    if(NOT MSVC60 AND NOT CMAKE_TEST_MAKEPROGRAM MATCHES "[mM][sS][bB][uU][iI][lL][dD]\\.[eE][xX][eE]")
+      # The test (and tested property) works with .sln files, so it's skipped when:
+      # * Using VS6, which doesn't use .sln files
+      # * cmake --build is set up to use MSBuild, since the MSBuild invocation does not use the .sln file
+      set(_last_test "")
+      foreach(config ${CMAKE_CONFIGURATION_TYPES})
+        add_test(NAME VSExcludeFromDefaultBuild-${config} COMMAND ${CMAKE_CTEST_COMMAND}
+          --build-and-test
+          "${CMake_SOURCE_DIR}/Tests/VSExcludeFromDefaultBuild"
+          "${CMake_BINARY_DIR}/Tests/VSExcludeFromDefaultBuild"
+          --build-config ${config}
+          --build-two-config
+          --build-generator ${CMAKE_TEST_GENERATOR}
+          --build-project VSExcludeFromDefaultBuild
+          --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+          --test-command ${CMAKE_COMMAND}
+             -D "activeConfig=${config}"
+             -D "allConfigs=${CMAKE_CONFIGURATION_TYPES}"
+             -D "dir=${CMake_BINARY_DIR}/Tests/VSExcludeFromDefaultBuild"
+             -P "${CMake_SOURCE_DIR}/Tests/VSExcludeFromDefaultBuild/ResultTest.cmake")
+        if(_last_test)
+          set_property(TEST VSExcludeFromDefaultBuild-${config} PROPERTY DEPENDS ${_last_test})
+        endif()
+        set(_last_test "VSExcludeFromDefaultBuild-${config}")
+      endforeach()
+      unset(_last_test)
+      list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSExcludeFromDefaultBuild")
+    endif()
   endif()
 
   if (APPLE)

+ 32 - 0
Tests/VSExcludeFromDefaultBuild/CMakeLists.txt

@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 2.8.9)
+project(VSExcludeFromDefaultBuild)
+
+# First step is to clear all .exe files in output so that possible past
+# failures of this test do not prevent it from succeeding.
+add_custom_target(ClearExes ALL
+  COMMAND "${CMAKE_COMMAND}"
+    -Ddir=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
+    -P ${CMAKE_CURRENT_SOURCE_DIR}/ClearExes.cmake
+  VERBATIM)
+
+# Make sure ClearExes is executed before other targets are built
+function(add_test_executable target)
+  add_executable("${target}" ${ARGN})
+  add_dependencies("${target}" ClearExes)
+endfunction()
+
+add_test_executable(DefaultBuilt main.c)
+
+add_test_executable(AlwaysBuilt main.c)
+set_target_properties(AlwaysBuilt PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD FALSE)
+
+add_test_executable(NeverBuilt main.c)
+set_target_properties(NeverBuilt PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE)
+
+foreach(config ${CMAKE_CONFIGURATION_TYPES})
+  string(TOUPPER ${config} Config)
+  add_test_executable(BuiltIn${config} main.c)
+  set_target_properties(BuiltIn${config} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE EXCLUDE_FROM_DEFAULT_BUILD_${Config} FALSE)
+  add_test_executable(ExcludedIn${config} main.c)
+  set_target_properties(ExcludedIn${config} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD_${Config} TRUE)
+endforeach()

+ 4 - 0
Tests/VSExcludeFromDefaultBuild/ClearExes.cmake

@@ -0,0 +1,4 @@
+file(GLOB exeFiles "${dir}/*.exe")
+foreach(exeFile IN LISTS exeFiles)
+  file(REMOVE "${exeFile}")
+endforeach()

+ 23 - 0
Tests/VSExcludeFromDefaultBuild/ResultTest.cmake

@@ -0,0 +1,23 @@
+message(STATUS "Testing configuration ${activeConfig}.")
+
+macro(TestExists exeName)
+  set(exeFile "${dir}/${activeConfig}/${exeName}.exe")
+  if(${ARGN} EXISTS "${exeFile}")
+    message(STATUS "File ${exeFile} was correctly found ${ARGN} to exist.")
+  else()
+    message(FATAL_ERROR "File ${exeFile} was expected ${ARGN} to exist!")
+  endif()
+endmacro()
+
+TestExists(DefaultBuilt)
+TestExists(AlwaysBuilt)
+TestExists(NeverBuilt NOT)
+foreach(config ${allConfigs})
+  if(config STREQUAL activeConfig)
+    TestExists(BuiltIn${config})
+    TestExists(ExcludedIn${config} NOT)
+  else()
+    TestExists(BuiltIn${config} NOT)
+    TestExists(ExcludedIn${config})
+  endif()
+endforeach()

+ 4 - 0
Tests/VSExcludeFromDefaultBuild/main.c

@@ -0,0 +1,4 @@
+int main(void)
+{
+  return 0;
+}