xref: /freebsd/contrib/tcpdump/cmake/Modules/FindCRYPTO.cmake (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
1#
2# Try to find libcrypto.
3#
4
5#
6# Were we told where to look for libcrypto?
7#
8if(NOT CRYPTO_ROOT)
9  #
10  # No.
11  #
12  # First, try looking for it with pkg-config, if we have it.
13  #
14  find_package(PkgConfig)
15
16  #
17  # Homebrew's pkg-config does not, by default, look for
18  # pkg-config files for packages it has installed.
19  # Furthermore, at least for OpenSSL, they appear to be
20  # dumped in package-specific directories whose paths are
21  # not only package-specific but package-version-specific.
22  #
23  # So the only way to find openssl is to get the value of
24  # PKG_CONFIG_PATH from "brew --env openssl" and add that
25  # to PKG_CONFIG_PATH.  (No, we can't just assume it's under
26  # /usr/local; Homebrew have conveniently chosen to put it
27  # under /opt/homebrew on ARM.)
28  #
29  # That's the nice thing about Homebrew - it makes things easier!
30  # Thanks!
31  #
32  find_program(BREW brew)
33  if(BREW)
34    #
35    # We have Homebrew.
36    # Get the pkg-config directory for openssl.
37    #
38    execute_process(COMMAND "${BREW}" "--env" "--plain" "openssl"
39      RESULT_VARIABLE BREW_RESULT
40      OUTPUT_VARIABLE BREW_OUTPUT
41      OUTPUT_STRIP_TRAILING_WHITESPACE
42    )
43    if(BREW_RESULT EQUAL 0)
44      #
45      # brew --env --plain openssl succeeded.
46      # Split its output into a list, one entry per line.
47      #
48      string(REGEX MATCHALL "[^\n\r]+" BREW_OUTPUT_LINES "${BREW_OUTPUT}")
49
50      #
51      # Find the line that begins with "PKG_CONFIG_PATH: ", and extract
52      # the path following that.
53      #
54      foreach(LINE IN LISTS BREW_OUTPUT_LINES)
55        if(LINE MATCHES "PKG_CONFIG_PATH: \(.*\)")
56          string(REGEX REPLACE "PKG_CONFIG_PATH: \(.*\)"
57              "\\1" OPENSSL_PKGCONFIG_DIR
58              ${LINE})
59        endif()
60      endforeach()
61    endif()
62  endif()
63
64  #
65  # Save the current value of the PKG_CONFIG_PATH environment
66  # variable.
67  #
68  set(SAVE_PKG_CONFIG_PATH $ENV{PKG_CONFIG_PATH})
69
70  #
71  # If we got an additional pkg-config directory from Homebrew, add
72  # it to the PKG_CONFIG_PATH environment variable.
73  #
74  if(OPENSSL_PKGCONFIG_DIR)
75    set(ENV{PKG_CONFIG_PATH} "${OPENSSL_PKGCONFIG_DIR}:$ENV{PKG_CONFIG_PATH}")
76  endif()
77
78  #
79  # Use pkg-config to find libcrypto.
80  #
81  pkg_check_modules(CRYPTO libcrypto)
82
83  #
84  # Revert the change to PKG_CONFIG_PATH.
85  #
86  set(ENV{PKG_CONFIG_PATH} "${SAVE_PKG_CONFIG_PATH}")
87
88  #
89  # Did pkg-config find it?
90  #
91  if(CRYPTO_FOUND)
92    #
93    # This "helpfully" supplies CRYPTO_LIBRARIES as a bunch of
94    # library names - not paths - and CRYPTO_LIBRARY_DIRS as
95    # a bunch of directories.
96    #
97    # CMake *really* doesn't like the notion of specifying "here are
98    # the directories in which to look for libraries" except in
99    # find_library() calls; it *really* prefers using full paths to
100    # library files, rather than library names.
101    #
102    # Find the libraries and add their full paths.
103    #
104    set(CRYPTO_LIBRARY_FULLPATHS)
105    foreach(_lib IN LISTS CRYPTO_LIBRARIES)
106      #
107      # Try to find this library, so we get its full path.
108      #
109      find_library(_libfullpath ${_lib} HINTS ${CRYPTO_LIBRARY_DIRS})
110      list(APPEND CRYPTO_LIBRARY_FULLPATHS ${_libfullpath})
111    endforeach()
112    set(CRYPTO_LIBRARIES "${CRYPTO_LIBRARY_FULLPATHS}")
113  else()
114    #
115    # No.  If we have Homebrew installed, see if it's in Homebrew.
116    #
117    if(BREW)
118      #
119      # The brew man page lies when it speaks of
120      # $BREW --prefix --installed <formula>
121      # outputting nothing.  In Homebrew 3.3.16,
122      # it produces output regardless of whether
123      # the formula is installed or not, so we
124      # send the standard output and error to
125      # the bit bucket.
126      #
127      # libcrypto isn't a formula, openssl is a formula.
128      #
129      execute_process(COMMAND "${BREW}" "--prefix" "--installed" "openssl"
130        RESULT_VARIABLE BREW_RESULT
131        OUTPUT_QUIET
132      )
133      if(BREW_RESULT EQUAL 0)
134        #
135        # Yes.  Get the include directory and library
136        # directory.  (No, we can't just assume it's
137        # under /usr/local; Homebrew have conveniently
138        # chosen to put it under /opt/homebrew on ARM.)
139        #
140        execute_process(COMMAND "${BREW}" "--prefix" "openssl"
141          RESULT_VARIABLE BREW_RESULT
142          OUTPUT_VARIABLE OPENSSL_PATH
143          OUTPUT_STRIP_TRAILING_WHITESPACE
144        )
145        set(CRYPTO_INCLUDE_DIRS "${OPENSSL_PATH}/include")
146
147        #
148        # Search for the libcrypto library under lib.
149        #
150        find_library(CRYPTO_LIBRARIES crypto
151            PATHS "${OPENSSL_PATH}/lib"
152            NO_DEFAULT_PATH)
153      endif()
154    endif()
155  endif()
156endif()
157
158#
159# Have we found it with pkg-config or Homebrew?
160#
161if(NOT CRYPTO_INCLUDE_DIRS)
162  #
163  # No.
164  # Try to find the openss/evp.h header.
165  # We search for that header to make sure that it's installed (if
166  # it's just a shared library for the benefit of existing
167  # programs, that's not useful).
168  #
169  find_path(CRYPTO_INCLUDE_DIRS openssl/evp.h)
170
171  #
172  # Try to find the library.
173  #
174  find_library(CRYPTO_LIBRARIES crypto)
175endif()
176
177include(FindPackageHandleStandardArgs)
178find_package_handle_standard_args(CRYPTO
179  DEFAULT_MSG
180  CRYPTO_INCLUDE_DIRS
181  CRYPTO_LIBRARIES
182)
183
184mark_as_advanced(
185  CRYPTO_INCLUDE_DIRS
186  CRYPTO_LIBRARIES
187)
188