]> git.proxmox.com Git - ceph.git/blob - ceph/src/arrow/r/tools/nixlibs.R
import quincy 17.2.0
[ceph.git] / ceph / src / arrow / r / tools / nixlibs.R
1 # Licensed to the Apache Software Foundation (ASF) under one
2 # or more contributor license agreements. See the NOTICE file
3 # distributed with this work for additional information
4 # regarding copyright ownership. The ASF licenses this file
5 # to you under the Apache License, Version 2.0 (the
6 # "License"); you may not use this file except in compliance
7 # with the License. You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing,
12 # software distributed under the License is distributed on an
13 # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # KIND, either express or implied. See the License for the
15 # specific language governing permissions and limitations
16 # under the License.
17
18 args <- commandArgs(TRUE)
19 VERSION <- args[1]
20 dst_dir <- paste0("libarrow/arrow-", VERSION)
21
22 arrow_repo <- "https://arrow-r-nightly.s3.amazonaws.com/libarrow/"
23
24 if (getRversion() < 3.4 && is.null(getOption("download.file.method"))) {
25 # default method doesn't work on R 3.3, nor does libcurl
26 options(download.file.method = "wget")
27 }
28
29 options(.arrow.cleanup = character()) # To collect dirs to rm on exit
30 on.exit(unlink(getOption(".arrow.cleanup")))
31
32 env_is <- function(var, value) identical(tolower(Sys.getenv(var)), value)
33
34 try_download <- function(from_url, to_file) {
35 status <- try(
36 suppressWarnings(
37 download.file(from_url, to_file, quiet = quietly)
38 ),
39 silent = quietly
40 )
41 # Return whether the download was successful
42 !inherits(status, "try-error") && status == 0
43 }
44
45 # For local debugging, set ARROW_R_DEV=TRUE to make this script print more
46 quietly <- !env_is("ARROW_R_DEV", "true")
47
48 # Default is build from source, not download a binary
49 build_ok <- !env_is("LIBARROW_BUILD", "false")
50 binary_ok <- env_is("LIBARROW_BINARY", "true")
51
52 # Check if we're doing an offline build.
53 # (Note that cmake will still be downloaded if necessary
54 # https://arrow.apache.org/docs/developers/cpp/building.html#offline-builds)
55 download_ok <- !env_is("TEST_OFFLINE_BUILD", "true") && try_download("https://github.com", tempfile())
56
57 # This "tools/thirdparty_dependencies" path, within the tar file, might exist if
58 # create_package_with_all_dependencies() was run, or if someone has created it
59 # manually before running make build.
60 # If you change this path, you also need to edit
61 # `create_package_with_all_dependencies()` in install-arrow.R
62 thirdparty_dependency_dir <- Sys.getenv("ARROW_THIRDPARTY_DEPENDENCY_DIR", "tools/thirdparty_dependencies")
63
64
65 download_binary <- function(os = identify_os()) {
66 libfile <- tempfile()
67 if (!is.null(os)) {
68 # See if we can map this os-version to one we have binaries for
69 os <- find_available_binary(os)
70 binary_url <- paste0(arrow_repo, "bin/", os, "/arrow-", VERSION, ".zip")
71 if (try_download(binary_url, libfile)) {
72 cat(sprintf("*** Successfully retrieved C++ binaries for %s\n", os))
73 if (!identical(os, "centos-7")) {
74 # centos-7 uses gcc 4.8 so the binary doesn't have ARROW_S3=ON but the others do
75 # TODO: actually check for system requirements?
76 cat("**** Binary package requires libcurl and openssl\n")
77 cat("**** If installation fails, retry after installing those system requirements\n")
78 }
79 } else {
80 cat(sprintf("*** No C++ binaries found for %s\n", os))
81 libfile <- NULL
82 }
83 } else {
84 libfile <- NULL
85 }
86 libfile
87 }
88
89 # Function to figure out which flavor of binary we should download, if at all.
90 # By default (unset or "FALSE"), it will not download a precompiled library,
91 # but you can override this by setting the env var LIBARROW_BINARY to:
92 # * `TRUE` (not case-sensitive), to try to discover your current OS, or
93 # * some other string, presumably a related "distro-version" that has binaries
94 # built that work for your OS
95 identify_os <- function(os = Sys.getenv("LIBARROW_BINARY")) {
96 if (tolower(os) %in% c("", "false")) {
97 # Env var says not to download a binary
98 return(NULL)
99 } else if (!identical(tolower(os), "true")) {
100 # Env var provided an os-version to use--maybe you're on Ubuntu 18.10 but
101 # we only build for 18.04 and that's fine--so use what the user set
102 return(os)
103 }
104
105 linux <- distro()
106 if (is.null(linux)) {
107 cat("*** Unable to identify current OS/version\n")
108 return(NULL)
109 }
110 paste(linux$id, linux$short_version, sep = "-")
111 }
112
113 #### start distro ####
114
115 distro <- function() {
116 # The code in this script is a (potentially stale) copy of the distro package
117 if (requireNamespace("distro", quietly = TRUE)) {
118 # Use the version from the package, which may be updated from this
119 return(distro::distro())
120 }
121
122 out <- lsb_release()
123 if (is.null(out)) {
124 out <- os_release()
125 if (is.null(out)) {
126 out <- system_release()
127 }
128 }
129 if (is.null(out)) {
130 return(NULL)
131 }
132
133 out$id <- tolower(out$id)
134 # debian unstable & testing lsb_release `version` don't include numbers but we can map from pretty name
135 if (is.null(out$version) || out$version %in% c("testing", "unstable")) {
136 if (grepl("bullseye", out$codename)) {
137 out$short_version <- "11"
138 } else if (grepl("bookworm", out$codename)) {
139 out$short_version <- "12"
140 }
141 } else if (out$id == "ubuntu") {
142 # Keep major.minor version
143 out$short_version <- sub('^"?([0-9]+\\.[0-9]+).*"?.*$', "\\1", out$version)
144 } else {
145 # Only major version number
146 out$short_version <- sub('^"?([0-9]+).*"?.*$', "\\1", out$version)
147 }
148 out
149 }
150
151 lsb_release <- function() {
152 if (have_lsb_release()) {
153 list(
154 id = call_lsb("-is"),
155 version = call_lsb("-rs"),
156 codename = call_lsb("-cs")
157 )
158 } else {
159 NULL
160 }
161 }
162
163 have_lsb_release <- function() nzchar(Sys.which("lsb_release"))
164 call_lsb <- function(args) system(paste("lsb_release", args), intern = TRUE)
165
166 os_release <- function() {
167 rel_data <- read_os_release()
168 if (!is.null(rel_data)) {
169 vals <- as.list(sub('^.*="?(.*?)"?$', "\\1", rel_data))
170 names(vals) <- sub("^(.*)=.*$", "\\1", rel_data)
171
172 out <- list(
173 id = vals[["ID"]],
174 version = vals[["VERSION_ID"]]
175 )
176 if ("VERSION_CODENAME" %in% names(vals)) {
177 out$codename <- vals[["VERSION_CODENAME"]]
178 } else {
179 # This probably isn't right, maybe could extract codename from pretty name?
180 out$codename <- vals[["PRETTY_NAME"]]
181 }
182 out
183 } else {
184 NULL
185 }
186 }
187
188 read_os_release <- function() {
189 if (file.exists("/etc/os-release")) {
190 readLines("/etc/os-release")
191 }
192 }
193
194 system_release <- function() {
195 rel_data <- read_system_release()
196 if (!is.null(rel_data)) {
197 # Something like "CentOS Linux release 7.7.1908 (Core)"
198 list(
199 id = sub("^([a-zA-Z]+) .* ([0-9.]+).*$", "\\1", rel_data),
200 version = sub("^([a-zA-Z]+) .* ([0-9.]+).*$", "\\2", rel_data),
201 codename = NA
202 )
203 } else {
204 NULL
205 }
206 }
207
208 read_system_release <- function() {
209 if (file.exists("/etc/system-release")) {
210 readLines("/etc/system-release")[1]
211 }
212 }
213
214 #### end distro ####
215
216 find_available_binary <- function(os) {
217 # Download a csv that maps one to the other, columns "actual" and "use_this"
218 u <- "https://raw.githubusercontent.com/ursa-labs/arrow-r-nightly/master/linux/distro-map.csv"
219 lookup <- try(utils::read.csv(u, stringsAsFactors = FALSE), silent = quietly)
220 if (!inherits(lookup, "try-error") && os %in% lookup$actual) {
221 new <- lookup$use_this[lookup$actual == os]
222 if (length(new) == 1 && !is.na(new)) { # Just some sanity checking
223 cat(sprintf("*** Using %s binary for %s\n", new, os))
224 os <- new
225 }
226 }
227 os
228 }
229
230 find_local_source <- function() {
231 # We'll take the first of these that exists
232 # The first case probably occurs if we're in the arrow git repo
233 # The second probably occurs if we're installing the arrow R package
234 cpp_dir_options <- c(
235 file.path(Sys.getenv("ARROW_SOURCE_HOME", ".."), "cpp"),
236 "tools/cpp"
237 )
238 for (cpp_dir in cpp_dir_options) {
239 if (file.exists(file.path(cpp_dir, "src/arrow/api.h"))) {
240 cat(paste0("*** Found local C++ source: '", cpp_dir, "'\n"))
241 return(cpp_dir)
242 }
243 }
244 NULL
245 }
246
247 env_vars_as_string <- function(env_var_list) {
248 # Do some basic checks on env_var_list:
249 # Check that env_var_list has names, that those names are valid POSIX
250 # environment variables, and that none of the values contain `'`.
251 stopifnot(
252 length(env_var_list) == length(names(env_var_list)),
253 all(grepl("^[^0-9]", names(env_var_list))),
254 all(grepl("^[A-Z0-9_]+$", names(env_var_list))),
255 !any(grepl("'", env_var_list, fixed = TRUE))
256 )
257 env_var_string <- paste0(names(env_var_list), "='", env_var_list, "'", collapse = " ")
258 if (nchar(env_var_string) > 30000) {
259 # This could happen if the full paths in *_SOURCE_URL were *very* long.
260 # A more formal check would look at getconf ARG_MAX, but this shouldn't matter
261 cat("*** Warning: Environment variables are very long. This could cause issues on some shells.\n")
262 }
263 env_var_string
264 }
265
266 build_libarrow <- function(src_dir, dst_dir) {
267 # We'll need to compile R bindings with these libs, so delete any .o files
268 system("rm src/*.o", ignore.stdout = TRUE, ignore.stderr = TRUE)
269 # Set up make for parallel building
270 makeflags <- Sys.getenv("MAKEFLAGS")
271 if (makeflags == "") {
272 # CRAN policy says not to use more than 2 cores during checks
273 # If you have more and want to use more, set MAKEFLAGS
274 ncores <- min(parallel::detectCores(), 2)
275 makeflags <- sprintf("-j%s", ncores)
276 Sys.setenv(MAKEFLAGS = makeflags)
277 }
278 if (!quietly) {
279 cat("*** Building with MAKEFLAGS=", makeflags, "\n")
280 }
281 # Check for libarrow build dependencies:
282 # * cmake
283 cmake <- ensure_cmake()
284
285 # Optionally build somewhere not in tmp so we can dissect the build if it fails
286 debug_dir <- Sys.getenv("LIBARROW_DEBUG_DIR")
287 if (nzchar(debug_dir)) {
288 build_dir <- debug_dir
289 } else {
290 # But normally we'll just build in a tmp dir
291 build_dir <- tempfile()
292 }
293 options(.arrow.cleanup = c(getOption(".arrow.cleanup"), build_dir))
294
295 R_CMD_config <- function(var) {
296 if (getRversion() < 3.4) {
297 # var names were called CXX1X instead of CXX11
298 var <- sub("^CXX11", "CXX1X", var)
299 }
300 # tools::Rcmd introduced R 3.3
301 tools::Rcmd(paste("config", var), stdout = TRUE)
302 }
303 env_var_list <- c(
304 SOURCE_DIR = src_dir,
305 BUILD_DIR = build_dir,
306 DEST_DIR = dst_dir,
307 CMAKE = cmake,
308 # EXTRA_CMAKE_FLAGS will often be "", but it's convenient later to have it defined
309 EXTRA_CMAKE_FLAGS = Sys.getenv("EXTRA_CMAKE_FLAGS"),
310 # Make sure we build with the same compiler settings that R is using
311 CC = R_CMD_config("CC"),
312 CXX = paste(R_CMD_config("CXX11"), R_CMD_config("CXX11STD")),
313 # CXXFLAGS = R_CMD_config("CXX11FLAGS"), # We don't want the same debug symbols
314 LDFLAGS = R_CMD_config("LDFLAGS")
315 )
316 env_var_list <- with_s3_support(env_var_list)
317 env_var_list <- with_mimalloc(env_var_list)
318
319 # turn_off_all_optional_features() needs to happen after with_mimalloc() and
320 # with_s3_support(), since those might turn features ON.
321 thirdparty_deps_unavailable <- !download_ok &&
322 !dir.exists(thirdparty_dependency_dir) &&
323 !env_is("ARROW_DEPENDENCY_SOURCE", "system")
324 on_solaris <- tolower(Sys.info()[["sysname"]]) %in% "sunos"
325 do_minimal_build <- on_solaris || env_is("LIBARROW_MINIMAL", "true")
326
327 if (do_minimal_build) {
328 # Note that JSON support does work on Solaris, but will be turned off with
329 # the rest of the optional dependencies.
330 # All other dependencies don't compile (e.g thrift, jemalloc, and xsimd)
331 # or do compile but `ar` fails to build
332 # libarrow_bundled_dependencies (e.g. re2 and utf8proc).
333 env_var_list <- turn_off_all_optional_features(env_var_list)
334 } else if (thirdparty_deps_unavailable) {
335 cat(paste0(
336 "*** Building C++ library from source, but downloading thirdparty dependencies\n",
337 " is not possible, so this build will turn off all thirdparty features.\n",
338 " See install vignette for details:\n",
339 " https://cran.r-project.org/web/packages/arrow/vignettes/install.html\n"
340 ))
341 env_var_list <- turn_off_all_optional_features(env_var_list)
342 } else if (dir.exists(thirdparty_dependency_dir)) {
343 # Add the *_SOURCE_URL env vars
344 env_var_list <- set_thirdparty_urls(env_var_list)
345 }
346 env_vars <- env_vars_as_string(env_var_list)
347
348 cat("**** arrow", ifelse(quietly, "", paste("with", env_vars)), "\n")
349 status <- suppressWarnings(system(
350 paste(env_vars, "inst/build_arrow_static.sh"),
351 ignore.stdout = quietly, ignore.stderr = quietly
352 ))
353 if (status != 0) {
354 # It failed :(
355 cat(
356 "**** Error building Arrow C++.",
357 ifelse(env_is("ARROW_R_DEV", "true"), "", "Re-run with ARROW_R_DEV=true for debug information."),
358 "\n"
359 )
360 }
361 invisible(status)
362 }
363
364 ensure_cmake <- function() {
365 cmake <- find_cmake(c(
366 Sys.getenv("CMAKE"),
367 Sys.which("cmake"),
368 Sys.which("cmake3")
369 ))
370
371 if (is.null(cmake)) {
372 # If not found, download it
373 cat("**** cmake\n")
374 CMAKE_VERSION <- Sys.getenv("CMAKE_VERSION", "3.19.2")
375 if (tolower(Sys.info()[["sysname"]]) %in% "darwin") {
376 postfix <- "-macos-universal.tar.gz"
377 } else {
378 postfix <- "-Linux-x86_64.tar.gz"
379 }
380 cmake_binary_url <- paste0(
381 "https://github.com/Kitware/CMake/releases/download/v", CMAKE_VERSION,
382 "/cmake-", CMAKE_VERSION, postfix
383 )
384 cmake_tar <- tempfile()
385 cmake_dir <- tempfile()
386 download_successful <- try_download(cmake_binary_url, cmake_tar)
387 if (!download_successful) {
388 cat(paste0(
389 "*** cmake was not found locally and download failed.\n",
390 " Make sure cmake >= 3.10 is installed and available on your PATH,\n",
391 " or download ", cmake_binary_url, "\n",
392 " and define the CMAKE environment variable.\n"
393 ))
394 }
395 untar(cmake_tar, exdir = cmake_dir)
396 unlink(cmake_tar)
397 options(.arrow.cleanup = c(getOption(".arrow.cleanup"), cmake_dir))
398 cmake <- paste0(
399 cmake_dir,
400 "/cmake-", CMAKE_VERSION, sub(".tar.gz", "", postfix, fixed = TRUE),
401 "/bin/cmake"
402 )
403 }
404 cmake
405 }
406
407 find_cmake <- function(paths, version_required = 3.10) {
408 # Given a list of possible cmake paths, return the first one that exists and is new enough
409 for (path in paths) {
410 if (nzchar(path) && cmake_version(path) >= version_required) {
411 # Sys.which() returns a named vector, but that plays badly with c() later
412 names(path) <- NULL
413 return(path)
414 }
415 }
416 # If none found, return NULL
417 NULL
418 }
419
420 cmake_version <- function(cmd = "cmake") {
421 tryCatch(
422 {
423 raw_version <- system(paste(cmd, "--version"), intern = TRUE, ignore.stderr = TRUE)
424 pat <- ".* ([0-9\\.]+).*?"
425 which_line <- grep(pat, raw_version)
426 package_version(sub(pat, "\\1", raw_version[which_line]))
427 },
428 error = function(e) {
429 return(0)
430 }
431 )
432 }
433
434 turn_off_all_optional_features <- function(env_var_list) {
435 # Because these are done as environment variables (as opposed to build flags),
436 # setting these to "OFF" overrides any previous setting. We don't need to
437 # check the existing value.
438 turn_off <- c(
439 "ARROW_MIMALLOC" = "OFF",
440 "ARROW_JEMALLOC" = "OFF",
441 "ARROW_JSON" = "OFF",
442 "ARROW_PARQUET" = "OFF", # depends on thrift
443 "ARROW_DATASET" = "OFF", # depends on parquet
444 "ARROW_S3" = "OFF",
445 "ARROW_WITH_BROTLI" = "OFF",
446 "ARROW_WITH_BZ2" = "OFF",
447 "ARROW_WITH_LZ4" = "OFF",
448 "ARROW_WITH_SNAPPY" = "OFF",
449 "ARROW_WITH_ZLIB" = "OFF",
450 "ARROW_WITH_ZSTD" = "OFF",
451 "ARROW_WITH_RE2" = "OFF",
452 "ARROW_WITH_UTF8PROC" = "OFF",
453 # The syntax to turn off XSIMD is different.
454 # Pull existing value of EXTRA_CMAKE_FLAGS first (must be defined)
455 "EXTRA_CMAKE_FLAGS" = paste(
456 env_var_list[["EXTRA_CMAKE_FLAGS"]],
457 "-DARROW_SIMD_LEVEL=NONE -DARROW_RUNTIME_SIMD_LEVEL=NONE"
458 )
459 )
460 # Create a new env_var_list, with the values of turn_off set.
461 # replace() also adds new values if they didn't exist before
462 replace(env_var_list, names(turn_off), turn_off)
463 }
464
465 set_thirdparty_urls <- function(env_var_list) {
466 # This function does *not* check if existing *_SOURCE_URL variables are set.
467 # The directory tools/thirdparty_dependencies is created by
468 # create_package_with_all_dependencies() and saved in the tar file.
469 files <- list.files(thirdparty_dependency_dir, full.names = FALSE)
470 url_env_varname <- toupper(sub("(.*?)-.*", "ARROW_\\1_URL", files))
471 # Special handling for the aws dependencies, which have extra `-`
472 aws <- grepl("^aws", files)
473 url_env_varname[aws] <- sub(
474 "AWS_SDK_CPP", "AWSSDK",
475 gsub(
476 "-", "_",
477 sub(
478 "(AWS.*)-.*", "ARROW_\\1_URL",
479 toupper(files[aws])
480 )
481 )
482 )
483 full_filenames <- file.path(normalizePath(thirdparty_dependency_dir), files)
484
485 env_var_list <- replace(env_var_list, url_env_varname, full_filenames)
486 if (!quietly) {
487 env_var_list <- replace(env_var_list, "ARROW_VERBOSE_THIRDPARTY_BUILD", "ON")
488 }
489 env_var_list
490 }
491
492 is_feature_requested <- function(env_varname, default = env_is("LIBARROW_MINIMAL", "false")) {
493 env_value <- tolower(Sys.getenv(env_varname))
494 if (identical(env_value, "off")) {
495 # If e.g. ARROW_MIMALLOC=OFF explicitly, override default
496 requested <- FALSE
497 } else if (identical(env_value, "on")) {
498 requested <- TRUE
499 } else {
500 requested <- default
501 }
502 requested
503 }
504
505 with_mimalloc <- function(env_var_list) {
506 arrow_mimalloc <- is_feature_requested("ARROW_MIMALLOC")
507 if (arrow_mimalloc) {
508 # User wants mimalloc. If they're using gcc, let's make sure the version is >= 4.9
509 if (isTRUE(cmake_gcc_version(env_var_list) < "4.9")) {
510 cat("**** mimalloc support not available for gcc < 4.9; building with ARROW_MIMALLOC=OFF\n")
511 arrow_mimalloc <- FALSE
512 }
513 }
514 replace(env_var_list, "ARROW_MIMALLOC", ifelse(arrow_mimalloc, "ON", "OFF"))
515 }
516
517 with_s3_support <- function(env_var_list) {
518 arrow_s3 <- is_feature_requested("ARROW_S3")
519 if (arrow_s3) {
520 # User wants S3 support. If they're using gcc, let's make sure the version is >= 4.9
521 # and make sure that we have curl and openssl system libs
522 if (isTRUE(cmake_gcc_version(env_var_list) < "4.9")) {
523 cat("**** S3 support not available for gcc < 4.9; building with ARROW_S3=OFF\n")
524 arrow_s3 <- FALSE
525 } else if (!cmake_find_package("CURL", NULL, env_var_list)) {
526 # curl on macos should be installed, so no need to alter this for macos
527 cat("**** S3 support requires libcurl-devel (rpm) or libcurl4-openssl-dev (deb); building with ARROW_S3=OFF\n")
528 arrow_s3 <- FALSE
529 } else if (!cmake_find_package("OpenSSL", "1.0.2", env_var_list)) {
530 cat("**** S3 support requires version >= 1.0.2 of openssl-devel (rpm), libssl-dev (deb), or openssl (brew); building with ARROW_S3=OFF\n")
531 arrow_s3 <- FALSE
532 }
533 }
534 replace(env_var_list, "ARROW_S3", ifelse(arrow_s3, "ON", "OFF"))
535 }
536
537 cmake_gcc_version <- function(env_var_list) {
538 # This function returns NA if using a non-gcc compiler
539 # Always enclose calls to it in isTRUE() or isFALSE()
540 vals <- cmake_cxx_compiler_vars(env_var_list)
541 if (!identical(vals[["CMAKE_CXX_COMPILER_ID"]], "GNU")) {
542 return(NA)
543 }
544 package_version(vals[["CMAKE_CXX_COMPILER_VERSION"]])
545 }
546
547 cmake_cxx_compiler_vars <- function(env_var_list) {
548 env_vars <- env_vars_as_string(env_var_list)
549 info <- system(paste("export", env_vars, "&& $CMAKE --system-information"), intern = TRUE)
550 info <- grep("^[A-Z_]* .*$", info, value = TRUE)
551 vals <- as.list(sub('^.*? "?(.*?)"?$', "\\1", info))
552 names(vals) <- sub("^(.*?) .*$", "\\1", info)
553 vals[grepl("^CMAKE_CXX_COMPILER_?", names(vals))]
554 }
555
556 cmake_find_package <- function(pkg, version = NULL, env_var_list) {
557 td <- tempfile()
558 dir.create(td)
559 options(.arrow.cleanup = c(getOption(".arrow.cleanup"), td))
560 find_package <- paste0("find_package(", pkg, " ", version, " REQUIRED)")
561 writeLines(find_package, file.path(td, "CMakeLists.txt"))
562 env_vars <- env_vars_as_string(env_var_list)
563 cmake_cmd <- paste0(
564 "export ", env_vars,
565 " && cd ", td,
566 " && $CMAKE ",
567 " -DCMAKE_EXPORT_NO_PACKAGE_REGISTRY=ON",
568 " -DCMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY=ON",
569 " ."
570 )
571 system(cmake_cmd, ignore.stdout = TRUE, ignore.stderr = TRUE) == 0
572 }
573
574 #####
575
576 if (!file.exists(paste0(dst_dir, "/include/arrow/api.h"))) {
577 # If we're working in a local checkout and have already built the libs, we
578 # don't need to do anything. Otherwise,
579 # (1) Look for a prebuilt binary for this version
580 bin_file <- src_dir <- NULL
581 if (download_ok && binary_ok) {
582 bin_file <- download_binary()
583 }
584 if (!is.null(bin_file)) {
585 # Extract them
586 dir.create(dst_dir, showWarnings = !quietly, recursive = TRUE)
587 unzip(bin_file, exdir = dst_dir)
588 unlink(bin_file)
589 } else if (build_ok) {
590 # (2) Find source and build it
591 src_dir <- find_local_source()
592 if (!is.null(src_dir)) {
593 cat("*** Building C++ libraries\n")
594 build_libarrow(src_dir, dst_dir)
595 } else {
596 cat("*** Proceeding without C++ dependencies\n")
597 }
598 } else {
599 cat("*** Proceeding without C++ dependencies\n")
600 }
601 }