cmake: add LDAP Find module

Move LDAP detection to its own Find module.

It supports `pkg-config` and the standard detection method used for
other dependencies, with version detection.

In curl CI it fixes LDAP detection in the OpenBSD job.

Closes #15273
This commit is contained in:
Viktor Szakats 2024-10-11 23:40:37 +02:00
parent ae3ca135d1
commit 49f2a23d50
No known key found for this signature in database
GPG Key ID: B5ABD165E2AEF201
3 changed files with 126 additions and 46 deletions

107
CMake/FindLDAP.cmake Normal file
View File

@ -0,0 +1,107 @@
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
# SPDX-License-Identifier: curl
#
###########################################################################
# Find the ldap library
#
# Input variables:
#
# - `LDAP_INCLUDE_DIR`: The ldap include directory.
# - `LDAP_LIBRARY`: Path to `ldap` library.
# - `LDAP_LBER_LIBRARY`: Path to `lber` library.
#
# Result variables:
#
# - `LDAP_FOUND`: System has ldap.
# - `LDAP_INCLUDE_DIRS`: The ldap include directories.
# - `LDAP_LIBRARIES`: The ldap library names.
# - `LDAP_LIBRARY_DIRS`: The ldap library directories.
# - `LDAP_PC_REQUIRES`: The ldap pkg-config packages.
# - `LDAP_CFLAGS`: Required compiler flags.
# - `LDAP_VERSION`: Version of ldap.
if(CURL_USE_PKGCONFIG AND
NOT DEFINED LDAP_INCLUDE_DIR AND
NOT DEFINED LDAP_LIBRARY AND
NOT DEFINED LDAP_LBER_LIBRARY)
find_package(PkgConfig QUIET)
pkg_check_modules(LDAP "ldap")
pkg_check_modules(LDAP_LBER "lber")
endif()
if(LDAP_FOUND AND LDAP_LBER_FOUND)
list(APPEND LDAP_LIBRARIES ${LDAP_LBER_LIBRARIES})
list(REVERSE LDAP_LIBRARIES)
list(REMOVE_DUPLICATES LDAP_LIBRARIES)
list(REVERSE LDAP_LIBRARIES)
set(LDAP_PC_REQUIRES "ldap")
string(REPLACE ";" " " LDAP_CFLAGS "${LDAP_CFLAGS}")
message(STATUS "Found LDAP (via pkg-config): ${LDAP_INCLUDE_DIRS} (found version \"${LDAP_VERSION}\")")
else()
# On Apple the SDK LDAP gets picked up from
# 'MacOSX.sdk/System/Library/Frameworks/LDAP.framework/Headers', which contains
# ldap.h and lber.h both being stubs to include <ldap.h> and <lber.h>.
# This causes an infinite inclusion loop in compile.
set(_save_cmake_system_framework_path ${CMAKE_SYSTEM_FRAMEWORK_PATH})
unset(CMAKE_SYSTEM_FRAMEWORK_PATH)
find_path(LDAP_INCLUDE_DIR NAMES "ldap.h")
set(CMAKE_SYSTEM_FRAMEWORK_PATH ${_save_cmake_system_framework_path})
find_library(LDAP_LIBRARY NAMES "ldap")
find_library(LDAP_LBER_LIBRARY NAMES "lber")
unset(LDAP_VERSION CACHE)
if(LDAP_INCLUDE_DIR AND EXISTS "${LDAP_INCLUDE_DIR}/ldap_features.h")
set(_version_regex1 "#[\t ]*define[\t ]+LDAP_VENDOR_VERSION_MAJOR[\t ]+([0-9]+).*")
set(_version_regex2 "#[\t ]*define[\t ]+LDAP_VENDOR_VERSION_MINOR[\t ]+([0-9]+).*")
set(_version_regex3 "#[\t ]*define[\t ]+LDAP_VENDOR_VERSION_PATCH[\t ]+([0-9]+).*")
file(STRINGS "${LDAP_INCLUDE_DIR}/ldap_features.h" _version_str1 REGEX "${_version_regex1}")
file(STRINGS "${LDAP_INCLUDE_DIR}/ldap_features.h" _version_str2 REGEX "${_version_regex2}")
file(STRINGS "${LDAP_INCLUDE_DIR}/ldap_features.h" _version_str3 REGEX "${_version_regex3}")
string(REGEX REPLACE "${_version_regex1}" "\\1" _version_str1 "${_version_str1}")
string(REGEX REPLACE "${_version_regex2}" "\\1" _version_str2 "${_version_str2}")
string(REGEX REPLACE "${_version_regex3}" "\\1" _version_str3 "${_version_str3}")
set(LDAP_VERSION "${_version_str1}.${_version_str2}.${_version_str3}")
unset(_version_regex1)
unset(_version_regex2)
unset(_version_regex3)
unset(_version_str1)
unset(_version_str2)
unset(_version_str3)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LDAP
REQUIRED_VARS
LDAP_INCLUDE_DIR
LDAP_LIBRARY
LDAP_LBER_LIBRARY
VERSION_VAR
LDAP_VERSION
)
if(LDAP_FOUND)
set(LDAP_INCLUDE_DIRS ${LDAP_INCLUDE_DIR})
set(LDAP_LIBRARIES ${LDAP_LIBRARY} ${LDAP_LBER_LIBRARY})
endif()
mark_as_advanced(LDAP_INCLUDE_DIR LDAP_LIBRARY LDAP_LBER_LIBRARY)
endif()

View File

@ -1011,59 +1011,28 @@ if(NOT CURL_DISABLE_LDAP)
# Now that we know, we are not using Windows LDAP...
if(NOT USE_WIN32_LDAP)
if(NOT DEFINED LDAP_LIBRARY)
set(LDAP_LIBRARY "ldap" CACHE STRING "Name or full path to ldap library")
endif()
if(NOT DEFINED LDAP_LBER_LIBRARY)
set(LDAP_LBER_LIBRARY "lber" CACHE STRING "Name or full path to lber library")
endif()
if(NOT DEFINED LDAP_INCLUDE_DIR)
set(LDAP_INCLUDE_DIR "" CACHE STRING "Path to LDAP include directory")
endif()
# Check for LDAP
cmake_push_check_state()
if(USE_OPENSSL)
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
endif()
check_library_exists("${LDAP_LIBRARY}" "ldap_init" "" HAVE_LIBLDAP)
if(HAVE_LIBLDAP)
check_library_exists("${LDAP_LIBRARY};${LDAP_LBER_LIBRARY}" "ber_init" "" HAVE_LIBLBER)
else()
check_library_exists("${LDAP_LBER_LIBRARY}" "ber_init" "" HAVE_LIBLBER)
endif()
if(LDAP_INCLUDE_DIR)
list(APPEND CMAKE_REQUIRED_INCLUDES ${LDAP_INCLUDE_DIR})
endif()
unset(_include_list)
check_include_file("lber.h" HAVE_LBER_H)
if(HAVE_LBER_H)
list(APPEND _include_list "lber.h")
endif()
check_include_files("${_include_list};ldap.h" HAVE_LDAP_H)
unset(_include_list)
if(NOT HAVE_LDAP_H)
message(STATUS "LDAP_H not found CURL_DISABLE_LDAP set ON")
set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
elseif(NOT HAVE_LIBLDAP)
message(STATUS "LDAP library '${LDAP_LIBRARY}' not found CURL_DISABLE_LDAP set ON")
set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
else()
if(LDAP_INCLUDE_DIR)
include_directories(SYSTEM ${LDAP_INCLUDE_DIR})
find_package(LDAP)
if(LDAP_FOUND)
set(HAVE_LBER_H 1)
set(CURL_LIBS "${LDAP_LIBRARIES};${CURL_LIBS}")
list(APPEND CURL_LIBDIRS ${LDAP_LIBRARY_DIRS})
set(LIBCURL_PC_REQUIRES_PRIVATE "${LDAP_PC_REQUIRES};${LIBCURL_PC_REQUIRES_PRIVATE}")
include_directories(SYSTEM ${LDAP_INCLUDE_DIRS})
link_directories(${LDAP_LIBRARY_DIRS})
if(LDAP_CFLAGS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LDAP_CFLAGS}")
endif()
# LDAP feature checks
list(APPEND CMAKE_REQUIRED_DEFINITIONS "-DLDAP_DEPRECATED=1")
list(APPEND CMAKE_REQUIRED_LIBRARIES ${LDAP_LIBRARY})
set(CURL_LIBS "${LDAP_LIBRARY};${CURL_LIBS}")
# FIXME: uncomment once pkg-config-based detection landed: https://github.com/curl/curl/pull/15273
# set(LIBCURL_PC_REQUIRES_PRIVATE "${LDAP_PC_REQUIRES};${LIBCURL_PC_REQUIRES_PRIVATE}")
if(HAVE_LIBLBER)
list(APPEND CMAKE_REQUIRED_LIBRARIES ${LDAP_LBER_LIBRARY})
set(CURL_LIBS "${LDAP_LBER_LIBRARY};${CURL_LIBS}")
endif()
list(APPEND CMAKE_REQUIRED_LIBRARIES ${LDAP_LIBRARIES})
curl_required_libpaths("${LDAP_LIBRARY_DIRS}")
check_function_exists("ldap_url_parse" HAVE_LDAP_URL_PARSE)
check_function_exists("ldap_init_fd" HAVE_LDAP_INIT_FD)
@ -1077,6 +1046,9 @@ if(NOT CURL_DISABLE_LDAP)
if(NOT CURL_DISABLE_LDAPS)
set(HAVE_LDAP_SSL ON)
endif()
else()
message(STATUS "LDAP not found. CURL_DISABLE_LDAP set ON")
set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
endif()
cmake_pop_check_state()
endif()

View File

@ -36,6 +36,7 @@ CMAKE_DIST = \
CMake/FindBrotli.cmake \
CMake/FindCares.cmake \
CMake/FindGSS.cmake \
CMake/FindLDAP.cmake \
CMake/FindLibgsasl.cmake \
CMake/FindLibidn2.cmake \
CMake/FindLibpsl.cmake \