summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2013-07-02 12:30:10 (GMT)
committerBrad King <brad.king@kitware.com>2013-07-16 17:44:57 (GMT)
commit9cf3547e1cd56d42bc96c3dc3adf9f745faea5ee (patch)
treeea220c1949611ac1977841ea77ff22bcac061497
parent1925cffa083bcbe3c54b8a0f2c63dc96f5168db0 (diff)
downloadCMake-9cf3547e1cd56d42bc96c3dc3adf9f745faea5ee.zip
CMake-9cf3547e1cd56d42bc96c3dc3adf9f745faea5ee.tar.gz
CMake-9cf3547e1cd56d42bc96c3dc3adf9f745faea5ee.tar.bz2
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.
-rw-r--r--Source/cmExportInstallFileGenerator.cxx4
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx8
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h2
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx4
-rw-r--r--Source/cmGeneratorTarget.cxx44
-rw-r--r--Source/cmGeneratorTarget.h2
-rw-r--r--Source/cmGlobalGenerator.cxx11
-rw-r--r--Source/cmTarget.cxx44
-rw-r--r--Source/cmTarget.h3
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.cxx17
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.h8
-rw-r--r--Tests/IncludeDirectories/CMakeLists.txt17
-rw-r--r--Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt19
-rw-r--r--Tests/IncludeDirectories/SystemIncludeDirectories/consumer.cpp7
-rw-r--r--Tests/IncludeDirectories/SystemIncludeDirectories/systemlib.cpp4
-rw-r--r--Tests/IncludeDirectories/SystemIncludeDirectories/systemlib/systemlib.h19
-rw-r--r--Tests/IncludeDirectories/SystemIncludeDirectories/upstream.cpp4
-rw-r--r--Tests/IncludeDirectories/SystemIncludeDirectories/upstream.h12
18 files changed, 215 insertions, 14 deletions
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index a966b16..43b17c6 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -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,
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index 5b79e35..d04e195 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -172,6 +172,14 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingIncludeDirectories() const
}
//----------------------------------------------------------------------------
+bool
+cmGeneratorExpressionDAGChecker::EvaluatingSystemIncludeDirectories() const
+{
+ const char *prop = this->Property.c_str();
+ return strcmp(prop, "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES") == 0;
+}
+
+//----------------------------------------------------------------------------
bool cmGeneratorExpressionDAGChecker::EvaluatingCompileDefinitions() const
{
const char *prop = this->Property.c_str();
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index 95d466a..f0524f2 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -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)
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index 05bbc1c..53fb35d 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -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)
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 9167b25..5ce0e6b 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -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);
+ }
+
+ typedef std::map<std::string, std::vector<std::string> > IncludeCacheType;
+ IncludeCacheType::iterator iter =
+ this->SystemIncludesCache.find(config_upper);
- 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())
+ 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;
}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index c0fd772..dedfa60 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -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&);
};
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index ad74767..2897114 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -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)
{
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 7ad42f8..806f77c 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -843,6 +843,17 @@ void cmTarget::DefineProperties(cmake *cm)
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.",
"Targets may populate this property to publish the compile definitions "
@@ -2556,6 +2567,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 )
{
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index ff6d923..09cddaf 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -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.
diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx
index ee91521..e7b906c 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.cxx
+++ b/Source/cmTargetIncludeDirectoriesCommand.cxx
@@ -84,10 +84,21 @@ void cmTargetIncludeDirectoriesCommand
const std::vector<std::string> &content,
bool prepend, bool system)
{
+ cmTargetPropCommandBase::HandleInterfaceContent(tgt, content,
+ prepend, system);
+
if (system)
{
- // Error.
+ 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());
}
- cmTargetPropCommandBase::HandleInterfaceContent(tgt, content,
- prepend, system);
}
diff --git a/Source/cmTargetIncludeDirectoriesCommand.h b/Source/cmTargetIncludeDirectoriesCommand.h
index a84ddd0..2968618 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.h
+++ b/Source/cmTargetIncludeDirectoriesCommand.h
@@ -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 \"$<...>\". "
diff --git a/Tests/IncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/CMakeLists.txt
index 3e3ecc9..596a280 100644
--- a/Tests/IncludeDirectories/CMakeLists.txt
+++ b/Tests/IncludeDirectories/CMakeLists.txt
@@ -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
")
diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt
new file mode 100644
index 0000000..aec6ff9
--- /dev/null
+++ b/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt
@@ -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)
diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/consumer.cpp b/Tests/IncludeDirectories/SystemIncludeDirectories/consumer.cpp
new file mode 100644
index 0000000..197dae8
--- /dev/null
+++ b/Tests/IncludeDirectories/SystemIncludeDirectories/consumer.cpp
@@ -0,0 +1,7 @@
+
+#include "upstream.h"
+
+int consumer()
+{
+ return upstream();
+}
diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/systemlib.cpp b/Tests/IncludeDirectories/SystemIncludeDirectories/systemlib.cpp
new file mode 100644
index 0000000..f111bfa
--- /dev/null
+++ b/Tests/IncludeDirectories/SystemIncludeDirectories/systemlib.cpp
@@ -0,0 +1,4 @@
+
+#include "systemlib.h"
+
+int systemlib() { return 0; }
diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/systemlib/systemlib.h b/Tests/IncludeDirectories/SystemIncludeDirectories/systemlib/systemlib.h
new file mode 100644
index 0000000..c84de6a
--- /dev/null
+++ b/Tests/IncludeDirectories/SystemIncludeDirectories/systemlib/systemlib.h
@@ -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
diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/upstream.cpp b/Tests/IncludeDirectories/SystemIncludeDirectories/upstream.cpp
new file mode 100644
index 0000000..f716b99
--- /dev/null
+++ b/Tests/IncludeDirectories/SystemIncludeDirectories/upstream.cpp
@@ -0,0 +1,4 @@
+
+#include "upstream.h"
+
+int upstream() { return systemlib(); }
diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/upstream.h b/Tests/IncludeDirectories/SystemIncludeDirectories/upstream.h
new file mode 100644
index 0000000..3628568
--- /dev/null
+++ b/Tests/IncludeDirectories/SystemIncludeDirectories/upstream.h
@@ -0,0 +1,12 @@
+
+#ifndef UPSTREAM_H
+#define UPSTREAM_H
+
+#include "systemlib.h"
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int upstream();
+
+#endif