How to static link existing object file to rust's standard library

I have created a object file from the object file from the following rust code with rustc --emit obj:

#![crate_type = "lib"]

#[no_mangle]
pub extern "C" fn testing() {
    println!("Hello");
}

I noticed that the object file contained the following undefined symbols, which I assume is because its not linked to the standard library:

    11: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _ZN4core9panicking5panic17h0ba7146865b2f9d6E
    13: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _ZN3std2io5stdio6_print17hd9c9dbd31aa97d70E

I would like to know if there is a way to static link the standard library into the object file and get an object file as output (something like ld --relocatable)

An object file is not linked. If you link many object files together, you either get a library or an executable, and not another object file. If you want to have a fully-fledged library with no external dependencies on other libs, then set crate-type = cdylib and use regular cargo build instead of rustc --emit obj.

Perhaps linking is not the right word here.

on c I can do something like the following to get an object file with no undefined symbols:

gcc -c main.c
ld -L/usr/lib/musl/lib -static main.o -lc -r -o out.o

ld's manpage seems to call this an incremental link

Is there something analogous to this in rust?

Linking is the right word, but that option is not "incremental linking" (which would be the link-time equivalent of incremental compilation). Instead, it creates a relocatable output. At that point, I would be hesitant to call the result an "object file" (the man page carefully avoids calling it either an object file or a library, it just says it's suitable as an input to further linking, which criterion is fulfilled by both types of file).

Again, if you want something that combines multiple object files and can be linked against, you can just create an ordinary library. Is there any reason why you want to avoid that?

My goal is to enable calling rust/c/c++ functions from a sandboxed python environment. Limitations of sandbox:

  • time limit on code execution (~1s would be ideal if loading of the rust code would load in less than 100ms)
  • only one python file is allowed per session (no data files etc.)
  • size limitation on python file (256KB)
  • disallows creating, modifying and deleting files on the system (might be able to bypass this but would like to avoid that)

I have gotten it to execute c functions in object files by using mmap + python's builtin cffi library (code for doing this)

Reasons I am trying to avoid creating a library are:

  • Not sure how to load a dynamic library without dlopen (as that requires the shared library to be a real file).
  • I can create a static library, but since a static library is just a collection of object files (at least on linux), I would need to merge them at some point right?

Ah, I see. That's an interesting challenge. (Is it some sort of competitive coding environment, in which you are trying to speed up the code?)

Right, object files are not yet fully ready to execute, a static lib still needs linking to be useful.

This appears to be possible at least on Linux and FreeBSD:

  • on Linux, you can write to /dev/shm and then simply dlopen() it; apparently the same can be done with /proc/self/fd/…, which seems to be a bit more robust/less roundabout.
  • on FreeBSD, you can create a file descriptor from a memory buffer, and then fdlopen() it.

Yes that is correct.

This seems to work well enough for my use case

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.