source_group(): Add file set support

This commit is contained in:
Marc Chevrier
2026-06-23 14:55:26 +02:00
parent 44fd6ec551
commit 6043014d1d
28 changed files with 385 additions and 95 deletions
+93 -36
View File
@@ -4,52 +4,37 @@ source_group
Define a grouping for source files in IDE project generation.
There are two different signatures to create source groups.
.. code-block:: cmake
Synopsis
^^^^^^^^
source_group(<name> [FILES <src>...] [REGULAR_EXPRESSION <regex>])
source_group(TREE <root> [PREFIX <prefix>] [FILES <src>...])
.. parsed-literal::
source_group(`\<group\>`_ [FILES <src>...] [REGULAR_EXPRESSION <regex>]
[FILE_SETS <fileset>... TARGET <target>]...)
source_group(`TREE`_ <root> [PREFIX <prefix>] [FILES <src>...])
Overview
^^^^^^^^
Defines a group into which sources will be placed in project files.
This is intended to set up file tabs in Visual Studio.
The group is scoped in the directory where the command is called,
and applies to sources in targets created in that directory.
The options are:
The group is scoped in the directory where the command is called, and applies
to sources in targets created in that directory.
``TREE``
.. versionadded:: 3.8
If the file is part of a file set, search for a group which explicitly lists
this file set. If no group has been found or the file is not part of a file
set, search for a group which explicitly lists the file.
CMake will automatically detect, from ``<src>`` files paths, source groups
it needs to create, to keep structure of source groups analogically to the
actual files and directories structure in the project. Paths of ``<src>``
files will be cut to be relative to ``<root>``. The command fails if the
paths within ``src`` do not start with ``root``.
If the file set or the source file matches multiple groups, the *last* group
that explicitly lists the file set with ``FILE_SETS`` or the file with
``FILES`` will be favored, if any.
``PREFIX``
.. versionadded:: 3.8
Source group and files located directly in ``<root>`` path, will be placed
in ``<prefix>`` source groups.
``FILES``
Any source file specified explicitly will be placed in group
``<name>``. Relative paths are interpreted with respect to the
current source directory.
.. versionadded:: 4.3
Arguments to ``FILES`` may use
:manual:`generator expressions <cmake-generator-expressions(7)>`.
``REGULAR_EXPRESSION``
Any source file whose name matches the regular expression will
be placed in group ``<name>``.
If a source file matches multiple groups, the *last* group that
explicitly lists the file with ``FILES`` will be favored, if any.
If no group explicitly lists the file, the *last* group whose
If no group explicitly lists the file set or the file, the *last* group whose
regular expression matches the file will be favored.
The ``<name>`` of the group and ``<prefix>`` argument may contain forward
The ``<group>`` and ``<prefix>`` arguments may contain forward
slashes or backslashes to specify subgroups. Backslashes need to be escaped
appropriately:
@@ -62,6 +47,78 @@ appropriately:
.. versionadded:: 3.18
Allow using forward slashes (``/``) to specify subgroups.
Commands
^^^^^^^^
.. signature::
source_group(<group> [FILES <src>...] [REGULAR_EXPRESSION <regex>]
[FILE_SETS <fileset>... TARGET <target>]...)
:target: <group>
The options are:
``<group>``
The name of the group.
``FILES <src>...``
Any source file specified explicitly will be placed in group
``<group>``. Relative paths are interpreted with respect to the
current source directory.
.. versionadded:: 4.3
Arguments to ``FILES`` may use
:manual:`generator expressions <cmake-generator-expressions(7)>`.
``REGULAR_EXPRESSION <regex>``
Any source file whose name matches the regular expression will
be placed in group ``<group>``.
``FILE_SETS <fileset>...``
.. versionadded:: 4.5
List of file sets. Files of these file sets will be placed in group
``<group>``. Arguments to ``FILE_SETS`` may use
:manual:`generator expressions <cmake-generator-expressions(7)>`.
``TARGET <target>``
.. versionadded:: 4.5
Associate the file sets declared with the previous ``FILE_SETS`` keyword
with the target ``<target>``.
.. note::
The pattern ``FILE_SETS <fileset>... TARGET <target>`` can be repeated
multiple times.
.. signature::
source_group(TREE <root> [PREFIX <prefix>] [FILES <src>...])
.. versionadded:: 3.8
The options are:
``TREE <root>``
CMake will automatically detect, from ``<src>`` files paths, source groups
it needs to create, to keep structure of source groups analogically to the
actual files and directories structure in the project. Paths of ``<src>``
files will be cut to be relative to ``<root>``. The command fails if the
paths within ``src`` do not start with ``root``.
``PREFIX <prefix>``
Source group and files located directly in ``<root>`` path, will be placed
in ``<prefix>`` source groups.
``FILES <src>...``
List of files used to create source group structure. Relative paths are
interpreted with respect to the current source directory.
.. versionadded:: 4.3
Arguments to ``FILES`` may use
:manual:`generator expressions <cmake-generator-expressions(7)>`.
Legacy Support
^^^^^^^^^^^^^^
For backwards compatibility, the short-hand signature
.. code-block:: cmake
@@ -0,0 +1,4 @@
source_group-FILE_SET-support
-----------------------------
* The :command:`source_group` command gains the support of the file sets.
+4 -4
View File
@@ -525,12 +525,12 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(cmXMLWriter& xml)
// get the files from the source lists then add them to the groups
cmSourceGroupFiles sourceGroupFiles;
std::vector<cmSourceFile*> files;
target->GetSourceFiles(
files, makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
cmValue config = makefile->GetDefinition("CMAKE_BUILD_TYPE");
target->GetSourceFiles(files, *config);
for (cmSourceFile* sf : files) {
// Add the file to the list of sources.
sourceGroupFiles.Add(lg->FindSourceGroup(sf->ResolveFullPath()),
sf);
sourceGroupFiles.Add(
lg->FindSourceGroup(target.get(), sf, *config), sf);
}
this->WriteGroups(makefile->GetSourceGroups(), sourceGroupFiles,
+4 -4
View File
@@ -1926,8 +1926,8 @@ Json::Value Target::DumpSource(cmGeneratorTarget::SourceAndKind const& sk,
}
}
if (cmSourceGroup const* sg =
this->GT->LocalGenerator->FindSourceGroup(path)) {
if (cmSourceGroup const* sg = this->GT->LocalGenerator->FindSourceGroup(
this->GT, sf, this->Config)) {
Json::ArrayIndex const groupIndex = this->AddSourceGroup(sg);
source["sourceGroupIndex"] = groupIndex;
this->SourceGroups[groupIndex].SourceIndexes.append(si);
@@ -2017,8 +2017,8 @@ Json::Value Target::DumpInterfaceSource(std::string path, Json::ArrayIndex si,
}
}
if (cmSourceGroup const* sg =
this->GT->LocalGenerator->FindSourceGroup(path)) {
if (cmSourceGroup const* sg = this->GT->LocalGenerator->FindSourceGroup(
this->GT, sf, this->Config)) {
Json::ArrayIndex const groupIndex = this->AddSourceGroup(sg);
source["sourceGroupIndex"] = groupIndex;
this->SourceGroups[groupIndex].InterfaceSourceIndexes.append(si);
+2 -2
View File
@@ -545,8 +545,8 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
std::map<std::string, std::vector<cmSourceFile*>> groupFiles;
std::set<std::string> groupNames;
for (cmSourceFile* sf : sources) {
cmSourceGroup const* sourceGroup =
this->LocalGenerator->FindSourceGroup(sf->ResolveFullPath());
cmSourceGroup const* sourceGroup = this->LocalGenerator->FindSourceGroup(
this->GeneratorTarget, sf, this->ConfigName);
std::string gn = sourceGroup->GetFullName();
groupFiles[gn].push_back(sf);
groupNames.insert(std::move(gn));
-1
View File
@@ -1810,7 +1810,6 @@ bool cmGlobalGenerator::Compute()
for (auto const& localGen : this->LocalGenerators) {
localGen->ComputeHomeRelativeOutputPath();
localGen->ComputeSourceGroupSearchIndex();
}
return true;
+12 -8
View File
@@ -4565,22 +4565,24 @@ bool cmGlobalXCodeGenerator::CreateGroups(
}
auto addSourceToGroup = [this, &gtgt,
&generator](std::string const& source) {
cmSourceGroup const* sourceGroup = generator->FindSourceGroup(source);
&generator](cmSourceFile const* source) {
cmSourceGroup const* sourceGroup = generator->FindSourceGroup(
gtgt.get(), source, this->CurrentConfigurationTypes.front());
cmXCodeObject* pbxgroup =
this->CreateOrGetPBXGroup(gtgt.get(), sourceGroup);
std::string key = GetGroupMapKeyFromPath(gtgt.get(), source);
std::string key =
GetGroupMapKeyFromPath(gtgt.get(), source->GetFullPath());
this->GroupMap[key] = pbxgroup;
};
// Put cmSourceFile instances in proper groups:
for (auto const& si : gtgt->GetAllConfigSources()) {
cmSourceFile const* sf = si.Source;
for (auto& si : gtgt->GetAllConfigSources()) {
cmSourceFile* sf = si.Source;
if (!sf->GetObjectLibrary().empty()) {
// Object library files go on the link line instead.
continue;
}
addSourceToGroup(sf->GetFullPath());
addSourceToGroup(sf);
}
// Add CMakeLists.txt file for user convenience.
@@ -4589,8 +4591,9 @@ bool cmGlobalXCodeGenerator::CreateGroups(
gtgt->GetLocalGenerator()->GetCurrentSourceDirectory());
cmSourceFile* sf = gtgt->Makefile->GetOrCreateSource(
listfile, false, cmSourceFileLocationKind::Known);
sf->ResolveFullPath();
sf->SetSpecialSourceType(cmSourceFile::SpecialSourceType::CMakeLists);
addSourceToGroup(sf->ResolveFullPath());
addSourceToGroup(sf);
}
// Add the Info.plist we are about to generate for an App Bundle.
@@ -4598,9 +4601,10 @@ bool cmGlobalXCodeGenerator::CreateGroups(
std::string plist = this->ComputeInfoPListLocation(gtgt.get());
cmSourceFile* sf = gtgt->Makefile->GetOrCreateSource(
plist, true, cmSourceFileLocationKind::Known);
sf->ResolveFullPath();
sf->SetSpecialSourceType(
cmSourceFile::SpecialSourceType::BundleInfoPlist);
addSourceToGroup(sf->ResolveFullPath());
addSourceToGroup(sf);
}
}
}
+37 -17
View File
@@ -9,7 +9,6 @@
#include <cstdlib>
#include <initializer_list>
#include <iterator>
#include <queue>
#include <sstream>
#include <unordered_set>
#include <utility>
@@ -4255,28 +4254,49 @@ std::string cmLocalGenerator::CreateSafeObjectFileName(
return ssin;
}
void cmLocalGenerator::ComputeSourceGroupSearchIndex()
// search a the source group defined for the file set or the source itself
// in case of match, result is stored in a cache to speed-up future searches
cmSourceGroup* cmLocalGenerator::FindSourceGroup(
cmGeneratorTarget const* target, cmSourceFile const* source,
std::string const& config)
{
#if !defined(CMAKE_BOOTSTRAP)
SourceGroupVector const& sourceGroups = this->Makefile->GetSourceGroups();
std::string const& targetName = target->GetName();
cmGeneratorFileSet const* fileSet =
target->GetFileSetForSource(config, source);
// Build lookup index from sources to source groups
std::queue<cmSourceGroup*> sgToVisit;
for (auto const& group : sourceGroups) {
cmSourceGroup* cmSourceGroup = group.get();
sgToVisit.emplace(cmSourceGroup);
}
while (!sgToVisit.empty()) {
cmSourceGroup* sourceGroup = sgToVisit.front();
sgToVisit.pop();
for (auto const& sgChild : sourceGroup->GetGroupChildren()) {
sgToVisit.emplace(sgChild.get());
if (fileSet) {
std::string fsName = fileSet->GetName();
std::string const fsKey = cmStrCat(targetName, "::", fsName);
auto const indexIt = this->SourceGroupSearchIndex.find(fsKey);
if (indexIt != this->SourceGroupSearchIndex.cend()) {
return indexIt->second;
}
for (std::string const& source : sourceGroup->GetGroupFiles()) {
this->SourceGroupSearchIndex.emplace(source, sourceGroup);
cmSourceGroup* sourceGroup = cmSourceGroup::FindSourceGroup(
targetName, fsName, this->Makefile->GetSourceGroups());
if (sourceGroup) {
this->SourceGroupSearchIndex.emplace(fsKey, sourceGroup);
return sourceGroup;
}
}
// no source group defined for the file set or the source is not part of a
// file set.
// search for source group defined at source level
auto const indexIt =
this->SourceGroupSearchIndex.find(source->GetFullPath());
if (indexIt != this->SourceGroupSearchIndex.cend()) {
return indexIt->second;
}
// look-up in source groups definitions
return this->FindSourceGroup(source->GetFullPath());
#else
static_cast<void>(target);
static_cast<void>(source);
static_cast<void>(config);
return nullptr;
#endif
}
+3 -5
View File
@@ -622,14 +622,12 @@ public:
std::string CreateSafeObjectFileName(std::string const& sin) const;
/**
* Build the search index from source files to source groups
*/
void ComputeSourceGroupSearchIndex();
/**
* find what source group this source is in
*/
cmSourceGroup* FindSourceGroup(cmGeneratorTarget const* target,
cmSourceFile const* source,
std::string const& config);
cmSourceGroup* FindSourceGroup(std::string const& source);
protected:
+5 -1
View File
@@ -1427,7 +1427,11 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
}
}
// Add the file to the list of sources.
sourceGroupFiles.Add(this->FindSourceGroup(sf->GetFullPath()), sf);
sourceGroupFiles.Add(
this->FindSourceGroup(
target, sf,
configs.empty() ? "" : configs[sources.Sources[si].Configs.front()]),
sf);
}
// open the project
+64 -3
View File
@@ -7,6 +7,7 @@
#include <cm/memory>
#include "cmGeneratorExpression.h"
#include "cmList.h"
#include "cmStringAlgorithms.h"
class cmSourceGroupInternals
@@ -43,10 +44,20 @@ void cmSourceGroup::ResolveGenex(cmLocalGenerator* lg,
{
std::set<std::string> files;
for (std::string const& file : this->GroupFiles) {
files.emplace(cmGeneratorExpression::Evaluate(file, lg, config));
for (auto& pair : this->GroupFileSets) {
files.clear();
for (std::string const& fileSet : pair.second) {
cmList list{ cmGeneratorExpression::Evaluate(fileSet, lg, config) };
files.insert(list.begin(), list.end());
}
pair.second = std::move(files);
}
files.clear();
for (std::string const& file : this->GroupFiles) {
cmList list{ cmGeneratorExpression::Evaluate(file, lg, config) };
files.insert(list.begin(), list.end());
}
this->GroupFiles = std::move(files);
if (!this->Internal) {
@@ -63,6 +74,13 @@ void cmSourceGroup::AddGroupFile(std::string const& name)
this->GroupFiles.insert(name);
}
void cmSourceGroup::AddGroupFileSets(std::string const& target,
std::set<std::string> const& fileSets)
{
auto& fs = this->GroupFileSets[target];
fs.insert(fileSets.begin(), fileSets.end());
}
std::string const& cmSourceGroup::GetName() const
{
return this->Name;
@@ -88,6 +106,11 @@ std::set<std::string> const& cmSourceGroup::GetGroupFiles() const
{
return this->GroupFiles;
}
std::map<std::string, std::set<std::string>> const&
cmSourceGroup::GetGroupFileSets() const
{
return this->GroupFileSets;
}
void cmSourceGroup::AddChild(std::unique_ptr<cmSourceGroup> child)
{
@@ -151,6 +174,23 @@ cmSourceGroup* cmSourceGroup::MatchChildrenRegex(std::string const& name) const
return nullptr;
}
cmSourceGroup* cmSourceGroup::MatchChildrenFileSets(std::string const& target,
std::string const& fileSet)
{
auto item = this->GroupFileSets.find(target);
if (item != this->GroupFileSets.end() &&
item->second.find(fileSet) != item->second.end()) {
return this;
}
for (auto const& group : this->Internal->GroupChildren) {
if (cmSourceGroup* result =
group->MatchChildrenFileSets(target, fileSet)) {
return result;
}
}
return nullptr;
}
SourceGroupVector const& cmSourceGroup::GetGroupChildren() const
{
return this->Internal->GroupChildren;
@@ -160,7 +200,7 @@ SourceGroupVector const& cmSourceGroup::GetGroupChildren() const
* Find a source group whose regular expression matches the filename
* part of the given source name. Search backward through the list of
* source groups, and take the first matching group found. This way
* non-inherited SOURCE_GROUP commands will have precedence over
* non-inherited source_group() commands will have precedence over
* inherited ones.
*/
cmSourceGroup* cmSourceGroup::FindSourceGroup(std::string const& source,
@@ -186,6 +226,27 @@ cmSourceGroup* cmSourceGroup::FindSourceGroup(std::string const& source,
return groups.data()->get();
}
/**
* Find a source group whose matches the target and file set.
* Search backward through the list of source groups, and take the first
* matching group found. This way non-inherited source_group() commands will
* have precedence over inherited ones.
*/
cmSourceGroup* cmSourceGroup::FindSourceGroup(std::string const& target,
std::string const& fileSet,
SourceGroupVector const& groups)
{
// First search for a group that lists the file set explicitly.
for (auto sg = groups.rbegin(); sg != groups.rend(); ++sg) {
if (cmSourceGroup* result =
(*sg)->MatchChildrenFileSets(target, fileSet)) {
return result;
}
}
return nullptr;
}
void cmSourceGroupFiles::Add(cmSourceGroup const* sg, cmSourceFile const* sf)
{
this->SourceFiles[sg].push_back(sf);
+29
View File
@@ -56,6 +56,12 @@ public:
*/
void AddGroupFile(std::string const& name);
/**
* Add file sets to the explicit list of file sets for this group.
*/
void AddGroupFileSets(std::string const& target,
std::set<std::string> const& fileSets);
/**
* Add child to this sourcegroup
*/
@@ -103,10 +109,21 @@ public:
*/
cmSourceGroup* MatchChildrenRegex(std::string const& name) const;
/**
* Check if the given name matches this group's explicit file list
* in children.
*/
cmSourceGroup* MatchChildrenFileSets(std::string const& target,
std::string const& fileSet);
/**
* Get the set of file names explicitly added to this source group.
*/
std::set<std::string> const& GetGroupFiles() const;
/**
* Get the set of file sets names explicitly added to this source group.
*/
std::map<std::string, std::set<std::string>> const& GetGroupFileSets() const;
SourceGroupVector const& GetGroupChildren() const;
@@ -115,6 +132,13 @@ public:
*/
static cmSourceGroup* FindSourceGroup(std::string const& source,
SourceGroupVector const& groups);
/**
* Given a source group collection, find the source group for a given
* target/file set.
*/
static cmSourceGroup* FindSourceGroup(std::string const& target,
std::string const& fileSet,
SourceGroupVector const& groups);
private:
/**
@@ -134,6 +158,11 @@ private:
*/
std::set<std::string> GroupFiles;
/**
* Set of file Sets indexed by target explicitly added to this group.
*/
std::map<std::string, std::set<std::string>> GroupFileSets;
std::unique_ptr<cmSourceGroupInternals> Internal;
};
+64 -3
View File
@@ -2,12 +2,15 @@
file LICENSE.rst or https://cmake.org/licensing for details. */
#include "cmSourceGroupCommand.h"
#include <cstddef>
#include <functional>
#include <map>
#include <memory>
#include <set>
#include <unordered_map>
#include <utility>
#include <cm/optional>
#include <cm/string_view>
#include <cmext/algorithm>
#include <cmext/string_view>
@@ -22,6 +25,7 @@
#include "cmSourceGroup.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
namespace {
template <typename Args>
@@ -127,8 +131,12 @@ bool cmSourceGroupCommand(std::vector<std::string> const& args,
cm::optional<std::string> GroupName;
cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> Files;
cm::optional<std::string> Regex;
cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>>
FileSets;
cm::optional<ArgumentParser::NonEmpty<std::string>> Tree;
cm::optional<ArgumentParser::MaybeEmpty<std::string>> Prefix;
std::map<std::string, std::set<std::string>> FileSetsPerTarget;
};
auto unsupportedKeyword =
@@ -147,6 +155,21 @@ bool cmSourceGroupCommand(std::vector<std::string> const& args,
}
return ArgumentParser::Continue::No;
};
auto handleTarget = [](Arguments& result,
cm::string_view value) -> ArgumentParser::Continue {
if (!result.FileSets) {
result.AddKeywordError(
"TARGET", cmStrCat("FILE_SETS is required for TARGET ", value, '.'));
return ArgumentParser::Continue::No;
}
if (!result.FileSets->empty()) {
result.FileSetsPerTarget[std::string{ value }].insert(
result.FileSets->begin(), result.FileSets->end());
}
result.FileSets.reset();
return ArgumentParser::Continue::Yes;
};
std::vector<std::string> unexpectedArgs;
auto parser =
@@ -156,11 +179,15 @@ bool cmSourceGroupCommand(std::vector<std::string> const& args,
// this is the TREE syntax
parser.Bind("TREE"_s, &Arguments::Tree)
.Bind("PREFIX"_s, &Arguments::Prefix)
.Bind("REGULAR_EXPRESSION"_s, unsupportedKeyword);
.Bind("REGULAR_EXPRESSION"_s, unsupportedKeyword)
.Bind("FILE_SETS"_s, unsupportedKeyword)
.Bind("TARGET"_s, unsupportedKeyword);
} else {
// assume that first argument is the group name
parser.Bind(0, &Arguments::GroupName)
.Bind("REGULAR_EXPRESSION"_s, handleRegex, 0)
.Bind("FILE_SETS"_s, &Arguments::FileSets)
.Bind("TARGET"_s, handleTarget)
.Bind("TREE"_s, unsupportedKeyword)
.Bind("PREFIX"_s, unsupportedKeyword);
}
@@ -177,6 +204,11 @@ bool cmSourceGroupCommand(std::vector<std::string> const& args,
cmSystemTools::SetFatalErrorOccurred();
return false;
}
if (!parsedArgs.Tree && parsedArgs.FileSets) {
status.SetError(cmStrCat("TARGET is required for FILE_SETS ",
cmJoin(*parsedArgs.FileSets, ", "), '.'));
return false;
}
if (parsedArgs.Tree) {
if (!ProcessTree(parsedArgs, status)) {
@@ -184,7 +216,8 @@ bool cmSourceGroupCommand(std::vector<std::string> const& args,
return false;
}
} else {
if (!parsedArgs.Files && !parsedArgs.Regex) {
if (!parsedArgs.Files && !parsedArgs.Regex &&
parsedArgs.FileSetsPerTarget.empty()) {
// group is not created
return true;
}
@@ -210,6 +243,34 @@ bool cmSourceGroupCommand(std::vector<std::string> const& args,
cmSystemTools::CollapseFullPath(file, currentSourceDir));
}
}
for (auto& item : parsedArgs.FileSetsPerTarget) {
// check validity of arguments
auto it = mf.GetTargets().find(item.first);
if (it == mf.GetTargets().end()) {
mf.IssueDiagnostic(
cmDiagnostics::CMD_AUTHOR,
cmStrCat(
"TARGET \"", item.first,
"\" is not defined in this directory. It will be ignored."));
continue;
}
cmTarget const& target = it->second;
for (auto it2 = item.second.begin(); it2 != item.second.end();) {
if (!target.GetFileSet(*it2)) {
mf.IssueDiagnostic(cmDiagnostics::CMD_AUTHOR,
cmStrCat("FILE_SET \"", *it2,
"\" is not known for TARGET \"",
item.first, "\". It will ignored."));
it2 = item.second.erase(it2);
} else {
++it2;
}
}
if (!item.second.empty()) {
sg->AddGroupFileSets(item.first, item.second);
}
}
}
return true;
+13 -10
View File
@@ -2006,17 +2006,18 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
std::set<cmSourceGroup const*> groupsUsed;
for (cmGeneratorTarget::AllConfigSource const& si : sources) {
std::string const& source = si.Source->GetFullPath();
cmSourceGroup const* sourceGroup =
this->LocalGenerator->FindSourceGroup(source);
cmSourceGroup const* sourceGroup = this->LocalGenerator->FindSourceGroup(
this->GeneratorTarget, si.Source,
this->Configurations.empty() ? ""
: this->Configurations[si.Configs.front()]);
groupsUsed.insert(sourceGroup);
}
if (cmSourceFile const* srcCMakeLists =
this->LocalGenerator->CreateVCProjBuildRule()) {
std::string const& source = srcCMakeLists->GetFullPath();
cmSourceGroup const* sourceGroup =
this->LocalGenerator->FindSourceGroup(source);
cmSourceGroup const* sourceGroup = this->LocalGenerator->FindSourceGroup(
this->GeneratorTarget, srcCMakeLists,
this->Configurations.empty() ? "" : this->Configurations.front());
groupsUsed.insert(sourceGroup);
}
@@ -2175,8 +2176,9 @@ void cmVisualStudio10TargetGenerator::WriteGroupSources(
for (ToolSource const& s : sources) {
cmSourceFile const* sf = s.SourceFile;
std::string const& source = sf->GetFullPath();
cmSourceGroup const* sourceGroup =
this->LocalGenerator->FindSourceGroup(source);
cmSourceGroup const* sourceGroup = this->LocalGenerator->FindSourceGroup(
this->GeneratorTarget, sf,
this->Configurations.empty() ? "" : this->Configurations.front());
std::string const& filter = sourceGroup->GetFullName();
std::string path = this->ConvertPath(source, s.RelativePath);
ConvertToWindowsSlash(path);
@@ -6095,8 +6097,9 @@ std::string cmVisualStudio10TargetGenerator::GetCSharpSourceLink(
std::string const& fullFileName = source->GetFullPath();
std::string const& srcDir = this->Makefile->GetCurrentSourceDirectory();
std::string const& binDir = this->Makefile->GetCurrentBinaryDirectory();
cmSourceGroup const* sourceGroup =
this->LocalGenerator->FindSourceGroup(fullFileName);
cmSourceGroup const* sourceGroup = this->LocalGenerator->FindSourceGroup(
this->GeneratorTarget, source,
this->Configurations.empty() ? "" : this->Configurations.front());
if (sourceGroup && !sourceGroup->GetFullName().empty()) {
sourceGroupedFile =
cmStrCat(sourceGroup->GetFullName(), '/',
@@ -9,3 +9,15 @@ CMake Warning \(author\) at IgnoredKeywords\.cmake:[0-9]+ \(source_group\):
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)
This warning is for project developers\. Use -Wno-author to suppress it\.
CMake Warning \(author\) at IgnoredKeywords\.cmake:[0-9]+ \(source_group\):
keyword "FILE_SETS" will be ignored in this context\.
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)
This warning is for project developers\. Use -Wno-author to suppress it\.
CMake Warning \(author\) at IgnoredKeywords\.cmake:[0-9]+ \(source_group\):
keyword "TARGET" will be ignored in this context\.
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)
This warning is for project developers\. Use -Wno-author to suppress it\.
@@ -1,4 +1,4 @@
source_group(foo PREFIX bar)
source_group(TREE foo REGULAR_EXPRESSION ".*")
source_group(TREE foo REGULAR_EXPRESSION ".*" FILE_SETS fs TARGET t)
@@ -0,0 +1 @@
1
@@ -0,0 +1,6 @@
CMake Error at MissingFILE_SETS\.cmake:[0-9]+ \(source_group\):
source_group given invalid argument:
TARGET: FILE_SETS is required for TARGET bar\.
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)
@@ -0,0 +1,2 @@
source_group(foo TARGET bar)
@@ -0,0 +1 @@
1
@@ -0,0 +1,4 @@
CMake Error at MissingTARGET\.cmake:[0-9]+ \(source_group\):
source_group TARGET is required for FILE_SETS bar\.
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)
@@ -0,0 +1,2 @@
source_group(foo FILE_SETS bar)
@@ -4,3 +4,7 @@ include(RunCMake)
run_cmake(MixedSignatures)
run_cmake(WrongRegex)
run_cmake(IgnoredKeywords)
run_cmake(MissingFILE_SETS)
run_cmake(UnknownFILE_SET)
run_cmake(MissingTARGET)
run_cmake(UnknownTARGET)
@@ -0,0 +1,5 @@
CMake Warning \(author\) at UnknownFILE_SET\.cmake:[0-9]+ \(source_group\):
FILE_SET "bar" is not known for TARGET "bar"\. It will ignored\.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
This warning is for project developers\. Use -Wno-author to suppress it\.
@@ -0,0 +1,6 @@
enable_language(C)
add_library(bar empty.c)
source_group(foo FILE_SETS bar TARGET bar)
@@ -0,0 +1,5 @@
CMake Warning \(author\) at UnknownTARGET\.cmake:[0-9]+ \(source_group\):
TARGET "bar" is not defined in this directory\. It will be ignored.
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)
This warning is for project developers\. Use -Wno-author to suppress it\.
@@ -0,0 +1,2 @@
source_group(foo FILE_SETS bar TARGET bar)
View File