Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows CMake build fails with OpenSSL unresolved external symbols #14405

Closed
micahsnyder opened this issue Aug 5, 2024 · 26 comments
Closed

Windows CMake build fails with OpenSSL unresolved external symbols #14405

micahsnyder opened this issue Aug 5, 2024 · 26 comments
Labels

Comments

@micahsnyder
Copy link

I did this

I compiled libcurl 8.9.1 on Windows 11 using cmake with the OpenSSL backend (version 3.3.1, though I also observed the issue with 3.2.0).

Build command:
cmake.exe .. -G "Visual Studio 17 2022" -A x64 -D CMAKE_INSTALL_PREFIX="C:/Users/micasnyd/dev/clamav-deps/x64" -D BUILD_LIBCURL_DOCS=OFF -D BUILD_SHARED_LIBS=ON -D CURL_USE_OPENSSL=ON -D OPENSSL_INCLUDE_DIR="C:/Users/micasnyd/dev/clamav-deps/x64/include" -D LIB_EAY_RELEASE="C:/Users/micasnyd/dev/clamav-deps/x64/lib/libcrypto.lib" -D SSL_EAY_RELEASE="C:/Users/micasnyd/dev/clamav-deps/x64/lib/libssl.lib" -D ZLIB_INCLUDE_DIR="C:/Users/micasnyd/dev/clamav-deps/x64/include" -D ZLIB_LIBRARY_RELEASE="C:/Users/micasnyd/dev/clamav-deps/x64/lib/zlibstatic.lib" -D LIBSSH2_INCLUDE_DIR="C:/Users/micasnyd/dev/clamav-deps/x64/include" -D LIBSSH2_LIBRARY="C:/Users/micasnyd/dev/clamav-deps/x64/lib/libssh2.lib" -D USE_NGHTTP2=ON -D NGHTTP2_INCLUDE_DIR="C:/Users/micasnyd/dev/clamav-deps/x64/include" -D NGHTTP2_LIBRARY="C:/Users/micasnyd/dev/clamav-deps/x64/lib/nghttp2.lib" -D BUILD_CURL_EXE=OFF

I encountered a build failure due to unresolved external symbols.

