Browse Source

Merge topic 'file-set-name-requirements' into release-3.23

b357d334fc target_sources(): Enforce stricter requirements for FILE_SET name

Acked-by: Kitware Robot <[email protected]>
Tested-by: buildbot <[email protected]>
Merge-request: !7037
Brad King 3 years ago
parent
commit
65da32c924

+ 2 - 1
Help/command/target_sources.rst

@@ -92,7 +92,8 @@ Each ``target_sources(FILE_SET)`` entry starts with ``INTERFACE``, ``PUBLIC``, o
 ``FILE_SET <set>``
 
   A string representing the name of the file set to create or add to. This must
-  not start with a capital letter, unless its name is ``HEADERS``.
+  contain only numbers, letters, and underscores, and must not start with a
+  capital letter or underscore, unless its name is ``HEADERS``.
 
 ``TYPE <type>``
 

+ 10 - 0
Source/cmFileSet.cxx

@@ -7,6 +7,8 @@
 #include <utility>
 #include <vector>
 
+#include "cmsys/RegularExpression.hxx"
+
 #include "cmGeneratorExpression.h"
 #include "cmListFileCache.h"
 #include "cmLocalGenerator.h"
@@ -149,3 +151,11 @@ void cmFileSet::EvaluateFileEntry(
     filesPerDir[relDir].push_back(file);
   }
 }
+
+bool cmFileSet::IsValidName(const std::string& name)
+{
+  static const cmsys::RegularExpression regex("^[a-z0-9][a-zA-Z0-9_]*$");
+
+  cmsys::RegularExpressionMatch match;
+  return regex.find(name.c_str(), match);
+}

+ 2 - 0
Source/cmFileSet.h

@@ -56,6 +56,8 @@ public:
     const cmGeneratorTarget* target,
     cmGeneratorExpressionDAGChecker* dagChecker = nullptr) const;
 
+  static bool IsValidName(const std::string& name);
+
 private:
   std::string Name;
   std::string Type;

+ 4 - 3
Source/cmTargetSourcesCommand.cxx

@@ -238,9 +238,10 @@ bool TargetSourcesImpl::HandleOneFileSet(
   auto fileSet = this->Target->GetOrCreateFileSet(args.FileSet, type);
   if (fileSet.second) {
     if (!isDefault) {
-      if (args.FileSet[0] >= 'A' && args.FileSet[0] <= 'Z') {
-        this->SetError(
-          "Non-default file set name must not start with a capital letter");
+      if (!cmFileSet::IsValidName(args.FileSet)) {
+        this->SetError("Non-default file set name must contain only letters, "
+                       "numbers, and underscores, and must not start with a "
+                       "capital letter or underscore");
         return false;
       }
     }

+ 1 - 0
Tests/RunCMake/target_sources/FileSetBadName-result.txt

@@ -0,0 +1 @@
+1

+ 6 - 0
Tests/RunCMake/target_sources/FileSetBadName-stderr.txt

@@ -0,0 +1,6 @@
+^CMake Error at FileSetBadName\.cmake:[0-9]+ \(target_sources\):
+  target_sources Non-default file set name must contain only letters,
+  numbers, and underscores, and must not start with a capital letter or
+  underscore
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)$

+ 4 - 0
Tests/RunCMake/target_sources/FileSetBadName.cmake

@@ -0,0 +1,4 @@
+enable_language(C)
+
+add_library(lib1 STATIC empty.c)
+target_sources(lib1 INTERFACE FILE_SET a+ TYPE HEADERS)

+ 1 - 0
Tests/RunCMake/target_sources/RunCMakeTest.cmake

@@ -39,6 +39,7 @@ run_cmake(FileSetNoExistInterface)
 run_cmake(FileSetNoExistInstall)
 run_cmake(FileSetDirectories)
 run_cmake(FileSetCustomTarget)
+run_cmake(FileSetBadName)
 
 set(RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0115=NEW)
 run_cmake(FileSetFileNoExist)