Coverage Report

Created: 2026-09-14 06:43

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