Как да компилирам статично C библиотека в Haskell модул, който по-късно мога да заредя с GHC API?

Ето моят желан случай на употреба:

Имам пакет с един модул, който чете HDF5 файлове и записва някои от техните данни в записи на Haskell. За да свърши работата, библиотеката използва пакета bindings-hdf5. Ето build-depends на моята кабала. reader-types е модул, който написах, който дефинира типовете на записите на Haskell, които съдържат данните за четене.

build-depends:         base >=4.7 && <4.8
                     , text
                     , vector
                     , containers
                     , bindings-hdf5
                     , reader-types

Имайте предвид, че моят cabal файл в момента не използва extra-libraries или ghc-options. Мога да заредя моя модул, src/Mabel.hs в ghci, стига да посоча необходимата hdf5_hl библиотека:

ghci src/Mabel.hs -lhdf5_hl -L/long/nixos/path/lib

и в рамките на ghci мога да изпълнявам функцията си перфектно.

Сега, това, което искам да направя, е да компилирам тази библиотека/модул в един компилиран файл, който по-късно мога да заредя с GHC API в различна програма на Haskell. Под един файл имам предвид, че трябва да се изпълнява дори ако библиотеката hdf5_hl не съществува в системата. За предпочитане е също да се изпълнява дори ако text, vector и/или containers липсват, но това не е от съществено значение, защото reader-types така или иначе изисква тези типове. Когато зареждам модула с GHC API, искам той да се зарежда във вече компилиран вид, а не да се изпълнява интерпретиран.

Моята цел да направя това е, че искам самостоятелният файл да действа като единичен, предварително компилиран плъгин файл, който по-късно се зарежда и изпълнява от различен изпълним файл на Haskell. Други плъгини може изобщо да не използват hdf5 и единственият пакет, който гарантирано ще използват, е reader-types, който по същество дефинира типовете интерфейс на плъгина.

Библиотеката hdf5 в моята система съдържа следните файлове: libhdf5_la.la, libhdf5_hl.so, libhdf5.la, libhdf5.so и подобни файлове, които имат номера на версията в името на файла.

Направих много гугъл, но се обърквам от всички крайни случаи, които намирам. Ето някои примери, за които или съм сигурен, че не отговарят на моя случай, или не мога да кажа.

  • Не искам да компилирам библиотека на Haskell, която да използвам от C или Python, само програма на Haskell, използваща GHC API.
  • Не искам да компилирам C обвивки за C++ библиотека в Haskell модул, тъй като обвързванията вече съществуват и библиотеката вече е C библиотека.
  • Не искам да компилирам библиотека, която е изцяло самостоятелна, тъй като, тъй като го зареждам с GHC API, нямам нужда от GHC време за изпълнение, включено в библиотеката. (Моето разбиране е, че добавките трябва да бъдат компилирани със същата ghc версия, с която ще бъдат заредени в GHC API).
  • Не искам да компилирам C свързвания и C библиотеката едновременно, тъй като C библиотеката вече е компилирана и обвързванията са посочени в отделен пакет (bindings-hdf5).
  • Най-близкият ресурс за това, което искам да направя, е тази борса в пощенския списък от 2009 г. Въпреки това добавих extra-libraries: hdf5_hl или extra-libraries: hdf5 към моя cabal файл и в двата случая получените файлове .a, .so, .dyn_hi, .dyn_o, .hi и .o в dist/build са всички точно същия размер като без да използвам extra-libraries, така че съм уверен, че не работи правилно.

Какви промени в моя cabal файл трябва да направя, за да създам самостоятелен, самостоятелен файл, който мога по-късно да заредя с GHC API? Ако това не е възможно, какви са алтернативите?

Вместо да използвам GHC API, аз също съм готов да използвам библиотеката plugins за зареждане на приставката , но самостоятелните изисквания са все същите.

РЕДАКТИРАНЕ: Не ме интересува каква форма трябва да приеме компилираният „плъгин“ (предполагам, че обектният файл е правилният начин), но искам да го заредя динамично от отделен изпълним файл по време на изпълнение и да изпълня функции, които той дефинира с известни имена и известни видове. Причината, поради която искам един файл, е, че в крайна сметка ще има други различни плъгини и искам всички те да се държат по един и същи начин, без да се налага да се тревожа за пътищата на библиотеката и зависимостите за всеки един. Компилираният единичен файл е по-прост интерфейс за извършване на това от компресирането/разархивирането на архиви, които включват обектен код на Haskell и техните зависимости.


person fluffynukeit    schedule 18.10.2014    source източник
comment
Искате ли да имате един файл с обект или просто статично свързан изпълним файл? В последния случай просто предаване на -optl-static към ghc трябва да свърши работа. В първия случай не съм сигурен защо бихте искали да направите това, тъй като няма причина да не можете просто да включите „hdf5_hl“ и други зависимости с вашата библиотека (разбира се, позволяващи лицензи).   -  person user2407038    schedule 19.10.2014
comment
@user2407038 Редактирах въпроса, за да обясня допълнително. Благодаря.   -  person fluffynukeit    schedule 19.10.2014