This is an automated email from the ASF dual-hosted git repository.
amoeba 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 876d50c6cc GH-49981: [R][Packaging] Support building R package under
r-universe/r-wasm (#49982)
876d50c6cc is described below
commit 876d50c6cc30ad1a26620529b6ad7da3ee209f41
Author: Bryce Mecum <[email protected]>
AuthorDate: Tue May 19 11:06:47 2026 -0700
GH-49981: [R][Packaging] Support building R package under r-universe/r-wasm
(#49982)
### Rationale for this change
Arrow C++ already supports Emscripten but the R package can't be built by
either the r-wasm or r-universe projects in its current state. We just need to
make the bundled build Emscripten aware we're in an Emscripten environment for
this to work.
### What changes are included in this PR?
- Adds Wasm detection to nixlibs.R
- Makes `build_arrow_static.sh` Emscripten-aware by adding support for
being called with a wrapper program
- Adds a new crossbow job to test building the R package with r-wasm in the
r-universe container
### Are these changes tested?
Yes. The R package builds in a local docker r-wasm-based container as well
as in Crossbow
### Are there any user-facing changes?
No.
* GitHub Issue: #49981
Authored-by: Bryce Mecum <[email protected]>
Signed-off-by: Bryce Mecum <[email protected]>
---
dev/tasks/r/github.linux.r-wasm.yml | 75 +++++++++++++++++++++++++++++++++++++
dev/tasks/tasks.yml | 4 ++
r/inst/build_arrow_static.sh | 7 +++-
r/tools/nixlibs.R | 35 +++++++++++++++++
4 files changed, 120 insertions(+), 1 deletion(-)
diff --git a/dev/tasks/r/github.linux.r-wasm.yml
b/dev/tasks/r/github.linux.r-wasm.yml
new file mode 100644
index 0000000000..ee38740bb4
--- /dev/null
+++ b/dev/tasks/r/github.linux.r-wasm.yml
@@ -0,0 +1,75 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+{% import 'macros.jinja' as macros with context %}
+
+{{ macros.github_header() }}
+
+jobs:
+ r-universe-wasm:
+ name: "R-universe Wasm build"
+ runs-on: ubuntu-latest
+ timeout-minutes: 60
+
+ steps:
+ {{ macros.github_checkout_arrow()|indent }}
+
+ - uses: r-lib/actions/setup-r@v2
+ with:
+ install-r: true
+
+ - name: Build Arrow R source package
+ shell: bash
+ run: |
+ cd arrow/r
+ make sync-cpp
+ R CMD build --no-build-vignettes .
+
+ - name: Pull the R-universe Wasm image
+ shell: bash
+ run: docker pull ghcr.io/r-universe-org/build-wasm:latest
+
+ - name: Build Wasm binary in the R-universe container
+ shell: bash
+ run: |
+ docker run --rm \
+ -v "${PWD}/arrow/r:/work" \
+ -w /work \
+ ghcr.io/r-universe-org/build-wasm:latest \
+ bash -lc '
+ set -euxo pipefail
+ R -q -e "if (!requireNamespace(\"pak\", quietly = TRUE))
install.packages(\"pak\", repos = \"https://cloud.r-project.org\"); if
(!requireNamespace(\"rwasm\", quietly = TRUE)) pak::pak(\"r-wasm/rwasm\");
rwasm::build(\".\")" \
+ 2>&1 | tee build-wasm.log
+ '
+
+ - name: List generated artifacts
+ if: always()
+ shell: bash
+ run: |
+ ls -lh arrow/r/arrow_*.tar.gz
+ ls -lh arrow/r/arrow_*.tgz || true
+ ls -lh arrow/r/build-wasm.log || true
+
+ - name: Upload Wasm build artifacts
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: r-wasm-build
+ path: |
+ arrow/r/arrow_*.tar.gz
+ arrow/r/arrow_*.tgz
+ arrow/r/build-wasm.log
diff --git a/dev/tasks/tasks.yml b/dev/tasks/tasks.yml
index 9647e5531d..2d2b9ae39e 100644
--- a/dev/tasks/tasks.yml
+++ b/dev/tasks/tasks.yml
@@ -651,6 +651,10 @@ tasks:
env:
CMAKE_BUILD_TYPE: MinSizeRel
+ test-r-wasm:
+ ci: github
+ template: r/github.linux.r-wasm.yml
+
test-r-devdocs:
ci: github
template: r/github.devdocs.yml
diff --git a/r/inst/build_arrow_static.sh b/r/inst/build_arrow_static.sh
index 241994223d..349531b75f 100755
--- a/r/inst/build_arrow_static.sh
+++ b/r/inst/build_arrow_static.sh
@@ -62,9 +62,12 @@ case "$CXX" in
;;
esac
+# Used for Emscripten
+: ${CMAKE_WRAPPER:=""}
+
mkdir -p "${BUILD_DIR}"
pushd "${BUILD_DIR}"
-${CMAKE} -DARROW_BOOST_USE_SHARED=OFF \
+${CMAKE_WRAPPER} ${CMAKE} -DARROW_BOOST_USE_SHARED=OFF \
-DARROW_SNAPPY_USE_SHARED=OFF \
-DARROW_BUILD_TESTS=OFF \
-DARROW_BUILD_SHARED=OFF \
@@ -74,6 +77,8 @@ ${CMAKE} -DARROW_BOOST_USE_SHARED=OFF \
-DARROW_CSV=ON \
-DARROW_DATASET=${ARROW_DATASET:-ON} \
-DARROW_DEPENDENCY_SOURCE=${ARROW_DEPENDENCY_SOURCE:-AUTO} \
+ -DARROW_DEPENDENCY_USE_SHARED=${ARROW_DEPENDENCY_USE_SHARED:-ON} \
+ -DARROW_ENABLE_THREADING=${ARROW_ENABLE_THREADING:-ON} \
-DAWSSDK_SOURCE=${AWSSDK_SOURCE:-} \
-DBoost_SOURCE=${Boost_SOURCE:-} \
-Dlz4_SOURCE=${lz4_SOURCE:-} \
diff --git a/r/tools/nixlibs.R b/r/tools/nixlibs.R
index 947bb6c3f5..ba705e03ad 100644
--- a/r/tools/nixlibs.R
+++ b/r/tools/nixlibs.R
@@ -616,6 +616,7 @@ build_libarrow <- function(src_dir, dst_dir) {
}
env_var_list <- with_cloud_support(env_var_list)
+ env_var_list <- with_wasm_support(env_var_list)
# turn_off_all_optional_features() needs to happen after
# with_cloud_support(), since it might turn features ON.
@@ -883,6 +884,40 @@ is_feature_requested <- function(env_varname,
env_var_list, default = env_is("LI
requested
}
+with_wasm_support <- function(env_var_list) {
+ cc <- env_var_list[["CC"]]
+ cxx <- env_var_list[["CXX"]]
+ if (!grepl("emcc", cc) && !grepl("em\\+\\+", cxx)) {
+ return(env_var_list)
+ }
+
+ lg("Emscripten compiler detected; configuring for WASM build", .indent =
"****")
+
+ if (!nzchar(Sys.which("emcmake"))) {
+ stop("emcmake is required for Emscripten/webR builds but was not found in
PATH")
+ }
+
+ wasm_overrides <- c(
+ CMAKE_WRAPPER = "emcmake",
+ ARROW_DEPENDENCY_SOURCE = "BUNDLED",
+ ARROW_DEPENDENCY_USE_SHARED = "OFF",
+ ARROW_ENABLE_THREADING = "OFF",
+ ARROW_GCS = "OFF",
+ ARROW_JEMALLOC = "OFF",
+ ARROW_MIMALLOC = "OFF",
+ ARROW_S3 = "OFF",
+ ARROW_WITH_BROTLI = "OFF",
+ ARROW_WITH_BZ2 = "OFF",
+ ARROW_WITH_ZSTD = "OFF",
+ N_JOBS = "2",
+ EXTRA_CMAKE_FLAGS = paste(
+ env_var_list[["EXTRA_CMAKE_FLAGS"]],
+ "-DARROW_SIMD_LEVEL=NONE -DARROW_RUNTIME_SIMD_LEVEL=NONE"
+ )
+ )
+ replace(env_var_list, names(wasm_overrides), wasm_overrides)
+}
+
with_cloud_support <- function(env_var_list) {
arrow_s3 <- is_feature_requested("ARROW_S3", env_var_list)
arrow_gcs <- is_feature_requested("ARROW_GCS", env_var_list)