mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-09 15:20:56 -06:00
cmGeneratorTarget: Factor INCLUDE_DIRECTORIES impl into own source
This commit is contained in:
@@ -285,6 +285,7 @@ add_library(
|
||||
cmGeneratorExpression.h
|
||||
cmGeneratorTarget.cxx
|
||||
cmGeneratorTarget.h
|
||||
cmGeneratorTarget_IncludeDirectories.cxx
|
||||
cmGeneratorTarget_Sources.cxx
|
||||
cmGeneratorTarget_TargetPropertyEntry.cxx
|
||||
cmLinkItemGraphVisitor.cxx
|
||||
|
||||
@@ -1414,110 +1414,6 @@ cmGeneratorTarget::IsTransitiveProperty(cm::string_view prop,
|
||||
return result;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
enum class IncludeDirectoryFallBack
|
||||
{
|
||||
BINARY,
|
||||
OBJECT
|
||||
};
|
||||
|
||||
std::string AddLangSpecificInterfaceIncludeDirectories(
|
||||
const cmGeneratorTarget* root, const cmGeneratorTarget* target,
|
||||
const std::string& lang, const std::string& config,
|
||||
const std::string& propertyName, IncludeDirectoryFallBack mode,
|
||||
cmGeneratorExpressionDAGChecker* context)
|
||||
{
|
||||
cmGeneratorExpressionDAGChecker dag{
|
||||
target->GetBacktrace(), target, propertyName, nullptr, context,
|
||||
target->GetLocalGenerator()
|
||||
};
|
||||
switch (dag.Check()) {
|
||||
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
|
||||
dag.ReportError(
|
||||
nullptr, "$<TARGET_PROPERTY:" + target->GetName() + ",propertyName");
|
||||
CM_FALLTHROUGH;
|
||||
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
|
||||
// No error. We just skip cyclic references.
|
||||
case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
|
||||
// No error. We have already seen this transitive property.
|
||||
return "";
|
||||
case cmGeneratorExpressionDAGChecker::DAG:
|
||||
break;
|
||||
}
|
||||
|
||||
std::string directories;
|
||||
if (const auto* link_interface =
|
||||
target->GetLinkInterfaceLibraries(config, root, UseTo::Compile)) {
|
||||
for (const cmLinkItem& library : link_interface->Libraries) {
|
||||
if (const cmGeneratorTarget* dependency = library.Target) {
|
||||
if (cm::contains(dependency->GetAllConfigCompileLanguages(), lang)) {
|
||||
auto* lg = dependency->GetLocalGenerator();
|
||||
std::string value = dependency->GetSafeProperty(propertyName);
|
||||
if (value.empty()) {
|
||||
if (mode == IncludeDirectoryFallBack::BINARY) {
|
||||
value = lg->GetCurrentBinaryDirectory();
|
||||
} else if (mode == IncludeDirectoryFallBack::OBJECT) {
|
||||
value = cmStrCat(lg->GetCurrentBinaryDirectory(), '/',
|
||||
lg->GetTargetDirectory(dependency));
|
||||
}
|
||||
}
|
||||
|
||||
if (!directories.empty()) {
|
||||
directories += ";";
|
||||
}
|
||||
directories += value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return directories;
|
||||
}
|
||||
|
||||
void AddLangSpecificImplicitIncludeDirectories(
|
||||
const cmGeneratorTarget* target, const std::string& lang,
|
||||
const std::string& config, const std::string& propertyName,
|
||||
IncludeDirectoryFallBack mode, EvaluatedTargetPropertyEntries& entries)
|
||||
{
|
||||
if (const auto* libraries =
|
||||
target->GetLinkImplementationLibraries(config, UseTo::Compile)) {
|
||||
cmGeneratorExpressionDAGChecker dag{
|
||||
target->GetBacktrace(), target, propertyName, nullptr, nullptr,
|
||||
target->GetLocalGenerator()
|
||||
};
|
||||
|
||||
for (const cmLinkImplItem& library : libraries->Libraries) {
|
||||
if (const cmGeneratorTarget* dependency = library.Target) {
|
||||
if (!dependency->IsInBuildSystem()) {
|
||||
continue;
|
||||
}
|
||||
if (cm::contains(dependency->GetAllConfigCompileLanguages(), lang)) {
|
||||
auto* lg = dependency->GetLocalGenerator();
|
||||
EvaluatedTargetPropertyEntry entry{ library, library.Backtrace };
|
||||
|
||||
if (cmValue val = dependency->GetProperty(propertyName)) {
|
||||
entry.Values.emplace_back(*val);
|
||||
} else {
|
||||
if (mode == IncludeDirectoryFallBack::BINARY) {
|
||||
entry.Values.emplace_back(lg->GetCurrentBinaryDirectory());
|
||||
} else if (mode == IncludeDirectoryFallBack::OBJECT) {
|
||||
entry.Values.emplace_back(
|
||||
dependency->GetObjectDirectory(config));
|
||||
}
|
||||
}
|
||||
|
||||
cmExpandList(
|
||||
AddLangSpecificInterfaceIncludeDirectories(
|
||||
target, dependency, lang, config, propertyName, mode, &dag),
|
||||
entry.Values);
|
||||
entries.Entries.emplace_back(std::move(entry));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
std::string cmGeneratorTarget::GetCompilePDBName(
|
||||
const std::string& config) const
|
||||
{
|
||||
@@ -2874,204 +2770,6 @@ std::string cmGeneratorTarget::GetClangTidyExportFixesDirectory(
|
||||
return cmSystemTools::CollapseFullPath(path);
|
||||
}
|
||||
|
||||
namespace {
|
||||
void processIncludeDirectories(cmGeneratorTarget const* tgt,
|
||||
EvaluatedTargetPropertyEntries& entries,
|
||||
std::vector<BT<std::string>>& includes,
|
||||
std::unordered_set<std::string>& uniqueIncludes,
|
||||
bool debugIncludes)
|
||||
{
|
||||
for (EvaluatedTargetPropertyEntry& entry : entries.Entries) {
|
||||
cmLinkImplItem const& item = entry.LinkImplItem;
|
||||
std::string const& targetName = item.AsStr();
|
||||
bool const fromImported = item.Target && item.Target->IsImported();
|
||||
bool const checkCMP0027 = item.CheckCMP0027;
|
||||
|
||||
std::string usedIncludes;
|
||||
for (std::string& entryInclude : entry.Values) {
|
||||
if (fromImported && !cmSystemTools::FileExists(entryInclude)) {
|
||||
std::ostringstream e;
|
||||
MessageType messageType = MessageType::FATAL_ERROR;
|
||||
if (checkCMP0027) {
|
||||
switch (tgt->GetPolicyStatusCMP0027()) {
|
||||
case cmPolicies::WARN:
|
||||
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0027) << "\n";
|
||||
CM_FALLTHROUGH;
|
||||
case cmPolicies::OLD:
|
||||
messageType = MessageType::AUTHOR_WARNING;
|
||||
break;
|
||||
case cmPolicies::REQUIRED_ALWAYS:
|
||||
case cmPolicies::REQUIRED_IF_USED:
|
||||
case cmPolicies::NEW:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* clang-format off */
|
||||
e << "Imported target \"" << targetName << "\" includes "
|
||||
"non-existent path\n \"" << entryInclude << "\"\nin its "
|
||||
"INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:\n"
|
||||
"* The path was deleted, renamed, or moved to another "
|
||||
"location.\n"
|
||||
"* An install or uninstall procedure did not complete "
|
||||
"successfully.\n"
|
||||
"* The installation package was faulty and references files it "
|
||||
"does not provide.\n";
|
||||
/* clang-format on */
|
||||
tgt->GetLocalGenerator()->IssueMessage(messageType, e.str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cmSystemTools::FileIsFullPath(entryInclude)) {
|
||||
std::ostringstream e;
|
||||
bool noMessage = false;
|
||||
MessageType messageType = MessageType::FATAL_ERROR;
|
||||
if (!targetName.empty()) {
|
||||
/* clang-format off */
|
||||
e << "Target \"" << targetName << "\" contains relative "
|
||||
"path in its INTERFACE_INCLUDE_DIRECTORIES:\n"
|
||||
" \"" << entryInclude << "\"";
|
||||
/* clang-format on */
|
||||
} else {
|
||||
switch (tgt->GetPolicyStatusCMP0021()) {
|
||||
case cmPolicies::WARN: {
|
||||
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0021) << "\n";
|
||||
messageType = MessageType::AUTHOR_WARNING;
|
||||
} break;
|
||||
case cmPolicies::OLD:
|
||||
noMessage = true;
|
||||
break;
|
||||
case cmPolicies::REQUIRED_IF_USED:
|
||||
case cmPolicies::REQUIRED_ALWAYS:
|
||||
case cmPolicies::NEW:
|
||||
// Issue the fatal message.
|
||||
break;
|
||||
}
|
||||
e << "Found relative path while evaluating include directories of "
|
||||
"\""
|
||||
<< tgt->GetName() << "\":\n \"" << entryInclude << "\"\n";
|
||||
}
|
||||
if (!noMessage) {
|
||||
tgt->GetLocalGenerator()->IssueMessage(messageType, e.str());
|
||||
if (messageType == MessageType::FATAL_ERROR) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!cmIsOff(entryInclude)) {
|
||||
cmSystemTools::ConvertToUnixSlashes(entryInclude);
|
||||
}
|
||||
|
||||
if (uniqueIncludes.insert(entryInclude).second) {
|
||||
includes.emplace_back(entryInclude, entry.Backtrace);
|
||||
if (debugIncludes) {
|
||||
usedIncludes += " * " + entryInclude + "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!usedIncludes.empty()) {
|
||||
tgt->GetLocalGenerator()->GetCMakeInstance()->IssueMessage(
|
||||
MessageType::LOG,
|
||||
std::string("Used includes for target ") + tgt->GetName() + ":\n" +
|
||||
usedIncludes,
|
||||
entry.Backtrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
|
||||
const std::string& config, const std::string& lang) const
|
||||
{
|
||||
ConfigAndLanguage cacheKey(config, lang);
|
||||
{
|
||||
auto it = this->IncludeDirectoriesCache.find(cacheKey);
|
||||
if (it != this->IncludeDirectoriesCache.end()) {
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
std::vector<BT<std::string>> includes;
|
||||
std::unordered_set<std::string> uniqueIncludes;
|
||||
|
||||
cmGeneratorExpressionDAGChecker dagChecker(
|
||||
this, "INCLUDE_DIRECTORIES", nullptr, nullptr, this->LocalGenerator);
|
||||
|
||||
cmList debugProperties{ this->Makefile->GetDefinition(
|
||||
"CMAKE_DEBUG_TARGET_PROPERTIES") };
|
||||
bool debugIncludes = !this->DebugIncludesDone &&
|
||||
cm::contains(debugProperties, "INCLUDE_DIRECTORIES");
|
||||
|
||||
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
|
||||
this->DebugIncludesDone = true;
|
||||
}
|
||||
|
||||
EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
|
||||
this, config, lang, &dagChecker, this->IncludeDirectoriesEntries);
|
||||
|
||||
if (lang == "Swift") {
|
||||
AddLangSpecificImplicitIncludeDirectories(
|
||||
this, lang, config, "Swift_MODULE_DIRECTORY",
|
||||
IncludeDirectoryFallBack::BINARY, entries);
|
||||
}
|
||||
|
||||
if (this->CanCompileSources() && (lang != "Swift" && lang != "Fortran")) {
|
||||
|
||||
const std::string propertyName = "ISPC_HEADER_DIRECTORY";
|
||||
|
||||
// If this target has ISPC sources make sure to add the header
|
||||
// directory to other compilation units
|
||||
if (cm::contains(this->GetAllConfigCompileLanguages(), "ISPC")) {
|
||||
if (cmValue val = this->GetProperty(propertyName)) {
|
||||
includes.emplace_back(*val);
|
||||
} else {
|
||||
includes.emplace_back(this->GetObjectDirectory(config));
|
||||
}
|
||||
}
|
||||
|
||||
AddLangSpecificImplicitIncludeDirectories(
|
||||
this, "ISPC", config, propertyName, IncludeDirectoryFallBack::OBJECT,
|
||||
entries);
|
||||
}
|
||||
|
||||
AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", lang,
|
||||
&dagChecker, entries, IncludeRuntimeInterface::Yes);
|
||||
|
||||
processIncludeDirectories(this, entries, includes, uniqueIncludes,
|
||||
debugIncludes);
|
||||
|
||||
if (this->IsApple()) {
|
||||
if (cmLinkImplementationLibraries const* impl =
|
||||
this->GetLinkImplementationLibraries(config, UseTo::Compile)) {
|
||||
for (cmLinkImplItem const& lib : impl->Libraries) {
|
||||
std::string libDir;
|
||||
if (lib.Target == nullptr) {
|
||||
libDir = cmSystemTools::CollapseFullPath(
|
||||
lib.AsStr(), this->Makefile->GetHomeOutputDirectory());
|
||||
} else if (lib.Target->Target->IsFrameworkOnApple() ||
|
||||
this->IsImportedFrameworkFolderOnApple(config)) {
|
||||
libDir = lib.Target->GetLocation(config);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto fwDescriptor =
|
||||
this->GetGlobalGenerator()->SplitFrameworkPath(libDir);
|
||||
if (!fwDescriptor) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto fwInclude = fwDescriptor->GetFrameworkPath();
|
||||
if (uniqueIncludes.insert(fwInclude).second) {
|
||||
includes.emplace_back(fwInclude, cmListFileBacktrace());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this->IncludeDirectoriesCache.emplace(cacheKey, includes);
|
||||
return includes;
|
||||
}
|
||||
|
||||
enum class OptionsParse
|
||||
{
|
||||
None,
|
||||
|
||||
334
Source/cmGeneratorTarget_IncludeDirectories.cxx
Normal file
334
Source/cmGeneratorTarget_IncludeDirectories.cxx
Normal file
@@ -0,0 +1,334 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
/* clang-format off */
|
||||
#include "cmGeneratorTarget.h"
|
||||
/* clang-format on */
|
||||
|
||||
#include "cmConfigure.h"
|
||||
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <cm/optional>
|
||||
#include <cmext/algorithm>
|
||||
|
||||
#include "cmEvaluatedTargetProperty.h"
|
||||
#include "cmGeneratorExpressionDAGChecker.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include "cmLinkItem.h"
|
||||
#include "cmList.h"
|
||||
#include "cmListFileCache.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmMessageType.h"
|
||||
#include "cmPolicies.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmTarget.h"
|
||||
#include "cmValue.h"
|
||||
#include "cmake.h"
|
||||
|
||||
namespace {
|
||||
using UseTo = cmGeneratorTarget::UseTo;
|
||||
|
||||
enum class IncludeDirectoryFallBack
|
||||
{
|
||||
BINARY,
|
||||
OBJECT
|
||||
};
|
||||
|
||||
std::string AddLangSpecificInterfaceIncludeDirectories(
|
||||
const cmGeneratorTarget* root, const cmGeneratorTarget* target,
|
||||
const std::string& lang, const std::string& config,
|
||||
const std::string& propertyName, IncludeDirectoryFallBack mode,
|
||||
cmGeneratorExpressionDAGChecker* context)
|
||||
{
|
||||
cmGeneratorExpressionDAGChecker dag{
|
||||
target->GetBacktrace(), target, propertyName, nullptr, context,
|
||||
target->GetLocalGenerator()
|
||||
};
|
||||
switch (dag.Check()) {
|
||||
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
|
||||
dag.ReportError(
|
||||
nullptr, "$<TARGET_PROPERTY:" + target->GetName() + ",propertyName");
|
||||
CM_FALLTHROUGH;
|
||||
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
|
||||
// No error. We just skip cyclic references.
|
||||
case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
|
||||
// No error. We have already seen this transitive property.
|
||||
return "";
|
||||
case cmGeneratorExpressionDAGChecker::DAG:
|
||||
break;
|
||||
}
|
||||
|
||||
std::string directories;
|
||||
if (const auto* link_interface =
|
||||
target->GetLinkInterfaceLibraries(config, root, UseTo::Compile)) {
|
||||
for (const cmLinkItem& library : link_interface->Libraries) {
|
||||
if (const cmGeneratorTarget* dependency = library.Target) {
|
||||
if (cm::contains(dependency->GetAllConfigCompileLanguages(), lang)) {
|
||||
auto* lg = dependency->GetLocalGenerator();
|
||||
std::string value = dependency->GetSafeProperty(propertyName);
|
||||
if (value.empty()) {
|
||||
if (mode == IncludeDirectoryFallBack::BINARY) {
|
||||
value = lg->GetCurrentBinaryDirectory();
|
||||
} else if (mode == IncludeDirectoryFallBack::OBJECT) {
|
||||
value = cmStrCat(lg->GetCurrentBinaryDirectory(), '/',
|
||||
lg->GetTargetDirectory(dependency));
|
||||
}
|
||||
}
|
||||
|
||||
if (!directories.empty()) {
|
||||
directories += ";";
|
||||
}
|
||||
directories += value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return directories;
|
||||
}
|
||||
|
||||
void AddLangSpecificImplicitIncludeDirectories(
|
||||
const cmGeneratorTarget* target, const std::string& lang,
|
||||
const std::string& config, const std::string& propertyName,
|
||||
IncludeDirectoryFallBack mode, EvaluatedTargetPropertyEntries& entries)
|
||||
{
|
||||
if (const auto* libraries =
|
||||
target->GetLinkImplementationLibraries(config, UseTo::Compile)) {
|
||||
cmGeneratorExpressionDAGChecker dag{
|
||||
target->GetBacktrace(), target, propertyName, nullptr, nullptr,
|
||||
target->GetLocalGenerator()
|
||||
};
|
||||
|
||||
for (const cmLinkImplItem& library : libraries->Libraries) {
|
||||
if (const cmGeneratorTarget* dependency = library.Target) {
|
||||
if (!dependency->IsInBuildSystem()) {
|
||||
continue;
|
||||
}
|
||||
if (cm::contains(dependency->GetAllConfigCompileLanguages(), lang)) {
|
||||
auto* lg = dependency->GetLocalGenerator();
|
||||
EvaluatedTargetPropertyEntry entry{ library, library.Backtrace };
|
||||
|
||||
if (cmValue val = dependency->GetProperty(propertyName)) {
|
||||
entry.Values.emplace_back(*val);
|
||||
} else {
|
||||
if (mode == IncludeDirectoryFallBack::BINARY) {
|
||||
entry.Values.emplace_back(lg->GetCurrentBinaryDirectory());
|
||||
} else if (mode == IncludeDirectoryFallBack::OBJECT) {
|
||||
entry.Values.emplace_back(
|
||||
dependency->GetObjectDirectory(config));
|
||||
}
|
||||
}
|
||||
|
||||
cmExpandList(
|
||||
AddLangSpecificInterfaceIncludeDirectories(
|
||||
target, dependency, lang, config, propertyName, mode, &dag),
|
||||
entry.Values);
|
||||
entries.Entries.emplace_back(std::move(entry));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void processIncludeDirectories(cmGeneratorTarget const* tgt,
|
||||
EvaluatedTargetPropertyEntries& entries,
|
||||
std::vector<BT<std::string>>& includes,
|
||||
std::unordered_set<std::string>& uniqueIncludes,
|
||||
bool debugIncludes)
|
||||
{
|
||||
for (EvaluatedTargetPropertyEntry& entry : entries.Entries) {
|
||||
cmLinkImplItem const& item = entry.LinkImplItem;
|
||||
std::string const& targetName = item.AsStr();
|
||||
bool const fromImported = item.Target && item.Target->IsImported();
|
||||
bool const checkCMP0027 = item.CheckCMP0027;
|
||||
|
||||
std::string usedIncludes;
|
||||
for (std::string& entryInclude : entry.Values) {
|
||||
if (fromImported && !cmSystemTools::FileExists(entryInclude)) {
|
||||
std::ostringstream e;
|
||||
MessageType messageType = MessageType::FATAL_ERROR;
|
||||
if (checkCMP0027) {
|
||||
switch (tgt->GetPolicyStatusCMP0027()) {
|
||||
case cmPolicies::WARN:
|
||||
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0027) << "\n";
|
||||
CM_FALLTHROUGH;
|
||||
case cmPolicies::OLD:
|
||||
messageType = MessageType::AUTHOR_WARNING;
|
||||
break;
|
||||
case cmPolicies::REQUIRED_ALWAYS:
|
||||
case cmPolicies::REQUIRED_IF_USED:
|
||||
case cmPolicies::NEW:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* clang-format off */
|
||||
e << "Imported target \"" << targetName << "\" includes "
|
||||
"non-existent path\n \"" << entryInclude << "\"\nin its "
|
||||
"INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:\n"
|
||||
"* The path was deleted, renamed, or moved to another "
|
||||
"location.\n"
|
||||
"* An install or uninstall procedure did not complete "
|
||||
"successfully.\n"
|
||||
"* The installation package was faulty and references files it "
|
||||
"does not provide.\n";
|
||||
/* clang-format on */
|
||||
tgt->GetLocalGenerator()->IssueMessage(messageType, e.str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cmSystemTools::FileIsFullPath(entryInclude)) {
|
||||
std::ostringstream e;
|
||||
bool noMessage = false;
|
||||
MessageType messageType = MessageType::FATAL_ERROR;
|
||||
if (!targetName.empty()) {
|
||||
/* clang-format off */
|
||||
e << "Target \"" << targetName << "\" contains relative "
|
||||
"path in its INTERFACE_INCLUDE_DIRECTORIES:\n"
|
||||
" \"" << entryInclude << "\"";
|
||||
/* clang-format on */
|
||||
} else {
|
||||
switch (tgt->GetPolicyStatusCMP0021()) {
|
||||
case cmPolicies::WARN: {
|
||||
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0021) << "\n";
|
||||
messageType = MessageType::AUTHOR_WARNING;
|
||||
} break;
|
||||
case cmPolicies::OLD:
|
||||
noMessage = true;
|
||||
break;
|
||||
case cmPolicies::REQUIRED_IF_USED:
|
||||
case cmPolicies::REQUIRED_ALWAYS:
|
||||
case cmPolicies::NEW:
|
||||
// Issue the fatal message.
|
||||
break;
|
||||
}
|
||||
e << "Found relative path while evaluating include directories of "
|
||||
"\""
|
||||
<< tgt->GetName() << "\":\n \"" << entryInclude << "\"\n";
|
||||
}
|
||||
if (!noMessage) {
|
||||
tgt->GetLocalGenerator()->IssueMessage(messageType, e.str());
|
||||
if (messageType == MessageType::FATAL_ERROR) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!cmIsOff(entryInclude)) {
|
||||
cmSystemTools::ConvertToUnixSlashes(entryInclude);
|
||||
}
|
||||
|
||||
if (uniqueIncludes.insert(entryInclude).second) {
|
||||
includes.emplace_back(entryInclude, entry.Backtrace);
|
||||
if (debugIncludes) {
|
||||
usedIncludes += " * " + entryInclude + "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!usedIncludes.empty()) {
|
||||
tgt->GetLocalGenerator()->GetCMakeInstance()->IssueMessage(
|
||||
MessageType::LOG,
|
||||
std::string("Used includes for target ") + tgt->GetName() + ":\n" +
|
||||
usedIncludes,
|
||||
entry.Backtrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
|
||||
const std::string& config, const std::string& lang) const
|
||||
{
|
||||
ConfigAndLanguage cacheKey(config, lang);
|
||||
{
|
||||
auto it = this->IncludeDirectoriesCache.find(cacheKey);
|
||||
if (it != this->IncludeDirectoriesCache.end()) {
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
std::vector<BT<std::string>> includes;
|
||||
std::unordered_set<std::string> uniqueIncludes;
|
||||
|
||||
cmGeneratorExpressionDAGChecker dagChecker(
|
||||
this, "INCLUDE_DIRECTORIES", nullptr, nullptr, this->LocalGenerator);
|
||||
|
||||
cmList debugProperties{ this->Makefile->GetDefinition(
|
||||
"CMAKE_DEBUG_TARGET_PROPERTIES") };
|
||||
bool debugIncludes = !this->DebugIncludesDone &&
|
||||
cm::contains(debugProperties, "INCLUDE_DIRECTORIES");
|
||||
|
||||
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
|
||||
this->DebugIncludesDone = true;
|
||||
}
|
||||
|
||||
EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
|
||||
this, config, lang, &dagChecker, this->IncludeDirectoriesEntries);
|
||||
|
||||
if (lang == "Swift") {
|
||||
AddLangSpecificImplicitIncludeDirectories(
|
||||
this, lang, config, "Swift_MODULE_DIRECTORY",
|
||||
IncludeDirectoryFallBack::BINARY, entries);
|
||||
}
|
||||
|
||||
if (this->CanCompileSources() && (lang != "Swift" && lang != "Fortran")) {
|
||||
|
||||
const std::string propertyName = "ISPC_HEADER_DIRECTORY";
|
||||
|
||||
// If this target has ISPC sources make sure to add the header
|
||||
// directory to other compilation units
|
||||
if (cm::contains(this->GetAllConfigCompileLanguages(), "ISPC")) {
|
||||
if (cmValue val = this->GetProperty(propertyName)) {
|
||||
includes.emplace_back(*val);
|
||||
} else {
|
||||
includes.emplace_back(this->GetObjectDirectory(config));
|
||||
}
|
||||
}
|
||||
|
||||
AddLangSpecificImplicitIncludeDirectories(
|
||||
this, "ISPC", config, propertyName, IncludeDirectoryFallBack::OBJECT,
|
||||
entries);
|
||||
}
|
||||
|
||||
AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", lang,
|
||||
&dagChecker, entries, IncludeRuntimeInterface::Yes);
|
||||
|
||||
processIncludeDirectories(this, entries, includes, uniqueIncludes,
|
||||
debugIncludes);
|
||||
|
||||
if (this->IsApple()) {
|
||||
if (cmLinkImplementationLibraries const* impl =
|
||||
this->GetLinkImplementationLibraries(config, UseTo::Compile)) {
|
||||
for (cmLinkImplItem const& lib : impl->Libraries) {
|
||||
std::string libDir;
|
||||
if (lib.Target == nullptr) {
|
||||
libDir = cmSystemTools::CollapseFullPath(
|
||||
lib.AsStr(), this->Makefile->GetHomeOutputDirectory());
|
||||
} else if (lib.Target->Target->IsFrameworkOnApple() ||
|
||||
this->IsImportedFrameworkFolderOnApple(config)) {
|
||||
libDir = lib.Target->GetLocation(config);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto fwDescriptor =
|
||||
this->GetGlobalGenerator()->SplitFrameworkPath(libDir);
|
||||
if (!fwDescriptor) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto fwInclude = fwDescriptor->GetFrameworkPath();
|
||||
if (uniqueIncludes.insert(fwInclude).second) {
|
||||
includes.emplace_back(fwInclude, cmListFileBacktrace());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this->IncludeDirectoriesCache.emplace(cacheKey, includes);
|
||||
return includes;
|
||||
}
|
||||
Reference in New Issue
Block a user