This is an automated email from the ASF dual-hosted git repository.

kou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/main by this push:
     new 62060ab55b GH-44096: [C++] Don't use Boost.Process with Emscripten 
(#44097)
62060ab55b is described below

commit 62060ab55be2dc811e5abf0c5aba9834d3056ee1
Author: Sutou Kouhei <[email protected]>
AuthorDate: Sat Sep 14 07:45:36 2024 +0900

    GH-44096: [C++] Don't use Boost.Process with Emscripten (#44097)
    
    ### Rationale for this change
    
    Boost.Process doesn't work with Emscripten. So we can't build 
`arrow::util::Process`.
    
    ### What changes are included in this PR?
    
    Don't use Boost.Process with Emscripten. `arrow::util::Process` returns 
`Status::NotImplemented` with Emscripten.
    
    ### Are these changes tested?
    
    Yes.
    
    ### Are there any user-facing changes?
    
    No.
    * GitHub Issue: #44096
    
    Authored-by: Sutou Kouhei <[email protected]>
    Signed-off-by: Sutou Kouhei <[email protected]>
---
 cpp/src/arrow/testing/process.cc | 169 ++++++++++++++++++++++++---------------
 1 file changed, 105 insertions(+), 64 deletions(-)

diff --git a/cpp/src/arrow/testing/process.cc b/cpp/src/arrow/testing/process.cc
index 941ddd9a6b..133768ff01 100644
--- a/cpp/src/arrow/testing/process.cc
+++ b/cpp/src/arrow/testing/process.cc
@@ -18,39 +18,45 @@
 #include "arrow/testing/process.h"
 #include "arrow/result.h"
 
+#define BOOST_PROCESS_AVAILABLE
+#ifdef __EMSCRIPTEN__
+#  undef BOOST_PROCESS_AVAILABLE
+#endif
+
+#ifdef BOOST_PROCESS_AVAILABLE
 // This boost/asio/io_context.hpp include is needless for no MinGW
 // build.
 //
 // This is for including boost/asio/detail/socket_types.hpp before any
 // "#include <windows.h>". boost/asio/detail/socket_types.hpp doesn't
 // work if windows.h is already included.
-#include <boost/asio/io_context.hpp>
+#  include <boost/asio/io_context.hpp>
 
-#ifdef BOOST_PROCESS_HAVE_V2
+#  ifdef BOOST_PROCESS_HAVE_V2
 // We can't use v2 API on Windows because v2 API doesn't support
 // process group [1] and GCS testbench uses multiple processes [2].
 //
 // [1] https://github.com/boostorg/process/issues/259
 // [2] https://github.com/googleapis/storage-testbench/issues/669
-#  ifndef _WIN32
-#    define BOOST_PROCESS_USE_V2
+#    ifndef _WIN32
+#      define BOOST_PROCESS_USE_V2
+#    endif
 #  endif
-#endif
 
-#ifdef BOOST_PROCESS_USE_V2
-#  ifdef BOOST_PROCESS_NEED_SOURCE
+#  ifdef BOOST_PROCESS_USE_V2
+#    ifdef BOOST_PROCESS_NEED_SOURCE
 // Workaround for https://github.com/boostorg/process/issues/312
-#    define BOOST_PROCESS_V2_SEPARATE_COMPILATION
-#    ifdef __APPLE__
-#      include <sys/sysctl.h>
+#      define BOOST_PROCESS_V2_SEPARATE_COMPILATION
+#      ifdef __APPLE__
+#        include <sys/sysctl.h>
+#      endif
+#      include <boost/process/v2.hpp>
+#      include <boost/process/v2/src.hpp>
+#    else
+#      include <boost/process/v2.hpp>
 #    endif
-#    include <boost/process/v2.hpp>
-#    include <boost/process/v2/src.hpp>
+#    include <unordered_map>
 #  else
-#    include <boost/process/v2.hpp>
-#  endif
-#  include <unordered_map>
-#else
 // We need BOOST_USE_WINDOWS_H definition with MinGW when we use
 // boost/process.hpp. boost/process/detail/windows/handle_workaround.hpp
 // doesn't work without BOOST_USE_WINDOWS_H with MinGW because MinGW
@@ -58,36 +64,37 @@
 //
 // See also:
 // 
https://github.com/boostorg/process/blob/develop/include/boost/process/detail/windows/handle_workaround.hpp
-#  ifdef __MINGW32__
-#    define BOOST_USE_WINDOWS_H = 1
-#  endif
-#  ifdef BOOST_PROCESS_HAVE_V1
-#    include <boost/process/v1.hpp>
-#  else
-#    include <boost/process.hpp>
+#    ifdef __MINGW32__
+#      define BOOST_USE_WINDOWS_H = 1
+#    endif
+#    ifdef BOOST_PROCESS_HAVE_V1
+#      include <boost/process/v1.hpp>
+#    else
+#      include <boost/process.hpp>
+#    endif
 #  endif
-#endif
 
-#ifdef __APPLE__
-#  include <limits.h>
-#  include <mach-o/dyld.h>
-#endif
+#  ifdef __APPLE__
+#    include <limits.h>
+#    include <mach-o/dyld.h>
+#  endif
 
-#include <chrono>
-#include <iostream>
-#include <sstream>
-#include <thread>
+#  include <chrono>
+#  include <iostream>
+#  include <sstream>
+#  include <thread>
 
-#ifdef BOOST_PROCESS_USE_V2
+#  ifdef BOOST_PROCESS_USE_V2
 namespace asio = BOOST_PROCESS_V2_ASIO_NAMESPACE;
 namespace process = BOOST_PROCESS_V2_NAMESPACE;
 namespace filesystem = process::filesystem;
-#elif defined(BOOST_PROCESS_HAVE_V1)
+#  elif defined(BOOST_PROCESS_HAVE_V1)
 namespace process = boost::process::v1;
 namespace filesystem = boost::process::v1::filesystem;
-#else
+#  else
 namespace process = boost::process;
 namespace filesystem = boost::filesystem;
+#  endif
 #endif
 
 namespace arrow::util {
@@ -96,17 +103,20 @@ class Process::Impl {
  public:
   Impl() {
     // Get a copy of the current environment.
-#ifdef BOOST_PROCESS_USE_V2
+#ifdef BOOST_PROCESS_AVAILABLE
+#  ifdef BOOST_PROCESS_USE_V2
     for (const auto& kv : process::environment::current()) {
       env_[kv.key()] = process::environment::value(kv.value());
     }
-#else
+#  else
     env_ = process::environment(boost::this_process::environment());
+#  endif
 #endif
   }
 
   ~Impl() {
-#ifdef BOOST_PROCESS_USE_V2
+#ifdef BOOST_PROCESS_AVAILABLE
+#  ifdef BOOST_PROCESS_USE_V2
     // V2 doesn't provide process group support yet:
     // https://github.com/boostorg/process/issues/259
     //
@@ -126,94 +136,124 @@ class Process::Impl {
         }
       }
     }
-#else
+#  else
     process_group_ = nullptr;
-#endif
+#  endif
     process_ = nullptr;
+#endif
   }
 
   Status SetExecutable(const std::string& name) {
-#ifdef BOOST_PROCESS_USE_V2
+#ifdef BOOST_PROCESS_AVAILABLE
+#  ifdef BOOST_PROCESS_USE_V2
     executable_ = process::environment::find_executable(name);
-#else
+#  else
     executable_ = process::search_path(name);
-#endif
+#  endif
     if (executable_.empty()) {
       // Search the current executable directory as fallback.
       ARROW_ASSIGN_OR_RAISE(auto current_exe, ResolveCurrentExecutable());
-#ifdef BOOST_PROCESS_USE_V2
+#  ifdef BOOST_PROCESS_USE_V2
       std::unordered_map<process::environment::key, 
process::environment::value> env;
       for (const auto& kv : process::environment::current()) {
         env[kv.key()] = process::environment::value(kv.value());
       }
       env["PATH"] = process::environment::value(current_exe.parent_path());
       executable_ = process::environment::find_executable(name, env);
-#else
+#  else
       executable_ = process::search_path(name, {current_exe.parent_path()});
-#endif
+#  endif
     }
     if (executable_.empty()) {
       return Status::IOError("Failed to find '", name, "' in PATH");
     }
     return Status::OK();
+#else
+    return Status::NotImplemented("Boost.Process isn't available on this 
system");
+#endif
   }
 
-  void SetArgs(const std::vector<std::string>& args) { args_ = args; }
+  void SetArgs(const std::vector<std::string>& args) {
+#ifdef BOOST_PROCESS_AVAILABLE
+    args_ = args;
+#endif
+  }
 
   void SetEnv(const std::string& name, const std::string& value) {
-#ifdef BOOST_PROCESS_USE_V2
+#ifdef BOOST_PROCESS_AVAILABLE
+#  ifdef BOOST_PROCESS_USE_V2
     env_[name] = process::environment::value(value);
-#else
+#  else
     env_[name] = value;
+#  endif
 #endif
   }
 
-  void IgnoreStderr() { keep_stderr_ = false; }
+  void IgnoreStderr() {
+#ifdef BOOST_PROCESS_AVAILABLE
+    keep_stderr_ = false;
+#endif
+  }
 
   Status Execute() {
+#ifdef BOOST_PROCESS_AVAILABLE
     try {
-#ifdef BOOST_PROCESS_USE_V2
+#  ifdef BOOST_PROCESS_USE_V2
       return ExecuteV2();
-#else
+#  else
       return ExecuteV1();
-#endif
+#  endif
     } catch (const std::exception& e) {
       return Status::IOError("Failed to launch '", executable_, "': ", 
e.what());
     }
+#else
+    return Status::NotImplemented("Boost.Process isn't available on this 
system");
+#endif
   }
 
   bool IsRunning() {
-#ifdef BOOST_PROCESS_USE_V2
+#ifdef BOOST_PROCESS_AVAILABLE
+#  ifdef BOOST_PROCESS_USE_V2
     boost::system::error_code error_code;
     return process_ && process_->running(error_code);
-#else
+#  else
     return process_ && process_->running();
+#  endif
+#else
+    return false;
 #endif
   }
 
   uint64_t pid() {
+#ifdef BOOST_PROCESS_AVAILABLE
     if (!process_) {
       return 0;
     }
     return process_->id();
+#else
+    return 0;
+#endif
   }
 
  private:
+#ifdef BOOST_PROCESS_AVAILABLE
   filesystem::path executable_;
   std::vector<std::string> args_;
   bool keep_stderr_ = true;
-#ifdef BOOST_PROCESS_USE_V2
+#  ifdef BOOST_PROCESS_USE_V2
   std::unordered_map<process::environment::key, process::environment::value> 
env_;
   std::unique_ptr<process::process> process_;
   asio::io_context ctx_;
   // boost/process/v2/ doesn't support process group yet:
   // https://github.com/boostorg/process/issues/259
-#else
+#  else
   process::environment env_;
   std::unique_ptr<process::child> process_;
   std::unique_ptr<process::group> process_group_;
+#  endif
 #endif
 
+#ifdef BOOST_PROCESS_AVAILABLE
   Result<filesystem::path> ResolveCurrentExecutable() {
     // See https://stackoverflow.com/a/1024937/10194 for various
     // platform-specific recipes.
@@ -221,25 +261,25 @@ class Process::Impl {
     filesystem::path path;
     boost::system::error_code error_code;
 
-#if defined(__linux__)
+#  if defined(__linux__)
     path = filesystem::canonical("/proc/self/exe", error_code);
-#elif defined(__APPLE__)
+#  elif defined(__APPLE__)
     char buf[PATH_MAX + 1];
     uint32_t bufsize = sizeof(buf);
     if (_NSGetExecutablePath(buf, &bufsize) < 0) {
       return Status::Invalid("Can't resolve current exe: path too large");
     }
     path = filesystem::canonical(buf, error_code);
-#elif defined(_WIN32)
+#  elif defined(_WIN32)
     char buf[MAX_PATH + 1];
     if (!GetModuleFileNameA(NULL, buf, sizeof(buf))) {
       return Status::Invalid("Can't get executable file path");
     }
     path = filesystem::canonical(buf, error_code);
-#else
+#  else
     ARROW_UNUSED(error_code);
     return Status::NotImplemented("Not available on this system");
-#endif
+#  endif
     if (error_code) {
       // XXX fold this into the Status class?
       return Status::IOError("Can't resolve current exe: ", 
error_code.message());
@@ -248,7 +288,7 @@ class Process::Impl {
     }
   }
 
-#ifdef BOOST_PROCESS_USE_V2
+#  ifdef BOOST_PROCESS_USE_V2
   Status ExecuteV2() {
     process::process_environment env(env_);
     // We can't use std::make_unique<process::process>.
@@ -258,7 +298,7 @@ class Process::Impl {
                                           : process::process_stdio{{}, {}, 
nullptr}));
     return Status::OK();
   }
-#else
+#  else
   Status ExecuteV1() {
     process_group_ = std::make_unique<process::group>();
     if (keep_stderr_) {
@@ -271,6 +311,7 @@ class Process::Impl {
     }
     return Status::OK();
   }
+#  endif
 #endif
 };
 

Reply via email to