From e2a23d5d0d566105237acec37a2c22a6f79cee3e Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Sun, 27 Apr 2025 12:26:41 +0200 Subject: [PATCH] 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 --- .github/workflows/distcheck.yml | 27 +++++-- tests/cmake/CMakeLists.txt | 38 +++++++-- tests/cmake/test.c | 5 +- tests/cmake/test.sh | 137 +++++++++++++++++++++++++++----- 4 files changed, 172 insertions(+), 35 deletions(-) diff --git a/.github/workflows/distcheck.yml b/.github/workflows/distcheck.yml index 5e550b8d0f..f0692f8710 100644 --- a/.github/workflows/distcheck.yml +++ b/.github/workflows/distcheck.yml @@ -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 diff --git a/tests/cmake/CMakeLists.txt b/tests/cmake/CMakeLists.txt index 1b0b6693f9..d752023464 100644 --- a/tests/cmake/CMakeLists.txt +++ b/tests/cmake/CMakeLists.txt @@ -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() diff --git a/tests/cmake/test.c b/tests/cmake/test.c index 1ffeb09991..32f8826df0 100644 --- a/tests/cmake/test.c +++ b/tests/cmake/test.c @@ -24,8 +24,9 @@ #include "curl/curl.h" #include -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; } diff --git a/tests/cmake/test.sh b/tests/cmake/test.sh index 52987e0273..b7c2a3191c 100755 --- a/tests/cmake/test.sh +++ b/tests/cmake/test.sh @@ -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+ + +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 - rm -rf bld-fetchcontent - cmake -B bld-fetchcontent \ +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 -- 2.47.3