1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2 file Copyright.txt or https://cmake.org/licensing for details. */ 3 #pragma once 4 5 #include "cmConfigure.h" // IWYU pragma: keep 6 7 #include <cstddef> 8 #include <map> 9 #include <memory> 10 #include <set> 11 #include <string> 12 #include <unordered_map> 13 #include <unordered_set> 14 #include <utility> 15 #include <vector> 16 17 #include <cm/optional> 18 19 #include "cmLinkItem.h" 20 #include "cmListFileCache.h" 21 #include "cmPolicies.h" 22 #include "cmStateTypes.h" 23 #include "cmValue.h" 24 25 class cmComputeLinkInformation; 26 class cmCustomCommand; 27 class cmGlobalGenerator; 28 class cmLocalGenerator; 29 class cmMakefile; 30 class cmSourceFile; 31 class cmTarget; 32 33 struct cmGeneratorExpressionContext; 34 struct cmGeneratorExpressionDAGChecker; 35 36 class cmGeneratorTarget 37 { 38 public: 39 cmGeneratorTarget(cmTarget*, cmLocalGenerator* lg); 40 ~cmGeneratorTarget(); 41 42 cmGeneratorTarget(cmGeneratorTarget const&) = delete; 43 cmGeneratorTarget& operator=(cmGeneratorTarget const&) = delete; 44 45 cmLocalGenerator* GetLocalGenerator() const; 46 47 cmGlobalGenerator* GetGlobalGenerator() const; 48 49 bool IsInBuildSystem() const; 50 bool IsImported() const; 51 bool IsImportedGloballyVisible() const; 52 bool CanCompileSources() const; 53 const std::string& GetLocation(const std::string& config) const; 54 55 /** Get the full path to the target's main artifact, if known. */ 56 cm::optional<std::string> MaybeGetLocation(std::string const& config) const; 57 58 std::vector<cmCustomCommand> const& GetPreBuildCommands() const; 59 std::vector<cmCustomCommand> const& GetPreLinkCommands() const; 60 std::vector<cmCustomCommand> const& GetPostBuildCommands() const; 61 62 void AppendCustomCommandSideEffects( 63 std::set<cmGeneratorTarget const*>& sideEffects) const; 64 void AppendLanguageSideEffects( 65 std::map<std::string, std::set<cmGeneratorTarget const*>>& sideEffects) 66 const; 67 68 #define DECLARE_TARGET_POLICY(POLICY) \ 69 cmPolicies::PolicyStatus GetPolicyStatus##POLICY() const \ 70 { \ 71 return this->PolicyMap.Get(cmPolicies::POLICY); \ 72 } 73 74 CM_FOR_EACH_TARGET_POLICY(DECLARE_TARGET_POLICY) 75 76 #undef DECLARE_TARGET_POLICY 77 78 /** Get the location of the target in the build tree with a placeholder 79 referencing the configuration in the native build system. This 80 location is suitable for use as the LOCATION target property. */ 81 const std::string& GetLocationForBuild() const; 82 83 cmComputeLinkInformation* GetLinkInformation( 84 const std::string& config) const; 85 86 cmStateEnums::TargetType GetType() const; 87 const std::string& GetName() const; 88 std::string GetExportName() const; 89 90 std::vector<std::string> GetPropertyKeys() const; 91 //! Might return a nullptr if the property is not set or invalid 92 cmValue GetProperty(const std::string& prop) const; 93 //! Always returns a valid pointer 94 std::string const& GetSafeProperty(std::string const& prop) const; 95 bool GetPropertyAsBool(const std::string& prop) const; 96 void GetSourceFiles(std::vector<cmSourceFile*>& files, 97 const std::string& config) const; 98 std::vector<BT<cmSourceFile*>> GetSourceFiles( 99 std::string const& config) const; 100 101 /** Source file kinds (classifications). 102 Generators use this to decide how to treat a source file. */ 103 enum SourceKind 104 { 105 SourceKindAppManifest, 106 SourceKindCertificate, 107 SourceKindCustomCommand, 108 SourceKindExternalObject, 109 SourceKindExtra, 110 SourceKindHeader, 111 SourceKindIDL, 112 SourceKindManifest, 113 SourceKindModuleDefinition, 114 SourceKindObjectSource, 115 SourceKindResx, 116 SourceKindXaml, 117 SourceKindUnityBatched 118 }; 119 120 /** A source file paired with a kind (classification). */ 121 struct SourceAndKind 122 { 123 BT<cmSourceFile*> Source; 124 SourceKind Kind; 125 }; 126 127 /** All sources needed for a configuration with kinds assigned. */ 128 struct KindedSources 129 { 130 std::vector<SourceAndKind> Sources; 131 bool Initialized = false; 132 }; 133 134 /** Get all sources needed for a configuration with kinds assigned. */ 135 KindedSources const& GetKindedSources(std::string const& config) const; 136 137 struct AllConfigSource 138 { 139 cmSourceFile* Source; 140 cmGeneratorTarget::SourceKind Kind; 141 std::vector<size_t> Configs; 142 }; 143 144 /** Get all sources needed for all configurations with kinds and 145 per-source configurations assigned. */ 146 std::vector<AllConfigSource> const& GetAllConfigSources() const; 147 148 /** Get all sources needed for all configurations with given kind. */ 149 std::vector<AllConfigSource> GetAllConfigSources(SourceKind kind) const; 150 151 /** Get all languages used to compile sources in any configuration. 152 This excludes the languages of objects from object libraries. */ 153 std::set<std::string> GetAllConfigCompileLanguages() const; 154 155 void GetObjectSources(std::vector<cmSourceFile const*>&, 156 const std::string& config) const; 157 const std::string& GetObjectName(cmSourceFile const* file); 158 const char* GetCustomObjectExtension() const; 159 160 bool HasExplicitObjectName(cmSourceFile const* file) const; 161 void AddExplicitObjectName(cmSourceFile const* sf); 162 163 BTs<std::string> const* GetLanguageStandardProperty( 164 std::string const& lang, std::string const& config) const; 165 166 cmValue GetLanguageStandard(std::string const& lang, 167 std::string const& config) const; 168 169 cmValue GetLanguageExtensions(std::string const& lang) const; 170 171 bool GetLanguageStandardRequired(std::string const& lang) const; 172 173 void GetModuleDefinitionSources(std::vector<cmSourceFile const*>&, 174 const std::string& config) const; 175 void GetExternalObjects(std::vector<cmSourceFile const*>&, 176 const std::string& config) const; 177 void GetHeaderSources(std::vector<cmSourceFile const*>&, 178 const std::string& config) const; 179 void GetExtraSources(std::vector<cmSourceFile const*>&, 180 const std::string& config) const; 181 void GetCustomCommands(std::vector<cmSourceFile const*>&, 182 const std::string& config) const; 183 void GetManifests(std::vector<cmSourceFile const*>&, 184 const std::string& config) const; 185 186 std::set<cmLinkItem> const& GetUtilityItems() const; 187 188 void ComputeObjectMapping(); 189 190 cmValue GetFeature(const std::string& feature, 191 const std::string& config) const; 192 193 const char* GetLinkPIEProperty(const std::string& config) const; 194 195 bool IsIPOEnabled(std::string const& lang, std::string const& config) const; 196 197 bool IsLinkInterfaceDependentBoolProperty(const std::string& p, 198 const std::string& config) const; 199 bool IsLinkInterfaceDependentStringProperty(const std::string& p, 200 const std::string& config) const; 201 bool IsLinkInterfaceDependentNumberMinProperty( 202 const std::string& p, const std::string& config) const; 203 bool IsLinkInterfaceDependentNumberMaxProperty( 204 const std::string& p, const std::string& config) const; 205 206 bool GetLinkInterfaceDependentBoolProperty(const std::string& p, 207 const std::string& config) const; 208 209 const char* GetLinkInterfaceDependentStringProperty( 210 const std::string& p, const std::string& config) const; 211 const char* GetLinkInterfaceDependentNumberMinProperty( 212 const std::string& p, const std::string& config) const; 213 const char* GetLinkInterfaceDependentNumberMaxProperty( 214 const std::string& p, const std::string& config) const; 215 216 class DeviceLinkSetter 217 { 218 public: DeviceLinkSetter(cmGeneratorTarget & target)219 DeviceLinkSetter(cmGeneratorTarget& target) 220 : Target(target) 221 { 222 this->PreviousState = target.SetDeviceLink(true); 223 } ~DeviceLinkSetter()224 ~DeviceLinkSetter() { this->Target.SetDeviceLink(this->PreviousState); } 225 226 private: 227 cmGeneratorTarget& Target; 228 bool PreviousState; 229 }; 230 231 bool SetDeviceLink(bool deviceLink); IsDeviceLink()232 bool IsDeviceLink() const { return this->DeviceLink; } 233 234 cmLinkInterface const* GetLinkInterface( 235 const std::string& config, const cmGeneratorTarget* headTarget) const; 236 void ComputeLinkInterface(const std::string& config, 237 cmOptionalLinkInterface& iface, 238 const cmGeneratorTarget* head) const; 239 240 cmLinkInterfaceLibraries const* GetLinkInterfaceLibraries( 241 const std::string& config, const cmGeneratorTarget* headTarget, 242 bool usage_requirements_only) const; 243 244 void ComputeLinkInterfaceLibraries(const std::string& config, 245 cmOptionalLinkInterface& iface, 246 const cmGeneratorTarget* head, 247 bool usage_requirements_only) const; 248 249 /** Get the library name for an imported interface library. */ 250 std::string GetImportedLibName(std::string const& config) const; 251 252 /** Get the full path to the target according to the settings in its 253 makefile and the configuration type. */ 254 std::string GetFullPath( 255 const std::string& config, 256 cmStateEnums::ArtifactType artifact = cmStateEnums::RuntimeBinaryArtifact, 257 bool realname = false) const; 258 std::string NormalGetFullPath(const std::string& config, 259 cmStateEnums::ArtifactType artifact, 260 bool realname) const; 261 std::string NormalGetRealName(const std::string& config) const; 262 263 /** Get the names of an object library's object files underneath 264 its object file directory. */ 265 void GetTargetObjectNames(std::string const& config, 266 std::vector<std::string>& objects) const; 267 268 /** What hierarchy level should the reported directory contain */ 269 enum BundleDirectoryLevel 270 { 271 BundleDirLevel, 272 ContentLevel, 273 FullLevel 274 }; 275 276 /** @return the Mac App directory without the base */ 277 std::string GetAppBundleDirectory(const std::string& config, 278 BundleDirectoryLevel level) const; 279 280 /** Return whether this target is marked as deprecated by the 281 maintainer */ 282 bool IsDeprecated() const; 283 284 /** Returns the deprecation message provided by the maintainer */ 285 std::string GetDeprecation() const; 286 287 /** Return whether this target is an executable Bundle, a framework 288 or CFBundle on Apple. */ 289 bool IsBundleOnApple() const; 290 291 /** Return whether this target is a Win32 executable */ 292 bool IsWin32Executable(const std::string& config) const; 293 294 /** Get the full name of the target according to the settings in its 295 makefile. */ 296 std::string GetFullName(const std::string& config, 297 cmStateEnums::ArtifactType artifact = 298 cmStateEnums::RuntimeBinaryArtifact) const; 299 300 /** @return the Mac framework directory without the base. */ 301 std::string GetFrameworkDirectory(const std::string& config, 302 BundleDirectoryLevel level) const; 303 304 /** Return the framework version string. Undefined if 305 IsFrameworkOnApple returns false. */ 306 std::string GetFrameworkVersion() const; 307 308 /** @return the Mac CFBundle directory without the base */ 309 std::string GetCFBundleDirectory(const std::string& config, 310 BundleDirectoryLevel level) const; 311 312 /** Return the install name directory for the target in the 313 * build tree. For example: "\@rpath/", "\@loader_path/", 314 * or "/full/path/to/library". */ 315 std::string GetInstallNameDirForBuildTree(const std::string& config) const; 316 317 /** Return the install name directory for the target in the 318 * install tree. For example: "\@rpath/" or "\@loader_path/". */ 319 std::string GetInstallNameDirForInstallTree( 320 const std::string& config, const std::string& installPrefix) const; 321 322 cmListFileBacktrace GetBacktrace() const; 323 324 std::set<BT<std::pair<std::string, bool>>> const& GetUtilities() const; 325 LinkLanguagePropagatesToDependents()326 bool LinkLanguagePropagatesToDependents() const 327 { 328 return this->GetType() == cmStateEnums::STATIC_LIBRARY; 329 } 330 331 /** Get the macro to define when building sources in this target. 332 If no macro should be defined null is returned. */ 333 const std::string* GetExportMacro() const; 334 335 /** Get the soname of the target. Allowed only for a shared library. */ 336 std::string GetSOName(const std::string& config) const; 337 338 void GetFullNameComponents(std::string& prefix, std::string& base, 339 std::string& suffix, const std::string& config, 340 cmStateEnums::ArtifactType artifact = 341 cmStateEnums::RuntimeBinaryArtifact) const; 342 343 /** Append to @a base the bundle directory hierarchy up to a certain @a level 344 * and return it. */ 345 std::string BuildBundleDirectory(const std::string& base, 346 const std::string& config, 347 BundleDirectoryLevel level) const; 348 349 /** @return the mac content directory for this target. */ 350 std::string GetMacContentDirectory( 351 const std::string& config, cmStateEnums::ArtifactType artifact) const; 352 353 /** @return folder prefix for IDEs. */ 354 std::string GetEffectiveFolderName() const; 355 356 cmTarget* Target; 357 cmMakefile* Makefile; 358 cmLocalGenerator* LocalGenerator; 359 cmGlobalGenerator const* GlobalGenerator; 360 361 struct ModuleDefinitionInfo 362 { 363 std::string DefFile; 364 bool DefFileGenerated; 365 bool WindowsExportAllSymbols; 366 std::vector<cmSourceFile const*> Sources; 367 }; 368 ModuleDefinitionInfo const* GetModuleDefinitionInfo( 369 std::string const& config) const; 370 371 /** Return whether or not the target is for a DLL platform. */ 372 bool IsDLLPlatform() const; 373 374 /** @return whether this target have a well defined output file name. */ 375 bool HaveWellDefinedOutputFiles() const; 376 377 /** Link information from the transitive closure of the link 378 implementation and the interfaces of its dependencies. */ 379 struct LinkClosure 380 { 381 // The preferred linker language. 382 std::string LinkerLanguage; 383 384 // Languages whose runtime libraries must be linked. 385 std::vector<std::string> Languages; 386 }; 387 388 LinkClosure const* GetLinkClosure(const std::string& config) const; 389 390 cmLinkImplementation const* GetLinkImplementation( 391 const std::string& config) const; 392 393 void ComputeLinkImplementationLanguages( 394 const std::string& config, cmOptionalLinkImplementation& impl) const; 395 396 cmLinkImplementationLibraries const* GetLinkImplementationLibraries( 397 const std::string& config) const; 398 399 void ComputeLinkImplementationLibraries(const std::string& config, 400 cmOptionalLinkImplementation& impl, 401 const cmGeneratorTarget* head) const; 402 403 struct TargetOrString 404 { 405 std::string String; 406 cmGeneratorTarget* Target = nullptr; 407 }; 408 TargetOrString ResolveTargetReference(std::string const& name) const; 409 TargetOrString ResolveTargetReference(std::string const& name, 410 cmLocalGenerator const* lg) const; 411 412 cmLinkItem ResolveLinkItem(BT<std::string> const& name) const; 413 cmLinkItem ResolveLinkItem(BT<std::string> const& name, 414 cmLocalGenerator const* lg) const; 415 416 // Compute the set of languages compiled by the target. This is 417 // computed every time it is called because the languages can change 418 // when source file properties are changed and we do not have enough 419 // information to forward these property changes to the targets 420 // until we have per-target object file properties. 421 void GetLanguages(std::set<std::string>& languages, 422 std::string const& config) const; 423 bool IsLanguageUsed(std::string const& language, 424 std::string const& config) const; 425 426 bool IsCSharpOnly() const; 427 428 void GetObjectLibrariesCMP0026( 429 std::vector<cmGeneratorTarget*>& objlibs) const; 430 431 std::string GetFullNameImported(const std::string& config, 432 cmStateEnums::ArtifactType artifact) const; 433 434 /** Get source files common to all configurations and diagnose cases 435 with per-config sources. Excludes sources added by a TARGET_OBJECTS 436 generator expression. Do not use outside the Xcode generator. */ 437 bool GetConfigCommonSourceFilesForXcode( 438 std::vector<cmSourceFile*>& files) const; 439 440 bool HaveBuildTreeRPATH(const std::string& config) const; 441 442 /** Full path with trailing slash to the top-level directory 443 holding object files for this target. Includes the build 444 time config name placeholder if needed for the generator. */ 445 std::string ObjectDirectory; 446 447 /** Full path with trailing slash to the top-level directory 448 holding object files for the given configuration. */ 449 std::string GetObjectDirectory(std::string const& config) const; 450 451 void GetAppleArchs(const std::string& config, 452 std::vector<std::string>& archVec) const; 453 454 void AddExplicitLanguageFlags(std::string& flags, 455 cmSourceFile const& sf) const; 456 457 void AddCUDAArchitectureFlags(std::string& flags) const; 458 void AddCUDAToolkitFlags(std::string& flags) const; 459 460 void AddHIPArchitectureFlags(std::string& flags) const; 461 462 void AddISPCTargetFlags(std::string& flags) const; 463 464 std::string GetFeatureSpecificLinkRuleVariable( 465 std::string const& var, std::string const& lang, 466 std::string const& config) const; 467 468 /** Return the rule variable used to create this type of target. */ 469 std::string GetCreateRuleVariable(std::string const& lang, 470 std::string const& config) const; 471 472 /** Get the include directories for this target. */ 473 std::vector<BT<std::string>> GetIncludeDirectories( 474 const std::string& config, const std::string& lang) const; 475 476 void GetCompileOptions(std::vector<std::string>& result, 477 const std::string& config, 478 const std::string& language) const; 479 std::vector<BT<std::string>> GetCompileOptions( 480 std::string const& config, std::string const& language) const; 481 482 void GetCompileFeatures(std::vector<std::string>& features, 483 const std::string& config) const; 484 std::vector<BT<std::string>> GetCompileFeatures( 485 std::string const& config) const; 486 487 void GetCompileDefinitions(std::vector<std::string>& result, 488 const std::string& config, 489 const std::string& language) const; 490 std::vector<BT<std::string>> GetCompileDefinitions( 491 std::string const& config, std::string const& language) const; 492 493 void GetLinkOptions(std::vector<std::string>& result, 494 const std::string& config, 495 const std::string& language) const; 496 std::vector<BT<std::string>> GetLinkOptions( 497 std::string const& config, std::string const& language) const; 498 499 std::vector<BT<std::string>>& ResolveLinkerWrapper( 500 std::vector<BT<std::string>>& result, const std::string& language) const; 501 502 void GetStaticLibraryLinkOptions(std::vector<std::string>& result, 503 const std::string& config, 504 const std::string& language) const; 505 std::vector<BT<std::string>> GetStaticLibraryLinkOptions( 506 std::string const& config, std::string const& language) const; 507 508 void GetLinkDirectories(std::vector<std::string>& result, 509 const std::string& config, 510 const std::string& language) const; 511 std::vector<BT<std::string>> GetLinkDirectories( 512 std::string const& config, std::string const& language) const; 513 514 void GetLinkDepends(std::vector<std::string>& result, 515 const std::string& config, 516 const std::string& language) const; 517 std::vector<BT<std::string>> GetLinkDepends( 518 std::string const& config, std::string const& language) const; 519 520 std::vector<BT<std::string>> GetPrecompileHeaders( 521 const std::string& config, const std::string& language) const; 522 523 std::string GetPchHeader(const std::string& config, 524 const std::string& language, 525 const std::string& arch = std::string()) const; 526 std::string GetPchSource(const std::string& config, 527 const std::string& language, 528 const std::string& arch = std::string()) const; 529 std::string GetPchFileObject(const std::string& config, 530 const std::string& language, 531 const std::string& arch = std::string()); 532 std::string GetPchFile(const std::string& config, 533 const std::string& language, 534 const std::string& arch = std::string()); 535 std::string GetPchCreateCompileOptions( 536 const std::string& config, const std::string& language, 537 const std::string& arch = std::string()); 538 std::string GetPchUseCompileOptions(const std::string& config, 539 const std::string& language, 540 const std::string& arch = std::string()); 541 542 void AddSourceFileToUnityBatch(const std::string& sourceFilename); 543 bool IsSourceFilePartOfUnityBatch(const std::string& sourceFilename) const; 544 545 bool IsSystemIncludeDirectory(const std::string& dir, 546 const std::string& config, 547 const std::string& language) const; 548 549 /** Add the target output files to the global generator manifest. */ 550 void ComputeTargetManifest(const std::string& config) const; 551 552 bool ComputeCompileFeatures(std::string const& config) const; 553 554 using LanguagePair = std::pair<std::string, std::string>; 555 bool ComputeCompileFeatures( 556 std::string const& config, 557 std::set<LanguagePair> const& languagePairs) const; 558 559 /** 560 * Trace through the source files in this target and add al source files 561 * that they depend on, used by all generators 562 */ 563 void TraceDependencies(); 564 565 /** Get the directory in which this target will be built. If the 566 configuration name is given then the generator will add its 567 subdirectory for that configuration. Otherwise just the canonical 568 output directory is given. */ 569 std::string GetDirectory(const std::string& config, 570 cmStateEnums::ArtifactType artifact = 571 cmStateEnums::RuntimeBinaryArtifact) const; 572 573 /** Get the directory in which to place the target compiler .pdb file. 574 If the configuration name is given then the generator will add its 575 subdirectory for that configuration. Otherwise just the canonical 576 compiler pdb output directory is given. */ 577 std::string GetCompilePDBDirectory(const std::string& config) const; 578 579 /** Get sources that must be built before the given source. */ 580 std::vector<cmSourceFile*> const* GetSourceDepends( 581 cmSourceFile const* sf) const; 582 583 /** Return whether this target uses the default value for its output 584 directory. */ 585 bool UsesDefaultOutputDir(const std::string& config, 586 cmStateEnums::ArtifactType artifact) const; 587 588 // Cache target output paths for each configuration. 589 struct OutputInfo 590 { 591 std::string OutDir; 592 std::string ImpDir; 593 std::string PdbDir; emptyOutputInfo594 bool empty() const 595 { 596 return this->OutDir.empty() && this->ImpDir.empty() && 597 this->PdbDir.empty(); 598 } 599 }; 600 601 OutputInfo const* GetOutputInfo(const std::string& config) const; 602 603 // Get the target PDB base name. 604 std::string GetPDBOutputName(const std::string& config) const; 605 606 /** Get the name of the pdb file for the target. */ 607 std::string GetPDBName(const std::string& config) const; 608 609 /** Whether this library has soname enabled and platform supports it. */ 610 bool HasSOName(const std::string& config) const; 611 612 struct CompileInfo 613 { 614 std::string CompilePdbDir; 615 }; 616 617 CompileInfo const* GetCompileInfo(const std::string& config) const; 618 619 using CompileInfoMapType = std::map<std::string, CompileInfo>; 620 mutable CompileInfoMapType CompileInfoMap; 621 622 bool IsNullImpliedByLinkLibraries(const std::string& p) const; 623 624 /** Get the name of the compiler pdb file for the target. */ 625 std::string GetCompilePDBName(const std::string& config) const; 626 627 /** Get the path for the MSVC /Fd option for this target. */ 628 std::string GetCompilePDBPath(const std::string& config) const; 629 630 // Get the target base name. 631 std::string GetOutputName(const std::string& config, 632 cmStateEnums::ArtifactType artifact) const; 633 634 /** Get target file prefix */ 635 std::string GetFilePrefix(const std::string& config, 636 cmStateEnums::ArtifactType artifact = 637 cmStateEnums::RuntimeBinaryArtifact) const; 638 /** Get target file prefix */ 639 std::string GetFileSuffix(const std::string& config, 640 cmStateEnums::ArtifactType artifact = 641 cmStateEnums::RuntimeBinaryArtifact) const; 642 643 /** Get target file postfix */ 644 std::string GetFilePostfix(const std::string& config) const; 645 646 /** Get framework multi-config-specific postfix */ 647 std::string GetFrameworkMultiConfigPostfix(const std::string& config) const; 648 649 /** Clears cached meta data for local and external source files. 650 * The meta data will be recomputed on demand. 651 */ 652 void ClearSourcesCache(); 653 654 void AddSource(const std::string& src, bool before = false); 655 void AddTracedSources(std::vector<std::string> const& srcs); 656 657 /** 658 * Adds an entry to the INCLUDE_DIRECTORIES list. 659 * If before is true the entry is pushed at the front. 660 */ 661 void AddIncludeDirectory(const std::string& src, bool before = false); 662 663 /** 664 * Flags for a given source file as used in this target. Typically assigned 665 * via SET_TARGET_PROPERTIES when the property is a list of source files. 666 */ 667 enum SourceFileType 668 { 669 SourceFileTypeNormal, 670 SourceFileTypePrivateHeader, // is in "PRIVATE_HEADER" target property 671 SourceFileTypePublicHeader, // is in "PUBLIC_HEADER" target property 672 SourceFileTypeResource, // is in "RESOURCE" target property *or* 673 // has MACOSX_PACKAGE_LOCATION=="Resources" 674 SourceFileTypeDeepResource, // MACOSX_PACKAGE_LOCATION starts with 675 // "Resources/" 676 SourceFileTypeMacContent // has MACOSX_PACKAGE_LOCATION!="Resources[/]" 677 }; 678 struct SourceFileFlags 679 { 680 SourceFileType Type = SourceFileTypeNormal; 681 const char* MacFolder = nullptr; // location inside Mac content folders 682 }; 683 void GetAutoUicOptions(std::vector<std::string>& result, 684 const std::string& config) const; 685 686 struct Names 687 { 688 std::string Base; 689 std::string Output; 690 std::string Real; 691 std::string ImportLibrary; 692 std::string PDB; 693 std::string SharedObject; 694 }; 695 696 /** Get the names of the executable needed to generate a build rule 697 that takes into account executable version numbers. This should 698 be called only on an executable target. */ 699 Names GetExecutableNames(const std::string& config) const; 700 701 /** Get the names of the library needed to generate a build rule 702 that takes into account shared library version numbers. This 703 should be called only on a library target. */ 704 Names GetLibraryNames(const std::string& config) const; 705 706 /** 707 * Compute whether this target must be relinked before installing. 708 */ 709 bool NeedRelinkBeforeInstall(const std::string& config) const; 710 711 /** Return true if builtin chrpath will work for this target */ 712 bool IsChrpathUsed(const std::string& config) const; 713 714 /** Get the directory in which this targets .pdb files will be placed. 715 If the configuration name is given then the generator will add its 716 subdirectory for that configuration. Otherwise just the canonical 717 pdb output directory is given. */ 718 std::string GetPDBDirectory(const std::string& config) const; 719 720 //! Return the preferred linker language for this target 721 std::string GetLinkerLanguage(const std::string& config) const; 722 723 /** Does this target have a GNU implib to convert to MS format? */ 724 bool HasImplibGNUtoMS(std::string const& config) const; 725 726 /** Convert the given GNU import library name (.dll.a) to a name with a new 727 extension (.lib or ${CMAKE_IMPORT_LIBRARY_SUFFIX}). */ 728 bool GetImplibGNUtoMS(std::string const& config, std::string const& gnuName, 729 std::string& out, const char* newExt = nullptr) const; 730 731 /** Can only ever return true if GetSourceFilePaths() was called before. 732 Otherwise, this is indeterminate and false will be assumed/returned! */ 733 bool HasContextDependentSources() const; 734 735 bool IsExecutableWithExports() const; 736 737 /** Return whether or not the target has a DLL import library. */ 738 bool HasImportLibrary(std::string const& config) const; 739 740 /** Get a build-tree directory in which to place target support files. */ 741 std::string GetSupportDirectory() const; 742 743 /** Return whether this target may be used to link another target. */ 744 bool IsLinkable() const; 745 746 /** Return whether this target is a shared library Framework on 747 Apple. */ 748 bool IsFrameworkOnApple() const; 749 750 /** Return whether this target is an executable Bundle on Apple. */ 751 bool IsAppBundleOnApple() const; 752 753 /** Return whether this target is a XCTest on Apple. */ 754 bool IsXCTestOnApple() const; 755 756 /** Return whether this target is a CFBundle (plugin) on Apple. */ 757 bool IsCFBundleOnApple() const; 758 759 /** Assembly types. The order of the values of this enum is relevant 760 because of smaller/larger comparison operations! */ 761 enum ManagedType 762 { 763 Undefined = 0, // target is no lib or executable 764 Native, // target compiles to unmanaged binary. 765 Mixed, // target compiles to mixed (managed and unmanaged) binary. 766 Managed // target compiles to managed binary. 767 }; 768 769 /** Return the type of assembly this target compiles to. */ 770 ManagedType GetManagedType(const std::string& config) const; 771 772 struct SourceFileFlags GetTargetSourceFileFlags( 773 const cmSourceFile* sf) const; 774 775 void ReportPropertyOrigin(const std::string& p, const std::string& result, 776 const std::string& report, 777 const std::string& compatibilityType) const; 778 779 class TargetPropertyEntry; 780 781 std::string EvaluateInterfaceProperty( 782 std::string const& prop, cmGeneratorExpressionContext* context, 783 cmGeneratorExpressionDAGChecker* dagCheckerParent, 784 bool usage_requirements_only = true) const; 785 786 bool HaveInstallTreeRPATH(const std::string& config) const; 787 788 bool GetBuildRPATH(const std::string& config, std::string& rpath) const; 789 bool GetInstallRPATH(const std::string& config, std::string& rpath) const; 790 791 /** Whether this library has \@rpath and platform supports it. */ 792 bool HasMacOSXRpathInstallNameDir(const std::string& config) const; 793 794 /** Whether this library defaults to \@rpath. */ 795 bool MacOSXRpathInstallNameDirDefault() const; 796 797 enum InstallNameType 798 { 799 INSTALL_NAME_FOR_BUILD, 800 INSTALL_NAME_FOR_INSTALL 801 }; 802 /** Whether to use INSTALL_NAME_DIR. */ 803 bool MacOSXUseInstallNameDir() const; 804 /** Whether to generate an install_name. */ 805 bool CanGenerateInstallNameDir(InstallNameType t) const; 806 807 /** Test for special case of a third-party shared library that has 808 no soname at all. */ 809 bool IsImportedSharedLibWithoutSOName(const std::string& config) const; 810 811 std::string ImportedGetLocation(const std::string& config) const; 812 813 /** Get the target major and minor version numbers interpreted from 814 the VERSION property. Version 0 is returned if the property is 815 not set or cannot be parsed. */ 816 void GetTargetVersion(int& major, int& minor) const; 817 818 /** Get the target major, minor, and patch version numbers 819 interpreted from the given property. Version 0 820 is returned if the property is not set or cannot be parsed. */ 821 void GetTargetVersion(std::string const& property, int& major, int& minor, 822 int& patch) const; 823 824 /** Get the target major, minor, and patch version numbers 825 interpreted from the given property and if empty use the 826 fallback property. Version 0 is returned if the property is 827 not set or cannot be parsed. */ 828 void GetTargetVersionFallback(const std::string& property, 829 const std::string& fallback_property, 830 int& major, int& minor, int& patch) const; 831 832 std::string GetRuntimeLinkLibrary(std::string const& lang, 833 std::string const& config) const; 834 835 std::string GetFortranModuleDirectory(std::string const& working_dir) const; 836 bool IsFortranBuildingInstrinsicModules() const; 837 838 cmValue GetSourcesProperty() const; 839 840 void AddISPCGeneratedHeader(std::string const& header, 841 std::string const& config); 842 std::vector<std::string> GetGeneratedISPCHeaders( 843 std::string const& config) const; 844 845 void AddISPCGeneratedObject(std::vector<std::string>&& objs, 846 std::string const& config); 847 std::vector<std::string> GetGeneratedISPCObjects( 848 std::string const& config) const; 849 850 private: 851 void AddSourceCommon(const std::string& src, bool before = false); 852 853 std::string CreateFortranModuleDirectory( 854 std::string const& working_dir) const; 855 mutable bool FortranModuleDirectoryCreated; 856 mutable std::string FortranModuleDirectory; 857 858 friend class cmTargetTraceDependencies; 859 struct SourceEntry 860 { 861 std::vector<cmSourceFile*> Depends; 862 }; 863 using SourceEntriesType = std::map<cmSourceFile const*, SourceEntry>; 864 SourceEntriesType SourceDepends; 865 mutable std::set<std::string> VisitedConfigsForObjects; 866 mutable std::map<cmSourceFile const*, std::string> Objects; 867 std::set<cmSourceFile const*> ExplicitObjectName; 868 869 using TargetPtrToBoolMap = std::unordered_map<cmTarget*, bool>; 870 mutable std::unordered_map<std::string, TargetPtrToBoolMap> 871 MacOSXRpathInstallNameDirCache; 872 bool DetermineHasMacOSXRpathInstallNameDir(const std::string& config) const; 873 874 // "config/language" is the key 875 mutable std::map<std::string, std::vector<std::string>> SystemIncludesCache; 876 877 mutable std::string ExportMacro; 878 879 void ConstructSourceFileFlags() const; 880 mutable bool SourceFileFlagsConstructed; 881 mutable std::map<cmSourceFile const*, SourceFileFlags> SourceFlagsMap; 882 883 mutable std::map<std::string, bool> DebugCompatiblePropertiesDone; 884 885 bool NeedImportLibraryName(std::string const& config) const; 886 887 cmValue GetFilePrefixInternal(std::string const& config, 888 cmStateEnums::ArtifactType artifact, 889 const std::string& language = "") const; 890 cmValue GetFileSuffixInternal(std::string const& config, 891 cmStateEnums::ArtifactType artifact, 892 const std::string& language = "") const; 893 894 std::string GetFullNameInternal(const std::string& config, 895 cmStateEnums::ArtifactType artifact) const; 896 void GetFullNameInternal(const std::string& config, 897 cmStateEnums::ArtifactType artifact, 898 std::string& outPrefix, std::string& outBase, 899 std::string& outSuffix) const; 900 901 mutable std::string LinkerLanguage; 902 using LinkClosureMapType = std::map<std::string, LinkClosure>; 903 mutable LinkClosureMapType LinkClosureMap; 904 bool DeviceLink = false; 905 906 // Returns ARCHIVE, LIBRARY, or RUNTIME based on platform and type. 907 const char* GetOutputTargetType(cmStateEnums::ArtifactType artifact) const; 908 909 void ComputeVersionedName(std::string& vName, std::string const& prefix, 910 std::string const& base, std::string const& suffix, 911 std::string const& name, cmValue version) const; 912 913 struct CompatibleInterfacesBase 914 { 915 std::set<std::string> PropsBool; 916 std::set<std::string> PropsString; 917 std::set<std::string> PropsNumberMax; 918 std::set<std::string> PropsNumberMin; 919 }; 920 CompatibleInterfacesBase const& GetCompatibleInterfaces( 921 std::string const& config) const; 922 923 struct CompatibleInterfaces : public CompatibleInterfacesBase 924 { 925 bool Done = false; 926 }; 927 mutable std::map<std::string, CompatibleInterfaces> CompatibleInterfacesMap; 928 929 using cmTargetLinkInformationMap = 930 std::map<std::string, std::unique_ptr<cmComputeLinkInformation>>; 931 mutable cmTargetLinkInformationMap LinkInformation; 932 933 void CheckPropertyCompatibility(cmComputeLinkInformation& info, 934 const std::string& config) const; 935 936 void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const; 937 bool ComputeLinkClosure(const std::string& config, LinkClosure& lc, 938 bool secondPass) const; 939 940 struct LinkImplClosure : public std::vector<cmGeneratorTarget const*> 941 { 942 bool Done = false; 943 }; 944 mutable std::map<std::string, LinkImplClosure> LinkImplClosureMap; 945 946 using LinkInterfaceMapType = std::map<std::string, cmHeadToLinkInterfaceMap>; 947 mutable LinkInterfaceMapType LinkInterfaceMap; 948 mutable LinkInterfaceMapType LinkInterfaceUsageRequirementsOnlyMap; 949 950 cmHeadToLinkInterfaceMap& GetHeadToLinkInterfaceMap( 951 std::string const& config) const; 952 cmHeadToLinkInterfaceMap& GetHeadToLinkInterfaceUsageRequirementsMap( 953 std::string const& config) const; 954 955 std::string GetLinkInterfaceDependentStringAsBoolProperty( 956 const std::string& p, const std::string& config) const; 957 958 friend class cmTargetCollectLinkLanguages; 959 cmLinkInterface const* GetLinkInterface(const std::string& config, 960 const cmGeneratorTarget* headTarget, 961 bool secondPass) const; 962 void ComputeLinkInterface(const std::string& config, 963 cmOptionalLinkInterface& iface, 964 const cmGeneratorTarget* head, 965 bool secondPass) const; 966 cmLinkImplementation const* GetLinkImplementation(const std::string& config, 967 bool secondPass) const; 968 969 // Cache import information from properties for each configuration. 970 struct ImportInfo 971 { 972 bool NoSOName = false; 973 ManagedType Managed = Native; 974 unsigned int Multiplicity = 0; 975 std::string Location; 976 std::string SOName; 977 std::string ImportLibrary; 978 std::string LibName; 979 std::string Languages; 980 std::string Libraries; 981 std::string LibrariesProp; 982 std::string SharedDeps; 983 }; 984 985 using ImportInfoMapType = std::map<std::string, ImportInfo>; 986 mutable ImportInfoMapType ImportInfoMap; 987 void ComputeImportInfo(std::string const& desired_config, 988 ImportInfo& info) const; 989 ImportInfo const* GetImportInfo(const std::string& config) const; 990 991 /** Strip off leading and trailing whitespace from an item named in 992 the link dependencies of this target. */ 993 std::string CheckCMP0004(std::string const& item) const; 994 995 cmLinkInterface const* GetImportLinkInterface(const std::string& config, 996 const cmGeneratorTarget* head, 997 bool usage_requirements_only, 998 bool secondPass = false) const; 999 1000 using KindedSourcesMapType = std::map<std::string, KindedSources>; 1001 mutable KindedSourcesMapType KindedSourcesMap; 1002 void ComputeKindedSources(KindedSources& files, 1003 std::string const& config) const; 1004 1005 mutable std::vector<AllConfigSource> AllConfigSources; 1006 void ComputeAllConfigSources() const; 1007 1008 mutable std::unordered_map<std::string, bool> MaybeInterfacePropertyExists; 1009 bool MaybeHaveInterfaceProperty(std::string const& prop, 1010 cmGeneratorExpressionContext* context, 1011 bool usage_requirements_only) const; 1012 1013 using TargetPropertyEntryVector = 1014 std::vector<std::unique_ptr<TargetPropertyEntry>>; 1015 1016 TargetPropertyEntryVector IncludeDirectoriesEntries; 1017 TargetPropertyEntryVector CompileOptionsEntries; 1018 TargetPropertyEntryVector CompileFeaturesEntries; 1019 TargetPropertyEntryVector CompileDefinitionsEntries; 1020 TargetPropertyEntryVector LinkOptionsEntries; 1021 TargetPropertyEntryVector LinkDirectoriesEntries; 1022 TargetPropertyEntryVector PrecompileHeadersEntries; 1023 TargetPropertyEntryVector SourceEntries; 1024 mutable std::set<std::string> LinkImplicitNullProperties; 1025 mutable std::map<std::string, std::string> PchHeaders; 1026 mutable std::map<std::string, std::string> PchSources; 1027 mutable std::map<std::string, std::string> PchObjectFiles; 1028 mutable std::map<std::string, std::string> PchFiles; 1029 mutable std::map<std::string, std::string> PchCreateCompileOptions; 1030 mutable std::map<std::string, std::string> PchUseCompileOptions; 1031 1032 std::unordered_set<std::string> UnityBatchedSourceFiles; 1033 1034 std::unordered_map<std::string, std::vector<std::string>> 1035 ISPCGeneratedHeaders; 1036 std::unordered_map<std::string, std::vector<std::string>> 1037 ISPCGeneratedObjects; 1038 1039 bool IsLinkLookupScope(std::string const& n, 1040 cmLocalGenerator const*& lg) const; 1041 1042 void ExpandLinkItems(std::string const& prop, std::string const& value, 1043 std::string const& config, 1044 const cmGeneratorTarget* headTarget, 1045 bool usage_requirements_only, 1046 cmLinkInterface& iface) const; 1047 1048 struct LookupLinkItemScope 1049 { 1050 cmLocalGenerator const* LG; 1051 }; 1052 cm::optional<cmLinkItem> LookupLinkItem(std::string const& n, 1053 cmListFileBacktrace const& bt, 1054 LookupLinkItemScope* scope) const; 1055 1056 std::vector<BT<std::string>> GetSourceFilePaths( 1057 std::string const& config) const; 1058 std::vector<BT<cmSourceFile*>> GetSourceFilesWithoutObjectLibraries( 1059 std::string const& config) const; 1060 void GetSourceFilesWithoutObjectLibraries(std::vector<cmSourceFile*>& files, 1061 const std::string& config) const; 1062 1063 struct HeadToLinkImplementationMap 1064 : public std::map<cmGeneratorTarget const*, cmOptionalLinkImplementation> 1065 { 1066 }; 1067 using LinkImplMapType = std::map<std::string, HeadToLinkImplementationMap>; 1068 mutable LinkImplMapType LinkImplMap; 1069 1070 cmLinkImplementationLibraries const* GetLinkImplementationLibrariesInternal( 1071 const std::string& config, const cmGeneratorTarget* head) const; 1072 bool ComputeOutputDir(const std::string& config, 1073 cmStateEnums::ArtifactType artifact, 1074 std::string& out) const; 1075 1076 using OutputInfoMapType = std::map<std::string, OutputInfo>; 1077 mutable OutputInfoMapType OutputInfoMap; 1078 1079 using ModuleDefinitionInfoMapType = 1080 std::map<std::string, ModuleDefinitionInfo>; 1081 mutable ModuleDefinitionInfoMapType ModuleDefinitionInfoMap; 1082 void ComputeModuleDefinitionInfo(std::string const& config, 1083 ModuleDefinitionInfo& info) const; 1084 1085 using OutputNameKey = std::pair<std::string, cmStateEnums::ArtifactType>; 1086 using OutputNameMapType = std::map<OutputNameKey, std::string>; 1087 mutable OutputNameMapType OutputNameMap; 1088 mutable std::set<cmLinkItem> UtilityItems; 1089 cmPolicies::PolicyMap PolicyMap; 1090 mutable bool PolicyWarnedCMP0022; 1091 mutable bool PolicyReportedCMP0069; 1092 mutable bool DebugIncludesDone; 1093 mutable bool DebugCompileOptionsDone; 1094 mutable bool DebugCompileFeaturesDone; 1095 mutable bool DebugCompileDefinitionsDone; 1096 mutable bool DebugLinkOptionsDone; 1097 mutable bool DebugLinkDirectoriesDone; 1098 mutable bool DebugPrecompileHeadersDone; 1099 mutable bool DebugSourcesDone; 1100 mutable bool UtilityItemsDone; 1101 enum class Tribool 1102 { 1103 False = 0x0, 1104 True = 0x1, 1105 Indeterminate = 0x2 1106 }; 1107 mutable Tribool SourcesAreContextDependent; 1108 1109 bool ComputePDBOutputDir(const std::string& kind, const std::string& config, 1110 std::string& out) const; 1111 1112 ManagedType CheckManagedType(std::string const& propval) const; 1113 1114 bool GetRPATH(const std::string& config, const std::string& prop, 1115 std::string& rpath) const; 1116 1117 mutable std::map<std::string, BTs<std::string>> LanguageStandardMap; 1118 1119 cmValue GetPropertyWithPairedLanguageSupport(std::string const& lang, 1120 const char* suffix) const; 1121 1122 void ComputeLinkImplementationRuntimeLibraries( 1123 const std::string& config, cmOptionalLinkImplementation& impl) const; 1124 1125 void ComputeLinkInterfaceRuntimeLibraries( 1126 const std::string& config, cmOptionalLinkInterface& iface) const; 1127 1128 public: 1129 const std::vector<const cmGeneratorTarget*>& GetLinkImplementationClosure( 1130 const std::string& config) const; 1131 1132 mutable std::map<std::string, std::string> MaxLanguageStandards; GetMaxLanguageStandards()1133 std::map<std::string, std::string> const& GetMaxLanguageStandards() const 1134 { 1135 return this->MaxLanguageStandards; 1136 } 1137 1138 struct StrictTargetComparison 1139 { 1140 bool operator()(cmGeneratorTarget const* t1, 1141 cmGeneratorTarget const* t2) const; 1142 }; 1143 }; 1144