2013-12-22 2 views
3

Я пытаюсь скомпилировать несколько грамотных файлов haskell (.lhs) для общего объекта (.so), а затем связать его с основным написанное в c. Проблема здесь, однако, в том, что 2 из файлов, используемых для создания .so, являются шаблонами haskell. Я следовал правилам компиляции .so с шаблоном haskell, что означает, что я сделал следующие шаги:
1. Я скомпилировал каждый файл .lhs, статически
2. Затем я скомпилировал их все время в два раза динамически.
3. Я создал общий объект из объектных файлов я получил от шагов 1 & 2.
4. Я скомпилировал main.c в main.o
5. Я создал исполняемый файл из шагов 3 & 4.
компиляция общего объекта, написанного в haskell и шаблона haskell, и связывания его с main в c

есть 3 файла, из которых создается .so. Dep1.lhs, Dep2.lhs & Dep3.lhs и основной написано в с

, когда я скомпилировать Makefile я получаю сообщение:

my_directory >> сделать все
гт -f *. o * .hi * .so * .dyn_hi * .dyn_o main
ghc -c Dep3.lhs -XTemplateHaskell -XForeignFunctionInterface -o Dep3.o
ghc -c Dep3.lhs -dynamic -XTemplateHaskell -fPIC -no-hs- main -XForeignFunctionInterface -o Dep3.dyn_o -osuf dyn_o -hisuf dyn_hi ghc -c Dep2.lhs -XTemplateHaskell -XForeignFunctionInterface -o Dep2.o
GHC -c Dep2.lhs -dynamic -XTemplateHaskell -fPIC -no-HS-Главный -XForeignFunctionInterface -o Dep2.dyn_o -osuf dyn_o -hisuf dyn_hi
GHC -c Dep1.lhs -XTemplateHaskell -XForeignFunctionInterface -o Dep1.o

Загрузка пакета ghc-prim ... linking ... done. Загрузка пакета integer-gmp ... linking ... done.
Загрузка пакета базы ... связь ... сделано.
Загрузка пакета pretty-1.1.1.0 ... linking ... done.
Загрузка пакета массива-0.4.0.1 ... linking ... done.
Загрузка пакета deepseq-1.3.0.1 ... linking ... done.
Загрузка пакетов контейнеров-0.5.0.0 ... связывание ... сделано.
Загрузка пакета template-haskell ... linking ... done.
ghc -c Dep1.lhs -dynamic -XTemplateHaskell -fPIC -no-hs-main -XForeignFunctionInterface -o Dep1.dyn_o -osuf dyn_o -hisuf dyn_hi
Загрузка пакета ghc-prim ... linking ... done.
Загрузка пакета integer-gmp ... linking ... done.
Загрузка пакета базы ... связь ... сделано.
Загрузка пакета pretty-1.1.1.0 ... linking ... done.
Загрузка пакета массива-0.4.0.1 ... linking ... done.
Загрузка пакета deepseq-1.3.0.1 ... linking ... done.
Загрузка пакетов контейнеров-0.5.0.0 ... связывание ... сделано.
Загрузка пакета template-haskell ... linking ... done.
ghc -O2 -dynamic -shared -fPIC Dep1.dyn_o Dep2.dyn_o Dep3.dyn_o -o libShared.so -lHSrts-ghc7.6.3
gcc -O2 -I/usr/local/lib/ghc-7.6.3/include -L/usr/local/lib/ghc-7.6.3 -L/usr/local/lib/ghc-7.6.3/template-haskell-2.8.0.0/-c Main.c -o main.o
gcc -o main main.o -L/usr/local/lib/ghc-7.6.3 -L/usr/local/lib/ghc-7.6.3/template-haskell-2.8.0.0/-L. -lShared -Wl, -rpath,/usr/local/lib/ghc-7.6.3 -L/home/tal/a_prerequisites/new_haskell/ghc-7.6.3/libraries/base/dist-install/build/libHSbase-4.6 .0.1-ghc7.6.3. -lHStemplate-Haskell-2.8.0.0
/USR/бен/LD: динамическая переменная `ghczmprim_GHCziTypes_True_closure 'равно нулю размер

/USR/бен/LD: динамическая переменная` ghczmprim_GHCziTypes_ZMZN_closure' равно нулю размер

