Преглед на файлове

PkgC: Implement cmake_pkg_config IMPORT / POPULATE

Issue: #26067
Vito Gamberini преди 9 месеца
родител
ревизия
28a92bde80
променени са 54 файла, в които са добавени 813 реда и са изтрити 184 реда
  1. 102 9
      Help/command/cmake_pkg_config.rst
  2. 6 0
      Help/release/dev/cmake-pkg-config-import.rst
  3. 412 107
      Source/cmCMakePkgConfigCommand.cxx
  4. 5 5
      Source/cmMakefile.cxx
  5. 44 22
      Source/cmPkgConfigResolver.cxx
  6. 4 1
      Source/cmPkgConfigResolver.h
  7. 0 0
      Tests/RunCMake/cmake_pkg_config/ExtractEnv-stderr.txt
  8. 0 0
      Tests/RunCMake/cmake_pkg_config/ExtractEnv.cmake
  9. 0 0
      Tests/RunCMake/cmake_pkg_config/ExtractFields-stderr.txt
  10. 0 0
      Tests/RunCMake/cmake_pkg_config/ExtractFields.cmake
  11. 0 0
      Tests/RunCMake/cmake_pkg_config/ExtractMangle-stderr.txt
  12. 0 0
      Tests/RunCMake/cmake_pkg_config/ExtractMangle.cmake
  13. 0 0
      Tests/RunCMake/cmake_pkg_config/ExtractQuiet.cmake
  14. 0 0
      Tests/RunCMake/cmake_pkg_config/ExtractRequired-result.txt
  15. 4 0
      Tests/RunCMake/cmake_pkg_config/ExtractRequired-stderr.txt
  16. 0 0
      Tests/RunCMake/cmake_pkg_config/ExtractRequired.cmake
  17. 0 0
      Tests/RunCMake/cmake_pkg_config/ExtractReroot-stderr.txt
  18. 0 0
      Tests/RunCMake/cmake_pkg_config/ExtractReroot.cmake
  19. 0 0
      Tests/RunCMake/cmake_pkg_config/ExtractStrictness-BEST_EFFORT-stderr.txt
  20. 4 4
      Tests/RunCMake/cmake_pkg_config/ExtractStrictness-PERMISSIVE-stderr.txt
  21. 5 5
      Tests/RunCMake/cmake_pkg_config/ExtractStrictness-STRICT-stderr.txt
  22. 0 0
      Tests/RunCMake/cmake_pkg_config/ExtractStrictness.cmake
  23. 0 0
      Tests/RunCMake/cmake_pkg_config/ExtractUninstalled-stderr.txt
  24. 0 0
      Tests/RunCMake/cmake_pkg_config/ExtractUninstalled.cmake
  25. 17 17
      Tests/RunCMake/cmake_pkg_config/ExtractVersion-stderr.txt
  26. 0 0
      Tests/RunCMake/cmake_pkg_config/ExtractVersion.cmake
  27. 14 0
      Tests/RunCMake/cmake_pkg_config/ImportRequires-check.cmake
  28. 18 0
      Tests/RunCMake/cmake_pkg_config/ImportRequires.cmake
  29. 15 0
      Tests/RunCMake/cmake_pkg_config/ImportSimple-check.cmake
  30. 15 0
      Tests/RunCMake/cmake_pkg_config/ImportSimple.cmake
  31. 1 0
      Tests/RunCMake/cmake_pkg_config/ImportTransitiveFail-result.txt
  32. 11 0
      Tests/RunCMake/cmake_pkg_config/ImportTransitiveFail-stderr.txt
  33. 5 0
      Tests/RunCMake/cmake_pkg_config/ImportTransitiveFail.cmake
  34. 3 0
      Tests/RunCMake/cmake_pkg_config/ImportTransitiveVersion.cmake
  35. 5 0
      Tests/RunCMake/cmake_pkg_config/ImportTransitiveVersionFail-stderr.txt
  36. 4 0
      Tests/RunCMake/cmake_pkg_config/ImportTransitiveVersionFail.cmake
  37. 5 0
      Tests/RunCMake/cmake_pkg_config/PackageRoot/RequiresPackages/alpha.pc
  38. 6 0
      Tests/RunCMake/cmake_pkg_config/PackageRoot/RequiresPackages/bravo.pc
  39. 6 0
      Tests/RunCMake/cmake_pkg_config/PackageRoot/RequiresPackages/charlie.pc
  40. 5 0
      Tests/RunCMake/cmake_pkg_config/PackageRoot/RequiresPackages/delta.pc
  41. 6 0
      Tests/RunCMake/cmake_pkg_config/PackageRoot/RequiresPackages/echo.pc
  42. 6 0
      Tests/RunCMake/cmake_pkg_config/PackageRoot/RequiresPackages/golf.pc
  43. 6 0
      Tests/RunCMake/cmake_pkg_config/PackageRoot/RequiresPackages/hotel.pc
  44. 6 0
      Tests/RunCMake/cmake_pkg_config/PackageRoot/RequiresPackages/india.pc
  45. 6 0
      Tests/RunCMake/cmake_pkg_config/PackageRoot/RequiresPackages/juliet.pc
  46. 6 0
      Tests/RunCMake/cmake_pkg_config/PackageRoot/import-simple.pc
  47. 8 0
      Tests/RunCMake/cmake_pkg_config/PopulateFoundVar-stderr.txt
  48. 7 0
      Tests/RunCMake/cmake_pkg_config/PopulateFoundVar.cmake
  49. 10 0
      Tests/RunCMake/cmake_pkg_config/PopulateMissing-check.cmake
  50. 19 0
      Tests/RunCMake/cmake_pkg_config/PopulateMissing.cmake
  51. 17 10
      Tests/RunCMake/cmake_pkg_config/RunCMakeTest.cmake
  52. 0 0
      Tests/RunCMake/cmake_pkg_config/TestDirectories/Include/dummy-header.h
  53. 0 0
      Tests/RunCMake/cmake_pkg_config/TestDirectories/Library/libdummy
  54. 0 4
      Tests/RunCMake/cmake_pkg_config/TestRequired-stderr.txt

+ 102 - 9
Help/command/cmake_pkg_config.rst

@@ -12,9 +12,11 @@ Process pkg-config format package files.
 Synopsis
 ^^^^^^^^
 
-.. code-block:: cmake
+.. parsed-literal::
 
-  cmake_pkg_config(EXTRACT <package> [<version>] [...])
+  cmake_pkg_config(`EXTRACT`_ <package> [<version>] [...])
+  cmake_pkg_config(`POPULATE`_ <package> [<version>] [...])
+  cmake_pkg_config(`IMPORT`_ <package> [<version>] [...])
 
 Introduction
 ^^^^^^^^^^^^
@@ -27,7 +29,31 @@ search patterns. The optional ``<version>`` string has the same format and
 semantics as a pkg-config style version specifier, with the exception that if
 no comparison operator is specified ``=`` is assumed.
 
-.. _`common options`:
+PkgConfig Targets
+^^^^^^^^^^^^^^^^^
+
+``cmake_pkg_config`` may recursively generate target-like names in the global
+scope in order to resolve a package ``IMPORT`` or ``POPULATE`` command. These
+names take the form of ``@foreign_pkgcfg::<package>`` and are exposed via the
+:prop_tgt:`INTERFACE_LINK_LIBRARIES` target property of an ``IMPORT``-generated
+target.
+
+It is not possible to modify or address these pkg-config native targets via
+normal target-based commands. Limited control over their generation is possible
+via the ``POPULATE`` command, but modification should generally be performed
+inside the corresponding package file, not downstream in CMake.
+
+Pkg-config targets are reused across commands. Once a given package name has
+been resolved via ``POPULATE`` or ``IMPORT`` (but not ``EXTRACT``), all future
+requests for the corresponding package name by those commands will resolve to
+the previously generated pkg-config target.
+
+``EXTRACT`` always performs the complete package name lookup in order to allow
+searches for multiple installations of the same package in custom dependency
+management schemes.
+
+Common Options
+^^^^^^^^^^^^^^
 
 There are multiple signatures for this command, and some of the options are
 common between them. They are:
@@ -143,7 +169,7 @@ common between them. They are:
      library directory paths and ``pc_sysrootdir`` will be set to ``/``
 
 ``TOP_BUILD_DIR <path>``
-  Overrides the top build directory path used to derived the ``pc_top_builddir``
+  Overrides the top build directory path used to derive the ``pc_top_builddir``
   package variable.
 
   When this option is not provided, the default top build directory path is
@@ -154,29 +180,41 @@ common between them. They are:
   #. If no top build directory path is available, the ``pc_top_builddir``
      package variable is not set
 
+``BIND_PC_REQUIRES``
+  A list of ``<Name>=<Target>`` pairs, the ``Name`` is a package name as it
+  appears in the ``Requires`` list of a pkg-config file and the ``Target`` is a
+  CMake-native target name (not a pkg-config target).
+
+  When a given package name appears in the ``Requires`` list of a package, it
+  will be fulfilled with the associated CMake target. This behavior applies to
+  all dependencies in the pkg-config graph that have not been previously
+  populated.
+
 Signatures
 ^^^^^^^^^^
 
 .. signature::
   cmake_pkg_config(EXTRACT <package> [<version>] [...])
 
+  .. versionadded:: 3.31
+
   Extract the contents of the package into variables.
 
   .. code-block:: cmake
 
     cmake_pkg_config(EXTRACT <package> [<version>]
                     [REQUIRED] [EXACT] [QUIET]
+                    [SYSTEM_INCLUDE_DIRS <path>...]
+                    [SYSTEM_LIBRARY_DIRS <path>...]
+                    [ALLOW_SYSTEM_INCLUDES <bool>]
+                    [ALLOW_SYSTEM_LIBS <bool>]
                     [STRICTNESS <mode>]
                     [ENV_MODE <mode>]
                     [PC_LIBDIR <path>...]
                     [PC_PATH <path>...]
                     [DISABLE_UNINSTALLED <bool>]
                     [PC_SYSROOT_DIR <path>]
-                    [TOP_BUILD_DIR <path>]
-                    [SYSTEM_INCLUDE_DIRS <path>...]
-                    [SYSTEM_LIBRARY_DIRS <path>...]
-                    [ALLOW_SYSTEM_INCLUDES <bool>]
-                    [ALLOW_SYSTEM_LIBS <bool>])
+                    [TOP_BUILD_DIR <path>])
 
 The following variables will be populated from the contents of package file:
 
@@ -261,3 +299,58 @@ The following variables will be populated from the contents of package file:
   #. ``CMAKE_PKG_CONFIG_ALLOW_SYS_LIBS``
   #. If the ``PKG_CONFIG_ALLOW_SYSTEM_LIBS`` environment variable is defined
      the flags are preserved, otherwise they are filtered during flag mangling.
+
+.. signature::
+  cmake_pkg_config(POPULATE <package> [<version>] [...])
+
+  .. versionadded:: 4.1
+
+  Populate a package in the pkg-config target namespace
+
+  .. code-block:: cmake
+
+    cmake_pkg_config(POPULATE <package> [<version>]
+                    [REQUIRED] [EXACT] [QUIET]
+                    [BIND_PC_REQUIRES <<name>=<target>>...]
+                    [STRICTNESS <mode>]
+                    [ENV_MODE <mode>]
+                    [PC_LIBDIR <path>...]
+                    [PC_PATH <path>...]
+                    [DISABLE_UNINSTALLED <bool>]
+                    [PC_SYSROOT_DIR <path>]
+                    [TOP_BUILD_DIR <path>])
+
+``POPULATE`` enables manual control of resolution of a given package's
+``Requires`` list without importing onto a native CMake target. Once populated,
+a package and its dependencies will be used for resolution of all future
+``POPULATE`` and ``IMPORT`` commands.
+
+A ``PKGCONFIG_<package>_FOUND`` variable will be set to indicate whether the
+package was found.
+
+.. signature::
+  cmake_pkg_config(IMPORT <package> [<version>] [...])
+
+  .. versionadded:: 4.1
+
+  Import a pkg-config target as a CMake :prop_tgt:`IMPORTED` target
+
+  .. code-block:: cmake
+
+    cmake_pkg_config(IMPORT <package> [<version>]
+                    [REQUIRED] [EXACT] [QUIET]
+                    [BIND_PC_REQUIRES <<name>=<target>>...]
+                    [STRICTNESS <mode>]
+                    [ENV_MODE <mode>]
+                    [PC_LIBDIR <path>...]
+                    [PC_PATH <path>...]
+                    [DISABLE_UNINSTALLED <bool>]
+                    [PC_SYSROOT_DIR <path>]
+                    [TOP_BUILD_DIR <path>])
+
+Creates a native CMake ``IMPORTED`` target that can be linked to via
+:command:`target_link_libraries`. This new target is named
+``PkgConfig::<package>``.
+
+A ``PKGCONFIG_<package>_FOUND`` variable will be set to indicate whether the
+package was found.

+ 6 - 0
Help/release/dev/cmake-pkg-config-import.rst

@@ -0,0 +1,6 @@
+cmake-pkg-config-import
+-----------------------
+
+* The :command:`cmake_pkg_config` command now supports the ``IMPORT`` and
+  ``POPULATE`` subcommands for interfacing CMake targets with pkg-config based
+  dependencies.

+ 412 - 107
Source/cmCMakePkgConfigCommand.cxx

@@ -6,6 +6,7 @@
 #include <cstdio>
 #include <memory>
 #include <string>
+#include <unordered_map>
 #include <utility>
 #include <vector>
 
@@ -28,12 +29,14 @@
 #include "cmStringAlgorithms.h"
 #include "cmSubcommandTable.h"
 #include "cmSystemTools.h"
+#include "cmTarget.h"
 #include "cmValue.h"
 #include <cmllpkgc/llpkgc.h>
 
 // IWYU wants this
 namespace {
 struct ExtractArguments;
+struct PopulateArguments;
 }
 
 namespace {
@@ -441,89 +444,59 @@ void CollectEnv(cmMakefile& mf, cmPkgConfigEnv& env,
   *env.SysLibs += GetPkgConfSysLibs(mf);
 }
 
-cm::optional<cmPkgConfigResult> HandleCommon(CommonArguments& args,
-                                             cmExecutionStatus& status)
+struct ImportEnv
 {
+  bool required;
+  bool quiet;
+  bool exact;
+  bool err;
+  CommonArguments::StrictnessType strictness;
+  cmExecutionStatus& status;
+};
 
-  auto& mf = status.GetMakefile();
-
-  if (!args.CheckArgs(status)) {
-    return {};
-  }
-
-  auto warn_or_error = [&](std::string const& err) {
-    if (args.Required) {
-      status.SetError(err);
-      cmSystemTools::SetFatalErrorOccurred();
-    } else if (!args.Quiet) {
-      mf.IssueMessage(MessageType::WARNING, err);
-    }
-  };
-
-  cm::filesystem::path path{ *args.Package };
-
-  cmPkgConfigEnv env;
-
-  if (args.PcLibdir) {
-    env.LibDirs = std::move(*args.PcLibdir);
-  }
-
-  if (args.PcPath) {
-    env.Path = std::move(*args.PcPath);
-  }
-
-  if (args.DisableUninstalled) {
-    env.DisableUninstalled = args.DisableUninstalled;
-  }
-
-  if (args.SysrootDir) {
-    env.SysrootDir = std::move(*args.SysrootDir);
-  }
-
-  if (args.TopBuildDir) {
-    env.TopBuildDir = std::move(*args.TopBuildDir);
+void warn_or_error(std::string const& err, ImportEnv& imEnv)
+{
+  if (imEnv.required) {
+    imEnv.status.SetError(err);
+    cmSystemTools::SetFatalErrorOccurred();
+  } else if (!imEnv.quiet) {
+    imEnv.status.GetMakefile().IssueMessage(MessageType::WARNING, err);
   }
+  imEnv.err = true;
+}
 
-  CollectEnv(mf, env, args.EnvMode);
+cm::optional<cmPkgConfigResult> ReadPackage(std::string const& package,
+                                            ImportEnv& imEnv,
+                                            cmPkgConfigEnv& pcEnv)
+{
+  cm::optional<cmPkgConfigResult> result;
+  cm::filesystem::path path{ package };
 
   if (path.extension() == ".pc") {
     if (!cmSystemTools::FileExists(path.string())) {
-      warn_or_error(cmStrCat("Could not find '", *args.Package, "'"));
-      return {};
+      return result;
     }
   } else {
 
-    std::vector<std::string> search;
-    if (env.Path) {
-      search = *env.Path;
-      if (env.LibDirs) {
-        search += *env.LibDirs;
-      }
-    } else if (env.LibDirs) {
-      search = *env.LibDirs;
-    }
-
-    if (env.DisableUninstalled && !*env.DisableUninstalled) {
+    if (pcEnv.DisableUninstalled && !*pcEnv.DisableUninstalled) {
       auto uninstalled = path;
       uninstalled.concat("-uninstalled.pc");
       uninstalled =
-        cmSystemTools::FindFile(uninstalled.string(), search, true);
+        cmSystemTools::FindFile(uninstalled.string(), pcEnv.search, true);
       if (uninstalled.empty()) {
-        path =
-          cmSystemTools::FindFile(path.concat(".pc").string(), search, true);
+        path = cmSystemTools::FindFile(path.concat(".pc").string(),
+                                       pcEnv.search, true);
         if (path.empty()) {
-          warn_or_error(cmStrCat("Could not find '", *args.Package, "'"));
-          return {};
+          return result;
         }
       } else {
         path = uninstalled;
       }
     } else {
-      path =
-        cmSystemTools::FindFile(path.concat(".pc").string(), search, true);
+      path = cmSystemTools::FindFile(path.concat(".pc").string(), pcEnv.search,
+                                     true);
       if (path.empty()) {
-        warn_or_error(cmStrCat("Could not find '", *args.Package, "'"));
-        return {};
+        return result;
       }
     }
   }
@@ -534,8 +507,9 @@ cm::optional<cmPkgConfigResult> HandleCommon(CommonArguments& args,
   cmsys::ifstream ifs(path.string().c_str(), std::ios::binary);
 
   if (!ifs) {
-    warn_or_error(cmStrCat("Could not open file '", path.string(), "'"));
-    return {};
+    warn_or_error(cmStrCat("Could not open file '", path.string(), "'"),
+                  imEnv);
+    return result;
   }
 
   std::unique_ptr<char[]> buf(new char[len]);
@@ -543,8 +517,9 @@ cm::optional<cmPkgConfigResult> HandleCommon(CommonArguments& args,
 
   // Shouldn't have hit eof on previous read, should hit eof now
   if (ifs.fail() || ifs.eof() || ifs.get() != EOF) {
-    warn_or_error(cmStrCat("Error while reading file '", path.string(), "'"));
-    return {};
+    warn_or_error(cmStrCat("Error while reading file '", path.string(), "'"),
+                  imEnv);
+    return result;
   }
 
   using StrictnessType = CommonArguments::StrictnessType;
@@ -552,53 +527,161 @@ cm::optional<cmPkgConfigResult> HandleCommon(CommonArguments& args,
   cmPkgConfigParser parser;
   auto err = parser.Finish(buf.get(), len);
 
-  if (args.Strictness != StrictnessType::STRICTNESS_BEST_EFFORT &&
+  if (imEnv.strictness != StrictnessType::STRICTNESS_BEST_EFFORT &&
       err != PCE_OK) {
-    warn_or_error(cmStrCat("Parsing failed for file '", path.string(), "'"));
-    return {};
+    warn_or_error(cmStrCat("Parsing failed for file '", path.string(), "'"),
+                  imEnv);
+    return result;
   }
 
-  cm::optional<cmPkgConfigResult> result;
-  if (args.Strictness == StrictnessType::STRICTNESS_STRICT) {
-    result = cmPkgConfigResolver::ResolveStrict(parser.Data(), std::move(env));
-  } else if (args.Strictness == StrictnessType::STRICTNESS_PERMISSIVE) {
-    result =
-      cmPkgConfigResolver::ResolvePermissive(parser.Data(), std::move(env));
+  if (imEnv.strictness == StrictnessType::STRICTNESS_STRICT) {
+    result = cmPkgConfigResolver::ResolveStrict(parser.Data(), pcEnv);
+  } else if (imEnv.strictness == StrictnessType::STRICTNESS_PERMISSIVE) {
+    result = cmPkgConfigResolver::ResolvePermissive(parser.Data(), pcEnv);
   } else {
-    result =
-      cmPkgConfigResolver::ResolveBestEffort(parser.Data(), std::move(env));
+    result = cmPkgConfigResolver::ResolveBestEffort(parser.Data(), pcEnv);
   }
 
   if (!result) {
-    warn_or_error(
-      cmStrCat("Resolution failed for file '", path.string(), "'"));
-  } else if (args.Exact) {
+    warn_or_error(cmStrCat("Resolution failed for file '", path.string(), "'"),
+                  imEnv);
+  }
+
+  return result;
+}
+
+cm::optional<cmPkgConfigResult> ImportPackage(
+  std::string const& package, cm::optional<std::string> version,
+  ImportEnv& imEnv, cmPkgConfigEnv& pcEnv)
+{
+  auto result = ReadPackage(package, imEnv, pcEnv);
+
+  if (!result) {
+    if (!imEnv.err) {
+      warn_or_error(cmStrCat("Could not find pkg-config: '", package, "'"),
+                    imEnv);
+    }
+    return result;
+  }
+
+  if (imEnv.exact) {
     std::string ver;
 
-    if (args.Version) {
-      ver = cmPkgConfigResolver::ParseVersion(*args.Version).Version;
+    if (version) {
+      ver = cmPkgConfigResolver::ParseVersion(*version).Version;
     }
 
     if (ver != result->Version()) {
       warn_or_error(
-        cmStrCat("Package '", *args.Package, "' version '", result->Version(),
-                 "' does not meet exact version requirement '", ver, "'"));
+        cmStrCat("Package '", package, "' version '", result->Version(),
+                 "' does not meet exact version requirement '", ver, "'"),
+        imEnv);
       return {};
     }
 
-  } else if (args.Version) {
-    auto rv = cmPkgConfigResolver::ParseVersion(*args.Version);
+  } else if (version) {
+    auto rv = cmPkgConfigResolver::ParseVersion(*version);
     if (!cmPkgConfigResolver::CheckVersion(rv, result->Version())) {
       warn_or_error(
-        cmStrCat("Package '", *args.Package, "' version '", result->Version(),
-                 "' does not meet version requirement '", *args.Version, "'"));
+        cmStrCat("Package '", package, "' version '", result->Version(),
+                 "' does not meet version requirement '", *version, "'"),
+        imEnv);
       return {};
     }
   }
 
+  result->env = &pcEnv;
   return result;
 }
 
+struct pkgStackEntry
+{
+  cmPkgConfigVersionReq ver;
+  std::string parent;
+};
+
+cm::optional<cmPkgConfigResult> ImportPackage(
+  std::string const& package, std::vector<pkgStackEntry> const& reqs,
+  ImportEnv& imEnv, cmPkgConfigEnv& pcEnv)
+{
+  auto result = ReadPackage(package, imEnv, pcEnv);
+
+  if (!result) {
+    if (!imEnv.err) {
+      std::string req_str = cmStrCat("'", reqs.begin()->parent, "'");
+      for (auto it = reqs.begin() + 1; it != reqs.end(); ++it) {
+        req_str = cmStrCat(req_str, ", '", it->parent, "'");
+      }
+      warn_or_error(cmStrCat("Could not find pkg-config: '", package,
+                             "' required by: ", req_str),
+                    imEnv);
+    }
+    return result;
+  }
+
+  auto ver = result->Version();
+  for (auto const& req : reqs) {
+
+    if (!cmPkgConfigResolver::CheckVersion(req.ver, ver)) {
+      warn_or_error(cmStrCat("Package '", package, "' version '", ver,
+                             "' does not meet version requirement '",
+                             req.ver.string(), "' ", "of '", req.parent, "'"),
+                    imEnv);
+      return {};
+    }
+  }
+
+  result->env = &pcEnv;
+  return result;
+}
+
+cm::optional<std::pair<cmPkgConfigEnv, ImportEnv>> HandleCommon(
+  CommonArguments& args, cmExecutionStatus& status)
+{
+
+  auto& mf = status.GetMakefile();
+
+  if (!args.CheckArgs(status)) {
+    return {};
+  }
+
+  cmPkgConfigEnv pcEnv;
+
+  if (args.PcLibdir) {
+    pcEnv.LibDirs = std::move(*args.PcLibdir);
+  }
+
+  if (args.PcPath) {
+    pcEnv.Path = std::move(*args.PcPath);
+  }
+
+  pcEnv.DisableUninstalled = args.DisableUninstalled;
+
+  if (args.SysrootDir) {
+    pcEnv.SysrootDir = std::move(*args.SysrootDir);
+  }
+
+  if (args.TopBuildDir) {
+    pcEnv.TopBuildDir = std::move(*args.TopBuildDir);
+  }
+
+  CollectEnv(mf, pcEnv, args.EnvMode);
+
+  if (pcEnv.Path) {
+    pcEnv.search = *pcEnv.Path;
+    if (pcEnv.LibDirs) {
+      pcEnv.search += *pcEnv.LibDirs;
+    }
+  } else if (pcEnv.LibDirs) {
+    pcEnv.search = *pcEnv.LibDirs;
+  }
+
+  return std::pair<cmPkgConfigEnv, ImportEnv>{
+    pcEnv,
+    { args.Required, args.Quiet, args.Exact, false, args.Strictness, status }
+  };
+}
+
 struct ExtractArguments : CommonArguments
 {
   cm::optional<bool> AllowSystemIncludes;
@@ -623,35 +706,41 @@ bool HandleExtractCommand(std::vector<std::string> const& args,
 
   std::vector<std::string> unparsed;
   auto parsedArgs = ExtractParser.Parse(args, &unparsed);
-  auto maybeResolved = HandleCommon(parsedArgs, status);
+  auto maybeEnv = HandleCommon(parsedArgs, status);
 
-  if (!maybeResolved) {
+  if (!maybeEnv) {
     return !parsedArgs.Required;
   }
+  auto& pcEnv = maybeEnv->first;
+  auto& imEnv = maybeEnv->second;
 
-  auto& resolved = *maybeResolved;
-  auto version = resolved.Version();
+  auto maybePackage =
+    ImportPackage(*parsedArgs.Package, parsedArgs.Version, imEnv, pcEnv);
+  if (!maybePackage) {
+    return !parsedArgs.Required;
+  }
+  auto& package = *maybePackage;
 
   if (parsedArgs.AllowSystemIncludes) {
-    resolved.env.AllowSysCflags = *parsedArgs.AllowSystemIncludes;
+    pcEnv.AllowSysCflags = *parsedArgs.AllowSystemIncludes;
   }
 
   if (parsedArgs.AllowSystemLibs) {
-    resolved.env.AllowSysLibs = *parsedArgs.AllowSystemLibs;
+    pcEnv.AllowSysLibs = *parsedArgs.AllowSystemLibs;
   }
 
   if (parsedArgs.SystemIncludeDirs) {
-    resolved.env.SysCflags = *parsedArgs.SystemIncludeDirs;
+    pcEnv.SysCflags = *parsedArgs.SystemIncludeDirs;
   }
 
   if (parsedArgs.SystemLibraryDirs) {
-    resolved.env.SysLibs = *parsedArgs.SystemLibraryDirs;
+    pcEnv.SysLibs = *parsedArgs.SystemLibraryDirs;
   }
 
   auto& mf = status.GetMakefile();
-  mf.AddDefinition("CMAKE_PKG_CONFIG_NAME", resolved.Name());
-  mf.AddDefinition("CMAKE_PKG_CONFIG_DESCRIPTION", resolved.Description());
-  mf.AddDefinition("CMAKE_PKG_CONFIG_VERSION", version);
+  mf.AddDefinition("CMAKE_PKG_CONFIG_NAME", package.Name());
+  mf.AddDefinition("CMAKE_PKG_CONFIG_DESCRIPTION", package.Description());
+  mf.AddDefinition("CMAKE_PKG_CONFIG_VERSION", package.Version());
 
   auto make_list = [&](char const* def,
                        std::vector<cmPkgConfigDependency> const& deps) {
@@ -665,26 +754,26 @@ bool HandleExtractCommand(std::vector<std::string> const& args,
     mf.AddDefinition(def, cmList::to_string(vec));
   };
 
-  make_list("CMAKE_PKG_CONFIG_CONFLICTS", resolved.Conflicts());
-  make_list("CMAKE_PKG_CONFIG_PROVIDES", resolved.Provides());
-  make_list("CMAKE_PKG_CONFIG_REQUIRES", resolved.Requires());
-  make_list("CMAKE_PKG_CONFIG_REQUIRES_PRIVATE", resolved.Requires(true));
+  make_list("CMAKE_PKG_CONFIG_CONFLICTS", package.Conflicts());
+  make_list("CMAKE_PKG_CONFIG_PROVIDES", package.Provides());
+  make_list("CMAKE_PKG_CONFIG_REQUIRES", package.Requires());
+  make_list("CMAKE_PKG_CONFIG_REQUIRES_PRIVATE", package.Requires(true));
 
-  auto cflags = resolved.Cflags();
+  auto cflags = package.Cflags();
   mf.AddDefinition("CMAKE_PKG_CONFIG_CFLAGS", cflags.Flagline);
   mf.AddDefinition("CMAKE_PKG_CONFIG_INCLUDES",
                    cmList::to_string(cflags.Includes));
   mf.AddDefinition("CMAKE_PKG_CONFIG_COMPILE_OPTIONS",
                    cmList::to_string(cflags.CompileOptions));
 
-  cflags = resolved.Cflags(true);
+  cflags = package.Cflags(true);
   mf.AddDefinition("CMAKE_PKG_CONFIG_CFLAGS_PRIVATE", cflags.Flagline);
   mf.AddDefinition("CMAKE_PKG_CONFIG_INCLUDES_PRIVATE",
                    cmList::to_string(cflags.Includes));
   mf.AddDefinition("CMAKE_PKG_CONFIG_COMPILE_OPTIONS_PRIVATE",
                    cmList::to_string(cflags.CompileOptions));
 
-  auto libs = resolved.Libs();
+  auto libs = package.Libs();
   mf.AddDefinition("CMAKE_PKG_CONFIG_LIBS", libs.Flagline);
   mf.AddDefinition("CMAKE_PKG_CONFIG_LIBDIRS",
                    cmList::to_string(libs.LibDirs));
@@ -693,7 +782,7 @@ bool HandleExtractCommand(std::vector<std::string> const& args,
   mf.AddDefinition("CMAKE_PKG_CONFIG_LINK_OPTIONS",
                    cmList::to_string(libs.LinkOptions));
 
-  libs = resolved.Libs(true);
+  libs = package.Libs(true);
   mf.AddDefinition("CMAKE_PKG_CONFIG_LIBS_PRIVATE", libs.Flagline);
   mf.AddDefinition("CMAKE_PKG_CONFIG_LIBDIRS_PRIVATE",
                    cmList::to_string(libs.LibDirs));
@@ -704,6 +793,220 @@ bool HandleExtractCommand(std::vector<std::string> const& args,
 
   return true;
 }
+
+using pkgStack = std::unordered_map<std::string, std::vector<pkgStackEntry>>;
+using pkgProviders = std::unordered_map<std::string, std::string>;
+
+cmTarget* CreateCMakeTarget(std::string const& name, cmPkgConfigResult& pkg,
+                            pkgProviders& providers, cmMakefile& mf)
+{
+  auto* tgt = mf.AddForeignTarget("pkgcfg", name);
+
+  tgt->AppendProperty("VERSION", pkg.Version());
+
+  auto libs = pkg.Libs();
+  for (auto const& flag : libs.LibNames) {
+    tgt->AppendProperty("INTERFACE_LINK_LIBRARIES", flag.substr(2));
+  }
+  for (auto const& flag : libs.LibDirs) {
+    tgt->AppendProperty("INTERFACE_LINK_DIRECTORIES", flag.substr(2));
+  }
+  tgt->AppendProperty("INTERFACE_LINK_OPTIONS",
+                      cmList::to_string(libs.LinkOptions));
+
+  auto cflags = pkg.Cflags();
+  for (auto const& flag : cflags.Includes) {
+    tgt->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES", flag.substr(2));
+  }
+  tgt->AppendProperty("INTERFACE_COMPILE_OPTIONS",
+                      cmList::to_string(cflags.CompileOptions));
+
+  for (auto& dep : pkg.Requires()) {
+    auto it = providers.find(dep.Name);
+    if (it != providers.end()) {
+      tgt->AppendProperty("INTERFACE_LINK_LIBRARIES", it->second);
+      continue;
+    }
+
+    tgt->AppendProperty("INTERFACE_LINK_LIBRARIES",
+                        cmStrCat("@foreign_pkgcfg::", dep.Name));
+  }
+  return tgt;
+}
+
+bool CheckPackageDependencies(
+  std::string const& name, cmPkgConfigResult& pkg, pkgStack& inStack,
+  std::unordered_map<std::string, cmPkgConfigResult>& outStack,
+  pkgProviders& providers, ImportEnv& imEnv)
+{
+  for (auto& dep : pkg.Requires()) {
+    auto prov_it = providers.find(dep.Name);
+    if (prov_it != providers.end()) {
+      continue;
+    }
+
+    auto* tgt = imEnv.status.GetMakefile().FindTargetToUse(
+      cmStrCat("@foreign_pkgcfg::", dep.Name),
+      cmStateEnums::TargetDomain::FOREIGN);
+    if (tgt) {
+      auto ver = tgt->GetProperty("VERSION");
+      if (!cmPkgConfigResolver::CheckVersion(dep.VerReq, *ver)) {
+        warn_or_error(cmStrCat("Package '", dep.Name, "' version '", *ver,
+                               "' does not meet version requirement '",
+                               dep.VerReq.string(), "' ", "of '", name, "'"),
+                      imEnv);
+        return false;
+      }
+      continue;
+    }
+
+    auto it = outStack.find(dep.Name);
+    if (it != outStack.end()) {
+      auto ver = it->second.Version();
+      if (!cmPkgConfigResolver::CheckVersion(dep.VerReq, ver)) {
+        warn_or_error(cmStrCat("Package '", dep.Name, "' version '", ver,
+                               "' does not meet version requirement '",
+                               dep.VerReq.string(), "' ", "of '", name, "'"),
+                      imEnv);
+        return false;
+      }
+      continue;
+    }
+
+    inStack[dep.Name].emplace_back(
+      pkgStackEntry{ std::move(dep.VerReq), name });
+  }
+
+  return true;
+}
+
+struct PopulateArguments : CommonArguments
+{
+  cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> providers;
+};
+
+auto const PopulateParser =
+  BIND_COMMON(PopulateArguments)
+    .Bind("BIND_PC_REQUIRES"_s, &PopulateArguments::providers);
+
+std::pair<bool, bool> PopulatePCTarget(PopulateArguments& args,
+                                       cmExecutionStatus& status)
+{
+
+  auto& mf = status.GetMakefile();
+  auto maybeEnv = HandleCommon(args, status);
+
+  if (!maybeEnv) {
+    return { !args.Required, false };
+  }
+  auto& pcEnv = maybeEnv->first;
+  auto& imEnv = maybeEnv->second;
+
+  pkgProviders providers;
+  if (args.providers) {
+    for (auto const& provider_str : *args.providers) {
+      auto assignment = provider_str.find('=');
+      if (assignment != std::string::npos) {
+        providers.emplace(provider_str.substr(0, assignment),
+                          provider_str.substr(assignment + 1));
+      } else {
+        imEnv.status.SetError(cmStrCat(
+          "No '=' found in BIND_PC_REQUIRES argument '", provider_str, "'"));
+        cmSystemTools::SetFatalErrorOccurred();
+        return { false, false };
+      }
+    }
+  }
+
+  pkgStack inStack;
+  std::unordered_map<std::string, cmPkgConfigResult> outStack;
+
+  auto maybePackage = ImportPackage(*args.Package, args.Version, imEnv, pcEnv);
+  if (!maybePackage) {
+    return { !args.Required, false };
+  }
+  imEnv.exact = false;
+
+  if (!CheckPackageDependencies(*args.Package, *maybePackage, inStack,
+                                outStack, providers, imEnv)) {
+    return { !args.Required, false };
+  }
+  outStack[*args.Package] = std::move(*maybePackage);
+
+  while (!inStack.empty()) {
+    auto name = inStack.begin()->first;
+    auto reqs = inStack.begin()->second;
+    maybePackage = ImportPackage(name, reqs, imEnv, pcEnv);
+    if (!maybePackage) {
+      return { !args.Required, false };
+    }
+    if (!CheckPackageDependencies(name, *maybePackage, inStack, outStack,
+                                  providers, imEnv)) {
+      return { !args.Required, false };
+    }
+    inStack.erase(name);
+    outStack[std::move(name)] = std::move(*maybePackage);
+  }
+
+  for (auto& entry : outStack) {
+    CreateCMakeTarget(entry.first, entry.second, providers, mf);
+  }
+
+  return { true, true };
+}
+
+bool HandlePopulateCommand(std::vector<std::string> const& args,
+                           cmExecutionStatus& status)
+{
+  std::vector<std::string> unparsed;
+  auto parsedArgs = PopulateParser.Parse(args, &unparsed);
+
+  auto foreign_name = cmStrCat("@foreign_pkgcfg::", *parsedArgs.Package);
+  auto found_var = cmStrCat("PKGCONFIG_", *parsedArgs.Package, "_FOUND");
+
+  auto& mf = status.GetMakefile();
+
+  if (mf.FindTargetToUse(foreign_name, cmStateEnums::TargetDomain::FOREIGN)) {
+    mf.AddDefinition(found_var, "TRUE");
+    return true;
+  }
+
+  auto result = PopulatePCTarget(parsedArgs, status);
+  mf.AddDefinition(found_var, result.second ? "TRUE" : "FALSE");
+  return result.first;
+}
+
+bool HandleImportCommand(std::vector<std::string> const& args,
+                         cmExecutionStatus& status)
+{
+  std::vector<std::string> unparsed;
+  auto parsedArgs = PopulateParser.Parse(args, &unparsed);
+  auto foreign_name = cmStrCat("@foreign_pkgcfg::", *parsedArgs.Package);
+  auto local_name = cmStrCat("PkgConfig::", *parsedArgs.Package);
+  auto found_var = cmStrCat("PKGCONFIG_", *parsedArgs.Package, "_FOUND");
+
+  auto& mf = status.GetMakefile();
+
+  if (mf.FindTargetToUse(local_name)) {
+    mf.AddDefinition(found_var, "TRUE");
+    return true;
+  }
+
+  if (!mf.FindTargetToUse(foreign_name, cmStateEnums::TargetDomain::FOREIGN)) {
+    auto result = PopulatePCTarget(parsedArgs, status);
+    if (!result.second) {
+      mf.AddDefinition(found_var, "FALSE");
+      return result.first;
+    }
+  }
+
+  mf.AddDefinition(found_var, "TRUE");
+  auto* tgt = mf.AddImportedTarget(
+    local_name, cmStateEnums::TargetType::INTERFACE_LIBRARY, false);
+  tgt->AppendProperty("INTERFACE_LINK_LIBRARIES", foreign_name);
+  return true;
+}
+
 } // namespace
 
 bool cmCMakePkgConfigCommand(std::vector<std::string> const& args,
@@ -716,6 +1019,8 @@ bool cmCMakePkgConfigCommand(std::vector<std::string> const& args,
 
   static cmSubcommandTable const subcommand{
     { "EXTRACT"_s, HandleExtractCommand },
+    { "POPULATE"_s, HandlePopulateCommand },
+    { "IMPORT"_s, HandleImportCommand },
   };
 
   return subcommand(args[0], args, status);

+ 5 - 5
Source/cmMakefile.cxx

@@ -3796,14 +3796,14 @@ cmTarget* cmMakefile::AddImportedTarget(std::string const& name,
 cmTarget* cmMakefile::AddForeignTarget(std::string const& origin,
                                        std::string const& name)
 {
+  auto foreign_name = cmStrCat("@foreign_", origin, "::", name);
   std::unique_ptr<cmTarget> target(new cmTarget(
-    cmStrCat("@foreign_", origin, "::", name),
-    cmStateEnums::TargetType::INTERFACE_LIBRARY, cmTarget::Visibility::Foreign,
-    this, cmTarget::PerConfig::Yes));
+    foreign_name, cmStateEnums::TargetType::INTERFACE_LIBRARY,
+    cmTarget::Visibility::Foreign, this, cmTarget::PerConfig::Yes));
 
-  this->ImportedTargets[name] = target.get();
+  this->ImportedTargets[foreign_name] = target.get();
   this->GetGlobalGenerator()->IndexTarget(target.get());
-  this->GetStateSnapshot().GetDirectory().AddImportedTargetName(name);
+  this->GetStateSnapshot().GetDirectory().AddImportedTargetName(foreign_name);
 
   this->ImportedTargetsOwned.push_back(std::move(target));
   return this->ImportedTargetsOwned.back().get();

+ 44 - 22
Source/cmPkgConfigResolver.cxx

@@ -16,6 +16,7 @@
 #include <cm/string_view>
 
 #include "cmPkgConfigParser.h"
+#include "cmStringAlgorithms.h"
 
 namespace {
 
@@ -57,6 +58,27 @@ std::string AppendAndTrim(std::string& str, cm::string_view sv)
 
 } // namespace
 
+std::string cmPkgConfigVersionReq::string() const
+{
+  switch (Operation) {
+    case ANY:
+      return "";
+    case LT:
+      return cmStrCat("<", Version);
+    case LT_EQ:
+      return cmStrCat("<=", Version);
+    case EQ:
+      return cmStrCat("=", Version);
+    case NEQ:
+      return cmStrCat("!=", Version);
+    case GT_EQ:
+      return cmStrCat(">=", Version);
+    case GT:
+      return cmStrCat(">", Version);
+  }
+  return "";
+}
+
 std::string cmPkgConfigResult::StrOrDefault(std::string const& key,
                                             cm::string_view def)
 {
@@ -127,24 +149,24 @@ cmPkgConfigCflagsResult cmPkgConfigResult::Cflags(bool priv)
 
   auto tokens = cmPkgConfigResolver::TokenizeFlags(cflags);
 
-  if (env.AllowSysCflags) {
-    if (env.SysrootDir) {
-      return cmPkgConfigResolver::MangleCflags(tokens, *env.SysrootDir);
+  if (env->AllowSysCflags) {
+    if (env->SysrootDir) {
+      return cmPkgConfigResolver::MangleCflags(tokens, *env->SysrootDir);
     }
     return cmPkgConfigResolver::MangleCflags(tokens);
   }
 
-  if (env.SysCflags) {
-    if (env.SysrootDir) {
-      return cmPkgConfigResolver::MangleCflags(tokens, *env.SysrootDir,
-                                               *env.SysCflags);
+  if (env->SysCflags) {
+    if (env->SysrootDir) {
+      return cmPkgConfigResolver::MangleCflags(tokens, *env->SysrootDir,
+                                               *env->SysCflags);
     }
-    return cmPkgConfigResolver::MangleCflags(tokens, *env.SysCflags);
+    return cmPkgConfigResolver::MangleCflags(tokens, *env->SysCflags);
   }
 
-  if (env.SysrootDir) {
+  if (env->SysrootDir) {
     return cmPkgConfigResolver::MangleCflags(
-      tokens, *env.SysrootDir, std::vector<std::string>{ "/usr/include" });
+      tokens, *env->SysrootDir, std::vector<std::string>{ "/usr/include" });
   }
 
   return cmPkgConfigResolver::MangleCflags(
@@ -160,24 +182,24 @@ cmPkgConfigLibsResult cmPkgConfigResult::Libs(bool priv)
 
   auto tokens = cmPkgConfigResolver::TokenizeFlags(it->second);
 
-  if (env.AllowSysLibs) {
-    if (env.SysrootDir) {
-      return cmPkgConfigResolver::MangleLibs(tokens, *env.SysrootDir);
+  if (env->AllowSysLibs) {
+    if (env->SysrootDir) {
+      return cmPkgConfigResolver::MangleLibs(tokens, *env->SysrootDir);
     }
     return cmPkgConfigResolver::MangleLibs(tokens);
   }
 
-  if (env.SysLibs) {
-    if (env.SysrootDir) {
-      return cmPkgConfigResolver::MangleLibs(tokens, *env.SysrootDir,
-                                             *env.SysLibs);
+  if (env->SysLibs) {
+    if (env->SysrootDir) {
+      return cmPkgConfigResolver::MangleLibs(tokens, *env->SysrootDir,
+                                             *env->SysLibs);
     }
-    return cmPkgConfigResolver::MangleLibs(tokens, *env.SysLibs);
+    return cmPkgConfigResolver::MangleLibs(tokens, *env->SysLibs);
   }
 
-  if (env.SysrootDir) {
+  if (env->SysrootDir) {
     return cmPkgConfigResolver::MangleLibs(
-      tokens, *env.SysrootDir, std::vector<std::string>{ "/usr/lib" });
+      tokens, *env->SysrootDir, std::vector<std::string>{ "/usr/lib" });
   }
 
   return cmPkgConfigResolver::MangleLibs(
@@ -210,7 +232,7 @@ cm::optional<cmPkgConfigResult> cmPkgConfigResolver::ResolveStrict(
     config.Variables["pc_top_builddir"] = *env.TopBuildDir;
   }
 
-  config.env = std::move(env);
+  config.env = &env;
 
   for (auto const& entry : entries) {
     std::string key(entry.Key);
@@ -288,7 +310,7 @@ cmPkgConfigResult cmPkgConfigResolver::ResolveBestEffort(
     result.Variables["pc_top_builddir"] = *env.TopBuildDir;
   }
 
-  result.env = std::move(env);
+  result.env = &env;
 
   for (auto const& entry : entries) {
     std::string key(entry.Key);

+ 4 - 1
Source/cmPkgConfigResolver.h

@@ -43,6 +43,8 @@ struct cmPkgConfigVersionReq
     GT,
   } Operation = ANY;
   std::string Version;
+
+  std::string string() const;
 };
 
 struct cmPkgConfigDependency
@@ -60,6 +62,7 @@ struct cmPkgConfigEnv
 
   cm::optional<std::string> SysrootDir;
   cm::optional<std::string> TopBuildDir;
+  std::vector<std::string> search;
 
   cm::optional<bool> DisableUninstalled;
 
@@ -84,7 +87,7 @@ public:
   cmPkgConfigCflagsResult Cflags(bool priv = false);
   cmPkgConfigLibsResult Libs(bool priv = false);
 
-  cmPkgConfigEnv env;
+  cmPkgConfigEnv* env;
 
 private:
   std::string StrOrDefault(std::string const& key, cm::string_view def = "");

+ 0 - 0
Tests/RunCMake/cmake_pkg_config/TestEnv-stderr.txt → Tests/RunCMake/cmake_pkg_config/ExtractEnv-stderr.txt


+ 0 - 0
Tests/RunCMake/cmake_pkg_config/TestEnv.cmake → Tests/RunCMake/cmake_pkg_config/ExtractEnv.cmake


+ 0 - 0
Tests/RunCMake/cmake_pkg_config/TestExtract-stderr.txt → Tests/RunCMake/cmake_pkg_config/ExtractFields-stderr.txt


+ 0 - 0
Tests/RunCMake/cmake_pkg_config/TestExtract.cmake → Tests/RunCMake/cmake_pkg_config/ExtractFields.cmake


+ 0 - 0
Tests/RunCMake/cmake_pkg_config/TestMangle-stderr.txt → Tests/RunCMake/cmake_pkg_config/ExtractMangle-stderr.txt


+ 0 - 0
Tests/RunCMake/cmake_pkg_config/TestMangle.cmake → Tests/RunCMake/cmake_pkg_config/ExtractMangle.cmake


+ 0 - 0
Tests/RunCMake/cmake_pkg_config/TestQuiet.cmake → Tests/RunCMake/cmake_pkg_config/ExtractQuiet.cmake


+ 0 - 0
Tests/RunCMake/cmake_pkg_config/TestRequired-result.txt → Tests/RunCMake/cmake_pkg_config/ExtractRequired-result.txt


+ 4 - 0
Tests/RunCMake/cmake_pkg_config/ExtractRequired-stderr.txt

@@ -0,0 +1,4 @@
+CMake Error at ExtractRequired.cmake:[0-9]+ \(cmake_pkg_config\):
+  cmake_pkg_config Could not find pkg-config: 'does-not-exist'
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)

+ 0 - 0
Tests/RunCMake/cmake_pkg_config/TestRequired.cmake → Tests/RunCMake/cmake_pkg_config/ExtractRequired.cmake


+ 0 - 0
Tests/RunCMake/cmake_pkg_config/TestReroot-stderr.txt → Tests/RunCMake/cmake_pkg_config/ExtractReroot-stderr.txt


+ 0 - 0
Tests/RunCMake/cmake_pkg_config/TestReroot.cmake → Tests/RunCMake/cmake_pkg_config/ExtractReroot.cmake


+ 0 - 0
Tests/RunCMake/cmake_pkg_config/TestStrictness-BEST_EFFORT-stderr.txt → Tests/RunCMake/cmake_pkg_config/ExtractStrictness-BEST_EFFORT-stderr.txt


+ 4 - 4
Tests/RunCMake/cmake_pkg_config/TestStrictness-PERMISSIVE-stderr.txt → Tests/RunCMake/cmake_pkg_config/ExtractStrictness-PERMISSIVE-stderr.txt

@@ -1,25 +1,25 @@
-CMake Warning at TestStrictness.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractStrictness.cmake:[0-9]+ \(cmake_pkg_config\):
   Resolution failed for file[^
 ]*(.)*/PackageRoot/no-name.pc'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestStrictness.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractStrictness.cmake:[0-9]+ \(cmake_pkg_config\):
   Resolution failed for file[^
 ]*(.)*/PackageRoot/no-description.pc'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestStrictness.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractStrictness.cmake:[0-9]+ \(cmake_pkg_config\):
   Resolution failed for file[^
 ]*(.)*/PackageRoot/no-version.pc'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestStrictness.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractStrictness.cmake:[0-9]+ \(cmake_pkg_config\):
   Parsing failed for file[^
 ]*(.)*/PackageRoot/invalid.pc'
 Call Stack \(most recent call first\):

+ 5 - 5
Tests/RunCMake/cmake_pkg_config/TestStrictness-STRICT-stderr.txt → Tests/RunCMake/cmake_pkg_config/ExtractStrictness-STRICT-stderr.txt

@@ -1,25 +1,25 @@
-CMake Warning at TestStrictness.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractStrictness.cmake:[0-9]+ \(cmake_pkg_config\):
   Resolution failed for file[^
 ]*(.)*/PackageRoot/no-name.pc'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestStrictness.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractStrictness.cmake:[0-9]+ \(cmake_pkg_config\):
   Resolution failed for file[^
 ]*(.)*/PackageRoot/no-description.pc'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestStrictness.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractStrictness.cmake:[0-9]+ \(cmake_pkg_config\):
   Resolution failed for file[^
 ]*(.)*/PackageRoot/no-version.pc'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestStrictness.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractStrictness.cmake:[0-9]+ \(cmake_pkg_config\):
   Parsing failed for file[^
 ]*(.)*/PackageRoot/invalid.pc'
 Call Stack \(most recent call first\):
@@ -28,7 +28,7 @@ Call Stack \(most recent call first\):
 
 Cflags: lowercase
 CFlags: uppercase
-CMake Warning at TestStrictness.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractStrictness.cmake:[0-9]+ \(cmake_pkg_config\):
   Resolution failed for file[^
 ]*(.)*/PackageRoot/cflags-bothcase-f.pc'
 Call Stack \(most recent call first\):

+ 0 - 0
Tests/RunCMake/cmake_pkg_config/TestStrictness.cmake → Tests/RunCMake/cmake_pkg_config/ExtractStrictness.cmake


+ 0 - 0
Tests/RunCMake/cmake_pkg_config/TestUninstalled-stderr.txt → Tests/RunCMake/cmake_pkg_config/ExtractUninstalled-stderr.txt


+ 0 - 0
Tests/RunCMake/cmake_pkg_config/TestUninstalled.cmake → Tests/RunCMake/cmake_pkg_config/ExtractUninstalled.cmake


+ 17 - 17
Tests/RunCMake/cmake_pkg_config/TestVersion-stderr.txt → Tests/RunCMake/cmake_pkg_config/ExtractVersion-stderr.txt

@@ -1,103 +1,103 @@
-CMake Warning at TestVersion.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractVersion.cmake:[0-9]+ \(cmake_pkg_config\):
   Package 'a' version 'aa' does not meet version requirement '<a'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestVersion.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractVersion.cmake:[0-9]+ \(cmake_pkg_config\):
   Package 'a' version 'aa' does not meet version requirement '>aaa'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestVersion.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractVersion.cmake:[0-9]+ \(cmake_pkg_config\):
   Package 'a' version 'aa' does not meet version requirement '>bb'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestVersion.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractVersion.cmake:[0-9]+ \(cmake_pkg_config\):
   Package 'a' version 'aa' does not meet version requirement '>1'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestVersion.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractVersion.cmake:[0-9]+ \(cmake_pkg_config\):
   Package 'empty-key' version '' does not meet version requirement '!='
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestVersion.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractVersion.cmake:[0-9]+ \(cmake_pkg_config\):
   Package 'empty-key' version '' does not meet version requirement '=0'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestVersion.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractVersion.cmake:[0-9]+ \(cmake_pkg_config\):
   Package 'one' version '11' does not meet version requirement '<1'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestVersion.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractVersion.cmake:[0-9]+ \(cmake_pkg_config\):
   Package 'one' version '11' does not meet version requirement '>111'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestVersion.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractVersion.cmake:[0-9]+ \(cmake_pkg_config\):
   Package 'one' version '11' does not meet version requirement '>22'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestVersion.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractVersion.cmake:[0-9]+ \(cmake_pkg_config\):
   Package 'one' version '11' does not meet version requirement '<a'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestVersion.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractVersion.cmake:[0-9]+ \(cmake_pkg_config\):
   Package 'onedot' version '1.1.1' does not meet version requirement '>1.2.1'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestVersion.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractVersion.cmake:[0-9]+ \(cmake_pkg_config\):
   Package 'onedot' version '1.1.1' does not meet version requirement '>
   1.2.1'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestVersion.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractVersion.cmake:[0-9]+ \(cmake_pkg_config\):
   Package 'onedot' version '1.1.1' does not meet exact version requirement
   '01.01.01'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestVersion.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractVersion.cmake:[0-9]+ \(cmake_pkg_config\):
   Package 'pseudo-empty' version '~0' does not meet version requirement '=~'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestVersion.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractVersion.cmake:[0-9]+ \(cmake_pkg_config\):
   Package 'pseudo-empty' version '~0' does not meet version requirement
   '!=~0'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestVersion.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractVersion.cmake:[0-9]+ \(cmake_pkg_config\):
   Package 'tilde' version '~~1' does not meet version requirement '>~1'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
 
 
-CMake Warning at TestVersion.cmake:[0-9]+ \(cmake_pkg_config\):
+CMake Warning at ExtractVersion.cmake:[0-9]+ \(cmake_pkg_config\):
   Package 'tilde' version '~~1' does not meet version requirement '<~~~1'
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)

+ 0 - 0
Tests/RunCMake/cmake_pkg_config/TestVersion.cmake → Tests/RunCMake/cmake_pkg_config/ExtractVersion.cmake


+ 14 - 0
Tests/RunCMake/cmake_pkg_config/ImportRequires-check.cmake

@@ -0,0 +1,14 @@
+set(expected
+  "alpha: Alpha
+bravo: Bravo;Alpha
+charlie: Charlie;Bravo;Alpha
+delta: Delta
+echo: Echo;Bravo;Alpha;Delta
+"
+)
+
+file(READ "${RunCMake_TEST_BINARY_DIR}/import-requires.txt" actual)
+
+if(NOT(expected STREQUAL actual))
+  set(RunCMake_TEST_FAILED "cmake_pkg_config import-requires.txt does not match expected:\n${actual}")
+endif()

+ 18 - 0
Tests/RunCMake/cmake_pkg_config/ImportRequires.cmake

@@ -0,0 +1,18 @@
+set(CMAKE_PKG_CONFIG_PC_PATH ${CMAKE_CURRENT_LIST_DIR}/PackageRoot/RequiresPackages)
+
+cmake_pkg_config(IMPORT echo REQUIRED)
+cmake_pkg_config(IMPORT delta REQUIRED)
+cmake_pkg_config(IMPORT charlie REQUIRED)
+cmake_pkg_config(IMPORT bravo REQUIRED)
+cmake_pkg_config(IMPORT alpha REQUIRED)
+
+file(GENERATE
+  OUTPUT import-requires.txt
+  CONTENT
+  "alpha: $<TARGET_PROPERTY:PkgConfig::alpha,INTERFACE_COMPILE_OPTIONS>
+bravo: $<TARGET_PROPERTY:PkgConfig::bravo,INTERFACE_COMPILE_OPTIONS>
+charlie: $<TARGET_PROPERTY:PkgConfig::charlie,INTERFACE_COMPILE_OPTIONS>
+delta: $<TARGET_PROPERTY:PkgConfig::delta,INTERFACE_COMPILE_OPTIONS>
+echo: $<TARGET_PROPERTY:PkgConfig::echo,INTERFACE_COMPILE_OPTIONS>
+"
+)

+ 15 - 0
Tests/RunCMake/cmake_pkg_config/ImportSimple-check.cmake

@@ -0,0 +1,15 @@
+set(expected
+"Import Simple Found: TRUE
+Include Directories: ${RunCMake_SOURCE_DIR}/TestDirectories/Include
+Compile Options: TestCflag
+Link Directories: ${RunCMake_SOURCE_DIR}/TestDirectories/Library
+Link Libraries: @foreign_pkgcfg::import-simple
+Link Options: TestLinkOption
+"
+)
+
+file(READ "${RunCMake_TEST_BINARY_DIR}/import-simple.txt" actual)
+
+if(NOT(expected STREQUAL actual))
+  set(RunCMake_TEST_FAILED "cmake_pkg_config import-simple.txt does not match expected:\n${actual}")
+endif()

+ 15 - 0
Tests/RunCMake/cmake_pkg_config/ImportSimple.cmake

@@ -0,0 +1,15 @@
+set(CMAKE_PKG_CONFIG_SYSROOT_DIR ${CMAKE_CURRENT_LIST_DIR})
+
+cmake_pkg_config(IMPORT import-simple REQUIRED)
+
+file(GENERATE
+  OUTPUT import-simple.txt
+  CONTENT
+"Import Simple Found: ${PKGCONFIG_import-simple_FOUND}
+Include Directories: $<TARGET_PROPERTY:PkgConfig::import-simple,INTERFACE_INCLUDE_DIRECTORIES>
+Compile Options: $<TARGET_PROPERTY:PkgConfig::import-simple,INTERFACE_COMPILE_OPTIONS>
+Link Directories: $<TARGET_PROPERTY:PkgConfig::import-simple,INTERFACE_LINK_DIRECTORIES>
+Link Libraries: $<TARGET_PROPERTY:PkgConfig::import-simple,INTERFACE_LINK_LIBRARIES>
+Link Options: $<TARGET_PROPERTY:PkgConfig::import-simple,INTERFACE_LINK_OPTIONS>
+"
+)

+ 1 - 0
Tests/RunCMake/cmake_pkg_config/ImportTransitiveFail-result.txt

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

+ 11 - 0
Tests/RunCMake/cmake_pkg_config/ImportTransitiveFail-stderr.txt

@@ -0,0 +1,11 @@
+CMake Warning at ImportTransitiveFail.cmake:[0-9]+ \(cmake_pkg_config\):
+  Could not find pkg-config: 'foxtrot' required by: 'golf'
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
+
+
+Import Golf Found: FALSE
+CMake Error at ImportTransitiveFail.cmake:[0-9]+ \(cmake_pkg_config\):
+  cmake_pkg_config Could not find pkg-config: 'foxtrot' required by: 'golf'
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)

+ 5 - 0
Tests/RunCMake/cmake_pkg_config/ImportTransitiveFail.cmake

@@ -0,0 +1,5 @@
+set(CMAKE_PKG_CONFIG_PC_PATH ${CMAKE_CURRENT_LIST_DIR}/PackageRoot/RequiresPackages)
+
+cmake_pkg_config(IMPORT golf)
+message("Import Golf Found: ${PKGCONFIG_golf_FOUND}")
+cmake_pkg_config(IMPORT golf REQUIRED)

+ 3 - 0
Tests/RunCMake/cmake_pkg_config/ImportTransitiveVersion.cmake

@@ -0,0 +1,3 @@
+set(CMAKE_PKG_CONFIG_PC_PATH ${CMAKE_CURRENT_LIST_DIR}/PackageRoot/RequiresPackages)
+
+cmake_pkg_config(IMPORT india)

+ 5 - 0
Tests/RunCMake/cmake_pkg_config/ImportTransitiveVersionFail-stderr.txt

@@ -0,0 +1,5 @@
+CMake Warning at ImportTransitiveVersionFail.cmake:[0-9]+ \(cmake_pkg_config\):
+  Package 'alpha' version '1.0.0' does not meet version requirement '>=2.0.0'
+  of 'hotel'
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)

+ 4 - 0
Tests/RunCMake/cmake_pkg_config/ImportTransitiveVersionFail.cmake

@@ -0,0 +1,4 @@
+set(CMAKE_PKG_CONFIG_PC_PATH ${CMAKE_CURRENT_LIST_DIR}/PackageRoot/RequiresPackages)
+
+cmake_pkg_config(POPULATE bravo)
+cmake_pkg_config(IMPORT hotel)

+ 5 - 0
Tests/RunCMake/cmake_pkg_config/PackageRoot/RequiresPackages/alpha.pc

@@ -0,0 +1,5 @@
+Name: Alpha
+Description: Alpha
+Version: 1.0.0
+
+Cflags: Alpha

+ 6 - 0
Tests/RunCMake/cmake_pkg_config/PackageRoot/RequiresPackages/bravo.pc

@@ -0,0 +1,6 @@
+Name: Bravo
+Description: Bravo
+Version: 1.0.0
+
+Cflags: Bravo
+Requires: alpha

+ 6 - 0
Tests/RunCMake/cmake_pkg_config/PackageRoot/RequiresPackages/charlie.pc

@@ -0,0 +1,6 @@
+Name: Charlie
+Description: Charlie
+Version: 1.0.0
+
+Cflags: Charlie
+Requires: bravo

+ 5 - 0
Tests/RunCMake/cmake_pkg_config/PackageRoot/RequiresPackages/delta.pc

@@ -0,0 +1,5 @@
+Name: Delta
+Description: Delta
+Version: 1.0.0
+
+Cflags: Delta

+ 6 - 0
Tests/RunCMake/cmake_pkg_config/PackageRoot/RequiresPackages/echo.pc

@@ -0,0 +1,6 @@
+Name: Echo
+Description: Echo
+Version: 1.0.0
+
+Cflags: Echo
+Requires: bravo delta

+ 6 - 0
Tests/RunCMake/cmake_pkg_config/PackageRoot/RequiresPackages/golf.pc

@@ -0,0 +1,6 @@
+Name: Golf
+Description: Golf
+Version: 1.0.0
+
+Cflags: Golf
+Requires: foxtrot

+ 6 - 0
Tests/RunCMake/cmake_pkg_config/PackageRoot/RequiresPackages/hotel.pc

@@ -0,0 +1,6 @@
+Name: Hotel
+Description: Hotel
+Version: 1.0.0
+
+Cflags: Hotel
+Requires: alpha >= 2.0.0

+ 6 - 0
Tests/RunCMake/cmake_pkg_config/PackageRoot/RequiresPackages/india.pc

@@ -0,0 +1,6 @@
+Name: India
+Description: India
+Version: 1.0.0
+
+Cflags: India
+Requires: alpha = 1.0.0 bravo > 0.5.0

+ 6 - 0
Tests/RunCMake/cmake_pkg_config/PackageRoot/RequiresPackages/juliet.pc

@@ -0,0 +1,6 @@
+Name: Juliet
+Description: Juliet
+Version: 1.0.0
+
+Cflags: Juliet
+Requires: golf

+ 6 - 0
Tests/RunCMake/cmake_pkg_config/PackageRoot/import-simple.pc

@@ -0,0 +1,6 @@
+Name: Import Simple
+Description: A simple import with no dependencies
+Version: 1.0.0
+
+Cflags: -I/TestDirectories/Include TestCflag
+Libs: -L/TestDirectories/Library -ldummy TestLinkOption

+ 8 - 0
Tests/RunCMake/cmake_pkg_config/PopulateFoundVar-stderr.txt

@@ -0,0 +1,8 @@
+Found Alpha: TRUE
+CMake Warning at PopulateFoundVar.cmake:[0-9]+ \(cmake_pkg_config\):
+  Could not find pkg-config: 'foxtrot'
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
+
+
+Found Foxtrot: FALSE

+ 7 - 0
Tests/RunCMake/cmake_pkg_config/PopulateFoundVar.cmake

@@ -0,0 +1,7 @@
+set(CMAKE_PKG_CONFIG_PC_PATH ${CMAKE_CURRENT_LIST_DIR}/PackageRoot/RequiresPackages)
+
+cmake_pkg_config(POPULATE alpha)
+message("Found Alpha: ${PKGCONFIG_alpha_FOUND}")
+
+cmake_pkg_config(POPULATE foxtrot)
+message("Found Foxtrot: ${PKGCONFIG_foxtrot_FOUND}")

+ 10 - 0
Tests/RunCMake/cmake_pkg_config/PopulateMissing-check.cmake

@@ -0,0 +1,10 @@
+set(expected
+  "juliet: Juliet;Golf;Foxtrot
+"
+)
+
+file(READ "${RunCMake_TEST_BINARY_DIR}/populate-missing.txt" actual)
+
+if(NOT(expected STREQUAL actual))
+  set(RunCMake_TEST_FAILED "cmake_pkg_config populate-missing.txt does not match expected:\n${actual}")
+endif()

+ 19 - 0
Tests/RunCMake/cmake_pkg_config/PopulateMissing.cmake

@@ -0,0 +1,19 @@
+set(CMAKE_PKG_CONFIG_PC_PATH ${CMAKE_CURRENT_LIST_DIR}/PackageRoot/RequiresPackages)
+
+add_library(native-foxtrot INTERFACE)
+target_compile_options(native-foxtrot INTERFACE Foxtrot)
+
+cmake_pkg_config(
+  POPULATE golf
+  BIND_PC_REQUIRES
+    foxtrot=native-foxtrot
+)
+
+cmake_pkg_config(IMPORT juliet)
+
+file(GENERATE
+  OUTPUT populate-missing.txt
+  CONTENT
+  "juliet: $<TARGET_PROPERTY:PkgConfig::juliet,INTERFACE_COMPILE_OPTIONS>
+"
+)

+ 17 - 10
Tests/RunCMake/cmake_pkg_config/RunCMakeTest.cmake

@@ -3,16 +3,23 @@ include(RunCMake)
 set(cmd ${CMAKE_COMMAND} ${CMAKE_CURRENT_LIST_DIR} -G ${RunCMake_GENERATOR})
 
 foreach(strictness IN ITEMS STRICT PERMISSIVE BEST_EFFORT)
-  run_cmake_command(TestStrictness-${strictness} ${cmd}
-    -DRunCMake_TEST=TestStrictness -DSTRICTNESS=${strictness}
+  run_cmake_command(ExtractStrictness-${strictness} ${cmd}
+    -DRunCMake_TEST=ExtractStrictness -DSTRICTNESS=${strictness}
   )
 endforeach()
 
-run_cmake(TestEnv)
-run_cmake(TestExtract)
-run_cmake(TestMangle)
-run_cmake(TestQuiet)
-run_cmake(TestRequired)
-run_cmake(TestReroot)
-run_cmake(TestUninstalled)
-run_cmake(TestVersion)
+run_cmake(ExtractEnv)
+run_cmake(ExtractFields)
+run_cmake(ExtractMangle)
+run_cmake(ExtractQuiet)
+run_cmake(ExtractRequired)
+run_cmake(ExtractReroot)
+run_cmake(ExtractUninstalled)
+run_cmake(ExtractVersion)
+run_cmake(ImportSimple)
+run_cmake(ImportRequires)
+run_cmake(ImportTransitiveFail)
+run_cmake(ImportTransitiveVersion)
+run_cmake(ImportTransitiveVersionFail)
+run_cmake(PopulateFoundVar)
+run_cmake(PopulateMissing)

+ 0 - 0
Tests/RunCMake/cmake_pkg_config/TestDirectories/Include/dummy-header.h


+ 0 - 0
Tests/RunCMake/cmake_pkg_config/TestDirectories/Library/libdummy


+ 0 - 4
Tests/RunCMake/cmake_pkg_config/TestRequired-stderr.txt

@@ -1,4 +0,0 @@
-CMake Error at TestRequired.cmake:[0-9]+ \(cmake_pkg_config\):
-  cmake_pkg_config Could not find 'does-not-exist'
-Call Stack \(most recent call first\):
-  CMakeLists.txt:[0-9]+ \(include\)