Checking lib and src under 3m15s versus 7m15s.
Downside: autotools clang-tidy support is no longer CI-tested.
The reason for the slowness is invoking a single clang-tidy command with
all source files, and clang-tidy checking them in a single thread,
sequentially. clang-tidy offers a `run-clang-tidy` Python script for
parallel processing, which may help with this. However at this point
it's more practical to use cmake, which also supports verifying the
whole codebase, not only lib and src.
Also:
- bump clang-tidy to the latest available, v20 (from v18).
- enable running clang-tidy on tests. Takes under 2 minutes.
Also tried `_CURL_TESTS_CONCAT=ON`, it brings down the build tests step
from 1m47s to 54s, saving 1 minute. Skipped using it for now.
Closes#20725
Reported by clang-tidy (seen on Linux with v18, v19, v20, not on macOS):
```
tests/server/dnsd.c:552:14: error: 1st function call argument is an uninitialized value [clang-analyzer-core.CallAndMessage]
tests/server/dnsd.c:556:14: error: 1st function call argument is an uninitialized value [clang-analyzer-core.CallAndMessage]
tests/server/rtspd.c:1183:14: error: 1st function call argument is an uninitialized value [clang-analyzer-core.CallAndMessage]
tests/server/rtspd.c:1187:14: error: 1st function call argument is an uninitialized value [clang-analyzer-core.CallAndMessage]
tests/server/sws.c:2235:14: error: 1st function call argument is an uninitialized value [clang-analyzer-core.CallAndMessage]
tests/server/sws.c:2239:14: error: 1st function call argument is an uninitialized value [clang-analyzer-core.CallAndMessage]
tests/server/tftpd.c:1188:14: error: 1st function call argument is an uninitialized value [clang-analyzer-core.CallAndMessage]
tests/server/tftpd.c:1192:14: error: 1st function call argument is an uninitialized value [clang-analyzer-core.CallAndMessage]
tests/server/util.c:860:21: error: 1st function call argument is an uninitialized value [clang-analyzer-core.CallAndMessage]
tests/server/util.c:864:21: error: 1st function call argument is an uninitialized value [clang-analyzer-core.CallAndMessage]
```
Ref: https://github.com/curl/curl/actions/runs/22424827575/job/64930560425?pr=20725
Cherry-picked from #20725Closes#20730
- run tests-clang-tidy when building testbins.
- drop redundant build-certs dependency for test targets.
Already present via testdeps.
Follow-up to aae361242f#20708Closes#20727
To fix building tests/server with cmake and both wolfSSL and OpenSSL
enabled (MultiSSL).
tests/server do not have libcurl dependency header paths setup because
it does not use libcurl. The code however includes `curl_setup.h`, which
tried including `wolfssl/version.h` before this patch to verify if the
wolfSSL coexist feature is available. Without a header path, it failed:
```
In file included from bld/tests/server/servers.c:3:
In file included from tests/server/first.h:40:
lib/curl_setup.h:737:12: fatal error: 'wolfssl/version.h' file not found
737 | # include <wolfssl/version.h>
| ^~~~~~~~~~~~~~~~~~~
1 error generated.
```
Ref: https://github.com/curl/curl/actions/runs/22410066319/job/64880787424#step:46:76
Fix by moving the include and version check to `vtls/wolfssl.c`.
Also: add an early version check to cmake.
Follow-up to 16f073ef49#16973
Cherry-picked from #20720Closes#20726
To allow building test binaries without test certs, replacing
`_CURL_SKIP_BUILD_CERTS` internal option with a build target that is
similar to `testdeps`, but without building the test certificates.
To make building test binaries a little bit faster, with less noisy
output, and without having to reconfigure the build.
Closes#20708
Pass system directories with `-isystem` to avoid clang-tidy parsing
3rd-party and system headers with `HeaderFilterRegex: '.*' enabled.
Also:
- drop rule exception no longer necessary.
- sync normal vs. system header path order with compiler invocation.
- tidy up `set()` syntax.
- clear a temporary variable.
Bug: https://github.com/curl/curl/pull/20670#issuecomment-3940840176
Follow-up to e088e10454#17705
Cherry-picked from: #20720Closes#20724
Prefer `sizeof()` over `strlen()`, static const variables over macros.
Add a couple of `NOLINT`s to silence false positives.
Also sync similar code patterns between libtests.
Cherry-picked from #20720Closes#20723
Tests are build in "unity"-style, by including sources into an umbrella
C files (similar to how CMake unity works). This does not play well with
clang-tidy, which seems to unconditionally ignore C sources included
like this. To fix it, curl's CMake implements a manual clang-tidy
support for tests, which compiles sources one-by-one, while also making
sure sources compile cleanly standalone (e.g. all sources need to
include `first.h`). The manual clang-tidy implementation is fragile, and
performance, in particular when targeting Windows, is abysmal.
This patch introduces an alternate solution, enabled by the
`_CURL_TESTS_CONCAT=ON` option. In this mode, umbrella sources include
the actual sources instead of `#including` them. Allowing to use CMake's
built-in clang-tidy support to compile them, with clang-tidy actually
checking the sources. Making the manual clang-tidy support unnecessary.
In the Windows CI job it results in a 4x performance improvement (4m ->
1m), making it practical to run clang-tidy on tests on Windows, in CI.
The main downside is that clang-tidy doesn't understand the `#line`
directive. Meaning issues found show the wrong filename and line number
next to them. It's not impossible to locate errors this way, but also
not convenient.
Minor/potential downside is that the concatenated source needs to be
reassembled each time an original source is updated. This may result in
more copying on the disk when used in local development. The largest
source is 1.4MB, so probably not a show-stopper on most machines.
Another is the complexity of maintaining two methods in parallel, which
may be necessary till clang-tidy understands `#line`:
https://github.com/llvm/llvm-project/issues/62405
This solution may in theory also enable adding clang-tidy support for
tests in autotools, though I haven't tried.
Targeted for curl CI for now, and used in a GHA/windows job. 100%
experimental, not recommended outside these.
Closes#20667
Reported when running `HeaderFilterRegex: '.*'` in CI.
Also replace an underscored symbol with a regular one in macro
definition.
Cherry-picked from #20720Closes#20721
- vms/curlmsg_vms.h: delete unused/commented code.
- vtls/schannel_verify: sort includes.
- typecheck-gcc.h: fix indent and alignment.
- lib/config-win32.h: drop idle `#undef`.
- spacecheck: check for stray empty lines before after curly braces.
- make literals more readable: 1048576 -> 1024 * 1024
- scope variables.
- use ISO date in a comment.
- drop redundant parentheses.
- drop empty comments.
- unfold lines.
- duplicate/stray spaces in comments.
- fix indent, whitespace, minor typos.
Closes#20690
Examples:
```
lib/vtls/openssl.c:2585:18: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
2585 | msg_type = *(const char *)buf;
lib/vtls/openssl.c:2593:18: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
2593 | msg_type = *(const char *)buf;
tests/server/mqttd.c:514:10: warning: comparison between 'signed char' and 'unsigned char' [bugprone-signed-char-misuse]
514 | if(passwd_flag == (char)(conn_flags & passwd_flag)) {
tests/server/tftpd.c:362:13: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
362 | c = test->rptr[0];
tests/server/tftpd.c:454:9: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
454 | c = *p++; /* pick up a character */
src/tool_urlglob.c:272:46: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
272 | pat->c.ascii.letter = pat->c.ascii.min = min_c;
src/tool_urlglob.c:273:24: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
273 | pat->c.ascii.max = max_c;
tests/libtest/cli_h2_pausing.c:164:23: warning: suspicious usage of 'sizeof()' on an expression of pointer type [bugprone-sizeof-expression]
164 | memset(&resolve, 0, sizeof(resolve));
tests/libtest/cli_upload_pausing.c:158:23: warning: suspicious usage of 'sizeof()' on an expression of pointer type [bugprone-sizeof-expression]
158 | memset(&resolve, 0, sizeof(resolve));
tests/libtest/first.c:86:15: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
86 | coptopt = arg[optpos];
```
Also:
- tests/server/mqttd: drop a redundant and a wrongly signed cast.
Ref: https://clang.llvm.org/extra/clang-tidy/checks/bugprone/signed-char-misuse.htmlCloses#20654
Detected by `readability-named-parameter` with `HeaderFilterRegex: '.*'`,
or `CURL_CLANG_TIDYFLAGS='--header-filter=.*'`. Seen on Windows.
Follow-up to e8415ad3c7#20657
Follow-up to c878160e9c#20624Closes#20693
Backtrack on previous change that aimed to solve the wrong `share.h`
being included. It turns out it did not fix this issue. At the same time
it introduced relative header filenames and the need to include the same
headers differently depending on the source files' location, reducing
readability and editability.
Replace this method by re-adding curl's lib source directory to the
header path and addressing headers by the their full, relative name to
that base directory. Aligning with this method already used in src and
tests.
With these advantages:
- makes includes easier to read, recognize, grep, sort, write, and copy
between sources,
- syncs the way these headers are included across curl components,
- avoids the ambiguity between system `schannel.h`, `rustls.h` vs.
local headers using the same names in `lib/vtls`,
- silences clang-tidy `readability-duplicate-include` checker, which
detects the above issue,
Ref: https://clang.llvm.org/extra/clang-tidy/checks/readability/duplicate-include.html
- possibly silences TIOBE coding standard warnings:
`6.10.2.a: Don't use relative paths in #include statements.`
- long shot: it works well with concatenated test sources, for
clang-tidy-friendly custom unity builds. Ref: #20667
Slight downside: it's not enforced.
If there happens to be a collision between a local `lib/*.h` header and
a system one, the solution is to rename (possibly with its `.c`
counterpart) into the `curl_` namespace. This is also the method used by
curl in the past.
Also:
- curlx/inet_pton: reduce scope of an include.
- toolx/tool_time: apply this to an include, and update VS project
files accordingly. Also dropping unnecessary lib/curlx header path.
- clang-tidy: enable `readability-duplicate-include`.
Follow-up to 3887069c66#19676
Follow-up to 625f2c1644#16991#16949Closes#20623
Also:
- include code to verify a C++-specific public header regression
reported in 8.19.0-rc2.
- curl/curl.h: mention C++ global namespace in comment.
- GHA/dist: add CI job for C++. Runtime: 15 seconds.
Follow-up to ee9b000438#20686
Ref: #20682Closes#20687
To avoid breaking 3rd-party code reusing these symbols as C++ methods,
e.g. in CMake sources:
```
cmake/src/v4.0.0-b30653ae0c.clean/Source/cmCurl.cxx:119:24: error: expected unqualified-id
119 | ::CURLcode res = ::curl_easy_setopt(curl, CURLOPT_CAINFO, cafile.c_str());
| ^
```
Also expand comment to highlight the case.
Reported-by: Kai Pastor
Bug: daa6b27b4d (r177869049)
Reported-by: Marcel Raad
Bug: https://curl.se/mail/lib-2026-02/0020.htmlFixes#20682
Follow-up to daa6b27b4d#20597Closes#20686
vtls/openssl.c:469:15: error: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
X509_get_X509_PUBKEY() now returns a const pointer - but only on OpenSSL
3, we must keep the non-const version for all forks.
Closes#20681
Detected by `readability-named-parameter` with `HeaderFilterRegex: '.*'`,
or `CURL_CLANG_TIDYFLAGS='--header-filter=.*'`.
Follow-up to c878160e9c#20624Closes#20657
It looks like a case that can never happen in practice.
Seen on mingw-w64 with experimental concatenated (vs. #included) test
sources:
```
tests/server/util.c:662:16: error: Null pointer passed as 1st
argument to string length function [clang-analyzer-unix.cstring.NullArg]
662 | size_t len = strlen(unix_socket);
| ^
```
Ref: https://github.com/curl/curl/actions/runs/22267482855/job/64416261156#step:10:273Closes#20668
Instead of globally disabling unity for all targets when clang-tidy is
enabled.
After this patch `CMAKE_UNITY_BUILD=ON` is honored for:
- static libcurl when building both static and shared separately.
- libcurlu and libcurltool internal libraries when building the test
target.
While keeping unity disabled for the libcurl build pass running
clang-tidy, and the curl tool, also running clang-tidy.
To make clang-tidy-enabled builds finish faster when unity mode is
enabled, yet performs the same clang-tidy checks as before this patch.
Effect on:
- GHA/macos: core build: same, buils tests 5-12 seconds faster,
with steps going down from 259 to 25.
52s: https://github.com/curl/curl/actions/runs/22279958340/job/64448913325 ->
47s: https://github.com/curl/curl/actions/runs/22279873606/job/64448710743
- GHA/windows (not enabled): it'd save about 1 minute, bringing total
time barely below 10m, still one of the slowest jobs overall.
(#20667 is trying a way for 4x speed-up (with a drawback)).
5m21s: https://github.com/curl/curl/actions/runs/22222907068/job/64284556852 ->
4m26s: https://github.com/curl/curl/actions/runs/22281033369/job/64451601548Closes#20670
On platforms that require building static and shared libcurl separately,
after this change clang-tidy is only run on one of them, to reduce build
time by avoiding the double-work. From a clang-tidy standpoint, static
and shared libs are identical.
Except `dllmain.c` on Windows, which is only present in shared. To keep
running it through clang-tidy, prefer the shared library for clang-tidy.
Closes#20675
- make sure that errors for specific options in config files identify
the file, line number and shows the error about the correct option
- improve some error message wording
- add warning for leading single quote of arguments in config files
(verified in test 1712)
- adjust test error outputs accordingly
test1712 introduces mode=warn
Use the mode="warn" attribute if the output curl warning output, as it
then makes the check without newlines and the prefix to better handle
that the lines may wrap at different points depending on the lengths of
the lines and terminal width.
Fixes#20598Closes#20666