summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2020-10-07 14:05:34 -0400
committerKyle Edwards <kyle.edwards@kitware.com>2020-10-13 09:46:54 -0400
commitfd50a75fa01b4727a58350b494dbb23f6b0f103f (patch)
tree6d4321f57bb2460e7ec76b6d5d76761b485b072c
parent521847809f4511352f01688227e8a22bc906f578 (diff)
downloadcmake-fd50a75fa01b4727a58350b494dbb23f6b0f103f.tar.gz
CMP0115: Require source file extensions to be explicit
-rw-r--r--Help/manual/cmake-policies.7.rst8
-rw-r--r--Help/policy/CMP0115.rst34
-rw-r--r--Help/release/dev/explicit-source-extensions.rst5
-rw-r--r--Source/cmGeneratorTarget.cxx8
-rw-r--r--Source/cmPolicies.h4
-rw-r--r--Source/cmSourceFile.cxx61
-rw-r--r--Source/cmSourceFile.h5
-rw-r--r--Tests/RunCMake/CMP0115/CMP0115-NEW-result.txt1
-rw-r--r--Tests/RunCMake/CMP0115/CMP0115-NEW-stderr.txt17
-rw-r--r--Tests/RunCMake/CMP0115/CMP0115-NEW.cmake1
-rw-r--r--Tests/RunCMake/CMP0115/CMP0115-OLD-result.txt1
-rw-r--r--Tests/RunCMake/CMP0115/CMP0115-OLD-stderr.txt22
-rw-r--r--Tests/RunCMake/CMP0115/CMP0115-OLD.cmake1
-rw-r--r--Tests/RunCMake/CMP0115/CMP0115-WARN-result.txt1
-rw-r--r--Tests/RunCMake/CMP0115/CMP0115-WARN-stderr.txt36
-rw-r--r--Tests/RunCMake/CMP0115/CMP0115-WARN.cmake1
-rw-r--r--Tests/RunCMake/CMP0115/CMP0115.cmake3
-rw-r--r--Tests/RunCMake/CMP0115/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0115/RunCMakeTest.cmake12
-rw-r--r--Tests/RunCMake/CMP0115/main.c4
-rw-r--r--Tests/RunCMake/CMakeLists.txt1
21 files changed, 208 insertions, 21 deletions
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 0392325e83..0836883f76 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -51,6 +51,14 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used
to determine whether to report an error on use of deprecated macros or
functions.
+Policies Introduced by CMake 3.20
+=================================
+
+.. toctree::
+ :maxdepth: 1
+
+ CMP0115: Source file extensions must be explicit. </policy/CMP0115>
+
Policies Introduced by CMake 3.19
=================================
diff --git a/Help/policy/CMP0115.rst b/Help/policy/CMP0115.rst
new file mode 100644
index 0000000000..7f82c43269
--- /dev/null
+++ b/Help/policy/CMP0115.rst
@@ -0,0 +1,34 @@
+CMP0115
+-------
+
+.. versionadded:: 3.20
+
+Source file extensions must be explicit.
+
+In CMake 3.19 and below, if a source file could not be found by the name
+specified, it would append a list of known extensions to the name to see if
+the file with the extension could be found. For example, this would allow the
+user to run:
+
+.. code-block:: cmake
+
+ add_executable(exe main)
+
+and put ``main.c`` in the executable without specifying the extension.
+
+Starting in CMake 3.20, CMake prefers all source files to have their extensions
+explicitly listed:
+
+.. code-block:: cmake
+
+ add_executable(exe main.c)
+
+The ``OLD`` behavior for this policy is to implicitly append known extensions
+to source files if they can't be found. The ``NEW`` behavior of this policy is
+to not append known extensions and require them to be explicit.
+
+This policy was introduced in CMake version 3.20. CMake version |release|
+warns when the policy is not set and uses ``OLD`` behavior. Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/release/dev/explicit-source-extensions.rst b/Help/release/dev/explicit-source-extensions.rst
new file mode 100644
index 0000000000..ccd933976b
--- /dev/null
+++ b/Help/release/dev/explicit-source-extensions.rst
@@ -0,0 +1,5 @@
+explicit-source-extensions
+--------------------------
+
+* Source file extensions must now be explicit. See policy :policy:`CMP0115` for
+ details.
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 6ebc9e1878..3b475509ff 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1539,10 +1539,14 @@ bool processSources(cmGeneratorTarget const* tgt,
for (std::string& src : entry.Values) {
cmSourceFile* sf = mf->GetOrCreateSource(src);
std::string e;
- std::string fullPath = sf->ResolveFullPath(&e);
+ std::string w;
+ std::string fullPath = sf->ResolveFullPath(&e, &w);
+ cmake* cm = tgt->GetLocalGenerator()->GetCMakeInstance();
+ if (!w.empty()) {
+ cm->IssueMessage(MessageType::AUTHOR_WARNING, w, tgt->GetBacktrace());
+ }
if (fullPath.empty()) {
if (!e.empty()) {
- cmake* cm = tgt->GetLocalGenerator()->GetCMakeInstance();
cm->IssueMessage(MessageType::FATAL_ERROR, e, tgt->GetBacktrace());
}
return contextDependent;
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 958d061041..f9f7d0e09f 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -340,7 +340,9 @@ class cmMakefile;
3, 19, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0114, \
"ExternalProject step targets fully adopt their steps.", 3, 19, 0, \
- cmPolicies::WARN)
+ cmPolicies::WARN) \
+ SELECT(POLICY, CMP0115, "Source file extensions must be explicit.", 3, 20, \
+ 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/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index ef44a578db..61f48e9a37 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -8,6 +8,7 @@
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmPolicies.h"
#include "cmProperty.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
@@ -93,10 +94,11 @@ cmSourceFileLocation const& cmSourceFile::GetLocation() const
return this->Location;
}
-std::string const& cmSourceFile::ResolveFullPath(std::string* error)
+std::string const& cmSourceFile::ResolveFullPath(std::string* error,
+ std::string* cmp0115Warning)
{
if (this->FullPath.empty()) {
- if (this->FindFullPath(error)) {
+ if (this->FindFullPath(error, cmp0115Warning)) {
this->CheckExtension();
}
}
@@ -108,7 +110,8 @@ std::string const& cmSourceFile::GetFullPath() const
return this->FullPath;
}
-bool cmSourceFile::FindFullPath(std::string* error)
+bool cmSourceFile::FindFullPath(std::string* error,
+ std::string* cmp0115Warning)
{
// If the file is generated compute the location without checking on disk.
if (this->GetIsGenerated()) {
@@ -131,9 +134,11 @@ bool cmSourceFile::FindFullPath(std::string* error)
// List of extension lists
std::vector<std::string> exts =
makefile->GetCMakeInstance()->GetAllExtensions();
+ auto cmp0115 = makefile->GetPolicyStatus(cmPolicies::CMP0115);
// Tries to find the file in a given directory
- auto findInDir = [this, &exts, &lPath](std::string const& dir) -> bool {
+ auto findInDir = [this, &exts, &lPath, cmp0115, cmp0115Warning,
+ makefile](std::string const& dir) -> bool {
// Compute full path
std::string const fullPath = cmSystemTools::CollapseFullPath(lPath, dir);
// Try full path
@@ -141,13 +146,29 @@ bool cmSourceFile::FindFullPath(std::string* error)
this->FullPath = fullPath;
return true;
}
- // Try full path with extension
- for (std::string const& ext : exts) {
- if (!ext.empty()) {
- std::string extPath = cmStrCat(fullPath, '.', ext);
- if (cmSystemTools::FileExists(extPath)) {
- this->FullPath = extPath;
- return true;
+ // This has to be an if statement due to a bug in Oracle Developer Studio.
+ // See https://community.oracle.com/tech/developers/discussion/4476246/
+ // for details.
+ if (cmp0115 == cmPolicies::OLD || cmp0115 == cmPolicies::WARN) {
+ // Try full path with extension
+ for (std::string const& ext : exts) {
+ if (!ext.empty()) {
+ std::string extPath = cmStrCat(fullPath, '.', ext);
+ if (cmSystemTools::FileExists(extPath)) {
+ this->FullPath = extPath;
+ if (cmp0115 == cmPolicies::WARN) {
+ std::string warning =
+ cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0115),
+ "\nFile:\n ", extPath);
+ if (cmp0115Warning) {
+ *cmp0115Warning = std::move(warning);
+ } else {
+ makefile->GetCMakeInstance()->IssueMessage(
+ MessageType::AUTHOR_WARNING, warning);
+ }
+ }
+ return true;
+ }
}
}
}
@@ -168,11 +189,19 @@ bool cmSourceFile::FindFullPath(std::string* error)
}
// Compose error
- std::string err =
- cmStrCat("Cannot find source file:\n ", lPath, "\nTried extensions");
- for (std::string const& ext : exts) {
- err += " .";
- err += ext;
+ std::string err = cmStrCat("Cannot find source file:\n ", lPath);
+ switch (cmp0115) {
+ case cmPolicies::OLD:
+ case cmPolicies::WARN:
+ err = cmStrCat(err, "\nTried extensions");
+ for (auto const& ext : exts) {
+ err = cmStrCat(err, " .", ext);
+ }
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ break;
}
if (error != nullptr) {
*error = std::move(err);
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index 39ea8e33f4..3196b3f90b 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -77,7 +77,8 @@ public:
* Resolves the full path to the file. Attempts to locate the file on disk
* and finalizes its location.
*/
- std::string const& ResolveFullPath(std::string* error = nullptr);
+ std::string const& ResolveFullPath(std::string* error = nullptr,
+ std::string* cmp0115Warning = nullptr);
/**
* The resolved full path to the file. The returned file name might be empty
@@ -138,7 +139,7 @@ private:
bool FindFullPathFailed = false;
bool IsGenerated = false;
- bool FindFullPath(std::string* error);
+ bool FindFullPath(std::string* error, std::string* cmp0115Warning);
void CheckExtension();
void CheckLanguage(std::string const& ext);
diff --git a/Tests/RunCMake/CMP0115/CMP0115-NEW-result.txt b/Tests/RunCMake/CMP0115/CMP0115-NEW-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/CMP0115-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0115/CMP0115-NEW-stderr.txt b/Tests/RunCMake/CMP0115/CMP0115-NEW-stderr.txt
new file mode 100644
index 0000000000..b63c53d538
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/CMP0115-NEW-stderr.txt
@@ -0,0 +1,17 @@
+^CMake Error at CMP0115\.cmake:[0-9]+ \(add_executable\):
+ Cannot find source file:
+
+ main
+Call Stack \(most recent call first\):
+ CMP0115-NEW\.cmake:[0-9]+ \(include\)
+ CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at CMP0115\.cmake:[0-9]+ \(add_executable\):
+ No SOURCES given to target: exe
+Call Stack \(most recent call first\):
+ CMP0115-NEW\.cmake:[0-9]+ \(include\)
+ CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/CMP0115/CMP0115-NEW.cmake b/Tests/RunCMake/CMP0115/CMP0115-NEW.cmake
new file mode 100644
index 0000000000..ddf5071f69
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/CMP0115-NEW.cmake
@@ -0,0 +1 @@
+include(CMP0115.cmake)
diff --git a/Tests/RunCMake/CMP0115/CMP0115-OLD-result.txt b/Tests/RunCMake/CMP0115/CMP0115-OLD-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/CMP0115-OLD-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0115/CMP0115-OLD-stderr.txt b/Tests/RunCMake/CMP0115/CMP0115-OLD-stderr.txt
new file mode 100644
index 0000000000..8b9031111d
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/CMP0115-OLD-stderr.txt
@@ -0,0 +1,22 @@
+^CMake Error at CMP0115\.cmake:[0-9]+ \(add_executable\):
+ Cannot find source file:
+
+ noexist
+
+ Tried extensions [^
+]*
+ [^
+]*
+Call Stack \(most recent call first\):
+ CMP0115-OLD\.cmake:[0-9]+ \(include\)
+ CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at CMP0115\.cmake:[0-9]+ \(add_executable\):
+ No SOURCES given to target: exe
+Call Stack \(most recent call first\):
+ CMP0115-OLD\.cmake:[0-9]+ \(include\)
+ CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/CMP0115/CMP0115-OLD.cmake b/Tests/RunCMake/CMP0115/CMP0115-OLD.cmake
new file mode 100644
index 0000000000..ddf5071f69
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/CMP0115-OLD.cmake
@@ -0,0 +1 @@
+include(CMP0115.cmake)
diff --git a/Tests/RunCMake/CMP0115/CMP0115-WARN-result.txt b/Tests/RunCMake/CMP0115/CMP0115-WARN-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/CMP0115-WARN-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0115/CMP0115-WARN-stderr.txt b/Tests/RunCMake/CMP0115/CMP0115-WARN-stderr.txt
new file mode 100644
index 0000000000..7b100b6e4c
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/CMP0115-WARN-stderr.txt
@@ -0,0 +1,36 @@
+^CMake Warning \(dev\) at CMP0115\.cmake:[0-9]+ \(add_executable\):
+ Policy CMP0115 is not set: Source file extensions must be explicit\. Run
+ "cmake --help-policy CMP0115" for policy details\. Use the cmake_policy
+ command to set the policy and suppress this warning\.
+
+ File:
+
+ [^
+]*/Tests/RunCMake/CMP0115/main\.c
+Call Stack \(most recent call first\):
+ CMP0115-WARN\.cmake:[0-9]+ \(include\)
+ CMakeLists\.txt:[0-9]+ \(include\)
+This warning is for project developers\. Use -Wno-dev to suppress it\.
+
+CMake Error at CMP0115\.cmake:[0-9]+ \(add_executable\):
+ Cannot find source file:
+
+ noexist
+
+ Tried extensions [^
+]*
+ [^
+]*
+Call Stack \(most recent call first\):
+ CMP0115-WARN\.cmake:[0-9]+ \(include\)
+ CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at CMP0115\.cmake:[0-9]+ \(add_executable\):
+ No SOURCES given to target: exe
+Call Stack \(most recent call first\):
+ CMP0115-WARN\.cmake:[0-9]+ \(include\)
+ CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/CMP0115/CMP0115-WARN.cmake b/Tests/RunCMake/CMP0115/CMP0115-WARN.cmake
new file mode 100644
index 0000000000..ddf5071f69
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/CMP0115-WARN.cmake
@@ -0,0 +1 @@
+include(CMP0115.cmake)
diff --git a/Tests/RunCMake/CMP0115/CMP0115.cmake b/Tests/RunCMake/CMP0115/CMP0115.cmake
new file mode 100644
index 0000000000..be910a420a
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/CMP0115.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+
+add_executable(exe main noexist)
diff --git a/Tests/RunCMake/CMP0115/CMakeLists.txt b/Tests/RunCMake/CMP0115/CMakeLists.txt
new file mode 100644
index 0000000000..b646c4ac67
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.18)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0115/RunCMakeTest.cmake b/Tests/RunCMake/CMP0115/RunCMakeTest.cmake
new file mode 100644
index 0000000000..58182ac75a
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/RunCMakeTest.cmake
@@ -0,0 +1,12 @@
+include(RunCMake)
+
+function(run_cmp0115 status)
+ if(NOT status STREQUAL "WARN")
+ set(RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0115=${status})
+ endif()
+ run_cmake(CMP0115-${status})
+endfunction()
+
+run_cmp0115(OLD)
+run_cmp0115(WARN)
+run_cmp0115(NEW)
diff --git a/Tests/RunCMake/CMP0115/main.c b/Tests/RunCMake/CMP0115/main.c
new file mode 100644
index 0000000000..8488f4e58f
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 63738d78a4..a8261c68d3 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -125,6 +125,7 @@ if(CMake_TEST_CUDA)
endif()
add_RunCMake_test(CMP0106)
add_RunCMake_test(CMP0111)
+add_RunCMake_test(CMP0115)
# The test for Policy 65 requires the use of the
# CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode