Bläddra i källkod

CPack: Use project version as default for `CPACK_PACKAGE_VERSION`

* Introduce `CMAKE_PROJECT_VERSION` and the corresponsing components:
  `CMAKE_PROJECT_VERSION_MAJOR`, `CMAKE_PROJECT_VERSION_MINOR`,
  `CMAKE_PROJECT_VERSION_PATCH` and `CMAKE_PROJECT_VERSION_TWEAK`.

* `CPack` module use `CMAKE_PROJECT_VERSION_MAJOR`,
  `CMAKE_PROJECT_VERSION_MINOR` and `CMAKE_PROJECT_VERSION_PATCH`
  to initialize corresponsing CPack variables.
Alex Turbov 7 år sedan
förälder
incheckning
af1c48871c

+ 3 - 2
Help/command/project.rst

@@ -76,8 +76,9 @@ call exists CMake will implicitly add one to the top that enables the
 default languages (``C`` and ``CXX``).  The name of the project set in
 the top level ``CMakeLists.txt`` file is available from the
 :variable:`CMAKE_PROJECT_NAME` variable, its description from
-:variable:`CMAKE_PROJECT_DESCRIPTION` and its homepage URL from
-:variable:`CMAKE_PROJECT_HOMEPAGE_URL`.
+:variable:`CMAKE_PROJECT_DESCRIPTION`, its homepage URL from
+:variable:`CMAKE_PROJECT_HOMEPAGE_URL` and its version from
+:variable:`CMAKE_PROJECT_VERSION`.
 
 .. note::
   Call the :command:`cmake_minimum_required` command at the beginning

+ 5 - 0
Help/manual/cmake-variables.7.rst

@@ -69,6 +69,11 @@ Variables that Provide Information
    /variable/CMAKE_PROJECT_DESCRIPTION
    /variable/CMAKE_PROJECT_HOMEPAGE_URL
    /variable/CMAKE_PROJECT_NAME
+   /variable/CMAKE_PROJECT_VERSION
+   /variable/CMAKE_PROJECT_VERSION_MAJOR
+   /variable/CMAKE_PROJECT_VERSION_MINOR
+   /variable/CMAKE_PROJECT_VERSION_PATCH
+   /variable/CMAKE_PROJECT_VERSION_TWEAK
    /variable/CMAKE_RANLIB
    /variable/CMAKE_ROOT
    /variable/CMAKE_SCRIPT_MODE_FILE

+ 10 - 0
Help/release/dev/cpack-use-project-version.rst

@@ -0,0 +1,10 @@
+cpack-use-project-version
+-------------------------
+
+* Introduce :variable:`CMAKE_PROJECT_VERSION` and the corresponding components:
+  :variable:`CMAKE_PROJECT_VERSION_MAJOR`, :variable:`CMAKE_PROJECT_VERSION_MINOR`,
+  :variable:`CMAKE_PROJECT_VERSION_PATCH` and :variable:`CMAKE_PROJECT_VERSION_TWEAK`.
+
+* :module:`CPack` module use :variable:`CMAKE_PROJECT_VERSION_MAJOR`,
+  :variable:`CMAKE_PROJECT_VERSION_MINOR` and :variable:`CMAKE_PROJECT_VERSION_PATCH`
+  to initialize corresponding CPack variables.

+ 35 - 0
Help/variable/CMAKE_PROJECT_VERSION.rst

@@ -0,0 +1,35 @@
+CMAKE_PROJECT_VERSION
+---------------------
+
+The version of the top level project.
+
+This variable holds the version of the project as specified in the top
+level CMakeLists.txt file by a :command:`project` command.  In the event that
+the top level CMakeLists.txt contains multiple :command:`project` calls,
+the most recently called one from that top level CMakeLists.txt will determine
+the value that ``CMAKE_PROJECT_VERSION`` contains.  For example, consider
+the following top level CMakeLists.txt:
+
+.. code-block:: cmake
+
+  cmake_minimum_required(VERSION 3.0)
+  project(First VERSION 1.2.3)
+  project(Second VERSION 3.4.5)
+  add_subdirectory(sub)
+  project(Third VERSION 6.7.8)
+
+And ``sub/CMakeLists.txt`` with the following contents:
+
+.. code-block:: cmake
+
+  project(SubProj VERSION 1)
+  message("CMAKE_PROJECT_VERSION = ${CMAKE_PROJECT_VERSION}")
+
+The most recently seen :command:`project` command from the top level
+CMakeLists.txt would be ``project(Second ...)``, so this will print::
+
+  CMAKE_PROJECT_VERSION = 3.4.5
+
+To obtain the version from the most recent call to :command:`project` in
+the current directory scope or above, see the :variable:`PROJECT_VERSION`
+variable.

+ 9 - 0
Help/variable/CMAKE_PROJECT_VERSION_MAJOR.rst

@@ -0,0 +1,9 @@
+CMAKE_PROJECT_VERSION_MAJOR
+---------------------------
+
+The major version of the top level project.
+
+This variable holds the major version of the project as specified in the top
+level CMakeLists.txt file by a :command:`project` command. Please see
+:variable:`CMAKE_PROJECT_VERSION` documentation for the behavior when
+multiple :command:`project` commands are used in the sources.

+ 9 - 0
Help/variable/CMAKE_PROJECT_VERSION_MINOR.rst

@@ -0,0 +1,9 @@
+CMAKE_PROJECT_VERSION_MINOR
+---------------------------
+
+The minor version of the top level project.
+
+This variable holds the minor version of the project as specified in the top
+level CMakeLists.txt file by a :command:`project` command. Please see
+:variable:`CMAKE_PROJECT_VERSION` documentation for the behavior when
+multiple :command:`project` commands are used in the sources.

+ 9 - 0
Help/variable/CMAKE_PROJECT_VERSION_PATCH.rst

@@ -0,0 +1,9 @@
+CMAKE_PROJECT_VERSION_PATCH
+---------------------------
+
+The patch version of the top level project.
+
+This variable holds the patch version of the project as specified in the top
+level CMakeLists.txt file by a :command:`project` command. Please see
+:variable:`CMAKE_PROJECT_VERSION` documentation for the behavior when
+multiple :command:`project` commands are used in the sources.

+ 9 - 0
Help/variable/CMAKE_PROJECT_VERSION_TWEAK.rst

@@ -0,0 +1,9 @@
+CMAKE_PROJECT_VERSION_TWEAK
+---------------------------
+
+The tweak version of the top level project.
+
+This variable holds the tweak version of the project as specified in the top
+level CMakeLists.txt file by a :command:`project` command. Please see
+:variable:`CMAKE_PROJECT_VERSION` documentation for the behavior when
+multiple :command:`project` commands are used in the sources.

+ 45 - 8
Modules/CPack.cmake

@@ -80,15 +80,35 @@
 #
 # .. variable:: CPACK_PACKAGE_VERSION_MAJOR
 #
-#  Package major Version. Default value is 0.
+#  Package major version.  This variable will always be set, but its default
+#  value depends on whether or not version details were given to the
+#  :command:`project` command in the top level CMakeLists.txt file.  If version
+#  details were given, the default value will be
+#  :variable:`CMAKE_PROJECT_VERSION_MAJOR`.  If no version details were given,
+#  a default version of 0.1.1 will be assumed, leading to
+#  ``CPACK_PACKAGE_VERSION_MAJOR`` having a default value of 0.
 #
 # .. variable:: CPACK_PACKAGE_VERSION_MINOR
 #
-#  Package minor Version. Default value is 1.
+#  Package minor version.  The default value is determined based on whether or
+#  not version details were given to the :command:`project` command in the top
+#  level CMakeLists.txt file.  If version details were given, the default
+#  value will be :variable:`CMAKE_PROJECT_VERSION_MINOR`, but if no minor
+#  version component was specified then ``CPACK_PACKAGE_VERSION_MINOR`` will be
+#  left unset.  If no project version was given at all, a default version of
+#  0.1.1 will be assumed, leading to ``CPACK_PACKAGE_VERSION_MINOR`` having a
+#  default value of 1.
 #
 # .. variable:: CPACK_PACKAGE_VERSION_PATCH
 #
-#  Package patch Version. Default value is 1.
+#  Package patch version.  The default value is determined based on whether or
+#  not version details were given to the :command:`project` command in the top
+#  level CMakeLists.txt file.  If version details were given, the default
+#  value will be :variable:`CMAKE_PROJECT_VERSION_PATCH`, but if no patch
+#  version component was specified then ``CPACK_PACKAGE_VERSION_PATCH`` will be
+#  left unset.  If no project version was given at all, a default version of
+#  0.1.1 will be assumed, leading to ``CPACK_PACKAGE_VERSION_PATCH`` having a
+#  default value of 1.
 #
 # .. variable:: CPACK_PACKAGE_DESCRIPTION_FILE
 #
@@ -368,11 +388,28 @@ endfunction()
 
 # Set the package name
 _cpack_set_default(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}")
