summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2024-04-03 13:38:36 (GMT)
committerKitware Robot <kwrobot@kitware.com>2024-04-03 13:38:46 (GMT)
commit7fde84352701a80500e5dcafae9cac32f9f5d437 (patch)
tree5e4495e9cc1ffd0c6e30a5b619dc0488dfc5fc17
parentbf116544b3545188535b2bab4c2dbaf9153041d7 (diff)
parent97464aa9701cc4bebb6d0a44c0201c3476489c3e (diff)
downloadCMake-7fde84352701a80500e5dcafae9cac32f9f5d437.zip
CMake-7fde84352701a80500e5dcafae9cac32f9f5d437.tar.gz
CMake-7fde84352701a80500e5dcafae9cac32f9f5d437.tar.bz2
Merge topic 'enable_language-before-project'
97464aa970 enable_language(): Fail if called before project() Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: buildbot <buildbot@kitware.com> Merge-request: !9396
-rw-r--r--Help/command/enable_language.rst16
-rw-r--r--Help/manual/cmake-policies.7.rst1
-rw-r--r--Help/policy/CMP0165.rst26
-rw-r--r--Help/release/dev/enable_language-before-project.rst6
-rw-r--r--Source/cmEnableLanguageCommand.cxx26
-rw-r--r--Source/cmPolicies.h5
-rw-r--r--Tests/RunCMake/CMP0165/CMP0165-NEW-result.txt1
-rw-r--r--Tests/RunCMake/CMP0165/CMP0165-NEW-stderr.txt4
-rw-r--r--Tests/RunCMake/CMP0165/CMP0165-NEW.cmake2
-rw-r--r--Tests/RunCMake/CMP0165/CMP0165-OLD.cmake2
-rw-r--r--Tests/RunCMake/CMP0165/CMP0165-WARN-stderr.txt5
-rw-r--r--Tests/RunCMake/CMP0165/CMP0165-WARN.cmake2
-rw-r--r--Tests/RunCMake/CMP0165/CMakeLists.txt7
-rw-r--r--Tests/RunCMake/CMP0165/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CMakeLists.txt1
15 files changed, 101 insertions, 8 deletions
diff --git a/Help/command/enable_language.rst b/Help/command/enable_language.rst
index 2f1cc23..d587310 100644
--- a/Help/command/enable_language.rst
+++ b/Help/command/enable_language.rst
@@ -9,15 +9,19 @@ Enable languages (CXX/C/OBJC/OBJCXX/Fortran/etc)
Enables support for the named languages in CMake. This is the same as
the :command:`project` command but does not create any of the extra
-variables that are created by the project command.
+variables that are created by the :command:`project` command.
.. include:: SUPPORTED_LANGUAGES.txt
-This command must be called in file scope, not in a function call.
-Furthermore, it must be called in the highest directory common to all
-targets using the named language directly for compiling sources or
-indirectly through link dependencies. It is simplest to enable all
-needed languages in the top-level directory of a project.
+The following restrictions apply to where ``enable_language()`` may be called:
+
+* It must be called in file scope, not in a function call.
+* It must not be called before the first call to :command:`project`.
+ See policy :policy:`CMP0165`.
+* It must be called in the highest directory common to all targets
+ using the named language directly for compiling sources or
+ indirectly through link dependencies. It is simplest to enable all
+ needed languages in the top-level directory of a project.
The ``OPTIONAL`` keyword is a placeholder for future implementation and
does not currently work. Instead you can use the :module:`CheckLanguage`
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index d874363..51b4ce6 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.30
.. toctree::
:maxdepth: 1
+ CMP0165: enable_language() must not be called before project(). </policy/CMP0165>
CMP0164: add_library() rejects SHARED libraries when not supported by the platform. </policy/CMP0164>
CMP0163: The GENERATED source file property is now visible in all directories. </policy/CMP0163>
CMP0162: Visual Studio generators add UseDebugLibraries indicators by default. </policy/CMP0162>
diff --git a/Help/policy/CMP0165.rst b/Help/policy/CMP0165.rst
new file mode 100644
index 0000000..7a79c44
--- /dev/null
+++ b/Help/policy/CMP0165.rst
@@ -0,0 +1,26 @@
+CMP0165
+-------
+
+.. versionadded:: 3.30
+
+:command:`enable_language` must not be called before :command:`project`.
+
+In CMake 3.29 and below, if a project called :command:`enable_language`
+before the first call to :command:`project`, the language would be enabled
+but possibly using unset details that were expected to be set.
+In CMake 3.30 and above, :command:`enable_language` prefers to reject this
+case and stop with a fatal error instead if it detects that :command:`project`
+has not yet been called. This policy provides compatibility for projects that
+happened to work when :command:`enable_language` was called before
+:command:`project` and have not been updated to call these commands in the
+required order.
+
+The ``OLD`` behavior for this policy is to allow :command:`enable_language`
+to be called before :command:`project`. The ``NEW`` behavior for this policy
+is to fail with a fatal error in such cases.
+
+.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 3.30
+.. |WARNS_OR_DOES_NOT_WARN| replace:: warns
+.. include:: STANDARD_ADVICE.txt
+
+.. include:: DEPRECATED.txt
diff --git a/Help/release/dev/enable_language-before-project.rst b/Help/release/dev/enable_language-before-project.rst
new file mode 100644
index 0000000..2b1fd1d
--- /dev/null
+++ b/Help/release/dev/enable_language-before-project.rst
@@ -0,0 +1,6 @@
+enable_language-before-project
+------------------------------
+
+* The :command:`enable_language` command now fails with an error
+ if it is called before the first :command:`project` call.
+ See policy :policy:`CMP0165`.
diff --git a/Source/cmEnableLanguageCommand.cxx b/Source/cmEnableLanguageCommand.cxx
index 59522c0..87fb077 100644
--- a/Source/cmEnableLanguageCommand.cxx
+++ b/Source/cmEnableLanguageCommand.cxx
@@ -4,6 +4,9 @@
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmPolicies.h"
+#include "cmSystemTools.h"
bool cmEnableLanguageCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
@@ -13,6 +16,27 @@ bool cmEnableLanguageCommand(std::vector<std::string> const& args,
return false;
}
+ cmMakefile& mf = status.GetMakefile();
+ if (!mf.IsNormalDefinitionSet("PROJECT_NAME")) {
+ switch (mf.GetPolicyStatus(cmPolicies::CMP0165)) {
+ case cmPolicies::WARN:
+ mf.IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ "project() should be called prior to this enable_language() call.");
+ break;
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::NEW:
+ mf.IssueMessage(
+ MessageType::FATAL_ERROR,
+ "project() must be called prior to this enable_language() call.");
+ cmSystemTools::SetFatalErrorOccurred();
+ return false;
+ default:
+ break;
+ }
+ }
+
bool optional = false;
std::vector<std::string> languages;
for (std::string const& it : args) {
@@ -23,6 +47,6 @@ bool cmEnableLanguageCommand(std::vector<std::string> const& args,
}
}
- status.GetMakefile().EnableLanguage(languages, optional);
+ mf.EnableLanguage(languages, optional);
return true;
}
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index e526dce..b0237d7 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -505,7 +505,10 @@ class cmMakefile;
SELECT(POLICY, CMP0164, \
"add_library() rejects SHARED libraries when not supported by the " \
"platform.", \
- 3, 30, 0, cmPolicies::WARN)
+ 3, 30, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0165, \
+ "enable_language() must not be called before project().", 3, 30, 0, \
+ cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
diff --git a/Tests/RunCMake/CMP0165/CMP0165-NEW-result.txt b/Tests/RunCMake/CMP0165/CMP0165-NEW-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CMP0165/CMP0165-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0165/CMP0165-NEW-stderr.txt b/Tests/RunCMake/CMP0165/CMP0165-NEW-stderr.txt
new file mode 100644
index 0000000..662d8ad
--- /dev/null
+++ b/Tests/RunCMake/CMP0165/CMP0165-NEW-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at CMP0165-NEW\.cmake:[0-9]+ \(enable_language\):
+ project\(\) must be called prior to this enable_language\(\) call\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/CMP0165/CMP0165-NEW.cmake b/Tests/RunCMake/CMP0165/CMP0165-NEW.cmake
new file mode 100644
index 0000000..8bcb3fd
--- /dev/null
+++ b/Tests/RunCMake/CMP0165/CMP0165-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0165 NEW)
+enable_language(C)
diff --git a/Tests/RunCMake/CMP0165/CMP0165-OLD.cmake b/Tests/RunCMake/CMP0165/CMP0165-OLD.cmake
new file mode 100644
index 0000000..c80ba76
--- /dev/null
+++ b/Tests/RunCMake/CMP0165/CMP0165-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0165 OLD)
+enable_language(C)
diff --git a/Tests/RunCMake/CMP0165/CMP0165-WARN-stderr.txt b/Tests/RunCMake/CMP0165/CMP0165-WARN-stderr.txt
new file mode 100644
index 0000000..32a79df
--- /dev/null
+++ b/Tests/RunCMake/CMP0165/CMP0165-WARN-stderr.txt
@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at CMP0165-WARN\.cmake:[0-9]+ \(enable_language\):
+ project\(\) should be called prior to this enable_language\(\) call\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
+This warning is for project developers\. Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/CMP0165/CMP0165-WARN.cmake b/Tests/RunCMake/CMP0165/CMP0165-WARN.cmake
new file mode 100644
index 0000000..75149dd
--- /dev/null
+++ b/Tests/RunCMake/CMP0165/CMP0165-WARN.cmake
@@ -0,0 +1,2 @@
+# Don't touch the policy, it should warn by default
+enable_language(C)
diff --git a/Tests/RunCMake/CMP0165/CMakeLists.txt b/Tests/RunCMake/CMP0165/CMakeLists.txt
new file mode 100644
index 0000000..2fa8c4e
--- /dev/null
+++ b/Tests/RunCMake/CMP0165/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.29)
+
+# This is different to the usual RunCMake test pattern. We are specifically
+# testing the scenario where enable_language() is called before project().
+include(${RunCMake_TEST}.cmake)
+
+project(${RunCMake_TEST} NONE)
diff --git a/Tests/RunCMake/CMP0165/RunCMakeTest.cmake b/Tests/RunCMake/CMP0165/RunCMakeTest.cmake
new file mode 100644
index 0000000..f5f167c
--- /dev/null
+++ b/Tests/RunCMake/CMP0165/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0165-WARN)
+run_cmake(CMP0165-OLD)
+run_cmake(CMP0165-NEW)
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 60388f1..a82c79f 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -174,6 +174,7 @@ add_RunCMake_test(CMP0156 -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
-DCMAKE_C_COMPILER_VERSION=${CMAKE_C_COMPILER_VERSION})
add_RunCMake_test(CMP0160)
add_RunCMake_test(CMP0163)
+add_RunCMake_test(CMP0165)
# The test for Policy 65 requires the use of the
# CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode