I have a Rust crate including asm files:
Cargo.toml:
[package]
name = "a"
version = "0.1.0"
authors = ["M Farkas-Dyck <strake888@gmail.com>"]
build = "build.rs"
build.rs:
use std::process::Command;
use std::env;
fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
if !(Command::new("as").args(&["-o", &(out_dir.clone() + "/a.o"),
"src/a.s"])
.status().unwrap().success() &&
Command::new("ar").args(&["-crus",
&(out_dir.clone() + "/liba.a"),
&(out_dir.clone() + "/a.o")])
.status().unwrap().success()) {
panic!("failed");
}
println!("cargo:rustc-link-search=native={}", out_dir);
println!("cargo:rustc-link-lib=static=a");
}
src/lib.rs:
extern "C" {
fn a() -> usize;
}
#[test]
fn test_a() {
assert_eq!(0, unsafe { a() });
}
src/a.s:
.intel_syntax noprefix
.text
a:
xor rax, rax
ret
but when i do cargo test
this happens:
Compiling a v0.1.0 (file:///home/strake/a.rs)
error: linking withcc
failed: exit code: 1
note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/strake/a.rs/target/debug/a-092a156f19993e2f.0.o" "-o" "/home/strake/a.rs/target/debug/a-092a156f19993e2f" "-Wl,--gc-sections" "-pie" "-nodefaultlibs" "-L" "/home/strake/a.rs/target/debug" "-L" "/home/strake/a.rs/target/debug/deps" "-L" "/home/strake/a.rs/target/debug/build/a-049bc247725cc2fd/out" "-L" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "-Wl,--whole-archive" "-l" "a" "-Wl,--no-whole-archive" "-Wl,-Bdynamic" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/libtest-2f39a9bd.rlib" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/libterm-2f39a9bd.rlib" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/libgetopts-2f39a9bd.rlib" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-2f39a9bd.rlib" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcollections-2f39a9bd.rlib" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_unicode-2f39a9bd.rlib" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/librand-2f39a9bd.rlib" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-2f39a9bd.rlib" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc_jemalloc-2f39a9bd.rlib" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-2f39a9bd.rlib" "/usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-2f39a9bd.rlib" "-l" "dl" "-l" "pthread" "-l" "gcc_s" "-l" "pthread" "-l" "c" "-l" "m" "-l" "rt" "-l" "util" "-l" "compiler-rt"
note: /home/strake/a.rs/target/debug/a-092a156f19993e2f.0.o: In functiona::test_a': /home/strake/a.rs/src/lib.rs:7: undefined reference to
a'
collect2: error: ld returned 1 exit status
I can cargo build
as usual, and objdump -t shows the symbol a
defined in liba.a:
In archive target/debug/build/a-049bc247725cc2fd/out/liba.a:
a.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l .text 0000000000000000 a
Why is it not seeing this symbol?