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/1623Closes#16973
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.htmlCloses#19169
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
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#15573Closes#15800
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#15408Closes#15827
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#15193Closes#15408
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/14885Closes#15388
- `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: #14580Closes#14601