fortran - 对 `_gfortran_cpu_time_4' 的 undefined reference

标签 fortran rust ffi

我试图从 Rust 调用一个 Fortran 函数,但我收到了这个错误:

/src/timer.f:4: undefined reference to `_gfortran_cpu_time_4'

我在互联网上搜索过,但找不到任何解决方案。 Fortran 代码 是:

subroutine timer(ttime)
  double precision ttime
  temp = sngl(ttime)
  call cpu_time(temp)
  ttime = dble(temp) 

  return
end

Rust 绑定(bind) 是:

use libc::{c_double};

extern "C" {
    pub fn timer_(d: *mut c_double);
}

我不知道我做错了什么。

最佳答案

正如评论者所说,您需要 link to libgfortran .

具体来说,在 Rust 世界中,您应该使用(或创建)一个 *-sys package详细说明了适当的链接步骤并公开了基本 API。然后在此基础上构建更高级别的抽象。


但是,我似乎不需要做任何这些:

timer.f90

subroutine timer(ttime)
  double precision ttime
  temp = sngl(ttime)
  call cpu_time(temp)
  ttime = dble(temp) 

  return
end

Cargo.toml

[package]
name = "woah"
version = "0.1.0"
authors = ["An Devloper <an.devloper@example.com>"]

build = "build.rs"

[dependencies]
libc = "*"

build.rs

fn main() {
    println!("cargo:rustc-link-lib=dylib=timer");
    println!("cargo:rustc-link-search=native=/tmp/woah");
}

src/main.rs

extern crate libc;

use libc::{c_double};

extern "C" {
    pub fn timer_(d: *mut c_double);
}

fn main() {
    let mut value = 0.0;
    unsafe { timer_(&mut value); }
    println!("The value was: {}", value);
}

它是通过

放在一起的
$ gfortran-4.2 -shared -o libtimer.dylib timer.f90
$ cargo run
The value was: 0.0037589999847114086

这似乎表明该共享库不需要 libgfortranit's being automatically included .

如果您改为创建一个静态库(并通过 cargo:rustc-link-lib=dylib=timer 适本地链接到它):

$ gfortran-4.2 -c -o timer.o timer.f90
$ ar cr libtimer.a *.o
$ cargo run
note: Undefined symbols for architecture x86_64:
  "__gfortran_cpu_time_4", referenced from:
      _timer_ in libtimer.a(timer.o)

在这种情况下,添加gfortran 允许代码编译:

println!("cargo:rustc-link-lib=dylib=gfortran");

免责声明:我以前从未编译过 Fortran,所以很可能我做了一些愚蠢的事情。

关于fortran - 对 `_gfortran_cpu_time_4' 的 undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37250095/

相关文章:

模块 use 语句中的 Fortran 内在关键字

rust - 你如何用 Tokio 简单地包装同步网络 I/O?

enums - 在宏中匹配类似元组的枚举变量,其中枚举类型和变量是元变量: how do I write the matching pattern?

rust - 使结构比赋予该结构的方法的参数更长寿

racket - Racket 和花栗鼠的 FFI 问题

javascript - node.js ffi 导入常量

c++ - 如何重置已保存变量以准备下次调用的模块的状态?

fortran - 傅科摆模拟

module - Fortran - 模块子例程参数意图混淆 - INOUT 与 OUT

rust - 当返回对范围外值的可变引用的不可变引用时,为什么在范围结束时丢弃可变引用?