cmake.exe .. -G "Visual Studio 17 2022" -A x64  -D CMAKE_INSTALL_PREFIX="C:/Users/micasnyd/dev/clamav-deps/x64"  -D BUILD_LIBCURL_DOCS=OFF  -D BUILD_SHARED_LIBS=ON  -D CURL_USE_OPENSSL=ON  -D OPENSSL_INCLUDE_DIR="C:/Users/micasnyd/dev/clamav-deps/x64/include"  -D LIB_EAY_RELEASE="C:/Users/micasnyd/dev/clamav-deps/x64/lib/libcrypto.lib"  -D SSL_EAY_RELEASE="C:/Users/micasnyd/dev/clamav-deps/x64/lib/libssl.lib"  -D ZLIB_INCLUDE_DIR="C:/Users/micasnyd/dev/clamav-deps/x64/include"  -D ZLIB_LIBRARY_RELEASE="C:/Users/micasnyd/dev/clamav-deps/x64/lib/zlibstatic.lib"  -D LIBSSH2_INCLUDE_DIR="C:/Users/micasnyd/dev/clamav-deps/x64/include"  -D LIBSSH2_LIBRARY="C:/Users/micasnyd/dev/clamav-deps/x64/lib/libssh2.lib"  -D USE_NGHTTP2=ON  -D NGHTTP2_INCLUDE_DIR="C:/Users/micasnyd/dev/clamav-deps/x64/include"  -D NGHTTP2_LIBRARY="C:/Users/micasnyd/dev/clamav-deps/x64/lib/nghttp2.lib"  -D BUILD_CURL_EXE=OFF
-- Using CMake version 3.29.0
-- The C compiler identification is MSVC 19.39.33523.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.39.33519/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- curl version=[8.9.0]
-- Found Perl: C:/Strawberry/perl/bin/perl.exe (found version "5.38.2")
-- Found OpenSSL: C:/Users/micasnyd/dev/clamav-deps/x64/lib/libcrypto.lib (found version "3.3.1")
-- Looking for OPENSSL_IS_BORINGSSL
-- Looking for OPENSSL_IS_BORINGSSL - not found
-- Looking for OPENSSL_IS_AWSLC
-- Looking for OPENSSL_IS_AWSLC - not found
-- Found ZLIB: C:/Users/micasnyd/dev/clamav-deps/x64/lib/zlibstatic.lib (found version "1.3.1")
-- Looking for SSL_set0_wbio
-- Looking for SSL_set0_wbio - found
-- Looking for SSL_CTX_set_srp_username
-- Looking for SSL_CTX_set_srp_username - found
-- Found NGHTTP2: C:/Users/micasnyd/dev/clamav-deps/x64/lib/nghttp2.lib
-- Looking for idn2_lookup_ul in idn2
-- Looking for idn2_lookup_ul in idn2 - not found
-- Checking for module 'libidn2'
--   Found libidn2, version 2.1.1
-- Could NOT find LibPSL (missing: LIBPSL_LIBRARY LIBPSL_INCLUDE_DIR)
-- Found LibSSH2: C:/Users/micasnyd/dev/clamav-deps/x64/lib/libssh2.lib (found version "1.11.0")
-- Performing Test HAVE_WIN32_WINNT
-- Performing Test HAVE_WIN32_WINNT - Success
-- Found _WIN32_WINNT=0x0a00
-- Looking for stdint.h
-- Looking for stdint.h - found
-- Check size of size_t
-- Check size of size_t - done
-- Check size of ssize_t
-- Check size of ssize_t - failed
-- Check size of long long
-- Check size of long long - done
-- Check size of long
-- Check size of long - done
-- Check size of int
-- Check size of int - done
-- Check size of __int64
-- Check size of __int64 - done
-- Check size of time_t
-- Check size of time_t - done
-- Check size of ADDRESS_FAMILY
-- Check size of ADDRESS_FAMILY - done
-- Check size of off_t
-- Check size of off_t - done
-- Check size of curl_off_t
-- Check size of curl_off_t - done
-- Check size of curl_socket_t
-- Check size of curl_socket_t - done
-- Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
-- Features: alt-svc AsynchDNS HSTS HTTP2 HTTPS-proxy IDN IPv6 Largefile libz NTLM SSL threadsafe TLS-SRP UnixSockets
-- Enabled SSL backends: OpenSSL
-- Configuring done (40.6s)
-- Generating done (4.6s)
-- Build files have been written to: C:/Users/micasnyd/dev/work/x64/curl-8.9.0/build
C:\Users\micasnyd\dev\work\x64\curl-8.9.0>cd build
C:\Users\micasnyd\dev\work\x64\curl-8.9.0\build>CALL cmake.exe --build . --config Release
MSBuild version 17.9.8+b34f75857 for .NET Framework
1>Checking Build System
Generating curl-config.1
Building Custom Rule C:/Users/micasnyd/dev/work/x64/curl-8.9.0/docs/CMakeLists.txt
Generating mk-ca-bundle.1
Building Custom Rule C:/Users/micasnyd/dev/work/x64/curl-8.9.0/docs/CMakeLists.txt
Building Custom Rule C:/Users/micasnyd/dev/work/x64/curl-8.9.0/lib/CMakeLists.txt
altsvc.c
amigaos.c
asyn-ares.c
asyn-thread.c
base64.c
bufq.c
bufref.c
c-hyper.c
cf-h1-proxy.c
cf-h2-proxy.c
cf-haproxy.c
cf-https-connect.c
cf-socket.c
cfilters.c
conncache.c
connect.c
content_encoding.c
cookie.c
curl_addrinfo.c
curl_des.c
curl_endian.c
curl_fnmatch.c
curl_get_line.c
curl_gethostname.c
curl_gssapi.c
curl_memrchr.c
curl_multibyte.c
curl_ntlm_core.c
curl_path.c
curl_range.c
curl_rtmp.c
curl_sasl.c
curl_sha512_256.c
curl_sspi.c
curl_threads.c
curl_trc.c
cw-out.c
dict.c
doh.c
dynbuf.c
dynhds.c
easy.c
easygetopt.c
easyoptions.c
escape.c
file.c
fileinfo.c
fopen.c
formdata.c
ftp.c
ftplistparser.c
getenv.c
getinfo.c
gopher.c
hash.c
headers.c
hmac.c
hostasyn.c
hostip.c
hostip4.c
hostip6.c
hostsyn.c
hsts.c
http.c
http1.c
http2.c
http_aws_sigv4.c
http_chunks.c
http_digest.c
http_negotiate.c
http_ntlm.c
http_proxy.c
idn.c
if2ip.c
imap.c
inet_ntop.c
inet_pton.c
krb5.c
ldap.c
llist.c
macos.c
md4.c
md5.c
memdebug.c
mime.c
mprintf.c
mqtt.c
multi.c
netrc.c
nonblock.c
noproxy.c
openldap.c
parsedate.c
pingpong.c
pop3.c
progress.c
psl.c
rand.c
rename.c
request.c
rtsp.c
select.c
sendf.c
setopt.c
sha256.c
share.c
slist.c
smb.c
smtp.c
socketpair.c
socks.c
socks_gssapi.c
socks_sspi.c
speedcheck.c
splay.c
strcase.c
strdup.c
strerror.c
strtok.c
strtoofft.c
system_win32.c
telnet.c
tftp.c
timediff.c
timeval.c
transfer.c
url.c
urlapi.c
version.c
version_win32.c
warnless.c
ws.c
cleartext.c
cram.c
digest.c
digest_sspi.c
gsasl.c
krb5_gssapi.c
krb5_sspi.c
ntlm.c
ntlm_sspi.c
oauth2.c
spnego_gssapi.c
spnego_sspi.c
vauth.c
bearssl.c
cipher_suite.c
gtls.c
hostcheck.c
keylog.c
mbedtls.c
mbedtls_threadlock.c
openssl.c
rustls.c
schannel.c
schannel_verify.c
sectransp.c
vtls.c
wolfssl.c
x509asn1.c
curl_msh3.c
curl_ngtcp2.c
curl_osslq.c
curl_quiche.c
vquic.c
vquic-tls.c
libssh.c
libssh2.c
wolfssh.c
libcurl_object.vcxproj -> C:\Users\micasnyd\dev\work\x64\curl-8.9.0\build\lib\libcurl_object.dir\Release\libcurl_object.lib
Building Custom Rule C:/Users/micasnyd/dev/work/x64/curl-8.9.0/lib/CMakeLists.txt
dllmain.c
Creating library C:/Users/micasnyd/dev/work/x64/curl-8.9.0/build/lib/Release/libcurl_imp.lib and object C:/Users/micasnyd/dev/work/x64/curl-8.9.0/build/lib/Release/libcurl_imp.exp
openssl.obj : error LNK2019: unresolved external symbol EVP_PKEY_id referenced in function Curl_ossl_certchain [C:\Users\micasnyd\dev\work\x64\curl-8.9.0\build\lib\libcurl_shared.vcxproj]
openssl.obj : error LNK2019: unresolved external symbol EVP_PKEY_bits referenced in function Curl_oss_check_peer_cert [C:\Users\micasnyd\dev\work\x64\curl-8.9.0\build\lib\libcurl_shared.vcxproj]
openssl.obj : error LNK2019: unresolved external symbol EVP_PKEY_security_bits referenced in function Curl_oss_check_peer_cert [C:\Users\micasnyd\dev\work\x64\curl-8.9.0\build\lib\libcurl_shared.vcxproj]
openssl.obj : error LNK2019: unresolved external symbol SSL_get_peer_certificate referenced in function Curl_oss_check_peer_cert [C:\Users\micasnyd\dev\work\x64\curl-8.9.0\build\lib\libcurl_shared.vcxproj]
C:\Users\micasnyd\dev\work\x64\curl-8.9.0\build\lib\Release\libcurl.dll : fatal error LNK1120: 4 unresolved externals [C:\Users\micasnyd\dev\work\x64\curl-8.9.0\build\lib\libcurl_shared.vcxproj]
libcurl-8.9.0 x64 build failed!
Command:
cd build
CALL cmake.exe --build . --config Release
Exit code: 1
"make" script failed for x64 build

I think the unresolved symbols in question were renamed in OpenSSL 3.x and the original names were converted to macros for backwards compatibility. So I suspect there's a header issue of some sort, and the macros aren't being included.

I checked with previous versions:

  • 8.9.0: fails with this same issue
  • 8.8.0: build succeeds

I expected the following

build should complete successfully

curl/libcurl version

curl 8.9.0

operating system

Windows 11 x64

@vszakats
Copy link
Member

vszakats commented Aug 6, 2024

It may be a case of OpenSSL header vs lib confusion.

Can you test if either of these settings would fix your build?:

  1. set PKG_CONFIG_LIBDIR= before calling cmake
  2. add -DUSE_LIBIDN2=OFF to the cmake command

@micahsnyder
Copy link
Author

@vszakats Apologies for the delay.

I tested with both settings and the build works. I haven't tried just one or the other. Would you like me to test that? Or test your PR?

@vszakats
Copy link
Member

vszakats commented Aug 9, 2024

@micahsnyder: Thanks! Yes, it would help if you could do a test with only the first setting (PKG_CONFIG_LIBDIR=).

It'd also be useful to see your build output, after you add this code to curl's main CMakeList.txt, right below the line: project(CURL C):

foreach(_env IN ITEMS PKG_CONFIG_PATH PKG_CONFIG_LIBDIR PKG_CONFIG_SYSROOT_DIR)
  if(DEFINED ENV{${_env}})
    message(STATUS "pkg-config ${_env}: '$ENV{${_env}}'")
  endif()
endforeach()

@micahsnyder
Copy link
Author

@vszakats For powershell it seems the correct way to set the environment variable is $env:PKG_CONFIG_LIBDIR = "...". Using set didn't work for me.

After switching to use $env: then this worked:


