Coverage Report

Created: 2026-06-15 07:03

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