Selaa lähdekoodia

Fix cmGeneratorExpression::Preprocess for interleaved inputs.

We can't find both preprocessing expressions at once, because then
the BUILD_INTERFACE will always be favored if both are present, even
if INSTALL_INTERFACE appears first.

This was affecting the behavior of install(EXPORT) because the
INTERFACE_INCLUDE_DIRECTORIES contained entries like

 /foo/include;$<INSTALL_INTERFACE:/bar/include>

As the INSTALL_INTERFACE always evaluates to '0', it always needs
to be preprocessed properly.
Stephen Kelly 12 vuotta sitten
vanhempi
sitoutus
7a619fa6fb
2 muutettua tiedostoa jossa 26 lisäystä ja 2 poistoa
  1. 22 2
      Source/cmGeneratorExpression.cxx
  2. 4 0
      Tests/ExportImport/Export/CMakeLists.txt

+ 22 - 2
Source/cmGeneratorExpression.cxx

@@ -236,9 +236,29 @@ static std::string stripExportInterface(const std::string &input,
 
 
   std::string::size_type pos = 0;
   std::string::size_type pos = 0;
   std::string::size_type lastPos = pos;
   std::string::size_type lastPos = pos;
-  while((pos = input.find("$<BUILD_INTERFACE:", lastPos)) != input.npos
-    || (pos = input.find("$<INSTALL_INTERFACE:", lastPos)) != input.npos)
+  while (true)
     {
     {
+    std::string::size_type bPos = input.find("$<BUILD_INTERFACE:", lastPos);
+    std::string::size_type iPos = input.find("$<INSTALL_INTERFACE:", lastPos);
+
+    if (bPos == std::string::npos && iPos == std::string::npos)
+      {
+      break;
+      }
+
+    if (bPos == std::string::npos)
+      {
+      pos = iPos;
+      }
+    else if (iPos == std::string::npos)
+      {
+      pos = bPos;
+      }
+    else
+      {
+      pos = (bPos < iPos) ? bPos : iPos;
+      }
+
     result += input.substr(lastPos, pos - lastPos);
     result += input.substr(lastPos, pos - lastPos);
     const bool gotInstallInterface = input[pos + 2] == 'I';
     const bool gotInstallInterface = input[pos + 2] == 'I';
     pos += gotInstallInterface ? sizeof("$<INSTALL_INTERFACE:") - 1
     pos += gotInstallInterface ? sizeof("$<INSTALL_INTERFACE:") - 1

+ 4 - 0
Tests/ExportImport/Export/CMakeLists.txt

@@ -148,6 +148,10 @@ set_property(TARGET testLibRequired APPEND PROPERTY
     $<BUILD_INTERFACE:$<TARGET_PROPERTY:testLibIncludeRequired4,INTERFACE_INCLUDE_DIRECTORIES>>
     $<BUILD_INTERFACE:$<TARGET_PROPERTY:testLibIncludeRequired4,INTERFACE_INCLUDE_DIRECTORIES>>
     $<BUILD_INTERFACE:$<TARGET_PROPERTY:testLibIncludeRequired5,INTERFACE_INCLUDE_DIRECTORIES>>
     $<BUILD_INTERFACE:$<TARGET_PROPERTY:testLibIncludeRequired5,INTERFACE_INCLUDE_DIRECTORIES>>
     $<INSTALL_INTERFACE:$<TARGET_PROPERTY:testLibIncludeRequired6,INTERFACE_INCLUDE_DIRECTORIES>>
     $<INSTALL_INTERFACE:$<TARGET_PROPERTY:testLibIncludeRequired6,INTERFACE_INCLUDE_DIRECTORIES>>
+    # The BUILD_INTERFACE entry from above is duplicated below. This is to test that
+    # the INSTALL_INTERFACE entry bound by a BUILD_INTERFACE entry on either side is
+    # preprocessed correctly on install(EXPORT).
+    $<BUILD_INTERFACE:$<TARGET_PROPERTY:testLibIncludeRequired5,INTERFACE_INCLUDE_DIRECTORIES>>
     # Test that the below is non-fatal
     # Test that the below is non-fatal
     $<$<STREQUAL:one,two>:$<TARGET_PROPERTY:not_a_target,INTERFACE_INCLUDE_DIRECTORIES>>
     $<$<STREQUAL:one,two>:$<TARGET_PROPERTY:not_a_target,INTERFACE_INCLUDE_DIRECTORIES>>
 )
 )