x64/curl-8.9.1/build via △ v3.29.0 took 7s
❯ rm -r -force ..\build\*

x64/curl-8.9.1/build
❯ $env:PKG_CONFIG_LIBDIR = "C:\Users\micasnyd\dev\clamav-deps\x64\lib"

x64/curl-8.9.1/build
❯ cmake.exe .. -G "Visual Studio 17 2022" -A x64  -D CMAKE_INSTALL_PREFIX="C:/Users/micasnyd/dev/clamav-deps/x64"  -D BUILD_LIBCURL_DOCS=OFF  -D BUILD_SHARED_LIBS=ON  -D CURL_USE_OPENSSL=ON  -D OPENSSL_INCLUDE_DIR="C:/Users/micasnyd/dev/clamav-deps/x64/include"  -D LIB_EAY_RELEASE="C:/Users/micasnyd/dev/clamav-deps/x64/lib/libcrypto.lib"  -D SSL_EAY_RELEASE="C:/Users/micasnyd/dev/clamav-deps/x64/lib/libssl.lib"  -D ZLIB_INCLUDE_DIR="C:/Users/micasnyd/dev/clamav-deps/x64/include"  -D ZLIB_LIBRARY_RELEASE="C:/Users/micasnyd/dev/clamav-deps/x64/lib/zlibstatic.lib"  -D LIBSSH2_INCLUDE_DIR="C:/Users/micasnyd/dev/clamav-deps/x64/include"  -D LIBSSH2_LIBRARY="C:/Users/micasnyd/dev/clamav-deps/x64/lib/libssh2.lib"  -D USE_NGHTTP2=ON  -D NGHTTP2_INCLUDE_DIR="C:/Users/micasnyd/dev/clamav-deps/x64/include"  -D NGHTTP2_LIBRARY="C:/Users/micasnyd/dev/clamav-deps/x64/lib/nghttp2.lib"  -D BUILD_CURL_EXE=OFF
-- Using CMake version 3.29.0
-- Selecting Windows SDK version 10.0.22621.0 to target Windows 10.0.22631.
-- The C compiler identification is MSVC 19.39.33523.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.39.33519/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- curl version=[8.9.1]
-- Found Perl: C:/Strawberry/perl/bin/perl.exe (found version "5.38.2")
-- Found OpenSSL: C:/Users/micasnyd/dev/clamav-deps/x64/lib/libcrypto.lib (found version "3.3.1")
-- Looking for OPENSSL_IS_BORINGSSL
-- Looking for OPENSSL_IS_BORINGSSL - not found
-- Looking for OPENSSL_IS_AWSLC
-- Looking for OPENSSL_IS_AWSLC - not found
-- Found ZLIB: C:/Users/micasnyd/dev/clamav-deps/x64/lib/zlibstatic.lib (found version "1.3.1")
-- Looking for SSL_set0_wbio
-- Looking for SSL_set0_wbio - found
-- Looking for SSL_CTX_set_srp_username
-- Looking for SSL_CTX_set_srp_username - found
-- Found NGHTTP2: C:/Users/micasnyd/dev/clamav-deps/x64/lib/nghttp2.lib
-- Looking for idn2_lookup_ul in idn2
-- Looking for idn2_lookup_ul in idn2 - not found
-- Checking for module 'libidn2'
--   Can't find libidn2.pc in any of C:/Users/micasnyd/dev/clamav-deps/x64/lib
use the PKG_CONFIG_PATH environment variable, or
specify extra search paths via 'search_paths'
-- Could NOT find LibPSL (missing: LIBPSL_LIBRARY LIBPSL_INCLUDE_DIR)
-- Found LibSSH2: C:/Users/micasnyd/dev/clamav-deps/x64/lib/libssh2.lib (found version "1.11.0")
-- Performing Test HAVE_WIN32_WINNT
-- Performing Test HAVE_WIN32_WINNT - Success
-- Found _WIN32_WINNT=0x0a00
-- Looking for stdint.h
-- Looking for stdint.h - found
-- Check size of size_t
-- Check size of size_t - done
-- Check size of ssize_t
-- Check size of ssize_t - failed
-- Check size of long long
-- Check size of long long - done
-- Check size of long
-- Check size of long - done
-- Check size of int
-- Check size of int - done
-- Check size of __int64
-- Check size of __int64 - done
-- Check size of time_t
-- Check size of time_t - done
-- Check size of ADDRESS_FAMILY
-- Check size of ADDRESS_FAMILY - done
-- Check size of off_t
-- Check size of off_t - done
-- Check size of curl_off_t
-- Check size of curl_off_t - done
-- Check size of curl_socket_t
-- Check size of curl_socket_t - done
-- Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
-- Features: alt-svc AsynchDNS HSTS HTTP2 HTTPS-proxy IPv6 Largefile libz NTLM SSL threadsafe TLS-SRP UnixSockets
-- Enabled SSL backends: OpenSSL
-- Configuring done (43.5s)
-- Generating done (4.9s)
-- Build files have been written to: C:/Users/micasnyd/dev/work/x64/curl-8.9.1/build

