summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorMarc Chevrier <marc.chevrier@sap.com>2017-12-21 17:03:18 +0100
committerMarc Chevrier <marc.chevrier@sap.com>2018-01-24 15:10:10 +0100
commit044831117955dfa33ed4e0c7799ea3f37258b149 (patch)
treea443e5f1695bc9290ac7a8c27e4d0df019146a8d /Source
parent3073bd1f3deecaaf090202075382e372a3b3656a (diff)
downloadcmake-044831117955dfa33ed4e0c7799ea3f37258b149.tar.gz
sourceFile properties: add property INCLUDE_DIRECTORIES
Diffstat (limited to 'Source')
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx42
-rw-r--r--Source/cmExtraSublimeTextGenerator.h3
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx10
-rw-r--r--Source/cmLocalGenerator.cxx48
-rw-r--r--Source/cmLocalGenerator.h17
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx13
-rw-r--r--Source/cmMakefileTargetGenerator.cxx22
-rw-r--r--Source/cmNinjaTargetGenerator.cxx26
-rw-r--r--Source/cmNinjaTargetGenerator.h3
-rw-r--r--Source/cmServerProtocol.cxx19
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx19
11 files changed, 206 insertions, 16 deletions
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 7e998c71f4..a89c18734b 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -257,6 +257,8 @@ void cmExtraSublimeTextGenerator::AppendTarget(
std::string flagsString =
this->ComputeFlagsForObject(sourceFile, lg, target);
std::string definesString = this->ComputeDefines(sourceFile, lg, target);
+ std::string includesString =
+ this->ComputeIncludes(sourceFile, lg, target);
flags.clear();
cmsys::RegularExpression flagRegex;
// Regular expression to extract compiler flags from a string
@@ -264,7 +266,8 @@ void cmExtraSublimeTextGenerator::AppendTarget(
const char* regexString =
"(^|[ ])-[DIOUWfgs][^= ]+(=\\\"[^\"]+\\\"|=[^\"][^ ]+)?";
flagRegex.compile(regexString);
- std::string workString = flagsString + " " + definesString;
+ std::string workString =
+ flagsString + " " + definesString + " " + includesString;
while (flagRegex.find(workString)) {
std::string::size_type start = flagRegex.start();
if (workString[start] == ' ') {
@@ -351,15 +354,6 @@ std::string cmExtraSublimeTextGenerator::ComputeFlagsForObject(
lg->GetTargetCompileFlags(gtgt, config, language, flags);
- // Add include directory flags.
- {
- std::vector<std::string> includes;
- lg->GetIncludeDirectories(includes, gtgt, language, config);
- std::string includeFlags = lg->GetIncludeFlags(includes, gtgt, language,
- true); // full include paths
- lg->AppendFlags(flags, includeFlags);
- }
-
// Add source file specific flags.
cmGeneratorExpressionInterpreter genexInterpreter(lg, gtgt, config,
gtgt->GetName(), language);
@@ -417,6 +411,34 @@ std::string cmExtraSublimeTextGenerator::ComputeDefines(
return definesString;
}
+std::string cmExtraSublimeTextGenerator::ComputeIncludes(
+ cmSourceFile* source, cmLocalGenerator* lg, cmGeneratorTarget* target)
+
+{
+ std::vector<std::string> includes;
+ cmMakefile* makefile = lg->GetMakefile();
+ const std::string& language = source->GetLanguage();
+ const std::string& config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ cmGeneratorExpressionInterpreter genexInterpreter(
+ lg, target, config, target->GetName(), language);
+
+ // Add include directories for this source file
+ const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
+ if (const char* cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) {
+ lg->AppendIncludeDirectories(
+ includes, genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES),
+ *source);
+ }
+
+ // Add include directory flags.
+ lg->GetIncludeDirectories(includes, target, language, config);
+
+ std::string includesString =
+ lg->GetIncludeFlags(includes, target, language, true, false, config);
+
+ return includesString;
+}
+
bool cmExtraSublimeTextGenerator::Open(const std::string& bindir,
const std::string& projectName,
bool dryRun)
diff --git a/Source/cmExtraSublimeTextGenerator.h b/Source/cmExtraSublimeTextGenerator.h
index 57ba1cfa13..bc158f6b4e 100644
--- a/Source/cmExtraSublimeTextGenerator.h
+++ b/Source/cmExtraSublimeTextGenerator.h
@@ -65,6 +65,9 @@ private:
std::string ComputeDefines(cmSourceFile* source, cmLocalGenerator* lg,
cmGeneratorTarget* gtgt);
+ std::string ComputeIncludes(cmSourceFile* source, cmLocalGenerator* lg,
+ cmGeneratorTarget* gtgt);
+
bool Open(const std::string& bindir, const std::string& projectName,
bool dryRun) override;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 7813ec778a..9db21d8d11 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -764,6 +764,16 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
flags += flagsBuild.GetString();
}
+ // Add per-source include directories.
+ std::vector<std::string> includes;
+ const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
+ if (const char* cincludes = sf->GetProperty(INCLUDE_DIRECTORIES)) {
+ lg->AppendIncludeDirectories(
+ includes, genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES),
+ *sf);
+ }
+ lg->AppendFlags(flags, lg->GetIncludeFlags(includes, gtgt, lang, true));
+
cmXCodeObject* buildFile =
this->CreateXCodeSourceFileFromPath(sf->GetFullPath(), gtgt, lang, sf);
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index d918cf335b..86b16f8e37 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -16,6 +16,7 @@
#include "cmMakefile.h"
#include "cmRulePlaceholderExpander.h"
#include "cmSourceFile.h"
+#include "cmSourceFileLocation.h"
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateTypes.h"
@@ -37,6 +38,7 @@
#include <sstream>
#include <stdio.h>
#include <string.h>
+#include <unordered_set>
#include <utility>
#if defined(__HAIKU__)
@@ -1959,6 +1961,52 @@ void cmLocalGenerator::AppendCompileOptions(
}
}
+void cmLocalGenerator::AppendIncludeDirectories(
+ std::vector<std::string>& includes, const char* includes_list,
+ const cmSourceFile& sourceFile) const
+{
+ // Short-circuit if there are no includes.
+ if (!includes_list) {
+ return;
+ }
+
+ // Expand the list of includes.
+ std::vector<std::string> includes_vec;
+ cmSystemTools::ExpandListArgument(includes_list, includes_vec);
+ this->AppendIncludeDirectories(includes, includes_vec, sourceFile);
+}
+
+void cmLocalGenerator::AppendIncludeDirectories(
+ std::vector<std::string>& includes,
+ const std::vector<std::string>& includes_vec,
+ const cmSourceFile& sourceFile) const
+{
+ std::unordered_set<std::string> uniqueIncludes;
+
+ for (const std::string& include : includes_vec) {
+ if (!cmSystemTools::FileIsFullPath(include.c_str())) {
+ std::ostringstream e;
+ e << "Found relative path while evaluating include directories of "
+ "\""
+ << sourceFile.GetLocation().GetName() << "\":\n \"" << include
+ << "\"\n";
+
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return;
+ }
+
+ std::string inc = include;
+
+ if (!cmSystemTools::IsOff(inc.c_str())) {
+ cmSystemTools::ConvertToUnixSlashes(inc);
+ }
+
+ if (uniqueIncludes.insert(inc).second) {
+ includes.push_back(inc);
+ }
+ }
+}
+
void cmLocalGenerator::AppendDefines(std::set<std::string>& defines,
const char* defines_list) const
{
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index b993967319..a66fa6e12c 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -153,6 +153,23 @@ public:
cmGeneratorTarget* FindGeneratorTargetToUse(const std::string& name) const;
/**
+ * Process a list of include directories
+ */
+ void AppendIncludeDirectories(std::vector<std::string>& includes,
+ const char* includes_list,
+ const cmSourceFile& sourceFile) const;
+ void AppendIncludeDirectories(std::vector<std::string>& includes,
+ std::string const& includes_list,
+ const cmSourceFile& sourceFile) const
+ {
+ this->AppendIncludeDirectories(includes, includes_list.c_str(),
+ sourceFile);
+ }
+ void AppendIncludeDirectories(std::vector<std::string>& includes,
+ const std::vector<std::string>& includes_vec,
+ const cmSourceFile& sourceFile) const;
+
+ /**
* Encode a list of preprocessor definitions for the compiler
* command line.
*/
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index f46c01a5cc..996a649566 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -1396,6 +1396,7 @@ struct cmLVS7GFileConfig
std::string CompileDefs;
std::string CompileDefsConfig;
std::string AdditionalDeps;
+ std::string IncludeDirs;
bool ExcludedFromBuild;
};
@@ -1484,6 +1485,12 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
needfc = true;
}
+ const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
+ if (const char* cincs = sf.GetProperty(INCLUDE_DIRECTORIES)) {
+ fc.IncludeDirs = genexInterpreter.Evaluate(cincs, INCLUDE_DIRECTORIES);
+ needfc = true;
+ }
+
// Check for extra object-file dependencies.
if (const char* deps = sf.GetProperty("OBJECT_DEPENDS")) {
std::vector<std::string> depends;
@@ -1661,7 +1668,7 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
fout << "\t\t\t\t\t<Tool\n"
<< "\t\t\t\t\tName=\"" << aCompilerTool << "\"\n";
if (!fc.CompileFlags.empty() || !fc.CompileDefs.empty() ||
- !fc.CompileDefsConfig.empty()) {
+ !fc.CompileDefsConfig.empty() || !fc.IncludeDirs.empty()) {
Options::Tool tool = Options::Compiler;
cmVS7FlagTable const* table =
cmLocalVisualStudio7GeneratorFlagTable;
@@ -1673,6 +1680,10 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
fileOptions.Parse(fc.CompileFlags.c_str());
fileOptions.AddDefines(fc.CompileDefs.c_str());
fileOptions.AddDefines(fc.CompileDefsConfig.c_str());
+ // validate source level include directories
+ std::vector<std::string> includes;
+ this->AppendIncludeDirectories(includes, fc.IncludeDirs, **sf);
+ fileOptions.AddIncludes(includes);
fileOptions.OutputFlagMap(fout, "\t\t\t\t\t");
fileOptions.OutputAdditionalIncludeDirectories(
fout, "\t\t\t\t\t", "\n",
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index bee016848e..1543536614 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -455,10 +455,25 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
<< "\n";
}
+ // Add include directories from source file properties.
+ std::vector<std::string> includes;
+
+ const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
+ if (const char* cincludes = source.GetProperty(INCLUDE_DIRECTORIES)) {
+ const char* evaluatedIncludes =
+ genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES);
+ this->LocalGenerator->AppendIncludeDirectories(includes, evaluatedIncludes,
+ source);
+ *this->FlagFileStream << "# Custom include directories: " << relativeObj
+ << "_INCLUDE_DIRECTORIES = " << evaluatedIncludes
+ << "\n"
+ << "\n";
+ }
+
// Add language-specific defines.
std::set<std::string> defines;
- // Add source-sepcific preprocessor definitions.
+ // Add source-specific preprocessor definitions.
const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
if (const char* compile_defs = source.GetProperty(COMPILE_DEFINITIONS)) {
const char* evaluatedDefs =
@@ -575,7 +590,10 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
vars.Defines = definesString.c_str();
- std::string const includesString = "$(" + lang + "_INCLUDES)";
+ std::string includesString = this->LocalGenerator->GetIncludeFlags(
+ includes, this->GeneratorTarget, lang, true, false, config);
+ this->LocalGenerator->AppendFlags(includesString,
+ "$(" + lang + "_INCLUDES)");
vars.Includes = includesString.c_str();
// At the moment, it is assumed that C, C++, Fortran, and CUDA have both
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 566924ff48..4f37882f29 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -211,6 +211,30 @@ std::string cmNinjaTargetGenerator::ComputeDefines(cmSourceFile const* source,
return definesString;
}
+std::string cmNinjaTargetGenerator::ComputeIncludes(
+ cmSourceFile const* source, const std::string& language)
+{
+ std::vector<std::string> includes;
+ const std::string config = this->LocalGenerator->GetConfigName();
+ cmGeneratorExpressionInterpreter genexInterpreter(
+ this->LocalGenerator, this->GeneratorTarget, config,
+ this->GeneratorTarget->GetName(), language);
+
+ const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
+ if (const char* cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) {
+ this->LocalGenerator->AppendIncludeDirectories(
+ includes, genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES),
+ *source);
+ }
+
+ std::string includesString = this->LocalGenerator->GetIncludeFlags(
+ includes, this->GeneratorTarget, language, true, false, config);
+ this->LocalGenerator->AppendFlags(includesString,
+ this->GetIncludes(language));
+
+ return includesString;
+}
+
cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const
{
// Static libraries never depend on other targets for linking.
@@ -825,7 +849,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
cmNinjaVars vars;
vars["FLAGS"] = this->ComputeFlagsForObject(source, language);
vars["DEFINES"] = this->ComputeDefines(source, language);
- vars["INCLUDES"] = this->GetIncludes(language);
+ vars["INCLUDES"] = this->ComputeIncludes(source, language);
if (!this->NeedDepTypeMSVC(language)) {
vars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat(
objectFileName + ".d", cmOutputConverter::SHELL);
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 770a99d7fa..4660a3ae8b 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -82,6 +82,9 @@ protected:
std::string ComputeDefines(cmSourceFile const* source,
const std::string& language);
+ std::string ComputeIncludes(cmSourceFile const* source,
+ const std::string& language);
+
std::string ConvertToNinjaPath(const std::string& path) const
{
return this->GetGlobalGenerator()->ConvertToNinjaPath(path);
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index f91d2966fc..c2dee8f96f 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -715,7 +715,24 @@ static Json::Value DumpSourceFilesList(
}
fileData.Flags = compileFlags;
- fileData.IncludePathList = ld.IncludePathList;
+ // Add include directories from source file properties.
+ std::vector<std::string> includes;
+
+ const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
+ if (const char* cincludes = file->GetProperty(INCLUDE_DIRECTORIES)) {
+ const char* evaluatedIncludes =
+ genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES);
+ lg->AppendIncludeDirectories(includes, evaluatedIncludes, *file);
+
+ for (const auto& include : includes) {
+ fileData.IncludePathList.push_back(std::make_pair(
+ include, target->IsSystemIncludeDirectory(include, config)));
+ }
+ }
+
+ fileData.IncludePathList.insert(fileData.IncludePathList.end(),
+ ld.IncludePathList.begin(),
+ ld.IncludePathList.end());
const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
std::set<std::string> defines;
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index c3a77e2af2..fc165b6301 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2024,6 +2024,8 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
bool configDependentOptions = false;
std::string defines;
bool configDependentDefines = false;
+ std::string includes;
+ bool configDependentIncludes = false;
if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) {
configDependentFlags =
cmGeneratorExpression::Find(cflags) != std::string::npos;
@@ -2039,6 +2041,11 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
cmGeneratorExpression::Find(cdefs) != std::string::npos;
defines += cdefs;
}
+ if (const char* cincludes = sf.GetProperty("INCLUDE_DIRECTORIES")) {
+ configDependentIncludes =
+ cmGeneratorExpression::Find(cincludes) != std::string::npos;
+ includes += cincludes;
+ }
std::string lang =
this->GlobalGenerator->GetLanguageFromExtension(sf.GetExtension().c_str());
std::string sourceLang = this->LocalGenerator->GetSourceFileLanguage(sf);
@@ -2091,7 +2098,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
// if we have flags or defines for this config then
// use them
if (!flags.empty() || !options.empty() || !configDefines.empty() ||
- compileAs || noWinRT) {
+ !includes.empty() || compileAs || noWinRT) {
(*this->BuildFileStream) << firstString;
firstString = ""; // only do firstString once
hasFlags = true;
@@ -2150,6 +2157,16 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
} else {
clOptions.AddDefines(configDefines.c_str());
}
+ std::vector<std::string> includeList;
+ if (configDependentIncludes) {
+ this->LocalGenerator->AppendIncludeDirectories(
+ includeList,
+ genexInterpreter.Evaluate(includes, "INCLUDE_DIRECTORIES"), *source);
+ } else {
+ this->LocalGenerator->AppendIncludeDirectories(includeList, includes,
+ *source);
+ }
+ clOptions.AddIncludes(includeList);
clOptions.SetConfiguration(config.c_str());
clOptions.PrependInheritedString("AdditionalOptions");
clOptions.OutputFlagMap(*this->BuildFileStream, " ");