Общая библиотека Haskell не загружается должным образом - PullRequest
0 голосов
/ 08 мая 2018

Я работаю над проектом, который включает компиляцию и загрузку пользовательского кода на Haskell. Для этого я хочу иметь возможность скомпилировать модуль Haskell в общую библиотеку (файл .so).

Я компилирую модуль с

ghc --make -dynamic -shared -fPIC Safe.hs -o libsafe.so

и моя тестовая программа с

ghc --make -no-hs-main -optc-O test.c -o test

Оба компилируются чисто. Однако, когда я запускаю test, я получаю

/usr/lib64/ghc-8.0.2/ghc-prim-0.5.0.0/libHSghc-prim-0.5.0.0-ghc8.0.2.so: undefined symbol: stg_thawArrayzh

Кажется, что-то я не связываю где-то, но не должен ли GHC справиться со всем этим для меня? Я использую GHC-8.0.2.

Исходный код

Safe.hs:

{-# LANGUAGE ForeignFunctionInterface #-}

module Safe where

import Foreign.C.Types

fibonacci :: Int -> Int
fibonacci n = fibs !! n
    where fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

fibonacci_hs :: CInt -> CInt
fibonacci_hs = fromIntegral . fibonacci . fromIntegral

foreign export ccall fibonacci_hs :: CInt -> CInt

test.c

#include <HsFFI.h>
#include <stdio.h>
#include <dlfcn.h>

int main(int argc, char *argv[])
{
    void* handle;

    hs_init(&argc, &argv);

    handle = dlopen("/home/ebehn/Desktop/libsafe.so", RTLD_NOW);
    if (!handle)
    {
        fprintf(stderr, "%s\n", dlerror());
        return 2;
    }

    hs_exit();
    return 0;
}

Бег ldd:

[bash]> ldd test
    linux-vdso.so.1 (0x00007ffef8ff1000)
    libgmp.so.10 => /lib64/libgmp.so.10 (0x00007ff046d0e000)
    libm.so.6 => /lib64/libm.so.6 (0x00007ff0469c3000)
    librt.so.1 => /lib64/librt.so.1 (0x00007ff0467bb000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007ff0465b7000)
    libffi.so.6 => /lib64/libffi.so.6 (0x00007ff0463af000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007ff046191000)
    libc.so.6 => /lib64/libc.so.6 (0x00007ff045ddb000)
    /lib64/ld-linux-x86-64.so.2 (0x00007ff046f86000)

[bash]> ldd libsafe.so 
    linux-vdso.so.1 (0x00007ffe44bf1000)
    libHSbase-4.9.1.0-ghc8.0.2.so => /usr/lib64/ghc-8.0.2/base-4.9.1.0/libHSbase-4.9.1.0-ghc8.0.2.so (0x00007fc705d0c000)
    libHSinteger-gmp-1.0.0.1-ghc8.0.2.so => /usr/lib64/ghc-8.0.2/integer-gmp-1.0.0.1/libHSinteger-gmp-1.0.0.1-ghc8.0.2.so (0x00007fc705ad6000)
    libHSghc-prim-0.5.0.0-ghc8.0.2.so => /usr/lib64/ghc-8.0.2/ghc-prim-0.5.0.0/libHSghc-prim-0.5.0.0-ghc8.0.2.so (0x00007fc7056d4000)
    libgmp.so.10 => /lib64/libgmp.so.10 (0x00007fc70545c000)
    libc.so.6 => /lib64/libc.so.6 (0x00007fc7050a6000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fc706b41000)

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

Я нашел полезное руководство здесь: https://www.vex.net/~trebla/haskell/so.xhtml

Сортировка: мне нужно связать свою библиотеку с библиотекой RTS:

ghc -dynamic -shared -fPIC -o libsafe.so Safe.hs -lHSrts-ghc8.2.2
0 голосов
/ 08 мая 2018

Функция, которую вы ищете, реализована в Cabal 2. В файле .cabal теперь вы можете использовать foreign-library раздел, который будет производить DSO, в котором все биты haskell статически связаны (насколько я понимаю). ). Затем этот DSO может быть загружен в не-кодовый код как обычный DSO.

Пример использования foreign-library:

foreign-library myforeignlib
  type:                native-shared
  lib-version-info:    1:2:3

  if os(Windows)
    options: standalone
    mod-def-file: MyForeignLib.def

  other-modules:       MyForeignLib.SomeModule
                       ...
  build-depends:       base
                       ...
  hs-source-dirs:      src
  c-sources:           csrc/some_c_code.c
...