diff --git a/Modules/Platform/gcc.cmake b/Modules/Platform/gcc.cmake index 149ecfef2..7d3235b41 100644 --- a/Modules/Platform/gcc.cmake +++ b/Modules/Platform/gcc.cmake @@ -6,6 +6,7 @@ IF(CMAKE_COMPILER_IS_GNUCC) SET (CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-O2 -g") SET (CMAKE_C_CREATE_PREPROCESSED_SOURCE " -E > ") SET (CMAKE_C_CREATE_ASSEMBLY_SOURCE " -S -o ") + SET (CMAKE_INCLUDE_SYSTEM_FLAG_C "-isystem ") ENDIF(CMAKE_COMPILER_IS_GNUCC) IF(CMAKE_COMPILER_IS_GNUCXX) @@ -16,5 +17,6 @@ IF(CMAKE_COMPILER_IS_GNUCXX) SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O2 -g") SET (CMAKE_CXX_CREATE_PREPROCESSED_SOURCE " -E > ") SET (CMAKE_CXX_CREATE_ASSEMBLY_SOURCE " -S -o ") + SET (CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-isystem ") ENDIF(CMAKE_COMPILER_IS_GNUCXX) diff --git a/Source/cmIncludeDirectoryCommand.cxx b/Source/cmIncludeDirectoryCommand.cxx index 193b3cc6f..a34b1164c 100644 --- a/Source/cmIncludeDirectoryCommand.cxx +++ b/Source/cmIncludeDirectoryCommand.cxx @@ -28,6 +28,7 @@ bool cmIncludeDirectoryCommand std::vector::const_iterator i = args.begin(); bool before = this->Makefile->IsOn("CMAKE_INCLUDE_DIRECTORIES_BEFORE"); + bool system = false; if ((*i) == "BEFORE") { @@ -42,6 +43,11 @@ bool cmIncludeDirectoryCommand for(; i != args.end(); ++i) { + if(*i == "SYSTEM") + { + system = true; + continue; + } if(i->size() == 0) { cmSystemTools::Error @@ -60,6 +66,10 @@ bool cmIncludeDirectoryCommand } } this->Makefile->AddIncludeDirectory(unixPath.c_str(), before); + if(system) + { + this->Makefile->AddSystemIncludeDirectory(unixPath.c_str()); + } } return true; } diff --git a/Source/cmIncludeDirectoryCommand.h b/Source/cmIncludeDirectoryCommand.h index a22bc0e13..9247bbbaa 100644 --- a/Source/cmIncludeDirectoryCommand.h +++ b/Source/cmIncludeDirectoryCommand.h @@ -61,13 +61,16 @@ public: virtual const char* GetFullDocumentation() { return - " INCLUDE_DIRECTORIES([AFTER|BEFORE] dir1 dir2 ...)\n" + " INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)\n" "Add the given directories to those searched by the compiler for " "include files. By default the directories are appended onto " "the current list of directories. This default behavior can be " "changed by setting CMAKE_INCLUDE_DIRECTORIES_BEFORE to ON. " "By using BEFORE or AFTER you can select between appending and " - "prepending, independent from the default. "; + "prepending, independent from the default. " + "If the SYSTEM option is given the compiler will be told that the " + "directories are meant as system include directories on some " + "platforms."; } cmTypeMacro(cmIncludeDirectoryCommand, cmCommand); diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 3436d6ff3..890e905c0 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1044,6 +1044,17 @@ const char* cmLocalGenerator::GetIncludeFlags(const char* lang) // given once i.e. -classpath a:b:c repeatFlag = false; } + + // Support special system include flag if it is available and the + // normal flag is repeated for each directory. + std::string sysFlagVar = "CMAKE_INCLUDE_SYSTEM_FLAG_"; + sysFlagVar += lang; + const char* sysIncludeFlag = 0; + if(repeatFlag) + { + sysIncludeFlag = this->Makefile->GetDefinition(sysFlagVar.c_str()); + } + bool flagUsed = false; std::set emitted; for(i = includes.begin(); i != includes.end(); ++i) @@ -1066,7 +1077,15 @@ const char* cmLocalGenerator::GetIncludeFlags(const char* lang) std::string include = *i; if(!flagUsed || repeatFlag) { - includeFlags << includeFlag; + if(sysIncludeFlag && + this->Makefile->IsSystemIncludeDirectory(i->c_str())) + { + includeFlags << sysIncludeFlag; + } + else + { + includeFlags << includeFlag; + } flagUsed = true; } std::string includePath = this->ConvertToOutputForExisting(i->c_str()); diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 226f5d51e..88f55ddca 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -106,6 +106,7 @@ cmMakefile::cmMakefile(const cmMakefile& mf) this->Tests = mf.Tests; this->IncludeDirectories = mf.IncludeDirectories; this->LinkDirectories = mf.LinkDirectories; + this->SystemIncludeDirectories = mf.SystemIncludeDirectories; this->ListFiles = mf.ListFiles; this->OutputFiles = mf.OutputFiles; this->LinkLibraries = mf.LinkLibraries; @@ -1025,6 +1026,7 @@ void cmMakefile::InitializeFromParent() // copy include paths this->IncludeDirectories = parent->IncludeDirectories; + this->SystemIncludeDirectories = parent->SystemIncludeDirectories; // define flags this->DefineFlags = parent->DefineFlags; @@ -1150,6 +1152,19 @@ void cmMakefile::AddIncludeDirectory(const char* inc, bool before) } } +//---------------------------------------------------------------------------- +void cmMakefile::AddSystemIncludeDirectory(const char* dir) +{ + this->SystemIncludeDirectories.insert(dir); +} + +//---------------------------------------------------------------------------- +bool cmMakefile::IsSystemIncludeDirectory(const char* dir) +{ + return (this->SystemIncludeDirectories.find(dir) != + this->SystemIncludeDirectories.end()); +} + void cmMakefile::AddDefinition(const char* name, const char* value) { if (!value ) diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 942858ee2..df3850450 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -441,6 +441,12 @@ public: this->IncludeDirectories = vec; } + /** + * Mark include directories as system directories. + */ + void AddSystemIncludeDirectory(const char* dir); + bool IsSystemIncludeDirectory(const char* dir); + /** Expand out any arguements in the vector that have ; separated * strings into multiple arguements. A new vector is created * containing the expanded versions of all arguments in argsIn. @@ -739,7 +745,11 @@ protected: // dependency, so they must be vectors (not set). std::vector IncludeDirectories; std::vector LinkDirectories; - + + // The set of include directories that are marked as system include + // directories. + std::set SystemIncludeDirectories; + std::vector ListFiles; // list of command files loaded std::vector OutputFiles; // list of command files loaded diff --git a/Tests/Complex/CMakeLists.txt b/Tests/Complex/CMakeLists.txt index 3e5619f93..90f4820f4 100644 --- a/Tests/Complex/CMakeLists.txt +++ b/Tests/Complex/CMakeLists.txt @@ -91,8 +91,8 @@ ENDIF(${fooCACHE_TEST_VAR2} MATCHES bar) # Specify include and lib dirs # (BEFORE is for coverage) # +INCLUDE_DIRECTORIES(SYSTEM Library) INCLUDE_DIRECTORIES( - Library ${Complex_SOURCE_DIR}/../../Source ${Complex_BINARY_DIR}/../../Source ) @@ -101,7 +101,7 @@ INCLUDE_DIRECTORIES(BEFORE ${Complex_BINARY_DIR} ) -INCLUDE_REGULAR_EXPRESSION("^(cmTest|file|sharedFile).*$" "^cmMissing") +INCLUDE_REGULAR_EXPRESSION("^(cmTest|file|sharedFile|test).*$" "^cmMissing") LINK_DIRECTORIES( ${Complex_BINARY_DIR}/Library diff --git a/Tests/Complex/Executable/CMakeLists.txt b/Tests/Complex/Executable/CMakeLists.txt index 11235f5ae..01b4b2007 100644 --- a/Tests/Complex/Executable/CMakeLists.txt +++ b/Tests/Complex/Executable/CMakeLists.txt @@ -118,6 +118,11 @@ ADD_DEPENDENCIES(notInAllCustom notInAllExe) # ADD_SUBDIRECTORY(Temp) +IF(CMAKE_COMPILER_IS_GNUCXX) + ADD_EXECUTABLE(testSystemDir testSystemDir.cxx) + SET_TARGET_PROPERTIES(testSystemDir PROPERTIES COMPILE_FLAGS "-Werror") +ENDIF(CMAKE_COMPILER_IS_GNUCXX) + # # Extra coverage.Not used. # diff --git a/Tests/Complex/Executable/testSystemDir.cxx b/Tests/Complex/Executable/testSystemDir.cxx new file mode 100644 index 000000000..e4815c679 --- /dev/null +++ b/Tests/Complex/Executable/testSystemDir.cxx @@ -0,0 +1,3 @@ +#include + +int main() { return foo(); } diff --git a/Tests/Complex/Library/testSystemDir.h b/Tests/Complex/Library/testSystemDir.h new file mode 100644 index 000000000..73be3538e --- /dev/null +++ b/Tests/Complex/Library/testSystemDir.h @@ -0,0 +1,2 @@ +// Purposely leave off the return type to create a warning. +foo() { return 0; } diff --git a/Tests/ComplexOneConfig/CMakeLists.txt b/Tests/ComplexOneConfig/CMakeLists.txt index 3e5619f93..90f4820f4 100644 --- a/Tests/ComplexOneConfig/CMakeLists.txt +++ b/Tests/ComplexOneConfig/CMakeLists.txt @@ -91,8 +91,8 @@ ENDIF(${fooCACHE_TEST_VAR2} MATCHES bar) # Specify include and lib dirs # (BEFORE is for coverage) # +INCLUDE_DIRECTORIES(SYSTEM Library) INCLUDE_DIRECTORIES( - Library ${Complex_SOURCE_DIR}/../../Source ${Complex_BINARY_DIR}/../../Source ) @@ -101,7 +101,7 @@ INCLUDE_DIRECTORIES(BEFORE ${Complex_BINARY_DIR} ) -INCLUDE_REGULAR_EXPRESSION("^(cmTest|file|sharedFile).*$" "^cmMissing") +INCLUDE_REGULAR_EXPRESSION("^(cmTest|file|sharedFile|test).*$" "^cmMissing") LINK_DIRECTORIES( ${Complex_BINARY_DIR}/Library diff --git a/Tests/ComplexOneConfig/Executable/CMakeLists.txt b/Tests/ComplexOneConfig/Executable/CMakeLists.txt index 11235f5ae..01b4b2007 100644 --- a/Tests/ComplexOneConfig/Executable/CMakeLists.txt +++ b/Tests/ComplexOneConfig/Executable/CMakeLists.txt @@ -118,6 +118,11 @@ ADD_DEPENDENCIES(notInAllCustom notInAllExe) # ADD_SUBDIRECTORY(Temp) +IF(CMAKE_COMPILER_IS_GNUCXX) + ADD_EXECUTABLE(testSystemDir testSystemDir.cxx) + SET_TARGET_PROPERTIES(testSystemDir PROPERTIES COMPILE_FLAGS "-Werror") +ENDIF(CMAKE_COMPILER_IS_GNUCXX) + # # Extra coverage.Not used. # diff --git a/Tests/ComplexOneConfig/Executable/testSystemDir.cxx b/Tests/ComplexOneConfig/Executable/testSystemDir.cxx new file mode 100644 index 000000000..e4815c679 --- /dev/null +++ b/Tests/ComplexOneConfig/Executable/testSystemDir.cxx @@ -0,0 +1,3 @@ +#include + +int main() { return foo(); } diff --git a/Tests/ComplexOneConfig/Library/testSystemDir.h b/Tests/ComplexOneConfig/Library/testSystemDir.h new file mode 100644 index 000000000..73be3538e --- /dev/null +++ b/Tests/ComplexOneConfig/Library/testSystemDir.h @@ -0,0 +1,2 @@ +// Purposely leave off the return type to create a warning. +foo() { return 0; } diff --git a/Tests/ComplexRelativePaths/CMakeLists.txt b/Tests/ComplexRelativePaths/CMakeLists.txt index 3e5619f93..90f4820f4 100644 --- a/Tests/ComplexRelativePaths/CMakeLists.txt +++ b/Tests/ComplexRelativePaths/CMakeLists.txt @@ -91,8 +91,8 @@ ENDIF(${fooCACHE_TEST_VAR2} MATCHES bar) # Specify include and lib dirs # (BEFORE is for coverage) # +INCLUDE_DIRECTORIES(SYSTEM Library) INCLUDE_DIRECTORIES( - Library ${Complex_SOURCE_DIR}/../../Source ${Complex_BINARY_DIR}/../../Source ) @@ -101,7 +101,7 @@ INCLUDE_DIRECTORIES(BEFORE ${Complex_BINARY_DIR} ) -INCLUDE_REGULAR_EXPRESSION("^(cmTest|file|sharedFile).*$" "^cmMissing") +INCLUDE_REGULAR_EXPRESSION("^(cmTest|file|sharedFile|test).*$" "^cmMissing") LINK_DIRECTORIES( ${Complex_BINARY_DIR}/Library diff --git a/Tests/ComplexRelativePaths/Executable/CMakeLists.txt b/Tests/ComplexRelativePaths/Executable/CMakeLists.txt index 11235f5ae..01b4b2007 100644 --- a/Tests/ComplexRelativePaths/Executable/CMakeLists.txt +++ b/Tests/ComplexRelativePaths/Executable/CMakeLists.txt @@ -118,6 +118,11 @@ ADD_DEPENDENCIES(notInAllCustom notInAllExe) # ADD_SUBDIRECTORY(Temp) +IF(CMAKE_COMPILER_IS_GNUCXX) + ADD_EXECUTABLE(testSystemDir testSystemDir.cxx) + SET_TARGET_PROPERTIES(testSystemDir PROPERTIES COMPILE_FLAGS "-Werror") +ENDIF(CMAKE_COMPILER_IS_GNUCXX) + # # Extra coverage.Not used. # diff --git a/Tests/ComplexRelativePaths/Executable/testSystemDir.cxx b/Tests/ComplexRelativePaths/Executable/testSystemDir.cxx new file mode 100644 index 000000000..e4815c679 --- /dev/null +++ b/Tests/ComplexRelativePaths/Executable/testSystemDir.cxx @@ -0,0 +1,3 @@ +#include + +int main() { return foo(); } diff --git a/Tests/ComplexRelativePaths/Library/testSystemDir.h b/Tests/ComplexRelativePaths/Library/testSystemDir.h new file mode 100644 index 000000000..73be3538e --- /dev/null +++ b/Tests/ComplexRelativePaths/Library/testSystemDir.h @@ -0,0 +1,2 @@ +// Purposely leave off the return type to create a warning. +foo() { return 0; }