]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
runtests: support multi-target cmake, drop workarounds from CI
authorViktor Szakats <commit@vsz.me>
Mon, 24 Feb 2025 14:27:35 +0000 (15:27 +0100)
committerViktor Szakats <commit@vsz.me>
Mon, 24 Feb 2025 20:00:30 +0000 (21:00 +0100)
Support multi-target cmake builds via `CURL_DIRSUFFIX` env. For example:
`export CURL_DIRSUFFIX=Debug/`.

Multi-target generators place their output to `src/<subdir>/`,
`lib/<subdir>/`, `tests/server/<subdir>`, `tests/libtest/<subdir>` and
`tests/unit/<subdir>/` by default. Before this patch, `runtests.pl`
couldn't run on such builds because it expected the binaries under the
their `<subdir>`-less directories. This patch allows to set such subdir
and make `runtests.pl` find the binaries. In CI we use multi-target
builds with tests for MSVC. It also helps Xcode-generator builds, though
in CI we don't have such job running tests.

There may be better solutions to configure this, but passing a custom
value to `runtests.pl` including its subprocesses is somewhat tricky.
The reason the configuration value expects the slash at the end is
because MSYS is automagically expanding the env to a (wrong) absolute
path if the slash is in the front.

Also:
- drop the `-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_*=` workaround from CI.
- replace `resolve` references in tests with a new `%RESOLVE` variable.
  It didn't use a filename extension before. After this patch it uses
  `exe_ext('TOOL')`. I'm not sure if this is the correct choice vs.
  `exe_ext('SRV')`.
- fix `-c` option format in manual.
- fix some whitespace.

Note, in CI we still tweak `CMAKE_RUNTIME_OUTPUT_DIRECTORY_*` in jobs
which share steps between `./configure` and cmake. It's easier that way.

Ref: #15000
Cherry-picked from #16394

Closes #16452

16 files changed:
.github/workflows/windows.yml
appveyor.sh
tests/FILEFORMAT.md
tests/data/test1083
tests/data/test1085
tests/data/test241
tests/ftpserver.pl
tests/globalconfig.pm
tests/http-server.pl
tests/rtspserver.pl
tests/runner.pm
tests/runtests.md
tests/runtests.pl
tests/serverhelp.pm
tests/servers.pm
tests/tftpserver.pl

index 8176b3b9841cf4a2a7a419b2c2c2dcd2f0b5c700..8265d3b703a4daf6d4ff610b97b4765572c94c52 100644 (file)
@@ -827,8 +827,6 @@ jobs:
               -DCMAKE_EXE_LINKER_FLAGS="-INCREMENTAL:NO ${ldflags}" \
               -DCMAKE_SHARED_LINKER_FLAGS="-INCREMENTAL:NO ${ldflags}" \
               -DCMAKE_VS_GLOBALS="TrackFileAccess=false${vsglobals}" \
-              -DCMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG= \
-              -DCMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE= \
               -DCMAKE_UNITY_BUILD=ON -DCURL_TEST_BUNDLES=ON \
               -DCURL_WERROR=ON \
               -DBUILD_SHARED_LIBS=OFF \
@@ -860,8 +858,8 @@ jobs:
         run: |
           PATH=/usr/bin find . \( -name '*.exe' -o -name '*.dll' -o -name '*.lib' \) -exec file '{}' \;
           if [ '${{ matrix.plat }}' != 'uwp' ]; then  # Missing: ucrtbased.dll, VCRUNTIME140D.dll, VCRUNTIME140D_APP.dll
-            PATH="$PWD/bld/lib:$PATH"
-            bld/src/curl.exe --disable --version
+            PATH="$PWD/bld/lib/${{ matrix.type }}:$PATH"
+            'bld/src/${{ matrix.type }}/curl.exe' --disable --version
           fi
 
       - name: 'build tests'
@@ -896,13 +894,14 @@ jobs:
         if: ${{ matrix.tflags != 'skipall' && matrix.tflags != 'skiprun' }}
         timeout-minutes: 10
         run: |
+          export CURL_DIRSUFFIX='${{ matrix.type }}/'
           export TFLAGS='-j8 ~WebSockets ~SCP ~612 ${{ matrix.tflags }}'
           if [[ '${{ matrix.install }}' = *'libssh2[core,zlib]'* ]]; then
             TFLAGS+=' ~SFTP'
           elif [[ '${{ matrix.install }}' = *'libssh '* ]]; then
             TFLAGS+=' ~614'  # 'SFTP pre-quote chmod' SFTP, pre-quote, directory
           fi
-          PATH="$PWD/bld/lib:$PATH:/c/Program Files (x86)/stunnel/bin:/c/Program Files/OpenSSH-Win64"
+          PATH="$PWD/bld/lib/${{ matrix.type }}:$PATH:/c/Program Files (x86)/stunnel/bin:/c/Program Files/OpenSSH-Win64"
           PATH="/c/msys64/usr/bin:$PATH"
           cmake --build bld --config '${{ matrix.type }}' --target test-ci
 
index e8f7678d60bc7c68759392f576bed144b6c3e711..d1363e72e6cbf53e740d06ad63cf46e98242bcc5 100644 (file)
@@ -55,8 +55,6 @@ if [ "${BUILD_SYSTEM}" = 'CMake' ]; then
     # shellcheck disable=SC2086
     cmake -B "_bld${_chkprefill}" -G "${PRJ_GEN}" ${TARGET} \
       -DCMAKE_VS_GLOBALS=TrackFileAccess=false \
-      -DCMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG= \
-      -DCMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE= \
       -DCMAKE_UNITY_BUILD="${UNITY}" -DCURL_TEST_BUNDLES=ON \
       -DCURL_WERROR=ON \
       -DBUILD_SHARED_LIBS="${SHARED}" \
@@ -78,9 +76,9 @@ if [ "${BUILD_SYSTEM}" = 'CMake' ]; then
   echo 'curl_config.h'; grep -F '#define' _bld/lib/curl_config.h | sort || true
   # shellcheck disable=SC2086
   cmake --build _bld --config "${PRJ_CFG}" --parallel 2 -- ${BUILD_OPT:-}
-  [ "${SHARED}" = 'ON' ] && PATH="$PWD/_bld/lib:$PATH"
+  [ "${SHARED}" = 'ON' ] && PATH="$PWD/_bld/lib/${PRJ_CFG}:$PATH"
   [ "${OPENSSL}" = 'ON' ] && PATH="${openssl_root}:$PATH"
