https://bugs.gentoo.org/955590
https://github.com/wesnoth/wesnoth/issues/10174
https://github.com/wesnoth/wesnoth/commit/1fa291599cf6fc869799aeaa7d5bdf1f5db7ee76
https://github.com/wesnoth/wesnoth/pull/10175

From 1fa291599cf6fc869799aeaa7d5bdf1f5db7ee76 Mon Sep 17 00:00:00 2001
From: smokespren <smokespren@protonmail.com>
Date: Sat, 3 May 2025 18:00:55 -0400
Subject: [PATCH] Fixed CMake build failure due to dependency on Boost CharConv
 (#10167)

---
 CMakeLists.txt     | 13 ++++++++-----
 src/CMakeLists.txt | 37 ++++---------------------------------
 2 files changed, 12 insertions(+), 38 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7ec8fdf8433f3..661daf5a192c6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -53,6 +53,14 @@ option(ENABLE_TESTS "Build unit tests")
 option(ENABLE_NLS "Enable building of translations" ${ENABLE_GAME})
 
 set(BOOST_VERSION "1.70")
+set(BOOST_REQ_COMPONENTS iostreams program_options regex system thread random coroutine locale filesystem graph)
+
+if(ENABLE_TESTS)
+  list(APPEND BOOST_REQ_COMPONENTS unit_test_framework)
+endif()
+
+find_package(Boost ${BOOST_VERSION} REQUIRED CONFIG COMPONENTS ${BOOST_REQ_COMPONENTS}
+                                           OPTIONAL_COMPONENTS charconv)
 
 if(NOT WIN32)
 	set(Lua_FIND_VERSION_MAJOR 5)
@@ -93,7 +101,6 @@ if(APPLE)
 	find_library(SECURITY_LIBRARY Security REQUIRED)
 endif()
 
-find_package(Boost ${BOOST_VERSION} REQUIRED CONFIG COMPONENTS iostreams program_options regex system thread random coroutine locale filesystem graph)
 find_package(ICU REQUIRED COMPONENTS data i18n uc)
 
 # no, gettext executables are not required when NLS is deactivated
@@ -551,10 +558,6 @@ if(ENABLE_GAME OR ENABLE_TESTS)
 	pkg_check_modules(LIBREADLINE readline)
 endif()
 
-if(ENABLE_TESTS)
-	find_package(Boost ${BOOST_VERSION} REQUIRED CONFIG COMPONENTS unit_test_framework)
-endif()
-
 if(ENABLE_GAME)
 	if(ENABLE_NOTIFICATIONS)
 		pkg_check_modules(LIBDBUS dbus-1)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c3a2c52d7412b..65a9929088275 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -218,14 +218,7 @@ if(ENABLE_GAME)
 		${game-external-libs}
 		OpenSSL::Crypto
 		OpenSSL::SSL
-		Boost::iostreams
-		Boost::program_options
-		Boost::regex
-		Boost::system
-		Boost::random
-		Boost::coroutine
-		Boost::locale
-		Boost::filesystem
+		${Boost_LIBRARIES}
 		Fontconfig::Fontconfig
 		SDL2::SDL2
 		SDL2::SDL2main
@@ -264,15 +257,7 @@ if(ENABLE_TESTS)
 		${game-external-libs}
 		OpenSSL::Crypto
 		OpenSSL::SSL
-		Boost::iostreams
-		Boost::program_options
-		Boost::regex
-		Boost::system
-		Boost::random
-		Boost::coroutine
-		Boost::locale
-		Boost::filesystem
-		Boost::unit_test_framework
+		${Boost_LIBRARIES}
 		Fontconfig::Fontconfig
 		SDL2::SDL2
 		SDL2::SDL2main
@@ -313,14 +298,7 @@ if(ENABLE_SERVER)
 		${MYSQL_LIBS}
 		OpenSSL::Crypto
 		OpenSSL::SSL
-		Boost::iostreams
-		Boost::program_options
-		Boost::regex
-		Boost::system
-		Boost::random
-		Boost::coroutine
-		Boost::locale
-		Boost::filesystem
+		${Boost_LIBRARIES}
 	)
 	if(MSVC)
 		target_link_options(wesnothd PRIVATE /WX)
@@ -354,14 +332,7 @@ if(ENABLE_CAMPAIGN_SERVER)
 		${MYSQL_LIBS}
 		OpenSSL::Crypto
 		OpenSSL::SSL
-		Boost::iostreams
-		Boost::program_options
-		Boost::regex
-		Boost::system
-		Boost::random
-		Boost::coroutine
-		Boost::locale
-		Boost::filesystem
+		${Boost_LIBRARIES}
 	)
 	if(MSVC)
 		target_link_options(campaignd PRIVATE /WX)

From e2117f08e1e08130edfce513808af30e598e61c5 Mon Sep 17 00:00:00 2001
From: Charles Dang <exodia339@gmail.com>
Date: Sat, 3 May 2025 18:08:22 -0400
Subject: [PATCH 1/3] Use boost::process::v2 on 1.81 and later

Except on MacOS, since MacCompileStuff needs to be updated manually...
---
 CMakeLists.txt                                |  2 +-
 SConstruct                                    |  3 ++
 packaging/flatpak/org.wesnoth.Wesnoth.json    |  2 +-
 src/filesystem.cpp                            | 31 +++++++++---
 src/game_launcher.cpp                         | 48 ++++++++++++++++---
 utils/dockerbuilds/CI/Dockerfile-base-steamrt |  2 +-
 6 files changed, 71 insertions(+), 17 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 661daf5a192c6..d4cd4806feb06 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -60,7 +60,7 @@ if(ENABLE_TESTS)
 endif()
 
 find_package(Boost ${BOOST_VERSION} REQUIRED CONFIG COMPONENTS ${BOOST_REQ_COMPONENTS}
-                                           OPTIONAL_COMPONENTS charconv)
+                                           OPTIONAL_COMPONENTS charconv process)
 
 if(NOT WIN32)
 	set(Lua_FIND_VERSION_MAJOR 5)
diff --git a/SConstruct b/SConstruct
index c177f51f02d8c..acca9d2251f74 100755
--- a/SConstruct
+++ b/SConstruct
@@ -397,6 +397,9 @@ if env["prereqs"]:
         conf.CheckBoostLocaleBackends(["icu", "winapi"]) \
             or Warning("Only icu and winapi backends of Boost Locale are supported. Bugs/crashes are very likely with other backends")
 
+    # Allowed to fail. We only need to link against process when using the v2 API
+    conf.CheckBoost("process", require_version = boost_version)
+
     if env['harden']:
         env["have_fortify"] = conf.CheckFortifySource()
 
diff --git a/packaging/flatpak/org.wesnoth.Wesnoth.json b/packaging/flatpak/org.wesnoth.Wesnoth.json
index 95275e2bed997..7aba34c87bbb7 100644
--- a/packaging/flatpak/org.wesnoth.Wesnoth.json
+++ b/packaging/flatpak/org.wesnoth.Wesnoth.json
@@ -54,7 +54,7 @@
             }
          ],
          "build-commands":[
-            "./bootstrap.sh --prefix=/app --with-libraries=filesystem,locale,iostreams,program_options,regex,random,thread,coroutine,context,graph,charconv",
+            "./bootstrap.sh --prefix=/app --with-libraries=filesystem,locale,iostreams,process,program_options,regex,random,thread,coroutine,context,graph,charconv",
             "./b2 -j$FLATPAK_BUILDER_N_JOBS install cxxflags='-fPIE -fstack-protector-strong' define=_FORTIFY_SOURCE=2 link=static variant=release address-model=64 --layout=system"
          ]
       },
diff --git a/src/filesystem.cpp b/src/filesystem.cpp
index d52adc2cc51d3..adfe361ceb613 100644
--- a/src/filesystem.cpp
+++ b/src/filesystem.cpp
@@ -22,6 +22,7 @@
 #include "filesystem.hpp"
 
 #include "config.hpp"
