Coverage Report

Created: 2026-10-28 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmTarget.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 "cmTarget.h"
4
5
#include <algorithm>
6
#include <cassert>
7
#include <functional>
8
#include <iterator>
9
#include <map>
10
#include <set>
11
#include <sstream>
12
#include <unordered_map>
13
#include <unordered_set>
14
15
#include <cm/memory>
16
#include <cm/string_view>
17
#include <cmext/algorithm>
18
#include <cmext/string_view>
19
20
#include "cmsys/RegularExpression.hxx"
21
22
#include "cmAlgorithms.h"
23
#include "cmCustomCommand.h"
24
#include "cmCxxModuleUsageEffects.h"
25
#include "cmFileSet.h"
26
#include "cmFileSetMetadata.h"
27
#include "cmFindPackageStack.h"
28
#include "cmGeneratorExpression.h"
29
#include "cmGeneratorTarget.h"
30
#include "cmGlobalGenerator.h"
31
#include "cmList.h"
32
#include "cmListFileCache.h"
33
#include "cmMakefile.h"
34
#include "cmMessageType.h"
35
#include "cmProperty.h"
36
#include "cmPropertyDefinition.h"
37
#include "cmPropertyMap.h"
38
#include "cmRange.h"
39
#include "cmSourceFile.h"
40
#include "cmSourceFileLocation.h"
41
#include "cmSourceFileLocationKind.h"
42
#include "cmStandardLevelResolver.h"
43
#include "cmState.h"
44
#include "cmStateDirectory.h"
45
#include "cmStateSnapshot.h"
46
#include "cmStringAlgorithms.h"
47
#include "cmSystemTools.h"
48
#include "cmTargetPropertyComputer.h"
49
#include "cmUnreachable.h"
50
#include "cmValue.h"
51
#include "cmXcFramework.h"
52
#include "cmake.h"
53
54
template <>
55
std::string const& cmTargetPropertyComputer::ImportedLocation<cmTarget>(
56
  cmTarget const* tgt, std::string const& config)
