Reputation: 9646
I am currently trying to set up a CMake-based build system for a small C library of mine. Since this library depends on libacl
, CMake should verify that it is present on the system, or fail otherwise.
Since there is no predefined FindACL
module, I used the one from the KDE project:
[...] 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)
I call it using the following (minimal) 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
It correctly detects that my system is lacking the libacl
includes, but does not stop processing, even though the manual states that
The REQUIRED option stops processing with an error message if the package cannot be found.
Do I have to explicitly check whether ACL_FOUND
is set, through an if
statement?
I am using CMake 3.13.4. Terminal output:
-- 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
Upvotes: 2
Views: 1243
Reputation: 66089
It seems that since some time CMake expects a FindXXX.cmake
script (used in MODULE mode of find_package
) to check REQUIRED option and emit an error if needed. Such change in CMake behavior makes old legacy "Find" scripts, like FindACL.cmake
, to be broken.
Indirect confirmation of that can be found in this "Common bug in find module", described in CMake wiki:
The module does not check _FIND_REQUIRED or _FIND_QUIETLY - and thus the find_package arguments QUIET and REQUIRED will have no effect
So, FindACL.cmake
script could be rewritten as follows:
# 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)
Actually, most "Find" scripts use the special helper which sets result of find_package
and cares about its options. FindACL.cmake
could also use this helper:
# 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
)
The things are different for XXXConfig.cmake
scripts, which are processed in CONFIG mode of find_package
. These scripts should only set XXX_FOUND
variable to false, and CMake will handle REQUIRED option by itself.
Upvotes: 1