-  curl='_bld/src/curl.exe'
+  curl="_bld/src/${PRJ_CFG}/curl.exe"
 elif [ "${BUILD_SYSTEM}" = 'VisualStudioSolution' ]; then
   (
     cd projects
@@ -131,6 +129,7 @@ fi
 
 if [ "${TFLAGS}" != 'skipall' ] && \
    [ "${TFLAGS}" != 'skiprun' ]; then
+  export CURL_DIRSUFFIX="${PRJ_CFG}/"
   if [ -x "$(cygpath "${SYSTEMROOT}/System32/curl.exe")" ]; then
     TFLAGS+=" -ac $(cygpath "${SYSTEMROOT}/System32/curl.exe")"
   elif [ -x "$(cygpath 'C:/msys64/usr/bin/curl.exe')" ]; then
index c408999249eb63dd193811b6388460b8d9678601..19485b6b49e0af866e3cfcf6a18fa5e98d798993 100644 (file)
@@ -163,6 +163,7 @@ Available substitute variables include:
 - `%POSIX_PWD` - Current directory somewhat MinGW friendly
 - `%PROXYPORT` - Port number of the HTTP proxy
 - `%PWD` - Current directory
+- `%RESOLVE` - server/resolve command
 - `%RTSP6PORT` - IPv6 port number of the RTSP server
 - `%RTSPPORT` - Port number of the RTSP server
 - `%SMBPORT` - Port number of the SMB server
index b82e308fc56e745a6f24295200f47189d528eb66..e588d7e7d1b2daf9dddde7f4031136396d75113e 100644 (file)
@@ -39,7 +39,7 @@ HTTP-IPv6 GET with ip6-localhost --interface
 -g "http://%HOST6IP:%HTTP6PORT/%TESTNUMBER" --interface ip6-localhost
 </command>
 <precheck>
-%PERL -e "if ('%CLIENT6IP' ne '[::1]') {print 'Test requires default test client host address';} else {exec './server/resolve --ipv6 ip6-localhost'; print 'Cannot run precheck resolve';}"
+%PERL -e "if ('%CLIENT6IP' ne '[::1]') {print 'Test requires default test client host address';} else {exec '%RESOLVE --ipv6 ip6-localhost'; print 'Cannot run precheck resolve';}"
 </precheck>
 </client>
 
index 55eb00e06901eb20c76ef82b252d916b6919aebf..c4a57800fba8e65473c1dee60e687f6e403a32f9 100644 (file)
@@ -34,7 +34,7 @@ HTTP-IPv6 GET with invalid --interface
 # Ensure the IPv6 stack is operational before running this test (other tests
 # use the startup of the IPv6 test server as a substitute check for this).
 <precheck>
-./server/resolve --ipv6 ::1
+%RESOLVE --ipv6 ::1
 </precheck>
 </client>
 
index 38dea3fd56a74d82e2be619eb18fc8100a262e82..f8cf6e9a43a26f1f6e72ffeddecd550690b54699 100644 (file)
@@ -36,7 +36,7 @@ HTTP-IPv6 GET (using ip6-localhost)
 -g "http://ip6-localhost:%HTTP6PORT/%TESTNUMBER"
 </command>
 <precheck>
-./server/resolve --ipv6 ip6-localhost
+%RESOLVE --ipv6 ip6-localhost
 </precheck>
 </client>
 
index abe04959d92c6396b5ea50822f9bd151a3e86ec8..afdd80e80f64e69a663ac7114643827ec3f4128b 100755 (executable)
@@ -68,16 +68,13 @@ use serverhelp qw(
     servername_str
     server_pidfilename
     server_logfilename
+    server_exe
     mainsockf_pidfilename
     mainsockf_logfilename
     datasockf_pidfilename
     datasockf_logfilename
     );
 
-use pathhelp qw(
-    exe_ext
-    );
-
 use globalconfig qw(
     $SERVERCMD
     $LOCKDIR
@@ -410,7 +407,7 @@ sub sysread_or_die {
 }
 
 sub startsf {
-    my @mainsockfcmd = ("./server/sockfilt".exe_ext('SRV'),
+    my @mainsockfcmd = (server_exe('sockfilt'),
         "--ipv$ipvnum",
         "--port", $port,
         "--pidfile", $mainsockf_pidfile,
@@ -2472,10 +2469,10 @@ sub PASV_ftp {
     logmsg "DATA sockfilt for passive data channel starting...\n";
 
     # We fire up a new sockfilt to do the data transfer for us.
-    my @datasockfcmd = ("./server/sockfilt".exe_ext('SRV'),
+    my @datasockfcmd = (server_exe('sockfilt'),
         "--ipv$ipvnum", "--port", 0,
         "--pidfile", $datasockf_pidfile,
-        "--logfile",  $datasockf_logfile);
+        "--logfile", $datasockf_logfile);
     if($nodataconn) {
         push(@datasockfcmd, '--bindonly');
     }
@@ -2694,7 +2691,7 @@ sub PORT_ftp {
     logmsg "DATA sockfilt for active data channel starting...\n";
 
     # We fire up a new sockfilt to do the data transfer for us.
-    my @datasockfcmd = ("./server/sockfilt".exe_ext('SRV'),
+    my @datasockfcmd = (server_exe('sockfilt'),
         "--ipv$ipvnum", "--connect", $port, "--addr", $addr,
         "--pidfile", $datasockf_pidfile,
         "--logfile", $datasockf_logfile);
index 140a9f686e68268ba95fe4ea9f209501eed006c7..70ded3f2bfb67b062b772f66b9a0fc9591a80952 100644 (file)
@@ -42,6 +42,8 @@ BEGIN {
         $DATE
         $has_shared
         $LIBDIR
+        $UNITDIR
+        $SRVDIR
         $listonly
         $LOCKDIR
         $LOGDIR
@@ -102,9 +104,11 @@ our $perlcmd=shell_quote($^X);
 our $perl="$perlcmd -I. " . shell_quote("-I$srcdir"); # invoke perl like this
 our $LOGDIR="log";  # root of the log directory; this will be different for
                     # each runner in multiprocess mode
-our $LIBDIR="./libtest";
+our $LIBDIR="./libtest/" . ($ENV{'CURL_DIRSUFFIX'} || '');
+our $UNITDIR="./unit/" . ($ENV{'CURL_DIRSUFFIX'} || '');
+our $SRVDIR="./server/" . ($ENV{'CURL_DIRSUFFIX'} || '');
 our $TESTDIR="$srcdir/data";
-our $CURL="../src/curl".exe_ext('TOOL'); # what curl binary to run on the tests
+our $CURL="../src/" . ($ENV{'CURL_DIRSUFFIX'} || '') . "curl".exe_ext('TOOL'); # what curl binary to run on the tests
 our $VCURL=$CURL;  # what curl binary to use to verify the servers with
                    # VCURL is handy to set to the system one when the one you
                    # just built hangs or crashes and thus prevent verification
index 526ec319bddbeb4af99a5b7b48649ecd9e2ef6d5..d100caef685433781fd8f697ca4fc29861f464ab 100755 (executable)
@@ -36,10 +36,7 @@ use File::Basename;
 use serverhelp qw(
     server_pidfilename
     server_logfilename
-    );
-
-use pathhelp qw(
-    exe_ext
+    server_exe
     );
 
 my $verbose = 0;     # set to 1 for debugging
@@ -187,8 +184,8 @@ if($ipvnum eq 'unix') {
 $flags .= "--srcdir \"$srcdir\"";
 
 if($verbose) {
-    print STDERR "RUN: server/sws".exe_ext('SRV')." $flags\n";
+    print STDERR "RUN: ".server_exe('sws')." $flags\n";
 }
 
 $| = 1;
-exec("exec server/sws".exe_ext('SRV')." $flags");
+exec("exec ".server_exe('sws')." $flags");
index 3282d9c231ea2ee664860490f70f9b05a7c0e469..d2e13390733859024f1be8b426d122577f65ef7f 100755 (executable)
@@ -34,10 +34,7 @@ BEGIN {
 use serverhelp qw(
     server_pidfilename
     server_logfilename
-    );
-
-use pathhelp qw(
-    exe_ext
+    server_exe
     );
 
 my $verbose = 0;     # set to 1 for debugging
@@ -133,4 +130,4 @@ $flags .= "--pidfile \"$pidfile\" ".
 $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
 
 $| = 1;
-exec("exec server/rtspd".exe_ext('SRV')." $flags");
+exec("exec ".server_exe('rtspd')." $flags");
index 12f67022b5911ca73ff99079197630f35f10914d..12391eaf21f5b4522ed88868d25c695e17c38514 100644 (file)
@@ -126,7 +126,6 @@ our $tortalloc;
 
 # local variables
 my %oldenv;       # environment variables before test is started
-my $UNITDIR="./unit";
 my $CURLLOG="$LOGDIR/commands.log"; # all command lines run
 my $defserverlogslocktimeout = 5; # timeout to await server logs lock removal
 my $defpostcommanddelay = 0; # delay between command and postcheck sections
@@ -263,7 +262,7 @@ sub event_loop {
 #
 sub checktestcmd {
     my ($cmd)=@_;
-    my @testpaths=("$LIBDIR/.libs", "$LIBDIR");
+    my @testpaths=($LIBDIR . ".libs", "$LIBDIR");
     return checkcmd($cmd, @testpaths);
 }
 
@@ -922,18 +921,18 @@ sub singletest_run {
 
         if($tool =~ /^lib/) {
             if($bundle) {
-                $CMDLINE="$LIBDIR/libtests";
+                $CMDLINE=$LIBDIR . "libtests";
             }
             else {
-                $CMDLINE="$LIBDIR/$tool";
+                $CMDLINE=$LIBDIR . $tool;
             }
         }
         elsif($tool =~ /^unit/) {
             if($bundle) {
-                $CMDLINE="$UNITDIR/units";
+                $CMDLINE=$UNITDIR . "units";
             }
             else {
-                $CMDLINE="$UNITDIR/$tool";
+                $CMDLINE=$UNITDIR . $tool;
             }
         }
 
@@ -1035,12 +1034,12 @@ sub singletest_run {
     if ($torture) {
         $cmdres = torture($CMDLINE,
                           $testnum,
-                          "$gdb --directory $LIBDIR " . shell_quote($DBGCURL) . " -x $LOGDIR/gdbcmd");
+                          "$gdb --directory $LIBDIR " . shell_quote($DBGCURL) . " -x $LOGDIR" . "gdbcmd");
     }
     elsif($gdbthis == 1) {
         # gdb
         my $GDBW = ($gdbxwin) ? "-w" : "";
-        runclient("$gdb --directory $LIBDIR " . shell_quote($DBGCURL) . " $GDBW -x $LOGDIR/gdbcmd");
+        runclient("$gdb --directory $LIBDIR " . shell_quote($DBGCURL) . " $GDBW -x $LOGDIR" . "gdbcmd");
         $cmdres=0; # makes it always continue after a debugged run
     }
     elsif($gdbthis == 2) {
index 4ac52a44601b36ebabd3c24a67423158096cf8f8..01b9182638eb1158cf797f2e20b56e0cb8df5916 100644 (file)
@@ -96,7 +96,7 @@ Display test results in automake style output (`PASS/FAIL: [number] [name]`).
 Run tests via bundled test binaries. Bundled test binaries contain all tests,
 and the test name passed as the first argument selects which test run.
 
-## `-c\<curl\>`
+## `-c \<curl\>`
 
 Provide a path to a custom curl binary to run the tests with. Default is the
 curl executable in the build tree.
index d6472935558c4a7b4113d6041cfccf5c8c3297f6..68582382be380ddf2dd7a1506f1af4bd2ae34a9c 100755 (executable)
@@ -84,6 +84,9 @@ use Digest::MD5 qw(md5);
 use List::Util 'sum';
 use I18N::Langinfo qw(langinfo CODESET);
 
+use serverhelp qw(
+    server_exe
+    );
 use pathhelp qw(
     exe_ext
     sys_native_current_path
@@ -510,7 +513,7 @@ sub checksystemfeatures {
     @version = <$versout>;
     close($versout);
 
-    open(my $disabledh, "-|", "server/disabled".exe_ext('TOOL'));
+    open(my $disabledh, "-|", server_exe('disabled', 'TOOL'));
     @disabled = <$disabledh>;
     close($disabledh);
 
@@ -766,7 +769,7 @@ sub checksystemfeatures {
         # client has IPv6 support
 
         # check if the HTTP server has it!
-        my $cmd = "server/sws".exe_ext('SRV')." --version";
+        my $cmd = server_exe('sws')." --version";
         my @sws = `$cmd`;
         if($sws[0] =~ /IPv6/) {
             # HTTP server has IPv6 support!
@@ -774,7 +777,7 @@ sub checksystemfeatures {
         }
 
         # check if the FTP server has it!
-        $cmd = "server/sockfilt".exe_ext('SRV')." --version";
+        $cmd = server_exe('sockfilt')." --version";
         @sws = `$cmd`;
         if($sws[0] =~ /IPv6/) {
             # FTP server has IPv6 support!
@@ -784,7 +787,7 @@ sub checksystemfeatures {
 
     if($feature{"UnixSockets"}) {
         # client has Unix sockets support, check whether the HTTP server has it
-        my $cmd = "server/sws".exe_ext('SRV')." --version";
+        my $cmd = server_exe('sws')." --version";
         my @sws = `$cmd`;
         $http_unix = 1 if($sws[0] =~ /unix/);
     }
index 22cf30e529c34a6d37fcd3dbadf8c4a346bedb60..7eb9a2b4954524e97aea2981cddae1aced2653a1 100644 (file)
@@ -45,6 +45,7 @@ BEGIN {
         server_cmdfilename
         server_inputfilename
         server_outputfilename
+        server_exe
         mainsockf_pidfilename
         mainsockf_logfilename
         datasockf_pidfilename
@@ -59,6 +60,10 @@ BEGIN {
     }
 }
 
+use globalconfig;
+use pathhelp qw(
+    exe_ext
+    );
 
 our $logfile;  # server log file name, for logmsg
 
@@ -230,6 +235,18 @@ sub server_outputfilename {
 }
 
 
+#***************************************************************************
+# Return filename for a server executable
+#
+sub server_exe {
+    my ($name, $ext) = @_;
+    if(!defined $ext) {
+        $ext = 'SRV';
+    }
+    return $SRVDIR . $name . exe_ext($ext);
+}
+
+
 #***************************************************************************
 # Return file name for main or primary sockfilter pid file.
 #
index 0169887eebf4bcfb1eeaba16aee8662071d2f3d2..7d644eed59e4dec718f0e32fa2afdb736af95bc1 100644 (file)
@@ -77,6 +77,7 @@ use serverhelp qw(
     server_pidfilename
     server_portfilename
     server_logfilename
+    server_exe
     );
 
 use sshhelp qw(
@@ -1959,8 +1960,8 @@ sub runmqttserver {
     my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
 
     # start our MQTT server - on a random port!
-    my $cmd="server/mqttd".exe_ext('SRV').
-        " --port 0 ".
+    my $cmd=server_exe('mqttd').
+        " --port 0".
         " --pidfile $pidfile".
         " --portfile $portfile".
         " --config $LOGDIR/$SERVERCMD".
@@ -2017,7 +2018,7 @@ sub runsocksserver {
     # start our socks server, get commands from the FTP cmd file
     my $cmd="";
     if($is_unix) {
-        $cmd="server/socksd".exe_ext('SRV').
+        $cmd=server_exe('socksd').
             " --pidfile $pidfile".
             " --reqfile $LOGDIR/$SOCKSIN".
             " --logfile $logfile".
@@ -2025,8 +2026,8 @@ sub runsocksserver {
             " --backend $HOSTIP".
             " --config $LOGDIR/$SERVERCMD";
     } else {
-        $cmd="server/socksd".exe_ext('SRV').
-            " --port 0 ".
+        $cmd=server_exe('socksd').
+            " --port 0".
             " --pidfile $pidfile".
             " --portfile $portfile".
             " --reqfile $LOGDIR/$SOCKSIN".
@@ -3114,6 +3115,8 @@ sub subvariables {
     $$thing =~ s/${prefix}VERNUM/$CURLVERNUM/g;
     $$thing =~ s/${prefix}DATE/$DATE/g;
     $$thing =~ s/${prefix}TESTNUMBER/$testnum/g;
+    my $resolve = server_exe('resolve', 'TOOL');
+    $$thing =~ s/${prefix}RESOLVE/$resolve/g;
 
     # POSIX/MSYS/Cygwin curl needs: file://localhost/d/path/to
     # Windows native    curl needs: file://localhost/D:/path/to
index 52ad01f0c22cb4e9066c302637e7434b49e2d8cf..98a284aaa389b548334c530026082eec49203387 100755 (executable)
@@ -34,10 +34,7 @@ BEGIN {
 use serverhelp qw(
     server_pidfilename
     server_logfilename
-    );
-
-use pathhelp qw(
-    exe_ext
+    server_exe
     );
 
 my $verbose = 0;     # set to 1 for debugging
@@ -130,4 +127,4 @@ $flags .= "--pidfile \"$pidfile\" ".
 $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
 
 $| = 1;
-exec("exec server/tftpd".exe_ext('SRV')." $flags");
+exec("exec ".server_exe('tftpd')." $flags");