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 Use the current active console's codepage or if that isn't
available then use ANSI. available then use ANSI.
This is the default since CMake 3.15. This was the default in CMake 3.15 through 3.30.
``ANSI`` ``ANSI``
Use the ANSI codepage. Use the ANSI codepage.
@@ -160,6 +160,8 @@ Options:
Use the UTF-8 codepage. Use the UTF-8 codepage.
This is the default. See policy :policy:`CMP0176`.
``UTF8`` ``UTF8``
Use the UTF-8 codepage. Use of this name is discouraged in favor 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>`_ 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:: .. toctree::
:maxdepth: 1 :maxdepth: 1
CMP0176: execute_process() ENCODING is UTF-8 by default. </policy/CMP0176>
CMP0175: add_custom_command() rejects invalid arguments. </policy/CMP0175> 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> 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> 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 "cmList.h"
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmMessageType.h" #include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmProcessOutput.h" #include "cmProcessOutput.h"
#include "cmStringAlgorithms.h" #include "cmStringAlgorithms.h"
#include "cmSystemTools.h" #include "cmSystemTools.h"
@@ -297,7 +298,12 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
}; };
ReadData outputData; ReadData outputData;
ReadData errorData; 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 (arguments.Encoding) {
if (cm::optional<cmProcessOutput::Encoding> maybeEncoding = if (cm::optional<cmProcessOutput::Encoding> maybeEncoding =
cmProcessOutput::FindEncoding(*arguments.Encoding)) { cmProcessOutput::FindEncoding(*arguments.Encoding)) {

View File

@@ -539,6 +539,8 @@ class cmMakefile;
"string after a single-value keyword.", \ "string after a single-value keyword.", \
3, 31, 0, cmPolicies::WARN) \ 3, 31, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0175, "add_custom_command() rejects invalid arguments.", \ 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) 3, 31, 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)

View File

@@ -2,7 +2,12 @@ if(ENCODING)
set(maybe_ENCODING ENCODING ${ENCODING}) set(maybe_ENCODING ENCODING ${ENCODING})
else() else()
set(maybe_ENCODING "") 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() endif()
execute_process( execute_process(
COMMAND ${TEST_ENCODING_EXE} ${ENCODING} ${CMAKE_CURRENT_LIST_DIR}/Encoding${ENCODING}-stderr.txt 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. # Set the console code page.
execute_process(COMMAND cmd /c chcp ${CODEPAGE}) execute_process(COMMAND cmd /c chcp ${CODEPAGE})

View File

@@ -1,9 +1,12 @@
if(CMAKE_HOST_WIN32 AND CODEPAGE) if(CMAKE_HOST_WIN32 AND CODEPAGE)
cmake_policy(GET CMP0176 CMP0176)
# Run cmake in a new Window to isolate its console code page. # Run cmake in a new Window to isolate its console code page.
execute_process(COMMAND cmd /c start /min /wait "" execute_process(COMMAND cmd /c start /min /wait ""
${CMAKE_COMMAND} -DTEST_ENCODING_EXE=${TEST_ENCODING_EXE} ${CMAKE_COMMAND} -DTEST_ENCODING_EXE=${TEST_ENCODING_EXE}
-DENCODING=${ENCODING} -DENCODING=${ENCODING}
-DCODEPAGE=${CODEPAGE} -DCODEPAGE=${CODEPAGE}
-DCMP0176=${CMP0176}
-P ${CMAKE_CURRENT_LIST_DIR}/Encoding-windows.cmake) -P ${CMAKE_CURRENT_LIST_DIR}/Encoding-windows.cmake)
# Load our internal UTF-8 representation of the output. # 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. # No explicit ENCODING option; fall back to default.
set(CODEPAGE 54936) set(CODEPAGE 54936)
include(${CMAKE_CURRENT_LIST_DIR}/Encoding.cmake) 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) run_cmake(EncodingMissing)
if(TEST_ENCODING_EXE) 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(EncodingAUTO -DTEST_ENCODING_EXE=${TEST_ENCODING_EXE})
run_cmake_script(EncodingUTF-8 -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}) run_cmake_script(EncodingUTF8 -DTEST_ENCODING_EXE=${TEST_ENCODING_EXE})