Browse Source

Add the INSTALL_PREFIX genex.

Stephen Kelly 12 years ago
parent
commit
34d1ade048

+ 2 - 0
Source/cmDocumentGeneratorExpressions.h

@@ -55,6 +55,8 @@
   "the 'head' target was created, else '0'.  If the policy was not "    \
   "set, the warning message for the policy will be emitted.  This "     \
   "generator expression only works for a subset of policies.\n"         \
+  "  $<INSTALL_PREFIX>         = Content of the install prefix when "   \
+  "the target is exported via INSTALL(EXPORT) and empty otherwise.\n"   \
   "Boolean expressions:\n"                                              \
   "  $<AND:?[,?]...>           = '1' if all '?' are '1', else '0'\n"    \
   "  $<OR:?[,?]...>            = '0' if all '?' are '0', else '1'\n"    \

+ 10 - 0
Source/cmExportFileGenerator.cxx

@@ -431,12 +431,22 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
     input.replace(pos, endPos - pos + 1, targetName);
     lastPos = endPos;
     }
+
+  this->ReplaceInstallPrefix(input);
+
   if (!errorString.empty())
     {
     mf->IssueMessage(cmake::FATAL_ERROR, errorString);
     }
 }
 
+//----------------------------------------------------------------------------
+void
+cmExportFileGenerator::ReplaceInstallPrefix(std::string &)
+{
+  // Do nothing
+}
+
 //----------------------------------------------------------------------------
 void
 cmExportFileGenerator

+ 2 - 0
Source/cmExportFileGenerator.h

@@ -152,6 +152,8 @@ private:
   void ResolveTargetsInGeneratorExpression(std::string &input,
                                     cmTarget* target,
                                     std::vector<std::string> &missingTargets);
+
+  virtual void ReplaceInstallPrefix(std::string &input);
 };
 
 #endif

+ 15 - 0
Source/cmExportInstallFileGenerator.cxx

@@ -154,6 +154,21 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
   return result;
 }
 
+//----------------------------------------------------------------------------
+void
+cmExportInstallFileGenerator::ReplaceInstallPrefix(std::string &input)
+{
+  std::string::size_type pos = 0;
+  std::string::size_type lastPos = pos;
+
+  while((pos = input.find("$<INSTALL_PREFIX>", lastPos)) != input.npos)
+    {
+    std::string::size_type endPos = pos + sizeof("$<INSTALL_PREFIX>") - 1;
+    input.replace(pos, endPos - pos, "${_IMPORT_PREFIX}");
+    lastPos = endPos;
+    }
+}
+
 //----------------------------------------------------------------------------
 bool
 cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config,

+ 2 - 0
Source/cmExportInstallFileGenerator.h

@@ -64,6 +64,8 @@ protected:
                                    cmTarget* depender,
                                    cmTarget* dependee);
 
+  virtual void ReplaceInstallPrefix(std::string &input);
+
   void ComplainAboutMissingTarget(cmTarget* depender,
                                   cmTarget* dependee,
                                   int occurrences);

+ 20 - 0
Source/cmGeneratorExpressionEvaluator.cxx

@@ -614,6 +614,24 @@ static const struct TargetPolicyNode : public cmGeneratorExpressionNode
 
 } targetPolicyNode;
 
+//----------------------------------------------------------------------------
+static const struct InstallPrefixNode : public cmGeneratorExpressionNode
+{
+  InstallPrefixNode() {}
+
+  virtual bool GeneratesContent() const { return false; }
+  virtual int NumExpectedParameters() const { return 0; }
+
+  std::string Evaluate(const std::vector<std::string> &,
+                       cmGeneratorExpressionContext *,
+                       const GeneratorExpressionContent *,
+                       cmGeneratorExpressionDAGChecker *) const
+  {
+    return std::string();
+  }
+
+} installPrefixNode;
+
 //----------------------------------------------------------------------------
 template<bool linker, bool soname>
 struct TargetFilesystemArtifactResultCreator
@@ -849,6 +867,8 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
     return &installInterfaceNode;
   else if (identifier == "TARGET_DEFINED")
     return &targetDefinedNode;
+  else if (identifier == "INSTALL_PREFIX")
+    return &installPrefixNode;
   return 0;
 
 }

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

@@ -113,9 +113,16 @@ macro(add_include_lib _libName)
   add_library(${_libName} "${CMAKE_CURRENT_BINARY_DIR}/${_libName}.c")
   file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_libName}")
   set_property(TARGET ${_libName} APPEND PROPERTY
-      INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/${_libName}")
+      INTERFACE_INCLUDE_DIRECTORIES
+        "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/${_libName}>"
+        "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/${_libName}>"
+      )
   if (NOT "${ARGV1}" STREQUAL "NO_HEADER")
       file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_libName}/${_libName}.h" "// no content\n")
+      install(FILES
+        "${CMAKE_CURRENT_BINARY_DIR}/${_libName}/${_libName}.h"
+          DESTINATION include/${_libName}
+      )
   endif()
 endmacro()
 
@@ -129,6 +136,10 @@ add_include_lib(testLibIncludeRequired3 NO_HEADER)
 # but we are testing that the INSTALL_INTERFACE causes it not to be used
 # at build time.
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired3/testLibIncludeRequired4.h" "#error Should not be included\n")
+install(FILES
+  "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired3/testLibIncludeRequired4.h"
+    DESTINATION include/testLibIncludeRequired3
+)
 add_include_lib(testLibIncludeRequired4)
 add_include_lib(testLibIncludeRequired5 NO_HEADER)
 # Generate testLibIncludeRequired6 in the testLibIncludeRequired5 directory
@@ -139,6 +150,10 @@ add_include_lib(testLibIncludeRequired5 NO_HEADER)
 # the Import side of this unit test, the '6' include from the '5' directory
 # will not be used because it is in the BUILD_INTERFACE only.
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired5/testLibIncludeRequired6.h" "#error Should not be included\n")
+install(FILES
+  "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired5/testLibIncludeRequired6.h"
+    DESTINATION include/testLibIncludeRequired5
+)
 add_include_lib(testLibIncludeRequired6)
 
 set_property(TARGET testLibRequired APPEND PROPERTY

+ 1 - 0
Tests/GeneratorExpression/CMakeLists.txt

@@ -89,6 +89,7 @@ add_custom_target(check-part2 ALL
     -Dtest_install_interface=$<INSTALL_INTERFACE:install>
     -Dtest_target_name_1=$<TARGET_NAME:tgt,ok>
     -Dtest_target_name_2=$<TARGET_NAME:tgt:ok>
+    -Dtest_install_prefix=$<INSTALL_PREFIX>
     -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part2.cmake
   COMMAND ${CMAKE_COMMAND} -E echo "check done (part 2 of 2)"
   VERBATIM

+ 1 - 0
Tests/GeneratorExpression/check-part2.cmake

@@ -26,3 +26,4 @@ check(test_build_interface "build")
 check(test_install_interface "")
 check(test_target_name_1 "tgt,ok")
 check(test_target_name_2 "tgt:ok")
+check(test_install_prefix "")