1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-14 02:08:27 +08:00

Merge topic 'explicit-source-extensions'

fd50a75fa0 CMP0115: Require source file extensions to be explicit

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Ben Boeckel <ben.boeckel@kitware.com>
Merge-request: !5346
This commit is contained in:
Kyle Edwards
2020-10-13 14:17:03 +00:00
committed by Kitware Robot
21 changed files with 208 additions and 21 deletions

View File

@@ -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 to determine whether to report an error on use of deprecated macros or
functions. 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 Policies Introduced by CMake 3.19
================================= =================================

34
Help/policy/CMP0115.rst Normal file
View File

@@ -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

View File

@@ -0,0 +1,5 @@
explicit-source-extensions
--------------------------
* Source file extensions must now be explicit. See policy :policy:`CMP0115` for
details.

View File

@@ -1539,10 +1539,14 @@ bool processSources(cmGeneratorTarget const* tgt,
for (std::string& src : entry.Values) { for (std::string& src : entry.Values) {
cmSourceFile* sf = mf->GetOrCreateSource(src); cmSourceFile* sf = mf->GetOrCreateSource(src);
std::string e; 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 (fullPath.empty()) {
if (!e.empty()) { if (!e.empty()) {
cmake* cm = tgt->GetLocalGenerator()->GetCMakeInstance();
cm->IssueMessage(MessageType::FATAL_ERROR, e, tgt->GetBacktrace()); cm->IssueMessage(MessageType::FATAL_ERROR, e, tgt->GetBacktrace());
} }
return contextDependent; return contextDependent;

View File

@@ -340,7 +340,9 @@ class cmMakefile;
3, 19, 0, cmPolicies::WARN) \ 3, 19, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0114, \ SELECT(POLICY, CMP0114, \
"ExternalProject step targets fully adopt their steps.", 3, 19, 0, \ "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_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \ #define CM_FOR_EACH_POLICY_ID(POLICY) \

View File

@@ -8,6 +8,7 @@
#include "cmListFileCache.h" #include "cmListFileCache.h"
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmMessageType.h" #include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmProperty.h" #include "cmProperty.h"
#include "cmState.h" #include "cmState.h"
#include "cmStringAlgorithms.h" #include "cmStringAlgorithms.h"
@@ -93,10 +94,11 @@ cmSourceFileLocation const& cmSourceFile::GetLocation() const
return this->Location; 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->FullPath.empty()) {
if (this->FindFullPath(error)) { if (this->FindFullPath(error, cmp0115Warning)) {
this->CheckExtension(); this->CheckExtension();
} }
} }
@@ -108,7 +110,8 @@ std::string const& cmSourceFile::GetFullPath() const
return this->FullPath; 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 the file is generated compute the location without checking on disk.
if (this->GetIsGenerated()) { if (this->GetIsGenerated()) {
@@ -131,9 +134,11 @@ bool cmSourceFile::FindFullPath(std::string* error)
// List of extension lists // List of extension lists
std::vector<std::string> exts = std::vector<std::string> exts =
makefile->GetCMakeInstance()->GetAllExtensions(); makefile->GetCMakeInstance()->GetAllExtensions();
auto cmp0115 = makefile->GetPolicyStatus(cmPolicies::CMP0115);
// Tries to find the file in a given directory // 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 // Compute full path
std::string const fullPath = cmSystemTools::CollapseFullPath(lPath, dir); std::string const fullPath = cmSystemTools::CollapseFullPath(lPath, dir);
// Try full path // Try full path
@@ -141,13 +146,29 @@ bool cmSourceFile::FindFullPath(std::string* error)
this->FullPath = fullPath; this->FullPath = fullPath;
return true; return true;
} }
// Try full path with extension // This has to be an if statement due to a bug in Oracle Developer Studio.
for (std::string const& ext : exts) { // See https://community.oracle.com/tech/developers/discussion/4476246/
if (!ext.empty()) { // for details.
std::string extPath = cmStrCat(fullPath, '.', ext); if (cmp0115 == cmPolicies::OLD || cmp0115 == cmPolicies::WARN) {
if (cmSystemTools::FileExists(extPath)) { // Try full path with extension
this->FullPath = extPath; for (std::string const& ext : exts) {
return true; 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 // Compose error
std::string err = std::string err = cmStrCat("Cannot find source file:\n ", lPath);
cmStrCat("Cannot find source file:\n ", lPath, "\nTried extensions"); switch (cmp0115) {
for (std::string const& ext : exts) { case cmPolicies::OLD:
err += " ."; case cmPolicies::WARN:
err += ext; 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) { if (error != nullptr) {
*error = std::move(err); *error = std::move(err);

View File

@@ -77,7 +77,8 @@ public:
* Resolves the full path to the file. Attempts to locate the file on disk * Resolves the full path to the file. Attempts to locate the file on disk
* and finalizes its location. * 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 * The resolved full path to the file. The returned file name might be empty
@@ -138,7 +139,7 @@ private:
bool FindFullPathFailed = false; bool FindFullPathFailed = false;
bool IsGenerated = false; bool IsGenerated = false;
bool FindFullPath(std::string* error); bool FindFullPath(std::string* error, std::string* cmp0115Warning);
void CheckExtension(); void CheckExtension();
void CheckLanguage(std::string const& ext); void CheckLanguage(std::string const& ext);

View File

@@ -0,0 +1 @@
1

View File

@@ -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\.$

View File

@@ -0,0 +1 @@
include(CMP0115.cmake)

View File

@@ -0,0 +1 @@
1

View File

@@ -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\.$

View File

@@ -0,0 +1 @@
include(CMP0115.cmake)

View File

@@ -0,0 +1 @@
1

View File

@@ -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\.$

View File

@@ -0,0 +1 @@
include(CMP0115.cmake)

View File

@@ -0,0 +1,3 @@
enable_language(C)
add_executable(exe main noexist)

View File

@@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.18)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)

View File

@@ -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)

View File

@@ -0,0 +1,4 @@
int main(void)
{
return 0;
}

View File

@@ -125,6 +125,7 @@ if(CMake_TEST_CUDA)
endif() endif()
add_RunCMake_test(CMP0106) add_RunCMake_test(CMP0106)
add_RunCMake_test(CMP0111) add_RunCMake_test(CMP0111)
add_RunCMake_test(CMP0115)
# The test for Policy 65 requires the use of the # The test for Policy 65 requires the use of the
# CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode # CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode