extendr / rextendr

An R package that helps scaffolding extendr-enabled packages or compiling Rust code dynamically
https://extendr.github.io/rextendr/
Other
174 stars 25 forks source link

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

Open Neutron3529 opened 3 weeks ago

Neutron3529 commented 3 weeks ago

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)

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, 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.