Coverage Report

Created: 2026-03-12 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmVersion_Dependencies.cxx
Line
Count
Source
1
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2
   file LICENSE.rst or https://cmake.org/licensing for details.  */
3
#include "cmVersion.h"
4
5
#if !defined(CMAKE_BOOTSTRAP)
6
#  include <cstddef>
7
#  include <string>
8
#  include <utility>
9
#  include <vector>
10
11
#  include <cm3p/archive.h>
12
#  include <cm3p/curl/curl.h>
13
#  include <cm3p/expat.h>
14
#  include <cm3p/json/version.h>
15
#  include <cm3p/kwiml/version.h>
16
17
#  include "cmThirdParty.h" // IWYU pragma: keep
18
19
#  ifdef CMAKE_USE_SYSTEM_LIBRHASH
20
#    include <cstdint>
21
22
#    include <cm3p/rhash.h>
23
#  endif
24
#  include <cm3p/uv.h>
25
#  include <cm3p/zlib.h>
26
27
#  include "cmStringAlgorithms.h"
28
29
std::vector<cmVersion::DependencyInfo> const&
30
cmVersion::CollectDependencyInfo()
31
0
{
32
0
  static std::vector<DependencyInfo> deps;
33
0
  if (!deps.empty()) {
34
0
    return deps;
35
0
  }
36
37
  // BZIP2 is not directly used in CMake, so it is not included here
38
39
  // BZIP2 (libarchive)
40
0
  {
41
0
    char const* bzip2Version = archive_bzlib_version();
42
0
    if (bzip2Version) {
43
0
      DependencyInfo info;
44
0
      info.name = "bzip2";
45
0
      info.version = bzip2Version;
46
0
      info.cameFrom = "libarchive";
47
0
      size_t pos = info.version.find(',');
48
0
      if (pos != std::string::npos) {
49
        // Convert `1.0.8, 30-Mar-2009` to `1.0.8`
50
0
        info.version.erase(pos);
51
0
      }
52
#  if defined(CMAKE_USE_SYSTEM_BZIP2) || defined(CMAKE_USE_SYSTEM_LIBARCHIVE)
53
      // System BZIP2 can be used by system or bundled libarchive
54
      // System libarchive always uses system BZIP2
55
      info.type = DependencyType::System;
56
#  else
57
0
      info.type = DependencyType::Bundled;
58
0
#  endif
59
0
      deps.emplace_back(std::move(info));
60
0
    }
61
0
  }
62
63
  // CPPDAP
64
0
  {
65
0
    DependencyInfo info;
66
0
    info.name = "cppdap";
67
#  ifdef CMAKE_USE_SYSTEM_CPPDAP
68
    info.type = DependencyType::System;
69
    // Cannot get runtime version from cppdap library
70
#  else
71
0
    info.type = DependencyType::Bundled;
72
    // Hardcoded in protocol.h header file comments
73
0
    info.version = "1.65.0";
74
0
#  endif
75
0
    deps.emplace_back(std::move(info));
76
0
  }
77
78
  // CURL
79
0
  {
80
0
    curl_version_info_data* curlVersion = curl_version_info(CURLVERSION_NOW);
81
0
    if (curlVersion) {
82
      // CURL itself
83
0
      {
84
0
        DependencyInfo info;
85
0
        info.name = "curl";
86
0
        if (curlVersion->version) {
87
0
          info.version = curlVersion->version;
88
0
        }
89
#  ifdef CMAKE_USE_SYSTEM_CURL
90
        info.type = DependencyType::System;
91
#  else
92
0
        info.type = DependencyType::Bundled;
93
0
#  endif
94
0
        deps.emplace_back(std::move(info));
95
0
      }
96
97
// Cannot use CURL_AT_LEAST_VERSION and CURL_VERSION_BITS macros,
98
// because they needs at least curl 7.43.0,
99
// but we support curl 7.29.0 from CentOS 7
100
0
#  if LIBCURL_VERSION_NUM >= 0x074200
101
      // NGHTTP2 (curl)
102
      // Added in curl 7.66.0 (0x074200), CURLVERSION_SIXTH
103
0
      if (curlVersion->age >= CURLVERSION_SIXTH &&
104
0
          curlVersion->nghttp2_version) {
105
0
        DependencyInfo info;
106
0
        info.name = "nghttp2";
107
0
        info.cameFrom = "curl";
108
109
0
        info.version = curlVersion->nghttp2_version;
110
111
#    if defined(CMAKE_USE_SYSTEM_NGHTTP2) || defined(CMAKE_USE_SYSTEM_CURL)
112
        // System CURL always uses system NGHTTP2
113
        // System NGHTTP2 can be used by system or bundled CURL
114
        info.type = DependencyType::System;
115
#    else
116
0
        info.type = DependencyType::Bundled;
117
0
#    endif
118
0
        deps.emplace_back(std::move(info));
119
0
      }
120
0
#  endif
121
122
      // OPENSSL (curl)
123
0
      if (curlVersion->ssl_version) {
124
0
        DependencyInfo info;
125
0
        info.name = "ssl";
126
0
        info.cameFrom = "curl";
127
0
        info.version = curlVersion->ssl_version;
128
129
        // With Multi-SSL, the version string is `OpenSSL/3.3.5,
130
        // BoringSSL/3.3.5`, etc.
131
0
        if (cmHasLiteralPrefix(info.version, "OpenSSL/") &&
132
0
            info.version.find('/', 8) == std::string::npos) {
133
0
          info.name = "openssl";
134
0
          info.version.erase(0, 8);
135
0
        }
136
        // Bundled version of OpenSSL is not presented
137
        // Multi-SSL can be used by system CURL only,
138
        // so the SSL library is always system
139
0
        info.type = DependencyType::System;
140
0
        deps.emplace_back(std::move(info));
141
0
      }
142
143
      // ZLIB (curl)
144
0
      if (curlVersion->libz_version) {
145
0
        DependencyInfo info;
146
0
        info.name = "zlib";
147
0
        info.cameFrom = "curl";
148
0
        info.version = curlVersion->libz_version;
149
#  if defined(CMAKE_USE_SYSTEM_ZLIB) || defined(CMAKE_USE_SYSTEM_CURL)
150
        // System CURL always uses system ZLIB
151
        // System ZLIB can be used by system or bundled CURL
152
        info.type = DependencyType::System;
153
#  else
154
0
        info.type = DependencyType::Bundled;
155
0
#  endif
156
0
        deps.emplace_back(std::move(info));
157
0
      }
158
0
    }
159
0
  }
160
161
  // EXPAT
162
0
  {
163
0
    DependencyInfo info;
164
0
    info.name = "expat";
165
166
0
    XML_Expat_Version version = XML_ExpatVersionInfo();
167
0
    info.version =
168
0
      cmStrCat(version.major, '.', version.minor, '.', version.micro);
169
#  ifdef CMAKE_USE_SYSTEM_EXPAT
170
    info.type = DependencyType::System;
171
#  else
172
0
    info.type = DependencyType::Bundled;
173
0
#  endif
174
0
    deps.emplace_back(std::move(info));
175
0
  }
176
177
  // FORM
178
0
  {
179
0
    DependencyInfo info;
180
0
    info.name = "form";
181
    // Cannot get any version from form library
182
#  ifdef CMAKE_USE_SYSTEM_FORM
183
    info.type = DependencyType::System;
184
#  else
185
0
    info.type = DependencyType::Bundled;
186
0
#  endif
187
0
    deps.emplace_back(std::move(info));
188
0
  }
189
190
  // JSONCPP
191
0
  {
192
0
    DependencyInfo info;
193
0
    info.name = "jsoncpp";
194
0
    info.version = JSONCPP_VERSION_STRING;
195
#  ifdef CMAKE_USE_SYSTEM_JSONCPP
196
    info.type = DependencyType::System;
197
#  else
198
0
    info.type = DependencyType::Bundled;
199
0
#  endif
200
0
    deps.emplace_back(std::move(info));
201
0
  }
202
203
  // KWIML
204
0
  {
205
0
    DependencyInfo info;
206
0
    info.name = "kwiml";
207
208
    // Library is header-only, so we can safely use the defined version
209
0
    info.version = KWIML_VERSION_STRING;
210
211
#  ifdef CMAKE_USE_SYSTEM_KWIML
212
    info.type = DependencyType::System;
213
#  else
214
0
    info.type = DependencyType::Bundled;
215
0
#  endif
216
0
    deps.emplace_back(std::move(info));
217
0
  }
218
219
  // LIBARCHIVE
220
0
  {
221
0
    DependencyInfo info;
222
0
    info.name = "libarchive";
223
0
    info.version = archive_version_string();
224
0
    if (cmHasLiteralPrefix(info.version, "libarchive ")) {
225
0
      info.version.erase(0, 11);
226
0
    }
227
#  ifdef CMAKE_USE_SYSTEM_LIBARCHIVE
228
    info.type = DependencyType::System;
229
#  else
230
0
    info.type = DependencyType::Bundled;
231
0
#  endif
232
0
    deps.emplace_back(std::move(info));
233
0
  }
234
235
  // LIBLZMA is not directly used in CMake, so it is not included here
236
237
  // LIBLZMA (libarchive)
238
0
  {
239
0
    char const* liblzmaVersion = archive_liblzma_version();
240
0
    if (liblzmaVersion) {
241
0
      DependencyInfo info;
242
0
      info.name = "liblzma";
243
0
      info.cameFrom = "libarchive";
244
0
      info.version = liblzmaVersion;
245
#  if defined(CMAKE_USE_SYSTEM_LIBLZMA) || defined(CMAKE_USE_SYSTEM_LIBARCHIVE)
246
      // System LIBLZMA can be used by system or bundled libarchive
247
      // System libarchive always uses system LIBLZMA
248
      info.type = DependencyType::System;
249
#  else
250
0
      info.type = DependencyType::Bundled;
251
0
#  endif
252
0
      deps.emplace_back(std::move(info));
253
0
    }
254
0
  }
255
256
  // LIBRHASH
257
0
  {
258
0
    DependencyInfo info;
259
0
    info.name = "librhash";
260
#  ifdef CMAKE_USE_SYSTEM_LIBRHASH
261
    info.type = DependencyType::System;
262
    std::uint64_t version = rhash_get_version();
263
    std::uint8_t major = (version >> 24) & 0xFFu;
264
    std::uint8_t minor = (version >> 16) & 0xFFu;
265
    std::uint8_t patch = (version >> 8) & 0xFFu;
266
    info.version = cmStrCat(major, '.', minor, '.', patch);
267
#  else
268
0
    info.type = DependencyType::Bundled;
269
    // Hardcoded in `update-librhash.bash` script
270
0
    info.version = "1.4.4";
271
0
#  endif
272
0
    deps.emplace_back(std::move(info));
273
0
  }
274
275
  // LIBUV
276
0
  {
277
0
    DependencyInfo info;
278
0
    info.name = "libuv";
279
0
    info.version = uv_version_string();
280
#  ifdef CMAKE_USE_SYSTEM_LIBUV
281
    info.type = DependencyType::System;
282
#  else
283
0
    info.type = DependencyType::Bundled;
284
0
#  endif
285
0
    deps.emplace_back(std::move(info));
286
0
  }
287
288
  // OPENSSL is not directly used in CMake, so it is not included here
289
290
0
#  if ARCHIVE_VERSION_NUMBER >= 3008000
291
  // OPENSSL (libarchive)
292
  // This function is available in libarchive 3.8.0 (3008000) and newer
293
0
  {
294
0
    char const* opensslVersion = archive_openssl_version();
295
0
    if (opensslVersion) {
296
0
      DependencyInfo info;
297
0
      info.name = "openssl";
298
0
      info.cameFrom = "libarchive";
299
0
      info.version = opensslVersion;
300
      // Bundled version of OpenSSL is not presented
301
0
      info.type = DependencyType::System;
302
0
      deps.emplace_back(std::move(info));
303
0
    }
304
0
  }
305
0
#  endif
306
307
  // ZLIB
308
0
  {
309
0
    DependencyInfo info;
310
0
    info.name = "zlib";
311
0
    info.version = zlibVersion();
312
#  ifdef CMAKE_USE_SYSTEM_ZLIB
313
    info.type = DependencyType::System;
314
#  else
315
0
    info.type = DependencyType::Bundled;
316
0
#  endif
317
0
    deps.emplace_back(std::move(info));
318
0
  }
319
320
  // ZLIB (libarchive)
321
0
  {
322
0
    char const* zlibVersion = archive_zlib_version();
323
0
    if (zlibVersion) {
324
0
      DependencyInfo info;
325
0
      info.name = "zlib";
326
0
      info.cameFrom = "libarchive";
327
0
      info.version = zlibVersion;
328
#  if defined(CMAKE_USE_SYSTEM_ZLIB) || defined(CMAKE_USE_SYSTEM_LIBARCHIVE)
329
      // System ZLIB can be used by system or bundled libarchive
330
      // System libarchive always uses system ZLIB
331
      info.type = DependencyType::System;
332
#  else
333
0
      info.type = DependencyType::Bundled;
334
0
#  endif
335
0
      deps.emplace_back(std::move(info));
336
0
    }
337
0
  }
338
339
  // ZSTD is not directly used in CMake, so it is not included here
340
341
  // ZSTD (libarchive)
342
0
  {
343
0
    char const* zstdVersion = archive_libzstd_version();
344
0
    if (zstdVersion) {
345
0
      DependencyInfo info;
346
0
      info.name = "zstd";
347
0
      info.cameFrom = "libarchive";
348
0
      info.version = zstdVersion;
349
#  if defined(CMAKE_USE_SYSTEM_ZSTD) || defined(CMAKE_USE_SYSTEM_LIBARCHIVE)
350
      // System ZSTD can be used by system or bundled libarchive
351
      // System libarchive always uses system ZSTD
352
      info.type = DependencyType::System;
353
#  else
354
0
      info.type = DependencyType::Bundled;
355
0
#  endif
356
0
      deps.emplace_back(std::move(info));
357
0
    }
358
0
  }
359
360
0
  return deps;
361
0
}
362
363
#endif