cmake: extend integration tests

- GHA: add cmake integration tests for Windows.
- make them run faster with prefill, unity, Ninja, omitting curl tool.
- also test static libcurl.
- add old-cmake support with auto-detection.
- auto-detect Ninja.
- run consumer test apps to see if they work.
- add support for Windows.
- make it more verbose.
- re-add `ExternalProject` cmake consumer test. It's broken.
- tidy up terminology.

Cherry-picked from #16973
Closes #17203
This commit is contained in:
Viktor Szakats 2025-04-27 12:26:41 +02:00
parent e9a35ded8a
commit e2a23d5d0d
No known key found for this signature in database
GPG key ID: B5ABD165E2AEF201
4 changed files with 172 additions and 35 deletions

View file

@ -167,15 +167,30 @@ jobs:
name: 'cmake-integration-on-${{ matrix.image }}'
runs-on: ${{ matrix.image }}
timeout-minutes: 10
defaults:
run:
shell: ${{ contains(matrix.image, 'windows') && 'msys2 {0}' || 'bash' }}
env:
CC: clang
CMAKE_GENERATOR: Ninja
CC: ${{ !contains(matrix.image, 'windows') && 'clang' || '' }}
TESTOPTS: ${{ contains(matrix.image, 'macos') && '-D_CURL_PREFILL=ON' || '' }} ${{ contains(matrix.image, 'windows') && '-DCMAKE_UNITY_BUILD_BATCH_SIZE=30' || '' }}
strategy:
fail-fast: false
matrix:
image: [ubuntu-latest, macos-latest]
image: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: msys2/setup-msys2@d44ca8e88d8b43d56cf5670f91747359d5537f97 # v2
if: ${{ contains(matrix.image, 'windows') }}
with:
msystem: mingw64
release: false
update: false
cache: false
path-type: inherit
install: >-
mingw-w64-x86_64-zlib mingw-w64-x86_64-zstd mingw-w64-x86_64-libpsl mingw-w64-x86_64-libssh2 mingw-w64-x86_64-nghttp2 mingw-w64-x86_64-openssl
- name: 'install prereqs'
if: ${{ !contains(matrix.image, 'windows') }}
run: |
if [[ '${{ matrix.image }}' = *'ubuntu'* ]]; then
sudo rm -f /var/lib/man-db/auto-update
@ -188,8 +203,8 @@ jobs:
with:
persist-credentials: false
- name: 'via FetchContent'
run: ./tests/cmake/test.sh FetchContent
run: ./tests/cmake/test.sh FetchContent ${TESTOPTS} -DCURL_USE_OPENSSL=ON
- name: 'via add_subdirectory'
run: ./tests/cmake/test.sh add_subdirectory
run: ./tests/cmake/test.sh add_subdirectory ${TESTOPTS} -DCURL_USE_OPENSSL=ON
- name: 'via find_package'
run: ./tests/cmake/test.sh find_package
run: ./tests/cmake/test.sh find_package ${TESTOPTS} -DCURL_USE_OPENSSL=ON

View file

