Browse Source

install: Allow generator expressions in DIRECTORY DESTINATION

Robert Goulet 10 years ago
parent
commit
bd189cc24e

+ 4 - 0
Help/command/install.rst

@@ -271,6 +271,10 @@ will install the ``icons`` directory to ``share/myproj/icons`` and the
 file permissions, the scripts will be given specific permissions, and any
 ``CVS`` directories will be excluded.
 
+The install destination given to the directory install ``DESTINATION`` may
+use "generator expressions" with the syntax ``$<...>``.  See the
+:manual:`cmake-generator-expressions(7)` manual for available expressions.
+
 Custom Installation Logic
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 

+ 5 - 0
Help/release/dev/install-directory-dest-genex.rst

@@ -0,0 +1,5 @@
+install-directory-dest-genex
+----------------------------
+
+* The :command:`install(DIRECTORY)` command ``DESTINATION`` option learned to
+  support :manual:`generator expressions <cmake-generator-expressions(7)>`.

+ 46 - 1
Source/cmInstallDirectoryGenerator.cxx

@@ -12,6 +12,8 @@
 #include "cmInstallDirectoryGenerator.h"
 
 #include "cmTarget.h"
+#include "cmGeneratorExpression.h"
+#include "cmLocalGenerator.h"
 
 //----------------------------------------------------------------------------
 cmInstallDirectoryGenerator
@@ -25,10 +27,16 @@ cmInstallDirectoryGenerator
                               const char* literal_args,
                               bool optional):
   cmInstallGenerator(dest, configurations, component, message),
+  LocalGenerator(0),
   Directories(dirs),
   FilePermissions(file_permissions), DirPermissions(dir_permissions),
   LiteralArguments(literal_args), Optional(optional)
 {
+  // We need per-config actions if destination have generator expressions.
+  if(cmGeneratorExpression::Find(Destination) != std::string::npos)
+    {
+    this->ActionsPerConfig = true;
+    }
 }
 
 //----------------------------------------------------------------------------
@@ -37,15 +45,43 @@ cmInstallDirectoryGenerator
 {
 }
 
+void cmInstallDirectoryGenerator::Compute(cmLocalGenerator* lg)
+{
+  LocalGenerator = lg;
+}
+
 //----------------------------------------------------------------------------
 void
 cmInstallDirectoryGenerator::GenerateScriptActions(std::ostream& os,
                                                    Indent const& indent)
+{
+  if(this->ActionsPerConfig)
+    {
+    this->cmInstallGenerator::GenerateScriptActions(os, indent);
+    }
+  else
+    {
+    this->AddDirectoryInstallRule(os, "", indent);
+    }
+}
+
+void cmInstallDirectoryGenerator::GenerateScriptForConfig(
+  std::ostream& os,
+  const std::string& config,
+  Indent const& indent)
+{
+  this->AddDirectoryInstallRule(os, config, indent);
+}
+
+void cmInstallDirectoryGenerator::AddDirectoryInstallRule(
+  std::ostream& os,
+  const std::string& config,
+  Indent const& indent)
 {
   // Write code to install the directories.
   const char* no_rename = 0;
   this->AddInstallRule(os,
-                       this->Destination,
+                       this->GetDestination(config),
                        cmInstallType_DIRECTORY,
                        this->Directories,
                        this->Optional,
@@ -54,3 +90,12 @@ cmInstallDirectoryGenerator::GenerateScriptActions(std::ostream& os,
                        no_rename, this->LiteralArguments.c_str(),
                        indent);
 }
+
+//----------------------------------------------------------------------------
+std::string
+cmInstallDirectoryGenerator::GetDestination(std::string const& config) const
+{
+  cmGeneratorExpression ge;
+  return ge.Parse(this->Destination)
+    ->Evaluate(this->LocalGenerator->GetMakefile(), config);
+}

+ 11 - 0
Source/cmInstallDirectoryGenerator.h

@@ -31,8 +31,19 @@ public:
                               bool optional = false);
   virtual ~cmInstallDirectoryGenerator();
 
+  void Compute(cmLocalGenerator* lg);
+
+  std::string GetDestination(std::string const& config) const;
+
 protected:
   virtual void GenerateScriptActions(std::ostream& os, Indent const& indent);
+  virtual void GenerateScriptForConfig(std::ostream& os,
+                                       const std::string& config,
+                                       Indent const& indent);
+  void AddDirectoryInstallRule(std::ostream& os,
+                               const std::string& config,
+                               Indent const& indent);
+  cmLocalGenerator* LocalGenerator;
   std::vector<std::string> Directories;
   std::string FilePermissions;
   std::string DirPermissions;

+ 1 - 1
Tests/ExportImport/Export/CMakeLists.txt

