Add the INTERFACE_SYSTEM_INCLUDE_DIRECTORIES target property.
Unlike other target properties, this does not have a corresponding non-INTERFACE variant. This allows propagation of system attribute on include directories from link dependents.
This commit is contained in:
parent
1925cffa08
commit
9cf3547e1c
|
@ -126,6 +126,10 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
this->PopulateIncludeDirectoriesInterface(te,
|
||||
cmGeneratorExpression::InstallInterface,
|
||||
properties, missingTargets);
|
||||
this->PopulateInterfaceProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES",
|
||||
te,
|
||||
cmGeneratorExpression::InstallInterface,
|
||||
properties, missingTargets);
|
||||
this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS",
|
||||
te,
|
||||
cmGeneratorExpression::InstallInterface,
|
||||
|
|
|
@ -171,6 +171,14 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingIncludeDirectories() const
|
|||
|| strcmp(prop, "INTERFACE_INCLUDE_DIRECTORIES") == 0 );
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
cmGeneratorExpressionDAGChecker::EvaluatingSystemIncludeDirectories() const
|
||||
{
|
||||
const char *prop = this->Property.c_str();
|
||||
return strcmp(prop, "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES") == 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmGeneratorExpressionDAGChecker::EvaluatingCompileDefinitions() const
|
||||
{
|
||||
|
|
|
@ -18,11 +18,13 @@
|
|||
|
||||
#define CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(F) \
|
||||
F(EvaluatingIncludeDirectories) \
|
||||
F(EvaluatingSystemIncludeDirectories) \
|
||||
F(EvaluatingCompileDefinitions) \
|
||||
F(EvaluatingCompileOptions)
|
||||
|
||||
#define CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(F) \
|
||||
F(INTERFACE_INCLUDE_DIRECTORIES) \
|
||||
F(INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) \
|
||||
F(INTERFACE_COMPILE_DEFINITIONS) \
|
||||
F(INTERFACE_COMPILE_OPTIONS)
|
||||
|
||||
|
|
|
@ -879,6 +879,10 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
|||
{
|
||||
interfacePropertyName = "INTERFACE_INCLUDE_DIRECTORIES";
|
||||
}
|
||||
else if (propertyName == "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES")
|
||||
{
|
||||
interfacePropertyName = "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES";
|
||||
}
|
||||
else if (propertyName == "INTERFACE_COMPILE_DEFINITIONS"
|
||||
|| propertyName == "COMPILE_DEFINITIONS"
|
||||
|| strncmp(propertyName.c_str(), "COMPILE_DEFINITIONS_", 20) == 0)
|
||||
|
|
|
@ -51,21 +51,43 @@ const char *cmGeneratorTarget::GetProperty(const char *prop)
|
|||
bool cmGeneratorTarget::IsSystemIncludeDirectory(const char *dir,
|
||||
const char *config)
|
||||
{
|
||||
for (std::set<cmStdString>::const_iterator
|
||||
it = this->Target->GetSystemIncludeDirectories().begin();
|
||||
it != this->Target->GetSystemIncludeDirectories().end(); ++it)
|
||||
std::string config_upper;
|
||||
if(config && *config)
|
||||
{
|
||||
cmListFileBacktrace lfbt;
|
||||
cmGeneratorExpression ge(lfbt);
|
||||
config_upper = cmSystemTools::UpperCase(config);
|
||||
}
|
||||
|
||||
std::vector<std::string> incs;
|
||||
cmSystemTools::ExpandListArgument(ge.Parse(*it)
|
||||
->Evaluate(this->Makefile,
|
||||
config, false), incs);
|
||||
if (std::find(incs.begin(), incs.end(), dir) != incs.end())
|
||||
typedef std::map<std::string, std::vector<std::string> > IncludeCacheType;
|
||||
IncludeCacheType::iterator iter =
|
||||
this->SystemIncludesCache.find(config_upper);
|
||||
|
||||
if (iter == this->SystemIncludesCache.end())
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
for (std::set<cmStdString>::const_iterator
|
||||
it = this->Target->GetSystemIncludeDirectories().begin();
|
||||
it != this->Target->GetSystemIncludeDirectories().end(); ++it)
|
||||
{
|
||||
return true;
|
||||
cmListFileBacktrace lfbt;
|
||||
cmGeneratorExpression ge(lfbt);
|
||||
|
||||
cmGeneratorExpressionDAGChecker dagChecker(lfbt,
|
||||
this->GetName(),
|
||||
"INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", 0, 0);
|
||||
|
||||
cmSystemTools::ExpandListArgument(ge.Parse(*it)
|
||||
->Evaluate(this->Makefile,
|
||||
config, false, this->Target,
|
||||
&dagChecker), result);
|
||||
}
|
||||
IncludeCacheType::value_type entry(config_upper, result);
|
||||
iter = this->SystemIncludesCache.insert(entry).first;
|
||||
}
|
||||
|
||||
if (std::find(iter->second.begin(),
|
||||
iter->second.end(), dir) != iter->second.end())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -78,6 +78,8 @@ private:
|
|||
void ClassifySources();
|
||||
void LookupObjectLibraries();
|
||||
|
||||
std::map<std::string, std::vector<std::string> > SystemIncludesCache;
|
||||
|
||||
cmGeneratorTarget(cmGeneratorTarget const&);
|
||||
void operator=(cmGeneratorTarget const&);
|
||||
};
|
||||
|
|
|
@ -1001,6 +1001,17 @@ void cmGlobalGenerator::Generate()
|
|||
// it builds by default.
|
||||
this->FillLocalGeneratorToTargetMap();
|
||||
|
||||
for (i = 0; i < this->LocalGenerators.size(); ++i)
|
||||
{
|
||||
cmMakefile* mf = this->LocalGenerators[i]->GetMakefile();
|
||||
cmTargets* targets = &(mf->GetTargets());
|
||||
for ( cmTargets::iterator it = targets->begin();
|
||||
it != targets->end(); ++ it )
|
||||
{
|
||||
it->second.FinalizeSystemIncludeDirectories();
|
||||
}
|
||||
}
|
||||
|
||||
// Generate project files
|
||||
for (i = 0; i < this->LocalGenerators.size(); ++i)
|
||||
{
|
||||
|
|
|
@ -842,6 +842,17 @@ void cmTarget::DefineProperties(cmake *cm)
|
|||
CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
|
||||
CM_DOCUMENT_LANGUAGE_GENERATOR_EXPRESSIONS);
|
||||
|
||||
cm->DefineProperty
|
||||
("SYSTEM_INTERFACE_INCLUDE_DIRECTORIES", cmProperty::TARGET,
|
||||
"List of public system include directories for a library.",
|
||||
"Targets may populate this property to publish the include directories "
|
||||
"which contain system headers, and therefore should not result in "
|
||||
"compiler warnings. Consuming targets will then mark the same include "
|
||||
"directories as system headers."
|
||||
"\n"
|
||||
CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
|
||||
CM_DOCUMENT_LANGUAGE_GENERATOR_EXPRESSIONS);
|
||||
|
||||
cm->DefineProperty
|
||||
("INTERFACE_COMPILE_DEFINITIONS", cmProperty::TARGET,
|
||||
"List of public compile definitions for a library.",
|
||||
|
@ -2555,6 +2566,39 @@ cmTarget::AddSystemIncludeDirectories(const std::vector<std::string> &incs)
|
|||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTarget::FinalizeSystemIncludeDirectories()
|
||||
{
|
||||
for (std::vector<cmValueWithOrigin>::const_iterator
|
||||
it = this->Internal->LinkInterfacePropertyEntries.begin(),
|
||||
end = this->Internal->LinkInterfacePropertyEntries.end();
|
||||
it != end; ++it)
|
||||
{
|
||||
{
|
||||
cmListFileBacktrace lfbt;
|
||||
cmGeneratorExpression ge(lfbt);
|
||||
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
|
||||
ge.Parse(it->Value);
|
||||
std::string targetName = cge->Evaluate(this->Makefile, 0,
|
||||
false, this, 0, 0);
|
||||
if (!this->Makefile->FindTargetToUse(targetName.c_str()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
std::string includeGenex = "$<TARGET_PROPERTY:" +
|
||||
it->Value + ",INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>";
|
||||
if (cmGeneratorExpression::Find(it->Value) != std::string::npos)
|
||||
{
|
||||
// Because it->Value is a generator expression, ensure that it
|
||||
// evaluates to the non-empty string before being used in the
|
||||
// TARGET_PROPERTY expression.
|
||||
includeGenex = "$<$<BOOL:" + it->Value + ">:" + includeGenex + ">";
|
||||
}
|
||||
this->SystemIncludeDirectories.insert(includeGenex);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
|
||||
|
|
|
@ -538,6 +538,9 @@ public:
|
|||
void AddSystemIncludeDirectories(const std::vector<std::string> &incs);
|
||||
std::set<cmStdString> const & GetSystemIncludeDirectories() const
|
||||
{ return this->SystemIncludeDirectories; }
|
||||
|
||||
void FinalizeSystemIncludeDirectories();
|
||||
|
||||
private:
|
||||
// The set of include directories that are marked as system include
|
||||
// directories.
|
||||
|
|
|
@ -84,10 +84,21 @@ void cmTargetIncludeDirectoriesCommand
|
|||
const std::vector<std::string> &content,
|
||||
bool prepend, bool system)
|
||||
{
|
||||
if (system)
|
||||
{
|
||||
// Error.
|
||||
}
|
||||
cmTargetPropCommandBase::HandleInterfaceContent(tgt, content,
|
||||
prepend, system);
|
||||
|
||||
if (system)
|
||||
{
|
||||
std::string joined;
|
||||
std::string sep;
|
||||
for(std::vector<std::string>::const_iterator it = content.begin();
|
||||
it != content.end(); ++it)
|
||||
{
|
||||
joined += sep;
|
||||
sep = ";";
|
||||
joined += *it;
|
||||
}
|
||||
tgt->AppendProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES",
|
||||
joined.c_str());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,6 +71,14 @@ public:
|
|||
"The following arguments specify include directories. Specified "
|
||||
"include directories may be absolute paths or relative paths. "
|
||||
"Repeated calls for the same <target> append items in the order called."
|
||||
"If SYSTEM is specified, the compiler will be told the "
|
||||
"directories are meant as system include directories on some "
|
||||
"platforms (signalling this setting might achieve effects such as "
|
||||
"the compiler skipping warnings, or these fixed-install system files "
|
||||
"not being considered in dependency calculations - see compiler "
|
||||
"docs). If SYSTEM is used together with PUBLIC or INTERFACE, the "
|
||||
"INTERFACE_SYSTEM_INCLUDE_DIRECTORIES target property will be "
|
||||
"populated with the specified directories."
|
||||
"\n"
|
||||
"Arguments to target_include_directories may use \"generator "
|
||||
"expressions\" with the syntax \"$<...>\". "
|
||||
|
|
|
@ -1,6 +1,23 @@
|
|||
cmake_minimum_required (VERSION 2.6)
|
||||
project(IncludeDirectories)
|
||||
|
||||
if (((CMAKE_C_COMPILER_ID STREQUAL GNU AND CMAKE_C_COMPILER_VERSION VERSION_GREATER 4.4)
|
||||
OR CMAKE_C_COMPILER_ID STREQUAL Clang)
|
||||
AND (CMAKE_GENERATOR STREQUAL "Unix Makefiles" OR CMAKE_GENERATOR STREQUAL "Ninja"))
|
||||
include(CheckCXXCompilerFlag)
|
||||
check_cxx_compiler_flag(-Wunused-variable run_sys_includes_test)
|
||||
if(run_sys_includes_test)
|
||||
# The Bullseye wrapper appears to break the -isystem effect.
|
||||
execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version OUTPUT_VARIABLE out ERROR_VARIABLE out)
|
||||
if("x${out}" MATCHES "Bullseye")
|
||||
set(run_sys_includes_test 0)
|
||||
endif()
|
||||
endif()
|
||||
if (run_sys_includes_test)
|
||||
add_subdirectory(SystemIncludeDirectories)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/Flags/Flags.h
|
||||
"//Flags.h
|
||||
")
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(SystemIncludeDirectories)
|
||||
|
||||
add_library(systemlib systemlib.cpp)
|
||||
target_include_directories(systemlib PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/systemlib")
|
||||
|
||||
add_library(upstream upstream.cpp)
|
||||
target_link_libraries(upstream LINK_PUBLIC systemlib)
|
||||
target_compile_options(upstream PRIVATE -Werror=unused-variable)
|
||||
|
||||
target_include_directories(upstream SYSTEM PUBLIC
|
||||
$<TARGET_PROPERTY:systemlib,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
|
||||
add_library(consumer consumer.cpp)
|
||||
target_link_libraries(consumer upstream)
|
||||
target_compile_options(consumer PRIVATE -Werror=unused-variable)
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
#include "upstream.h"
|
||||
|
||||
int consumer()
|
||||
{
|
||||
return upstream();
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
#include "systemlib.h"
|
||||
|
||||
int systemlib() { return 0; }
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
#ifndef SYSTEMLIB_H
|
||||
#define SYSTEMLIB_H
|
||||
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int systemlib();
|
||||
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int unusedFunc()
|
||||
{
|
||||
int unused;
|
||||
return systemlib();
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
#include "upstream.h"
|
||||
|
||||
int upstream() { return systemlib(); }
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
#ifndef UPSTREAM_H
|
||||
#define UPSTREAM_H
|
||||
|
||||
#include "systemlib.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int upstream();
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue