Skip to content

Commit 3bb3065

Browse files
committed
Merge bitcoin/bitcoin#32380: Modernize use of UTF-8 in Windows code
53e4951 Switch to ANSI Windows API in `fsbridge::fopen()` function (Hennadii Stepanov) dbe770d Switch to ANSI Windows API in `Win32ErrorString()` function (Hennadii Stepanov) 06d0be4 Remove no longer necessary `WinCmdLineArgs` class (Hennadii Stepanov) f366408 cmake: Set process code page to UTF-8 on Windows (Hennadii Stepanov) dccbb17 Set minimum supported Windows version to 1903 (May 2019 Update) (Hennadii Stepanov) Pull request description: The main goal is to remove [deprecated](bitcoin/bitcoin#32361) code (removed in C++26). This PR employs Microsoft's modern [approach](https://learn.microsoft.com/en-us/windows/apps/design/globalizing/use-utf8-code-page) to handling UTF-8: > Until recently, Windows has emphasized "Unicode" -W variants over -A APIs. However, recent releases have used the ANSI code page and -A APIs as a means to introduce UTF-8 support to apps. If the ANSI code page is configured for UTF-8, then -A APIs typically operate in UTF-8. This model has the benefit of supporting existing code built with -A APIs without any code changes. TODO: - [x] Handle application manifests properly when building with MSVC. - [x] Bump the minimum supported Windows version to 1903 (May 2019 Update). - [x] Remove all remaining use cases of the deprecated `std:wstring_convert`. - The instance in `subprocess.h` will be addressed in a follow-up PR, as additional tests are likely needed. - The usage in `common/system.cpp` is handled in bitcoin/bitcoin#32566. Resolves partially bitcoin/bitcoin#32361. ACKs for top commit: laanwj: re-ACK 53e4951 hodlinator: re-ACK 53e4951 davidgumberg: untested crACK bitcoin/bitcoin@53e4951 Tree-SHA512: 0dbe9badca8b979ac2b4814fea6e4a7e53c423a1c96cb76ce894253137d3640a87631a5b22b9645e8f0c2a36a107122eb19ed8e92978c17384ffa8b9ab9993b5
2 parents 5a58d49 + 53e4951 commit 3bb3065

File tree

16 files changed

+27
-80
lines changed

16 files changed

+27
-80
lines changed

cmake/windows-app.manifest.in

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2-
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
2+
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
33
<assemblyIdentity
44
type="win32"
55
name="org.bitcoincore.${target}"
66
version="${CLIENT_VERSION_MAJOR}.${CLIENT_VERSION_MINOR}.${CLIENT_VERSION_BUILD}.0"
77
/>
8+
<asmv3:application>
9+
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">
10+
<activeCodePage>UTF-8</activeCodePage>
11+
</asmv3:windowsSettings>
12+
</asmv3:application>
813
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
914
<security>
1015
<requestedPrivileges>

doc/release-notes-empty-template.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ wallet versions of Bitcoin Core are generally supported.
3535
Compatibility
3636
==============
3737

38-
Bitcoin Core is supported and tested on operating systems using the
39-
Linux Kernel 3.17+, macOS 14+, and Windows 10+. Bitcoin
38+
Bitcoin Core is supported and tested on the following operating systems or newer:
39+
Linux Kernel 3.17, macOS 14, and Windows 10 (version 1903). Bitcoin
4040
Core should also work on most other Unix-like systems but is not as
4141
frequently tested on them. It is not recommended to use Bitcoin Core on
4242
unsupported systems.

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ if(BUILD_UTIL_CHAINSTATE)
410410
add_executable(bitcoin-chainstate
411411
bitcoin-chainstate.cpp
412412
)
413+
add_windows_application_manifest(bitcoin-chainstate)
413414
# TODO: The `SKIP_BUILD_RPATH` property setting can be deleted
414415
# in the future after reordering Guix script commands to
415416
# perform binary checks after the installation step.

src/bench/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ add_executable(bench_bitcoin
5656
verify_script.cpp
5757
)
5858

59+
add_windows_application_manifest(bench_bitcoin)
60+
5961
include(TargetDataSources)
6062
target_raw_data_sources(bench_bitcoin NAMESPACE benchmark::data
6163
data/block413567.raw

src/bitcoin-cli.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,10 +1328,6 @@ static int CommandLineRPC(int argc, char *argv[])
13281328

13291329
MAIN_FUNCTION
13301330
{
1331-
#ifdef WIN32
1332-
common::WinCmdLineArgs winArgs;
1333-
std::tie(argc, argv) = winArgs.get();
1334-
#endif
13351331
SetupEnvironment();
13361332
if (!SetupNetworking()) {
13371333
tfm::format(std::cerr, "Error: Initializing networking failed\n");

src/bitcoin-wallet.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,6 @@ static std::optional<int> WalletAppInit(ArgsManager& args, int argc, char* argv[
9494
MAIN_FUNCTION
9595
{
9696
ArgsManager& args = gArgs;
97-
#ifdef WIN32
98-
common::WinCmdLineArgs winArgs;
99-
std::tie(argc, argv) = winArgs.get();
100-
#endif
10197

10298
int exit_status;
10399
std::unique_ptr<interfaces::Init> init = interfaces::MakeWalletInit(argc, argv, exit_status);

src/bitcoin.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <clientversion.h>
88
#include <common/args.h>
9+
#include <common/system.h>
910
#include <util/fs.h>
1011
#include <util/exec.h>
1112
#include <util/strencodings.h>
@@ -61,6 +62,8 @@ static void ExecCommand(const std::vector<const char*>& args, std::string_view a
6162

6263
int main(int argc, char* argv[])
6364
{
65+
SetupEnvironment();
66+
6467
try {
6568
CommandLine cmd{ParseCommandLine(argc, argv)};
6669
if (cmd.show_version) {

src/bitcoind.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -259,11 +259,6 @@ static bool AppInit(NodeContext& node)
259259

260260
MAIN_FUNCTION
261261
{
262-
#ifdef WIN32
263-
common::WinCmdLineArgs winArgs;
264-
std::tie(argc, argv) = winArgs.get();
265-
#endif
266-
267262
NodeContext node;
268263
int exit_status;
269264
std::unique_ptr<interfaces::Init> init = interfaces::MakeNodeInit(node, argc, argv, exit_status);

src/common/args.cpp

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
#include <util/string.h>
2020

2121
#ifdef WIN32
22-
#include <codecvt>
23-
#include <shellapi.h>
2422
#include <shlobj.h>
2523
#endif
2624

@@ -879,30 +877,3 @@ void ArgsManager::LogArgs() const
879877
}
880878
logArgsPrefix("Command-line arg:", "", m_settings.command_line_options);
881879
}
882-
883-
namespace common {
884-
#ifdef WIN32
885-
WinCmdLineArgs::WinCmdLineArgs()
886-
{
887-
wchar_t** wargv = CommandLineToArgvW(GetCommandLineW(), &argc);
888-
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> utf8_cvt;
889-
argv = new char*[argc];
890-
args.resize(argc);
891-
for (int i = 0; i < argc; i++) {
892-
args[i] = utf8_cvt.to_bytes(wargv[i]);
893-
argv[i] = &*args[i].begin();
894-
}
895-
LocalFree(wargv);
896-
}
897-
898-
WinCmdLineArgs::~WinCmdLineArgs()
899-
{
900-
delete[] argv;
901-
}
902-
903-
std::pair<int, char**> WinCmdLineArgs::get()
904-
{
905-
return std::make_pair(argc, argv);
906-
}
907-
#endif
908-
} // namespace common

src/common/args.h

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -480,21 +480,4 @@ std::string HelpMessageGroup(const std::string& message);
480480
*/
481481
std::string HelpMessageOpt(const std::string& option, const std::string& message);
482482

483-
namespace common {
484-
#ifdef WIN32
485-
class WinCmdLineArgs
486-
{
487-
public:
488-
WinCmdLineArgs();
489-
~WinCmdLineArgs();
490-
std::pair<int, char**> get();
491-
492-
private:
493-
int argc;
494-
char** argv;
495-
std::vector<std::string> args;
496-
};
497-
#endif
498-
} // namespace common
499-
500483
#endif // BITCOIN_COMMON_ARGS_H

0 commit comments

Comments
 (0)