【发布时间】:2022-01-03 05:16:19
【问题描述】:
到目前为止,我还没有将 Haskell 库链接到 Rust 项目。我有很多错误,最新的是 recompile with -fPIC 对应于 ghc。
我设法获得了一个动态链接的功能示例,但无法将其静态链接。
立即附加我当前的设置:
-
build.rs
fn main() { println!("cargo:rustc-link-search=native=deps"); println!("cargo:rustc-link-lib=static=tesths"); } -
src/main.rs
extern "C" { pub fn addTwo(x: i32) -> i32; pub fn init(); pub fn fin(); } fn main() { println!("Hello, world!"); } -
src/haskell/Lib.hs
module Lib where import Foreign.C.Types addTwo :: CInt -> CInt addTwo = (2 + ) foreign export ccall addTwo :: CInt -> CInt -
cwrapper.c
#include <HsFFI.h> #ifdef __GLASGOW_HASKELL__ #include "Lib_stub.h" #endif #include <stdio.h> void init(void) { static char *argv[] = {"libhs.so", 0}, **argv_ = argv; static int argc = 1; hs_init(&argc, &argv_); } void fin(void) { hs_exit(); }
我用ghc -c -static -lHSrts -lffi cwrapper.c 编译#4,得到cwrapper.o。同样,我用ghc -c -static -fPIC -lffi Lib.hs 编译#3 并获得目标代码。
完成后,我继续使用ar rcs libtesths.a Lib.o cwrapper.o 归档这两个文件。
开启cargo build:
note: /usr/bin/ld: deps/libtesths.a(Lib.o):(.text+0x29): undefined reference to `newCAF'
/usr/bin/ld: deps/libtesths.a(Lib.o):(.text+0x39): undefined reference to `stg_bh_upd_frame_info'
/usr/bin/ld: deps/libtesths.a(Lib.o):(.text+0x48): undefined reference to `base_ForeignziCziTypes_zdfNumCInt_closure'
/usr/bin/ld: deps/libtesths.a(Lib.o):(.text+0x4f): undefined reference to `stg_ap_p_info'
…
我有一种预感,libHSrts 由于某种原因没有被静态链接。
更新
我听从了 Shepmaster 的建议,成功地做了一个工作示例。但我现在与我的 rust 执行官链接时遇到问题。
我使用堆栈与ghc-options: -staticlib -stubdir . 和c-sources: cwrapper.c 进行构建。当我尝试使用cargo rustc — -C relocation-model=static 构建 rust 项目时:
/usr/bin/ld: deps/liba.a(Type.o): in function `integerzmwiredzmin_GHCziIntegerziType_zdwplusBigNatWord_info'
(.text.integerzmwiredzmin_GHCziIntegerziType_zdwplusBigNatWord_info+0x128): undefined reference to `__gmpn_add_1'
/usr/bin/ld: deps/liba.a(Type.o): in function
`integerzmwiredzmin_GHCziIntegerziType_zdwminusBigNatWord_info'
(.text.integerzmwiredzmin_GHCziIntegerziType_zdwminusBigNatWord_info+0xdf): undefined reference to `__gmpn_sub_1'
/usr/bin/ld: deps/liba.a(Type.o): in function `integerzmwiredzmin_GHCziIntegerziType_complementInteger_info'
(.text.integerzmwiredzmin_GHCziIntegerziType_complementInteger_info+0x138): undefined reference to `__gmpn_sub_1'
/usr/bin/ld: deps/liba.a(Type.o): in function `integerzmwiredzmin_GHCziIntegerziType_zdwtimesBigNatWord_info'
(.text.integerzmwiredzmin_GHCziIntegerziType_zdwtimesBigNatWord_info+0x158): undefined reference to `__gmpn_mul_1'
还提到了wrappers.o。任何帮助表示赞赏。
更新 2
我通过将build.rs 也设置为链接libgmp 解决了gmp 问题。不过,我现在有一个不同的问题。
note: /usr/bin/ld: deps/libhssource.a(Lib.o): in function `testFFI':
(.text+0x88fd): multiple definition of `testFFI'; deps/libhssource.a(Lib.o):(.text+0x1b66): first defined here
/usr/bin/ld: deps/libhssource.a(cwrapper.o): in function `init':
cwrapper.c:(.text+0x0): multiple definition of `init'; deps/libhssource.a(cwrapper.o):cwrapper.c:(.text+0x0): first defined here
/usr/bin/ld: deps/libhssource.a(cwrapper.o): in function `fin':
cwrapper.c:(.text+0x20): multiple definition of `fin'; deps/libhssource.a(cwrapper.o):cwrapper.c:(.text+0x1a): first defined here
collect2: error: ld returned 1 exit status
更新 3
这是解决问题的最终构建命令:
cargo rustc -- -C relocation-model=static -Clink-arg=-Wl,--allow-multiple-definition
使用RUSTFLAGS 将导致构建崩溃,因为它使用静态重定位模型构建所有依赖项,在我的情况下,这对于rustversion crate 不起作用。会报recompile with -fPIC错误。
【问题讨论】:
-
哇,@Shepmaster,我只是在谷歌上搜索,看到了你的 FFI 综合回购!恒星的东西!很遗憾我正在尝试以相反的方式进行操作:(
-
感谢您的客气话。好消息是,大部分知识是可转移的(但在这种情况下不适用)。
-
SmokedTurkey 和@shepmaster:我想知道你们正在从事哪些非常酷的项目,涉及世界上两种最佳语言之间的 FFI!
-
@gspr 哈哈.. 我正在开发一些分析软件。 Haskell 是一头野兽,非常适合当你想要一些简洁但简洁的代码,用几行代码描述真正涉及的算法时。当我第一次发现 GHC 作为编译器的出色表现时,我感到震惊。
rustc和ghc是两件精美的艺术品。 -
请不要将答案放在问题中。您可以添加自己的答案,甚至接受它。