From df70a68984308952dcacf33d11593cb22ad80464 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Tue, 7 Oct 2025 12:36:49 +0200 Subject: [PATCH] cmake: support building some complicated examples, build them in CI Build these examples when the necessary dependencies are present: - cacertinmem, usercertinmem (OpenSSL/fork) - multi-uv (libuv) - multithread, threaded-ssl (pthread) - sessioninfo (GnuTLS) Indicate the necessary dependency via a `Required:` comment placed in the source file. A single dependency per source is supported as of now. The name of the dependency should match the variable used within the cmake scripts, which in turn matches the macro used in the config header. E.g. for GnuTLS it's `USE_GNUTLS`. Also: - GHA/macos: build examples in two job to test GnuTLS and pthread ones. - GHA/linux: enable libuv to test it with examples. Follow-up to 6bb77140322565ca17f5a66aa5d8500d8d469cca #18914 Closes #18909 --- .github/workflows/linux.yml | 4 ++-- .github/workflows/macos.yml | 4 ++-- docs/examples/CMakeLists.txt | 34 +++++++++++++++++++++++++++++++--- docs/examples/Makefile.am | 5 +++-- docs/examples/Makefile.inc | 16 ++++++++++------ docs/examples/cacertinmem.c | 2 ++ docs/examples/multi-uv.c | 4 +++- docs/examples/multithread.c | 2 ++ docs/examples/sessioninfo.c | 2 ++ docs/examples/threaded-ssl.c | 3 ++- docs/examples/usercertinmem.c | 2 ++ 11 files changed, 61 insertions(+), 17 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index d78789b8a1..d01fb4a0b9 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -109,10 +109,10 @@ jobs: configure: CC=clang LDFLAGS=-Wl,-rpath,/home/runner/mbedtls/lib --with-mbedtls=/home/runner/mbedtls --enable-debug --with-fish-functions-dir --with-zsh-functions-dir - name: 'mbedtls' - install_packages: libnghttp2-dev + install_packages: libnghttp2-dev libuv1-dev install_steps: mbedtls PKG_CONFIG_PATH: /home/runner/mbedtls/lib/pkgconfig # Requires v3.6.0 - generate: -DCURL_USE_MBEDTLS=ON -DENABLE_DEBUG=ON + generate: -DCURL_USE_MBEDTLS=ON -DCURL_USE_LIBUV=ON -DENABLE_DEBUG=ON - name: 'mbedtls-pkg MultiSSL !pc' install_packages: libnghttp2-dev libmbedtls-dev diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index c32b71439c..b4bbc8ea79 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -276,7 +276,7 @@ jobs: configure: --enable-debug --with-openssl=/opt/homebrew/opt/openssl tflags: --test-event # cmake - - name: 'OpenSSL gsasl rtmp AppleIDN SecTrust' + - name: 'OpenSSL gsasl rtmp AppleIDN SecTrust +examples' install: libnghttp3 libngtcp2 gsasl rtmpdump generate: -DOPENSSL_ROOT_DIR=/opt/homebrew/opt/openssl -DCURL_USE_GSASL=ON -DUSE_LIBRTMP=ON -DUSE_APPLE_IDN=ON -DUSE_NGTCP2=ON -DCURL_DISABLE_VERBOSE_STRINGS=ON -DUSE_APPLE_SECTRUST=ON - name: 'MultiSSL AppleIDN clang-tidy +examples' @@ -314,7 +314,7 @@ jobs: install: brotli mbedtls zstd install_steps: codeset-test generate: -DCURL_USE_MBEDTLS=ON -DCURL_DISABLE_LDAP=ON -DCURL_DEFAULT_SSL_BACKEND=mbedtls -DCURL_USE_OPENSSL=ON -DUSE_APPLE_IDN=ON - - name: 'GnuTLS !ldap krb5' + - name: 'GnuTLS !ldap krb5 +examples' install: gnutls nettle krb5 generate: -DENABLE_DEBUG=ON -DCURL_USE_GNUTLS=ON -DCURL_USE_OPENSSL=OFF -DCURL_USE_GSSAPI=ON -DGSS_ROOT_DIR=/opt/homebrew/opt/krb5 -DCURL_DISABLE_LDAP=ON -DUSE_SSLS_EXPORT=ON - name: 'aws-lc' diff --git a/docs/examples/CMakeLists.txt b/docs/examples/CMakeLists.txt index d86494c870..c86e8439fd 100644 --- a/docs/examples/CMakeLists.txt +++ b/docs/examples/CMakeLists.txt @@ -24,14 +24,22 @@ add_custom_target(curl-examples) -# Get check_PROGRAMS variable +# Get check_PROGRAMS, COMPLICATED_MAY_BUILD, COMPLICATED_EXAMPLES variables curl_transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") +set(_with_deps "") set(_all_src "") set(_all_canary "") set(_all "all") -foreach(_target IN LISTS check_PROGRAMS _all) # keep '_all' last +foreach(_target IN LISTS COMPLICATED_MAY_BUILD check_PROGRAMS _all) # keep 'COMPLICATED_MAY_BUILD' first, and '_all' last + # Strip .c suffix from COMPLICATED_MAY_BUILD items + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.20) + cmake_path(GET _target STEM _target) + else() + get_filename_component(_target "${_target}" NAME_WE) + endif() + set(_more_libs "") set(_target_name "curl-example-${_target}") if(_target STREQUAL "all") if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12) @@ -50,16 +58,36 @@ foreach(_target IN LISTS check_PROGRAMS _all) # keep '_all' last else() add_library(${_target_name} STATIC EXCLUDE_FROM_ALL ${_all_src}) endif() + if(_with_deps) + set(_more_libs ${CURL_LIBS}) # If any examples required dependencies, link them + endif() add_custom_target(curl-examples-build) # Special target to compile all tests quickly and build a single test to probe linkage add_dependencies(curl-examples-build ${_target_name} ${_all_canary}) # Include a full build of a single test else() + # Check if the example requires a build option. Then check if that build option is enabled. + # If it is, link all dependencies to the example. + set(_requires_regex "/\\* Requires: ([A-Z0-9_]+) \\*/") + file(STRINGS "${_target}.c" _req REGEX "${_requires_regex}") + string(REGEX REPLACE "${_requires_regex}" "\\1" _req "${_req}") + if(_req) + if(${${_req}}) + string(APPEND _with_deps " ${_target}:${_req}") + set(_more_libs ${CURL_LIBS}) + else() + continue() # Option required, but not found + endif() + endif() set(_all_canary ${_target_name}) # Save the last test for the curl-examples-build target list(APPEND _all_src "${_target}.c") add_executable(${_target_name} EXCLUDE_FROM_ALL "${_target}.c") add_dependencies(curl-examples ${_target_name}) endif() - target_link_libraries(${_target_name} ${LIB_SELECTED} ${CURL_NETWORK_AND_TIME_LIBS}) + target_link_libraries(${_target_name} ${LIB_SELECTED} ${CURL_NETWORK_AND_TIME_LIBS} ${_more_libs}) target_compile_definitions(${_target_name} PRIVATE "CURL_NO_OLDIES" "$<$:WIN32_LEAN_AND_MEAN>" "$<$:_CRT_SECURE_NO_DEPRECATE>") set_target_properties(${_target_name} PROPERTIES OUTPUT_NAME "${_target}" PROJECT_LABEL "Example ${_target}" UNITY_BUILD OFF) endforeach() + +if(_with_deps) + message(STATUS "Enabled examples with dependencies:${_with_deps}") +endif() diff --git a/docs/examples/Makefile.am b/docs/examples/Makefile.am index 89ebcc9840..0885b925c4 100644 --- a/docs/examples/Makefile.am +++ b/docs/examples/Makefile.am @@ -24,7 +24,8 @@ AUTOMAKE_OPTIONS = foreign nostdinc -EXTRA_DIST = CMakeLists.txt .checksrc README.md Makefile.example $(COMPLICATED_EXAMPLES) +EXTRA_DIST = CMakeLists.txt .checksrc README.md Makefile.example \ + $(COMPLICATED_MAY_BUILD) $(COMPLICATED_EXAMPLES) # Specify our include paths here, and do it relative to $(top_srcdir) and # $(top_builddir), to ensure that these paths which belong to the library @@ -53,7 +54,7 @@ LDADD = $(top_builddir)/lib/libcurl.la # This might hold -Werror CFLAGS += @CURL_CFLAG_EXTRAS@ -# Get check_PROGRAMS variable +# Get check_PROGRAMS, COMPLICATED_MAY_BUILD, COMPLICATED_EXAMPLES variables include Makefile.inc all: $(check_PROGRAMS) diff --git a/docs/examples/Makefile.inc b/docs/examples/Makefile.inc index bb6e42971b..3bb68f25aa 100644 --- a/docs/examples/Makefile.inc +++ b/docs/examples/Makefile.inc @@ -140,10 +140,19 @@ check_PROGRAMS = \ websocket-cb \ websocket-updown +# These examples require external dependencies that may be available during +# the build. +COMPLICATED_MAY_BUILD = \ + cacertinmem.c \ + multi-uv.c \ + multithread.c \ + sessioninfo.c \ + threaded-ssl.c \ + usercertinmem.c + # These examples require external dependencies that may not be commonly # available on POSIX systems, so do not bother attempting to compile them here. COMPLICATED_EXAMPLES = \ - cacertinmem.c \ crawler.c \ ephiperfifo.c \ evhiperfifo.c \ @@ -152,11 +161,6 @@ COMPLICATED_EXAMPLES = \ htmltidy.c \ htmltitle.cpp \ multi-event.c \ - multi-uv.c \ - multithread.c \ - sessioninfo.c \ smooth-gtk-thread.c \ - threaded-ssl.c \ - usercertinmem.c \ version-check.pl \ xmlstream.c diff --git a/docs/examples/cacertinmem.c b/docs/examples/cacertinmem.c index 6a2649b29b..e552ce5d69 100644 --- a/docs/examples/cacertinmem.c +++ b/docs/examples/cacertinmem.c @@ -26,6 +26,8 @@ * */ +/* Requires: USE_OPENSSL */ + #include #include #include diff --git a/docs/examples/multi-uv.c b/docs/examples/multi-uv.c index 07774c93eb..8cebcd5e26 100644 --- a/docs/examples/multi-uv.c +++ b/docs/examples/multi-uv.c @@ -21,11 +21,11 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ - /* * multi_socket API using libuv * */ + /* Use the socket_action interface to download multiple files in parallel, powered by libuv. @@ -34,6 +34,8 @@ See https://docs.libuv.org/en/v1.x/index.html libuv API documentation */ +/* Requires: USE_LIBUV */ + #include #include #include diff --git a/docs/examples/multithread.c b/docs/examples/multithread.c index 4cdb74fbe4..b98977c443 100644 --- a/docs/examples/multithread.c +++ b/docs/examples/multithread.c @@ -26,6 +26,8 @@ * */ +/* Requires: HAVE_PTHREAD_H */ + #include #include #include diff --git a/docs/examples/sessioninfo.c b/docs/examples/sessioninfo.c index 5fbc1cc4df..b9b3a3c462 100644 --- a/docs/examples/sessioninfo.c +++ b/docs/examples/sessioninfo.c @@ -29,6 +29,8 @@ /* Note that this example currently requires curl to be linked against GnuTLS (and this program must also be linked against -lgnutls). */ +/* Requires: USE_GNUTLS */ + #ifndef CURL_DISABLE_DEPRECATION #define CURL_DISABLE_DEPRECATION #endif diff --git a/docs/examples/threaded-ssl.c b/docs/examples/threaded-ssl.c index 6590e8b202..3868899e4f 100644 --- a/docs/examples/threaded-ssl.c +++ b/docs/examples/threaded-ssl.c @@ -36,7 +36,8 @@ * https://github.com/curl/curl/blob/curl-7_88_1/docs/examples/threaded-ssl.c */ -#define USE_OPENSSL /* or USE_GNUTLS accordingly */ +/* Requires: HAVE_PTHREAD_H */ +/* Also requires TLS support to run */ #include #include diff --git a/docs/examples/usercertinmem.c b/docs/examples/usercertinmem.c index 899895592e..2a3c2b0006 100644 --- a/docs/examples/usercertinmem.c +++ b/docs/examples/usercertinmem.c @@ -31,6 +31,8 @@ * must be used in real circumstances when a secure connection is required. */ +/* Requires: USE_OPENSSL */ + #ifndef OPENSSL_SUPPRESS_DEPRECATED #define OPENSSL_SUPPRESS_DEPRECATED #endif -- 2.47.3