| 158 | } |
| 159 | |
| 160 | std::vector<std::string> cmFileSet::EvaluateDirectoryEntries( |
| 161 | std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> const& cges, |
| 162 | cm::GenEx::Context const& context, cmGeneratorTarget const* target, |
| 163 | cmGeneratorExpressionDAGChecker* dagChecker) const |
| 164 | { |
| 165 | struct DirCacheEntry |
| 166 | { |
| 167 | std::string collapsedDir; |
| 168 | cm::optional<cmSystemTools::FileId> fileId; |
| 169 | }; |
| 170 | |
| 171 | std::unordered_map<std::string, DirCacheEntry> dirCache; |
| 172 | std::vector<std::string> result; |
| 173 | for (auto const& cge : cges) { |
| 174 | auto entry = cge->Evaluate(context, dagChecker, target); |
| 175 | cmList dirs{ entry }; |
| 176 | for (std::string dir : dirs) { |
| 177 | if (!cmSystemTools::FileIsFullPath(dir)) { |
| 178 | dir = cmStrCat(context.LG->GetCurrentSourceDirectory(), '/', dir); |
| 179 | } |
| 180 | |
| 181 | auto dirCacheResult = dirCache.emplace(dir, DirCacheEntry()); |
| 182 | auto& dirCacheEntry = dirCacheResult.first->second; |
| 183 | auto const isNewCacheEntry = dirCacheResult.second; |
| 184 | |
| 185 | if (isNewCacheEntry) { |
| 186 | cmSystemTools::FileId fileId; |
| 187 | auto isFileIdValid = cmSystemTools::GetFileId(dir, fileId); |
| 188 | dirCacheEntry.collapsedDir = cmSystemTools::CollapseFullPath(dir); |
| 189 | dirCacheEntry.fileId = |
| 190 | isFileIdValid ? cm::optional<decltype(fileId)>(fileId) : cm::nullopt; |
| 191 | } |
| 192 | |
| 193 | for (auto const& priorDir : result) { |
| 194 | auto priorDirCacheEntry = dirCache.at(priorDir); |
| 195 | bool sameFile = dirCacheEntry.fileId.has_value() && |
| 196 | priorDirCacheEntry.fileId.has_value() && |
| 197 | (*dirCacheEntry.fileId == *priorDirCacheEntry.fileId); |
| 198 | if (!sameFile && |
| 199 | (cmSystemTools::IsSubDirectory(dirCacheEntry.collapsedDir, |
| 200 | priorDirCacheEntry.collapsedDir) || |
| 201 | cmSystemTools::IsSubDirectory(priorDirCacheEntry.collapsedDir, |
| 202 | dirCacheEntry.collapsedDir))) { |
| 203 | context.LG->GetCMakeInstance()->IssueMessage( |
| 204 | MessageType::FATAL_ERROR, |
| 205 | cmStrCat( |
| 206 | "Base directories in file set cannot be subdirectories of each " |
| 207 | "other:\n ", |
| 208 | priorDir, "\n ", dir), |
| 209 | cge->GetBacktrace()); |
| 210 | return {}; |
| 211 | } |
| 212 | } |
| 213 | result.push_back(dir); |
| 214 | } |
| 215 | } |
| 216 | return result; |
| 217 | } |
no test coverage detected