Forráskód Böngészése

Merge topic 'build-local-interface-genex'

38cbf5e15b Genex: Add $<BUILD_LOCAL_INTERFACE:...> genex
37b5c78688 cmGeneratorExpression: Refactor stripExportInterface() to use enum class

Acked-by: Kitware Robot <[email protected]>
Acked-by: buildbot <[email protected]>
Merge-request: !7919
Brad King 2 éve
szülő
commit
e558beeef6

+ 7 - 0
Help/manual/cmake-generator-expressions.7.rst

@@ -1711,6 +1711,13 @@ Export And Install Expressions
   when the target is used by another target in the same buildsystem. Expands to
   the empty string otherwise.
 
+.. genex:: $<BUILD_LOCAL_INTERFACE:...>
+
+  .. versionadded:: 3.26
+
+  Content of ``...`` when the target is used by another target in the same
+  buildsystem. Expands to the empty string otherwise.
+
 .. genex:: $<INSTALL_PREFIX>
 
   Content of the install prefix when the target is exported via

+ 5 - 0
Help/release/dev/build-local-interface-genex.rst

@@ -0,0 +1,5 @@
+build-local-interface-genex
+---------------------------
+
+* The :genex:`BUILD_LOCAL_INTERFACE` generator expression was added to
+  prevent usage requirements from being exported to dependent projects.

+ 36 - 16
Source/cmGeneratorExpression.cxx

@@ -2,6 +2,7 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmGeneratorExpression.h"
 
+#include <algorithm>
 #include <cassert>
 #include <memory>
 #include <utility>
@@ -226,23 +227,33 @@ static std::string stripExportInterface(
   while (true) {
     std::string::size_type bPos = input.find("$<BUILD_INTERFACE:", lastPos);
     std::string::size_type iPos = input.find("$<INSTALL_INTERFACE:", lastPos);
+    std::string::size_type lPos =
+      input.find("$<BUILD_LOCAL_INTERFACE:", lastPos);
 
-    if (bPos == std::string::npos && iPos == std::string::npos) {
+    pos = std::min({ bPos, iPos, lPos });
+    if (pos == std::string::npos) {
       break;
     }
 
-    if (bPos == std::string::npos) {
-      pos = iPos;
-    } else if (iPos == std::string::npos) {
-      pos = bPos;
+    result += input.substr(lastPos, pos - lastPos);
+    enum class FoundGenex
+    {
+      BuildInterface,
+      InstallInterface,
+      BuildLocalInterface,
+    } foundGenex = FoundGenex::BuildInterface;
+    if (pos == bPos) {
+      foundGenex = FoundGenex::BuildInterface;
+      pos += cmStrLen("$<BUILD_INTERFACE:");
+    } else if (pos == iPos) {
+      foundGenex = FoundGenex::InstallInterface;
+      pos += cmStrLen("$<INSTALL_INTERFACE:");
+    } else if (pos == lPos) {
+      foundGenex = FoundGenex::BuildLocalInterface;
+      pos += cmStrLen("$<BUILD_LOCAL_INTERFACE:");
     } else {
-      pos = (bPos < iPos) ? bPos : iPos;
+      assert(false && "Invalid position found");
     }
-
-    result += input.substr(lastPos, pos - lastPos);
-    const bool gotInstallInterface = input[pos + 2] == 'I';
-    pos += gotInstallInterface ? sizeof("$<INSTALL_INTERFACE:") - 1
-                               : sizeof("$<BUILD_INTERFACE:") - 1;
     nestingLevel = 1;
     const char* c = input.c_str() + pos;
     const char* const cStart = c;
@@ -258,10 +269,10 @@ static std::string stripExportInterface(
           continue;
         }
         if (context == cmGeneratorExpression::BuildInterface &&
-            !gotInstallInterface) {
+            foundGenex == FoundGenex::BuildInterface) {
           result += input.substr(pos, c - cStart);
         } else if (context == cmGeneratorExpression::InstallInterface &&
-                   gotInstallInterface) {
+                   foundGenex == FoundGenex::InstallInterface) {
           const std::string content = input.substr(pos, c - cStart);
           if (resolveRelative) {
             prefixItems(content, result, "${_IMPORT_PREFIX}/");
@@ -274,9 +285,18 @@ static std::string stripExportInterface(
     }
     const std::string::size_type traversed = (c - cStart) + 1;
     if (!*c) {
-      result += std::string(gotInstallInterface ? "$<INSTALL_INTERFACE:"
-                                                : "$<BUILD_INTERFACE:") +
-        input.substr(pos, traversed);
+      auto remaining = input.substr(pos, traversed);
+      switch (foundGenex) {
+        case FoundGenex::BuildInterface:
+          result = cmStrCat(result, "$<BUILD_INTERFACE:", remaining);
+          break;
+        case FoundGenex::InstallInterface:
+          result = cmStrCat(result, "$<INSTALL_INTERFACE:", remaining);
+          break;
+        case FoundGenex::BuildLocalInterface:
+          result = cmStrCat(result, "$<BUILD_LOCAL_INTERFACE:", remaining);
+          break;
+      }
     }
     pos += traversed;
     lastPos = pos;

+ 3 - 0
Source/cmGeneratorExpressionNode.cxx

@@ -114,6 +114,8 @@ static const struct OneNode buildInterfaceNode;
 
 static const struct ZeroNode installInterfaceNode;
 
+static const struct OneNode buildLocalInterfaceNode;
+
 struct BooleanOpNode : public cmGeneratorExpressionNode
 {
   BooleanOpNode(const char* op_, const char* successVal_,
@@ -3323,6 +3325,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
     { "GENEX_EVAL", &genexEvalNode },
     { "BUILD_INTERFACE", &buildInterfaceNode },
     { "INSTALL_INTERFACE", &installInterfaceNode },
+    { "BUILD_LOCAL_INTERFACE", &buildLocalInterfaceNode },
     { "INSTALL_PREFIX", &installPrefixNode },
     { "JOIN", &joinNode },
     { "LINK_ONLY", &linkOnlyNode },

+ 14 - 0
Tests/RunCMake/ExportImport/BuildInstallInterfaceGenex-export.cmake

@@ -0,0 +1,14 @@
+enable_language(C)
+
+add_library(mainlib STATIC foo.c)
+target_compile_definitions(mainlib INTERFACE
+  $<BUILD_LOCAL_INTERFACE:BUILD_LOCAL_INTERFACE>
+  $<BUILD_INTERFACE:BUILD_INTERFACE>
+  $<INSTALL_INTERFACE:INSTALL_INTERFACE>
+  )
+add_library(locallib STATIC locallib.c)
+target_link_libraries(locallib PRIVATE mainlib)
+
+install(TARGETS mainlib EXPORT export)
+install(EXPORT export DESTINATION lib/cmake/install FILE install-config.cmake NAMESPACE install::)
+export(EXPORT export FILE build-config.cmake NAMESPACE build::)

+ 9 - 0
Tests/RunCMake/ExportImport/BuildInstallInterfaceGenex-import.cmake

@@ -0,0 +1,9 @@
+enable_language(C)
+
+find_package(build REQUIRED)
+find_package(install REQUIRED)
+
+add_library(buildlib STATIC buildlib.c)
+target_link_libraries(buildlib PRIVATE build::mainlib)
+add_library(installlib STATIC installlib.c)
+target_link_libraries(installlib PRIVATE install::mainlib)

+ 25 - 0
Tests/RunCMake/ExportImport/RunCMakeTest.cmake

@@ -22,3 +22,28 @@ function(run_ExportImport_test case)
 endfunction()
 
 run_ExportImport_test(SharedDep)
+
+function(run_ExportImportBuildInstall_test case)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-export-build)
+  set(CMAKE_INSTALL_PREFIX ${RunCMake_TEST_BINARY_DIR}/root)
+  if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+  endif()
+  run_cmake(${case}-export)
+  unset(RunCMake_TEST_OPTIONS)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  run_cmake_command(${case}-export-build ${CMAKE_COMMAND} --build . --config Debug)
+  run_cmake_command(${case}-export-install ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DBUILD_TYPE=Debug -P cmake_install.cmake)
+  unset(RunCMake_TEST_NO_CLEAN)
+
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-import-build)
+  run_cmake_with_options(${case}-import
+    -Dbuild_DIR=${RunCMake_BINARY_DIR}/${case}-export-build
+    -Dinstall_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/install
+    )
+  set(RunCMake_TEST_NO_CLEAN 1)
+  run_cmake_command(${case}-import-build ${CMAKE_COMMAND} --build . --config Debug)
+  unset(RunCMake_TEST_NO_CLEAN)
+endfunction()
+
+run_ExportImportBuildInstall_test(BuildInstallInterfaceGenex)

+ 8 - 0
Tests/RunCMake/ExportImport/buildlib.c

@@ -0,0 +1,8 @@
+#if !(!defined(BUILD_LOCAL_INTERFACE) && defined(BUILD_INTERFACE) &&          \
+      !defined(INSTALL_INTERFACE))
+#  error "Incorrect compile definitions"
+#endif
+
+void buildlib(void)
+{
+}

+ 8 - 0
Tests/RunCMake/ExportImport/installlib.c

@@ -0,0 +1,8 @@
+#if !(!defined(BUILD_LOCAL_INTERFACE) && !defined(BUILD_INTERFACE) &&         \
+      defined(INSTALL_INTERFACE))
+#  error "Incorrect compile definitions"
+#endif
+
+void installlib(void)
+{
+}

+ 8 - 0
Tests/RunCMake/ExportImport/locallib.c

@@ -0,0 +1,8 @@
+#if !(defined(BUILD_LOCAL_INTERFACE) && defined(BUILD_INTERFACE) &&           \
+      !defined(INSTALL_INTERFACE))
+#  error "Incorrect compile definitions"
+#endif
+
+void locallib(void)
+{
+}