Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@
^_pkgdown\.yml$
^docs$
^pkgdown$
^src/rust/vendor$
^src/rust/target$
^src/Makevars$
^src/Makevars\.win$
6 changes: 4 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: mdl
Title: Modern model matrices
Version: 0.0.0.9000
Version: 0.0.0.9001
Authors@R: c(
person("Simon", "Couch", , "simon.couch@posit.co", role = c("aut", "cre"),
comment = c(ORCID = "0000-0001-5676-5107")),
Expand All @@ -19,10 +19,12 @@ Imports:
withr
Suggests:
testthat (>= 3.0.0)
Config/rextendr/version: 0.3.1.9000
Config/rextendr/version: 0.3.1.9001
Config/testthat/edition: 3
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.2
SystemRequirements: Cargo (Rust's package manager), rustc
Config/Needs/website: r-lib/bench#144, dplyr, ggplot2, rmarkdown, tidyverse/tidytemplate
Depends:
R (>= 4.2)
3 changes: 3 additions & 0 deletions configure
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env sh
: "${R_HOME=`R RHOME`}"
"${R_HOME}/bin/Rscript" tools/config.R
2 changes: 2 additions & 0 deletions configure.win
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/usr/bin/env sh
"${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" tools/config.R
3 changes: 3 additions & 0 deletions src/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@
*.dll
target
.cargo
rust/vendor
Makevars
Makevars.win
46 changes: 46 additions & 0 deletions src/Makevars.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
TARGET_DIR = ./rust/target
LIBDIR = $(TARGET_DIR)/@LIBDIR@
STATLIB = $(LIBDIR)/libmdl.a
PKG_LIBS = -L$(LIBDIR) -lmdl

all: $(SHLIB) rust_clean

.PHONY: $(STATLIB)

$(SHLIB): $(STATLIB)

CARGOTMP = $(CURDIR)/.cargo
VENDOR_DIR = $(CURDIR)/vendor


# RUSTFLAGS appends --print=native-static-libs to ensure that
# the correct linkers are used. Use this for debugging if need.
#
# CRAN note: Cargo and Rustc versions are reported during
# configure via tools/msrv.R.
#
# When the NOT_CRAN flag is *not* set, the vendor.tar.xz, if present,
# is unzipped and used for offline compilation.
$(STATLIB):

# Check if NOT_CRAN is false and unzip vendor.tar.xz if so
if [ "$(NOT_CRAN)" != "true" ]; then \
if [ -f ./rust/vendor.tar.xz ]; then \
tar xf rust/vendor.tar.xz && \
mkdir -p $(CARGOTMP) && \
cp rust/vendor-config.toml $(CARGOTMP)/config.toml; \
fi; \
fi

export CARGO_HOME=$(CARGOTMP) && \
export PATH="$(PATH):$(HOME)/.cargo/bin" && \
RUSTFLAGS="$(RUSTFLAGS) --print=native-static-libs" cargo build @CRAN_FLAGS@ --lib @PROFILE@ --manifest-path=./rust/Cargo.toml --target-dir $(TARGET_DIR)

# Always clean up CARGOTMP
rm -Rf $(CARGOTMP);

rust_clean: $(SHLIB)
rm -Rf $(CARGOTMP) $(VENDOR_DIR) @CLEAN_TARGET@

clean:
rm -Rf $(SHLIB) $(STATLIB) $(OBJECTS) $(TARGET_DIR)
41 changes: 41 additions & 0 deletions src/Makevars.win.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
TARGET = $(subst 64,x86_64,$(subst 32,i686,$(WIN)))-pc-windows-gnu

TARGET_DIR = ./rust/target
LIBDIR = $(TARGET_DIR)/$(TARGET)/@LIBDIR@
STATLIB = $(LIBDIR)/libmdl.a
PKG_LIBS = -L$(LIBDIR) -lmdl -lws2_32 -ladvapi32 -luserenv -lbcrypt -lntdll

all: $(SHLIB) rust_clean

.PHONY: $(STATLIB)

$(SHLIB): $(STATLIB)

CARGOTMP = $(CURDIR)/.cargo
VENDOR_DIR = vendor

$(STATLIB):
mkdir -p $(TARGET_DIR)/libgcc_mock
touch $(TARGET_DIR)/libgcc_mock/libgcc_eh.a

if [ "$(NOT_CRAN)" != "true" ]; then \
if [ -f ./rust/vendor.tar.xz ]; then \
tar xf rust/vendor.tar.xz && \
mkdir -p $(CARGOTMP) && \
cp rust/vendor-config.toml $(CARGOTMP)/config.toml; \
fi; \
fi

# Build the project using Cargo with additional flags
export CARGO_HOME=$(CARGOTMP) && \
export LIBRARY_PATH="$(LIBRARY_PATH);$(CURDIR)/$(TARGET_DIR)/libgcc_mock" && \
RUSTFLAGS="$(RUSTFLAGS) --print=native-static-libs" cargo build @CRAN_FLAGS@ --target=$(TARGET) --lib @PROFILE@ --manifest-path=rust/Cargo.toml --target-dir=$(TARGET_DIR)

# Always clean up CARGOTMP
rm -Rf $(CARGOTMP);

rust_clean: $(SHLIB)
rm -Rf $(CARGOTMP) $(VENDOR_DIR) @CLEAN_TARGET@

clean:
rm -Rf $(SHLIB) $(STATLIB) $(OBJECTS) $(TARGET_DIR)
41 changes: 25 additions & 16 deletions src/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions src/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ name = 'mdl'
publish = false
version = '0.1.0'
edition = '2021'
rust-version = "1.65"

[lib]
crate-type = ['staticlib']
name = 'mdl'

[dev-dependencies]
extendr-engine = { version = "0.7.1" }
extendr-engine = { version = "0.8.0" }

[dependencies]
extendr-api = { version = "0.7.1" }
extendr-api = { version = "0.8.0" }
rayon = {version = "1.10.0", optional = true}

[features]
Expand Down
77 changes: 77 additions & 0 deletions tools/config.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# 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)")

# when we are using a debug build we need to use target/debug instead of target/release
.libdir <- ifelse(is_debug, "debug", "release")

# read in the Makevars.in file
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}
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 = _)

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

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