Commit Graph

22 Commits

Author SHA1 Message Date
Viktor Szakats
89043ba906
cmake: drop support for CMake 3.17 and older
Require CMake 3.18 (2020-07-15) or newer, up from 3.7 (2016-11-11)
prior to this patch.

This requirement also applies to the distributed `curl-config.cmake`.

To allow dropping compatibility code maintained for old versions, and to
use features which were unpractical in separate code paths. Also to make
testing, documentation and development easier, CI builds faster due to
CMake performance improvements over time. (e.g. integration tests on
macOS run 8x faster (10 minutes is now under 1.5m) in CI, 2.5x faster on
Windows.)

CMake offers pre-built binaries for major platforms. They work without
an install step, just by unpacking and pointing the cmake command to
them. Making upgrades easy in many cases:
https://cmake.org/download/
https://cmake.org/files/
https://github.com/Kitware/CMake/releases

CMake 3.18 brings these feature as generally available when building or
consuming curl/libcurl:

LTO support, improved performance, `pkg-config` and interface target
support, `OBJECT` target (for faster libcurl builds), modern invocation
with `-S`/`-B` options, better support for custom linker options,
FetchContent, `GnuTLS::GnuTLS` target, `--verbose` and `--install`
options, `CMAKE_GENERATOR` env, last but not least unity mode and Ninja
generator.

For maximum build speed, use:
`-DCMAKE_UNITY_BUILD=ON -DCURL_DROP_UNUSED=ON`

As for deprecations, C++11 is required to build CMake itself, which may
be a limit on some platforms. autotools continues to cover them.

Follow-up to 9bcdfb3809 #20408
Follow-up to a7c974e038 #19902
Follow-up to dfbe035c8b #10161
Discussion: https://github.com/curl/curl/discussions/18704

Closes #20407
2026-03-21 13:24:47 +01:00
Viktor Szakats
16f073ef49
cmake: define dependencies as IMPORTED interface targets
Rework the way curl's custom Find modules advertise their properties.

Before this patch, Find modules returned detected dependency properties
(header dirs, libs, libdirs, C flags, etc.) via global variables. curl's
main `CMakeLists.txt` copied their values into global lists, which it
later applied to targets. This solution worked internally, but it was
unsuited for the public, distributed `CURLConfig.cmake` and publishing
curl's Find modules with it, due to polluting the namespace of consumer
projects. It's also impractical to apply the many individual variables
to every targets depending on libcurl.

To allow using Find modules in consumer projects, this patch makes them
define as imported interface targets, named `CURL::<dependency>`. Then
store dependency information as target properties. It avoids namespace
pollution and makes the dependency information apply automatically
to all targets using `CURL::libcurl_static`.

Find modules continue to return `*_FOUND` and `*_VERSION` variables.

For dependencies detected via `pkg-config`, CMake 3.16+ is recommended.
Older CMake versions have a varying degree of support for
propagating/handling library directories. This may cause issues in envs
where dependencies reside in non-system locations and detected via
`pkg-config` (e.g. macOS + Homebrew). Use `CURL_USE_PKGCONFIG=OFF`
to fix these issues. Or upgrade to newer CMake, or link libcurl
dynamically.

Also:
- re-enable `pkg-config` for old cmake `find_library()` integration
  tests.
- make `curlinfo` build after these changes.
- distribute local Find modules.
- export the raw list of lib dependencies via `CURL_LIBRARIES_PRIVATE`.
- `CURLconfig.cmake`: use curl's Find modules to detect dependencies in
  the consumer env.
- add custom property to target property debug function.
- the curl build process no longer modifies `CMAKE_C_FLAGS`.
  Follow-up to e86542038d #17047

Ref: #14930
Ref: https://github.com/libssh2/libssh2/pull/1535
Ref: https://github.com/libssh2/libssh2/pull/1571
Ref: https://github.com/libssh2/libssh2/pull/1581
Ref: https://github.com/libssh2/libssh2/pull/1623

Closes #16973
2025-11-29 01:41:40 +01:00
Viktor Szakats
38c19edd67
cmake: say 'absolute path' in option descriptions and docs
To not have to guess. Also to sync with autotools, which already uses
this wording.

Also:
- replace the stray term 'folder' with 'directory' for consistency.
- store help text in a temp variable to avoid overly long strings
  (mandatory in CMake <4.2.0 and can't be trivially split), also
  to avoid repeating this string 4 times.

Ref: https://cmake.org/cmake/help/v4.2/command/set.html

Closes #19169
2025-10-21 15:07:36 +02:00
Viktor Szakats
2b9b3ec579
cmake/Find: set <Modulename>_FOUND for compatibility when found via pkg-config
For Find modules where `<Modulename>` is not fully uppercase.

`<Modulename>` is case-exact name used in the Find modules filename:
`CMake/Find<Moduleame>.cmake`.

`find_package_handle_standard_args()` sets both `<MODULENAME>_FOUND` and
`<Modulename>_FOUND` when detecting the dependency. Some CMake code
relies on this and 3rd-party code may rely on it too. Make sure to set
the latter variant when detecting the dependency via `pkg-config`, where
we don't call `find_package_handle_standard_args()`.

CMake sets these variable to `TRUE` (not `ON` or `1`). Replicate this
for compatibility.

Closes #16153
2025-02-07 00:07:38 +01:00
Viktor Szakats
fb1883d226
cmake: move pkg-config names to Find modules
Make the Find modules set and return their respective `pkg-config`
module name(s) to the CMake build process, which then adds those
to the `Requires:` list.

Before this patch, `pkg-config` module names were maintainted in two
separate places. After this patch, they are maintained in the Find
modules for dependencies that have one (most do).

Re-align existing modules with this change: msh3, mbedtls, rustls.
These modules return their `pkg-config` module name only when
detected via `pkg-config`.

Follow-up to d511ec8b0a #15573
Closes #15800
2024-12-26 12:59:59 +01:00
Viktor Szakats
aafc074f87
cmake: clear package version after pkg-config detection
`pkg_check_modules()` seems to leave `<PACKAGE>_VERSION` defined with an
empty value, if the package is not found.

When the package is also not found in the fallback branch,
`find_package_handle_standard_args()` logs and error message. In this
message it includes the bogus empty value as: `(found version "")`:
```
Could NOT find Libssh2 (missing: LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY) (found version "")
```
https://github.com/curl/curl/actions/runs/11509727553/job/32040378958?pr=15408#step:31:99

Clear the version number to avoid the confusion:
```
Could NOT find Libssh2 (missing: LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY)
```
https://github.com/curl/curl/actions/runs/11510022503/job/32041149129?pr=15408#step:31:99

Seen with CMake v3.30.5.

Follow-up to 7bab201abe #15193
Closes #15409
2024-10-25 15:04:35 +02:00
Viktor Szakats
f66af623cf
cmake: document -D and env build options
Extend `INSTALL-CMAKE` document with the list of available options,
a short description and default values.

The list may not be 100% complete.

There are no component boundaries in CMake, so the line is blurry
between curl options, CMake options, CMake Find modules options.
I included certain CMake options that seemed useful, and/or have
dedicated use withing curl's CMake source. But, all CMake built-in
options are usable, as documented upstream in CMake.

The naming of the options has a heritage and the inconsistencies with
it, including a lack of clear namespace. This may be subject to future
updates, also after figuring out which name has special meaning within
CMake and/or CMake projects out of unwritten convention or something
more tangible.

CMake allows to initialize any internal variable via `-D`. This may be
useful to pre-initialize/override feature check results. The list
doesn't contain these, and they remain officially undocumented.

Also:
- make adjustments to keep the spellchecker happy.
- retrofit description changes to the cmake sources.
- stop documenting deprecated `Find*` variables.

Reported-by: Daniel Stenberg
Fixes https://github.com/curl/curl/discussions/14885
Closes #15388
2024-10-24 23:06:40 +02:00
Viktor Szakats
7c0b6eb3bd
cmake: respect cflags/libdirs of native pkg-config detections
In Find modules with native pkg-config detection (libgsasl, libidn2,
libssh, libuv, nettle) use the C compiler flags returned by pkg-config.
Also use the library paths, and return the pathless library names.

Also:
- add these library paths to `libcurl.pc`/`curl-config`.
- fix libgsasl detection to use the detected header directory.

FindGSS already did this before this patch.

Fixes #14641

Closes #14652
2024-08-23 10:43:43 +02:00
Viktor Szakats
0c37894611
cmake: pkg-config 'found' message sync with native CMake
Cherry-picked from #14610
2024-08-23 00:11:23 +02:00
Viktor Szakats
3a2e47afb7
cmake: fix Find module and package names
- fix BearSSL warning about name mismatch.
- fix Nettle Find module not found on Linux.
- tidy-up: drop quotes from a package name.

Package names must match case-sensitively to work on all platforms:
- `find_package(<NAME> ...)` in `CMakeLists.txt`.
- `CMake/Find<NAME>.cmake` filenames.
- `find_package_handle_standard_args(<NAME> ...` in Find modules.
- `message(STATUS "Found <NAME> ...` in Find modules.
  (to match the message shown by `find_package_handle_standard_args()`)

Closes #14599
2024-08-20 00:44:43 +02:00
Viktor Szakats
c2e814f8d7
cmake/FindNettle: log message when found via pkg-config
The message mimics the CMake-native message (by
`find_package_handle_standard_args()`), with the header path and version number.

Closes #14596
2024-08-19 14:09:14 +02:00
Viktor Szakats
47849be5d5
cmake/FindNettle: skip pkg-config for custom configs
If either `NETTLE_INCLUDE_DIR` or `NETTLE_LIBRARY` is set to customize
the `nettle` dependency, skip `pkg-config` and use the CMake-native
detection to honor these custom settings.

Closes #14584
2024-08-19 14:09:14 +02:00
Viktor Szakats
3e60f174ee
cmake: tidy up more in Find modules
- add `NAMES` where missing.
- document input variables (including deprecated ones.)
- comment cleanups.
- FindWolfSSL: drop stray `QUIET` from `pkg_check_modules()`.
  (`QUIET` may be re-added for all modules in the future.)

Closes #14579
2024-08-18 22:53:09 +02:00
Viktor Szakats
432f2fd9ac
cmake: sync up version detection in Find modules
- use the same pattern across all Find modules:
  - verify if the version header exists before reading it.
  - use a single regex per lookup.
  - sync regexes between Find modules.
  - use generic temporary variable names.
  - improve readability.
  - make it simpler to transition to new CMake syntax in the future:
    ```cmake
    file(STRINGS "${CARES_INCLUDE_DIR}/ares_version.h" _version_str REGEX "<...>")
    unset(_version_str)
    set(CARES_VERSION "${CMAKE_MATCH_1}")
    ```
    Ref: https://cmake.org/cmake/help/latest/policy/CMP0159.html#policy:CMP0159

- fix zstd version detection to be CMake 3.7 compatible.
  Required 3.9 before this patch, for the `CMAKE_MATCH_<n>` feature.
  Follow-up to c5d506e9bb #12200

Follow-up to 4e2f3641f8 #14548

Closes #14572
2024-08-17 10:33:26 +02:00
Viktor Szakats
f3a03df6a1
cmake: revert to pkg_check_modules()
Prefer `pkg_check_modules()` over `pkg_search_module()`.

`pkg_check_modules()` logs a line when there is a hit, and also warnings
if a sub-dependency is missing. In `QUIET` mode, both are silent.

The extra info is useful to see if a detection happened via
`pkg-config`.

Keep `pkg_search_module()` in `FindGSS`. We pass two dependencies
there and we want to keep stopping on the first one.

Partially reverts c2889a7b41 #14388

Closes #14573
2024-08-17 00:31:52 +02:00
Viktor Szakats
8ae7049f4b
cmake: sync up formatting in Find modules
- lowercase internal variable names (FindGSS)
- comments
- whitespace

Closes #14527
2024-08-14 01:44:16 +02:00
Viktor Szakats
b910122fe3
cmake: add CURL_USE_PKGCONFIG option
Add option to control whether to use `pkg-config` to detect
dependencies. Curl's CMake uses `pkg-config` by default for all targets
except for MSVC without vcpkg.

With the CMake option `-DCURL_USE_PKGCONFIG=ON` you can override it to
use `pkg-config` always.

If `pkg-config` is causing issues, e.g. in cross-builds or other cases,
`-DCURL_USE_PKGCONFIG=OFF` disables all use of `pkg-config`.

Also add it to `curl-config.cmake`. Not yet used, but will be once curl
starts referencing any curl-specific `Find*` module from this public
script.

Follow-up to 9dfdc6ff42 #14483
Closes #14504
2024-08-13 09:28:27 +02:00
Viktor Szakats
9dfdc6ff42
cmake: allow pkg-config in more envs
Before this patch, `pkg-config` was used for `UNIX` builds only (with
a few exceptions like wolfSSL, libssh, gsasl, libuv). This patch extends
`pkg-config` use to all envs except: `MSVC` without vcpkg. Meaning MSVC
with vcpkg will now use it. Also mingw on Windows.

Also apply the new condition to options where `pkg-config` was used
unconditionally (= for all targets). These are:
`-DCURL_USE_WOLFSSL=ON`, `-DCURL_USE_LIBSSH=ON`,
`-DCURL_USE_GSASL=ON` and `-DCURL_USE_LIBUV=ON`

This patch may still cause regressions for cross-builds (e.g. mingw
cross-build from Unix) and potentially other cases. If that happens, we
recommend using some of these methods to explicitly disable `pkg-config`
when using CMake:
- CMake option: `-DPKG_CONFIG_EXECUTABLE=`
  (or `-DPKG_CONFIG_EXECUTABLE=nonexistent` or similar)
  This is similar to the (curl-specific) `PKG_CONFIG` env for autotools.
- export env: `PKG_CONFIG_LIBDIR=`
  (or `PKG_CONFIG_PATH`, `PKG_CONFIG_SYSROOT_DIR`,
  or the CMake-specific `PKG_CONFIG`)

We may improve control over this in a future patch, also allowing opting
in MSVC (without vcpkg).

Ref: #14405
Ref: #14408
Ref: #14140
Closes #14483
2024-08-12 14:57:10 +02:00
Viktor Szakats
c2889a7b41
cmake: more syntax tidy-up
- quote string literals.
  In the hope it improves syntax-highlighting and readability.

- use lowercase, underscore-prefixed local var names.
  As a hint for scope, to help readability.

- prefer `pkg_search_module` (over `pkg_check_modules`).
  They are the same, but `pkg_search_module` stops searching
  at the first hit.

- more `IN LISTS` in `foreach()`.

- OtherTests.cmake: clear `CMAKE_EXTRA_INCLUDE_FILES` after use.

- add `PROJECT_LABEL` for http/client and unit test targets.

- sync `Find*` module comments and formatting.

- drop a few local variables.

- drop bogus `CARES_LIBRARIES` from comment.

- unquote numeric literal.

Follow-up to acbc6b703f #14197
Closes #14388
2024-08-07 23:41:27 +02:00
Viktor Szakats
acbc6b703f
cmake: tidy-ups
- tidy-up comments.
- use lowercase, underscore prefixed names for internal variables.
- use `IN LISTS` and `IN ITEMS` in `foreach()` loops.
- rename variable name `OUTPUT` to a more distinctive one.
- tidy-up `STREQUAL` syntax.
- delete commented code.
- indent/whitespace.

Closes #14197
2024-08-03 20:49:15 +02:00
Viktor Szakats
b92ead34dd
cmake: drop if(PKG_CONFIG_FOUND) guard for pkg_check_modules()
The oldest cmake supported by curl is v3.7.0, which already has such
guard (using `PKG_CONFIG_EXECUTABLE`) inside `pkg_check_modules()`. The
advantage of leaving that guard to CMake is that it will define/reset
all output variables, while the manual guard doesn't do this and also
leaves for example `NETTLE_FOUND` undefined.

Delete the single use of this guard from the recently added `nettle`
detection, where I included it by accident. Then possibly re-introduce
it universally if we find it useful after more evaluation.

Follow-up to 669ce42275 #14285
Closes #14309
2024-07-30 14:33:50 +02:00
Viktor Szakats
669ce42275
cmake: detect nettle when building with GnuTLS
`nettle` is a direct dependency of curl, when building with GnuTLS.
Add a new `Find` module to detect it.

Also:
- GHA/macos: drop `nettle` hack no longer necessary.
- add `nettle` to `libcurl.pc`.
- also add `nettle` to `libcurl.pc` in autotools builds.

Follow-up to 781242ffa4 #11967
Closes #14285
2024-07-29 20:41:39 +02:00