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:
@@ -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
34
Help/policy/CMP0115.rst
Normal 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
|
5
Help/release/dev/explicit-source-extensions.rst
Normal file
5
Help/release/dev/explicit-source-extensions.rst
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
explicit-source-extensions
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
* Source file extensions must now be explicit. See policy :policy:`CMP0115` for
|
||||||
|
details.
|
@@ -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;
|
||||||
|
@@ -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) \
|
||||||
|
@@ -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);
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
1
Tests/RunCMake/CMP0115/CMP0115-NEW-result.txt
Normal file
1
Tests/RunCMake/CMP0115/CMP0115-NEW-result.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
1
|
17
Tests/RunCMake/CMP0115/CMP0115-NEW-stderr.txt
Normal file
17
Tests/RunCMake/CMP0115/CMP0115-NEW-stderr.txt
Normal 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\.$
|
1
Tests/RunCMake/CMP0115/CMP0115-NEW.cmake
Normal file
1
Tests/RunCMake/CMP0115/CMP0115-NEW.cmake
Normal file
@@ -0,0 +1 @@
|
|||||||
|
include(CMP0115.cmake)
|
1
Tests/RunCMake/CMP0115/CMP0115-OLD-result.txt
Normal file
1
Tests/RunCMake/CMP0115/CMP0115-OLD-result.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
1
|
22
Tests/RunCMake/CMP0115/CMP0115-OLD-stderr.txt
Normal file
22
Tests/RunCMake/CMP0115/CMP0115-OLD-stderr.txt
Normal 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\.$
|
1
Tests/RunCMake/CMP0115/CMP0115-OLD.cmake
Normal file
1
Tests/RunCMake/CMP0115/CMP0115-OLD.cmake
Normal file
@@ -0,0 +1 @@
|
|||||||
|
include(CMP0115.cmake)
|
1
Tests/RunCMake/CMP0115/CMP0115-WARN-result.txt
Normal file
1
Tests/RunCMake/CMP0115/CMP0115-WARN-result.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
1
|
36
Tests/RunCMake/CMP0115/CMP0115-WARN-stderr.txt
Normal file
36
Tests/RunCMake/CMP0115/CMP0115-WARN-stderr.txt
Normal 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\.$
|
1
Tests/RunCMake/CMP0115/CMP0115-WARN.cmake
Normal file
1
Tests/RunCMake/CMP0115/CMP0115-WARN.cmake
Normal file
@@ -0,0 +1 @@
|
|||||||
|
include(CMP0115.cmake)
|
3
Tests/RunCMake/CMP0115/CMP0115.cmake
Normal file
3
Tests/RunCMake/CMP0115/CMP0115.cmake
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
enable_language(C)
|
||||||
|
|
||||||
|
add_executable(exe main noexist)
|
3
Tests/RunCMake/CMP0115/CMakeLists.txt
Normal file
3
Tests/RunCMake/CMP0115/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.18)
|
||||||
|
project(${RunCMake_TEST} NONE)
|
||||||
|
include(${RunCMake_TEST}.cmake)
|
12
Tests/RunCMake/CMP0115/RunCMakeTest.cmake
Normal file
12
Tests/RunCMake/CMP0115/RunCMakeTest.cmake
Normal 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)
|
4
Tests/RunCMake/CMP0115/main.c
Normal file
4
Tests/RunCMake/CMP0115/main.c
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user