8 Commits

Author SHA1 Message Date
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
98f419172b cmake/FindLibpsl: protect against pkg-config "half-detection"
Same issue as seen before with libssh2: `libpsl`'s pkg-config module
depends on another module, but that's not found. CMake ends up reporting
`LIBPSL_FOUND=YES`, while leaving `LIBPSL_INCLUDE_DIRS` empty. Then
the build fails to find `psl.h`.

The missing dependency in this case is `icu4c`, which is "keg-only",
meaning it's not exposed in the default Homebrew header, pkg-config,
lib, etc locations. It must be added to the `PKG_CONFIG_PATH` env, as
suggested by the warnings messages of `pkgconf`.

To avoid this fallout, let's ensure that `LIBPSL_INCLUDE_DIRS` is
non-empty when detecting via `pkg-config` and fall back to the CMake
detection method otherwise.

This was an issue till Homebrew libpsl 0.21.5_1, fixed in 0.21.5_2, that
no longer depends on `icu4c`.

Example log:
```
-- Checking for module 'libpsl'
--   Found libpsl, version 0.21.5
Package icu-uc was not found in the pkg-config search path.
Perhaps you should add the directory containing `icu-uc.pc'
to the PKG_CONFIG_PATH environment variable
Package 'icu-uc', required by 'libpsl', not found
[...]
-- Found Libpsl (via pkg-config):  (found version "0.21.5")
[...]
In file included from curl/_bld/lib/CMakeFiles/libcurl_static.dir/Unity/unity_0_c.c:4:
In file included from curl/lib/altsvc.c:32:
In file included from curl/lib/urldata.h:145:
curl/lib/psl.h:28:10: fatal error: 'libpsl.h' file not found
         ^~~~~~~~~~
1 error generated.
```

Follow-up to 39c741b7b0 #15408
Closes #15827
2024-12-25 21:46:55 +01:00
Viktor Szakats
39c741b7b0 cmake: add native pkg-config detection for remaining Find modules
brotli, c-ares, libpsl, libssh2, nghttp2, nghttp3, ntgcp2, zstd.

Also:

Add workaround for CMake reporting successful libssh2 detection, but
leaving the header directory empty, and causing `libssh2.h` not found
while compiling. It happens when `pkgconf` is not detecting libssh2
dependency libcrypto in Homebrew after `brew unlink openssl` (as in
GHA/macos). The workaround is to require a non-empty header directory
to consider the detection successful. This workaround may need to be
tweaked and/or applied to other Find modules.

Follow-up to 7bab201abe #15193

Closes #15408
2024-12-17 02:30:55 +01: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
211cbcb4f6 cmake: rename Find modules
- `FindCARES`   -> `FindCares`
- `FindLibPSL`  -> `FindLibpsl`
- `FindLibSSH2` -> `FindLibssh2`
- `FindQUICHE`  -> `FindQuiche`
- `Findrustls`  -> `FindRustls`

Our convention for naming Find modules (the part after the `Find`
prefix, also called as 'package name') is:

Always start with uppercase. Follow with lowercase, unless there is
a clear preference for a stylized name. E.g. the project itself uses it
that way with a matching `<Name>Config.cmake` file, or we use it that
way elsewhere, or the name is an acronym.

Ref: #14580

Closes #14601
2024-08-20 00:50:10 +02:00