Search code examples
cgcclinkerrust

Rust's .o file format not recognized by GCC


I'm trying to build a simple application in C that calls Rust functions, in Windows, using MinGW with GCC 4.9.3 and Rust 1.9.0 stable.

Here's the source code:

test.rs

#![crate_type = "staticlib"]

#[no_mangle]
pub extern "C" fn get_number() -> isize {
    42 as isize
}

main.c

#include <stdio.h>

int get_number();

int main()
{
    printf("Hello, world!\n");
    printf("Number is %d.\n", get_number());
    return 0;
}

Now, I know I should use C-compatible types in Rust and whatnot. But before going into program correctness, there's a problem in that Rust seems to be generating object files that GCC doesn't understand. Here's what I'm trying:

rustc --emit obj test.rs
gcc -c main.c
gcc -static-libgcc test.o main.o -lmingw32 -o test.exe

But the linker command terminates with:

test.o: file not recognized: File format not recognized
collect2.exe: error: ld returned 1 exit status

I've searched for Rust compiler directives that would change output format, but I couldn't find any. I've read Rust's FFI docs, but it doesn't mention anything like this. Usually, information is about calling C from Rust. Asking Rust to generate ASM files and assembling with GCC's as doesn't work, due to incompatible syntax, apparently.

Is this a compatibility issue with the Windows version of Rust/GCC? Is there anything I can do to generate compatible object files from Rust? Or rather, what kind of output should I ask Rust to generate to make this possible? I'm also interested in calling Rust code from C on a variety of gaming console SDKs. What kind of setup would I need to maximize compatibility with other linkers?


Solution

  • Works fine for me:

    $ rustc test.rs --emit=obj
    $ gcc -c main.c
    $ file test.o
    test.o: 80386 COFF executable not stripped - version 30821
    $ file main.o
    main.o: 80386 COFF executable not stripped - version 30821
    $ gcc test.o main.o -o awesome
    $ file awesome.exe
    awesome.exe: PE32 executable (console) Intel 80386, for MS Windows
    
    $ ./awesome.exe
    Hello, world!
    Number is 42.
    
    $ rustc --version --verbose
    rustc 1.9.0 (e4e8b6668 2016-05-18)
    binary: rustc
    commit-hash: e4e8b666850a763fdf1c3c2c142856ab51e32779
    commit-date: 2016-05-18
    host: i686-pc-windows-gnu
    release: 1.9.0
    $ gcc --version
    gcc (GCC) 5.3.0