浏览代码

Merge topic 'project-version-fix'

aa16b8eb9a project: Revert changes to VERSION handling

Acked-by: Kitware Robot <[email protected]>
Tested-by: buildbot <[email protected]>
Merge-request: !11131
Brad King 3 月之前
父节点
当前提交
7eec7ca851

+ 35 - 5
Source/cmProjectCommand.cxx

@@ -204,6 +204,7 @@ bool cmProjectCommand(std::vector<std::string> const& args,
   std::string version_string;
   std::array<std::string, MAX_VERSION_COMPONENTS> version_components;
 
+  bool has_version = prArgs.Version.has_value();
   if (prArgs.Version) {
     if (!vx.find(*prArgs.Version)) {
       std::string e =
@@ -269,11 +270,40 @@ bool cmProjectCommand(std::vector<std::string> const& args,
     TopLevelCMakeVarCondSet(mf, cmStrCat("CMAKE_PROJECT_"_s, var), val);
   };
 
-  createVariables("VERSION"_s, version_string);
-  createVariables("VERSION_MAJOR"_s, version_components[0]);
-  createVariables("VERSION_MINOR"_s, version_components[1]);
-  createVariables("VERSION_PATCH"_s, version_components[2]);
-  createVariables("VERSION_TWEAK"_s, version_components[3]);
+  // Note, this intentionally doesn't touch cache variables as the legacy
+  // behavior did not modify cache
+  auto checkAndClearVariables = [&](cm::string_view var) {
+    std::vector<std::string> vv = { "PROJECT_", cmStrCat(projectName, "_") };
+    if (mf.IsRootMakefile()) {
+      vv.push_back("CMAKE_PROJECT_");
+    }
+    for (std::string const& prefix : vv) {
+      std::string def = cmStrCat(prefix, var);
+      if (!mf.GetDefinition(def).IsEmpty()) {
+        mf.AddDefinition(def, "");
+      }
+    }
+  };
+
+  // TODO: We should treat VERSION the same as all other project variables, but
+  // setting it to empty string unconditionally causes various behavior
+  // changes. It needs a policy. For now, maintain the old behavior and add a
+  // policy in a future release.
+
+  if (has_version) {
+    createVariables("VERSION"_s, version_string);
+    createVariables("VERSION_MAJOR"_s, version_components[0]);
+    createVariables("VERSION_MINOR"_s, version_components[1]);
+    createVariables("VERSION_PATCH"_s, version_components[2]);
+    createVariables("VERSION_TWEAK"_s, version_components[3]);
+  } else {
+    checkAndClearVariables("VERSION"_s);
+    checkAndClearVariables("VERSION_MAJOR"_s);
+    checkAndClearVariables("VERSION_MINOR"_s);
+    checkAndClearVariables("VERSION_PATCH"_s);
+    checkAndClearVariables("VERSION_TWEAK"_s);
+  }
+
   createVariables("COMPAT_VERSION"_s, prArgs.CompatVersion.value_or(""));
   createVariables("SPDX_LICENSE"_s, prArgs.License.value_or(""));
   createVariables("DESCRIPTION"_s, prArgs.Description.value_or(""));

+ 9 - 5
Tests/RunCMake/project/Omissions.cmake

@@ -14,11 +14,15 @@ function(expect_empty SUFFIX)
 endfunction()
 
 project(Omissions LANGUAGES)
-expect_empty(VERSION)
-expect_empty(VERSION_MAJOR)
-expect_empty(VERSION_MINOR)
-expect_empty(VERSION_PATCH)
-expect_empty(VERSION_TWEAK)
+
+# TODO: Test these when a policy is in place to handle projects expecting
+# legacy handling of the version variables
+# expect_empty(VERSION)
+# expect_empty(VERSION_MAJOR)
+# expect_empty(VERSION_MINOR)
+# expect_empty(VERSION_PATCH)
+# expect_empty(VERSION_TWEAK)
+
 expect_empty(COMPAT_VERSION)
 expect_empty(SPDX_LICENSE)
 expect_empty(DESCRIPTION)

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

@@ -48,6 +48,7 @@ run_cmake(ProjectIsTopLevelMultiple)
 run_cmake(ProjectIsTopLevelSubdirectory)
 run_cmake(ProjectTwice)
 run_cmake(Omissions)
+run_cmake(VersionAbsent)
 run_cmake(VersionAndLanguagesEmpty)
 run_cmake(VersionEmpty)
 run_cmake(VersionInvalid)

+ 14 - 0
Tests/RunCMake/project/VersionAbsent.cmake

@@ -0,0 +1,14 @@
+# TODO: In the future this should be a policy test, but for now verify version
+# variables remain undefined for various configurations.
+
+project(NoVersion LANGUAGES NONE)
+
+foreach(pre "NoVersion_" "PROJECT_" "CMAKE_PROJECT_")
+  foreach(post "" "_MAJOR" "_MINOR" "_PATCH" "_TWEAK")
+    if(DEFINED ${pre}VERSION${post})
+      message(SEND_ERROR "${pre}VERSION${post} is defined when no project version was provided")
+    endif()
+  endforeach()
+endforeach()
+
+add_subdirectory(VersionSubdir)

+ 24 - 0
Tests/RunCMake/project/VersionSubdir/CMakeLists.txt

@@ -0,0 +1,24 @@
+project(WithVersion LANGUAGES NONE VERSION 1.1.1.1)
+
+project(SubdirNoVersion LANGUAGES NONE)
+
+foreach(post "" "_MAJOR" "_MINOR" "_PATCH" "_TWEAK")
+  if(NOT DEFINED PROJECT_VERSION${post})
+    message(SEND_ERROR "PROJECT_VERSION${post} is not defined when previous project version was provided")
+    continue()
+  endif()
+
+  if(NOT PROJECT_VERSION${post} STREQUAL "")
+    message(SEND_ERROR "PROJECT_VERSION${post} has value '${PROJECT_VERSION${post}}' when empty string is expected")
+  endif()
+endforeach()
+
+if(NOT CMAKE_PROJECT_VERSION STREQUAL "1.1.1.1")
+  message(SEND_ERROR "CMAKE_PROJECT_VERSION has value '${CMAKE_PROJECT_VERION}' when 1.1.1.1 is expected")
+endif()
+
+foreach(post "_MAJOR" "_MINOR" "_PATCH" "_TWEAK")
+  if(NOT CMAKE_PROJECT_VERSION${post} STREQUAL "1")
+    message(SEND_ERROR "CMAKE_PROJECT_VERSION${post} has value '${CMAKE_PROJECT_VERSION${post}}' when 1 is expected")
+  endif()
+endforeach()