x64/curl-8.9.1/build via △ took 49s
❯ cmake --build . --config Release
MSBuild version 17.9.8+b34f75857 for .NET Framework

  1>Checking Build System
  Generating curl-config.1
  Building Custom Rule C:/Users/micasnyd/dev/work/x64/curl-8.9.1/docs/CMakeLists.txt
  Generating mk-ca-bundle.1
  Building Custom Rule C:/Users/micasnyd/dev/work/x64/curl-8.9.1/docs/CMakeLists.txt
  Building Custom Rule C:/Users/micasnyd/dev/work/x64/curl-8.9.1/lib/CMakeLists.txt
  altsvc.c
  amigaos.c
  asyn-ares.c
  asyn-thread.c
  base64.c
  bufq.c
  bufref.c
  c-hyper.c
  cf-h1-proxy.c
  cf-h2-proxy.c
  cf-haproxy.c
  cf-https-connect.c
  cf-socket.c
  cfilters.c
  conncache.c
  connect.c
  content_encoding.c
  cookie.c
  curl_addrinfo.c
  curl_des.c
  curl_endian.c
  curl_fnmatch.c
  curl_get_line.c
  curl_gethostname.c
  curl_gssapi.c
  curl_memrchr.c
  curl_multibyte.c
  curl_ntlm_core.c
  curl_path.c
  curl_range.c
  curl_rtmp.c
  curl_sasl.c
  curl_sha512_256.c
  curl_sspi.c
  curl_threads.c
  curl_trc.c
  cw-out.c
  dict.c
  doh.c
  dynbuf.c
  dynhds.c
  easy.c
  easygetopt.c
  easyoptions.c
  escape.c
  file.c
  fileinfo.c
  fopen.c
  formdata.c
  ftp.c
  ftplistparser.c
  getenv.c
  getinfo.c
  gopher.c
  hash.c
  headers.c
  hmac.c
  hostasyn.c
  hostip.c
  hostip4.c
  hostip6.c
  hostsyn.c
  hsts.c
  http.c
  http1.c
  http2.c
  http_aws_sigv4.c
  http_chunks.c
  http_digest.c
  http_negotiate.c
  http_ntlm.c
  http_proxy.c
  idn.c
  if2ip.c
  imap.c
  inet_ntop.c
  inet_pton.c
  krb5.c
  ldap.c
  llist.c
  macos.c
  md4.c
  md5.c
  memdebug.c
  mime.c
  mprintf.c
  mqtt.c
  multi.c
  netrc.c
  nonblock.c
  noproxy.c
  openldap.c
  parsedate.c
  pingpong.c
  pop3.c
  progress.c
  psl.c
  rand.c
  rename.c
  request.c
  rtsp.c
  select.c
  sendf.c
  setopt.c
  sha256.c
  share.c
  slist.c
  smb.c
  smtp.c
  socketpair.c
  socks.c
  socks_gssapi.c
  socks_sspi.c
  speedcheck.c
  splay.c
  strcase.c
  strdup.c
  strerror.c
  strtok.c
  strtoofft.c
  system_win32.c
  telnet.c
  tftp.c
  timediff.c
  timeval.c
  transfer.c
  url.c
  urlapi.c
  version.c
  version_win32.c
  warnless.c
  ws.c
  cleartext.c
  cram.c
  digest.c
  digest_sspi.c
  gsasl.c
  krb5_gssapi.c
  krb5_sspi.c
  ntlm.c
  ntlm_sspi.c
  oauth2.c
  spnego_gssapi.c
  spnego_sspi.c
  vauth.c
  bearssl.c
  cipher_suite.c
  gtls.c
  hostcheck.c
  keylog.c
  mbedtls.c
  mbedtls_threadlock.c
  openssl.c
  rustls.c
  schannel.c
  schannel_verify.c
  sectransp.c
  vtls.c
  wolfssl.c
  x509asn1.c
  curl_msh3.c
  curl_ngtcp2.c
  curl_osslq.c
  curl_quiche.c
  vquic.c
  vquic-tls.c
  libssh.c
  libssh2.c
  wolfssh.c
  libcurl_object.vcxproj -> C:\Users\micasnyd\dev\work\x64\curl-8.9.1\build\lib\libcurl_object.dir\Release\libcurl_object.lib
  Building Custom Rule C:/Users/micasnyd/dev/work/x64/curl-8.9.1/lib/CMakeLists.txt
  dllmain.c
     Creating library C:/Users/micasnyd/dev/work/x64/curl-8.9.1/build/lib/Release/libcurl_imp.lib and object C:/Users/micasnyd/dev/work/x64/curl-8.9.1/build/li
  b/Release/libcurl_imp.exp
  libcurl_shared.vcxproj -> C:\Users\micasnyd\dev\work\x64\curl-8.9.1\build\lib\Release\libcurl.dll
  Building Custom Rule C:/Users/micasnyd/dev/work/x64/curl-8.9.1/CMakeLists.txt

@micahsnyder
Copy link
Author

@vszakats I tried your suggested change:
image

I also made sure to unset that environment variable. This didn't work:

x64/curl-8.9.1/build via △ took 9s
❯ rm -r -force ..\build\*

x64/curl-8.9.1/build took 2s
❯ $env:PKG_CONFIG_LIBDIR = $null

x64/curl-8.9.1/build
❯ echo $env:PKG_CONFIG_LIBDIR

x64/curl-8.9.1/build
❯ cmake.exe .. -G "Visual Studio 17 2022" -A x64  -D CMAKE_INSTALL_PREFIX="C:/Users/micasnyd/dev/clamav-deps/x64"  -D BUILD_LIBCURL_DOCS=OFF  -D BUILD_SHARED_LIBS=ON  -D CURL_USE_OPENSSL=ON  -D OPENSSL_INCLUDE_DIR="C:/Users/micasnyd/dev/clamav-deps/x64/include"  -D LIB_EAY_RELEASE="C:/Users/micasnyd/dev/clamav-deps/x64/lib/libcrypto.lib"  -D SSL_EAY_RELEASE="C:/Users/micasnyd/dev/clamav-deps/x64/lib/libssl.lib"  -D ZLIB_INCLUDE_DIR="C:/Users/micasnyd/dev/clamav-deps/x64/include"  -D ZLIB_LIBRARY_RELEASE="C:/Users/micasnyd/dev/clamav-deps/x64/lib/zlibstatic.lib"  -D LIBSSH2_INCLUDE_DIR="C:/Users/micasnyd/dev/clamav-deps/x64/include"  -D LIBSSH2_LIBRARY="C:/Users/micasnyd/dev/clamav-deps/x64/lib/libssh2.lib"  -D USE_NGHTTP2=ON  -D NGHTTP2_INCLUDE_DIR="C:/Users/micasnyd/dev/clamav-deps/x64/include"  -D NGHTTP2_LIBRARY="C:/Users/micasnyd/dev/clamav-deps/x64/lib/nghttp2.lib"  -D BUILD_CURL_EXE=OFF
-- Using CMake version 3.29.0
-- Selecting Windows SDK version 10.0.22621.0 to target Windows 10.0.22631.
-- The C compiler identification is MSVC 19.39.33523.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.39.33519/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- curl version=[8.9.1]
-- Found Perl: C:/Strawberry/perl/bin/perl.exe (found version "5.38.2")
-- Found OpenSSL: C:/Users/micasnyd/dev/clamav-deps/x64/lib/libcrypto.lib (found version "3.3.1")
-- Looking for OPENSSL_IS_BORINGSSL
-- Looking for OPENSSL_IS_BORINGSSL - not found
-- Looking for OPENSSL_IS_AWSLC
-- Looking for OPENSSL_IS_AWSLC - not found
-- Found ZLIB: C:/Users/micasnyd/dev/clamav-deps/x64/lib/zlibstatic.lib (found version "1.3.1")
-- Looking for SSL_set0_wbio
-- Looking for SSL_set0_wbio - found
-- Looking for SSL_CTX_set_srp_username
-- Looking for SSL_CTX_set_srp_username - found
-- Found NGHTTP2: C:/Users/micasnyd/dev/clamav-deps/x64/lib/nghttp2.lib
-- Looking for idn2_lookup_ul in idn2
-- Looking for idn2_lookup_ul in idn2 - not found
-- Checking for module 'libidn2'
--   Found libidn2, version 2.1.1
-- Could NOT find LibPSL (missing: LIBPSL_LIBRARY LIBPSL_INCLUDE_DIR)
-- Found LibSSH2: C:/Users/micasnyd/dev/clamav-deps/x64/lib/libssh2.lib (found version "1.11.0")
-- Performing Test HAVE_WIN32_WINNT
-- Performing Test HAVE_WIN32_WINNT - Success
-- Found _WIN32_WINNT=0x0a00
-- Looking for stdint.h
-- Looking for stdint.h - found
-- Check size of size_t
-- Check size of size_t - done
-- Check size of ssize_t
-- Check size of ssize_t - failed
-- Check size of long long
-- Check size of long long - done
-- Check size of long
-- Check size of long - done
-- Check size of int
-- Check size of int - done
-- Check size of __int64
-- Check size of __int64 - done
-- Check size of time_t
-- Check size of time_t - done
-- Check size of ADDRESS_FAMILY
-- Check size of ADDRESS_FAMILY - done
-- Check size of off_t
-- Check size of off_t - done
-- Check size of curl_off_t
-- Check size of curl_off_t - done
-- Check size of curl_socket_t
-- Check size of curl_socket_t - done
-- Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
-- Features: alt-svc AsynchDNS HSTS HTTP2 HTTPS-proxy IDN IPv6 Largefile libz NTLM SSL threadsafe TLS-SRP UnixSockets
-- Enabled SSL backends: OpenSSL
-- Configuring done (39.8s)
-- Generating done (4.8s)
-- Build files have been written to: C:/Users/micasnyd/dev/work/x64/curl-8.9.1/build

