Browse Source

Merge topic 'install-EXCLUDE_FROM_ALL'

586e56d0 Help: Add notes for topic 'install-EXCLUDE_FROM_ALL'
d321c196 Tests: Add cases for install() command EXCLUDE_FROM_ALL option
18ce97c4 install: Add EXCLUDE_FROM_ALL option (#14921)
Brad King 10 years ago
parent
commit
3b8c0fbfd7
30 changed files with 178 additions and 41 deletions
  1. 15 8
      Help/command/install.rst
  2. 5 0
      Help/release/dev/install-EXCLUDE_FROM_ALL.rst
  3. 27 4
      Source/cmInstallCommand.cxx
  4. 22 8
      Source/cmInstallCommandArguments.cxx
  5. 2 0
      Source/cmInstallCommandArguments.h
  6. 3 1
      Source/cmInstallDirectoryGenerator.cxx
  7. 1 0
      Source/cmInstallDirectoryGenerator.h
  8. 3 1
      Source/cmInstallExportGenerator.cxx
  9. 1 0
      Source/cmInstallExportGenerator.h
  10. 3 1
      Source/cmInstallFilesCommand.cxx
  11. 3 1
      Source/cmInstallFilesGenerator.cxx
  12. 1 0
      Source/cmInstallFilesGenerator.h
  13. 12 6
      Source/cmInstallGenerator.cxx
  14. 5 2
      Source/cmInstallGenerator.h
  15. 3 1
      Source/cmInstallProgramsCommand.cxx
  16. 4 3
      Source/cmInstallScriptGenerator.cxx
  17. 1 1
      Source/cmInstallScriptGenerator.h
  18. 3 1
      Source/cmInstallTargetGenerator.cxx
  19. 1 0
      Source/cmInstallTargetGenerator.h
  20. 3 3
      Source/cmLocalGenerator.cxx
  21. 1 0
      Tests/RunCMake/install/FILES-EXCLUDE_FROM_ALL-all-check.cmake
  22. 1 0
      Tests/RunCMake/install/FILES-EXCLUDE_FROM_ALL-exc-check.cmake
  23. 1 0
      Tests/RunCMake/install/FILES-EXCLUDE_FROM_ALL-uns-check.cmake
  24. 3 0
      Tests/RunCMake/install/FILES-EXCLUDE_FROM_ALL.cmake
  25. 45 0
      Tests/RunCMake/install/RunCMakeTest.cmake
  26. 1 0
      Tests/RunCMake/install/TARGETS-EXCLUDE_FROM_ALL-all-check.cmake
  27. 1 0
      Tests/RunCMake/install/TARGETS-EXCLUDE_FROM_ALL-exc-check.cmake
  28. 1 0
      Tests/RunCMake/install/TARGETS-EXCLUDE_FROM_ALL-uns-check.cmake
  29. 5 0
      Tests/RunCMake/install/TARGETS-EXCLUDE_FROM_ALL.cmake
  30. 1 0
      Tests/RunCMake/install/main.c

+ 15 - 8
Help/command/install.rst

@@ -45,11 +45,15 @@ signatures that specify them.  The common options are:
   is associated, such as "runtime" or "development".  During
   component-specific installation only install rules associated with
   the given component name will be executed.  During a full installation
-  all components are installed.  If ``COMPONENT`` is not provided a
-  default component "Unspecified" is created.  The default component
-  name may be controlled with the
+  all components are installed unless marked with ``EXCLUDE_FROM_ALL``.
+  If ``COMPONENT`` is not provided a default component "Unspecified" is
+  created.  The default component name may be controlled with the
   :variable:`CMAKE_INSTALL_DEFAULT_COMPONENT_NAME` variable.
 
+``EXCLUDE_FROM_ALL``
+  Specify that the file is excluded from a full installation and only
+  installed as part of a component-specific installation
+
 ``RENAME``
   Specify a name for an installed file that may be different from the
   original file.  Renaming is allowed only when a single file is
@@ -76,7 +80,8 @@ Installing Targets
            [PERMISSIONS permissions...]
            [CONFIGURATIONS [Debug|Release|...]]
            [COMPONENT <component>]
-           [OPTIONAL] [NAMELINK_ONLY|NAMELINK_SKIP]
+           [OPTIONAL] [EXCLUDE_FROM_ALL]
+           [NAMELINK_ONLY|NAMELINK_SKIP]
           ] [...])
 
 The ``TARGETS`` form specifies rules for installing targets from a
@@ -172,7 +177,7 @@ Installing Files
           [PERMISSIONS permissions...]
           [CONFIGURATIONS [Debug|Release|...]]
           [COMPONENT <component>]
-          [RENAME <name>] [OPTIONAL])
+          [RENAME <name>] [OPTIONAL] [EXCLUDE_FROM_ALL])
 
 The ``FILES`` form specifies rules for installing files for a project.
 File names given as relative paths are interpreted with respect to the
@@ -206,7 +211,8 @@ Installing Directories
           [DIRECTORY_PERMISSIONS permissions...]
           [USE_SOURCE_PERMISSIONS] [OPTIONAL] [MESSAGE_NEVER]
           [CONFIGURATIONS [Debug|Release|...]]
-          [COMPONENT <component>] [FILES_MATCHING]
+          [COMPONENT <component>] [EXCLUDE_FROM_ALL]
+          [FILES_MATCHING]
           [[PATTERN <pattern> | REGEX <regex>]
            [EXCLUDE] [PERMISSIONS permissions...]] [...])
 
@@ -282,7 +288,7 @@ Custom Installation Logic
 ::
 
   install([[SCRIPT <file>] [CODE <code>]]
-          [COMPONENT <component>] [...])
+          [COMPONENT <component>] [EXCLUDE_FROM_ALL] [...])
 
 The ``SCRIPT`` form will invoke the given CMake script files during
 installation.  If the script file name is a relative path it will be
@@ -307,7 +313,8 @@ Installing Exports
           [PERMISSIONS permissions...]
           [CONFIGURATIONS [Debug|Release|...]]
           [EXPORT_LINK_INTERFACE_LIBRARIES]
-          [COMPONENT <component>])
+          [COMPONENT <component>]
+          [EXCLUDE_FROM_ALL])
 
 The ``EXPORT`` form generates and installs a CMake file containing code to
 import targets from the installation tree into another project.

+ 5 - 0
Help/release/dev/install-EXCLUDE_FROM_ALL.rst

@@ -0,0 +1,5 @@
+install-EXCLUDE_FROM_ALL
+------------------------
+
+* The :command:`install` command learned a new ``EXCLUDE_FROM_ALL`` option
+  to leave installation rules out of the default installation.

+ 27 - 4
Source/cmInstallCommand.cxx

@@ -33,6 +33,7 @@ static cmInstallTargetGenerator* CreateInstallTargetGenerator(cmTarget& target,
                         impLib, args.GetPermissions().c_str(),
                         args.GetConfigurations(), args.GetComponent().c_str(),
                         message,
+                        args.GetExcludeFromAll(),
                         args.GetOptional() || forceOpt);
 }
 
@@ -48,7 +49,8 @@ static cmInstallFilesGenerator* CreateInstallFilesGenerator(
                         programs, args.GetPermissions().c_str(),
                         args.GetConfigurations(), args.GetComponent().c_str(),
                         message,
-                        args.GetRename().c_str(), args.GetOptional());
+                        args.GetExcludeFromAll(), args.GetRename().c_str(),
+                        args.GetOptional());
 }
 
 
@@ -117,6 +119,7 @@ bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args)
   int componentCount = 0;
   bool doing_script = false;
   bool doing_code = false;
+  bool exclude_from_all = false;
 
   // Scan the args once for COMPONENT. Only allow one.
   //
@@ -128,6 +131,10 @@ bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args)
         ++i;
         component = args[i];
         }
+    if(args[i] == "EXCLUDE_FROM_ALL")
+      {
+      exclude_from_all = true;
+      }
     }
 
   if(componentCount>1)
@@ -175,7 +182,7 @@ bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args)
         }
       this->Makefile->AddInstallGenerator(
         new cmInstallScriptGenerator(script.c_str(), false,
-                                     component.c_str()));
+                                     component.c_str(), exclude_from_all));
       }
     else if(doing_code)
       {
@@ -183,7 +190,7 @@ bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args)
       std::string code = args[i];
       this->Makefile->AddInstallGenerator(
         new cmInstallScriptGenerator(code.c_str(), true,
-                                     component.c_str()));
+                                     component.c_str(), exclude_from_all));
       }
     }
 
@@ -949,6 +956,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
   Doing doing = DoingDirs;
   bool in_match_mode = false;
   bool optional = false;
+  bool exclude_from_all = false;
   bool message_never = false;
   std::vector<std::string> dirs;
   const char* destination = 0;
@@ -1130,6 +1138,19 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
       // Switch to setting the component property.
       doing = DoingComponent;
       }
+    else if(args[i] == "EXCLUDE_FROM_ALL")
+      {
+      if(in_match_mode)
+        {
+        std::ostringstream e;
+        e << args[0] << " does not allow \""
+          << args[i] << "\" after PATTERN or REGEX.";
+        this->SetError(e.str().c_str());
+        return false;
+        }
+      exclude_from_all = true;
+      doing = DoingNone;
+      }
     else if(doing == DoingDirs)
       {
       // Convert this directory to a full path.
@@ -1273,6 +1294,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
                                     configurations,
                                     component.c_str(),
                                     message,
+                                    exclude_from_all,
                                     literal_args.c_str(),
                                     optional));
 
@@ -1403,7 +1425,8 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
       exportSet,
       ica.GetDestination().c_str(),
       ica.GetPermissions().c_str(), ica.GetConfigurations(),
-      ica.GetComponent().c_str(), message, fname.c_str(),
+      ica.GetComponent().c_str(), message,
+      ica.GetExcludeFromAll(), fname.c_str(),
       name_space.GetCString(), exportOld.IsEnabled());
   this->Makefile->AddInstallGenerator(exportGenerator);
 

+ 22 - 8
Source/cmInstallCommandArguments.cxx

@@ -27,14 +27,15 @@ cmInstallCommandArguments::cmInstallCommandArguments(
                                            const std::string& defaultComponent)
 :Parser()
 ,ArgumentGroup()
-,Destination   (&Parser, "DESTINATION"   , &ArgumentGroup)
-,Component     (&Parser, "COMPONENT"     , &ArgumentGroup)
-,Rename        (&Parser, "RENAME"        , &ArgumentGroup)
-,Permissions   (&Parser, "PERMISSIONS"   , &ArgumentGroup)
-,Configurations(&Parser, "CONFIGURATIONS", &ArgumentGroup)
-,Optional      (&Parser, "OPTIONAL"      , &ArgumentGroup)
-,NamelinkOnly  (&Parser, "NAMELINK_ONLY" , &ArgumentGroup)
-,NamelinkSkip  (&Parser, "NAMELINK_SKIP" , &ArgumentGroup)
+,Destination   (&Parser, "DESTINATION"     , &ArgumentGroup)
+,Component     (&Parser, "COMPONENT"       , &ArgumentGroup)
+,ExcludeFromAll(&Parser, "EXCLUDE_FROM_ALL", &ArgumentGroup)
+,Rename        (&Parser, "RENAME"          , &ArgumentGroup)
+,Permissions   (&Parser, "PERMISSIONS"     , &ArgumentGroup)
+,Configurations(&Parser, "CONFIGURATIONS"  , &ArgumentGroup)
+,Optional      (&Parser, "OPTIONAL"        , &ArgumentGroup)
+,NamelinkOnly  (&Parser, "NAMELINK_ONLY"   , &ArgumentGroup)
+,NamelinkSkip  (&Parser, "NAMELINK_SKIP"   , &ArgumentGroup)
 ,GenericArguments(0)
 ,DefaultComponentName(defaultComponent)
 {
@@ -110,6 +111,19 @@ bool cmInstallCommandArguments::GetOptional() const
   return false;
 }
 
