-
Notifications
You must be signed in to change notification settings - Fork 211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using compiler-builtins with FFI, linking with libc? #345
Comments
Yeah unfortunately there's a few things in play here which makes this situtation a bit unfortunate:
Unfortunately I don't really know of a great workaround for this. The "best" thing to do would be to somehow excise the compiler-builtins objects out of the Rust object file, and then hope the system compiler-builtins has enough intrinsics for the Rust code you're building. In the limit it doesn't, but for most projects it should suffice. |
The second point is exactly the case: I am not quite sure why Ultimately, we may not want to excise anything: keep the After doing some tinkering, I was able to do: |
I think that makes sense yeah. I also don't know what's going on with |
I'm having a similar issue on embedded where we produce a static library then link it into an embedded project (TI RTOS). We ran into issues because TI's compiler would produce unaligned reads that would work with their Their I've been working around it by modifying the built archive to remove all of the compiler-builtins object files:
It's sort of slow to do this on every build though, it takes about 27s to strip all the |
Some follow-up on this: It appears that the cleanest solution for this might be to first do: This appears to make a rust staticlib link properly in C static linking. It looks like As far as I can tell, this collision is unavoidable - for static linking, even global "hidden" symbols will still collide with libc builtins at link time. One other oddity to tack on here: |
The proper way to deal with this is to make sure each function in compiler-builtins is in a separate object file. We already have hacks in place to do this. This works because linkers will only pull in an object file from an archive if it has a symbol that is needed by the compilation. If |
I also ran into this issue. Unfortunately, I needed some symbols from compiler_builtins. I'm assuming this is due to Rust using LLVM and that I'm compiling my C code with gcc. Anyway, my solution was to pull the library .a apart, make all symbols from compiler_builtins weak using objcopy, then put the .a back together.
Would be great to have a better fix. |
@Amanieu Are your "hacks" in your own C-side build system? I am encountering this problem when trying to do a pretty straightforward linking of a rustlib Fortunately, the As far as I know (and please correct me if wrong): there just is no solution for a global label collision at link-time. I can only guess that truly fixing this would require a declaration of "C compiler builtins" that are Could that be accomplished with a feature flag for this crate? |
See the comment here which explains how we ensure the intrinsics are split into separate object files internally: compiler-builtins/src/macros.rs Lines 257 to 268 in b81db2f
The issue is that the |
Any updates on this? I run into the same problem today? |
I am having some issues using a rust staticlib that is being called from C via FFI, being built for an embedded target (Cortex M). This issue is sort-of a result of needing this library, not necessarily an error in the code.
To get the linking step to succeed, I have to link the rust staticlib in last. If not, I will get link errors for multiple definitions of
memset
, where one implementation is providing the unmangled symbol from thiscompiler-builtins
crate.Linking the rustlib last does resolve that. However, it causes all uses of
memset
in the C code to be linked to thecompiler-builtins
implementations.Even beyond that, using a softfp MCU, even FP multiple like
float a=b*c
will end up linking the__aebi_fmul
to the Rust implementation!Example of how invoke linking:
arm-none-eabi-gcc -mcpu=cortex-m0plus -mthumb -specs=nano.specs -specs=nosys.specs -TSTM32L072CZEx_FLASH.ld -lnosys -Wl,-Map=target/double.map,--cref -Wl,--gc-sections target/startup_stm32l072xx.o target/stm32l0xx_it.o target/main.o target/thumbv6m-none-eabi/debug/libdouble_input.a -o target/double
(where the name "double" is because I am using the
libdouble_input
from FFI examples and adding a few other tests: https://github.com/alexcrichton/rust-ffi-examples/tree/master/c-to-rust )Is this a known limitation?
Is there a workaround to avoid that level of hybridization of the C codes into the rust code, given the overlapping implementations?
As far as I understand the notes in the README, that does not cover this case for the behavior I am trying to get.
I have tried partially linking all the C code first with
-lc
, and it does pick up the libc implementations ofmemcpy
, float multiply, etc, but then the final linking step fails becasue there are still twomemset
objects in the output files.The text was updated successfully, but these errors were encountered: