The following module AssertLibraryFunction improves upon CheckLibrariesExists in two respects:It honors the optional argument REQUIRED of find_package: if the check fails, it raises a FATAL_ERROR. It also honors QUIET.Its result is cached in a variable named ${LIBNAME}_${FUNCTION}. Therefore, argument 4 of CheckLibrariesExists, VARIABLE, is no longer needed.Of course this comes at a slight expense in flexibility. Nevertheless, I believe this module could help substantially in writing compact Find<Package>.cmake modules.Questions:Is this novel functionality, or could I achieve about the same, with comparable brevity, with an existing module?Would it make sense to propose AssertLibraryFunction for inclusion in future cmake versions?Regardless of the above, are there ways to improve my cmake coding style?Here the module AssertLibraryFunction:#.rst:# AssertLibraryFunction# ---------------------## ASSERT_LIBRARY_FUNCTION checks whether given libraries contain# a given function. If this is not the case, a fatal error is raised.## CHECK_LIBRARY_EXISTS (LIBNAME FUNCTION LOCATION)## ::##   LIBNAME  - library name (case sensitive)#   FUNCTION - name of the function to be searched in ${LIBNAME}_LIBRARIES#   LOCATION - where the library should be found (if unsure, use )### The following variables may be set before calling this macro to modify# the way the check is run:## ::##   CMAKE_REQUIRED_FLAGS = string of compile command line flags#   CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)#   CMAKE_REQUIRED_LIBRARIES = list of libraries to link#   CMAKE_REQUIRED_QUIET = execute quietly without messages## This function is meant to be used in Find<Package>.cmake modules,# which in turn should be called through## ::##   find_package(<Package> [QUIET] [REQUIRED])## Within a Find<Package>.cmake module, find_package_handle_standard_args# must be called before any call of ASSERT_LIBRARY_FUNCTION.# Typically, Find<Package>.cmake looks like the following:## ::# #   find_path(<Package>_INCLUDE_DIR <include_file>)#   find_library(<Package>_LIBRARIES NAMES <library_name> <Package>)#   #   include(FindPackageHandleStandardArgs)#   find_package_handle_standard_args(<Package> DEFAULT_MSG <Package>_LIBRARIES <Package>_INCLUDE_DIR)#   #   include(AssertLibraryFunction)#   assert_library_function(<Package> <function_name> )#   #   mark_as_advanced(<Package>_INCLUDE_DIR <Package>_LIBRARIES)#   # The result of ASSERT_LIBRARY_FUNCTION is cached in a variable named# ${LIBNAME}_${FUNCTION}.#=============================================================================# Based on CheckLibrariesExists (Copyright 2002-2009 Kitware, Inc.)# Author: Joachim Wuttke (Copyright 2015 Forschungszentrum Jlich)# License: BSD (see cmake License for details)#=============================================================================macro(alf_status_message _msg)    if( ${LIBNAME}_FIND_QUIETLY )    else()        message(STATUS ${_msg})    endif()endmacro()function(ASSERT_LIBRARY_FUNCTION LIBNAME FUNCTION LOCATION)    set(LIBRARY ${${LIBNAME}_LIBRARIES})    set(VARIABLE ${LIBNAME}_${FUNCTION})    set(_MSG Search ${FUNCTION} in ${LIBRARY})    if(DEFINED ${VARIABLE})        if(${${VARIABLE}})            alf_status_message(${_MSG} -- cached)            return()        endif()    endif()    alf_status_message(Search ${FUNCTION} in ${LIBRARY})    set(MACRO_CHECK_LIBRARY_EXISTS_DEFINITION        -DCHECK_FUNCTION_EXISTS=${FUNCTION} ${CMAKE_REQUIRED_FLAGS})    set(CHECK_LIBRARY_EXISTS_LIBRARIES ${LIBRARY})    if(CMAKE_REQUIRED_LIBRARIES)        set(CHECK_LIBRARY_EXISTS_LIBRARIES            ${CHECK_LIBRARY_EXISTS_LIBRARIES} ${CMAKE_REQUIRED_LIBRARIES})    endif()    try_compile(COMPILE_OK        ${CMAKE_BINARY_DIR}        ${CMAKE_ROOT}/Modules/CheckFunctionExists.c        COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}        LINK_LIBRARIES ${CHECK_LIBRARY_EXISTS_LIBRARIES}        CMAKE_FLAGS        -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_LIBRARY_EXISTS_DEFINITION}        -DLINK_DIRECTORIES:STRING=${LOCATION}        OUTPUT_VARIABLE OUTPUT)    if(${COMPILE_OK})        if(NOT CMAKE_REQUIRED_QUIET)            alf_status_message(${_MSG} -- found)        endif()        set(${VARIABLE} 1 CACHE INTERNAL Library ${LIBRARY} has ${function})        file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log            Determining if the function ${FUNCTION} exists in the ${LIBRARY}             passed with the following output:\n            ${OUTPUT}\n\n)    else()        set(${VARIABLE}  CACHE INTERNAL Library ${LIBRARY} has no ${function})        file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log            Determining if the function ${FUNCTION} exists in the ${LIBRARY}             failed with the following output:\n            ${OUTPUT}\n\n)        if( ${LIBNAME}_FIND_REQUIRED )            message(FATAL_ERROR ${_MSG} -- not found)        else()            alf_status_message(${_MSG} -- not found)        endif()    endif()endfunction()And here is a sample module FindReadline.cmake that would use the above:# Find libreadline## Usage:#   find_package(Readline [REQUIRED] [QUIET])## Sets the following variables:#   - Readline_FOUND        .. true if library is found#   - Readline_LIBRARIES    .. full path to library#   - Readline_INCLUDE_DIR  .. full path to include directory## Copyright 2015 Joachim Wuttke, Forschungszentrum Jlich.# Redistribution permitted.find_path(Readline_INCLUDE_DIR readline/readline.h)find_library(Readline_LIBRARIES NAMES readline Readline)include(FindPackageHandleStandardArgs) # handles QUIET, REQUIRED; sets Readline_FOUNDfind_package_handle_standard_args(Readline DEFAULT_MSG Readline_LIBRARIES Readline_INCLUDE_DIR)include(AssertLibraryFunction)assert_library_function(Readline rl_initialize )assert_library_function(Readline add_history )mark_as_advanced(Readline_INCLUDE_DIR Readline_LIBRARIES)
Cmake module that improves upon CheckLibrariesExists
cmake