cmake: make the ExternalProject test work

By micromanaging the project dependency and its inclusion into the test
project. It feels like an awkward construct, but perhaps better than
nothing.

It's also fragile because it's a static build with no assistance from
the external project (curl in this case). Mitigated in test by disabling
all dependencies and some features.

Since there is no special core cmake logic to be tested here, in CI
the test is tested really. To keep CI jobs at minimum, only add 3 of
them, taking 42s in total. (All 6 would take 270s.)

Follow-up to e2a23d5d0d #17203

Closes #18208
This commit is contained in:
Viktor Szakats 2025-08-06 19:21:16 +02:00
parent a93113b5b4
commit b8296d367a
No known key found for this signature in database
GPG Key ID: B5ABD165E2AEF201
3 changed files with 62 additions and 24 deletions

View File

@ -301,6 +301,9 @@ jobs:
with:
persist-credentials: false
- name: 'via ExternalProject'
if: ${{ !contains(matrix.image, 'linux') }}
run: ./tests/cmake/test.sh ExternalProject ${TESTOPTS}
- name: 'via FetchContent'
run: ./tests/cmake/test.sh FetchContent ${TESTOPTS} -DCURL_USE_OPENSSL=ON
- name: 'via add_subdirectory'
@ -308,6 +311,20 @@ jobs:
- name: 'via find_package'
run: ./tests/cmake/test.sh find_package ${TESTOPTS} -DCURL_USE_OPENSSL=ON
- name: 'via ExternalProject (old cmake)'
if: ${{ contains(matrix.image, 'linux') }}
run: |
export TEST_CMAKE_CONSUMER; TEST_CMAKE_CONSUMER="$(cat ~/old-cmake-path.txt)"
if [[ "${MATRIX_IMAGE}" = *'macos'* ]]; then
export CFLAGS='-arch arm64'
export TEST_CMAKE_FLAGS='-DCURL_USE_LIBPSL=OFF' # auto-detection does not work with old-cmake
fi
if [[ "${MATRIX_IMAGE}" = *'windows'* ]]; then
export TEST_CMAKE_GENERATOR='MSYS Makefiles'
export TEST_CMAKE_FLAGS='-DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc -DOPENSSL_ROOT_DIR=C:/msys64/mingw64'
fi
./tests/cmake/test.sh ExternalProject ${TESTOPTS}
- name: 'via add_subdirectory OpenSSL (old cmake)'
run: |
export TEST_CMAKE_CONSUMER; TEST_CMAKE_CONSUMER="$(cat ~/old-cmake-path.txt)"

View File

@ -31,20 +31,7 @@ option(TEST_INTEGRATION_MODE "Integration mode" "find_package")
message(STATUS "TEST_INTEGRATION_MODE: ${TEST_INTEGRATION_MODE}")
if(TEST_INTEGRATION_MODE STREQUAL "FetchContent" AND CMAKE_VERSION VERSION_LESS 3.14)
message(FATAL_ERROR "This test requires CMake 3.14 or upper")
endif()
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")
if(TEST_INTEGRATION_MODE STREQUAL "find_package")
find_package(CURL REQUIRED CONFIG)
find_package(CURL REQUIRED CONFIG) # Double-inclusion test
foreach(_result_var IN ITEMS
@ -75,6 +62,9 @@ elseif(TEST_INTEGRATION_MODE STREQUAL "add_subdirectory")
set(BUILD_STATIC_LIBS ON CACHE BOOL "")
add_subdirectory(curl)
elseif(TEST_INTEGRATION_MODE STREQUAL "FetchContent")
if(CMAKE_VERSION VERSION_LESS 3.14)
message(FATAL_ERROR "This test requires CMake 3.14 or upper")
endif()
include(FetchContent)
option(FROM_GIT_REPO "Git URL" "https://github.com/curl/curl.git")
option(FROM_GIT_TAG "Git tag" "master")
@ -85,17 +75,48 @@ elseif(TEST_INTEGRATION_MODE STREQUAL "FetchContent")
set(BUILD_SHARED_LIBS ON CACHE BOOL "")
set(BUILD_STATIC_LIBS ON CACHE BOOL "")
FetchContent_MakeAvailable(curl) # Requires CMake 3.14
elseif(TEST_INTEGRATION_MODE STREQUAL "ExternalProject")
include(ExternalProject)
set(_curl_install_dir "${CMAKE_BINARY_DIR}/curl-external-install")
set(_curl_libcurl_static_lib "${_curl_install_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}curl${CMAKE_STATIC_LIBRARY_SUFFIX}")
string(REPLACE " " ";" CURL_TEST_OPTS "${CURL_TEST_OPTS}")
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24)
set(_download_extract_timestamp "DOWNLOAD_EXTRACT_TIMESTAMP" "ON")
endif()
ExternalProject_Add(curl-external
URL "${FROM_ARCHIVE}" URL_HASH "SHA256=${FROM_HASH}"
${_download_extract_timestamp}
PREFIX "${CMAKE_BINARY_DIR}/curl-external"
CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=${_curl_install_dir}" -DBUILD_SHARED_LIBS=OFF -DCURL_USE_LIBPSL=OFF -DCURL_USE_PKGCONFIG=OFF
-DCURL_ENABLE_SSL=OFF -DCURL_ENABLE_SSL=OFF -DCURL_DISABLE_LDAP=ON -DCURL_USE_LIBSSH2=OFF -DUSE_NGHTTP2=OFF
-DCURL_BROTLI=OFF -DCURL_ZLIB=OFF -DCURL_ZSTD=OFF -DUSE_LIBIDN2=OFF -DENABLE_IPV6=OFF
${CURL_TEST_OPTS}
BUILD_BYPRODUCTS "${_curl_libcurl_static_lib}")
add_executable(test-consumer-static-fetch "test.c")
add_dependencies(test-consumer-static-fetch curl-external)
if(WIN32)
target_compile_definitions(test-consumer-static-fetch PRIVATE "CURL_STATICLIB")
list(APPEND _curl_libcurl_static_lib "ws2_32" "bcrypt")
endif()
target_include_directories(test-consumer-static-fetch PRIVATE "${_curl_install_dir}/include")
target_link_libraries(test-consumer-static-fetch PRIVATE "${_curl_libcurl_static_lib}")
endif()
add_executable(test-consumer-static-ns "test.c")
target_link_libraries(test-consumer-static-ns PRIVATE "CURL::libcurl_static")
if(TEST_INTEGRATION_MODE STREQUAL "find_package" OR
TEST_INTEGRATION_MODE STREQUAL "add_subdirectory" OR
TEST_INTEGRATION_MODE STREQUAL "FetchContent")
add_executable(test-consumer-shared-ns "test.c")
target_link_libraries(test-consumer-shared-ns PRIVATE "CURL::libcurl_shared")
add_executable(test-consumer-static-ns "test.c")
target_link_libraries(test-consumer-static-ns PRIVATE "CURL::libcurl_static")
# Alias for either shared or static library
add_executable(test-consumer-selected-ns "test.c")
target_link_libraries(test-consumer-selected-ns PRIVATE "CURL::libcurl")
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-consumer-selected-ns "test.c")
target_link_libraries(test-consumer-selected-ns PRIVATE "CURL::libcurl")
endif()
if(TEST_INTEGRATION_MODE STREQUAL "add_subdirectory" OR
TEST_INTEGRATION_MODE STREQUAL "FetchContent")

View File

@ -41,20 +41,20 @@ runresults() {
set -x
}
if [ "${mode}" = 'ExternalProject' ]; then # Broken
if [ "${mode}" = 'all' ] || [ "${mode}" = 'ExternalProject' ]; then
(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}" -G "${gen}" ${cmake_opts} -DCMAKE_UNITY_BUILD=ON ${TEST_CMAKE_FLAGS:-} "$@" \
"${cmake_consumer}" -B "${bldc}" -G "${gen}" ${TEST_CMAKE_FLAGS:-} -DCURL_TEST_OPTS="${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}" .. -G "${gen}" ${cmake_opts} ${TEST_CMAKE_FLAGS:-} "$@" \
"${cmake_consumer}" .. -G "${gen}" ${TEST_CMAKE_FLAGS:-} -DCURL_TEST_OPTS="${cmake_opts} $*" \
-DTEST_INTEGRATION_MODE=ExternalProject \
-DFROM_ARCHIVE="${src}" -DFROM_HASH="${sha}"
VERBOSE=1 "${cmake_consumer}" --build .