GHA/configure-vs-cmake: check libcurl.pc/curl-config, fix issues

Add CI checker to compare `libcurl.pc` and `curl-config` files
generated by autotools and cmake builds.

Fix differences and apply tiny cleanups:
- curl-config: use single-quotes for literals.
- curl-config: quote all variables.
- curl-config: replace double with single quotes in a substituted value
  that's always literal (`@prefix@`).
- libcurl.pc: spelling in `Description:`.
- libcurl.pc: avoid substitution in a comment.
- cmake: fill `libdir` with `${exec_prefix}` instead of a literal.
  To sync with './configure'.
- configure: fix `CURL_CA_BUNDLE` value to not generate nested quotes
  in `curl-config`.
- configure: add missing `LDFLAGS` to `Libs.private` in `libcurl.pc`.
  To sync with CMake.
- cmake: skip adding `CMAKE_C_IMPLICIT_LINK_LIBRARIES` for MINGW and
  UNIX. They added these values as seen in CI:
  MINGW: `-lmingw32 -lgcc -lmoldname -lmingwex -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc -lmoldname -lmingwex`
  Linux: `-lgcc -lgcc_s -lc -lgcc -lgcc_s`
- cmake: delete FIXME about enabling libssh2 by default.
  `./configure` has special defaults for these packages (called: "off"):
  brotli, zstd, libpsl, libssh2, libssh, wolfssl, librtmp
  It looks for them, but only at system locations, which makes them
  never detected e.g. on macOS. CMake doesn't offer such default mode
  for now.
- GHA/macos: drop now redundant `-DCURL_DISABLE_LDAPS=ON`.
- cmake: use `CMAKE_INSTALL_INCLUDEDIR` and `CMAKE_INSTALL_LIBDIR`
  instead of hardcoded `include`/`lib` when generating `libcurl.pc`.

Updates to the GHA workflow:
- move autotools out-of-tree and rename cmake out-of-tree directory
  to `bld_cm` to tell it's cmake.
- disable static libcurl for `./configure` to match cmake.
- enable `pkg-config` debug output with `./configure`.
- dump list of Homebrew packages on macOS.
- dump `./configure` detailed logs.
- disable zstd and brotli for Linux, to match cmake.

There remain differences, mostly due to detection order and method. Also
some values are inherently different when using CMake and autotools,
such as `--cc`, `--configure`. autotools also generates duplicates for
`-lssl` and `-lcrypto`. macOS LDAP wants to link `-lber` while autotools
doesn't. Some build defaults are also different in autotools and cmake.
These differences are smoothened out for now by the checker script, or
via build options. Notice that lib order (a dupes) _can_ be significant
in some cases. E.g. the binutils linker is infamous for that on Windows.

Closes #14681
This commit is contained in:
Viktor Szakats 2024-08-25 21:40:13 +02:00
parent ce7d0d4137
commit 9f56bb608e
No known key found for this signature in database
GPG Key ID: B5ABD165E2AEF201
6 changed files with 144 additions and 34 deletions

49
.github/scripts/cmp-pkg-config.sh vendored Executable file
View File

@ -0,0 +1,49 @@
#!/usr/bin/env bash
# Copyright (C) Viktor Szakats
#
# SPDX-License-Identifier: curl
# Sort list of libs, libpaths, cflags found in libcurl.pc and curl-config files,
# then diff the autotools and cmake generated ones.
sort_lists() {
prevline=''
section=''
while IFS= read -r l; do
if [[ "${prevline}" =~ (--cc|--configure) ]]; then # curl-config
echo "<IGNORED>"
else
# libcurl.pc
if [[ "${l}" =~ ^(Requires|Libs|Cflags)(\.private)?:\ (.+)$ ]]; then
if [ "${BASH_REMATCH[1]}" = 'Requires' ]; then
# Spec does not allow duplicates here:
# https://manpages.debian.org/unstable/pkg-config/pkg-config.1.en.html#Requires:
# "You may only mention the same package one time on the Requires: line"
val="$(printf '%s' "${BASH_REMATCH[3]}" | tr ',' '\n' | sort | tr '\n' ' ')"
else
val="$(printf '%s' "${BASH_REMATCH[3]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')"
fi
l="${BASH_REMATCH[1]}${BASH_REMATCH[2]}: ${val}"
# curl-config
elif [[ "${section}" =~ (--libs|--static-libs) && "${l}" =~ ^( *echo\ \")(.+)(\")$ ]]; then
val="$(printf '%s' "${BASH_REMATCH[2]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')"
l="${BASH_REMATCH[1]}${val}${BASH_REMATCH[3]}"
section=''
fi
echo "${l}"
fi
# curl-config
prevline="${l}"
if [[ "${l}" =~ --[a-z-]+\) ]]; then
section="${BASH_REMATCH[0]}"
fi
done < "$1"
}
am=$(mktemp -t autotools.XXX); sort_lists "$1" > "${am}"
cm=$(mktemp -t cmake.XXX) ; sort_lists "$2" > "${cm}"
diff -u "${am}" "${cm}"
res="$?"
rm -r -f "${am}" "${cm}"
exit "${res}"

View File

@ -37,14 +37,27 @@ jobs:
- name: run configure --with-openssl
run: |
autoreconf -fi
./configure --with-openssl --without-libpsl
export PKG_CONFIG_DEBUG_SPEW=1
mkdir bld-am && cd bld-am && ../configure --enable-static=no --with-openssl --without-libpsl --without-brotli --without-zstd
- name: run cmake
run: |
cmake -B build -DCURL_USE_LIBPSL=OFF
cmake -B bld-cm -DCURL_USE_LIBPSL=OFF
- name: 'configure log'
run: cat bld-am/config.log 2>/dev/null || true
- name: 'cmake log'
run: cat bld-cm/CMakeFiles/CMakeConfigureLog.yaml 2>/dev/null || true
- name: compare generated curl_config.h files
run: ./.github/scripts/cmp-config.pl lib/curl_config.h build/lib/curl_config.h
run: ./.github/scripts/cmp-config.pl bld-am/lib/curl_config.h bld-cm/lib/curl_config.h
- name: compare generated libcurl.pc files
run: ./.github/scripts/cmp-pkg-config.sh bld-am/libcurl.pc bld-cm/libcurl.pc
- name: compare generated curl-config files
run: ./.github/scripts/cmp-pkg-config.sh bld-am/curl-config bld-cm/curl-config
check-macos:
runs-on: macos-latest
@ -53,21 +66,38 @@ jobs:
run: |
while [[ $? == 0 ]]; do for i in 1 2 3; do brew update && brew install libtool autoconf automake && break 2 || { echo Error: wait to try again; sleep 10; } done; false Too many retries; done
- name: 'toolchain versions'
run: |
echo '::group::brew packages installed'; ls -l "$(brew --prefix)/opt"; echo '::endgroup::'
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
- name: run configure --with-openssl
run: |
autoreconf -fi
./configure --with-openssl --without-libpsl
export PKG_CONFIG_DEBUG_SPEW=1
mkdir bld-am && cd bld-am && ../configure --enable-static=no --with-openssl --without-libpsl --disable-ldap
- name: run cmake
run: |
cmake -B build -DCURL_USE_LIBPSL=OFF \
cmake -B bld-cm -DCURL_USE_LIBPSL=OFF -DCURL_DISABLE_LDAP=ON \
"-DCMAKE_C_COMPILER_TARGET=$(uname -m | sed 's/arm64/aarch64/')-apple-darwin$(uname -r)" \
-DCURL_USE_LIBSSH2=OFF
- name: 'configure log'
run: cat bld-am/config.log 2>/dev/null || true
- name: 'cmake log'
run: cat bld-cm/CMakeFiles/CMakeConfigureLog.yaml 2>/dev/null || true
- name: compare generated curl_config.h files
run: ./.github/scripts/cmp-config.pl lib/curl_config.h build/lib/curl_config.h
run: ./.github/scripts/cmp-config.pl bld-am/lib/curl_config.h bld-cm/lib/curl_config.h
- name: compare generated libcurl.pc files
run: ./.github/scripts/cmp-pkg-config.sh bld-am/libcurl.pc bld-cm/libcurl.pc
- name: compare generated curl-config files
run: ./.github/scripts/cmp-pkg-config.sh bld-am/curl-config bld-cm/curl-config
check-windows:
runs-on: ubuntu-latest
@ -82,14 +112,27 @@ jobs:
- name: run configure --with-schannel
run: |
autoreconf -fi
./configure --with-schannel --without-libpsl --host=${TRIPLET}
export PKG_CONFIG_DEBUG_SPEW=1
mkdir bld-am && cd bld-am && ../configure --enable-static=no --with-schannel --without-libpsl --host=${TRIPLET}
- name: run cmake
run: |
cmake -B build -DCURL_USE_SCHANNEL=ON -DCURL_USE_LIBPSL=OFF \
cmake -B bld-cm -DCURL_USE_SCHANNEL=ON -DCURL_USE_LIBPSL=OFF \
-DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_C_COMPILER_TARGET=${TRIPLET} \
-DCMAKE_C_COMPILER=${TRIPLET}-gcc
- name: 'configure log'
run: cat bld-am/config.log 2>/dev/null || true
- name: 'cmake log'
run: cat bld-cm/CMakeFiles/CMakeConfigureLog.yaml 2>/dev/null || true
- name: compare generated curl_config.h files
run: ./.github/scripts/cmp-config.pl lib/curl_config.h build/lib/curl_config.h
run: ./.github/scripts/cmp-config.pl bld-am/lib/curl_config.h bld-cm/lib/curl_config.h
- name: compare generated libcurl.pc files
run: ./.github/scripts/cmp-pkg-config.sh bld-am/libcurl.pc bld-cm/libcurl.pc
- name: compare generated curl-config files
run: ./.github/scripts/cmp-pkg-config.sh bld-am/curl-config bld-cm/curl-config

View File

@ -1077,7 +1077,7 @@ if(CURL_USE_LIBPSL)
endif()
# libssh2
option(CURL_USE_LIBSSH2 "Use libssh2" ON) # FIXME: default is OFF in autotools
option(CURL_USE_LIBSSH2 "Use libssh2" ON)
mark_as_advanced(CURL_USE_LIBSSH2)
set(USE_LIBSSH2 OFF)
@ -1948,9 +1948,17 @@ if(NOT CURL_DISABLE_INSTALL)
set(VERSIONNUM "${CURL_VERSION_NUM}")
set(prefix "${CMAKE_INSTALL_PREFIX}")
set(exec_prefix "\${prefix}")
set(includedir "\${prefix}/include")
if(IS_ABSOLUTE ${CMAKE_INSTALL_INCLUDEDIR})
set(includedir "${CMAKE_INSTALL_INCLUDEDIR}")
else()
set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
endif()
if(IS_ABSOLUTE ${CMAKE_INSTALL_LIBDIR})
set(libdir "${CMAKE_INSTALL_LIBDIR}")
else()
set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
endif()
set(LDFLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
set(libdir "${CMAKE_INSTALL_PREFIX}/lib")
# "a" (Linux) or "lib" (Windows)
string(REPLACE "." "" libext "${CMAKE_STATIC_LIBRARY_SUFFIX}")
@ -1983,7 +1991,12 @@ if(NOT CURL_DISABLE_INSTALL)
endif()
endforeach()
foreach(_lib IN LISTS CMAKE_C_IMPLICIT_LINK_LIBRARIES CURL_LIBS)
unset(_implicit_libs)
if(NOT MINGW AND NOT UNIX)
set(_implicit_libs ${CMAKE_C_IMPLICIT_LINK_LIBRARIES})
endif()
foreach(_lib IN LISTS _implicit_libs CURL_LIBS)
if(TARGET "${_lib}")
set(_libname "${_lib}")
get_target_property(_imported "${_libname}" IMPORTED)
@ -2029,8 +2042,8 @@ if(NOT CURL_DISABLE_INSTALL)
if(_ldflags)
list(REMOVE_DUPLICATES _ldflags)
string(REPLACE ";" " " _ldflags "${_ldflags}")
set(LIBCURL_PC_LIBS_PRIVATE "${_ldflags} ${LIBCURL_PC_LIBS_PRIVATE}")
string(STRIP "${LIBCURL_PC_LIBS_PRIVATE}" LIBCURL_PC_LIBS_PRIVATE)
set(LDFLAGS "${LDFLAGS} ${_ldflags}")
string(STRIP "${LDFLAGS}" LDFLAGS)
endif()
set(LIBCURL_PC_CFLAGS_PRIVATE "-DCURL_STATICLIB")
@ -2097,6 +2110,11 @@ if(NOT CURL_DISABLE_INSTALL)
# prefix
# SUPPORT_FEATURES
# SUPPORT_PROTOCOLS
# Documentation:
# https://people.freedesktop.org/~dbn/pkg-config-guide.html
# https://manpages.debian.org/unstable/pkgconf/pkg-config.1.en.html
# https://manpages.debian.org/unstable/pkg-config/pkg-config.1.en.html
# https://www.msys2.org/docs/pkgconfig/
configure_file(
"${CURL_SOURCE_DIR}/libcurl.pc.in"
"${CURL_BINARY_DIR}/libcurl.pc" @ONLY)

View File

@ -1304,7 +1304,7 @@ AS_HELP_STRING([--without-ca-path], [Don't use a default CA path]),
fi
if test "x$ca" != "xno"; then
CURL_CA_BUNDLE='"'$ca'"'
CURL_CA_BUNDLE="$ca"
AC_DEFINE_UNQUOTED(CURL_CA_BUNDLE, "$ca", [Location of default ca bundle])
AC_SUBST(CURL_CA_BUNDLE)
AC_MSG_RESULT([$ca])

View File

@ -25,13 +25,13 @@
# shellcheck disable=SC2006
prefix="@prefix@"
# Used in @libdir@
prefix='@prefix@'
# Used in 'libdir'
# shellcheck disable=SC2034
exec_prefix=@exec_prefix@
exec_prefix="@exec_prefix@"
# shellcheck disable=SC2034
includedir=@includedir@
cppflag_curl_staticlib=@LIBCURL_PC_CFLAGS@
includedir="@includedir@"
cppflag_curl_staticlib='@LIBCURL_PC_CFLAGS@'
usage()
{
@ -83,7 +83,7 @@ while test "$#" -gt 0; do
;;
--feature|--features)
for feature in @SUPPORT_FEATURES@ ""; do
for feature in @SUPPORT_FEATURES@ ''; do
test -n "$feature" && echo "$feature"
done
;;
@ -101,7 +101,7 @@ while test "$#" -gt 0; do
;;
--checkfor)
checkfor=$2
checkfor="$2"
cmajor=`echo "$checkfor" | cut -d. -f1`
cminor=`echo "$checkfor" | cut -d. -f2`
# when extracting the patch part we strip off everything after a
@ -142,12 +142,12 @@ while test "$#" -gt 0; do
;;
--cflags)
if test "X$cppflag_curl_staticlib" = "X-DCURL_STATICLIB"; then
CPPFLAG_CURL_STATICLIB="-DCURL_STATICLIB "
if test "X$cppflag_curl_staticlib" = 'X-DCURL_STATICLIB'; then
CPPFLAG_CURL_STATICLIB='-DCURL_STATICLIB '
else
CPPFLAG_CURL_STATICLIB=""
CPPFLAG_CURL_STATICLIB=''
fi
if test "X@includedir@" = "X/usr/include"; then
if test "X@includedir@" = 'X/usr/include'; then
echo "${CPPFLAG_CURL_STATICLIB}"
else
echo "${CPPFLAG_CURL_STATICLIB}-I@includedir@"
@ -155,12 +155,12 @@ while test "$#" -gt 0; do
;;
--libs)
if test "X@libdir@" != "X/usr/lib" -a "X@libdir@" != "X/usr/lib64"; then
if test "X@libdir@" != 'X/usr/lib' -a "X@libdir@" != 'X/usr/lib64'; then
CURLLIBDIR="-L@libdir@ "
else
CURLLIBDIR=""
CURLLIBDIR=''
fi
if test "X@ENABLE_SHARED@" = "Xno"; then
if test 'X@ENABLE_SHARED@' = 'Xno'; then
echo "${CURLLIBDIR}-lcurl @LIBCURL_PC_LIBS_PRIVATE@"
else
echo "${CURLLIBDIR}-lcurl"
@ -172,8 +172,8 @@ while test "$#" -gt 0; do
;;
--static-libs)
if test "X@ENABLE_STATIC@" != "Xno" ; then
echo "@libdir@/libcurl.@libext@" @LDFLAGS@ @LIBCURL_PC_LIBS_PRIVATE@
if test 'X@ENABLE_STATIC@' != 'Xno'; then
echo "@libdir@/libcurl.@libext@ @LDFLAGS@ @LIBCURL_PC_LIBS_PRIVATE@"
else
echo 'curl was built with static libraries disabled' >&2
exit 1

View File

@ -31,11 +31,11 @@ supported_features="@SUPPORT_FEATURES@"
Name: libcurl
URL: https://curl.se/
Description: Library to transfer files with ftp, http, etc.
Description: Library to transfer files with HTTP, FTP, etc.
Version: @CURLVERSION@
Requires: @LIBCURL_PC_REQUIRES@
Requires.private: @LIBCURL_PC_REQUIRES_PRIVATE@
Libs: -L${libdir} -lcurl @LIBCURL_PC_LIBS@
Libs.private: @LIBCURL_PC_LIBS_PRIVATE@
Libs.private: @LDFLAGS@ @LIBCURL_PC_LIBS_PRIVATE@
Cflags: -I${includedir} @LIBCURL_PC_CFLAGS@
Cflags.private: @LIBCURL_PC_CFLAGS_PRIVATE@