diff options
Diffstat (limited to 'cmake/Modules')
-rw-r--r-- | cmake/Modules/FindCRYPTO.cmake | 185 |
1 files changed, 174 insertions, 11 deletions
diff --git a/cmake/Modules/FindCRYPTO.cmake b/cmake/Modules/FindCRYPTO.cmake index 453c651..25846f3 100644 --- a/cmake/Modules/FindCRYPTO.cmake +++ b/cmake/Modules/FindCRYPTO.cmake @@ -2,23 +2,186 @@ # Try to find libcrypto. # -# Try to find the header -find_path(CRYPTO_INCLUDE_DIR openssl/crypto.h) +# +# Were we told where to look for libcrypto? +# +if(NOT CRYPTO_ROOT) + # + # No. + # + # First, try looking for it with pkg-config, if we have it. + # + find_package(PkgConfig) + + # + # Homebrew's pkg-config does not, by default, look for + # pkg-config files for packages it has installed. + # Furthermore, at least for OpenSSL, they appear to be + # dumped in package-specific directories whose paths are + # not only package-specific but package-version-specific. + # + # So the only way to find openssl is to get the value of + # PKG_CONFIG_PATH from "brew --env openssl" and add that + # to PKG_CONFIG_PATH. (No, we can't just assume it's under + # /usr/local; Homebrew have conveniently chosen to put it + # under /opt/homebrew on ARM.) + # + # That's the nice thing about Homebrew - it makes things easier! + # Thanks! + # + find_program(BREW brew) + if(BREW) + # + # We have Homebrew. + # Get the pkg-config directory for openssl. + # + execute_process(COMMAND "${BREW}" "--env" "--plain" "openssl" + RESULT_VARIABLE BREW_RESULT + OUTPUT_VARIABLE BREW_OUTPUT + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(BREW_RESULT EQUAL 0) + # + # brew --env --plain openssl succeeded. + # Split its output into a list, one entry per line. + # + string(REGEX MATCHALL "[^\n\r]+" BREW_OUTPUT_LINES "${BREW_OUTPUT}") + + # + # Find the line that begins with "PKG_CONFIG_PATH: ", and extract + # the path following that. + # + foreach(LINE IN LISTS BREW_OUTPUT_LINES) + if(LINE MATCHES "PKG_CONFIG_PATH: \(.*\)") + string(REGEX REPLACE "PKG_CONFIG_PATH: \(.*\)" + "\\1" OPENSSL_PKGCONFIG_DIR + ${LINE}) + endif() + endforeach() + endif() + endif() + + # + # Save the current value of the PKG_CONFIG_PATH environment + # variable. + # + set(SAVE_PKG_CONFIG_PATH $ENV{PKG_CONFIG_PATH}) + + # + # If we got an additional pkg-config directory from Homebrew, add + # it to the PKG_CONFIG_PATH environment variable. + # + if(OPENSSL_PKGCONFIG_DIR) + set(ENV{PKG_CONFIG_PATH} "${OPENSSL_PKGCONFIG_DIR}:$ENV{PKG_CONFIG_PATH}") + endif() + + # + # Use pkg-config to find libcrypto. + # + pkg_check_modules(CRYPTO libcrypto) -# Try to find the library -find_library(CRYPTO_LIBRARY crypto) + # + # Revert the change to PKG_CONFIG_PATH. + # + set(ENV{PKG_CONFIG_PATH} "${SAVE_PKG_CONFIG_PATH}") + + # + # Did pkg-config find it? + # + if(CRYPTO_FOUND) + # + # This "helpfully" supplies CRYPTO_LIBRARIES as a bunch of + # library names - not paths - and CRYPTO_LIBRARY_DIRS as + # a bunch of directories. + # + # CMake *really* doesn't like the notion of specifying "here are + # the directories in which to look for libraries" except in + # find_library() calls; it *really* prefers using full paths to + # library files, rather than library names. + # + # Find the libraries and add their full paths. + # + set(CRYPTO_LIBRARY_FULLPATHS) + foreach(_lib IN LISTS CRYPTO_LIBRARIES) + # + # Try to find this library, so we get its full path. + # + find_library(_libfullpath ${_lib} HINTS ${CRYPTO_LIBRARY_DIRS}) + list(APPEND CRYPTO_LIBRARY_FULLPATHS ${_libfullpath}) + endforeach() + set(CRYPTO_LIBRARIES "${CRYPTO_LIBRARY_FULLPATHS}") + else() + # + # No. If we have Homebrew installed, see if it's in Homebrew. + # + if(BREW) + # + # The brew man page lies when it speaks of + # $BREW --prefix --installed <formula> + # outputting nothing. In Homebrew 3.3.16, + # it produces output regardless of whether + # the formula is installed or not, so we + # send the standard output and error to + # the bit bucket. + # + # libcrypto isn't a formula, openssl is a formula. + # + execute_process(COMMAND "${BREW}" "--prefix" "--installed" "openssl" + RESULT_VARIABLE BREW_RESULT + OUTPUT_QUIET + ) + if(BREW_RESULT EQUAL 0) + # + # Yes. Get the include directory and library + # directory. (No, we can't just assume it's + # under /usr/local; Homebrew have conveniently + # chosen to put it under /opt/homebrew on ARM.) + # + execute_process(COMMAND "${BREW}" "--prefix" "openssl" + RESULT_VARIABLE BREW_RESULT + OUTPUT_VARIABLE OPENSSL_PATH + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + set(CRYPTO_INCLUDE_DIRS "${OPENSSL_PATH}/include") + + # + # Search for the libcrypto library under lib. + # + find_library(CRYPTO_LIBRARIES crypto + PATHS "${OPENSSL_PATH}/lib" + NO_DEFAULT_PATH) + endif() + endif() + endif() +endif() + +# +# Have we found it with pkg-config or Homebrew? +# +if(NOT CRYPTO_INCLUDE_DIRS) + # + # No. + # Try to find the openss/evp.h header. + # We search for that header to make sure that it's installed (if + # it's just a shared library for the benefit of existing + # programs, that's not useful). + # + find_path(CRYPTO_INCLUDE_DIRS openssl/evp.h) + + # + # Try to find the library. + # + find_library(CRYPTO_LIBRARIES crypto) +endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args(CRYPTO DEFAULT_MSG - CRYPTO_INCLUDE_DIR - CRYPTO_LIBRARY + CRYPTO_INCLUDE_DIRS + CRYPTO_LIBRARIES ) mark_as_advanced( - CRYPTO_INCLUDE_DIR - CRYPTO_LIBRARY + CRYPTO_INCLUDE_DIRS + CRYPTO_LIBRARIES ) - -set(CRYPTO_INCLUDE_DIRS ${CRYPTO_INCLUDE_DIR}) -set(CRYPTO_LIBRARIES ${CRYPTO_LIBRARY}) |