tools/config.R

# Note: Any variables prefixed with `.` are used for text
# replacement in the Makevars.in and Makevars.win.in

# check the packages MSRV first
source("tools/msrv.R")

# check DEBUG and NOT_CRAN environment variables
env_debug <- Sys.getenv("DEBUG")
env_not_cran <- Sys.getenv("NOT_CRAN")

# check if the vendored zip file exists
vendor_exists <- file.exists("src/rust/vendor.tar.xz")

is_not_cran <- env_not_cran != ""
is_debug <- env_debug != ""

if (is_debug) {
  # if we have DEBUG then we set not cran to true
  # CRAN is always release build
  is_not_cran <- TRUE
  message("Creating DEBUG build.")
}

if (!is_not_cran) {
  message("Building for CRAN.")
}

# we set cran flags only if NOT_CRAN is empty and if
# the vendored crates are present.
.cran_flags <- ifelse(
  !is_not_cran && vendor_exists,
  "-j 2 --offline",
  ""
)

# when DEBUG env var is present we use `--debug` build
.profile <- ifelse(is_debug, "", "--release")
.clean_targets <- ifelse(is_debug, "", "$(TARGET_DIR)")

# We specify this target when building for webR
webr_target <- "wasm32-unknown-emscripten"

# here we check if the platform we are building for is webr
is_wasm <- identical(R.version$platform, webr_target)

# print to terminal to inform we are building for webr
if (is_wasm) {
  message("Building for WebR")
}

# we check if we are making a debug build or not
# if so, the LIBDIR environment variable becomes:
# LIBDIR = $(TARGET_DIR)/{wasm32-unknown-emscripten}/debug
# this will be used to fill out the LIBDIR env var for Makevars.in
target_libpath <- if (is_wasm) "wasm32-unknown-emscripten" else NULL
cfg <- if (is_debug) "debug" else "release"

# used to replace @LIBDIR@
.libdir <- paste(c(target_libpath, cfg), collapse = "/")

# use this to replace @TARGET@
# we specify the target _only_ on webR
# there may be use cases later where this can be adapted or expanded
.target <- ifelse(is_wasm, paste0("--target=", webr_target), "")

# add panic exports only for WASM builds
.panic_exports <- ifelse(
  is_wasm,
  "CARGO_PROFILE_DEV_PANIC=\"abort\" CARGO_PROFILE_RELEASE_PANIC=\"abort\" ",
  ""
)

# macOS deployment target ---------------------------------------------------
#
# The `cc` crate (used to assemble psm/stacker) falls back to the *SDK* version
# when MACOSX_DEPLOYMENT_TARGET is unset, while the final link performed by R
# targets whatever R's C compiler targets. The mismatch makes ld emit "object
# file was built for newer 'macOS' version than being linked", which
# `R CMD check` reports as a WARNING.
#
# We therefore pass an explicit deployment target to cargo:
#   * we first ask R's C compiler which minimum version it targets. This
#     covers a `-mmacos-version-min` flag baked into CC (e.g.
#     CC="clang -mmacos-version-min=26" on a macOS 27 host), an inherited
#     MACOSX_DEPLOYMENT_TARGET, and clang's own default;
#   * failing that, a MACOSX_DEPLOYMENT_TARGET from the environment is
#     respected verbatim;
#   * otherwise we use "<major>.0" of the running system.
# On other platforms the prefix is empty.
.macos_deployment <- ""

# Minimum macOS version targeted by R's C compiler ("" if it can't be found).
macos_cc_target <- function() {
  r_cmd <- file.path(R.home("bin"), "R")
  r_config <- function(var) {
    out <- tryCatch(
      suppressWarnings(
        system2(r_cmd, c("CMD", "config", var), stdout = TRUE, stderr = FALSE)
      ),
      error = function(e) character()
    )
    if (length(out) && is.null(attr(out, "status"))) out[[1]] else ""
  }
  cc <- r_config("CC")
  if (!nzchar(cc)) {
    return("")
  }
  src <- tempfile(fileext = ".c")
  on.exit(unlink(src), add = TRUE)
  writeLines("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", src)
  out <- tryCatch(
    suppressWarnings(
      system(
        paste(cc, r_config("CFLAGS"), "-E -P", shQuote(src)),
        intern = TRUE,
        ignore.stderr = TRUE
      )
    ),
    error = function(e) character()
  )
  # encoded as MMmmpp (e.g. 260000, 110300) or, before 10.10, as MMmp (1090)
  code <- grep("^[0-9]{4,6}$", trimws(out), value = TRUE)
  if (!length(code)) {
    return("")
  }
  code <- as.integer(code[[1]])
  if (code >= 100000L) {
    paste0(code %/% 10000L, ".", (code %/% 100L) %% 100L)
  } else {
    paste0(code %/% 100L, ".", (code %/% 10L) %% 10L)
  }
}

if (identical(Sys.info()[["sysname"]], "Darwin")) {
  target <- macos_cc_target()
  if (!nzchar(target)) {
    target <- Sys.getenv("MACOSX_DEPLOYMENT_TARGET", "")
  }
  if (!nzchar(target)) {
    product <- tryCatch(
      system("sw_vers -productVersion", intern = TRUE, ignore.stderr = TRUE),
      error = function(e) character()
    )
    if (length(product) && grepl("^[0-9]+", product[[1]])) {
      target <- paste0(sub("^([0-9]+).*$", "\\1", product[[1]]), ".0")
    }
  }
  if (nzchar(target)) {
    message("Using MACOSX_DEPLOYMENT_TARGET=", target, " for the Rust build.")
    .macos_deployment <- paste0("MACOSX_DEPLOYMENT_TARGET=\"", target, "\" ")
  }
}

# read in the Makevars.in file checking
is_windows <- .Platform[["OS.type"]] == "windows"

# if windows we replace in the Makevars.win.in
mv_fp <- ifelse(
  is_windows,
  "src/Makevars.win.in",
  "src/Makevars.in"
)

# set the output file
mv_ofp <- ifelse(
  is_windows,
  "src/Makevars.win",
  "src/Makevars"
)

# delete the existing Makevars{.win/.wasm}
if (file.exists(mv_ofp)) {
  message("Cleaning previous `", mv_ofp, "`.")
  invisible(file.remove(mv_ofp))
}

# read as a single string
mv_txt <- readLines(mv_fp)

# replace placeholder values
new_txt <- gsub("@CRAN_FLAGS@", .cran_flags, mv_txt) |>
  gsub("@PROFILE@", .profile, x = _) |>
  gsub("@CLEAN_TARGET@", .clean_targets, x = _) |>
  gsub("@LIBDIR@", .libdir, x = _) |>
  gsub("@TARGET@", .target, x = _) |>
  gsub("@PANIC_EXPORTS@", .panic_exports, x = _) |>
  gsub("@MACOS_DEPLOYMENT@", .macos_deployment, x = _)

message("Writing `", mv_ofp, "`.")
con <- file(mv_ofp, open = "wb")
writeLines(new_txt, con, sep = "\n")
close(con)

message("`tools/config.R` has finished.")

Try the polyglotSQL package in your browser

Any scripts or data that you put into this service are public.

polyglotSQL documentation built on Sept. 27, 2026, 5:06 p.m.