+#include "game_config_view.hpp"
 #include "gettext.hpp"
 #include "log.hpp"
 #include "serialization/base64.hpp"
@@ -31,13 +32,22 @@
 #include "utils/general.hpp"
 
 #include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string/replace.hpp>
 #include <boost/filesystem.hpp>
 #include <boost/filesystem/fstream.hpp>
 #include <boost/format.hpp>
 #include <boost/iostreams/device/file_descriptor.hpp>
 #include <boost/iostreams/stream.hpp>
-#include <boost/process.hpp>
-#include "game_config_view.hpp"
+
+#if !defined(_WIN32) && !defined(__APPLE__)
+
+#if BOOST_VERSION >= 108100
+#include <boost/process/v2/environment.hpp>
+#else
+#include <boost/process/search_path.hpp>
+#endif
+
+#endif
 
 #ifdef _WIN32
 #include <boost/locale.hpp>
@@ -78,7 +88,6 @@ static lg::log_domain log_filesystem("filesystem");
 #define WRN_FS LOG_STREAM(warn, log_filesystem)
 #define ERR_FS LOG_STREAM(err, log_filesystem)
 
-namespace bp = boost::process;
 namespace bfs = boost::filesystem;
 using boost::system::error_code;
 
@@ -1012,15 +1021,23 @@ std::string get_exe_path()
 	// with version
 	std::string version = std::to_string(game_config::wesnoth_version.major_version()) + "." + std::to_string(game_config::wesnoth_version.minor_version());
 	std::string exe = filesystem::get_program_invocation("wesnoth-"+version);
-	bfs::path search = bp::search_path(exe).string();
-	if(!search.string().empty()) {
+#if BOOST_VERSION >= 108600
+	bfs::path search = boost::process::v2::environment::find_executable(exe);
+#else
+	bfs::path search = boost::process::search_path(exe);
+#endif
+	if(!search.empty()) {
 		return search.string();
 	}
 
 	// versionless
 	exe = filesystem::get_program_invocation("wesnoth");
-	search = bp::search_path(exe).string();
-	if(!search.string().empty()) {
+#if BOOST_VERSION >= 108600
+	search = boost::process::v2::environment::find_executable(exe);
+#else
+	search = boost::process::search_path(exe);
+#endif
+	if(!search.empty()) {
 		return search.string();
 	}
 
diff --git a/src/game_launcher.cpp b/src/game_launcher.cpp
index 0943ad15c3664..9f1106b89af71 100644
--- a/src/game_launcher.cpp
+++ b/src/game_launcher.cpp
@@ -50,11 +50,38 @@
 #include "wesnothd_connection_error.hpp"
 #include "wml_exception.hpp" // for wml_exception
 
-#include <algorithm> // for copy, max, min, stable_sort
+#ifdef __APPLE__
+
+//
+// HACK: MacCompileStuff is currently on 1.86, so it could use the v2 API,
+// but we need to update the libs manually to link against boost::process.
+//
+// -- vultraz, 2025-05-12
+//
+#if BOOST_VERSION > 108600
+#error MacCompileStuff has been updated. Remove this block and the accompanying __APPLE__ checks below.
+#endif
+#include <boost/process/v1/child.hpp>
+
+#elif BOOST_VERSION >= 108100
+
+// boost::asio (via boost::process) complains about winsock.h otherwise
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <boost/process/v2/process.hpp>
+
+#else
+
+// process::v1 only. The v1 folders do not exist until 1.86
 #ifdef _WIN32
 #include <boost/process/windows.hpp>
 #endif
-#include <boost/process.hpp>
+#include <boost/process/child.hpp>
+
+#endif
+
+#include <algorithm> // for copy, max, min, stable_sort
 #include <cstdlib>   // for system
 #include <new>
 #include <thread>
@@ -85,8 +112,6 @@ static lg::log_domain log_network("network");
 static lg::log_domain log_enginerefac("enginerefac");
 #define LOG_RG LOG_STREAM(info, log_enginerefac)
 
-namespace bp = boost::process;
-
 game_launcher::game_launcher(const commandline_options& cmdline_opts)
 	: cmdline_opts_(cmdline_opts)
 	, font_manager_()
@@ -783,10 +808,15 @@ void game_launcher::start_wesnothd()
 	LOG_GENERAL << "Starting wesnothd";
 	try
 	{
+#if !defined(__APPLE__) && BOOST_VERSION >= 108100
+		boost::asio::io_context io_context;
+		auto c = boost::process::v2::process{io_context, wesnothd_program, { "-c", config }};
+#else
 #ifndef _WIN32
-		bp::child c(wesnothd_program, "-c", config);
+		boost::process::child c(wesnothd_program, "-c", config);
 #else
-		bp::child c(wesnothd_program, "-c", config, bp::windows::create_no_window);
+		boost::process::child c(wesnothd_program, "-c", config, boost::process::windows::create_no_window);
+#endif
 #endif
 		c.detach();
 		// Give server a moment to start up
@@ -794,7 +824,11 @@ void game_launcher::start_wesnothd()
 		std::this_thread::sleep_for(50ms);
 		return;
 	}
-	catch(const bp::process_error& e)
+#if defined(__APPLE__) || BOOST_VERSION < 108100
+	catch(const boost::process::process_error& e)
+#else
+	catch(const std::exception& e)
+#endif
 	{
 		prefs::get().set_mp_server_program_name("");
 
diff --git a/utils/dockerbuilds/CI/Dockerfile-base-steamrt b/utils/dockerbuilds/CI/Dockerfile-base-steamrt
index b872942a5790b..cc7ca1d66ec30 100644
--- a/utils/dockerbuilds/CI/Dockerfile-base-steamrt
+++ b/utils/dockerbuilds/CI/Dockerfile-base-steamrt
@@ -10,7 +10,7 @@ RUN apt-get install -y scons meson libreadline-dev expect-dev
 
 RUN wget --max-redirect 3 https://archives.boost.io/release/${BOOST_VERSION}/source/boost_${BOOST_VERSION_}.tar.gz
 RUN mkdir -p /src/boost && tar zxf boost_${BOOST_VERSION_}.tar.gz -C /src/boost --strip-components=1
-RUN cd /src/boost && ./bootstrap.sh --with-libraries=charconv,iostreams,regex,system,filesystem,program_options,random,locale,context,coroutine,graph && ./b2 toolset=gcc-10 --layout=system link=static variant=release cxxflags='-fPIE -fstack-protector-strong' define=_FORTIFY_SOURCE=2 install
+RUN cd /src/boost && ./bootstrap.sh --with-libraries=charconv,iostreams,regex,system,filesystem,process,program_options,random,locale,context,coroutine,graph && ./b2 toolset=gcc-10 --layout=system link=static variant=release cxxflags='-fPIE -fstack-protector-strong' define=_FORTIFY_SOURCE=2 install
 
 RUN wget --max-redirect 3 https://download.gnome.org/sources/pango/${PANGO_VERSION}/pango-${PANGO_VERSION_FULL}.tar.xz
 RUN mkdir -p /src/pango && tar xf pango-${PANGO_VERSION_FULL}.tar.xz -C /src/pango --strip-components=1

From 5e25513e6531b0f078800c24eee13fe1c8c2cb0d Mon Sep 17 00:00:00 2001
From: Charles Dang <exodia339@gmail.com>
Date: Mon, 12 May 2025 13:13:50 -0400
Subject: [PATCH 2/3] fixup

---
 src/filesystem.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/filesystem.cpp b/src/filesystem.cpp
index adfe361ceb613..759d1395030ed 100644
--- a/src/filesystem.cpp
+++ b/src/filesystem.cpp
@@ -1021,7 +1021,7 @@ std::string get_exe_path()
 	// with version
 	std::string version = std::to_string(game_config::wesnoth_version.major_version()) + "." + std::to_string(game_config::wesnoth_version.minor_version());
 	std::string exe = filesystem::get_program_invocation("wesnoth-"+version);
-#if BOOST_VERSION >= 108600
+#if BOOST_VERSION >= 108100
 	bfs::path search = boost::process::v2::environment::find_executable(exe);
 #else
 	bfs::path search = boost::process::search_path(exe);
@@ -1032,7 +1032,7 @@ std::string get_exe_path()
 
 	// versionless
 	exe = filesystem::get_program_invocation("wesnoth");
-#if BOOST_VERSION >= 108600
+#if BOOST_VERSION >= 108100
 	search = boost::process::v2::environment::find_executable(exe);
 #else
 	search = boost::process::search_path(exe);

From 8b59674eb64848db47beebd404e579be83c2ee1d Mon Sep 17 00:00:00 2001
From: Charles Dang <exodia339@gmail.com>
Date: Mon, 12 May 2025 13:37:53 -0400
Subject: [PATCH 3/3] let's try 86 again

---
 src/filesystem.cpp    | 6 +++---
 src/game_launcher.cpp | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/filesystem.cpp b/src/filesystem.cpp
index 759d1395030ed..5eed05df8d586 100644
--- a/src/filesystem.cpp
+++ b/src/filesystem.cpp
@@ -41,7 +41,7 @@
 
 #if !defined(_WIN32) && !defined(__APPLE__)
 
-#if BOOST_VERSION >= 108100
+#if BOOST_VERSION >= 108600
 #include <boost/process/v2/environment.hpp>
 #else
 #include <boost/process/search_path.hpp>
@@ -1021,7 +1021,7 @@ std::string get_exe_path()
 	// with version
 	std::string version = std::to_string(game_config::wesnoth_version.major_version()) + "." + std::to_string(game_config::wesnoth_version.minor_version());
 	std::string exe = filesystem::get_program_invocation("wesnoth-"+version);
-#if BOOST_VERSION >= 108100
+#if BOOST_VERSION >= 108600
 	bfs::path search = boost::process::v2::environment::find_executable(exe);
 #else
 	bfs::path search = boost::process::search_path(exe);
@@ -1032,7 +1032,7 @@ std::string get_exe_path()
 
 	// versionless
 	exe = filesystem::get_program_invocation("wesnoth");
-#if BOOST_VERSION >= 108100
+#if BOOST_VERSION >= 108600
 	search = boost::process::v2::environment::find_executable(exe);
 #else
 	search = boost::process::search_path(exe);
diff --git a/src/game_launcher.cpp b/src/game_launcher.cpp
index 9f1106b89af71..8a32fac619023 100644
--- a/src/game_launcher.cpp
+++ b/src/game_launcher.cpp
@@ -63,7 +63,7 @@
 #endif
 #include <boost/process/v1/child.hpp>
 
-#elif BOOST_VERSION >= 108100
+#elif BOOST_VERSION >= 108600
 
 // boost::asio (via boost::process) complains about winsock.h otherwise
 #ifdef _WIN32
@@ -808,7 +808,7 @@ void game_launcher::start_wesnothd()
 	LOG_GENERAL << "Starting wesnothd";
 	try
 	{
-#if !defined(__APPLE__) && BOOST_VERSION >= 108100
+#if !defined(__APPLE__) && BOOST_VERSION >= 108600
 		boost::asio::io_context io_context;
 		auto c = boost::process::v2::process{io_context, wesnothd_program, { "-c", config }};
 #else
@@ -824,7 +824,7 @@ void game_launcher::start_wesnothd()
 		std::this_thread::sleep_for(50ms);
 		return;
 	}
-#if defined(__APPLE__) || BOOST_VERSION < 108100
+#if defined(__APPLE__) || BOOST_VERSION < 108600
 	catch(const boost::process::process_error& e)
 #else
 	catch(const std::exception& e)