/usr/bin/ld: /usr/local/lib/ghc-7.6.3/template-haskell-2.8.0.0//libHStemplate-haskell-2.8.0.0.a(Syntax__1744.o)(.text+0x77): неразрешимое R_X86_64_32 перемещение против символа `ghczmprim_GHCziTypes_True_closure»

/USR/бен/л.д.: /usr/local/lib/ghc-7.6.3/template-haskell-2.8.0.0//libHStemplate-haskell-2.8.0.0. а (Lib__228.o) (.text + 0x14): неразрешимой R_X86_64_32S перемещение против символа `ghczmprim_GHCziTypes_ZMZN_closure»

/USR/бен/LD: /usr/local/lib/ghc-7.6.3/template-haskell-2.8.0.0//libHStemplate -haskell-2.8.0.0.a (Lib__137.o) (текст + 0x14.): неразрешимой R_X86_64_32S перемещение против символа `ghczmprim_GHCziTypes_ZMZN_closure»

/USR/бен/LD: /usr/local/lib/ghc-7.6 0,3/шаблон-Haskell-2.8.0.0 // libHStemplate-Haskell-2.8.0.0.a (Lib__227.o) (текст + 0x14.): неразрешимой R_X86_64_32S перемещение против символа `ghczmprim_GHCziTypes_ZMZN_closure»

/USR/бен/ld: /usr/local/lib/ghc-7.6.3/temp в конце-Haskell-2.8.0.0 // libHStemplate-Haskell-2.8.0.0.a (Lib__124.o) (текст + 0x14.): неразрешимая R_X86_64_32S перемещение против символа `ghczmprim_GHCziTypes_ZMZN_closure

и исполняемого 'главного' является создан, но когда я пытаюсь запустить его, происходит следующее:

host113 @/дома/тал/Документы/mfbus >> главная
основной: ошибка при загрузке разделяемых библиотек: libHSbase-4.6.0.1- ghc7.6.3.so: невозможно открыть файл общих объектов: нет такого файла или каталога

Я попытался включить в последнее правило (главное) каталог «libHSbase-4.6.0.1-ghc7.6.3.so» в опции «-l», чтобы он загружал его. Но он, похоже, не работает. Может кто-то понять про ошибку?

код для Dep1.lhs:

> {-# LANGUAGE TemplateHaskell #-} <br/> 
> {-# LANGUAGE ForeignFunctionInterface #-} <br/> 

> module Dep1 where 

> import Foreign <br/> 
> import Foreign.C.Types <br/> 
> import Dep3 <br/> 

> data MyData = MyData 
> { foo :: String 
> , bar :: Int 
> } 

> emptyShow ''MyData 

> foreign export ccall some_func :: IO() <br/> 
> foreign export ccall factorial :: Int -> Int 

> some_func :: IO() <br/> 
> some_func = print $ MyData { foo = "bar", bar = 5 } 

> factorial :: Int -> Int <br/> 
> factorial 0 = 1 <br/> 
> factorial n = n *(factorial $ n - 1)  

код для Dep3.lhs (приходит сюда, потому что Dep1.lhs импортирует его):

> {-# LANGUAGE TemplateHaskell, FlexibleInstances #-} 

> module Dep3 where 

> import Language.Haskell.TH 

> emptyShow :: Name -> Q [Dec] <br/> 
> emptyShow name = [d|instance Show $(conT name) where show _ = "some meaningful sentence"|] 

код для Dep2.lhs:

> {-# LANGUAGE ForeignFunctionInterface #-} 

> module Dep2 where <br/> 

> import Foreign <br/> 
> import Foreign.C.Types 

> foreign export ccall power :: CInt -> CInt 

> power :: CInt -> CInt 
> power n = n*n 

код для main.c:

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <HsFFI.h> 

#ifdef __GLASGOW_HASKELL__ 
#include "Tal2_stub.h" 
#endif 

#ifdef __GLASGOW_HASKELL__ 
extern void __stginit_power (void); 
#endif 

// int power(int i){ return i*i; } 

int fact(int i){ 
    if (i == 0) return 1; 
    else return i * fact(i-1); 
} 
nt main(int argc, char *argv[]){ 
    hs_init(&argc, &argv); 

#ifdef __GLASGOW_HASKELL__ 
    hs_add_root(__stginit_power); 
#endif 

printf("what is 5!?\n"); 
char buf[2048]; 
scanf("%s",buf); 
int x = atoi(buf); 
if(x == fact(5)){ 
    printf("You're right!\n"); 
} else { 
    printf("You're wrong!\n"); 
} 
printf("what is the power of 2?\n"); 
scanf("%s",buf); 
x = atoi(buf); 
if(x == power(2)){ 
    printf("You're right!\n"); 
} else { 
    printf("You're wrong!\n"); 
} 
hs_exit(); 
return 0; 
} 

мой Makefile код:

all : clean main 

main : shared main.o 
     gcc -o main main.o -L/usr/local/lib/ghc-7.6.3 -L/usr/local/lib/ghc-7.6.3/template-haskell-2.8.0.0/ -L. -lShared -Wl,-rpath,/usr/local/lib/ghc-7.6.3 -L/home/tal/a_prerequisites/new_haskell/ghc-7.6.3/libraries/base/dist-install/build/libHSbase-4.6.0.1-ghc7.6.3. -lHStemplate-haskell-2.8.0.0 

main.o : 
    gcc -O2 -I/usr/local/lib/ghc-7.6.3/include -L/usr/local/lib/ghc-7.6.3 -L/usr/local/lib/ghc-7.6.3/template-haskell-2.8.0.0/ -c Main.c -o main.o 

shared : dep3second dep2second dep1second 
     ghc -O2 -dynamic -shared -fPIC Dep1.dyn_o Dep2.dyn_o Dep3.dyn_o -o libShared.so -lHSrts-ghc7.6.3 

dep1second : dep1first 
    ghc -c Dep1.lhs -dynamic -XTemplateHaskell -fPIC -no-hs-main -XForeignFunctionInterface -o Dep1.dyn_o -osuf dyn_o -hisuf dyn_hi 

dep2second : dep2first 
    ghc -c Dep2.lhs -dynamic -XTemplateHaskell -fPIC -no-hs-main -XForeignFunctionInterface -o Dep2.dyn_o -osuf dyn_o -hisuf dyn_hi 

dep3second: dep3first 
    ghc -c Dep3.lhs -dynamic -XTemplateHaskell -fPIC -no-hs-main -XForeignFunctionInterface -o Dep3.dyn_o -osuf dyn_o -hisuf dyn_hi 

dep1first : 
    ghc -c Dep1.lhs -XTemplateHaskell -XForeignFunctionInterface -o Dep1.o 

dep2first : 
    ghc -c Dep2.lhs -XTemplateHaskell -XForeignFunctionInterface -o Dep2.o 

dep3first : 
    ghc -c Dep3.lhs -XTemplateHaskell -XForeignFunctionInterface -o Dep3.o 

.PHONY : clean 
clean : 
    -rm -f *.o *.hi *.so *.dyn_hi *.dyn_o main 
+0

Это много кода только для ошибки времени выполнения ... – rene

ответ

1

Примечание: мое знание Haskell ограничено, и этот ответ ничего не предположить о Haskell вообще.

Ошибка говорит:

<executable>: ошибка при загрузке разделяемых библиотек: <shared lib> .so: не удается открыть общий объектный файл: Нет такого файла или каталога

, что означает, что при попытке выполнить ваша программа, общий объект не найден. Обратите внимание на разницу между поиском общего объекта во время ссылки и во время выполнения.

Грубо говоря, когда вы используете -L и -l для ссылки на общий объект, ссылка не выполнена полностью, но ее необходимо запомнить во время выполнения. Когда вы выполняете исполняемый файл, который зависит от этого общего объекта, кто-то другой (а не компилятор) должен иметь возможность находить общий объект и выполнять привязку: снова грубо говоря, Linux.

Так что вам нужно, чтобы Linux тоже нашел свой общий объект. Есть несколько способов сделать это, некоторые из которых устарели. То, как я бы рекомендовал, это написать файл с пустым разделяемым объектом и поставить его под /etc/ld.so.conf.d/. Затем выполните ldconfig как root (например, с помощью sudo), и Linux должен иметь возможность находить общий объект.

Я не тестировал это, но если вы просто отредактируете /etc/ld.so.conf и добавьте строку, содержащую ., то Linux должен иметь возможность находить общий объект, если он находится в том же каталоге, из которого выполняется исполняемый файл. Это может быть хорошо для разработки, но я бы не рекомендовал его, если должен быть установлен общий объект.