From 1b24e19b92c9bbff14133c9a78aac34f680460b5 Mon Sep 17 00:00:00 2001 From: lumaparallax <257510328+lumaparallax@users.noreply.github.com> Date: Sat, 25 Apr 2026 20:31:22 +0900 Subject: [PATCH 1/7] addpkg(x11/qrcodegen): C++ port of QR Code generator --- tur/qrcodegen/build.sh | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 tur/qrcodegen/build.sh diff --git a/tur/qrcodegen/build.sh b/tur/qrcodegen/build.sh new file mode 100644 index 0000000000..953b93f261 --- /dev/null +++ b/tur/qrcodegen/build.sh @@ -0,0 +1,25 @@ +TERMUX_PKG_HOMEPAGE=https://github.com/nayuki/QR-Code-generator +TERMUX_PKG_DESCRIPTION="High-quality C and C++ QR Code generator library" +TERMUX_PKG_LICENSE="MIT" +TERMUX_PKG_MAINTAINER="@termux-user-repository" +TERMUX_PKG_VERSION=1.8.0 +TERMUX_PKG_SRCURL=( + "https://github.com/EasyCoding/qrcodegen-cmake/archive/refs/tags/v${TERMUX_PKG_VERSION}-cmake4.tar.gz" + "https://github.com/nayuki/QR-Code-generator/archive/refs/tags/v${TERMUX_PKG_VERSION}.tar.gz" +) +TERMUX_PKG_SHA256=( + b576111a224aa34811c81a03d8c30a13d7a048f085276b0ae87509cbf52b5ace + 2ec0a4d33d6f521c942eeaf473d42d5fe139abcfa57d2beffe10c5cf7d34ae60 +) +TERMUX_PKG_AUTO_UPDATE=true +TERMUX_PKG_EXTRA_CONFIGURE_ARGS=" +-DQRCODEGEN_BUILD_EXAMPLES=OFF +-DQRCODEGEN_BUILD_TESTS=OFF +-DBUILD_SHARED_LIBS=ON +" + +termux_step_post_get_source() { + # Pull the source folders out of the secondary tarball's directory + mv "QR-Code-generator-${TERMUX_PKG_VERSION}/c" ./ + mv "QR-Code-generator-${TERMUX_PKG_VERSION}/cpp" ./ +} From a9676e709004cd524e06ab57179fae4e8f380744 Mon Sep 17 00:00:00 2001 From: lumaparallax <257510328+lumaparallax@users.noreply.github.com> Date: Sat, 25 Apr 2026 20:30:32 +0900 Subject: [PATCH 2/7] addpkg(x11/websocketpp): C++ WebSocket client/server library --- tur/websocketpp/0001-boost-1_87-compat.patch | 2534 ++++++++++++++++++ tur/websocketpp/build.sh | 14 + 2 files changed, 2548 insertions(+) create mode 100644 tur/websocketpp/0001-boost-1_87-compat.patch create mode 100644 tur/websocketpp/build.sh diff --git a/tur/websocketpp/0001-boost-1_87-compat.patch b/tur/websocketpp/0001-boost-1_87-compat.patch new file mode 100644 index 0000000000..71c51cdb86 --- /dev/null +++ b/tur/websocketpp/0001-boost-1_87-compat.patch @@ -0,0 +1,2534 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Amini Allight +Date: Wed, 12 Feb 2025 03:53:35 +0000 +Subject: [PATCH 1/7] fixed incompatibility with Boost 1.87 due to use of + previously-deprecated now-removed functionality + +(cherry picked from commit 146925c2404655dbb61b9a18e57692bfc18eb6c6) + + Conflicts: + examples/broadcast_server/broadcast_server.cpp + websocketpp/transport/asio/endpoint.hpp + websocketpp/transport/asio/security/none.hpp + websocketpp/transport/asio/security/tls.hpp +--- + SConstruct | 4 +- + docs/faq.dox | 12 +- + .../broadcast_server/broadcast_server.cpp | 2 +- + examples/debug_client/debug_client.cpp | 2 +- + examples/debug_server/debug_server.cpp | 2 +- + examples/echo_client/echo_client.cpp | 2 +- + examples/echo_server/echo_server.cpp | 2 +- + .../echo_server_both/echo_server_both.cpp | 8 +- + examples/echo_server_tls/echo_server_tls.cpp | 2 +- + .../CMakeLists.txt | 2 +- + .../SConscript | 4 +- + .../external_io_context.cpp} | 14 +- + .../tcp_echo_server.hpp | 12 +- + examples/print_client/print_client.cpp | 2 +- + .../print_client_tls/print_client_tls.cpp | 2 +- + examples/scratch_server/scratch_server.cpp | 2 +- + examples/sip_client/sip_client.cpp | 2 +- + .../telemetry_client/telemetry_client.cpp | 4 +- + .../telemetry_server/telemetry_server.cpp | 2 +- + examples/testee_client/testee_client.cpp | 2 +- + examples/testee_server/testee_server.cpp | 2 +- + test/endpoint/endpoint.cpp | 6 +- + test/transport/asio/timers.cpp | 8 +- + test/transport/integration.cpp | 27 ++- + tutorials/utility_server/step1.cpp | 2 +- + tutorials/utility_server/step2.cpp | 2 +- + tutorials/utility_server/utility_server.md | 8 +- + websocketpp/roles/server_endpoint.hpp | 4 +- + websocketpp/transport/asio/base.hpp | 2 +- + websocketpp/transport/asio/connection.hpp | 44 ++--- + websocketpp/transport/asio/endpoint.hpp | 182 +++++++++--------- + websocketpp/transport/asio/security/none.hpp | 16 +- + websocketpp/transport/asio/security/tls.hpp | 20 +- + websocketpp/transport/debug/endpoint.hpp | 2 +- + websocketpp/transport/iostream/endpoint.hpp | 2 +- + websocketpp/transport/stub/endpoint.hpp | 2 +- + 36 files changed, 205 insertions(+), 208 deletions(-) + rename examples/{external_io_service => external_io_context}/CMakeLists.txt (87%) + rename examples/{external_io_service => external_io_context}/SConscript (72%) + rename examples/{external_io_service/external_io_service.cpp => external_io_context/external_io_context.cpp} (92%) + rename examples/{external_io_service => external_io_context}/tcp_echo_server.hpp (92%) + +diff --git a/SConstruct b/SConstruct +index ae3df10..08a75a3 100644 +--- a/SConstruct ++++ b/SConstruct +@@ -271,8 +271,8 @@ subprotocol_server = SConscript('#/examples/subprotocol_server/SConscript',varia + # telemetry_server + telemetry_server = SConscript('#/examples/telemetry_server/SConscript',variant_dir = builddir + 'telemetry_server',duplicate = 0) + +-# external_io_service +-external_io_service = SConscript('#/examples/external_io_service/SConscript',variant_dir = builddir + 'external_io_service',duplicate = 0) ++# external_io_context ++external_io_context = SConscript('#/examples/external_io_context/SConscript',variant_dir = builddir + 'external_io_context',duplicate = 0) + + if not env['PLATFORM'].startswith('win'): + # iostream_server +diff --git a/docs/faq.dox b/docs/faq.dox +index 9f417ec..c89e85b 100644 +--- a/docs/faq.dox ++++ b/docs/faq.dox +@@ -29,19 +29,19 @@ Note: some browsers will allow the connection to continue if they requested a su + + ### How do I cleanly exit an Asio transport based program + +-The Asio transport based clients and servers use the Asio library's underlying `io_service` to handle asyncronous networking operations. The standard behavior of the io_service is to run until there are no async operations left and then return. WebSocket++, when using the Asio transport, behaves like a standard Asio application. If you want your WebSocket++/Asio based program to stop network operations and cleanly close all sockets you will want to do the following: ++The Asio transport based clients and servers use the Asio library's underlying `io_context` to handle asyncronous networking operations. The standard behavior of the io_context is to run until there are no async operations left and then return. WebSocket++, when using the Asio transport, behaves like a standard Asio application. If you want your WebSocket++/Asio based program to stop network operations and cleanly close all sockets you will want to do the following: + + - For servers, call `websocketpp::transport::asio::endpoint::stop_listening` to initiate the closing of the server listening socket. + - For clients, if you have engaged perpetual mode with `websocketpp::transport::asio::endpoint::start_perpetual`, disable it with `websocketpp::transport::asio::endpoint::stop_perpetual`. + - For both, run `websocketpp::endpoint::close` or `websocketpp::connection::close` on all currently outstanding connections. This will initiate the WebSocket closing handshake for these connections +-- Wait. Asio is asyncronous. When the calls to the above methods (stop_listening, close, etc) complete the server *will still be listening*, the connections *will still be active* until the io_service gets around to asyncronously processing the socket and WebSocket protocol closing handshakes. The `io_service::run` method will exit cleanly and automatically when all operations are complete. ++- Wait. Asio is asyncronous. When the calls to the above methods (stop_listening, close, etc) complete the server *will still be listening*, the connections *will still be active* until the io_context gets around to asyncronously processing the socket and WebSocket protocol closing handshakes. The `io_context::run` method will exit cleanly and automatically when all operations are complete. + +-__WARNING__: Asio's `io_service` has a method called `stop`. WebSocket++ wraps this method as `websocketpp::transport::asio::endpoint::stop`. While this operation has a benign sounding name, it is a powerful and destructive operation that should only be used in special cases. If you are using `io_service::stop` or `endpoint::stop` without a very good reason your program is likely broken and may exhibit erratic behavior. Specifically, `io_service::stop` stops the processing of events entirely. This does not give current operations (such as socket closing handshakes) the opportunity to finish. It will leave your sockets in a dangling state that may invoke operating system level timeouts or other errors. ++__WARNING__: Asio's `io_context` has a method called `stop`. WebSocket++ wraps this method as `websocketpp::transport::asio::endpoint::stop`. While this operation has a benign sounding name, it is a powerful and destructive operation that should only be used in special cases. If you are using `io_context::stop` or `endpoint::stop` without a very good reason your program is likely broken and may exhibit erratic behavior. Specifically, `io_context::stop` stops the processing of events entirely. This does not give current operations (such as socket closing handshakes) the opportunity to finish. It will leave your sockets in a dangling state that may invoke operating system level timeouts or other errors. + + __Special cases__: +-- If your client uses the `start_perpetual` method it will prevent the io_service from exiting even if it has nothing to do. This is useful if you want a client endpoint to idle in the background to allow new connections to be formed on demand rather than generating a new endpoint for each. +-- If you are using an external io_service and/or are placing non-WebSocket++ operations on the `io_service` those operations may keep the `io_service` open even after all WebSocket++ operations have completed. +-- If you are using `poll`/`poll_one`/`run_one` or otherwise manually driving the `io_service` event loop you may need to adjust usage to make sure you are correctly recognizing the "done with work" and "not done but idling / `io_service::work`" cases. ++- If your client uses the `start_perpetual` method it will prevent the io_context from exiting even if it has nothing to do. This is useful if you want a client endpoint to idle in the background to allow new connections to be formed on demand rather than generating a new endpoint for each. ++- If you are using an external io_context and/or are placing non-WebSocket++ operations on the `io_context` those operations may keep the `io_context` open even after all WebSocket++ operations have completed. ++- If you are using `poll`/`poll_one`/`run_one` or otherwise manually driving the `io_context` event loop you may need to adjust usage to make sure you are correctly recognizing the "done with work" and "not done but idling / `io_context::work`" cases. + + ### Is there a way to check the validity of a `connection_hdl`? + +diff --git a/examples/broadcast_server/broadcast_server.cpp b/examples/broadcast_server/broadcast_server.cpp +index b02e7cd..106eba7 100644 +--- a/examples/broadcast_server/broadcast_server.cpp ++++ b/examples/broadcast_server/broadcast_server.cpp +@@ -63,7 +63,7 @@ public: + // Start the server accept loop + m_server.start_accept(); + +- // Start the ASIO io_service run loop ++ // Start the ASIO io_context run loop + try { + m_server.run(); + } catch (const std::exception & e) { +diff --git a/examples/debug_client/debug_client.cpp b/examples/debug_client/debug_client.cpp +index d3e9153..d3e21ab 100644 +--- a/examples/debug_client/debug_client.cpp ++++ b/examples/debug_client/debug_client.cpp +@@ -83,7 +83,7 @@ public: + + m_endpoint.connect(con); + +- // Start the ASIO io_service run loop ++ // Start the ASIO io_context run loop + m_start = std::chrono::high_resolution_clock::now(); + m_endpoint.run(); + } +diff --git a/examples/debug_server/debug_server.cpp b/examples/debug_server/debug_server.cpp +index 8d1ff0e..3748800 100644 +--- a/examples/debug_server/debug_server.cpp ++++ b/examples/debug_server/debug_server.cpp +@@ -162,7 +162,7 @@ int main() { + // Start the server accept loop + echo_server.start_accept(); + +- // Start the ASIO io_service run loop ++ // Start the ASIO io_context run loop + echo_server.run(); + } catch (websocketpp::exception const & e) { + std::cout << e.what() << std::endl; +diff --git a/examples/echo_client/echo_client.cpp b/examples/echo_client/echo_client.cpp +index 59af661..88171d9 100644 +--- a/examples/echo_client/echo_client.cpp ++++ b/examples/echo_client/echo_client.cpp +@@ -87,7 +87,7 @@ int main(int argc, char* argv[]) { + // exchanged until the event loop starts running in the next line. + c.connect(con); + +- // Start the ASIO io_service run loop ++ // Start the ASIO io_context run loop + // this will cause a single connection to be made to the server. c.run() + // will exit when this connection is closed. + c.run(); +diff --git a/examples/echo_server/echo_server.cpp b/examples/echo_server/echo_server.cpp +index d234009..639c79f 100644 +--- a/examples/echo_server/echo_server.cpp ++++ b/examples/echo_server/echo_server.cpp +@@ -55,7 +55,7 @@ int main() { + // Start the server accept loop + echo_server.start_accept(); + +- // Start the ASIO io_service run loop ++ // Start the ASIO io_context run loop + echo_server.run(); + } catch (websocketpp::exception const & e) { + std::cout << e.what() << std::endl; +diff --git a/examples/echo_server_both/echo_server_both.cpp b/examples/echo_server_both/echo_server_both.cpp +index 2c2c4ea..869c006 100644 +--- a/examples/echo_server_both/echo_server_both.cpp ++++ b/examples/echo_server_both/echo_server_both.cpp +@@ -58,13 +58,13 @@ context_ptr on_tls_init(websocketpp::connection_hdl hdl) { + } + + int main() { +- // set up an external io_service to run both endpoints on. This is not ++ // set up an external io_context to run both endpoints on. This is not + // strictly necessary, but simplifies thread management a bit. +- boost::asio::io_service ios; ++ boost::asio::io_context ios; + + // set up plain endpoint + server_plain endpoint_plain; +- // initialize asio with our external io_service rather than an internal one ++ // initialize asio with our external io_context rather than an internal one + endpoint_plain.init_asio(&ios); + endpoint_plain.set_message_handler( + bind(&on_message,&endpoint_plain,::_1,::_2)); +@@ -82,6 +82,6 @@ int main() { + endpoint_tls.listen(443); + endpoint_tls.start_accept(); + +- // Start the ASIO io_service run loop running both endpoints ++ // Start the ASIO io_context run loop running both endpoints + ios.run(); + } +diff --git a/examples/echo_server_tls/echo_server_tls.cpp b/examples/echo_server_tls/echo_server_tls.cpp +index 3d704f5..2f75a7d 100644 +--- a/examples/echo_server_tls/echo_server_tls.cpp ++++ b/examples/echo_server_tls/echo_server_tls.cpp +@@ -148,7 +148,7 @@ int main() { + // Start the server accept loop + echo_server.start_accept(); + +- // Start the ASIO io_service run loop ++ // Start the ASIO io_context run loop + echo_server.run(); + + } +diff --git a/examples/external_io_service/CMakeLists.txt b/examples/external_io_context/CMakeLists.txt +similarity index 87% +rename from examples/external_io_service/CMakeLists.txt +rename to examples/external_io_context/CMakeLists.txt +index 5223da1..a0e89ec 100644 +--- a/examples/external_io_service/CMakeLists.txt ++++ b/examples/external_io_context/CMakeLists.txt +@@ -2,7 +2,7 @@ + file (GLOB SOURCE_FILES *.cpp) + file (GLOB HEADER_FILES *.hpp) + +-init_target (external_io_service) ++init_target (external_io_context) + + build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES}) + +diff --git a/examples/external_io_service/SConscript b/examples/external_io_context/SConscript +similarity index 72% +rename from examples/external_io_service/SConscript +rename to examples/external_io_context/SConscript +index beb7c1c..57305aa 100644 +--- a/examples/external_io_service/SConscript ++++ b/examples/external_io_context/SConscript +@@ -15,9 +15,9 @@ prgs = [] + # if a C++11 environment is available build using that, otherwise use boost + if env_cpp11.has_key('WSPP_CPP11_ENABLED'): + ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] +- prgs += env_cpp11.Program('external_io_service', ["external_io_service.cpp"], LIBS = ALL_LIBS) ++ prgs += env_cpp11.Program('external_io_context', ["external_io_context.cpp"], LIBS = ALL_LIBS) + else: + ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs] +- prgs += env.Program('external_io_service', ["external_io_service.cpp"], LIBS = ALL_LIBS) ++ prgs += env.Program('external_io_context', ["external_io_context.cpp"], LIBS = ALL_LIBS) + + Return('prgs') +diff --git a/examples/external_io_service/external_io_service.cpp b/examples/external_io_context/external_io_context.cpp +similarity index 92% +rename from examples/external_io_service/external_io_service.cpp +rename to examples/external_io_context/external_io_context.cpp +index 7372d59..c5ba0a4 100644 +--- a/examples/external_io_service/external_io_service.cpp ++++ b/examples/external_io_context/external_io_context.cpp +@@ -59,10 +59,10 @@ void on_message(ws_echo_server* s, websocketpp::connection_hdl hdl, ws_echo_serv + } + + int main() { +- asio::io_service service; ++ asio::io_context context; + + // Add a TCP echo server on port 9003 +- tcp_echo_server custom_http_server(service, 9003); ++ tcp_echo_server custom_http_server(context, 9003); + + // Add a WebSocket echo server on port 9002 + ws_echo_server ws_server; +@@ -70,8 +70,8 @@ int main() { + ws_server.clear_access_channels(websocketpp::log::alevel::frame_payload); + + // The only difference in this code between an internal and external +- // io_service is the different constructor to init_asio +- ws_server.init_asio(&service); ++ // io_context is the different constructor to init_asio ++ ws_server.init_asio(&context); + + // Register our message handler + ws_server.set_message_handler(bind(&on_message,&ws_server,::_1,::_2)); +@@ -80,6 +80,6 @@ int main() { + + // TODO: add a timer? + +- // Start the Asio io_service run loop for all +- service.run(); +-} +\ No newline at end of file ++ // Start the Asio io_context run loop for all ++ context.run(); ++} +diff --git a/examples/external_io_service/tcp_echo_server.hpp b/examples/external_io_context/tcp_echo_server.hpp +similarity index 92% +rename from examples/external_io_service/tcp_echo_server.hpp +rename to examples/external_io_context/tcp_echo_server.hpp +index ef4ce18..2e14703 100644 +--- a/examples/external_io_service/tcp_echo_server.hpp ++++ b/examples/external_io_context/tcp_echo_server.hpp +@@ -44,7 +44,7 @@ namespace asio = websocketpp::lib::asio; + struct tcp_echo_session : websocketpp::lib::enable_shared_from_this { + typedef websocketpp::lib::shared_ptr ptr; + +- tcp_echo_session(asio::io_service & service) : m_socket(service) {} ++ tcp_echo_session(asio::io_context & context) : m_socket(context) {} + + void start() { + m_socket.async_read_some(asio::buffer(m_buffer, sizeof(m_buffer)), +@@ -72,15 +72,15 @@ struct tcp_echo_session : websocketpp::lib::enable_shared_from_thisstart_accept(); + } + + void start_accept() { +- tcp_echo_session::ptr new_session(new tcp_echo_session(m_service)); ++ tcp_echo_session::ptr new_session(new tcp_echo_session(m_context)); + m_acceptor.async_accept(new_session->m_socket, + bind(&tcp_echo_server::handle_accept, this, new_session, _1)); + } +@@ -92,6 +92,6 @@ struct tcp_echo_server { + start_accept(); + } + +- asio::io_service & m_service; ++ asio::io_context & m_context; + asio::ip::tcp::acceptor m_acceptor; + }; +diff --git a/examples/print_client/print_client.cpp b/examples/print_client/print_client.cpp +index 7ba6e5f..20a2bd3 100644 +--- a/examples/print_client/print_client.cpp ++++ b/examples/print_client/print_client.cpp +@@ -68,7 +68,7 @@ int main(int argc, char* argv[]) { + // exchanged until the event loop starts running in the next line. + c.connect(con); + +- // Start the ASIO io_service run loop ++ // Start the ASIO io_context run loop + // this will cause a single connection to be made to the server. c.run() + // will exit when this connection is closed. + c.run(); +diff --git a/examples/print_client_tls/print_client_tls.cpp b/examples/print_client_tls/print_client_tls.cpp +index 469d9c6..43164ea 100644 +--- a/examples/print_client_tls/print_client_tls.cpp ++++ b/examples/print_client_tls/print_client_tls.cpp +@@ -239,7 +239,7 @@ int main(int argc, char* argv[]) { + + c.get_alog().write(websocketpp::log::alevel::app, "Connecting to " + uri); + +- // Start the ASIO io_service run loop ++ // Start the ASIO io_context run loop + // this will cause a single connection to be made to the server. c.run() + // will exit when this connection is closed. + c.run(); +diff --git a/examples/scratch_server/scratch_server.cpp b/examples/scratch_server/scratch_server.cpp +index 901ae8e..dab20b9 100644 +--- a/examples/scratch_server/scratch_server.cpp ++++ b/examples/scratch_server/scratch_server.cpp +@@ -94,7 +94,7 @@ int main(int argc, char * argv[]) { + // Start the server accept loop + echo_server.start_accept(); + +- // Start the ASIO io_service run loop ++ // Start the ASIO io_context run loop + echo_server.run(); + } catch (websocketpp::exception const & e) { + std::cout << e.what() << std::endl; +diff --git a/examples/sip_client/sip_client.cpp b/examples/sip_client/sip_client.cpp +index 66fa857..c9f33e7 100644 +--- a/examples/sip_client/sip_client.cpp ++++ b/examples/sip_client/sip_client.cpp +@@ -69,7 +69,7 @@ int main(int argc, char* argv[]) { + + sip_client.connect(con); + +- // Start the ASIO io_service run loop ++ // Start the ASIO io_context run loop + sip_client.run(); + + while(!received) { +diff --git a/examples/telemetry_client/telemetry_client.cpp b/examples/telemetry_client/telemetry_client.cpp +index f0f7fae..12390b8 100644 +--- a/examples/telemetry_client/telemetry_client.cpp ++++ b/examples/telemetry_client/telemetry_client.cpp +@@ -62,10 +62,10 @@ public: + m_hdl = con->get_handle(); + + // Queue the connection. No DNS queries or network connections will be +- // made until the io_service event loop is run. ++ // made until the io_context event loop is run. + m_client.connect(con); + +- // Create a thread to run the ASIO io_service event loop ++ // Create a thread to run the ASIO io_context event loop + websocketpp::lib::thread asio_thread(&client::run, &m_client); + + // Create a thread to run the telemetry loop +diff --git a/examples/telemetry_server/telemetry_server.cpp b/examples/telemetry_server/telemetry_server.cpp +index 3f8e604..2286c50 100644 +--- a/examples/telemetry_server/telemetry_server.cpp ++++ b/examples/telemetry_server/telemetry_server.cpp +@@ -66,7 +66,7 @@ public: + // Set the initial timer to start telemetry + set_timer(); + +- // Start the ASIO io_service run loop ++ // Start the ASIO io_context run loop + try { + m_endpoint.run(); + } catch (websocketpp::exception const & e) { +diff --git a/examples/testee_client/testee_client.cpp b/examples/testee_client/testee_client.cpp +index b66e633..12583e5 100644 +--- a/examples/testee_client/testee_client.cpp ++++ b/examples/testee_client/testee_client.cpp +@@ -117,7 +117,7 @@ int main(int argc, char* argv[]) { + client::connection_ptr con = c.get_connection(uri+"/getCaseCount", ec); + c.connect(con); + +- // Start the ASIO io_service run loop ++ // Start the ASIO io_context run loop + c.run(); + + std::cout << "case count: " << case_count << std::endl; +diff --git a/examples/testee_server/testee_server.cpp b/examples/testee_server/testee_server.cpp +index 9ac9a7d..13e574e 100644 +--- a/examples/testee_server/testee_server.cpp ++++ b/examples/testee_server/testee_server.cpp +@@ -124,7 +124,7 @@ int main(int argc, char * argv[]) { + // Start the server accept loop + testee_server.start_accept(); + +- // Start the ASIO io_service run loop ++ // Start the ASIO io_context run loop + if (num_threads == 1) { + testee_server.run(); + } else { +diff --git a/test/endpoint/endpoint.cpp b/test/endpoint/endpoint.cpp +index b4c429e..fa58e66 100644 +--- a/test/endpoint/endpoint.cpp ++++ b/test/endpoint/endpoint.cpp +@@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE( initialize_server_asio ) { + + BOOST_AUTO_TEST_CASE( initialize_server_asio_external ) { + websocketpp::server s; +- boost::asio::io_service ios; ++ boost::asio::io_context ios; + s.init_asio(&ios); + } + +@@ -141,8 +141,8 @@ BOOST_AUTO_TEST_CASE( listen_after_listen_failure ) { + server1.init_asio(); + server2.init_asio(); + +- boost::asio::ip::tcp::endpoint ep1(boost::asio::ip::address::from_string("127.0.0.1"), 12345); +- boost::asio::ip::tcp::endpoint ep2(boost::asio::ip::address::from_string("127.0.0.1"), 23456); ++ boost::asio::ip::tcp::endpoint ep1(boost::asio::ip::make_address("127.0.0.1"), 12345); ++ boost::asio::ip::tcp::endpoint ep2(boost::asio::ip::make_address("127.0.0.1"), 23456); + + server1.listen(ep1, ec); + BOOST_CHECK(!ec); +diff --git a/test/transport/asio/timers.cpp b/test/transport/asio/timers.cpp +index aa03d61..391b755 100644 +--- a/test/transport/asio/timers.cpp ++++ b/test/transport/asio/timers.cpp +@@ -54,9 +54,9 @@ void run_dummy_server(int port) { + using boost::asio::ip::tcp; + + try { +- boost::asio::io_service io_service; +- tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v6(), port)); +- tcp::socket socket(io_service); ++ boost::asio::io_context io_context; ++ tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v6(), port)); ++ tcp::socket socket(io_context); + + acceptor.accept(socket); + for (;;) { +@@ -79,7 +79,7 @@ void run_dummy_server(int port) { + + // Wait for the specified time period then fail the test + void run_test_timer(long value) { +- boost::asio::io_service ios; ++ boost::asio::io_context ios; + boost::asio::deadline_timer t(ios,boost::posix_time::milliseconds(value)); + boost::system::error_code ec; + t.wait(ec); +diff --git a/test/transport/integration.cpp b/test/transport/integration.cpp +index c083cfd..ab82b1a 100644 +--- a/test/transport/integration.cpp ++++ b/test/transport/integration.cpp +@@ -221,9 +221,9 @@ void run_dummy_server(int port) { + using boost::asio::ip::tcp; + + try { +- boost::asio::io_service io_service; +- tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v6(), port)); +- tcp::socket socket(io_service); ++ boost::asio::io_context io_context; ++ tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v6(), port)); ++ tcp::socket socket(io_context); + + acceptor.accept(socket); + for (;;) { +@@ -248,13 +248,12 @@ void run_dummy_client(std::string port) { + using boost::asio::ip::tcp; + + try { +- boost::asio::io_service io_service; +- tcp::resolver resolver(io_service); +- tcp::resolver::query query("localhost", port); +- tcp::resolver::iterator iterator = resolver.resolve(query); +- tcp::socket socket(io_service); ++ boost::asio::io_context io_context; ++ tcp::resolver resolver(io_context); ++ tcp::resolver::results_type endpoints = resolver.resolve("localhost", port); ++ tcp::socket socket(io_context); + +- boost::asio::connect(socket, iterator); ++ boost::asio::connect(socket, endpoints); + for (;;) { + char data[512]; + boost::system::error_code ec; +@@ -358,11 +357,11 @@ class test_deadline_timer + { + public: + test_deadline_timer(int seconds) +- : m_timer(m_io_service, boost::posix_time::seconds(seconds)) ++ : m_timer(m_io_context, boost::posix_time::seconds(seconds)) + { + m_timer.async_wait(bind(&test_deadline_timer::expired, this, ::_1)); +- std::size_t (boost::asio::io_service::*run)() = &boost::asio::io_service::run; +- m_timer_thread = websocketpp::lib::thread(websocketpp::lib::bind(run, &m_io_service)); ++ std::size_t (boost::asio::io_context::*run)() = &boost::asio::io_context::run; ++ m_timer_thread = websocketpp::lib::thread(websocketpp::lib::bind(run, &m_io_context)); + } + ~test_deadline_timer() + { +@@ -379,7 +378,7 @@ public: + BOOST_FAIL("Test timed out"); + } + +- boost::asio::io_service m_io_service; ++ boost::asio::io_context m_io_context; + boost::asio::deadline_timer m_timer; + websocketpp::lib::thread m_timer_thread; + }; +@@ -541,7 +540,7 @@ BOOST_AUTO_TEST_CASE( client_runs_out_of_work ) { + + c.run(); + +- // This test checks that an io_service with no work ends immediately. ++ // This test checks that an io_context with no work ends immediately. + BOOST_CHECK(true); + } + +diff --git a/tutorials/utility_server/step1.cpp b/tutorials/utility_server/step1.cpp +index c0e4643..dae4a2a 100644 +--- a/tutorials/utility_server/step1.cpp ++++ b/tutorials/utility_server/step1.cpp +@@ -57,7 +57,7 @@ public: + // Queues a connection accept operation + m_endpoint.start_accept(); + +- // Start the Asio io_service run loop ++ // Start the Asio io_context run loop + m_endpoint.run(); + } + private: +diff --git a/tutorials/utility_server/step2.cpp b/tutorials/utility_server/step2.cpp +index a2815bb..c4fe486 100644 +--- a/tutorials/utility_server/step2.cpp ++++ b/tutorials/utility_server/step2.cpp +@@ -68,7 +68,7 @@ public: + // Queues a connection accept operation + m_endpoint.start_accept(); + +- // Start the Asio io_service run loop ++ // Start the Asio io_context run loop + m_endpoint.run(); + } + private: +diff --git a/tutorials/utility_server/utility_server.md b/tutorials/utility_server/utility_server.md +index 1c7ee3f..461eed0 100644 +--- a/tutorials/utility_server/utility_server.md ++++ b/tutorials/utility_server/utility_server.md +@@ -56,7 +56,7 @@ m_endpoint.set_access_channels(websocketpp::log::alevel::all ^ websocketpp::log: + + Next, we initialize the transport system underlying the endpoint. This method is specific to the Asio transport not WebSocket++ core. It will not be necessary or present in endpoints that use a non-asio config. + +-> **Note:** This example uses an internal Asio `io_service` that is managed by the endpoint itself. This is a simple arrangement suitable for programs where WebSocket++ is the only code using Asio. If you have an existing program that already manages an `io_service` object or want to build a new program where WebSocket++ handlers share an io_service with other handlers you can pass the `io_service` you want WebSocket++ to register its handlers on to the `init_asio()` method and it will use it instead of generating and managing its own. [TODO: FAQ link instead?] ++> **Note:** This example uses an internal Asio `io_context` that is managed by the endpoint itself. This is a simple arrangement suitable for programs where WebSocket++ is the only code using Asio. If you have an existing program that already manages an `io_context` object or want to build a new program where WebSocket++ handlers share an io_context with other handlers you can pass the `io_context` you want WebSocket++ to register its handlers on to the `init_asio()` method and it will use it instead of generating and managing its own. [TODO: FAQ link instead?] + + ~~~{.cpp} + m_endpoint.init_asio(); +@@ -64,7 +64,7 @@ m_endpoint.init_asio(); + + #### `utility_server::run` method + +-In addition to the constructor, we also add a run method that sets up the listening socket, begins accepting connections, starts the Asio io_service event loop. ++In addition to the constructor, we also add a run method that sets up the listening socket, begins accepting connections, starts the Asio io_context event loop. + + ~~~{.cpp} + // Listen on port 9002 +@@ -73,7 +73,7 @@ m_endpoint.listen(9002); + // Queues a connection accept operation + m_endpoint.start_accept(); + +-// Start the Asio io_service run loop ++// Start the Asio io_context run loop + m_endpoint.run(); + ~~~ + +@@ -123,7 +123,7 @@ public: + // Queues a connection accept operation + m_endpoint.start_accept(); + +- // Start the Asio io_service run loop ++ // Start the Asio io_context run loop + m_endpoint.run(); + } + private: +diff --git a/websocketpp/roles/server_endpoint.hpp b/websocketpp/roles/server_endpoint.hpp +index 9cc652f..ed4b703 100644 +--- a/websocketpp/roles/server_endpoint.hpp ++++ b/websocketpp/roles/server_endpoint.hpp +@@ -110,8 +110,8 @@ public: + /// Starts the server's async connection acceptance loop (exception free) + /** + * Initiates the server connection acceptance loop. Must be called after +- * listen. This method will have no effect until the underlying io_service +- * starts running. It may be called after the io_service is already running. ++ * listen. This method will have no effect until the underlying io_context ++ * starts running. It may be called after the io_context is already running. + * + * Refer to documentation for the transport policy you are using for + * instructions on how to stop this acceptance loop. +diff --git a/websocketpp/transport/asio/base.hpp b/websocketpp/transport/asio/base.hpp +index b945fe1..8d980ad 100644 +--- a/websocketpp/transport/asio/base.hpp ++++ b/websocketpp/transport/asio/base.hpp +@@ -40,7 +40,7 @@ namespace websocketpp { + namespace transport { + /// Transport policy that uses asio + /** +- * This policy uses a single asio io_service to provide transport ++ * This policy uses a single asio io_context to provide transport + * services to a WebSocket++ endpoint. + */ + namespace asio { +diff --git a/websocketpp/transport/asio/connection.hpp b/websocketpp/transport/asio/connection.hpp +index 57dda74..eaee6bc 100644 +--- a/websocketpp/transport/asio/connection.hpp ++++ b/websocketpp/transport/asio/connection.hpp +@@ -85,10 +85,10 @@ public: + typedef typename config::response_type response_type; + typedef typename response_type::ptr response_ptr; + +- /// Type of a pointer to the Asio io_service being used +- typedef lib::asio::io_service * io_service_ptr; +- /// Type of a pointer to the Asio io_service::strand being used +- typedef lib::shared_ptr strand_ptr; ++ /// Type of a pointer to the Asio io_context being used ++ typedef lib::asio::io_context * io_context_ptr; ++ /// Type of a pointer to the Asio io_context::strand being used ++ typedef lib::shared_ptr strand_ptr; + /// Type of a pointer to the Asio timer class + typedef lib::shared_ptr timer_ptr; + +@@ -97,7 +97,7 @@ public: + // to the public api. + friend class endpoint; + +- // generate and manage our own io_service ++ // generate and manage our own io_context + explicit connection(bool is_server, const lib::shared_ptr & alog, const lib::shared_ptr & elog) + : m_is_server(is_server) + , m_alog(alog) +@@ -313,7 +313,7 @@ public: + timer_ptr set_timer(long duration, timer_handler callback) { + timer_ptr new_timer( + new lib::asio::steady_timer( +- *m_io_service, ++ *m_io_context, + lib::asio::milliseconds(duration)) + ); + +@@ -393,7 +393,7 @@ public: + /// Initialize transport for reading + /** + * init_asio is called once immediately after construction to initialize +- * Asio components to the io_service ++ * Asio components to the io_context + * + * The transport initialization sequence consists of the following steps: + * - Pre-init: the underlying socket is initialized to the point where +@@ -451,21 +451,21 @@ protected: + /// Finish constructing the transport + /** + * init_asio is called once immediately after construction to initialize +- * Asio components to the io_service. ++ * Asio components to the io_context. + * +- * @param io_service A pointer to the io_service to register with this ++ * @param io_context A pointer to the io_context to register with this + * connection + * + * @return Status code for the success or failure of the initialization + */ +- lib::error_code init_asio (io_service_ptr io_service) { +- m_io_service = io_service; ++ lib::error_code init_asio (io_context_ptr io_context) { ++ m_io_context = io_context; + + if (config::enable_multithreading) { +- m_strand.reset(new lib::asio::io_service::strand(*io_service)); ++ m_strand.reset(new lib::asio::io_context::strand(*io_context)); + } + +- lib::error_code ec = socket_con_type::init_asio(io_service, m_strand, ++ lib::error_code ec = socket_con_type::init_asio(io_context, m_strand, + m_is_server); + + return ec; +@@ -573,7 +573,7 @@ protected: + lib::error_code const & ec) + { + if (ec == transport::error::operation_aborted || +- (post_timer && lib::asio::is_neg(post_timer->expires_from_now()))) ++ (post_timer && lib::asio::is_neg(post_timer->expiry() - std::chrono::steady_clock::now()))) + { + m_alog->write(log::alevel::devel,"post_init cancelled"); + return; +@@ -679,7 +679,7 @@ protected: + // Whatever aborted it will be issuing the callback so we are safe to + // return + if (ec == lib::asio::error::operation_aborted || +- lib::asio::is_neg(m_proxy_data->timer->expires_from_now())) ++ lib::asio::is_neg(m_proxy_data->timer->expiry() - std::chrono::steady_clock::now())) + { + m_elog->write(log::elevel::devel,"write operation aborted"); + return; +@@ -751,7 +751,7 @@ protected: + // Whatever aborted it will be issuing the callback so we are safe to + // return + if (ec == lib::asio::error::operation_aborted || +- lib::asio::is_neg(m_proxy_data->timer->expires_from_now())) ++ lib::asio::is_neg(m_proxy_data->timer->expiry() - std::chrono::steady_clock::now())) + { + m_elog->write(log::elevel::devel,"read operation aborted"); + return; +@@ -1012,18 +1012,18 @@ protected: + */ + lib::error_code interrupt(interrupt_handler handler) { + if (config::enable_multithreading) { +- m_io_service->post(m_strand->wrap(handler)); ++ boost::asio::post(m_io_context->get_executor(), m_strand->wrap(handler)); + } else { +- m_io_service->post(handler); ++ boost::asio::post(m_io_context->get_executor(), handler); + } + return lib::error_code(); + } + + lib::error_code dispatch(dispatch_handler handler) { + if (config::enable_multithreading) { +- m_io_service->post(m_strand->wrap(handler)); ++ boost::asio::post(m_io_context->get_executor(), m_strand->wrap(handler)); + } else { +- m_io_service->post(handler); ++ boost::asio::post(m_io_context->get_executor(), handler); + } + return lib::error_code(); + } +@@ -1095,7 +1095,7 @@ protected: + callback, lib::asio::error_code const & ec) + { + if (ec == lib::asio::error::operation_aborted || +- lib::asio::is_neg(shutdown_timer->expires_from_now())) ++ lib::asio::is_neg(shutdown_timer->expiry() - std::chrono::steady_clock::now())) + { + m_alog->write(log::alevel::devel,"async_shutdown cancelled"); + return; +@@ -1172,7 +1172,7 @@ private: + lib::shared_ptr m_proxy_data; + + // transport resources +- io_service_ptr m_io_service; ++ io_context_ptr m_io_context; + strand_ptr m_strand; + connection_hdl m_connection_hdl; + +diff --git a/websocketpp/transport/asio/endpoint.hpp b/websocketpp/transport/asio/endpoint.hpp +index 94509ad..7af0915 100644 +--- a/websocketpp/transport/asio/endpoint.hpp ++++ b/websocketpp/transport/asio/endpoint.hpp +@@ -77,25 +77,25 @@ public: + /// associated with this endpoint transport component + typedef typename transport_con_type::ptr transport_con_ptr; + +- /// Type of a pointer to the ASIO io_service being used +- typedef lib::asio::io_service * io_service_ptr; ++ /// Type of a pointer to the ASIO io_context being used ++ typedef lib::asio::io_context * io_context_ptr; + /// Type of a shared pointer to the acceptor being used + typedef lib::shared_ptr acceptor_ptr; + /// Type of a shared pointer to the resolver being used + typedef lib::shared_ptr resolver_ptr; + /// Type of timer handle + typedef lib::shared_ptr timer_ptr; +- /// Type of a shared pointer to an io_service work object +- typedef lib::shared_ptr work_ptr; ++ /// Type of a shared pointer to an io_context work object ++ typedef lib::shared_ptr> work_ptr; + + /// Type of socket pre-bind handler + typedef lib::function tcp_pre_bind_handler; + +- // generate and manage our own io_service ++ // generate and manage our own io_context + explicit endpoint() +- : m_io_service(NULL) +- , m_external_io_service(false) +- , m_listen_backlog(lib::asio::socket_base::max_connections) ++ : m_io_context(NULL) ++ , m_external_io_context(false) ++ , m_listen_backlog(lib::asio::socket_base::max_listen_connections) + , m_reuse_addr(false) + , m_state(UNINITIALIZED) + { +@@ -103,14 +103,14 @@ public: + } + + ~endpoint() { +- // clean up our io_service if we were initialized with an internal one. ++ // clean up our io_context if we were initialized with an internal one. + + // Explicitly destroy local objects + m_acceptor.reset(); + m_resolver.reset(); + m_work.reset(); +- if (m_state != UNINITIALIZED && !m_external_io_service) { +- delete m_io_service; ++ if (m_state != UNINITIALIZED && !m_external_io_context) { ++ delete m_io_context; + } + } + +@@ -132,34 +132,34 @@ public: + : config::socket_type(std::move(src)) + , m_tcp_pre_init_handler(src.m_tcp_pre_init_handler) + , m_tcp_post_init_handler(src.m_tcp_post_init_handler) +- , m_io_service(src.m_io_service) +- , m_external_io_service(src.m_external_io_service) ++ , m_io_context(src.m_io_context) ++ , m_external_io_context(src.m_external_io_context) + , m_acceptor(src.m_acceptor) +- , m_listen_backlog(lib::asio::socket_base::max_connections) ++ , m_listen_backlog(lib::asio::socket_base::max_listen_connections) + , m_reuse_addr(src.m_reuse_addr) + , m_elog(src.m_elog) + , m_alog(src.m_alog) + , m_state(src.m_state) + { +- src.m_io_service = NULL; +- src.m_external_io_service = false; ++ src.m_io_context = NULL; ++ src.m_external_io_context = false; + src.m_acceptor = NULL; + src.m_state = UNINITIALIZED; + } + + /*endpoint & operator= (const endpoint && rhs) { + if (this != &rhs) { +- m_io_service = rhs.m_io_service; +- m_external_io_service = rhs.m_external_io_service; ++ m_io_context = rhs.m_io_context; ++ m_external_io_context = rhs.m_external_io_context; + m_acceptor = rhs.m_acceptor; + m_listen_backlog = rhs.m_listen_backlog; + m_reuse_addr = rhs.m_reuse_addr; + m_state = rhs.m_state; + +- rhs.m_io_service = NULL; +- rhs.m_external_io_service = false; ++ rhs.m_io_context = NULL; ++ rhs.m_external_io_context = false; + rhs.m_acceptor = NULL; +- rhs.m_listen_backlog = lib::asio::socket_base::max_connections; ++ rhs.m_listen_backlog = lib::asio::socket_base::max_listen_connections; + rhs.m_state = UNINITIALIZED; + + // TODO: this needs to be updated +@@ -173,16 +173,16 @@ public: + return socket_type::is_secure(); + } + +- /// initialize asio transport with external io_service (exception free) ++ /// initialize asio transport with external io_context (exception free) + /** + * Initialize the ASIO transport policy for this endpoint using the provided +- * io_service object. asio_init must be called exactly once on any endpoint ++ * io_context object. asio_init must be called exactly once on any endpoint + * that uses transport::asio before it can be used. + * +- * @param ptr A pointer to the io_service to use for asio events ++ * @param ptr A pointer to the io_context to use for asio events + * @param ec Set to indicate what error occurred, if any. + */ +- void init_asio(io_service_ptr ptr, lib::error_code & ec) { ++ void init_asio(io_context_ptr ptr, lib::error_code & ec) { + if (m_state != UNINITIALIZED) { + m_elog->write(log::elevel::library, + "asio::init_asio called from the wrong state"); +@@ -193,34 +193,34 @@ public: + + m_alog->write(log::alevel::devel,"asio::init_asio"); + +- m_io_service = ptr; +- m_external_io_service = true; +- m_acceptor.reset(new lib::asio::ip::tcp::acceptor(*m_io_service)); ++ m_io_context = ptr; ++ m_external_io_context = true; ++ m_acceptor.reset(new lib::asio::ip::tcp::acceptor(*m_io_context)); + + m_state = READY; + ec = lib::error_code(); + } + +- /// initialize asio transport with external io_service ++ /// initialize asio transport with external io_context + /** + * Initialize the ASIO transport policy for this endpoint using the provided +- * io_service object. asio_init must be called exactly once on any endpoint ++ * io_context object. asio_init must be called exactly once on any endpoint + * that uses transport::asio before it can be used. + * +- * @param ptr A pointer to the io_service to use for asio events ++ * @param ptr A pointer to the io_context to use for asio events + */ +- void init_asio(io_service_ptr ptr) { ++ void init_asio(io_context_ptr ptr) { + lib::error_code ec; + init_asio(ptr,ec); + if (ec) { throw exception(ec); } + } + +- /// Initialize asio transport with internal io_service (exception free) ++ /// Initialize asio transport with internal io_context (exception free) + /** + * This method of initialization will allocate and use an internally managed +- * io_service. ++ * io_context. + * +- * @see init_asio(io_service_ptr ptr) ++ * @see init_asio(io_context_ptr ptr) + * + * @param ec Set to indicate what error occurred, if any. + */ +@@ -230,21 +230,21 @@ public: + // TODO: remove the use of auto_ptr when C++98/03 support is no longer + // necessary. + #ifdef _WEBSOCKETPP_CPP11_MEMORY_ +- lib::unique_ptr service(new lib::asio::io_service()); ++ lib::unique_ptr context(new lib::asio::io_context()); + #else +- lib::auto_ptr service(new lib::asio::io_service()); ++ lib::auto_ptr context(new lib::asio::io_context()); + #endif +- init_asio(service.get(), ec); +- if( !ec ) service.release(); // Call was successful, transfer ownership +- m_external_io_service = false; ++ init_asio(context.get(), ec); ++ if( !ec ) context.release(); // Call was successful, transfer ownership ++ m_external_io_context = false; + } + +- /// Initialize asio transport with internal io_service ++ /// Initialize asio transport with internal io_context + /** + * This method of initialization will allocate and use an internally managed +- * io_service. ++ * io_context. + * +- * @see init_asio(io_service_ptr ptr) ++ * @see init_asio(io_context_ptr ptr) + */ + void init_asio() { + // Use a smart pointer until the call is successful and ownership has +@@ -252,14 +252,14 @@ public: + // TODO: remove the use of auto_ptr when C++98/03 support is no longer + // necessary. + #ifdef _WEBSOCKETPP_CPP11_MEMORY_ +- lib::unique_ptr service(new lib::asio::io_service()); ++ lib::unique_ptr context(new lib::asio::io_context()); + #else +- lib::auto_ptr service(new lib::asio::io_service()); ++ lib::auto_ptr context(new lib::asio::io_context()); + #endif +- init_asio( service.get() ); ++ init_asio( context.get() ); + // If control got this far without an exception, then ownership has successfully been taken +- service.release(); +- m_external_io_service = false; ++ context.release(); ++ m_external_io_context = false; + } + + /// Sets the tcp pre bind handler +@@ -330,7 +330,7 @@ public: + * + * New values affect future calls to listen only. + * +- * The default value is specified as *::asio::socket_base::max_connections ++ * The default value is specified as *::asio::socket_base::max_listen_connections + * which uses the operating system defined maximum queue length. Your OS + * may restrict or silently lower this value. A value of zero may cause + * all connections to be rejected. +@@ -364,19 +364,19 @@ public: + m_reuse_addr = value; + } + +- /// Retrieve a reference to the endpoint's io_service ++ /// Retrieve a reference to the endpoint's io_context + /** +- * The io_service may be an internal or external one. This may be used to +- * call methods of the io_service that are not explicitly wrapped by the ++ * The io_context may be an internal or external one. This may be used to ++ * call methods of the io_context that are not explicitly wrapped by the + * endpoint. + * + * This method is only valid after the endpoint has been initialized with + * `init_asio`. No error will be returned if it isn't. + * +- * @return A reference to the endpoint's io_service ++ * @return A reference to the endpoint's io_context + */ +- lib::asio::io_service & get_io_service() { +- return *m_io_service; ++ lib::asio::io_context & get_io_context() { ++ return *m_io_context; + } + + /// Get local TCP endpoint +@@ -557,17 +557,15 @@ public: + lib::error_code & ec) + { + using lib::asio::ip::tcp; +- tcp::resolver r(*m_io_service); +- tcp::resolver::query query(host, service); +- tcp::resolver::iterator endpoint_iterator = r.resolve(query); +- tcp::resolver::iterator end; +- if (endpoint_iterator == end) { ++ tcp::resolver r(*m_io_context); ++ tcp::resolver::results_type endpoints = r.resolve(host, service); ++ if (endpoints.empty()) { + m_elog->write(log::elevel::library, + "asio::listen could not resolve the supplied host or service"); + ec = make_error_code(error::invalid_host_service); + return; + } +- listen(*endpoint_iterator,ec); ++ listen(*endpoints.begin(),ec); + } + + /// Set up endpoint for listening on a host and service +@@ -636,42 +634,42 @@ public: + return (m_state == LISTENING); + } + +- /// wraps the run method of the internal io_service object ++ /// wraps the run method of the internal io_context object + std::size_t run() { +- return m_io_service->run(); ++ return m_io_context->run(); + } + +- /// wraps the run_one method of the internal io_service object ++ /// wraps the run_one method of the internal io_context object + /** + * @since 0.3.0-alpha4 + */ + std::size_t run_one() { +- return m_io_service->run_one(); ++ return m_io_context->run_one(); + } + +- /// wraps the stop method of the internal io_service object ++ /// wraps the stop method of the internal io_context object + void stop() { +- m_io_service->stop(); ++ m_io_context->stop(); + } + +- /// wraps the poll method of the internal io_service object ++ /// wraps the poll method of the internal io_context object + std::size_t poll() { +- return m_io_service->poll(); ++ return m_io_context->poll(); + } + +- /// wraps the poll_one method of the internal io_service object ++ /// wraps the poll_one method of the internal io_context object + std::size_t poll_one() { +- return m_io_service->poll_one(); ++ return m_io_context->poll_one(); + } + +- /// wraps the reset method of the internal io_service object ++ /// wraps the restart method of the internal io_context object + void reset() { +- m_io_service->reset(); ++ m_io_context->restart(); + } + +- /// wraps the stopped method of the internal io_service object ++ /// wraps the stopped method of the internal io_context object + bool stopped() const { +- return m_io_service->stopped(); ++ return m_io_context->stopped(); + } + + /// Marks the endpoint as perpetual, stopping it from exiting when empty +@@ -687,7 +685,7 @@ public: + * @since 0.3.0 + */ + void start_perpetual() { +- m_work.reset(new lib::asio::io_service::work(*m_io_service)); ++ m_work.reset(new lib::asio::executor_work_guard(m_io_context->get_executor())); + } + + /// Clears the endpoint's perpetual flag, allowing it to exit when empty +@@ -716,7 +714,7 @@ public: + */ + timer_ptr set_timer(long duration, timer_handler callback) { + timer_ptr new_timer = lib::make_shared( +- *m_io_service, ++ *m_io_context, + lib::asio::milliseconds(duration) + ); + +@@ -851,7 +849,7 @@ protected: + + // Create a resolver + if (!m_resolver) { +- m_resolver.reset(new lib::asio::ip::tcp::resolver(*m_io_service)); ++ m_resolver.reset(new lib::asio::ip::tcp::resolver(*m_io_context)); + } + + tcon->set_uri(u); +@@ -883,8 +881,6 @@ protected: + port = pu->get_port_str(); + } + +- tcp::resolver::query query(host,port); +- + if (m_alog->static_test(log::alevel::devel)) { + m_alog->write(log::alevel::devel, + "starting async DNS resolve for "+host+":"+port); +@@ -905,7 +901,8 @@ protected: + + if (config::enable_multithreading) { + m_resolver->async_resolve( +- query, ++ host, ++ port, + tcon->get_strand()->wrap(lib::bind( + &type::handle_resolve, + this, +@@ -918,7 +915,8 @@ protected: + ); + } else { + m_resolver->async_resolve( +- query, ++ host, ++ port, + lib::bind( + &type::handle_resolve, + this, +@@ -966,10 +964,10 @@ protected: + + void handle_resolve(transport_con_ptr tcon, timer_ptr dns_timer, + connect_handler callback, lib::asio::error_code const & ec, +- lib::asio::ip::tcp::resolver::iterator iterator) ++ lib::asio::ip::tcp::resolver::results_type endpoints) + { + if (ec == lib::asio::error::operation_aborted || +- lib::asio::is_neg(dns_timer->expires_from_now())) ++ lib::asio::is_neg(dns_timer->expiry() - std::chrono::steady_clock::now())) + { + m_alog->write(log::alevel::devel,"async_resolve cancelled"); + return; +@@ -987,8 +985,8 @@ protected: + std::stringstream s; + s << "Async DNS resolve successful. Results: "; + +- lib::asio::ip::tcp::resolver::iterator it, end; +- for (it = iterator; it != end; ++it) { ++ lib::asio::ip::tcp::resolver::results_type::iterator it; ++ for (it = endpoints.begin(); it != endpoints.end(); ++it) { + s << (*it).endpoint() << " "; + } + +@@ -1014,7 +1012,7 @@ protected: + if (config::enable_multithreading) { + lib::asio::async_connect( + tcon->get_raw_socket(), +- iterator, ++ endpoints, + tcon->get_strand()->wrap(lib::bind( + &type::handle_connect, + this, +@@ -1027,7 +1025,7 @@ protected: + } else { + lib::asio::async_connect( + tcon->get_raw_socket(), +- iterator, ++ endpoints, + lib::bind( + &type::handle_connect, + this, +@@ -1077,7 +1075,7 @@ protected: + connect_handler callback, lib::asio::error_code const & ec) + { + if (ec == lib::asio::error::operation_aborted || +- lib::asio::is_neg(con_timer->expires_from_now())) ++ lib::asio::is_neg(con_timer->expiry() - std::chrono::steady_clock::now())) + { + m_alog->write(log::alevel::devel,"async_connect cancelled"); + return; +@@ -1119,7 +1117,7 @@ protected: + + lib::error_code ec; + +- ec = tcon->init_asio(m_io_service); ++ ec = tcon->init_asio(m_io_context); + if (ec) {return ec;} + + tcon->set_tcp_pre_init_handler(m_tcp_pre_init_handler); +@@ -1158,8 +1156,8 @@ private: + tcp_init_handler m_tcp_post_init_handler; + + // Network Resources +- io_service_ptr m_io_service; +- bool m_external_io_service; ++ io_context_ptr m_io_context; ++ bool m_external_io_context; + acceptor_ptr m_acceptor; + resolver_ptr m_resolver; + work_ptr m_work; +diff --git a/websocketpp/transport/asio/security/none.hpp b/websocketpp/transport/asio/security/none.hpp +index 6c7d352..009063f 100644 +--- a/websocketpp/transport/asio/security/none.hpp ++++ b/websocketpp/transport/asio/security/none.hpp +@@ -62,10 +62,10 @@ public: + /// Type of a shared pointer to this connection socket component + typedef lib::shared_ptr ptr; + +- /// Type of a pointer to the Asio io_service being used +- typedef lib::asio::io_service* io_service_ptr; +- /// Type of a pointer to the Asio io_service strand being used +- typedef lib::shared_ptr strand_ptr; ++ /// Type of a pointer to the Asio io_context being used ++ typedef lib::asio::io_context* io_context_ptr; ++ /// Type of a pointer to the Asio io_context strand being used ++ typedef lib::shared_ptr strand_ptr; + /// Type of the ASIO socket being used + typedef lib::asio::ip::tcp::socket socket_type; + /// Type of a shared pointer to the socket being used. +@@ -156,19 +156,19 @@ protected: + /// Perform one time initializations + /** + * init_asio is called once immediately after construction to initialize +- * Asio components to the io_service ++ * Asio components to the io_context + * +- * @param service A pointer to the endpoint's io_service ++ * @param service A pointer to the endpoint's io_context + * @param strand A shared pointer to the connection's asio strand + * @param is_server Whether or not the endpoint is a server or not. + */ +- lib::error_code init_asio (io_service_ptr service, strand_ptr, bool) ++ lib::error_code init_asio (io_context_ptr context, strand_ptr, bool) + { + if (m_state != UNINITIALIZED) { + return socket::make_error_code(socket::error::invalid_state); + } + +- m_socket.reset(new lib::asio::ip::tcp::socket(*service)); ++ m_socket.reset(new lib::asio::ip::tcp::socket(*context)); + + if (m_socket_init_handler) { + m_socket_init_handler(m_hdl, *m_socket); +diff --git a/websocketpp/transport/asio/security/tls.hpp b/websocketpp/transport/asio/security/tls.hpp +index 04ac379..9f86fc1 100644 +--- a/websocketpp/transport/asio/security/tls.hpp ++++ b/websocketpp/transport/asio/security/tls.hpp +@@ -71,10 +71,10 @@ public: + typedef lib::asio::ssl::stream socket_type; + /// Type of a shared pointer to the ASIO socket being used + typedef lib::shared_ptr socket_ptr; +- /// Type of a pointer to the ASIO io_service being used +- typedef lib::asio::io_service * io_service_ptr; +- /// Type of a pointer to the ASIO io_service strand being used +- typedef lib::shared_ptr strand_ptr; ++ /// Type of a pointer to the ASIO io_context being used ++ typedef lib::asio::io_context * io_context_ptr; ++ /// Type of a pointer to the ASIO io_context strand being used ++ typedef lib::shared_ptr strand_ptr; + /// Type of a shared pointer to the ASIO TLS context being used + typedef lib::shared_ptr context_ptr; + +@@ -176,13 +176,13 @@ protected: + /// Perform one time initializations + /** + * init_asio is called once immediately after construction to initialize +- * Asio components to the io_service ++ * Asio components to the io_context + * +- * @param service A pointer to the endpoint's io_service ++ * @param service A pointer to the endpoint's io_context + * @param strand A pointer to the connection's strand + * @param is_server Whether or not the endpoint is a server or not. + */ +- lib::error_code init_asio (io_service_ptr service, strand_ptr strand, ++ lib::error_code init_asio (io_context_ptr context, strand_ptr strand, + bool is_server) + { + if (!m_tls_init_handler) { +@@ -193,13 +193,13 @@ protected: + if (!m_context) { + return socket::make_error_code(socket::error::invalid_tls_context); + } +- m_socket.reset(new socket_type(*service, *m_context)); ++ m_socket.reset(new socket_type(*context, *m_context)); + + if (m_socket_init_handler) { + m_socket_init_handler(m_hdl, get_socket()); + } + +- m_io_service = service; ++ m_io_context = context; + m_strand = strand; + m_is_server = is_server; + +@@ -381,7 +381,7 @@ private: + } + } + +- io_service_ptr m_io_service; ++ io_context_ptr m_io_context; + strand_ptr m_strand; + context_ptr m_context; + socket_ptr m_socket; +diff --git a/websocketpp/transport/debug/endpoint.hpp b/websocketpp/transport/debug/endpoint.hpp +index adc89b3..3606441 100644 +--- a/websocketpp/transport/debug/endpoint.hpp ++++ b/websocketpp/transport/debug/endpoint.hpp +@@ -60,7 +60,7 @@ public: + /// associated connection transport component + typedef typename transport_con_type::ptr transport_con_ptr; + +- // generate and manage our own io_service ++ // generate and manage our own io_context + explicit endpoint() + { + //std::cout << "transport::iostream::endpoint constructor" << std::endl; +diff --git a/websocketpp/transport/iostream/endpoint.hpp b/websocketpp/transport/iostream/endpoint.hpp +index 14cba72..257472d 100644 +--- a/websocketpp/transport/iostream/endpoint.hpp ++++ b/websocketpp/transport/iostream/endpoint.hpp +@@ -64,7 +64,7 @@ public: + /// associated connection transport component + typedef typename transport_con_type::ptr transport_con_ptr; + +- // generate and manage our own io_service ++ // generate and manage our own io_context + explicit endpoint() : m_output_stream(NULL), m_is_secure(false) + { + //std::cout << "transport::iostream::endpoint constructor" << std::endl; +diff --git a/websocketpp/transport/stub/endpoint.hpp b/websocketpp/transport/stub/endpoint.hpp +index 3bbb78f..8f8493a 100644 +--- a/websocketpp/transport/stub/endpoint.hpp ++++ b/websocketpp/transport/stub/endpoint.hpp +@@ -60,7 +60,7 @@ public: + /// associated connection transport component + typedef typename transport_con_type::ptr transport_con_ptr; + +- // generate and manage our own io_service ++ // generate and manage our own io_context + explicit endpoint() + { + //std::cout << "transport::iostream::endpoint constructor" << std::endl; +-- +2.48.1 + + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Amini Allight +Date: Wed, 12 Feb 2025 04:46:30 +0000 +Subject: [PATCH 2/7] updated docstrings + +(cherry picked from commit 30e77468e093e8384fa07819b345f81a0431eb37) + + Conflicts: + websocketpp/transport/asio/endpoint.hpp +--- + websocketpp/transport/asio/endpoint.hpp | 2 +- + websocketpp/transport/asio/security/none.hpp | 2 +- + websocketpp/transport/asio/security/tls.hpp | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/websocketpp/transport/asio/endpoint.hpp b/websocketpp/transport/asio/endpoint.hpp +index 7af0915..a5e1700 100644 +--- a/websocketpp/transport/asio/endpoint.hpp ++++ b/websocketpp/transport/asio/endpoint.hpp +@@ -549,7 +549,7 @@ public: + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. +- * @param service A string identifying the requested service. This may be a ++ * @param context A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. + * @param ec Set to indicate what error occurred, if any. + */ +diff --git a/websocketpp/transport/asio/security/none.hpp b/websocketpp/transport/asio/security/none.hpp +index 009063f..ff19d5c 100644 +--- a/websocketpp/transport/asio/security/none.hpp ++++ b/websocketpp/transport/asio/security/none.hpp +@@ -158,7 +158,7 @@ protected: + * init_asio is called once immediately after construction to initialize + * Asio components to the io_context + * +- * @param service A pointer to the endpoint's io_context ++ * @param context A pointer to the endpoint's io_context + * @param strand A shared pointer to the connection's asio strand + * @param is_server Whether or not the endpoint is a server or not. + */ +diff --git a/websocketpp/transport/asio/security/tls.hpp b/websocketpp/transport/asio/security/tls.hpp +index 9f86fc1..8b27656 100644 +--- a/websocketpp/transport/asio/security/tls.hpp ++++ b/websocketpp/transport/asio/security/tls.hpp +@@ -178,7 +178,7 @@ protected: + * init_asio is called once immediately after construction to initialize + * Asio components to the io_context + * +- * @param service A pointer to the endpoint's io_context ++ * @param context A pointer to the endpoint's io_context + * @param strand A pointer to the connection's strand + * @param is_server Whether or not the endpoint is a server or not. + */ +-- +2.48.1 + + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Amini Allight +Date: Wed, 12 Feb 2025 04:48:13 +0000 +Subject: [PATCH 3/7] updated docstrings + +(cherry picked from commit 3d13472f7489bda718ded20d885dbaf98e36442c) +--- + websocketpp/transport/asio/endpoint.hpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/websocketpp/transport/asio/endpoint.hpp b/websocketpp/transport/asio/endpoint.hpp +index a5e1700..7af0915 100644 +--- a/websocketpp/transport/asio/endpoint.hpp ++++ b/websocketpp/transport/asio/endpoint.hpp +@@ -549,7 +549,7 @@ public: + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. +- * @param context A string identifying the requested service. This may be a ++ * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. + * @param ec Set to indicate what error occurred, if any. + */ +-- +2.48.1 + + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Amini Allight +Date: Fri, 14 Feb 2025 07:48:42 +0000 +Subject: [PATCH 4/7] silenced warning about unused variable in TLS IP address + validation, improved time-to-expiry calculation (credit toonetown), added + CMake flag to compile tests and examples with ASIO standalone, fixed example + and test compilation with ASIO standalone + +(cherry picked from commit 6867ad089932fc2a786c39dae5ed152991e4ee46) + + Conflicts: + websocketpp/transport/asio/security/tls.hpp +--- + CMakeLists.txt | 5 +++ + examples/debug_client/debug_client.cpp | 12 +++--- + .../echo_server_both/echo_server_both.cpp | 16 ++++---- + .../external_io_context.cpp | 2 +- + .../external_io_context/tcp_echo_server.hpp | 28 +++++++------- + .../print_client_tls/print_client_tls.cpp | 14 +++---- + examples/testee_server/testee_server.cpp | 4 +- + test/endpoint/endpoint.cpp | 6 +-- + test/http/parser_perf.cpp | 4 +- + test/transport/asio/timers.cpp | 4 +- + test/transport/integration.cpp | 38 ++++++++++--------- + websocketpp/common/asio.hpp | 2 +- + websocketpp/transport/asio/connection.hpp | 18 ++++----- + websocketpp/transport/asio/endpoint.hpp | 4 +- + 14 files changed, 81 insertions(+), 76 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 4f93e24..cde4273 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -75,6 +75,7 @@ include (CMakeHelpers) + option (ENABLE_CPP11 "Build websocketpp with CPP11 features enabled." TRUE) + option (BUILD_EXAMPLES "Build websocketpp examples." FALSE) + option (BUILD_TESTS "Build websocketpp tests." FALSE) ++option (USE_ASIO_STANDALONE "Build websocketpp examples and tests using the standalone ASIO library." FALSE) + + if (BUILD_TESTS OR BUILD_EXAMPLES) + +@@ -246,6 +247,10 @@ endif() + + ############ Add projects + ++if (USE_ASIO_STANDALONE) ++ add_definitions("-DASIO_STANDALONE -DASIO_HAS_BOOST_DATE_TIME") ++endif () ++ + # Add main library + add_subdirectory (websocketpp) + +diff --git a/examples/debug_client/debug_client.cpp b/examples/debug_client/debug_client.cpp +index d3e21ab..7b6b40e 100644 +--- a/examples/debug_client/debug_client.cpp ++++ b/examples/debug_client/debug_client.cpp +@@ -44,7 +44,7 @@ using websocketpp::lib::bind; + + // pull out the type of messages sent by our config + typedef websocketpp::config::asio_tls_client::message_type::ptr message_ptr; +-typedef websocketpp::lib::shared_ptr context_ptr; ++typedef websocketpp::lib::shared_ptr context_ptr; + typedef client::connection_ptr connection_ptr; + + +@@ -94,13 +94,13 @@ public: + + context_ptr on_tls_init(websocketpp::connection_hdl) { + m_tls_init = std::chrono::high_resolution_clock::now(); +- context_ptr ctx = websocketpp::lib::make_shared(boost::asio::ssl::context::tlsv1); ++ context_ptr ctx = websocketpp::lib::make_shared(websocketpp::lib::asio::ssl::context::tlsv1); + + try { +- ctx->set_options(boost::asio::ssl::context::default_workarounds | +- boost::asio::ssl::context::no_sslv2 | +- boost::asio::ssl::context::no_sslv3 | +- boost::asio::ssl::context::single_dh_use); ++ ctx->set_options(websocketpp::lib::asio::ssl::context::default_workarounds | ++ websocketpp::lib::asio::ssl::context::no_sslv2 | ++ websocketpp::lib::asio::ssl::context::no_sslv3 | ++ websocketpp::lib::asio::ssl::context::single_dh_use); + } catch (std::exception& e) { + std::cout << e.what() << std::endl; + } +diff --git a/examples/echo_server_both/echo_server_both.cpp b/examples/echo_server_both/echo_server_both.cpp +index 869c006..a4f6a19 100644 +--- a/examples/echo_server_both/echo_server_both.cpp ++++ b/examples/echo_server_both/echo_server_both.cpp +@@ -14,7 +14,7 @@ using websocketpp::lib::placeholders::_2; + using websocketpp::lib::bind; + + // type of the ssl context pointer is long so alias it +-typedef websocketpp::lib::shared_ptr context_ptr; ++typedef websocketpp::lib::shared_ptr context_ptr; + + // The shared on_message handler takes a template parameter so the function can + // resolve any endpoint dependent types like message_ptr or connection_ptr +@@ -41,16 +41,16 @@ std::string get_password() { + + context_ptr on_tls_init(websocketpp::connection_hdl hdl) { + std::cout << "on_tls_init called with hdl: " << hdl.lock().get() << std::endl; +- context_ptr ctx(new boost::asio::ssl::context(boost::asio::ssl::context::tlsv1)); ++ context_ptr ctx(new websocketpp::lib::asio::ssl::context(websocketpp::lib::asio::ssl::context::tlsv1)); + + try { +- ctx->set_options(boost::asio::ssl::context::default_workarounds | +- boost::asio::ssl::context::no_sslv2 | +- boost::asio::ssl::context::no_sslv3 | +- boost::asio::ssl::context::single_dh_use); ++ ctx->set_options(websocketpp::lib::asio::ssl::context::default_workarounds | ++ websocketpp::lib::asio::ssl::context::no_sslv2 | ++ websocketpp::lib::asio::ssl::context::no_sslv3 | ++ websocketpp::lib::asio::ssl::context::single_dh_use); + ctx->set_password_callback(bind(&get_password)); + ctx->use_certificate_chain_file("server.pem"); +- ctx->use_private_key_file("server.pem", boost::asio::ssl::context::pem); ++ ctx->use_private_key_file("server.pem", websocketpp::lib::asio::ssl::context::pem); + } catch (std::exception& e) { + std::cout << e.what() << std::endl; + } +@@ -60,7 +60,7 @@ context_ptr on_tls_init(websocketpp::connection_hdl hdl) { + int main() { + // set up an external io_context to run both endpoints on. This is not + // strictly necessary, but simplifies thread management a bit. +- boost::asio::io_context ios; ++ websocketpp::lib::asio::io_context ios; + + // set up plain endpoint + server_plain endpoint_plain; +diff --git a/examples/external_io_context/external_io_context.cpp b/examples/external_io_context/external_io_context.cpp +index c5ba0a4..c6132ed 100644 +--- a/examples/external_io_context/external_io_context.cpp ++++ b/examples/external_io_context/external_io_context.cpp +@@ -59,7 +59,7 @@ void on_message(ws_echo_server* s, websocketpp::connection_hdl hdl, ws_echo_serv + } + + int main() { +- asio::io_context context; ++ websocketpp::lib::asio::io_context context; + + // Add a TCP echo server on port 9003 + tcp_echo_server custom_http_server(context, 9003); +diff --git a/examples/external_io_context/tcp_echo_server.hpp b/examples/external_io_context/tcp_echo_server.hpp +index 2e14703..f132c06 100644 +--- a/examples/external_io_context/tcp_echo_server.hpp ++++ b/examples/external_io_context/tcp_echo_server.hpp +@@ -39,42 +39,40 @@ using websocketpp::lib::placeholders::_1; + using websocketpp::lib::placeholders::_2; + using websocketpp::lib::bind; + +-namespace asio = websocketpp::lib::asio; +- + struct tcp_echo_session : websocketpp::lib::enable_shared_from_this { + typedef websocketpp::lib::shared_ptr ptr; + +- tcp_echo_session(asio::io_context & context) : m_socket(context) {} ++ tcp_echo_session(websocketpp::lib::asio::io_context & context) : m_socket(context) {} + + void start() { +- m_socket.async_read_some(asio::buffer(m_buffer, sizeof(m_buffer)), ++ m_socket.async_read_some(websocketpp::lib::asio::buffer(m_buffer, sizeof(m_buffer)), + websocketpp::lib::bind( + &tcp_echo_session::handle_read, shared_from_this(), _1, _2)); + } + +- void handle_read(const asio::error_code & ec, size_t transferred) { ++ void handle_read(const websocketpp::lib::asio::error_code & ec, size_t transferred) { + if (!ec) { +- asio::async_write(m_socket, +- asio::buffer(m_buffer, transferred), ++ websocketpp::lib::asio::async_write(m_socket, ++ websocketpp::lib::asio::buffer(m_buffer, transferred), + bind(&tcp_echo_session::handle_write, shared_from_this(), _1)); + } + } + +- void handle_write(const asio::error_code & ec) { ++ void handle_write(const websocketpp::lib::asio::error_code & ec) { + if (!ec) { +- m_socket.async_read_some(asio::buffer(m_buffer, sizeof(m_buffer)), ++ m_socket.async_read_some(websocketpp::lib::asio::buffer(m_buffer, sizeof(m_buffer)), + bind(&tcp_echo_session::handle_read, shared_from_this(), _1, _2)); + } + } + +- asio::ip::tcp::socket m_socket; ++ websocketpp::lib::asio::ip::tcp::socket m_socket; + char m_buffer[1024]; + }; + + struct tcp_echo_server { +- tcp_echo_server(asio::io_context & context, short port) ++ tcp_echo_server(websocketpp::lib::asio::io_context & context, short port) + : m_context(context) +- , m_acceptor(context, asio::ip::tcp::endpoint(asio::ip::tcp::v6(), port)) ++ , m_acceptor(context, websocketpp::lib::asio::ip::tcp::endpoint(websocketpp::lib::asio::ip::tcp::v6(), port)) + { + this->start_accept(); + } +@@ -85,13 +83,13 @@ struct tcp_echo_server { + bind(&tcp_echo_server::handle_accept, this, new_session, _1)); + } + +- void handle_accept(tcp_echo_session::ptr new_session, const asio::error_code & ec) { ++ void handle_accept(tcp_echo_session::ptr new_session, const websocketpp::lib::asio::error_code & ec) { + if (!ec) { + new_session->start(); + } + start_accept(); + } + +- asio::io_context & m_context; +- asio::ip::tcp::acceptor m_acceptor; ++ websocketpp::lib::asio::io_context & m_context; ++ websocketpp::lib::asio::ip::tcp::acceptor m_acceptor; + }; +diff --git a/examples/print_client_tls/print_client_tls.cpp b/examples/print_client_tls/print_client_tls.cpp +index 43164ea..cf616e1 100644 +--- a/examples/print_client_tls/print_client_tls.cpp ++++ b/examples/print_client_tls/print_client_tls.cpp +@@ -112,7 +112,7 @@ bool verify_common_name(char const * hostname, X509 * cert) { + * and + * https://github.com/iSECPartners/ssl-conservatory + */ +-bool verify_certificate(const char * hostname, bool preverified, boost::asio::ssl::verify_context& ctx) { ++bool verify_certificate(const char * hostname, bool preverified, websocketpp::lib::asio::ssl::verify_context& ctx) { + // The verify callback can be used to check whether the certificate that is + // being presented is valid for the peer. For example, RFC 2818 describes + // the steps involved in doing this for HTTPS. Consult the OpenSSL +@@ -176,16 +176,16 @@ bool verify_certificate(const char * hostname, bool preverified, boost::asio::ss + * (websocketpp.org, for example). + */ + context_ptr on_tls_init(const char * hostname, websocketpp::connection_hdl) { +- context_ptr ctx = websocketpp::lib::make_shared(boost::asio::ssl::context::sslv23); ++ context_ptr ctx = websocketpp::lib::make_shared(websocketpp::lib::asio::ssl::context::sslv23); + + try { +- ctx->set_options(boost::asio::ssl::context::default_workarounds | +- boost::asio::ssl::context::no_sslv2 | +- boost::asio::ssl::context::no_sslv3 | +- boost::asio::ssl::context::single_dh_use); ++ ctx->set_options(websocketpp::lib::asio::ssl::context::default_workarounds | ++ websocketpp::lib::asio::ssl::context::no_sslv2 | ++ websocketpp::lib::asio::ssl::context::no_sslv3 | ++ websocketpp::lib::asio::ssl::context::single_dh_use); + + +- ctx->set_verify_mode(boost::asio::ssl::verify_peer); ++ ctx->set_verify_mode(websocketpp::lib::asio::ssl::verify_peer); + ctx->set_verify_callback(bind(&verify_certificate, hostname, ::_1, ::_2)); + + // Here we load the CA certificates of all CA's that this client trusts. +diff --git a/examples/testee_server/testee_server.cpp b/examples/testee_server/testee_server.cpp +index 13e574e..8920270 100644 +--- a/examples/testee_server/testee_server.cpp ++++ b/examples/testee_server/testee_server.cpp +@@ -87,8 +87,8 @@ void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) { + s->send(hdl, msg->get_payload(), msg->get_opcode()); + } + +-void on_socket_init(websocketpp::connection_hdl, boost::asio::ip::tcp::socket & s) { +- boost::asio::ip::tcp::no_delay option(true); ++void on_socket_init(websocketpp::connection_hdl, websocketpp::lib::asio::ip::tcp::socket & s) { ++ websocketpp::lib::asio::ip::tcp::no_delay option(true); + s.set_option(option); + } + +diff --git a/test/endpoint/endpoint.cpp b/test/endpoint/endpoint.cpp +index fa58e66..c5f5a82 100644 +--- a/test/endpoint/endpoint.cpp ++++ b/test/endpoint/endpoint.cpp +@@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE( initialize_server_asio ) { + + BOOST_AUTO_TEST_CASE( initialize_server_asio_external ) { + websocketpp::server s; +- boost::asio::io_context ios; ++ websocketpp::lib::asio::io_context ios; + s.init_asio(&ios); + } + +@@ -141,8 +141,8 @@ BOOST_AUTO_TEST_CASE( listen_after_listen_failure ) { + server1.init_asio(); + server2.init_asio(); + +- boost::asio::ip::tcp::endpoint ep1(boost::asio::ip::make_address("127.0.0.1"), 12345); +- boost::asio::ip::tcp::endpoint ep2(boost::asio::ip::make_address("127.0.0.1"), 23456); ++ websocketpp::lib::asio::ip::tcp::endpoint ep1(websocketpp::lib::asio::ip::make_address("127.0.0.1"), 12345); ++ websocketpp::lib::asio::ip::tcp::endpoint ep2(websocketpp::lib::asio::ip::make_address("127.0.0.1"), 23456); + + server1.listen(ep1, ec); + BOOST_CHECK(!ec); +diff --git a/test/http/parser_perf.cpp b/test/http/parser_perf.cpp +index 0c76bc7..0a9cc0b 100644 +--- a/test/http/parser_perf.cpp ++++ b/test/http/parser_perf.cpp +@@ -31,11 +31,11 @@ + + class scoped_timer { + public: +- scoped_timer(std::string i) : m_id(i),m_start(std::chrono::steady_clock::now()) { ++ scoped_timer(std::string i) : m_id(i),m_start(timer_ptr::element_type::clock_type::now()) { + std::cout << "Clock " << i << ": "; + } + ~scoped_timer() { +- std::chrono::nanoseconds time_taken = std::chrono::steady_clock::now()-m_start; ++ std::chrono::nanoseconds time_taken = timer_ptr::element_type::clock_type::now()-m_start; + + //nanoseconds_per_test + +diff --git a/test/transport/asio/timers.cpp b/test/transport/asio/timers.cpp +index 391b755..d59654d 100644 +--- a/test/transport/asio/timers.cpp ++++ b/test/transport/asio/timers.cpp +@@ -106,9 +106,9 @@ struct config { + }; + + // Mock context that does no validation +-typedef websocketpp::lib::shared_ptr context_ptr; ++typedef websocketpp::lib::shared_ptr context_ptr; + context_ptr on_tls_init(websocketpp::connection_hdl) { +- return context_ptr(new boost::asio::ssl::context(boost::asio::ssl::context::sslv23)); ++ return context_ptr(new websocketpp::lib::asio::ssl::context(websocketpp::lib::asio::ssl::context::sslv23)); + } + + // Mock connection +diff --git a/test/transport/integration.cpp b/test/transport/integration.cpp +index ab82b1a..526b243 100644 +--- a/test/transport/integration.cpp ++++ b/test/transport/integration.cpp +@@ -38,6 +38,8 @@ + #include + #include + ++#include "boost/date_time/posix_time/posix_time.hpp" ++ + struct config : public websocketpp::config::asio_client { + typedef config type; + typedef websocketpp::config::asio base; +@@ -218,19 +220,19 @@ void run_time_limited_client(client & c, std::string uri, long timeout, + } + + void run_dummy_server(int port) { +- using boost::asio::ip::tcp; ++ using websocketpp::lib::asio::ip::tcp; + + try { +- boost::asio::io_context io_context; ++ websocketpp::lib::asio::io_context io_context; + tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v6(), port)); + tcp::socket socket(io_context); + + acceptor.accept(socket); + for (;;) { + char data[512]; +- boost::system::error_code ec; +- socket.read_some(boost::asio::buffer(data), ec); +- if (ec == boost::asio::error::eof) { ++ websocketpp::lib::asio::error_code ec; ++ socket.read_some(websocketpp::lib::asio::buffer(data), ec); ++ if (ec == websocketpp::lib::asio::error::eof) { + break; + } else if (ec) { + // other error +@@ -239,26 +241,26 @@ void run_dummy_server(int port) { + } + } catch (std::exception & e) { + std::cout << e.what() << std::endl; +- } catch (boost::system::error_code & ec) { ++ } catch (websocketpp::lib::asio::error_code & ec) { + std::cout << ec.message() << std::endl; + } + } + + void run_dummy_client(std::string port) { +- using boost::asio::ip::tcp; ++ using websocketpp::lib::asio::ip::tcp; + + try { +- boost::asio::io_context io_context; ++ websocketpp::lib::asio::io_context io_context; + tcp::resolver resolver(io_context); + tcp::resolver::results_type endpoints = resolver.resolve("localhost", port); + tcp::socket socket(io_context); + +- boost::asio::connect(socket, endpoints); ++ websocketpp::lib::asio::connect(socket, endpoints); + for (;;) { + char data[512]; +- boost::system::error_code ec; +- socket.read_some(boost::asio::buffer(data), ec); +- if (ec == boost::asio::error::eof) { ++ websocketpp::lib::asio::error_code ec; ++ socket.read_some(websocketpp::lib::asio::buffer(data), ec); ++ if (ec == websocketpp::lib::asio::error::eof) { + break; + } else if (ec) { + // other error +@@ -267,7 +269,7 @@ void run_dummy_client(std::string port) { + } + } catch (std::exception & e) { + std::cout << e.what() << std::endl; +- } catch (boost::system::error_code & ec) { ++ } catch (websocketpp::lib::asio::error_code & ec) { + std::cout << ec.message() << std::endl; + } + } +@@ -360,7 +362,7 @@ public: + : m_timer(m_io_context, boost::posix_time::seconds(seconds)) + { + m_timer.async_wait(bind(&test_deadline_timer::expired, this, ::_1)); +- std::size_t (boost::asio::io_context::*run)() = &boost::asio::io_context::run; ++ std::size_t (websocketpp::lib::asio::io_context::*run)() = &websocketpp::lib::asio::io_context::run; + m_timer_thread = websocketpp::lib::thread(websocketpp::lib::bind(run, &m_io_context)); + } + ~test_deadline_timer() +@@ -370,16 +372,16 @@ public: + } + + private: +- void expired(const boost::system::error_code & ec) ++ void expired(const websocketpp::lib::asio::error_code & ec) + { +- if (ec == boost::asio::error::operation_aborted) ++ if (ec == websocketpp::lib::asio::error::operation_aborted) + return; + BOOST_CHECK(!ec); + BOOST_FAIL("Test timed out"); + } + +- boost::asio::io_context m_io_context; +- boost::asio::deadline_timer m_timer; ++ websocketpp::lib::asio::io_context m_io_context; ++ websocketpp::lib::asio::deadline_timer m_timer; + websocketpp::lib::thread m_timer_thread; + }; + +diff --git a/websocketpp/common/asio.hpp b/websocketpp/common/asio.hpp +index 3c8fa13..7322c25 100644 +--- a/websocketpp/common/asio.hpp ++++ b/websocketpp/common/asio.hpp +@@ -51,7 +51,7 @@ + + #include + #include +- #include ++ #include + #else + #include + +diff --git a/websocketpp/transport/asio/connection.hpp b/websocketpp/transport/asio/connection.hpp +index eaee6bc..d1a2c20 100644 +--- a/websocketpp/transport/asio/connection.hpp ++++ b/websocketpp/transport/asio/connection.hpp +@@ -374,7 +374,7 @@ public: + * fail handler is called. + * + * Primarily used if you are using mismatched asio / system_error +- * implementations such as `boost::asio` with `std::system_error`. In these ++ * implementations such as `lib::asio` with `std::system_error`. In these + * cases the transport error type is different than the library error type + * and some WebSocket++ functions that return transport errors via the + * library error code type will be coerced into a catch all `pass_through` +@@ -573,7 +573,7 @@ protected: + lib::error_code const & ec) + { + if (ec == transport::error::operation_aborted || +- (post_timer && lib::asio::is_neg(post_timer->expiry() - std::chrono::steady_clock::now()))) ++ (post_timer && lib::asio::is_neg(post_timer->expiry() - timer_ptr::element_type::clock_type::now()))) + { + m_alog->write(log::alevel::devel,"post_init cancelled"); + return; +@@ -679,7 +679,7 @@ protected: + // Whatever aborted it will be issuing the callback so we are safe to + // return + if (ec == lib::asio::error::operation_aborted || +- lib::asio::is_neg(m_proxy_data->timer->expiry() - std::chrono::steady_clock::now())) ++ lib::asio::is_neg(m_proxy_data->timer->expiry() - timer_ptr::element_type::clock_type::now())) + { + m_elog->write(log::elevel::devel,"write operation aborted"); + return; +@@ -751,7 +751,7 @@ protected: + // Whatever aborted it will be issuing the callback so we are safe to + // return + if (ec == lib::asio::error::operation_aborted || +- lib::asio::is_neg(m_proxy_data->timer->expiry() - std::chrono::steady_clock::now())) ++ lib::asio::is_neg(m_proxy_data->timer->expiry() - timer_ptr::element_type::clock_type::now())) + { + m_elog->write(log::elevel::devel,"read operation aborted"); + return; +@@ -1012,18 +1012,18 @@ protected: + */ + lib::error_code interrupt(interrupt_handler handler) { + if (config::enable_multithreading) { +- boost::asio::post(m_io_context->get_executor(), m_strand->wrap(handler)); ++ lib::asio::post(m_io_context->get_executor(), m_strand->wrap(handler)); + } else { +- boost::asio::post(m_io_context->get_executor(), handler); ++ lib::asio::post(m_io_context->get_executor(), handler); + } + return lib::error_code(); + } + + lib::error_code dispatch(dispatch_handler handler) { + if (config::enable_multithreading) { +- boost::asio::post(m_io_context->get_executor(), m_strand->wrap(handler)); ++ lib::asio::post(m_io_context->get_executor(), m_strand->wrap(handler)); + } else { +- boost::asio::post(m_io_context->get_executor(), handler); ++ lib::asio::post(m_io_context->get_executor(), handler); + } + return lib::error_code(); + } +@@ -1095,7 +1095,7 @@ protected: + callback, lib::asio::error_code const & ec) + { + if (ec == lib::asio::error::operation_aborted || +- lib::asio::is_neg(shutdown_timer->expiry() - std::chrono::steady_clock::now())) ++ lib::asio::is_neg(shutdown_timer->expiry() - timer_ptr::element_type::clock_type::now())) + { + m_alog->write(log::alevel::devel,"async_shutdown cancelled"); + return; +diff --git a/websocketpp/transport/asio/endpoint.hpp b/websocketpp/transport/asio/endpoint.hpp +index 7af0915..57f784f 100644 +--- a/websocketpp/transport/asio/endpoint.hpp ++++ b/websocketpp/transport/asio/endpoint.hpp +@@ -967,7 +967,7 @@ protected: + lib::asio::ip::tcp::resolver::results_type endpoints) + { + if (ec == lib::asio::error::operation_aborted || +- lib::asio::is_neg(dns_timer->expiry() - std::chrono::steady_clock::now())) ++ lib::asio::is_neg(dns_timer->expiry() - timer_ptr::element_type::clock_type::now())) + { + m_alog->write(log::alevel::devel,"async_resolve cancelled"); + return; +@@ -1075,7 +1075,7 @@ protected: + connect_handler callback, lib::asio::error_code const & ec) + { + if (ec == lib::asio::error::operation_aborted || +- lib::asio::is_neg(con_timer->expiry() - std::chrono::steady_clock::now())) ++ lib::asio::is_neg(con_timer->expiry() - timer_ptr::element_type::clock_type::now())) + { + m_alog->write(log::alevel::devel,"async_connect cancelled"); + return; +-- +2.48.1 + + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Amini Allight +Date: Fri, 14 Feb 2025 23:13:38 +0000 +Subject: [PATCH 5/7] improved variable names and fixed comments + +(cherry picked from commit dbdde20a9b4ffd49f480fd9e6e29ea212a73253b) + + Conflicts: + websocketpp/transport/asio/endpoint.hpp +--- + .../echo_server_both/echo_server_both.cpp | 8 +++--- + test/endpoint/endpoint.cpp | 4 +-- + test/transport/asio/timers.cpp | 4 +-- + test/transport/integration.cpp | 4 +-- + websocketpp/transport/asio/connection.hpp | 2 +- + websocketpp/transport/asio/endpoint.hpp | 27 +++++++++---------- + 6 files changed, 24 insertions(+), 25 deletions(-) + +diff --git a/examples/echo_server_both/echo_server_both.cpp b/examples/echo_server_both/echo_server_both.cpp +index a4f6a19..886ea7f 100644 +--- a/examples/echo_server_both/echo_server_both.cpp ++++ b/examples/echo_server_both/echo_server_both.cpp +@@ -60,12 +60,12 @@ context_ptr on_tls_init(websocketpp::connection_hdl hdl) { + int main() { + // set up an external io_context to run both endpoints on. This is not + // strictly necessary, but simplifies thread management a bit. +- websocketpp::lib::asio::io_context ios; ++ websocketpp::lib::asio::io_context ctx; + + // set up plain endpoint + server_plain endpoint_plain; + // initialize asio with our external io_context rather than an internal one +- endpoint_plain.init_asio(&ios); ++ endpoint_plain.init_asio(&ctx); + endpoint_plain.set_message_handler( + bind(&on_message,&endpoint_plain,::_1,::_2)); + endpoint_plain.listen(80); +@@ -73,7 +73,7 @@ int main() { + + // set up tls endpoint + server_tls endpoint_tls; +- endpoint_tls.init_asio(&ios); ++ endpoint_tls.init_asio(&ctx); + endpoint_tls.set_message_handler( + bind(&on_message,&endpoint_tls,::_1,::_2)); + // TLS endpoint has an extra handler for the tls init +@@ -83,5 +83,5 @@ int main() { + endpoint_tls.start_accept(); + + // Start the ASIO io_context run loop running both endpoints +- ios.run(); ++ ctx.run(); + } +diff --git a/test/endpoint/endpoint.cpp b/test/endpoint/endpoint.cpp +index c5f5a82..1840278 100644 +--- a/test/endpoint/endpoint.cpp ++++ b/test/endpoint/endpoint.cpp +@@ -53,8 +53,8 @@ BOOST_AUTO_TEST_CASE( initialize_server_asio ) { + + BOOST_AUTO_TEST_CASE( initialize_server_asio_external ) { + websocketpp::server s; +- websocketpp::lib::asio::io_context ios; +- s.init_asio(&ios); ++ websocketpp::lib::asio::io_context ctx; ++ s.init_asio(&ctx); + } + + #ifdef _WEBSOCKETPP_MOVE_SEMANTICS_ +diff --git a/test/transport/asio/timers.cpp b/test/transport/asio/timers.cpp +index d59654d..84938cb 100644 +--- a/test/transport/asio/timers.cpp ++++ b/test/transport/asio/timers.cpp +@@ -79,8 +79,8 @@ void run_dummy_server(int port) { + + // Wait for the specified time period then fail the test + void run_test_timer(long value) { +- boost::asio::io_context ios; +- boost::asio::deadline_timer t(ios,boost::posix_time::milliseconds(value)); ++ boost::asio::io_context ctx; ++ boost::asio::deadline_timer t(ctx,boost::posix_time::milliseconds(value)); + boost::system::error_code ec; + t.wait(ec); + BOOST_FAIL( "Test timed out" ); +diff --git a/test/transport/integration.cpp b/test/transport/integration.cpp +index 526b243..371c554 100644 +--- a/test/transport/integration.cpp ++++ b/test/transport/integration.cpp +@@ -252,10 +252,10 @@ void run_dummy_client(std::string port) { + try { + websocketpp::lib::asio::io_context io_context; + tcp::resolver resolver(io_context); +- tcp::resolver::results_type endpoints = resolver.resolve("localhost", port); ++ tcp::resolver::results_type results = resolver.resolve("localhost", port); + tcp::socket socket(io_context); + +- websocketpp::lib::asio::connect(socket, endpoints); ++ websocketpp::lib::asio::connect(socket, results); + for (;;) { + char data[512]; + websocketpp::lib::asio::error_code ec; +diff --git a/websocketpp/transport/asio/connection.hpp b/websocketpp/transport/asio/connection.hpp +index d1a2c20..f4c13f3 100644 +--- a/websocketpp/transport/asio/connection.hpp ++++ b/websocketpp/transport/asio/connection.hpp +@@ -374,7 +374,7 @@ public: + * fail handler is called. + * + * Primarily used if you are using mismatched asio / system_error +- * implementations such as `lib::asio` with `std::system_error`. In these ++ * implementations such as `boost::asio` with `std::system_error`. In these + * cases the transport error type is different than the library error type + * and some WebSocket++ functions that return transport errors via the + * library error code type will be coerced into a catch all `pass_through` +diff --git a/websocketpp/transport/asio/endpoint.hpp b/websocketpp/transport/asio/endpoint.hpp +index 57f784f..2aafd67 100644 +--- a/websocketpp/transport/asio/endpoint.hpp ++++ b/websocketpp/transport/asio/endpoint.hpp +@@ -86,7 +86,7 @@ public: + /// Type of timer handle + typedef lib::shared_ptr timer_ptr; + /// Type of a shared pointer to an io_context work object +- typedef lib::shared_ptr> work_ptr; ++ typedef lib::shared_ptr> work_guard_ptr; + + /// Type of socket pre-bind handler + typedef lib::function tcp_pre_bind_handler; +@@ -108,7 +108,7 @@ public: + // Explicitly destroy local objects + m_acceptor.reset(); + m_resolver.reset(); +- m_work.reset(); ++ m_work_guard.reset(); + if (m_state != UNINITIALIZED && !m_external_io_context) { + delete m_io_context; + } +@@ -541,8 +541,7 @@ public: + /** + * Bind the internal acceptor using the given host and service. More details + * about what host and service can be are available in the Asio +- * documentation for ip::basic_resolver_query::basic_resolver_query's +- * constructors. ++ * documentation for the ip::basic_resolver::resolve function. + * + * The endpoint must have been initialized by calling init_asio before + * listening. +@@ -558,14 +557,14 @@ public: + { + using lib::asio::ip::tcp; + tcp::resolver r(*m_io_context); +- tcp::resolver::results_type endpoints = r.resolve(host, service); +- if (endpoints.empty()) { ++ tcp::resolver::results_type results = r.resolve(host, service); ++ if (results.empty()) { + m_elog->write(log::elevel::library, + "asio::listen could not resolve the supplied host or service"); + ec = make_error_code(error::invalid_host_service); + return; + } +- listen(*endpoints.begin(),ec); ++ listen(*(results.begin()),ec); + } + + /// Set up endpoint for listening on a host and service +@@ -685,7 +684,7 @@ public: + * @since 0.3.0 + */ + void start_perpetual() { +- m_work.reset(new lib::asio::executor_work_guard(m_io_context->get_executor())); ++ m_work_guard.reset(new lib::asio::executor_work_guard(m_io_context->get_executor())); + } + + /// Clears the endpoint's perpetual flag, allowing it to exit when empty +@@ -697,7 +696,7 @@ public: + * @since 0.3.0 + */ + void stop_perpetual() { +- m_work.reset(); ++ m_work_guard.reset(); + } + + /// Call back a function after a period of time. +@@ -964,7 +963,7 @@ protected: + + void handle_resolve(transport_con_ptr tcon, timer_ptr dns_timer, + connect_handler callback, lib::asio::error_code const & ec, +- lib::asio::ip::tcp::resolver::results_type endpoints) ++ lib::asio::ip::tcp::resolver::results_type results) + { + if (ec == lib::asio::error::operation_aborted || + lib::asio::is_neg(dns_timer->expiry() - timer_ptr::element_type::clock_type::now())) +@@ -986,7 +985,7 @@ protected: + s << "Async DNS resolve successful. Results: "; + + lib::asio::ip::tcp::resolver::results_type::iterator it; +- for (it = endpoints.begin(); it != endpoints.end(); ++it) { ++ for (it = results.begin(); it != results.end(); ++it) { + s << (*it).endpoint() << " "; + } + +@@ -1012,7 +1011,7 @@ protected: + if (config::enable_multithreading) { + lib::asio::async_connect( + tcon->get_raw_socket(), +- endpoints, ++ results, + tcon->get_strand()->wrap(lib::bind( + &type::handle_connect, + this, +@@ -1025,7 +1024,7 @@ protected: + } else { + lib::asio::async_connect( + tcon->get_raw_socket(), +- endpoints, ++ results, + lib::bind( + &type::handle_connect, + this, +@@ -1160,7 +1159,7 @@ private: + bool m_external_io_context; + acceptor_ptr m_acceptor; + resolver_ptr m_resolver; +- work_ptr m_work; ++ work_guard_ptr m_work_guard; + + // Network constants + int m_listen_backlog; +-- +2.48.1 + + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Amini Allight +Date: Thu, 20 Feb 2025 06:19:46 +0000 +Subject: [PATCH 6/7] fixed use of deprecated boost::asio::deadline_timer in + tests + +(cherry picked from commit 096487461fe834c30fb322ac0b9088ad82e5a2d5) +--- + test/transport/asio/timers.cpp | 3 ++- + test/transport/integration.cpp | 27 ++++++++++++++------------- + 2 files changed, 16 insertions(+), 14 deletions(-) + +diff --git a/test/transport/asio/timers.cpp b/test/transport/asio/timers.cpp +index 84938cb..22a4bba 100644 +--- a/test/transport/asio/timers.cpp ++++ b/test/transport/asio/timers.cpp +@@ -80,7 +80,8 @@ void run_dummy_server(int port) { + // Wait for the specified time period then fail the test + void run_test_timer(long value) { + boost::asio::io_context ctx; +- boost::asio::deadline_timer t(ctx,boost::posix_time::milliseconds(value)); ++ boost::asio::system_timer t(ctx); ++ t.expires_after(std::chrono::milliseconds(value)); + boost::system::error_code ec; + t.wait(ec); + BOOST_FAIL( "Test timed out" ); +diff --git a/test/transport/integration.cpp b/test/transport/integration.cpp +index 371c554..70f4442 100644 +--- a/test/transport/integration.cpp ++++ b/test/transport/integration.cpp +@@ -355,17 +355,18 @@ void close(T * e, websocketpp::connection_hdl hdl) { + e->get_con_from_hdl(hdl)->close(websocketpp::close::status::normal,""); + } + +-class test_deadline_timer ++class test_system_timer + { + public: +- test_deadline_timer(int seconds) +- : m_timer(m_io_context, boost::posix_time::seconds(seconds)) ++ test_system_timer(int seconds) ++ : m_timer(m_io_context) + { +- m_timer.async_wait(bind(&test_deadline_timer::expired, this, ::_1)); ++ m_timer.expires_after(std::chrono::seconds(seconds)); ++ m_timer.async_wait(bind(&test_system_timer::expired, this, ::_1)); + std::size_t (websocketpp::lib::asio::io_context::*run)() = &websocketpp::lib::asio::io_context::run; + m_timer_thread = websocketpp::lib::thread(websocketpp::lib::bind(run, &m_io_context)); + } +- ~test_deadline_timer() ++ ~test_system_timer() + { + m_timer.cancel(); + m_timer_thread.join(); +@@ -381,7 +382,7 @@ public: + } + + websocketpp::lib::asio::io_context m_io_context; +- websocketpp::lib::asio::deadline_timer m_timer; ++ websocketpp::lib::asio::system_timer m_timer; + websocketpp::lib::thread m_timer_thread; + }; + +@@ -427,7 +428,7 @@ BOOST_AUTO_TEST_CASE( pong_timeout ) { + websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false)); + sleep(1); // give the server thread some time to start + +- test_deadline_timer deadline(10); ++ test_system_timer deadline(10); + + run_client(c, "http://localhost:9005",false); + +@@ -448,7 +449,7 @@ BOOST_AUTO_TEST_CASE( client_open_handshake_timeout ) { + + sleep(1); // give the server thread some time to start + +- test_deadline_timer deadline(10); ++ test_system_timer deadline(10); + + run_client(c, "http://localhost:9005"); + } +@@ -464,7 +465,7 @@ BOOST_AUTO_TEST_CASE( server_open_handshake_timeout ) { + + websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false)); + +- test_deadline_timer deadline(10); ++ test_system_timer deadline(10); + + sleep(1); // give the server thread some time to start + +@@ -489,7 +490,7 @@ BOOST_AUTO_TEST_CASE( client_self_initiated_close_handshake_timeout ) { + + websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false)); + +- test_deadline_timer deadline(10); ++ test_system_timer deadline(10); + + sleep(1); // give the server thread some time to start + +@@ -522,7 +523,7 @@ BOOST_AUTO_TEST_CASE( server_self_initiated_close_handshake_timeout ) { + c.set_open_handler(bind(&delay,::_1,1)); + + websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false)); +- test_deadline_timer deadline(10); ++ test_system_timer deadline(10); + + sleep(1); // give the server thread some time to start + +@@ -534,7 +535,7 @@ BOOST_AUTO_TEST_CASE( server_self_initiated_close_handshake_timeout ) { + BOOST_AUTO_TEST_CASE( client_runs_out_of_work ) { + client c; + +- test_deadline_timer deadline(3); ++ test_system_timer deadline(3); + + websocketpp::lib::error_code ec; + c.init_asio(ec); +@@ -600,7 +601,7 @@ BOOST_AUTO_TEST_CASE( stop_listening ) { + c.set_open_handler(bind(&close,&c,::_1)); + + websocketpp::lib::thread sthread(websocketpp::lib::bind(&run_server,&s,9005,false)); +- test_deadline_timer deadline(5); ++ test_system_timer deadline(5); + + sleep(1); // give the server thread some time to start + +-- +2.48.1 + + +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Amini Allight +Date: Thu, 20 Feb 2025 17:25:03 +0000 +Subject: [PATCH 7/7] replaced uses of boost::asio::io_context::strand::wrap + with boost::asio::bind_executor to avoid future deprecation issues + +(cherry picked from commit a11fa6fe4937ca251753e90b1836a68bf57768a9) +--- + websocketpp/transport/asio/connection.hpp | 16 ++++++++-------- + websocketpp/transport/asio/endpoint.hpp | 6 +++--- + websocketpp/transport/asio/security/tls.hpp | 4 ++-- + 3 files changed, 13 insertions(+), 13 deletions(-) + +diff --git a/websocketpp/transport/asio/connection.hpp b/websocketpp/transport/asio/connection.hpp +index f4c13f3..4baa2ea 100644 +--- a/websocketpp/transport/asio/connection.hpp ++++ b/websocketpp/transport/asio/connection.hpp +@@ -318,7 +318,7 @@ public: + ); + + if (config::enable_multithreading) { +- new_timer->async_wait(m_strand->wrap(lib::bind( ++ new_timer->async_wait(lib::asio::bind_executor(*m_strand, lib::bind( + &type::handle_timer, get_shared(), + new_timer, + callback, +@@ -629,7 +629,7 @@ protected: + lib::asio::async_write( + socket_con_type::get_next_layer(), + m_bufs, +- m_strand->wrap(lib::bind( ++ lib::asio::bind_executor(*m_strand, lib::bind( + &type::handle_proxy_write, get_shared(), + callback, + lib::placeholders::_1 +@@ -713,7 +713,7 @@ protected: + socket_con_type::get_next_layer(), + m_proxy_data->read_buf, + "\r\n\r\n", +- m_strand->wrap(lib::bind( ++ lib::asio::bind_executor(*m_strand, lib::bind( + &type::handle_proxy_read, get_shared(), + callback, + lib::placeholders::_1, lib::placeholders::_2 +@@ -841,7 +841,7 @@ protected: + socket_con_type::get_socket(), + lib::asio::buffer(buf,len), + lib::asio::transfer_at_least(num_bytes), +- m_strand->wrap(make_custom_alloc_handler( ++ lib::asio::bind_executor(*m_strand, make_custom_alloc_handler( + m_read_handler_allocator, + lib::bind( + &type::handle_async_read, get_shared(), +@@ -910,7 +910,7 @@ protected: + lib::asio::async_write( + socket_con_type::get_socket(), + m_bufs, +- m_strand->wrap(make_custom_alloc_handler( ++ lib::asio::bind_executor(*m_strand, make_custom_alloc_handler( + m_write_handler_allocator, + lib::bind( + &type::handle_async_write, get_shared(), +@@ -947,7 +947,7 @@ protected: + lib::asio::async_write( + socket_con_type::get_socket(), + m_bufs, +- m_strand->wrap(make_custom_alloc_handler( ++ lib::asio::bind_executor(*m_strand, make_custom_alloc_handler( + m_write_handler_allocator, + lib::bind( + &type::handle_async_write, get_shared(), +@@ -1012,7 +1012,7 @@ protected: + */ + lib::error_code interrupt(interrupt_handler handler) { + if (config::enable_multithreading) { +- lib::asio::post(m_io_context->get_executor(), m_strand->wrap(handler)); ++ lib::asio::post(m_io_context->get_executor(), lib::asio::bind_executor(*m_strand, handler)); + } else { + lib::asio::post(m_io_context->get_executor(), handler); + } +@@ -1021,7 +1021,7 @@ protected: + + lib::error_code dispatch(dispatch_handler handler) { + if (config::enable_multithreading) { +- lib::asio::post(m_io_context->get_executor(), m_strand->wrap(handler)); ++ lib::asio::post(m_io_context->get_executor(), lib::asio::bind_executor(*m_strand, handler)); + } else { + lib::asio::post(m_io_context->get_executor(), handler); + } +diff --git a/websocketpp/transport/asio/endpoint.hpp b/websocketpp/transport/asio/endpoint.hpp +index 2aafd67..b9e1ae8 100644 +--- a/websocketpp/transport/asio/endpoint.hpp ++++ b/websocketpp/transport/asio/endpoint.hpp +@@ -776,7 +776,7 @@ public: + if (config::enable_multithreading) { + m_acceptor->async_accept( + tcon->get_raw_socket(), +- tcon->get_strand()->wrap(lib::bind( ++ lib::asio::bind_executor(*tcon->get_strand(), lib::bind( + &type::handle_accept, + this, + callback, +@@ -902,7 +902,7 @@ protected: + m_resolver->async_resolve( + host, + port, +- tcon->get_strand()->wrap(lib::bind( ++ lib::asio::bind_executor(*tcon->get_strand(), lib::bind( + &type::handle_resolve, + this, + tcon, +@@ -1012,7 +1012,7 @@ protected: + lib::asio::async_connect( + tcon->get_raw_socket(), + results, +- tcon->get_strand()->wrap(lib::bind( ++ lib::asio::bind_executor(*tcon->get_strand(), lib::bind( + &type::handle_connect, + this, + tcon, +diff --git a/websocketpp/transport/asio/security/tls.hpp b/websocketpp/transport/asio/security/tls.hpp +index 8b27656..07651c0 100644 +--- a/websocketpp/transport/asio/security/tls.hpp ++++ b/websocketpp/transport/asio/security/tls.hpp +@@ -266,7 +266,7 @@ protected: + if (m_strand) { + m_socket->async_handshake( + get_handshake_type(), +- m_strand->wrap(lib::bind( ++ lib::asio::bind_executor(*m_strand, lib::bind( + &type::handle_init, get_shared(), + callback, + lib::placeholders::_1 +@@ -326,7 +326,7 @@ protected: + + void async_shutdown(socket::shutdown_handler callback) { + if (m_strand) { +- m_socket->async_shutdown(m_strand->wrap(callback)); ++ m_socket->async_shutdown(lib::asio::bind_executor(*m_strand, callback)); + } else { + m_socket->async_shutdown(callback); + } +-- +2.48.1 + diff --git a/tur/websocketpp/build.sh b/tur/websocketpp/build.sh new file mode 100644 index 0000000000..d4caf3d61f --- /dev/null +++ b/tur/websocketpp/build.sh @@ -0,0 +1,14 @@ +TERMUX_PKG_HOMEPAGE=https://www.zaphoyd.com/websocketpp/ +TERMUX_PKG_DESCRIPTION="C++/Boost Asio based websocket client/server library" +TERMUX_PKG_LICENSE="BSD" +TERMUX_PKG_MAINTAINER="@termux-user-repository" +TERMUX_PKG_VERSION=0.8.2 +TERMUX_PKG_SRCURL=https://github.com/zaphoyd/websocketpp/archive/${TERMUX_PKG_VERSION}.tar.gz +TERMUX_PKG_SHA256=6ce889d85ecdc2d8fa07408d6787e7352510750daa66b5ad44aacb47bea76755 +TERMUX_PKG_DEPENDS="libasio, openssl, zlib" +TERMUX_PKG_EXTRA_CONFIGURE_ARGS=" +-DENABLE_CPP11=ON +-DBUILD_EXAMPLES=OFF +-DBUILD_TESTS=OFF +-DCMAKE_POLICY_VERSION_MINIMUM=3.5 +" From 454069ceb5801f59842c35e04248aa8bb50aff1a Mon Sep 17 00:00:00 2001 From: lumaparallax <257510328+lumaparallax@users.noreply.github.com> Date: Sat, 25 Apr 2026 20:28:20 +0900 Subject: [PATCH 3/7] addpkg(libdatachannel): WebRTC Data Channels library --- tur/libdatachannel/build.sh | 47 +++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 tur/libdatachannel/build.sh diff --git a/tur/libdatachannel/build.sh b/tur/libdatachannel/build.sh new file mode 100644 index 0000000000..0399d86dd1 --- /dev/null +++ b/tur/libdatachannel/build.sh @@ -0,0 +1,47 @@ +TERMUX_PKG_HOMEPAGE=https://libdatachannel.org/ +TERMUX_PKG_DESCRIPTION="C/C++ WebRTC network library featuring Data Channels, Media Transport, and WebSockets" +TERMUX_PKG_LICENSE="MPL-2.0, MIT, BSD 3-Clause" +TERMUX_PKG_MAINTAINER="@termux-user-repository" +TERMUX_PKG_VERSION=( + "0.24.2" + "1.1.11" + "0.9.5.0" + "1.7.1" + "2.8.0" +) +TERMUX_PKG_SRCURL=( + "https://github.com/paullouisageneau/libdatachannel/archive/refs/tags/v${TERMUX_PKG_VERSION[0]}.tar.gz" + "https://github.com/SergiusTheBest/plog/archive/refs/tags/${TERMUX_PKG_VERSION[1]}.tar.gz" + "https://github.com/sctplab/usrsctp/archive/refs/tags/${TERMUX_PKG_VERSION[2]}.tar.gz" + "https://github.com/paullouisageneau/libjuice/archive/refs/tags/v${TERMUX_PKG_VERSION[3]}.tar.gz" + "https://github.com/cisco/libsrtp/archive/refs/tags/v${TERMUX_PKG_VERSION[4]}.tar.gz" +) +TERMUX_PKG_SHA256=( + 91a4795c98e13e91935127ab7880109309bf35b5e5a96c8fcc08e08322576402 + d60b8b35f56c7c852b7f00f58cbe9c1c2e9e59566c5b200512d0cdbb6309a7c2 + 260107caf318650a57a8caa593550e39bca6943e93f970c80d6c17e59d62cd92 + c127629ff42b9fffc06c65e94abb25fce03856160ce05d9fdfdad4ed80ea59bf + d123dcff5c56d4f1a9006f2b311ea99a85016cbf3bb24b1007885d422237db85 +) +TERMUX_PKG_DEPENDS="openssl" +TERMUX_PKG_BUILD_DEPENDS="nlohmann-json" +TERMUX_PKG_AUTO_UPDATE=false +TERMUX_PKG_EXTRA_CONFIGURE_ARGS=" +-DUSE_GNUTLS=OFF +-DUSE_NICE=OFF +-DNO_EXAMPLES=ON +-DNO_TESTS=ON +-DUSE_SYSTEM_JSON=ON +-DCMAKE_POLICY_VERSION_MINIMUM=3.5 +" + +termux_step_post_get_source() { + # Remove the empty placeholder folders + rm -rf deps/plog deps/usrsctp deps/libjuice deps/libsrtp + + # Move the extracted GitHub folders into their correct deps/ locations + mv "plog-${TERMUX_PKG_VERSION[1]}" deps/plog + mv "usrsctp-${TERMUX_PKG_VERSION[2]}" deps/usrsctp + mv "libjuice-${TERMUX_PKG_VERSION[3]}" deps/libjuice + mv "libsrtp-${TERMUX_PKG_VERSION[4]}" deps/libsrtp +} From 1300a70f7b8fd5b516e2c4c10902d9027f256e2c Mon Sep 17 00:00:00 2001 From: lumaparallax <257510328+lumaparallax@users.noreply.github.com> Date: Sat, 25 Apr 2026 20:53:21 +0900 Subject: [PATCH 4/7] addpkg(x11/obs-studio): Free and open source software for video recording and live streaming --- .../0001-android-build-compatabilty.patch | 133 ++++++++ tur/obs-studio/0002-system-info-android.patch | 175 ++++++++++ .../0003-fix-android-timespec.patch | 32 ++ .../0004-fix-file-path-specifics.patch | 65 ++++ tur/obs-studio/0005-egl-saftey-checks.patch | 41 +++ ...x-capture-switch-to-memfd-based-xshm.patch | 317 ++++++++++++++++++ ...7-disable-vaapi-and-its-dependencies.patch | 72 ++++ .../0008-relax-Qt-and-libvlc-versioning.patch | 46 +++ .../0009-fix-local-IP-detection.patch | 91 +++++ .../0010-fix-browser-and-its-submodule.patch | 56 ++++ tur/obs-studio/build.sh | 87 +++++ 11 files changed, 1115 insertions(+) create mode 100644 tur/obs-studio/0001-android-build-compatabilty.patch create mode 100644 tur/obs-studio/0002-system-info-android.patch create mode 100644 tur/obs-studio/0003-fix-android-timespec.patch create mode 100644 tur/obs-studio/0004-fix-file-path-specifics.patch create mode 100644 tur/obs-studio/0005-egl-saftey-checks.patch create mode 100644 tur/obs-studio/0006-linux-capture-switch-to-memfd-based-xshm.patch create mode 100644 tur/obs-studio/0007-disable-vaapi-and-its-dependencies.patch create mode 100644 tur/obs-studio/0008-relax-Qt-and-libvlc-versioning.patch create mode 100644 tur/obs-studio/0009-fix-local-IP-detection.patch create mode 100644 tur/obs-studio/0010-fix-browser-and-its-submodule.patch create mode 100644 tur/obs-studio/build.sh diff --git a/tur/obs-studio/0001-android-build-compatabilty.patch b/tur/obs-studio/0001-android-build-compatabilty.patch new file mode 100644 index 0000000000..51a9e55eb1 --- /dev/null +++ b/tur/obs-studio/0001-android-build-compatabilty.patch @@ -0,0 +1,133 @@ +From bab337368cb4af98ba86f96fb97bd11973358bba Mon Sep 17 00:00:00 2001 +From: lumaparallax <257510328+lumaparallax@users.noreply.github.com> +Date: Mon, 20 Apr 2026 20:19:17 +0900 +Subject: [PATCH 01/10] android-build-compatabilty + +--- + CMakeLists.txt | 10 ++++++++++ + cmake/common/compiler_common.cmake | 6 +++++- + cmake/common/osconfig.cmake | 11 ++++++++--- + cmake/linux/compilerconfig.cmake | 10 ++++++++++ + frontend/cmake/os-linux.cmake | 6 ++++-- + plugins/CMakeLists.txt | 4 +++- + 6 files changed, 40 insertions(+), 7 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 4af6f90b7..22daf3e67 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -4,6 +4,16 @@ include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/common/bootstrap.cmake" NO_POLICY_SCO + + project(obs-studio VERSION ${OBS_VERSION_CANONICAL}) + ++# OBS subdirectories and Find*.cmake modules often strictly check for "Linux". ++if(CMAKE_SYSTEM_NAME MATCHES "Android" OR CMAKE_HOST_SYSTEM_NAME MATCHES "Android") ++ message(STATUS "Android platform detected. Enforcing Linux build paths.") ++ set(CMAKE_SYSTEM_NAME "Linux") ++ set(CMAKE_HOST_SYSTEM_NAME "Linux") ++ set(OS_LINUX TRUE) ++ set(OS_POSIX TRUE) ++ set(OS_ANDROID TRUE) ++endif() ++ + if(CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") + include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/windows/architecture.cmake") + if(NOT OBS_PARENT_ARCHITECTURE STREQUAL CMAKE_VS_PLATFORM_NAME) +diff --git a/cmake/common/compiler_common.cmake b/cmake/common/compiler_common.cmake +index f6b9dd36f..bcb522b39 100644 +--- a/cmake/common/compiler_common.cmake ++++ b/cmake/common/compiler_common.cmake +@@ -83,7 +83,11 @@ if(CMAKE_CXX_STANDARD GREATER_EQUAL 20) + endif() + + if(NOT DEFINED CMAKE_COMPILE_WARNING_AS_ERROR) +- set(CMAKE_COMPILE_WARNING_AS_ERROR ON) ++ if(OS_ANDROID) ++ set(CMAKE_COMPILE_WARNING_AS_ERROR OFF) ++ else() ++ set(CMAKE_COMPILE_WARNING_AS_ERROR ON) ++ endif() + endif() + + # Enable interprocedural optimization +diff --git a/cmake/common/osconfig.cmake b/cmake/common/osconfig.cmake +index 2dc6dedb8..2c765d35b 100644 +--- a/cmake/common/osconfig.cmake ++++ b/cmake/common/osconfig.cmake +@@ -12,9 +12,14 @@ elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") + set(CMAKE_CXX_EXTENSIONS FALSE) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos") + set(OS_MACOS TRUE) +-elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD|OpenBSD") ++elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD|OpenBSD|Android") + set(CMAKE_CXX_EXTENSIONS FALSE) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/linux") +- string(TOUPPER "${CMAKE_HOST_SYSTEM_NAME}" _SYSTEM_NAME_U) +- set(OS_${_SYSTEM_NAME_U} TRUE) ++ if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android") ++ set(OS_LINUX TRUE) ++ set(OS_ANDROID TRUE) ++ else() ++ string(TOUPPER "${CMAKE_HOST_SYSTEM_NAME}" _SYSTEM_NAME_U) ++ set(OS_${_SYSTEM_NAME_U} TRUE) ++ endif() + endif() +diff --git a/cmake/linux/compilerconfig.cmake b/cmake/linux/compilerconfig.cmake +index 3f4d45e4d..53bd28c82 100644 +--- a/cmake/linux/compilerconfig.cmake ++++ b/cmake/linux/compilerconfig.cmake +@@ -85,3 +85,13 @@ else() + endif() + + add_compile_definitions($<$:DEBUG> $<$:_DEBUG> SIMDE_ENABLE_OPENMP) ++ ++if(OS_ANDROID OR CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64") ++ add_compile_options(-fPIC) ++ add_compile_options(-ftls-model=global-dynamic) ++ if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.13) ++ add_link_options(-fPIC) ++ else() ++ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fPIC") ++ endif() ++endif() +diff --git a/frontend/cmake/os-linux.cmake b/frontend/cmake/os-linux.cmake +index d146e7297..0aa18d558 100644 +--- a/frontend/cmake/os-linux.cmake ++++ b/frontend/cmake/os-linux.cmake +@@ -16,8 +16,10 @@ if(Qt6_VERSION AND Qt6_VERSION VERSION_LESS "6.9.0") + target_link_libraries(obs-studio PRIVATE Qt::GuiPrivate) + endif() + +-find_package(Libpci REQUIRED) +-target_link_libraries(obs-studio PRIVATE Libpci::pci) ++if(NOT OS_ANDROID) ++ find_package(Libpci REQUIRED) ++ target_link_libraries(obs-studio PRIVATE Libpci::pci) ++endif() + + if(TARGET OBS::python) + find_package(Python REQUIRED COMPONENTS Interpreter Development) +diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt +index c12f015c8..5f540bd77 100644 +--- a/plugins/CMakeLists.txt ++++ b/plugins/CMakeLists.txt +@@ -61,13 +61,15 @@ check_obs_browser() + add_obs_plugin(obs-ffmpeg) + add_obs_plugin(obs-filters) + add_obs_plugin(obs-libfdk) +-add_obs_plugin(obs-nvenc PLATFORMS WINDOWS LINUX ARCHITECTURES x64 x86_64) + add_obs_plugin(obs-outputs) ++if (NOT OS_ANDROID) ++add_obs_plugin(obs-nvenc PLATFORMS WINDOWS LINUX ARCHITECTURES x64 x86_64) + add_obs_plugin( + obs-qsv11 + PLATFORMS WINDOWS LINUX + ARCHITECTURES x64 x86_64 + ) ++endif() + add_obs_plugin(obs-text PLATFORMS WINDOWS) + add_obs_plugin(obs-transitions) + add_obs_plugin( +-- +2.54.0 + diff --git a/tur/obs-studio/0002-system-info-android.patch b/tur/obs-studio/0002-system-info-android.patch new file mode 100644 index 0000000000..c1e5b2b2ad --- /dev/null +++ b/tur/obs-studio/0002-system-info-android.patch @@ -0,0 +1,175 @@ +From 44346c3ee23bddb477f507882c55a120fce7aee4 Mon Sep 17 00:00:00 2001 +From: lumaparallax <257510328+lumaparallax@users.noreply.github.com> +Date: Mon, 20 Apr 2026 20:24:41 +0900 +Subject: [PATCH 02/10] system-info-android + +--- + frontend/cmake/os-linux.cmake | 3 +- + frontend/utility/system-info-android.cpp | 141 +++++++++++++++++++++++ + 2 files changed, 143 insertions(+), 1 deletion(-) + create mode 100644 frontend/utility/system-info-android.cpp + +diff --git a/frontend/cmake/os-linux.cmake b/frontend/cmake/os-linux.cmake +index 0aa18d558..29aa32e3e 100644 +--- a/frontend/cmake/os-linux.cmake ++++ b/frontend/cmake/os-linux.cmake +@@ -4,7 +4,8 @@ target_sources( + utility/CrashHandler_Linux.cpp + utility/NativeEventFilter.cpp + utility/platform-x11.cpp +- utility/system-info-posix.cpp ++ $<$>:utility/system-info-posix.cpp> ++ $<$:utility/system-info-android.cpp> + ) + target_compile_definitions( + obs-studio +diff --git a/frontend/utility/system-info-android.cpp b/frontend/utility/system-info-android.cpp +new file mode 100644 +index 000000000..f99ab71b0 +--- /dev/null ++++ b/frontend/utility/system-info-android.cpp +@@ -0,0 +1,141 @@ ++#include "system-info.hpp" ++#include "util/platform.h" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++namespace { ++ ++std::vector system_gpu_data() { ++ std::vector adapter_info; ++ GoLiveApi::Gpu gpu{}; ++ ++ obs_enter_graphics(); ++ const char *renderer = gs_get_renderer(); ++ const char *driver_ver = gs_get_driver_version(); ++ ++ // Convert from MB (as returned by OBS) to bytes ++ gpu.dedicated_video_memory = (uint64_t)gs_get_gpu_dmem() * 1024 * 1024; ++ gpu.shared_system_memory = (uint64_t)gs_get_gpu_smem() * 1024 * 1024; ++ obs_leave_graphics(); ++ ++ gpu.vendor_id = 0; // Blocked by SELinux on Android ++ gpu.device_id = 0; ++ gpu.model = renderer && *renderer ? renderer : "Unknown Android GPU"; ++ gpu.driver_version = driver_ver ? driver_ver : "Unknown Android Driver"; ++ ++ adapter_info.push_back(gpu); ++ return adapter_info; ++} ++ ++bool get_cpu_name(std::optional &proc_name) { ++ std::ifstream file("/proc/cpuinfo"); ++ std::string line; ++ ++ // Default fallback ++ proc_name = "Unknown ARM Processor"; ++ ++ if (!file.is_open()) ++ return false; ++ ++ while (std::getline(file, line)) { ++ // Android ARM chips usually use "Hardware", "Processor", or "model name" ++ if (line.compare(0, 8, "Hardware") == 0 || ++ line.compare(0, 9, "Processor") == 0 || ++ line.compare(0, 10, "model name") == 0) { ++ ++ auto pos = line.find(':'); ++ if (pos == std::string::npos) ++ continue; ++ ++ std::string name = line.substr(pos + 1); ++ ++ // Trim whitespace ++ const char* trimChars = " \t\n\r\f\v"; ++ auto start = name.find_first_not_of(trimChars); ++ if (start == std::string::npos) { ++ name.clear(); ++ } else { ++ auto end = name.find_last_not_of(trimChars); ++ name = name.substr(start, end - start + 1); ++ } ++ ++ // Skip generic "Processor" or "BogoMIPS" type labels ++ if (!name.empty() && name != "Processor") { ++ proc_name = name; ++ return true; ++ } ++ } ++ } ++ return false; ++} ++ ++bool get_cpu_freq(uint32_t &cpu_freq) { ++ std::ifstream f("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq"); ++ std::string line; ++ cpu_freq = 0; ++ ++ if (!f.is_open()) ++ return false; ++ ++ if (std::getline(f, line)) { ++ try { ++ // kHz -> MHz ++ cpu_freq = std::stoul(line) / 1000; ++ return true; ++ } catch (...) { ++ cpu_freq = 0; ++ } ++ } ++ return false; ++} ++ ++} // namespace ++ ++void system_info(GoLiveApi::Capabilities &capabilities) { ++ capabilities = GoLiveApi::Capabilities{}; ++ ++ // GPU Data ++ capabilities.gpu = system_gpu_data(); ++ ++ // CPU Data ++ auto &cpu_data = capabilities.cpu; ++ cpu_data.physical_cores = os_get_physical_cores(); ++ cpu_data.logical_cores = os_get_logical_cores(); ++ get_cpu_name(cpu_data.name); ++ ++ uint32_t freq = 0; ++ if (get_cpu_freq(freq)) ++ cpu_data.speed = freq; ++ ++ // Memory Data ++ auto &mem_data = capabilities.memory; ++ mem_data.total = os_get_sys_total_size(); ++ mem_data.free = os_get_sys_free_size(); ++ ++ // System info ++ auto &sys_data = capabilities.system; ++ sys_data.name = "Android"; ++ ++ struct utsname utsinfo; ++ if (uname(&utsinfo) == 0) { ++ // utsinfo.release is the kernel version (e.g., "6.1.25-android14") ++ sys_data.release = utsinfo.release; ++ sys_data.bits = sizeof(void*) * 8; ++ sys_data.arm = strstr(utsinfo.machine, "arm") || strstr(utsinfo.machine, "aarch"); ++ sys_data.version = std::string(utsinfo.sysname) + " " + utsinfo.release; ++ } else { ++ // If uname fails, we truly don't know the kernel or OS version ++ sys_data.release = "Unknown"; ++ sys_data.version = "Android (Generic)"; ++ } ++ ++ sys_data.armEmulation = os_get_emulation_status(); ++ ++ // Explicitly handle unused fields ++ UNUSED_PARAMETER(capabilities.gaming_features); ++} +-- +2.54.0 + diff --git a/tur/obs-studio/0003-fix-android-timespec.patch b/tur/obs-studio/0003-fix-android-timespec.patch new file mode 100644 index 0000000000..ecea359325 --- /dev/null +++ b/tur/obs-studio/0003-fix-android-timespec.patch @@ -0,0 +1,32 @@ +From bf598127d032d909971125cf4f79abb47d360495 Mon Sep 17 00:00:00 2001 +From: lumaparallax <257510328+lumaparallax@users.noreply.github.com> +Date: Mon, 20 Apr 2026 20:32:04 +0900 +Subject: [PATCH 03/10] fix-android-timespec + +--- + libobs/util/platform.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/libobs/util/platform.c b/libobs/util/platform.c +index 548afc03f..abd83bc8a 100644 +--- a/libobs/util/platform.c ++++ b/libobs/util/platform.c +@@ -799,7 +799,15 @@ static struct { + + static void init_timespec_offset(void) + { ++#if defined(__ANDROID__) ++ struct timespec ts; ++ int ret = clock_gettime(CLOCK_REALTIME, &ts); ++ timespec_offset.ts_valid = (ret == 0); ++ if (ret == 0) ++ timespec_offset.ts = ts; ++#else + timespec_offset.ts_valid = timespec_get(×pec_offset.ts, TIME_UTC) == TIME_UTC; ++#endif + timespec_offset.timestamp = os_gettime_ns(); + } + +-- +2.54.0 + diff --git a/tur/obs-studio/0004-fix-file-path-specifics.patch b/tur/obs-studio/0004-fix-file-path-specifics.patch new file mode 100644 index 0000000000..5139598583 --- /dev/null +++ b/tur/obs-studio/0004-fix-file-path-specifics.patch @@ -0,0 +1,65 @@ +From 6c41b24d3621f3856e240e233f21aca827c9d1ab Mon Sep 17 00:00:00 2001 +From: lumaparallax <257510328+lumaparallax@users.noreply.github.com> +Date: Fri, 24 Apr 2026 21:36:11 +0900 +Subject: [PATCH 04/10] fix file path specifics + +--- + frontend/utility/platform-x11.cpp | 2 +- + libobs/util/platform-nix.c | 6 +++--- + plugins/obs-outputs/librtmp/rtmp.c | 4 ++-- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/frontend/utility/platform-x11.cpp b/frontend/utility/platform-x11.cpp +index 61b874368..7bacd88db 100644 +--- a/frontend/utility/platform-x11.cpp ++++ b/frontend/utility/platform-x11.cpp +@@ -147,7 +147,7 @@ const char *RunOnce::thr_name = "OBS runonce"; + + void CheckIfAlreadyRunning(bool &already_running) + { +- std::string tmpfile_name = "/tmp/obs-studio.lock." + std::to_string(geteuid()); ++ std::string tmpfile_name = "@TERMUX_PREFIX/tmp/obs-studio.lock." + std::to_string(geteuid()); + int fd = open(tmpfile_name.c_str(), O_RDWR | O_CREAT | O_EXLOCK, 0600); + if (fd == -1) { + already_running = true; +diff --git a/libobs/util/platform-nix.c b/libobs/util/platform-nix.c +index 5648ca61b..ab854e5c5 100644 +--- a/libobs/util/platform-nix.c ++++ b/libobs/util/platform-nix.c +@@ -275,14 +275,14 @@ char *os_get_config_path_ptr(const char *name) + + int os_get_program_data_path(char *dst, size_t size, const char *name) + { +- return snprintf(dst, size, "/usr/local/share/%s", !!name ? name : ""); ++ return snprintf(dst, size, "@TERMUX_PREFIX@/share/%s", !!name ? name : ""); + } + + char *os_get_program_data_path_ptr(const char *name) + { +- size_t len = snprintf(NULL, 0, "/usr/local/share/%s", !!name ? name : ""); ++ size_t len = snprintf(NULL, 0, "@TERMUX_PREFIX@/share/%s", !!name ? name : ""); + char *str = bmalloc(len + 1); +- snprintf(str, len + 1, "/usr/local/share/%s", !!name ? name : ""); ++ snprintf(str, len + 1, "@TERMUX_PREFIX@/share/%s", !!name ? name : ""); + str[len] = 0; + return str; + } +diff --git a/plugins/obs-outputs/librtmp/rtmp.c b/plugins/obs-outputs/librtmp/rtmp.c +index 1898558f5..e7467ed23 100644 +--- a/plugins/obs-outputs/librtmp/rtmp.c ++++ b/plugins/obs-outputs/librtmp/rtmp.c +@@ -340,9 +340,9 @@ RTMP_TLS_LoadCerts(RTMP *r) { + CFRelease(anchors); + + #elif defined(__linux__) || defined(__FreeBSD__) +- if (mbedtls_x509_crt_parse_path(chain, "/etc/ssl/certs/") < 0) { ++ if (mbedtls_x509_crt_parse_path(chain, "@TERMUX_PREFIX@/etc/tls/") < 0) { + RTMP_Log(RTMP_LOGERROR, "mbedtls_x509_crt_parse_path: Couldn't parse " +- "/etc/ssl/certs"); ++ "@TERMUX_PREFIX@/etc/tls"); + goto error; + } + #elif defined(__OpenBSD__) +-- +2.54.0 + diff --git a/tur/obs-studio/0005-egl-saftey-checks.patch b/tur/obs-studio/0005-egl-saftey-checks.patch new file mode 100644 index 0000000000..19f8fffaad --- /dev/null +++ b/tur/obs-studio/0005-egl-saftey-checks.patch @@ -0,0 +1,41 @@ +From 8951ccb530f1db44300ab43a440f1f26c38cf906 Mon Sep 17 00:00:00 2001 +From: lumaparallax <257510328+lumaparallax@users.noreply.github.com> +Date: Mon, 20 Apr 2026 20:52:34 +0900 +Subject: [PATCH 05/10] egl-saftey-checks + +--- + libobs-opengl/gl-x11-egl.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/libobs-opengl/gl-x11-egl.c b/libobs-opengl/gl-x11-egl.c +index a8d1d5d12..4e2bc14f0 100644 +--- a/libobs-opengl/gl-x11-egl.c ++++ b/libobs-opengl/gl-x11-egl.c +@@ -419,7 +419,7 @@ static bool gl_x11_egl_platform_init_swapchain(struct gs_swap_chain *swap) + goto fail_window_surface; + } + +- const EGLSurface surface = eglCreateWindowSurface(plat->edisplay, plat->config, wid, 0); ++ const EGLSurface surface = eglCreateWindowSurface(plat->edisplay, plat->config, (EGLNativeWindowType)(uintptr_t)wid, 0); + if (EGL_NO_SURFACE == surface) { + blog(LOG_ERROR, "Cannot get window EGL surface: %s", get_egl_error_string()); + goto fail_window_surface; +@@ -517,6 +517,15 @@ static void gl_x11_egl_device_load_swapchain(gs_device_t *device, gs_swapchain_t + + static void gl_x11_egl_device_present(gs_device_t *device) + { ++ // Ensure the device, platform, swapchain and window info pointer exist ++ if (!device || !device->plat || !device->cur_swap || !device->cur_swap->wi) ++ return; ++ // Ensure the swapchain actually has a valid EGL surface initialized ++ if (device->cur_swap->wi->surface == EGL_NO_SURFACE) ++ return; ++ // Ensure the current thread's draw surface matches the swapchain's surface ++ if (eglGetCurrentSurface(EGL_DRAW) != device->cur_swap->wi->surface) ++ return; + Display *display = device->plat->xdisplay; + + xcb_connection_t *xcb_conn = XGetXCBConnection(display); +-- +2.54.0 + diff --git a/tur/obs-studio/0006-linux-capture-switch-to-memfd-based-xshm.patch b/tur/obs-studio/0006-linux-capture-switch-to-memfd-based-xshm.patch new file mode 100644 index 0000000000..167cd37e72 --- /dev/null +++ b/tur/obs-studio/0006-linux-capture-switch-to-memfd-based-xshm.patch @@ -0,0 +1,317 @@ +From 605f9d9c6cb6cfd0bce23d4ba9df6476c60da968 Mon Sep 17 00:00:00 2001 +From: lumaparallax <257510328+lumaparallax@users.noreply.github.com> +Date: Fri, 24 Apr 2026 15:30:22 +0900 +Subject: [PATCH 06/10] linux capture switch to memfd based xshm + +--- + plugins/linux-capture/xcomposite-input.c | 82 ++++++++++++++++++++++++ + plugins/linux-capture/xhelpers.c | 13 ++++ + plugins/linux-capture/xshm-input.c | 70 ++++++++++++++++++++ + 3 files changed, 165 insertions(+) + +diff --git a/plugins/linux-capture/xcomposite-input.c b/plugins/linux-capture/xcomposite-input.c +index 0e86fe443..0cefc382c 100644 +--- a/plugins/linux-capture/xcomposite-input.c ++++ b/plugins/linux-capture/xcomposite-input.c +@@ -22,6 +22,32 @@ + #include + #include + ++#if defined(__ANDROID__) ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Polyfill for memfd_create. */ ++#ifndef MFD_CLOEXEC ++#define MFD_CLOEXEC 0x0001U ++#endif ++ ++#ifndef SYS_memfd_create ++#if defined(__NR_memfd_create) ++#define SYS_memfd_create __NR_memfd_create ++#else ++#define SYS_memfd_create 319 /* Default standard Linux syscall number */ ++#endif ++#endif ++ ++static inline int sys_memfd_create(const char *name, unsigned int flags) { ++ return syscall(SYS_memfd_create, name, flags); ++} ++#endif ++ + #define WIN_STRING_DIV "\r\n" + #define FIND_WINDOW_INTERVAL 2.0 + +@@ -61,6 +87,12 @@ struct xcompcap { + Pixmap pixmap; + gs_texture_t *gltex; + ++ #if defined(__ANDROID__) ++ int shm_fd; ++ xcb_shm_seg_t shm_seg; ++ void *shm_data; ++ #endif ++ + pthread_mutex_t lock; + + bool show_cursor; +@@ -335,6 +367,14 @@ void xcomp_cleanup_pixmap(Display *disp, struct xcompcap *s) + gs_texture_destroy(s->gltex); + s->gltex = 0; + } ++ #if defined(__ANDROID__) ++ if (s->shm_data) { ++ xcb_shm_detach(XGetXCBConnection(disp), s->shm_seg); ++ munmap(s->shm_data, s->width * s->height * 4); ++ close(s->shm_fd); ++ s->shm_data = NULL; ++ } ++ #endif + + if (s->pixmap) { + XFreePixmap(disp, s->pixmap); +@@ -387,9 +427,30 @@ void xcomp_create_pixmap(xcb_connection_t *conn, struct xcompcap *s, int log_lev + return; + } + ++#if defined(__ANDROID__) ++ uint32_t size = s->width * s->height * 4; ++ s->shm_fd = sys_memfd_create("obs_xcomposite_shm", MFD_CLOEXEC); ++ if (s->shm_fd < 0) { ++ blog(LOG_ERROR, "xcompcap: memfd_create failed"); ++ } else { ++ ftruncate(s->shm_fd, size); ++ s->shm_data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, s->shm_fd, 0); ++ ++ if (s->shm_data == MAP_FAILED) { ++ blog(LOG_ERROR, "xcompcap: mmap failed"); ++ close(s->shm_fd); ++ s->shm_data = NULL; ++ } else { ++ s->shm_seg = xcb_generate_id(conn); ++ xcb_shm_attach_fd(conn, s->shm_seg, s->shm_fd, 0); ++ } ++ } ++ s->gltex = gs_texture_create(s->width, s->height, GS_BGRA_UNORM, 1, NULL, GS_DYNAMIC); ++#else + XErrorHandler prev = XSetErrorHandler(silence_x11_errors); + s->gltex = gs_texture_create_from_pixmap(s->width, s->height, GS_BGRA_UNORM, GL_TEXTURE_2D, (void *)s->pixmap); + XSetErrorHandler(prev); ++#endif + } + + struct reg_item { +@@ -655,6 +716,27 @@ static void xcompcap_video_tick(void *data, float seconds) + if (xcompcap_get_height(s) == 0 || xcompcap_get_width(s) == 0) + goto done; + ++#if defined(__ANDROID__) ++ // Use XSHM CPU readback with FDs ++ if (s->gltex && s->pixmap && s->shm_data && xcompcap_get_height(s) > 0 && xcompcap_get_width(s) > 0) { ++ xcb_shm_get_image_cookie_t img_c = xcb_shm_get_image_unchecked( ++ conn, s->pixmap, 0, 0, ++ s->width, s->height, ~0, XCB_IMAGE_FORMAT_Z_PIXMAP, ++ s->shm_seg, 0); ++ ++ xcb_shm_get_image_reply_t *img_r = xcb_shm_get_image_reply(conn, img_c, NULL); ++ if (img_r) { ++ gs_texture_set_image(s->gltex, s->shm_data, s->width * 4, false); ++ free(img_r); ++ } ++ } ++#endif ++ if (!s->gltex) ++ goto done; ++ ++ if (xcompcap_get_height(s) == 0 || xcompcap_get_width(s) == 0) ++ goto done; ++ + if (s->show_cursor) { + xcb_xcursor_update(conn, s->cursor); + +diff --git a/plugins/linux-capture/xhelpers.c b/plugins/linux-capture/xhelpers.c +index c5ffd9353..5fb357e6f 100644 +--- a/plugins/linux-capture/xhelpers.c ++++ b/plugins/linux-capture/xhelpers.c +@@ -16,7 +16,9 @@ along with this program. If not, see . + */ + + #include ++#if !defined(__ANDROID__) + #include ++#endif + #include + #include + #include +@@ -264,6 +266,12 @@ fail: + + xcb_shm_t *xshm_xcb_attach(xcb_connection_t *xcb, const int w, const int h) + { ++#if defined(__ANDROID__) ++ UNUSED_PARAMETER(xcb); ++ UNUSED_PARAMETER(w); ++ UNUSED_PARAMETER(h); ++ return NULL; ++#else + if (!xcb) + return NULL; + +@@ -283,10 +291,14 @@ xcb_shm_t *xshm_xcb_attach(xcb_connection_t *xcb, const int w, const int h) + fail: + xshm_xcb_detach(shm); + return NULL; ++#endif + } + + void xshm_xcb_detach(xcb_shm_t *shm) + { ++#if defined(__ANDROID__) ++ UNUSED_PARAMETER(shm); ++#else + if (!shm) + return; + +@@ -299,6 +311,7 @@ void xshm_xcb_detach(xcb_shm_t *shm) + shmctl(shm->shmid, IPC_RMID, NULL); + + bfree(shm); ++#endif + } + + xcb_screen_t *xcb_get_screen(xcb_connection_t *xcb, int screen) +diff --git a/plugins/linux-capture/xshm-input.c b/plugins/linux-capture/xshm-input.c +index c927209d0..bdb61ed31 100644 +--- a/plugins/linux-capture/xshm-input.c ++++ b/plugins/linux-capture/xshm-input.c +@@ -28,6 +28,30 @@ along with this program. If not, see . + #include "xcursor-xcb.h" + #include "xhelpers.h" + ++#if defined(__ANDROID__) ++#include ++#include ++#include ++#include ++ ++/* Polyfill for memfd_create. */ ++#ifndef MFD_CLOEXEC ++#define MFD_CLOEXEC 0x0001U ++#endif ++ ++#ifndef SYS_memfd_create ++#if defined(__NR_memfd_create) ++#define SYS_memfd_create __NR_memfd_create ++#else ++#define SYS_memfd_create 319 /* Default standard Linux syscall number */ ++#endif ++#endif ++ ++static inline int sys_memfd_create(const char *name, unsigned int flags) { ++ return syscall(SYS_memfd_create, name, flags); ++} ++#endif ++ + #define XSHM_DATA(voidptr) struct xshm_data *data = voidptr; + + #define blog(level, msg, ...) blog(level, "xshm-input: " msg, ##__VA_ARGS__) +@@ -40,6 +64,11 @@ struct xshm_data { + xcb_connection_t *xcb; + xcb_screen_t *xcb_screen; + xcb_shm_t *xshm; ++#if defined(__ANDROID__) ++ int shm_fd; ++ xcb_shm_seg_t shm_seg; ++ void *shm_data; ++#endif + xcb_xcursor_t *cursor; + + char *server; +@@ -197,10 +226,19 @@ static void xshm_capture_stop(struct xshm_data *data) + + obs_leave_graphics(); + ++#if defined(__ANDROID__) ++ if (data->shm_data) { ++ xcb_shm_detach(data->xcb, data->shm_seg); ++ munmap(data->shm_data, data->adj_width * data->adj_height * 4); ++ close(data->shm_fd); ++ data->shm_data = NULL; ++ } ++#else + if (data->xshm) { + xshm_xcb_detach(data->xshm); + data->xshm = NULL; + } ++#endif + + if (data->xcb) { + xcb_disconnect(data->xcb); +@@ -247,11 +285,33 @@ static void xshm_capture_start(struct xshm_data *data) + goto fail; + } + ++#if defined(__ANDROID__) ++ uint32_t size = data->adj_width * data->adj_height * 4; ++ data->shm_fd = sys_memfd_create("obs_xshm_capture", MFD_CLOEXEC); ++ if (data->shm_fd < 0) { ++ blog(LOG_ERROR, "failed to create memfd !"); ++ goto fail; ++ } else { ++ ftruncate(data->shm_fd, size); ++ data->shm_data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, data->shm_fd, 0); ++ ++ if (data->shm_data == MAP_FAILED) { ++ blog(LOG_ERROR, "failed to mmap shm !"); ++ close(data->shm_fd); ++ data->shm_data = NULL; ++ goto fail; ++ } else { ++ data->shm_seg = xcb_generate_id(data->xcb); ++ xcb_shm_attach_fd(data->xcb, data->shm_seg, data->shm_fd, 0); ++ } ++ } ++#else + data->xshm = xshm_xcb_attach(data->xcb, data->adj_width, data->adj_height); + if (!data->xshm) { + blog(LOG_ERROR, "failed to attach shm !"); + goto fail; + } ++#endif + + data->cursor = xcb_xcursor_init(data->xcb); + xcb_xcursor_offset(data->cursor, data->adj_x_org, data->adj_y_org); +@@ -497,9 +557,15 @@ static void xshm_video_tick(void *vptr, float seconds) + xcb_shm_get_image_cookie_t img_c; + xcb_shm_get_image_reply_t *img_r; + ++#if defined(__ANDROID__) ++ img_c = xcb_shm_get_image_unchecked(data->xcb, data->xcb_screen->root, data->adj_x_org, data->adj_y_org, ++ data->adj_width, data->adj_height, ~0, XCB_IMAGE_FORMAT_Z_PIXMAP, ++ data->shm_seg, 0); ++#else + img_c = xcb_shm_get_image_unchecked(data->xcb, data->xcb_screen->root, data->adj_x_org, data->adj_y_org, + data->adj_width, data->adj_height, ~0, XCB_IMAGE_FORMAT_Z_PIXMAP, + data->xshm->seg, 0); ++#endif + + img_r = xcb_shm_get_image_reply(data->xcb, img_c, NULL); + +@@ -508,7 +574,11 @@ static void xshm_video_tick(void *vptr, float seconds) + + obs_enter_graphics(); + ++#if defined(__ANDROID__) ++ gs_texture_set_image(data->texture, data->shm_data, data->adj_width * 4, false); ++#else + gs_texture_set_image(data->texture, (void *)data->xshm->data, data->adj_width * 4, false); ++#endif + xcb_xcursor_update(data->xcb, data->cursor); + + obs_leave_graphics(); +-- +2.54.0 + diff --git a/tur/obs-studio/0007-disable-vaapi-and-its-dependencies.patch b/tur/obs-studio/0007-disable-vaapi-and-its-dependencies.patch new file mode 100644 index 0000000000..e076f3897a --- /dev/null +++ b/tur/obs-studio/0007-disable-vaapi-and-its-dependencies.patch @@ -0,0 +1,72 @@ +From 6aa9bb7a0f5c941d62ea2bd32c7e4fef24706e09 Mon Sep 17 00:00:00 2001 +From: lumaparallax <257510328+lumaparallax@users.noreply.github.com> +Date: Mon, 20 Apr 2026 21:18:06 +0900 +Subject: [PATCH 07/10] disable vaapi and its dependencies + +--- + plugins/obs-ffmpeg/CMakeLists.txt | 14 +++++++------- + plugins/obs-ffmpeg/cmake/dependencies.cmake | 2 +- + plugins/obs-ffmpeg/obs-ffmpeg.c | 2 +- + 3 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/plugins/obs-ffmpeg/CMakeLists.txt b/plugins/obs-ffmpeg/CMakeLists.txt +index 7d37eeb6e..2c093dd3c 100644 +--- a/plugins/obs-ffmpeg/CMakeLists.txt ++++ b/plugins/obs-ffmpeg/CMakeLists.txt +@@ -23,9 +23,9 @@ target_sources( + $<$:obs-ffmpeg-rist.h> + $<$:obs-ffmpeg-srt.h> + $<$:obs-ffmpeg-url.h> +- $<$:obs-ffmpeg-vaapi.c> +- $<$:vaapi-utils.c> +- $<$:vaapi-utils.h> ++ $<$,$>>:obs-ffmpeg-vaapi.c> ++ $<$,$>>:vaapi-utils.c> ++ $<$,$>>:vaapi-utils.h> + obs-ffmpeg-audio-encoders.c + obs-ffmpeg-av1.c + obs-ffmpeg-compat.h +@@ -65,10 +65,10 @@ target_link_libraries( + FFmpeg::swresample + $<$:OBS::w32-pthreads> + $<$:ws2_32> +- $<$:Libva::va> +- $<$:Libva::drm> +- $<$:Libpci::pci> +- $<$:Libdrm::Libdrm> ++ $<$,$>>:Libva::va> ++ $<$,$>>:Libva::drm> ++ $<$,$>>:Libpci::pci> ++ $<$,$>>:Libdrm::Libdrm> + $<$:Librist::Librist> + $<$:Libsrt::Libsrt> + ) +diff --git a/plugins/obs-ffmpeg/cmake/dependencies.cmake b/plugins/obs-ffmpeg/cmake/dependencies.cmake +index 5e523cd37..e46ac94a5 100644 +--- a/plugins/obs-ffmpeg/cmake/dependencies.cmake ++++ b/plugins/obs-ffmpeg/cmake/dependencies.cmake +@@ -15,7 +15,7 @@ endif() + if(OS_WINDOWS AND CMAKE_VS_PLATFORM_NAME STREQUAL x64) + find_package(AMF 1.4.29 REQUIRED) + add_subdirectory(obs-amf-test) +-elseif(OS_LINUX OR OS_FREEBSD OR OS_OPENBSD) ++elseif((OS_LINUX AND NOT OS_ANDROID) OR OS_FREEBSD OR OS_OPENBSD) + find_package(Libva REQUIRED) + find_package(Libpci REQUIRED) + find_package(Libdrm REQUIRED) +diff --git a/plugins/obs-ffmpeg/obs-ffmpeg.c b/plugins/obs-ffmpeg/obs-ffmpeg.c +index d7880e51c..56df4b70b 100644 +--- a/plugins/obs-ffmpeg/obs-ffmpeg.c ++++ b/plugins/obs-ffmpeg/obs-ffmpeg.c +@@ -9,7 +9,7 @@ + #include + #endif + +-#if !defined(_WIN32) && !defined(__APPLE__) ++#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__ANDROID__) + #include "vaapi-utils.h" + + #define LIBAVUTIL_VAAPI_AVAILABLE +-- +2.54.0 + diff --git a/tur/obs-studio/0008-relax-Qt-and-libvlc-versioning.patch b/tur/obs-studio/0008-relax-Qt-and-libvlc-versioning.patch new file mode 100644 index 0000000000..74d2a0666a --- /dev/null +++ b/tur/obs-studio/0008-relax-Qt-and-libvlc-versioning.patch @@ -0,0 +1,46 @@ +From 52856e27c737182278670d8a318e7a7abbcabe6c Mon Sep 17 00:00:00 2001 +From: lumaparallax <257510328+lumaparallax@users.noreply.github.com> +Date: Mon, 20 Apr 2026 21:32:52 +0900 +Subject: [PATCH 08/10] relax Qt and libvlc versioning + +--- + frontend/cmake/os-linux.cmake | 9 +++++++++ + plugins/vlc-video/vlc-video-plugin.c | 2 ++ + 2 files changed, 11 insertions(+) + +diff --git a/frontend/cmake/os-linux.cmake b/frontend/cmake/os-linux.cmake +index 29aa32e3e..1f7273b5d 100644 +--- a/frontend/cmake/os-linux.cmake ++++ b/frontend/cmake/os-linux.cmake +@@ -13,6 +13,15 @@ target_compile_definitions( + ) + target_link_libraries(obs-studio PRIVATE Qt::DBus) + ++if(OS_ANDROID) ++ find_package(Qt6 REQUIRED COMPONENTS GuiPrivate) ++ target_link_libraries(obs-studio PRIVATE Qt::GuiPrivate) ++else() ++ if(Qt6_VERSION VERSION_LESS "6.9.0") ++ target_link_libraries(obs-studio PRIVATE Qt::GuiPrivate) ++ endif() ++endif() ++ + if(Qt6_VERSION AND Qt6_VERSION VERSION_LESS "6.9.0") + target_link_libraries(obs-studio PRIVATE Qt::GuiPrivate) + endif() +diff --git a/plugins/vlc-video/vlc-video-plugin.c b/plugins/vlc-video/vlc-video-plugin.c +index d92397538..ba7882e52 100644 +--- a/plugins/vlc-video/vlc-video-plugin.c ++++ b/plugins/vlc-video/vlc-video-plugin.c +@@ -187,6 +187,8 @@ static bool load_libvlc_module(void) + + if (!libvlc_core_module) + return false; ++#elif defined(__ANDROID__) ++#define LIBVLC_FILE "libvlc.so" + #else + #define LIBVLC_FILE "libvlc.so.5" + #endif +-- +2.54.0 + diff --git a/tur/obs-studio/0009-fix-local-IP-detection.patch b/tur/obs-studio/0009-fix-local-IP-detection.patch new file mode 100644 index 0000000000..5c91d94feb --- /dev/null +++ b/tur/obs-studio/0009-fix-local-IP-detection.patch @@ -0,0 +1,91 @@ +From 53ae3546c6148b7aa4e25d9c811284d500284b71 Mon Sep 17 00:00:00 2001 +From: lumaparallax <257510328+lumaparallax@users.noreply.github.com> +Date: Fri, 24 Apr 2026 15:37:35 +0900 +Subject: [PATCH 09/10] fix local IP detection + +--- + plugins/obs-websocket | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Submodule plugins/obs-websocket 1fcb95b15..32aa80ab2: +diff --git a/plugins/obs-websocket/src/utils/Platform.cpp b/plugins/obs-websocket/src/utils/Platform.cpp +index e8045dd..023ce1f 100644 +--- a/plugins/obs-websocket/src/utils/Platform.cpp ++++ b/plugins/obs-websocket/src/utils/Platform.cpp +@@ -23,11 +23,17 @@ with this program. If not, see + #include + #include + ++#include ++#include ++#include ++ + #include "Platform.h" + #include "plugin-macros.generated.h" + + std::string Utils::Platform::GetLocalAddress() + { ++ std::string localIp = "127.0.0.1"; // Fallback to localhost ++try { + std::vector validAddresses; + for (auto address : QNetworkInterface::allAddresses()) { + // Exclude addresses which won't work +@@ -45,10 +51,6 @@ std::string Utils::Platform::GetLocalAddress() + validAddresses.push_back(address.toString()); + } + +- // Return early if no valid addresses were found +- if (validAddresses.size() == 0) +- return "0.0.0.0"; +- + std::vector> preferredAddresses; + for (auto address : validAddresses) { + // Attribute a priority (0 is best) to the address to choose the best picks +@@ -72,8 +74,44 @@ std::string Utils::Platform::GetLocalAddress() + std::sort(preferredAddresses.begin(), preferredAddresses.end(), + [=](std::pair a, std::pair b) { return a.second < b.second; }); + ++ if (!preferredAddresses.empty()) { + // Return highest priority address + return preferredAddresses[0].first.toStdString(); ++ } ++} catch (...) { ++ //ignore any exceptions thrown by QT and proceed to Fallback ++ } ++ ++ //Androd Fallback ++ struct ifaddrs *interfaces = nullptr; ++ struct ifaddrs *temp_addr = nullptr; ++ ++ if (getifaddrs(&interfaces) == 0) { ++ temp_addr = interfaces; ++ while (temp_addr != nullptr) { ++ if (temp_addr->ifa_addr != nullptr && temp_addr->ifa_addr->sa_family == AF_INET) { // IPv4 only ++ std::string ifName = temp_addr->ifa_name; ++ ++ // Prioritize Android Wi-Fi (wlan0) or Ethernet (eth0) ++ if (ifName == "wlan0" || ifName == "eth0") { ++ char ipBuffer[INET_ADDRSTRLEN]; ++ inet_ntop(AF_INET, &((struct sockaddr_in*)temp_addr->ifa_addr)->sin_addr, ipBuffer, INET_ADDRSTRLEN); ++ localIp = ipBuffer; ++ break; ++ } ++ // Fallback: If not wlan0/eth0, grab the first thing that isn't loopback (lo) or cellular (rmnet) ++ else if (ifName != "lo" && localIp == "127.0.0.1" && ifName.find("rmnet") == std::string::npos) { ++ char ipBuffer[INET_ADDRSTRLEN]; ++ inet_ntop(AF_INET, &((struct sockaddr_in*)temp_addr->ifa_addr)->sin_addr, ipBuffer, INET_ADDRSTRLEN); ++ localIp = ipBuffer; ++ } ++ } ++ temp_addr = temp_addr->ifa_next; ++ } ++ freeifaddrs(interfaces); ++ } ++ ++ return localIp; + } + + QString Utils::Platform::GetCommandLineArgument(QString arg) +-- +2.54.0 + diff --git a/tur/obs-studio/0010-fix-browser-and-its-submodule.patch b/tur/obs-studio/0010-fix-browser-and-its-submodule.patch new file mode 100644 index 0000000000..9dfb2c5b42 --- /dev/null +++ b/tur/obs-studio/0010-fix-browser-and-its-submodule.patch @@ -0,0 +1,56 @@ +From d7e4a8304f3f6608643101fef63fc8c4ac5b78cb Mon Sep 17 00:00:00 2001 +From: lumaparallax <257510328+lumaparallax@users.noreply.github.com> +Date: Tue, 21 Apr 2026 17:31:20 +0900 +Subject: [PATCH 10/11] fix browser and its submodule + +--- + frontend/OBSApp.cpp | 4 +++- + plugins/obs-browser | 2 +- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/frontend/OBSApp.cpp b/frontend/OBSApp.cpp +index 6ade93c5d..10c8e1947 100644 +--- a/frontend/OBSApp.cpp ++++ b/frontend/OBSApp.cpp +@@ -315,7 +315,9 @@ bool OBSApp::InitGlobalConfigDefaults() + config_set_default_bool(appConfig, "Audio", "DisableAudioDucking", true); + #endif + +-#if defined(_WIN32) || defined(__APPLE__) || defined(__linux__) ++#if defined(__ANDROID__) ++ config_set_default_bool(appConfig, "General", "BrowserHWAccel",false); ++#elif defined(_WIN32) || defined(__APPLE__) || defined(__linux__) + config_set_default_bool(appConfig, "General", "BrowserHWAccel", true); + #endif + +Submodule plugins/obs-browser ea04212e4..962bfa92b: +diff --git a/plugins/obs-browser/browser-app.cpp b/plugins/obs-browser/browser-app.cpp +index 5d2c4dc..0ad2f7a 100644 +--- a/plugins/obs-browser/browser-app.cpp ++++ b/plugins/obs-browser/browser-app.cpp +@@ -92,6 +92,22 @@ void BrowserApp::OnBeforeCommandLineProcessing(const CefString &, CefRefPtrAppendSwitchWithValue("autoplay-policy", "no-user-gesture-required"); ++ ++#ifdef __ANDROID__ ++ // TERMUX OPTIMIZATIONS & FIXES ++ ++ // 1. Termux Sandbox & Security Fixes ++ command_line->AppendSwitch("no-sandbox"); ++ command_line->AppendSwitchWithValue("password-store", "basic"); ++ ++ // 2. Permissive GPU Flags (Optimizes internal Turnip/Zink rendering before RAM handoff) ++ command_line->AppendSwitch("ignore-gpu-blocklist"); ++ command_line->AppendSwitch("disable-gpu-sandbox"); ++ command_line->AppendSwitchWithValue("use-gl", "angle"); ++ command_line->AppendSwitchWithValue("use-angle", "gles"); ++ ++#endif ++ + #ifdef __APPLE__ + command_line->AppendSwitch("use-mock-keychain"); + #elif !defined(_WIN32) +-- +2.54.0 + diff --git a/tur/obs-studio/build.sh b/tur/obs-studio/build.sh new file mode 100644 index 0000000000..73c2af3e65 --- /dev/null +++ b/tur/obs-studio/build.sh @@ -0,0 +1,87 @@ +TERMUX_PKG_HOMEPAGE=https://obsproject.com +TERMUX_PKG_DESCRIPTION="Free and open source software for live streaming and screen recording" +TERMUX_PKG_LICENSE="GPL-2.0-or-later" +TERMUX_PKG_MAINTAINER="@termux-user-repository" +TERMUX_PKG_VERSION=( + "32.1.2" + "5.7.3" + "2.23.4" +) +_COMMIT=ea04212e4bbadd077f9e6038758c4e4779c24fa3 +TERMUX_PKG_SRCURL=( + "https://github.com/obsproject/obs-studio/archive/refs/tags/${TERMUX_PKG_VERSION[0]}.tar.gz" + "https://github.com/obsproject/obs-websocket/archive/refs/tags/${TERMUX_PKG_VERSION[1]}.tar.gz" + "https://github.com/obsproject/obs-browser/archive/${_COMMIT}.tar.gz" +) +TERMUX_PKG_SHA256=( + b4a59410cddb46d0e31df1ee13b8ec66f30862d7e980c1a8c4e3b5d16fae6053 + 5e9f06aae32a8ac0f94886e8caa5947ad7da41670169c9ee1a08e28cf53c65f5 + 932bca40aa70b2ff1663c8e9e1183874e01f73cf55822fe324e91261b9116ace +) +TERMUX_PKG_DEPENDS="ffmpeg, libcurl, libfdk-aac, libjansson, mesa, pulseaudio, qt6-qtbase, qt6-qtsvg, qrcodegen, librnnoise, libx11, libxcb, libxkbcommon, zlib, glib, libuuid, fontconfig, freetype, libx264, vulkan-loader, libxext, libxfixes, libxcomposite, libxinerama, libxrandr, libxrender, libxcursor, libxdamage, libandroid-glob, libandroid-spawn" +TERMUX_PKG_BUILD_DEPENDS="extra-cmake-modules, swig, glslang, pkg-config, nlohmann-json, websocketpp, simde, uthash, libasio, libwayland, vlc-qt, python,libdatachannel, libfdk-aac, luajit, speexdsp, librnnoise, mbedtls-static, python, libcef-for-brow6el-dev" +TERMUX_PKG_SUGGESTS="vlc-qt, luajit, python,libdatachannel, librnnoise, libfdk-aac, speexdsp, libcef-for-brow6el" +TERMUX_PKG_EXTRA_CONFIGURE_ARGS=" +-DENABLE_AJA=OFF +-DENABLE_DECKLINK=OFF +-DENABLE_JACK=OFF +-DENABLE_SNDIO=OFF +-DENABLE_V4L2=OFF +-DENABLE_VST=OFF +-DENABLE_ALSA=OFF +-DENABLE_PIPEWIRE=OFF +-DENABLE_WAYLAND=ON +-DENABLE_UI=ON +-DENABLE_WEBRTC=ON +-DENABLE_WEBSOCKET=ON +-DENABLE_LIBFDK=ON +-DENABLE_RNNOISE=ON +-DENABLE_SCRIPTING_PYTHON=ON +-DENABLE_FREETYPE=ON +-DENABLE_NEW_MPEGTS_OUTPUT=OFF +-DENABLE_FFMPEG_NVENC=OFF +-DENABLE_TEST_INPUT=OFF +-DENABLE_RELOCATABLE=OFF +-DENABLE_PORTABLE_CONFIG=OFF +-DOBS_COMPILE_DEPRECATION_AS_WARNING=OFF +-DCMAKE_INSTALL_BINDIR=bin +-DCMAKE_INSTALL_LIBDIR=lib +-DCMAKE_INSTALL_INCLUDEDIR=include +-DCMAKE_INSTALL_DATAROOTDIR=share +-DCMAKE_PLATFORM_NO_VERSIONED_SONAME=OFF +-Dqrcodegencpp_DIR=$TERMUX_PREFIX/lib/cmake/qrcodegencpp +-Dwebsocketpp_DIR=$TERMUX_PREFIX/lib/cmake/websocketpp +-DUUID_INCLUDE_DIR=$TERMUX_PREFIX/include +-DUUID_LIBRARY=$TERMUX_PREFIX/lib/libuuid.so +" + +#Error 1: CMake error : "cef_version.h cannot be read" +#Obs browser excepts it to be in CEF_ROOT_DIR,so try move or copy or link "$TERMUX_PREFIX/opt/libcef-for-brow6el-dev/include/version.h" to "$TERMUX_PREFIX/opt/libcef-for-brow6el-dev" +#PS: Changing CEF_ROOT_DIR to point $TERMUX_PREFIX/opt/libcef-for-brow6el-dev/include insted, will throw this error: "fatal error: 'include/cef_app.h' file not found during build time, atleast it did for me in local/on device build" + +#Error 2:CMake error: Missing libcef_dll_wrapper.a +#Build Solution I found during local/ on-device build: +#cd $TERMUX_PREFIX/opt/libcef-for-brow6el-dev +#cmake -B build -DCMAKE_SYSTEM_PROCESSOR=arm64 -DPROJECT_ARCH=arm64 +#Build it. +#After getting the libcef_dll_wrapper.a update the path below of CEF_LIBRARY_WRAPPER_RELEASE + +TERMUX_PKG_EXTRA_CONFIGURE_ARGS+=" +-DENABLE_BROWSER=ON +-DCEF_INCLUDE_DIR=$TERMUX_PREFIX/opt/libcef-for-brow6el +-DCEF_ROOT_DIR=$TERMUX_PREFIX/opt/libcef-for-brow6el-dev +-DCEF_LIBRARY_WRAPPER_RELEASE=$TERMUX_PREFIX/path-to-wherever-this-is->/libcef_dll_wrapper.a +" + +termux_step_post_get_source() { + # Remove the empty placeholder folders + rm -rf plugins/obs-websocket plugins/obs-browser + + # Move the extracted GitHub folders into their respective locations + mv "obs-websocket-${TERMUX_PKG_VERSION[1]}" plugins/obs-websocket + mv "obs-browser-${_COMMIT}" plugins/obs-browser +} + +termux_step_pre_configure() { + export LDFLAGS+=" -lm -landroid-glob -landroid-spawn" +} From e2e337bab5707e8e75a2119a6ad11bfd8df5c187 Mon Sep 17 00:00:00 2001 From: lumaparallax <257510328+lumaparallax@users.noreply.github.com> Date: Sun, 26 Apr 2026 00:02:44 +0900 Subject: [PATCH 5/7] addpkg(x11/obs-move-transition): Move sources to a new position during scene transition --- ...01-cmake-android-build-compatibility.patch | 50 +++++++++++++++++++ tur/obs-move-transition/build.sh | 16 ++++++ 2 files changed, 66 insertions(+) create mode 100644 tur/obs-move-transition/0001-cmake-android-build-compatibility.patch create mode 100644 tur/obs-move-transition/build.sh diff --git a/tur/obs-move-transition/0001-cmake-android-build-compatibility.patch b/tur/obs-move-transition/0001-cmake-android-build-compatibility.patch new file mode 100644 index 0000000000..dbb546ba16 --- /dev/null +++ b/tur/obs-move-transition/0001-cmake-android-build-compatibility.patch @@ -0,0 +1,50 @@ +From f13058e19801abd8e5b2a7c3209221dfb0069691 Mon Sep 17 00:00:00 2001 +From: lumaparallax <257510328+lumaparallax@users.noreply.github.com> +Date: Fri, 24 Apr 2026 22:22:24 +0900 +Subject: [PATCH] cmake android build compatablity + +--- + cmake/common/compiler_common.cmake | 6 +++++- + cmake/common/osconfig.cmake | 11 ++++++++--- + 2 files changed, 13 insertions(+), 4 deletions(-) + +diff --git a/cmake/common/compiler_common.cmake b/cmake/common/compiler_common.cmake +index fcd2568..aacfd47 100644 +--- a/cmake/common/compiler_common.cmake ++++ b/cmake/common/compiler_common.cmake +@@ -79,5 +79,9 @@ if(CMAKE_CXX_STANDARD GREATER_EQUAL 20) + endif() + + if(NOT DEFINED CMAKE_COMPILE_WARNING_AS_ERROR) +- set(CMAKE_COMPILE_WARNING_AS_ERROR ON) ++ if(OS_ANDROID) ++ set(CMAKE_COMPILE_WARNING_AS_ERROR OFF) ++ else() ++ set(CMAKE_COMPILE_WARNING_AS_ERROR ON) ++ endif() + endif() +diff --git a/cmake/common/osconfig.cmake b/cmake/common/osconfig.cmake +index 87d435a..9b700c9 100644 +--- a/cmake/common/osconfig.cmake ++++ b/cmake/common/osconfig.cmake +@@ -12,9 +12,14 @@ elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") + set(CMAKE_CXX_EXTENSIONS FALSE) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos") + set(OS_MACOS TRUE) +-elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD|OpenBSD") ++elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD|OpenBSD|Android") + set(CMAKE_CXX_EXTENSIONS FALSE) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/linux") +- string(TOUPPER "${CMAKE_HOST_SYSTEM_NAME}" _SYSTEM_NAME_U) +- set(OS_${_SYSTEM_NAME_U} TRUE) ++ if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android") ++ set(OS_LINUX TRUE) ++ set(OS_ANDROID TRUE) ++ else() ++ string(TOUPPER "${CMAKE_HOST_SYSTEM_NAME}" _SYSTEM_NAME_U) ++ set(OS_${_SYSTEM_NAME_U} TRUE) ++ endif() + endif() +-- +2.54.0 + diff --git a/tur/obs-move-transition/build.sh b/tur/obs-move-transition/build.sh new file mode 100644 index 0000000000..25d178858f --- /dev/null +++ b/tur/obs-move-transition/build.sh @@ -0,0 +1,16 @@ +TERMUX_PKG_HOMEPAGE=https://github.com/exeldro/obs-move-transition +TERMUX_PKG_DESCRIPTION="Move transition for OBS Studio" +TERMUX_PKG_LICENSE="GPL-2.0" +TERMUX_PKG_MAINTAINER="@termux-user-repository" +TERMUX_PKG_VERSION="3.2.1" +TERMUX_PKG_SRCURL="https://github.com/exeldro/obs-move-transition/archive/refs/tags/${TERMUX_PKG_VERSION}.tar.gz" +TERMUX_PKG_SHA256=676259c4346832eac964301166b97ac12c2914a874ee53c4b91e31a613859c36 +TERMUX_PKG_AUTO_UPDATE=true +TERMUX_PKG_DEPENDS="obs-studio" +TERMUX_PKG_EXTRA_CONFIGURE_ARGS=" +-DBUILD_OUT_OF_TREE=ON +" + +termux_step_pre_configure() { + LDFLAGS+=" -lm" +} From 99b1fe2b40aa42c14e5d830dd4b84e11cdc76971 Mon Sep 17 00:00:00 2001 From: lumaparallax <257510328+lumaparallax@users.noreply.github.com> Date: Sun, 26 Apr 2026 00:03:35 +0900 Subject: [PATCH 6/7] addpkg(x11/obs-stroke-glow-shadow): Efficient Stroke, Glow, and Shadow filter for OBS Studio --- tur/obs-stroke-glow-shadow/build.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tur/obs-stroke-glow-shadow/build.sh diff --git a/tur/obs-stroke-glow-shadow/build.sh b/tur/obs-stroke-glow-shadow/build.sh new file mode 100644 index 0000000000..b4cca35428 --- /dev/null +++ b/tur/obs-stroke-glow-shadow/build.sh @@ -0,0 +1,17 @@ +TERMUX_PKG_HOMEPAGE="https://github.com/FiniteSingularity/obs-stroke-glow-shadow" +TERMUX_PKG_DESCRIPTION="An OBS plugin to provide Stroke, Glow, and Shadow effect on masked sources" +TERMUX_PKG_LICENSE="GPL-2.0" +TERMUX_PKG_MAINTAINER="@termux-user-repository" +TERMUX_PKG_VERSION="1.5.3" +TERMUX_PKG_SRCURL="https://github.com/FiniteSingularity/obs-stroke-glow-shadow/archive/refs/tags/v${TERMUX_PKG_VERSION}.tar.gz" +TERMUX_PKG_SHA256=bd82a676249fd8bc14c7bd368ce705d23d14eedfff0ac43566f096028463d823 +TERMUX_PKG_AUTO_UPDATE=true +TERMUX_PKG_DEPENDS="obs-studio" +TERMUX_PKG_EXTRA_CONFIGURE_ARGS=" +-DBUILD_OUT_OF_TREE=ON +-DCMAKE_CXX_SCAN_FOR_MODULES=OFF +" + +termux_step_pre_configure() { + LDFLAGS+=" -lm" +} From 66e003564d618c200d10e8ca49dec56908a8f690 Mon Sep 17 00:00:00 2001 From: lumaparallax <257510328+lumaparallax@users.noreply.github.com> Date: Sun, 26 Apr 2026 00:04:14 +0900 Subject: [PATCH 7/7] addpkg(x11/obs-backgroundremoval): AI powered background removal for OBS Studio --- ...01-cmake-android-build-compatibility.patch | 50 +++++++++++++++++++ tur/obs-backgroundremoval/build.sh | 19 +++++++ 2 files changed, 69 insertions(+) create mode 100644 tur/obs-backgroundremoval/0001-cmake-android-build-compatibility.patch create mode 100644 tur/obs-backgroundremoval/build.sh diff --git a/tur/obs-backgroundremoval/0001-cmake-android-build-compatibility.patch b/tur/obs-backgroundremoval/0001-cmake-android-build-compatibility.patch new file mode 100644 index 0000000000..84bf34b179 --- /dev/null +++ b/tur/obs-backgroundremoval/0001-cmake-android-build-compatibility.patch @@ -0,0 +1,50 @@ +From 492e1671ab90f067605225608d2da7a3154d3dc2 Mon Sep 17 00:00:00 2001 +From: lumaparallax <257510328+lumaparallax@users.noreply.github.com> +Date: Fri, 24 Apr 2026 22:16:38 +0900 +Subject: [PATCH] cmake android build compatibility + +--- + cmake/common/compiler_common.cmake | 6 +++++- + cmake/common/osconfig.cmake | 11 ++++++++--- + 2 files changed, 13 insertions(+), 4 deletions(-) + +diff --git a/cmake/common/compiler_common.cmake b/cmake/common/compiler_common.cmake +index fcd2568..aacfd47 100644 +--- a/cmake/common/compiler_common.cmake ++++ b/cmake/common/compiler_common.cmake +@@ -79,5 +79,9 @@ if(CMAKE_CXX_STANDARD GREATER_EQUAL 20) + endif() + + if(NOT DEFINED CMAKE_COMPILE_WARNING_AS_ERROR) +- set(CMAKE_COMPILE_WARNING_AS_ERROR ON) ++ if(OS_ANDROID) ++ set(CMAKE_COMPILE_WARNING_AS_ERROR OFF) ++ else() ++ set(CMAKE_COMPILE_WARNING_AS_ERROR ON) ++ endif() + endif() +diff --git a/cmake/common/osconfig.cmake b/cmake/common/osconfig.cmake +index 87d435a..9b700c9 100644 +--- a/cmake/common/osconfig.cmake ++++ b/cmake/common/osconfig.cmake +@@ -12,9 +12,14 @@ elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") + set(CMAKE_CXX_EXTENSIONS FALSE) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos") + set(OS_MACOS TRUE) +-elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD|OpenBSD") ++elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD|OpenBSD|Android") + set(CMAKE_CXX_EXTENSIONS FALSE) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/linux") +- string(TOUPPER "${CMAKE_HOST_SYSTEM_NAME}" _SYSTEM_NAME_U) +- set(OS_${_SYSTEM_NAME_U} TRUE) ++ if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android") ++ set(OS_LINUX TRUE) ++ set(OS_ANDROID TRUE) ++ else() ++ string(TOUPPER "${CMAKE_HOST_SYSTEM_NAME}" _SYSTEM_NAME_U) ++ set(OS_${_SYSTEM_NAME_U} TRUE) ++ endif() + endif() +-- +2.54.0 + diff --git a/tur/obs-backgroundremoval/build.sh b/tur/obs-backgroundremoval/build.sh new file mode 100644 index 0000000000..c80f14e4e1 --- /dev/null +++ b/tur/obs-backgroundremoval/build.sh @@ -0,0 +1,19 @@ +TERMUX_PKG_HOMEPAGE="https://github.com/royshil/obs-backgroundremoval" +TERMUX_PKG_DESCRIPTION="Portrait background removal/virtual green-screen and low-light enhancement for obs studio" +TERMUX_PKG_LICENSE="GPL-3.0" +TERMUX_PKG_MAINTAINER="@termux-user-repository" +TERMUX_PKG_VERSION=1.3.7 +TERMUX_PKG_SRCURL="https://github.com/royshil/obs-backgroundremoval/archive/refs/tags/${TERMUX_PKG_VERSION}.tar.gz" +TERMUX_PKG_SHA256=0994dd60cb34f132273fb3d0be7db770cdb7c732d08908b584b74b44bc820da1 +TERMUX_PKG_AUTO_UPDATE=true +TERMUX_PKG_DEPENDS="obs-studio, onnxruntime, opencv" +TERMUX_PKG_EXTRA_CONFIGURE_ARGS=" +-DBUILD_OUT_OF_TREE=ON +-DCMAKE_CXX_SCAN_FOR_MODULES=OFF +-DOpenCV_DIR=${TERMUX_PREFIX}/lib/cmake/opencv4 +" + +termux_step_pre_configure() { + # Ensuring the compiler can find OpenCV headers in the Termux prefix + CXXFLAGS+=" -I${TERMUX_PREFIX}/include/opencv4" +}