+bool cmInstallCommandArguments::GetExcludeFromAll() const
+{
+  if (this->ExcludeFromAll.IsEnabled())
+    {
+    return true;
+    }
+  if (this->GenericArguments!=0)
+    {
+    return this->GenericArguments->GetExcludeFromAll();
+    }
+  return false;
+}
+
 bool cmInstallCommandArguments::GetNamelinkOnly() const
 {
   if (this->NamelinkOnly.IsEnabled())

+ 2 - 0
Source/cmInstallCommandArguments.h

@@ -30,6 +30,7 @@ class cmInstallCommandArguments
 
     const std::string& GetDestination() const;
     const std::string& GetComponent() const;
+    bool GetExcludeFromAll() const;
     const std::string& GetRename() const;
     const std::string& GetPermissions() const;
     const std::vector<std::string>& GetConfigurations() const;
@@ -48,6 +49,7 @@ class cmInstallCommandArguments
     cmInstallCommandArguments(); // disabled
     cmCAString Destination;
     cmCAString Component;
+    cmCAEnabler ExcludeFromAll;
     cmCAString Rename;
     cmCAStringVector Permissions;
     cmCAStringVector Configurations;

+ 3 - 1
Source/cmInstallDirectoryGenerator.cxx

@@ -23,9 +23,11 @@ cmInstallDirectoryGenerator
                               std::vector<std::string> const& configurations,
                               const char* component,
                               MessageLevel message,
+                              bool exclude_from_all,
                               const char* literal_args,
                               bool optional):
-  cmInstallGenerator(dest, configurations, component, message),
+  cmInstallGenerator(dest, configurations, component, message,
+                     exclude_from_all),
   LocalGenerator(0),
   Directories(dirs),
   FilePermissions(file_permissions), DirPermissions(dir_permissions),

+ 1 - 0
Source/cmInstallDirectoryGenerator.h

@@ -27,6 +27,7 @@ public:
                               std::vector<std::string> const& configurations,
                               const char* component,
                               MessageLevel message,
+                              bool exclude_from_all,
                               const char* literal_args,
                               bool optional = false);
   virtual ~cmInstallDirectoryGenerator();

+ 3 - 1
Source/cmInstallExportGenerator.cxx

@@ -33,9 +33,11 @@ cmInstallExportGenerator::cmInstallExportGenerator(
   std::vector<std::string> const& configurations,
   const char* component,
   MessageLevel message,
+  bool exclude_from_all,
   const char* filename, const char* name_space,
   bool exportOld)
-  :cmInstallGenerator(destination, configurations, component, message)
+  :cmInstallGenerator(destination, configurations, component, message,
+                      exclude_from_all)
   ,ExportSet(exportSet)
   ,FilePermissions(file_permissions)
   ,FileName(filename)

+ 1 - 0
Source/cmInstallExportGenerator.h

@@ -31,6 +31,7 @@ public:
                            const std::vector<std::string>& configurations,
                            const char* component,
                            MessageLevel message,
+                           bool exclude_from_all,
                            const char* filename, const char* name_space,
                            bool exportOld);
   ~cmInstallExportGenerator();

+ 3 - 1
Source/cmInstallFilesCommand.cxx

@@ -122,6 +122,7 @@ void cmInstallFilesCommand::CreateInstallGenerator() const
   // Use a file install generator.
   const char* no_permissions = "";
   const char* no_rename = "";
+  bool no_exclude_from_all = false;
   std::string no_component = this->Makefile->GetSafeDefinition(
                                        "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
   std::vector<std::string> no_configurations;
@@ -131,7 +132,8 @@ void cmInstallFilesCommand::CreateInstallGenerator() const
     new cmInstallFilesGenerator(this->Files,
                                 destination.c_str(), false,
                                 no_permissions, no_configurations,
-                                no_component.c_str(), message, no_rename));
+                                no_component.c_str(), message,
+                                no_exclude_from_all, no_rename));
 }
 
 

+ 3 - 1
Source/cmInstallFilesGenerator.cxx

@@ -24,9 +24,11 @@ cmInstallFilesGenerator
                           std::vector<std::string> const& configurations,
                           const char* component,
                           MessageLevel message,
+                          bool exclude_from_all,
                           const char* rename,
                           bool optional):
-  cmInstallGenerator(dest, configurations, component, message),
+  cmInstallGenerator(dest, configurations, component, message,
+                     exclude_from_all),
   LocalGenerator(0),
   Files(files),
   FilePermissions(file_permissions),

+ 1 - 0
Source/cmInstallFilesGenerator.h

@@ -26,6 +26,7 @@ public:
                           std::vector<std::string> const& configurations,
                           const char* component,
                           MessageLevel message,
+                          bool exclude_from_all,
                           const char* rename,
                           bool optional = false);
   virtual ~cmInstallFilesGenerator();

+ 12 - 6
Source/cmInstallGenerator.cxx

@@ -19,11 +19,13 @@ cmInstallGenerator
 ::cmInstallGenerator(const char* destination,
                      std::vector<std::string> const& configurations,
                      const char* component,
-                     MessageLevel message):
+                     MessageLevel message,
+                     bool exclude_from_all):
   cmScriptGenerator("CMAKE_INSTALL_CONFIG_NAME", configurations),
   Destination(destination? destination:""),
   Component(component? component:""),
-  Message(message)
+  Message(message),
+  ExcludeFromAll(exclude_from_all)
 {
 }
 
@@ -146,12 +148,16 @@ void cmInstallGenerator
 
 //----------------------------------------------------------------------------
 std::string
-cmInstallGenerator::CreateComponentTest(const char* component)
+cmInstallGenerator::CreateComponentTest(const char* component,
+                                        bool exclude_from_all)
 {
-  std::string result = "NOT CMAKE_INSTALL_COMPONENT OR "
-    "\"${CMAKE_INSTALL_COMPONENT}\" STREQUAL \"";
+  std::string result = "\"${CMAKE_INSTALL_COMPONENT}\" STREQUAL \"";
   result += component;
   result += "\"";
+  if(!exclude_from_all)
+    {
+    result += " OR NOT CMAKE_INSTALL_COMPONENT";
+    }
   return result;
 }
 
@@ -163,7 +169,7 @@ void cmInstallGenerator::GenerateScript(std::ostream& os)
 
   // Begin this block of installation.
   std::string component_test =
-    this->CreateComponentTest(this->Component.c_str());
+    this->CreateComponentTest(this->Component.c_str(),this->ExcludeFromAll);
   os << indent << "if(" << component_test << ")\n";
 
   // Generate the script possibly with per-configuration code.

+ 5 - 2
Source/cmInstallGenerator.h

@@ -36,7 +36,8 @@ public:
   cmInstallGenerator(const char* destination,
                      std::vector<std::string> const& configurations,
                      const char* component,
-                     MessageLevel message);
+                     MessageLevel message,
+                     bool exclude_from_all);
   virtual ~cmInstallGenerator();
 
   void AddInstallRule(
@@ -67,12 +68,14 @@ public:
 protected:
   virtual void GenerateScript(std::ostream& os);
 
-  std::string CreateComponentTest(const char* component);
+  std::string CreateComponentTest(const char* component,
+                                  bool exclude_from_all);
 
   // Information shared by most generator types.
   std::string Destination;
   std::string Component;
   MessageLevel Message;
+  bool ExcludeFromAll;
 };
 
 #endif

+ 3 - 1
Source/cmInstallProgramsCommand.cxx

@@ -85,6 +85,7 @@ void cmInstallProgramsCommand::FinalPass()
   // Use a file install generator.
   const char* no_permissions = "";
   const char* no_rename = "";