57
0
{
58
0
  static std::string loc;
59
0
  assert(tgt->IsImported());
60
0
  loc = tgt->ImportedGetFullPath(config, cmStateEnums::RuntimeBinaryArtifact);
61
0
  return loc;
62
0
}
63
64
template <>
65
cmValue cmTargetPropertyComputer::GetSources<cmTarget>(cmTarget const* tgt)
66
0
{
67
0
  cmBTStringRange entries = tgt->GetSourceEntries();
68
0
  if (entries.empty()) {
69
0
    return nullptr;
70
0
  }
71
72
0
  std::ostringstream ss;
73
0
  char const* sep = "";
74
0
  for (auto const& entry : entries) {
75
0
    cmList files{ entry.Value };
76
0
    for (std::string const& file : files) {
77
0
      if ((cmHasLiteralPrefix(file, "$<TARGET_OBJECTS:") &&
78
0
           file.back() == '>') ||
79
0
          cmGeneratorExpression::Find(file) == std::string::npos) {
80
0
        ss << sep;
81
0
        sep = ";";
82
0
        ss << file;
83
0
      } else {
84
0
        cmSourceFile* sf = tgt->GetMakefile()->GetOrCreateSource(file);
85
        // Construct what is known about this source file location.
86
0
        cmSourceFileLocation const& location = sf->GetLocation();
87
0
        std::string sname = location.GetDirectory();
88
0
        if (!sname.empty()) {
89
0
          sname += "/";
90
0
        }
91
0
        sname += location.GetName();
92
93
0
        ss << sep;
94
0
        sep = ";";
95
        // Append this list entry.
96
0
        ss << sname;
97
0
      }
98
0
    }
99
0
  }
100
0
  static std::string srcs;
101
0
  srcs = ss.str();
102
0
  return cmValue(srcs);
103
0
}
104
105
namespace {
106
struct FileSetEntries
107
{
108
  FileSetEntries(cm::string_view propertyName)
109
509k
    : PropertyName(propertyName)
110
509k
  {
111
509k
  }
112
113
  cm::string_view const PropertyName;
114
  std::vector<BT<std::string>> Entries;
115
};
116
117
struct FileSetType
118
{
119
  FileSetType(cm::string_view typeName,
120
              cm::static_string_view defaultDirectoryProperty,
121
              cm::static_string_view defaultPathProperty,
122
              cm::static_string_view directoryPrefix,
123
              cm::static_string_view pathPrefix,
124
              cm::static_string_view typeDescription,
125
              cm::static_string_view defaultDescription,
126
              cm::static_string_view arbitraryDescription,
127
              FileSetEntries selfEntries, FileSetEntries interfaceEntries)
128
254k
    : TypeName(typeName)
129
254k
    , DefaultDirectoryProperty(defaultDirectoryProperty)
130
254k
    , DefaultPathProperty(defaultPathProperty)
131
254k
    , DirectoryPrefix(directoryPrefix)
132
254k
    , PathPrefix(pathPrefix)
133
254k
    , TypeDescription(typeDescription)
134
254k
    , DefaultDescription(defaultDescription)
135
254k
    , ArbitraryDescription(arbitraryDescription)
136
254k
    , SelfEntries(std::move(selfEntries))
137
254k
    , InterfaceEntries(std::move(interfaceEntries))
138
254k
  {
139
254k
  }
140
141
  cm::string_view const TypeName;
142
  cm::static_string_view const DefaultDirectoryProperty;
143
  cm::static_string_view const DefaultPathProperty;
144
  cm::static_string_view const DirectoryPrefix;
145
  cm::static_string_view const PathPrefix;
146
  cm::static_string_view const TypeDescription;
147
  cm::static_string_view const DefaultDescription;
148
  cm::static_string_view const ArbitraryDescription;
149
150
  FileSetEntries SelfEntries;
151
  FileSetEntries InterfaceEntries;
152
153
  enum class Action
154
  {
155
    Set,
156
    Append,
157
  };
158
159
  template <typename ValueType>
160
  bool WriteProperties(cmTarget* tgt, cmTargetInternals* impl,
161
                       std::string const& prop, ValueType value,
162
                       Action action);
163
  std::pair<bool, cmValue> ReadProperties(cmTarget const* tgt,
164
                                          cmTargetInternals const* impl,
165
                                          std::string const& prop) const;
166
167
  void AddFileSet(std::string const& name, cm::FileSetMetadata::Visibility vis,
168
                  cmListFileBacktrace bt);
169
170
  // We recompute this every time since some of the property
171
  // names depend on names of the file sets
172
  cmPropertyMap GetProperties(cmTarget const* tgt,
173
                              cmTargetInternals const* impl) const;
174
};
175
176
struct FileSetRule
177
{
178
  std::vector<BT<std::string>> SelfEntries;
179
  std::vector<BT<std::string>> InterfaceEntries;
180
181
  void AddFileSet(std::string const& name, cm::FileSetMetadata::Visibility vis,
182
                  cmListFileBacktrace bt);
183
};
184
185
struct UsageRequirementProperty
186
{
187
  enum class AppendEmpty
188
  {
189
    Yes,
190
    No,
191
  };
192
193
  UsageRequirementProperty(cm::static_string_view name,
194
                           AppendEmpty appendEmpty = AppendEmpty::No)
195
1.78M
    : Name(name)
196
1.78M
    , AppendBehavior(appendEmpty)
197
1.78M
  {
198
1.78M
  }
199
200
  void CopyFromEntries(cmBTStringRange entries)
201
142k
  {
202
142k
    cm::append(this->Entries, entries);
203
142k
  }
204
205
  enum class Action
206
  {
207
    Set,
208
    Prepend,
209
    Append,
210
  };
211
212
  template <typename ValueType>
213
  bool Write(cmTargetInternals const* impl,
214
             cm::optional<cmListFileBacktrace> const& bt,
215
             std::string const& prop, ValueType value, Action action);
216
  template <typename ValueType>
217
  void WriteDirect(cmTargetInternals const* impl,
218
                   cm::optional<cmListFileBacktrace> const& bt,
219
                   ValueType value, Action action);
220
  void WriteDirect(BT<std::string> value, Action action);
221
  std::pair<bool, cmValue> Read(std::string const& prop) const;
222
223
  cm::static_string_view const Name;
224
  AppendEmpty const AppendBehavior;
225
226
  std::vector<BT<std::string>> Entries;
227
};
228
229
struct TargetProperty
230
{
231
  enum class InitCondition
232
  {
233
    // Always initialize the property.
234
    Always,
235
    // Never initialize the property.
236
    Never,
237
    // Only initialize if the target can compile sources.
238
    CanCompileSources,
239
    // Only apply to Xcode generators.
240
    NeedsXcode,
241
    // Only apply to Xcode generators on targets that can compile sources.
242
    NeedsXcodeAndCanCompileSources,
243
    // Needs to be a "normal" target (any non-global, non-utility target).
244
    NormalTarget,
245
    // Any non-imported target.
246
    NonImportedTarget,
247
    // Needs to be a "normal" target (any non-global, non-utility target) that
248
    // is not `IMPORTED`.
249
    NormalNonImportedTarget,
250
    // Needs to be a "normal" target with an artifact (no `INTERFACE`
251
    // libraries).
252
    TargetWithArtifact,
253
    // Needs to be a "normal" target with an artifact that is not an
254
    // executable.
255
    NonExecutableWithArtifact,
256
    // Needs to be a linkable library target (no `OBJECT` or `MODULE`
257
    // libraries).
258
    LinkableLibraryTarget,
259
    // Needs to be an executable.
260
    ExecutableTarget,
261
    // Needs to be a shared library (`SHARED`).
262
    SharedLibraryTarget,
263
    // Needs to be a target with meaningful symbol exports (`SHARED` or
264
    // `EXECUTABLE`).
265
    TargetWithSymbolExports,
266
    // Targets with "commands" associated with them. Basically everything
267
    // except global and `INTERFACE` targets.
268
    TargetWithCommands,
269
  };
270
271
  enum class Repetition
272
  {
273
    Once,
274
    PerConfig,
275
    PerConfigPrefix,
276
  };
277
278
  TargetProperty(cm::static_string_view name)
279
30
    : Name(name)
280
30
  {
281
30
  }
282
283
  TargetProperty(cm::static_string_view name, cm::static_string_view dflt,
284
                 InitCondition init)
285
90
    : Name(name)
286
90
    , Default(dflt)
287
90
    , InitConditional(init)
288
90
  {
289
90
  }
290
291
  TargetProperty(cm::static_string_view name, InitCondition init)
292
1.95k
    : Name(name)
293
1.95k
    , InitConditional(init)
294
1.95k
  {
295
1.95k
  }
296
297
  TargetProperty(cm::static_string_view name, InitCondition init,
298
                 Repetition repeat)
299
90
    : Name(name)
300
90
    , InitConditional(init)
301
90
    , Repeat(repeat)
302
90
  {
303
90
  }
304
305
  cm::static_string_view const Name;
306
  // Explicit initialization is needed for AppleClang in Xcode 8 and below
307
  // NOLINTNEXTLINE(readability-redundant-member-init)
308
  cm::optional<cm::static_string_view> const Default = {};
309
  InitCondition const InitConditional = InitCondition::Always;
310
  Repetition const Repeat = Repetition::Once;
311
};
312
313
#define IC TargetProperty::InitCondition
314
#define R TargetProperty::Repetition
315
316
/* clang-format off */
317
#define COMMON_LANGUAGE_PROPERTIES(lang)                                      \
318
  { #lang "_COMPILER_LAUNCHER"_s, IC::CanCompileSources },                    \
319
  { #lang "_STANDARD"_s, IC::CanCompileSources },                             \
320
  { #lang "_STANDARD_REQUIRED"_s, IC::CanCompileSources },                    \
321
  { #lang "_EXTENSIONS"_s, IC::CanCompileSources },                           \
322
  { #lang "_VISIBILITY_PRESET"_s, IC::CanCompileSources }
323
/* clang-format on */
324
325
TargetProperty const StaticTargetProperties[] = {
326
  /* clang-format off */
327
  // -- Debugger Properties
328
  { "DEBUGGER_WORKING_DIRECTORY"_s, IC::ExecutableTarget },
329
  // Compilation properties
330
  { "COMPILE_WARNING_AS_ERROR"_s, IC::CanCompileSources },
331
  { "INTERPROCEDURAL_OPTIMIZATION"_s, IC::CanCompileSources },
332
  { "INTERPROCEDURAL_OPTIMIZATION_"_s, IC::TargetWithArtifact, R::PerConfig },
333
  { "NO_SYSTEM_FROM_IMPORTED"_s, IC::CanCompileSources },
334
  // Set to `True` for `SHARED` and `MODULE` targets.
335
  { "POSITION_INDEPENDENT_CODE"_s, IC::CanCompileSources },
336
  { "VISIBILITY_INLINES_HIDDEN"_s, IC::CanCompileSources },
337
  // -- Features
338
  // ---- PCH
339
  { "DISABLE_PRECOMPILE_HEADERS"_s, IC::CanCompileSources },
340
  { "PCH_WARN_INVALID"_s, "ON"_s, IC::CanCompileSources },
341
  { "PCH_INSTANTIATE_TEMPLATES"_s, "ON"_s, IC::CanCompileSources },
342
  { "PCH_WARNINGS"_s, IC::CanCompileSources },
343
  // -- Platforms
344
  // ---- Android
345
  { "ANDROID_API"_s, IC::CanCompileSources },
346
  { "ANDROID_API_MIN"_s, IC::CanCompileSources },
347
  { "ANDROID_ARCH"_s, IC::CanCompileSources },
348
  { "ANDROID_ASSETS_DIRECTORIES"_s, IC::CanCompileSources },
349
  { "ANDROID_JAVA_SOURCE_DIR"_s, IC::CanCompileSources },
350
  { "ANDROID_STL_TYPE"_s, IC::CanCompileSources },
351
  // ---- macOS
352
  { "OSX_ARCHITECTURES"_s, IC::CanCompileSources },
353
  // ---- Windows
354
  { "MSVC_DEBUG_INFORMATION_FORMAT"_s, IC::CanCompileSources },
355
  { "MSVC_RUNTIME_CHECKS"_s, IC::CanCompileSources },
356
  { "MSVC_RUNTIME_LIBRARY"_s, IC::CanCompileSources },
357
  { "VS_JUST_MY_CODE_DEBUGGING"_s, IC::CanCompileSources },
358
  { "VS_DEBUGGER_COMMAND"_s, IC::ExecutableTarget },
359
  { "VS_DEBUGGER_COMMAND_ARGUMENTS"_s, IC::ExecutableTarget },
360
  { "VS_DEBUGGER_ENVIRONMENT"_s, IC::ExecutableTarget },
361
  { "VS_DEBUGGER_WORKING_DIRECTORY"_s, IC::ExecutableTarget },
362
  { "VS_USE_DEBUG_LIBRARIES"_s, IC::NonImportedTarget },
363
  // ---- OpenWatcom
364
  { "WATCOM_RUNTIME_LIBRARY"_s, IC::CanCompileSources },
365
  // ---- AIX
366
  { "AIX_SHARED_LIBRARY_ARCHIVE"_s, IC::SharedLibraryTarget },
367
  // -- Language
368
  // ---- C
369
  COMMON_LANGUAGE_PROPERTIES(C),
370
  // ---- C++
371
  COMMON_LANGUAGE_PROPERTIES(CXX),
372
  // ---- SYCL
373
  { "SYCL_COMPILER_LAUNCHER"_s, IC::CanCompileSources },
374
  { "SYCL_CXX_STANDARD"_s, IC::CanCompileSources },
375
  { "SYCL_CXX_STANDARD_REQUIRED"_s, IC::CanCompileSources },
376
  { "SYCL_EXTENSIONS"_s, IC::CanCompileSources },
377
  { "SYCL_VISIBILITY_PRESET"_s, IC::CanCompileSources },
378
  { "SYCL_EXTENSION_MODE"_s, IC::CanCompileSources },
379
  { "SYCL_DEVICE_TARGETS"_s, IC::CanCompileSources },
380
  { "SYCL_SEPARABLE_COMPILATION"_s, IC::CanCompileSources },
381
  { "SYCL_RESOLVE_DEVICE_SYMBOLS"_s, IC::CanCompileSources },
382
  // ---- CSharp
383
  { "DOTNET_SDK"_s, IC::NonImportedTarget },
384
  { "DOTNET_TARGET_FRAMEWORK"_s, IC::TargetWithCommands },
385
  { "DOTNET_TARGET_FRAMEWORK_VERSION"_s, IC::TargetWithCommands },
386
  // ---- CUDA
387
  COMMON_LANGUAGE_PROPERTIES(CUDA),
388
  { "CUDA_SEPARABLE_COMPILATION"_s, IC::CanCompileSources },
389
  { "CUDA_ARCHITECTURES"_s, IC::CanCompileSources },
390
  // ---- Fortran
391
  { "Fortran_FORMAT"_s, IC::CanCompileSources },
392
  { "Fortran_MODULE_DIRECTORY"_s, IC::CanCompileSources },
393
  { "Fortran_COMPILER_LAUNCHER"_s, IC::CanCompileSources },
394
  { "Fortran_PREPROCESS"_s, IC::CanCompileSources },
395
  { "Fortran_VISIBILITY_PRESET"_s, IC::CanCompileSources },
396
  // ---- HIP
397
  COMMON_LANGUAGE_PROPERTIES(HIP),
398
  { "HIP_ARCHITECTURES"_s, IC::CanCompileSources },
399
  // ---- ISPC
400
  { "ISPC_COMPILER_LAUNCHER"_s, IC::CanCompileSources },
401
  { "ISPC_HEADER_DIRECTORY"_s, IC::CanCompileSources },
402
  { "ISPC_HEADER_SUFFIX"_s, "_ispc.h"_s, IC::CanCompileSources },
403
  { "ISPC_INSTRUCTION_SETS"_s, IC::CanCompileSources },
404
  // ---- Objective C
405
  COMMON_LANGUAGE_PROPERTIES(OBJC),
406
  // ---- Objective C++
407
  COMMON_LANGUAGE_PROPERTIES(OBJCXX),
408
  // ---- Swift
409
  { "Swift_LANGUAGE_VERSION"_s, IC::CanCompileSources },
410
  { "Swift_MODULE_DIRECTORY"_s, IC::CanCompileSources },
411
  { "Swift_COMPILATION_MODE"_s, IC::CanCompileSources },
412
  { "Swift_SEPARATE_MODULE_EMISSION"_s, IC::CanCompileSources },
413
  // ---- Rust
414
  { "Rust_EDITION"_s, IC::CanCompileSources },
415
  { "Rust_COMPILER_LAUNCHER"_s, IC::CanCompileSources },
416
  { "Rust_MAIN_CRATE_ROOT"_s, IC::CanCompileSources },
417
  // ---- moc
418
  { "AUTOMOC"_s, IC::CanCompileSources },
419
  { "AUTOMOC_COMPILER_PREDEFINES"_s, IC::CanCompileSources },
420
  { "AUTOMOC_INCLUDE_DIRECTORIES"_s, IC::CanCompileSources },
421
  { "AUTOMOC_MACRO_NAMES"_s, IC::CanCompileSources },
422
  { "AUTOMOC_MOC_OPTIONS"_s, IC::CanCompileSources },
423
  { "AUTOMOC_PATH_PREFIX"_s, IC::CanCompileSources },
424
  { "AUTOMOC_EXECUTABLE"_s, IC::CanCompileSources },
425
  // ---- uic
426
  { "AUTOUIC"_s, IC::CanCompileSources },
427
  { "AUTOUIC_OPTIONS"_s, IC::CanCompileSources },
428
  { "AUTOUIC_SEARCH_PATHS"_s, IC::CanCompileSources },
429
  { "AUTOUIC_EXECUTABLE"_s, IC::CanCompileSources },
430
  // ---- rcc
431
  { "AUTORCC"_s, IC::CanCompileSources },
432
  { "AUTORCC_OPTIONS"_s, IC::CanCompileSources },
433
  { "AUTORCC_EXECUTABLE"_s, IC::CanCompileSources },
434
435
  // Linking properties
436
  { "LINKER_TYPE"_s, IC::CanCompileSources },
437
  { "LINK_WARNING_AS_ERROR"_s, IC::CanCompileSources },
438
  { "ENABLE_EXPORTS"_s, IC::TargetWithSymbolExports },
439
  { "LINK_LIBRARIES_ONLY_TARGETS"_s, IC::NormalNonImportedTarget },
440
  { "LINK_LIBRARIES_STRATEGY"_s, IC::NormalNonImportedTarget },
441
  { "LINK_SEARCH_START_STATIC"_s, IC::CanCompileSources },
442
  { "LINK_SEARCH_END_STATIC"_s, IC::CanCompileSources },
443
  // Initialize per-configuration name postfix property from the variable only
444
  // for non-executable targets.  This preserves compatibility with previous
445
  // CMake versions in which executables did not support this variable.
446
  // Projects may still specify the property directly.
447
  { "_POSTFIX"_s, IC::NonExecutableWithArtifact, R::PerConfigPrefix },
448
  // -- Dependent library lookup
449
  { "MACOSX_RPATH"_s, IC::CanCompileSources },
450
  // ---- Build
451
  { "BUILD_RPATH"_s, IC::CanCompileSources },
452
  { "BUILD_RPATH_USE_ORIGIN"_s, IC::CanCompileSources },
453
  { "SKIP_BUILD_RPATH"_s, "OFF"_s, IC::CanCompileSources },
454
  { "BUILD_WITH_INSTALL_RPATH"_s, "OFF"_s, IC::CanCompileSources },
455
  { "BUILD_WITH_INSTALL_NAME_DIR"_s, IC::CanCompileSources },
456
  // ---- Install
457
  { "INSTALL_NAME_DIR"_s, IC::CanCompileSources },
458
  { "INSTALL_OBJECT_NAME_STRATEGY"_s, IC::CanCompileSources },
459
  { "INSTALL_OBJECT_ONLY_USE_DESTINATION"_s, IC::CanCompileSources },
460
  { "INSTALL_REMOVE_ENVIRONMENT_RPATH"_s, IC::CanCompileSources },
461
  { "INSTALL_RPATH"_s, ""_s, IC::CanCompileSources },
462
  { "INSTALL_RPATH_USE_LINK_PATH"_s, "OFF"_s, IC::CanCompileSources },
463
  // -- Platforms
464
  // ---- AIX
465
  { "AIX_EXPORT_ALL_SYMBOLS"_s, IC::TargetWithSymbolExports },
466
  // ---- Android
467
  { "ANDROID_GUI"_s, IC::ExecutableTarget },
468
  { "ANDROID_JAR_DIRECTORIES"_s, IC::CanCompileSources },
469
  { "ANDROID_JAR_DEPENDENCIES"_s, IC::CanCompileSources },
470
  { "ANDROID_NATIVE_LIB_DIRECTORIES"_s, IC::CanCompileSources },
471
  { "ANDROID_NATIVE_LIB_DEPENDENCIES"_s, IC::CanCompileSources },
472
  { "ANDROID_PROGUARD"_s, IC::CanCompileSources },
473
  { "ANDROID_PROGUARD_CONFIG_PATH"_s, IC::CanCompileSources },
474
  { "ANDROID_SECURE_PROPS_PATH"_s, IC::CanCompileSources },
475
  // ---- iOS
476
  { "IOS_INSTALL_COMBINED"_s, IC::CanCompileSources },
477
  // ---- macOS
478
  { "FRAMEWORK_MULTI_CONFIG_POSTFIX_"_s, IC::LinkableLibraryTarget, R::PerConfig },
479
  // ---- Windows
480
  { "DLL_NAME_WITH_SOVERSION"_s, IC::SharedLibraryTarget },
481
  { "GNUtoMS"_s, IC::CanCompileSources },
482
  { "WIN32_EXECUTABLE"_s, IC::CanCompileSources },
483
  { "WINDOWS_EXPORT_ALL_SYMBOLS"_s, IC::TargetWithSymbolExports },
484
  // -- Languages
485
  // ---- C
486
  { "C_LINKER_LAUNCHER"_s, IC::CanCompileSources },
487
  // ---- C++
488
  { "CXX_LINKER_LAUNCHER"_s, IC::CanCompileSources },
489
  // ---- CUDA
490
  { "CUDA_LINKER_LAUNCHER"_s, IC::CanCompileSources },
491
  { "CUDA_RESOLVE_DEVICE_SYMBOLS"_s, IC::CanCompileSources },
492
  { "CUDA_RUNTIME_LIBRARY"_s, IC::CanCompileSources },
493
  // ---- HIP
494
  { "HIP_LINKER_LAUNCHER"_s, IC::CanCompileSources },
495
  { "HIP_RUNTIME_LIBRARY"_s, IC::CanCompileSources },
496
  // ---- SYCL
497
  { "SYCL_LINKER_LAUNCHER"_s, IC::CanCompileSources },
498
  // ---- Objective C
499
  { "OBJC_LINKER_LAUNCHER"_s, IC::CanCompileSources },
500
  // ---- Objective C++
501
  { "OBJCXX_LINKER_LAUNCHER"_s, IC::CanCompileSources },
502
  // ---- Fortran
503
  { "Fortran_LINKER_LAUNCHER"_s, IC::CanCompileSources },
504
505
  // Static analysis
506
  { "SKIP_LINTING"_s, IC::CanCompileSources },
507
  // -- C
508
  { "C_CLANG_TIDY"_s, IC::CanCompileSources },
509
  { "C_CLANG_TIDY_EXPORT_FIXES_DIR"_s, IC::CanCompileSources },
510
  { "C_CPPLINT"_s, IC::CanCompileSources },
511
  { "C_CPPCHECK"_s, IC::CanCompileSources },
512
  { "C_ICSTAT"_s, IC::CanCompileSources },
513
  { "C_INCLUDE_WHAT_YOU_USE"_s, IC::CanCompileSources },
514
  { "C_PVS_STUDIO"_s, IC::CanCompileSources },
515
  // -- C++
516
  { "CXX_CLANG_TIDY"_s, IC::CanCompileSources },
517
  { "CXX_CLANG_TIDY_EXPORT_FIXES_DIR"_s, IC::CanCompileSources },
518
  { "CXX_CPPLINT"_s, IC::CanCompileSources },
519
  { "CXX_CPPCHECK"_s, IC::CanCompileSources },
520
  { "CXX_ICSTAT"_s, IC::CanCompileSources },
521
  { "CXX_INCLUDE_WHAT_YOU_USE"_s, IC::CanCompileSources },
522
  { "CXX_PVS_STUDIO"_s, IC::CanCompileSources },
523
  // -- Objective C
524
  { "OBJC_CLANG_TIDY"_s, IC::CanCompileSources },
525
  { "OBJC_CLANG_TIDY_EXPORT_FIXES_DIR"_s, IC::CanCompileSources },
526
  // -- Objective C++
527
  { "OBJCXX_CLANG_TIDY"_s, IC::CanCompileSources },
528
  { "OBJCXX_CLANG_TIDY_EXPORT_FIXES_DIR"_s, IC::CanCompileSources },
529
  // -- Linking
530
  { "LINK_WHAT_YOU_USE"_s, IC::CanCompileSources },
531
532
  // Build graph properties
533
  { "LINK_DEPENDS_NO_SHARED"_s, IC::CanCompileSources },
534
  { "UNITY_BUILD"_s, IC::CanCompileSources },
535
  { "UNITY_BUILD_UNIQUE_ID"_s, IC::CanCompileSources },
536
  { "UNITY_BUILD_BATCH_SIZE"_s, "8"_s, IC::CanCompileSources },
537
  { "UNITY_BUILD_MODE"_s, "BATCH"_s, IC::CanCompileSources },
538
  { "UNITY_BUILD_RELOCATABLE"_s, IC::CanCompileSources },
539
  { "OPTIMIZE_DEPENDENCIES"_s, IC::CanCompileSources },
540
  { "VERIFY_INTERFACE_HEADER_SETS"_s },
541
  { "VERIFY_PRIVATE_HEADER_SETS"_s },
542
  // -- Android
543
  { "ANDROID_ANT_ADDITIONAL_OPTIONS"_s, IC::CanCompileSources },
544
  { "ANDROID_PROCESS_MAX"_s, IC::CanCompileSources },
545
  { "ANDROID_SKIP_ANT_STEP"_s, IC::CanCompileSources },
546
  // -- Autogen
547
  { "AUTOGEN_COMMAND_LINE_LENGTH_MAX"_s, IC::CanCompileSources },
548
  { "AUTOGEN_ORIGIN_DEPENDS"_s, IC::CanCompileSources },
549
  { "AUTOGEN_PARALLEL"_s, IC::CanCompileSources },
550
  { "AUTOGEN_USE_SYSTEM_INCLUDE"_s, IC::CanCompileSources },
551
  { "AUTOGEN_BETTER_GRAPH_MULTI_CONFIG"_s, IC::CanCompileSources },
552
  // -- moc
553
  { "AUTOMOC_DEPEND_FILTERS"_s, IC::CanCompileSources },
554
  // -- C++
555
  { "CXX_SCAN_FOR_MODULES"_s, IC::CanCompileSources },
556
  // -- Ninja
557
  { "JOB_POOL_COMPILE"_s, IC::CanCompileSources },
558
  { "JOB_POOL_LINK"_s, IC::CanCompileSources },
559
  { "JOB_POOL_PRECOMPILE_HEADER"_s, IC::CanCompileSources },
560
  // -- Visual Studio
561
  { "VS_NO_COMPILE_BATCHING"_s, IC::CanCompileSources },
562
  { "VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION"_s, IC::CanCompileSources},
563
564
  // Output location properties
565
  { "ARCHIVE_OUTPUT_DIRECTORY"_s, IC::CanCompileSources },
566
  { "ARCHIVE_OUTPUT_DIRECTORY_"_s, IC::TargetWithArtifact, R::PerConfig },
567
  { "COMPILE_PDB_OUTPUT_DIRECTORY"_s, IC::CanCompileSources },
568
  { "COMPILE_PDB_OUTPUT_DIRECTORY_"_s, IC::TargetWithArtifact, R::PerConfig },
569
  { "LIBRARY_OUTPUT_DIRECTORY"_s, IC::CanCompileSources },
570
  { "LIBRARY_OUTPUT_DIRECTORY_"_s, IC::TargetWithArtifact, R::PerConfig },
571
  { "PDB_OUTPUT_DIRECTORY"_s, IC::CanCompileSources },
572
  { "PDB_OUTPUT_DIRECTORY_"_s, IC::TargetWithArtifact, R::PerConfig },
573
  { "RUNTIME_OUTPUT_DIRECTORY"_s, IC::CanCompileSources },
574
  { "RUNTIME_OUTPUT_DIRECTORY_"_s, IC::TargetWithArtifact, R::PerConfig },
575
576
  // macOS bundle properties
577
  { "FRAMEWORK"_s, IC::CanCompileSources },
578
  { "FRAMEWORK_MULTI_CONFIG_POSTFIX"_s, IC::CanCompileSources },
579
  { "MACOSX_BUNDLE"_s, IC::CanCompileSources },
580
581
  // Usage requirement properties
582
  { "LINK_INTERFACE_LIBRARIES"_s, IC::CanCompileSources },
583
  { "MAP_IMPORTED_CONFIG_"_s, IC::NormalTarget, R::PerConfig },
584
  { "EXPORT_FIND_PACKAGE_NAME"_s, IC::NormalTarget },
585
586
  // Metadata
587
  { "CROSSCOMPILING_EMULATOR"_s, IC::ExecutableTarget },
588
  { "EXPORT_BUILD_DATABASE"_s, IC::CanCompileSources },
589
  { "EXPORT_COMPILE_COMMANDS"_s, IC::CanCompileSources },
590
  { "FOLDER"_s },
591
  { "TEST_LAUNCHER"_s, IC::ExecutableTarget },
592
593
  // Xcode properties
594
  { "XCODE_GENERATE_SCHEME"_s, IC::NeedsXcode },
595
596
#ifdef __APPLE__
597
  { "XCODE_SCHEME_ADDRESS_SANITIZER"_s, IC::NeedsXcodeAndCanCompileSources },
598
  { "XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN"_s, IC::NeedsXcodeAndCanCompileSources },
599
  { "XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING"_s, IC::NeedsXcodeAndCanCompileSources },
600
  { "XCODE_SCHEME_ENABLE_GPU_FRAME_CAPTURE_MODE"_s, IC::NeedsXcodeAndCanCompileSources },
601
  { "XCODE_SCHEME_THREAD_SANITIZER"_s, IC::NeedsXcodeAndCanCompileSources },
602
  { "XCODE_SCHEME_THREAD_SANITIZER_STOP"_s, IC::NeedsXcodeAndCanCompileSources },
603
  { "XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER"_s, IC::NeedsXcodeAndCanCompileSources },
604
  { "XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP"_s, IC::NeedsXcodeAndCanCompileSources },
605
  { "XCODE_SCHEME_LAUNCH_CONFIGURATION"_s, IC::NeedsXcodeAndCanCompileSources },
606
  { "XCODE_SCHEME_TEST_CONFIGURATION"_s, IC::NeedsXcodeAndCanCompileSources },
607
  { "XCODE_SCHEME_ENABLE_GPU_API_VALIDATION"_s, IC::NeedsXcodeAndCanCompileSources },
608
  { "XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION"_s, IC::NeedsXcodeAndCanCompileSources },
609
  { "XCODE_SCHEME_WORKING_DIRECTORY"_s, IC::NeedsXcodeAndCanCompileSources },
610
  { "XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER"_s, IC::NeedsXcodeAndCanCompileSources },
611
  { "XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP"_s, IC::NeedsXcodeAndCanCompileSources },
612
  { "XCODE_SCHEME_MALLOC_SCRIBBLE"_s, IC::NeedsXcodeAndCanCompileSources },
613
  { "XCODE_SCHEME_MALLOC_GUARD_EDGES"_s, IC::NeedsXcodeAndCanCompileSources },
614
  { "XCODE_SCHEME_GUARD_MALLOC"_s, IC::NeedsXcodeAndCanCompileSources },
615
  { "XCODE_SCHEME_LAUNCH_MODE"_s, IC::NeedsXcodeAndCanCompileSources },
616
  { "XCODE_SCHEME_LLDB_INIT_FILE"_s, IC::NeedsXcodeAndCanCompileSources },
617
  { "XCODE_SCHEME_ZOMBIE_OBJECTS"_s, IC::NeedsXcodeAndCanCompileSources },
618
  { "XCODE_SCHEME_MALLOC_STACK"_s, IC::NeedsXcodeAndCanCompileSources },
619
  { "XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE"_s, IC::NeedsXcodeAndCanCompileSources },
620
  { "XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS"_s, IC::NeedsXcodeAndCanCompileSources },
621
  { "XCODE_SCHEME_ENVIRONMENT"_s, IC::NeedsXcodeAndCanCompileSources },
622
  { "XCODE_LINK_BUILD_PHASE_MODE"_s, "NONE"_s, IC::NeedsXcodeAndCanCompileSources },
623
#endif
624
  /* clang-format on */
625
};
626
627
#undef COMMON_LANGUAGE_PROPERTIES
628
#undef IC
629
#undef R
630
631
cmValue copyProperty(cmTarget const* src, cmTarget* dst,
632
                     std::string const& prop)
633
0
{
634
0
  cmValue value = src->GetProperty(prop);
635
  // Always set the property; it may have been explicitly unset.
636
0
  dst->SetProperty(prop, value);
637
0
  return value;
638
0
};
639
640
}
641
642
class cmTargetInternals
643
{
644
public:
645
  cm::TargetType TargetType;
646
  cmTarget::Origin Origin = cmTarget::Origin::Unknown;
647
  cmMakefile* Makefile;
648
  cmPolicies::PolicyMap PolicyMap;
649
  cmTarget const* TemplateTarget = nullptr;
650
  std::string Name;
651
  std::string InstallPath;
652
  std::string RuntimeInstallPath;
653
  cmPropertyMap Properties;
654
  bool IsGeneratorProvided = false;
655
  bool HaveInstallRule = false;
656
  bool IsDLLPlatform = false;
657
  bool IsAIX = false;
658
  bool IsApple = false;
659
  bool IsAndroid = false;
660
  bool BuildInterfaceIncludesAppended = false;
661
  bool PerConfig = false;
662
  bool IsSymbolic = false;
663
  bool IsForTryCompile = false;
664
  bool IsExportPassthrough = false;
665
  bool CxxModuleNeedsInterfaceObjects = false;
666
  std::vector<BT<std::string>> CxxModuleSynthCompileOptions;
667
  cmTarget::Visibility TargetVisibility;
668
  std::string ForeignPackageName;
669
  cmTarget* ForeignTarget = nullptr;
670
  std::set<BT<std::pair<std::string, bool>>> Utilities;
671
  std::set<std::string> CodegenDependencies;
672
  std::vector<cmCustomCommand> PreBuildCommands;
673
  std::vector<cmCustomCommand> PreLinkCommands;
674
  std::vector<cmCustomCommand> PostBuildCommands;
675
  std::vector<cmInstallTargetGenerator*> InstallGenerators;
676
  std::set<std::string> SystemIncludeDirectories;
677
  cmTarget::LinkLibraryVectorType OriginalLinkLibraries;
678
  std::map<std::string, BTs<std::string>> LanguageStandardProperties;
679
  std::map<cmTargetExport const*, std::vector<std::string>>
680
    InstallIncludeDirectoriesEntries;
681
  std::vector<std::pair<cmTarget::TLLSignature, cmListFileContext>>
682
    TLLCommands;
683
  std::map<std::string, cmFileSet> FileSets;
684
  cmListFileBacktrace Backtrace;
685
  cmFindPackageStack FindPackageStack;
686
687
  UsageRequirementProperty IncludeDirectories;
688
  UsageRequirementProperty CompileOptions;
689
  UsageRequirementProperty CompileFeatures;
690
  UsageRequirementProperty CompileDefinitions;
691
  UsageRequirementProperty CompileWrappers;
692
  UsageRequirementProperty PrecompileHeaders;
693
  UsageRequirementProperty Sources;
694
  UsageRequirementProperty LinkOptions;
695
  UsageRequirementProperty LinkDirectories;
696
  UsageRequirementProperty LinkLibraries;
697
  UsageRequirementProperty LinkWrappers;
698
  UsageRequirementProperty InterfaceCompileWrappers;
699
  UsageRequirementProperty InterfaceLinkLibraries;
700
  UsageRequirementProperty InterfaceLinkLibrariesDirect;
701
  UsageRequirementProperty InterfaceLinkLibrariesDirectExclude;
702
  UsageRequirementProperty InterfaceLinkWrappers;
703
  UsageRequirementProperty ImportedCxxModulesIncludeDirectories;
704
  UsageRequirementProperty ImportedCxxModulesCompileDefinitions;
705
  UsageRequirementProperty ImportedCxxModulesCompileFeatures;
706
  UsageRequirementProperty ImportedCxxModulesCompileOptions;
707
  UsageRequirementProperty ImportedCxxModulesLinkLibraries;
708
709
  std::unordered_map<cm::string_view, FileSetType> FileSetTypes;
710
  std::unordered_map<std::string, FileSetRule> FileSetRules;
711
712
  cmTargetInternals(std::string name, cm::TargetType type,
713
                    cmTarget::Visibility visibility, cmMakefile* mf,
714
                    cmTarget::PerConfig perConfig);
715
716
  bool IsImported() const;
717
718
  bool CheckImportedLibName(std::string const& prop,
719
                            std::string const& value) const;
720
721
  template <typename ValueType>
722
  void AddDirectoryToFileSet(cmTarget* self, std::string const& fileSetName,
723
                             ValueType value, cm::string_view fileSetType,
724
                             cm::string_view description,
725
                             FileSetType::Action action);
726
  template <typename ValueType>
727
  void AddPathToFileSet(cmTarget* self, std::string const& fileSetName,
728
                        ValueType value, cm::string_view fileSetType,
729
                        cm::string_view description,
730
                        FileSetType::Action action);
731
  cmValue GetFileSetDirectories(cmTarget const* self,
732
                                std::string const& fileSetName,
733
                                cm::string_view fileSetType) const;
734
  cmValue GetFileSetPaths(cmTarget const* self, std::string const& fileSetName,
735
                          cm::string_view fileSetType) const;
736
737
  cmListFileBacktrace GetBacktrace(
738
    cm::optional<cmListFileBacktrace> const& bt) const
739
155k
  {
740
155k
    return bt ? *bt : this->Makefile->GetBacktrace();
741
155k
  }
742
};
743
744
cmTargetInternals::cmTargetInternals(std::string name, cm::TargetType type,
745
                                     cmTarget::Visibility visibility,
746
                                     cmMakefile* mf,
747
                                     cmTarget::PerConfig perConfig)
748
84.9k
  : TargetType(type)
749
84.9k
  , Makefile(mf)
750
84.9k
  , Name(std::move(name))
751
84.9k
  , PerConfig(perConfig == cmTarget::PerConfig::Yes)
752
84.9k
  , TargetVisibility(visibility)
753
84.9k
  , IncludeDirectories("INCLUDE_DIRECTORIES"_s)
754
84.9k
  , CompileOptions("COMPILE_OPTIONS"_s)
755
84.9k
  , CompileFeatures("COMPILE_FEATURES"_s)
756
84.9k
  , CompileDefinitions("COMPILE_DEFINITIONS"_s)
757
84.9k
  , CompileWrappers("COMPILE_WRAPPERS"_s)
758
84.9k
  , PrecompileHeaders("PRECOMPILE_HEADERS"_s)
759
84.9k
  , Sources("SOURCES"_s, UsageRequirementProperty::AppendEmpty::Yes)
760
84.9k
  , LinkOptions("LINK_OPTIONS"_s)
761
84.9k
  , LinkDirectories("LINK_DIRECTORIES"_s)
762
84.9k
  , LinkLibraries("LINK_LIBRARIES"_s)
763
84.9k
  , LinkWrappers("LINK_WRAPPERS"_s)
764
84.9k
  , InterfaceCompileWrappers("INTERFACE_COMPILE_WRAPPERS"_s)
765
84.9k
  , InterfaceLinkLibraries("INTERFACE_LINK_LIBRARIES"_s)
766
84.9k
  , InterfaceLinkLibrariesDirect("INTERFACE_LINK_LIBRARIES_DIRECT"_s)
767
84.9k
  , InterfaceLinkLibrariesDirectExclude(
768
84.9k
      "INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE"_s)
769
84.9k
  , InterfaceLinkWrappers("INTERFACE_LINK_WRAPPERS"_s)
770
84.9k
  , ImportedCxxModulesIncludeDirectories(
771
84.9k
      "IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES"_s)
772
84.9k
  , ImportedCxxModulesCompileDefinitions(
773
84.9k
      "IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS"_s)
774
84.9k
  , ImportedCxxModulesCompileFeatures(
775
84.9k
      "IMPORTED_CXX_MODULES_COMPILE_FEATURES"_s)
776
84.9k
  , ImportedCxxModulesCompileOptions("IMPORTED_CXX_MODULES_COMPILE_OPTIONS"_s)
777
84.9k
  , ImportedCxxModulesLinkLibraries("IMPORTED_CXX_MODULES_LINK_LIBRARIES"_s)
778
84.9k
  , FileSetTypes{ { cm::FileSetMetadata::HEADERS,
779
84.9k
                    { cm::FileSetMetadata::HEADERS, "HEADER_DIRS"_s,
780
84.9k
                      "HEADER_SET"_s, "HEADER_DIRS_"_s, "HEADER_SET_"_s,
781
84.9k
                      "Header"_s, "The default header set"_s, "Header set"_s,
782
84.9k
                      FileSetEntries{ "HEADER_SETS"_s },
783
84.9k
                      FileSetEntries{ "INTERFACE_HEADER_SETS"_s } } },
784
84.9k
                  { cm::FileSetMetadata::SOURCES,
785
84.9k
                    { cm::FileSetMetadata::SOURCES, "SOURCE_DIRS"_s,
786
84.9k
                      "SOURCE_SET"_s, "SOURCE_DIRS_"_s, "SOURCE_SET_"_s,
787
84.9k
                      "Source"_s, "The default source set"_s, "Source set"_s,
788
84.9k
                      FileSetEntries{ "SOURCE_SETS"_s },
789
84.9k
                      FileSetEntries{ "INTERFACE_SOURCE_SETS"_s } } },
790
84.9k
                  { cm::FileSetMetadata::CXX_MODULES,
791
84.9k
                    { cm::FileSetMetadata::CXX_MODULES, "CXX_MODULE_DIRS"_s,
792
84.9k
                      "CXX_MODULE_SET"_s, "CXX_MODULE_DIRS_"_s,
793
84.9k
                      "CXX_MODULE_SET_"_s, "C++ module"_s,
794
84.9k
                      "The default C++ module set"_s, "C++ module set"_s,
795
84.9k
                      FileSetEntries{ "CXX_MODULE_SETS"_s },
796
84.9k
                      FileSetEntries{ "INTERFACE_CXX_MODULE_SETS"_s } } } }
797
84.9k
{
798
84.9k
  assert(mf);
799
800
  // Check whether this is a DLL platform.
801
84.9k
  this->IsDLLPlatform =
802
84.9k
    !mf->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX").empty();
803
804
  // Check whether we are targeting AIX.
805
84.9k
  {
806
84.9k
    std::string const& systemName = mf->GetSafeDefinition("CMAKE_SYSTEM_NAME");
807
84.9k
    this->IsAIX = (systemName == "AIX" || systemName == "OS400");
808
84.9k
  }
809
810
  // Check whether we are targeting Apple.
811
84.9k
  this->IsApple = mf->IsOn("APPLE");
812
813
  // Check whether we are targeting an Android platform.
814
84.9k
  this->IsAndroid = (mf->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "Android");
815
816
  // Save the backtrace of target construction.
817
84.9k
  this->Backtrace = mf->GetBacktrace();
818
84.9k
  if (this->IsImported()) {
819
49.3k
    this->FindPackageStack = mf->GetFindPackageStack();
820
49.3k
  }
821
84.9k
}
822
823
template <typename ValueType>
824
bool FileSetType::WriteProperties(cmTarget* tgt, cmTargetInternals* impl,
825
                                  std::string const& prop, ValueType value,
826
                                  Action action)
827
1.57M
{
828
1.57M
  if (prop == this->DefaultDirectoryProperty) {
829
0
    impl->AddDirectoryToFileSet(tgt, std::string(this->TypeName), value,
830
0
                                this->TypeName, this->DefaultDescription,
831
0
                                action);
832
0
    return true;
833
0
  }
834
1.57M
  if (prop == this->DefaultPathProperty) {
835
0
    impl->AddPathToFileSet(tgt, std::string(this->TypeName), value,
836
0
                           this->TypeName, this->DefaultDescription, action);
837
0
    return true;
838
0
  }
839
1.57M
  if (cmHasPrefix(prop, this->DirectoryPrefix)) {
840
0
    auto fileSetName = prop.substr(this->DirectoryPrefix.size());
841
0
    if (fileSetName.empty()) {
842
0
      impl->Makefile->IssueMessage(
843
0
        MessageType::FATAL_ERROR,
844
0
        cmStrCat(this->ArbitraryDescription, " name cannot be empty."));
845
0
    } else {
846
0
      impl->AddDirectoryToFileSet(
847
0
        tgt, fileSetName, value, this->TypeName,
848
0
        cmStrCat(this->ArbitraryDescription, " \"", fileSetName, '"'), action);
849
0
    }
850
0
    return true;
851
0
  }
852
1.57M
  if (cmHasPrefix(prop, this->PathPrefix)) {
853
0
    auto fileSetName = prop.substr(this->PathPrefix.size());
854
0
    if (fileSetName.empty()) {
855
0
      impl->Makefile->IssueMessage(
856
0
        MessageType::FATAL_ERROR,
857
0
        cmStrCat(this->ArbitraryDescription, " name cannot be empty."));
858
0
    } else {
859
0
      impl->AddPathToFileSet(
860
0
        tgt, fileSetName, value, this->TypeName,
861
0
        cmStrCat(this->ArbitraryDescription, " \"", fileSetName, '"'), action);
862
0
    }
863
0
    return true;
864
0
  }
865
1.57M
  return false;
866
1.57M
}
cmTarget.cxx:bool (anonymous namespace)::FileSetType::WriteProperties<cmValue>(cmTarget*, cmTargetInternals*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cmValue, (anonymous namespace)::FileSetType::Action)
Line
Count
Source
827
1.19M
{
828
1.19M
  if (prop == this->DefaultDirectoryProperty) {
829
0
    impl->AddDirectoryToFileSet(tgt, std::string(this->TypeName), value,
830
0
                                this->TypeName, this->DefaultDescription,
831
0
                                action);
832
0
    return true;
833
0
  }
834
1.19M
  if (prop == this->DefaultPathProperty) {
835
0
    impl->AddPathToFileSet(tgt, std::string(this->TypeName), value,
836
0
                           this->TypeName, this->DefaultDescription, action);
837
0
    return true;
838
0
  }
839
1.19M
  if (cmHasPrefix(prop, this->DirectoryPrefix)) {
840
0
    auto fileSetName = prop.substr(this->DirectoryPrefix.size());
841
0
    if (fileSetName.empty()) {
842
0
      impl->Makefile->IssueMessage(
843
0
        MessageType::FATAL_ERROR,
844
0
        cmStrCat(this->ArbitraryDescription, " name cannot be empty."));
845
0
    } else {
846
0
      impl->AddDirectoryToFileSet(
847
0
        tgt, fileSetName, value, this->TypeName,
848
0
        cmStrCat(this->ArbitraryDescription, " \"", fileSetName, '"'), action);
849
0
    }
850
0
    return true;
851
0
  }
852
1.19M
  if (cmHasPrefix(prop, this->PathPrefix)) {
853
0
    auto fileSetName = prop.substr(this->PathPrefix.size());
854
0
    if (fileSetName.empty()) {
855
0
      impl->Makefile->IssueMessage(
856
0
        MessageType::FATAL_ERROR,
857
0
        cmStrCat(this->ArbitraryDescription, " name cannot be empty."));
858
0
    } else {
859
0
      impl->AddPathToFileSet(
860
0
        tgt, fileSetName, value, this->TypeName,
861
0
        cmStrCat(this->ArbitraryDescription, " \"", fileSetName, '"'), action);
862
0
    }
863
0
    return true;
864
0
  }
865
1.19M
  return false;
866
1.19M
}
cmTarget.cxx:bool (anonymous namespace)::FileSetType::WriteProperties<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(cmTarget*, cmTargetInternals*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, (anonymous namespace)::FileSetType::Action)
Line
Count
Source
827
385k
{
828
385k
  if (prop == this->DefaultDirectoryProperty) {
829
0
    impl->AddDirectoryToFileSet(tgt, std::string(this->TypeName), value,
830
0
                                this->TypeName, this->DefaultDescription,
831
0
                                action);
832
0
    return true;
833
0
  }
834
385k
  if (prop == this->DefaultPathProperty) {
835
0
    impl->AddPathToFileSet(tgt, std::string(this->TypeName), value,
836
0
                           this->TypeName, this->DefaultDescription, action);
837
0
    return true;
838
0
  }
839
385k
  if (cmHasPrefix(prop, this->DirectoryPrefix)) {
840
0
    auto fileSetName = prop.substr(this->DirectoryPrefix.size());
841
0
    if (fileSetName.empty()) {
842
0
      impl->Makefile->IssueMessage(
843
0
        MessageType::FATAL_ERROR,
844
0
        cmStrCat(this->ArbitraryDescription, " name cannot be empty."));
845
0
    } else {
846
0
      impl->AddDirectoryToFileSet(
847
0
        tgt, fileSetName, value, this->TypeName,
848
0
        cmStrCat(this->ArbitraryDescription, " \"", fileSetName, '"'), action);
849
0
    }
850
0
    return true;
851
0
  }
852
385k
  if (cmHasPrefix(prop, this->PathPrefix)) {
853
0
    auto fileSetName = prop.substr(this->PathPrefix.size());
854
0
    if (fileSetName.empty()) {
855
0
      impl->Makefile->IssueMessage(
856
0
        MessageType::FATAL_ERROR,
857
0
        cmStrCat(this->ArbitraryDescription, " name cannot be empty."));
858
0
    } else {
859
0
      impl->AddPathToFileSet(
860
0
        tgt, fileSetName, value, this->TypeName,
861
0
        cmStrCat(this->ArbitraryDescription, " \"", fileSetName, '"'), action);
862
0
    }
863
0
    return true;
864
0
  }
865
385k
  return false;
866
385k
}
867
868
std::pair<bool, cmValue> FileSetType::ReadProperties(
869
  cmTarget const* tgt, cmTargetInternals const* impl,
870
  std::string const& prop) const
871
955k
{
872
955k
  bool did_read = false;
873
955k
  cmValue value = nullptr;
874
955k
  if (prop == this->DefaultDirectoryProperty) {
875
0
    value = impl->GetFileSetDirectories(tgt, std::string(this->TypeName),
876
0
                                        this->TypeName);
877
0
    did_read = true;
878
955k
  } else if (prop == this->DefaultPathProperty) {
879
0
    value =
880
0
      impl->GetFileSetPaths(tgt, std::string(this->TypeName), this->TypeName);
881
0
    did_read = true;
882
955k
  } else if (prop == this->SelfEntries.PropertyName) {
883
0
    static std::string output;
884
0
    output = cmList::to_string(this->SelfEntries.Entries);
885
0
    value = cmValue(output);
886
0
    did_read = true;
887
955k
  } else if (prop == this->InterfaceEntries.PropertyName) {
888
0
    static std::string output;
889
0
    output = cmList::to_string(this->InterfaceEntries.Entries);
890
0
    value = cmValue(output);
891
0
    did_read = true;
892
955k
  } else if (cmHasPrefix(prop, this->DirectoryPrefix)) {
893
1
    std::string fileSetName = prop.substr(this->DirectoryPrefix.size());
894
1
    if (!fileSetName.empty()) {
895
1
      value = impl->GetFileSetDirectories(tgt, fileSetName, this->TypeName);
896
1
    }
897
1
    did_read = true;
898
955k
  } else if (cmHasPrefix(prop, this->PathPrefix)) {
899
0
    std::string fileSetName = prop.substr(this->PathPrefix.size());
900
0
    if (!fileSetName.empty()) {
901
0
      value = impl->GetFileSetPaths(tgt, fileSetName, this->TypeName);
902
0
    }
903
0
    did_read = true;
904
0
  }
905
955k
  return { did_read, value };
906
955k
}
907
908
void FileSetType::AddFileSet(std::string const& name,
909
                             cm::FileSetMetadata::Visibility vis,
910
                             cmListFileBacktrace bt)
911
6.93k
{
912
6.93k
  if (cm::FileSetMetadata::VisibilityIsForSelf(vis)) {
913
0
    this->SelfEntries.Entries.emplace_back(name, bt);
914
0
  }
915
6.93k
  if (cm::FileSetMetadata::VisibilityIsForInterface(vis)) {
916
6.93k
    this->InterfaceEntries.Entries.emplace_back(name, std::move(bt));
917
6.93k
  }
918
6.93k
}
919
920
cmPropertyMap FileSetType::GetProperties(cmTarget const* tgt,
921
                                         cmTargetInternals const* impl) const
922
0
{
923
0
  std::set<std::string> propNames{ std::string(this->DefaultDirectoryProperty),
924
0
                                   std::string(this->DefaultPathProperty),
925
0
                                   std::string(this->SelfEntries.PropertyName),
926
0
                                   std::string(
927
0
                                     this->InterfaceEntries.PropertyName) };
928
929
0
  for (auto const& entry : this->SelfEntries.Entries) {
930
0
    std::string directoryPropertyName =
931
0
      cmStrCat(this->DirectoryPrefix, entry.Value);
932
0
    std::string pathPropertyName = cmStrCat(this->PathPrefix, entry.Value);
933
0
    propNames.emplace(directoryPropertyName);
934
0
    propNames.emplace(pathPropertyName);
935
0
  }
936
937
0
  for (auto const& entry : this->InterfaceEntries.Entries) {
938
0
    std::string directoryPropertyName =
939
0
      cmStrCat(this->DirectoryPrefix, entry.Value);
940
0
    std::string pathPropertyName = cmStrCat(this->PathPrefix, entry.Value);
941
0
    propNames.emplace(directoryPropertyName);
942
0
    propNames.emplace(pathPropertyName);
943
0
  }
944
945
0
  cmPropertyMap propertyMap;
946
947
0
  for (std::string const& prop : propNames) {
948
0
    auto value = this->ReadProperties(tgt, impl, prop);
949
0
    if (value.first) {
950
0
      propertyMap.SetProperty(prop, value.second);
951
0
    }
952
0
  }
953
954
0
  return propertyMap;
955
0
}
956
957
void FileSetRule::AddFileSet(std::string const& name,
958
                             cm::FileSetMetadata::Visibility vis,
959
                             cmListFileBacktrace bt)
960
0
{
961
0
  if (cm::FileSetMetadata::VisibilityIsForSelf(vis)) {
962
0
    this->SelfEntries.emplace_back(name, bt);
963
0
  }
964
0
  if (cm::FileSetMetadata::VisibilityIsForInterface(vis)) {
965
0
    this->InterfaceEntries.emplace_back(name, std::move(bt));
966
0
  }
967
0
}
968
969
template <typename ValueType>
970
bool UsageRequirementProperty::Write(
971
  cmTargetInternals const* impl, cm::optional<cmListFileBacktrace> const& bt,
972
  std::string const& prop, ValueType value, Action action)
973
12.5M
{
974
12.5M
  if (prop == this->Name) {
975
131k
    this->WriteDirect(impl, bt, value, action);
976
131k
    return true;
977
131k
  }
978
12.4M
  return false;
979
12.5M
}
980
981
template <typename ValueType>
982
void UsageRequirementProperty::WriteDirect(
983
  cmTargetInternals const* impl, cm::optional<cmListFileBacktrace> const& bt,
984
  ValueType value, Action action)
985
155k
{
986
155k
  if (action == Action::Set) {
987
15.1k
    this->Entries.clear();
988
15.1k
  }
989
155k
  if (value) {
990
155k
    cmListFileBacktrace lfbt = impl->GetBacktrace(bt);
991
155k
    if (action == Action::Prepend) {
992
0
      this->Entries.emplace(this->Entries.begin(), value, lfbt);
993
155k
    } else if (action == Action::Set || cmNonempty(value) ||
994
154k
               this->AppendBehavior == AppendEmpty::Yes) {
995
154k
      this->Entries.emplace_back(value, lfbt);
996
154k
    }
997
155k
  }
998
155k
}
999
1000
void UsageRequirementProperty::WriteDirect(BT<std::string> value,
1001
                                           Action action)
1002
0
{
1003
0
  if (action == Action::Set) {
1004
0
    this->Entries.clear();
1005
0
  }
1006
0
  if (action == Action::Prepend) {
1007
0
    this->Entries.emplace(this->Entries.begin(), std::move(value));
1008
0
  } else {
1009
0
    this->Entries.emplace_back(std::move(value));
1010
0
  }
1011
0
}
1012
1013
std::pair<bool, cmValue> UsageRequirementProperty::Read(
1014
  std::string const& prop) const
1015
159k
{
1016
159k
  bool did_read = false;
1017
159k
  cmValue value = nullptr;
1018
159k
  if (prop == this->Name) {
1019
37.0k
    if (!this->Entries.empty()) {
1020
      // Storage to back the returned `cmValue`.
1021
9.26k
      static std::string output;
1022
9.26k
      output = cmList::to_string(this->Entries);
1023
9.26k
      value = cmValue(output);
1024
9.26k
    }
1025
37.0k
    did_read = true;
1026
37.0k
  }
1027
159k
  return { did_read, value };
1028
159k
}
1029
1030
cmTarget::cmTarget(std::string name, cm::TargetType type, Visibility vis,
1031
                   cmMakefile* mf, PerConfig perConfig)
1032
84.9k
  : impl(cm::make_unique<cmTargetInternals>(std::move(name), type, vis, mf,
1033
84.9k
                                            perConfig))
1034
84.9k
{
1035
84.9k
  if (this->IsNormal()) {
1036
    // Initialize the INCLUDE_DIRECTORIES property based on the current value
1037
    // of the same directory property:
1038
35.5k
    this->impl->IncludeDirectories.CopyFromEntries(
1039
35.5k
      this->impl->Makefile->GetIncludeDirectoriesEntries());
1040
1041
35.5k
    {
1042
35.5k
      auto const& sysInc = this->impl->Makefile->GetSystemIncludeDirectories();
1043
35.5k
      this->impl->SystemIncludeDirectories.insert(sysInc.begin(),
1044
35.5k
                                                  sysInc.end());
1045
35.5k
    }
1046
1047
35.5k
    this->impl->CompileOptions.CopyFromEntries(
1048
35.5k
      this->impl->Makefile->GetCompileOptionsEntries());
1049
35.5k
    this->impl->LinkOptions.CopyFromEntries(
1050
35.5k
      this->impl->Makefile->GetLinkOptionsEntries());
1051
35.5k
    this->impl->LinkDirectories.CopyFromEntries(
1052
35.5k
      this->impl->Makefile->GetLinkDirectoriesEntries());
1053
35.5k
  }
1054
1055
  // Record current policies for later use.
1056
84.9k
  this->impl->Makefile->RecordPolicies(this->impl->PolicyMap);
1057
1058
84.9k
  std::set<TargetProperty::InitCondition> metConditions;
1059
84.9k
  metConditions.insert(TargetProperty::InitCondition::Always);
1060
84.9k
  if (this->CanCompileSources()) {
1061
17.7k
    metConditions.insert(TargetProperty::InitCondition::CanCompileSources);
1062
17.7k
  }
1063
84.9k
  if (this->GetGlobalGenerator()->IsXcode()) {
1064
0
    metConditions.insert(TargetProperty::InitCondition::NeedsXcode);
1065
0
    if (this->CanCompileSources()) {
1066
0
      metConditions.insert(
1067
0
        TargetProperty::InitCondition::NeedsXcodeAndCanCompileSources);
1068
0
    }
1069
0
  }
1070
84.9k
  if (!this->IsImported()) {
1071
35.5k
    metConditions.insert(TargetProperty::InitCondition::NonImportedTarget);
1072
35.5k
  }
1073
84.9k
  if (this->impl->TargetType != cm::TargetType::UTILITY &&
1074
79.0k
      this->impl->TargetType != cm::TargetType::GLOBAL_TARGET) {
1075
79.0k
    metConditions.insert(TargetProperty::InitCondition::NormalTarget);
1076
79.0k
    if (this->IsNormal()) {
1077
29.6k
      metConditions.insert(
1078
29.6k
        TargetProperty::InitCondition::NormalNonImportedTarget);
1079
29.6k
    }
1080
79.0k
    if (this->impl->TargetType != cm::TargetType::INTERFACE_LIBRARY) {
1081
57.9k
      metConditions.insert(TargetProperty::InitCondition::TargetWithArtifact);
1082
57.9k
      if (this->impl->TargetType != cm::TargetType::EXECUTABLE) {
1083
46.0k
        metConditions.insert(
1084
46.0k
          TargetProperty::InitCondition::NonExecutableWithArtifact);
1085
46.0k
      }
1086
57.9k
    }
1087
79.0k
    if (this->impl->TargetType == cm::TargetType::SHARED_LIBRARY ||
1088
66.4k
        this->impl->TargetType == cm::TargetType::STATIC_LIBRARY) {
1089
40.0k
      metConditions.insert(
1090
40.0k
        TargetProperty::InitCondition::LinkableLibraryTarget);
1091
40.0k
    }
1092
79.0k
    if (this->impl->TargetType == cm::TargetType::SHARED_LIBRARY) {
1093
12.5k
      metConditions.insert(TargetProperty::InitCondition::SharedLibraryTarget);
1094
12.5k
    }
1095
79.0k
  }
1096
84.9k
  if (this->impl->TargetType == cm::TargetType::EXECUTABLE) {
1097
11.9k
    metConditions.insert(TargetProperty::InitCondition::ExecutableTarget);
1098
11.9k
  }
1099
84.9k
  if (this->impl->TargetType == cm::TargetType::SHARED_LIBRARY ||
1100
72.3k
      this->impl->TargetType == cm::TargetType::EXECUTABLE) {
1101
24.5k
    metConditions.insert(
1102
24.5k
      TargetProperty::InitCondition::TargetWithSymbolExports);
1103
24.5k
  }
1104
84.9k
  if (this->impl->TargetType <= cm::TargetType::GLOBAL_TARGET) {
1105
63.9k
    metConditions.insert(TargetProperty::InitCondition::TargetWithCommands);
1106
63.9k
  }
1107
1108
84.9k
  std::vector<std::string> configNames =
1109
84.9k
    mf->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
1110
84.9k
  for (auto& config : configNames) {
1111
53.3k
    config = cmSystemTools::UpperCase(config);
1112
53.3k
  }
1113
1114
84.9k
  std::string defKey;
1115
84.9k
  defKey.reserve(128);
1116
84.9k
  defKey += "CMAKE_";
1117
84.9k
  auto initProperty = [this, mf, &defKey](std::string const& property,
1118
4.34M
                                          char const* default_value) {
1119
    // special init for ENABLE_EXPORTS
1120
    // For SHARED_LIBRARY, only CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS variable
1121
    // is used
1122
    // For EXECUTABLE, CMAKE_EXECUTABLE_ENABLE_EXPORTS or else
1123
    // CMAKE_ENABLE_EXPORTS variables are used
1124
4.34M
    if (property == "ENABLE_EXPORTS"_s) {
1125
      // Replace everything after "CMAKE_"
1126
24.5k
      defKey.replace(
1127
24.5k
        defKey.begin() + 6, defKey.end(),
1128
24.5k
        cmStrCat(this->impl->TargetType == cm::TargetType::EXECUTABLE
1129
24.5k
                   ? "EXECUTABLE"
1130
24.5k
                   : "SHARED_LIBRARY",
1131
24.5k
                 '_', property));
1132
24.5k
      if (cmValue value = mf->GetDefinition(defKey)) {
1133
0
        this->SetProperty(property, value);
1134
0
        return;
1135
0
      }
1136
24.5k
      if (this->impl->TargetType == cm::TargetType::SHARED_LIBRARY) {
1137
12.5k
        if (default_value) {
1138
0
          this->SetProperty(property, default_value);
1139
0
        }
1140
12.5k
        return;
1141
12.5k
      }
1142
24.5k
    }
1143
1144
    // Imported targets must set AIX_SHARED_LIBRARY_ARCHIVE explicitly.
1145
4.32M
    if (this->IsImported() && property == "AIX_SHARED_LIBRARY_ARCHIVE"_s) {
1146
12.5k
      return;
1147
12.5k
    }
1148
1149
    // Replace everything after "CMAKE_"
1150
4.31M
    defKey.replace(defKey.begin() + 6, defKey.end(), property);
1151
4.31M
    if (cmValue value = mf->GetDefinition(defKey)) {
1152
0
      this->SetProperty(property, value);
1153
4.31M
    } else if (default_value) {
1154
160k
      this->SetProperty(property, default_value);
1155
160k
    }
1156
4.31M
  };
1157
1158
84.9k
  std::string dflt_storage;
1159
18.3M
  for (auto const& tp : StaticTargetProperties) {
1160
    // Ignore properties that we have not met the condition for.
1161
18.3M
    if (!metConditions.count(tp.InitConditional)) {
1162
13.7M
      continue;
1163
13.7M
    }
1164
1165
4.55M
    char const* dflt = nullptr;
1166
4.55M
    if (tp.Default) {
1167
160k
      dflt_storage = std::string(*tp.Default);
1168
160k
      dflt = dflt_storage.c_str();
1169
160k
    }
1170
1171
4.55M
    if (tp.Repeat == TargetProperty::Repetition::Once) {
1172
4.04M
      initProperty(std::string(tp.Name), dflt);
1173
4.04M
    } else {
1174
513k
      std::string propertyName;
1175
513k
      for (auto const& configName : configNames) {
1176
302k
        if (tp.Repeat == TargetProperty::Repetition::PerConfig) {
1177
278k
          propertyName = cmStrCat(tp.Name, configName);
1178
278k
        } else if (tp.Repeat == TargetProperty::Repetition::PerConfigPrefix) {
1179
23.7k
          propertyName = cmStrCat(configName, tp.Name);
1180
23.7k
        }
1181
302k
        initProperty(propertyName, dflt);
1182
302k
      }
1183
513k
    }
1184
4.55M
  }
1185
1186
  // Clean up some property defaults.
1187
84.9k
  if (this->impl->TargetType == cm::TargetType::SHARED_LIBRARY ||
1188
72.3k
      this->impl->TargetType == cm::TargetType::MODULE_LIBRARY) {
1189
12.6k
    this->SetProperty("POSITION_INDEPENDENT_CODE", "True");
1190
12.6k
  }
1191
1192
  // check for "CMAKE_VS_GLOBALS" variable and set up target properties
1193
  // if any
1194
84.9k
  cmValue globals = mf->GetDefinition("CMAKE_VS_GLOBALS");
1195
84.9k
  if (globals) {
1196
0
    std::string const genName = mf->GetGlobalGenerator()->GetName();
1197
0
    if (cmHasLiteralPrefix(genName, "Visual Studio")) {
1198
0
      cmList props{ *globals };
1199
0
      std::string const vsGlobal = "VS_GLOBAL_";
1200
0
      for (std::string const& i : props) {
1201
        // split NAME=VALUE
1202
0
        std::string::size_type const assignment = i.find('=');
1203
0
        if (assignment != std::string::npos) {
1204
0
          std::string const propName = vsGlobal + i.substr(0, assignment);
1205
0
          std::string const propValue = i.substr(assignment + 1);
1206
0
          initProperty(propName, propValue.c_str());
1207
0
        }
1208
0
      }
1209
0
    }
1210
0
  }
1211
1212
84.9k
  if (!this->IsNormal() || mf->GetPropertyAsBool("SYSTEM")) {
1213
49.3k
    this->SetProperty("SYSTEM", "ON");
1214
49.3k
  }
1215
1216
84.9k
  for (auto const& prop : mf->GetState()->GetPropertyDefinitions().GetMap()) {
1217
0
    auto iter = prop.second.find(cmProperty::TARGET);
1218
0
    if (iter != prop.second.end()) {
1219
0
      if (!iter->second.GetInitializeFromVariable().empty()) {
1220
0
        if (auto value =
1221
0
              mf->GetDefinition(iter->second.GetInitializeFromVariable())) {
1222
0
          this->SetProperty(prop.first, value);
1223
0
        }
1224
0
      }
1225
0
    }
1226
0
  }
1227
84.9k
}
1228
1229
35.5k
cmTarget::cmTarget(cmTarget&&) noexcept = default;
1230
120k
cmTarget::~cmTarget() = default;
1231
1232
0
cmTarget& cmTarget::operator=(cmTarget&&) noexcept = default;
1233
1234
cm::TargetType cmTarget::GetType() const
1235
1.13M
{
1236
1.13M
  return this->impl->TargetType;
1237
1.13M
}
1238
1239
void cmTarget::SetOrigin(Origin origin)
1240
31.5k
{
1241
31.5k
  assert(origin != cmTarget::Origin::Unknown);
1242
31.5k
  assert(this->impl->Origin == cmTarget::Origin::Unknown);
1243
31.5k
  this->impl->Origin = origin;
1244
31.5k
}
1245
1246
cmTarget::Origin cmTarget::GetOrigin() const
1247
8
{
1248
8
  return this->impl->Origin;
1249
8
}
1250
1251
cmMakefile* cmTarget::GetMakefile() const
1252
85.3k
{
1253
85.3k
  return this->impl->Makefile;
1254
85.3k
}
1255
1256
cmPolicies::PolicyMap const& cmTarget::GetPolicyMap() const
1257
53.3k
{
1258
53.3k
  return this->impl->PolicyMap;
1259
53.3k
}
1260
1261
std::string const& cmTarget::GetName() const
1262
363k
{
1263
363k
  return this->impl->Name;
1264
363k
}
1265
1266
std::string const& cmTarget::GetTemplateName() const
1267
0
{
1268
0
  if (this->impl->TemplateTarget) {
1269
0
    return this->impl->TemplateTarget->GetTemplateName();
1270
0
  }
1271
0
  return this->impl->Name;
1272
0
}
1273
1274
cmPolicies::PolicyStatus cmTarget::GetPolicyStatus(
1275
  cmPolicies::PolicyID policy) const
1276
15.3k
{
1277
15.3k
  return this->impl->PolicyMap.Get(policy);
1278
15.3k
}
1279
1280
cmGlobalGenerator* cmTarget::GetGlobalGenerator() const
1281
84.9k
{
1282
84.9k
  return this->impl->Makefile->GetGlobalGenerator();
1283
84.9k
}
1284
1285
bool cmTarget::CxxModuleNeedsInterfaceObjects() const
1286
0
{
1287
0
  return this->impl->CxxModuleNeedsInterfaceObjects;
1288
0
}
1289
1290
void cmTarget::SetCxxModuleNeedsInterfaceObjects(bool v)
1291
0
{
1292
0
  this->impl->CxxModuleNeedsInterfaceObjects = v;
1293
0
}
1294
1295
void cmTarget::AddCxxModuleSynthCompileOption(BT<std::string> option)
1296
0
{
1297
0
  this->impl->CxxModuleSynthCompileOptions.push_back(std::move(option));
1298
0
}
1299
1300
cmBTStringRange cmTarget::GetCxxModuleSynthCompileOptions() const
1301
0
{
1302
0
  return cmMakeRange(this->impl->CxxModuleSynthCompileOptions);
1303
0
}
1304
1305
BTs<std::string> const* cmTarget::GetLanguageStandardProperty(
1306
  std::string const& propertyName) const
1307
12
{
1308
12
  auto entry = this->impl->LanguageStandardProperties.find(propertyName);
1309
12
  if (entry != this->impl->LanguageStandardProperties.end()) {
1310
0
    return &entry->second;
1311
0
  }
1312
1313
12
  return nullptr;
1314
12
}
1315
1316
void cmTarget::SetLanguageStandardProperty(std::string const& lang,
1317
                                           std::string const& value,
1318
                                           std::string const& feature)
1319
0
{
1320
0
  cmListFileBacktrace featureBacktrace;
1321
0
  for (auto const& entry : this->impl->CompileFeatures.Entries) {
1322
0
    if (entry.Value == feature) {
1323
0
      featureBacktrace = entry.Backtrace;
1324
0
      break;
1325
0
    }
1326
0
  }
1327
1328
0
  BTs<std::string>& languageStandardProperty =
1329
0
    this->impl->LanguageStandardProperties
1330
0
      [cmStandardLevelResolver::GetStandardPropertyName(lang)];
1331
0
  if (languageStandardProperty.Value != value) {
1332
0
    languageStandardProperty.Value = value;
1333
0
    languageStandardProperty.Backtraces.clear();
1334
0
  }
1335
0
  languageStandardProperty.Backtraces.emplace_back(featureBacktrace);
1336
0
}
1337
1338
void cmTarget::AddUtility(std::string const& name, bool cross,
1339
                          cmMakefile const* mf)
1340
0
{
1341
0
  this->impl->Utilities.insert(BT<std::pair<std::string, bool>>(
1342
0
    { name, cross }, mf ? mf->GetBacktrace() : cmListFileBacktrace()));
1343
0
}
1344
1345
void cmTarget::AddUtility(BT<std::pair<std::string, bool>> util)
1346
0
{
1347
0
  this->impl->Utilities.emplace(std::move(util));
1348
0
}
1349
1350
void cmTarget::AddCodegenDependency(std::string const& name)
1351
0
{
1352
0
  this->impl->CodegenDependencies.emplace(name);
1353
0
}
1354
1355
std::set<std::string> const& cmTarget::GetCodegenDeps() const
1356
0
{
1357
0
  return this->impl->CodegenDependencies;
1358
0
}
1359
1360
std::set<BT<std::pair<std::string, bool>>> const& cmTarget::GetUtilities()
1361
  const
1362
0
{
1363
0
  return this->impl->Utilities;
1364
0
}
1365
1366
cmListFileBacktrace const& cmTarget::GetBacktrace() const
1367
8.53k
{
1368
8.53k
  return this->impl->Backtrace;
1369
8.53k
}
1370
1371
cmFindPackageStack const& cmTarget::GetFindPackageStack() const
1372
0
{
1373
0
  return this->impl->FindPackageStack;
1374
0
}
1375
1376
bool cmTarget::IsExecutableWithExports() const
1377
2.66k
{
1378
2.66k
  return (this->GetType() == cm::TargetType::EXECUTABLE &&
1379
36
          this->GetPropertyAsBool("ENABLE_EXPORTS"));
1380
2.66k
}
1381
1382
bool cmTarget::IsSharedLibraryWithExports() const
1383
0
{
1384
0
  return (this->GetType() == cm::TargetType::SHARED_LIBRARY &&
1385
0
          this->GetPropertyAsBool("ENABLE_EXPORTS"));
1386
0
}
1387
1388
bool cmTarget::IsFrameworkOnApple() const
1389
64.5k
{
1390
64.5k
  return ((this->GetType() == cm::TargetType::SHARED_LIBRARY ||
1391
58.0k
           this->GetType() == cm::TargetType::STATIC_LIBRARY) &&
1392
22.3k
          this->IsApple() && this->GetPropertyAsBool("FRAMEWORK"));
1393
64.5k
}
1394
1395
bool cmTarget::IsArchivedAIXSharedLibrary() const
1396
3.08k
{
1397
3.08k
  if (this->GetType() == cm::TargetType::SHARED_LIBRARY && this->IsAIX()) {
1398
0
    cmValue value = this->GetProperty("AIX_SHARED_LIBRARY_ARCHIVE");
1399
0
    if (!value.IsEmpty()) {
1400
0
      return value.IsOn();
1401
0
    }
1402
0
    if (this->IsImported()) {
1403
0
      return false;
1404
0
    }
1405
0
    switch (this->GetPolicyStatusCMP0182()) {
1406
0
      case cmPolicies::WARN:
1407
0
      case cmPolicies::OLD:
1408
        // The OLD behavior's default is to disable shared library archives.
1409
0
        break;
1410
0
      case cmPolicies::NEW:
1411
        // The NEW behavior's default is to enable shared library archives.
1412
0
        return true;
1413
0
    }
1414
0
  }
1415
3.08k
  return false;
1416
3.08k
}
1417
1418
bool cmTarget::IsAppBundleOnApple() const
1419
2.81k
{
1420
2.81k
  return (this->GetType() == cm::TargetType::EXECUTABLE && this->IsApple() &&
1421
0
          this->GetPropertyAsBool("MACOSX_BUNDLE"));
1422
2.81k
}
1423
1424
bool cmTarget::IsAndroidGuiExecutable() const
1425
330
{
1426
330
  return (this->GetType() == cm::TargetType::EXECUTABLE &&
1427
330
          this->impl->IsAndroid && this->GetPropertyAsBool("ANDROID_GUI"));
1428
330
}
1429
1430
bool cmTarget::HasKnownObjectFileLocation(std::string* reason) const
1431
13
{
1432
13
  return this->GetGlobalGenerator()->HasKnownObjectFileLocation(*this, reason);
1433
13
}
1434
1435
std::vector<cmCustomCommand> const& cmTarget::GetPreBuildCommands() const
1436
0
{
1437
0
  return this->impl->PreBuildCommands;
1438
0
}
1439
1440
void cmTarget::AddPreBuildCommand(cmCustomCommand const& cmd)
1441
0
{
1442
0
  this->impl->PreBuildCommands.push_back(cmd);
1443
0
}
1444
1445
void cmTarget::AddPreBuildCommand(cmCustomCommand&& cmd)
1446
0
{
1447
0
  this->impl->PreBuildCommands.push_back(std::move(cmd));
1448
0
}
1449
1450
std::vector<cmCustomCommand> const& cmTarget::GetPreLinkCommands() const
1451
0
{
1452
0
  return this->impl->PreLinkCommands;
1453
0
}
1454
1455
void cmTarget::AddPreLinkCommand(cmCustomCommand const& cmd)
1456
0
{
1457
0
  this->impl->PreLinkCommands.push_back(cmd);
1458
0
}
1459
1460
void cmTarget::AddPreLinkCommand(cmCustomCommand&& cmd)
1461
0
{
1462
0
  this->impl->PreLinkCommands.push_back(std::move(cmd));
1463
0
}
1464
1465
std::vector<cmCustomCommand> const& cmTarget::GetPostBuildCommands() const
1466
0
{
1467
0
  return this->impl->PostBuildCommands;
1468
0
}
1469
1470
void cmTarget::AddPostBuildCommand(cmCustomCommand const& cmd)
1471
0
{
1472
0
  this->impl->PostBuildCommands.push_back(cmd);
1473
0
}
1474
1475
void cmTarget::AddPostBuildCommand(cmCustomCommand&& cmd)
1476
0
{
1477
0
  this->impl->PostBuildCommands.push_back(std::move(cmd));
1478
0
}
1479
1480
void cmTarget::AddTracedSources(std::vector<std::string> const& srcs)
1481
35.5k
{
1482
35.5k
  if (!srcs.empty()) {
1483
17.7k
    this->impl->Sources.WriteDirect(this->impl.get(), {},
1484
17.7k
                                    cmValue(cmJoin(srcs, ";")),
1485
17.7k
                                    UsageRequirementProperty::Action::Append);
1486
17.7k
  }
1487
35.5k
}
1488
1489
void cmTarget::AddSources(std::vector<std::string> const& srcs)
1490
35.5k
{
1491
35.5k
  std::vector<std::string> srcFiles;
1492
35.5k
  for (std::string const& filename : srcs) {
1493
23.7k
    if (!cmGeneratorExpression::StartsWithGeneratorExpression(filename)) {
1494
23.7k
      this->impl->Makefile->GetOrCreateSource(filename);
1495
23.7k
    }
1496
23.7k
    srcFiles.emplace_back(filename);
1497
23.7k
  }
1498
35.5k
  this->AddTracedSources(srcFiles);
1499
35.5k
}
1500
1501
struct CreateLocation
1502
{
1503
  cmMakefile const* Makefile;
1504
1505
  CreateLocation(cmMakefile const* mf)
1506
0
    : Makefile(mf)
1507
0
  {
1508
0
  }
1509
1510
  cmSourceFileLocation operator()(std::string const& filename) const
1511
0
  {
1512
0
    return cmSourceFileLocation(this->Makefile, filename);
1513
0
  }
1514
};
1515
1516
struct LocationMatcher
1517
{
1518
  cmSourceFileLocation const& Needle;
1519
1520
  LocationMatcher(cmSourceFileLocation const& needle)
1521
0
    : Needle(needle)
1522
0
  {
1523
0
  }
1524
1525
  bool operator()(cmSourceFileLocation& loc)
1526
0
  {
1527
0
    return loc.Matches(this->Needle);
1528
0
  }
1529
};
1530
1531
struct TargetPropertyEntryFinder
1532
{
1533
private:
1534
  cmSourceFileLocation const& Needle;
1535
1536
public:
1537
  TargetPropertyEntryFinder(cmSourceFileLocation const& needle)
1538
5.92k
    : Needle(needle)
1539
5.92k
  {
1540
5.92k
  }
1541
1542
  bool operator()(BT<std::string> const& entry)
1543
0
  {
1544
0
    cmList files{ entry.Value };
1545
0
    std::vector<cmSourceFileLocation> locations;
1546
0
    locations.reserve(files.size());
1547
0
    std::transform(files.begin(), files.end(), std::back_inserter(locations),
1548
0
                   CreateLocation(this->Needle.GetMakefile()));
1549
1550
0
    return std::find_if(locations.begin(), locations.end(),
1551
0
                        LocationMatcher(this->Needle)) != locations.end();
1552
0
  }
1553
};
1554
1555
cmSourceFile* cmTarget::AddSource(std::string const& src, bool before)
1556
5.92k
{
1557
5.92k
  cmSourceFileLocation sfl(this->impl->Makefile, src,
1558
5.92k
                           cmSourceFileLocationKind::Known);
1559
5.92k
  auto const& sources = this->impl->Sources.Entries;
1560
5.92k
  if (std::find_if(sources.begin(), sources.end(),
1561
5.92k
                   TargetPropertyEntryFinder(sfl)) == sources.end()) {
1562
5.92k
    this->impl->Sources.WriteDirect(
1563
5.92k
      this->impl.get(), {}, cmValue(src),
1564
5.92k
      before ? UsageRequirementProperty::Action::Prepend
1565
5.92k
             : UsageRequirementProperty::Action::Append);
1566
5.92k
  }
1567
5.92k
  if (cmGeneratorExpression::Find(src) != std::string::npos) {
1568
0
    return nullptr;
1569
0
  }
1570
5.92k
  return this->impl->Makefile->GetOrCreateSource(
1571
5.92k
    src, false, cmSourceFileLocationKind::Known);
1572
5.92k
}
1573
1574
void cmTarget::ClearDependencyInformation(cmMakefile& mf) const
1575
23.7k
{
1576
23.7k
  std::string depname = cmStrCat(this->GetName(), "_LIB_DEPENDS");
1577
23.7k
  mf.RemoveCacheDefinition(depname);
1578
23.7k
}
1579
1580
std::string cmTarget::GetDebugGeneratorExpressions(
1581
  std::string const& value, cmTargetLinkLibraryType llt) const
1582
59.2k
{
1583
59.2k
  if (llt == GENERAL_LibraryType) {
1584
59.2k
    return value;
1585
59.2k
  }
1586
1587
  // Get the list of configurations considered to be DEBUG.
1588
0
  std::vector<std::string> debugConfigs =
1589
0
    this->impl->Makefile->GetCMakeInstance()->GetDebugConfigs();
1590
1591
0
  std::string configString = cmStrCat("$<CONFIG:", debugConfigs[0], '>');
1592
1593
0
  if (debugConfigs.size() > 1) {
1594
0
    for (std::string const& conf : cmMakeRange(debugConfigs).advance(1)) {
1595
0
      configString =
1596
0
        cmStrCat(std::move(configString), ",$<CONFIG:", conf, '>');
1597
0
    }
1598
0
    configString = cmStrCat("$<OR:", std::move(configString), '>');
1599
0
  }
1600
1601
0
  if (llt == OPTIMIZED_LibraryType) {
1602
0
    configString = cmStrCat("$<NOT:", std::move(configString), '>');
1603
0
  }
1604
0
  return cmStrCat("$<", configString, ':', value, '>');
1605
59.2k
}
1606
1607
static std::string targetNameGenex(std::string const& lib)
1608
0
{
1609
0
  return cmStrCat("$<TARGET_NAME:", lib, '>');
1610
0
}
1611
1612
bool cmTarget::PushTLLCommandTrace(TLLSignature signature,
1613
                                   cmListFileContext const& lfc)
1614
41.4k
{
1615
41.4k
  bool ret = true;
1616
41.4k
  if (!this->impl->TLLCommands.empty()) {
1617
23.7k
    if (this->impl->TLLCommands.back().first != signature) {
1618
0
      ret = false;
1619
0
    }
1620
23.7k
  }
1621
41.4k
  if (this->impl->TLLCommands.empty() ||
1622
23.7k
      this->impl->TLLCommands.back().second != lfc) {
1623
17.7k
    this->impl->TLLCommands.emplace_back(signature, lfc);
1624
17.7k
  }
1625
41.4k
  return ret;
1626
41.4k
}
1627
1628
void cmTarget::GetTllSignatureTraces(std::ostream& s, TLLSignature sig) const
1629
0
{
1630
0
  char const* sigString =
1631
0
    (sig == cmTarget::KeywordTLLSignature ? "keyword" : "plain");
1632
0
  s << "The uses of the " << sigString << " signature are here:\n";
1633
0
  for (auto const& cmd : this->impl->TLLCommands) {
1634
0
    if (cmd.first == sig) {
1635
0
      cmListFileContext lfc = cmd.second;
1636
0
      lfc.FilePath = cmSystemTools::RelativeIfUnder(
1637
0
        this->impl->Makefile->GetState()->GetSourceDirectory(), lfc.FilePath);
1638
0
      s << " * " << lfc << '\n';
1639
0
    }
1640
0
  }
1641
0
}
1642
1643
std::string const& cmTarget::GetInstallPath() const
1644
0
{
1645
0
  return this->impl->InstallPath;
1646
0
}
1647
1648
void cmTarget::SetInstallPath(std::string const& name)
1649
0
{
1650
0
  this->impl->InstallPath = name;
1651
0
}
1652
1653
std::string const& cmTarget::GetRuntimeInstallPath() const
1654
0
{
1655
0
  return this->impl->RuntimeInstallPath;
1656
0
}
1657
1658
void cmTarget::SetRuntimeInstallPath(std::string const& name)
1659
0
{
1660
0
  this->impl->RuntimeInstallPath = name;
1661
0
}
1662
1663
bool cmTarget::GetHaveInstallRule() const
1664
0
{
1665
0
  return this->impl->HaveInstallRule;
1666
0
}
1667
1668
void cmTarget::SetHaveInstallRule(bool hir)
1669
0
{
1670
0
  this->impl->HaveInstallRule = hir;
1671
0
}
1672
1673
void cmTarget::AddInstallGenerator(cmInstallTargetGenerator* g)
1674
0
{
1675
0
  this->impl->InstallGenerators.emplace_back(g);
1676
0
}
1677
1678
std::vector<cmInstallTargetGenerator*> const& cmTarget::GetInstallGenerators()
1679
  const
1680
0
{
1681
0
  return this->impl->InstallGenerators;
1682
0
}
1683
1684
bool cmTarget::GetIsGeneratorProvided() const
1685
0
{
1686
0
  return this->impl->IsGeneratorProvided;
1687
0
}
1688
1689
void cmTarget::SetIsGeneratorProvided(bool igp)
1690
0
{
1691
0
  this->impl->IsGeneratorProvided = igp;
1692
0
}
1693
1694
cmTarget::LinkLibraryVectorType const& cmTarget::GetOriginalLinkLibraries()
1695
  const
1696
32.2k
{
1697
32.2k
  return this->impl->OriginalLinkLibraries;
1698
32.2k
}
1699
1700
void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib,
1701
                              cmTargetLinkLibraryType llt)
1702
23.7k
{
1703
23.7k
  cmTarget* tgt = mf.FindTargetToUse(lib);
1704
23.7k
  {
1705
23.7k
    bool const isNonImportedTarget = tgt && !tgt->IsImported();
1706
1707
23.7k
    std::string const libName =
1708
23.7k
      (isNonImportedTarget && llt != GENERAL_LibraryType)
1709
23.7k
      ? targetNameGenex(lib)
1710
23.7k
      : lib;
1711
23.7k
    this->AppendProperty("LINK_LIBRARIES",
1712
23.7k
                         this->GetDebugGeneratorExpressions(libName, llt),
1713
23.7k
                         mf.GetBacktrace());
1714
23.7k
  }
1715
1716
23.7k
  if (cmGeneratorExpression::Find(lib) != std::string::npos ||
1717
23.7k
      (tgt &&
1718
23.7k
       (tgt->GetType() == cm::TargetType::INTERFACE_LIBRARY ||
1719
17.7k
        tgt->GetType() == cm::TargetType::OBJECT_LIBRARY)) ||
1720
11.8k
      (this->impl->Name == lib)) {
1721
11.8k
    return;
1722
11.8k
  }
1723
1724
11.8k
  this->impl->OriginalLinkLibraries.emplace_back(lib, llt);
1725
1726
  // Add the explicit dependency information for libraries. This is
1727
  // simply a set of libraries separated by ";". There should always
1728
  // be a trailing ";". These library names are not canonical, in that
1729
  // they may be "-framework x", "-ly", "/path/libz.a", etc.
1730
  // We shouldn't remove duplicates here because external libraries
1731
  // may be purposefully duplicated to handle recursive dependencies,
1732
  // and we removing one instance will break the link line. Duplicates
1733
  // will be appropriately eliminated at emit time.
1734
11.8k
  if (this->impl->TargetType >= cm::TargetType::STATIC_LIBRARY &&
1735
5.92k
      this->impl->TargetType <= cm::TargetType::MODULE_LIBRARY &&
1736
5.92k
      (this->GetPolicyStatusCMP0073() == cmPolicies::OLD ||
1737
5.92k
       this->GetPolicyStatusCMP0073() == cmPolicies::WARN)) {
1738
0
    std::string targetEntry = cmStrCat(this->impl->Name, "_LIB_DEPENDS");
1739
0
    std::string dependencies;
1740
0
    cmValue old_val = mf.GetDefinition(targetEntry);
1741
0
    if (old_val) {
1742
0
      dependencies += *old_val;
1743
0
    }
1744
0
    switch (llt) {
1745
0
      case GENERAL_LibraryType:
1746
0
        dependencies += "general";
1747
0
        break;
1748
0
      case DEBUG_LibraryType:
1749
0
        dependencies += "debug";
1750
0
        break;
1751
0
      case OPTIMIZED_LibraryType:
1752
0
        dependencies += "optimized";
1753
0
        break;
1754
0
    }
1755
0
    dependencies += ";";
1756
0
    dependencies += lib;
1757
0
    dependencies += ";";
1758
0
    mf.AddCacheDefinition(targetEntry, dependencies,
1759
0
                          "Dependencies for the target", cmStateEnums::STATIC);
1760
0
  }
1761
11.8k
}
1762
1763
void cmTarget::AddSystemIncludeDirectories(std::set<std::string> const& incs)
1764
0
{
1765
0
  this->impl->SystemIncludeDirectories.insert(incs.begin(), incs.end());
1766
0
}
1767
1768
std::set<std::string> const& cmTarget::GetSystemIncludeDirectories() const
1769
0
{
1770
0
  return this->impl->SystemIncludeDirectories;
1771
0
}
1772
1773
void cmTarget::AddInstallIncludeDirectories(cmTargetExport const& te,
1774
                                            cmStringRange incs)
1775
0
{
1776
0
  std::copy(
1777
0
    incs.begin(), incs.end(),
1778
0
    std::back_inserter(this->impl->InstallIncludeDirectoriesEntries[&te]));
1779
0
}
1780
1781
cmStringRange cmTarget::GetInstallIncludeDirectoriesEntries(
1782
  cmTargetExport const& te) const
1783
0
{
1784
0
  auto i = this->impl->InstallIncludeDirectoriesEntries.find(&te);
1785
0
  if (i == this->impl->InstallIncludeDirectoriesEntries.end()) {
1786
0
    decltype(i->second) empty;
1787
0
    return cmMakeRange(empty);
1788
0
  }
1789
0
  return cmMakeRange(i->second);
1790
0
}
1791
1792
cmBTStringRange cmTarget::GetIncludeDirectoriesEntries() const
1793
53.3k
{
1794
53.3k
  return cmMakeRange(this->impl->IncludeDirectories.Entries);
1795
53.3k
}
1796
1797
cmBTStringRange cmTarget::GetCompileOptionsEntries() const
1798
53.3k
{
1799
53.3k
  return cmMakeRange(this->impl->CompileOptions.Entries);
1800
53.3k
}
1801
1802
cmBTStringRange cmTarget::GetImportedCxxModulesCompileOptionsEntries() const
1803
0
{
1804
0
  return cmMakeRange(this->impl->ImportedCxxModulesCompileOptions.Entries);
1805
0
}
1806
1807
cmBTStringRange cmTarget::GetCompileFeaturesEntries() const
1808
53.3k
{
1809
53.3k
  return cmMakeRange(this->impl->CompileFeatures.Entries);
1810
53.3k
}
1811
1812
cmBTStringRange cmTarget::GetImportedCxxModulesCompileFeaturesEntries() const
1813
0
{
1814
0
  return cmMakeRange(this->impl->ImportedCxxModulesCompileFeatures.Entries);
1815
0
}
1816
1817
cmBTStringRange cmTarget::GetCompileDefinitionsEntries() const
1818
53.3k
{
1819
53.3k
  return cmMakeRange(this->impl->CompileDefinitions.Entries);
1820
53.3k
}
1821
1822
cmBTStringRange cmTarget::GetCompileWrappersEntries() const
1823
53.3k
{
1824
53.3k
  return cmMakeRange(this->impl->CompileWrappers.Entries);
1825
53.3k
}
1826
1827
cmBTStringRange cmTarget::GetPrecompileHeadersEntries() const
1828
53.3k
{
1829
53.3k
  return cmMakeRange(this->impl->PrecompileHeaders.Entries);
1830
53.3k
}
1831
1832
cmBTStringRange cmTarget::GetSourceEntries() const
1833
53.3k
{
1834
53.3k
  return cmMakeRange(this->impl->Sources.Entries);
1835
53.3k
}
1836
1837
cmBTStringRange cmTarget::GetLinkOptionsEntries() const
1838
53.3k
{
1839
53.3k
  return cmMakeRange(this->impl->LinkOptions.Entries);
1840
53.3k
}
1841
1842
cmBTStringRange cmTarget::GetLinkWrappersEntries() const
1843
53.3k
{
1844
53.3k
  return cmMakeRange(this->impl->LinkWrappers.Entries);
1845
53.3k
}
1846
1847
cmBTStringRange cmTarget::GetLinkDirectoriesEntries() const
1848
53.3k
{
1849
53.3k
  return cmMakeRange(this->impl->LinkDirectories.Entries);
1850
53.3k
}
1851
1852
cmBTStringRange cmTarget::GetLinkImplementationEntries() const
1853
8.59k
{
1854
8.59k
  return cmMakeRange(this->impl->LinkLibraries.Entries);
1855
8.59k
}
1856
1857
cmBTStringRange cmTarget::GetLinkInterfaceEntries() const
1858
26.5k
{
1859
26.5k
  return cmMakeRange(this->impl->InterfaceLinkLibraries.Entries);
1860
26.5k
}
1861
1862
cmBTStringRange cmTarget::GetLinkInterfaceDirectEntries() const
1863
18.8k
{
1864
18.8k
  return cmMakeRange(this->impl->InterfaceLinkLibrariesDirect.Entries);
1865
18.8k
}
1866
1867
cmBTStringRange cmTarget::GetLinkInterfaceDirectExcludeEntries() const
1868
18.8k
{
1869
18.8k
  return cmMakeRange(this->impl->InterfaceLinkLibrariesDirectExclude.Entries);
1870
18.8k
}
1871
1872
void cmTarget::CopyUsageEffects(cmGeneratorTarget const* gt,
1873
                                std::string const& config)
1874
0
{
1875
  // Normal targets cannot be the target of a copy.
1876
0
  assert(!this->IsNormal());
1877
  // Imported targets cannot be the target of a copy.
1878
0
  assert(!this->IsImported());
1879
1880
0
  auto const* tgt = gt->Target;
1881
1882
  // Only imported or normal targets can be the source of a copy.
1883
0
  assert(tgt->IsImported() || tgt->IsNormal());
1884
1885
0
  this->impl->CompileFeatures.Entries.clear();
1886
0
  this->impl->CompileOptions.Entries.clear();
1887
1888
0
  if (tgt->IsImported()) {
1889
0
    this->impl->CompileFeatures.CopyFromEntries(
1890
0
      cmMakeRange(tgt->impl->ImportedCxxModulesCompileFeatures.Entries));
1891
0
    this->impl->CompileOptions.CopyFromEntries(
1892
0
      cmMakeRange(tgt->impl->ImportedCxxModulesCompileOptions.Entries));
1893
0
  } else {
1894
0
    this->impl->CompileFeatures.CopyFromEntries(
1895
0
      cmMakeRange(gt->GetCompileFeatures(config)));
1896
0
    this->impl->CompileOptions.CopyFromEntries(
1897
0
      cmMakeRange(gt->GetCompileOptions(config, "CXX")));
1898
0
  }
1899
1900
0
  cmValue langStd = gt->GetLanguageStandard("CXX", config);
1901
0
  if (langStd) {
1902
0
    this->SetProperty("CXX_STANDARD", *langStd);
1903
0
  }
1904
0
  copyProperty(tgt, this, "CXX_EXTENSIONS");
1905
0
  copyProperty(tgt, this, "CXX_STANDARD_REQUIRED");
1906
0
  this->SetProperty(
1907
0
    "MSVC_RUNTIME_LIBRARY",
1908
0
    gt->GetCxxModuleUsageEffects(config).GetMsvcRuntimeLibrary());
1909
0
}
1910
1911
void cmTarget::CopyPolicyStatuses(cmTarget const* tgt)
1912
0
{
1913
  // Normal targets cannot be the target of a copy.
1914
0
  assert(!this->IsNormal());
1915
  // Imported targets cannot be the target of a copy.
1916
0
  assert(!this->IsImported());
1917
1918
  // Only imported or normal targets can be the source of a copy.
1919
0
  assert(tgt->IsImported() || tgt->IsNormal());
1920
1921
0
  this->impl->PolicyMap = tgt->impl->PolicyMap;
1922
0
  this->impl->TemplateTarget = tgt;
1923
0
}
1924
1925
void cmTarget::CopyCxxModulesEntries(cmTarget const* tgt)
1926
0
{
1927
  // Normal targets cannot be the target of a copy.
1928
0
  assert(!this->IsNormal());
1929
  // Imported targets cannot be the target of a copy.
1930
0
  assert(!this->IsImported());
1931
  // Only imported or normal targets can be the source of a copy.
1932
0
  assert(tgt->IsImported() || tgt->IsNormal());
1933
1934
0
  this->impl->IncludeDirectories.Entries.clear();
1935
0
  this->impl->CompileDefinitions.Entries.clear();
1936
0
  this->impl->LinkLibraries.Entries.clear();
1937
1938
0
  if (tgt->IsImported()) {
1939
0
    this->impl->IncludeDirectories.CopyFromEntries(
1940
0
      cmMakeRange(tgt->impl->ImportedCxxModulesIncludeDirectories.Entries));
1941
0
    this->impl->CompileDefinitions.CopyFromEntries(
1942
0
      cmMakeRange(tgt->impl->ImportedCxxModulesCompileDefinitions.Entries));
1943
0
    this->impl->LinkLibraries.CopyFromEntries(
1944
0
      cmMakeRange(tgt->impl->ImportedCxxModulesLinkLibraries.Entries));
1945
0
  } else {
1946
0
    this->impl->IncludeDirectories.CopyFromEntries(
1947
0
      cmMakeRange(tgt->impl->IncludeDirectories.Entries));
1948
0
    this->impl->CompileDefinitions.CopyFromEntries(
1949
0
      cmMakeRange(tgt->impl->CompileDefinitions.Entries));
1950
0
    this->impl->LinkLibraries.CopyFromEntries(
1951
0
      cmMakeRange(tgt->impl->LinkLibraries.Entries));
1952
0
  }
1953
1954
  // Copy the C++ module fileset entries from `tgt`'s `INTERFACE` to this
1955
  // target's `PRIVATE`.
1956
0
  auto& entries = this->impl->FileSetTypes.at(cm::FileSetMetadata::CXX_MODULES)
1957
0
                    .SelfEntries.Entries;
1958
0
  entries.clear();
1959
0
  entries = tgt->impl->FileSetTypes.at(cm::FileSetMetadata::CXX_MODULES)
1960
0
              .InterfaceEntries.Entries;
1961
0
}
1962
1963
void cmTarget::CopyCxxModulesProperties(cmTarget const* tgt)
1964
0
{
1965
  // Normal targets cannot be the target of a copy.
1966
0
  assert(!this->IsNormal());
1967
  // Imported targets cannot be the target of a copy.
1968
0
  assert(!this->IsImported());
1969
  // Only imported or normal targets can be the source of a copy.
1970
0
  assert(tgt->IsImported() || tgt->IsNormal());
1971
1972
  // The list of properties that are relevant here include:
1973
  // - compilation-specific properties for any language or platform
1974
  // - compilation-specific properties for C++
1975
  // - build graph-specific properties that affect compilation
1976
  // - IDE metadata properties
1977
  // - static analysis properties
1978
1979
0
  static std::string const propertiesToCopy[] = {
1980
    // Compilation properties
1981
0
    "DEFINE_SYMBOL",
1982
0
    "DEPRECATION",
1983
0
    "NO_SYSTEM_FROM_IMPORTED",
1984
0
    "POSITION_INDEPENDENT_CODE",
1985
0
    "VISIBILITY_INLINES_HIDDEN",
1986
    // -- Platforms
1987
    // ---- Android
1988
0
    "ANDROID_API",
1989
0
    "ANDROID_API_MIN",
1990
0
    "ANDROID_ARCH",
1991
0
    "ANDROID_STL_TYPE",
1992
    // ---- macOS
1993
0
    "OSX_ARCHITECTURES",
1994
    // ---- Windows
1995
0
    "MSVC_DEBUG_INFORMATION_FORMAT",
1996
0
    "MSVC_RUNTIME_CHECKS",
1997
0
    "VS_PLATFORM_TOOLSET",
1998
    // ---- OpenWatcom
1999
0
    "WATCOM_RUNTIME_LIBRARY",
2000
    // -- Language
2001
    // ---- C++
2002
0
    "CXX_COMPILER_LAUNCHER",
2003
0
    "CXX_VISIBILITY_PRESET",
2004
2005
    // Static analysis
2006
0
    "CXX_CLANG_TIDY",
2007
0
    "CXX_CLANG_TIDY_EXPORT_FIXES_DIR",
2008
0
    "CXX_CPPLINT",
2009
0
    "CXX_CPPCHECK",
2010
0
    "CXX_ICSTAT",
2011
0
    "CXX_INCLUDE_WHAT_YOU_USE",
2012
0
    "CXX_PVS_STUDIO",
2013
0
    "SKIP_LINTING",
2014
2015
    // Build graph properties
2016
0
    "EXCLUDE_FROM_ALL",
2017
0
    "EXCLUDE_FROM_DEFAULT_BUILD",
2018
0
    "OPTIMIZE_DEPENDENCIES",
2019
    // -- Ninja
2020
0
    "JOB_POOL_COMPILE",
2021
    // -- Visual Studio
2022
0
    "VS_NO_COMPILE_BATCHING",
2023
0
    "VS_PROJECT_IMPORT",
2024
2025
    // Metadata
2026
0
    "EchoString",
2027
    // Do *not* copy this property; it should be re-initialized at synthesis
2028
    // time from the `CMAKE_EXPORT_BUILD_DATABASE` variable as `IMPORTED`
2029
    // targets ignore the property initialization.
2030
    // "EXPORT_BUILD_DATABASE",
2031
0
    "FOLDER",
2032
0
    "LABELS",
2033
0
    "PROJECT_LABEL",
2034
0
    "SYSTEM",
2035
0
  };
2036
2037
0
  for (auto const& prop : propertiesToCopy) {
2038
0
    copyProperty(tgt, this, prop);
2039
0
  }
2040
2041
  // Imported targets do not initialize this property.  Keep the synthetic
2042
  // target's initialization from CMAKE_EXPORT_COMPILE_COMMANDS instead.
2043
0
  if (!tgt->IsImported()) {
2044
0
    copyProperty(tgt, this, "EXPORT_COMPILE_COMMANDS");
2045
0
  }
2046
2047
0
  static cm::static_string_view const perConfigPropertiesToCopy[] = {
2048
0
    "EXCLUDE_FROM_DEFAULT_BUILD_"_s,
2049
0
    "IMPORTED_CXX_MODULES_"_s,
2050
0
    "MAP_IMPORTED_CONFIG_"_s,
2051
0
    "OSX_ARCHITECTURES_"_s,
2052
0
  };
2053
2054
0
  std::vector<std::string> configNames =
2055
0
    this->impl->Makefile->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
2056
0
  for (std::string const& configName : configNames) {
2057
0
    std::string configUpper = cmSystemTools::UpperCase(configName);
2058
0
    for (auto const& perConfigProp : perConfigPropertiesToCopy) {
2059
0
      copyProperty(tgt, this, cmStrCat(perConfigProp, configUpper));
2060
0
    }
2061
0
  }
2062
2063
0
  if (this->GetGlobalGenerator()->IsXcode()) {
2064
0
    cmValue xcodeGenerateScheme =
2065
0
      copyProperty(tgt, this, "XCODE_GENERATE_SCHEME");
2066
2067
    // TODO: Make sure these show up on the imported target in the first place
2068
    // XCODE_ATTRIBUTE_???
2069
2070
0
    if (xcodeGenerateScheme.IsOn()) {
2071
#ifdef __APPLE__
2072
      static std::string const xcodeSchemePropertiesToCopy[] = {
2073
        // FIXME: Do all of these apply? Do they matter?
2074
        "XCODE_SCHEME_ADDRESS_SANITIZER",
2075
        "XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN",
2076
        "XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER",
2077
        "XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS",
2078
        "XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE",
2079
        "XCODE_SCHEME_ENABLE_GPU_API_VALIDATION",
2080
        "XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION",
2081
        "XCODE_SCHEME_GUARD_MALLOC",
2082
        "XCODE_SCHEME_LAUNCH_CONFIGURATION",
2083
        "XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP",
2084
        "XCODE_SCHEME_MALLOC_GUARD_EDGES",
2085
        "XCODE_SCHEME_MALLOC_SCRIBBLE",
2086
        "XCODE_SCHEME_MALLOC_STACK",
2087
        "XCODE_SCHEME_THREAD_SANITIZER",
2088
        "XCODE_SCHEME_THREAD_SANITIZER_STOP",
2089
        "XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER",
2090
        "XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP",
2091
        "XCODE_SCHEME_ZOMBIE_OBJECTS",
2092
      };
2093
2094
      for (auto const& xcodeProperty : xcodeSchemePropertiesToCopy) {
2095
        copyProperty(tgt, this, xcodeProperty);
2096
      }
2097
#endif
2098
0
    }
2099
0
  }
2100
0
}
2101
2102
namespace {
2103
std::vector<BT<std::string>> EmptyEntries;
2104
}
2105
2106
cmBTStringRange cmTarget::GetFileSetsEntries(cm::string_view type) const
2107
77
{
2108
77
  if (cm::contains(this->impl->FileSetTypes, type)) {
2109
0
    return cmMakeRange(this->impl->FileSetTypes.at(type).SelfEntries.Entries);
2110
0
  }
2111
77
  auto strType = std::string{ type };
2112
77
  if (cm::contains(this->impl->FileSetRules, strType)) {
2113
0
    return cmMakeRange(this->impl->FileSetRules.at(strType).SelfEntries);
2114
0
  }
2115
77
  return cmMakeRange(EmptyEntries);
2116
77
}
2117
2118
cmBTStringRange cmTarget::GetInterfaceFileSetsEntries(
2119
  cm::string_view type) const
2120
0
{
2121
0
  if (cm::contains(this->impl->FileSetTypes, type)) {
2122
0
    return cmMakeRange(
2123
0
      this->impl->FileSetTypes.at(type).InterfaceEntries.Entries);
2124
0
  }
2125
0
  auto strType = std::string{ type };
2126
0
  if (cm::contains(this->impl->FileSetRules, strType)) {
2127
0
    return cmMakeRange(this->impl->FileSetRules.at(strType).InterfaceEntries);
2128
0
  }
2129
0
  return cmMakeRange(EmptyEntries);
2130
0
}
2131
2132
namespace {
2133
#define MAKE_PROP(PROP) const std::string prop##PROP = #PROP
2134
MAKE_PROP(C_STANDARD);
2135
MAKE_PROP(CXX_STANDARD);
2136
MAKE_PROP(CUDA_STANDARD);
2137
MAKE_PROP(HIP_STANDARD);
2138
MAKE_PROP(OBJC_STANDARD);
2139
MAKE_PROP(OBJCXX_STANDARD);
2140
MAKE_PROP(SYCL_CXX_STANDARD);
2141
MAKE_PROP(COMPILE_DEFINITIONS);
2142
MAKE_PROP(COMPILE_FEATURES);
2143
MAKE_PROP(COMPILE_OPTIONS);
2144
MAKE_PROP(COMPILE_WRAPPERS);
2145
MAKE_PROP(PRECOMPILE_HEADERS);
2146
MAKE_PROP(CUDA_CUBIN_COMPILATION);
2147
MAKE_PROP(CUDA_FATBIN_COMPILATION);
2148
MAKE_PROP(CUDA_OPTIX_COMPILATION);
2149
MAKE_PROP(CUDA_PTX_COMPILATION);
2150
MAKE_PROP(IMPORTED);
2151
MAKE_PROP(IMPORTED_GLOBAL);
2152
MAKE_PROP(INCLUDE_DIRECTORIES);
2153
MAKE_PROP(LINK_OPTIONS);
2154
MAKE_PROP(IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES);
2155
MAKE_PROP(IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS);
2156
MAKE_PROP(IMPORTED_CXX_MODULES_COMPILE_FEATURES);
2157
MAKE_PROP(IMPORTED_CXX_MODULES_COMPILE_OPTIONS);
2158
MAKE_PROP(IMPORTED_CXX_MODULES_LINK_LIBRARIES);
2159
MAKE_PROP(LINK_DIRECTORIES);
2160
MAKE_PROP(LINK_LIBRARIES);
2161
MAKE_PROP(LINK_WRAPPERS);
2162
MAKE_PROP(MANUALLY_ADDED_DEPENDENCIES);
2163
MAKE_PROP(NAME);
2164
MAKE_PROP(SOURCES);
2165
MAKE_PROP(SYMBOLIC);
2166
MAKE_PROP(TYPE);
2167
MAKE_PROP(BINARY_DIR);
2168
MAKE_PROP(SOURCE_DIR);
2169
MAKE_PROP(FALSE);
2170
MAKE_PROP(TRUE);
2171
MAKE_PROP(INTERFACE_COMPILE_WRAPPERS);
2172
MAKE_PROP(INTERFACE_LINK_LIBRARIES);
2173
MAKE_PROP(INTERFACE_LINK_LIBRARIES_DIRECT);
2174
MAKE_PROP(INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE);
2175
MAKE_PROP(INTERFACE_LINK_WRAPPERS);
2176
#undef MAKE_PROP
2177
}
2178
2179
namespace {
2180
2181
enum class ReadOnlyCondition
2182
{
2183
  All,
2184
  Imported,
2185
  NonImported,
2186
};
2187
2188
struct ReadOnlyProperty
2189
{
2190
  ReadOnlyProperty(ReadOnlyCondition cond)
2191
39
    : Condition{ cond }
2192
39
  {
2193
39
  }
2194
  ReadOnlyProperty(ReadOnlyCondition cond, cmPolicies::PolicyID id)
2195
24
    : Condition{ cond }
2196
24
    , Policy{ id }
2197
24
  {
2198
24
  }
2199
2200
  ReadOnlyCondition Condition;
2201
  cm::optional<cmPolicies::PolicyID> Policy;
2202
2203
  std::string message(std::string const& prop, cmTarget* target) const
2204
0
  {
2205
0
    std::string msg;
2206
0
    if (this->Condition == ReadOnlyCondition::All) {
2207
0
      msg = " property is read-only for target(\"";
2208
0
    } else if (this->Condition == ReadOnlyCondition::Imported) {
2209
0
      msg = " property can't be set on imported targets(\"";
2210
0
    } else if (this->Condition == ReadOnlyCondition::NonImported) {
2211
0
      msg = " property can't be set on non-imported targets(\"";
2212
0
    }
2213
0
    return cmStrCat(prop, msg, target->GetName(), "\")\n");
2214
0
  }
2215
2216
  bool isReadOnly(std::string const& prop, cmMakefile* context,
2217
                  cmTarget* target) const
2218
0
  {
2219
0
    auto importedTarget = target->IsImported();
2220
0
    bool matchingCondition = true;
2221
0
    if ((!importedTarget && this->Condition == ReadOnlyCondition::Imported) ||
2222
0
        (importedTarget &&
2223
0
         this->Condition == ReadOnlyCondition::NonImported)) {
2224
0
      matchingCondition = false;
2225
0
    }
2226
0
    if (!matchingCondition) {
2227
      // Not read-only in this scenario
2228
0
      return false;
2229
0
    }
2230
2231
0
    bool readOnly = true;
2232
0
    if (!this->Policy) {
2233
      // No policy associated, so is always read-only
2234
0
      context->IssueMessage(MessageType::FATAL_ERROR,
2235
0
                            this->message(prop, target));
2236
0
    } else {
2237
0
      switch (target->GetPolicyStatus(*this->Policy)) {
2238
0
        case cmPolicies::WARN:
2239
0
          context->IssuePolicyWarning(cmPolicies::CMP0160, {},
2240
0
                                      this->message(prop, target));
2241
0
          CM_FALLTHROUGH;
2242
0
        case cmPolicies::OLD:
2243
0
          readOnly = false;
2244
0
          break;
2245
0
        case cmPolicies::NEW:
2246
0
          context->IssueMessage(MessageType::FATAL_ERROR,
2247
0
                                this->message(prop, target));
2248
0
          break;
2249
0
      }
2250
0
    }
2251
0
    return readOnly;
2252
0
  }
2253
};
2254
2255
bool IsSettableProperty(cmMakefile* context, cmTarget* target,
2256
                        std::string const& prop)
2257
657k
{
2258
657k
  using ROC = ReadOnlyCondition;
2259
657k
  static std::unordered_map<std::string, ReadOnlyProperty> const readOnlyProps{
2260
657k
    { "EXPORT_NAME", { ROC::Imported } },
2261
657k
    { "FILE_SET_TYPES", { ROC::All } },
2262
657k
    { "HEADER_SETS", { ROC::All } },
2263
657k
    { "IMPORTED_GLOBAL", { ROC::NonImported } },
2264
657k
    { "INTERFACE_HEADER_SETS", { ROC::All } },
2265
657k
    { "MANUALLY_ADDED_DEPENDENCIES", { ROC::All } },
2266
657k
    { "NAME", { ROC::All } },
2267
657k
    { "SOURCES", { ROC::Imported } },
2268
657k
    { "SOURCE_SETS", { ROC::All } },
2269
657k
    { "INTERFACE_SOURCE_SETS", { ROC::All } },
2270
657k
    { "SYMBOLIC", { ROC::All } },
2271
657k
    { "TYPE", { ROC::All } },
2272
657k
    { "ALIAS_GLOBAL", { ROC::All, cmPolicies::CMP0160 } },
2273
657k
    { "ALIASED_TARGET", { ROC::All } },
2274
657k
    { "BINARY_DIR", { ROC::All, cmPolicies::CMP0160 } },
2275
657k
    { "CXX_MODULE_SETS", { ROC::All, cmPolicies::CMP0160 } },
2276
657k
    { "IMPORTED", { ROC::All, cmPolicies::CMP0160 } },
2277
657k
    { "INTERFACE_CXX_MODULE_SETS", { ROC::All, cmPolicies::CMP0160 } },
2278
657k
    { "LOCATION", { ROC::All, cmPolicies::CMP0160 } },
2279
657k
    { "LOCATION_CONFIG", { ROC::All, cmPolicies::CMP0160 } },
2280
657k
    { "SOURCE_DIR", { ROC::All, cmPolicies::CMP0160 } }
2281
657k
  };
2282
2283
657k
  auto it = readOnlyProps.find(prop);
2284
2285
657k
  if (it != readOnlyProps.end()) {
2286
0
    return !(it->second.isReadOnly(prop, context, target));
2287
0
  }
2288
657k
  return true;
2289
657k
}
2290
}
2291
2292
void cmTarget::SetSymbolic(bool const value)
2293
35.5k
{
2294
35.5k
  this->impl->IsSymbolic = value;
2295
35.5k
}
2296
2297
void cmTarget::SetExportPassthrough(bool value)
2298
0
{
2299
0
  assert(this->impl->TargetType == cm::TargetType::INTERFACE_LIBRARY);
2300
0
  this->impl->IsExportPassthrough = value;
2301
0
}
2302
2303
void cmTarget::SetProperty(std::string const& prop, cmValue value)
2304
412k
{
2305
412k
  if (!IsSettableProperty(this->impl->Makefile, this, prop)) {
2306
0
    return;
2307
0
  }
2308
2309
412k
  UsageRequirementProperty* usageRequirements[] = {
2310
412k
    &this->impl->IncludeDirectories,
2311
412k
    &this->impl->CompileOptions,
2312
412k
    &this->impl->CompileFeatures,
2313
412k
    &this->impl->CompileDefinitions,
2314
412k
    &this->impl->CompileWrappers,
2315
412k
    &this->impl->PrecompileHeaders,
2316
412k
    &this->impl->Sources,
2317
412k
    &this->impl->LinkOptions,
2318
412k
    &this->impl->LinkDirectories,
2319
412k
    &this->impl->LinkLibraries,
2320
412k
    &this->impl->LinkWrappers,
2321
412k
    &this->impl->InterfaceCompileWrappers,
2322
412k
    &this->impl->InterfaceLinkLibraries,
2323
412k
    &this->impl->InterfaceLinkLibrariesDirect,
2324
412k
    &this->impl->InterfaceLinkLibrariesDirectExclude,
2325
412k
    &this->impl->InterfaceLinkWrappers,
2326
412k
    &this->impl->ImportedCxxModulesIncludeDirectories,
2327
412k
    &this->impl->ImportedCxxModulesCompileDefinitions,
2328
412k
    &this->impl->ImportedCxxModulesCompileFeatures,
2329
412k
    &this->impl->ImportedCxxModulesCompileOptions,
2330
412k
    &this->impl->ImportedCxxModulesLinkLibraries,
2331
412k
  };
2332
2333
8.49M
  for (auto* usageRequirement : usageRequirements) {
2334
8.49M
    if (usageRequirement->Write(this->impl.get(), {}, prop, value,
2335
8.49M
                                UsageRequirementProperty::Action::Set)) {
2336
15.1k
      return;
2337
15.1k
    }
2338
8.49M
  }
2339
2340
397k
  if (cmHasPrefix(prop, "FILE_SETS_"_s) ||
2341
397k
      cmHasPrefix(prop, "INTERFACE_FILE_SETS_"_s)) {
2342
    // these properties are always read-only
2343
0
    return;
2344
0
  }
2345
1.19M
  for (auto& fileSetType : this->impl->FileSetTypes) {
2346
1.19M
    if (fileSetType.second.WriteProperties(this, this->impl.get(), prop, value,
2347
1.19M
                                           FileSetType::Action::Set)) {
2348
0
      return;
2349
0
    }
2350
1.19M
  }
2351
2352
397k
  if (prop == propIMPORTED_GLOBAL) {
2353
0
    if (!value.IsOn()) {
2354
0
      this->impl->Makefile->IssueMessage(
2355
0
        MessageType::FATAL_ERROR,
2356
0
        cmStrCat("IMPORTED_GLOBAL property can't be set to FALSE on targets "
2357
0
                 "(\"",
2358
0
                 this->impl->Name, "\")\n"));
2359
0
      return;
2360
0
    }
2361
    /* no need to change anything if value does not change */
2362
0
    if (!this->IsImportedGloballyVisible()) {
2363
0
      this->impl->TargetVisibility = Visibility::ImportedGlobally;
2364
0
      this->GetGlobalGenerator()->IndexTarget(this);
2365
0
    }
2366
397k
  } else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME") &&
2367
0
             !this->impl->CheckImportedLibName(
2368
0
               prop,
2369
0
               value ? value
2370
0
                     : std::string{})) { // NOLINT(bugprone-branch-clone)
2371
    /* error was reported by check method */
2372
397k
  } else if (prop == propCUDA_CUBIN_COMPILATION ||
2373
397k
             prop == propCUDA_FATBIN_COMPILATION ||
2374
397k
             prop == propCUDA_OPTIX_COMPILATION ||
2375
397k
             prop == propCUDA_PTX_COMPILATION) {
2376
0
    auto const& compiler =
2377
0
      this->impl->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_ID");
2378
0
    auto const& compilerVersion =
2379
0
      this->impl->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_VERSION");
2380
0
    if (this->GetType() != cm::TargetType::OBJECT_LIBRARY) {
2381
0
      auto e =
2382
0
        cmStrCat(prop, " property can only be applied to OBJECT targets(",
2383
0
                 this->impl->Name, ")\n");
2384
0
      this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
2385
0
      return;
2386
0
    }
2387
0
    bool const flag_found =
2388
0
      (prop == propCUDA_PTX_COMPILATION &&
2389
0
       this->impl->Makefile->GetDefinition("_CMAKE_CUDA_PTX_FLAG")) ||
2390
0
      (prop == propCUDA_CUBIN_COMPILATION &&
2391
0
       this->impl->Makefile->GetDefinition("_CMAKE_CUDA_CUBIN_FLAG")) ||
2392
0
      (prop == propCUDA_FATBIN_COMPILATION &&
2393
0
       this->impl->Makefile->GetDefinition("_CMAKE_CUDA_FATBIN_FLAG")) ||
2394
0
      (prop == propCUDA_OPTIX_COMPILATION &&
2395
0
       this->impl->Makefile->GetDefinition("_CMAKE_CUDA_OPTIX_FLAG"));
2396
0
    if (flag_found) {
2397
0
      this->impl->Properties.SetProperty(prop, value);
2398
0
    } else {
2399
0
      auto e = cmStrCat(prop, " property is not supported by ", compiler,
2400
0
                        "  compiler version ", compilerVersion, '.');
2401
0
      this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
2402
0
      return;
2403
0
    }
2404
397k
  } else if (prop == propC_STANDARD || prop == propCXX_STANDARD ||
2405
397k
             prop == propCUDA_STANDARD || prop == propHIP_STANDARD ||
2406
397k
             prop == propOBJC_STANDARD || prop == propOBJCXX_STANDARD ||
2407
397k
             prop == propSYCL_CXX_STANDARD) {
2408
0
    if (value) {
2409
0
      this->impl->LanguageStandardProperties[prop] =
2410
0
        BTs<std::string>(value, this->impl->Makefile->GetBacktrace());
2411
0
    } else {
2412
0
      this->impl->LanguageStandardProperties.erase(prop);
2413
0
    }
2414
397k
  } else {
2415
397k
    this->impl->Properties.SetProperty(prop, value);
2416
397k
  }
2417
397k
}
2418
2419
void cmTarget::AppendProperty(std::string const& prop,
2420
                              std::string const& value,
2421
                              cm::optional<cmListFileBacktrace> const& bt,
2422
                              bool asString)
2423
244k
{
2424
244k
  if (!IsSettableProperty(this->impl->Makefile, this, prop)) {
2425
0
    return;
2426
0
  }
2427
244k
  if (prop == "IMPORTED_GLOBAL") {
2428
0
    this->impl->Makefile->IssueMessage(
2429
0
      MessageType::FATAL_ERROR,
2430
0
      cmStrCat("IMPORTED_GLOBAL property can't be appended, only set on "
2431
0
               "imported targets (\"",
2432
0
               this->impl->Name, "\")\n"));
2433
0
  }
2434
2435
244k
  UsageRequirementProperty* usageRequirements[] = {
2436
244k
    &this->impl->IncludeDirectories,
2437
244k
    &this->impl->CompileOptions,
2438
244k
    &this->impl->CompileFeatures,
2439
244k
    &this->impl->CompileDefinitions,
2440
244k
    &this->impl->CompileWrappers,
2441
244k
    &this->impl->PrecompileHeaders,
2442
244k
    &this->impl->Sources,
2443
244k
    &this->impl->LinkOptions,
2444
244k
    &this->impl->LinkDirectories,
2445
244k
    &this->impl->LinkLibraries,
2446
244k
    &this->impl->LinkWrappers,
2447
244k
    &this->impl->InterfaceCompileWrappers,
2448
244k
    &this->impl->InterfaceLinkLibraries,
2449
244k
    &this->impl->InterfaceLinkLibrariesDirect,
2450
244k
    &this->impl->InterfaceLinkLibrariesDirectExclude,
2451
244k
    &this->impl->InterfaceLinkWrappers,
2452
244k
    &this->impl->ImportedCxxModulesIncludeDirectories,
2453
244k
    &this->impl->ImportedCxxModulesCompileDefinitions,
2454
244k
    &this->impl->ImportedCxxModulesCompileFeatures,
2455
244k
    &this->impl->ImportedCxxModulesCompileOptions,
2456
244k
    &this->impl->ImportedCxxModulesLinkLibraries,
2457
244k
  };
2458
2459
4.08M
  for (auto* usageRequirement : usageRequirements) {
2460
4.08M
    if (usageRequirement->Write(this->impl.get(), bt, prop, cmValue(value),
2461
4.08M
                                UsageRequirementProperty::Action::Append)) {
2462
116k
      return;
2463
116k
    }
2464
4.08M
  }
2465
2466
385k
  for (auto& fileSetType : this->impl->FileSetTypes) {
2467
385k
    if (fileSetType.second.WriteProperties(this, this->impl.get(), prop, value,
2468
385k
                                           FileSetType::Action::Append)) {
2469
0
      return;
2470
0
    }
2471
385k
  }
2472
2473
128k
  if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME")) {
2474
0
    this->impl->Makefile->IssueMessage(
2475
0
      MessageType::FATAL_ERROR, prop + " property may not be APPENDed.");
2476
128k
  } else if (prop == "C_STANDARD" || prop == "CXX_STANDARD" ||
2477
128k
             prop == "CUDA_STANDARD" || prop == "HIP_STANDARD" ||
2478
128k
             prop == "OBJC_STANDARD" || prop == "OBJCXX_STANDARD" ||
2479
128k
             prop == "SYCL_CXX_STANDARD") {
2480
0
    this->impl->Makefile->IssueMessage(
2481
0
      MessageType::FATAL_ERROR, prop + " property may not be appended.");
2482
128k
  } else {
2483
128k
    this->impl->Properties.AppendProperty(prop, value, asString);
2484
128k
  }
2485
128k
}
2486
2487
template <typename ValueType>
2488
void cmTargetInternals::AddDirectoryToFileSet(cmTarget* self,
2489
                                              std::string const& fileSetName,
2490
                                              ValueType value,
2491
                                              cm::string_view fileSetType,
2492
                                              cm::string_view description,
2493
                                              FileSetType::Action action)
2494
0
{
2495
0
  auto* fileSet = self->GetFileSet(fileSetName);
2496
0
  if (!fileSet) {
2497
0
    this->Makefile->IssueMessage(
2498
0
      MessageType::FATAL_ERROR,
2499
0
      cmStrCat(description, "has not yet been created."));
2500
0
    return;
2501
0
  }
2502
0
  if (fileSet->GetType() != fileSetType) {
2503
0
    this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
2504
0
                                 cmStrCat("File set \"", fileSetName,
2505
0
                                          "\" is not of type \"", fileSetType,
2506
0
                                          "\"."));
2507
0
    return;
2508
0
  }
2509
0
  if (action == FileSetType::Action::Set) {
2510
0
    fileSet->ClearDirectoryEntries();
2511
0
  }
2512
0
  if (cmNonempty(value)) {
2513
0
    fileSet->AddDirectoryEntry(
2514
0
      BT<std::string>(value, this->Makefile->GetBacktrace()));
2515
0
  }
2516
0
}
Unexecuted instantiation: cmTarget.cxx:void cmTargetInternals::AddDirectoryToFileSet<cmValue>(cmTarget*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cmValue, std::__1::basic_string_view<char, std::__1::char_traits<char> >, std::__1::basic_string_view<char, std::__1::char_traits<char> >, (anonymous namespace)::FileSetType::Action)
Unexecuted instantiation: cmTarget.cxx:void cmTargetInternals::AddDirectoryToFileSet<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(cmTarget*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string_view<char, std::__1::char_traits<char> >, std::__1::basic_string_view<char, std::__1::char_traits<char> >, (anonymous namespace)::FileSetType::Action)
2517
2518
template <typename ValueType>
2519
void cmTargetInternals::AddPathToFileSet(cmTarget* self,
2520
                                         std::string const& fileSetName,
2521
                                         ValueType value,
2522
                                         cm::string_view fileSetType,
2523
                                         cm::string_view description,
2524
                                         FileSetType::Action action)
2525
0
{
2526
0
  auto* fileSet = self->GetFileSet(fileSetName);
2527
0
  if (!fileSet) {
2528
0
    this->Makefile->IssueMessage(
2529
0
      MessageType::FATAL_ERROR,
2530
0
      cmStrCat(description, "has not yet been created."));
2531
0
    return;
2532
0
  }
2533
0
  if (fileSet->GetType() != fileSetType) {
2534
0
    this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
2535
0
                                 cmStrCat("File set \"", fileSetName,
2536
0
                                          "\" is not of type \"", fileSetType,
2537
0
                                          "\"."));
2538
0
    return;
2539
0
  }
2540
0
  if (action == FileSetType::Action::Set) {
2541
0
    fileSet->ClearFileEntries();
2542
0
  }
2543
0
  if (cmNonempty(value)) {
2544
0
    fileSet->AddFileEntry(
2545
0
      BT<std::string>(value, this->Makefile->GetBacktrace()));
2546
0
  }
2547
0
}
Unexecuted instantiation: cmTarget.cxx:void cmTargetInternals::AddPathToFileSet<cmValue>(cmTarget*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cmValue, std::__1::basic_string_view<char, std::__1::char_traits<char> >, std::__1::basic_string_view<char, std::__1::char_traits<char> >, (anonymous namespace)::FileSetType::Action)
Unexecuted instantiation: cmTarget.cxx:void cmTargetInternals::AddPathToFileSet<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(cmTarget*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string_view<char, std::__1::char_traits<char> >, std::__1::basic_string_view<char, std::__1::char_traits<char> >, (anonymous namespace)::FileSetType::Action)
2548
2549
cmValue cmTargetInternals::GetFileSetDirectories(
2550
  cmTarget const* self, std::string const& fileSetName,
2551
  cm::string_view fileSetType) const
2552
1
{
2553
1
  auto const* fileSet = self->GetFileSet(fileSetName);
2554
1
  if (!fileSet) {
2555
1
    return nullptr;
2556
1
  }
2557
0
  if (fileSet->GetType() != fileSetType) {
2558
0
    this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
2559
0
                                 cmStrCat("File set \"", fileSetName,
2560
0
                                          "\" is not of type \"", fileSetType,
2561
0
                                          "\"."));
2562
0
    return nullptr;
2563
0
  }
2564
0
  static std::string output;
2565
0
  output = cmList::to_string(fileSet->GetDirectoryEntries());
2566
0
  return cmValue(output);
2567
0
}
2568
2569
cmValue cmTargetInternals::GetFileSetPaths(cmTarget const* self,
2570
                                           std::string const& fileSetName,
2571
                                           cm::string_view fileSetType) const
2572
0
{
2573
0
  auto const* fileSet = self->GetFileSet(fileSetName);
2574
0
  if (!fileSet) {
2575
0
    return nullptr;
2576
0
  }
2577
0
  if (fileSet->GetType() != fileSetType) {
2578
0
    this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
2579
0
                                 cmStrCat("File set \"", fileSetName,
2580
0
                                          "\" is not of type \"", fileSetType,
2581
0
                                          "\"."));
2582
0
    return nullptr;
2583
0
  }
2584
0
  static std::string output;
2585
0
  output = cmList::to_string(fileSet->GetFileEntries());
2586
0
  return cmValue(output);
2587
0
}
2588
2589
void cmTarget::AppendBuildInterfaceIncludes()
2590
0
{
2591
0
  if (this->GetType() != cm::TargetType::SHARED_LIBRARY &&
2592
0
      this->GetType() != cm::TargetType::STATIC_LIBRARY &&
2593
0
      this->GetType() != cm::TargetType::MODULE_LIBRARY &&
2594
0
      this->GetType() != cm::TargetType::INTERFACE_LIBRARY &&
2595
0
      !this->IsExecutableWithExports()) {
2596
0
    return;
2597
0
  }
2598
0
  if (this->impl->BuildInterfaceIncludesAppended) {
2599
0
    return;
2600
0
  }
2601
0
  this->impl->BuildInterfaceIncludesAppended = true;
2602
2603
0
  if (this->impl->Makefile->IsOn("CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE")) {
2604
0
    std::string dirs = this->impl->Makefile->GetCurrentBinaryDirectory();
2605
0
    if (!dirs.empty()) {
2606
0
      dirs += ';';
2607
0
    }
2608
0
    dirs += this->impl->Makefile->GetCurrentSourceDirectory();
2609
0
    if (!dirs.empty()) {
2610
0
      this->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
2611
0
                           (cmStrCat("$<BUILD_INTERFACE:", dirs, '>')));
2612
0
    }
2613
0
  }
2614
0
}
2615
2616
namespace {
2617
bool CheckLinkLibraryPattern(UsageRequirementProperty const& usage,
2618
                             cmake* context)
2619
0
{
2620
  // Look for <LINK_LIBRARY:> and </LINK_LIBRARY:> internal tags
2621
0
  static cmsys::RegularExpression linkPattern(
2622
0
    "(^|;)(</?LINK_(LIBRARY|GROUP):[^;>]*>)(;|$)");
2623
2624
0
  bool isValid = true;
2625
2626
0
  for (auto const& item : usage.Entries) {
2627
0
    if (!linkPattern.find(item.Value)) {
2628
0
      continue;
2629
0
    }
2630
2631
0
    isValid = false;
2632
2633
    // Report an error.
2634
0
    context->IssueMessage(
2635
0
      MessageType::FATAL_ERROR,
2636
0
      cmStrCat(
2637
0
        "Property ", usage.Name, " contains the invalid item \"",
2638
0
        linkPattern.match(2), "\". The ", usage.Name,
2639
0
        " property may contain the generator-expression \"$<LINK_",
2640
0
        linkPattern.match(3),
2641
0
        ":...>\" which may be used to specify how the libraries are linked."),
2642
0
      item.Backtrace);
2643
0
  }
2644
2645
0
  return isValid;
2646
0
}
2647
}
2648
2649
void cmTarget::FinalizeTargetConfiguration(cmBTStringRange compileDefinitions)
2650
0
{
2651
0
  if (this->GetType() == cm::TargetType::GLOBAL_TARGET) {
2652
0
    return;
2653
0
  }
2654
2655
0
  if (!CheckLinkLibraryPattern(this->impl->LinkLibraries,
2656
0
                               this->GetMakefile()->GetCMakeInstance()) ||
2657
0
      !CheckLinkLibraryPattern(this->impl->InterfaceLinkLibraries,
2658
0
                               this->GetMakefile()->GetCMakeInstance()) ||
2659
0
      !CheckLinkLibraryPattern(this->impl->InterfaceLinkLibrariesDirect,
2660
0
                               this->GetMakefile()->GetCMakeInstance())) {
2661
0
    return;
2662
0
  }
2663
2664
0
  this->AppendBuildInterfaceIncludes();
2665
2666
0
  if (this->GetType() == cm::TargetType::INTERFACE_LIBRARY) {
2667
0
    return;
2668
0
  }
2669
2670
0
  for (auto const& def : compileDefinitions) {
2671
0
    this->InsertCompileDefinition(def);
2672
0
  }
2673
0
}
2674
2675
void cmTarget::InsertInclude(BT<std::string> const& entry, bool before)
2676
0
{
2677
0
  this->impl->IncludeDirectories.WriteDirect(
2678
0
    entry,
2679
0
    before ? UsageRequirementProperty::Action::Prepend
2680
0
           : UsageRequirementProperty::Action::Append);
2681
0
}
2682
2683
void cmTarget::InsertCompileOption(BT<std::string> const& entry, bool before)
2684
0
{
2685
0
  this->impl->CompileOptions.WriteDirect(
2686
0
    entry,
2687
0
    before ? UsageRequirementProperty::Action::Prepend
2688
0
           : UsageRequirementProperty::Action::Append);
2689
0
}
2690
2691
void cmTarget::InsertCompileDefinition(BT<std::string> const& entry)
2692
0
{
2693
0
  this->impl->CompileDefinitions.WriteDirect(
2694
0
    entry, UsageRequirementProperty::Action::Append);
2695
0
}
2696
2697
void cmTarget::InsertLinkOption(BT<std::string> const& entry, bool before)
2698
0
{
2699
0
  this->impl->LinkOptions.WriteDirect(
2700
0
    entry,
2701
0
    before ? UsageRequirementProperty::Action::Prepend
2702
0
           : UsageRequirementProperty::Action::Append);
2703
0
}
2704
2705
void cmTarget::InsertLinkDirectory(BT<std::string> const& entry, bool before)
2706
0
{
2707
0
  this->impl->LinkDirectories.WriteDirect(
2708
0
    entry,
2709
0
    before ? UsageRequirementProperty::Action::Prepend
2710
0
           : UsageRequirementProperty::Action::Append);
2711
0
}
2712
2713
void cmTarget::InsertPrecompileHeader(BT<std::string> const& entry)
2714
0
{
2715
0
  this->impl->PrecompileHeaders.WriteDirect(
2716
0
    entry, UsageRequirementProperty::Action::Append);
2717
0
}
2718
2719
namespace {
2720
void CheckLINK_INTERFACE_LIBRARIES(std::string const& prop,
2721
                                   std::string const& value,
2722
                                   cmMakefile* context, bool imported)
2723
0
{
2724
  // Support imported and non-imported versions of the property.
2725
0
  char const* base = (imported ? "IMPORTED_LINK_INTERFACE_LIBRARIES"
2726
0
                               : "LINK_INTERFACE_LIBRARIES");
2727
2728
  // Look for link-type keywords in the value.
2729
0
  static cmsys::RegularExpression keys("(^|;)(debug|optimized|general)(;|$)");
2730
0
  if (keys.find(value)) {
2731
    // Report an error.
2732
0
    std::ostringstream e;
2733
0
    e << "Property " << prop << " may not contain link-type keyword \""
2734
0
      << keys.match(2) << "\".  "
2735
0
      << "The " << base << " property has a per-configuration "
2736
0
      << "version called " << base << "_<CONFIG> which may be "
2737
0
      << "used to specify per-configuration rules.";
2738
0
    if (!imported) {
2739
0
      e << "  "
2740
0
        << "Alternatively, an IMPORTED library may be created, configured "
2741
0
        << "with a per-configuration location, and then named in the "
2742
0
        << "property value.  "
2743
0
        << "See the add_library command's IMPORTED mode for details."
2744
0
        << "\n"
2745
0
        << "If you have a list of libraries that already contains the "
2746
0
        << "keyword, use the target_link_libraries command with its "
2747
0
        << "LINK_INTERFACE_LIBRARIES mode to set the property.  "
2748
0
        << "The command automatically recognizes link-type keywords and sets "
2749
0
        << "the LINK_INTERFACE_LIBRARIES and LINK_INTERFACE_LIBRARIES_DEBUG "
2750
0
        << "properties accordingly.";
2751
0
    }
2752
0
    context->IssueMessage(MessageType::FATAL_ERROR, e.str());
2753
0
  }
2754
0
}
2755
2756
void CheckINTERFACE_LINK_LIBRARIES(std::string const& value,
2757
                                   cmMakefile* context)
2758
5.92k
{
2759
  // Look for link-type keywords in the value.
2760
5.92k
  static cmsys::RegularExpression keys("(^|;)(debug|optimized|general)(;|$)");
2761
5.92k
  if (keys.find(value)) {
2762
    // Report an error.
2763
0
    context->IssueMessage(
2764
0
      MessageType::FATAL_ERROR,
2765
0
      cmStrCat("Property INTERFACE_LINK_LIBRARIES may not contain link-type "
2766
0
               "keyword \"",
2767
0
               keys.match(2),
2768
0
               "\".  The INTERFACE_LINK_LIBRARIES "
2769
0
               "property may contain configuration-sensitive "
2770
0
               "generator-expressions "
2771
0
               "which may be used to specify per-configuration rules."));
2772
0
  }
2773
5.92k
}
2774
2775
void CheckIMPORTED_GLOBAL(cmTarget const* target, cmMakefile* context)
2776
0
{
2777
0
  auto const& targets = context->GetOwnedImportedTargets();
2778
0
  auto it =
2779
0
    std::find_if(targets.begin(), targets.end(),
2780
0
                 [&](std::unique_ptr<cmTarget> const& importTarget) -> bool {
2781
0
                   return target == importTarget.get();
2782
0
                 });
2783
0
  if (it == targets.end()) {
2784
0
    context->IssueMessage(
2785
0
      MessageType::FATAL_ERROR,
2786
0
      cmStrCat("Attempt to promote imported target \"", target->GetName(),
2787
0
               "\" to global scope (by setting IMPORTED_GLOBAL) "
2788
0
               "which is not built in this directory."));
2789
0
  }
2790
0
}
2791
}
2792
2793
void cmTarget::CheckProperty(std::string const& prop,
2794
                             cmMakefile* context) const
2795
142k
{
2796
  // Certain properties need checking.
2797
142k
  if (cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES")) {
2798
0
    if (cmValue value = this->GetProperty(prop)) {
2799
0
      CheckLINK_INTERFACE_LIBRARIES(prop, *value, context, false);
2800
0
    }
2801
142k
  } else if (cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES")) {
2802
0
    if (cmValue value = this->GetProperty(prop)) {
2803
0
      CheckLINK_INTERFACE_LIBRARIES(prop, *value, context, true);
2804
0
    }
2805
142k
  } else if (prop == "INTERFACE_LINK_LIBRARIES") {
2806
5.92k
    if (cmValue value = this->GetProperty(prop)) {
2807
5.92k
      CheckINTERFACE_LINK_LIBRARIES(*value, context);
2808
5.92k
    }
2809
136k
  } else if (prop == "IMPORTED_GLOBAL") {
2810
0
    if (this->IsImported()) {
2811
0
      CheckIMPORTED_GLOBAL(this, context);
2812
0
    }
2813
0
  }
2814
142k
}
2815
2816
std::unordered_set<std::string> const& cmTarget::GetSpecialPropertyNames()
2817
355k
{
2818
355k
  static std::unordered_set<std::string> const specialProps{
2819
355k
    propC_STANDARD,
2820
355k
    propCXX_STANDARD,
2821
355k
    propCUDA_STANDARD,
2822
355k
    propHIP_STANDARD,
2823
355k
    propOBJC_STANDARD,
2824
355k
    propOBJCXX_STANDARD,
2825
355k
    propSYCL_CXX_STANDARD,
2826
355k
    propLINK_LIBRARIES,
2827
355k
    propTYPE,
2828
355k
    propINCLUDE_DIRECTORIES,
2829
355k
    propCOMPILE_FEATURES,
2830
355k
    propCOMPILE_OPTIONS,
2831
355k
    propCOMPILE_DEFINITIONS,
2832
355k
    propCOMPILE_WRAPPERS,
2833
355k
    propPRECOMPILE_HEADERS,
2834
355k
    propLINK_OPTIONS,
2835
355k
    propLINK_DIRECTORIES,
2836
355k
    propLINK_WRAPPERS,
2837
355k
    propIMPORTED,
2838
355k
    propIMPORTED_GLOBAL,
2839
355k
    propMANUALLY_ADDED_DEPENDENCIES,
2840
355k
    propNAME,
2841
355k
    propBINARY_DIR,
2842
355k
    propSOURCE_DIR,
2843
355k
    propSOURCES,
2844
355k
    propSYMBOLIC,
2845
355k
    propINTERFACE_COMPILE_WRAPPERS,
2846
355k
    propINTERFACE_LINK_LIBRARIES,
2847
355k
    propINTERFACE_LINK_LIBRARIES_DIRECT,
2848
355k
    propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE,
2849
355k
    propINTERFACE_LINK_WRAPPERS,
2850
355k
    propIMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES,
2851
355k
    propIMPORTED_CXX_MODULES_COMPILE_DEFINITIONS,
2852
355k
    propIMPORTED_CXX_MODULES_COMPILE_FEATURES,
2853
355k
    propIMPORTED_CXX_MODULES_COMPILE_OPTIONS,
2854
355k
    propIMPORTED_CXX_MODULES_LINK_LIBRARIES,
2855
355k
  };
2856
355k
  return specialProps;
2857
355k
}
2858
2859
cmValue cmTarget::GetComputedProperty(std::string const& prop,
2860
                                      cmMakefile& mf) const
2861
0
{
2862
0
  return cmTargetPropertyComputer::GetProperty(this, prop, mf);
2863
0
}
2864
2865
cmValue cmTarget::GetProperty(std::string const& prop) const
2866
355k
{
2867
355k
  auto const& specialProps = cmTarget::GetSpecialPropertyNames();
2868
355k
  if (specialProps.count(prop)) {
2869
37.0k
    if (prop == propC_STANDARD || prop == propCXX_STANDARD ||
2870
37.0k
        prop == propCUDA_STANDARD || prop == propHIP_STANDARD ||
2871
37.0k
        prop == propOBJC_STANDARD || prop == propOBJCXX_STANDARD ||
2872
37.0k
        prop == propSYCL_CXX_STANDARD) {
2873
0
      auto propertyIter = this->impl->LanguageStandardProperties.find(prop);
2874
0
      if (propertyIter == this->impl->LanguageStandardProperties.end()) {
2875
0
        return nullptr;
2876
0
      }
2877
0
      return cmValue(propertyIter->second.Value);
2878
0
    }
2879
2880
37.0k
    if (prop == propSYMBOLIC) {
2881
0
      return this->IsSymbolic() ? cmValue(propTRUE) : cmValue(propFALSE);
2882
0
    }
2883
2884
37.0k
    UsageRequirementProperty const* usageRequirements[] = {
2885
37.0k
      &this->impl->IncludeDirectories,
2886
37.0k
      &this->impl->CompileOptions,
2887
37.0k
      &this->impl->CompileFeatures,
2888
37.0k
      &this->impl->CompileDefinitions,
2889
37.0k
      &this->impl->CompileWrappers,
2890
37.0k
      &this->impl->PrecompileHeaders,
2891
37.0k
      &this->impl->Sources,
2892
37.0k
      &this->impl->LinkOptions,
2893
37.0k
      &this->impl->LinkDirectories,
2894
37.0k
      &this->impl->LinkLibraries,
2895
37.0k
      &this->impl->LinkWrappers,
2896
37.0k
      &this->impl->InterfaceCompileWrappers,
2897
37.0k
      &this->impl->InterfaceLinkLibraries,
2898
37.0k
      &this->impl->InterfaceLinkLibrariesDirect,
2899
37.0k
      &this->impl->InterfaceLinkLibrariesDirectExclude,
2900
37.0k
      &this->impl->InterfaceLinkWrappers,
2901
37.0k
      &this->impl->ImportedCxxModulesIncludeDirectories,
2902
37.0k
      &this->impl->ImportedCxxModulesCompileDefinitions,
2903
37.0k
      &this->impl->ImportedCxxModulesCompileFeatures,
2904
37.0k
      &this->impl->ImportedCxxModulesCompileOptions,
2905
37.0k
      &this->impl->ImportedCxxModulesLinkLibraries,
2906
37.0k
    };
2907
2908
159k
    for (auto const* usageRequirement : usageRequirements) {
2909
159k
      auto value = usageRequirement->Read(prop);
2910
159k
      if (value.first) {
2911
37.0k
        return value.second;
2912
37.0k
      }
2913
159k
    }
2914
2915
    // the type property returns what type the target is
2916
3
    if (prop == propTYPE) {
2917
0
      return cmValue(cmState::GetTargetTypeName(this->GetType()));
2918
0
    }
2919
3
    if (prop == propMANUALLY_ADDED_DEPENDENCIES) {
2920
0
      if (this->impl->Utilities.empty()) {
2921
0
        return nullptr;
2922
0
      }
2923
2924
0
      static std::string output;
2925
0
      static std::vector<std::string> utilities;
2926
0
      utilities.resize(this->impl->Utilities.size());
2927
0
      std::transform(
2928
0
        this->impl->Utilities.cbegin(), this->impl->Utilities.cend(),
2929
0
        utilities.begin(),
2930
0
        [](const BT<std::pair<std::string, bool>>& item) -> std::string {
2931
0
          return item.Value.first;
2932
0
        });
2933
0
      output = cmList::to_string(utilities);
2934
0
      return cmValue(output);
2935
0
    }
2936
3
    if (prop == propIMPORTED) {
2937
3
      return this->IsImported() ? cmValue(propTRUE) : cmValue(propFALSE);
2938
3
    }
2939
0
    if (prop == propIMPORTED_GLOBAL) {
2940
0
      return this->IsImportedGloballyVisible() ? cmValue(propTRUE)
2941
0
                                               : cmValue(propFALSE);
2942
0
    }
2943
0
    if (prop == propNAME) {
2944
0
      return cmValue(this->GetName());
2945
0
    }
2946
0
    if (prop == propBINARY_DIR) {
2947
0
      return cmValue(this->impl->Makefile->GetStateSnapshot()
2948
0
                       .GetDirectory()
2949
0
                       .GetCurrentBinary());
2950
0
    }
2951
0
    if (prop == propSOURCE_DIR) {
2952
0
      return cmValue(this->impl->Makefile->GetStateSnapshot()
2953
0
                       .GetDirectory()
2954
0
                       .GetCurrentSource());
2955
0
    }
2956
0
  }
2957
2958
  // Check fileset properties.
2959
318k
  if (prop == "FILE_SET_TYPES"_s) {
2960
0
    static std::string fsTypes;
2961
0
    cmList types;
2962
0
    for (auto const& fileSetType : this->impl->FileSetTypes) {
2963
0
      if (!fileSetType.second.SelfEntries.Entries.empty() ||
2964
0
          !fileSetType.second.InterfaceEntries.Entries.empty()) {
2965
0
        types.push_back(fileSetType.first);
2966
0
      }
2967
0
    }
2968
0
    for (auto const& fileSetRule : this->impl->FileSetRules) {
2969
0
      if (!fileSetRule.second.SelfEntries.empty() ||
2970
0
          !fileSetRule.second.InterfaceEntries.empty()) {
2971
0
        types.push_back(fileSetRule.first);
2972
0
      }
2973
0
    }
2974
0
    std::sort(types.begin(), types.end());
2975
0
    fsTypes = types.to_string();
2976
0
    return cmValue{ fsTypes };
2977
0
  }
2978
318k
  if (cmHasPrefix(prop, "FILE_SETS_"_s)) {
2979
77
    static std::string fileSets;
2980
77
    std::string type = prop.substr(10);
2981
77
    fileSets = cmList::to_string(this->GetFileSetsEntries(type));
2982
77
    return cmValue{ fileSets };
2983
77
  }
2984
318k
  if (cmHasPrefix(prop, "INTERFACE_FILE_SETS_"_s)) {
2985
0
    static std::string fileSets;
2986
0
    std::string type = prop.substr(20);
2987
0
    fileSets = cmList::to_string(this->GetInterfaceFileSetsEntries(type));
2988
0
    return cmValue{ fileSets };
2989
0
  }
2990
2991
318k
  {
2992
955k
    for (auto const& fileSetType : this->impl->FileSetTypes) {
2993
955k
      auto value =
2994
955k
        fileSetType.second.ReadProperties(this, this->impl.get(), prop);
2995
955k
      if (value.first) {
2996
1
        return value.second;
2997
1
      }
2998
955k
    }
2999
318k
  }
3000
3001
318k
  cmValue retVal = this->impl->Properties.GetPropertyValue(prop);
3002
318k
  if (!retVal) {
3003
286k
    bool const chain = this->impl->Makefile->GetState()->IsPropertyChained(
3004
286k
      prop, cmProperty::TARGET);
3005
286k
    if (chain) {
3006
0
      return this->impl->Makefile->GetStateSnapshot()
3007
0
        .GetDirectory()
3008
0
        .GetProperty(prop, chain);
3009
0
    }
3010
286k
    return nullptr;
3011
286k
  }
3012
32.1k
  return retVal;
3013
318k
}
3014
3015
std::string const& cmTarget::GetSafeProperty(std::string const& prop) const
3016
53.9k
{
3017
53.9k
  cmValue ret = this->GetProperty(prop);
3018
53.9k
  if (ret) {
3019
0
    return *ret;
3020
0
  }
3021
3022
53.9k
  static std::string const s_empty;
3023
53.9k
  return s_empty;
3024
53.9k
}
3025
3026
bool cmTarget::GetPropertyAsBool(std::string const& prop) const
3027
54.9k
{
3028
54.9k
  return this->GetProperty(prop).IsOn();
3029
54.9k
}
3030
3031
cmPropertyMap const& cmTarget::GetDirectProperties() const
3032
5.50k
{
3033
5.50k
  return this->impl->Properties;
3034
5.50k
}
3035
3036
cmPropertyMap cmTarget::GetExtendedProperties() const
3037
0
{
3038
  // Get properties in the base property map
3039
0
  cmPropertyMap pm = this->impl->Properties;
3040
3041
  // Get special properties
3042
0
  auto const& specialProps = cmTarget::GetSpecialPropertyNames();
3043
0
  for (auto const& propName : specialProps) {
3044
0
    cmValue propValue = this->GetProperty(propName);
3045
0
    if (propValue) {
3046
0
      pm.SetProperty(propName, propValue);
3047
0
    }
3048
0
  }
3049
3050
  // Get fileset properties
3051
0
  for (auto const& fileSetType : this->impl->FileSetTypes) {
3052
0
    cmPropertyMap fileSetProperties =
3053
0
      fileSetType.second.GetProperties(this, this->impl.get());
3054
0
    auto fileSetPropertiesList = fileSetProperties.GetList();
3055
0
    for (auto const& propPair : fileSetPropertiesList) {
3056
0
      pm.SetProperty(propPair.first, propPair.second);
3057
0
    }
3058
0
  }
3059
3060
0
  return pm;
3061
0
}
3062
3063
bool cmTarget::IsDLLPlatform() const
3064
1.25k
{
3065
1.25k
  return this->impl->IsDLLPlatform;
3066
1.25k
}
3067
3068
bool cmTarget::IsAIX() const
3069
2.47k
{
3070
2.47k
  return this->impl->IsAIX;
3071
2.47k
}
3072
bool cmTarget::IsApple() const
3073
32.2k
{
3074
32.2k
  return this->impl->IsApple;
3075
32.2k
}
3076
3077
bool cmTarget::IsSymbolic() const
3078
88.9k
{
3079
88.9k
  return this->impl->IsSymbolic;
3080
88.9k
}
3081
3082
bool cmTarget::IsNormal() const
3083
250k
{
3084
250k
  switch (this->impl->TargetVisibility) {
3085
102k
    case Visibility::Normal:
3086
102k
      return true;
3087
0
    case Visibility::Generated:
3088
82.9k
    case Visibility::Imported:
3089
148k
    case Visibility::ImportedGlobally:
3090
148k
    case Visibility::Foreign:
3091
148k
      return false;
3092
250k
  }
3093
0
  CM_UNREACHABLE;
3094
0
  return false;
3095
250k
}
3096
3097
bool cmTarget::IsSynthetic() const
3098
66.0k
{
3099
66.0k
  switch (this->impl->TargetVisibility) {
3100
0
    case Visibility::Generated:
3101
0
      return true;
3102
66.0k
    case Visibility::Normal:
3103
66.0k
    case Visibility::Imported:
3104
66.0k
    case Visibility::ImportedGlobally:
3105
66.0k
    case Visibility::Foreign:
3106
66.0k
      return false;
3107
66.0k
  }
3108
0
  CM_UNREACHABLE;
3109
0
  return false;
3110
66.0k
}
3111
3112
bool cmTargetInternals::IsImported() const
3113
4.97M
{
3114
4.97M
  switch (this->TargetVisibility) {
3115
467k
    case cmTarget::Visibility::Imported:
3116
799k
    case cmTarget::Visibility::ImportedGlobally:
3117
799k
    case cmTarget::Visibility::Foreign:
3118
799k
      return true;
3119
4.17M
    case cmTarget::Visibility::Normal:
3120
4.17M
    case cmTarget::Visibility::Generated:
3121
4.17M
      return false;
3122
4.97M
  }
3123
0
  CM_UNREACHABLE;
3124
0
  return false;
3125
4.97M
}
3126
3127
bool cmTarget::IsImported() const
3128
4.88M
{
3129
4.88M
  return this->impl->IsImported();
3130
4.88M
}
3131
3132
bool cmTarget::IsImportedGloballyVisible() const
3133
73.0k
{
3134
73.0k
  switch (this->impl->TargetVisibility) {
3135
33.5k
    case Visibility::ImportedGlobally:
3136
33.5k
      return true;
3137
0
    case Visibility::Normal:
3138
0
    case Visibility::Generated:
3139
39.5k
    case Visibility::Imported:
3140
39.5k
    case Visibility::Foreign:
3141
39.5k
      return false;
3142
73.0k
  }
3143
0
  CM_UNREACHABLE;
3144
0
  return false;
3145
73.0k
}
3146
3147
bool cmTarget::IsForeign() const
3148
157k
{
3149
157k
  switch (this->impl->TargetVisibility) {
3150
0
    case Visibility::Foreign:
3151
0
      return true;
3152
119k
    case Visibility::Normal:
3153
119k
    case Visibility::Generated:
3154
132k
    case Visibility::Imported:
3155
157k
    case Visibility::ImportedGlobally:
3156
157k
      return false;
3157
157k
  }
3158
0
  CM_UNREACHABLE;
3159
0
  return false;
3160
157k
}
3161
3162
bool cmTarget::IsPerConfig() const
3163
0
{
3164
0
  return this->impl->PerConfig;
3165
0
}
3166
3167
bool cmTarget::IsRuntimeBinary() const
3168
0
{
3169
0
  switch (this->GetType()) {
3170
0
    case cm::TargetType::EXECUTABLE:
3171
0
    case cm::TargetType::SHARED_LIBRARY:
3172
0
    case cm::TargetType::MODULE_LIBRARY:
3173
0
      return true;
3174
0
    case cm::TargetType::OBJECT_LIBRARY:
3175
0
    case cm::TargetType::STATIC_LIBRARY:
3176
0
    case cm::TargetType::UTILITY:
3177
0
    case cm::TargetType::INTERFACE_LIBRARY:
3178
0
    case cm::TargetType::GLOBAL_TARGET:
3179
0
    case cm::TargetType::UNKNOWN_LIBRARY:
3180
0
      break;
3181
0
  }
3182
0
  return false;
3183
0
}
3184
3185
bool cmTarget::CanCompileSources() const
3186
112k
{
3187
112k
  if (this->IsImported()) {
3188
49.7k
    return false;
3189
49.7k
  }
3190
63.2k
  if (this->IsSynthetic()) {
3191
0
    return true;
3192
0
  }
3193
63.2k
  switch (this->GetType()) {
3194
26.7k
    case cm::TargetType::EXECUTABLE:
3195
37.8k
    case cm::TargetType::STATIC_LIBRARY:
3196
37.8k
    case cm::TargetType::SHARED_LIBRARY:
3197
37.8k
    case cm::TargetType::MODULE_LIBRARY:
3198
44.9k
    case cm::TargetType::OBJECT_LIBRARY:
3199
44.9k
      return true;
3200
6.02k
    case cm::TargetType::UTILITY:
3201
18.2k
    case cm::TargetType::INTERFACE_LIBRARY:
3202
18.2k
    case cm::TargetType::GLOBAL_TARGET:
3203
18.2k
    case cm::TargetType::UNKNOWN_LIBRARY:
3204
18.2k
      break;
3205
63.2k
  }
3206
18.2k
  return false;
3207
63.2k
}
3208
3209
void cmTarget::SetIsForTryCompile()
3210
0
{
3211
0
  this->impl->IsForTryCompile = true;
3212
0
}
3213
3214
bool cmTarget::IsForTryCompile() const
3215
0
{
3216
0
  return this->impl->IsForTryCompile;
3217
0
}
3218
3219
std::vector<std::string> cmTarget::GetExportTargets() const
3220
0
{
3221
0
  if (this->impl->IsExportPassthrough) {
3222
0
    return cm::remove_BT(this->impl->InterfaceLinkLibraries.Entries);
3223
0
  }
3224
0
  return {};
3225
0
}
3226
3227
char const* cmTarget::GetSuffixVariableInternal(
3228
  cmStateEnums::ArtifactType artifact) const
3229
567
{
3230
567
  switch (this->GetType()) {
3231
402
    case cm::TargetType::STATIC_LIBRARY:
3232
402
      return "CMAKE_STATIC_LIBRARY_SUFFIX";
3233
0
    case cm::TargetType::SHARED_LIBRARY:
3234
0
      switch (artifact) {
3235
0
        case cmStateEnums::RuntimeBinaryArtifact:
3236
0
          return this->IsArchivedAIXSharedLibrary()
3237
0
            ? "CMAKE_SHARED_LIBRARY_ARCHIVE_SUFFIX"
3238
0
            : "CMAKE_SHARED_LIBRARY_SUFFIX";
3239
0
        case cmStateEnums::ImportLibraryArtifact:
3240
0
          return this->IsApple() ? "CMAKE_APPLE_IMPORT_FILE_SUFFIX"
3241
0
                                 : "CMAKE_IMPORT_LIBRARY_SUFFIX";
3242
0
      }
3243
0
      break;
3244
0
    case cm::TargetType::MODULE_LIBRARY:
3245
0
      switch (artifact) {
3246
0
        case cmStateEnums::RuntimeBinaryArtifact:
3247
0
          return "CMAKE_SHARED_MODULE_SUFFIX";
3248
0
        case cmStateEnums::ImportLibraryArtifact:
3249
0
          return "CMAKE_IMPORT_LIBRARY_SUFFIX";
3250
0
      }
3251
0
      break;
3252
165
    case cm::TargetType::EXECUTABLE:
3253
165
      switch (artifact) {
3254
165
        case cmStateEnums::RuntimeBinaryArtifact:
3255
          // Android GUI application packages store the native
3256
          // binary as a shared library.
3257
165
          return (this->IsAndroidGuiExecutable()
3258
165
                    ? "CMAKE_SHARED_LIBRARY_SUFFIX"
3259
165
                    : "CMAKE_EXECUTABLE_SUFFIX");
3260
0
        case cmStateEnums::ImportLibraryArtifact:
3261
0
          return (this->impl->IsAIX ? "CMAKE_AIX_IMPORT_FILE_SUFFIX"
3262
0
                                    : "CMAKE_IMPORT_LIBRARY_SUFFIX");
3263
165
      }
3264
0
      break;
3265
0
    default:
3266
0
      break;
3267
567
  }
3268
0
  return "";
3269
567
}
3270
3271
char const* cmTarget::GetPrefixVariableInternal(
3272
  cmStateEnums::ArtifactType artifact) const
3273
567
{
3274
567
  switch (this->GetType()) {
3275
402
    case cm::TargetType::STATIC_LIBRARY:
3276
402
      return "CMAKE_STATIC_LIBRARY_PREFIX";
3277
0
    case cm::TargetType::SHARED_LIBRARY:
3278
0
      switch (artifact) {
3279
0
        case cmStateEnums::RuntimeBinaryArtifact:
3280
0
          return "CMAKE_SHARED_LIBRARY_PREFIX";
3281
0
        case cmStateEnums::ImportLibraryArtifact:
3282
0
          return this->IsApple() ? "CMAKE_APPLE_IMPORT_FILE_PREFIX"
3283
0
                                 : "CMAKE_IMPORT_LIBRARY_PREFIX";
3284
0
      }
3285
0
      break;
3286
0
    case cm::TargetType::MODULE_LIBRARY:
3287
0
      switch (artifact) {
3288
0
        case cmStateEnums::RuntimeBinaryArtifact:
3289
0
          return "CMAKE_SHARED_MODULE_PREFIX";
3290
0
        case cmStateEnums::ImportLibraryArtifact:
3291
0
          return "CMAKE_IMPORT_LIBRARY_PREFIX";
3292
0
      }
3293
0
      break;
3294
165
    case cm::TargetType::EXECUTABLE:
3295
165
      switch (artifact) {
3296
165
        case cmStateEnums::RuntimeBinaryArtifact:
3297
          // Android GUI application packages store the native
3298
          // binary as a shared library.
3299
165
          return (this->IsAndroidGuiExecutable()
3300
165
                    ? "CMAKE_SHARED_LIBRARY_PREFIX"
3301
165
                    : "");
3302
0
        case cmStateEnums::ImportLibraryArtifact:
3303
0
          return (this->impl->IsAIX ? "CMAKE_AIX_IMPORT_FILE_PREFIX"
3304
0
                                    : "CMAKE_IMPORT_LIBRARY_PREFIX");
3305
165
      }
3306
0
      break;
3307
0
    default:
3308
0
      break;
3309
567
  }
3310
0
  return "";
3311
567
}
3312
3313
std::string cmTarget::ImportedGetFullPath(
3314
  std::string const& config, cmStateEnums::ArtifactType artifact,
3315
  ImportArtifactMissingOk missingOk) const
3316
971
{
3317
971
  assert(this->IsImported());
3318
3319
  // Lookup/compute/cache the import information for this
3320
  // configuration.
3321
971
  std::string desired_config = config;
3322
971
  if (config.empty()) {
3323
49
    desired_config = "NOCONFIG";
3324
49
  }
3325
3326
971
  std::string result;
3327
3328
971
  cmValue loc = nullptr;
3329
971
  cmValue imp = nullptr;
3330
971
  std::string suffix;
3331
3332
971
  if (this->GetType() != cm::TargetType::INTERFACE_LIBRARY &&
3333
971
      this->GetMappedConfig(desired_config, loc, imp, suffix)) {
3334
971
    switch (artifact) {
3335
971
      case cmStateEnums::RuntimeBinaryArtifact:
3336
971
        if (loc) {
3337
971
          result = *loc;
3338
971
        } else if (imp) {
3339
0
          result = *imp;
3340
0
        } else {
3341
0
          std::string impProp = cmStrCat("IMPORTED_LOCATION", suffix);
3342
0
          if (cmValue config_location = this->GetProperty(impProp)) {
3343
0
            result = *config_location;
3344
0
          } else if (cmValue location =
3345
0
                       this->GetProperty("IMPORTED_LOCATION")) {
3346
0
            result = *location;
3347
0
          }
3348
0
          if (result.empty() &&
3349
0
              (this->GetType() == cm::TargetType::SHARED_LIBRARY ||
3350
0
               this->IsExecutableWithExports())) {
3351
0
            impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
3352
0
            if (cmValue config_implib = this->GetProperty(impProp)) {
3353
0
              result = *config_implib;
3354
0
            } else if (cmValue implib = this->GetProperty("IMPORTED_IMPLIB")) {
3355
0
              result = *implib;
3356
0
            }
3357
0
          }
3358
0
        }
3359
971
        if (this->IsApple() &&
3360
0
            (this->impl->TargetType == cm::TargetType::SHARED_LIBRARY ||
3361
0
             this->impl->TargetType == cm::TargetType::STATIC_LIBRARY ||
3362
0
             this->impl->TargetType == cm::TargetType::UNKNOWN_LIBRARY) &&
3363
0
            cmSystemTools::IsPathToXcFramework(result)) {
3364
0
          auto plist = cmParseXcFrameworkPlist(result, *this->impl->Makefile,
3365
0
                                               this->impl->Backtrace);
3366
0
          if (!plist) {
3367
0
            return "";
3368
0
          }
3369
0
          auto const* library = plist->SelectSuitableLibrary(
3370
0
            *this->impl->Makefile, this->impl->Backtrace);
3371
0
          if (library) {
3372
0
            result =
3373
0
              cmStrCat(std::move(result), '/', library->LibraryIdentifier, '/',
3374
0
                       library->LibraryPath);
3375
0
          } else {
3376
0
            return "";
3377
0
          }
3378
0
        }
3379
971
        break;
3380
3381
971
      case cmStateEnums::ImportLibraryArtifact:
3382
0
        if (imp) {
3383
0
          result = *imp;
3384
0
        } else if (this->GetType() == cm::TargetType::SHARED_LIBRARY ||
3385
0
                   this->IsExecutableWithExports()) {
3386
0
          std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
3387
0
          if (cmValue config_implib = this->GetProperty(impProp)) {
3388
0
            result = *config_implib;
3389
0
          } else if (cmValue implib = this->GetProperty("IMPORTED_IMPLIB")) {
3390
0
            result = *implib;
3391
0
          }
3392
0
        }
3393
0
        break;
3394
971
    }
3395
971
  }
3396
3397
971
  if (result.empty() && missingOk != ImportArtifactMissingOk::Yes) {
3398
0
    if (this->GetType() != cm::TargetType::INTERFACE_LIBRARY) {
3399
0
      auto message = [&]() -> std::string {
3400
0
        std::string unset;
3401
0
        std::string configuration;
3402
3403
0
        if (this->GetType() == cm::TargetType::SHARED_LIBRARY &&
3404
0
            artifact == cmStateEnums::RuntimeBinaryArtifact) {
3405
0
          unset = "IMPORTED_LOCATION or IMPORTED_IMPLIB";
3406
0
        } else if (artifact == cmStateEnums::RuntimeBinaryArtifact) {
3407
0
          unset = "IMPORTED_LOCATION";
3408
0
        } else if (artifact == cmStateEnums::ImportLibraryArtifact) {
3409
0
          unset = "IMPORTED_IMPLIB";
3410
0
        }
3411
3412
0
        if (!config.empty()) {
3413
0
          configuration = cmStrCat(" configuration \"", config, '"');
3414
0
        }
3415
3416
0
        return cmStrCat(unset, " not set for imported target \"",
3417
0
                        this->GetName(), '"', configuration, '.');
3418
0
      };
3419
3420
0
      switch (this->GetPolicyStatus(cmPolicies::CMP0111)) {
3421
0
        case cmPolicies::WARN:
3422
0
          this->impl->Makefile->IssuePolicyWarning(cmPolicies::CMP0111, {},
3423
0
                                                   message());
3424
0
          CM_FALLTHROUGH;
3425
0
        case cmPolicies::OLD:
3426
0
          break;
3427
0
        default:
3428
0
          this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
3429
0
                                             message());
3430
0
      }
3431
0
    }
3432
3433
0
    result = cmStrCat(this->GetName(), "-NOTFOUND");
3434
0
  }
3435
971
  return result;
3436
971
}
3437
3438
void cmTarget::SetForeignPackageName(std::string const& name)
3439
0
{
3440
0
  this->impl->ForeignPackageName = name;
3441
0
}
3442
3443
std::string const& cmTarget::GetForeignPackageName() const
3444
0
{
3445
0
  return this->impl->ForeignPackageName;
3446
0
}
3447
3448
void cmTarget::SetForeignTarget(cmTarget* target)
3449
0
{
3450
0
  this->impl->ForeignTarget = target;
3451
0
}
3452
3453
cmTarget* cmTarget::GetForeignTarget() const
3454
0
{
3455
0
  return this->impl->ForeignTarget;
3456
0
}
3457
3458
cmFileSet const* cmTarget::GetFileSet(std::string const& name) const
3459
1
{
3460
1
  auto it = this->impl->FileSets.find(name);
3461
1
  return it == this->impl->FileSets.end() ? nullptr : &it->second;
3462
1
}
3463
3464
cmFileSet* cmTarget::GetFileSet(std::string const& name)
3465
5.92k
{
3466
5.92k
  auto it = this->impl->FileSets.find(name);
3467
5.92k
  return it == this->impl->FileSets.end() ? nullptr : &it->second;
3468
5.92k
}
3469
3470
std::pair<cmFileSet*, bool> cmTarget::GetOrCreateFileSet(
3471
  std::string const& name, std::string const& type,
3472
  cm::FileSetMetadata::Visibility vis, cmMakefile* mf)
3473
9.76k
{
3474
9.76k
  auto result =
3475
9.76k
    this->impl->FileSets.emplace(name, cmFileSet(mf, this, name, type, vis));
3476
9.76k
  if (result.second) {
3477
6.93k
    auto bt = this->impl->Makefile->GetBacktrace();
3478
    // if (cm::contains(this->impl->FileSetTypes, type)) {
3479
6.93k
    if (result.first->second.GetDomain() ==
3480
6.93k
        cm::FileSetMetadata::FileSetDomain::NATIVE) {
3481
6.93k
      this->impl->FileSetTypes.at(type).AddFileSet(name, vis, std::move(bt));
3482
6.93k
    } else {
3483
0
      this->impl->FileSetRules[type].AddFileSet(name, vis, std::move(bt));
3484
0
    }
3485
6.93k
  }
3486
9.76k
  return std::make_pair(&result.first->second, result.second);
3487
9.76k
}
3488
3489
std::string cmTarget::GetFileSetsPropertyName(std::string const& type) const
3490
0
{
3491
0
  if (cm::contains(this->impl->FileSetTypes, type)) {
3492
0
    return std::string{
3493
0
      this->impl->FileSetTypes.at(type).SelfEntries.PropertyName
3494
0
    };
3495
0
  }
3496
0
  return "";
3497
0
}
3498
3499
std::string cmTarget::GetInterfaceFileSetsPropertyName(
3500
  std::string const& type) const
3501
0
{
3502
0
  if (cm::contains(this->impl->FileSetTypes, type)) {
3503
0
    return std::string{
3504
0
      this->impl->FileSetTypes.at(type).InterfaceEntries.PropertyName
3505
0
    };
3506
0
  }
3507
0
  return "";
3508
0
}
3509
3510
std::vector<std::string> cmTarget::GetAllFileSetNames(
3511
  cm::FileSetMetadata::FileSetDomainSet domains) const
3512
0
{
3513
0
  std::vector<std::string> result;
3514
3515
0
  for (auto const& it : this->impl->FileSets) {
3516
0
    if (domains.contains(it.second.GetDomain())) {
3517
0
      result.push_back(it.first);
3518
0
    }
3519
0
  }
3520
3521
0
  return result;
3522
0
}
3523
3524
namespace {
3525
void RetrieveFileSetNames(
3526
  std::unordered_map<cm::string_view, FileSetType> const& fileSetTypes,
3527
  std::function<
3528
    std::vector<BT<std::string>> const&(FileSetType const& fileSetType)>
3529
    GetFileSets,
3530
  std::vector<std::string>& result)
3531
106k
{
3532
106k
  auto inserter = std::back_inserter(result);
3533
3534
320k
  auto appendEntries = [=](std::vector<BT<std::string>> const& entries) {
3535
320k
    for (auto const& entry : entries) {
3536
5.92k
      cmList expanded{ entry.Value };
3537
5.92k
      std::copy(expanded.begin(), expanded.end(), inserter);
3538
5.92k
    }
3539
320k
  };
3540
3541
320k
  for (auto const& fileSetType : fileSetTypes) {
3542
320k
    appendEntries(GetFileSets(fileSetType.second));
3543
320k
  }
3544
106k
}
3545
3546
void RetrieveFileSetNames(
3547
  std::unordered_map<std::string, FileSetRule> const& fileSetRules,
3548
  std::function<
3549
    std::vector<BT<std::string>> const&(FileSetRule const& fileSetRule)>
3550
    GetFileSets,
3551
  std::vector<std::string>& result)
3552
106k
{
3553
106k
  auto appendEntries = [&result](std::vector<BT<std::string>> const& entries) {
3554
0
    for (auto const& entry : entries) {
3555
0
      result.push_back(entry.Value);
3556
0
    }
3557
0
  };
3558
3559
106k
  for (auto const& fileSetRule : fileSetRules) {
3560
0
    appendEntries(GetFileSets(fileSetRule.second));
3561
0
  }
3562
106k
}
3563
}
3564
3565
std::vector<std::string> cmTarget::GetAllPrivateFileSets(
3566
  cm::FileSetMetadata::FileSetDomainSet domains) const
3567
106k
{
3568
106k
  std::vector<std::string> result;
3569
3570
106k
  if (domains.contains(cm::FileSetMetadata::FileSetDomain::NATIVE)) {
3571
53.3k
    RetrieveFileSetNames(
3572
53.3k
      this->impl->FileSetTypes,
3573
53.3k
      [](FileSetType const& fileSetType)
3574
160k
        -> std::vector<BT<std::string>> const& {
3575
160k
        return fileSetType.SelfEntries.Entries;
3576
160k
      },
3577
53.3k
      result);
3578
53.3k
  }
3579
106k
  if (domains.contains(cm::FileSetMetadata::FileSetDomain::RULE)) {
3580
53.3k
    RetrieveFileSetNames(
3581
53.3k
      this->impl->FileSetRules,
3582
53.3k
      [](FileSetRule const& fileSetRule)
3583
53.3k
        -> std::vector<BT<std::string>> const& {
3584
0
        return fileSetRule.SelfEntries;
3585
0
      },
3586
53.3k
      result);
3587
53.3k
  }
3588
3589
106k
  return result;
3590
106k
}
3591
3592
std::vector<std::string> cmTarget::GetAllInterfaceFileSets(
3593
  cm::FileSetMetadata::FileSetDomainSet domains) const
3594
106k
{
3595
106k
  std::vector<std::string> result;
3596
3597
106k
  if (domains.contains(cm::FileSetMetadata::FileSetDomain::NATIVE)) {
3598
53.3k
    RetrieveFileSetNames(
3599
53.3k
      this->impl->FileSetTypes,
3600
53.3k
      [](FileSetType const& fileSetType)
3601
160k
        -> std::vector<BT<std::string>> const& {
3602
160k
        return fileSetType.InterfaceEntries.Entries;
3603
160k
      },
3604
53.3k
      result);
3605
53.3k
  }
3606
106k
  if (domains.contains(cm::FileSetMetadata::FileSetDomain::RULE)) {
3607
53.3k
    RetrieveFileSetNames(
3608
53.3k
      this->impl->FileSetRules,
3609
53.3k
      [](FileSetRule const& fileSetRule)
3610
53.3k
        -> std::vector<BT<std::string>> const& {
3611
0
        return fileSetRule.InterfaceEntries;
3612
0
      },
3613
53.3k
      result);
3614
53.3k
  }
3615
3616
106k
  return result;
3617
106k
}
3618
3619
bool cmTarget::HasFileSets() const
3620
0
{
3621
0
  return !this->impl->FileSets.empty();
3622
0
}
3623
3624
bool cmTargetInternals::CheckImportedLibName(std::string const& prop,
3625
                                             std::string const& value) const
3626
0
{
3627
0
  if (this->TargetType != cm::TargetType::INTERFACE_LIBRARY ||
3628
0
      !this->IsImported()) {
3629
0
    this->Makefile->IssueMessage(
3630
0
      MessageType::FATAL_ERROR,
3631
0
      prop +
3632
0
        " property may be set only on imported INTERFACE library targets.");
3633
0
    return false;
3634
0
  }
3635
0
  if (!value.empty()) {
3636
0
    if (value[0] == '-') {
3637
0
      this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
3638
0
                                   cmStrCat(prop, " property value\n  ", value,
3639
0
                                            "\nmay not start with '-'."));
3640
0
      return false;
3641
0
    }
3642
0
    std::string::size_type bad = value.find_first_of(":/\\;");
3643
0
    if (bad != std::string::npos) {
3644
0
      this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
3645
0
                                   cmStrCat(prop, " property value\n  ", value,
3646
0
                                            "\nmay not contain '",
3647
0
                                            value.substr(bad, 1), "'."));
3648
0
      return false;
3649
0
    }
3650
0
  }
3651
0
  return true;
3652
0
}
3653
3654
bool cmTarget::GetMappedConfig(std::string const& desiredConfig, cmValue& loc,
3655
                               cmValue& imp, std::string& suffix) const
3656
3.54k
{
3657
3.54k
  switch (this->GetPolicyStatusCMP0200()) {
3658
3.54k
    case cmPolicies::WARN:
3659
3.54k
      if (this->GetMakefile()->PolicyOptionalWarningEnabled(
3660
3.54k
            "CMAKE_POLICY_WARNING_CMP0200")) {
3661
0
        break;
3662
0
      }
3663
3.54k
      CM_FALLTHROUGH;
3664
3.54k
    case cmPolicies::OLD:
3665
3.54k
      return this->GetMappedConfigOld(desiredConfig, loc, imp, suffix);
3666
0
    case cmPolicies::NEW:
3667
0
      return this->GetMappedConfigNew(desiredConfig, loc, imp, suffix);
3668
3.54k
  }
3669
3670
0
  cmValue newLoc;
3671
0
  cmValue newImp;
3672
0
  std::string newSuffix;
3673
3674
0
  bool const newResult =
3675
0
    this->GetMappedConfigNew(desiredConfig, newLoc, newImp, newSuffix);
3676
3677
0
  auto configFromSuffix = [](cm::string_view s) -> cm::string_view {
3678
0
    return s.empty() ? "(none)"_s : s.substr(1);
3679
0
  };
3680
3681
0
  if (!this->GetMappedConfigOld(desiredConfig, loc, imp, suffix)) {
3682
0
    if (newResult) {
3683
      // NEW policy found a configuration, OLD did not.
3684
0
      cm::string_view newConfig = configFromSuffix(newSuffix);
3685
0
      this->GetMakefile()->IssuePolicyWarning(
3686
0
        cmPolicies::CMP0200, {},
3687
0
        cmStrCat("Configuration selection for imported target \""_s,
3688
0
                 this->GetName(),
3689
0
                 "\" failed, but would select configuration \""_s, newConfig,
3690
0
                 "\" under the NEW policy."_s));
3691
0
    }
3692
3693
0
    return false;
3694
0
  }
3695
3696
0
  cm::string_view oldConfig = configFromSuffix(suffix);
3697
0
  if (!newResult) {
3698
    // NEW policy did not find a configuration, OLD did.
3699
0
    this->GetMakefile()->IssuePolicyWarning(
3700
0
      cmPolicies::CMP0200, {},
3701
0
      cmStrCat("Configuration selection for imported target \""_s,
3702
0
               this->GetName(), "\" selected configuration \""_s, oldConfig,
3703
0
               "\", but would fail under the NEW policy."_s));
3704
0
  } else if (suffix != newSuffix) {
3705
    // OLD and NEW policies found different configurations.
3706
0
    cm::string_view newConfig = configFromSuffix(newSuffix);
3707
0
    this->GetMakefile()->IssuePolicyWarning(
3708
0
      cmPolicies::CMP0200, {},
3709
0
      cmStrCat("Configuration selection for imported target \""_s,
3710
0
               this->GetName(), "\" selected configuration \""_s, oldConfig,
3711
0
               "\", but would select configuration \""_s, newConfig,
3712
0
               "\" under the NEW policy."_s));
3713
0
  }
3714
3715
0
  return true;
3716
0
}
3717
3718
bool cmTarget::GetMappedConfigOld(std::string const& desired_config,
3719
                                  cmValue& loc, cmValue& imp,
3720
                                  std::string& suffix) const
3721
3.54k
{
3722
3.54k
  std::string config_upper;
3723
3.54k
  if (!desired_config.empty()) {
3724
3.53k
    config_upper = cmSystemTools::UpperCase(desired_config);
3725
3.53k
  }
3726
3727
3.54k
  std::string locPropBase;
3728
3.54k
  if (this->GetType() == cm::TargetType::INTERFACE_LIBRARY) {
3729
0
    locPropBase = "IMPORTED_LIBNAME";
3730
3.54k
  } else if (this->GetType() == cm::TargetType::OBJECT_LIBRARY) {
3731
0
    locPropBase = "IMPORTED_OBJECTS";
3732
3.54k
  } else {
3733
3.54k
    locPropBase = "IMPORTED_LOCATION";
3734
3.54k
  }
3735
3736
  // Track the configuration-specific property suffix.
3737
3.54k
  suffix = cmStrCat('_', config_upper);
3738
3739
3.54k
  cmList mappedConfigs;
3740
3.54k
  {
3741
3.54k
    std::string mapProp = cmStrCat("MAP_IMPORTED_CONFIG_", config_upper);
3742
3.54k
    if (cmValue mapValue = this->GetProperty(mapProp)) {
3743
394
      mappedConfigs.assign(*mapValue, cmList::EmptyElements::Yes);
3744
394
    }
3745
3.54k
  }
3746
3747
  // If we needed to find one of the mapped configurations but did not
3748
  // There may be only IMPORTED_IMPLIB for a shared library or an executable
3749
  // with exports.
3750
3.54k
  bool allowImp = (this->GetType() == cm::TargetType::SHARED_LIBRARY ||
3751
1.35k
                   this->IsExecutableWithExports()) ||
3752
1.35k
    (this->IsAIX() && this->IsExecutableWithExports()) ||
3753
1.35k
    (this->GetMakefile()->PlatformSupportsAppleTextStubs() &&
3754
0
     this->IsSharedLibraryWithExports());
3755
3756
  // If a mapping was found, check its configurations.
3757
3.54k
  for (auto mci = mappedConfigs.begin();
3758
3.93k
       !loc && !imp && mci != mappedConfigs.end(); ++mci) {
3759
    // Look for this configuration.
3760
394
    if (mci->empty()) {
3761
      // An empty string in the mapping has a special meaning:
3762
      // look up the config-less properties.
3763
0
      loc = this->GetProperty(locPropBase);
3764
0
      if (allowImp) {
3765
0
        imp = this->GetProperty("IMPORTED_IMPLIB");
3766
0
      }
3767
      // If it was found, set the suffix.
3768
0
      if (loc || imp) {
3769
0
        suffix.clear();
3770
0
      }
3771
394
    } else {
3772
394
      std::string mcUpper = cmSystemTools::UpperCase(*mci);
3773
394
      std::string locProp = cmStrCat(locPropBase, '_', mcUpper);
3774
394
      loc = this->GetProperty(locProp);
3775
394
      if (allowImp) {
3776
0
        std::string impProp = cmStrCat("IMPORTED_IMPLIB_", mcUpper);
3777
0
        imp = this->GetProperty(impProp);
3778
0
      }
3779
3780
      // If it was found, use it for all properties below.
3781
394
      if (loc || imp) {
3782
394
        suffix = cmStrCat('_', mcUpper);
3783
394
      }
3784
394
    }
3785
394
  }
3786
3787
  // If we needed to find one of the mapped configurations but did not
3788
  // then the target location is not found.  The project does not want
3789
  // any other configuration.
3790
3.54k
  if (!mappedConfigs.empty() && !loc && !imp) {
3791
    // Interface libraries are always available because their
3792
    // library name is optional so it is okay to leave loc empty.
3793
0
    return this->GetType() == cm::TargetType::INTERFACE_LIBRARY;
3794
0
  }
3795
3796
  // If we have not yet found it then there are no mapped
3797
  // configurations.  Look for an exact-match.
3798
3.54k
  if (!loc && !imp) {
3799
3.15k
    std::string locProp = cmStrCat(locPropBase, suffix);
3800
3.15k
    loc = this->GetProperty(locProp);
3801
3.15k
    if (allowImp) {
3802
2.19k
      std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
3803
2.19k
      imp = this->GetProperty(impProp);
3804
2.19k
    }
3805
3.15k
  }
3806
3807
  // If we have not yet found it then there are no mapped
3808
  // configurations and no exact match.
3809
3.54k
  if (!loc && !imp) {
3810
    // The suffix computed above is not useful.
3811
2.39k
    suffix.clear();
3812
3813
    // Look for a configuration-less location.  This may be set by
3814
    // manually-written code.
3815
2.39k
    loc = this->GetProperty(locPropBase);
3816
2.39k
    if (allowImp) {
3817
2.19k
      imp = this->GetProperty("IMPORTED_IMPLIB");
3818
2.19k
    }
3819
2.39k
  }
3820
3821
  // If we have not yet found it then the project is willing to try
3822
  // any available configuration.
3823
3.54k
  if (!loc && !imp) {
3824
199
    cmList availableConfigs;
3825
199
    if (cmValue iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS")) {
3826
199
      availableConfigs.assign(*iconfigs);
3827
199
    }
3828
199
    for (auto it = availableConfigs.begin();
3829
398
         !loc && !imp && it != availableConfigs.end(); ++it) {
3830
199
      suffix = cmStrCat('_', cmSystemTools::UpperCase(*it));
3831
199
      std::string locProp = cmStrCat(locPropBase, suffix);
3832
199
      loc = this->GetProperty(locProp);
3833
199
      if (allowImp) {
3834
0
        std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
3835
0
        imp = this->GetProperty(impProp);
3836
0
      }
3837
199
    }
3838
199
  }
3839
  // If we have not yet found it then the target location is not available.
3840
3.54k
  if (!loc && !imp) {
3841
    // Interface libraries are always available because their
3842
    // library name is optional so it is okay to leave loc empty.
3843
0
    return this->GetType() == cm::TargetType::INTERFACE_LIBRARY;
3844
0
  }
3845
3846
3.54k
  return true;
3847
3.54k
}
3848
3849
cmValue cmTarget::GetLocation(std::string const& base,
3850
                              std::string const& suffix) const
3851
0
{
3852
0
  cmValue value = this->GetProperty(cmStrCat(base, suffix));
3853
0
  if (value || suffix.empty()) {
3854
0
    return value;
3855
0
  }
3856
0
  return this->GetProperty(base);
3857
0
}
3858
3859
bool cmTarget::GetLocation(std::string const& config, cmValue& loc,
3860
                           cmValue& imp, std::string& suffix) const
3861
0
{
3862
0
  suffix = (config.empty() ? std::string{} : cmStrCat('_', config));
3863
3864
  // There may be only IMPORTED_IMPLIB for a shared library or an executable
3865
  // with exports.
3866
0
  bool const allowImp = (this->GetType() == cm::TargetType::SHARED_LIBRARY ||
3867
0
                         this->IsExecutableWithExports()) ||
3868
0
    (this->IsAIX() && this->IsExecutableWithExports()) ||
3869
0
    (this->GetMakefile()->PlatformSupportsAppleTextStubs() &&
3870
0
     this->IsSharedLibraryWithExports());
3871
3872
0
  if (allowImp) {
3873
0
    imp = this->GetLocation("IMPORTED_IMPLIB", suffix);
3874
0
  }
3875
3876
0
  switch (this->GetType()) {
3877
0
    case cm::TargetType::INTERFACE_LIBRARY:
3878
0
      loc = this->GetLocation("IMPORTED_LIBNAME", suffix);
3879
0
      break;
3880
0
    case cm::TargetType::OBJECT_LIBRARY:
3881
0
      loc = this->GetLocation("IMPORTED_OBJECTS", suffix);
3882
0
      break;
3883
0
    default:
3884
0
      loc = this->GetLocation("IMPORTED_LOCATION", suffix);
3885
0
      break;
3886
0
  }
3887
3888
0
  return loc || imp || (this->GetType() == cm::TargetType::INTERFACE_LIBRARY);
3889
0
}
3890
3891
bool cmTarget::GetMappedConfigNew(std::string desiredConfig, cmValue& loc,
3892
                                  cmValue& imp, std::string& suffix) const
3893
0
{
3894
0
  desiredConfig = cmSystemTools::UpperCase(desiredConfig);
3895
3896
  // Get configuration mapping, if present.
3897
0
  cmList mappedConfigs;
3898
0
  if (!desiredConfig.empty()) {
3899
0
    std::string mapProp = cmStrCat("MAP_IMPORTED_CONFIG_", desiredConfig);
3900
0
    if (cmValue mapValue = this->GetProperty(mapProp)) {
3901
0
      mappedConfigs.assign(cmSystemTools::UpperCase(*mapValue),
3902
0
                           cmList::EmptyElements::Yes);
3903
0
    }
3904
0
  }
3905
3906
  // Get imported configurations, if specified.
3907
0
  cmValue const iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS");
3908
0
  if (!iconfigs.IsEmpty()) {
3909
0
    cmList const availableConfigs{ cmSystemTools::UpperCase(*iconfigs) };
3910
3911
0
    if (!mappedConfigs.empty()) {
3912
0
      for (auto const& c : mappedConfigs) {
3913
0
        if (cm::contains(availableConfigs, c)) {
3914
0
          this->GetLocation(c, loc, imp, suffix);
3915
0
          return true;
3916
0
        }
3917
0
      }
3918
3919
      // If a configuration mapping was specified, but no matching
3920
      // configuration was found, we don't want to try anything else.
3921
0
      return false;
3922
0
    }
3923
3924
    // There is no mapping; try the requested configuration first.
3925
0
    if (cm::contains(availableConfigs, desiredConfig)) {
3926
0
      this->GetLocation(desiredConfig, loc, imp, suffix);
3927
0
      return true;
3928
0
    }
3929
3930
    // If there is no mapping and the requested configuration is not one of
3931
    // the available configurations, just take the first available
3932
    // configuration.
3933
0
    this->GetLocation(availableConfigs[0], loc, imp, suffix);
3934
0
    return true;
3935
0
  }
3936
3937
0
  if (!mappedConfigs.empty()) {
3938
0
    for (auto const& c : mappedConfigs) {
3939
0
      if (this->GetLocation(c, loc, imp, suffix)) {
3940
0
        return true;
3941
0
      }
3942
0
    }
3943
3944
    // If a configuration mapping was specified, but no matching
3945
    // configuration was found, we don't want to try anything else.
3946
0
    return false;
3947
0
  }
3948
3949
  // There is no mapping and no explicit list of configurations; the only
3950
  // configuration left to try is the requested configuration.
3951
0
  if (this->GetLocation(desiredConfig, loc, imp, suffix)) {
3952
0
    return true;
3953
0
  }
3954
3955
0
  return false;
3956
0
}