Merge topic 'enum_set-enhancements'
4d48958965 enum_set enhancements, step 3
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !10335
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 124bf7e..82d0968 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -439,9 +439,9 @@
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
-t:hip5.5-nvidia:
+t:hip6.3-nvidia:
extends:
- - .hip5.5_nvidia
+ - .hip6.3_nvidia
- .cmake_test_linux_release
- .linux_x86_64_tags_cuda
- .run_dependent
@@ -449,9 +449,9 @@
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
-t:hip5.5-radeon:
+t:hip6.3-radeon:
extends:
- - .hip5.5_radeon
+ - .hip6.3_radeon
- .cmake_test_linux_release
- .linux_x86_64_tags_radeon
- .run_dependent
diff --git a/.gitlab/ci/configure_hip5.5_nvidia.cmake b/.gitlab/ci/configure_hip6.3_nvidia.cmake
similarity index 100%
rename from .gitlab/ci/configure_hip5.5_nvidia.cmake
rename to .gitlab/ci/configure_hip6.3_nvidia.cmake
diff --git a/.gitlab/ci/configure_hip5.5_radeon.cmake b/.gitlab/ci/configure_hip6.3_radeon.cmake
similarity index 100%
rename from .gitlab/ci/configure_hip5.5_radeon.cmake
rename to .gitlab/ci/configure_hip6.3_radeon.cmake
diff --git a/.gitlab/ci/docker/hip5.5/deps_packages.lst b/.gitlab/ci/docker/hip5.5/deps_packages.lst
deleted file mode 100644
index 3276055..0000000
--- a/.gitlab/ci/docker/hip5.5/deps_packages.lst
+++ /dev/null
@@ -1,21 +0,0 @@
-# Install development tools.
-g++
-curl
-git
-
-# NVIDIA CUDA Compiler
-cuda-keyring
-cuda-nvcc-11-8
-cuda-profiler-api-11-8
-
-# NVIDIA CUDA Toolkit
-# These are not needed for HIP, but having them in
-# the environment allows us to run CUDA tests too.
-cuda-nvrtc-dev-11-8
-cuda-nvtx-11-8
-libcublas-dev-11-8
-libcufft-dev-11-8
-libcurand-dev-11-8
-libcusolver-dev-11-8
-libcusparse-dev-11-8
-libnpp-dev-11-8
diff --git a/.gitlab/ci/docker/hip5.5/Dockerfile b/.gitlab/ci/docker/hip6.3/Dockerfile
similarity index 92%
rename from .gitlab/ci/docker/hip5.5/Dockerfile
rename to .gitlab/ci/docker/hip6.3/Dockerfile
index 3a4aa53..a9f8303 100644
--- a/.gitlab/ci/docker/hip5.5/Dockerfile
+++ b/.gitlab/ci/docker/hip6.3/Dockerfile
@@ -1,9 +1,9 @@
# syntax=docker/dockerfile:1
-ARG BASE_IMAGE=rocm/dev-ubuntu-22.04:5.5
+ARG BASE_IMAGE=rocm/dev-ubuntu-24.04:6.3.2
FROM ${BASE_IMAGE} AS cuda-keyring
-ADD https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb /root/
+ADD https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-keyring_1.1-1_all.deb /root/
RUN --mount=type=tmpfs,target=/var/log \
dpkg -i /root/cuda-keyring_1.1-1_all.deb \
&& rm /root/cuda-keyring_1.1-1_all.deb
@@ -22,7 +22,7 @@
MAINTAINER Brad King <brad.king@kitware.com>
ENV NVIDIA_DRIVER_CAPABILITIES=compute,utility
-ENV NVIDIA_REQUIRE_CUDA=cuda>=11.8
+ENV NVIDIA_REQUIRE_CUDA=cuda>=12.6
ENV NVIDIA_VISIBLE_DEVICES=all
ENV PATH="/opt/rocm/bin:$PATH"
diff --git a/.gitlab/ci/docker/hip6.3/deps_packages.lst b/.gitlab/ci/docker/hip6.3/deps_packages.lst
new file mode 100644
index 0000000..2ecf81e
--- /dev/null
+++ b/.gitlab/ci/docker/hip6.3/deps_packages.lst
@@ -0,0 +1,23 @@
+# Install development tools.
+g++
+curl
+git
+
+# NVIDIA CUDA Compiler
+cuda-keyring
+cuda-nvcc-12-6
+cuda-profiler-api-12-6
+
+# NVIDIA CUDA Toolkit
+# These are not needed for HIP, but having them in
+# the environment allows us to run CUDA tests too.
+cuda-nvrtc-dev-12-6
+cuda-nvtx-12-6
+cuda-opencl-dev-12-6
+libcublas-dev-12-6
+libcufft-dev-12-6
+libcurand-dev-12-6
+libcusolver-dev-12-6
+libcusparse-dev-12-6
+libnpp-dev-12-6
+libnvjitlink-dev-12-6
diff --git a/.gitlab/ci/docker/hip5.5/docker-clean b/.gitlab/ci/docker/hip6.3/docker-clean
similarity index 100%
rename from .gitlab/ci/docker/hip5.5/docker-clean
rename to .gitlab/ci/docker/hip6.3/docker-clean
diff --git a/.gitlab/ci/docker/hip5.5/dpkg-exclude b/.gitlab/ci/docker/hip6.3/dpkg-exclude
similarity index 100%
rename from .gitlab/ci/docker/hip5.5/dpkg-exclude
rename to .gitlab/ci/docker/hip6.3/dpkg-exclude
diff --git a/.gitlab/ci/docker/hip5.5/install_deps.sh b/.gitlab/ci/docker/hip6.3/install_deps.sh
similarity index 100%
rename from .gitlab/ci/docker/hip5.5/install_deps.sh
rename to .gitlab/ci/docker/hip6.3/install_deps.sh
diff --git a/.gitlab/ci/env_hip5.5_nvidia.sh b/.gitlab/ci/env_hip5.5_nvidia.sh
deleted file mode 100644
index 67d1ef2..0000000
--- a/.gitlab/ci/env_hip5.5_nvidia.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-export HIP_PLATFORM=nvidia
-export CUDA_PATH=/usr/local/cuda-11.8
-export PATH=/usr/local/cuda-11.8/bin:$PATH
-export LD_LIBRARY_PATH=/usr/local/cuda-11.8/lib64
diff --git a/.gitlab/ci/env_hip6.3_nvidia.sh b/.gitlab/ci/env_hip6.3_nvidia.sh
new file mode 100644
index 0000000..3b326cb
--- /dev/null
+++ b/.gitlab/ci/env_hip6.3_nvidia.sh
@@ -0,0 +1,4 @@
+export HIP_PLATFORM=nvidia
+export CUDA_PATH=/usr/local/cuda-12.6
+export PATH=/usr/local/cuda-12.6/bin:$PATH
+export LD_LIBRARY_PATH=/usr/local/cuda-12.6/lib64
diff --git a/.gitlab/ci/typos.bash b/.gitlab/ci/typos.bash
index 7293a03..4c92383 100755
--- a/.gitlab/ci/typos.bash
+++ b/.gitlab/ci/typos.bash
@@ -7,8 +7,17 @@
echo "Running 'typos' on source code..."
typos || result=1
-# FIXME(typos): checking commit messages hits false positives
-# on "words" inside commit hashes. We'd need a way to disable
-# checking of combined identifiers to avoid this.
+cfg='.typos.toml'
+tmp_cfg="${TEMP:-/tmp}/$cfg"
+# Uncomment `extend-ignore-identifiers-re` in the top-level config file
+# to make Git hashes (possibly used in commit messages) valid "identifiers".
+sed 's/^#\s*\(extend-ignore-identifiers-re\)/\1/' "$cfg" >"$tmp_cfg"
+
+if [ -n "$CI_MERGE_REQUEST_DIFF_BASE_SHA" ]; then
+ for COMMIT in $(git rev-list "^$CI_MERGE_REQUEST_DIFF_BASE_SHA" "$CI_COMMIT_SHA"); do
+ echo "Running 'typos' on commit message of $COMMIT..."
+ git show --format=%B -s "$COMMIT" | typos -c "$tmp_cfg" - || result=1
+ done
+fi
exit $result
diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml
index eacacad..461b34e 100644
--- a/.gitlab/os-linux.yml
+++ b/.gitlab/os-linux.yml
@@ -434,19 +434,21 @@
### HIP builds
-.hip5.5:
- image: "kitware/cmake:ci-hip5.5-x86_64-2023-09-18"
+.hip6.3:
+ image: "kitware/cmake:ci-hip6.3-x86_64-2025-02-14"
variables:
GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
CMAKE_ARCH: x86_64
CTEST_LABELS: "HIP"
-.hip5.5_radeon:
- extends: .hip5.5
+.hip6.3_radeon:
+ extends: .hip6.3
variables:
- CMAKE_CONFIGURATION: hip5.5_radeon
+ # FIXME(rocclr): device modules fail loading from binaries in paths with spaces
+ GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake-ci"
+ CMAKE_CONFIGURATION: hip6.3_radeon
CMAKE_GENERATOR: "Ninja Multi-Config"
.debian12_hip_radeon:
@@ -463,11 +465,11 @@
CMAKE_CONFIGURATION: fedora41_hip_radeon
CTEST_LABELS: "HIP"
-.hip5.5_nvidia:
- extends: .hip5.5
+.hip6.3_nvidia:
+ extends: .hip6.3
variables:
- CMAKE_CONFIGURATION: hip5.5_nvidia
+ CMAKE_CONFIGURATION: hip6.3_nvidia
CTEST_LABELS: "HIP"
### C++ modules
diff --git a/.gitlab/os-windows.yml b/.gitlab/os-windows.yml
index d19dd74..d024f41 100644
--- a/.gitlab/os-windows.yml
+++ b/.gitlab/os-windows.yml
@@ -35,25 +35,25 @@
variables:
VCVARSALL: "${VS170COMNTOOLS}\\..\\..\\VC\\Auxiliary\\Build\\vcvarsall.bat"
VCVARSPLATFORM: "x64"
- VCVARSVERSION: "14.42.34433"
+ VCVARSVERSION: "14.43.34808"
.windows_vcvarsall_vs2022_x86:
variables:
VCVARSALL: "${VS170COMNTOOLS}\\..\\..\\VC\\Auxiliary\\Build\\vcvarsall.bat"
VCVARSPLATFORM: "x86"
- VCVARSVERSION: "14.42.34433"
+ VCVARSVERSION: "14.43.34808"
.windows_vcvarsall_vs2022_x64_arm64:
variables:
VCVARSALL: "${VS170COMNTOOLS}\\..\\..\\VC\\Auxiliary\\Build\\vcvarsall.bat"
VCVARSPLATFORM: "x64_arm64"
- VCVARSVERSION: "14.42.34433"
+ VCVARSVERSION: "14.43.34808"
.windows_arm64_vcvarsall_vs2022:
variables:
VCVARSALL: "${VS170COMNTOOLS}\\..\\..\\VC\\Auxiliary\\Build\\vcvarsall.bat"
VCVARSPLATFORM: "arm64"
- VCVARSVERSION: "14.42.34433"
+ VCVARSVERSION: "14.43.34808"
.windows_vs2022_x64_pch:
extends:
@@ -119,7 +119,7 @@
CMAKE_CONFIGURATION: windows_vs2022_x64
CMAKE_GENERATOR: "Visual Studio 17 2022"
CMAKE_GENERATOR_PLATFORM: "x64"
- CMAKE_GENERATOR_TOOLSET: "v143,version=14.42.34433"
+ CMAKE_GENERATOR_TOOLSET: "v143,version=14.43.34808"
CMAKE_CI_NIGHTLY_IGNORE_DEPS: "true"
.windows_vs2019_x64:
@@ -282,7 +282,7 @@
CMAKE_CONFIGURATION: windows_arm64_vs2022
CMAKE_GENERATOR: "Visual Studio 17 2022"
CMAKE_GENERATOR_PLATFORM: "ARM64"
- CMAKE_GENERATOR_TOOLSET: "v143,version=14.42.34433"
+ CMAKE_GENERATOR_TOOLSET: "v143,version=14.43.34808"
CMAKE_CI_NIGHTLY_IGNORE_DEPS: "true"
.mingw_osdn_io:
@@ -316,7 +316,7 @@
- windows-x86_64
- shell
- vs2022
- - msvc-14.42
+ - msvc-14.43
- nonconcurrent
.windows_x86_64_tags_nonconcurrent_vs2022_arm64:
@@ -325,7 +325,7 @@
- windows-x86_64
- shell
- vs2022
- - msvc-14.42-arm64
+ - msvc-14.43-arm64
- nonconcurrent
.windows_x86_64_tags_concurrent_vs2022:
@@ -334,7 +334,7 @@
- windows-x86_64
- shell
- vs2022
- - msvc-14.42
+ - msvc-14.43
- concurrent
.windows_x86_64_tags_concurrent_vs2022_android:
@@ -344,7 +344,7 @@
- shell
- vs2022
- vs17-android
- - msvc-14.42
+ - msvc-14.43
- concurrent
.windows_x86_64_tags_concurrent_vs2019_android:
@@ -370,7 +370,7 @@
- windows-arm64
- shell
- vs2022
- - msvc-14.42
+ - msvc-14.43
- nonconcurrent
.windows_arm64_tags_concurrent_vs2022:
@@ -379,7 +379,7 @@
- windows-arm64
- shell
- vs2022
- - msvc-14.42
+ - msvc-14.43
- concurrent
## Windows-specific scripts
diff --git a/.typos.toml b/.typos.toml
index c494769..c06745a 100644
--- a/.typos.toml
+++ b/.typos.toml
@@ -11,6 +11,11 @@
, "(?Rm)^.*(#|/(/|\\*)|\\.\\.)\\s*(NOQA|noqa):? spellcheck(: *|=| +)disable-line$"
]
locale = "en-us"
+# ATTENTION If, for any reason, you want to add the
+# `extend-ignore-identifiers-re` to this section,
+# please also modify the `.gitlab/ci/typos.bash`
+# script accordingly.
+#extend-ignore-identifiers-re=["\\b[0-9a-f]{10}\\b"]
# Add repo-wide false positives here in the form of `word = "word"`.
# Check the manual for details.
diff --git a/Help/command/POLICY_VERSION.txt b/Help/command/POLICY_VERSION.txt
new file mode 100644
index 0000000..424849d
--- /dev/null
+++ b/Help/command/POLICY_VERSION.txt
@@ -0,0 +1,16 @@
+This specifies that the current CMake code is written for the given range of
+CMake versions, ``<min>[...<max>]``. It sets the "policy version" to:
+
+* the range's ``<max>`` version, if specified, or to
+* the ``<min>`` version, or to
+* the value of the :variable:`CMAKE_POLICY_VERSION_MINIMUM` variable
+ if it is higher than the other two versions.
+
+The policy version effectively requests behavior preferred as of a given CMake
+version and tells newer CMake versions to warn about their new policies.
+All policies known to the running version of CMake and introduced
+in that version or earlier will be set to use ``NEW`` behavior.
+All policies introduced in later versions will be unset (unless the
+:variable:`CMAKE_POLICY_DEFAULT_CMP<NNNN>` variable sets a default).
+This effectively requests behavior preferred as of a given CMake
+version and tells newer CMake versions to warn about their new policies.
diff --git a/Help/command/cmake_minimum_required.rst b/Help/command/cmake_minimum_required.rst
index 2833ed7..47e8e6b 100644
--- a/Help/command/cmake_minimum_required.rst
+++ b/Help/command/cmake_minimum_required.rst
@@ -19,7 +19,7 @@
If the running version of CMake is lower than the ``<min>`` required
version it will stop processing the project and report an error.
The optional ``<policy_max>`` version, if specified, must be at least the
-``<min>`` version and affects policy settings as described in `Policy Settings`_.
+``<min>`` version and sets the `Policy Version`_.
If the running version of CMake is older than 3.12, the extra ``...``
dots will be seen as version component separators, resulting in the
``...<max>`` part being ignored and preserving the pre-3.12 behavior
@@ -48,38 +48,18 @@
calling scope, calling ``cmake_minimum_required()`` inside a function
is generally discouraged.
-.. _`Policy Settings`:
+.. _`Policy Version`:
-Policy Settings
-^^^^^^^^^^^^^^^
+Policy Version
+^^^^^^^^^^^^^^
-The ``cmake_minimum_required(VERSION)`` command implicitly invokes the
-:command:`cmake_policy(VERSION)` command to specify that the current
-project code is written for the given range of CMake versions.
-All policies known to the running version of CMake and introduced
-in the ``<min>`` (or ``<max>``, if specified) version or earlier will
-be set to use ``NEW`` behavior. All policies introduced in later
-versions will be unset (unless the
-:variable:`CMAKE_POLICY_DEFAULT_CMP<NNNN>` variable sets a default).
-This effectively requests behavior preferred as of a given CMake
-version and tells newer CMake versions to warn about their new policies.
-
-When a ``<min>`` version higher than 2.4 is specified the command
-implicitly invokes
+``cmake_minimum_required(VERSION <min>[...<max>])`` implicitly invokes
.. code-block:: cmake
cmake_policy(VERSION <min>[...<max>])
-which sets CMake policies based on the range of versions specified.
-When a ``<min>`` version 2.4 or lower is given the command implicitly
-invokes
-
-.. code-block:: cmake
-
- cmake_policy(VERSION 2.4[...<max>])
-
-which enables compatibility features for CMake 2.4 and lower.
+.. include:: POLICY_VERSION.txt
.. include:: DEPRECATED_POLICY_VERSIONS.txt
diff --git a/Help/command/cmake_policy.rst b/Help/command/cmake_policy.rst
index 4a08c01..276e160 100644
--- a/Help/command/cmake_policy.rst
+++ b/Help/command/cmake_policy.rst
@@ -39,14 +39,7 @@
component separators, resulting in the ``...<max>`` part being ignored and
preserving the pre-3.12 behavior of basing policies on ``<min>``.
-This specifies that the current CMake code is written for the given
-range of CMake versions. All policies known to the running version of CMake
-and introduced in the ``<min>`` (or ``<max>``, if specified) version
-or earlier will be set to use ``NEW`` behavior. All policies
-introduced in later versions will be unset (unless the
-:variable:`CMAKE_POLICY_DEFAULT_CMP<NNNN>` variable sets a default).
-This effectively requests behavior preferred as of a given CMake
-version and tells newer CMake versions to warn about their new policies.
+.. include:: POLICY_VERSION.txt
Note that the :command:`cmake_minimum_required(VERSION)`
command implicitly calls ``cmake_policy(VERSION)`` too.
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index 1b6a555..cae7150 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -79,18 +79,14 @@
version files are used).
.. note::
-
If the experimental ``CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES`` is enabled,
files named ``<PackageName>.cps`` and ``<lowercasePackageName>.cps`` are
also considered. These files provide package information according to the
|CPS|_ (CPS), which is more portable than CMake script. Aside from any
explicitly noted exceptions, any references to "config files", "config
mode", "package configuration files", and so forth refer equally to both
- CPS and CMake-script files. However, some features of ``find_package``
- are not supported at this time when a CPS file is found. In particular,
- if a ``VERSION`` requirement is specified, only ``.cps`` files which do not
- provide version information will be rejected. (We expect to implement
- proper version validation in the near future.)
+ CPS and CMake-script files. This functionality is a work in progress, and
+ some features may be missing.
Search is implemented in a manner that will tend to prefer |CPS| files
over CMake-script config files in most cases. Specifying ``CONFIGS``
@@ -211,15 +207,20 @@
* A single version with the format ``major[.minor[.patch[.tweak]]]``, where
each component is a numeric value.
* A version range with the format ``versionMin...[<]versionMax`` where
- ``versionMin`` and ``versionMax`` have the same format and constraints
- on components being integers as the single version. By default, both end
- points are included. By specifying ``<``, the upper end point will be
- excluded. Version ranges are only supported with CMake 3.19 or later.
- Note that it is not possible to extend the compatibility range specified
- by the package's version file. For example, if the package version file
- specifies compatibility within a minor version, it is not possible to
- extend the compatibility to several minor versions by specifying a
- version range.
+ ``versionMin`` and ``versionMax`` have the same format and constraints on
+ components being integers as the single version. By default, both end points
+ are included. By specifying ``<``, the upper end point will be excluded.
+ Version ranges are only supported with CMake 3.19 or later.
+
+.. note::
+ With the exception of CPS packages, version support is currently provided
+ only on a package-by-package basis. When a version range is specified but
+ the package is only designed to expect a single version, the package will
+ ignore the upper end point of the range and only take the single version at
+ the lower end of the range into account. Non-CPS packages that do support
+ version ranges do so in a manner that is determined by the individual
+ package. See the `Version Selection`_ section below for details and
+ important caveats.
The ``EXACT`` option requests that the version be matched exactly. This option
is incompatible with the specification of a version range.
@@ -227,11 +228,7 @@
If no ``[version]`` and/or component list is given to a recursive invocation
inside a find-module, the corresponding arguments are forwarded
automatically from the outer call (including the ``EXACT`` flag for
-``[version]``). Version support is currently provided only on a
-package-by-package basis (see the `Version Selection`_ section below).
-When a version range is specified but the package is only designed to expect
-a single version, the package will ignore the upper end point of the range and
-only take the single version at the lower end of the range into account.
+``[version]``).
See the :command:`cmake_policy` command documentation for discussion
of the ``NO_POLICY_SCOPE`` option.
@@ -749,7 +746,7 @@
These variables are checked by the ``find_package`` command to determine
whether the configuration file provides an acceptable version. They
are not available after the ``find_package`` call returns. If the version
-is acceptable the following variables are set:
+is acceptable, the following variables are set:
``<PackageName>_VERSION``
Full provided version string
@@ -766,12 +763,80 @@
and the corresponding package configuration file is loaded.
+.. note::
+ While the exact behavior of version matching is determined by the individual
+ package, many packages use :command:`write_basic_package_version_file` to
+ supply this logic. The version check scripts this produces have some notable
+ caveats with respect to version ranges:
+
+ * The upper end of a version range acts as a hard limit on what versions will
+ be accepted. Thus, while a request for version ``1.4.0`` might be
+ satisfied by a package whose version is ``1.6.0`` and which advertises
+ 'same major version' compatibility, the same package will be rejected if
+ the requested version range is ``1.4.0...1.5.0``.
+
+ * Both ends of the version range must match the package's advertised
+ compatibility level. For example, if a package advertises 'same major and
+ minor version' compatibility, requesting the version range
+ ``1.4.0...<1.5.5`` or ``1.4.0...1.5.0`` will result in that package being
+ rejected, even if the package version is ``1.4.1``.
+
+ As a result, it is not possible to use a version range to extend the range
+ of compatible package versions that will be accepted.
+
|CPS|
"""""
-For |CPS| package configuration files, no version checking is performed at
-this time. However, packages using the ``simple`` version schema will set
-the following variables:
+For |CPS| package configuration files, package version numbers are checked by
+CMake according to the set of recognized version schemas. At present, the
+following schemas are recognized:
+
+ ``simple``
+ Version numbers are a tuple of integers followed by an optional trailing
+ segment which is ignored with respect to version comparisons.
+
+ ``custom``
+ The mechanism for interpreting version numbers is unspecified. The version
+ strings must match exactly for the package to be accepted.
+
+Refer to |cps-version_schema|_ for a more detailed explanation of each schema
+and how comparisons for each are performed. Note that the specification may
+include schemas that are not supported by CMake.
+
+In addition to the package's ``version``, CPS allows packages to optionally
+specify a |cps-compat_version|_, which is the oldest version for which the
+package provides compatibility. That is, the package warrants that a consumer
+expecting the ``compat_version`` should be able to use the package, even if the
+package's actual version is newer. If not specified, the ``compat_version``
+is implicitly equal to the package version, i.e. no backwards compatibility is
+provided.
+
+When a package uses a recognized schema, CMake will determine the package's
+acceptability according to the following rules:
+
+* If ``EXACT`` was specified, or if the package does not supply a
+ ``compat_version``, the package's ``version`` must equal the requested
+ version.
+
+* Otherwise:
+
+ * The package's ``version`` must be greater than or equal to the requested
+ (minimum) version, and
+
+ * the package's ``compat_version`` must be less than or equal to the
+ requested (minimum) version, and
+
+ * if a requested maximum version was given, it must be greater than (or equal
+ to, depending on whether the maximum version is specified as inclusive or
+ exclusive) the package's ``version``.
+
+.. note::
+ This implementation of range matching was chosen in order to most closely
+ match the behavior of :command:`write_basic_package_version_file`, albeit
+ without the case where an overly broad range matches nothing.
+
+For packages using the ``simple`` version schema, if the version is acceptable,
+the following variables are set:
``<PackageName>_VERSION``
Full provided version string
@@ -878,3 +943,9 @@
.. _CPS: https://cps-org.github.io/cps/
.. |CPS| replace:: Common Package Specification
+
+.. _cps-compat_version: https://cps-org.github.io/cps/schema.html#compat-version
+.. |cps-compat_version| replace:: ``compat_version``
+
+.. _cps-version_schema: https://cps-org.github.io/cps/schema.html#version-schema
+.. |cps-version_schema| replace:: ``version_schema``
diff --git a/Help/command/list.rst b/Help/command/list.rst
index 0110021..abae8d2 100644
--- a/Help/command/list.rst
+++ b/Help/command/list.rst
@@ -246,6 +246,11 @@
<replace_expression> ...)
:target: TRANSFORM_REPLACE
+ .. versionchanged:: 4.1
+ The ``^`` anchor now matches only at the beginning of the input
+ element instead of the beginning of each repeated search.
+ See policy :policy:`CMP0186`.
+
``<SELECTOR>`` determines which elements of the list will be transformed.
Only one type of selector can be specified at a time.
When given, ``<SELECTOR>`` must be one of the following:
diff --git a/Help/command/string.rst b/Help/command/string.rst
index e9de32e..c510ff4 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -117,6 +117,11 @@
two backslashes (``\\1``) are required in CMake code to get a backslash
through argument parsing.
+.. versionchanged:: 4.1
+ The ``^`` anchor now matches only at the beginning of the input
+ string instead of the beginning of each repeated search.
+ See policy :policy:`CMP0186`.
+
.. _`Regex Specification`:
Regex Specification
diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst
index d363485..4fa878e 100644
--- a/Help/manual/cmake-buildsystem.7.rst
+++ b/Help/manual/cmake-buildsystem.7.rst
@@ -1513,7 +1513,7 @@
add_library(Eigen INTERFACE)
- target_sources(Eigen INTERFACE
+ target_sources(Eigen PUBLIC
FILE_SET HEADERS
BASE_DIRS src
FILES src/eigen.h src/vector.h src/matrix.h
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 271d7a9..f434e55 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -532,6 +532,11 @@
$<LIST:TRANSFORM,list,REPLACE,regular_expression,replace_expression[,SELECTOR]>
+ .. versionchanged:: 4.1
+ The ``^`` anchor now matches only at the beginning of the input
+ element instead of the beginning of each repeated search.
+ See policy :policy:`CMP0186`.
+
``SELECTOR`` determines which items of the list will be transformed.
Only one type of selector can be specified at a time. When given,
``SELECTOR`` must be one of the following:
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index bf0933a..9f3de09 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -92,6 +92,14 @@
The following policies are supported.
+Policies Introduced by CMake 4.1
+--------------------------------
+
+.. toctree::
+ :maxdepth: 1
+
+ CMP0186: Regular expressions match ^ at most once in repeated searches. </policy/CMP0186>
+
Policies Introduced by CMake 4.0
--------------------------------
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 200fc18..cbf8a92 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -254,6 +254,7 @@
/variable/CMAKE_MFC_FLAG
/variable/CMAKE_MODULE_PATH
/variable/CMAKE_POLICY_DEFAULT_CMPNNNN
+ /variable/CMAKE_POLICY_VERSION_MINIMUM
/variable/CMAKE_POLICY_WARNING_CMPNNNN
/variable/CMAKE_PREFIX_PATH
/variable/CMAKE_PROGRAM_PATH
diff --git a/Help/policy/CMP0186.rst b/Help/policy/CMP0186.rst
new file mode 100644
index 0000000..747bce2
--- /dev/null
+++ b/Help/policy/CMP0186.rst
@@ -0,0 +1,43 @@
+CMP0186
+-------
+
+.. versionadded:: 4.1
+
+Regular expressions match ``^`` at most once in repeated searches.
+
+This policy affects commands that perform multiple regular expression
+searches:
+
+* :command:`string(REGEX MATCHALL)`
+* :command:`string(REGEX REPLACE)`
+* :command:`list(TRANSFORM REPLACE)`
+
+and the generator expression :genex:`$<LIST:TRANSFORM,list,REPLACE>`.
+
+CMake 4.0 and below match the ``^`` anchor at the start of every
+successive search, leading to multiple matches:
+
+.. code-block:: cmake
+
+ string(REGEX REPLACE "^a" "b" result "aaaa") # result="bbbb"
+ string(REGEX MATCHALL "^a" result "aaaa") # result="a;a;a;a"
+
+CMake 4.1 and above prefer to match the ``^`` anchor at most once,
+at the start of the input string:
+
+.. code-block:: cmake
+
+ string(REGEX REPLACE "^a" "b" result "aaaa") # result="abbb"
+ string(REGEX MATCHALL "^a" result "aaaa") # result="a"
+
+This policy provides compatibility for projects that have not been updated.
+
+The ``OLD`` behavior for this policy is to match ``^`` multiple times,
+at the start of each search. The ``NEW`` behavior for this policy is
+to match ``^`` at most once, at the start of the input string.
+
+.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.1
+.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn
+.. include:: STANDARD_ADVICE.txt
+
+.. include:: DEPRECATED.txt
diff --git a/Help/release/4.0.rst b/Help/release/4.0.rst
index 80a55bf..b1102d5 100644
--- a/Help/release/4.0.rst
+++ b/Help/release/4.0.rst
@@ -72,6 +72,10 @@
to select runtime checks for compilers targeting the MSVC ABI.
See policy :policy:`CMP0184`.
+* The :variable:`CMAKE_POLICY_VERSION_MINIMUM` variable was added to
+ help pacakgers and end users try to configure existing projects that
+ have not been updated to work with supported CMake versions.
+
* The :variable:`CMAKE_XCODE_SCHEME_LLDB_INIT_FILE` variable and corresponding
:prop_tgt:`XCODE_SCHEME_LLDB_INIT_FILE` target property were added to tell
the :generator:`Xcode` generator what to put in the scheme's "LLDB Init File"
diff --git a/Help/release/dev/diab-compiler-support.rst b/Help/release/dev/diab-compiler-support.rst
new file mode 100644
index 0000000..2cf0bd6
--- /dev/null
+++ b/Help/release/dev/diab-compiler-support.rst
@@ -0,0 +1,8 @@
+diab-compiler-support
+---------------------
+
+* `Diab compilers from Wind River Systems`_, versions 5.9.x+, are now
+ supported with :variable:`compiler id <CMAKE_<LANG>_COMPILER_ID>` ``Diab``
+ for languages ``ASM``, ``C``, and ``CXX``.
+
+.. _`Diab compilers from Wind River Systems`: https://www.windriver.com/resource/wind-river-diab-compiler-product-overview
diff --git a/Help/release/dev/regex-fixes.rst b/Help/release/dev/regex-fixes.rst
new file mode 100644
index 0000000..e979c03
--- /dev/null
+++ b/Help/release/dev/regex-fixes.rst
@@ -0,0 +1,5 @@
+regex-fixes
+-----------
+
+* Regular expressions match the ``^`` anchor at most once in repeated
+ searches, at the start of the input. See policy :policy:`CMP0186`.
diff --git a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.rst b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.rst
index f8f553d..c4f5b98 100644
--- a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.rst
+++ b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.rst
@@ -39,5 +39,6 @@
endfunction()
See also :variable:`CMAKE_CURRENT_FUNCTION`,
-:variable:`CMAKE_CURRENT_FUNCTION_LIST_FILE` and
-:variable:`CMAKE_CURRENT_FUNCTION_LIST_LINE`.
+:variable:`CMAKE_CURRENT_FUNCTION_LIST_FILE`,
+:variable:`CMAKE_CURRENT_FUNCTION_LIST_LINE` and
+:variable:`CMAKE_CURRENT_LIST_DIR`.
diff --git a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_FILE.rst b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_FILE.rst
index 437dfec..d533441 100644
--- a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_FILE.rst
+++ b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_FILE.rst
@@ -7,5 +7,6 @@
contains the full path to the listfile that defined the current function.
See also :variable:`CMAKE_CURRENT_FUNCTION`,
-:variable:`CMAKE_CURRENT_FUNCTION_LIST_DIR` and
-:variable:`CMAKE_CURRENT_FUNCTION_LIST_LINE`.
+:variable:`CMAKE_CURRENT_FUNCTION_LIST_DIR`,
+:variable:`CMAKE_CURRENT_FUNCTION_LIST_LINE` and
+:variable:`CMAKE_CURRENT_LIST_FILE`.
diff --git a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_LINE.rst b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_LINE.rst
index 2fc7012..2b1f472 100644
--- a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_LINE.rst
+++ b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_LINE.rst
@@ -8,5 +8,6 @@
was defined.
See also :variable:`CMAKE_CURRENT_FUNCTION`,
-:variable:`CMAKE_CURRENT_FUNCTION_LIST_DIR` and
-:variable:`CMAKE_CURRENT_FUNCTION_LIST_FILE`.
+:variable:`CMAKE_CURRENT_FUNCTION_LIST_DIR`,
+:variable:`CMAKE_CURRENT_FUNCTION_LIST_FILE` and
+:variable:`CMAKE_CURRENT_LIST_LINE`.
diff --git a/Help/variable/CMAKE_CURRENT_LIST_DIR.rst b/Help/variable/CMAKE_CURRENT_LIST_DIR.rst
index ebc3ab9..b55bc37 100644
--- a/Help/variable/CMAKE_CURRENT_LIST_DIR.rst
+++ b/Help/variable/CMAKE_CURRENT_LIST_DIR.rst
@@ -14,4 +14,5 @@
on the call stack, not the directory of the file containing the macro
or function definition.
-See also :variable:`CMAKE_CURRENT_LIST_FILE`.
+See also :variable:`CMAKE_CURRENT_LIST_FILE` and
+:variable:`CMAKE_CURRENT_FUNCTION_LIST_DIR`.
diff --git a/Help/variable/CMAKE_CURRENT_LIST_FILE.rst b/Help/variable/CMAKE_CURRENT_LIST_FILE.rst
index 84b0eee..c94933d 100644
--- a/Help/variable/CMAKE_CURRENT_LIST_FILE.rst
+++ b/Help/variable/CMAKE_CURRENT_LIST_FILE.rst
@@ -12,4 +12,5 @@
is the file invoking the bottom-most entry on the call stack, not the
file containing the macro or function definition.
-See also :variable:`CMAKE_PARENT_LIST_FILE`.
+See also :variable:`CMAKE_PARENT_LIST_FILE` and
+:variable:`CMAKE_CURRENT_FUNCTION_LIST_FILE`.
diff --git a/Help/variable/CMAKE_CURRENT_LIST_LINE.rst b/Help/variable/CMAKE_CURRENT_LIST_LINE.rst
index 7f839c2..f23ba2f 100644
--- a/Help/variable/CMAKE_CURRENT_LIST_LINE.rst
+++ b/Help/variable/CMAKE_CURRENT_LIST_LINE.rst
@@ -9,3 +9,5 @@
If CMake is currently processing deferred calls scheduled by
the :command:`cmake_language(DEFER)` command, this variable
evaluates to ``DEFERRED`` instead of a specific line number.
+
+See also :variable:`CMAKE_CURRENT_FUNCTION_LIST_LINE`.
diff --git a/Help/variable/CMAKE_LANG_COMPILER_ID.rst b/Help/variable/CMAKE_LANG_COMPILER_ID.rst
index a4f899e..f46ac73 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_ID.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_ID.rst
@@ -19,6 +19,7 @@
``Clang`` `LLVM Clang`_
``Cray`` Cray Compiler
``CrayClang`` Cray Clang-based Compiler
+``Diab`` `Wind River Systems Diab Compiler`_
``Embarcadero``, ``Borland`` `Embarcadero`_
``Flang`` `Classic Flang Fortran Compiler`_
``LLVMFlang`` `LLVM Flang Fortran Compiler`_
@@ -71,3 +72,4 @@
.. _Tiny C Compiler: https://bellard.org/tcc
.. _Tasking Compiler Toolsets: https://www.tasking.com
.. _Texas Instruments Clang-based Compilers: https://www.ti.com/tool/download/ARM-CGT-CLANG
+.. _Wind River Systems Diab Compiler: https://www.windriver.com/resource/wind-river-diab-compiler-product-overview
diff --git a/Help/variable/CMAKE_POLICY_DEFAULT_CMPNNNN.rst b/Help/variable/CMAKE_POLICY_DEFAULT_CMPNNNN.rst
index d643fb8..5f47d4e 100644
--- a/Help/variable/CMAKE_POLICY_DEFAULT_CMPNNNN.rst
+++ b/Help/variable/CMAKE_POLICY_DEFAULT_CMPNNNN.rst
@@ -22,3 +22,6 @@
* Projects may set this variable before a call to :command:`add_subdirectory`
that adds a third-party project in order to set its policies without
modifying third-party code.
+
+See :variable:`CMAKE_POLICY_VERSION_MINIMUM` set policies to ``NEW``
+based on the version of CMake that introduced them.
diff --git a/Help/variable/CMAKE_POLICY_VERSION_MINIMUM.rst b/Help/variable/CMAKE_POLICY_VERSION_MINIMUM.rst
new file mode 100644
index 0000000..cf48ecf
--- /dev/null
+++ b/Help/variable/CMAKE_POLICY_VERSION_MINIMUM.rst
@@ -0,0 +1,23 @@
+CMAKE_POLICY_VERSION_MINIMUM
+----------------------------
+
+.. versionadded:: 4.0
+
+Specify a minimum :ref:`Policy Version` for a project without modifying
+its calls to :command:`cmake_minimum_required(VERSION)` and
+:command:`cmake_policy(VERSION)`.
+
+This variable should not be set by a project in CMake code as a way to
+set its own policy version. Use :command:`cmake_minimum_required(VERSION)`
+and/or :command:`cmake_policy(VERSION)` for that. This variable is meant
+to externally set policies for which a project has not itself been updated:
+
+* Users running CMake may set this variable in the cache, e.g.,
+ ``-DCMAKE_POLICY_VERSION_MINIMUM=3.5``, to try configuring a project
+ that has not been updated to set at least that policy version itself.
+
+* Projects may set this variable before a call to :command:`add_subdirectory`
+ that adds a third-party project in order to set its policy version without
+ modifying third-party code.
+
+See :variable:`CMAKE_POLICY_DEFAULT_CMP<NNNN>` to set individual policies.
diff --git a/Modules/CMakeCompilerIdDetection.cmake b/Modules/CMakeCompilerIdDetection.cmake
index 2817d37..ad73373 100644
--- a/Modules/CMakeCompilerIdDetection.cmake
+++ b/Modules/CMakeCompilerIdDetection.cmake
@@ -89,6 +89,7 @@
MSVC
ADSP
IAR
+ Diab
)
if ("x${lang}" STREQUAL "xC")
list(APPEND ordered_compilers
diff --git a/Modules/CMakeDetermineASMCompiler.cmake b/Modules/CMakeDetermineASMCompiler.cmake
index 412fe36..d3b425a 100644
--- a/Modules/CMakeDetermineASMCompiler.cmake
+++ b/Modules/CMakeDetermineASMCompiler.cmake
@@ -110,6 +110,10 @@
set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_IAR )
set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_IAR "IAR Assembler")
+ list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS Diab)
+ set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_Diab "-V" )
+ set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_Diab "Wind River Systems")
+
list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS ARMCC)
set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_ARMCC )
set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_ARMCC "(ARM Compiler)|(ARM Assembler)|(Arm Compiler)")
diff --git a/Modules/Compiler/Diab-ASM.cmake b/Modules/Compiler/Diab-ASM.cmake
new file mode 100644
index 0000000..ccc8cb6
--- /dev/null
+++ b/Modules/Compiler/Diab-ASM.cmake
@@ -0,0 +1,3 @@
+include(Compiler/Diab)
+
+__compiler_diab(ASM)
diff --git a/Modules/Compiler/Diab-C.cmake b/Modules/Compiler/Diab-C.cmake
new file mode 100644
index 0000000..0fd5345
--- /dev/null
+++ b/Modules/Compiler/Diab-C.cmake
@@ -0,0 +1,9 @@
+include(Compiler/Diab)
+
+__compiler_diab(C)
+
+# c89/90 is both -Xdialect-c89
+set(CMAKE_C89_STANDARD_COMPILE_OPTION "-Xdialect-c89")
+set(CMAKE_C90_STANDARD_COMPILE_OPTION "-Xdialect-c89")
+set(CMAKE_C99_STANDARD_COMPILE_OPTION "-Xdialect-c99")
+set(CMAKE_C11_STANDARD_COMPILE_OPTION "-Xdialect-c11")
diff --git a/Modules/Compiler/Diab-CXX.cmake b/Modules/Compiler/Diab-CXX.cmake
new file mode 100644
index 0000000..a8a17c5
--- /dev/null
+++ b/Modules/Compiler/Diab-CXX.cmake
@@ -0,0 +1,12 @@
+include(Compiler/Diab)
+
+__compiler_diab(CXX)
+
+# Diab C++98 is named as -Xdialect-c++03
+set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-Xdialect-c++03")
+set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-Xdialect-c++11")
+set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-Xdialect-c++14")
+set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-Xdialect-c++17")
+set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-Xdialect-c++20")
+
+__compiler_check_default_language_standard(CXX 4.0 98 5.0 11)
diff --git a/Modules/Compiler/Diab-DetermineCompiler.cmake b/Modules/Compiler/Diab-DetermineCompiler.cmake
new file mode 100644
index 0000000..86518f5
--- /dev/null
+++ b/Modules/Compiler/Diab-DetermineCompiler.cmake
@@ -0,0 +1,10 @@
+# Diab Toolchain. Works only for versions 5.9.x or higher.
+set(_compiler_id_pp_test "defined(__DCC__) && defined(_DIAB_TOOL)")
+
+set(_compiler_id_version_compute "
+ # define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__VERSION_MAJOR_NUMBER__)
+ # define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__VERSION_MINOR_NUMBER__)
+ # define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__VERSION_ARCH_FEATURE_NUMBER__)
+ # define @PREFIX@COMPILER_VERSION_TWEAK @MACRO_DEC@(__VERSION_BUG_FIX_NUMBER__)
+"
+)
diff --git a/Modules/Compiler/Diab-FindBinUtils.cmake b/Modules/Compiler/Diab-FindBinUtils.cmake
new file mode 100644
index 0000000..7ca00cb
--- /dev/null
+++ b/Modules/Compiler/Diab-FindBinUtils.cmake
@@ -0,0 +1,15 @@
+# Find the archiver for the compiler architecture, which is always in the same
+# directory as the compiler.
+if(NOT DEFINED _CMAKE_PROCESSING_LANGUAGE OR _CMAKE_PROCESSING_LANGUAGE STREQUAL "")
+ message(FATAL_ERROR "Internal error: _CMAKE_PROCESSING_LANGUAGE is not set")
+endif()
+
+get_filename_component(__diab_path "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER}" DIRECTORY)
+
+find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_AR
+ NAMES dar
+ HINTS ${__diab_path}
+ NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH
+ DOC "Diab Archiver"
+)
+mark_as_advanced(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_AR)
diff --git a/Modules/Compiler/Diab.cmake b/Modules/Compiler/Diab.cmake
new file mode 100644
index 0000000..cf32139
--- /dev/null
+++ b/Modules/Compiler/Diab.cmake
@@ -0,0 +1,33 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# This module is shared by multiple languages; use include blocker.
+if(__COMPILER_Diab)
+ return()
+endif()
+set(__COMPILER_Diab 1)
+
+include(Compiler/CMakeCommonCompilerMacros)
+
+macro(__compiler_diab lang)
+ set(CMAKE_${lang}_VERBOSE_FLAG "-#")
+ set(CMAKE_${lang}_OUTPUT_EXTENSION ".o")
+
+ string(APPEND CMAKE_${lang}_FLAGS_INIT " ")
+ string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -g")
+ string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -O -Xsize-opt")
+ string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -XO")
+ string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -XO -g3")
+
+ set(__DIAB_AR "${CMAKE_${lang}_COMPILER_AR}")
+ set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "\"${__DIAB_AR}\" -r <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_${lang}_ARCHIVE_CREATE "\"${__DIAB_AR}\" -r <TARGET> <LINK_FLAGS> <OBJECTS>")
+
+ set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
+ set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_IPO -XO -Xwhole-program-optim)
+endmacro()
+
+set(CMAKE_EXECUTABLE_SUFFIX "")
+set(CMAKE_LIBRARY_PATH_TERMINATOR "")
+set(CMAKE_LIBRARY_PATH_FLAG "")
diff --git a/Modules/FindGettext.cmake b/Modules/FindGettext.cmake
index 940d2c0..b982bb9 100644
--- a/Modules/FindGettext.cmake
+++ b/Modules/FindGettext.cmake
@@ -35,10 +35,11 @@
.. code-block:: cmake
- gettext_create_translations(<mofile> [ALL] <file>...)
+ gettext_create_translations(<potfile> [ALL] <file>...)
- This will create a target "translations" which will convert the
- given input .po files into the binary output .mo file. Options:
+ This function creates a custom target "translations" which processes the
+ given .pot file to .mo files. The generated binary files will be installed
+ into ``share/locale/`` directory. Options:
``ALL``
The translations will be created when building the default target.
@@ -77,7 +78,7 @@
``INSTALL_DESTINATION``
Install the results into the given directory (``share/locale/`` by
- default). The language subdirectory will be taken into account .
+ default). The language subdirectory will be taken into account.
.. versionadded:: 3.2
If you wish to use the Gettext runtime library (libintl), use
@@ -95,7 +96,7 @@
OUTPUT_STRIP_TRAILING_WHITESPACE)
get_filename_component(msgmerge_name ${GETTEXT_MSGMERGE_EXECUTABLE} NAME)
get_filename_component(msgmerge_namewe ${GETTEXT_MSGMERGE_EXECUTABLE} NAME_WE)
- if (gettext_version MATCHES "^(${msgmerge_name}|${msgmerge_namewe}) \\([^\\)]*\\) ([0-9\\.]+[^ \n]*)")
+ if(gettext_version MATCHES "^(${msgmerge_name}|${msgmerge_namewe}) \\([^\\)]*\\) ([0-9\\.]+[^ \n]*)")
set(GETTEXT_VERSION_STRING "${CMAKE_MATCH_2}")
endif()
unset(gettext_version)
@@ -116,7 +117,7 @@
endif()
set(${_unique_name} "${_name}_${currentCounter}" PARENT_SCOPE)
math(EXPR currentCounter "${currentCounter} + 1")
- set_property(GLOBAL PROPERTY ${propertyName} ${currentCounter} )
+ set_property(GLOBAL PROPERTY ${propertyName} ${currentCounter})
endfunction()
macro(GETTEXT_CREATE_TRANSLATIONS _potFile _firstPoFileArg)
@@ -134,7 +135,7 @@
set(_firstPoFile)
endif()
- foreach (_currentPoFile ${_firstPoFile} ${ARGN})
+ foreach(_currentPoFile ${_firstPoFile} ${ARGN})
get_filename_component(_absFile ${_currentPoFile} ABSOLUTE)
get_filename_component(_abs_PATH ${_absFile} PATH)
get_filename_component(_lang ${_absFile} NAME_WE)
@@ -150,7 +151,7 @@
install(FILES ${_gmoFile} DESTINATION share/locale/${_lang}/LC_MESSAGES RENAME ${_potBasename}.mo)
set(_gmoFiles ${_gmoFiles} ${_gmoFile})
- endforeach ()
+ endforeach()
if(NOT TARGET translations)
add_custom_target(translations)
@@ -177,7 +178,7 @@
string(REGEX REPLACE "^(.+)(\\.[^.]+)$" "\\1" _potBasename ${_potName})
get_filename_component(_absPotFile ${_potFile} ABSOLUTE)
- foreach (_lang ${_parsedArguments_LANGUAGES})
+ foreach(_lang ${_parsedArguments_LANGUAGES})
set(_poFile "${CMAKE_CURRENT_BINARY_DIR}/${_lang}.po")
set(_gmoFile "${CMAKE_CURRENT_BINARY_DIR}/${_lang}.gmo")
@@ -197,7 +198,7 @@
install(FILES ${_gmoFile} DESTINATION ${_parsedArguments_INSTALL_DESTINATION}/${_lang}/LC_MESSAGES RENAME ${_potBasename}.mo)
endif()
list(APPEND _gmoFiles ${_gmoFile})
- endforeach ()
+ endforeach()
if(NOT TARGET potfiles)
add_custom_target(potfiles)
@@ -245,7 +246,7 @@
add_custom_target(pofiles)
endif()
- _GETTEXT_GET_UNIQUE_TARGET_NAME( pofiles uniqueTargetName)
+ _GETTEXT_GET_UNIQUE_TARGET_NAME(pofiles uniqueTargetName)
if(_parsedArguments_ALL)
add_custom_target(${uniqueTargetName} ALL DEPENDS ${_gmoFiles})
diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake
index 93521cf..1c5641e 100644
--- a/Modules/FindPython/Support.cmake
+++ b/Modules/FindPython/Support.cmake
@@ -47,9 +47,10 @@
endif ()
endif()
+ set (${_PYTHON_BASE}_FOUND FALSE)
set (${_PYTHON_PREFIX}_FOUND FALSE)
- string (TOUPPER "${_PYTHON_PREFIX}" _${_PYTHON_PREFIX}_UPPER_PREFIX)
- set (${_PYTHON_UPPER_PREFIX}_FOUND FALSE)
+ string (TOUPPER "${_PYTHON_BASE}" _${_PYTHON_BASE}_UPPER_PREFIX)
+ set (${_${_PYTHON_BASE}_UPPER_PREFIX}_FOUND FALSE)
endmacro()
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index bf50f8c..080e99f 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 4)
set(CMake_VERSION_MINOR 0)
-set(CMake_VERSION_PATCH 20250213)
+set(CMake_VERSION_PATCH 20250215)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/Modules/CMakeBuildUtilities.cmake b/Source/Modules/CMakeBuildUtilities.cmake
index 09d8250..dba9d50 100644
--- a/Source/Modules/CMakeBuildUtilities.cmake
+++ b/Source/Modules/CMakeBuildUtilities.cmake
@@ -159,6 +159,7 @@
set(CURL_CA_BUNDLE "" CACHE FILEPATH "Path to SSL CA Certificate Bundle")
set(CURL_CA_PATH "" CACHE PATH "Path to SSL CA Certificate Directory")
mark_as_advanced(CURL_CA_BUNDLE CURL_CA_PATH)
+ find_package(OpenSSL)
endif()
if(NOT CMAKE_USE_SYSTEM_NGHTTP2)
# Tell curl's FindNGHTTP2 module to use our library.
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 63a313c..7720485 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -59,6 +59,7 @@
namespace {
using pdt = cmFindPackageCommand::PackageDescriptionType;
+using ParsedVersion = cmPackageInfoReader::Pep440Version;
template <template <typename> class Op>
struct StrverscmpOp
@@ -2717,12 +2718,61 @@
std::unique_ptr<cmPackageInfoReader> reader =
cmPackageInfoReader::Read(config_file);
if (reader && reader->GetName() == this->Name) {
+ // Read version information.
cm::optional<std::string> cpsVersion = reader->GetVersion();
- if (cpsVersion) {
- // TODO: Implement version check for CPS
- result = true;
- } else {
- result = this->Version.empty();
+ cm::optional<ParsedVersion> const& parsedVersion =
+ reader->ParseVersion(cpsVersion);
+ bool const hasVersion = cpsVersion.has_value();
+
+ // Test for version compatibility.
+ result = this->Version.empty();
+ if (hasVersion) {
+ version = std::move(*cpsVersion);
+
+ if (!this->Version.empty()) {
+ if (!parsedVersion) {
+ // If we don't understand the version, compare the exact versions
+ // using full string comparison. This is the correct behavior for
+ // the "custom" schema, and the best we can do otherwise.
+ result = (this->Version == version);
+ } else if (this->VersionExact) {
+ // If EXACT is specified, the version must be exactly the requested
+ // version.
+ result =
+ cmSystemTools::VersionCompareEqual(this->Version, version);
+ } else {
+ // Do we have a compat_version?
+ cm::optional<std::string> const& compatVersion =
+ reader->GetCompatVersion();
+ if (reader->ParseVersion(compatVersion)) {
+ // If yes, the initial result is whether the requested version is
+ // between the actual version and the compat version, inclusive.
+ result = cmSystemTools::VersionCompareGreaterEq(version,
+ this->Version) &&
+ cmSystemTools::VersionCompareGreaterEq(this->Version,
+ *compatVersion);
+
+ if (result && !this->VersionMax.empty()) {
+ // We must also check that the version is less than the version
+ // limit.
+ if (this->VersionRangeMax == VERSION_ENDPOINT_EXCLUDED) {
+ result = cmSystemTools::VersionCompareGreater(
+ this->VersionMax, version);
+ } else {
+ result = cmSystemTools::VersionCompareGreaterEq(
+ this->VersionMax, version);
+ }
+ }
+ } else {
+ // If no, compat_version is assumed to be exactly the actual
+ // version, so the result is whether the requested version is
+ // exactly the actual version, and we can ignore the version
+ // limit.
+ result =
+ cmSystemTools::VersionCompareEqual(this->Version, version);
+ }
+ }
+ }
}
if (result) {
@@ -2752,26 +2802,33 @@
result = false;
}
- if (result && cpsVersion) {
- this->VersionFound = (version = std::move(*cpsVersion));
+ if (result && hasVersion) {
+ this->VersionFound = version;
- std::vector<unsigned> const& versionParts = reader->ParseVersion();
- this->VersionFoundCount = static_cast<unsigned>(versionParts.size());
- switch (this->VersionFoundCount) {
- case 4:
- this->VersionFoundTweak = versionParts[3];
- CM_FALLTHROUGH;
- case 3:
- this->VersionFoundPatch = versionParts[2];
- CM_FALLTHROUGH;
- case 2:
- this->VersionFoundMinor = versionParts[1];
- CM_FALLTHROUGH;
- case 1:
- this->VersionFoundMajor = versionParts[0];
- CM_FALLTHROUGH;
- default:
- break;
+ if (parsedVersion) {
+ std::vector<unsigned> const& versionParts =
+ parsedVersion->ReleaseComponents;
+
+ this->VersionFoundCount =
+ static_cast<unsigned>(versionParts.size());
+ switch (std::min(this->VersionFoundCount, 4u)) {
+ case 4:
+ this->VersionFoundTweak = versionParts[3];
+ CM_FALLTHROUGH;
+ case 3:
+ this->VersionFoundPatch = versionParts[2];
+ CM_FALLTHROUGH;
+ case 2:
+ this->VersionFoundMinor = versionParts[1];
+ CM_FALLTHROUGH;
+ case 1:
+ this->VersionFoundMajor = versionParts[0];
+ CM_FALLTHROUGH;
+ default:
+ break;
+ }
+ } else {
+ this->VersionFoundCount = 0;
}
}
this->CpsReader = std::move(reader);
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 3f38b73..c67ce01 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1706,6 +1706,11 @@
return std::string{};
}
+ if (!selector) {
+ selector = cmList::TransformSelector::New();
+ }
+ selector->Makefile = ctx->LG->GetMakefile();
+
return list
.transform(descriptor->Action, arguments,
std::move(selector))
diff --git a/Source/cmList.cxx b/Source/cmList.cxx
index 074e06f..529b2bb 100644
--- a/Source/cmList.cxx
+++ b/Source/cmList.cxx
@@ -523,8 +523,8 @@
std::string const& replace) override
{
TransformAction::Initialize(selector);
- this->ReplaceHelper =
- cm::make_unique<cmStringReplaceHelper>(regex, replace);
+ this->ReplaceHelper = cm::make_unique<cmStringReplaceHelper>(
+ regex, replace, selector->Makefile);
if (!this->ReplaceHelper->IsRegularExpressionValid()) {
throw transform_error(
@@ -643,6 +643,11 @@
}
}
+std::unique_ptr<cmList::TransformSelector> cmList::TransformSelector::New()
+{
+ return cm::make_unique<TransformNoSelector>();
+}
+
std::unique_ptr<cmList::TransformSelector> cmList::TransformSelector::NewAT(
std::initializer_list<index_type> indexes)
{
diff --git a/Source/cmList.h b/Source/cmList.h
index b5be0b9..68772b9 100644
--- a/Source/cmList.h
+++ b/Source/cmList.h
@@ -23,6 +23,7 @@
template <typename T>
class BT;
+class cmMakefile;
/**
* CMake lists management
@@ -893,6 +894,7 @@
// cmList::TransformSelector::New<AT>({1, 2, 5, 6});
// or
// cmList::TransformSelector::New<REGEX>("^XX.*");
+ static std::unique_ptr<TransformSelector> New();
template <typename Type>
static std::unique_ptr<TransformSelector> New(
std::initializer_list<index_type>);
@@ -907,6 +909,8 @@
template <typename Type>
static std::unique_ptr<TransformSelector> New(std::string&&);
+ cmMakefile* Makefile = nullptr;
+
private:
static std::unique_ptr<TransformSelector> NewAT(
std::initializer_list<index_type> init);
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index 7e046e0..eb6147b 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -678,6 +678,11 @@
return true;
}
+ if (!selector) {
+ selector = cmList::TransformSelector::New();
+ }
+ selector->Makefile = &status.GetMakefile();
+
list->transform(descriptor->Action, arguments, std::move(selector));
status.GetMakefile().AddDefinition(outputName, list->to_string());
return true;
diff --git a/Source/cmPackageInfoReader.cxx b/Source/cmPackageInfoReader.cxx
index 82f2cb8..40ed54e 100644
--- a/Source/cmPackageInfoReader.cxx
+++ b/Source/cmPackageInfoReader.cxx
@@ -366,6 +366,62 @@
}
}
+cm::optional<cmPackageInfoReader::Pep440Version> ParseSimpleVersion(
+ std::string const& version)
+{
+ if (version.empty()) {
+ return cm::nullopt;
+ }
+
+ cmPackageInfoReader::Pep440Version result;
+ result.Simple = true;
+
+ cm::string_view remnant{ version };
+ for (;;) {
+ // Find the next part separator.
+ std::string::size_type const n = remnant.find_first_of(".+-"_s);
+ if (n == 0) {
+ // The part is an empty string.
+ return cm::nullopt;
+ }
+
+ // Extract the part as a number.
+ cm::string_view const part = remnant.substr(0, n);
+ std::string::size_type const l = part.size();
+ std::string::size_type p;
+ unsigned long const value = std::stoul(std::string{ part }, &p);
+ if (p != l || value > std::numeric_limits<unsigned>::max()) {
+ // The part was not a valid number or is too big.
+ return cm::nullopt;
+ }
+ result.ReleaseComponents.push_back(static_cast<unsigned>(value));
+
+ // Have we consumed the entire input?
+ if (n == std::string::npos) {
+ return { std::move(result) };
+ }
+
+ // Lop off the current part.
+ char const sep = remnant[n];
+ remnant = remnant.substr(n + 1);
+ if (sep == '+' || sep == '-') {
+ // If we hit the local label, we're done.
+ result.LocalLabel = remnant;
+ return { std::move(result) };
+ }
+
+ // We just consumed a '.'; check that there's more.
+ if (remnant.empty()) {
+ // A trailing part separator is not allowed.
+ return cm::nullopt;
+ }
+
+ // Continue with the remaining input.
+ }
+
+ // Unreachable.
+}
+
} // namespace
std::unique_ptr<cmPackageInfoReader> cmPackageInfoReader::Read(
@@ -428,40 +484,31 @@
return cm::nullopt;
}
-std::vector<unsigned> cmPackageInfoReader::ParseVersion() const
+cm::optional<std::string> cmPackageInfoReader::GetCompatVersion() const
+{
+ Json::Value const& version = this->Data["compat_version"];
+ if (version.isString()) {
+ return version.asString();
+ }
+ return cm::nullopt;
+}
+
+cm::optional<cmPackageInfoReader::Pep440Version>
+cmPackageInfoReader::ParseVersion(
+ cm::optional<std::string> const& version) const
{
// Check that we have a version.
- cm::optional<std::string> const& version = this->GetVersion();
if (!version) {
- return {};
+ return cm::nullopt;
}
- std::vector<unsigned> result;
- cm::string_view remnant{ *version };
-
// Check if we know how to parse the version.
Json::Value const& schema = this->Data["version_schema"];
if (schema.isNull() || cmStrCaseEq(schema.asString(), "simple"_s)) {
- // Keep going until we run out of parts.
- while (!remnant.empty()) {
- std::string::size_type n = remnant.find('.');
- cm::string_view part = remnant.substr(0, n);
- if (n == std::string::npos) {
- remnant = {};
- } else {
- remnant = remnant.substr(n + 1);
- }
-
- unsigned long const value = std::stoul(std::string{ part }, &n);
- if (n == 0 || value > std::numeric_limits<unsigned>::max()) {
- // The part was not a valid number or is too big.
- return {};
- }
- result.push_back(static_cast<unsigned>(value));
- }
+ return ParseSimpleVersion(*version);
}
- return result;
+ return cm::nullopt;
}
std::vector<cmPackageRequirement> cmPackageInfoReader::GetRequirements() const
diff --git a/Source/cmPackageInfoReader.h b/Source/cmPackageInfoReader.h
index d31cee9..26eb807 100644
--- a/Source/cmPackageInfoReader.h
+++ b/Source/cmPackageInfoReader.h
@@ -43,11 +43,34 @@
std::string GetName() const;
cm::optional<std::string> GetVersion() const;
+ cm::optional<std::string> GetCompatVersion() const;
- /// If the package uses the 'simple' version scheme, obtain the version as
- /// a numeric tuple. Returns an empty vector for other schemes or if no
- /// version is specified.
- std::vector<unsigned> ParseVersion() const;
+ // NOTE: The eventual intent is for CPS to support multiple version schemas,
+ // and in particular, we expect to want to support "simple", "custom", "rpm",
+ // "dpkg" and "pep440". Additionally, we desire to be able to parse each of
+ // these to the maximum extent possible; in particular, we want to be able
+ // to decompose "simple" and "pep440" versions into components represented
+ // as numeric types rather than strings, which is not possible with the "rpm"
+ // and "dpkg" schemas. Therefore, we require different data structures to
+ // represent different version schemas.
+
+ struct Pep440Version
+ {
+ // NOTE: This structure is currently incomplete as we only support the
+ // "simple" schema at this time.
+ bool Simple; // "simple" can be represented as a subset of "pep440"
+ std::vector<unsigned> ReleaseComponents;
+ cm::optional<std::string> LocalLabel;
+ };
+
+ // FIXME: Return a sum type (e.g. {cm,std}::variant) of possible versions
+ // when we support more than just the "simple" (and possibly "pep440")
+ // schema(s).
+ /// If the package uses the 'simple' version scheme, parse the provided
+ /// version string as a numeric tuple and optional trailing string. Returns
+ /// a disengaged optional for other schemes or if no version is specified.
+ cm::optional<Pep440Version> ParseVersion(
+ cm::optional<std::string> const& version) const;
std::vector<cmPackageRequirement> GetRequirements() const;
std::vector<std::string> GetComponentNames() const;
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 9de978e..908a786 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -15,6 +15,7 @@
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmValue.h"
#include "cmVersion.h"
static bool stringToId(char const* input, cmPolicies::PolicyID& pid)
@@ -294,6 +295,30 @@
unsigned int patchVer,
WarnCompat warnCompat)
{
+ cmValue varVer = mf->GetDefinition("CMAKE_POLICY_VERSION_MINIMUM");
+ if (!varVer.IsEmpty()) {
+ unsigned int varMajor = 0;
+ unsigned int varMinor = 0;
+ unsigned int varPatch = 0;
+ unsigned int varTweak = 0;
+ if (sscanf(varVer.GetCStr(), "%u.%u.%u.%u", &varMajor, &varMinor,
+ &varPatch, &varTweak) < 2) {
+ mf->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Invalid CMAKE_POLICY_VERSION_MINIMUM value \"", varVer,
+ "\". "
+ "A numeric major.minor[.patch[.tweak]] must be given."));
+ return false;
+ }
+ if (varMajor > majorVer || (varMajor == majorVer && varMinor > minorVer) ||
+ (varMajor == majorVer && varMinor == minorVer &&
+ varPatch > patchVer)) {
+ majorVer = varMajor;
+ minorVer = varMinor;
+ patchVer = varPatch;
+ }
+ }
+
// Error on policy versions for which support has been removed.
if (majorVer < 3 || (majorVer == 3 && minorVer < 5)) {
if (IsFromLegacyInstallEXPORT(mf, majorVer, minorVer, patchVer)) {
@@ -305,7 +330,9 @@
} else {
mf->IssueMessage(MessageType::FATAL_ERROR,
"Compatibility with CMake < 3.5 has been removed "
- "from CMake.\n" ADVICE_UPDATE_VERSION_ARGUMENT);
+ "from CMake.\n" ADVICE_UPDATE_VERSION_ARGUMENT "\n"
+ "Or, add -DCMAKE_POLICY_VERSION_MINIMUM=3.5 to try "
+ "configuring anyway.");
cmSystemTools::SetFatalErrorOccurred();
return false;
}
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index d8a63a6..5f5f383 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -555,7 +555,10 @@
WARN) \
SELECT(POLICY, CMP0185, \
"FindRuby no longer provides upper-case RUBY_* variables.", 4, 0, 0, \
- WARN)
+ WARN) \
+ SELECT(POLICY, CMP0186, \
+ "Regular expressions match ^ at most once in repeated searches.", 4, \
+ 1, 0, WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 72c9405..152a68b 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -1451,8 +1451,11 @@
if (this->AutogenTarget.DependOrigin) {
// add_dependencies/addUtility do not support generator expressions.
// We depend only on the libraries found in all configs therefore.
- std::map<cmGeneratorTarget const*, std::size_t> commonTargets;
+ std::map<cmGeneratorTarget const*, std::size_t> targetsPartOfAllConfigs;
for (std::string const& config : this->ConfigsList) {
+ // The same target might appear multiple times in a config, but we
+ // should only count it once.
+ std::set<cmGeneratorTarget const*> seenTargets;
cmLinkImplementationLibraries const* libs =
this->GenTarget->GetLinkImplementationLibraries(
config, cmGeneratorTarget::UseTo::Link);
@@ -1460,14 +1463,15 @@
for (cmLinkItem const& item : libs->Libraries) {
cmGeneratorTarget const* libTarget = item.Target;
if (libTarget &&
- !StaticLibraryCycle(this->GenTarget, libTarget, config)) {
+ !StaticLibraryCycle(this->GenTarget, libTarget, config) &&
+ seenTargets.insert(libTarget).second) {
// Increment target config count
- commonTargets[libTarget]++;
+ targetsPartOfAllConfigs[libTarget]++;
}
}
}
}
- for (auto const& item : commonTargets) {
+ for (auto const& item : targetsPartOfAllConfigs) {
if (item.second == this->ConfigsList.size()) {
this->AutogenTarget.DependTargets.insert(item.first->Target);
}
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 33930d8..f923ba6 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -29,6 +29,7 @@
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmPolicies.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmStringReplaceHelper.h"
@@ -288,10 +289,16 @@
// Concatenate all the last arguments together.
std::string input = cmJoin(cmMakeRange(args).advance(4), std::string());
+ unsigned optAnchor = 0;
+ if (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0186) !=
+ cmPolicies::NEW) {
+ optAnchor = cmsys::RegularExpression::BOL_AT_OFFSET;
+ }
+
// Scan through the input for all matches.
std::string output;
- char const* p = input.c_str();
- while (re.find(p)) {
+ std::string::size_type base = 0;
+ while (re.find(input, base, optAnchor)) {
status.GetMakefile().ClearMatches();
status.GetMakefile().StoreMatches(re);
std::string::size_type l = re.start();
@@ -305,8 +312,8 @@
if (!output.empty()) {
output += ";";
}
- output += std::string(p + l, r - l);
- p += r;
+ output += re.match();
+ base = r;
}
// Store the output in the provided variable.
diff --git a/Source/cmStringReplaceHelper.cxx b/Source/cmStringReplaceHelper.cxx
index 0715f0b..5cd159e 100644
--- a/Source/cmStringReplaceHelper.cxx
+++ b/Source/cmStringReplaceHelper.cxx
@@ -7,6 +7,7 @@
#include <utility>
#include "cmMakefile.h"
+#include "cmPolicies.h"
cmStringReplaceHelper::cmStringReplaceHelper(std::string const& regex,
std::string replace_expr,
@@ -24,9 +25,16 @@
{
output.clear();
+ unsigned optAnchor = 0;
+ if (this->Makefile &&
+ this->Makefile->GetPolicyStatus(cmPolicies::CMP0186) !=
+ cmPolicies::NEW) {
+ optAnchor = cmsys::RegularExpression::BOL_AT_OFFSET;
+ }
+
// Scan through the input for all matches.
std::string::size_type base = 0;
- while (this->RegularExpression.find(input.c_str() + base)) {
+ while (this->RegularExpression.find(input, base, optAnchor)) {
if (this->Makefile) {
this->Makefile->ClearMatches();
this->Makefile->StoreMatches(this->RegularExpression);
@@ -35,7 +43,7 @@
auto r = this->RegularExpression.end();
// Concatenate the part of the input that was not matched.
- output += input.substr(base, l2);
+ output += input.substr(base, l2 - base);
// Make sure the match had some text.
if (r - l2 == 0) {
@@ -54,11 +62,8 @@
// Replace with part of the match.
auto n = replacement.Number;
auto start = this->RegularExpression.start(n);
- auto end = this->RegularExpression.end(n);
- auto len = input.length() - base;
- if ((start != std::string::npos) && (end != std::string::npos) &&
- (start <= len) && (end <= len)) {
- output += input.substr(base + start, end - start);
+ if (start != std::string::npos) {
+ output += this->RegularExpression.match(n);
} else {
std::ostringstream error;
error << "replace expression \"" << this->ReplaceExpression
@@ -71,11 +76,11 @@
}
// Move past the match.
- base += r;
+ base = r;
}
// Concatenate the text after the last match.
- output += input.substr(base, input.length() - base);
+ output += input.substr(base);
return true;
}
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 57ba964..88b3e9a 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -4590,6 +4590,13 @@
}
linkOptions.AddFlag("ProgramDataBaseFile", pdb);
+ // Add image version
+ int major, minor;
+ this->GeneratorTarget->GetTargetVersion(major, minor);
+ if (major || minor) {
+ linkOptions.AddFlag("Version", cmStrCat(major, '.', minor));
+ }
+
// A Windows Runtime component uses internal .NET metadata,
// so does not have an import library.
if (this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT") &&
diff --git a/Tests/CMakeLib/testList.cxx b/Tests/CMakeLib/testList.cxx
index aa1a21e..aade305 100644
--- a/Tests/CMakeLib/testList.cxx
+++ b/Tests/CMakeLib/testList.cxx
@@ -740,7 +740,7 @@
cmList list({ "ABC", "BBCB", "BCCCBC", "BCBCDD", "EBCBCEBC" });
list.transform(cmList::TransformAction::REPLACE, "^BC|BC$", "X");
- if (list.to_string() != "AX;BBCB;XCCX;XXDD;EBCBCEX") {
+ if (list.to_string() != "AX;BBCB;XCCX;XBCDD;EBCBCEX") {
result = false;
}
}
diff --git a/Tests/FindPackageCpsTest/CMakeLists.txt b/Tests/FindPackageCpsTest/CMakeLists.txt
index 58de268..73b76da 100644
--- a/Tests/FindPackageCpsTest/CMakeLists.txt
+++ b/Tests/FindPackageCpsTest/CMakeLists.txt
@@ -22,23 +22,52 @@
add_executable(FindPackageCpsTest FindPackageTest.cxx)
###############################################################################
+
+function(expect PACKAGE VAR OP VALUE WHAT)
+ if(NOT ${PACKAGE}_${VAR} ${OP} ${VALUE})
+ message(SEND_ERROR "${PACKAGE} wrong ${WHAT} ${${PACKAGE}_${VAR}} !")
+ endif()
+endfunction()
+
+function(test_version PACKAGE LITERAL COUNT MAJOR MINOR PATCH TWEAK)
+ if(NOT ${PACKAGE}_FOUND)
+ message(SEND_ERROR "${PACKAGE} not found !")
+ else()
+ expect(${PACKAGE} VERSION STREQUAL "${LITERAL}" "version")
+ expect(${PACKAGE} VERSION_COUNT EQUAL ${COUNT} "version count")
+ expect(${PACKAGE} VERSION_MAJOR EQUAL ${MAJOR} "major version")
+ expect(${PACKAGE} VERSION_MINOR EQUAL ${MINOR} "minor version")
+ expect(${PACKAGE} VERSION_PATCH EQUAL ${PATCH} "patch version")
+ expect(${PACKAGE} VERSION_TWEAK EQUAL ${TWEAK} "tweak version")
+ endif()
+endfunction()
+
+function(test_unparsed_version PACKAGE VERSION)
+ find_package(${PACKAGE} CONFIG)
+ test_version(${PACKAGE} "${VERSION}" 0 0 0 0 0)
+endfunction()
+
+###############################################################################
# Test a basic package search.
# It should NOT find the package's CMake package file.
find_package(Sample CONFIG)
-if(NOT Sample_FOUND)
- message(SEND_ERROR "Sample not found !")
-elseif(NOT Sample_VERSION STREQUAL "2.10.11")
- message(SEND_ERROR "Sample wrong version ${Sample_VERSION} !")
-elseif(NOT Sample_VERSION_MAJOR EQUAL 2)
- message(SEND_ERROR "Sample wrong major version ${Sample_VERSION_MAJOR} !")
-elseif(NOT Sample_VERSION_MINOR EQUAL 10)
- message(SEND_ERROR "Sample wrong minor version ${Sample_VERSION_MINOR} !")
-elseif(NOT Sample_VERSION_PATCH EQUAL 11)
- message(SEND_ERROR "Sample wrong patch version ${Sample_VERSION_PATCH} !")
-elseif(NOT Sample_VERSION_TWEAK EQUAL 0)
- message(SEND_ERROR "Sample wrong tweak version ${Sample_VERSION_TWEAK} !")
-endif()
+test_version(Sample "2.10.11" 3 2 10 11 0)
+
+###############################################################################
+# Test some more complicated version parsing.
+
+find_package(LongVersion CONFIG)
+test_version(LongVersion "1.1.2.3.5.8+fibonacci" 6 1 1 2 3)
+
+find_package(EmptyMarker CONFIG)
+test_version(EmptyMarker "1.1+" 2 1 1 0 0)
+
+test_unparsed_version(BadVersion1 "1..1")
+test_unparsed_version(BadVersion2 "1.1a.0")
+test_unparsed_version(BadVersion3 "1.1.")
+test_unparsed_version(BadVersion4 "+42")
+test_unparsed_version(CustomVersion "VII")
###############################################################################
# Test glob sorting.
@@ -62,13 +91,12 @@
set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
unset(SortLib_VERSION)
-# TODO Add this test once CPS version checking is implemented.
-# set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
-# FIND_PACKAGE(SortLib 4.0 CONFIG)
-# IF (NOT "${SortLib_VERSION}" STREQUAL "4.0.0")
-# message(SEND_ERROR "FIND_PACKAGE_SORT_ORDER gave up too soon! ${SortLib_VERSION}")
-# endif()
-# unset(SortLib_VERSION)
+set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
+FIND_PACKAGE(SortLib 4.0 CONFIG)
+IF (NOT "${SortLib_VERSION}" STREQUAL "4.0.0")
+ message(SEND_ERROR "FIND_PACKAGE_SORT_ORDER gave up too soon! ${SortLib_VERSION}")
+endif()
+unset(SortLib_VERSION)
set(SortFramework_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
set(CMAKE_FIND_PACKAGE_SORT_ORDER NAME)
diff --git a/Tests/FindPackageCpsTest/cps/badversion1.cps b/Tests/FindPackageCpsTest/cps/badversion1.cps
new file mode 100644
index 0000000..05acfa1
--- /dev/null
+++ b/Tests/FindPackageCpsTest/cps/badversion1.cps
@@ -0,0 +1,8 @@
+{
+ "cps_version": "0.13",
+ "name": "BadVersion1",
+ "version": "1..1",
+ "version_schema": "simple",
+ "cps_path": "@prefix@/cps",
+ "components": {}
+}
diff --git a/Tests/FindPackageCpsTest/cps/badversion2.cps b/Tests/FindPackageCpsTest/cps/badversion2.cps
new file mode 100644
index 0000000..99e683d
--- /dev/null
+++ b/Tests/FindPackageCpsTest/cps/badversion2.cps
@@ -0,0 +1,8 @@
+{
+ "cps_version": "0.13",
+ "name": "BadVersion2",
+ "version": "1.1a.0",
+ "version_schema": "simple",
+ "cps_path": "@prefix@/cps",
+ "components": {}
+}
diff --git a/Tests/FindPackageCpsTest/cps/badversion3.cps b/Tests/FindPackageCpsTest/cps/badversion3.cps
new file mode 100644
index 0000000..97e670d
--- /dev/null
+++ b/Tests/FindPackageCpsTest/cps/badversion3.cps
@@ -0,0 +1,8 @@
+{
+ "cps_version": "0.13",
+ "name": "BadVersion3",
+ "version": "1.1.",
+ "version_schema": "simple",
+ "cps_path": "@prefix@/cps",
+ "components": {}
+}
diff --git a/Tests/FindPackageCpsTest/cps/badversion4.cps b/Tests/FindPackageCpsTest/cps/badversion4.cps
new file mode 100644
index 0000000..2574866
--- /dev/null
+++ b/Tests/FindPackageCpsTest/cps/badversion4.cps
@@ -0,0 +1,8 @@
+{
+ "cps_version": "0.13",
+ "name": "BadVersion4",
+ "version": "+42",
+ "version_schema": "simple",
+ "cps_path": "@prefix@/cps",
+ "components": {}
+}
diff --git a/Tests/FindPackageCpsTest/cps/customversion.cps b/Tests/FindPackageCpsTest/cps/customversion.cps
new file mode 100644
index 0000000..30aa29d
--- /dev/null
+++ b/Tests/FindPackageCpsTest/cps/customversion.cps
@@ -0,0 +1,8 @@
+{
+ "cps_version": "0.13",
+ "name": "CustomVersion",
+ "version": "VII",
+ "version_schema": "roman",
+ "cps_path": "@prefix@/cps",
+ "components": {}
+}
diff --git a/Tests/FindPackageCpsTest/cps/emptymarker.cps b/Tests/FindPackageCpsTest/cps/emptymarker.cps
new file mode 100644
index 0000000..2099c92
--- /dev/null
+++ b/Tests/FindPackageCpsTest/cps/emptymarker.cps
@@ -0,0 +1,8 @@
+{
+ "cps_version": "0.13",
+ "name": "EmptyMarker",
+ "version": "1.1+",
+ "version_schema": "simple",
+ "cps_path": "@prefix@/cps",
+ "components": {}
+}
diff --git a/Tests/FindPackageCpsTest/cps/longversion.cps b/Tests/FindPackageCpsTest/cps/longversion.cps
new file mode 100644
index 0000000..300952d
--- /dev/null
+++ b/Tests/FindPackageCpsTest/cps/longversion.cps
@@ -0,0 +1,8 @@
+{
+ "cps_version": "0.13",
+ "name": "LongVersion",
+ "version": "1.1.2.3.5.8+fibonacci",
+ "version_schema": "simple",
+ "cps_path": "@prefix@/cps",
+ "components": {}
+}
diff --git a/Tests/FindPackageCpsTest/share/cps/SortLib/SortLib.cps b/Tests/FindPackageCpsTest/share/cps/SortLib/SortLib.cps
new file mode 100644
index 0000000..fdc99dc
--- /dev/null
+++ b/Tests/FindPackageCpsTest/share/cps/SortLib/SortLib.cps
@@ -0,0 +1,7 @@
+{
+ "cps_version": "0.13",
+ "name": "SortLib",
+ "version": "4.0.0",
+ "cps_path": "@prefix@/cps/SortLib",
+ "components": {}
+}
diff --git a/Tests/RunCMake/Autogen_1/AutogenDuplicateDependency.cmake b/Tests/RunCMake/Autogen_1/AutogenDuplicateDependency.cmake
new file mode 100644
index 0000000..f6968d4
--- /dev/null
+++ b/Tests/RunCMake/Autogen_1/AutogenDuplicateDependency.cmake
@@ -0,0 +1,38 @@
+enable_language(CXX)
+
+find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core)
+
+set(CMAKE_AUTOMOC ON)
+
+file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/lib.cpp"
+ CONTENT "void foo() {}")
+file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
+ CONTENT "int main() {return 0;}")
+
+# Test case.
+# App depends on Lib, which means App_autogen depends on Lib_autogen by default.
+# Which means building App_autogen should trigger the generation of the
+# fancy_generated.txt file, which is a dependency of Lib_autogen.
+
+# Create a shared library and an executable.
+add_library(Lib SHARED "${CMAKE_CURRENT_BINARY_DIR}/lib.cpp")
+add_executable(App "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
+
+# Link Lib into App more than once. Previously this was not properly handled by AUTOGEN,
+# which discarded the Lib_autogen dependency from App_autogen entirely, and the
+# file was not generated.
+foreach(i RANGE 1 ${LIB_LINK_COUNT})
+ target_link_libraries(App PRIVATE Lib)
+endforeach()
+
+# Add a custom target that generates a file.
+set(generated_file_path "${CMAKE_CURRENT_BINARY_DIR}/fancy_generated.txt")
+add_custom_command(
+ OUTPUT "${generated_file_path}"
+ COMMAND ${CMAKE_COMMAND} -E touch "${generated_file_path}"
+)
+add_custom_target(generate_file DEPENDS "${generated_file_path}")
+
+# Make sure the file is generated as part of building the Lib_autogen target.
+set_target_properties(Lib PROPERTIES
+ AUTOGEN_TARGET_DEPENDS generate_file)
diff --git a/Tests/RunCMake/Autogen_1/RunCMakeTest.cmake b/Tests/RunCMake/Autogen_1/RunCMakeTest.cmake
index 2cf60e4..c49f09c 100644
--- a/Tests/RunCMake/Autogen_1/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Autogen_1/RunCMakeTest.cmake
@@ -131,4 +131,19 @@
endblock()
endif()
endif()
+ block()
+ foreach(LIB_LINK_COUNT RANGE 1 4)
+ set(RunCMake_TEST_VARIANT_DESCRIPTION "-link-count-${LIB_LINK_COUNT}")
+ set(RunCMake_TEST_BINARY_DIR
+ "${RunCMake_BINARY_DIR}/AutogenDuplicateDependency-build-${LIB_LINK_COUNT}")
+ run_cmake_with_options(AutogenDuplicateDependency ${RunCMake_TEST_OPTIONS} -DLIB_LINK_COUNT=${LIB_LINK_COUNT})
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_EXPECT_stdout "fancy_generated.txt")
+ run_cmake_command("AutogenDuplicateDependency-build"
+ ${CMAKE_COMMAND} --build . --target App_autogen --verbose)
+ unset(RunCMake_TEST_VARIANT_DESCRIPTION)
+ unset(RunCMake_TEST_EXPECT_stdout)
+ unset(RunCMake_TEST_NO_CLEAN)
+ endforeach()
+ endblock()
endif ()
diff --git a/Tests/RunCMake/CPack/ArchiveCommon/common_helpers.cmake b/Tests/RunCMake/CPack/ArchiveCommon/common_helpers.cmake
index 948c6ab..34c8abf 100644
--- a/Tests/RunCMake/CPack/ArchiveCommon/common_helpers.cmake
+++ b/Tests/RunCMake/CPack/ArchiveCommon/common_helpers.cmake
@@ -60,7 +60,7 @@
unset(filtered_)
foreach(part_ IN LISTS prepared_)
- string(REGEX REPLACE "^/" "" part_ "${part_}")
+ string(REGEX REPLACE "^/+" "" part_ "${part_}")
if(part_)
list(APPEND filtered_ "${prefix_}${part_}")
diff --git a/Tests/RunCMake/GenEx-LIST/CMP0186-NEW-check.cmake b/Tests/RunCMake/GenEx-LIST/CMP0186-NEW-check.cmake
new file mode 100644
index 0000000..0a1ef60
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/CMP0186-NEW-check.cmake
@@ -0,0 +1,11 @@
+set(expected "
+ 000;1001;002
+ x000;1001;x002
+ x000;x01;x002
+")
+
+file(READ "${RunCMake_TEST_BINARY_DIR}/generated.txt" generated)
+
+if(NOT generated STREQUAL expected)
+ set(RunCMake_TEST_FAILED "generated:${generated}\nexpected:${expected}")
+endif()
diff --git a/Tests/RunCMake/GenEx-LIST/CMP0186-NEW.cmake b/Tests/RunCMake/GenEx-LIST/CMP0186-NEW.cmake
new file mode 100644
index 0000000..6f97614
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/CMP0186-NEW.cmake
@@ -0,0 +1,5 @@
+file(GENERATE OUTPUT "generated.txt" CONTENT "
+ $<LIST:TRANSFORM,0000;1001;0002,REPLACE,^0,>
+ $<LIST:TRANSFORM,0000;1001;0002,REPLACE,^(a|0),x>
+ $<LIST:TRANSFORM,0000;1001;0002,REPLACE,(1|^)0,x>
+")
diff --git a/Tests/RunCMake/GenEx-LIST/CMP0186-OLD-check.cmake b/Tests/RunCMake/GenEx-LIST/CMP0186-OLD-check.cmake
new file mode 100644
index 0000000..e44ab3b
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/CMP0186-OLD-check.cmake
@@ -0,0 +1,11 @@
+set(expected "
+ ;1001;2
+ xxxx;1001;xxx2
+ xxxx;xx1;xxx2
+")
+
+file(READ "${RunCMake_TEST_BINARY_DIR}/generated.txt" generated)
+
+if(NOT generated STREQUAL expected)
+ set(RunCMake_TEST_FAILED "generated:${generated}\nexpected:${expected}")
+endif()
diff --git a/Tests/RunCMake/GenEx-LIST/CMP0186-OLD.cmake b/Tests/RunCMake/GenEx-LIST/CMP0186-OLD.cmake
new file mode 100644
index 0000000..845005a
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/CMP0186-OLD.cmake
@@ -0,0 +1 @@
+include(CMP0186-NEW.cmake)
diff --git a/Tests/RunCMake/GenEx-LIST/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-LIST/RunCMakeTest.cmake
index 1946e84..0b0177a 100644
--- a/Tests/RunCMake/GenEx-LIST/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GenEx-LIST/RunCMakeTest.cmake
@@ -128,3 +128,6 @@
check_list_execution (TRANSFORM-REPLACE)
check_list_execution (REVERSE)
check_list_execution (SORT)
+
+run_cmake_with_options(CMP0186-OLD -DCMAKE_POLICY_DEFAULT_CMP0186=OLD)
+run_cmake_with_options(CMP0186-NEW -DCMAKE_POLICY_DEFAULT_CMP0186=NEW)
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index 37f780c..232e637 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -49,12 +49,14 @@
run_cmake(VsPlatformToolset)
run_cmake(VsControlFlowGuardLinkSetting)
run_cmake(VsToolOverride)
+run_cmake(VsImageVersion)
run_cmake(VsWinRTByDefault)
-set(RunCMake_GENERATOR_TOOLSET "VCTargetsPath=$(VCTargetsPath)")
-run_cmake(VsVCTargetsPath)
-unset(RunCMake_GENERATOR_TOOLSET)
+block()
+ set(RunCMake_GENERATOR_TOOLSET "VCTargetsPath=$(VCTargetsPath)")
+ run_cmake(VsVCTargetsPath)
+endblock()
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.05)
run_cmake(VsJustMyCode)
@@ -65,9 +67,8 @@
endif()
# Visual Studio 2017 has toolset version 141
-string(REPLACE "v" "" generator_toolset "${RunCMake_GENERATOR_TOOLSET}")
if (RunCMake_GENERATOR MATCHES "Visual Studio 1[0-4] 201[0-5]" OR
- (RunCMake_GENERATOR_TOOLSET AND generator_toolset VERSION_LESS "141"))
+ (RunCMake_GENERATOR_TOOLSET MATCHES "^v([0-9]+)" AND CMAKE_MATCH_1 LESS 141))
run_cmake(UnityBuildPre2017)
else()
run_cmake(UnityBuildNative)
diff --git a/Tests/RunCMake/VS10Project/VsImageVersion-check.cmake b/Tests/RunCMake/VS10Project/VsImageVersion-check.cmake
new file mode 100644
index 0000000..f0eeecd
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsImageVersion-check.cmake
@@ -0,0 +1,28 @@
+macro(ensure_link_version projectFile expected)
+ if(NOT EXISTS "${projectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${projectFile} does not exist.")
+ return()
+ endif()
+
+ file(STRINGS "${projectFile}" lines)
+ set(version "")
+ foreach(line IN LISTS lines)
+ if(line MATCHES "<Link>")
+ set(in_link TRUE)
+ elseif(line MATCHES "</Link>")
+ if(NOT version STREQUAL "${expected}")
+ set(RunCMake_TEST_FAILED "<Version> not found or incorrect: ${version} vs ${expected}")
+ return()
+ endif()
+ set(in_link FALSE)
+ set(version "")
+ elseif(in_link AND line MATCHES "<Version>([^<]+)</Version>")
+ set(version ${CMAKE_MATCH_1})
+ endif()
+ endforeach()
+endmacro()
+
+ensure_link_version("${RunCMake_TEST_BINARY_DIR}/app-C.vcxproj" 0.1)
+ensure_link_version("${RunCMake_TEST_BINARY_DIR}/app-CXX.vcxproj" 1.0)
+ensure_link_version("${RunCMake_TEST_BINARY_DIR}/lib-C.vcxproj" 65535.65535)
+ensure_link_version("${RunCMake_TEST_BINARY_DIR}/lib-CXX.vcxproj" "")
diff --git a/Tests/RunCMake/VS10Project/VsImageVersion.cmake b/Tests/RunCMake/VS10Project/VsImageVersion.cmake
new file mode 100644
index 0000000..80e49a6
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsImageVersion.cmake
@@ -0,0 +1,11 @@
+enable_language(C CXX)
+
+add_executable(app-C empty.c)
+add_executable(app-CXX empty.cxx)
+add_library(lib-C SHARED empty.c)
+add_library(lib-CXX SHARED empty.cxx)
+
+set_property(TARGET app-C PROPERTY VERSION 0.1)
+set_property(TARGET app-CXX PROPERTY VERSION 1.0)
+set_property(TARGET lib-C PROPERTY VERSION 65535.65535)
+set_property(TARGET lib-CXX PROPERTY VERSION "")
diff --git a/Tests/RunCMake/cmake_minimum_required/BeforeVersionRemoved-stderr.txt b/Tests/RunCMake/cmake_minimum_required/BeforeVersionRemoved-stderr.txt
index 62145e6..f2f41af 100644
--- a/Tests/RunCMake/cmake_minimum_required/BeforeVersionRemoved-stderr.txt
+++ b/Tests/RunCMake/cmake_minimum_required/BeforeVersionRemoved-stderr.txt
@@ -4,5 +4,7 @@
Update the VERSION argument <min> value\. Or, use the <min>\.\.\.<max> syntax
to tell CMake that the project requires at least <min> but has been updated
to work with policies introduced by <max> or earlier\.
+
+ Or, add -DCMAKE_POLICY_VERSION_MINIMUM=3\.5 to try configuring anyway\.
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/cmake_minimum_required/PolicyBeforeVersionRemoved-stderr.txt b/Tests/RunCMake/cmake_minimum_required/PolicyBeforeVersionRemoved-stderr.txt
index c9eba0f..bf4035a 100644
--- a/Tests/RunCMake/cmake_minimum_required/PolicyBeforeVersionRemoved-stderr.txt
+++ b/Tests/RunCMake/cmake_minimum_required/PolicyBeforeVersionRemoved-stderr.txt
@@ -4,5 +4,7 @@
Update the VERSION argument <min> value\. Or, use the <min>\.\.\.<max> syntax
to tell CMake that the project requires at least <min> but has been updated
to work with policies introduced by <max> or earlier\.
+
+ Or, add -DCMAKE_POLICY_VERSION_MINIMUM=3\.5 to try configuring anyway\.
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariable-stderr.txt b/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariable-stderr.txt
new file mode 100644
index 0000000..4f161bf
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariable-stderr.txt
@@ -0,0 +1,3 @@
+^CMAKE_MINIMUM_REQUIRED_VERSION='3\.1'
+CMP0071='NEW'
+CMP0072=''$
diff --git a/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariable.cmake b/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariable.cmake
new file mode 100644
index 0000000..553fc94
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariable.cmake
@@ -0,0 +1,7 @@
+set(CMAKE_POLICY_VERSION_MINIMUM 3.10)
+cmake_minimum_required(VERSION 3.1...3.4)
+message("CMAKE_MINIMUM_REQUIRED_VERSION='${CMAKE_MINIMUM_REQUIRED_VERSION}'")
+foreach(policy CMP0071 CMP0072)
+ cmake_policy(GET ${policy} status)
+ message("${policy}='${status}'")
+endforeach()
diff --git a/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariableBad-result.txt b/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariableBad-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariableBad-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariableBad-stderr.txt b/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariableBad-stderr.txt
new file mode 100644
index 0000000..3a59bb7
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariableBad-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at PolicyVersionVariableBad\.cmake:2 \(cmake_minimum_required\):
+ Invalid CMAKE_POLICY_VERSION_MINIMUM value "\.\.\.3\.10"\. A numeric
+ major\.minor\[\.patch\[\.tweak\]\] must be given\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariableBad.cmake b/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariableBad.cmake
new file mode 100644
index 0000000..763997b
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/PolicyVersionVariableBad.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_POLICY_VERSION_MINIMUM ...3.10)
+cmake_minimum_required(VERSION 3.1...3.4)
diff --git a/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake b/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake
index cd63093..d91f171 100644
--- a/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake
+++ b/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake
@@ -7,3 +7,5 @@
run_cmake(Range)
run_cmake(RangeBad)
run_cmake(Unknown)
+run_cmake(PolicyVersionVariable)
+run_cmake(PolicyVersionVariableBad)
diff --git a/Tests/RunCMake/find_package-CPS/CompatVersion.cmake b/Tests/RunCMake/find_package-CPS/CompatVersion.cmake
new file mode 100644
index 0000000..a8a26e1
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/CompatVersion.cmake
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 4.0)
+
+include(Setup.cmake)
+
+set(CMAKE_FIND_PACKAGE_SORT_ORDER NAME)
+set(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
+
+###############################################################################
+# Test finding a package that is version-compatible with our request.
+find_package(Sample 1.2.0 REQUIRED)
+if(NOT Sample_VERSION STREQUAL "1.2.3+clarke")
+ message(SEND_ERROR "Sample wrong version ${Sample_VERSION} !")
+endif()
diff --git a/Tests/RunCMake/find_package-CPS/CustomVersion.cmake b/Tests/RunCMake/find_package-CPS/CustomVersion.cmake
new file mode 100644
index 0000000..5ec5f85
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/CustomVersion.cmake
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 4.0)
+
+include(Setup.cmake)
+
+set(CMAKE_FIND_PACKAGE_SORT_ORDER NAME)
+set(CMAKE_FIND_PACKAGE_SORT_DIRECTION ASC)
+
+###############################################################################
+# Test finding a package that uses the "custom" version schema.
+find_package(CustomVersion 42 REQUIRED)
+if(NOT CustomVersion_VERSION EQUAL 42)
+ message(SEND_ERROR "CustomVersion wrong version ${CustomVersion_VERSION} !")
+endif()
diff --git a/Tests/RunCMake/find_package-CPS/ExactVersion.cmake b/Tests/RunCMake/find_package-CPS/ExactVersion.cmake
new file mode 100644
index 0000000..6fbf614
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/ExactVersion.cmake
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 4.0)
+
+include(Setup.cmake)
+
+set(CMAKE_FIND_PACKAGE_SORT_ORDER NAME)
+set(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
+
+###############################################################################
+# Test finding a package with multiple suitable versions (exact match).
+find_package(Sample 1.1.0 EXACT REQUIRED)
+if(NOT Sample_VERSION STREQUAL "1.1.0+asimov")
+ message(SEND_ERROR "Sample wrong version ${Sample_VERSION} !")
+endif()
diff --git a/Tests/RunCMake/find_package-CPS/MissingComponent-stderr.txt b/Tests/RunCMake/find_package-CPS/MissingComponent-stderr.txt
index d617cfd..14f1f0a 100644
--- a/Tests/RunCMake/find_package-CPS/MissingComponent-stderr.txt
+++ b/Tests/RunCMake/find_package-CPS/MissingComponent-stderr.txt
@@ -5,7 +5,7 @@
The following configuration files were considered but not accepted:
(
[^
-]*/Tests/RunCMake/find_package-CPS/cps/[Cc]omponent[Tt]est\.cps, version: unknown)+
+]*/Tests/RunCMake/find_package-CPS/cps/[Cc]omponent[Tt]est\.cps, version: 1\.0)+
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_package-CPS/MissingTransitiveComponent-stderr.txt b/Tests/RunCMake/find_package-CPS/MissingTransitiveComponent-stderr.txt
index c102911..50c4afe 100644
--- a/Tests/RunCMake/find_package-CPS/MissingTransitiveComponent-stderr.txt
+++ b/Tests/RunCMake/find_package-CPS/MissingTransitiveComponent-stderr.txt
@@ -5,7 +5,7 @@
The following configuration files were considered but not accepted:
(
[^
-]*/Tests/RunCMake/find_package-CPS/cps/[Cc]omponent[Tt]est\.cps, version: unknown)+
+]*/Tests/RunCMake/find_package-CPS/cps/[Cc]omponent[Tt]est\.cps, version: 1\.0)+
Call Stack \(most recent call first\):
MissingTransitiveComponent\.cmake:[0-9]+ \(find_package\)
diff --git a/Tests/RunCMake/find_package-CPS/MissingVersion1-result.txt b/Tests/RunCMake/find_package-CPS/MissingVersion1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/MissingVersion1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_package-CPS/MissingVersion1-stderr.txt b/Tests/RunCMake/find_package-CPS/MissingVersion1-stderr.txt
new file mode 100644
index 0000000..76879a2
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/MissingVersion1-stderr.txt
@@ -0,0 +1,13 @@
+CMake Error at MissingVersion1\.cmake:[0-9]+ \(find_package\):
+ Could not find a configuration file for package "Sample" that is compatible
+ with requested version "1\.2\.7"\.
+
+ The following configuration files were considered but not accepted:
+
+ .*/Tests/RunCMake/find_package-CPS/cps/sample/1\.5\.0/sample\.cps, version: 1\.5\.0\+niven
+ .*/Tests/RunCMake/find_package-CPS/cps/sample/1\.4\.2/sample\.cps, version: 1\.4\.2\+adams
+ .*/Tests/RunCMake/find_package-CPS/cps/sample/1\.2\.3/sample\.cps, version: 1\.2\.3\+clarke
+ .*/Tests/RunCMake/find_package-CPS/cps/sample/1\.1\.0/sample\.cps, version: 1\.1\.0\+asimov
+
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_package-CPS/MissingVersion1.cmake b/Tests/RunCMake/find_package-CPS/MissingVersion1.cmake
new file mode 100644
index 0000000..1a01bb9
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/MissingVersion1.cmake
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 4.0)
+
+include(Setup.cmake)
+
+set(CMAKE_FIND_PACKAGE_SORT_ORDER NAME)
+set(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
+
+###############################################################################
+# Test finding a package with no suitable version matches.
+find_package(Sample 1.2.7 REQUIRED)
diff --git a/Tests/RunCMake/find_package-CPS/MissingVersion2-result.txt b/Tests/RunCMake/find_package-CPS/MissingVersion2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/MissingVersion2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_package-CPS/MissingVersion2-stderr.txt b/Tests/RunCMake/find_package-CPS/MissingVersion2-stderr.txt
new file mode 100644
index 0000000..c984ce7
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/MissingVersion2-stderr.txt
@@ -0,0 +1,13 @@
+CMake Error at MissingVersion2\.cmake:[0-9]+ \(find_package\):
+ Could not find a configuration file for package "Sample" that is compatible
+ with requested version "1\.4\.9"\.
+
+ The following configuration files were considered but not accepted:
+
+ .*/Tests/RunCMake/find_package-CPS/cps/sample/1\.5\.0/sample\.cps, version: 1\.5\.0\+niven
+ .*/Tests/RunCMake/find_package-CPS/cps/sample/1\.4\.2/sample\.cps, version: 1\.4\.2\+adams
+ .*/Tests/RunCMake/find_package-CPS/cps/sample/1\.2\.3/sample\.cps, version: 1\.2\.3\+clarke
+ .*/Tests/RunCMake/find_package-CPS/cps/sample/1\.1\.0/sample\.cps, version: 1\.1\.0\+asimov
+
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_package-CPS/MissingVersion2.cmake b/Tests/RunCMake/find_package-CPS/MissingVersion2.cmake
new file mode 100644
index 0000000..2e8e737
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/MissingVersion2.cmake
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 4.0)
+
+include(Setup.cmake)
+
+set(CMAKE_FIND_PACKAGE_SORT_ORDER NAME)
+set(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
+
+###############################################################################
+# Test finding a package with no suitable version matches.
+find_package(Sample 1.4.9 REQUIRED)
diff --git a/Tests/RunCMake/find_package-CPS/MultipleVersions.cmake b/Tests/RunCMake/find_package-CPS/MultipleVersions.cmake
new file mode 100644
index 0000000..6fe1691
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/MultipleVersions.cmake
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 4.0)
+
+include(Setup.cmake)
+
+set(CMAKE_FIND_PACKAGE_SORT_ORDER NAME)
+set(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
+
+###############################################################################
+# Test finding a package with multiple suitable versions (permissive match).
+find_package(Sample 1.1.0 REQUIRED)
+if(NOT Sample_VERSION STREQUAL "1.2.3+clarke")
+ message(SEND_ERROR "Sample wrong version ${Sample_VERSION} !")
+endif()
diff --git a/Tests/RunCMake/find_package-CPS/RunCMakeTest.cmake b/Tests/RunCMake/find_package-CPS/RunCMakeTest.cmake
index 67de955..8df4f60 100644
--- a/Tests/RunCMake/find_package-CPS/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_package-CPS/RunCMakeTest.cmake
@@ -8,6 +8,22 @@
"-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261"
)
+# Version-matching tests
+run_cmake(ExactVersion)
+run_cmake(CompatVersion)
+run_cmake(MultipleVersions)
+run_cmake(VersionLimit1)
+run_cmake(VersionLimit2)
+run_cmake(TransitiveVersion)
+run_cmake(CustomVersion)
+
+# Version-matching failure tests
+run_cmake(MissingVersion1)
+run_cmake(MissingVersion2)
+run_cmake(VersionLimit3)
+run_cmake(VersionLimit4)
+
+# Component-related failure tests
run_cmake(MissingTransitiveDependency)
run_cmake(MissingComponent)
run_cmake(MissingComponentDependency)
diff --git a/Tests/RunCMake/find_package-CPS/TransitiveVersion.cmake b/Tests/RunCMake/find_package-CPS/TransitiveVersion.cmake
new file mode 100644
index 0000000..d4172ab
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/TransitiveVersion.cmake
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 4.0)
+
+include(Setup.cmake)
+
+set(CMAKE_FIND_PACKAGE_SORT_ORDER NAME)
+set(CMAKE_FIND_PACKAGE_SORT_DIRECTION ASC)
+
+###############################################################################
+# Test finding a package with a versioned dependency.
+find_package(TransitiveVersion REQUIRED)
+if(NOT Sample_VERSION STREQUAL "1.2.3+clarke")
+ message(SEND_ERROR "Sample wrong version ${Sample_VERSION} !")
+endif()
diff --git a/Tests/RunCMake/find_package-CPS/VersionLimit1.cmake b/Tests/RunCMake/find_package-CPS/VersionLimit1.cmake
new file mode 100644
index 0000000..877746d
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/VersionLimit1.cmake
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 4.0)
+
+include(Setup.cmake)
+
+set(CMAKE_FIND_PACKAGE_SORT_ORDER NAME)
+set(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
+
+###############################################################################
+# Test finding a package with multiple suitable versions when a version limit
+# is present but not restricting the matches.
+find_package(Sample 1.1.0...1.2.5 REQUIRED)
+if(NOT Sample_VERSION STREQUAL "1.2.3+clarke")
+ message(SEND_ERROR "Sample wrong version ${Sample_VERSION} !")
+endif()
diff --git a/Tests/RunCMake/find_package-CPS/VersionLimit2.cmake b/Tests/RunCMake/find_package-CPS/VersionLimit2.cmake
new file mode 100644
index 0000000..3d614b4
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/VersionLimit2.cmake
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 4.0)
+
+include(Setup.cmake)
+
+set(CMAKE_FIND_PACKAGE_SORT_ORDER NAME)
+set(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
+
+###############################################################################
+# Test finding a package with multiple suitable versions when a version limit
+# is present and restricting the matches.
+find_package(Sample 1.1.0...<1.2.0 REQUIRED)
+if(NOT Sample_VERSION STREQUAL "1.1.0+asimov")
+ message(SEND_ERROR "Sample wrong version ${Sample_VERSION} !")
+endif()
diff --git a/Tests/RunCMake/find_package-CPS/VersionLimit3-result.txt b/Tests/RunCMake/find_package-CPS/VersionLimit3-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/VersionLimit3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_package-CPS/VersionLimit3-stderr.txt b/Tests/RunCMake/find_package-CPS/VersionLimit3-stderr.txt
new file mode 100644
index 0000000..3b1c5ef
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/VersionLimit3-stderr.txt
@@ -0,0 +1,13 @@
+CMake Error at VersionLimit3\.cmake:[0-9]+ \(find_package\):
+ Could not find a configuration file for package "Sample" that is compatible
+ with requested version range "1\.2\.0\.\.\.1\.2\.2"\.
+
+ The following configuration files were considered but not accepted:
+
+ .*/Tests/RunCMake/find_package-CPS/cps/sample/1\.5\.0/sample\.cps, version: 1\.5\.0\+niven
+ .*/Tests/RunCMake/find_package-CPS/cps/sample/1\.4\.2/sample\.cps, version: 1\.4\.2\+adams
+ .*/Tests/RunCMake/find_package-CPS/cps/sample/1\.2\.3/sample\.cps, version: 1\.2\.3\+clarke
+ .*/Tests/RunCMake/find_package-CPS/cps/sample/1\.1\.0/sample\.cps, version: 1\.1\.0\+asimov
+
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_package-CPS/VersionLimit3.cmake b/Tests/RunCMake/find_package-CPS/VersionLimit3.cmake
new file mode 100644
index 0000000..a7101f2
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/VersionLimit3.cmake
@@ -0,0 +1,11 @@
+cmake_minimum_required(VERSION 4.0)
+
+include(Setup.cmake)
+
+set(CMAKE_FIND_PACKAGE_SORT_ORDER NAME)
+set(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
+
+###############################################################################
+# Test finding a package with multiple suitable versions when a version limit
+# is excluding a match.
+find_package(Sample 1.2.0...1.2.2 REQUIRED)
diff --git a/Tests/RunCMake/find_package-CPS/VersionLimit4-result.txt b/Tests/RunCMake/find_package-CPS/VersionLimit4-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/VersionLimit4-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_package-CPS/VersionLimit4-stderr.txt b/Tests/RunCMake/find_package-CPS/VersionLimit4-stderr.txt
new file mode 100644
index 0000000..67cef15
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/VersionLimit4-stderr.txt
@@ -0,0 +1,13 @@
+CMake Error at VersionLimit4\.cmake:[0-9]+ \(find_package\):
+ Could not find a configuration file for package "Sample" that is compatible
+ with requested version range "1\.2\.0\.\.\.<1\.2\.3"\.
+
+ The following configuration files were considered but not accepted:
+
+ .*/Tests/RunCMake/find_package-CPS/cps/sample/1\.5\.0/sample\.cps, version: 1\.5\.0\+niven
+ .*/Tests/RunCMake/find_package-CPS/cps/sample/1\.4\.2/sample\.cps, version: 1\.4\.2\+adams
+ .*/Tests/RunCMake/find_package-CPS/cps/sample/1\.2\.3/sample\.cps, version: 1\.2\.3\+clarke
+ .*/Tests/RunCMake/find_package-CPS/cps/sample/1\.1\.0/sample\.cps, version: 1\.1\.0\+asimov
+
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_package-CPS/VersionLimit4.cmake b/Tests/RunCMake/find_package-CPS/VersionLimit4.cmake
new file mode 100644
index 0000000..ade7bfb
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/VersionLimit4.cmake
@@ -0,0 +1,11 @@
+cmake_minimum_required(VERSION 4.0)
+
+include(Setup.cmake)
+
+set(CMAKE_FIND_PACKAGE_SORT_ORDER NAME)
+set(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
+
+###############################################################################
+# Test finding a package with multiple suitable versions when a version limit
+# is excluding a match.
+find_package(Sample 1.2.0...<1.2.3 REQUIRED)
diff --git a/Tests/RunCMake/find_package-CPS/cps/CustomVersion/37/CustomVersion.cps b/Tests/RunCMake/find_package-CPS/cps/CustomVersion/37/CustomVersion.cps
new file mode 100644
index 0000000..805694b
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/cps/CustomVersion/37/CustomVersion.cps
@@ -0,0 +1,8 @@
+{
+ "cps_version": "0.13",
+ "name": "CustomVersion",
+ "version": "37",
+ "version_schema": "custom",
+ "cps_path": "@prefix@/cps/CustomVersion/37",
+ "components": {}
+}
diff --git a/Tests/RunCMake/find_package-CPS/cps/CustomVersion/42/CustomVersion.cps b/Tests/RunCMake/find_package-CPS/cps/CustomVersion/42/CustomVersion.cps
new file mode 100644
index 0000000..973900e
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/cps/CustomVersion/42/CustomVersion.cps
@@ -0,0 +1,8 @@
+{
+ "cps_version": "0.13",
+ "name": "CustomVersion",
+ "version": "42",
+ "version_schema": "custom",
+ "cps_path": "@prefix@/cps/CustomVersion/42",
+ "components": {}
+}
diff --git a/Tests/RunCMake/find_package-CPS/cps/CustomVersion/55/CustomVersion.cps b/Tests/RunCMake/find_package-CPS/cps/CustomVersion/55/CustomVersion.cps
new file mode 100644
index 0000000..23226ac
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/cps/CustomVersion/55/CustomVersion.cps
@@ -0,0 +1,8 @@
+{
+ "cps_version": "0.13",
+ "name": "CustomVersion",
+ "version": "55",
+ "version_schema": "custom",
+ "cps_path": "@prefix@/cps/CustomVersion/55",
+ "components": {}
+}
diff --git a/Tests/RunCMake/find_package-CPS/cps/componenttest.cps b/Tests/RunCMake/find_package-CPS/cps/componenttest.cps
index ef49af4..dbbe095 100644
--- a/Tests/RunCMake/find_package-CPS/cps/componenttest.cps
+++ b/Tests/RunCMake/find_package-CPS/cps/componenttest.cps
@@ -1,6 +1,7 @@
{
"cps_version": "0.13",
"name": "ComponentTest",
+ "version": "1.0",
"cps_path": "@prefix@/cps",
"components": {}
}
diff --git a/Tests/RunCMake/find_package-CPS/cps/sample/1.1.0/sample.cps b/Tests/RunCMake/find_package-CPS/cps/sample/1.1.0/sample.cps
new file mode 100644
index 0000000..5716b9b
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/cps/sample/1.1.0/sample.cps
@@ -0,0 +1,8 @@
+{
+ "cps_version": "0.13",
+ "name": "Sample",
+ "version": "1.1.0+asimov",
+ "compat_version": "1.0.0",
+ "cps_path": "@prefix@/cps/sample/1.1.0",
+ "components": {}
+}
diff --git a/Tests/RunCMake/find_package-CPS/cps/sample/1.2.3/sample.cps b/Tests/RunCMake/find_package-CPS/cps/sample/1.2.3/sample.cps
new file mode 100644
index 0000000..e748528
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/cps/sample/1.2.3/sample.cps
@@ -0,0 +1,8 @@
+{
+ "cps_version": "0.13",
+ "name": "Sample",
+ "version": "1.2.3+clarke",
+ "compat_version": "1.0.0",
+ "cps_path": "@prefix@/cps/sample/1.2.3",
+ "components": {}
+}
diff --git a/Tests/RunCMake/find_package-CPS/cps/sample/1.4.2/sample.cps b/Tests/RunCMake/find_package-CPS/cps/sample/1.4.2/sample.cps
new file mode 100644
index 0000000..8b017bc
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/cps/sample/1.4.2/sample.cps
@@ -0,0 +1,8 @@
+{
+ "cps_version": "0.13",
+ "name": "Sample",
+ "version": "1.4.2+adams",
+ "compat_version": "1.3.0",
+ "cps_path": "@prefix@/cps/sample/1.4.2",
+ "components": {}
+}
diff --git a/Tests/RunCMake/find_package-CPS/cps/sample/1.5.0/sample.cps b/Tests/RunCMake/find_package-CPS/cps/sample/1.5.0/sample.cps
new file mode 100644
index 0000000..bf9a375
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/cps/sample/1.5.0/sample.cps
@@ -0,0 +1,7 @@
+{
+ "cps_version": "0.13",
+ "name": "Sample",
+ "version": "1.5.0+niven",
+ "cps_path": "@prefix@/cps/sample/1.5.0",
+ "components": {}
+}
diff --git a/Tests/RunCMake/find_package-CPS/cps/transitiveversion.cps b/Tests/RunCMake/find_package-CPS/cps/transitiveversion.cps
new file mode 100644
index 0000000..71b2f03
--- /dev/null
+++ b/Tests/RunCMake/find_package-CPS/cps/transitiveversion.cps
@@ -0,0 +1,11 @@
+{
+ "cps_version": "0.13",
+ "name": "TransitiveVersion",
+ "cps_path": "@prefix@/cps",
+ "requires": {
+ "Sample": {
+ "version": "1.2.0"
+ }
+ },
+ "components": {}
+}
diff --git a/Tests/RunCMake/list/CMP0186.cmake b/Tests/RunCMake/list/CMP0186.cmake
new file mode 100644
index 0000000..088b03e
--- /dev/null
+++ b/Tests/RunCMake/list/CMP0186.cmake
@@ -0,0 +1,43 @@
+set(mylist 0000 1001 0002)
+
+# OLD
+cmake_policy(SET CMP0186 OLD)
+
+unset(output)
+list(TRANSFORM mylist REPLACE "^0" "" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL ";1001;2")
+ message(FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \";1001;2\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "^(a|0)" "x" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "xxxx;1001;xxx2")
+ message(FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"xxxx;1001;xxx2\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(1|^)0" "x" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "xxxx;xx1;xxx2")
+ message(FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"xxxx;xx1;xxx2\"")
+endif()
+
+# NEW, same cases as above
+cmake_policy(SET CMP0186 NEW)
+
+unset(output)
+list(TRANSFORM mylist REPLACE "^0" "" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "000;1001;002")
+ message(FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"000;1001;002\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "^(a|0)" "x" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "x000;1001;x002")
+ message(FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"x000;1001;x002\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(1|^)0" "x" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "x000;x01;x002")
+ message(FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"x000;xx1;x002\"")
+endif()
diff --git a/Tests/RunCMake/list/RunCMakeTest.cmake b/Tests/RunCMake/list/RunCMakeTest.cmake
index 1b67635..e428cd0 100644
--- a/Tests/RunCMake/list/RunCMakeTest.cmake
+++ b/Tests/RunCMake/list/RunCMakeTest.cmake
@@ -90,6 +90,7 @@
run_cmake(TRANSFORM-APPEND)
run_cmake(TRANSFORM-PREPEND)
run_cmake(TRANSFORM-REPLACE)
+run_cmake(CMP0186)
# argument tests
run_cmake(SORT-WrongOption)
diff --git a/Tests/RunCMake/string/CMP0186.cmake b/Tests/RunCMake/string/CMP0186.cmake
new file mode 100644
index 0000000..bc9dcf8
--- /dev/null
+++ b/Tests/RunCMake/string/CMP0186.cmake
@@ -0,0 +1,90 @@
+function(check_output name expected)
+ set(output "${${name}}")
+ if(NOT output STREQUAL expected)
+ message(FATAL_ERROR "\"string(REGEX)\" set ${name} to \"${output}\", expected \"${expected}\"")
+ endif()
+endfunction()
+
+# OLD
+cmake_policy(SET CMP0186 OLD)
+
+string(REGEX MATCHALL "^0" out "0000")
+check_output(out "0;0;0;0")
+
+string(REGEX MATCHALL "^0+" out "0000")
+check_output(out "0000")
+
+string(REGEX MATCHALL "^(0|a)" out "0000" )
+check_output(out "0;0;0;0")
+
+string(REGEX MATCHALL "^(0|a)" out "aaaa")
+check_output(out "a;a;a;a")
+
+string(REGEX MATCHALL "^(0|a)" out "a0a0")
+check_output(out "a;0;a;0")
+
+string(REGEX MATCHALL "(^|a)0" out "00a0")
+check_output(out "0;0;a0")
+
+string(REGEX REPLACE "^0" "" out "0000")
+check_output(out "")
+
+string(REGEX REPLACE "^0" "x" out "0000")
+check_output(out "xxxx")
+
+string(REGEX REPLACE "^0+" "x" out "0000")
+check_output(out "x")
+
+string(REGEX REPLACE "^(0|a)" "x" out "0000")
+check_output(out "xxxx")
+
+string(REGEX REPLACE "^(0|a)" "x" out "aaaa")
+check_output(out "xxxx")
+
+string(REGEX REPLACE "^(0|a)" "x" out "a0a0")
+check_output(out "xxxx")
+
+string(REGEX REPLACE "(^|a)0" "x" out "00a0")
+check_output(out "xxx")
+
+# NEW, same cases as above
+cmake_policy(SET CMP0186 NEW)
+
+string(REGEX MATCHALL "^0" out "0000")
+check_output(out "0")
+
+string(REGEX MATCHALL "^0+" out "0000")
+check_output(out "0000")
+
+string(REGEX MATCHALL "^(0|a)" out "0000")
+check_output(out "0")
+
+string(REGEX MATCHALL "^(0|a)" out "aaaa")
+check_output(out "a")
+
+string(REGEX MATCHALL "^(0|a)" out "a0a0")
+check_output(out "a")
+
+string(REGEX MATCHALL "(^|a)0" out "00a0")
+check_output(out "0;a0")
+
+string(REGEX REPLACE "^0" "" out "0000")
+check_output(out "000")
+
+string(REGEX REPLACE "^0" "x" out "0000")
+check_output(out "x000")
+
+string(REGEX REPLACE "^0+" "x" out "0000")
+check_output(out "x")
+
+string(REGEX REPLACE "^(0|a)" "x" out "0000")
+check_output(out "x000")
+
+string(REGEX REPLACE "^(0|a)" "x" out "aaaa")
+check_output(out "xaaa")
+
+string(REGEX REPLACE "^(0|a)" "x" out "a0a0")
+check_output(out "x0a0")
+
+string(REGEX REPLACE "(^|a)0" "x" out "00a0")
+check_output(out "x0x")
diff --git a/Tests/RunCMake/string/RegexMultiMatchClear-stderr.txt b/Tests/RunCMake/string/RegexMultiMatchClear-stderr.txt
index 4360d79..9ebf49b 100644
--- a/Tests/RunCMake/string/RegexMultiMatchClear-stderr.txt
+++ b/Tests/RunCMake/string/RegexMultiMatchClear-stderr.txt
@@ -1,12 +1,12 @@
-^matches: Some::;Scope
+^matches: Some::
results from: string\(REGEX MATCHALL\)
-CMAKE_MATCH_0: -->Scope<--
-CMAKE_MATCH_1: -->Scope<--
-CMAKE_MATCH_2: --><--
-CMAKE_MATCH_COUNT: -->1<--
-replace: \[Some\]\[Scope\]
+CMAKE_MATCH_0: -->Some::<--
+CMAKE_MATCH_1: -->Some<--
+CMAKE_MATCH_2: -->::<--
+CMAKE_MATCH_COUNT: -->2<--
+replace: \[Some\]Scope
results from: string\(REGEX REPLACE\)
-CMAKE_MATCH_0: -->Scope<--
-CMAKE_MATCH_1: -->Scope<--
-CMAKE_MATCH_2: --><--
-CMAKE_MATCH_COUNT: -->1<--$
+CMAKE_MATCH_0: -->Some::<--
+CMAKE_MATCH_1: -->Some<--
+CMAKE_MATCH_2: -->::<--
+CMAKE_MATCH_COUNT: -->2<--$
diff --git a/Tests/RunCMake/string/RegexMultiMatchClear.cmake b/Tests/RunCMake/string/RegexMultiMatchClear.cmake
index 788ba5e..99d4646 100644
--- a/Tests/RunCMake/string/RegexMultiMatchClear.cmake
+++ b/Tests/RunCMake/string/RegexMultiMatchClear.cmake
@@ -1,3 +1,5 @@
+cmake_policy(SET CMP0186 NEW)
+
function (output_results msg)
message("results from: ${msg}")
message("CMAKE_MATCH_0: -->${CMAKE_MATCH_0}<--")
diff --git a/Tests/RunCMake/string/RunCMakeTest.cmake b/Tests/RunCMake/string/RunCMakeTest.cmake
index ff0bb51..e352fcb 100644
--- a/Tests/RunCMake/string/RunCMakeTest.cmake
+++ b/Tests/RunCMake/string/RunCMakeTest.cmake
@@ -35,6 +35,7 @@
run_cmake(RegexClear)
run_cmake(RegexMultiMatchClear)
+run_cmake(CMP0186)
run_cmake(UTF-16BE)
run_cmake(UTF-16LE)
diff --git a/Utilities/Release/linux/aarch64/cache.txt b/Utilities/Release/linux/aarch64/cache.txt
index 9b13440..3cc9712 100644
--- a/Utilities/Release/linux/aarch64/cache.txt
+++ b/Utilities/Release/linux/aarch64/cache.txt
@@ -8,7 +8,7 @@
# Enable ssl support in curl
CMAKE_USE_OPENSSL:BOOL=ON
-OPENSSL_CRYPTO_LIBRARY:STRING=/opt/openssl/lib/libcrypto.a;-pthread
+OPENSSL_CRYPTO_LIBRARY:STRING=/opt/openssl/lib/libcrypto.a
OPENSSL_INCLUDE_DIR:PATH=/opt/openssl/include
OPENSSL_SSL_LIBRARY:FILEPATH=/opt/openssl/lib/libssl.a
diff --git a/Utilities/Release/linux/x86_64/cache.txt b/Utilities/Release/linux/x86_64/cache.txt
index a40f8fb..46dc81a 100644
--- a/Utilities/Release/linux/x86_64/cache.txt
+++ b/Utilities/Release/linux/x86_64/cache.txt
@@ -8,7 +8,7 @@
# Enable ssl support in curl
CMAKE_USE_OPENSSL:BOOL=ON
-OPENSSL_CRYPTO_LIBRARY:STRING=/opt/openssl/lib/libcrypto.a;-pthread
+OPENSSL_CRYPTO_LIBRARY:STRING=/opt/openssl/lib/libcrypto.a
OPENSSL_INCLUDE_DIR:PATH=/opt/openssl/include
OPENSSL_SSL_LIBRARY:FILEPATH=/opt/openssl/lib/libssl.a
diff --git a/Utilities/Scripts/update-curl.bash b/Utilities/Scripts/update-curl.bash
index 82be5a3..a1c82d3 100755
--- a/Utilities/Scripts/update-curl.bash
+++ b/Utilities/Scripts/update-curl.bash
@@ -8,7 +8,7 @@
readonly ownership="Curl Upstream <curl-library@lists.haxx.se>"
readonly subtree="Utilities/cmcurl"
readonly repo="https://github.com/curl/curl.git"
-readonly tag="curl-8_12_0"
+readonly tag="curl-8_12_1"
readonly shortlog=false
readonly paths="
CMake/*
diff --git a/Utilities/cmcurl/CMake/CurlTests.c b/Utilities/cmcurl/CMake/CurlTests.c
index 1428238..c5a5257 100644
--- a/Utilities/cmcurl/CMake/CurlTests.c
+++ b/Utilities/cmcurl/CMake/CurlTests.c
@@ -70,7 +70,7 @@
#include <netdb.h>
int main(void)
{
- char *address = "example.com";
+ const char *address = "example.com";
int length = 0;
int type = 0;
struct hostent h;
@@ -167,7 +167,7 @@
int main(void)
{
/* ioctlsocket source code */
- int socket;
+ int socket = -1;
unsigned long flags = ioctlsocket(socket, FIONBIO, &flags);
;
return 0;
diff --git a/Utilities/cmcurl/CMake/FindBrotli.cmake b/Utilities/cmcurl/CMake/FindBrotli.cmake
index 8a692bd..b72f190 100644
--- a/Utilities/cmcurl/CMake/FindBrotli.cmake
+++ b/Utilities/cmcurl/CMake/FindBrotli.cmake
@@ -51,6 +51,7 @@
endif()
if(BROTLI_FOUND AND BROTLIDEC_FOUND)
+ set(Brotli_FOUND TRUE)
list(APPEND BROTLIDEC_LIBRARIES ${BROTLI_LIBRARIES}) # order is significant: brotlidec then brotlicommon
list(REVERSE BROTLIDEC_LIBRARIES)
list(REMOVE_DUPLICATES BROTLIDEC_LIBRARIES)
diff --git a/Utilities/cmcurl/CMake/FindCares.cmake b/Utilities/cmcurl/CMake/FindCares.cmake
index 67dec09..cc47e2d 100644
--- a/Utilities/cmcurl/CMake/FindCares.cmake
+++ b/Utilities/cmcurl/CMake/FindCares.cmake
@@ -48,6 +48,7 @@
endif()
if(CARES_FOUND)
+ set(Cares_FOUND TRUE)
string(REPLACE ";" " " CARES_CFLAGS "${CARES_CFLAGS}")
message(STATUS "Found Cares (via pkg-config): ${CARES_INCLUDE_DIRS} (found version \"${CARES_VERSION}\")")
else()
diff --git a/Utilities/cmcurl/CMake/FindLibgsasl.cmake b/Utilities/cmcurl/CMake/FindLibgsasl.cmake
index c0ce673..c726ce1 100644
--- a/Utilities/cmcurl/CMake/FindLibgsasl.cmake
+++ b/Utilities/cmcurl/CMake/FindLibgsasl.cmake
@@ -48,6 +48,7 @@
endif()
if(LIBGSASL_FOUND)
+ set(Libgsasl_FOUND TRUE)
string(REPLACE ";" " " LIBGSASL_CFLAGS "${LIBGSASL_CFLAGS}")
message(STATUS "Found Libgsasl (via pkg-config): ${LIBGSASL_INCLUDE_DIRS} (found version \"${LIBGSASL_VERSION}\")")
else()
diff --git a/Utilities/cmcurl/CMake/FindLibidn2.cmake b/Utilities/cmcurl/CMake/FindLibidn2.cmake
index a8887e8..f8f00f0 100644
--- a/Utilities/cmcurl/CMake/FindLibidn2.cmake
+++ b/Utilities/cmcurl/CMake/FindLibidn2.cmake
@@ -48,6 +48,7 @@
endif()
if(LIBIDN2_FOUND)
+ set(Libidn2_FOUND TRUE)
string(REPLACE ";" " " LIBIDN2_CFLAGS "${LIBIDN2_CFLAGS}")
message(STATUS "Found Libidn2 (via pkg-config): ${LIBIDN2_INCLUDE_DIRS} (found version \"${LIBIDN2_VERSION}\")")
else()
diff --git a/Utilities/cmcurl/CMake/FindLibpsl.cmake b/Utilities/cmcurl/CMake/FindLibpsl.cmake
index 0d96995..d6fde4b 100644
--- a/Utilities/cmcurl/CMake/FindLibpsl.cmake
+++ b/Utilities/cmcurl/CMake/FindLibpsl.cmake
@@ -48,6 +48,7 @@
endif()
if(LIBPSL_FOUND AND LIBPSL_INCLUDE_DIRS)
+ set(Libpsl_FOUND TRUE)
string(REPLACE ";" " " LIBPSL_CFLAGS "${LIBPSL_CFLAGS}")
message(STATUS "Found Libpsl (via pkg-config): ${LIBPSL_INCLUDE_DIRS} (found version \"${LIBPSL_VERSION}\")")
else()
diff --git a/Utilities/cmcurl/CMake/FindLibrtmp.cmake b/Utilities/cmcurl/CMake/FindLibrtmp.cmake
index dd3fb9e..50fc969 100644
--- a/Utilities/cmcurl/CMake/FindLibrtmp.cmake
+++ b/Utilities/cmcurl/CMake/FindLibrtmp.cmake
@@ -48,6 +48,7 @@
endif()
if(LIBRTMP_FOUND AND LIBRTMP_INCLUDE_DIRS)
+ set(Librtmp_FOUND TRUE)
string(REPLACE ";" " " LIBRTMP_CFLAGS "${LIBRTMP_CFLAGS}")
message(STATUS "Found Librtmp (via pkg-config): ${LIBRTMP_INCLUDE_DIRS} (found version \"${LIBRTMP_VERSION}\")")
else()
diff --git a/Utilities/cmcurl/CMake/FindLibssh.cmake b/Utilities/cmcurl/CMake/FindLibssh.cmake
index b8b4a51..e2b27d9 100644
--- a/Utilities/cmcurl/CMake/FindLibssh.cmake
+++ b/Utilities/cmcurl/CMake/FindLibssh.cmake
@@ -48,6 +48,7 @@
endif()
if(LIBSSH_FOUND)
+ set(Libssh_FOUND TRUE)
string(REPLACE ";" " " LIBSSH_CFLAGS "${LIBSSH_CFLAGS}")
message(STATUS "Found Libssh (via pkg-config): ${LIBSSH_INCLUDE_DIRS} (found version \"${LIBSSH_VERSION}\")")
else()
diff --git a/Utilities/cmcurl/CMake/FindLibssh2.cmake b/Utilities/cmcurl/CMake/FindLibssh2.cmake
index dfb0582..0b81ecb 100644
--- a/Utilities/cmcurl/CMake/FindLibssh2.cmake
+++ b/Utilities/cmcurl/CMake/FindLibssh2.cmake
@@ -48,6 +48,7 @@
endif()
if(LIBSSH2_FOUND AND LIBSSH2_INCLUDE_DIRS)
+ set(Libssh2_FOUND TRUE)
string(REPLACE ";" " " LIBSSH2_CFLAGS "${LIBSSH2_CFLAGS}")
message(STATUS "Found Libssh2 (via pkg-config): ${LIBSSH2_INCLUDE_DIRS} (found version \"${LIBSSH2_VERSION}\")")
else()
diff --git a/Utilities/cmcurl/CMake/FindLibuv.cmake b/Utilities/cmcurl/CMake/FindLibuv.cmake
index 8255eaa..b16b355 100644
--- a/Utilities/cmcurl/CMake/FindLibuv.cmake
+++ b/Utilities/cmcurl/CMake/FindLibuv.cmake
@@ -48,6 +48,7 @@
endif()
if(LIBUV_FOUND)
+ set(Libuv_FOUND TRUE)
string(REPLACE ";" " " LIBUV_CFLAGS "${LIBUV_CFLAGS}")
message(STATUS "Found Libuv (via pkg-config): ${LIBUV_INCLUDE_DIRS} (found version \"${LIBUV_VERSION}\")")
else()
diff --git a/Utilities/cmcurl/CMake/FindMbedTLS.cmake b/Utilities/cmcurl/CMake/FindMbedTLS.cmake
index c3ba27d..83f1371 100644
--- a/Utilities/cmcurl/CMake/FindMbedTLS.cmake
+++ b/Utilities/cmcurl/CMake/FindMbedTLS.cmake
@@ -60,6 +60,7 @@
endif()
if(MBEDTLS_FOUND AND MBEDX509_FOUND AND MBEDCRYPTO_FOUND)
+ set(MbedTLS_FOUND TRUE)
list(APPEND MBEDTLS_LIBRARIES ${MBEDX509_LIBRARIES} ${MBEDCRYPTO_LIBRARIES})
list(REVERSE MBEDTLS_LIBRARIES)
list(REMOVE_DUPLICATES MBEDTLS_LIBRARIES)
diff --git a/Utilities/cmcurl/CMake/FindNettle.cmake b/Utilities/cmcurl/CMake/FindNettle.cmake
index 753633a..c2decf6 100644
--- a/Utilities/cmcurl/CMake/FindNettle.cmake
+++ b/Utilities/cmcurl/CMake/FindNettle.cmake
@@ -48,6 +48,7 @@
endif()
if(NETTLE_FOUND)
+ set(Nettle_FOUND TRUE)
string(REPLACE ";" " " NETTLE_CFLAGS "${NETTLE_CFLAGS}")
message(STATUS "Found Nettle (via pkg-config): ${NETTLE_INCLUDE_DIRS} (found version \"${NETTLE_VERSION}\")")
else()
diff --git a/Utilities/cmcurl/CMake/FindQuiche.cmake b/Utilities/cmcurl/CMake/FindQuiche.cmake
index 092aff8..6939c64 100644
--- a/Utilities/cmcurl/CMake/FindQuiche.cmake
+++ b/Utilities/cmcurl/CMake/FindQuiche.cmake
@@ -48,6 +48,7 @@
endif()
if(QUICHE_FOUND)
+ set(Quiche_FOUND TRUE)
string(REPLACE ";" " " QUICHE_CFLAGS "${QUICHE_CFLAGS}")
message(STATUS "Found Quiche (via pkg-config): ${QUICHE_INCLUDE_DIRS} (found version \"${QUICHE_VERSION}\")")
else()
diff --git a/Utilities/cmcurl/CMake/FindRustls.cmake b/Utilities/cmcurl/CMake/FindRustls.cmake
index 51f4506..564b08c 100644
--- a/Utilities/cmcurl/CMake/FindRustls.cmake
+++ b/Utilities/cmcurl/CMake/FindRustls.cmake
@@ -48,6 +48,7 @@
endif()
if(RUSTLS_FOUND)
+ set(Rustls_FOUND TRUE)
string(REPLACE ";" " " RUSTLS_CFLAGS "${RUSTLS_CFLAGS}")
message(STATUS "Found Rustls (via pkg-config): ${RUSTLS_INCLUDE_DIRS} (found version \"${RUSTLS_VERSION}\")")
else()
diff --git a/Utilities/cmcurl/CMake/FindWolfSSL.cmake b/Utilities/cmcurl/CMake/FindWolfSSL.cmake
index 3163fee..e33fef8 100644
--- a/Utilities/cmcurl/CMake/FindWolfSSL.cmake
+++ b/Utilities/cmcurl/CMake/FindWolfSSL.cmake
@@ -57,6 +57,7 @@
endif()
if(WOLFSSL_FOUND)
+ set(WolfSSL_FOUND TRUE)
string(REPLACE ";" " " WOLFSSL_CFLAGS "${WOLFSSL_CFLAGS}")
message(STATUS "Found WolfSSL (via pkg-config): ${WOLFSSL_INCLUDE_DIRS} (found version \"${WOLFSSL_VERSION}\")")
else()
diff --git a/Utilities/cmcurl/CMake/FindZstd.cmake b/Utilities/cmcurl/CMake/FindZstd.cmake
index dbfede7..0ea1fef 100644
--- a/Utilities/cmcurl/CMake/FindZstd.cmake
+++ b/Utilities/cmcurl/CMake/FindZstd.cmake
@@ -57,6 +57,7 @@
endif()
if(ZSTD_FOUND)
+ set(Zstd_FOUND TRUE)
string(REPLACE ";" " " ZSTD_CFLAGS "${ZSTD_CFLAGS}")
message(STATUS "Found Zstd (via pkg-config): ${ZSTD_INCLUDE_DIRS} (found version \"${ZSTD_VERSION}\")")
else()
diff --git a/Utilities/cmcurl/CMake/Macros.cmake b/Utilities/cmcurl/CMake/Macros.cmake
index ad0df18..8653f36 100644
--- a/Utilities/cmcurl/CMake/Macros.cmake
+++ b/Utilities/cmcurl/CMake/Macros.cmake
@@ -34,11 +34,14 @@
endif()
endmacro()
+set(CURL_TEST_DEFINES "") # Initialize global variable
+
# For other curl specific tests, use this macro.
# Return result in variable: CURL_TEST_OUTPUT
macro(curl_internal_test _curl_test)
if(NOT DEFINED "${_curl_test}")
string(REPLACE ";" " " _cmake_required_definitions "${CMAKE_REQUIRED_DEFINITIONS}")
+ set(_curl_test_add_libraries "")
if(CMAKE_REQUIRED_LIBRARIES)
set(_curl_test_add_libraries
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
diff --git a/Utilities/cmcurl/CMake/OtherTests.cmake b/Utilities/cmcurl/CMake/OtherTests.cmake
index 0188538..8a7faaf 100644
--- a/Utilities/cmcurl/CMake/OtherTests.cmake
+++ b/Utilities/cmcurl/CMake/OtherTests.cmake
@@ -65,6 +65,9 @@
set(_source_epilogue "#undef inline")
curl_add_header_include(HAVE_SYS_TIME_H "sys/time.h")
check_c_source_compiles("${_source_epilogue}
+ #ifdef _MSC_VER
+ #include <winsock2.h>
+ #endif
#include <time.h>
int main(void)
{
diff --git a/Utilities/cmcurl/CMake/PickyWarnings.cmake b/Utilities/cmcurl/CMake/PickyWarnings.cmake
index 23341c4..15f771b 100644
--- a/Utilities/cmcurl/CMake/PickyWarnings.cmake
+++ b/Utilities/cmcurl/CMake/PickyWarnings.cmake
@@ -274,6 +274,6 @@
if(_picky)
string(REPLACE ";" " " _picky "${_picky}")
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_picky}")
+ string(APPEND CMAKE_C_FLAGS " ${_picky}")
message(STATUS "Picky compiler options: ${_picky}")
endif()
diff --git a/Utilities/cmcurl/CMake/Utilities.cmake b/Utilities/cmcurl/CMake/Utilities.cmake
index 869d591..ff2173f 100644
--- a/Utilities/cmcurl/CMake/Utilities.cmake
+++ b/Utilities/cmcurl/CMake/Utilities.cmake
@@ -47,7 +47,7 @@
if(_var_advanced)
set(_var_advanced " [adv]")
endif()
- message("${_var}${_var_type}${_var_advanced} = ${${_var}}")
+ message("${_var}${_var_type}${_var_advanced} = '${${_var}}'")
endforeach()
message("::endgroup::")
endfunction()
diff --git a/Utilities/cmcurl/CMake/win32-cache.cmake b/Utilities/cmcurl/CMake/win32-cache.cmake
index 9d46736..272f513 100644
--- a/Utilities/cmcurl/CMake/win32-cache.cmake
+++ b/Utilities/cmcurl/CMake/win32-cache.cmake
@@ -74,12 +74,12 @@
set(HAVE_UNISTD_H 0)
set(HAVE_STDDEF_H 1) # detected by CMake internally in check_type_size()
set(HAVE_STDATOMIC_H 0)
- if(NOT MSVC_VERSION LESS 1600)
+ if(MSVC_VERSION GREATER_EQUAL 1600)
set(HAVE_STDINT_H 1) # detected by CMake internally in check_type_size()
else()
set(HAVE_STDINT_H 0) # detected by CMake internally in check_type_size()
endif()
- if(NOT MSVC_VERSION LESS 1800)
+ if(MSVC_VERSION GREATER_EQUAL 1800)
set(HAVE_STDBOOL_H 1)
set(HAVE_STRTOLL 1)
else()
@@ -87,7 +87,7 @@
set(HAVE_STRTOLL 0)
endif()
set(HAVE_BOOL_T "${HAVE_STDBOOL_H}")
- if(NOT MSVC_VERSION LESS 1900)
+ if(MSVC_VERSION GREATER_EQUAL 1900)
set(HAVE_SNPRINTF 1)
else()
set(HAVE_SNPRINTF 0)
diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt
index 4d4166a..75b5102 100644
--- a/Utilities/cmcurl/CMakeLists.txt
+++ b/Utilities/cmcurl/CMakeLists.txt
@@ -1,4 +1,5 @@
# Set curl options as needed for CMake build
+set(_CURL_QUICK_DETECT ON)
set(BUILD_CURL_EXE OFF CACHE INTERNAL "No curl exe")
set(BUILD_DASHBOARD_REPORTS OFF CACHE INTERNAL "No curl dashboard reports")
set(BUILD_RELEASE_DEBUG_DIRS OFF CACHE INTERNAL "No curl release/debug dirs")
@@ -235,13 +236,13 @@
else()
set(_cache_var_type ":${_cache_var_type}")
endif()
- set(_cmake_args "${_cmake_args} -D${_cache_var}${_cache_var_type}=\"${_cache_var_value}\"")
+ string(APPEND _cmake_args " -D${_cache_var}${_cache_var_type}=\"${_cache_var_value}\"")
endif()
endforeach()
endif()
endif() # XXX(cmake): end
-set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")
+set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH})
include(Utilities)
include(Macros)
include(CMakeDependentOption)
@@ -289,49 +290,49 @@
set(_target_flags "")
if(APPLE)
- set(_target_flags "${_target_flags} APPLE")
+ string(APPEND _target_flags " APPLE")
endif()
if(UNIX)
- set(_target_flags "${_target_flags} UNIX")
+ string(APPEND _target_flags " UNIX")
endif()
if(BSD)
- set(_target_flags "${_target_flags} BSD")
+ string(APPEND _target_flags " BSD")
endif()
if(ANDROID)
- set(_target_flags "${_target_flags} ANDROID-${ANDROID_PLATFORM_LEVEL}")
+ string(APPEND _target_flags " ANDROID-${ANDROID_PLATFORM_LEVEL}")
endif()
if(WIN32)
- set(_target_flags "${_target_flags} WIN32")
+ string(APPEND _target_flags " WIN32")
endif()
if(WINDOWS_STORE)
- set(_target_flags "${_target_flags} UWP")
+ string(APPEND _target_flags " UWP")
endif()
if(CYGWIN)
- set(_target_flags "${_target_flags} CYGWIN")
+ string(APPEND _target_flags " CYGWIN")
endif()
if(MSYS)
- set(_target_flags "${_target_flags} MSYS")
+ string(APPEND _target_flags " MSYS")
endif()
if(DOS)
- set(_target_flags "${_target_flags} DOS")
+ string(APPEND _target_flags " DOS")
endif()
if(AMIGA)
- set(_target_flags "${_target_flags} AMIGA")
+ string(APPEND _target_flags " AMIGA")
endif()
if(CMAKE_COMPILER_IS_GNUCC)
- set(_target_flags "${_target_flags} GCC")
+ string(APPEND _target_flags " GCC")
endif()
if(MINGW)
- set(_target_flags "${_target_flags} MINGW")
+ string(APPEND _target_flags " MINGW")
endif()
if(MSVC)
- set(_target_flags "${_target_flags} MSVC-${MSVC_VERSION}")
+ string(APPEND _target_flags " MSVC-${MSVC_VERSION}")
endif()
if(VCPKG_TOOLCHAIN)
- set(_target_flags "${_target_flags} VCPKG")
+ string(APPEND _target_flags " VCPKG")
endif()
if(CMAKE_CROSSCOMPILING)
- set(_target_flags "${_target_flags} CROSS")
+ string(APPEND _target_flags " CROSS")
endif()
if(0) # XXX(cmake): not needed for build within cmake
message(STATUS "CMake platform flags:${_target_flags}")
@@ -379,8 +380,8 @@
option(CURL_STATIC_CRT "Build libcurl with static CRT with MSVC (/MT)" OFF)
if(CURL_STATIC_CRT AND MSVC)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
- set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -MT")
- set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -MTd")
+ string(APPEND CMAKE_C_FLAGS_RELEASE " -MT")
+ string(APPEND CMAKE_C_FLAGS_DEBUG " -MTd")
endif()
option(ENABLE_UNICODE "Use the Unicode version of the Windows API functions" OFF)
@@ -395,7 +396,11 @@
endif()
if(0) # XXX(cmake): not needed for build within cmake
- list(APPEND CMAKE_REQUIRED_DEFINITIONS "-DWIN32_LEAN_AND_MEAN") # Apply to all feature checks
+ # Apply to all feature checks
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS "-DWIN32_LEAN_AND_MEAN")
+ if(MSVC)
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D_CRT_NONSTDC_NO_DEPRECATE") # for strdup() detection
+ endif()
set(CURL_TARGET_WINDOWS_VERSION "" CACHE STRING "Minimum target Windows version as hex string")
if(CURL_TARGET_WINDOWS_VERSION)
@@ -446,7 +451,7 @@
endif() # XXX(cmake): end
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_GNU_SOURCE") # Required for sendmmsg()
+ string(APPEND CMAKE_C_FLAGS " -D_GNU_SOURCE") # Required for sendmmsg()
endif()
option(ENABLE_DEBUG "Enable curl debug features (for developing curl itself)" OFF)
@@ -455,10 +460,6 @@
endif()
option(ENABLE_CURLDEBUG "Enable TrackMemory debug feature" ${ENABLE_DEBUG})
-if(MSVC)
- set(ENABLE_CURLDEBUG OFF) # FIXME: TrackMemory + MSVC fails test 558 and 1330. Tested with static build, Debug mode.
-endif()
-
if(ENABLE_DEBUG)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS "DEBUGBUILD")
endif()
@@ -542,7 +543,7 @@
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${CARES_PC_REQUIRES})
link_directories(${CARES_LIBRARY_DIRS})
if(CARES_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CARES_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${CARES_CFLAGS}")
endif()
endif()
@@ -679,35 +680,6 @@
set(CURL_DISABLE_TELNET ON) # telnet code needs fixing to compile for UWP.
endif()
-option(ENABLE_IPV6 "Enable IPv6 support" ON)
-mark_as_advanced(ENABLE_IPV6)
-if(ENABLE_IPV6 AND NOT WIN32)
- include(CheckStructHasMember)
- check_struct_has_member("struct sockaddr_in6" "sin6_addr" "netinet/in.h" HAVE_SOCKADDR_IN6_SIN6_ADDR)
- check_struct_has_member("struct sockaddr_in6" "sin6_scope_id" "netinet/in.h" HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
- if(NOT HAVE_SOCKADDR_IN6_SIN6_ADDR)
- if(NOT DOS AND NOT AMIGA)
- message(WARNING "struct sockaddr_in6 not available, disabling IPv6 support")
- endif()
- # Force the feature off as this name is used as guard macro...
- set(ENABLE_IPV6 OFF CACHE BOOL "Enable IPv6 support" FORCE)
- endif()
-
- if(APPLE AND NOT ENABLE_ARES)
- set(_use_core_foundation_and_core_services ON)
-
- find_library(SYSTEMCONFIGURATION_FRAMEWORK NAMES "SystemConfiguration")
- mark_as_advanced(SYSTEMCONFIGURATION_FRAMEWORK)
- if(NOT SYSTEMCONFIGURATION_FRAMEWORK)
- message(FATAL_ERROR "SystemConfiguration framework not found")
- endif()
- list(APPEND CURL_LIBS "-framework SystemConfiguration")
- endif()
-endif()
-if(ENABLE_IPV6)
- set(USE_IPV6 ON)
-endif()
-
if(0) # XXX(cmake): not needed for build within cmake
find_package(Perl)
@@ -740,7 +712,7 @@
# Disable warnings on Borland to avoid changing 3rd party code.
if(BORLAND)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w-")
+ string(APPEND CMAKE_C_FLAGS " -w-")
endif()
# If we are on AIX, do the _ALL_SOURCE magic
@@ -766,15 +738,18 @@
include(CheckTypeSize)
include(CheckCSourceCompiles)
-if(WIN32)
- # Preload settings on Windows
- include("${CMAKE_CURRENT_SOURCE_DIR}/CMake/win32-cache.cmake")
-elseif(APPLE)
- # Fast-track predictable feature detections
- set(HAVE_EVENTFD 0)
- set(HAVE_GETPASS_R 0)
- set(HAVE_SENDMMSG 0)
-elseif(AMIGA)
+option(_CURL_QUICK_DETECT "Fast-track known feature detection results (Windows, some Apple)" ON)
+if(_CURL_QUICK_DETECT)
+ if(WIN32)
+ include("${CMAKE_CURRENT_SOURCE_DIR}/CMake/win32-cache.cmake")
+ elseif(APPLE)
+ set(HAVE_EVENTFD 0)
+ set(HAVE_GETPASS_R 0)
+ set(HAVE_SENDMMSG 0)
+ endif()
+endif()
+
+if(AMIGA)
set(HAVE_GETADDRINFO 0) # Breaks the build when detected and used.
endif()
if(DOS OR AMIGA)
@@ -817,12 +792,40 @@
elseif(NOT WIN32 AND NOT APPLE)
check_library_exists("socket" "connect" "" HAVE_LIBSOCKET)
if(HAVE_LIBSOCKET)
- set(CURL_LIBS "socket;${CURL_LIBS}")
+ set(CURL_LIBS "socket" ${CURL_LIBS})
endif()
endif()
-if(WIN32)
- list(APPEND CURL_LIBS "ws2_32" "bcrypt")
+option(ENABLE_IPV6 "Enable IPv6 support" ON)
+mark_as_advanced(ENABLE_IPV6)
+if(ENABLE_IPV6)
+ include(CheckStructHasMember)
+ if(WIN32)
+ check_struct_has_member("struct sockaddr_in6" "sin6_scope_id" "winsock2.h;ws2tcpip.h" HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
+ else()
+ check_struct_has_member("struct sockaddr_in6" "sin6_addr" "netinet/in.h" HAVE_SOCKADDR_IN6_SIN6_ADDR)
+ check_struct_has_member("struct sockaddr_in6" "sin6_scope_id" "netinet/in.h" HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
+ if(NOT HAVE_SOCKADDR_IN6_SIN6_ADDR)
+ if(NOT DOS AND NOT AMIGA)
+ message(WARNING "struct sockaddr_in6 not available, disabling IPv6 support")
+ endif()
+ set(ENABLE_IPV6 OFF CACHE BOOL "Enable IPv6 support" FORCE) # Force the feature off as we use this name as guard macro
+ endif()
+
+ if(APPLE AND NOT ENABLE_ARES)
+ set(_use_core_foundation_and_core_services ON)
+
+ find_library(SYSTEMCONFIGURATION_FRAMEWORK NAMES "SystemConfiguration")
+ mark_as_advanced(SYSTEMCONFIGURATION_FRAMEWORK)
+ if(NOT SYSTEMCONFIGURATION_FRAMEWORK)
+ message(FATAL_ERROR "SystemConfiguration framework not found")
+ endif()
+ list(APPEND CURL_LIBS "-framework SystemConfiguration")
+ endif()
+ endif()
+endif()
+if(ENABLE_IPV6)
+ set(USE_IPV6 ON)
endif()
if(0) # XXX(cmake): not needed for build within cmake
@@ -944,8 +947,9 @@
set(_ssl_enabled ON)
set(USE_OPENSSL ON)
- list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
- include_directories(${OPENSSL_INCLUDE_DIR})
+ # Depend on OpenSSL via imported targets. This allows our dependents to
+ # get our dependencies transitively.
+ list(APPEND CURL_LIBS OpenSSL::SSL OpenSSL::Crypto)
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "openssl")
if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "openssl")
@@ -954,7 +958,7 @@
set(_curl_ca_bundle_supported TRUE)
cmake_push_check_state()
- list(APPEND CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
+ list(APPEND CMAKE_REQUIRED_LIBRARIES OpenSSL::SSL OpenSSL::Crypto)
if(NOT DEFINED HAVE_BORINGSSL)
check_symbol_exists("OPENSSL_IS_BORINGSSL" "openssl/base.h" HAVE_BORINGSSL)
endif()
@@ -1010,7 +1014,7 @@
include_directories(SYSTEM ${MBEDTLS_INCLUDE_DIRS})
link_directories(${MBEDTLS_LIBRARY_DIRS})
if(MBEDTLS_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MBEDTLS_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${MBEDTLS_CFLAGS}")
endif()
if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "mbedtls")
@@ -1046,7 +1050,7 @@
include_directories(SYSTEM ${WOLFSSL_INCLUDE_DIRS})
link_directories(${WOLFSSL_LIBRARY_DIRS})
if(WOLFSSL_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WOLFSSL_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${WOLFSSL_CFLAGS}")
endif()
if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "wolfssl")
@@ -1061,6 +1065,10 @@
pkg_check_modules(GNUTLS "gnutls")
if(GNUTLS_FOUND)
set(GNUTLS_LIBRARIES ${GNUTLS_LINK_LIBRARIES})
+ string(REPLACE ";" " " GNUTLS_CFLAGS "${GNUTLS_CFLAGS}")
+ if(GNUTLS_CFLAGS)
+ string(APPEND CMAKE_C_FLAGS " ${GNUTLS_CFLAGS}")
+ endif()
endif()
endif()
if(NOT GNUTLS_FOUND)
@@ -1070,12 +1078,12 @@
set(_ssl_enabled ON)
set(USE_GNUTLS ON)
list(APPEND CURL_LIBS ${GNUTLS_LIBRARIES} ${NETTLE_LIBRARIES})
- list(APPEND CURL_LIBDIRS ${NETTLE_LIBRARY_DIRS})
+ list(APPEND CURL_LIBDIRS ${GNUTLS_LIBRARY_DIRS} ${NETTLE_LIBRARY_DIRS})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "gnutls" ${NETTLE_PC_REQUIRES})
include_directories(SYSTEM ${GNUTLS_INCLUDE_DIRS} ${NETTLE_INCLUDE_DIRS})
link_directories(${NETTLE_LIBRARY_DIRS})
if(NETTLE_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${NETTLE_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${NETTLE_CFLAGS}")
endif()
if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "gnutls")
@@ -1102,7 +1110,7 @@
include_directories(SYSTEM ${RUSTLS_INCLUDE_DIRS})
link_directories(${RUSTLS_LIBRARY_DIRS})
if(RUSTLS_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${RUSTLS_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${RUSTLS_CFLAGS}")
endif()
if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "rustls")
@@ -1142,7 +1150,7 @@
include_directories(SYSTEM ${BROTLI_INCLUDE_DIRS})
link_directories(${BROTLI_LIBRARY_DIRS})
if(BROTLI_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${BROTLI_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${BROTLI_CFLAGS}")
endif()
endif()
@@ -1157,7 +1165,7 @@
include_directories(SYSTEM ${ZSTD_INCLUDE_DIRS})
link_directories(${ZSTD_LIBRARY_DIRS})
if(ZSTD_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ZSTD_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${ZSTD_CFLAGS}")
endif()
else()
message(WARNING "zstd v1.0.0 or newer is required, disabling zstd support.")
@@ -1168,10 +1176,14 @@
macro(curl_openssl_check_symbol_exists _symbol _files _variable)
cmake_push_check_state()
if(USE_OPENSSL)
- list(APPEND CMAKE_REQUIRED_INCLUDES "${OPENSSL_INCLUDE_DIR}")
- list(APPEND CMAKE_REQUIRED_LIBRARIES "${OPENSSL_LIBRARIES}")
+ list(APPEND CMAKE_REQUIRED_LIBRARIES OpenSSL::SSL OpenSSL::Crypto)
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS "-DOPENSSL_SUPPRESS_DEPRECATED") # for SSL_CTX_set_srp_username deprecated since 3.0.0
if(HAVE_LIBZ)
- list(APPEND CMAKE_REQUIRED_LIBRARIES "${ZLIB_LIBRARIES}")
+ if(CMAKE_USE_SYSTEM_ZLIB)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES ZLIB::ZLIB)
+ else()
+ list(APPEND CMAKE_REQUIRED_LIBRARIES cmzlib)
+ endif()
endif()
if(WIN32)
list(APPEND CMAKE_REQUIRED_LIBRARIES "ws2_32")
@@ -1183,8 +1195,7 @@
list(APPEND CMAKE_REQUIRED_LIBRARIES "${WOLFSSL_LIBRARIES}")
curl_required_libpaths("${WOLFSSL_LIBRARY_DIRS}")
if(HAVE_LIBZ)
- list(APPEND CMAKE_REQUIRED_INCLUDES "${ZLIB_INCLUDE_DIRS}") # Public wolfSSL headers require zlib headers
- list(APPEND CMAKE_REQUIRED_LIBRARIES "${ZLIB_LIBRARIES}")
+ list(APPEND CMAKE_REQUIRED_LIBRARIES ZLIB::ZLIB) # Public wolfSSL headers also require zlib headers
endif()
if(WIN32)
list(APPEND CMAKE_REQUIRED_LIBRARIES "ws2_32" "crypt32")
@@ -1276,7 +1287,7 @@
include_directories(SYSTEM ${NGHTTP2_INCLUDE_DIRS})
link_directories(${NGHTTP2_LIBRARY_DIRS})
if(NGHTTP2_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${NGHTTP2_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${NGHTTP2_CFLAGS}")
endif()
else()
set(USE_NGHTTP2 OFF)
@@ -1308,7 +1319,7 @@
include_directories(SYSTEM ${NGTCP2_INCLUDE_DIRS})
link_directories(${NGTCP2_LIBRARY_DIRS})
if(NGTCP2_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${NGTCP2_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${NGTCP2_CFLAGS}")
endif()
find_package(NGHTTP3 REQUIRED)
@@ -1319,7 +1330,7 @@
include_directories(SYSTEM ${NGHTTP3_INCLUDE_DIRS})
link_directories(${NGHTTP3_LIBRARY_DIRS})
if(NGHTTP3_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${NGHTTP3_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${NGHTTP3_CFLAGS}")
endif()
endif()
@@ -1339,7 +1350,7 @@
include_directories(SYSTEM ${QUICHE_INCLUDE_DIRS})
link_directories(${QUICHE_LIBRARY_DIRS})
if(QUICHE_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${QUICHE_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${QUICHE_CFLAGS}")
endif()
if(NOT DEFINED HAVE_QUICHE_CONN_SET_QLOG_FD)
cmake_push_check_state()
@@ -1368,7 +1379,7 @@
include_directories(SYSTEM ${MSH3_INCLUDE_DIRS})
link_directories(${MSH3_LIBRARY_DIRS})
if(MSH3_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MSH3_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${MSH3_CFLAGS}")
endif()
endif()
@@ -1409,20 +1420,20 @@
# Check for LDAP
cmake_push_check_state()
if(USE_OPENSSL)
- list(APPEND CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
+ list(APPEND CMAKE_REQUIRED_LIBRARIES OpenSSL::SSL OpenSSL::Crypto)
endif()
find_package(LDAP)
if(LDAP_FOUND)
set(HAVE_LBER_H 1)
- set(CURL_LIBS "${LDAP_LIBRARIES};${CURL_LIBS}")
+ set(CURL_LIBS ${LDAP_LIBRARIES} ${CURL_LIBS})
list(APPEND CURL_LIBDIRS ${LDAP_LIBRARY_DIRS})
if(LDAP_PC_REQUIRES)
- set(LIBCURL_PC_REQUIRES_PRIVATE "${LDAP_PC_REQUIRES};${LIBCURL_PC_REQUIRES_PRIVATE}")
+ set(LIBCURL_PC_REQUIRES_PRIVATE ${LDAP_PC_REQUIRES} ${LIBCURL_PC_REQUIRES_PRIVATE})
endif()
include_directories(SYSTEM ${LDAP_INCLUDE_DIRS})
link_directories(${LDAP_LIBRARY_DIRS})
if(LDAP_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LDAP_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${LDAP_CFLAGS}")
endif()
# LDAP feature checks
@@ -1438,7 +1449,6 @@
if(HAVE_LDAP_INIT_FD)
set(USE_OPENLDAP ON)
- add_definitions("-DLDAP_DEPRECATED=1")
endif()
if(NOT CURL_DISABLE_LDAPS)
set(HAVE_LDAP_SSL ON)
@@ -1492,13 +1502,13 @@
if(USE_LIBIDN2 AND NOT USE_APPLE_IDN AND NOT USE_WIN32_IDN)
find_package(Libidn2 QUIET)
if(LIBIDN2_FOUND)
- set(CURL_LIBS "${LIBIDN2_LIBRARIES};${CURL_LIBS}")
+ set(CURL_LIBS ${LIBIDN2_LIBRARIES} ${CURL_LIBS})
list(APPEND CURL_LIBDIRS ${LIBIDN2_LIBRARY_DIRS})
- set(LIBCURL_PC_REQUIRES_PRIVATE "${LIBIDN2_PC_REQUIRES};${LIBCURL_PC_REQUIRES_PRIVATE}")
+ set(LIBCURL_PC_REQUIRES_PRIVATE ${LIBIDN2_PC_REQUIRES} ${LIBCURL_PC_REQUIRES_PRIVATE})
include_directories(SYSTEM ${LIBIDN2_INCLUDE_DIRS})
link_directories(${LIBIDN2_LIBRARY_DIRS})
if(LIBIDN2_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBIDN2_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${LIBIDN2_CFLAGS}")
endif()
set(HAVE_IDN2_H 1)
set(HAVE_LIBIDN2 1)
@@ -1518,7 +1528,7 @@
include_directories(SYSTEM ${LIBPSL_INCLUDE_DIRS})
link_directories(${LIBPSL_LIBRARY_DIRS})
if(LIBPSL_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBPSL_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${LIBPSL_CFLAGS}")
endif()
set(USE_LIBPSL ON)
endif()
@@ -1531,13 +1541,13 @@
if(CURL_USE_LIBSSH2)
find_package(Libssh2)
if(LIBSSH2_FOUND)
- list(APPEND CURL_LIBS ${LIBSSH2_LIBRARIES})
+ set(CURL_LIBS ${LIBSSH2_LIBRARIES} ${CURL_LIBS}) # keep it before TLS-crypto, compression
list(APPEND CURL_LIBDIRS ${LIBSSH2_LIBRARY_DIRS})
- list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${LIBSSH2_PC_REQUIRES})
+ set(LIBCURL_PC_REQUIRES_PRIVATE ${LIBSSH2_PC_REQUIRES} ${LIBCURL_PC_REQUIRES_PRIVATE})
include_directories(SYSTEM ${LIBSSH2_INCLUDE_DIRS})
link_directories(${LIBSSH2_LIBRARY_DIRS})
if(LIBSSH2_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBSSH2_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${LIBSSH2_CFLAGS}")
endif()
set(USE_LIBSSH2 ON)
endif()
@@ -1548,13 +1558,13 @@
mark_as_advanced(CURL_USE_LIBSSH)
if(NOT USE_LIBSSH2 AND CURL_USE_LIBSSH)
find_package(Libssh REQUIRED)
- list(APPEND CURL_LIBS ${LIBSSH_LIBRARIES})
+ set(CURL_LIBS ${LIBSSH_LIBRARIES} ${CURL_LIBS}) # keep it before TLS-crypto, compression
list(APPEND CURL_LIBDIRS ${LIBSSH_LIBRARY_DIRS})
- list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${LIBSSH_PC_REQUIRES})
+ set(LIBCURL_PC_REQUIRES_PRIVATE ${LIBSSH_PC_REQUIRES} ${LIBCURL_PC_REQUIRES_PRIVATE})
include_directories(SYSTEM ${LIBSSH_INCLUDE_DIRS})
link_directories(${LIBSSH_LIBRARY_DIRS})
if(LIBSSH_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBSSH_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${LIBSSH_CFLAGS}")
endif()
set(USE_LIBSSH ON)
endif()
@@ -1567,7 +1577,7 @@
if(USE_WOLFSSL)
find_package(WolfSSH)
if(WOLFSSH_FOUND)
- list(APPEND CURL_LIBS ${WOLFSSH_LIBRARIES})
+ set(CURL_LIBS ${WOLFSSH_LIBRARIES} ${CURL_LIBS}) # keep it before TLS-crypto, compression
include_directories(SYSTEM ${WOLFSSH_INCLUDE_DIRS})
set(USE_WOLFSSH ON)
endif()
@@ -1586,7 +1596,7 @@
include_directories(SYSTEM ${LIBGSASL_INCLUDE_DIRS})
link_directories(${LIBGSASL_LIBRARY_DIRS})
if(LIBGSASL_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBGSASL_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${LIBGSASL_CFLAGS}")
endif()
set(USE_GSASL ON)
endif()
@@ -1605,7 +1615,7 @@
include_directories(SYSTEM ${GSS_INCLUDE_DIRS})
link_directories(${GSS_LIBRARY_DIRS})
if(GSS_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GSS_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${GSS_CFLAGS}")
endif()
if(GSS_FLAVOUR STREQUAL "GNU")
@@ -1631,7 +1641,7 @@
endif()
if(NOT DEFINED HAVE_GSS_C_NT_HOSTBASED_SERVICE)
- set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${GSS_CFLAGS}")
+ string(APPEND CMAKE_REQUIRED_FLAGS " ${GSS_CFLAGS}")
list(APPEND CMAKE_REQUIRED_LIBRARIES ${GSS_LIBRARIES})
curl_required_libpaths("${GSS_LIBRARY_DIRS}")
check_symbol_exists("GSS_C_NT_HOSTBASED_SERVICE" "${_include_list}" HAVE_GSS_C_NT_HOSTBASED_SERVICE)
@@ -1661,7 +1671,7 @@
include_directories(SYSTEM ${LIBUV_INCLUDE_DIRS})
link_directories(${LIBUV_LIBRARY_DIRS})
if(LIBUV_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBUV_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${LIBUV_CFLAGS}")
endif()
set(USE_LIBUV ON)
set(HAVE_UV_H ON)
@@ -1676,7 +1686,7 @@
include_directories(SYSTEM ${LIBRTMP_INCLUDE_DIRS})
link_directories(${LIBRTMP_LIBRARY_DIRS})
if(LIBRTMP_CFLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBRTMP_CFLAGS}")
+ string(APPEND CMAKE_C_FLAGS " ${LIBRTMP_CFLAGS}")
endif()
endif()
@@ -1875,7 +1885,7 @@
HAVE_UNISTD_H
)
if(${_variable})
- set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${_variable}")
+ string(APPEND CURL_TEST_DEFINES " -D${_variable}")
endif()
endforeach()
@@ -1946,14 +1956,15 @@
check_symbol_exists("ftruncate" "unistd.h" HAVE_FTRUNCATE)
check_symbol_exists("getpeername" "${CURL_INCLUDES}" HAVE_GETPEERNAME) # winsock2.h unistd.h proto/bsdsocket.h
check_symbol_exists("getsockname" "${CURL_INCLUDES}" HAVE_GETSOCKNAME) # winsock2.h unistd.h proto/bsdsocket.h
-check_function_exists("if_nametoindex" HAVE_IF_NAMETOINDEX) # winsock2.h net/if.h
check_function_exists("getrlimit" HAVE_GETRLIMIT)
check_function_exists("setlocale" HAVE_SETLOCALE)
check_function_exists("setmode" HAVE_SETMODE)
check_function_exists("setrlimit" HAVE_SETRLIMIT)
if(NOT WIN32)
- check_function_exists("sched_yield" HAVE_SCHED_YIELD)
+ check_function_exists("if_nametoindex" HAVE_IF_NAMETOINDEX) # iphlpapi.h (Windows non-UWP), net/if.h
+ check_function_exists("realpath" HAVE_REALPATH)
+ check_function_exists("sched_yield" HAVE_SCHED_YIELD)
check_symbol_exists("strcasecmp" "string.h" HAVE_STRCASECMP)
check_symbol_exists("stricmp" "string.h" HAVE_STRICMP)
check_symbol_exists("strcmpi" "string.h" HAVE_STRCMPI)
@@ -1971,15 +1982,16 @@
check_symbol_exists("arc4random" "${CURL_INCLUDES};stdlib.h" HAVE_ARC4RANDOM)
endif()
-if(NOT MSVC OR (MSVC_VERSION GREATER_EQUAL 1900))
- # Earlier MSVC compilers had faulty snprintf implementations
- check_function_exists("snprintf" HAVE_SNPRINTF)
+if(NOT MSVC)
+ check_function_exists("snprintf" HAVE_SNPRINTF) # to match detection method in ./configure
+elseif(MSVC_VERSION GREATER_EQUAL 1900) # Earlier MSVC compilers had faulty snprintf implementations
+ check_symbol_exists("snprintf" "stdio.h" HAVE_SNPRINTF) # snprintf may be a compatibility macro, not an exported function
endif()
if(APPLE)
check_function_exists("mach_absolute_time" HAVE_MACH_ABSOLUTE_TIME)
endif()
-check_symbol_exists("inet_ntop" "${CURL_INCLUDES};stdlib.h;string.h" HAVE_INET_NTOP) # arpa/inet.h
-check_symbol_exists("inet_pton" "${CURL_INCLUDES};stdlib.h;string.h" HAVE_INET_PTON) # arpa/inet.h
+check_symbol_exists("inet_ntop" "${CURL_INCLUDES};stdlib.h;string.h" HAVE_INET_NTOP) # arpa/inet.h netinet/in.h sys/socket.h
+check_symbol_exists("inet_pton" "${CURL_INCLUDES};stdlib.h;string.h" HAVE_INET_PTON) # arpa/inet.h netinet/in.h sys/socket.h
check_symbol_exists("fsetxattr" "sys/xattr.h" HAVE_FSETXATTR)
if(HAVE_FSETXATTR)
@@ -2124,7 +2136,7 @@
# The Mac version of GCC warns about use of long double. Disable it.
get_source_file_property(_mprintf_compile_flags "mprintf.c" COMPILE_FLAGS)
if(_mprintf_compile_flags)
- set(_mprintf_compile_flags "${_mprintf_compile_flags} -Wno-long-double")
+ string(APPEND _mprintf_compile_flags " -Wno-long-double")
else()
set(_mprintf_compile_flags "-Wno-long-double")
endif()
@@ -2143,13 +2155,15 @@
add_definitions("-DHAVE_CONFIG_H")
if(WIN32)
+ list(APPEND CURL_LIBS "ws2_32" "bcrypt")
+
# _fseeki64() requires VS2005
if(NOT MSVC OR (MSVC_VERSION GREATER_EQUAL 1400))
set(USE_WIN32_LARGE_FILES ON)
endif()
# Use the manifest embedded in the Windows Resource
- set(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} -DCURL_EMBED_MANIFEST")
+ string(APPEND CMAKE_RC_FLAGS " -DCURL_EMBED_MANIFEST")
# We use crypto functions that are not available for UWP apps
if(NOT WINDOWS_STORE)
@@ -2164,26 +2178,25 @@
if(MSVC)
# Disable default manifest added by CMake
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -MANIFEST:NO")
+ string(APPEND CMAKE_EXE_LINKER_FLAGS " -MANIFEST:NO")
if(CMAKE_C_FLAGS MATCHES "[/-]W[0-4]")
string(REGEX REPLACE "[/-]W[0-4]" "-W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
else()
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -W4")
+ string(APPEND CMAKE_C_FLAGS " -W4")
endif()
# Use multithreaded compilation on VS2008+
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND MSVC_VERSION GREATER_EQUAL 1500)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -MP")
+ string(APPEND CMAKE_C_FLAGS " -MP")
endif()
endif()
if(CURL_WERROR)
if(MSVC)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -WX")
+ string(APPEND CMAKE_C_FLAGS " -WX")
else()
- # This assumes clang or gcc style options
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
+ string(APPEND CMAKE_C_FLAGS " -Werror") # This assumes clang or gcc style options
endif()
endif()
@@ -2352,7 +2365,7 @@
curl_add_if("gsasl" USE_GSASL)
curl_add_if("zstd" HAVE_ZSTD)
curl_add_if("AsynchDNS" USE_ARES OR USE_THREADS_POSIX OR USE_THREADS_WIN32)
-curl_add_if("asyn-rr" USE_ARES AND ENABLE_THREADED_RESOLVER)
+curl_add_if("asyn-rr" USE_ARES AND ENABLE_THREADED_RESOLVER AND USE_HTTPSRR)
curl_add_if("IDN" (HAVE_LIBIDN2 AND HAVE_IDN2_H) OR
USE_WIN32_IDN OR
USE_APPLE_IDN)
@@ -2427,7 +2440,6 @@
# curl-config needs the following options to be set.
set(CC "${CMAKE_C_COMPILER}")
- # TODO: probably put a -D... options here?
set(CONFIGURE_OPTIONS "")
set(CURLVERSION "${_curl_version}")
set(VERSIONNUM "${_curl_version_num}")
@@ -2471,18 +2483,18 @@
endforeach()
# Avoid getting unnecessary -L options for known system directories.
- set(_sys_libdirs "")
+ set(_sys_libdirs "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
foreach(_libdir IN LISTS CMAKE_SYSTEM_PREFIX_PATH)
if(_libdir MATCHES "/$")
- set(_libdir "${_libdir}lib")
+ string(APPEND _libdir "lib")
else()
- set(_libdir "${_libdir}/lib")
+ string(APPEND _libdir "/lib")
endif()
if(IS_DIRECTORY "${_libdir}")
list(APPEND _sys_libdirs "${_libdir}")
endif()
if(DEFINED CMAKE_LIBRARY_ARCHITECTURE)
- set(_libdir "${_libdir}/${CMAKE_LIBRARY_ARCHITECTURE}")
+ string(APPEND _libdir "/${CMAKE_LIBRARY_ARCHITECTURE}")
if(IS_DIRECTORY "${_libdir}")
list(APPEND _sys_libdirs "${_libdir}")
endif()
@@ -2490,6 +2502,9 @@
endforeach()
foreach(_libdir IN LISTS _custom_libdirs CURL_LIBDIRS)
+ if(NOT CMAKE_VERSION VERSION_LESS 3.20)
+ cmake_path(SET _libdir NORMALIZE "${_libdir}")
+ endif()
list(FIND _sys_libdirs "${_libdir}" _libdir_index)
if(_libdir_index LESS 0)
list(APPEND _ldflags "-L${_libdir}")
@@ -2498,7 +2513,7 @@
set(_implicit_libs "")
if(NOT MINGW AND NOT UNIX)
- set(_implicit_libs ${CMAKE_C_IMPLICIT_LINK_LIBRARIES})
+ set(_implicit_libs "${CMAKE_C_IMPLICIT_LINK_LIBRARIES}")
endif()
foreach(_lib IN LISTS _implicit_libs _custom_libs CURL_LIBS)
@@ -2524,6 +2539,9 @@
get_filename_component(_libdir ${_lib} DIRECTORY)
get_filename_component(_libname ${_lib} NAME_WE)
if(_libname MATCHES "^lib")
+ if(NOT CMAKE_VERSION VERSION_LESS 3.20)
+ cmake_path(SET _libdir NORMALIZE "${_libdir}")
+ endif()
list(FIND _sys_libdirs "${_libdir}" _libdir_index)
if(_libdir_index LESS 0)
list(APPEND _ldflags "-L${_libdir}")
@@ -2694,6 +2712,7 @@
endif()
# Save build info for test runner to pick up and log
+set(_cmake_sysroot "")
if(CMAKE_OSX_SYSROOT)
set(_cmake_sysroot ${CMAKE_OSX_SYSROOT})
elseif(CMAKE_SYSROOT)
diff --git a/Utilities/cmcurl/include/curl/curlver.h b/Utilities/cmcurl/include/curl/curlver.h
index a7c1a08..1c00572 100644
--- a/Utilities/cmcurl/include/curl/curlver.h
+++ b/Utilities/cmcurl/include/curl/curlver.h
@@ -32,13 +32,13 @@
/* This is the version number of the libcurl package from which this header
file origins: */
-#define LIBCURL_VERSION "8.12.0"
+#define LIBCURL_VERSION "8.12.1"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 8
#define LIBCURL_VERSION_MINOR 12
-#define LIBCURL_VERSION_PATCH 0
+#define LIBCURL_VERSION_PATCH 1
/* This is the numeric version of the libcurl version number, meant for easier
parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will
@@ -59,7 +59,7 @@
CURL_VERSION_BITS() macro since curl's own configure script greps for it
and needs it to contain the full number.
*/
-#define LIBCURL_VERSION_NUM 0x080c00
+#define LIBCURL_VERSION_NUM 0x080c01
/*
* This is the date and time when the full source package was created. The
diff --git a/Utilities/cmcurl/lib/CMakeLists.txt b/Utilities/cmcurl/lib/CMakeLists.txt
index ecdfe3b..ae5fa5a 100644
--- a/Utilities/cmcurl/lib/CMakeLists.txt
+++ b/Utilities/cmcurl/lib/CMakeLists.txt
@@ -94,6 +94,9 @@
)
target_compile_definitions(curlu PUBLIC "UNITTESTS" "CURL_STATICLIB")
target_link_libraries(curlu PRIVATE ${CURL_LIBS})
+ # There is plenty of parallelism when building the testdeps target.
+ # Override the curlu batch size with the maximum to optimize performance.
+ set_target_properties(curlu PROPERTIES UNITY_BUILD_BATCH_SIZE 0)
endif()
if(ENABLE_CURLDEBUG)
@@ -104,6 +107,13 @@
## Library definition
+if(NOT DEFINED IMPORT_LIB_SUFFIX)
+ set(IMPORT_LIB_SUFFIX "")
+endif()
+if(NOT DEFINED STATIC_LIB_SUFFIX)
+ set(STATIC_LIB_SUFFIX "")
+endif()
+
# Add "_imp" as a suffix before the extension to avoid conflicting with
# the statically linked "libcurl.lib" (typically with MSVC)
if(WIN32 AND
diff --git a/Utilities/cmcurl/lib/asyn-ares.c b/Utilities/cmcurl/lib/asyn-ares.c
index 38dc729..640c8a9 100644
--- a/Utilities/cmcurl/lib/asyn-ares.c
+++ b/Utilities/cmcurl/lib/asyn-ares.c
@@ -109,6 +109,9 @@
int i;
int num = 0;
+ if(!channel)
+ return 0;
+
bitmask = ares_getsock(channel, socks, ARES_GETSOCK_MAXNUM);
for(i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
diff --git a/Utilities/cmcurl/lib/asyn-thread.c b/Utilities/cmcurl/lib/asyn-thread.c
index b8c3049..f989415 100644
--- a/Utilities/cmcurl/lib/asyn-thread.c
+++ b/Utilities/cmcurl/lib/asyn-thread.c
@@ -138,14 +138,14 @@
return Curl_resolver_init(easy, to);
}
-static void destroy_async_data(struct Curl_async *);
+static void destroy_async_data(struct Curl_easy *);
/*
* Cancel all possibly still on-going resolves for this connection.
*/
void Curl_resolver_cancel(struct Curl_easy *data)
{
- destroy_async_data(&data->state.async);
+ destroy_async_data(data);
}
/* This function is used to init a threaded resolve */
@@ -282,14 +282,6 @@
struct thread_data *td = tsd->td;
char service[12];
int rc;
-#ifndef CURL_DISABLE_SOCKETPAIR
-#ifdef USE_EVENTFD
- const void *buf;
- const uint64_t val = 1;
-#else
- char buf[1];
-#endif
-#endif
msnprintf(service, sizeof(service), "%d", tsd->port);
@@ -315,9 +307,9 @@
#ifndef CURL_DISABLE_SOCKETPAIR
if(tsd->sock_pair[1] != CURL_SOCKET_BAD) {
#ifdef USE_EVENTFD
- buf = &val;
+ const uint64_t buf[1] = { 1 };
#else
- buf[0] = 1;
+ const char buf[1] = { 1 };
#endif
/* DNS has been resolved, signal client task */
if(wakeup_write(tsd->sock_pair[1], buf, sizeof(buf)) < 0) {
@@ -377,18 +369,22 @@
/*
* destroy_async_data() cleans up async resolver data and thread handle.
*/
-static void destroy_async_data(struct Curl_async *async)
+static void destroy_async_data(struct Curl_easy *data)
{
+ struct Curl_async *async;
+ DEBUGASSERT(data);
+ async = &data->state.async;
+ DEBUGASSERT(async);
if(async->tdata) {
struct thread_data *td = async->tdata;
bool done;
#ifndef CURL_DISABLE_SOCKETPAIR
curl_socket_t sock_rd = td->tsd.sock_pair[0];
- struct Curl_easy *data = td->tsd.data;
#endif
#ifdef USE_HTTPSRR_ARES
- ares_destroy(data->state.async.tdata->channel);
+ if(data->state.async.tdata->channel)
+ ares_destroy(data->state.async.tdata->channel);
#endif
/*
* if the thread is still blocking in the resolve syscall, detach it and
@@ -495,12 +491,12 @@
}
#ifdef USE_HTTPSRR_ARES
if(resolve_httpsrr(data, asp))
- goto err_exit;
+ infof(data, "Failed HTTPS RR operation");
#endif
return TRUE;
err_exit:
- destroy_async_data(asp);
+ destroy_async_data(data);
errno_exit:
errno = err;
@@ -539,7 +535,7 @@
/* a name was not resolved, report error */
result = Curl_resolver_error(data);
- destroy_async_data(&data->state.async);
+ destroy_async_data(data);
if(!data->state.async.dns && report)
connclose(data->conn, "asynch resolve failed");
@@ -617,7 +613,7 @@
if(!data->state.async.dns) {
CURLcode result = Curl_resolver_error(data);
- destroy_async_data(&data->state.async);
+ destroy_async_data(data);
return result;
}
#ifdef USE_HTTPSRR_ARES
@@ -625,13 +621,13 @@
struct Curl_https_rrinfo *lhrr =
Curl_memdup(&td->hinfo, sizeof(struct Curl_https_rrinfo));
if(!lhrr) {
- destroy_async_data(&data->state.async);
+ destroy_async_data(data);
return CURLE_OUT_OF_MEMORY;
}
data->state.async.dns->hinfo = lhrr;
}
#endif
- destroy_async_data(&data->state.async);
+ destroy_async_data(data);
*entry = data->state.async.dns;
}
else {
@@ -665,15 +661,17 @@
timediff_t milli;
timediff_t ms;
struct resdata *reslv = (struct resdata *)data->state.async.resolver;
- int socketi = 0;
#ifndef CURL_DISABLE_SOCKETPAIR
struct thread_data *td = data->state.async.tdata;
+#endif
+#if !defined(CURL_DISABLE_SOCKETPAIR) || defined(USE_HTTPSRR_ARES)
+ int socketi = 0;
#else
(void)socks;
#endif
#ifdef USE_HTTPSRR_ARES
- if(data->state.async.tdata) {
+ if(data->state.async.tdata && data->state.async.tdata->channel) {
ret_val = Curl_ares_getsock(data, data->state.async.tdata->channel, socks);
for(socketi = 0; socketi < (MAX_SOCKSPEREASYHANDLE - 1); socketi++)
if(!ARES_GETSOCK_READABLE(ret_val, socketi) &&
@@ -685,8 +683,7 @@
if(td) {
/* return read fd to client for polling the DNS resolution status */
socks[socketi] = td->tsd.sock_pair[0];
- td->tsd.data = data;
- ret_val = GETSOCK_READSOCK(socketi);
+ ret_val |= GETSOCK_READSOCK(socketi);
}
else {
#endif
diff --git a/Utilities/cmcurl/lib/asyn.h b/Utilities/cmcurl/lib/asyn.h
index c674541..5a21329 100644
--- a/Utilities/cmcurl/lib/asyn.h
+++ b/Utilities/cmcurl/lib/asyn.h
@@ -40,20 +40,19 @@
/* Data for synchronization between resolver thread and its parent */
struct thread_sync_data {
curl_mutex_t *mtx;
- bool done;
- int port;
char *hostname; /* hostname to resolve, Curl_async.hostname
duplicate */
#ifndef CURL_DISABLE_SOCKETPAIR
- struct Curl_easy *data;
curl_socket_t sock_pair[2]; /* eventfd/pipes/socket pair */
#endif
- int sock_error;
struct Curl_addrinfo *res;
#ifdef HAVE_GETADDRINFO
struct addrinfo hints;
#endif
struct thread_data *td; /* for thread-self cleanup */
+ int port;
+ int sock_error;
+ bool done;
};
struct thread_data {
diff --git a/Utilities/cmcurl/lib/cf-h1-proxy.c b/Utilities/cmcurl/lib/cf-h1-proxy.c
index 2e13f39..9b75d08 100644
--- a/Utilities/cmcurl/lib/cf-h1-proxy.c
+++ b/Utilities/cmcurl/lib/cf-h1-proxy.c
@@ -660,7 +660,6 @@
cf->ctx = ts;
}
- /* TODO: can we do blocking? */
/* We want "seamless" operations through HTTP proxy tunnel */
result = H1_CONNECT(cf, data, ts);
diff --git a/Utilities/cmcurl/lib/cf-h2-proxy.c b/Utilities/cmcurl/lib/cf-h2-proxy.c
index 771ecc1..d8b9128 100644
--- a/Utilities/cmcurl/lib/cf-h2-proxy.c
+++ b/Utilities/cmcurl/lib/cf-h2-proxy.c
@@ -1408,7 +1408,7 @@
ssize_t nwritten;
CURLcode result;
- (void)eos; /* TODO, maybe useful for blocks? */
+ (void)eos;
if(ctx->tunnel.state != H2_TUNNEL_ESTABLISHED) {
*err = CURLE_SEND_ERROR;
return -1;
diff --git a/Utilities/cmcurl/lib/cf-https-connect.c b/Utilities/cmcurl/lib/cf-https-connect.c
index 2b39e98..f073647 100644
--- a/Utilities/cmcurl/lib/cf-https-connect.c
+++ b/Utilities/cmcurl/lib/cf-https-connect.c
@@ -42,11 +42,6 @@
#include "curl_memory.h"
#include "memdebug.h"
-
-#ifndef ARRAYSIZE
-#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
-#endif
-
typedef enum {
CF_HC_INIT,
CF_HC_CONNECT,
@@ -592,8 +587,8 @@
DEBUGASSERT(alpnids);
DEBUGASSERT(alpn_count);
- DEBUGASSERT(alpn_count <= ARRAYSIZE(ctx->ballers));
- if(!alpn_count || (alpn_count > ARRAYSIZE(ctx->ballers))) {
+ DEBUGASSERT(alpn_count <= CURL_ARRAYSIZE(ctx->ballers));
+ if(!alpn_count || (alpn_count > CURL_ARRAYSIZE(ctx->ballers))) {
failf(data, "https-connect filter create with unsupported %zu ALPN ids",
alpn_count);
return CURLE_FAILED_INIT;
@@ -607,7 +602,7 @@
ctx->remotehost = remotehost;
for(i = 0; i < alpn_count; ++i)
cf_hc_baller_assign(&ctx->ballers[i], alpnids[i]);
- for(; i < ARRAYSIZE(ctx->ballers); ++i)
+ for(; i < CURL_ARRAYSIZE(ctx->ballers); ++i)
ctx->ballers[i].alpn_id = ALPN_none;
ctx->baller_count = alpn_count;
@@ -663,8 +658,8 @@
if(conn->dns_entry && conn->dns_entry->hinfo &&
!conn->dns_entry->hinfo->no_def_alpn) {
size_t i, j;
- for(i = 0; i < ARRAYSIZE(conn->dns_entry->hinfo->alpns) &&
- alpn_count < ARRAYSIZE(alpn_ids); ++i) {
+ for(i = 0; i < CURL_ARRAYSIZE(conn->dns_entry->hinfo->alpns) &&
+ alpn_count < CURL_ARRAYSIZE(alpn_ids); ++i) {
bool present = FALSE;
enum alpnid alpn = conn->dns_entry->hinfo->alpns[i];
for(j = 0; j < alpn_count; ++j) {
@@ -701,7 +696,6 @@
break;
case CURL_HTTP_VERSION_3:
/* We assume that silently not even trying H3 is ok here */
- /* TODO: should we fail instead? */
if(Curl_conn_may_http3(data, conn) == CURLE_OK)
alpn_ids[alpn_count++] = ALPN_h3;
alpn_ids[alpn_count++] = ALPN_h2;
diff --git a/Utilities/cmcurl/lib/cf-socket.c b/Utilities/cmcurl/lib/cf-socket.c
index edda348..a6f9888 100644
--- a/Utilities/cmcurl/lib/cf-socket.c
+++ b/Utilities/cmcurl/lib/cf-socket.c
@@ -1325,7 +1325,6 @@
return CURLE_OK;
}
- /* TODO: need to support blocking connect? */
if(blocking)
return CURLE_UNSUPPORTED_PROTOCOL;
@@ -1432,7 +1431,7 @@
/* A listening socket filter needs to be connected before the accept
* for some weird FTP interaction. This should be rewritten, so that
* FTP no longer does the socket checks and accept calls and delegates
- * all that to the filter. TODO. */
+ * all that to the filter. */
if(ctx->listening) {
Curl_pollset_set_in_only(data, ps, ctx->sock);
CURL_TRC_CF(data, cf, "adjust_pollset, listening, POLLIN fd=%"
@@ -1850,7 +1849,7 @@
/* QUIC needs a connected socket, nonblocking */
DEBUGASSERT(ctx->sock != CURL_SOCKET_BAD);
- rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, /* NOLINT FIXME */
+ rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, /* NOLINT */
(curl_socklen_t)ctx->addr.addrlen);
if(-1 == rc) {
return socket_connect_result(data, ctx->ip.remote_ip, SOCKERRNO);
@@ -2213,7 +2212,7 @@
cf_tcp_accept_connect,
cf_socket_close,
cf_socket_shutdown,
- cf_socket_get_host, /* TODO: not accurate */
+ cf_socket_get_host,
cf_socket_adjust_pollset,
cf_socket_data_pending,
cf_socket_send,
diff --git a/Utilities/cmcurl/lib/cfilters.c b/Utilities/cmcurl/lib/cfilters.c
index 3be0840..6a894e8 100644
--- a/Utilities/cmcurl/lib/cfilters.c
+++ b/Utilities/cmcurl/lib/cfilters.c
@@ -41,10 +41,6 @@
#include "curl_memory.h"
#include "memdebug.h"
-#ifndef ARRAYSIZE
-#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
-#endif
-
static void cf_cntrl_update_info(struct Curl_easy *data,
struct connectdata *conn);
@@ -724,7 +720,7 @@
CURLcode result = CURLE_OK;
size_t i;
- for(i = 0; i < ARRAYSIZE(conn->cfilter); ++i) {
+ for(i = 0; i < CURL_ARRAYSIZE(conn->cfilter); ++i) {
result = Curl_conn_cf_cntrl(conn->cfilter[i], data, ignore_result,
event, arg1, arg2);
if(!ignore_result && result)
diff --git a/Utilities/cmcurl/lib/conncache.c b/Utilities/cmcurl/lib/conncache.c
index 85435bf..b8a0515 100644
--- a/Utilities/cmcurl/lib/conncache.c
+++ b/Utilities/cmcurl/lib/conncache.c
@@ -166,11 +166,11 @@
if(!cpool->idata)
return 1; /* bad */
cpool->idata->state.internal = TRUE;
- /* TODO: this is quirky. We need an internal handle for certain
- * operations, but we do not add it to the multi (if there is one).
- * But we give it the multi so that socket event operations can work.
- * Probably better to have an internal handle owned by the multi that
- * can be used for cpool operations. */
+ /* This is quirky. We need an internal handle for certain operations, but we
+ * do not add it to the multi (if there is one). We give it the multi so
+ * that socket event operations can work. Probably better to have an
+ * internal handle owned by the multi that can be used for cpool
+ * operations. */
cpool->idata->multi = multi;
#ifdef DEBUGBUILD
if(getenv("CURL_DEBUG"))
@@ -1302,7 +1302,6 @@
void *param)
{
struct curltime *now = param;
- /* TODO, shall we reap connections that return an error here? */
Curl_conn_upkeep(data, conn, now);
return 0; /* continue iteration */
}
diff --git a/Utilities/cmcurl/lib/connect.c b/Utilities/cmcurl/lib/connect.c
index 05aabff..67cdb54 100644
--- a/Utilities/cmcurl/lib/connect.c
+++ b/Utilities/cmcurl/lib/connect.c
@@ -85,10 +85,6 @@
#include "curl_memory.h"
#include "memdebug.h"
-#ifndef ARRAYSIZE
-#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
-#endif
-
#if !defined(CURL_DISABLE_ALTSVC) || defined(USE_HTTPSRR)
enum alpnid Curl_alpn2alpnid(char *name, size_t len)
@@ -644,7 +640,7 @@
*connected = FALSE; /* a negative world view is best */
now = Curl_now();
ongoing = not_started = 0;
- for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
+ for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) {
struct eyeballer *baller = ctx->baller[i];
if(!baller || baller->is_done)
@@ -705,7 +701,7 @@
if(not_started > 0) {
int added = 0;
- for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
+ for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) {
struct eyeballer *baller = ctx->baller[i];
if(!baller || baller->has_started)
@@ -739,7 +735,7 @@
/* all ballers have failed to connect. */
CURL_TRC_CF(data, cf, "all eyeballers failed");
result = CURLE_COULDNT_CONNECT;
- for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
+ for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) {
struct eyeballer *baller = ctx->baller[i];
if(!baller)
continue;
@@ -884,7 +880,7 @@
DEBUGASSERT(ctx);
DEBUGASSERT(data);
- for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
+ for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) {
baller_free(ctx->baller[i], data);
ctx->baller[i] = NULL;
}
@@ -907,7 +903,7 @@
/* shutdown all ballers that have not done so already. If one fails,
* continue shutting down others until all are shutdown. */
- for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
+ for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) {
struct eyeballer *baller = ctx->baller[i];
bool bdone = FALSE;
if(!baller || !baller->cf || baller->shutdown)
@@ -918,12 +914,12 @@
}
*done = TRUE;
- for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
+ for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) {
if(ctx->baller[i] && !ctx->baller[i]->shutdown)
*done = FALSE;
}
if(*done) {
- for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
+ for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) {
if(ctx->baller[i] && ctx->baller[i]->result)
result = ctx->baller[i]->result;
}
@@ -940,7 +936,7 @@
size_t i;
if(!cf->connected) {
- for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
+ for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) {
struct eyeballer *baller = ctx->baller[i];
if(!baller || !baller->cf)
continue;
@@ -962,7 +958,7 @@
return CURLE_OK;
}
- (void)blocking; /* TODO: do we want to support this? */
+ (void)blocking;
DEBUGASSERT(ctx);
*done = FALSE;
@@ -1037,7 +1033,7 @@
if(cf->connected)
return cf->next->cft->has_data_pending(cf->next, data);
- for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
+ for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) {
struct eyeballer *baller = ctx->baller[i];
if(!baller || !baller->cf)
continue;
@@ -1056,7 +1052,7 @@
size_t i;
memset(&tmax, 0, sizeof(tmax));
- for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
+ for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) {
struct eyeballer *baller = ctx->baller[i];
memset(&t, 0, sizeof(t));
@@ -1081,7 +1077,7 @@
int reply_ms = -1;
size_t i;
- for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
+ for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) {
struct eyeballer *baller = ctx->baller[i];
int breply_ms;
@@ -1215,7 +1211,7 @@
static cf_ip_connect_create *get_cf_create(int transport)
{
size_t i;
- for(i = 0; i < ARRAYSIZE(transport_providers); ++i) {
+ for(i = 0; i < CURL_ARRAYSIZE(transport_providers); ++i) {
if(transport == transport_providers[i].transport)
return transport_providers[i].cf_create;
}
@@ -1469,7 +1465,7 @@
cf_ip_connect_create *cf_create)
{
size_t i;
- for(i = 0; i < ARRAYSIZE(transport_providers); ++i) {
+ for(i = 0; i < CURL_ARRAYSIZE(transport_providers); ++i) {
if(transport == transport_providers[i].transport) {
transport_providers[i].cf_create = cf_create;
return;
diff --git a/Utilities/cmcurl/lib/content_encoding.c b/Utilities/cmcurl/lib/content_encoding.c
index 3111bed..e83a790 100644
--- a/Utilities/cmcurl/lib/content_encoding.c
+++ b/Utilities/cmcurl/lib/content_encoding.c
@@ -69,6 +69,10 @@
#ifdef HAVE_LIBZ
+#if !defined(ZLIB_VERNUM) || (ZLIB_VERNUM < 0x1204)
+#error "requires zlib 1.2.0.4 or newer"
+#endif
+
typedef enum {
ZLIB_UNINIT, /* uninitialized */
ZLIB_INIT, /* initialized */
@@ -309,24 +313,15 @@
{
struct zlib_writer *zp = (struct zlib_writer *) writer;
z_stream *z = &zp->z; /* zlib state structure */
- const char *v = zlibVersion();
/* Initialize zlib */
z->zalloc = (alloc_func) zalloc_cb;
z->zfree = (free_func) zfree_cb;
- if(strcmp(v, "1.2.0.4") >= 0) {
- /* zlib version >= 1.2.0.4 supports transparent gzip decompressing */
- if(inflateInit2(z, MAX_WBITS + 32) != Z_OK) {
- return process_zlib_error(data, z);
- }
- zp->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */
- }
- else {
- failf(data, "too old zlib version: %s", v);
- return CURLE_FAILED_INIT;
- }
+ if(inflateInit2(z, MAX_WBITS + 32) != Z_OK)
+ return process_zlib_error(data, z);
+ zp->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */
return CURLE_OK;
}
diff --git a/Utilities/cmcurl/lib/cookie.c b/Utilities/cmcurl/lib/cookie.c
index 6fe949b..9819768 100644
--- a/Utilities/cmcurl/lib/cookie.c
+++ b/Utilities/cmcurl/lib/cookie.c
@@ -879,7 +879,7 @@
/*
* flag: A TRUE/FALSE value indicating if all machines within a given
* domain can access the variable. Set TRUE when the cookie says
- * .domain.com and to false when the domain is complete www.domain.com
+ * .example.com and to false when the domain is complete www.example.com
*/
co->tailmatch = !!strncasecompare(ptr, "TRUE", len);
break;
diff --git a/Utilities/cmcurl/lib/curl_config.h.cmake b/Utilities/cmcurl/lib/curl_config.h.cmake
index 32f1d0c..2091065 100644
--- a/Utilities/cmcurl/lib/curl_config.h.cmake
+++ b/Utilities/cmcurl/lib/curl_config.h.cmake
@@ -428,6 +428,9 @@
/* If you have poll */
#cmakedefine HAVE_POLL 1
+/* If you have realpath */
+#cmakedefine HAVE_REALPATH 1
+
/* Define to 1 if you have the <poll.h> header file. */
#cmakedefine HAVE_POLL_H 1
diff --git a/Utilities/cmcurl/lib/curl_setup.h b/Utilities/cmcurl/lib/curl_setup.h
index 1aac082..89500a1 100644
--- a/Utilities/cmcurl/lib/curl_setup.h
+++ b/Utilities/cmcurl/lib/curl_setup.h
@@ -948,6 +948,8 @@
as their argument */
#define STRCONST(x) x,sizeof(x)-1
+#define CURL_ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
+
/* Some versions of the Android NDK is missing the declaration */
#if defined(HAVE_GETPWUID_R) && \
defined(__ANDROID_API__) && (__ANDROID_API__ < 21)
@@ -998,10 +1000,16 @@
# endif
#endif
+#ifdef USE_OPENSSL
/* OpenSSLv3 marks DES, MD5 and ENGINE functions deprecated but we have no
replacements (yet) so tell the compiler to not warn for them. */
-#ifdef USE_OPENSSL
-#define OPENSSL_SUPPRESS_DEPRECATED
+# define OPENSSL_SUPPRESS_DEPRECATED
+# ifdef _WIN32
+/* Silence LibreSSL warnings about wincrypt.h collision. Works in 3.8.2+ */
+# ifndef LIBRESSL_DISABLE_OVERRIDE_WINCRYPT_DEFINES_WARNING
+# define LIBRESSL_DISABLE_OVERRIDE_WINCRYPT_DEFINES_WARNING
+# endif
+# endif
#endif
#if defined(CURL_INLINE)
diff --git a/Utilities/cmcurl/lib/curl_trc.c b/Utilities/cmcurl/lib/curl_trc.c
index e773e4f..07137c1 100644
--- a/Utilities/cmcurl/lib/curl_trc.c
+++ b/Utilities/cmcurl/lib/curl_trc.c
@@ -53,10 +53,6 @@
#include "curl_memory.h"
#include "memdebug.h"
-#ifndef ARRAYSIZE
-#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
-#endif
-
void Curl_debug(struct Curl_easy *data, curl_infotype type,
char *ptr, size_t size)
{
@@ -349,13 +345,13 @@
{
size_t i;
- for(i = 0; i < ARRAYSIZE(trc_cfts); ++i) {
+ for(i = 0; i < CURL_ARRAYSIZE(trc_cfts); ++i) {
if(strcasecompare(token, trc_cfts[i].cft->name)) {
trc_cfts[i].cft->log_level = lvl;
break;
}
}
- for(i = 0; i < ARRAYSIZE(trc_feats); ++i) {
+ for(i = 0; i < CURL_ARRAYSIZE(trc_feats); ++i) {
if(strcasecompare(token, trc_feats[i].feat->name)) {
trc_feats[i].feat->log_level = lvl;
break;
@@ -367,11 +363,11 @@
{
size_t i;
- for(i = 0; i < ARRAYSIZE(trc_cfts); ++i) {
+ for(i = 0; i < CURL_ARRAYSIZE(trc_cfts); ++i) {
if(!category || (trc_cfts[i].category & category))
trc_cfts[i].cft->log_level = lvl;
}
- for(i = 0; i < ARRAYSIZE(trc_feats); ++i) {
+ for(i = 0; i < CURL_ARRAYSIZE(trc_feats); ++i) {
if(!category || (trc_feats[i].category & category))
trc_feats[i].feat->log_level = lvl;
}
diff --git a/Utilities/cmcurl/lib/ftp.c b/Utilities/cmcurl/lib/ftp.c
index 8e7ec5e..5733d69 100644
--- a/Utilities/cmcurl/lib/ftp.c
+++ b/Utilities/cmcurl/lib/ftp.c
@@ -4108,11 +4108,6 @@
return CURLE_OK;
}
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4706) /* assignment within conditional expression */
-#endif
-
/***********************************************************************
*
* ftp_parse_url_path()
@@ -4203,7 +4198,8 @@
}
/* parse the URL path into separate path components */
- while((slashPos = strchr(curPos, '/'))) {
+ /* !checksrc! disable EQUALSNULL 1 */
+ while((slashPos = strchr(curPos, '/')) != NULL) {
size_t compLen = slashPos - curPos;
/* path starts with a slash: add that as a directory */
@@ -4267,10 +4263,6 @@
return CURLE_OK;
}
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
/* call this when the DO phase has completed */
static CURLcode ftp_dophase_done(struct Curl_easy *data, bool connected)
{
diff --git a/Utilities/cmcurl/lib/http.c b/Utilities/cmcurl/lib/http.c
index 1fe0904..5bd2bd4 100644
--- a/Utilities/cmcurl/lib/http.c
+++ b/Utilities/cmcurl/lib/http.c
@@ -495,7 +495,6 @@
ongoing_auth ? " send, " : "");
/* We decided to abort the ongoing transfer */
streamclose(conn, "Mid-auth HTTP and much data left to send");
- /* FIXME: questionable manipulation here, can we do this differently? */
data->req.size = 0; /* do not download any more than 0 bytes */
}
return CURLE_OK;
@@ -2477,7 +2476,7 @@
}
else if(data->state.resume_from) {
/* This is because "resume" was selected */
- /* TODO: not sure if we want to send this header during authentication
+ /* Not sure if we want to send this header during authentication
* negotiation, but test1084 checks for it. In which case we have a
* "null" client reader installed that gives an unexpected length. */
curl_off_t total_len = data->req.authneg ?
@@ -3597,10 +3596,9 @@
}
#endif
else {
- /* We silently accept this as the final response.
- * TODO: this looks, uhm, wrong. What are we switching to if we
- * did not ask for an Upgrade? Maybe the application provided an
- * `Upgrade: xxx` header? */
+ /* We silently accept this as the final response. What are we
+ * switching to if we did not ask for an Upgrade? Maybe the
+ * application provided an `Upgrade: xxx` header? */
k->header = FALSE;
}
break;
diff --git a/Utilities/cmcurl/lib/http1.c b/Utilities/cmcurl/lib/http1.c
index f135b20..9d2461e 100644
--- a/Utilities/cmcurl/lib/http1.c
+++ b/Utilities/cmcurl/lib/http1.c
@@ -167,8 +167,6 @@
if(!target_len || !hv_len)
goto out;
- /* TODO: we do not check HTTP_VERSION for conformity, should
- + do that when STRICT option is supplied. */
(void)hv;
/* The TARGET can be (rfc 9112, ch. 3.2):
diff --git a/Utilities/cmcurl/lib/imap.c b/Utilities/cmcurl/lib/imap.c
index e5ee401..49abaf4 100644
--- a/Utilities/cmcurl/lib/imap.c
+++ b/Utilities/cmcurl/lib/imap.c
@@ -193,19 +193,6 @@
};
-#ifdef USE_SSL
-static void imap_to_imaps(struct connectdata *conn)
-{
- /* Change the connection handler */
- conn->handler = &Curl_handler_imaps;
-
- /* Set the connection's upgraded to TLS flag */
- conn->bits.tls_upgraded = TRUE;
-}
-#else
-#define imap_to_imaps(x) Curl_nop_stmt
-#endif
-
/***********************************************************************
*
* imap_matchresp()
@@ -474,6 +461,7 @@
static CURLcode imap_perform_upgrade_tls(struct Curl_easy *data,
struct connectdata *conn)
{
+#ifdef USE_SSL
/* Start the SSL connection */
struct imap_conn *imapc = &conn->proto.imapc;
CURLcode result;
@@ -483,21 +471,27 @@
result = Curl_ssl_cfilter_add(data, conn, FIRSTSOCKET);
if(result)
goto out;
+ /* Change the connection handler */
+ conn->handler = &Curl_handler_imaps;
+ conn->bits.tls_upgraded = TRUE;
}
+ DEBUGASSERT(!imapc->ssldone);
result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssldone);
- if(!result) {
+ DEBUGF(infof(data, "imap_perform_upgrade_tls, connect -> %d, %d",
+ result, ssldone));
+ if(!result && ssldone) {
imapc->ssldone = ssldone;
- if(imapc->state != IMAP_UPGRADETLS)
- imap_state(data, IMAP_UPGRADETLS);
-
- if(imapc->ssldone) {
- imap_to_imaps(conn);
- result = imap_perform_capability(data, conn);
- }
+ /* perform CAPA now, changes imapc->state out of IMAP_UPGRADETLS */
+ result = imap_perform_capability(data, conn);
}
out:
return result;
+#else
+ (void)data;
+ (void)conn;
+ return CURLE_NOT_BUILT_IN;
+#endif
}
/***********************************************************************
@@ -998,7 +992,7 @@
result = imap_perform_authentication(data, conn);
}
else
- result = imap_perform_upgrade_tls(data, conn);
+ imap_state(data, IMAP_UPGRADETLS);
return result;
}
@@ -1307,8 +1301,12 @@
(void)data;
/* Busy upgrading the connection; right now all I/O is SSL/TLS, not IMAP */
- if(imapc->state == IMAP_UPGRADETLS)
- return imap_perform_upgrade_tls(data, conn);
+upgrade_tls:
+ if(imapc->state == IMAP_UPGRADETLS) {
+ result = imap_perform_upgrade_tls(data, conn);
+ if(result || (imapc->state == IMAP_UPGRADETLS))
+ return result;
+ }
/* Flush any data that needs to be sent */
if(pp->sendleft)
@@ -1339,6 +1337,10 @@
case IMAP_STARTTLS:
result = imap_state_starttls_resp(data, imapcode, imapc->state);
+ /* During UPGRADETLS, leave the read loop as we need to connect
+ * (e.g. TLS handshake) before we continue sending/receiving. */
+ if(!result && (imapc->state == IMAP_UPGRADETLS))
+ goto upgrade_tls;
break;
case IMAP_AUTHENTICATE:
@@ -1392,14 +1394,6 @@
struct connectdata *conn = data->conn;
struct imap_conn *imapc = &conn->proto.imapc;
- if(Curl_conn_is_ssl(conn, FIRSTSOCKET) && !imapc->ssldone) {
- bool ssldone = FALSE;
- result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssldone);
- imapc->ssldone = ssldone;
- if(result || !ssldone)
- return result;
- }
-
result = Curl_pp_statemach(data, &imapc->pp, FALSE, FALSE);
*done = (imapc->state == IMAP_STOP);
diff --git a/Utilities/cmcurl/lib/inet_ntop.h b/Utilities/cmcurl/lib/inet_ntop.h
index 3b90ed3..6bc7e27 100644
--- a/Utilities/cmcurl/lib/inet_ntop.h
+++ b/Utilities/cmcurl/lib/inet_ntop.h
@@ -29,6 +29,12 @@
char *Curl_inet_ntop(int af, const void *addr, char *buf, size_t size);
#ifdef HAVE_INET_NTOP
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
diff --git a/Utilities/cmcurl/lib/inet_pton.h b/Utilities/cmcurl/lib/inet_pton.h
index 50bce61..915385f 100644
--- a/Utilities/cmcurl/lib/inet_pton.h
+++ b/Utilities/cmcurl/lib/inet_pton.h
@@ -29,6 +29,12 @@
int Curl_inet_pton(int, const char *, void *);
#ifdef HAVE_INET_PTON
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
diff --git a/Utilities/cmcurl/lib/ldap.c b/Utilities/cmcurl/lib/ldap.c
index 0fa304b..77bd9fb 100644
--- a/Utilities/cmcurl/lib/ldap.c
+++ b/Utilities/cmcurl/lib/ldap.c
@@ -389,55 +389,7 @@
#else
int ldap_option;
char *ldap_ca = conn->ssl_config.CAfile;
-#if defined(CURL_HAS_NOVELL_LDAPSDK)
- rc = ldapssl_client_init(NULL, NULL);
- if(rc != LDAP_SUCCESS) {
- failf(data, "LDAP local: ldapssl_client_init %s", ldap_err2string(rc));
- result = CURLE_SSL_CERTPROBLEM;
- goto quit;
- }
- if(conn->ssl_config.verifypeer) {
- /* Novell SDK supports DER or BASE64 files. */
- int cert_type = LDAPSSL_CERT_FILETYPE_B64;
- if((data->set.ssl.cert_type) &&
- (strcasecompare(data->set.ssl.cert_type, "DER")))
- cert_type = LDAPSSL_CERT_FILETYPE_DER;
- if(!ldap_ca) {
- failf(data, "LDAP local: ERROR %s CA cert not set",
- (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"));
- result = CURLE_SSL_CERTPROBLEM;
- goto quit;
- }
- infof(data, "LDAP local: using %s CA cert '%s'",
- (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"),
- ldap_ca);
- rc = ldapssl_add_trusted_cert(ldap_ca, cert_type);
- if(rc != LDAP_SUCCESS) {
- failf(data, "LDAP local: ERROR setting %s CA cert: %s",
- (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"),
- ldap_err2string(rc));
- result = CURLE_SSL_CERTPROBLEM;
- goto quit;
- }
- ldap_option = LDAPSSL_VERIFY_SERVER;
- }
- else
- ldap_option = LDAPSSL_VERIFY_NONE;
- rc = ldapssl_set_verify_mode(ldap_option);
- if(rc != LDAP_SUCCESS) {
- failf(data, "LDAP local: ERROR setting cert verify mode: %s",
- ldap_err2string(rc));
- result = CURLE_SSL_CERTPROBLEM;
- goto quit;
- }
- server = ldapssl_init(host, conn->primary.remote_port, 1);
- if(!server) {
- failf(data, "LDAP local: Cannot connect to %s:%u",
- conn->host.dispname, conn->primary.remote_port);
- result = CURLE_COULDNT_CONNECT;
- goto quit;
- }
-#elif defined(LDAP_OPT_X_TLS)
+#ifdef LDAP_OPT_X_TLS
if(conn->ssl_config.verifypeer) {
/* OpenLDAP SDK supports BASE64 files. */
if((data->set.ssl.cert_type) &&
@@ -758,10 +710,6 @@
ldap_free_urldesc(ludp);
if(server)
ldap_unbind_s(server);
-#if defined(HAVE_LDAP_SSL) && defined(CURL_HAS_NOVELL_LDAPSDK)
- if(ldap_ssl)
- ldapssl_client_deinit();
-#endif /* HAVE_LDAP_SSL && CURL_HAS_NOVELL_LDAPSDK */
FREE_ON_WINLDAP(host);
diff --git a/Utilities/cmcurl/lib/mime.c b/Utilities/cmcurl/lib/mime.c
index d448891..a90d170 100644
--- a/Utilities/cmcurl/lib/mime.c
+++ b/Utilities/cmcurl/lib/mime.c
@@ -1598,8 +1598,8 @@
(void) size; /* Always 1. */
- /* TODO: this loop is broken. If `nitems` is <= 4, some encoders will
- * return STOP_FILLING without adding any data and this loops infinitely. */
+ /* If `nitems` is <= 4, some encoders will return STOP_FILLING without
+ * adding any data and this loops infinitely. */
do {
hasread = FALSE;
ret = readback_part(part, buffer, nitems, &hasread);
diff --git a/Utilities/cmcurl/lib/multi.c b/Utilities/cmcurl/lib/multi.c
index d4dd4a0..2b05e94 100644
--- a/Utilities/cmcurl/lib/multi.c
+++ b/Utilities/cmcurl/lib/multi.c
@@ -1538,15 +1538,6 @@
Curl_multi struct that are constant */
struct Curl_multi *multi = m;
-#if defined(ENABLE_WAKEUP) && !defined(USE_WINSOCK)
-#ifdef USE_EVENTFD
- const void *buf;
- const uint64_t val = 1;
-#else
- char buf[1];
-#endif
-#endif
-
/* GOOD_MULTI_HANDLE can be safely called */
if(!GOOD_MULTI_HANDLE(multi))
return CURLM_BAD_HANDLE;
@@ -1560,15 +1551,14 @@
making it safe to access from another thread after the init part
and before cleanup */
if(multi->wakeup_pair[1] != CURL_SOCKET_BAD) {
-#ifdef USE_EVENTFD
- buf = &val;
- /* eventfd has a stringent rule of requiring the 8-byte buffer when
- calling write(2) on it, which makes the sizeof(buf) below fine since
- this is only used on 64-bit systems and then the pointer is 64-bit */
-#else
- buf[0] = 1;
-#endif
while(1) {
+#ifdef USE_EVENTFD
+ /* eventfd has a stringent rule of requiring the 8-byte buffer when
+ calling write(2) on it */
+ const uint64_t buf[1] = { 1 };
+#else
+ const char buf[1] = { 1 };
+#endif
/* swrite() is not thread-safe in general, because concurrent calls
can have their messages interleaved, but in this case the content
of the messages does not matter, which makes it ok to call.
diff --git a/Utilities/cmcurl/lib/netrc.c b/Utilities/cmcurl/lib/netrc.c
index 7ad81ec..ba67089 100644
--- a/Utilities/cmcurl/lib/netrc.c
+++ b/Utilities/cmcurl/lib/netrc.c
@@ -59,23 +59,26 @@
#define FOUND_LOGIN 1
#define FOUND_PASSWORD 2
-#define NETRC_FILE_MISSING 1
-#define NETRC_FAILED -1
-#define NETRC_SUCCESS 0
-
#define MAX_NETRC_LINE 16384
#define MAX_NETRC_FILE (128*1024)
#define MAX_NETRC_TOKEN 4096
-static CURLcode file2memory(const char *filename, struct dynbuf *filebuf)
+/* convert a dynbuf call CURLcode error to a NETRCcode error */
+#define curl2netrc(result) \
+ (((result) == CURLE_OUT_OF_MEMORY) ? \
+ NETRC_OUT_OF_MEMORY : NETRC_SYNTAX_ERROR)
+
+static NETRCcode file2memory(const char *filename, struct dynbuf *filebuf)
{
- CURLcode result = CURLE_OK;
+ NETRCcode ret = NETRC_FILE_MISSING; /* if it cannot open the file */
FILE *file = fopen(filename, FOPEN_READTEXT);
struct dynbuf linebuf;
Curl_dyn_init(&linebuf, MAX_NETRC_LINE);
if(file) {
+ ret = NETRC_OK;
while(Curl_get_line(&linebuf, file)) {
+ CURLcode result;
const char *line = Curl_dyn_ptr(&linebuf);
/* skip comments on load */
while(ISBLANK(*line))
@@ -83,27 +86,29 @@
if(*line == '#')
continue;
result = Curl_dyn_add(filebuf, line);
- if(result)
+ if(result) {
+ ret = curl2netrc(result);
goto done;
+ }
}
}
done:
Curl_dyn_free(&linebuf);
if(file)
fclose(file);
- return result;
+ return ret;
}
/*
* Returns zero on success.
*/
-static int parsenetrc(struct store_netrc *store,
- const char *host,
- char **loginp, /* might point to a username */
- char **passwordp,
- const char *netrcfile)
+static NETRCcode parsenetrc(struct store_netrc *store,
+ const char *host,
+ char **loginp, /* might point to a username */
+ char **passwordp,
+ const char *netrcfile)
{
- int retcode = NETRC_FILE_MISSING;
+ NETRCcode retcode = NETRC_NO_MATCH;
char *login = *loginp;
char *password = NULL;
bool specific_login = !!login; /* points to something */
@@ -120,8 +125,9 @@
Curl_dyn_init(&token, MAX_NETRC_TOKEN);
if(!store->loaded) {
- if(file2memory(netrcfile, filebuf))
- return NETRC_FAILED;
+ NETRCcode ret = file2memory(netrcfile, filebuf);
+ if(ret)
+ return ret;
store->loaded = TRUE;
}
@@ -151,12 +157,18 @@
tok_end = tok;
if(!quoted) {
size_t len = 0;
+ CURLcode result;
while(!ISSPACE(*tok_end)) {
tok_end++;
len++;
}
- if(!len || Curl_dyn_addn(&token, tok, len)) {
- retcode = NETRC_FAILED;
+ if(!len) {
+ retcode = NETRC_SYNTAX_ERROR;
+ goto out;
+ }
+ result = Curl_dyn_addn(&token, tok, len);
+ if(result) {
+ retcode = curl2netrc(result);
goto out;
}
}
@@ -165,6 +177,7 @@
bool endquote = FALSE;
tok_end++; /* pass the leading quote */
while(*tok_end) {
+ CURLcode result;
char s = *tok_end;
if(escape) {
escape = FALSE;
@@ -190,15 +203,16 @@
endquote = TRUE;
break;
}
- if(Curl_dyn_addn(&token, &s, 1)) {
- retcode = NETRC_FAILED;
+ result = Curl_dyn_addn(&token, &s, 1);
+ if(result) {
+ retcode = curl2netrc(result);
goto out;
}
tok_end++;
}
if(escape || !endquote) {
/* bad syntax, get out */
- retcode = NETRC_FAILED;
+ retcode = NETRC_SYNTAX_ERROR;
goto out;
}
}
@@ -226,7 +240,7 @@
}
else if(strcasecompare("default", tok)) {
state = HOSTVALID;
- retcode = NETRC_SUCCESS; /* we did find our host */
+ retcode = NETRC_OK; /* we did find our host */
}
break;
case MACDEF:
@@ -237,7 +251,7 @@
if(strcasecompare(host, tok)) {
/* and yes, this is our host! */
state = HOSTVALID;
- retcode = NETRC_SUCCESS; /* we did find our host */
+ retcode = NETRC_OK; /* we did find our host */
}
else
/* not our host */
@@ -253,7 +267,7 @@
free(login);
login = strdup(tok);
if(!login) {
- retcode = NETRC_FAILED; /* allocation failed */
+ retcode = NETRC_OUT_OF_MEMORY; /* allocation failed */
goto out;
}
}
@@ -264,7 +278,7 @@
free(password);
password = strdup(tok);
if(!password) {
- retcode = NETRC_FAILED; /* allocation failed */
+ retcode = NETRC_OUT_OF_MEMORY; /* allocation failed */
goto out;
}
if(!specific_login || our_login)
@@ -290,7 +304,7 @@
}
else if(strcasecompare("default", tok)) {
state = HOSTVALID;
- retcode = NETRC_SUCCESS; /* we did find our host */
+ retcode = NETRC_OK; /* we did find our host */
Curl_safefree(password);
if(!specific_login)
Curl_safefree(login);
@@ -321,11 +335,11 @@
/* success without a password, set a blank one */
password = strdup("");
if(!password)
- retcode = 1; /* out of memory */
+ retcode = NETRC_OUT_OF_MEMORY; /* out of memory */
}
else if(!login && !password)
/* a default with no credentials */
- retcode = NETRC_FILE_MISSING;
+ retcode = NETRC_NO_MATCH;
}
if(!retcode) {
/* success */
@@ -343,17 +357,34 @@
return retcode;
}
+const char *Curl_netrc_strerror(NETRCcode ret)
+{
+ switch(ret) {
+ default:
+ return ""; /* not a legit error */
+ case NETRC_FILE_MISSING:
+ return "no such file";
+ case NETRC_NO_MATCH:
+ return "no matching entry";
+ case NETRC_OUT_OF_MEMORY:
+ return "out of memory";
+ case NETRC_SYNTAX_ERROR:
+ return "syntax error";
+ }
+ /* never reached */
+}
+
/*
* @unittest: 1304
*
* *loginp and *passwordp MUST be allocated if they are not NULL when passed
* in.
*/
-int Curl_parsenetrc(struct store_netrc *store, const char *host,
- char **loginp, char **passwordp,
- char *netrcfile)
+NETRCcode Curl_parsenetrc(struct store_netrc *store, const char *host,
+ char **loginp, char **passwordp,
+ char *netrcfile)
{
- int retcode = 1;
+ NETRCcode retcode = NETRC_OK;
char *filealloc = NULL;
if(!netrcfile) {
@@ -391,23 +422,23 @@
}
if(!home)
- return retcode; /* no home directory found (or possibly out of
- memory) */
+ return NETRC_FILE_MISSING; /* no home directory found (or possibly out
+ of memory) */
filealloc = aprintf("%s%s.netrc", home, DIR_CHAR);
if(!filealloc) {
free(homea);
- return -1;
+ return NETRC_OUT_OF_MEMORY;
}
retcode = parsenetrc(store, host, loginp, passwordp, filealloc);
free(filealloc);
#ifdef _WIN32
- if((retcode == NETRC_FILE_MISSING) || (retcode == NETRC_FAILED)) {
+ if(retcode == NETRC_FILE_MISSING) {
/* fallback to the old-style "_netrc" file */
filealloc = aprintf("%s%s_netrc", home, DIR_CHAR);
if(!filealloc) {
free(homea);
- return -1;
+ return NETRC_OUT_OF_MEMORY;
}
retcode = parsenetrc(store, host, loginp, passwordp, filealloc);
free(filealloc);
diff --git a/Utilities/cmcurl/lib/netrc.h b/Utilities/cmcurl/lib/netrc.h
index 0ef9ff7..ac0f886 100644
--- a/Utilities/cmcurl/lib/netrc.h
+++ b/Utilities/cmcurl/lib/netrc.h
@@ -34,12 +34,21 @@
BIT(loaded);
};
+typedef enum {
+ NETRC_OK,
+ NETRC_NO_MATCH, /* no matching entry in the file */
+ NETRC_SYNTAX_ERROR, /* in the netrc file */
+ NETRC_FILE_MISSING, /* the netrc file does not exist */
+ NETRC_OUT_OF_MEMORY, /* while parsing netrc */
+ NETRC_LAST /* never used */
+} NETRCcode;
+
+const char *Curl_netrc_strerror(NETRCcode ret);
void Curl_netrc_init(struct store_netrc *s);
void Curl_netrc_cleanup(struct store_netrc *s);
-/* returns -1 on failure, 0 if the host is found, 1 is the host is not found */
-int Curl_parsenetrc(struct store_netrc *s, const char *host, char **loginp,
- char **passwordp, char *filename);
+NETRCcode Curl_parsenetrc(struct store_netrc *s, const char *host,
+ char **loginp, char **passwordp, char *filename);
/* Assume: (*passwordp)[0]=0, host[0] != 0.
* If (*loginp)[0] = 0, search for login and password within a machine
* section in the netrc.
diff --git a/Utilities/cmcurl/lib/pop3.c b/Utilities/cmcurl/lib/pop3.c
index 86e9eca..07c7dba 100644
--- a/Utilities/cmcurl/lib/pop3.c
+++ b/Utilities/cmcurl/lib/pop3.c
@@ -83,10 +83,6 @@
#include "curl_memory.h"
#include "memdebug.h"
-#ifndef ARRAYSIZE
-#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
-#endif
-
/* Local API functions */
static CURLcode pop3_regular_transfer(struct Curl_easy *data, bool *done);
static CURLcode pop3_do(struct Curl_easy *data, bool *done);
@@ -192,19 +188,6 @@
SASL_FLAG_BASE64 /* Configuration flags */
};
-#ifdef USE_SSL
-static void pop3_to_pop3s(struct connectdata *conn)
-{
- /* Change the connection handler */
- conn->handler = &Curl_handler_pop3s;
-
- /* Set the connection's upgraded to TLS flag */
- conn->bits.tls_upgraded = TRUE;
-}
-#else
-#define pop3_to_pop3s(x) Curl_nop_stmt
-#endif
-
struct pop3_cmd {
const char *name;
unsigned short nlen;
@@ -239,7 +222,7 @@
static bool pop3_is_multiline(const char *cmdline)
{
size_t i;
- for(i = 0; i < ARRAYSIZE(pop3cmds); ++i) {
+ for(i = 0; i < CURL_ARRAYSIZE(pop3cmds); ++i) {
if(strncasecompare(pop3cmds[i].name, cmdline, pop3cmds[i].nlen)) {
if(!cmdline[pop3cmds[i].nlen])
return pop3cmds[i].multiline;
@@ -425,6 +408,7 @@
static CURLcode pop3_perform_upgrade_tls(struct Curl_easy *data,
struct connectdata *conn)
{
+#ifdef USE_SSL
/* Start the SSL connection */
struct pop3_conn *pop3c = &conn->proto.pop3c;
CURLcode result;
@@ -434,22 +418,27 @@
result = Curl_ssl_cfilter_add(data, conn, FIRSTSOCKET);
if(result)
goto out;
+ /* Change the connection handler */
+ conn->handler = &Curl_handler_pop3s;
+ conn->bits.tls_upgraded = TRUE;
}
+ DEBUGASSERT(!pop3c->ssldone);
result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssldone);
-
- if(!result) {
+ DEBUGF(infof(data, "pop3_perform_upgrade_tls, connect -> %d, %d",
+ result, ssldone));
+ if(!result && ssldone) {
pop3c->ssldone = ssldone;
- if(pop3c->state != POP3_UPGRADETLS)
- pop3_state(data, POP3_UPGRADETLS);
-
- if(pop3c->ssldone) {
- pop3_to_pop3s(conn);
- result = pop3_perform_capa(data, conn);
- }
+ /* perform CAPA now, changes pop3c->state out of POP3_UPGRADETLS */
+ result = pop3_perform_capa(data, conn);
}
out:
return result;
+#else
+ (void)data;
+ (void)conn;
+ return CURLE_NOT_BUILT_IN;
+#endif
}
/***********************************************************************
@@ -861,7 +850,7 @@
result = pop3_perform_authentication(data, conn);
}
else
- result = pop3_perform_upgrade_tls(data, conn);
+ pop3_state(data, POP3_UPGRADETLS);
return result;
}
@@ -1039,8 +1028,12 @@
(void)data;
/* Busy upgrading the connection; right now all I/O is SSL/TLS, not POP3 */
- if(pop3c->state == POP3_UPGRADETLS)
- return pop3_perform_upgrade_tls(data, conn);
+upgrade_tls:
+ if(pop3c->state == POP3_UPGRADETLS) {
+ result = pop3_perform_upgrade_tls(data, conn);
+ if(result || (pop3c->state == POP3_UPGRADETLS))
+ return result;
+ }
/* Flush any data that needs to be sent */
if(pp->sendleft)
@@ -1067,6 +1060,10 @@
case POP3_STARTTLS:
result = pop3_state_starttls_resp(data, conn, pop3code, pop3c->state);
+ /* During UPGRADETLS, leave the read loop as we need to connect
+ * (e.g. TLS handshake) before we continue sending/receiving. */
+ if(!result && (pop3c->state == POP3_UPGRADETLS))
+ goto upgrade_tls;
break;
case POP3_AUTH:
@@ -1112,17 +1109,6 @@
struct connectdata *conn = data->conn;
struct pop3_conn *pop3c = &conn->proto.pop3c;
- /* Issue #16166, STLS seems to stall and time out. Revert to previous
- * check, but it remains to find out why this is wrong. */
- /* if(Curl_conn_is_ssl(conn, FIRSTSOCKET) && !pop3c->ssldone) { */
- if((conn->handler->flags & PROTOPT_SSL) && !pop3c->ssldone) {
- bool ssldone = FALSE;
- result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssldone);
- pop3c->ssldone = ssldone;
- if(result || !pop3c->ssldone)
- return result;
- }
-
result = Curl_pp_statemach(data, &pop3c->pp, FALSE, FALSE);
*done = (pop3c->state == POP3_STOP);
diff --git a/Utilities/cmcurl/lib/setopt.c b/Utilities/cmcurl/lib/setopt.c
index e264c73..8a87d24 100644
--- a/Utilities/cmcurl/lib/setopt.c
+++ b/Utilities/cmcurl/lib/setopt.c
@@ -601,8 +601,8 @@
switch(arg) {
case CURL_HTTP_VERSION_NONE:
#ifdef USE_HTTP2
- /* TODO: this seems an undesirable quirk to force a behaviour on
- * lower implementations that they should recognize independently? */
+ /* This seems an undesirable quirk to force a behaviour on lower
+ * implementations that they should recognize independently? */
arg = CURL_HTTP_VERSION_2TLS;
#endif
/* accepted */
@@ -1584,10 +1584,6 @@
if(data->share->hsts == data->hsts)
data->hsts = NULL;
#endif
-#ifdef USE_SSL
- if(data->share->ssl_scache == data->state.ssl_scache)
- data->state.ssl_scache = data->multi ? data->multi->ssl_scache : NULL;
-#endif
#ifdef USE_LIBPSL
if(data->psl == &data->share->psl)
data->psl = data->multi ? &data->multi->psl : NULL;
@@ -1628,10 +1624,6 @@
data->hsts = data->share->hsts;
}
#endif
-#ifdef USE_SSL
- if(data->share->ssl_scache)
- data->state.ssl_scache = data->share->ssl_scache;
-#endif
#ifdef USE_LIBPSL
if(data->share->specifier & (1 << CURL_LOCK_DATA_PSL))
data->psl = &data->share->psl;
@@ -2425,6 +2417,7 @@
*/
return Curl_setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY], ptr);
+#if defined(USE_LIBSSH2) || defined(USE_LIBSSH)
case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
/*
* Option to allow for the MD5 of the host public key to be checked
@@ -2437,7 +2430,7 @@
* Store the filename to read known hosts from.
*/
return Curl_setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS], ptr);
-
+#endif
case CURLOPT_SSH_KEYDATA:
/*
* Custom client data to pass to the SSH keyfunc callback
diff --git a/Utilities/cmcurl/lib/smb.c b/Utilities/cmcurl/lib/smb.c
index 752386d..d22030c 100644
--- a/Utilities/cmcurl/lib/smb.c
+++ b/Utilities/cmcurl/lib/smb.c
@@ -881,7 +881,16 @@
return CURLE_COULDNT_CONNECT;
}
nrsp = msg;
+#if defined(__GNUC__) && __GNUC__ >= 13
+#pragma GCC diagnostic push
+/* error: 'memcpy' offset [74, 80] from the object at '<unknown>' is out of
+ the bounds of referenced subobject 'bytes' with type 'char[1]' */
+#pragma GCC diagnostic ignored "-Warray-bounds"
+#endif
memcpy(smbc->challenge, nrsp->bytes, sizeof(smbc->challenge));
+#if defined(__GNUC__) && __GNUC__ >= 13
+#pragma GCC diagnostic pop
+#endif
smbc->session_key = smb_swap32(nrsp->session_key);
result = smb_send_setup(data);
if(result) {
diff --git a/Utilities/cmcurl/lib/smtp.c b/Utilities/cmcurl/lib/smtp.c
index 7c631a1..b763557 100644
--- a/Utilities/cmcurl/lib/smtp.c
+++ b/Utilities/cmcurl/lib/smtp.c
@@ -189,19 +189,6 @@
SASL_FLAG_BASE64 /* Configuration flags */
};
-#ifdef USE_SSL
-static void smtp_to_smtps(struct connectdata *conn)
-{
- /* Change the connection handler */
- conn->handler = &Curl_handler_smtps;
-
- /* Set the connection's upgraded to TLS flag */
- conn->bits.tls_upgraded = TRUE;
-}
-#else
-#define smtp_to_smtps(x) Curl_nop_stmt
-#endif
-
/***********************************************************************
*
* smtp_endofresp()
@@ -396,31 +383,38 @@
*/
static CURLcode smtp_perform_upgrade_tls(struct Curl_easy *data)
{
+#ifdef USE_SSL
/* Start the SSL connection */
struct connectdata *conn = data->conn;
struct smtp_conn *smtpc = &conn->proto.smtpc;
CURLcode result;
bool ssldone = FALSE;
+ DEBUGASSERT(smtpc->state == SMTP_UPGRADETLS);
if(!Curl_conn_is_ssl(conn, FIRSTSOCKET)) {
result = Curl_ssl_cfilter_add(data, conn, FIRSTSOCKET);
if(result)
goto out;
+ /* Change the connection handler and SMTP state */
+ conn->handler = &Curl_handler_smtps;
+ conn->bits.tls_upgraded = TRUE;
}
+ DEBUGASSERT(!smtpc->ssldone);
result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssldone);
- if(!result) {
+ DEBUGF(infof(data, "smtp_perform_upgrade_tls, connect -> %d, %d",
+ result, ssldone));
+ if(!result && ssldone) {
smtpc->ssldone = ssldone;
- if(smtpc->state != SMTP_UPGRADETLS)
- smtp_state(data, SMTP_UPGRADETLS);
-
- if(smtpc->ssldone) {
- smtp_to_smtps(conn);
- result = smtp_perform_ehlo(data);
- }
+ /* perform EHLO now, changes smpt->state out of SMTP_UPGRADETLS */
+ result = smtp_perform_ehlo(data);
}
out:
return result;
+#else
+ (void)data;
+ return CURLE_NOT_BUILT_IN;
+#endif
}
/***********************************************************************
@@ -875,7 +869,7 @@
result = smtp_perform_authentication(data);
}
else
- result = smtp_perform_upgrade_tls(data);
+ smtp_state(data, SMTP_UPGRADETLS);
return result;
}
@@ -1204,8 +1198,11 @@
/* Busy upgrading the connection; right now all I/O is SSL/TLS, not SMTP */
upgrade_tls:
- if(smtpc->state == SMTP_UPGRADETLS)
- return smtp_perform_upgrade_tls(data);
+ if(smtpc->state == SMTP_UPGRADETLS) {
+ result = smtp_perform_upgrade_tls(data);
+ if(result || (smtpc->state == SMTP_UPGRADETLS))
+ return result;
+ }
/* Flush any data that needs to be sent */
if(pp->sendleft)
@@ -1288,14 +1285,6 @@
struct connectdata *conn = data->conn;
struct smtp_conn *smtpc = &conn->proto.smtpc;
- if(Curl_conn_is_ssl(conn, FIRSTSOCKET) && !smtpc->ssldone) {
- bool ssldone = FALSE;
- result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssldone);
- smtpc->ssldone = ssldone;
- if(result || !smtpc->ssldone)
- return result;
- }
-
result = Curl_pp_statemach(data, &smtpc->pp, FALSE, FALSE);
*done = (smtpc->state == SMTP_STOP);
diff --git a/Utilities/cmcurl/lib/telnet.c b/Utilities/cmcurl/lib/telnet.c
index 589f9da..e383917 100644
--- a/Utilities/cmcurl/lib/telnet.c
+++ b/Utilities/cmcurl/lib/telnet.c
@@ -777,22 +777,15 @@
}
}
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4706) /* assignment within conditional expression */
-#endif
static bool str_is_nonascii(const char *str)
{
char c;
- while((c = *str++))
+ while((c = *str++) != 0)
if(c & 0x80)
return TRUE;
return FALSE;
}
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
static CURLcode check_telnet_options(struct Curl_easy *data)
{
@@ -1559,10 +1552,9 @@
/* returned not-zero, this an error */
if(result) {
keepon = FALSE;
- /* TODO: in test 1452, macOS sees a ECONNRESET sometimes?
- * Is this the telnet test server not shutting down the socket
- * in a clean way? Seems to be timing related, happens more
- * on slow debug build */
+ /* In test 1452, macOS sees a ECONNRESET sometimes? Is this the
+ * telnet test server not shutting down the socket in a clean way?
+ * Seems to be timing related, happens more on slow debug build */
if(data->state.os_errno == ECONNRESET) {
DEBUGF(infof(data, "telnet_do, unexpected ECONNRESET on recv"));
}
diff --git a/Utilities/cmcurl/lib/transfer.c b/Utilities/cmcurl/lib/transfer.c
index c4b23a8..742828a 100644
--- a/Utilities/cmcurl/lib/transfer.c
+++ b/Utilities/cmcurl/lib/transfer.c
@@ -567,12 +567,6 @@
#endif
data->state.httpreq = data->set.method;
-#ifdef USE_SSL
- if(!data->state.ssl_scache)
- /* There was no ssl session cache set via a share, use the multi one */
- data->state.ssl_scache = data->multi->ssl_scache;
-#endif
-
data->state.requests = 0;
data->state.followlocation = 0; /* reset the location-follow counter */
data->state.this_is_a_follow = FALSE; /* reset this */
diff --git a/Utilities/cmcurl/lib/url.c b/Utilities/cmcurl/lib/url.c
index 0f3d100..516ee08 100644
--- a/Utilities/cmcurl/lib/url.c
+++ b/Utilities/cmcurl/lib/url.c
@@ -125,10 +125,6 @@
#include "curl_memory.h"
#include "memdebug.h"
-#ifndef ARRAYSIZE
-#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
-#endif
-
#ifdef USE_NGHTTP2
static void data_priority_cleanup(struct Curl_easy *data);
#else
@@ -566,7 +562,7 @@
DEBUGASSERT(conn);
- for(i = 0; i < ARRAYSIZE(conn->cfilter); ++i) {
+ for(i = 0; i < CURL_ARRAYSIZE(conn->cfilter); ++i) {
Curl_conn_cf_discard_all(data, conn, (int)i);
}
@@ -2690,7 +2686,6 @@
}
conn->bits.netrc = FALSE;
if(data->set.use_netrc && !data->set.str[STRING_USERNAME]) {
- int ret;
bool url_provided = FALSE;
if(data->state.aptr.user &&
@@ -2702,17 +2697,19 @@
}
if(!*passwdp) {
- ret = Curl_parsenetrc(&data->state.netrc, conn->host.name,
- userp, passwdp,
- data->set.str[STRING_NETRC_FILE]);
- if(ret > 0) {
+ NETRCcode ret = Curl_parsenetrc(&data->state.netrc, conn->host.name,
+ userp, passwdp,
+ data->set.str[STRING_NETRC_FILE]);
+ if(ret && ((ret == NETRC_NO_MATCH) ||
+ (data->set.use_netrc == CURL_NETRC_OPTIONAL))) {
infof(data, "Couldn't find host %s in the %s file; using defaults",
conn->host.name,
(data->set.str[STRING_NETRC_FILE] ?
data->set.str[STRING_NETRC_FILE] : ".netrc"));
}
- else if(ret < 0) {
- failf(data, ".netrc parser error");
+ else if(ret) {
+ const char *m = Curl_netrc_strerror(ret);
+ failf(data, ".netrc error: %s", m);
return CURLE_READ_ERROR;
}
else {
@@ -3105,7 +3102,7 @@
DEBUGF(infof(data, "check Alt-Svc for host %s", host));
if(srcalpnid == ALPN_none) {
/* scan all alt-svc protocol ids in order or relevance */
- for(i = 0; !hit && (i < ARRAYSIZE(alpn_ids)); ++i) {
+ for(i = 0; !hit && (i < CURL_ARRAYSIZE(alpn_ids)); ++i) {
srcalpnid = alpn_ids[i];
hit = Curl_altsvc_lookup(data->asi,
srcalpnid, host, conn->remote_port, /* from */
@@ -3215,7 +3212,7 @@
#endif
if(unix_path) {
- /* TODO, this only works if previous transport is TRNSPRT_TCP. Check it? */
+ /* This only works if previous transport is TRNSPRT_TCP. Check it? */
conn->transport = TRNSPRT_UNIX;
return resolve_unix(data, conn, unix_path);
}
@@ -3313,7 +3310,7 @@
* We want to reuse an existing conn to the remote endpoint.
* Since connection reuse does not match on conn->host necessarily, we
* switch `existing` conn to `temp` conn's host settings.
- * TODO: is this correct in the case of TLS connections that have
+ * Is this correct in the case of TLS connections that have
* used the original hostname in SNI to negotiate? Do we send
* requests for another host through the different SNI?
*/
@@ -3573,7 +3570,6 @@
if(result)
goto out;
- /* FIXME: do we really want to run this every time we add a transfer? */
Curl_cpool_prune_dead(data);
/*************************************************************
diff --git a/Utilities/cmcurl/lib/urlapi.c b/Utilities/cmcurl/lib/urlapi.c
index d9b04e3..2368bd7 100644
--- a/Utilities/cmcurl/lib/urlapi.c
+++ b/Utilities/cmcurl/lib/urlapi.c
@@ -395,7 +395,7 @@
/* We will now try to extract the
* possible login information in a string like:
- * ftp://user:password@ftp.my.site:8021/README */
+ * ftp://user:password@ftp.site.example:8021/README */
ptr++;
/* if this is a known scheme, get some details */
diff --git a/Utilities/cmcurl/lib/urldata.h b/Utilities/cmcurl/lib/urldata.h
index 33fa0d1..d9acb2b 100644
--- a/Utilities/cmcurl/lib/urldata.h
+++ b/Utilities/cmcurl/lib/urldata.h
@@ -1108,7 +1108,6 @@
/**
* Priority information for an easy handle in relation to others
* on the same connection.
- * TODO: we need to adapt it to the new priority scheme as defined in RFC 9218
*/
struct Curl_data_priority {
#ifdef USE_NGHTTP2
@@ -1199,7 +1198,6 @@
curl_prot_t first_remote_protocol;
int retrycount; /* number of retries on a new connection */
- struct Curl_ssl_scache *ssl_scache; /* TLS session pool */
int os_errno; /* filled in with errno whenever an error occurs */
long followlocation; /* redirect counter */
int requests; /* request counter: redirects + authentication retakes */
diff --git a/Utilities/cmcurl/lib/vquic/curl_msh3.c b/Utilities/cmcurl/lib/vquic/curl_msh3.c
index 9e7cfbe..e0b5949 100644
--- a/Utilities/cmcurl/lib/vquic/curl_msh3.c
+++ b/Utilities/cmcurl/lib/vquic/curl_msh3.c
@@ -441,10 +441,10 @@
CURLcode result;
bool rv = FALSE;
- /* TODO: we would like to limit the amount of data we are buffer here.
- * There seems to be no mechanism in msh3 to adjust flow control and
- * it is undocumented what happens if we return FALSE here or less
- * length (buflen is an inout parameter).
+ /* We would like to limit the amount of data we are buffer here. There seems
+ * to be no mechanism in msh3 to adjust flow control and it is undocumented
+ * what happens if we return FALSE here or less length (buflen is an inout
+ * parameter).
*/
(void)Request;
if(!stream)
@@ -703,8 +703,8 @@
goto out;
}
- /* TODO - msh3/msquic will hold onto this memory until the send complete
- event. How do we make sure curl does not free it until then? */
+ /* msh3/msquic will hold onto this memory until the send complete event.
+ How do we make sure curl does not free it until then? */
*err = CURLE_OK;
nwritten = len;
}
@@ -838,7 +838,7 @@
MSH3_SET_PORT(&addr, (uint16_t)cf->conn->remote_port);
if(verify && (conn_config->CAfile || conn_config->CApath)) {
- /* TODO: need a way to provide trust anchors to MSH3 */
+ /* Need a way to provide trust anchors to MSH3 */
#ifdef DEBUGBUILD
/* we need this for our test cases to run */
CURL_TRC_CF(data, cf, "non-standard CA not supported, "
@@ -1006,7 +1006,7 @@
switch(query) {
case CF_QUERY_MAX_CONCURRENT: {
- /* TODO: we do not have access to this so far, fake it */
+ /* We do not have access to this so far, fake it */
(void)ctx;
*pres1 = 100;
return CURLE_OK;
@@ -1091,7 +1091,7 @@
(void)data;
(void)conn;
- (void)ai; /* TODO: msh3 resolves itself? */
+ (void)ai; /* msh3 resolves itself? */
ctx = calloc(1, sizeof(*ctx));
if(!ctx) {
result = CURLE_OUT_OF_MEMORY;
diff --git a/Utilities/cmcurl/lib/vquic/curl_ngtcp2.c b/Utilities/cmcurl/lib/vquic/curl_ngtcp2.c
index f2ceff2..cc9d560 100644
--- a/Utilities/cmcurl/lib/vquic/curl_ngtcp2.c
+++ b/Utilities/cmcurl/lib/vquic/curl_ngtcp2.c
@@ -394,7 +394,7 @@
struct Curl_cfilter *cf = user_data;
struct cf_ngtcp2_ctx *ctx = cf->ctx;
- (void)ctx; /* TODO: need an easy handle to infof() message */
+ (void)ctx; /* need an easy handle to infof() message */
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
@@ -1591,7 +1591,7 @@
if(ctx->tls_vrfy_result)
return ctx->tls_vrfy_result;
- (void)eos; /* TODO: use for stream EOF and block handling */
+ (void)eos; /* use for stream EOF and block handling */
result = cf_progress_ingress(cf, data, &pktx);
if(result) {
*err = result;
@@ -1965,8 +1965,8 @@
struct Curl_easy *data,
bool pause)
{
- /* TODO: there seems right now no API in ngtcp2 to shrink/enlarge
- * the streams windows. As we do in HTTP/2. */
+ /* There seems to exist no API in ngtcp2 to shrink/enlarge the streams
+ * windows. As we do in HTTP/2. */
if(!pause) {
h3_drain_stream(cf, data);
Curl_expire(data, 0, EXPIRE_RUN_NOW);
diff --git a/Utilities/cmcurl/lib/vquic/curl_osslq.c b/Utilities/cmcurl/lib/vquic/curl_osslq.c
index 1b78497..4fd4fee 100644
--- a/Utilities/cmcurl/lib/vquic/curl_osslq.c
+++ b/Utilities/cmcurl/lib/vquic/curl_osslq.c
@@ -82,10 +82,6 @@
#define H3_STREAM_SEND_CHUNKS \
(H3_STREAM_WINDOW_SIZE / H3_STREAM_CHUNK_SIZE)
-#ifndef ARRAYSIZE
-#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
-#endif
-
#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
typedef uint32_t sslerr_t;
#else
@@ -458,7 +454,7 @@
struct cf_osslq_ctx *ctx = cf->ctx;
curl_int64_t stream_id = (curl_int64_t)SSL_get_stream_id(stream_ssl);
- if(h3->remote_ctrl_n >= ARRAYSIZE(h3->remote_ctrl)) {
+ if(h3->remote_ctrl_n >= CURL_ARRAYSIZE(h3->remote_ctrl)) {
/* rejected, we are full */
CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] rejecting remote stream",
stream_id);
@@ -1564,7 +1560,7 @@
bool blocked = FALSE, eos_written = FALSE;
n = nghttp3_conn_writev_stream(ctx->h3.conn, &stream_id, &eos,
- vec, ARRAYSIZE(vec));
+ vec, CURL_ARRAYSIZE(vec));
if(n < 0) {
failf(data, "nghttp3_conn_writev_stream returned error: %s",
nghttp3_strerror((int)n));
@@ -1984,7 +1980,7 @@
ssize_t nwritten;
CURLcode result;
- (void)eos; /* TODO: use to end stream */
+ (void)eos; /* use to end stream */
CF_DATA_SAVE(save, cf, data);
DEBUGASSERT(cf->connected);
DEBUGASSERT(ctx->tls.ossl.ssl);
diff --git a/Utilities/cmcurl/lib/vquic/curl_quiche.c b/Utilities/cmcurl/lib/vquic/curl_quiche.c
index ec0dcce..679cba3 100644
--- a/Utilities/cmcurl/lib/vquic/curl_quiche.c
+++ b/Utilities/cmcurl/lib/vquic/curl_quiche.c
@@ -926,8 +926,8 @@
nwritten = quiche_h3_send_body(ctx->h3c, ctx->qconn, stream->id,
(uint8_t *)buf, len, eos);
if(nwritten == QUICHE_H3_ERR_DONE || (nwritten == 0 && len > 0)) {
- /* TODO: we seem to be blocked on flow control and should HOLD
- * sending. But when do we open again? */
+ /* Blocked on flow control and should HOLD sending. But when do we open
+ * again? */
if(!quiche_conn_stream_writable(ctx->qconn, stream->id, len)) {
CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] send_body(len=%zu) "
"-> window exhausted", stream->id, len);
@@ -1204,8 +1204,8 @@
struct Curl_easy *data,
bool pause)
{
- /* TODO: there seems right now no API in quiche to shrink/enlarge
- * the streams windows. As we do in HTTP/2. */
+ /* There seems to exist no API in quiche to shrink/enlarge the streams
+ * windows. As we do in HTTP/2. */
if(!pause) {
h3_drain_stream(cf, data);
Curl_expire(data, 0, EXPIRE_RUN_NOW);
diff --git a/Utilities/cmcurl/lib/vquic/vquic-tls.c b/Utilities/cmcurl/lib/vquic/vquic-tls.c
index 6e1ace2..ff2445d 100644
--- a/Utilities/cmcurl/lib/vquic/vquic-tls.c
+++ b/Utilities/cmcurl/lib/vquic/vquic-tls.c
@@ -58,10 +58,6 @@
#include "curl_memory.h"
#include "memdebug.h"
-#ifndef ARRAYSIZE
-#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
-#endif
-
#if defined(USE_WOLFSSL)
#define QUIC_CIPHERS \
diff --git a/Utilities/cmcurl/lib/vquic/vquic.c b/Utilities/cmcurl/lib/vquic/vquic.c
index 9ac3518..69de5c1 100644
--- a/Utilities/cmcurl/lib/vquic/vquic.c
+++ b/Utilities/cmcurl/lib/vquic/vquic.c
@@ -163,7 +163,7 @@
case EIO:
if(pktlen > gsolen) {
/* GSO failure */
- failf(data, "sendmsg() returned %zd (errno %d); disable GSO", sent,
+ infof(data, "sendmsg() returned %zd (errno %d); disable GSO", sent,
SOCKERRNO);
qctx->no_gso = TRUE;
return send_packet_no_gso(cf, data, qctx, pkt, pktlen, gsolen, psent);
diff --git a/Utilities/cmcurl/lib/vssh/libssh.c b/Utilities/cmcurl/lib/vssh/libssh.c
index 8d42ddd..2390967 100644
--- a/Utilities/cmcurl/lib/vssh/libssh.c
+++ b/Utilities/cmcurl/lib/vssh/libssh.c
@@ -342,17 +342,11 @@
struct curl_khkey *knownkeyp = NULL;
curl_sshkeycallback func =
data->set.ssh_keyfunc;
-
-#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0)
struct ssh_knownhosts_entry *knownhostsentry = NULL;
struct curl_khkey knownkey;
-#endif
-#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,8,0)
rc = ssh_get_server_publickey(sshc->ssh_session, &pubkey);
-#else
- rc = ssh_get_publickey(sshc->ssh_session, &pubkey);
-#endif
+
if(rc != SSH_OK)
return rc;
@@ -388,7 +382,6 @@
if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
-#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0)
/* Get the known_key from the known hosts file */
vstate = ssh_session_get_known_hosts_entry(sshc->ssh_session,
&knownhostsentry);
@@ -446,22 +439,6 @@
break;
}
-#else
- vstate = ssh_is_server_known(sshc->ssh_session);
- switch(vstate) {
- case SSH_SERVER_KNOWN_OK:
- keymatch = CURLKHMATCH_OK;
- break;
- case SSH_SERVER_FILE_NOT_FOUND:
- case SSH_SERVER_NOT_KNOWN:
- keymatch = CURLKHMATCH_MISSING;
- break;
- default:
- keymatch = CURLKHMATCH_MISMATCH;
- break;
- }
-#endif
-
if(func) { /* use callback to determine action */
rc = ssh_pki_export_pubkey_base64(pubkey, &found_base64);
if(rc != SSH_OK)
@@ -478,18 +455,14 @@
foundkey.keytype = CURLKHTYPE_RSA1;
break;
case SSH_KEYTYPE_ECDSA:
-#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0)
case SSH_KEYTYPE_ECDSA_P256:
case SSH_KEYTYPE_ECDSA_P384:
case SSH_KEYTYPE_ECDSA_P521:
-#endif
foundkey.keytype = CURLKHTYPE_ECDSA;
break;
-#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,7,0)
case SSH_KEYTYPE_ED25519:
foundkey.keytype = CURLKHTYPE_ED25519;
break;
-#endif
case SSH_KEYTYPE_DSS:
foundkey.keytype = CURLKHTYPE_DSS;
break;
@@ -506,11 +479,7 @@
switch(rc) {
case CURLKHSTAT_FINE_ADD_TO_FILE:
-#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,8,0)
rc = ssh_session_update_known_hosts(sshc->ssh_session);
-#else
- rc = ssh_write_knownhost(sshc->ssh_session);
-#endif
if(rc != SSH_OK) {
goto cleanup;
}
@@ -541,11 +510,9 @@
if(hash)
ssh_clean_pubkey_hash(&hash);
ssh_key_free(pubkey);
-#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0)
if(knownhostsentry) {
ssh_knownhosts_entry_free(knownhostsentry);
}
-#endif
return rc;
}
@@ -1848,7 +1815,7 @@
}
rc = ssh_scp_push_file(sshc->scp_session, protop->path,
- data->state.infilesize,
+ (size_t)data->state.infilesize,
(int)data->set.new_file_perms);
if(rc != SSH_OK) {
err_msg = ssh_get_error(sshc->ssh_session);
diff --git a/Utilities/cmcurl/lib/vssh/libssh2.c b/Utilities/cmcurl/lib/vssh/libssh2.c
index edfadc8..429abac 100644
--- a/Utilities/cmcurl/lib/vssh/libssh2.c
+++ b/Utilities/cmcurl/lib/vssh/libssh2.c
@@ -83,15 +83,6 @@
#include "curl_memory.h"
#include "memdebug.h"
-#if LIBSSH2_VERSION_NUM >= 0x010206
-/* libssh2_sftp_statvfs and friends were added in 1.2.6 */
-#define HAS_STATVFS_SUPPORT 1
-#endif
-
-#define sftp_libssh2_realpath(s,p,t,m) \
- libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
- (t), (m), LIBSSH2_SFTP_REALPATH)
-
/* Local functions: */
static const char *sftp_libssh2_strerror(unsigned long err);
static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
@@ -389,8 +380,6 @@
sshc->state = nowstate;
}
-
-#ifdef HAVE_LIBSSH2_KNOWNHOST_API
static int sshkeycallback(CURL *easy,
const struct curl_khkey *knownkey, /* known */
const struct curl_khkey *foundkey, /* found */
@@ -405,37 +394,7 @@
/* we only allow perfect matches, and we reject everything else */
return (match != CURLKHMATCH_OK) ? CURLKHSTAT_REJECT : CURLKHSTAT_FINE;
}
-#endif
-/*
- * Earlier libssh2 versions did not have the ability to seek to 64-bit
- * positions with 32-bit size_t.
- */
-#ifdef HAVE_LIBSSH2_SFTP_SEEK64
-#define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
-#else
-#define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
-#endif
-
-/*
- * Earlier libssh2 versions did not do SCP properly beyond 32-bit sizes on
- * 32-bit architectures so we check of the necessary function is present.
- */
-#ifndef HAVE_LIBSSH2_SCP_SEND64
-#define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
-#else
-#define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
- (libssh2_int64_t)d, 0, 0)
-#endif
-
-/*
- * libssh2 1.2.8 fixed the problem with 32-bit ints used for sockets on win64.
- */
-#ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
-#define session_startup(x,y) libssh2_session_handshake(x, y)
-#else
-#define session_startup(x,y) libssh2_session_startup(x, (int)y)
-#endif
static enum curl_khtype convert_ssh2_keytype(int sshkeytype)
{
enum curl_khtype keytype = CURLKHTYPE_UNKNOWN;
@@ -477,7 +436,6 @@
int rc = 0;
CURLcode result = CURLE_OK;
-#ifdef HAVE_LIBSSH2_KNOWNHOST_API
if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
/* we are asked to verify the host against a file */
struct connectdata *conn = data->conn;
@@ -537,7 +495,6 @@
/* no check means failure! */
rc = CURLKHSTAT_REJECT;
else {
-#ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP
keycheck = libssh2_knownhost_checkp(sshc->kh,
conn->host.name,
(conn->remote_port != PORT_SSH) ?
@@ -547,15 +504,6 @@
LIBSSH2_KNOWNHOST_KEYENC_RAW|
keybit,
&host);
-#else
- keycheck = libssh2_knownhost_check(sshc->kh,
- conn->host.name,
- remotekey, keylen,
- LIBSSH2_KNOWNHOST_TYPE_PLAIN|
- LIBSSH2_KNOWNHOST_KEYENC_RAW|
- keybit,
- &host);
-#endif
infof(data, "SSH host check: %d, key: %s", keycheck,
(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) ?
@@ -639,9 +587,6 @@
break;
}
}
-#else /* HAVE_LIBSSH2_KNOWNHOST_API */
- (void)data;
-#endif
return result;
}
@@ -819,8 +764,6 @@
{
CURLcode result = CURLE_OK;
-#ifdef HAVE_LIBSSH2_KNOWNHOST_API
-
#ifdef LIBSSH2_KNOWNHOST_KEY_ED25519
static const char * const hostkey_method_ssh_ed25519
= "ssh-ed25519";
@@ -916,12 +859,10 @@
break;
#endif
case LIBSSH2_KNOWNHOST_KEY_SSHRSA:
-#ifdef HAVE_LIBSSH2_VERSION
if(libssh2_version(0x010900))
/* since 1.9.0 libssh2_session_method_pref() works as expected */
hostkey_method = hostkey_method_ssh_rsa_all;
else
-#endif
/* old libssh2 which cannot correctly remove unsupported methods due
* to bug in src/kex.c or does not support the new methods anyways.
*/
@@ -956,8 +897,6 @@
}
}
-#endif /* HAVE_LIBSSH2_KNOWNHOST_API */
-
return result;
}
@@ -1094,12 +1033,10 @@
state(data, SSH_SFTP_QUOTE_UNLINK);
return result;
}
-#ifdef HAS_STATVFS_SUPPORT
else if(strncasecompare(cmd, "statvfs ", 8)) {
state(data, SSH_SFTP_QUOTE_STATVFS);
return result;
}
-#endif
failf(data, "Unknown SFTP command");
Curl_safefree(sshc->quote_path1);
@@ -1264,7 +1201,8 @@
Curl_pgrsSetUploadSize(data, data->state.infilesize);
}
- SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
+ libssh2_sftp_seek64(sshc->sftp_handle,
+ (libssh2_uint64_t)data->state.resume_from);
}
if(data->state.infilesize > 0) {
data->req.size = data->state.infilesize;
@@ -1565,7 +1503,7 @@
size = to - from + 1;
}
- SFTP_SEEK(sshc->sftp_handle, from);
+ libssh2_sftp_seek64(sshc->sftp_handle, (libssh2_uint64_t)from);
}
data->req.size = size;
data->req.maxdownload = size;
@@ -1598,7 +1536,8 @@
data->req.maxdownload = attrs.filesize - data->state.resume_from;
Curl_pgrsSetDownloadSize(data,
attrs.filesize - data->state.resume_from);
- SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
+ libssh2_sftp_seek64(sshc->sftp_handle,
+ (libssh2_uint64_t)data->state.resume_from);
}
/* Setup the actual download */
@@ -1670,10 +1609,10 @@
return result;
}
}
- else if(rc == 0) {
+ else if(!rc) {
state(data, SSH_SFTP_READDIR_DONE);
}
- else if(rc < 0) {
+ else {
unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
result = sftp_libssh2_error_to_CURLE(sftperr);
sshc->actualcode = result ? result : CURLE_SSH;
@@ -1723,7 +1662,8 @@
FALLTHROUGH();
case SSH_S_STARTUP:
- rc = session_startup(sshc->ssh_session, conn->sock[FIRSTSOCKET]);
+ rc = libssh2_session_handshake(sshc->ssh_session,
+ conn->sock[FIRSTSOCKET]);
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
@@ -1878,7 +1818,6 @@
break;
case SSH_AUTH_AGENT_INIT:
-#ifdef HAVE_LIBSSH2_AGENT_API
if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
&& (strstr(sshc->authlist, "publickey") != NULL)) {
@@ -1908,12 +1847,10 @@
}
}
else
-#endif /* HAVE_LIBSSH2_AGENT_API */
state(data, SSH_AUTH_KEY_INIT);
break;
case SSH_AUTH_AGENT_LIST:
-#ifdef HAVE_LIBSSH2_AGENT_API
rc = libssh2_agent_list_identities(sshc->ssh_agent);
if(rc == LIBSSH2_ERROR_EAGAIN)
@@ -1927,11 +1864,9 @@
state(data, SSH_AUTH_AGENT);
sshc->sshagent_prev_identity = NULL;
}
-#endif
break;
case SSH_AUTH_AGENT:
-#ifdef HAVE_LIBSSH2_AGENT_API
/* as prev_identity evolves only after an identity user auth finished we
can safely request it again as long as EAGAIN is returned here or by
libssh2_agent_userauth */
@@ -1968,7 +1903,6 @@
state(data, SSH_AUTH_KEY_INIT);
rc = 0; /* clear rc and continue */
}
-#endif
break;
case SSH_AUTH_KEY_INIT:
@@ -2051,8 +1985,10 @@
/*
* Get the "home" directory
*/
- rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
- sshp->readdir_filename, CURL_PATH_MAX);
+ rc = libssh2_sftp_symlink_ex(sshc->sftp_session,
+ ".", curlx_uztoui(strlen(".")),
+ sshp->readdir_filename, CURL_PATH_MAX,
+ LIBSSH2_SFTP_REALPATH);
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
@@ -2288,7 +2224,6 @@
state(data, SSH_SFTP_NEXT_QUOTE);
break;
-#ifdef HAS_STATVFS_SUPPORT
case SSH_SFTP_QUOTE_STATVFS:
{
LIBSSH2_SFTP_STATVFS statvfs;
@@ -2351,7 +2286,7 @@
state(data, SSH_SFTP_NEXT_QUOTE);
break;
}
-#endif
+
case SSH_SFTP_GETINFO:
{
if(data->set.get_filetime) {
@@ -2684,8 +2619,9 @@
* directory in the path.
*/
sshc->ssh_channel =
- SCP_SEND(sshc->ssh_session, sshp->path, data->set.new_file_perms,
- data->state.infilesize);
+ libssh2_scp_send64(sshc->ssh_session, sshp->path,
+ (int)data->set.new_file_perms,
+ (libssh2_int64_t)data->state.infilesize, 0, 0);
if(!sshc->ssh_channel) {
int ssh_err;
char *err_msg = NULL;
@@ -2920,14 +2856,11 @@
break;
case SSH_SESSION_FREE:
-#ifdef HAVE_LIBSSH2_KNOWNHOST_API
if(sshc->kh) {
libssh2_knownhost_free(sshc->kh);
sshc->kh = NULL;
}
-#endif
-#ifdef HAVE_LIBSSH2_AGENT_API
if(sshc->ssh_agent) {
rc = libssh2_agent_disconnect(sshc->ssh_agent);
if(rc == LIBSSH2_ERROR_EAGAIN) {
@@ -2948,7 +2881,6 @@
sshc->sshagent_identity = NULL;
sshc->sshagent_prev_identity = NULL;
}
-#endif
if(sshc->ssh_session) {
rc = libssh2_session_free(sshc->ssh_session);
@@ -2970,12 +2902,8 @@
DEBUGASSERT(sshc->ssh_channel == NULL);
DEBUGASSERT(sshc->sftp_session == NULL);
DEBUGASSERT(sshc->sftp_handle == NULL);
-#ifdef HAVE_LIBSSH2_KNOWNHOST_API
DEBUGASSERT(sshc->kh == NULL);
-#endif
-#ifdef HAVE_LIBSSH2_AGENT_API
DEBUGASSERT(sshc->ssh_agent == NULL);
-#endif
Curl_safefree(sshc->rsa_pub);
Curl_safefree(sshc->rsa);
@@ -3325,14 +3253,11 @@
conn->send[FIRSTSOCKET] = sftp_send;
}
- if(data->set.ssh_compression) {
-#if LIBSSH2_VERSION_NUM >= 0x010208
- if(libssh2_session_flag(sshc->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0)
-#endif
- infof(data, "Failed to enable compression for ssh session");
+ if(data->set.ssh_compression &&
+ libssh2_session_flag(sshc->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0) {
+ infof(data, "Failed to enable compression for ssh session");
}
-#ifdef HAVE_LIBSSH2_KNOWNHOST_API
if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
int rc;
sshc->kh = libssh2_knownhost_init(sshc->ssh_session);
@@ -3350,7 +3275,6 @@
infof(data, "Failed to read known hosts from %s",
data->set.str[STRING_SSH_KNOWNHOSTS]);
}
-#endif /* HAVE_LIBSSH2_KNOWNHOST_API */
#ifdef CURL_LIBSSH2_DEBUG
libssh2_trace(sshc->ssh_session, ~0);
@@ -3761,25 +3685,21 @@
CURLcode Curl_ssh_init(void)
{
-#ifdef HAVE_LIBSSH2_INIT
if(libssh2_init(0)) {
DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n"));
return CURLE_FAILED_INIT;
}
-#endif
return CURLE_OK;
}
void Curl_ssh_cleanup(void)
{
-#ifdef HAVE_LIBSSH2_EXIT
(void)libssh2_exit();
-#endif
}
void Curl_ssh_version(char *buffer, size_t buflen)
{
- (void)msnprintf(buffer, buflen, "libssh2/%s", CURL_LIBSSH2_VERSION);
+ (void)msnprintf(buffer, buflen, "libssh2/%s", libssh2_version(0));
}
/* The SSH session is associated with the *CONNECTION* but the callback user
diff --git a/Utilities/cmcurl/lib/vssh/ssh.h b/Utilities/cmcurl/lib/vssh/ssh.h
index 8d8a9b3..bbbe95d 100644
--- a/Utilities/cmcurl/lib/vssh/ssh.h
+++ b/Utilities/cmcurl/lib/vssh/ssh.h
@@ -201,17 +201,10 @@
Curl_send *tls_send;
#endif
-#ifdef HAVE_LIBSSH2_AGENT_API
LIBSSH2_AGENT *ssh_agent; /* proxy to ssh-agent/pageant */
- struct libssh2_agent_publickey *sshagent_identity,
- *sshagent_prev_identity;
-#endif
-
- /* note that HAVE_LIBSSH2_KNOWNHOST_API is a define set in the libssh2.h
- header */
-#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+ struct libssh2_agent_publickey *sshagent_identity;
+ struct libssh2_agent_publickey *sshagent_prev_identity;
LIBSSH2_KNOWNHOSTS *kh;
-#endif
#elif defined(USE_WOLFSSH)
WOLFSSH *ssh_session;
WOLFSSH_CTX *ctx;
@@ -221,43 +214,20 @@
#endif /* USE_LIBSSH */
};
+#ifdef USE_LIBSSH
+#if LIBSSH_VERSION_INT < SSH_VERSION_INT(0, 9, 0)
+# error "SCP/SFTP protocols require libssh 0.9.0 or later"
+#endif
+#endif
+
#if defined(USE_LIBSSH2)
/* Feature detection based on version numbers to better work with
non-configure platforms */
-#if !defined(LIBSSH2_VERSION_NUM) || (LIBSSH2_VERSION_NUM < 0x001000)
-# error "SCP/SFTP protocols require libssh2 0.16 or later"
-#endif
-
-#if LIBSSH2_VERSION_NUM >= 0x010000
-#define HAVE_LIBSSH2_SFTP_SEEK64 1
-#endif
-
-#if LIBSSH2_VERSION_NUM >= 0x010100
-#define HAVE_LIBSSH2_VERSION 1
-#endif
-
-#if LIBSSH2_VERSION_NUM >= 0x010205
-#define HAVE_LIBSSH2_INIT 1
-#define HAVE_LIBSSH2_EXIT 1
-#endif
-
-#if LIBSSH2_VERSION_NUM >= 0x010206
-#define HAVE_LIBSSH2_KNOWNHOST_CHECKP 1
-#define HAVE_LIBSSH2_SCP_SEND64 1
-#endif
-
-#if LIBSSH2_VERSION_NUM >= 0x010208
-#define HAVE_LIBSSH2_SESSION_HANDSHAKE 1
-#endif
-
-#ifdef HAVE_LIBSSH2_VERSION
-/* get it runtime if possible */
-#define CURL_LIBSSH2_VERSION libssh2_version(0)
-#else
-/* use build-time if runtime not possible */
-#define CURL_LIBSSH2_VERSION LIBSSH2_VERSION
+#if !defined(LIBSSH2_VERSION_NUM) || (LIBSSH2_VERSION_NUM < 0x010208)
+# error "SCP/SFTP protocols require libssh2 1.2.8 or later"
+/* 1.2.8 was released on April 5 2011 */
#endif
#endif /* USE_LIBSSH2 */
diff --git a/Utilities/cmcurl/lib/vtls/gtls.c b/Utilities/cmcurl/lib/vtls/gtls.c
index d2c0172..a47d803 100644
--- a/Utilities/cmcurl/lib/vtls/gtls.c
+++ b/Utilities/cmcurl/lib/vtls/gtls.c
@@ -63,10 +63,6 @@
/* The last #include file should be: */
#include "memdebug.h"
-#ifndef ARRAYSIZE
-#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
-#endif
-
#define QUIC_PRIORITY \
"NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM:+AES-256-GCM:" \
"+CHACHA20-POLY1305:+AES-128-CCM:-GROUP-ALL:+GROUP-SECP256R1:" \
@@ -1223,7 +1219,7 @@
size_t i, alen = alpn_len;
unsigned char *salpn = (unsigned char *)alpn;
unsigned char slen;
- for(i = 0; (i < ARRAYSIZE(gtls_alpns)) && alen; ++i) {
+ for(i = 0; (i < CURL_ARRAYSIZE(gtls_alpns)) && alen; ++i) {
slen = salpn[0];
if(slen >= alen)
return CURLE_FAILED_INIT;
diff --git a/Utilities/cmcurl/lib/vtls/mbedtls.c b/Utilities/cmcurl/lib/vtls/mbedtls.c
index 456b561..13e44c7 100644
--- a/Utilities/cmcurl/lib/vtls/mbedtls.c
+++ b/Utilities/cmcurl/lib/vtls/mbedtls.c
@@ -79,11 +79,8 @@
#include "memdebug.h"
/* ALPN for http2 */
-#ifdef USE_HTTP2
-# undef HAS_ALPN
-# ifdef MBEDTLS_SSL_ALPN
-# define HAS_ALPN
-# endif
+#if defined(USE_HTTP2) && defined(MBEDTLS_SSL_ALPN)
+# define HAS_ALPN_MBEDTLS
#endif
struct mbed_ssl_backend_data {
@@ -97,7 +94,7 @@
#endif
mbedtls_pk_context pk;
mbedtls_ssl_config config;
-#ifdef HAS_ALPN
+#ifdef HAS_ALPN_MBEDTLS
const char *protocols[3];
#endif
int *ciphersuites;
@@ -931,7 +928,7 @@
return CURLE_SSL_CONNECT_ERROR;
}
-#ifdef HAS_ALPN
+#ifdef HAS_ALPN_MBEDTLS
if(connssl->alpn) {
struct alpn_proto_buf proto;
size_t i;
@@ -1109,7 +1106,7 @@
}
}
-#ifdef HAS_ALPN
+#ifdef HAS_ALPN_MBEDTLS
if(connssl->alpn) {
const char *proto = mbedtls_ssl_get_alpn_protocol(&backend->ssl);
@@ -1636,7 +1633,6 @@
unsigned char *sha256sum,
size_t sha256len UNUSED_PARAM)
{
- /* TODO: explain this for different mbedtls 2.x vs 3 version */
(void)sha256len;
#if MBEDTLS_VERSION_NUMBER < 0x02070000
mbedtls_sha256(input, inputlen, sha256sum, 0);
diff --git a/Utilities/cmcurl/lib/vtls/openssl.c b/Utilities/cmcurl/lib/vtls/openssl.c
index ddb05f2..71f4b0d 100644
--- a/Utilities/cmcurl/lib/vtls/openssl.c
+++ b/Utilities/cmcurl/lib/vtls/openssl.c
@@ -116,10 +116,6 @@
#include "curl_memory.h"
#include "memdebug.h"
-#ifndef ARRAYSIZE
-#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
-#endif
-
/* Uncomment the ALLOW_RENEG line to a real #define if you want to allow TLS
renegotiations when built with BoringSSL. Renegotiating is non-compliant
with HTTP/2 and "an extremely dangerous protocol feature". Beware.
@@ -1313,7 +1309,9 @@
if(cert_file || cert_blob || (file_type == SSL_FILETYPE_ENGINE) ||
(file_type == SSL_FILETYPE_PROVIDER)) {
SSL *ssl;
- X509 *x509;
+ X509 *x509 = NULL;
+ EVP_PKEY *pri = NULL;
+ STACK_OF(X509) *ca = NULL;
int cert_done = 0;
int cert_use_result;
@@ -1502,8 +1500,6 @@
{
BIO *cert_bio = NULL;
PKCS12 *p12 = NULL;
- EVP_PKEY *pri;
- STACK_OF(X509) *ca = NULL;
if(cert_blob) {
cert_bio = BIO_new_mem_buf(cert_blob->data, (int)(cert_blob->len));
if(!cert_bio) {
@@ -1544,8 +1540,7 @@
PKCS12_PBE_add();
- if(!PKCS12_parse(p12, key_passwd, &pri, &x509,
- &ca)) {
+ if(!PKCS12_parse(p12, key_passwd, &pri, &x509, &ca)) {
failf(data,
"could not parse PKCS12 file, check password, " OSSL_PACKAGE
" error %s",
@@ -2067,8 +2062,6 @@
sizeof(error_buffer)));
/* Do not attempt to load it again */
data->state.provider_failed = TRUE;
- /* FIXME not the right error but much less fuss than creating a new
- * public one */
return CURLE_SSL_ENGINE_NOTFOUND;
}
data->state.provider = TRUE;
@@ -2884,10 +2877,9 @@
/* ====================================================== */
/* Check for OpenSSL 1.0.2 which has ALPN support. */
-#undef HAS_ALPN
#if OPENSSL_VERSION_NUMBER >= 0x10002000L \
&& !defined(OPENSSL_NO_TLSEXT)
-# define HAS_ALPN 1
+# define HAS_ALPN_OPENSSL
#endif
/* Check for OpenSSL 1.1.0 which has set_{min,max}_proto_version(). */
@@ -3381,7 +3373,7 @@
"CA" /* Intermediate Certification Authorities */
};
size_t i;
- for(i = 0; i < ARRAYSIZE(storeNames); ++i) {
+ for(i = 0; i < CURL_ARRAYSIZE(storeNames); ++i) {
bool imported = FALSE;
result = import_windows_cert_store(data, storeNames[i], store,
&imported);
@@ -3692,7 +3684,7 @@
ctx_option_t ctx_options = 0;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
- const long int ssl_version_min = conn_config->version;
+ unsigned int ssl_version_min = conn_config->version;
char * const ssl_cert = ssl_config->primary.clientcert;
const struct curl_blob *ssl_cert_blob = ssl_config->primary.cert_blob;
const char * const ssl_cert_type = ssl_config->cert_type;
@@ -3735,6 +3727,7 @@
}
break;
case TRNSPRT_QUIC:
+ ssl_version_min = CURL_SSLVERSION_TLSv1_3;
if(conn_config->version_max &&
(conn_config->version_max != CURL_SSLVERSION_MAX_TLSv1_3)) {
failf(data, "QUIC needs at least TLS version 1.3");
@@ -3875,7 +3868,7 @@
#endif
if(alpn && alpn_len) {
-#ifdef HAS_ALPN
+#ifdef HAS_ALPN_OPENSSL
if(SSL_CTX_set_alpn_protos(octx->ssl_ctx, alpn, (int)alpn_len)) {
failf(data, "Error setting ALPN");
return CURLE_SSL_CONNECT_ERROR;
@@ -3898,7 +3891,7 @@
ciphers = conn_config->cipher_list;
if(!ciphers && (peer->transport != TRNSPRT_QUIC))
ciphers = DEFAULT_CIPHER_SELECTION;
- if(ciphers) {
+ if(ciphers && (ssl_version_min < CURL_SSLVERSION_TLSv1_3)) {
if(!SSL_CTX_set_cipher_list(octx->ssl_ctx, ciphers)) {
failf(data, "failed setting cipher list: %s", ciphers);
return CURLE_SSL_CIPHER;
@@ -3909,7 +3902,9 @@
#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
{
const char *ciphers13 = conn_config->cipher_list13;
- if(ciphers13) {
+ if(ciphers13 &&
+ (!conn_config->version_max ||
+ (conn_config->version_max >= CURL_SSLVERSION_MAX_TLSv1_3))) {
if(!SSL_CTX_set_ciphersuites(octx->ssl_ctx, ciphers13)) {
failf(data, "failed setting TLS 1.3 cipher suite: %s", ciphers13);
return CURLE_SSL_CIPHER;
@@ -4213,7 +4208,7 @@
DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
DEBUGASSERT(octx);
memset(&proto, 0, sizeof(proto));
-#ifdef HAS_ALPN
+#ifdef HAS_ALPN_OPENSSL
if(connssl->alpn) {
result = Curl_alpn_to_proto_buf(&proto, connssl->alpn);
if(result) {
@@ -4250,7 +4245,7 @@
SSL_set_bio(octx->ssl, bio, bio);
#endif
-#ifdef HAS_ALPN
+#ifdef HAS_ALPN_OPENSSL
if(connssl->alpn) {
Curl_alpn_to_proto_str(&proto, connssl->alpn);
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data);
@@ -4307,7 +4302,6 @@
servername_type = SSL_get_servername_type(ssl);
inner = SSL_get_servername(ssl, servername_type);
SSL_get0_ech_name_override(ssl, &outer, &out_name_len);
- /* TODO: get the inner from BoringSSL */
infof(data, "ECH: retry_configs for %s from %s, %d %d",
inner ? inner : "NULL", outer ? outer : "NULL", reason, rv);
#endif
@@ -4562,7 +4556,7 @@
# endif /* !OPENSSL_IS_BORINGSSL && !OPENSSL_IS_AWSLC */
#endif /* USE_ECH_OPENSSL */
-#ifdef HAS_ALPN
+#ifdef HAS_ALPN_OPENSSL
/* Sets data and len to negotiated protocol, len is 0 if no protocol was
* negotiated
*/
diff --git a/Utilities/cmcurl/lib/vtls/schannel.c b/Utilities/cmcurl/lib/vtls/schannel.c
index 8441b46..2af29a4 100644
--- a/Utilities/cmcurl/lib/vtls/schannel.c
+++ b/Utilities/cmcurl/lib/vtls/schannel.c
@@ -77,7 +77,7 @@
https://technet.microsoft.com/en-us/library/hh831771%28v=ws.11%29.aspx
*/
#if defined(_MSC_VER) && (_MSC_VER >= 1800) && !defined(_USING_V110_SDK71_)
-# define HAS_ALPN 1
+# define HAS_ALPN_SCHANNEL
#endif
#ifndef BCRYPT_CHACHA20_POLY1305_ALGORITHM
@@ -888,7 +888,7 @@
SecBufferDesc outbuf_desc;
SecBuffer inbuf;
SecBufferDesc inbuf_desc;
-#ifdef HAS_ALPN
+#ifdef HAS_ALPN_SCHANNEL
unsigned char alpn_buffer[128];
#endif
SECURITY_STATUS sspi_status = SEC_E_OK;
@@ -908,7 +908,7 @@
"connect to some servers due to lack of SNI, algorithms, etc.");
}
-#ifdef HAS_ALPN
+#ifdef HAS_ALPN_SCHANNEL
/* ALPN is only supported on Windows 8.1 / Server 2012 R2 and above.
Also it does not seem to be supported for WINE, see curl bug #983. */
backend->use_alpn = connssl->alpn &&
@@ -991,7 +991,7 @@
infof(data, "schannel: using IP address, SNI is not supported by OS.");
}
-#ifdef HAS_ALPN
+#ifdef HAS_ALPN_SCHANNEL
if(backend->use_alpn) {
int cur = 0;
int list_start_index = 0;
@@ -1039,7 +1039,7 @@
InitSecBuffer(&inbuf, SECBUFFER_EMPTY, NULL, 0);
InitSecBufferDesc(&inbuf_desc, &inbuf, 1);
}
-#else /* HAS_ALPN */
+#else /* HAS_ALPN_SCHANNEL */
InitSecBuffer(&inbuf, SECBUFFER_EMPTY, NULL, 0);
InitSecBufferDesc(&inbuf_desc, &inbuf, 1);
#endif
@@ -1533,7 +1533,7 @@
CURLcode result = CURLE_OK;
SECURITY_STATUS sspi_status = SEC_E_OK;
CERT_CONTEXT *ccert_context = NULL;
-#ifdef HAS_ALPN
+#ifdef HAS_ALPN_SCHANNEL
SecPkgContext_ApplicationProtocol alpn_result;
#endif
@@ -1562,7 +1562,7 @@
return CURLE_SSL_CONNECT_ERROR;
}
-#ifdef HAS_ALPN
+#ifdef HAS_ALPN_SCHANNEL
if(backend->use_alpn) {
sspi_status =
Curl_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle,
@@ -2367,7 +2367,6 @@
Curl_pSecFn->FreeContextBuffer(outbuf.pvBuffer);
if(!result) {
if(written < (ssize_t)outbuf.cbBuffer) {
- /* TODO: handle partial sends */
failf(data, "schannel: failed to send close msg: %s"
" (bytes written: %zd)", curl_easy_strerror(result), written);
result = CURLE_SEND_ERROR;
diff --git a/Utilities/cmcurl/lib/vtls/vtls.c b/Utilities/cmcurl/lib/vtls/vtls.c
index c258b11..9c59b4c 100644
--- a/Utilities/cmcurl/lib/vtls/vtls.c
+++ b/Utilities/cmcurl/lib/vtls/vtls.c
@@ -915,7 +915,9 @@
{
if(multissl_setup(NULL))
return 1;
- return Curl_ssl->init();
+ if(Curl_ssl->init)
+ return Curl_ssl->init();
+ return 1;
}
static CURLcode multissl_connect(struct Curl_cfilter *cf,
@@ -1939,8 +1941,8 @@
else {
*palpn = CURL_HTTP_VERSION_NONE;
failf(data, "unsupported ALPN protocol: '%.*s'", (int)proto_len, proto);
- /* TODO: do we want to fail this? Previous code just ignored it and
- * some vtls backends even ignore the return code of this function. */
+ /* Previous code just ignored it and some vtls backends even ignore the
+ * return code of this function. */
/* return CURLE_NOT_BUILT_IN; */
goto out;
}
diff --git a/Utilities/cmcurl/lib/vtls/vtls_scache.c b/Utilities/cmcurl/lib/vtls/vtls_scache.c
index 9c04b77..365e945 100644
--- a/Utilities/cmcurl/lib/vtls/vtls_scache.c
+++ b/Utilities/cmcurl/lib/vtls/vtls_scache.c
@@ -75,13 +75,35 @@
BIT(hmac_set); /* if key_salt and key_hmac are present */
};
+#define CURL_SCACHE_MAGIC 0x000e1551
+
+#define GOOD_SCACHE(x) ((x) && (x)->magic == CURL_SCACHE_MAGIC)
+
struct Curl_ssl_scache {
+ unsigned int magic;
struct Curl_ssl_scache_peer *peers;
size_t peer_count;
int default_lifetime_secs;
long age;
};
+static struct Curl_ssl_scache *cf_ssl_scache_get(struct Curl_easy *data)
+{
+ struct Curl_ssl_scache *scache = NULL;
+ /* If a share is present, its ssl_scache has preference over the multi */
+ if(data->share && data->share->ssl_scache)
+ scache = data->share->ssl_scache;
+ else if(data->multi && data->multi->ssl_scache)
+ scache = data->multi->ssl_scache;
+ if(scache && !GOOD_SCACHE(scache)) {
+ failf(data, "transfer would use an invalid scache at %p, denied",
+ (void *)scache);
+ DEBUGASSERT(0);
+ return NULL;
+ }
+ return scache;
+}
+
static void cf_ssl_scache_clear_session(struct Curl_ssl_session *s)
{
if(s->sdata) {
@@ -306,6 +328,7 @@
return CURLE_OUT_OF_MEMORY;
}
+ scache->magic = CURL_SCACHE_MAGIC;
scache->default_lifetime_secs = (24*60*60); /* 1 day */
scache->peer_count = max_peers;
scache->peers = peers;
@@ -322,8 +345,9 @@
void Curl_ssl_scache_destroy(struct Curl_ssl_scache *scache)
{
- if(scache) {
+ if(scache && GOOD_SCACHE(scache)) {
size_t i;
+ scache->magic = 0;
for(i = 0; i < scache->peer_count; ++i) {
cf_ssl_scache_clear_peer(&scache->peers[i]);
}
@@ -359,7 +383,7 @@
char abspath[_MAX_PATH];
if(_fullpath(abspath, path, _MAX_PATH))
return Curl_dyn_addf(buf, ":%s-%s", name, abspath);
-#else
+#elif defined(HAVE_REALPATH)
if(path[0] != '/') {
char *abspath = realpath(path, NULL);
if(abspath) {
@@ -588,6 +612,13 @@
CURLcode result = CURLE_OK;
*ppeer = NULL;
+ if(!GOOD_SCACHE(scache)) {
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
+
+ CURL_TRC_SSLS(data, "find peer slot for %s among %zu slots",
+ ssl_peer_key, scache->peer_count);
+
/* check for entries with known peer_key */
for(i = 0; scache && i < scache->peer_count; i++) {
if(scache->peers[i].ssl_peer_key &&
@@ -792,7 +823,7 @@
const char *ssl_peer_key,
struct Curl_ssl_session *s)
{
- struct Curl_ssl_scache *scache = data->state.ssl_scache;
+ struct Curl_ssl_scache *scache = cf_ssl_scache_get(data);
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
CURLcode result;
DEBUGASSERT(ssl_config);
@@ -801,6 +832,10 @@
Curl_ssl_session_destroy(s);
return CURLE_OK;
}
+ if(!GOOD_SCACHE(scache)) {
+ Curl_ssl_session_destroy(s);
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ }
Curl_ssl_scache_lock(data);
result = cf_scache_add_session(cf, data, scache, ssl_peer_key, s);
@@ -826,7 +861,7 @@
const char *ssl_peer_key,
struct Curl_ssl_session **ps)
{
- struct Curl_ssl_scache *scache = data->state.ssl_scache;
+ struct Curl_ssl_scache *scache = cf_ssl_scache_get(data);
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct Curl_ssl_scache_peer *peer = NULL;
struct Curl_llist_node *n;
@@ -870,7 +905,7 @@
void *sobj,
Curl_ssl_scache_obj_dtor *sobj_free)
{
- struct Curl_ssl_scache *scache = data->state.ssl_scache;
+ struct Curl_ssl_scache *scache = cf_ssl_scache_get(data);
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct Curl_ssl_scache_peer *peer = NULL;
CURLcode result;
@@ -878,6 +913,11 @@
DEBUGASSERT(sobj);
DEBUGASSERT(sobj_free);
+ if(!scache) {
+ result = CURLE_BAD_FUNCTION_ARGUMENT;
+ goto out;
+ }
+
result = cf_ssl_add_peer(data, scache, ssl_peer_key, conn_config, &peer);
if(result || !peer) {
CURL_TRC_SSLS(data, "unable to add scache peer: %d", result);
@@ -898,7 +938,7 @@
const char *ssl_peer_key,
void **sobj)
{
- struct Curl_ssl_scache *scache = data->state.ssl_scache;
+ struct Curl_ssl_scache *scache = cf_ssl_scache_get(data);
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct Curl_ssl_scache_peer *peer = NULL;
CURLcode result;
@@ -924,7 +964,7 @@
struct Curl_easy *data,
const char *ssl_peer_key)
{
- struct Curl_ssl_scache *scache = data->state.ssl_scache;
+ struct Curl_ssl_scache *scache = cf_ssl_scache_get(data);
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct Curl_ssl_scache_peer *peer = NULL;
CURLcode result;
@@ -977,6 +1017,9 @@
CURLcode result = CURLE_OK;
*ppeer = NULL;
+ if(!GOOD_SCACHE(scache))
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+
/* look for an entry that matches salt+hmac exactly or has a known
* ssl_peer_key which salt+hmac's to the same. */
for(i = 0; scache && i < scache->peer_count; i++) {
@@ -1021,7 +1064,7 @@
const unsigned char *shmac, size_t shmac_len,
const unsigned char *sdata, size_t sdata_len)
{
- struct Curl_ssl_scache *scache = data->state.ssl_scache;
+ struct Curl_ssl_scache *scache = cf_ssl_scache_get(data);
struct Curl_ssl_scache_peer *peer = NULL;
struct Curl_ssl_session *s = NULL;
bool locked = FALSE;
@@ -1092,7 +1135,7 @@
curl_ssls_export_cb *export_fn,
void *userptr)
{
- struct Curl_ssl_scache *scache = data->state.ssl_scache;
+ struct Curl_ssl_scache *scache = cf_ssl_scache_get(data);
struct Curl_ssl_scache_peer *peer;
struct dynbuf sbuf, hbuf;
struct Curl_llist_node *n;
diff --git a/Utilities/cmcurl/lib/vtls/wolfssl.c b/Utilities/cmcurl/lib/vtls/wolfssl.c
index 82b21af..546ba03 100644
--- a/Utilities/cmcurl/lib/vtls/wolfssl.c
+++ b/Utilities/cmcurl/lib/vtls/wolfssl.c
@@ -770,7 +770,7 @@
int i;
char *str;
- for(i = 0; (str = wolfSSL_get_cipher_list(i)); i++) {
+ for(i = 0; (str = wolfSSL_get_cipher_list(i)) != NULL; i++) {
size_t n;
if((strncmp(str, "TLS13", 5) == 0) != tls13)
continue;
diff --git a/Utilities/cmlibarchive/CMakeLists.txt b/Utilities/cmlibarchive/CMakeLists.txt
index 166b301..04d986b 100644
--- a/Utilities/cmlibarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/CMakeLists.txt
@@ -887,8 +887,8 @@
IF(OPENSSL_FOUND)
SET(HAVE_LIBCRYPTO 1)
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
- LIST(APPEND ADDITIONAL_LIBS ${OPENSSL_CRYPTO_LIBRARY})
- SET(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
+ list(APPEND ADDITIONAL_LIBS OpenSSL::Crypto)
+ set(CMAKE_REQUIRED_LIBRARIES OpenSSL::Crypto)
SET(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
LA_CHECK_INCLUDE_FILE("openssl/evp.h" HAVE_OPENSSL_EVP_H)
CHECK_FUNCTION_EXISTS(PKCS5_PBKDF2_HMAC_SHA1 HAVE_PKCS5_PBKDF2_HMAC_SHA1)
@@ -1018,9 +1018,8 @@
# was found on this platform.
IF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
- INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
- LIST(APPEND ADDITIONAL_LIBS ${OPENSSL_LIBRARIES})
- LIST(REMOVE_DUPLICATES ADDITIONAL_LIBS)
+ LIST(APPEND ADDITIONAL_LIBS OpenSSL::Crypto)
+ LIST(REMOVE_DUPLICATES ADDITIONAL_LIBS)
ENDIF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
ENDIF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
ENDIF(NOT ARCHIVE_CRYPTO_${ALGORITHM})