x64/curl-8.9.1/build via △ v3.29.0 took 45s
❯ cmake --build . --config Release
MSBuild version 17.9.8+b34f75857 for .NET Framework

  1>Checking Build System
  Generating curl-config.1
  Building Custom Rule C:/Users/micasnyd/dev/work/x64/curl-8.9.1/docs/CMakeLists.txt
  Generating mk-ca-bundle.1
  Building Custom Rule C:/Users/micasnyd/dev/work/x64/curl-8.9.1/docs/CMakeLists.txt
  Building Custom Rule C:/Users/micasnyd/dev/work/x64/curl-8.9.1/lib/CMakeLists.txt
  altsvc.c
  amigaos.c
  asyn-ares.c
  asyn-thread.c
  base64.c
  bufq.c
  bufref.c
  c-hyper.c
  cf-h1-proxy.c
  cf-h2-proxy.c
  cf-haproxy.c
  cf-https-connect.c
  cf-socket.c
  cfilters.c
  conncache.c
  connect.c
  content_encoding.c
  cookie.c
  curl_addrinfo.c
  curl_des.c
  curl_endian.c
  curl_fnmatch.c
  curl_get_line.c
  curl_gethostname.c
  curl_gssapi.c
  curl_memrchr.c
  curl_multibyte.c
  curl_ntlm_core.c
  curl_path.c
  curl_range.c
  curl_rtmp.c
  curl_sasl.c
  curl_sha512_256.c
  curl_sspi.c
  curl_threads.c
  curl_trc.c
  cw-out.c
  dict.c
  doh.c
  dynbuf.c
  dynhds.c
  easy.c
  easygetopt.c
  easyoptions.c
  escape.c
  file.c
  fileinfo.c
  fopen.c
  formdata.c
  ftp.c
  ftplistparser.c
  getenv.c
  getinfo.c
  gopher.c
  hash.c
  headers.c
  hmac.c
  hostasyn.c
  hostip.c
  hostip4.c
  hostip6.c
  hostsyn.c
  hsts.c
  http.c
  http1.c
  http2.c
  http_aws_sigv4.c
  http_chunks.c
  http_digest.c
  http_negotiate.c
  http_ntlm.c
  http_proxy.c
  idn.c
  if2ip.c
  imap.c
  inet_ntop.c
  inet_pton.c
  krb5.c
  ldap.c
  llist.c
  macos.c
  md4.c
  md5.c
  memdebug.c
  mime.c
  mprintf.c
  mqtt.c
  multi.c
  netrc.c
  nonblock.c
  noproxy.c
  openldap.c
  parsedate.c
  pingpong.c
  pop3.c
  progress.c
  psl.c
  rand.c
  rename.c
  request.c
  rtsp.c
  select.c
  sendf.c
  setopt.c
  sha256.c
  share.c
  slist.c
  smb.c
  smtp.c
  socketpair.c
  socks.c
  socks_gssapi.c
  socks_sspi.c
  speedcheck.c
  splay.c
  strcase.c
  strdup.c
  strerror.c
  strtok.c
  strtoofft.c
  system_win32.c
  telnet.c
  tftp.c
  timediff.c
  timeval.c
  transfer.c
  url.c
  urlapi.c
  version.c
  version_win32.c
  warnless.c
  ws.c
  cleartext.c
  cram.c
  digest.c
  digest_sspi.c
  gsasl.c
  krb5_gssapi.c
  krb5_sspi.c
  ntlm.c
  ntlm_sspi.c
  oauth2.c
  spnego_gssapi.c
  spnego_sspi.c
  vauth.c
  bearssl.c
  cipher_suite.c
  gtls.c
  hostcheck.c
  keylog.c
  mbedtls.c
  mbedtls_threadlock.c
  openssl.c
  rustls.c
  schannel.c
  schannel_verify.c
  sectransp.c
  vtls.c
  wolfssl.c
  x509asn1.c
  curl_msh3.c
  curl_ngtcp2.c
  curl_osslq.c
  curl_quiche.c
  vquic.c
  vquic-tls.c
  libssh.c
  libssh2.c
  wolfssh.c
  libcurl_object.vcxproj -> C:\Users\micasnyd\dev\work\x64\curl-8.9.1\build\lib\libcurl_object.dir\Release\libcurl_object.lib
  Building Custom Rule C:/Users/micasnyd/dev/work/x64/curl-8.9.1/lib/CMakeLists.txt
  dllmain.c
     Creating library C:/Users/micasnyd/dev/work/x64/curl-8.9.1/build/lib/Release/libcurl_imp.lib and object C:/Users/micasnyd/dev/work/x64/curl-8.9.1/build/li
  b/Release/libcurl_imp.exp
openssl.obj : error LNK2019: unresolved external symbol EVP_PKEY_id referenced in function Curl_ossl_certchain [C:\Users\micasnyd\dev\work\x64\curl-8.9.1\build
\lib\libcurl_shared.vcxproj]
openssl.obj : error LNK2019: unresolved external symbol EVP_PKEY_bits referenced in function Curl_oss_check_peer_cert [C:\Users\micasnyd\dev\work\x64\curl-8.9.
1\build\lib\libcurl_shared.vcxproj]
openssl.obj : error LNK2019: unresolved external symbol EVP_PKEY_security_bits referenced in function Curl_oss_check_peer_cert [C:\Users\micasnyd\dev\work\x64\
curl-8.9.1\build\lib\libcurl_shared.vcxproj]
openssl.obj : error LNK2019: unresolved external symbol SSL_get_peer_certificate referenced in function Curl_oss_check_peer_cert [C:\Users\micasnyd\dev\work\x6
4\curl-8.9.1\build\lib\libcurl_shared.vcxproj]
C:\Users\micasnyd\dev\work\x64\curl-8.9.1\build\lib\Release\libcurl.dll : fatal error LNK1120: 4 unresolved externals [C:\Users\micasnyd\dev\work\x64\curl-8.9.
1\build\lib\libcurl_shared.vcxproj]

@vszakats
Copy link
Member

vszakats commented Aug 9, 2024

Thanks for your tests @micahsnyder!

May I ask for one more: without changing/clearing PKG_CONFIG_LIBDIR and with the suggested CMake change?

I'm interested in the top of the cmake output that may show us if any of these PKG_CONFIG_* variables are set in your env by default, and if so to what value(s).

@micahsnyder
Copy link
Author

@vszakats here ya go


x64/curl-8.9.1/build via △ v3.29.0 took 8s
❯ $env:PKG_CONFIG_LIBDIR = "C:\Users\micasnyd\dev\clamav-deps\x64\lib"

x64/curl-8.9.1/build via △
❯ rm -r -force ..\build\*

x64/curl-8.9.1/build
❯ cmake.exe .. -G "Visual Studio 17 2022" -A x64  -D CMAKE_INSTALL_PREFIX="C:/Users/micasnyd/dev/clamav-deps/x64"  -D BUILD_LIBCURL_DOCS=OFF  -D BUILD_SHARED_LIBS=ON  -D CURL_USE_OPENSSL=ON  -D OPENSSL_INCLUDE_DIR="C:/Users/micasnyd/dev/clamav-deps/x64/include"  -D LIB_EAY_RELEASE="C:/Users/micasnyd/dev/clamav-deps/x64/lib/libcrypto.lib"  -D SSL_EAY_RELEASE="C:/Users/micasnyd/dev/clamav-deps/x64/lib/libssl.lib"  -D ZLIB_INCLUDE_DIR="C:/Users/micasnyd/dev/clamav-deps/x64/include"  -D ZLIB_LIBRARY_RELEASE="C:/Users/micasnyd/dev/clamav-deps/x64/lib/zlibstatic.lib"  -D LIBSSH2_INCLUDE_DIR="C:/Users/micasnyd/dev/clamav-deps/x64/include"  -D LIBSSH2_LIBRARY="C:/Users/micasnyd/dev/clamav-deps/x64/lib/libssh2.lib"  -D USE_NGHTTP2=ON  -D NGHTTP2_INCLUDE_DIR="C:/Users/micasnyd/dev/clamav-deps/x64/include"  -D NGHTTP2_LIBRARY="C:/Users/micasnyd/dev/clamav-deps/x64/lib/nghttp2.lib"  -D BUILD_CURL_EXE=OFF
-- Using CMake version 3.29.0
-- Selecting Windows SDK version 10.0.22621.0 to target Windows 10.0.22631.
-- The C compiler identification is MSVC 19.39.33523.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.39.33519/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- pkg-config PKG_CONFIG_LIBDIR: 'C:\Users\micasnyd\dev\clamav-deps\x64\lib'
-- curl version=[8.9.1]
-- Found Perl: C:/Strawberry/perl/bin/perl.exe (found version "5.38.2")
-- Found OpenSSL: C:/Users/micasnyd/dev/clamav-deps/x64/lib/libcrypto.lib (found version "3.3.1")
-- Looking for OPENSSL_IS_BORINGSSL
-- Looking for OPENSSL_IS_BORINGSSL - not found
-- Looking for OPENSSL_IS_AWSLC
-- Looking for OPENSSL_IS_AWSLC - not found
-- Found ZLIB: C:/Users/micasnyd/dev/clamav-deps/x64/lib/zlibstatic.lib (found version "1.3.1")
-- Looking for SSL_set0_wbio
-- Looking for SSL_set0_wbio - found
-- Looking for SSL_CTX_set_srp_username
-- Looking for SSL_CTX_set_srp_username - found
-- Found NGHTTP2: C:/Users/micasnyd/dev/clamav-deps/x64/lib/nghttp2.lib
-- Looking for idn2_lookup_ul in idn2
-- Looking for idn2_lookup_ul in idn2 - not found
-- Checking for module 'libidn2'
--   Can't find libidn2.pc in any of C:/Users/micasnyd/dev/clamav-deps/x64/lib
use the PKG_CONFIG_PATH environment variable, or
specify extra search paths via 'search_paths'
-- Could NOT find LibPSL (missing: LIBPSL_LIBRARY LIBPSL_INCLUDE_DIR)
-- Found LibSSH2: C:/Users/micasnyd/dev/clamav-deps/x64/lib/libssh2.lib (found version "1.11.0")
-- Performing Test HAVE_WIN32_WINNT
-- Performing Test HAVE_WIN32_WINNT - Success
-- Found _WIN32_WINNT=0x0a00
-- Looking for stdint.h
-- Looking for stdint.h - found
-- Check size of size_t
-- Check size of size_t - done
-- Check size of ssize_t
-- Check size of ssize_t - failed
-- Check size of long long
-- Check size of long long - done
-- Check size of long
-- Check size of long - done
-- Check size of int
-- Check size of int - done
-- Check size of __int64
-- Check size of __int64 - done
-- Check size of time_t
-- Check size of time_t - done
-- Check size of ADDRESS_FAMILY
-- Check size of ADDRESS_FAMILY - done
-- Check size of off_t
-- Check size of off_t - done
-- Check size of curl_off_t
-- Check size of curl_off_t - done
-- Check size of curl_socket_t
-- Check size of curl_socket_t - done
-- Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
-- Features: alt-svc AsynchDNS HSTS HTTP2 HTTPS-proxy IPv6 Largefile libz NTLM SSL threadsafe TLS-SRP UnixSockets
-- Enabled SSL backends: OpenSSL
-- Configuring done (35.5s)
-- Generating done (4.2s)
-- Build files have been written to: C:/Users/micasnyd/dev/work/x64/curl-8.9.1/build

x64/curl-8.9.1/build via △ v3.29.0 took 40s
❯ cmake --build . --config Release
MSBuild version 17.9.8+b34f75857 for .NET Framework

  1>Checking Build System
  Generating curl-config.1
  Building Custom Rule C:/Users/micasnyd/dev/work/x64/curl-8.9.1/docs/CMakeLists.txt
  Generating mk-ca-bundle.1
  Building Custom Rule C:/Users/micasnyd/dev/work/x64/curl-8.9.1/docs/CMakeLists.txt
  Building Custom Rule C:/Users/micasnyd/dev/work/x64/curl-8.9.1/lib/CMakeLists.txt
  altsvc.c
  amigaos.c
  asyn-ares.c
  asyn-thread.c
  base64.c
  bufq.c
  bufref.c
  c-hyper.c
  cf-h1-proxy.c
  cf-h2-proxy.c
  cf-haproxy.c
  cf-https-connect.c
  cf-socket.c
  cfilters.c
  conncache.c
  connect.c
  content_encoding.c
  cookie.c
  curl_addrinfo.c
  curl_des.c
  curl_endian.c
  curl_fnmatch.c
  curl_get_line.c
  curl_gethostname.c
  curl_gssapi.c
  curl_memrchr.c
  curl_multibyte.c
  curl_ntlm_core.c
  curl_path.c
  curl_range.c
  curl_rtmp.c
  curl_sasl.c
  curl_sha512_256.c
  curl_sspi.c
  curl_threads.c
  curl_trc.c
  cw-out.c
  dict.c
  doh.c
  dynbuf.c
  dynhds.c
  easy.c
  easygetopt.c
  easyoptions.c
  escape.c
  file.c
  fileinfo.c
  fopen.c
  formdata.c
  ftp.c
  ftplistparser.c
  getenv.c
  getinfo.c
  gopher.c
  hash.c
  headers.c
  hmac.c
  hostasyn.c
  hostip.c
  hostip4.c
  hostip6.c
  hostsyn.c
  hsts.c
  http.c
  http1.c
  http2.c
  http_aws_sigv4.c
  http_chunks.c
  http_digest.c
  http_negotiate.c
  http_ntlm.c
  http_proxy.c
  idn.c
  if2ip.c
  imap.c
  inet_ntop.c
  inet_pton.c
  krb5.c
  ldap.c
  llist.c
  macos.c
  md4.c
  md5.c
  memdebug.c
  mime.c
  mprintf.c
  mqtt.c
  multi.c
  netrc.c
  nonblock.c
  noproxy.c
  openldap.c
  parsedate.c
  pingpong.c
  pop3.c
  progress.c
  psl.c
  rand.c
  rename.c
  request.c
  rtsp.c
  select.c
  sendf.c
  setopt.c
  sha256.c
  share.c
  slist.c
  smb.c
  smtp.c
  socketpair.c
  socks.c
  socks_gssapi.c
  socks_sspi.c
  speedcheck.c
  splay.c
  strcase.c
  strdup.c
  strerror.c
  strtok.c
  strtoofft.c
  system_win32.c
  telnet.c
  tftp.c
  timediff.c
  timeval.c
  transfer.c
  url.c
  urlapi.c
  version.c
  version_win32.c
  warnless.c
  ws.c
  cleartext.c
  cram.c
  digest.c
  digest_sspi.c
  gsasl.c
  krb5_gssapi.c
  krb5_sspi.c
  ntlm.c
  ntlm_sspi.c
  oauth2.c
  spnego_gssapi.c
  spnego_sspi.c
  vauth.c
  bearssl.c
  cipher_suite.c
  gtls.c
  hostcheck.c
  keylog.c
  mbedtls.c
  mbedtls_threadlock.c
  openssl.c
  rustls.c
  schannel.c
  schannel_verify.c
  sectransp.c
  vtls.c
  wolfssl.c
  x509asn1.c
  curl_msh3.c
  curl_ngtcp2.c
  curl_osslq.c
  curl_quiche.c
  vquic.c
  vquic-tls.c
  libssh.c
  libssh2.c
  wolfssh.c
  libcurl_object.vcxproj -> C:\Users\micasnyd\dev\work\x64\curl-8.9.1\build\lib\libcurl_object.dir\Release\libcurl_object.lib
  Building Custom Rule C:/Users/micasnyd/dev/work/x64/curl-8.9.1/lib/CMakeLists.txt
  dllmain.c
     Creating library C:/Users/micasnyd/dev/work/x64/curl-8.9.1/build/lib/Release/libcurl_imp.lib and object C:/Users/micasnyd/dev/work/x64/curl-8.9.1/build/lib/Re
  lease/libcurl_imp.exp
  libcurl_shared.vcxproj -> C:\Users\micasnyd\dev\work\x64\curl-8.9.1\build\lib\Release\libcurl.dll
  Building Custom Rule C:/Users/micasnyd/dev/work/x64/curl-8.9.1/CMakeLists.txt

@vszakats
Copy link
Member

vszakats commented Aug 9, 2024

Thank you @micahsnyder!

What seems to be happening is that your env has the PKG_CONFIG_LIBDIR=C:\<USERPROFILE>\dev\clamav-deps\x64\lib setting, which tells pkg-config to look for dependencies there. It makes CMake find libidn2 which changes header path / libpath in a way that adds an alternate OpenSSL header / lib to the build, which then leads to a mismatched header / lib situation (building against one version of the headers and linking to a different version.)

More details could be seen via a verbose build log.

Unless there is a good reason to keep the PKG_CONFIG_LIBDIR env, the solution is to delete it. If it's needed, the conflict needs to be fixed differently, e.g. by deleting one OpenSSL copy. USE_LIBIDN2=OFF may also work as a temporary workaround.

As for curl's side, we're not yet sure what's the best way to allowlist and handle toggling pkg-config lookups.
Reports like yours help figuring it out. Thanks again!

@vszakats vszakats added the not-a-curl-bug This is not a bug in curl label Aug 9, 2024
@vszakats
Copy link
Member

vszakats commented Aug 9, 2024

One more: Just a shot in the dark for configuring OpenSSL: It might work better via -DOPENSSL_ROOT_DIR= (vs OPENSSL_INCLUDE_DIR). This tells where to look for the libs and headers, while the other only points to the headers.

@micahsnyder
Copy link
Author

Sounds good. Thanks @vszakats. I don't do as much dev on Windows as I do on Linux these days. To be honest, didn't know that I have libidn2 anywhere on this box. In fact, I haven't heard of it before.

I modified the curl CMakeLists to print where it found libidn2 and discovered that it pkg-config somehow found it in C:/Strawberry which is how I installed Perl, which necessary to compile OpenSSL on Windows (due to their hand-crafted build system):

-- Found libidn2 2.1.1 in C:/Strawberry/c/lib/pkgconfig/../.. with include dir C:/Strawberry/c/lib/pkgconfig/../../include

In the past we've used ActivePerl to build OpenSSL. But ActiveState has been trying to force users to register accounts and use their development tools in order to obtain ActivePerl. Hence switching to Strawberry Perl.

I'll probably work around it by setting USE_LIBIDN2=OFF.

@vszakats thank you for your support on this issue.

@jay jay removed the needs-info label Aug 9, 2024
@jay jay closed this as completed Aug 9, 2024
@vszakats
Copy link
Member

vszakats commented Aug 9, 2024

Ah okay, so pkg-config is picking up Strawberry stuff! Presumably by default? This changes the situation a little bit, but also explains where the colliding OpenSSL bits may be coming from (Strawberry ships with one!). Meaning the problem might not have been PKG_CONFIG_LIBDIR per se, but setting it to empty avoids picking up stuff from default locations.

Peeking into Strawberry: It comes with a Perl implemenation of pkg-config, libidn2, OpenSSL, mingw and a list of other things.

Windows can present interesting situations indeed when mixing its many "islands" of quasi package envs. OpenSSL specifically is prone for confusion, in other envs too due when using forks or versions side by side. We use tricks in CI to avoid issues.

@micahsnyder
Copy link
Author

Another thought -- it would be nice if we could disable pkg-config. I tried -D PKG_CONFIG_FOUND=FALSE, with no luck.

IMO, the worst thing about the C language (beyond memory safety) is that the build systems comb your harddrive to find libraries.
It means you can't guarantee reproducible builds unless you distribute entire operating systems (e.g. VMs or Docker images) for your build environment. /rant

@micahsnyder
Copy link
Author

Oh, this works: -D PKG_CONFIG_EXECUTABLE=none

@micahsnyder
Copy link
Author

@vszakats If you're interested, I built Mussels as a cross-platform solution to automate building C library dependency chains in a way that is as deterministic as possible, while still using each library's build system.

