<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:DengXian;
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:DengXian;
panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:DengXian;}
.MsoChpDefault
{mso-style-type:export-only;}
/* Page Definitions */
@page WordSection1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;}
div.WordSection1
{page:WordSection1;}
--></style>
</head>
<body lang="ZH-CN" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">Hi team,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">I discovered a problem while running `bash configure` on Windows platform in Chinese environment. The command fails, complaining CPU mismatch.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">> configure: error: Target CPU mismatch. We are building for x86_64 but CL is for "</span><span style="font-size:12.0pt">版<span lang="EN-US">"; expected "x64".<o:p></o:p></span></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">There is also a warning complaining version mismatch:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">> configure: WARNING: You are using microsoft
</span><span style="font-size:12.0pt">用于<span lang="EN-US"> x64 </span>的<span lang="EN-US"> Microsoft (R) C/C++
</span>优化编译器<span lang="EN-US"> 19.37.32825 </span>版<span lang="EN-US"> which is older than 19.28.0.0. This is not a supported configuration.<o:p></o:p></span></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">The line "</span><span style="font-size:12.0pt">用于<span lang="EN-US"> x64
</span>的<span lang="EN-US"> Microsoft (R) C/C++ </span>优化编译器<span lang="EN-US"> 19.37.32825
</span>版<span lang="EN-US">" is output by `cl.exe`. In English environment, it should be "Microsoft (R) C/C++ Optimizing Compiler Version 19.37.32825 for x64".<o:p></o:p></span></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">Therefore, several questions arise, and I will try to answer them below.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">1. Does JDK welcome localized Visual Studio?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">I read the file `make/autoconf/toolchains.m4` and found the following comment:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">> elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">> # There is no specific version flag, but all output starts with a version string.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">> # First line typically looks something like:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">> # Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">> # but the compiler name may vary depending on locale.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">> COMPILER_VERSION_OUTPUT=`$COMPILER 2>&1 1>/dev/null | $HEAD -n 1 | $TR -d '\r'`<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">Therefore, it can be inferred that JDK knows that there are different localizations of Visual Studio and is ready for them. JDK thinks that maybe there will be different names of "Optimizing Compiler"
or others. However, in some languages, the whole structure of the sentence is completely different, not just the names.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">2. How can the problem be solved?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">One solution is to change the way to parse the output of `cl.exe`. For example, JDK treat the last word separated by a blank as the target CPU, which is "x64" in English environment but "</span><span style="font-size:12.0pt">版<span lang="EN-US">"
in Chinese environment. (`make/autoconf/toolchain.m4`, Lines 983 to 997.) We may use `grep` command to search for "x64" directly, and then the issue can be solved.<o:p></o:p></span></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">However, this solution is not good enough, because it is also based on parsing the output, which is intended to be read by human, not by scripts. (What if "x64" is changed into "64-bit" or "64
</span><span style="font-size:12.0pt">位<span lang="EN-US">" in a future version?)<o:p></o:p></span></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">3. What is the best solution?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">According to MSVC reference, a solid way to get the MSVC version and the target CPU is via predefined macros.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">To get the MSVC version, we can use `_MSC_VER`. When Visual Studio 2019 is used, the macro evaluates between 1920 and 1929. When Visual Studio 2022 is used, the macro evaluates above 1930.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">To get the target CPU, we can use `_M_X64`, `_M_IX86`, `_M_ARM` and `_M_ARM64`. For example, if the target CPU is x64, `_M_X64` will be evaluated to 100, and the other three macros are undefined.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">The reference page is at https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=msvc-170 .<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">To use these macros, we may need to add 4 .c files. For example, if we need to get the MSVC version, let's create a file `get_msvc_version.c`. This file is absolutely simple and it just contains
eight characters:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">_MSC_VER<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">Then we can use cl.exe to prepocess this .c file:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">> $ cl /EP get_msvc_version.c<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">> </span><span style="font-size:12.0pt">用于<span lang="EN-US"> x64
</span>的<span lang="EN-US"> Microsoft (R) C/C++ </span>优化编译器<span lang="EN-US"> 19.37.32825
</span>版<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">> </span><span style="font-size:12.0pt">版权所有<span lang="EN-US">(C) Microsoft Corporation</span>。保留所有权利。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">> <o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">> get_msvc_version.c<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">> <o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">> 1937<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">The last line `1937` contains the MSVC version, a pure number which will not be impacted by localizations. We may use `tail` command to get it.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">We can use similar methods to get the target CPU.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">4. How many changes need to be made?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">- Four new simple .c files (which do not contain any "real" C code). Maybe a new folder to place them.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">- `make/autoconf/toolchain.m4`, Lines 425 to 441 and 983 to 997.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">- No change needed in any API or implementation of Java.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">Guozhang Wu (</span><span style="font-size:12.0pt">吴国璋<span lang="EN-US">)<o:p></o:p></span></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">GitHub: zcxsythenew<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:12.0pt">GitHub anonymous email: 30565051+zcxsythenew@users.noreply.github.com</span></p>
</div>
</body>
</html>