Skip to content

Commit fc8465a

Browse files
committed
CMake: use pkg-config and Homebrew when looking for libcrypto.
Do the same sort of stuff that configure does, but CMake-style.
1 parent 749988b commit fc8465a

File tree

2 files changed

+248
-16
lines changed

2 files changed

+248
-16
lines changed

CMakeLists.txt

Lines changed: 74 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,80 @@ project(tcpdump C)
130130
#
131131
set(SIZEOF_VOID_P "${CMAKE_SIZEOF_VOID_P}")
132132

133+
#
134+
# Show the bit width for which we're compiling.
135+
# This can help debug problems if you're dealing with a compiler that
136+
# defaults to generating 32-bit code even when running on a 64-bit
137+
# platform, and where that platform may provide only 64-bit versions of
138+
# libraries that we might use (looking at *you*, Oracle Studio!).
139+
#
140+
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
141+
message(STATUS "Building 32-bit")
142+
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
143+
message(STATUS "Building 64-bit")
144+
endif()
145+
146+
#
147+
# Solaris pkg-config is annoying. For at least one package (D-Bus, I'm
148+
# looking at *you*!), there are separate include files for 32-bit and
149+
# 64-bit builds (I guess using "unsigned long long" as a 64-bit integer
150+
# type on a 64-bit build is like crossing the beams or something), and
151+
# there are two separate .pc files, so if we're doing a 32-bit build we
152+
# should make sure we look in /usr/lib/pkgconfig for .pc files and if
153+
# we're doing a 64-bit build we should make sure we look in
154+
# /usr/lib/amd64/pkgconfig for .pc files.
155+
#
156+
if(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND CMAKE_SYSTEM_VERSION MATCHES "5[.][0-9.]*")
157+
#
158+
# Note: string(REPLACE) does not appear to support using ENV{...}
159+
# as an argument, so we set a variable and then use set() to set
160+
# the environment variable.
161+
#
162+
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
163+
#
164+
# 64-bit build. If /usr/lib/pkgconfig appears in the path,
165+
# prepend /usr/lib/amd64/pkgconfig to it; otherwise,
166+
# put /usr/lib/amd64 at the end.
167+
#
168+
if((NOT DEFINED ENV{PKG_CONFIG_PATH}) OR "$ENV{PKG_CONFIG_PATH}" EQUAL "")
169+
#
170+
# Not set, or empty. Set it to /usr/lib/amd64/pkgconfig.
171+
#
172+
set(fixed_path "/usr/lib/amd64/pkgconfig")
173+
elseif("$ENV{PKG_CONFIG_PATH}" MATCHES "/usr/lib/pkgconfig")
174+
#
175+
# It contains /usr/lib/pkgconfig. Prepend
176+
# /usr/lib/amd64/pkgconfig to /usr/lib/pkgconfig.
177+
#
178+
string(REPLACE "/usr/lib/pkgconfig"
179+
"/usr/lib/amd64/pkgconfig:/usr/lib/pkgconfig"
180+
fixed_path "$ENV{PKG_CONFIG_PATH}")
181+
else()
182+
#
183+
# Not empty, but doesn't contain /usr/lib/pkgconfig.
184+
# Append /usr/lib/amd64/pkgconfig to it.
185+
#
186+
set(fixed_path "$ENV{PKG_CONFIG_PATH}:/usr/lib/amd64/pkgconfig")
187+
endif()
188+
set(ENV{PKG_CONFIG_PATH} "${fixed_path}")
189+
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
190+
#
191+
# 32-bit build. If /usr/amd64/lib/pkgconfig appears in the path,
192+
# prepend /usr/lib/pkgconfig to it.
193+
#
194+
if("$ENV{PKG_CONFIG_PATH}" MATCHES "/usr/lib/amd64/pkgconfig")
195+
#
196+
# It contains /usr/lib/amd64/pkgconfig. Prepend
197+
# /usr/lib/pkgconfig to /usr/lib/amd64/pkgconfig.
198+
#
199+
string(REPLACE "/usr/lib/amd64/pkgconfig"
200+
"/usr/lib/pkgconfig:/usr/lib/amd64/pkgconfig"
201+
fixed_path "$ENV{PKG_CONFIG_PATH}")
202+
set(ENV{PKG_CONFIG_PATH} "${fixed_path}")
203+
endif()
204+
endif()
205+
endif()
206+
133207
#
134208
# For checking if a compiler flag works and adding it if it does.
135209
#
@@ -828,11 +902,6 @@ endif(WITH_SMI)
828902
if(WITH_CRYPTO)
829903
find_package(CRYPTO)
830904
if(CRYPTO_FOUND)
831-
#
832-
# Check for some headers and functions.
833-
#
834-
check_include_file(openssl/evp.h HAVE_OPENSSL_EVP_H)
835-
836905
#
837906
# 1) do we have EVP_CIPHER_CTX_new?
838907
# If so, we use it to allocate an EVP_CIPHER_CTX, as

cmake/Modules/FindCRYPTO.cmake

Lines changed: 174 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,186 @@
22
# Try to find libcrypto.
33
#
44

5-
# Try to find the header
6-
find_path(CRYPTO_INCLUDE_DIR openssl/crypto.h)
5+
#
6+
# Were we told where to look for libcrypto?
7+
#
8+
if(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)
782

8-
# Try to find the library
9-
find_library(CRYPTO_LIBRARY crypto)
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()
156+
endif()
157+
158+
#
159+
# Have we found it with pkg-config or Homebrew?
160+
#
161+
if(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)
175+
endif()
10176

11177
include(FindPackageHandleStandardArgs)
12178
find_package_handle_standard_args(CRYPTO
13179
DEFAULT_MSG
14-
CRYPTO_INCLUDE_DIR
15-
CRYPTO_LIBRARY
180+
CRYPTO_INCLUDE_DIRS
181+
CRYPTO_LIBRARIES
16182
)
17183

18184
mark_as_advanced(
19-
CRYPTO_INCLUDE_DIR
20-
CRYPTO_LIBRARY
185+
CRYPTO_INCLUDE_DIRS
186+
CRYPTO_LIBRARIES
21187
)
22-
23-
set(CRYPTO_INCLUDE_DIRS ${CRYPTO_INCLUDE_DIR})
24-
set(CRYPTO_LIBRARIES ${CRYPTO_LIBRARY})

0 commit comments

Comments
 (0)