@ -25,7 +25,7 @@
cmake_minimum_required(VERSION 3.7...3.16 FATAL_ERROR)
message(STATUS "Using CMake version ${CMAKE_VERSION}")
project(test-dependent C)
project(test-consumer C)
option(TEST_INTEGRATION_MODE "Integration mode" "find_package")
@ -35,7 +35,16 @@ if(TEST_INTEGRATION_MODE STREQUAL "FetchContent" AND CMAKE_VERSION VERSION_LESS
message(FATAL_ERROR "This test requires CMake 3.14 or upper")
endif()
if(TEST_INTEGRATION_MODE STREQUAL "find_package")
if(TEST_INTEGRATION_MODE STREQUAL "ExternalProject") # Broken
include(ExternalProject)
ExternalProject_Add(libssh2
URL "${FROM_ARCHIVE}" URL_HASH "SHA256=${FROM_HASH}"
INSTALL_COMMAND ""
DOWNLOAD_EXTRACT_TIMESTAMP ON)
endif()
if(TEST_INTEGRATION_MODE STREQUAL "find_package" OR
TEST_INTEGRATION_MODE STREQUAL "ExternalProject")
find_package(CURL REQUIRED CONFIG)
find_package(CURL REQUIRED CONFIG) # Double-inclusion test
foreach(result_var IN ITEMS
@ -62,6 +71,8 @@ if(TEST_INTEGRATION_MODE STREQUAL "find_package")
endif()
endforeach()
elseif(TEST_INTEGRATION_MODE STREQUAL "add_subdirectory")
set(BUILD_SHARED_LIBS ON CACHE BOOL "")
set(BUILD_STATIC_LIBS ON CACHE BOOL "")
add_subdirectory(curl)
elseif(TEST_INTEGRATION_MODE STREQUAL "FetchContent")
include(FetchContent)
@ -71,15 +82,30 @@ elseif(TEST_INTEGRATION_MODE STREQUAL "FetchContent")
GIT_REPOSITORY "${FROM_GIT_REPO}"
GIT_TAG "${FROM_GIT_TAG}"
GIT_SHALLOW)
set(BUILD_SHARED_LIBS ON CACHE BOOL "")
set(BUILD_STATIC_LIBS ON CACHE BOOL "")
FetchContent_MakeAvailable(curl) # Requires CMake 3.14
endif()
add_executable(test-consumer-static-ns "test.c")
target_link_libraries(test-consumer-static-ns PRIVATE "CURL::libcurl_static")
add_executable(test-consumer-shared-ns "test.c")
target_link_libraries(test-consumer-shared-ns PRIVATE "CURL::libcurl_shared")
# Alias for either shared or static library
add_executable(test-dependent-selected-ns "test.c")
target_link_libraries(test-dependent-selected-ns PRIVATE "CURL::libcurl")
add_executable(test-consumer-selected-ns "test.c")
target_link_libraries(test-consumer-selected-ns PRIVATE "CURL::libcurl")
if(TEST_INTEGRATION_MODE STREQUAL "add_subdirectory" OR
TEST_INTEGRATION_MODE STREQUAL "FetchContent")
add_executable(test-dependent-selected-bare "test.c")
target_link_libraries(test-dependent-selected-bare PRIVATE "libcurl")
add_executable(test-consumer-static-bare "test.c")
target_link_libraries(test-consumer-static-bare PRIVATE "libcurl_static")
add_executable(test-consumer-shared-bare "test.c")
target_link_libraries(test-consumer-shared-bare PRIVATE "libcurl_shared")
add_executable(test-consumer-selected-bare "test.c")
target_link_libraries(test-consumer-selected-bare PRIVATE "libcurl")
endif()

View file

@ -24,8 +24,9 @@
#include "curl/curl.h"
#include <stdio.h>
int main(void)
int main(int argc, char **argv)
{
printf("curl_version(): |%s|\n", curl_version());
(void)argc;
printf("libcurl test: |%s|%s|\n", argv[0], curl_version());
return 0;
}

View file

@ -1,39 +1,134 @@
#!/bin/sh
#!/bin/sh -x
# Copyright (C) Viktor Szakats
#
# SPDX-License-Identifier: curl
# shellcheck disable=SC2086
set -eu
cd "$(dirname "$0")"
mode="${1:-all}"
command -v ninja >/dev/null && export CMAKE_GENERATOR=Ninja # 3.17+
if [ "${mode}" = 'all' ] || [ "${mode}" = 'FetchContent' ]; then
rm -rf bld-fetchcontent
cmake -B bld-fetchcontent \
mode="${1:-all}"; shift
cmake_consumer="${CMAKE_CONSUMER:-cmake}"
cmake_provider="${CMAKE_PROVIDER:-${cmake_consumer}}"
# 'modern': supports -S/-B (3.13+), --install (3.15+)
"${cmake_consumer}" --help | grep -q -- '--install' && cmake_consumer_modern=1
"${cmake_provider}" --help | grep -q -- '--install' && cmake_provider_modern=1
cmake_opts='-DBUILD_CURL_EXE=OFF -DBUILD_LIBCURL_DOCS=OFF -DBUILD_MISC_DOCS=OFF -DENABLE_CURL_MANUAL=OFF'
src='../..'
runresults() {
set +x
for bin in "$1"/test-consumer*; do
file "${bin}" || true
${CURL_TEST_EXE_RUNNER:-} "${bin}" || true
done
set -x
}
if [ "${mode}" = 'ExternalProject' ]; then # Broken
(cd "${src}"; git archive --format=tar HEAD) | gzip > source.tar.gz
src="${PWD}/source.tar.gz"
sha="$(openssl dgst -sha256 "${src}" | grep -a -i -o -E '[0-9a-f]{64}$')"
bldc='bld-externalproject'
rm -rf "${bldc}"
if [ -n "${cmake_consumer_modern:-}" ]; then # 3.15+
"${cmake_consumer}" -B "${bldc}" ${cmake_opts} -DCMAKE_UNITY_BUILD=ON "$@" \
-DTEST_INTEGRATION_MODE=ExternalProject \
-DFROM_ARCHIVE="${src}" -DFROM_HASH="${sha}"
"${cmake_consumer}" --build "${bldc}" --verbose
else
mkdir "${bldc}"; cd "${bldc}"
"${cmake_consumer}" .. ${cmake_opts} "$@" \
-DTEST_INTEGRATION_MODE=ExternalProject \
-DFROM_ARCHIVE="${src}" -DFROM_HASH="${sha}"
VERBOSE=1 "${cmake_consumer}" --build .
cd ..
fi
runresults "${bldc}"
fi
if [ "${mode}" = 'all' ] || [ "${mode}" = 'FetchContent' ]; then # 3.14+
src="${PWD}/${src}"
bldc='bld-fetchcontent'
rm -rf "${bldc}"
"${cmake_consumer}" -B "${bldc}" ${cmake_opts} -DCMAKE_UNITY_BUILD=ON "$@" \
-DTEST_INTEGRATION_MODE=FetchContent \
-DFROM_GIT_REPO="${PWD}/../.." \
-DFROM_GIT_REPO="${src}" \
-DFROM_GIT_TAG="$(git rev-parse HEAD)"
cmake --build bld-fetchcontent
"${cmake_consumer}" --build "${bldc}" --verbose
PATH="${bldc}/_deps/curl-build/lib:${PATH}"
runresults "${bldc}"
fi
if [ "${mode}" = 'all' ] || [ "${mode}" = 'add_subdirectory' ]; then
rm -rf curl; ln -s ../.. curl
rm -rf bld-add_subdirectory
cmake -B bld-add_subdirectory \
-DTEST_INTEGRATION_MODE=add_subdirectory
cmake --build bld-add_subdirectory
rm -rf curl
if ! ln -s "${src}" curl; then
rm -rf curl; mkdir curl; (cd "${src}"; git archive --format=tar HEAD) | tar -x --directory=curl # for MSYS2/Cygwin
fi
bldc='bld-add_subdirectory'
rm -rf "${bldc}"
if [ -n "${cmake_consumer_modern:-}" ]; then # 3.15+
"${cmake_consumer}" -B "${bldc}" ${cmake_opts} -DCMAKE_UNITY_BUILD=ON "$@" \
-DTEST_INTEGRATION_MODE=add_subdirectory
"${cmake_consumer}" --build "${bldc}" --verbose
else
mkdir "${bldc}"; cd "${bldc}"
# Disable `pkg-config` for CMake <= 3.12. These versions cannot propagate
# library directories to the consumer project.
"${cmake_consumer}" .. ${cmake_opts} -DCURL_USE_PKGCONFIG=OFF "$@" \
-DTEST_INTEGRATION_MODE=add_subdirectory
VERBOSE=1 "${cmake_consumer}" --build .
cd ..
fi
PATH="${bldc}/curl/lib:${PATH}"
runresults "${bldc}"
fi
if [ "${mode}" = 'all' ] || [ "${mode}" = 'find_package' ]; then
rm -rf bld-curl
cmake ../.. -B bld-curl -DCMAKE_INSTALL_PREFIX="${PWD}/bld-curl/_pkg"
cmake --build bld-curl
cmake --install bld-curl
rm -rf bld-find_package
cmake -B bld-find_package \
-DTEST_INTEGRATION_MODE=find_package \
-DCMAKE_PREFIX_PATH="${PWD}/bld-curl/_pkg/lib/cmake/CURL"
cmake --build bld-find_package
src="${PWD}/${src}"
bldp='bld-curl'
prefix="${PWD}/${bldp}/_pkg"
rm -rf "${bldp}"
if [ -n "${cmake_provider_modern:-}" ]; then # 3.15+
"${cmake_provider}" -B "${bldp}" -S "${src}" ${cmake_opts} -DCMAKE_UNITY_BUILD=ON "$@" \
-DBUILD_SHARED_LIBS=ON \
-DBUILD_STATIC_LIBS=ON \
-DCMAKE_INSTALL_PREFIX="${prefix}"
"${cmake_provider}" --build "${bldp}"
"${cmake_provider}" --install "${bldp}"
else
mkdir "${bldp}"; cd "${bldp}"
"${cmake_provider}" "${src}" ${cmake_opts} "$@" \
-DBUILD_SHARED_LIBS=ON \
-DBUILD_STATIC_LIBS=ON \
-DCMAKE_INSTALL_PREFIX="${prefix}"
"${cmake_provider}" --build .
make install
cd ..
fi
bldc='bld-find_package'
rm -rf "${bldc}"
if [ -n "${cmake_consumer_modern:-}" ]; then # 3.15+
"${cmake_consumer}" -B "${bldc}" \
-DTEST_INTEGRATION_MODE=find_package \
-DCMAKE_PREFIX_PATH="${prefix}/lib/cmake/CURL"
"${cmake_consumer}" --build "${bldc}" --verbose
else
mkdir "${bldc}"; cd "${bldc}"
"${cmake_consumer}" .. \
-DTEST_INTEGRATION_MODE=find_package \
-DCMAKE_PREFIX_PATH="${prefix}/lib/cmake/CURL"
VERBOSE=1 "${cmake_consumer}" --build .
cd ..
fi
PATH="${prefix}/bin:${PATH}"
runresults "${bldc}"
fi