Skip to content

#[link(kind="static")] extern still prefers .so #12557

Closed
@kmcallister

Description

@kmcallister

foo.c:

#include <stdio.h>

void foo() {
    puts("Hello, foo()!");
}

bar.rs:

#[link(name="foo", kind="static")]
extern {
    fn foo();
}

pub fn bar() {
    unsafe { foo(); }
}

When I build only a static libfoo.a I get the expected behavior, with foo statically linked into the Rust crate .so.

$ rm -f *.o *.so *.a
$ gcc -Wall -fPIC -c foo.c
$ ar rcs libfoo.a foo.o
$ rustc -v
rustc 0.10-pre (6ae5de0 2014-02-19 12:51:48 -0800)
host: x86_64-unknown-linux-gnu
$ rustc --crate-type dylib bar.rs
$ objdump -d libbar-*.so
...
0000000000000a80 <foo>:
 a80:   55                      push   %rbp
 a81:   48 89 e5                mov    %rsp,%rbp
 a84:   48 8d 3d 22 00 00 00    lea    0x22(%rip),%rdi        # aad <_fini+0x9>
 a8b:   e8 80 fe ff ff          callq  910 <puts@plt>
 a90:   5d                      pop    %rbp
 a91:   c3                      retq   
 a92:   90                      nop

But when I also have libfoo.so in the same directory, rustc prefers that even though kind="static" is set.

$ gcc -shared -o libfoo.so foo.o
$ file libfoo.*
libfoo.a:  current ar archive
libfoo.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked
$ rustc --crate-type dylib bar.rs 
$ objdump -d libbar-*.so | grep foo
00000000000008b0 <foo@plt>:
 9f6:   e8 b5 fe ff ff          callq  8b0 <foo@plt>

strace confirms that it looks for both libfoo.so and libfoo.a, in that order, in each directory of the library search path, and it stops when it finds ./libfoo.so.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-FFIArea: Foreign function interface (FFI)A-linkageArea: linking into static, shared libraries and binaries

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions