浏览代码

Merge topic 'project-homepage-url'

73f9b2974c project: Add HOMEPAGE_URL named parameter
fd28c382b4 project: Add <PROJECT-NAME>_DESCRIPTION
9b57cb62ea Help: Fix minor typo in docs for CMAKE_PROJECT_DESCRIPTION
c89993d529 Tests: Avoid enabling languages unnecessarily in RunCMake.project

Acked-by: Kitware Robot <[email protected]>
Merge-request: !1816
Craig Scott 7 年之前
父节点
当前提交
80784ef77f

+ 17 - 6
Help/command/project.rst

@@ -9,6 +9,7 @@ Sets project details such as name, version, etc. and enables languages.
  project(<PROJECT-NAME>
          [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
          [DESCRIPTION <project-description-string>]
+         [HOMEPAGE_URL <url-string>]
          [LANGUAGES <language-name>...])
 
 Sets the name of the project and stores the name in the
@@ -41,9 +42,18 @@ in variables
 Variables corresponding to unspecified versions are set to the empty string
 (if policy :policy:`CMP0048` is set to ``NEW``).
 
-If optional ``DESCRIPTION`` is given, then additional :variable:`PROJECT_DESCRIPTION`
-variable will be set to its argument. The argument must be a string with short
-description of the project (only a few words).
+If the optional ``DESCRIPTION`` is given, then :variable:`PROJECT_DESCRIPTION`
+and :variable:`<PROJECT-NAME>_DESCRIPTION` will be set to its argument.
+The description is expected to be a relatively short string, usually no more
+than a few words.
+
+The optional ``HOMEPAGE_URL`` sets the analogous variables
+:variable:`PROJECT_HOMEPAGE_URL` and :variable:`<PROJECT-NAME>_HOMEPAGE_URL`.
+When this option is given, the URL provided should be the canonical home for
+the project.
+
+Note that the description and homepage URL may be used as defaults for
+things like packaging meta-data, documentation, etc.
 
 Optionally you can specify which languages your project supports.
 Example languages include ``C``, ``CXX`` (i.e.  C++), ``CUDA``,
@@ -64,9 +74,10 @@ literal, direct call to the :command:`project` command; loading one
 through the :command:`include` command is not sufficient.  If no such
 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 and its description from
-:variable:`CMAKE_PROJECT_DESCRIPTION`.
+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`.
 
 .. note::
   Call the :command:`cmake_minimum_required` command at the beginning

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

@@ -67,6 +67,7 @@ Variables that Provide Information
    /variable/CMAKE_PARENT_LIST_FILE
    /variable/CMAKE_PATCH_VERSION
    /variable/CMAKE_PROJECT_DESCRIPTION
+   /variable/CMAKE_PROJECT_HOMEPAGE_URL
    /variable/CMAKE_PROJECT_NAME
    /variable/CMAKE_RANLIB
    /variable/CMAKE_ROOT
@@ -97,6 +98,8 @@ Variables that Provide Information
    /variable/CMAKE_XCODE_GENERATE_SCHEME
    /variable/CMAKE_XCODE_PLATFORM_TOOLSET
    /variable/PROJECT-NAME_BINARY_DIR
+   /variable/PROJECT-NAME_DESCRIPTION
+   /variable/PROJECT-NAME_HOMEPAGE_URL
    /variable/PROJECT-NAME_SOURCE_DIR
    /variable/PROJECT-NAME_VERSION
    /variable/PROJECT-NAME_VERSION_MAJOR
@@ -105,6 +108,7 @@ Variables that Provide Information
    /variable/PROJECT-NAME_VERSION_TWEAK
    /variable/PROJECT_BINARY_DIR
    /variable/PROJECT_DESCRIPTION
+   /variable/PROJECT_HOMEPAGE_URL
    /variable/PROJECT_NAME
    /variable/PROJECT_SOURCE_DIR
    /variable/PROJECT_VERSION

+ 7 - 0
Help/release/dev/project-homepage.rst

@@ -0,0 +1,7 @@
+project-homepage
+----------------
+
+* The :command:`project` command learned an optional ``HOMEPAGE_URL``
+  parameter which has the effect of setting variables like
+  :variable:`PROJECT_HOMEPAGE_URL`, :variable:`<PROJECT-NAME>_HOMEPAGE_URL`
+  and :variable:`CMAKE_PROJECT_HOMEPAGE_URL`.

+ 1 - 1
Help/variable/CMAKE_PROJECT_DESCRIPTION.rst

@@ -7,7 +7,7 @@ This variable holds the description 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 name that ``CMAKE_PROJECT_DESCRIPTION`` contains.  For example, consider
+the value that ``CMAKE_PROJECT_DESCRIPTION`` contains.  For example, consider
 the following top level CMakeLists.txt:
 
 .. code-block:: cmake

+ 35 - 0
Help/variable/CMAKE_PROJECT_HOMEPAGE_URL.rst

@@ -0,0 +1,35 @@
+CMAKE_PROJECT_HOMEPAGE_URL
+--------------------------
+
+The homepage URL of the top level project.
+
+This variable holds the homepage URL 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_HOMEPAGE_URL`` contains.  For example, consider
+the following top level CMakeLists.txt:
+
+.. code-block:: cmake
+
+  cmake_minimum_required(VERSION 3.0)
+  project(First HOMEPAGE_URL "http://first.example.com")
+  project(Second HOMEPAGE_URL "http://second.example.com")
+  add_subdirectory(sub)
+  project(Third HOMEPAGE_URL "http://third.example.com")
+
+And ``sub/CMakeLists.txt`` with the following contents:
+
+.. code-block:: cmake
+
+  project(SubProj HOMEPAGE_URL "http://subproj.example.com")
+  message("CMAKE_PROJECT_HOMEPAGE_URL = ${CMAKE_PROJECT_HOMEPAGE_URL}")
+
+The most recently seen :command:`project` command from the top level
+CMakeLists.txt would be ``project(Second ...)``, so this will print::
+
+  CMAKE_PROJECT_HOMEPAGE_URL = http://second.example.com
+
+To obtain the homepage URL from the most recent call to :command:`project` in
+the current directory scope or above, see the :variable:`PROJECT_HOMEPAGE_URL`
+variable.

+ 5 - 0
Help/variable/PROJECT-NAME_DESCRIPTION.rst

@@ -0,0 +1,5 @@
+<PROJECT-NAME>_DESCRIPTION
+--------------------------
+
+Value given to the ``DESCRIPTION`` option of the most recent call to the
+:command:`project` command with project name ``<PROJECT-NAME>``, if any.

+ 5 - 0
Help/variable/PROJECT-NAME_HOMEPAGE_URL.rst

@@ -0,0 +1,5 @@
+<PROJECT-NAME>_HOMEPAGE_URL
+---------------------------
+
+Value given to the ``HOMEPAGE_URL`` option of the most recent call to the
+:command:`project` command with project name ``<PROJECT-NAME>``, if any.

+ 9 - 0
Help/variable/PROJECT_HOMEPAGE_URL.rst

@@ -0,0 +1,9 @@
+PROJECT_HOMEPAGE_URL
+--------------------
+
+The homepage URL of the project.
+
+This is the homepage URL given to the most recently called :command:`project`
+command in the current directory scope or above.  To obtain the homepage URL
+of the top level project, see the :variable:`CMAKE_PROJECT_HOMEPAGE_URL`
+variable.

+ 6 - 1
Modules/CPackDeb.cmake

@@ -254,7 +254,7 @@
 #  upstream documentation or information may be found.
 #
 #  * Mandatory : NO
-#  * Default   : -
+#  * Default   : :variable:`CMAKE_PROJECT_HOMEPAGE_URL`
 #
 #  .. note::
 #
@@ -914,6 +914,11 @@ function(cpack_deb_prepare_package_vars)
     endif()
   endif()
 
+  # Homepage: (optional)
+  if(NOT CPACK_DEBIAN_PACKAGE_HOMEPAGE AND CMAKE_PROJECT_HOMEPAGE_URL)
+    set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "${CMAKE_PROJECT_HOMEPAGE_URL}")
+  endif()
+
   # Section: (recommended)
   if(NOT CPACK_DEBIAN_PACKAGE_SECTION)
     set(CPACK_DEBIAN_PACKAGE_SECTION "devel")

+ 3 - 1
Modules/CPackFreeBSD.cmake

@@ -80,7 +80,8 @@ the RPM information (e.g. package license).
   * Mandatory: YES
   * Default:
 
-   - :variable:`CPACK_DEBIAN_PACKAGE_HOMEPAGE` (this may be set already
+   - :variable:`CMAKE_PROJECT_HOMEPAGE_URL`, or if that is not set,
+     :variable:`CPACK_DEBIAN_PACKAGE_HOMEPAGE` (this may be set already
      for Debian packaging, so we may as well re-use it).
 
 .. variable:: CPACK_FREEBSD_PACKAGE_LICENSE
@@ -208,6 +209,7 @@ _cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_DESCRIPTION"
 # There's really only one homepage for a project, so
 # re-use the Debian setting if it's there.
 _cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_WWW"
+    "CMAKE_PROJECT_HOMEPAGE_URL"
     "CPACK_DEBIAN_PACKAGE_HOMEPAGE"
     "_cpack_freebsd_fallback_www"
     )

+ 5 - 1
Modules/CPackRPM.cmake

@@ -191,7 +191,7 @@
 #  The projects URL.
 #
 #  * Mandatory : NO
-#  * Default   : -
+#  * Default   : :variable:`CMAKE_PROJECT_HOMEPAGE_URL`
 #
 # .. variable:: CPACK_RPM_PACKAGE_DESCRIPTION
 #               CPACK_RPM_<component>_PACKAGE_DESCRIPTION
@@ -1787,6 +1787,10 @@ function(cpack_rpm_generate_package)
     endif()
   endif()
 
+  if(NOT CPACK_RPM_PACKAGE_URL AND CMAKE_PROJECT_HOMEPAGE_URL)
+    set(CPACK_RPM_PACKAGE_URL "${CMAKE_PROJECT_HOMEPAGE_URL}")
+  endif()
+
   # CPACK_RPM_PACKAGE_NAME (mandatory)
   if(NOT CPACK_RPM_PACKAGE_NAME)
     string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_RPM_PACKAGE_NAME)

+ 46 - 3
Source/cmProjectCommand.cxx

@@ -68,8 +68,10 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
   bool haveVersion = false;
   bool haveLanguages = false;
   bool haveDescription = false;
+  bool haveHomepage = false;
   std::string version;
   std::string description;
+  std::string homepage;
   std::vector<std::string> languages;
   std::function<void()> missedValueReporter;
   auto resetReporter = [&missedValueReporter]() {
@@ -78,6 +80,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
   enum Doing
   {
     DoingDescription,
+    DoingHomepage,
     DoingLanguages,
     DoingVersion
   };
@@ -141,6 +144,22 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
           "by a value that expanded to nothing.");
         resetReporter();
       };
+    } else if (args[i] == "HOMEPAGE_URL") {
+      if (haveHomepage) {
+        this->Makefile->IssueMessage(
+          cmake::FATAL_ERROR, "HOMEPAGE_URL may be specified at most once.");
+        cmSystemTools::SetFatalErrorOccured();
+        return true;
+      }
+      haveHomepage = true;
+      doing = DoingHomepage;
+      missedValueReporter = [this, &resetReporter]() {
+        this->Makefile->IssueMessage(
+          cmake::WARNING,
+          "HOMEPAGE_URL keyword not followed by a value or was followed "
+          "by a value that expanded to nothing.");
+        resetReporter();
+      };
     } else if (doing == DoingVersion) {
       doing = DoingLanguages;
       version = args[i];
@@ -149,6 +168,10 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
       doing = DoingLanguages;
       description = args[i];
       resetReporter();
+    } else if (doing == DoingHomepage) {
+      doing = DoingLanguages;
+      homepage = args[i];
+      resetReporter();
     } else // doing == DoingLanguages
     {
       languages.push_back(args[i]);
@@ -159,12 +182,12 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
     missedValueReporter();
   }
 
-  if ((haveVersion || haveDescription) && !haveLanguages &&
+  if ((haveVersion || haveDescription || haveHomepage) && !haveLanguages &&
       !languages.empty()) {
     this->Makefile->IssueMessage(
       cmake::FATAL_ERROR,
-      "project with VERSION or DESCRIPTION must use LANGUAGES before "
-      "language names.");
+      "project with VERSION, DESCRIPTION or HOMEPAGE_URL must "
+      "use LANGUAGES before language names.");
     cmSystemTools::SetFatalErrorOccured();
     return true;
   }
@@ -261,6 +284,8 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
 
   if (haveDescription) {
     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
@@ -275,6 +300,24 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
     }
   }
 
+  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);
+    }
+  }
+
   if (languages.empty()) {
     // if no language is specified do c and c++
     languages.push_back("C");

+ 1 - 1
Tests/RunCMake/project/ProjectDescriptionNoArg.cmake

@@ -1,2 +1,2 @@
 cmake_policy(SET CMP0048 NEW)
-project(ProjectDescriptionTest VERSION 1.0.0 DESCRIPTION)
+project(ProjectDescriptionTest VERSION 1.0.0 LANGUAGES NONE DESCRIPTION)

+ 3 - 0
Tests/RunCMake/project/ProjectHomepage-stdout.txt

@@ -0,0 +1,3 @@
+-- PROJECT_HOMEPAGE_URL=http://example.com
+-- CMAKE_PROJECT_HOMEPAGE_URL=http://example.com
+-- ProjectHomepageTest_HOMEPAGE_URL=http://example.com

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

@@ -0,0 +1,14 @@
+cmake_policy(SET CMP0048 NEW)
+project(ProjectHomepageTest VERSION 1.0.0 HOMEPAGE_URL "http://example.com" LANGUAGES)
+if(NOT PROJECT_HOMEPAGE_URL)
+  message(FATAL_ERROR "PROJECT_HOMEPAGE_URL expected to be set")
+endif()
+if(NOT CMAKE_PROJECT_HOMEPAGE_URL)
+  message(FATAL_ERROR "CMAKE_PROJECT_HOMEPAGE_URL expected to be set")
+endif()
+if(NOT ProjectHomepageTest_HOMEPAGE_URL)
+  message(FATAL_ERROR "ProjectHomepageTest_HOMEPAGE_URL expected to be set")
+endif()
+message(STATUS "PROJECT_HOMEPAGE_URL=${PROJECT_HOMEPAGE_URL}")
+message(STATUS "CMAKE_PROJECT_HOMEPAGE_URL=${CMAKE_PROJECT_HOMEPAGE_URL}")
+message(STATUS "ProjectHomepageTest_HOMEPAGE_URL=${ProjectHomepageTest_HOMEPAGE_URL}")

+ 1 - 0
Tests/RunCMake/project/ProjectHomepage2-result.txt

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

+ 4 - 0
Tests/RunCMake/project/ProjectHomepage2-stderr.txt

@@ -0,0 +1,4 @@
+^CMake Error at ProjectHomepage2.cmake:2 \(project\):
+  HOMEPAGE_URL may be specified at most once.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$

+ 2 - 0
Tests/RunCMake/project/ProjectHomepage2.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0048 NEW)
+project(ProjectDescriptionTest VERSION 1.0.0 HOMEPAGE_URL "http://example.com" HOMEPAGE_URL "http://example.com" LANGUAGES)

+ 5 - 0
Tests/RunCMake/project/ProjectHomepageNoArg-stderr.txt

@@ -0,0 +1,5 @@
+^CMake Warning at ProjectHomepageNoArg.cmake:2 \(project\):
+  HOMEPAGE_URL keyword not followed by a value or was followed by a value
+  that expanded to nothing.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$

+ 2 - 0
Tests/RunCMake/project/ProjectHomepageNoArg.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0048 NEW)
+project(ProjectDescriptionTest VERSION 1.0.0 LANGUAGES NONE HOMEPAGE_URL)

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

@@ -12,6 +12,9 @@ run_cmake(ProjectDescription)
 run_cmake(ProjectDescription2)
 run_cmake(ProjectDescriptionNoArg)
 run_cmake(ProjectDescriptionNoArg2)
+run_cmake(ProjectHomepage)
+run_cmake(ProjectHomepage2)
+run_cmake(ProjectHomepageNoArg)
 run_cmake(VersionAndLanguagesEmpty)
 run_cmake(VersionEmpty)
 run_cmake(VersionInvalid)

+ 2 - 2
Tests/RunCMake/project/VersionMissingLanguages-stderr.txt

@@ -1,5 +1,5 @@
 CMake Error at VersionMissingLanguages.cmake:2 \(project\):
-  project with VERSION or DESCRIPTION must use LANGUAGES before language
-  names.
+  project with VERSION, DESCRIPTION or HOMEPAGE_URL must use LANGUAGES before
+  language names.
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)$