CMake中find_package的使用

      CMake中的命令find_package用于查找指定的package

      find_package支持两种主要的搜索方法注意:<PackageName>是区分大小写的
      (1).Config mode(配置模式):使用该方法,find_package会查找通常由package本身提供的文件在这种模式下,CMake会搜索名为<lowercasePackageName>-config.cmake或<PackageName>Config.cmake的文件,如OpenCV生成的库中的OpenCVConfig.cmake文件。如果指定了版本详细信息,它还将查找<lowercasePackageName>-config-version.cmake或<PackageName>ConfigVersion.cmake。config和version files通常作为package的一部分安装,因此它们往往比Find modules更可靠。它们通常包含对package内容的直接了解,因此在config或version files本身中不需要搜索或启发(searching or heuristics)。find_package的基本签名(basic signature)和完整签名(full signature)都支持这种模式

      config-file packages:config file是package附带的文本文件,用于定义CMake targets, variables, commands等等。config file是一个普通的CMake脚本,由find_package命令读入。config files通常可以在lib/cmake/<PackageName>匹配的目录中找到,如编译OpenCV 4.6.0源码时生成的OpenCVConfig.cmake文件在lib/cmake/opencv4目录下,config files也可能位于其它位置。<PackageName>通常是find_package命令第一个参数,甚至可能是唯一的参数
      config file必须命名为<PackageName>Config.cmake或<LowercasePackageName>-config.cmake。此文件是package的入口点。<PackageName>Config.cmake或<LowercasePackageName>-config.cmake也可能存在于同一目录中。CMake使用此文件来确定package的版本是否满足对find_package的调用中包含的任何版本约束。在调用find_package时指定版本是可选的,即使存在<PackageName>ConfigVersion.cmake文件。
      如果找到<PackageName>Config.cmake文件并且满足任何版本约束(version constraint),则find_package命令认为已找到该package,并假定整个package按设计完成。
      如果package的位置在CMake已知的目录中,则find_package调用应该成功。CMake已知的目录是特定于平台(platform-specific)的。例如,在Linux上使用标准系统包管理器(standard system package manager)安装的package将自动在/usr前缀中找到。在Windows上安装在Program Files中的package同样会被自动找到。
      如果package位于CMake不知道的位置,例如/opt/lib,则不会在没有帮助的情况下自动找到它们。这是正常情况,CMake为用户提供了几种方法指定在哪里可以找到此类库。
      CMAKE_PREFIX_PATH变量可以在调用CMake时设置。它被视为搜索config file的基本路径列表。安装在/opt/lib/somepackage中的package通常会安装config file,例如/opt/lib/somepackage/lib/cmake/SomePackageConfig.cmake。在这种情况下,应将/opt/lib/somepackage添加到CMAKE_PREFIX_PATH。
      环境变量CMAKE_PREFIX_PATH也可以填充前缀以搜索package。与PATH环境变量一样,这是一个列表,但它需要使用特定于平台的环境变量列表项分隔符,如在Linux上为":",在Windows上为";"。
      CMAKE_PREFIX_PATH变量在需要指定多个前缀的情况下提供了便利,或者当多个package在同一前缀下可用时。也可以通过设置匹配<PackageName>_DIR的变量来指定package的路径,例如SomePackage_DIR。注意,这不是前缀,而应该是包含config-style package文件的目录的完整路径,例如上面的/opt/lib/somepackage/lib/cmake。
      (2).Module mode(模块模式):并非所有packages都支持CMake,许多不提供支持config modes所需的文件。对于这种情况,可以由项目(project)或CMake单独提供Find module文件。Find module通常是一种启发式实现(heuristic implementation),它知道package通常提供什么以及如何将该package呈现给项目(project)。由于Find module通常与package分开发布(distribute),因此它们不那么可靠。它们通常是单独维护的,并且可能遵循不同的发布时间表,因此它们很容易过时在这种模式下,CMake搜索名为Find<PackageName>.cmake的文件,如OpenCV源码中cmake/FindCUDA.cmake文件。首先在CMAKE_MODULE_PATH中列出的位置中查找,然后在CMake安装提供的Find Modules中查找。如果找到该文件,则由CMake读取并处理该文件。该文件负责查找package、检查版本并生成任何需要的消息(message)。Find<PackageName>.cmake文件通常不由package本身提供。相反它通常由package外部的东西提供,例如操作系统、CMake本身、甚至是调用find_package命令的项目。Module mode仅被find_package的基本签名支持
      根据使用的参数,find_package可以使用上述方法之一或两者。
      通过将选项限制为仅基本签名(basic signature),可以使用config mode和module mode来满足依赖关系。其它选项的存在可能会将调用限制为仅用两种方法中的一种,从而可能降低find_package查找依赖项的能力。

      Find Module Files:如果FindSomePackage.cmake文件可用,仍然可以使用find_package命令找到不提供config file的package。这些Find module files与config files的不同之处在于
      A.Find module files不应由package本身提供。
      B.Find<PackageName>.cmake文件的可用性并不表示package或package的任何特定部分的可用性。
      C.CMake不会在CMAKE_PREFIX_PATH变量中指定的位置搜索Find<PackageName>.cmake文件。相反,CMake在CMAKE_MODULE_PATH变量给定的位置搜索此类文件。用户在运行CMake时设置CMAKE_MODULE_PATH是很常见的,CMake projects通常会附加到(append to)CMAKE_MODULE_PATH以允许使用本地Find module files。
      D.CMake为某些第三方packages提供Find<PackageName>.cmake文件。这些文件由CMake维护,并且这些文件落后于与其关联的packages的最新版本并不罕见。通常,新的Find modules不再添加到CMake。
      (3).FetchContent redirection mode:3.24版本中引入。对find_package的调用可以在内部重定向到FetchContent module提供的package。对调用者而言,此行为类似于Config mode,只是绕过了搜索逻辑并且不使用组件信息。
      当未重定向到FetchContent提供的package时,由find_package参数决定使用Module mode还是Config mode。
      当使用基本签名时,find_package首先在Module mode下搜索。如果未找到package,则搜索回退到Config mode。用户可以将CMAKE_FIND_PACKAGE_PREFER_CONFIG变量设置为true以反转优先级并指示CMake在返回到Module mode之前首先使用Config mode进行搜索。也可以强制基本签名仅使用带有MODULE关键字的Module mode。如果使用完整签名,则find_package仅在Config mode下搜索。
      在可能的情况下,用户代码通常应该使用基本签名来查找package,因为这样可以在任何mode下找到package。

      Imported Targets:表示一个预先存在的依赖性。通常这样的targets是由上游package定义的,应该被视为不可变的。在声明一个Imported Target之后,可以像使用任何其它常规target一样,使用诸如target_compile_definitions, target_include_directories, target_compile_options或target_link_libraries之类的命令来调整其target属性。
      config files和Find module files都可以定义Imported Targets。这些通常具有SomePrefix::ThingName形式的名称。

      find_package的基本签名(Basic Signature)如下:

find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
             [REQUIRED] [[COMPONENTS] [components...]]
             [OPTIONAL_COMPONENTS components...]
             [REGISTRY_VIEW  (64|32|64_32|32_64|HOST|TARGET|BOTH)]
             [GLOBAL]
             [NO_POLICY_SCOPE]
             [BYPASS_PROVIDER]
)

      Module和Config modes都支持基本签名。选项包括:无论使用何种模式,都会设置一个<PackageName>_FOUND变量来指示是否找到了package。当找到package时,可以通过package本身记录的其它变量和导入的目标(Imported Targets)来提供package特定的信息(package-specific information)。
      (1).MODULE:意味着只能使用Module mode来查找package,而不能回退到Config mode。示例代码段如下:

find_package(OpenCV) # Found OpenCV: /usr (found version "4.5.4")
message("OpenCV_FOUND: ${OpenCV_FOUND}") # OpenCV_FOUND: 1
message("OpenCV_INCLUDE_DIRS: ${OpenCV_INCLUDE_DIRS}") # OpenCV_INCLUDE_DIRS: /usr/include/opencv4

find_package(OpenCV MODULE) # CMake Warning at test_find_package.cmake:10 (find_package): No "FindOpenCV.cmake" found in CMAKE_MODULE_PATH
message("CMAKE_MODULE_PATH: ${CMAKE_MODULE_PATH}") # CMAKE_MODULE_PATH:
message("OpenCV_FOUND: ${OpenCV_FOUND}") # OpenCV_FOUND: 0

      (2).QUIET:禁用消息性消息(disables informational messages),包括那些指示如果package不是REQUIRED则无法找到的消息。示例代码段如下:

find_package(OpenCV QUIET) # 不会再显示: Found OpenCV: /usr (found version "4.5.4")
message("OpenCV_FOUND: ${OpenCV_FOUND}") # OpenCV_FOUND: 1

find_package(OpenCV MODULE QUIET) # 不会再显示: CMake Warning at test_find_package.cmake:17 (find_package): No "FindOpenCV.cmake" found in CMAKE_MODULE_PATH
message("OpenCV_FOUND: ${OpenCV_FOUND}") # OpenCV_FOUND: 0

      (3).REQUIRED:如果找不到package,则REQUIRED选项会停止处理并触发错误消息。示例代码段如下:

find_package(OpenCV MODULE REQUIRED) # CMake Error at test_find_package.cmake:20 (find_package): No "FindOpenCV.cmake" found in CMAKE_MODULE_PATH

      (4).COMPONENTS:此关键字之后可能会列出所需组件的特定于package(package-specific)列表。如果不能满足这些组件中的任何一个,则认为未找到整个package。如果还存在REQUIRED选项,则将其视为fatal error,否则仍会继续执行。作为一种简写模式,如果存在REQUIRED选项,则可以省略COMPONENTS关键字,并且可以在REQUIRED之后直接列出所需的组件。示例代码段如下:

find_package(OpenCV COMPONENTS opencv_core) # Found OpenCV: /usr (found version "4.5.4") found components: opencv_core
message("OpenCV_FOUND: ${OpenCV_FOUND}") # OpenCV_FOUND: 1

find_package(OpenCV COMPONENTS opencv_xxxx) # Could NOT find OpenCV (missing: opencv_xxxx) (found version "4.5.4"))
                                            # CMake Warning at test_find_package.cmake:25 (find_package): Found package configuration file:
                                            # /usr/lib/x86_64-linux-gnu/cmake/opencv4/OpenCVConfig.cmake
                                            # but it set OpenCV_FOUND to FALSE so package "OpenCV" is considered to be NOT FOUND.
message("OpenCV_FOUND: ${OpenCV_FOUND}") # OpenCV_FOUND: 0

      (5).OPTIONAL_COMPONENTS:其它可选组件可能会在OPTIONAL_COMPONENTS之后列出。如果这些都不能满足,只要满足所有必需的组件,仍然可以认为整个package都找到了
可用组件的集合及其含义由target package定义。示例代码段如下:

find_package(OpenCV COMPONENTS opencv_core  opencv_highgui) # Found OpenCV: /usr (found version "4.5.4") found components: opencv_core opencv_highgui
message("OpenCV_FOUND: ${OpenCV_FOUND}") # OpenCV_FOUND: 1

find_package(OpenCV COMPONENTS opencv_core opencv_highgui OPTIONAL_COMPONENTS opencv_xxxx opencv_yyyy) # Found OpenCV: /usr (found version "4.5.4") found components: opencv_core opencv_highgui missing components: opencv_xxxx opencv_yyyy
message("OpenCV_FOUND: ${OpenCV_FOUND}") # OpenCV_FOUND: 1

      (6).REGISTRY_VIEW:3.24版本中引入。指定应要查询的注册表视图(registry views)。此选项仅在Windows平台上有意义,在其它平台上将被忽略。
      (7).GLOBAL:3.24版本中引入。指定此关键字会将所有imported targets提升到导入项目(improting project)的全局范围。或者可以通过设置CMAKE_FIND_PACKAGE_TARGETS_GLOBAL变量来启用此功能。
      (8).version:此参数请求找到的package应该兼容的版本。有两种可能的形式可以指定它:
      单个版本(single version):格式为:major[.minor[.patch[.tweak]]],其中每个组件都是一个数值。
      版本范围(version range):3.19版本中引入。格式为:versionMin...[<]versionMax,其中versionMin和versionMax具有与单个版本相同的格式和约束。默认情况下,两个端点都包括在内。通过指定<,将排除上端点(the upper end point will be excluded)。

find_package(OpenCV 3.4.2) # Found OpenCV: /opt/opencv3.4.2 (found suitable version "3.4.2", minimum required is "3.4.2")
message("OpenCV_FOUND: ${OpenCV_FOUND}") # OpenCV_FOUND: 1
message("OpenCV_INCLUDE_DIRS: ${OpenCV_INCLUDE_DIRS}") # OpenCV_INCLUDE_DIRS: /opt/opencv3.4.2/include;/opt/opencv3.4.2/include/opencv

find_package(OpenCV 2.4.13.7) # CMake Warning at test_find_package.cmake:41 (find_package):
                                # Could not find a configuration file for package "OpenCV" that is compatible with requested version "2.4.13.7".
                                # The following configuration files were considered but not accepted:
                                #   /opt/opencv3.4.2/share/OpenCV/OpenCVConfig.cmake, version: 3.4.2
                                #   /usr/lib/x86_64-linux-gnu/cmake/opencv4/OpenCVConfig.cmake, version: 4.5.4
                                #   /lib/x86_64-linux-gnu/cmake/opencv4/OpenCVConfig.cmake, version: 4.5.4
                                #   /opt/opencv3.1/share/OpenCV/OpenCVConfig.cmake, version: 3.1.0
message("OpenCV_FOUND: ${OpenCV_FOUND}") # OpenCV_FOUND: 0

      (9).EXACT:此选项要求version完全匹配。此选项与version range的规范不兼容。

find_package(OpenCV 3.4.2) # Found OpenCV: /opt/opencv3.4.2 (found suitable version "3.4.2", minimum required is "3.4.2")
message("OpenCV_FOUND: ${OpenCV_FOUND}") # OpenCV_FOUND: 1
message("OpenCV_INCLUDE_DIRS: ${OpenCV_INCLUDE_DIRS}") # OpenCV_INCLUDE_DIRS: /opt/opencv3.4.2/include;/opt/opencv3.4.2/include/opencv

find_package(OpenCV 3.0.0) # Found OpenCV: /opt/opencv3.4.2 (found suitable version "3.4.2", minimum required is "3.0.0")
message("OpenCV_FOUND: ${OpenCV_FOUND}") # OpenCV_FOUND: 1

find_package(OpenCV 3.0.0 EXACT) # CMake Warning at test_find_package.cmake:57 (find_package):
                                    # Could not find a configuration file for package "OpenCV" that exactly matches requested version "3.0.0".
                                    # The following configuration files were considered but not accepted:
                                    #  /opt/opencv3.4.2/share/OpenCV/OpenCVConfig.cmake, version: 3.4.2
                                    #  /usr/lib/x86_64-linux-gnu/cmake/opencv4/OpenCVConfig.cmake, version: 4.5.4
                                    #  /lib/x86_64-linux-gnu/cmake/opencv4/OpenCVConfig.cmake, version: 4.5.4
                                    #  /opt/opencv3.1/share/OpenCV/OpenCVConfig.cmake, version: 3.1.0
message("OpenCV_FOUND: ${OpenCV_FOUND}") # OpenCV_FOUND: 0

      find_package的完整签名(Full Signature)如下:

find_package(<PackageName> [version] [EXACT] [QUIET]
             [REQUIRED] [[COMPONENTS] [components...]]
             [OPTIONAL_COMPONENTS components...]
             [CONFIG|NO_MODULE]
             [GLOBAL]
             [NO_POLICY_SCOPE]
             [BYPASS_PROVIDER]
             [NAMES name1 [name2 ...]]
             [CONFIGS config1 [config2 ...]]
             [HINTS path1 [path2 ... ]]
             [PATHS path1 [path2 ... ]]
             [REGISTRY_VIEW  (64|32|64_32|32_64|HOST|TARGET|BOTH)]
             [PATH_SUFFIXES suffix1 [suffix2 ...]]
             [NO_DEFAULT_PATH]
             [NO_PACKAGE_ROOT_PATH]
             [NO_CMAKE_PATH]
             [NO_CMAKE_ENVIRONMENT_PATH]
             [NO_SYSTEM_ENVIRONMENT_PATH]
             [NO_CMAKE_PACKAGE_REGISTRY]
             [NO_CMAKE_BUILDS_PATH] # Deprecated; does nothing.
             [NO_CMAKE_SYSTEM_PATH]
             [NO_CMAKE_INSTALL_PREFIX]
             [NO_CMAKE_SYSTEM_PACKAGE_REGISTRY]
             [CMAKE_FIND_ROOT_PATH_BOTH |
              ONLY_CMAKE_FIND_ROOT_PATH |
              NO_CMAKE_FIND_ROOT_PATH]
)

      (1).CONFIG|NO_MODULE:CONFIG选项、同义的NO_MODULE选项或使用基本签名中未指定的选项都强制执行纯Config mode。在纯Config mode下,该命令会跳过Module mode搜索并立即进行Config mode搜索。

find_package(OpenCV 3.1.0 EXACT CONFIG)
message("OpenCV_FOUND: ${OpenCV_FOUND}") # OpenCV_FOUND: 1
message("OpenCV_INCLUDE_DIRS: ${OpenCV_INCLUDE_DIRS}") # OpenCV_INCLUDE_DIRS: /opt/opencv3.1/include/opencv;/opt/opencv3.1/include

find_package(OpenCV 4.5.4 EXACT NO_MODULE) # Found OpenCV: /usr (found suitable exact version "4.5.4")
message("OpenCV_FOUND: ${OpenCV_FOUND}") # OpenCV_FOUND: 1
message("OpenCV_INCLUDE_DIRS: ${OpenCV_INCLUDE_DIRS}") # OpenCV_INCLUDE_DIRS: /usr/include/opencv4

      (2).NAMES:Config mode搜索试图定位要找到的package提供的配置文件。创建一个名为<PackageName>_DIR的缓存条目(cache entry)来保存包含该文件的目录。默认情况下,find_package搜索名称为<PackageName>。如果给出了NAMES选项,则使用它后面的名称而不是<PackageName>。

find_package(opencv) # CMake Warning at test_find_package.cmake:74 (find_package):
                        # By not providing "Findopencv.cmake" in CMAKE_MODULE_PATH this project has
                        # asked CMake to find a package configuration file provided by "opencv", but CMake did not find one.
                        # Could not find a package configuration file provided by "opencv" with any of the following names:
                        #   opencvConfig.cmake
                        #   opencv-config.cmake
message("OpenCV_FOUND: ${OpenCV_FOUND}") # OpenCV_FOUND:

find_package(opencv NAMES OpenCV) # Found OpenCV: /usr (found version "4.5.4")
message("OpenCV_FOUND: ${OpenCV_FOUND}") # OpenCV_FOUND: TRUE

      (3).CONFIGS:find_package为每个指定的名称搜索名为<PackageName>Config.cmake或<lowercasePackageName>-config.cmake的文件。可以使用CONFIGS选项给出一组可能的配置文件名的替换。Config mode搜索过程如下所示:一旦找到,就会检查任何版本约束(any version constraint is checked),如果满足,则CMake读取并处理配置文件。由于该文件是由package提供的,因此它已经知道package内容的位置。配置文件的完整路径存储在cmake变量<PackageName>_CONFIG中。

# 手动copy一份/opt/opencv3.1到/opt/opencv,并将/opt/opencv/share/OpenCV/OpenCVConfig.cmake调整为/opt/opencv/share/opencv/cv_config.cmake
set(OpenCV_DIR "/opt/opencv/share/opencv/")
find_package(OpenCV NO_DEFAULT_PATH) # Could NOT find OpenCV (missing: OpenCV_DIR)
message("OpenCV_FOUND: ${OpenCV_FOUND}") # OpenCV_FOUND: 0

set(OpenCV_DIR "/opt/opencv/share/opencv/")
find_package(OpenCV CONFIGS cv_config.cmake NO_DEFAULT_PATH)
message("OpenCV_INCLUDE_DIRS: ${OpenCV_INCLUDE_DIRS}") # OpenCV_INCLUDE_DIRS: /opt/opencv/include/opencv;/opt/opencv/include
message("OpenCV_FOUND: ${OpenCV_FOUND}") # OpenCV_FOUND: 1
message("OpenCV_CONFIG: ${OpenCV_CONFIG}") # OpenCV_CONFIG: /opt/opencv/share/opencv/cv_config.cmake
message("OpenCV_CONSIDERED_CONFIGS: ${OpenCV_CONSIDERED_CONFIGS}") # OpenCV_CONSIDERED_CONFIGS: /opt/opencv/share/opencv/cv_config.cmake
message("OpenCV_CONSIDERED_VERSIONS: ${OpenCV_CONSIDERED_VERSIONS}") # OpenCV_CONSIDERED_VERSIONS: unknown

      CMake在搜索具有适当版本的package时考虑的所有配置文件都存储在<PackageName>_CONSIDERED_CONFIGS变量中,相关版本存储在<PackageName>_CONSIDERED_VERSIONS变量中。
      如果找不到package配置文件,除非指定QUIET参数,否则CMake将生成描述问题的错误。如果指定了REQUIRED并且未找到package,则会生成致命错误(fatal error)并且配置步骤停止执行(configure step stops executing)。如果<PackageName>_DIR已设置为不包含配置文件的目录,CMake将忽略它并从头开始搜索。

find_package(OpenCV) # Found OpenCV: /usr (found version "4.5.4")
message("OpenCV_FOUND: ${OpenCV_FOUND}") # OpenCV_FOUND: 1
message("OpenCV_CONSIDERED_CONFIGS: ${OpenCV_CONSIDERED_CONFIGS}") # OpenCV_CONSIDERED_CONFIGS: /usr/lib/x86_64-linux-gnu/cmake/opencv4/OpenCVConfig.cmake
message("OpenCV_CONSIDERED_VERSIONS: ${OpenCV_CONSIDERED_VERSIONS}") # OpenCV_CONSIDERED_VERSIONS: 4.5.4
message("CMAKE_LIBRARY_ARCHITECTURE: ${CMAKE_LIBRARY_ARCHITECTURE}") # CMAKE_LIBRARY_ARCHITECTURE: x86_64-linux-gnu
message("FIND_LIBRARY_USE_LIB64_PATHS: ${FIND_LIBRARY_USE_LIB64_PATHS}") # FIND_LIBRARY_USE_LIB64_PATHS:

      Config mode搜索过程:无论是完整签名还是基本签名,当使用Config mode时都会应用此搜索过程
      (1).3.24版本中引入:所有对find_package的调用(即使在Module mode下)首先在CMAKE_FIND_PACKAGE_REDIRECTS_DIR目录中查找config package file。

      FetchContent module,甚至project本身,可能会将文件写入该位置,以将find_package调用重定向到project已提供的内容。如果在该位置未找到config package file,则搜索将按照下面描述的逻辑进行:
      (2).CMake为package构造了一组可能的安装前缀。在每个前缀下搜索几个目录以查找配置文件。下表显示了搜索的目录:每个条目(each entry)都适用于遵循Windows(W), UNIX(U), 或Apple(A)约定的安装树(installation trees)

<prefix>/                                                       (W)
<prefix>/(cmake|CMake)/                                         (W)
<prefix>/<name>*/                                               (W)
<prefix>/<name>*/(cmake|CMake)/                                 (W)
<prefix>/<name>*/(cmake|CMake)/<name>*/                         (W)
<prefix>/(lib/<arch>|lib*|share)/cmake/<name>*/                 (U)
<prefix>/(lib/<arch>|lib*|share)/<name>*/                       (U)
<prefix>/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/         (U)
<prefix>/<name>*/(lib/<arch>|lib*|share)/cmake/<name>*/         (W/U)
<prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/               (W/U)
<prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/ (W/U)
<prefix>/<name>.framework/Resources/                    (A)
<prefix>/<name>.framework/Resources/CMake/              (A)
<prefix>/<name>.framework/Versions/*/Resources/         (A)
<prefix>/<name>.framework/Versions/*/Resources/CMake/   (A)
<prefix>/<name>.app/Contents/Resources/                 (A)
<prefix>/<name>.app/Contents/Resources/CMake/           (A)

      在所有情况下,<name>都被视为不区分大小写,并且对应于任何指定的名称(<PackageName>或由NAMES给出的名称)
      (3).如果设置了CMAKE_LIBRARY_ARCHITECTURE变量,则启用带有lib/<arch>的路径。lib*包括一个或多个值lib64, lib32, libx32或lib(按该顺序搜索):
      A.如果FIND_LIBRARY_USE_LIB64_PATHS属性设置为TRUE,则在64位平台上搜索具有lib64的路径。
      B.如果FIND_LIBRARY_USE_LIB32_PATHS属性设置为TRUE,则在32位平台上搜索具有lib32的路径。
      C.如果FIND_LIBRARY_USE_LIBX32_PATHS属性设置为TRUE,则在x32 ABI平台上搜索具有libx32的路径。
      D.总是搜索lib路径。
      (4).3.24版本中更改:在Windows平台上,可以使用专用语法将注册表查询作为通过HINTS和PATHS关键字指定的目录的一部分。在所有其它平台上,此类规范将被忽略。
      (5).3.24版本中引入:可以指定REGISTRY_VIEW管理Windows注册表查询作为PATHS和HINTS的一部分。
      指定必须要查询的注册表视图(registry views)。此选项仅在Windows平台上有意义,在其它平台上将被忽略。如果未指定,则在CMP0134策略为NEW时使用TARGET view。
      (6).如果指定了PATH_SUFFIXES,则后缀将一个接一个地附加到每个(W)或(U)目录条目(directory entry)。
      (7).如果指定了NO_DEFAULT_PATH,则启用所有NO_*选项。

      以上测试代码搜索本机中的OpenCV头文件,本机中有多个版本的OpenCV库:
      (1).4.5.4:头文件存放路径,系统默认的安装路径,通过命令sudo apt install libopencv-dev安装:/usr/include/opencv4/; OpenCVConfig.cmake存放路径:/usr/lib/x86_64-linux-gnu/cmake/opencv4/
      (2).3.1:头文件存放路径:/opt/opencv3.1/include/; OpenCVConfig.cmake存放路径:/opt/opencv3.1/share/OpenCV/
      (3).3.4.2:头文件存放路径:/opt/opencv3.4.2/include/; OpenCVConfig.cmake存放路径:/opt/opencv3.4.2/share/OpenCV/

      执行上述测试代码需要3个文件:build.sh, CMakeLists.txt, test_find_package.cmake

     build.sh内容如下:

#! /bin/bash

# supported input parameters(cmake commands)
params=(function macro cmake_parse_arguments \
		find_library find_path find_file find_program find_package \
		cmake_policy)

usage()
{
	echo "Error: $0 needs to have an input parameter"

	echo "supported input parameters:"
	for param in ${params[@]}; do
		echo "  $0 ${param}"
	done

	exit -1
}

if [ $# != 1 ]; then
	usage
fi

flag=0
for param in ${params[@]}; do
	if [ $1 == ${param} ]; then
		flag=1
		break
	fi
done

if [ ${flag} == 0 ]; then
	echo "Error: parameter \"$1\" is not supported"
	usage
	exit -1
fi

if [[ ! -d "build" ]]; then
	mkdir build
	cd build
else
	cd build
fi

echo "==== test $1 ===="
cmake -DTEST_CMAKE_FEATURE=$1 ..

     CMakeLists.txt内容如下:

cmake_minimum_required(VERSION 3.22)
project(cmake_feature_usage)

message("#### current cmake version: ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}")
include(test_${TEST_CMAKE_FEATURE}.cmake)
message("==== test finish ====")

      test_find_package.cmake内容:为上面所有的示例代码

      执行可能的结果如下图所示:

      GitHub: https://github.com/fengbingchun/Linux_Code_Test​​​​​​​

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`find_package` 是 CMake 用于查找和加载外部依赖库的命令。它会在系统搜索指定名称的库,并自动配置编译选项。一般情况下,我们需要在 CMakeLists.txt 文件使用 `find_package` 命令来查找我们需要的库,然后将它们链接到我们的项目。 下面是使用 `find_package` 命令的一般步骤: 1. 在 CMakeLists.txt 文件使用 `find_package` 命令,指定要查找的库的名称和版本。 例如,要查找 Boost 库,可以使用以下命令: ``` find_package(Boost 1.46 REQUIRED COMPONENTS system thread) ``` 2. 如果库没有被找到,可以通过设置 `CMAKE_PREFIX_PATH` 环境变量或者 `CMAKE_MODULE_PATH` 变量来指定库的安装路径或者 CMake 模块所在路径。 3. 如果找到了库,`find_package` 命令会自动定义一些变量,用于指定库的路径、头文件路径和库文件路径等信息。 例如,对于 Boost 库,`find_package` 命令会定义以下变量: ``` Boost_FOUND Boost_INCLUDE_DIRS Boost_LIBRARY_DIRS Boost_LIBRARIES ``` 4. 在项目使用这些变量,例如: ``` include_directories(${Boost_INCLUDE_DIRS}) link_directories(${Boost_LIBRARY_DIRS}) target_link_libraries(my_target ${Boost_LIBRARIES}) ``` 这些变量包含了库的路径信息,可以用来编译和链接项目。 需要注意的是,`find_package` 命令只能用于已经被 CMake 支持的库。对于一些非常规的库,可能需要手动配置编译选项来使用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值