-_cpack_set_default(CPACK_PACKAGE_VERSION_MAJOR "0")
-_cpack_set_default(CPACK_PACKAGE_VERSION_MINOR "1")
-_cpack_set_default(CPACK_PACKAGE_VERSION_PATCH "1")
-_cpack_set_default(CPACK_PACKAGE_VERSION
-  "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
+if(CMAKE_PROJECT_VERSION_MAJOR)
+    _cpack_set_default(CPACK_PACKAGE_VERSION_MAJOR "${CMAKE_PROJECT_VERSION_MAJOR}")
+    if(CMAKE_PROJECT_VERSION_MINOR)
+        _cpack_set_default(CPACK_PACKAGE_VERSION_MINOR "${CMAKE_PROJECT_VERSION_MINOR}")
+        if(CMAKE_PROJECT_VERSION_PATCH)
+            _cpack_set_default(CPACK_PACKAGE_VERSION_PATCH "${CMAKE_PROJECT_VERSION_PATCH}")
+            _cpack_set_default(CPACK_PACKAGE_VERSION
+                "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
+        else()
+            _cpack_set_default(CPACK_PACKAGE_VERSION
+            "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}")
+        endif()
+    else()
+        _cpack_set_default(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}")
+    endif()
+else()
+    _cpack_set_default(CPACK_PACKAGE_VERSION_MAJOR "0")
+    _cpack_set_default(CPACK_PACKAGE_VERSION_MINOR "1")
+    _cpack_set_default(CPACK_PACKAGE_VERSION_PATCH "1")
+    _cpack_set_default(CPACK_PACKAGE_VERSION
+        "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
+endif()
 _cpack_set_default(CPACK_PACKAGE_VENDOR "Humanity")
 if(CMAKE_PROJECT_DESCRIPTION)
   _cpack_set_default(CPACK_PACKAGE_DESCRIPTION_SUMMARY

+ 30 - 24
Source/cmProjectCommand.cxx

@@ -249,6 +249,12 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
     vv = projectName + "_VERSION_TWEAK";
     this->Makefile->AddDefinition("PROJECT_VERSION_TWEAK", vb[3]);
     this->Makefile->AddDefinition(vv, vb[3]);
+    // Also, try set top level variables
+    TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION", vs.c_str());
+    TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MAJOR", vb[0]);
+    TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MINOR", vb[1]);
+    TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_PATCH", vb[2]);
+    TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_TWEAK", vb[3]);
   } else if (cmp0048 != cmPolicies::OLD) {
     // Set project VERSION variables to empty
     std::vector<std::string> vv;
@@ -262,6 +268,13 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
     vv.push_back(projectName + "_VERSION_MINOR");
     vv.push_back(projectName + "_VERSION_PATCH");
     vv.push_back(projectName + "_VERSION_TWEAK");
+    if (this->Makefile->IsRootMakefile()) {
+      vv.push_back("CMAKE_PROJECT_VERSION");
+      vv.push_back("CMAKE_PROJECT_VERSION_MAJOR");
+      vv.push_back("CMAKE_PROJECT_VERSION_MINOR");
+      vv.push_back("CMAKE_PROJECT_VERSION_PATCH");
+      vv.push_back("CMAKE_PROJECT_VERSION_TWEAK");
+    }
     std::string vw;
     for (std::string const& i : vv) {
       const char* v = this->Makefile->GetDefinition(i);
@@ -286,36 +299,14 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
     this->Makefile->AddDefinition("PROJECT_DESCRIPTION", description.c_str());
     this->Makefile->AddDefinition(projectName + "_DESCRIPTION",
                                   description.c_str());
-    // Set the CMAKE_PROJECT_DESCRIPTION variable to be the highest-level
-    // project name in the tree. If there are two project commands
-    // in the same CMakeLists.txt file, and it is the top level
-    // CMakeLists.txt file, then go with the last one.
-    if (!this->Makefile->GetDefinition("CMAKE_PROJECT_DESCRIPTION") ||
-        (this->Makefile->IsRootMakefile())) {
-      this->Makefile->AddDefinition("CMAKE_PROJECT_DESCRIPTION",
-                                    description.c_str());
-      this->Makefile->AddCacheDefinition(
-        "CMAKE_PROJECT_DESCRIPTION", description.c_str(),
-        "Value Computed by CMake", cmStateEnums::STATIC);
-    }
+    TopLevelCMakeVarCondSet("CMAKE_PROJECT_DESCRIPTION", description.c_str());
   }
 
   if (haveHomepage) {
     this->Makefile->AddDefinition("PROJECT_HOMEPAGE_URL", homepage.c_str());
     this->Makefile->AddDefinition(projectName + "_HOMEPAGE_URL",
                                   homepage.c_str());
-    // Set the CMAKE_PROJECT_HOMEPAGE_URL variable to be the highest-level
-    // project name in the tree. If there are two project commands
-    // in the same CMakeLists.txt file, and it is the top level
-    // CMakeLists.txt file, then go with the last one.
-    if (!this->Makefile->GetDefinition("CMAKE_PROJECT_HOMEPAGE_URL") ||
-        (this->Makefile->IsRootMakefile())) {
-      this->Makefile->AddDefinition("CMAKE_PROJECT_HOMEPAGE_URL",
-                                    homepage.c_str());
-      this->Makefile->AddCacheDefinition(
-        "CMAKE_PROJECT_HOMEPAGE_URL", homepage.c_str(),
-        "Value Computed by CMake", cmStateEnums::STATIC);
-    }
+    TopLevelCMakeVarCondSet("CMAKE_PROJECT_HOMEPAGE_URL", homepage.c_str());
   }
 
   if (languages.empty()) {
@@ -338,3 +329,18 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
   }
   return true;
 }
+
+void cmProjectCommand::TopLevelCMakeVarCondSet(const char* const name,
+                                               const char* const value)
+{
+  // Set the CMAKE_PROJECT_XXX variable to be the highest-level
+  // project name in the tree. If there are two project commands
+  // in the same CMakeLists.txt file, and it is the top level
+  // CMakeLists.txt file, then go with the last one.
+  if (!this->Makefile->GetDefinition(name) ||
+      (this->Makefile->IsRootMakefile())) {
+    this->Makefile->AddDefinition(name, value);
+    this->Makefile->AddCacheDefinition(name, value, "Value Computed by CMake",
+                                       cmStateEnums::STATIC);
+  }
+}

+ 3 - 0
Source/cmProjectCommand.h

@@ -34,6 +34,9 @@ public:
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) override;
+
+private:
+  void TopLevelCMakeVarCondSet(const char* name, const char* value);
 };
 
 #endif

+ 38 - 0
Tests/CMakeLists.txt

@@ -951,6 +951,44 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
     endif()
   endif()
 
+  if(CTEST_TEST_CPACK)
+    add_test(CPackUseDefaultVersion ${CMAKE_CTEST_COMMAND}
+      --build-and-test
+      "${CMake_SOURCE_DIR}/Tests/CPackUseDefaultVersion"
+      "${CMake_BINARY_DIR}/Tests/CPackUseDefaultVersion"
+      ${build_generator_args}
+      --build-project CPackUseDefaultVersion
+      --build-two-config
+      --build-options ${build_options}
+        ${CPackUseDefaultVersion_BUILD_OPTIONS})
+    set_tests_properties(CPackUseDefaultVersion PROPERTIES PASS_REGULAR_EXPRESSION "CPACK_PACKAGE_VERSION=0\\.1\\.1")
+    list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CPackUseDefaultVersion")
+
+    add_test(CPackUseProjectVersion ${CMAKE_CTEST_COMMAND}
+      --build-and-test
+      "${CMake_SOURCE_DIR}/Tests/CPackUseProjectVersion"
+      "${CMake_BINARY_DIR}/Tests/CPackUseProjectVersion"
+      ${build_generator_args}
+      --build-project CPackUseProjectVersion
+      --build-two-config
+      --build-options ${build_options}
+        ${CPackUseProjectVersion_BUILD_OPTIONS})
+    set_tests_properties(CPackUseProjectVersion PROPERTIES PASS_REGULAR_EXPRESSION "CPACK_PACKAGE_VERSION=1\\.2\\.3")
+    list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CPackUseProjectVersion")
+
+    add_test(CPackUseShortProjectVersion ${CMAKE_CTEST_COMMAND}
+      --build-and-test
+      "${CMake_SOURCE_DIR}/Tests/CPackUseShortProjectVersion"
+      "${CMake_BINARY_DIR}/Tests/CPackUseShortProjectVersion"
+      ${build_generator_args}
+      --build-project CPackUseShortProjectVersion
+      --build-two-config
+      --build-options ${build_options}
+        ${CPackUseProjectVersion_BUILD_OPTIONS})
+    set_tests_properties(CPackUseShortProjectVersion PROPERTIES PASS_REGULAR_EXPRESSION "CPACK_PACKAGE_VERSION=2")
+    list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CPackUseShortProjectVersion")
+  endif()
+
   if(CTEST_RUN_CPackComponents)
     set(CPackComponents_BUILD_OPTIONS)
     if(APPLE)

+ 6 - 0
Tests/CPackUseDefaultVersion/CMakeLists.txt

@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.2)
+project(CPackUseProjectVersion NONE)
+
+include(CPack)
+
+message("CPACK_PACKAGE_VERSION=${CPACK_PACKAGE_VERSION}")

+ 6 - 0
Tests/CPackUseProjectVersion/CMakeLists.txt

@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.2)
+project(CPackUseProjectVersion VERSION 1.2.3 LANGUAGES NONE)
+
+include(CPack)
+
+message("CPACK_PACKAGE_VERSION=${CPACK_PACKAGE_VERSION}")

+ 6 - 0
Tests/CPackUseShortProjectVersion/CMakeLists.txt

@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.2)
+project(CPackUseProjectVersion VERSION 2 LANGUAGES NONE)
+
+include(CPack)
+
+message("CPACK_PACKAGE_VERSION=${CPACK_PACKAGE_VERSION}")