https://github.com/Cisco-Talos/Mussels

Our recipe for building libcurl is here: https://github.com/Cisco-Talos/clamav-mussels-cookbook/blob/master/recipes/libcurl-8.yaml

Time for me to update that recipe with what I've learned today.

@vszakats
Copy link
Member

vszakats commented Aug 9, 2024

@micahsnyder Thanks for the -DPKG_CONFIG_EXECUTABLE=none tip, I'll be testing it! And the Mussels link with recipe, I did not know about it.

Yeah, Windows having no standards for nothing at all, makes it an anything-goes kind of environment. I wish there was a standard lib format, a universal Windows SDK and some naming conventions for starters. One can dream!

You can find my attempt for building curl (and dependencies) reproducibly at: https://github.com/curl/curl-for-win

@micahsnyder
Copy link
Author

@vszakats Your curl-for-win project is impressive!

Akin to my homegrown Mussels project, Microsoft has "vcpkg":

They have a ton of recipes for Windows, and some for other platforms. A couple years ago they made it so you an define your own recipes, which I guess makes Mussels obsolete. 😅 But I'll probably still keep using Mussels.

@vszakats
Copy link
Member

vszakats commented Aug 9, 2024

@micahsnyder Thank you! Yes, vcpkg, we just recently started using it in curl CI. It also happens to be the MSVC env where pkg-config is supported; the idea to make more use of pkg-config under Windows in curl was suggested by vcpkg contributors.

If reproducibility is a goal, I think for now there is no other option then rolling our own.

@micahsnyder
Copy link
Author

pkg-config under Windows in curl was suggested by vcpkg contributors.

That's ... disappointing.

@vszakats
Copy link
Member

vszakats commented Aug 9, 2024

pkg-config is IMO a good resource to use, also for curl, and for static linking in particular. We need to learn how to extend its use with the least disruption. It's limited to UNIX for now, but some Windows envs may also benefit from it.

@vszakats
Copy link
Member

vszakats commented Aug 9, 2024

@micahsnyder: Can confirm that -DPKG_CONFIG_EXECUTABLE=none works to disable pkg-config. -DPKG_CONFIG_EXECUTABLE= also (on macOS; this may be platform dependent?). It seems any non-existing executable name works that way, even "pkg-config" without an absolute path. I wonder what is the best universal "OFF" value here.

I like it better than the env PKG_CONFIG_LIBDIR, because this one is a CMake option.

@vszakats
Copy link
Member

vszakats commented Aug 10, 2024

@micahsnyder Regarding patching this issue within curl: would you mind making a test with this patch? (without using any of the other workarounds discussed in this Issue):

--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -959,8 +959,10 @@ if(USE_LIBIDN2)
     check_include_file_concat("idn2.h" HAVE_IDN2_H)
   endif()
   if(NOT HAVE_LIBIDN2 OR NOT HAVE_IDN2_H)
-    find_package(PkgConfig QUIET)
-    pkg_search_module(LIBIDN2 "libidn2")
+    if(NOT MSVC OR VCPKG_TOOLCHAIN)
+      find_package(PkgConfig QUIET)
+      pkg_search_module(LIBIDN2 "libidn2")
+    endif()
     if(LIBIDN2_FOUND)
       include_directories(${LIBIDN2_INCLUDE_DIRS})
       set(HAVE_LIBIDN2 ON)

@vszakats vszakats removed the not-a-curl-bug This is not a bug in curl label Aug 10, 2024
vszakats added a commit that referenced this issue Aug 10, 2024
libidn2 is detected by default, which triggers a `pkg-config` detectio
attempt by default. This in turn may pick up libidn2 inadvertently from
the disk, and append the libidn2 header directory to the include path.
This header directory might contain incompatible system and/or component
headers, causing confusion and failed builds.

Some of these side-effects may be the result of an unknowningly
configured (or misconfigured) `pkg-config`. In another reported case,
it was hit by the `pkg-config` from Strawberry Perl. Until we
investigate the reasons and come up with a technique to avoid these
issues, limit `pkg-config` detection to UNIX platforms, like we already
do in `Find*` modules.

Notice that `-DCURL_USE_LIBSSH=ON`, `-DCURL_USE_GSASL=ON`, and
`-DCURL_USE_LIBUV=ON` options continue to have the above side-effects,
though these options are disabled by default.

Follow-up to f43adc2 #14137
Reported-by: Micah Snyder
Fixes #14405
Closes #14408
@micahsnyder
Copy link
Author

@vszakats sure I'll give it a try tomorrow.

@micahsnyder
Copy link
Author

The build with this patch also completed successfully.

Idle curiosity - I wonder if vcpkg has some method to prevent pkg-config from picking up undesired packages, like those from Strawberry.

@vszakats
Copy link
Member

Nice, thanks @micahsnyder!

Good question indeed.

@vszakats
Copy link
Member

Maybe... vcpkg overrides the pkg-config tool with its own, which then comes with its own default config, that doesn't include Strawberry?

vszakats added a commit that referenced this issue Aug 12, 2024
Before this patch, `pkg-config` was used for `UNIX` builds only (with
a few exceptions like wolfSSL, libssh, gsasl, libuv). This patch extends
`pkg-config` use to all envs except: `MSVC` without vcpkg. Meaning MSVC
with vcpkg will now use it. Also mingw on Windows.

Also apply the new condition to options where `pkg-config` was used
unconditionally (= for all targets). These are:
`-DCURL_USE_WOLFSSL=ON`, `-DCURL_USE_LIBSSH=ON`,
`-DCURL_USE_GSASL=ON` and `-DCURL_USE_LIBUV=ON`

This patch may still cause regressions for cross-builds (e.g. mingw
cross-build from Unix) and potentially other cases. If that happens, we
recommend using some of these methods to explicitly disable `pkg-config`
when using CMake:
- CMake option: `-DPKG_CONFIG_EXECUTABLE=`
  (or `-DPKG_CONFIG_EXECUTABLE=nonexistent` or similar)
  This is similar to the (curl-specific) `PKG_CONFIG` env for autotools.
- export env: `PKG_CONFIG_LIBDIR=`
  (or `PKG_CONFIG_PATH`, `PKG_CONFIG_SYSROOT_DIR`,
  or the CMake-specific `PKG_CONFIG`)

We may improve control over this in a future patch, also allowing opting
in MSVC (without vcpkg).

Ref: #14405
Ref: #14408
Ref: #14140
Closes #14483
@jay
Copy link
Member

jay commented Aug 12, 2024

I doubt we can ever be in control of this. Whether pkg-config or not, if two or more lib directories are specified/detected during library search and it turns out that more than one has some library we're going to use (eg OpenSSL) then we can't guarantee which one will be used. It seems arbitrary. Even though we can change or otherwise alter the detection to accommodate one user then some other user may be affected.

edit: to clarify, I'm saying like if library foo is detected in -L/x/foo but library bar was specified -L/x/bar but is also in -L/x/foo then bar may be pulled from /x/foo or /x/bar depending on the order passed to the linker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging a pull request may close this issue.

3 participants