extendr / extendr/rextendr

Is it possible to remove the `entrypoint.c` file?

Open
#359 3 comments 1 reaction 0 assignees View on GitHub
Dominant language
R
Stars
263
Forks
35
Avg merge
8d 9h
Merged PRs (30d)
2

Description

I tried this setting in linux:

src/rust/Cargo.toml: set crate type to cdylib

src/Makevars: Use Rust .so file directly

```
TARGET_DIR = ./rust/target
LIBDIR = $(TARGET_DIR)/release
RUSTLIB = $(LIBDIR)/librext.so
PKG_LIBS = -lrext

all: C_clean

$(SHLIB): $(RUSTLIB)

CARGOTMP = $(CURDIR)/.cargo

$(RUSTLIB):
if [ "$(NOT_CRAN)" != "true" ]; then \
export CARGO_HOME=$(CARGOTMP); \
fi && \
export PATH="$(PATH):$(HOME)/.cargo/bin" && \
cargo build --lib --release --manifest-path=./rust/Cargo.toml --target-dir $(TARGET_DIR) && \
cp $(RUSTLIB) $(SHLIB)
if [ "$(NOT_CRAN)" != "true" ]; then \
rm -Rf $(CARGOTMP) && \
rm -Rf $(LIBDIR)/build; \
fi

C_clean:
rm -Rf $(SHLIB) $(RUSTLIB) $(OBJECTS)

clean:
rm -Rf $(SHLIB) $(RUSTLIB) $(OBJECTS) $(TARGET_DIR)
```
export function in `lib.rs`: (since I don't want to modify the original macro, I have to write another export function)

```rust
mod export {
#[no_mangle]
extern fn R_init_rext(dll:*const u8) { // if R_init_rext_extendr is renamed to R_init_rext, no need to write this.
unsafe {R_init_rext_extendr(dll)};
}
extern "C" {
fn R_init_rext_extendr(void:*const u8);
}
}
```

Steps:

1. create a dir `rext`, cd to this dir, open R, execute `usethis::create_package('.');rextendr::use_extendr('.');rextendr::document()`
2. delete generated `rext.so`, `entrypoint.c/.o`
3. adding export function to `lib.rs`
4. edit `src/Makevars` and `src/rust/Cargo.toml`
5. open R again, use `devtools::load_all('.')` to trigger package loading and compile the package
6. check whether `hello_world` function is usable

The check is successful, thus there might be no need to use `entrypoint.*`.

Is it possible to remove the entry files?

---

What's more, the `extendr_module!` grammar seems a little bit annoying. I have an attempt that use proc-macro to export all of them directly (just `done!{}` at the end of `lib.rs` is enough.) The issue is that, the current rust implementation may change and using global static variable might be disallowed in the future. [I'm trying to examine the importance with rust developers](https://internals.rust-lang.org/t/proc-macro-output-dir/21001), maybe we could simplify the grammar to something like `exported!();` or `done!();` directly in the future, if we found more use case about how to register a global function.

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the issue's package setup and review src/Makevars, src/rust/Cargo.toml, lib.rs, and the generated entrypoint.c/.o files. Compare the direct cdylib approach with the current loading path across supported environments; done means entrypoint.* is no longer required and devtools::load_all('.') still makes hello_world usable.

Written by the indexing model from the issue text.

Assessment

Tech stack
r, rust
Domain
build-system, tooling
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.