+  bool no_exclude_from_all = false;
   std::string no_component = this->Makefile->GetSafeDefinition(
                                        "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
   std::vector<std::string> no_configurations;
@@ -94,7 +95,8 @@ void cmInstallProgramsCommand::FinalPass()
     new cmInstallFilesGenerator(this->Files,
                                 destination.c_str(), true,
                                 no_permissions, no_configurations,
-                                no_component.c_str(), message, no_rename));
+                                no_component.c_str(), message,
+                                no_exclude_from_all, no_rename));
 }
 
 /**

+ 4 - 3
Source/cmInstallScriptGenerator.cxx

@@ -14,8 +14,9 @@
 //----------------------------------------------------------------------------
 cmInstallScriptGenerator
 ::cmInstallScriptGenerator(const char* script, bool code,
-                           const char* component) :
-  cmInstallGenerator(0, std::vector<std::string>(), component, MessageDefault),
+                           const char* component, bool exclude_from_all) :
+  cmInstallGenerator(0, std::vector<std::string>(), component, MessageDefault,
+                     exclude_from_all),
   Script(script), Code(code)
 {
 }
@@ -31,7 +32,7 @@ void cmInstallScriptGenerator::GenerateScript(std::ostream& os)
 {
   Indent indent;
   std::string component_test =
-    this->CreateComponentTest(this->Component.c_str());
+    this->CreateComponentTest(this->Component.c_str(), this->ExcludeFromAll);
   os << indent << "if(" << component_test << ")\n";
 
   if(this->Code)

+ 1 - 1
Source/cmInstallScriptGenerator.h

@@ -21,7 +21,7 @@ class cmInstallScriptGenerator: public cmInstallGenerator
 {
 public:
   cmInstallScriptGenerator(const char* script, bool code,
-    const char* component);
+    const char* component, bool exclude_from_all);
   virtual ~cmInstallScriptGenerator();
 
 protected:

+ 3 - 1
Source/cmInstallTargetGenerator.cxx

@@ -30,8 +30,10 @@ cmInstallTargetGenerator
                            std::vector<std::string> const& configurations,
                            const char* component,
                            MessageLevel message,
+                           bool exclude_from_all,
                            bool optional):
-  cmInstallGenerator(dest, configurations, component, message),
+  cmInstallGenerator(dest, configurations, component, message,
+                     exclude_from_all),
   TargetName(targetName),
   Target(0),
   FilePermissions(file_permissions),

+ 1 - 0
Source/cmInstallTargetGenerator.h

@@ -28,6 +28,7 @@ public:
     std::vector<std::string> const& configurations,
     const char* component,
     MessageLevel message,
+    bool exclude_from_all,
     bool optional
     );
   virtual ~cmInstallTargetGenerator();

+ 3 - 3
Source/cmLocalGenerator.cxx

@@ -2557,7 +2557,7 @@ public:
     cmInstallTargetGenerator(
       t, dest, implib, "", std::vector<std::string>(), "Unspecified",
       cmInstallGenerator::SelectMessageLevel(lg->GetMakefile()),
-      false)
+      false, false)
   {
     this->Compute(lg);
   }
@@ -2584,7 +2584,7 @@ cmLocalGenerator
     // Include the user-specified pre-install script for this target.
     if(const char* preinstall = (*l)->GetProperty("PRE_INSTALL_SCRIPT"))
       {
-      cmInstallScriptGenerator g(preinstall, false, 0);
+      cmInstallScriptGenerator g(preinstall, false, 0, false);
       g.Generate(os, config, configurationTypes);
       }
 
@@ -2645,7 +2645,7 @@ cmLocalGenerator
     // Include the user-specified post-install script for this target.
     if(const char* postinstall = (*l)->GetProperty("POST_INSTALL_SCRIPT"))
       {
-      cmInstallScriptGenerator g(postinstall, false, 0);
+      cmInstallScriptGenerator g(postinstall, false, 0, false);
       g.Generate(os, config, configurationTypes);
       }
     }

+ 1 - 0
Tests/RunCMake/install/FILES-EXCLUDE_FROM_ALL-all-check.cmake

@@ -0,0 +1 @@
+check_installed([[^src-all;src-all/main\.c$]])

+ 1 - 0
Tests/RunCMake/install/FILES-EXCLUDE_FROM_ALL-exc-check.cmake

@@ -0,0 +1 @@
+check_installed([[^src-exc;src-exc/main\.c$]])

+ 1 - 0
Tests/RunCMake/install/FILES-EXCLUDE_FROM_ALL-uns-check.cmake

@@ -0,0 +1 @@
+check_installed([[^src-all;src-all/main\.c;src-uns;src-uns/main\.c$]])

+ 3 - 0
Tests/RunCMake/install/FILES-EXCLUDE_FROM_ALL.cmake

@@ -0,0 +1,3 @@
+install(FILES main.c DESTINATION src-all)
+install(FILES main.c DESTINATION src-uns EXCLUDE_FROM_ALL)
+install(FILES main.c DESTINATION src-exc EXCLUDE_FROM_ALL COMPONENT exc)

+ 45 - 0
Tests/RunCMake/install/RunCMakeTest.cmake

@@ -1,4 +1,46 @@
+cmake_minimum_required(VERSION 3.4)
 include(RunCMake)
+
+# Function to build and install a project.  The latter step *-check.cmake
+# scripts can check installed files using the check_installed function.
+function(run_install_test case)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  run_cmake(${case})
+  run_cmake_command(${case}-build ${CMAKE_COMMAND} --build . --config Debug)
+  # Check "all" components.
+  set(CMAKE_INSTALL_PREFIX ${RunCMake_TEST_BINARY_DIR}/root-all)
+  run_cmake_command(${case}-all ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DBUILD_TYPE=Debug -P cmake_install.cmake)
+  # Check unspecified component.
+  set(CMAKE_INSTALL_PREFIX ${RunCMake_TEST_BINARY_DIR}/root-uns)
+  run_cmake_command(${case}-uns ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DBUILD_TYPE=Debug -DCOMPONENT=Unspecified -P cmake_install.cmake)
+  # Check explicit component.
+  set(CMAKE_INSTALL_PREFIX ${RunCMake_TEST_BINARY_DIR}/root-exc)
+  run_cmake_command(${case}-exc ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DBUILD_TYPE=Debug -DCOMPONENT=exc -P cmake_install.cmake)
+endfunction()
+
+# Function called in *-check.cmake scripts to check installed files.
+function(check_installed expect)
+  file(GLOB_RECURSE actual
+    LIST_DIRECTORIES TRUE
+    RELATIVE ${CMAKE_INSTALL_PREFIX}
+    ${CMAKE_INSTALL_PREFIX}/*
+    )
+  if(actual)
+    list(SORT actual)
+  endif()
+  if(NOT "${actual}" MATCHES "${expect}")
+    set(RunCMake_TEST_FAILED "Installed files:
+  ${actual}
+do not match what we expected:
+  ${expect}
+in directory:
+  ${CMAKE_INSTALL_PREFIX}" PARENT_SCOPE)
+  endif()
+endfunction()
+
 run_cmake(DIRECTORY-MESSAGE_NEVER)
 run_cmake(DIRECTORY-PATTERN-MESSAGE_NEVER)
 run_cmake(DIRECTORY-message)
@@ -14,3 +56,6 @@ run_cmake(EXPORT-OldIFace)
 run_cmake(CMP0062-OLD)
 run_cmake(CMP0062-NEW)
 run_cmake(CMP0062-WARN)
+
+run_install_test(FILES-EXCLUDE_FROM_ALL)
+run_install_test(TARGETS-EXCLUDE_FROM_ALL)

+ 1 - 0
Tests/RunCMake/install/TARGETS-EXCLUDE_FROM_ALL-all-check.cmake

@@ -0,0 +1 @@
+check_installed([[^bin-all;bin-all/myexe(\.exe)?$]])

+ 1 - 0
Tests/RunCMake/install/TARGETS-EXCLUDE_FROM_ALL-exc-check.cmake

@@ -0,0 +1 @@
+check_installed([[^bin-exc;bin-exc/myexe(\.exe)?$]])

+ 1 - 0
Tests/RunCMake/install/TARGETS-EXCLUDE_FROM_ALL-uns-check.cmake

@@ -0,0 +1 @@
+check_installed([[^bin-all;bin-all/myexe(\.exe)?;bin-uns;bin-uns/myexe(\.exe)?$]])

+ 5 - 0
Tests/RunCMake/install/TARGETS-EXCLUDE_FROM_ALL.cmake

@@ -0,0 +1,5 @@
+enable_language(C)
+add_executable(myexe main.c)
+install(TARGETS myexe DESTINATION bin-all)
+install(TARGETS myexe DESTINATION bin-uns EXCLUDE_FROM_ALL)
+install(TARGETS myexe DESTINATION bin-exc EXCLUDE_FROM_ALL COMPONENT exc)

+ 1 - 0
Tests/RunCMake/install/main.c

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