Je n'ai pas eu de chance jusqu'à présent avec la liaison d'une bibliothèque Haskell à un Rust. J'ai eu beaucoup d'erreurs, la dernière étant la recompile with -fPIC
pour ghc
.
J'ai réussi à obtenir un exemple fonctionnel de relier dynamiquement - mais j'ai été incapable de le faire lier de manière statique.
Joindre ma configuration actuelle en ce moment:
construire.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(); }
Je compile # 4 avec ghc -c -static -lHSrts -lffi cwrapper.c
, obtenir cwrapper.o
. De même, je compile # 3 avec ghc -c -static -fPIC -lffi Lib.hs
et obtenir le code objet pour cela aussi.
Une fois que cela est fait, je vais de l'avant et archivez les deux avec ar rcs libtesths.a Lib.o cwrapper.o
.
Au 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'
…
J'ai un hunch que libhsrts ne soit pas lié de manière statique pour une raison quelconque.
J'ai suivi les conseils de Shepmaster et j'ai effectué un exemple de travail avec succès. Mais j'ai des problèmes liés à mon Rust EXEC maintenant.
J'ai utilisé la pile avec ghc-options: -staticlib -stubdir .
et c-sources: cwrapper.c
construire. Quand j'essaie de construire le Rust Project avec cargo rustc — -C relocation-model=static
:
/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'
Il y a aussi une mention d'un wrappers.o
. Toute aide est appréciée.
J'ai résolu les problèmes gmp
en définissant build.rs
Pour lier libgmp
aussi. J'ai un problème différent maintenant, cependant.
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
Ceci la commande finale de construction qui fait l'affaire:
cargo rustc -- -C relocation-model=static -Clink-arg=-Wl,--allow-multiple-definition
L'utilisation de RUSTFLAGS
provoquera la construction de la construction car elle construit toutes les dépendances avec un modèle de relocalisation statique, qui ne fonctionnera pas - dans mon cas - pour la caisse rustversion
. Il signalera un recompile with -fPIC
Erreur.
J'ai compilé la bibliothèque Haskell et C Shim à la fois, passant le -staticlib
Drapeau:
ghc -c -staticlib Lib.hs cwrapper.c -o libtesths.a
J'ai ensuite appelé les fonctions:
extern "C" {
pub fn addTwo(x: i32) -> i32;
pub fn init();
pub fn fin();
}
fn main() {
unsafe {
init();
println!("{}", addTwo(40));
fin();
}
}
% cargo run -q
42
Cela a fonctionné pour moi sur MacOS 12.0.1 sur un Apple Processeur de silicium utilisant GHC 8.10.7.
Si vous êtes sur X86_64 Linux, vous devrez peut-être ajouter RUSTFLAGS='-C relocation-model=static'
.