@@ -551,5 +551,5 @@ install(
   ARCHIVE DESTINATION lib
   INCLUDES DESTINATION include/abs
   )
-install(DIRECTORY include/abs DESTINATION include)
+install(DIRECTORY include/abs DESTINATION $<1:include>$<0:/wrong>)
 install(EXPORT expAbs NAMESPACE expAbs_ DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/expAbs)

+ 1 - 0
Tests/RunCMake/install/DIRECTORY-DESTINATION-bad-result.txt

@@ -0,0 +1 @@
+1

+ 6 - 0
Tests/RunCMake/install/DIRECTORY-DESTINATION-bad-stderr.txt

@@ -0,0 +1,6 @@
+CMake Error:
+  Error evaluating generator expression:
+
+    \$<NOTAGENEX>
+
+  Expression did not evaluate to a known generator expression

+ 1 - 0
Tests/RunCMake/install/DIRECTORY-DESTINATION-bad.cmake

@@ -0,0 +1 @@
+install(DIRECTORY dir DESTINATION $<NOTAGENEX>)

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

@@ -6,6 +6,7 @@ run_cmake(DIRECTORY-message-lazy)
 run_cmake(SkipInstallRulesWarning)
 run_cmake(SkipInstallRulesNoWarning1)
 run_cmake(SkipInstallRulesNoWarning2)
+run_cmake(DIRECTORY-DESTINATION-bad)
 run_cmake(FILES-DESTINATION-bad)
 run_cmake(TARGETS-DESTINATION-bad)
 run_cmake(CMP0062-OLD)

+ 3 - 3
Tests/SimpleInstall/CMakeLists.txt

@@ -252,7 +252,7 @@ else()
   file(REMOVE_RECURSE "${CMAKE_INSTALL_PREFIX}/MyTest/share/CVS")
   file(REMOVE_RECURSE "${CMAKE_INSTALL_PREFIX}/MyTest/share/TestSubDir/CVS")
   install(
-    DIRECTORY TestSubDir scripts/ DESTINATION MyTest/share
+    DIRECTORY TestSubDir scripts/ DESTINATION $<1:MyTest/share>$<0:/wrong>
     FILE_PERMISSIONS OWNER_READ OWNER_WRITE
     DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
                           GROUP_READ GROUP_EXECUTE
@@ -263,14 +263,14 @@ else()
 
   # Alternate directory installation for coverage.
   install(
-    DIRECTORY scripts/ DESTINATION MyTest/share/alt
+    DIRECTORY scripts/ DESTINATION $<1:MyTest/share/alt>$<0:/wrong>
     COMPONENT Development
     USE_SOURCE_PERMISSIONS
     PATTERN "CVS" EXCLUDE
     REGEX "\\.txt$" EXCLUDE
     )
   install(
-    DIRECTORY TestSubDir DESTINATION MyTest/share/alt
+    DIRECTORY TestSubDir DESTINATION $<1:MyTest/share/alt>$<0:/wrong>
     FILE_PERMISSIONS OWNER_READ OWNER_WRITE
     DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
                           GROUP_READ GROUP_EXECUTE

+ 3 - 3
Tests/SimpleInstallS2/CMakeLists.txt

@@ -252,7 +252,7 @@ else()
   file(REMOVE_RECURSE "${CMAKE_INSTALL_PREFIX}/MyTest/share/CVS")
   file(REMOVE_RECURSE "${CMAKE_INSTALL_PREFIX}/MyTest/share/TestSubDir/CVS")
   install(
-    DIRECTORY TestSubDir scripts/ DESTINATION MyTest/share
+    DIRECTORY TestSubDir scripts/ DESTINATION $<1:MyTest/share>$<0:/wrong>
     FILE_PERMISSIONS OWNER_READ OWNER_WRITE
     DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
                           GROUP_READ GROUP_EXECUTE
@@ -263,14 +263,14 @@ else()
 
   # Alternate directory installation for coverage.
   install(
-    DIRECTORY scripts/ DESTINATION MyTest/share/alt
+    DIRECTORY scripts/ DESTINATION $<1:MyTest/share/alt>$<0:/wrong>
     COMPONENT Development
     USE_SOURCE_PERMISSIONS
     PATTERN "CVS" EXCLUDE
     REGEX "\\.txt$" EXCLUDE
     )
   install(
-    DIRECTORY TestSubDir DESTINATION MyTest/share/alt
+    DIRECTORY TestSubDir DESTINATION $<1:MyTest/share/alt>$<0:/wrong>
     FILE_PERMISSIONS OWNER_READ OWNER_WRITE
     DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
                           GROUP_READ GROUP_EXECUTE