[Cmake-commits] CMake branch, next, updated. v3.7.1-2134-g927c6bf

Brad King brad.king at kitware.com
Thu Jan 12 15:24:31 EST 2017


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  927c6bf2a8f640f4a60bf3acc97af8d838a29969 (commit)
       via  e2210140b158c7f8edffe4875722165928566fc0 (commit)
      from  7508f58de59e532dd011edc3c0281ff60aaad7b8 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=927c6bf2a8f640f4a60bf3acc97af8d838a29969
commit 927c6bf2a8f640f4a60bf3acc97af8d838a29969
Merge: 7508f58 e221014
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Jan 12 15:24:27 2017 -0500
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Thu Jan 12 15:24:27 2017 -0500

    Merge topic 'source_group-tree' into next
    
    e2210140 source_group: Add options create groups matching directory tree


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e2210140b158c7f8edffe4875722165928566fc0
commit e2210140b158c7f8edffe4875722165928566fc0
Author:     Mateusz Janek <stryku2393 at gmail.com>
AuthorDate: Wed Dec 21 15:27:49 2016 +0100
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Wed Jan 11 11:08:00 2017 -0500

    source_group: Add options create groups matching directory tree
    
    Add `TREE` and `PREFIX` arguments to enable this behavior.

diff --git a/Help/command/source_group.rst b/Help/command/source_group.rst
index 6e3829c..938ca40 100644
--- a/Help/command/source_group.rst
+++ b/Help/command/source_group.rst
@@ -2,15 +2,27 @@ source_group
 ------------
 
 Define a grouping for source files in IDE project generation.
+There are two different signatures to create source groups.
 
-.. code-block:: cmake
+::
 
   source_group(<name> [FILES <src>...] [REGULAR_EXPRESSION <regex>])
+  source_group(TREE <root> [PREFIX <prefix>] [FILES <src>...])
 
 Defines a group into which sources will be placed in project files.
 This is intended to set up file tabs in Visual Studio.
 The options are:
 
+``TREE``
+ 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>``.
+
+``PREFIX``
+ 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
@@ -25,11 +37,13 @@ explicitly lists the file with ``FILES`` will be favored, if any.
 If no group explicitly lists the file, the *last* group whose
 regular expression matches the file will be favored.
 
-The ``<name>`` of the group may contain backslashes to specify subgroups:
+The ``<name>`` of the group and ``<prefix>`` argument may contain backslashes
+to specify subgroups:
 
 .. code-block:: cmake
 
   source_group(outer\\inner ...)
+  source_group(TREE <root> PREFIX sources\\inc ...)
 
 For backwards compatibility, the short-hand signature
 
diff --git a/Help/release/dev/source_group-tree.rst b/Help/release/dev/source_group-tree.rst
new file mode 100644
index 0000000..c5fec1d
--- /dev/null
+++ b/Help/release/dev/source_group-tree.rst
@@ -0,0 +1,5 @@
+source_group-tree
+-----------------
+
+* The :command:`source_group` command gained ``TREE`` and ``PREFIX``
+  options to add groups following source tree directory structure.
diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx
index 3f20d4e..dac4b82 100644
--- a/Source/cmSourceGroupCommand.cxx
+++ b/Source/cmSourceGroupCommand.cxx
@@ -8,6 +8,99 @@
 #include "cmSourceGroup.h"
 #include "cmSystemTools.h"
 
+namespace {
+const size_t RootIndex = 1;
+const size_t FilesWithoutPrefixKeywordIndex = 2;
+const size_t FilesWithPrefixKeywordIndex = 4;
+const size_t PrefixKeywordIdex = 2;
+
+std::vector<std::string> tokenizePath(const std::string& path)
+{
+  return cmSystemTools::tokenize(path, "\\/");
+}
+
+std::string getFullFilePath(const std::string& currentPath,
+                            const std::string& path)
+{
+  std::string fullPath = path;
+
+  if (!cmSystemTools::FileIsFullPath(path.c_str())) {
+    fullPath = currentPath;
+    fullPath += "/";
+    fullPath += path;
+  }
+
+  return cmSystemTools::CollapseFullPath(fullPath);
+}
+
+std::set<std::string> getSourceGroupFilesPaths(
+  const std::string& currentPath, const std::string& root,
+  const std::vector<std::string>& files)
+{
+  std::set<std::string> ret;
+  const std::string::size_type rootLength = root.length();
+
+  for (size_t i = 0; i < files.size(); ++i) {
+    const std::string fullPath = getFullFilePath(currentPath, files[i]);
+
+    ret.insert(fullPath.substr(rootLength + 1)); // +1 to also omnit last '/'
+  }
+
+  return ret;
+}
+
+cmSourceGroup* addSourceGroup(const std::vector<std::string>& tokenizedPath,
+                              cmMakefile& makefile)
+{
+  cmSourceGroup* sg;
+
+  sg = makefile.GetSourceGroup(tokenizedPath);
+  if (!sg) {
+    makefile.AddSourceGroup(tokenizedPath);
+    sg = makefile.GetSourceGroup(tokenizedPath);
+    if (!sg) {
+      return CM_NULLPTR;
+    }
+  }
+
+  return sg;
+}
+
+bool addFilesToItsSourceGroups(const std::set<std::string>& sgFilesPaths,
+                               const std::string& prefix, cmMakefile& makefile,
+                               std::string& errorMsg)
+{
+  cmSourceGroup* sg;
+
+  for (std::set<std::string>::const_iterator it = std::begin(sgFilesPaths);
+       it != std::end(sgFilesPaths); ++it) {
+
+    std::vector<std::string> tokenizedPath;
+    if (!prefix.empty()) {
+      tokenizedPath = tokenizePath(prefix + '/' + *it);
+    } else {
+      tokenizedPath = tokenizePath(*it);
+    }
+
+    if (tokenizedPath.size() > 1) {
+      tokenizedPath.pop_back();
+
+      sg = addSourceGroup(tokenizedPath, makefile);
+
+      if (!sg) {
+        errorMsg = "Could not create source group for file: " + *it;
+        return false;
+      }
+      const std::string fullPath =
+        getFullFilePath(makefile.GetCurrentSourceDirectory(), *it);
+      sg->AddGroupFile(fullPath);
+    }
+  }
+
+  return true;
+}
+}
+
 class cmExecutionStatus;
 
 // cmSourceGroupCommand
@@ -19,6 +112,17 @@ bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args,
     return false;
   }
 
+  if (args[0] == "TREE") {
+    std::string error;
+
+    if (!processTree(args, error)) {
+      this->SetError(error);
+      return false;
+    }
+
+    return true;
+  }
+
   std::string delimiter = "\\";
   if (this->Makefile->GetDefinition("SOURCE_GROUP_DELIMITER")) {
     delimiter = this->Makefile->GetDefinition("SOURCE_GROUP_DELIMITER");
@@ -82,3 +186,64 @@ bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args,
 
   return true;
 }
+
+bool cmSourceGroupCommand::checkTreeArgumentsPreconditions(
+  const std::vector<std::string>& args, std::string& errorMsg) const
+{
+  if (args.size() == 1) {
+    errorMsg = "TREE argument given without a root.";
+    return false;
+  }
+
+  if (args.size() < 3) {
+    errorMsg = "Missing FILES arguments.";
+    return false;
+  }
+
+  if (args[FilesWithoutPrefixKeywordIndex] != "FILES" &&
+      args[PrefixKeywordIdex] != "PREFIX") {
+    errorMsg = "Unknown argument \"" + args[2] +
+      "\". Perhaps the FILES keyword is missing.\n";
+    return false;
+  }
+
+  if (args[PrefixKeywordIdex] == "PREFIX" &&
+      (args.size() < 5 || args[FilesWithPrefixKeywordIndex] != "FILES")) {
+    errorMsg = "Missing FILES arguments.";
+    return false;
+  }
+
+  return true;
+}
+
+bool cmSourceGroupCommand::processTree(const std::vector<std::string>& args,
+                                       std::string& errorMsg)
+{
+  if (!checkTreeArgumentsPreconditions(args, errorMsg)) {
+    return false;
+  }
+
+  const std::string root = cmSystemTools::CollapseFullPath(args[RootIndex]);
+  std::string prefix;
+  size_t filesBegin = FilesWithoutPrefixKeywordIndex + 1;
+  if (args[PrefixKeywordIdex] == "PREFIX") {
+    prefix = args[PrefixKeywordIdex + 1];
+    filesBegin = FilesWithPrefixKeywordIndex + 1;
+  }
+
+  const std::vector<std::string> filesVector(args.cbegin() + filesBegin,
+                                             args.cend());
+
+  std::set<std::string> sourceGroupPaths = getSourceGroupFilesPaths(
+    this->Makefile->GetCurrentSourceDirectory(), root, filesVector);
+
+  addFilesToItsSourceGroups(sourceGroupPaths, prefix, *(this->Makefile),
+                            errorMsg);
+
+  if (!errorMsg.empty()) {
+    this->SetError(errorMsg.c_str());
+    return false;
+  }
+
+  return true;
+}
diff --git a/Source/cmSourceGroupCommand.h b/Source/cmSourceGroupCommand.h
index f533be1..5549096 100644
--- a/Source/cmSourceGroupCommand.h
+++ b/Source/cmSourceGroupCommand.h
@@ -36,6 +36,12 @@ public:
    * The name of the command as specified in CMakeList.txt.
    */
   std::string GetName() const CM_OVERRIDE { return "source_group"; }
+
+private:
+  bool processTree(const std::vector<std::string>& args,
+                   std::string& errorMsg);
+  bool checkTreeArgumentsPreconditions(const std::vector<std::string>& args,
+                                       std::string& errorMsg) const;
 };
 
 #endif
diff --git a/Tests/SourceGroups/CMakeLists.txt b/Tests/SourceGroups/CMakeLists.txt
index 6573c82..9289e84 100644
--- a/Tests/SourceGroups/CMakeLists.txt
+++ b/Tests/SourceGroups/CMakeLists.txt
@@ -30,6 +30,17 @@ source_group(Base\\Sub1\\Base FILES bar.c)
 # a group without files, is currently not created
 source_group(EmptyGroup)
 
+set(root ${CMAKE_CURRENT_SOURCE_DIR})
 
-add_executable(SourceGroups main.c bar.c foo.c sub1/foo.c sub1/foobar.c baz.c README.txt)
+set(tree_files_without_prefix ${root}/sub1/tree_bar.c
+                              ${root}/sub1/tree_baz.c
+                              ${root}/sub1/tree_subdir/tree_foobar.c)
 
+set(tree_files_with_prefix ${root}/tree_foo.c)
+
+source_group(TREE ${root} FILES ${tree_files_without_prefix})
+
+source_group(TREE ${root} PREFIX tree_root/subgroup FILES ${tree_files_with_prefix})
+
+add_executable(SourceGroups main.c bar.c foo.c sub1/foo.c sub1/foobar.c baz.c
+                            ${tree_files_with_prefix} ${tree_files_without_prefix} README.txt)
diff --git a/Tests/SourceGroups/main.c b/Tests/SourceGroups/main.c
index f259f98..b88f2f8 100644
--- a/Tests/SourceGroups/main.c
+++ b/Tests/SourceGroups/main.c
@@ -5,10 +5,17 @@ extern int bar(void);
 extern int foobar(void);
 extern int barbar(void);
 extern int baz(void);
+extern int tree_foo(void);
+extern int tree_bar(void);
+extern int tree_foobar(void);
+extern int tree_baz(void);
 
 int main()
 {
   printf("foo: %d bar: %d foobar: %d barbar: %d baz: %d\n", foo(), bar(),
          foobar(), barbar(), baz());
+
+  printf("tree_foo: %d tree_bar: %d tree_foobar: %d tree_baz: %d\n",
+         tree_foo(), tree_bar(), tree_foobar(), tree_baz());
   return 0;
 }
diff --git a/Tests/SourceGroups/sub1/tree_bar.c b/Tests/SourceGroups/sub1/tree_bar.c
new file mode 100644
index 0000000..6b79239
--- /dev/null
+++ b/Tests/SourceGroups/sub1/tree_bar.c
@@ -0,0 +1,4 @@
+int tree_bar(void)
+{
+  return 8;
+}
diff --git a/Tests/SourceGroups/sub1/tree_baz.c b/Tests/SourceGroups/sub1/tree_baz.c
new file mode 100644
index 0000000..27ff5ab
--- /dev/null
+++ b/Tests/SourceGroups/sub1/tree_baz.c
@@ -0,0 +1,4 @@
+int tree_baz(void)
+{
+  return 9;
+}
diff --git a/Tests/SourceGroups/sub1/tree_subdir/tree_foobar.c b/Tests/SourceGroups/sub1/tree_subdir/tree_foobar.c
new file mode 100644
index 0000000..e955e04
--- /dev/null
+++ b/Tests/SourceGroups/sub1/tree_subdir/tree_foobar.c
@@ -0,0 +1,4 @@
+int tree_foobar(void)
+{
+  return 7;
+}
diff --git a/Tests/SourceGroups/tree_foo.c b/Tests/SourceGroups/tree_foo.c
new file mode 100644
index 0000000..d392e41
--- /dev/null
+++ b/Tests/SourceGroups/tree_foo.c
@@ -0,0 +1,4 @@
+int tree_foo(void)
+{
+  return 6;
+}

-----------------------------------------------------------------------

Summary of changes:
 Help/command/source_group.rst                     |   18 ++-
 Help/release/dev/source_group-tree.rst            |    5 +
 Source/cmSourceGroupCommand.cxx                   |  165 +++++++++++++++++++++
 Source/cmSourceGroupCommand.h                     |    6 +
 Tests/SourceGroups/CMakeLists.txt                 |   13 +-
 Tests/SourceGroups/main.c                         |    7 +
 Tests/SourceGroups/sub1/tree_bar.c                |    4 +
 Tests/SourceGroups/sub1/tree_baz.c                |    4 +
 Tests/SourceGroups/sub1/tree_subdir/tree_foobar.c |    4 +
 Tests/SourceGroups/tree_foo.c                     |    4 +
 10 files changed, 227 insertions(+), 3 deletions(-)
 create mode 100644 Help/release/dev/source_group-tree.rst
 create mode 100644 Tests/SourceGroups/sub1/tree_bar.c
 create mode 100644 Tests/SourceGroups/sub1/tree_baz.c
 create mode 100644 Tests/SourceGroups/sub1/tree_subdir/tree_foobar.c
 create mode 100644 Tests/SourceGroups/tree_foo.c


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list