Skip to content
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

Re-exporting extern "C" and `#[no_mangle] symbols in cdylib doesn’t work with gcc on Linux #63125

Closed
ddeville opened this issue Jul 30, 2019 · 2 comments
Labels
A-FFI Area: Foreign function interface (FFI) A-linkage Area: linking into static, shared libraries and binaries C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@ddeville
Copy link

ddeville commented Jul 30, 2019

Building a cdylib crate that has a dependency on a crate with extern "C" and #[no_mangle] symbols fails to export the symbols on Linux, even when the symbols are re-exported as public. Symbols are correctly exported on Mac and Windows.

The problem was somewhat discussed on #36342 but as far as I can tell, only gcc and Linux are behaving abnormally today.

In order to reproduce the issue, I used the following simple setup with two crates.

mycrate/Cargo.toml

[package]
name = "mycrate"
version = "0.1.0"
edition = "2018"

mycrate/src/lib.rs

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

mylib/Cargo.toml

[package]
name = "mylib"
version = "0.1.0"
edition = "2018"

[lib]
name = "mylib"
crate-type = ["cdylib"]

[dependencies]
mycrate = { path = "../mycrate" }

mylib/src/lib.rs

pub use mycrate::*;

I then ran cargo build in mylib and inspected the resulting library under mylib/target/debug.

On Mac

$ nm -gnU mylib/target/debug/libmylib.dylib
0000000000000fd0 T _do_you_see_me
000000000000b000 T _rust_eh_personality

On Windows

$ DUMPBIN /EXPORTS mylib\target\debug\mylib.dll
    ordinal hint RVA      name
          1    0 00016A80 do_you_see_me = do_you_see_me
          2    1 0000EC00 rust_eh_personality = rust_eh_personality

On Linux

$ nm -g --defined-only target/debug/libmylib.so
00000000000012a0 T rust_eh_personality

I expected do_you_see_me to be exported by the dynamic library on Linux too.

This makes it pretty hard to ship a cdylib built on top of crates that expose a C ABI. I realize that it’s technically possible to "wrap" the symbols from mycrate in new #[no_mangle] and extern "C" functions in mylib but for a project with a substantial number of exported symbols it’s simply not practical.

Meta

Versions of rustc and various compilers I am using.

On Mac

$ rustc --version --verbose
rustc 1.36.0 (a53f9df32 2019-07-03)
binary: rustc
commit-hash: a53f9df32fbb0b5f4382caaad8f1a46f36ea887c
commit-date: 2019-07-03
host: x86_64-apple-darwin
release: 1.36.0
LLVM version: 8.0

$ clang --version
Apple LLVM version 10.0.1 (clang-1001.0.46.4)

On Linux

$ rustc --version --verbose
rustc 1.36.0 (a53f9df32 2019-07-03)
binary: rustc
commit-hash: a53f9df32fbb0b5f4382caaad8f1a46f36ea887c
commit-date: 2019-07-03
host: x86_64-unknown-linux-gnu
release: 1.36.0
LLVM version: 8.0

$ gcc --version
gcc (GCC) 9.1.0

On Windows

$ >rustc --version --verbose
rustc 1.36.0 (a53f9df32 2019-07-03)
binary: rustc
commit-hash: a53f9df32fbb0b5f4382caaad8f1a46f36ea887c
commit-date: 2019-07-03
host: x86_64-pc-windows-msvc
release: 1.36.0
LLVM version: 8.0

$ CL
Microsoft (R) C/C++ Optimizing Compiler Version 19.22.27905 for x64
@ddeville ddeville changed the title Re-exporting extern "C" symbols in cdylib doesn’t work with gcc on Linux Re-exporting extern "C" and `#[no_mangle] symbols in cdylib doesn’t work with gcc on Linux Jul 30, 2019
@jonas-schievink jonas-schievink added A-FFI Area: Foreign function interface (FFI) A-linkage Area: linking into static, shared libraries and binaries C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jul 30, 2019
@CryZe
Copy link
Contributor

CryZe commented Jul 30, 2019

Yeah this is the same bug as this #50007

Turning on LTO fixes it.

@Mark-Simulacrum
Copy link
Member

Closing as duplicate of #50007.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-FFI Area: Foreign function interface (FFI) A-linkage Area: linking into static, shared libraries and binaries C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants