mirror of
https://github.com/Kitware/CMake.git
synced 2025-12-30 18:29:37 -06:00
if command: Add PATH_EQUAL operator
This commit is contained in:
@@ -47,7 +47,7 @@ Compound conditions are evaluated in the following order of precedence:
|
||||
`GREATER_EQUAL`_, `STREQUAL`_, `STRLESS`_, `STRLESS_EQUAL`_,
|
||||
`STRGREATER`_, `STRGREATER_EQUAL`_, `VERSION_EQUAL`_, `VERSION_LESS`_,
|
||||
`VERSION_LESS_EQUAL`_, `VERSION_GREATER`_, `VERSION_GREATER_EQUAL`_,
|
||||
and `MATCHES`_.
|
||||
`PATH_EQUAL`_, and `MATCHES`_.
|
||||
|
||||
4. Unary logical operator `NOT`_.
|
||||
|
||||
@@ -314,6 +314,34 @@ Version Comparisons
|
||||
Any non-integer version component or non-integer trailing part of a version
|
||||
component effectively truncates the string at that point.
|
||||
|
||||
Path Comparisons
|
||||
""""""""""""""""
|
||||
|
||||
.. _PATH_EQUAL:
|
||||
|
||||
``if(<variable|string> PATH_EQUAL <variable|string>)``
|
||||
.. versionadded:: 3.24
|
||||
Compares the lexical representations of two paths provided as string
|
||||
literals or variables. No normalization is performed on either path.
|
||||
|
||||
Lexical comparison has the advantage over string comparison to have a
|
||||
knowledge of the structure of the path. So, the following comparison is
|
||||
``TRUE`` using ``PATH_EQUAL`` operator, but ``FALSE`` with ``STREQUAL``:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
# comparison is TRUE
|
||||
if ("/a//b/c" PATH_EQUAL "/a/b/c")
|
||||
...
|
||||
endif()
|
||||
|
||||
# comparison is FALSE
|
||||
if ("/a//b/c" STREQUAL "/a/b/c")
|
||||
...
|
||||
endif()
|
||||
|
||||
See :ref:`cmake_path(COMPARE) <Path COMPARE>` for more details.
|
||||
|
||||
Variable Expansion
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ Policies Introduced by CMake 3.24
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
CMP0139: The if() command supports path comparisons using PATH_EQUAL operator. </policy/CMP0139>
|
||||
CMP0138: MSVC compilers use -ZI instead of /Zi for x86 and x64 by default. </policy/CMP0138>
|
||||
CMP0137: try_compile() passes platform variables in project mode. </policy/CMP0137>
|
||||
CMP0136: Watcom runtime library flags are selected by an abstraction. </policy/CMP0136>
|
||||
|
||||
17
Help/policy/CMP0139.rst
Normal file
17
Help/policy/CMP0139.rst
Normal file
@@ -0,0 +1,17 @@
|
||||
CMP0139
|
||||
-------
|
||||
|
||||
.. versionadded:: 3.24
|
||||
|
||||
The :command:`if` command supports path comparisons using ``PATH_EQUAL``
|
||||
operator.
|
||||
|
||||
The ``OLD`` behavior for this policy is to ignore the ``PATH_EQUAL`` operator.
|
||||
The ``NEW`` behavior is to interpret the ``PATH_EQUAL`` operator.
|
||||
|
||||
This policy was introduced in CMake version 3.24.
|
||||
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/if-PATH_EQUAL.rst
Normal file
5
Help/release/dev/if-PATH_EQUAL.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
if-PATH_EQUAL
|
||||
-------------
|
||||
|
||||
* The :command:`if` command gains the capability to compare paths by using the
|
||||
``PATH_EQUAL`` operator. See policy :policy:`CMP0139`.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "cmsys/RegularExpression.hxx"
|
||||
|
||||
#include "cmCMakePath.h"
|
||||
#include "cmExpandedCommandArgument.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmMessageType.h"
|
||||
@@ -58,6 +59,7 @@ auto const keyVERSION_GREATER = "VERSION_GREATER"_s;
|
||||
auto const keyVERSION_GREATER_EQUAL = "VERSION_GREATER_EQUAL"_s;
|
||||
auto const keyVERSION_LESS = "VERSION_LESS"_s;
|
||||
auto const keyVERSION_LESS_EQUAL = "VERSION_LESS_EQUAL"_s;
|
||||
auto const keyPATH_EQUAL = "PATH_EQUAL"_s;
|
||||
|
||||
cmSystemTools::CompareOp const MATCH2CMPOP[5] = {
|
||||
cmSystemTools::OP_LESS, cmSystemTools::OP_LESS_EQUAL,
|
||||
@@ -217,6 +219,7 @@ cmConditionEvaluator::cmConditionEvaluator(cmMakefile& makefile,
|
||||
, Policy54Status(makefile.GetPolicyStatus(cmPolicies::CMP0054))
|
||||
, Policy57Status(makefile.GetPolicyStatus(cmPolicies::CMP0057))
|
||||
, Policy64Status(makefile.GetPolicyStatus(cmPolicies::CMP0064))
|
||||
, Policy139Status(makefile.GetPolicyStatus(cmPolicies::CMP0139))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -775,6 +778,29 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList& newArgs,
|
||||
this->Makefile.IssueMessage(MessageType::AUTHOR_WARNING, e.str());
|
||||
}
|
||||
}
|
||||
|
||||
else if (this->IsKeyword(keyPATH_EQUAL, *args.next)) {
|
||||
|
||||
if (this->Policy139Status != cmPolicies::OLD &&
|
||||
this->Policy139Status != cmPolicies::WARN) {
|
||||
|
||||
cmValue lhs = this->GetVariableOrString(*args.current);
|
||||
cmValue rhs = this->GetVariableOrString(*args.nextnext);
|
||||
const auto result = cmCMakePath{ *lhs } == cmCMakePath{ *rhs };
|
||||
newArgs.ReduceTwoArgs(result, args);
|
||||
}
|
||||
|
||||
else if (this->Policy139Status == cmPolicies::WARN) {
|
||||
std::ostringstream e;
|
||||
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0139)
|
||||
<< "\n"
|
||||
"PATH_EQUAL will be interpreted as an operator "
|
||||
"when the policy is set to NEW. "
|
||||
"Since the policy is not set the OLD behavior will be used.";
|
||||
|
||||
this->Makefile.IssueMessage(MessageType::AUTHOR_WARNING, e.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -79,4 +79,5 @@ private:
|
||||
cmPolicies::PolicyStatus Policy54Status;
|
||||
cmPolicies::PolicyStatus Policy57Status;
|
||||
cmPolicies::PolicyStatus Policy64Status;
|
||||
cmPolicies::PolicyStatus Policy139Status;
|
||||
};
|
||||
|
||||
@@ -417,7 +417,11 @@ class cmMakefile;
|
||||
cmPolicies::WARN) \
|
||||
SELECT(POLICY, CMP0138, \
|
||||
"MSVC compilers use -ZI instead of /Zi for x86 and x64 by default.", \
|
||||
3, 24, 0, cmPolicies::WARN)
|
||||
3, 24, 0, cmPolicies::WARN) \
|
||||
SELECT( \
|
||||
POLICY, CMP0139, \
|
||||
"The if() command supports path comparisons using PATH_EQUAL operator.", \
|
||||
3, 24, 0, cmPolicies::WARN)
|
||||
|
||||
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
|
||||
#define CM_FOR_EACH_POLICY_ID(POLICY) \
|
||||
|
||||
25
Tests/RunCMake/CMP0139/CMP0139-NEW.cmake
Normal file
25
Tests/RunCMake/CMP0139/CMP0139-NEW.cmake
Normal file
@@ -0,0 +1,25 @@
|
||||
cmake_policy(SET CMP0139 NEW)
|
||||
|
||||
|
||||
set(path "a///b/c")
|
||||
if (NOT path PATH_EQUAL "a/b/c")
|
||||
message(SEND_ERROR "if(PATH_EQUAL): '${path}' not equal to 'a/b/c'")
|
||||
endif()
|
||||
set(path2 "a/b/c")
|
||||
if (NOT path PATH_EQUAL path2)
|
||||
message(SEND_ERROR "if(PATH_EQUAL): '${path}' not equal to '${path2}'")
|
||||
endif()
|
||||
|
||||
set (path "a/b/d/../c")
|
||||
if (path PATH_EQUAL "a/b/c")
|
||||
message(SEND_ERROR "if(PATH_EQUAL): '${path}' equal to 'a/b/c'")
|
||||
endif()
|
||||
set(path2 "a/b/c")
|
||||
if ("a/b/d/../c" PATH_EQUAL path2)
|
||||
message(SEND_ERROR "if(PATH_EQUAL): 'a/b/d/../c' equal to '${path2}'")
|
||||
endif()
|
||||
|
||||
cmake_path(NORMAL_PATH path)
|
||||
if (NOT path PATH_EQUAL "a/b/c")
|
||||
message(SEND_ERROR "if(PATH_EQUAL): '${path}' not equal to 'a/b/c'")
|
||||
endif()
|
||||
1
Tests/RunCMake/CMP0139/CMP0139-OLD-result.txt
Normal file
1
Tests/RunCMake/CMP0139/CMP0139-OLD-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
1
|
||||
8
Tests/RunCMake/CMP0139/CMP0139-OLD-stderr.txt
Normal file
8
Tests/RunCMake/CMP0139/CMP0139-OLD-stderr.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
CMake Error at CMP0139-OLD.cmake:[0-9]+ \(if\):
|
||||
if given arguments:
|
||||
|
||||
"/path1" "PATH_EQUAL" "/path2"
|
||||
|
||||
Unknown arguments specified
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:[0-9]+ \(include\)
|
||||
5
Tests/RunCMake/CMP0139/CMP0139-OLD.cmake
Normal file
5
Tests/RunCMake/CMP0139/CMP0139-OLD.cmake
Normal file
@@ -0,0 +1,5 @@
|
||||
cmake_policy(SET CMP0139 OLD)
|
||||
|
||||
if("/path1" PATH_EQUAL "/path2")
|
||||
message("PATH_EQUAL recognized")
|
||||
endif()
|
||||
1
Tests/RunCMake/CMP0139/CMP0139-WARN-result.txt
Normal file
1
Tests/RunCMake/CMP0139/CMP0139-WARN-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
1
|
||||
19
Tests/RunCMake/CMP0139/CMP0139-WARN-stderr.txt
Normal file
19
Tests/RunCMake/CMP0139/CMP0139-WARN-stderr.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
CMake Warning \(dev\) at CMP0139-WARN.cmake:[0-9]+ \(if\):
|
||||
Policy CMP0139 is not set: The if\(\) command supports path comparisons using
|
||||
PATH_EQUAL operator. Run "cmake --help-policy CMP0139" for policy details.
|
||||
Use the cmake_policy command to set the policy and suppress this warning.
|
||||
|
||||
PATH_EQUAL will be interpreted as an operator when the policy is set to
|
||||
NEW. Since the policy is not set the OLD behavior will be used.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:[0-9]+ \(include\)
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
CMake Error at CMP0139-WARN.cmake:[0-9]+ \(if\):
|
||||
if given arguments:
|
||||
|
||||
"/path1" "PATH_EQUAL" "/path2"
|
||||
|
||||
Unknown arguments specified
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:[0-9]+ \(include\)
|
||||
4
Tests/RunCMake/CMP0139/CMP0139-WARN.cmake
Normal file
4
Tests/RunCMake/CMP0139/CMP0139-WARN.cmake
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
if("/path1" PATH_EQUAL "/path2")
|
||||
message("PATH_EQUAL recognized")
|
||||
endif()
|
||||
3
Tests/RunCMake/CMP0139/CMakeLists.txt
Normal file
3
Tests/RunCMake/CMP0139/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
||||
5
Tests/RunCMake/CMP0139/RunCMakeTest.cmake
Normal file
5
Tests/RunCMake/CMP0139/RunCMakeTest.cmake
Normal file
@@ -0,0 +1,5 @@
|
||||
include(RunCMake)
|
||||
|
||||
run_cmake(CMP0139-OLD)
|
||||
run_cmake(CMP0139-WARN)
|
||||
run_cmake(CMP0139-NEW)
|
||||
@@ -150,6 +150,7 @@ endif()
|
||||
|
||||
add_RunCMake_test(CMP0132)
|
||||
add_RunCMake_test(CMP0135)
|
||||
add_RunCMake_test(CMP0139)
|
||||
|
||||
# The test for Policy 65 requires the use of the
|
||||
# CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode
|
||||
|
||||
Reference in New Issue
Block a user