源码视角看CMake在Config模式下目录搜寻规则

先看看官方的解释:
https://cmake.org/cmake/help/v3.29/command/find_package.html

Config模式下搜索路径规则如下表:
在这里插入图片描述

其中前缀部分主要涉及的变量是:

  • <PackageName>_DIR
  • CMAKE_PREFIX_PATH
  • CMAKE_FRAMEWORK_PATH
  • CMAKE_APPBUNDLE_PATH
  • PATH(以/bin或/sbin结尾的路径条目会自动转换为它们的父目录)

W/U原文说明如下:

This set of directories is intended to work in cooperation with projects that provide configuration files in their installation trees. Directories above marked with (W) are intended for installations on Windows where the prefix may point at the top of an application’s installation directory. Those marked with (U) are intended for installations on UNIX platforms where the prefix is shared by multiple packages. This is merely a convention, so all (W) and (U) directories are still searched on all platforms. Directories marked with (A) are intended for installations on Apple platforms.

怎么理解这里的 W/U的区别呢, 下面结合源码看看,
请看源码
https://github.com/Kitware/CMake/blob/228fd59897dd2f58ecfd83e3d98348339b38b52c/Source/cmFindPackageCommand.cxx#L2636片段

// cmFindPackageCommand::SearchPrefix
bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
{
  assert(!prefix_in.empty() && prefix_in.back() == '/');

  // Skip this if the prefix does not exist.
  if (!cmSystemTools::FileIsDirectory(prefix_in)) {
    return false;
  }

  // Skip this if it's in ignored paths.
  std::string prefixWithoutSlash = prefix_in;
  if (prefixWithoutSlash != "/" && prefixWithoutSlash.back() == '/') {
    prefixWithoutSlash.erase(prefixWithoutSlash.length() - 1);
  }
  if (this->IgnoredPaths.count(prefixWithoutSlash) ||
      this->IgnoredPrefixPaths.count(prefixWithoutSlash)) {
    return false;
  }

  // PREFIX/ (useful on windows or in build trees)
  if (this->SearchDirectory(prefix_in)) {
    return true;
  }

  // Strip the trailing slash because the path generator is about to
  // add one.
  std::string const prefix = prefix_in.substr(0, prefix_in.size() - 1);

  auto searchFn = [this](const std::string& fullPath) -> bool {
    return this->SearchDirectory(fullPath);
  };

  auto iCMakeGen = cmCaseInsensitiveDirectoryListGenerator{ "cmake"_s };
  auto firstPkgDirGen =
    cmProjectDirectoryListGenerator{ this->Names, this->SortOrder,
                                     this->SortDirection };

  // PREFIX/(cmake|CMake)/ (useful on windows or in build trees)
  if (TryGeneratedPaths(searchFn, prefix, iCMakeGen)) {
    return true;
  }

  // PREFIX/(Foo|foo|FOO).*/
  if (TryGeneratedPaths(searchFn, prefix, firstPkgDirGen)) {
    return true;
  }

  // PREFIX/(Foo|foo|FOO).*/(cmake|CMake)/
  if (TryGeneratedPaths(searchFn, prefix, firstPkgDirGen, iCMakeGen)) {
    return true;
  }

  auto secondPkgDirGen =
    cmProjectDirectoryListGenerator{ this->Names, this->SortOrder,
                                     this->SortDirection };

  // PREFIX/(Foo|foo|FOO).*/(cmake|CMake)/(Foo|foo|FOO).*/
  if (TryGeneratedPaths(searchFn, prefix, firstPkgDirGen, iCMakeGen,
                        secondPkgDirGen)) {
    return true;
  }

  // Construct list of common install locations (lib and share).
  std::vector<cm::string_view> common;
  std::string libArch;
  if (!this->LibraryArchitecture.empty()) {
    libArch = "lib/" + this->LibraryArchitecture;
    common.emplace_back(libArch);
  }
  if (this->UseLib32Paths) {
    common.emplace_back("lib32"_s);
  }
  if (this->UseLib64Paths) {
    common.emplace_back("lib64"_s);
  }
  if (this->UseLibx32Paths) {
    common.emplace_back("libx32"_s);
  }
  common.emplace_back("lib"_s);
  common.emplace_back("share"_s);

  auto cmnGen = cmEnumPathSegmentsGenerator{ common };
  auto cmakeGen = cmAppendPathSegmentGenerator{ "cmake"_s };

  // PREFIX/(lib/ARCH|lib*|share)/cmake/(Foo|foo|FOO).*/
  if (TryGeneratedPaths(searchFn, prefix, cmnGen, cmakeGen, firstPkgDirGen)) {
    return true;
  }

  // PREFIX/(lib/ARCH|lib*|share)/(Foo|foo|FOO).*/
  if (TryGeneratedPaths(searchFn, prefix, cmnGen, firstPkgDirGen)) {
    return true;
  }

  // PREFIX/(lib/ARCH|lib*|share)/(Foo|foo|FOO).*/(cmake|CMake)/
  if (TryGeneratedPaths(searchFn, prefix, cmnGen, firstPkgDirGen, iCMakeGen)) {
    return true;
  }

  // PREFIX/(Foo|foo|FOO).*/(lib/ARCH|lib*|share)/cmake/(Foo|foo|FOO).*/
  if (TryGeneratedPaths(searchFn, prefix, firstPkgDirGen, cmnGen, cmakeGen,
                        secondPkgDirGen)) {
    return true;
  }

  // PREFIX/(Foo|foo|FOO).*/(lib/ARCH|lib*|share)/(Foo|foo|FOO).*/
  if (TryGeneratedPaths(searchFn, prefix, firstPkgDirGen, cmnGen,
                        secondPkgDirGen)) {
    return true;
  }

  // PREFIX/(Foo|foo|FOO).*/(lib/ARCH|lib*|share)/(Foo|foo|FOO).*/(cmake|CMake)/
  return TryGeneratedPaths(searchFn, prefix, firstPkgDirGen, cmnGen,
                           secondPkgDirGen, iCMakeGen);
}

读完源码, 可以看出, 所有平台上,W,U,W/U路径都会搜寻.

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-13 01:42:01       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-13 01:42:01       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-13 01:42:01       58 阅读
  4. Python语言-面向对象

    2024-07-13 01:42:01       69 阅读

热门阅读

  1. SSH协议

    SSH协议

    2024-07-13 01:42:01      18 阅读
  2. 【Spring Boot】spring boot主启动类_内置服务

    2024-07-13 01:42:01       21 阅读
  3. qt 折线图

    2024-07-13 01:42:01       21 阅读
  4. 【Linux】02.shell命令及其运行原理

    2024-07-13 01:42:01       23 阅读
  5. RAG的上限在哪里?边界在哪里?

    2024-07-13 01:42:01       21 阅读
  6. 我的大事记

    2024-07-13 01:42:01       19 阅读
  7. 每天一个数据分析题(四百二十八)- 方差分析

    2024-07-13 01:42:01       24 阅读
  8. C++ 函数返回值是void* 使用场景

    2024-07-13 01:42:01       23 阅读
  9. 2974.最小数字游戏

    2024-07-13 01:42:01       21 阅读
  10. ahb 总线的一些思考

    2024-07-13 01:42:01       24 阅读
  11. 级联目标检测:构建高效目标识别的多阶段策略

    2024-07-13 01:42:01       23 阅读
  12. C语言8 数组与字符串

    2024-07-13 01:42:01       21 阅读
  13. 人工智能讲座——深度学习实现行人重识别

    2024-07-13 01:42:01       23 阅读
  14. LeetCode 算法:全排列 c++

    2024-07-13 01:42:01       24 阅读