1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-23 00:48:55 +08:00

execute_process: Change default ENCODING to UTF-8

Windows is heading toward making UTF-8 the preferred MBCS.  As CMake's
internal encoding, `UTF-8` is effectively equivalent to `NONE`, which
was CMake's behavior prior to 3.15's accidental change to `AUTO`.
Behavior of `ENCODING UTF-8` is independent of CMake's internal
encoding, making it in principle a better default than `NONE`.

Add policy CMP0176 for compatibility and to document the default's
history.

Fixes: #26262
This commit is contained in:
Brad King
2024-09-13 11:49:50 -04:00
parent 9a4533405b
commit e782811cfe
14 changed files with 67 additions and 4 deletions

View File

@@ -147,7 +147,7 @@ Options:
Use the current active console's codepage or if that isn't
available then use ANSI.
This is the default since CMake 3.15.
This was the default in CMake 3.15 through 3.30.
``ANSI``
Use the ANSI codepage.
@@ -160,6 +160,8 @@ Options:
Use the UTF-8 codepage.
This is the default. See policy :policy:`CMP0176`.
``UTF8``
Use the UTF-8 codepage. Use of this name is discouraged in favor
of ``UTF-8`` to match the `UTF-8 RFC <https://www.ietf.org/rfc/rfc3629>`_

View File

@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.31
.. toctree::
:maxdepth: 1
CMP0176: execute_process() ENCODING is UTF-8 by default. </policy/CMP0176>
CMP0175: add_custom_command() rejects invalid arguments. </policy/CMP0175>
CMP0174: cmake_parse_arguments(PARSE_ARGV) defines a variable for an empty string after a single-value keyword. </policy/CMP0174>
CMP0173: The CMakeFindFrameworks module is removed. </policy/CMP0173>

27
Help/policy/CMP0176.rst Normal file
View File

@@ -0,0 +1,27 @@
CMP0176
-------
.. versionadded:: 3.31
:command:`execute_process` ``ENCODING`` is ``UTF-8`` by default.
The ``ENCODING`` option is meaningful only on Windows. It specifies the
character encoding expected in the process's output on stdout and stderr.
In CMake 3.14 and below the default encoding was ``NONE``, which corresponds
to CMake's internal UTF-8 encoding. In CMake 3.15 through CMake 3.30 the
default encoding was accidentally changed to ``AUTO``, but the change went
unnoticed and was not documented.
CMake 3.31 and above prefer the ``ENCODING`` default to be ``UTF-8``.
This policy provides compatibility with projects that may have been
relying on the default being ``AUTO``.
The ``OLD`` behavior of this policy is for :command:`execute_process`
to use ``AUTO`` by default if no ``ENCODING`` is specified. The ``NEW``
behavior for this policy is to use ``UTF-8`` as the default ``ENCODING``.
.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 3.31
.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn
.. include:: STANDARD_ADVICE.txt
.. include:: DEPRECATED.txt

View File

@@ -0,0 +1,6 @@
execute_process-encoding
------------------------
* The :command:`execute_process` command's ``ENCODING`` option,
meaningful on Windows, now defaults to ``UTF-8``.
See policy :policy:`CMP0176`.

View File

@@ -23,6 +23,7 @@
#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmProcessOutput.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -297,7 +298,12 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
};
ReadData outputData;
ReadData errorData;
cmProcessOutput::Encoding encoding = cmProcessOutput::Auto;
cmPolicies::PolicyStatus const cmp0176 =
status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0176);
cmProcessOutput::Encoding encoding =
cmp0176 == cmPolicies::OLD || cmp0176 == cmPolicies::WARN
? cmProcessOutput::Auto
: cmProcessOutput::UTF8;
if (arguments.Encoding) {
if (cm::optional<cmProcessOutput::Encoding> maybeEncoding =
cmProcessOutput::FindEncoding(*arguments.Encoding)) {

View File

@@ -539,6 +539,8 @@ class cmMakefile;
"string after a single-value keyword.", \
3, 31, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0175, "add_custom_command() rejects invalid arguments.", \
3, 31, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0176, "execute_process() ENCODING is UTF-8 by default.", \
3, 31, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)

View File

@@ -2,7 +2,12 @@ if(ENCODING)
set(maybe_ENCODING ENCODING ${ENCODING})
else()
set(maybe_ENCODING "")
set(ENCODING AUTO) # execute_process's default ENCODING
cmake_policy(GET CMP0176 cmp0176)
if(cmp0176 STREQUAL "NEW")
set(ENCODING UTF-8) # execute_process's default ENCODING
else()
set(ENCODING AUTO) # execute_process's default ENCODING
endif()
endif()
execute_process(
COMMAND ${TEST_ENCODING_EXE} ${ENCODING} ${CMAKE_CURRENT_LIST_DIR}/Encoding${ENCODING}-stderr.txt

View File

@@ -1,3 +1,7 @@
if(CMP0176 STREQUAL "NEW")
cmake_policy(SET CMP0176 NEW)
endif()
# Set the console code page.
execute_process(COMMAND cmd /c chcp ${CODEPAGE})

View File

@@ -1,9 +1,12 @@
if(CMAKE_HOST_WIN32 AND CODEPAGE)
cmake_policy(GET CMP0176 CMP0176)
# Run cmake in a new Window to isolate its console code page.
execute_process(COMMAND cmd /c start /min /wait ""
${CMAKE_COMMAND} -DTEST_ENCODING_EXE=${TEST_ENCODING_EXE}
-DENCODING=${ENCODING}
-DCODEPAGE=${CODEPAGE}
-DCMP0176=${CMP0176}
-P ${CMAKE_CURRENT_LIST_DIR}/Encoding-windows.cmake)
# Load our internal UTF-8 representation of the output.

View File

@@ -0,0 +1,2 @@
Chinese Hindi Greek English Russian
注意 यूनिकोड είναι very здорово!

View File

@@ -0,0 +1,3 @@
cmake_policy(SET CMP0176 NEW)
# No explicit ENCODING option; fall back to default.
include(${CMAKE_CURRENT_LIST_DIR}/Encoding.cmake)

View File

@@ -1,3 +1,4 @@
cmake_policy(SET CMP0176 OLD)
# No explicit ENCODING option; fall back to default.
set(CODEPAGE 54936)
include(${CMAKE_CURRENT_LIST_DIR}/Encoding.cmake)

View File

@@ -9,7 +9,8 @@ run_cmake_command(MergeOutputVars ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/Mer
run_cmake(EncodingMissing)
if(TEST_ENCODING_EXE)
run_cmake_script(EncodingDefault -DTEST_ENCODING_EXE=${TEST_ENCODING_EXE})
run_cmake_script(EncodingCMP0176-NEW -DTEST_ENCODING_EXE=${TEST_ENCODING_EXE})
run_cmake_script(EncodingCMP0176-OLD -DTEST_ENCODING_EXE=${TEST_ENCODING_EXE})
run_cmake_script(EncodingAUTO -DTEST_ENCODING_EXE=${TEST_ENCODING_EXE})
run_cmake_script(EncodingUTF-8 -DTEST_ENCODING_EXE=${TEST_ENCODING_EXE})
run_cmake_script(EncodingUTF8 -DTEST_ENCODING_EXE=${TEST_ENCODING_EXE})