Browse Source

project: Warn at top-level if `cmake_minimum_required` wasn't called

The top-level project() call will now issue an AUTHOR_WARNING if it
wasn't called after cmake_minimum_required().

Fixes: #24071
friendlyanon 3 years ago
parent
commit
59573bf5b9

+ 2 - 1
Help/command/project.rst

@@ -188,5 +188,6 @@ call exists, CMake will issue a warning and pretend there is a
   Call the ``project()`` command near the top of the top-level
   ``CMakeLists.txt``, but *after* calling :command:`cmake_minimum_required`.
   It is important to establish version and policy settings before invoking
-  other commands whose behavior they may affect.
+  other commands whose behavior they may affect and for this reason the
+  ``project()`` command will issue a warning if this order is not kept.
   See also policy :policy:`CMP0000`.

+ 6 - 0
Help/release/dev/top-level-command-order.rst

@@ -0,0 +1,6 @@
+top-level-command-order
+-----------------------
+
+* The top-level :command:`project` call will now emit an author warning if the
+  documented command order in relation to :command:`cmake_minimum_required` is
+  not respected.

+ 9 - 0
Source/cmProjectCommand.cxx

@@ -34,6 +34,15 @@ bool cmProjectCommand(std::vector<std::string> const& args,
   }
 
   cmMakefile& mf = status.GetMakefile();
+  if (mf.IsRootMakefile() &&
+      !mf.GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION")) {
+    mf.IssueMessage(
+      MessageType::AUTHOR_WARNING,
+      "cmake_minimum_required() should be called prior to this top-level "
+      "project() call. Please see the cmake-commands(7) manual for usage "
+      "documentation of both commands.");
+  }
+
   if (!IncludeByVariable(status, "CMAKE_PROJECT_INCLUDE_BEFORE")) {
     return false;
   }

+ 2 - 0
Tests/RunCMake/CommandLine/C_buildsrcdir/initial-cache.txt

@@ -1,3 +1,5 @@
+set(CMAKE_MINIMUM_REQUIRED_VERSION "" CACHE STRING "")
+
 # Used to verify that the values match what is passed via -S and -B, and are retained in cache.
 set(INITIAL_SOURCE_DIR "${CMAKE_SOURCE_DIR}" CACHE PATH "defined in initial.cmake")
 set(INITIAL_BINARY_DIR "${CMAKE_BINARY_DIR}" CACHE PATH "defined in initial.cmake")

+ 3 - 1
Tests/RunCMake/project/CMakeLists.txt

@@ -1,3 +1,5 @@
-cmake_minimum_required(VERSION 2.8.12)
+if(NOT "x${RunCMake_TEST}" STREQUAL "xNoMinimumRequired")
+  cmake_minimum_required(VERSION 2.8.12)
+endif()
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)

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

@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
+  cmake_minimum_required\(\) should be called prior to this top-level project\(\)
+  call\.  Please see the cmake-commands\(7\) manual for usage documentation of
+  both commands\.
+This warning is for project developers\.  Use -Wno-dev to suppress it\.$

+ 0 - 0
Tests/RunCMake/project/NoMinimumRequired.cmake


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

@@ -52,3 +52,5 @@ run_cmake(CMP0048-NEW)
 run_cmake(CMP0096-WARN)
 run_cmake(CMP0096-OLD)
 run_cmake(CMP0096-NEW)
+
+run_cmake(NoMinimumRequired)

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

@@ -1,6 +1,7 @@
 include(RunCMake)
 
 set(RunCMake_TEST_OPTIONS
+  -DCMAKE_MINIMUM_REQUIRED_VERSION:STATIC=
   # Simulate a previous CMake run that used `project(... VERSION ...)`
   # in a non-injected call site.
   -DCMAKE_PROJECT_VERSION:STATIC=1.2.3