浏览代码

source_group: Restore TREE support for relative paths

The fix in commit v3.8.1~4^2 (source_group: Fix TREE with root that is
not current source dir, 2017-04-20) accidentally broke support for
specifying paths relative to the source directory.  Fix it and add a
test covering the case.

While at it, fix a typo in a variable name.

Fixes: #16876
Mateusz Janek 8 年之前
父节点
当前提交
4716f2be83

+ 20 - 12
Source/cmSourceGroupCommand.cxx

@@ -2,8 +2,6 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmSourceGroupCommand.h"
 #include "cmSourceGroupCommand.h"
 
 
-#include <algorithm>
-#include <iterator>
 #include <set>
 #include <set>
 #include <sstream>
 #include <sstream>
 
 
@@ -15,7 +13,7 @@ namespace {
 const size_t RootIndex = 1;
 const size_t RootIndex = 1;
 const size_t FilesWithoutPrefixKeywordIndex = 2;
 const size_t FilesWithoutPrefixKeywordIndex = 2;
 const size_t FilesWithPrefixKeywordIndex = 4;
 const size_t FilesWithPrefixKeywordIndex = 4;
-const size_t PrefixKeywordIdex = 2;
+const size_t PrefixKeywordIndex = 2;
 
 
 std::vector<std::string> tokenizePath(const std::string& path)
 std::vector<std::string> tokenizePath(const std::string& path)
 {
 {
@@ -79,17 +77,26 @@ cmSourceGroup* addSourceGroup(const std::vector<std::string>& tokenizedPath,
   return sg;
   return sg;
 }
 }
 
 
-std::string prepareFilePathForTree(const std::string& path)
+std::string prepareFilePathForTree(const std::string& path,
+                                   const std::string& currentSourceDir)
 {
 {
+  if (!cmSystemTools::FileIsFullPath(path)) {
+    return cmSystemTools::CollapseFullPath(currentSourceDir + "/" + path);
+  }
   return cmSystemTools::CollapseFullPath(path);
   return cmSystemTools::CollapseFullPath(path);
 }
 }
 
 
 std::vector<std::string> prepareFilesPathsForTree(
 std::vector<std::string> prepareFilesPathsForTree(
   std::vector<std::string>::const_iterator begin,
   std::vector<std::string>::const_iterator begin,
-  std::vector<std::string>::const_iterator end)
+  std::vector<std::string>::const_iterator end,
+  const std::string& currentSourceDir)
 {
 {
-  std::vector<std::string> prepared(std::distance(begin, end));
-  std::transform(begin, end, prepared.begin(), prepareFilePathForTree);
+  std::vector<std::string> prepared;
+
+  for (; begin != end; ++begin) {
+    prepared.push_back(prepareFilePathForTree(*begin, currentSourceDir));
+  }
+
   return prepared;
   return prepared;
 }
 }
 
 
@@ -228,13 +235,13 @@ bool cmSourceGroupCommand::checkTreeArgumentsPreconditions(
   }
   }
 
 
   if (args[FilesWithoutPrefixKeywordIndex] != "FILES" &&
   if (args[FilesWithoutPrefixKeywordIndex] != "FILES" &&
-      args[PrefixKeywordIdex] != "PREFIX") {
+      args[PrefixKeywordIndex] != "PREFIX") {
     errorMsg = "Unknown argument \"" + args[2] +
     errorMsg = "Unknown argument \"" + args[2] +
       "\". Perhaps the FILES keyword is missing.\n";
       "\". Perhaps the FILES keyword is missing.\n";
     return false;
     return false;
   }
   }
 
 
-  if (args[PrefixKeywordIdex] == "PREFIX" &&
+  if (args[PrefixKeywordIndex] == "PREFIX" &&
       (args.size() < 5 || args[FilesWithPrefixKeywordIndex] != "FILES")) {
       (args.size() < 5 || args[FilesWithPrefixKeywordIndex] != "FILES")) {
     errorMsg = "Missing FILES arguments.";
     errorMsg = "Missing FILES arguments.";
     return false;
     return false;
@@ -253,13 +260,14 @@ bool cmSourceGroupCommand::processTree(const std::vector<std::string>& args,
   const std::string root = cmSystemTools::CollapseFullPath(args[RootIndex]);
   const std::string root = cmSystemTools::CollapseFullPath(args[RootIndex]);
   std::string prefix;
   std::string prefix;
   size_t filesBegin = FilesWithoutPrefixKeywordIndex + 1;
   size_t filesBegin = FilesWithoutPrefixKeywordIndex + 1;
-  if (args[PrefixKeywordIdex] == "PREFIX") {
-    prefix = args[PrefixKeywordIdex + 1];
+  if (args[PrefixKeywordIndex] == "PREFIX") {
+    prefix = args[PrefixKeywordIndex + 1];
     filesBegin = FilesWithPrefixKeywordIndex + 1;
     filesBegin = FilesWithPrefixKeywordIndex + 1;
   }
   }
 
 
   const std::vector<std::string> filesVector =
   const std::vector<std::string> filesVector =
-    prepareFilesPathsForTree(args.begin() + filesBegin, args.end());
+    prepareFilesPathsForTree(args.begin() + filesBegin, args.end(),
+                             this->Makefile->GetCurrentSourceDirectory());
 
 
   if (!rootIsPrefix(root, filesVector, errorMsg)) {
   if (!rootIsPrefix(root, filesVector, errorMsg)) {
     return false;
     return false;

+ 5 - 4
Tests/SourceGroups/CMakeLists.txt

@@ -1,4 +1,4 @@
-cmake_minimum_required (VERSION 2.6)
+cmake_minimum_required (VERSION 3.8)
 project(SourceGroups)
 project(SourceGroups)
 
 
 # this is not really a test which can fail
 # this is not really a test which can fail
@@ -33,10 +33,11 @@ source_group(EmptyGroup)
 set(root ${CMAKE_CURRENT_SOURCE_DIR})
 set(root ${CMAKE_CURRENT_SOURCE_DIR})
 
 
 set(tree_files_without_prefix ${root}/sub1/tree_bar.c
 set(tree_files_without_prefix ${root}/sub1/tree_bar.c
-                              ${root}/sub1/tree_baz.c
-                              ${root}/sub1/tree_subdir/tree_foobar.c)
+                              sub1/tree_baz.c
+                              sub1/../sub1/tree_subdir/tree_foobar.c)
 
 
-set(tree_files_with_prefix ${root}/tree_foo.c)
+set(tree_files_with_prefix ${root}/tree_prefix_foo.c
+                           tree_prefix_bar.c)
 
 
 source_group(TREE ${root} FILES ${tree_files_without_prefix})
 source_group(TREE ${root} FILES ${tree_files_without_prefix})
 
 

+ 6 - 3
Tests/SourceGroups/main.c

@@ -5,7 +5,8 @@ extern int bar(void);
 extern int foobar(void);
 extern int foobar(void);
 extern int barbar(void);
 extern int barbar(void);
 extern int baz(void);
 extern int baz(void);
-extern int tree_foo(void);
+extern int tree_prefix_foo(void);
+extern int tree_prefix_bar(void);
 extern int tree_bar(void);
 extern int tree_bar(void);
 extern int tree_foobar(void);
 extern int tree_foobar(void);
 extern int tree_baz(void);
 extern int tree_baz(void);
@@ -15,7 +16,9 @@ int main()
   printf("foo: %d bar: %d foobar: %d barbar: %d baz: %d\n", foo(), bar(),
   printf("foo: %d bar: %d foobar: %d barbar: %d baz: %d\n", foo(), bar(),
          foobar(), barbar(), baz());
          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());
+  printf("tree_prefix_foo: %d tree_prefix_bar: %d tree_bar: %d tree_foobar: "
+         "%d tree_baz: %d\n",
+         tree_prefix_foo(), tree_prefix_bar(), tree_bar(), tree_foobar(),
+         tree_baz());
   return 0;
   return 0;
 }
 }

+ 0 - 4
Tests/SourceGroups/tree_foo.c

@@ -1,4 +0,0 @@
-int tree_foo(void)
-{
-  return 6;
-}

+ 4 - 0
Tests/SourceGroups/tree_prefix_bar.c

@@ -0,0 +1,4 @@
+int tree_prefix_bar(void)
+{
+  return 66;
+}

+ 4 - 0
Tests/SourceGroups/tree_prefix_foo.c

@@ -0,0 +1,4 @@
+int tree_prefix_foo(void)
+{
+  return 6;
+}