diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmExtraSublimeTextGenerator.cxx | 42 | ||||
-rw-r--r-- | Source/cmExtraSublimeTextGenerator.h | 3 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.cxx | 10 | ||||
-rw-r--r-- | Source/cmLocalGenerator.cxx | 48 | ||||
-rw-r--r-- | Source/cmLocalGenerator.h | 17 | ||||
-rw-r--r-- | Source/cmLocalVisualStudio7Generator.cxx | 13 | ||||
-rw-r--r-- | Source/cmMakefileTargetGenerator.cxx | 22 | ||||
-rw-r--r-- | Source/cmNinjaTargetGenerator.cxx | 26 | ||||
-rw-r--r-- | Source/cmNinjaTargetGenerator.h | 3 | ||||
-rw-r--r-- | Source/cmServerProtocol.cxx | 19 | ||||
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.cxx | 19 |
11 files changed, 206 insertions, 16 deletions
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx index 7e998c7..a89c187 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 57ba1cf..bc158f6 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 7813ec7..9db21d8 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 d918cf3..86b16f8 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 b993967..a66fa6e 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 f46c01a..996a649 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 bee0168..1543536 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 566924f..4f37882 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 770a99d..4660a3a 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 f91d296..c2dee8f 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 c3a77e2..fc165b6 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, " "); |