From b61fcdc8bc0d4b7b5104195abcfe03154e35bf52 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 29 Jul 2019 10:58:47 -0400 Subject: fileapi: Compute codemodel compile groups without target-wide settings Previously we computed the entire description of each source file including all target-wide settings, and then computed compile groups using those complete descriptions. This is inefficient when target-wide settings are large because they are included in comparisons even though they are the same for every source. Instead compute source groups using only the source-specific settings, and then merge the target-wide settings into place only once per unique compile group. This is a slight behavior change in the case that a source-specific compile definition duplicates a target-wide definition. Previously that source would still be grouped with other sources which do not have the definition because they would all get it from the target. Now that source will be in its own compile group even though it ultimately compiles with the same settings as another group. This is acceptable because the source is specified by the project with source-specific settings already. Fixes: #19520 --- Source/cmFileAPICodemodel.cxx | 53 ++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx index 2a15fd7..e9ee7f5 100644 --- a/Source/cmFileAPICodemodel.cxx +++ b/Source/cmFileAPICodemodel.cxx @@ -359,6 +359,7 @@ class Target Json::ArrayIndex AddSourceGroup(cmSourceGroup* sg, Json::ArrayIndex si); CompileData BuildCompileData(cmSourceFile* sf); + CompileData MergeCompileData(CompileData const& fd); Json::ArrayIndex AddSourceCompileGroup(cmSourceFile* sf, Json::ArrayIndex si); void AddBacktrace(Json::Value& object, cmListFileBacktrace const& bt); @@ -839,15 +840,11 @@ CompileData Target::BuildCompileData(cmSourceFile* sf) if (fd.Language.empty()) { return fd; } - CompileData const& cd = this->CompileDataMap.at(fd.Language); - - fd.Sysroot = cd.Sysroot; cmLocalGenerator* lg = this->GT->GetLocalGenerator(); cmGeneratorExpressionInterpreter genexInterpreter(lg, this->Config, this->GT, fd.Language); - fd.Flags = cd.Flags; const std::string COMPILE_FLAGS("COMPILE_FLAGS"); if (const char* cflags = sf->GetProperty(COMPILE_FLAGS)) { std::string flags = genexInterpreter.Evaluate(cflags, COMPILE_FLAGS); @@ -877,8 +874,6 @@ CompileData Target::BuildCompileData(cmSourceFile* sf) } } } - fd.Includes.insert(fd.Includes.end(), cd.Includes.begin(), - cd.Includes.end()); const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS"); std::set fileDefines; @@ -895,20 +890,51 @@ CompileData Target::BuildCompileData(cmSourceFile* sf) genexInterpreter.Evaluate(config_defs, COMPILE_DEFINITIONS)); } - fd.Defines.reserve(cd.Defines.size() + fileDefines.size()); - fd.Defines = cd.Defines; + fd.Defines.reserve(fileDefines.size()); for (std::string const& d : fileDefines) { fd.Defines.emplace_back(d, JBTIndex()); } + return fd; +} + +CompileData Target::MergeCompileData(CompileData const& fd) +{ + CompileData cd; + cd.Language = fd.Language; + if (cd.Language.empty()) { + return cd; + } + CompileData const& td = this->CompileDataMap.at(cd.Language); + + // All compile groups share the sysroot of the target. + cd.Sysroot = td.Sysroot; + + // Use target-wide flags followed by source-specific flags. + cd.Flags.reserve(td.Flags.size() + fd.Flags.size()); + cd.Flags.insert(cd.Flags.end(), td.Flags.begin(), td.Flags.end()); + cd.Flags.insert(cd.Flags.end(), fd.Flags.begin(), fd.Flags.end()); + + // Use source-specific includes followed by target-wide includes. + cd.Includes.reserve(fd.Includes.size() + td.Includes.size()); + cd.Includes.insert(cd.Includes.end(), fd.Includes.begin(), + fd.Includes.end()); + cd.Includes.insert(cd.Includes.end(), td.Includes.begin(), + td.Includes.end()); + + // Use target-wide defines followed by source-specific defines. + cd.Defines.reserve(td.Defines.size() + fd.Defines.size()); + cd.Defines.insert(cd.Defines.end(), td.Defines.begin(), td.Defines.end()); + cd.Defines.insert(cd.Defines.end(), fd.Defines.begin(), fd.Defines.end()); + // De-duplicate defines. - std::stable_sort(fd.Defines.begin(), fd.Defines.end(), + std::stable_sort(cd.Defines.begin(), cd.Defines.end(), JBT::ValueLess); - auto end = std::unique(fd.Defines.begin(), fd.Defines.end(), + auto end = std::unique(cd.Defines.begin(), cd.Defines.end(), JBT::ValueEq); - fd.Defines.erase(end, fd.Defines.end()); + cd.Defines.erase(end, cd.Defines.end()); - return fd; + return cd; } Json::ArrayIndex Target::AddSourceCompileGroup(cmSourceFile* sf, @@ -1084,7 +1110,8 @@ Json::Value Target::DumpCompileGroups() Json::Value Target::DumpCompileGroup(CompileGroup& cg) { - Json::Value group = this->DumpCompileData(cg.Entry->first); + Json::Value group = + this->DumpCompileData(this->MergeCompileData(cg.Entry->first)); group["sourceIndexes"] = std::move(cg.SourceIndexes); return group; } -- cgit v0.12