首页 > 解决方案 > find_package(ACL REQUIRED) 不会停止处理

问题描述

我目前正在尝试为我的一个小型 C 库建立一个基于 CMake 的构建系统。由于这个库依赖于libacl,CMake 应该验证它是否存在于系统上,否则会失败。

由于没有预定义FindACL模块,我使用了KDE 项目中的一个:

[...] check_include_files [...] find_library [...]

if (ACL_HEADERS_FOUND AND ACL_LIBS AND ATTR_LIBS)
   set(ACL_FOUND TRUE)
   set(ACL_LIBS ${ACL_LIBS} ${ATTR_LIBS})
   message(STATUS "Found ACL support: ${ACL_LIBS}")
endif (ACL_HEADERS_FOUND AND ACL_LIBS AND ATTR_LIBS)

我使用以下(最小)调用它CMakeLists.txt

cmake_minimum_required(VERSION 3.12)

project(
    cmaketest
    VERSION 1.0
    DESCRIPTION "cmake test"
    LANGUAGES C
)

set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
find_package(ACL REQUIRED) # ACL_LIBS

它正确检测到我的系统缺少libacl包含,但不会停止处理,即使手册指出

如果找不到包,则 REQUIRED 选项会停止处理并显示错误消息。

我是否必须ACL_FOUND通过if语句明确检查是否已设置?

我正在使用 CMake 3.13.4。终端输出:

-- The C compiler identification is GNU 8.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Looking for include file attr/libattr.h
-- Looking for include file attr/libattr.h - not found
-- Looking for include file sys/xattr.h
-- Looking for include file sys/xattr.h - found
-- Looking for include file sys/acl.h
-- Looking for include file sys/acl.h - not found
-- Looking for include file acl/libacl.h
-- Looking for include file acl/libacl.h - not found
-- Configuring done
-- Generating done
-- Build files have been written to: [redacted]/build

标签: cmake

解决方案


似乎有一段时间以来,CMake 需要一个FindXXX.cmake脚本(在MODULE模式下使用find_package)来检查REQUIRED选项并在需要时发出错误。CMake 行为的这种变化使得旧的“查找”脚本(如FindACL.cmake)被破坏。

可以在CMake wiki中描述的“查找模块中的常见错误”中找到对此的间接确认:

该模块不检查 _FIND_REQUIRED 或 _FIND_QUIETLY - 因此 find_package 参数 QUIET 和 REQUIRED 将无效

因此,FindACL.cmake脚本可以重写如下:

# FindACL.cmake

# ...

if (ACL_HEADERS_FOUND AND ACL_LIBS AND ATTR_LIBS)
  set(ACL_FOUND TRUE)
  set(ACL_LIBS ${ACL_LIBS} ${ATTR_LIBS})
  message(STATUS "Found ACL support: ${ACL_LIBS}")
elif (ACL_FIND_REQUIRED)
  # ACL hasn't been found but REQUIRED. Emit an error.
  message(FATAL_ERROR "Cannot find ACL")
endif (ACL_HEADERS_FOUND AND ACL_LIBS AND ATTR_LIBS)

实际上,大多数“查找”脚本使用设置结果find_package并关心其选项的特殊助手。FindACL.cmake也可以使用这个助手:

# FindACL.cmake

# ...

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(ACL
  # Use default message on fail.
  DEFAULT_MSG
  # Variables which should be true-evaluated for assume the package to be found
  ACL_HEADERS_FOUND ACL_LIBS ATTR_LIBS
)

脚本的情况有所不同XXXConfig.cmake,它们在CONFIG模式下处理find_package。这些脚本只应将XXX_FOUND变量设置为 false,CMake 将自行处理 REQUIRED 选项。


推荐阅读