Статически связывает мусл с GHC
Я пытаюсь создать с помощью GHC статический двоичный файл для веб-приложения на основе CGI, написанного на Haskell, для развертывания на общем сервере.
Я хотел бы использовать мусл, как указано в этом ответе.
К сожалению, это не простая задача:
$ ghc -static -optl-static -pgmc musl-gcc -pgml musl-gcc -L/usr/local/lib app.hs
[1 of 1] Compiling Main ( app.hs, app.o )
Linking app...
/usr/lib/ghc-7.6.3/libHSrts.a(Itimer.o): In function `exitTicker':
(.text+0x1af): undefined reference to `__sysv_signal'
collect2: error: ld returned 1 exit status
Что я делаю неправильно? (Полный отказ от ответственности: я новичок на Haskell (:)
Я использую Arch Linux, GHC 7.6.3 и Network.CGI.
1 ответ
Похоже, ваша среда исполнения на Haskell была скомпилирована для glibc, но вы пытаетесь скомпилировать исходный код на Haskell для musl. В общем, вы не можете смешивать две библиотеки C в одной программе.
Ваша конкретная проблема заключается в том, что glibc поддерживает несколько разных конфликтующих наборов семантики для signal
функция, чтобы соответствовать тому, что предоставили различные исторические версии UNIX. Он выбирает, какую версию использовать, основываясь на макросах тестирования функций, которые определяет ваш код C. И чтобы фактически переключаться между ними, он использует препроцессор C, чтобы заменить ссылки вашей программы на signal
со ссылками на версию функции с любой семантикой, которую вы запросили (в вашем случае ваша среда выполнения на Haskell имеет ссылку на __sysv_signal
).
Проблема в том, что мусл не делает то же самое. Это выставляет одну версию signal
это соответствует тому, что стандарт POSIX определяет его семантику, и это раскрывает его под именем signal
,
Правильный способ исправить это - перекомпилировать среду выполнения Haskell против заголовков musl. Я не знаю, пытался ли кто-нибудь сделать это на самом деле, так что, YMMV.
Обратите внимание, что вам следует избегать установки библиотек в одном системном каталоге, но скомпилированных с разными библиотеками C. Это может привести к поломке, потому что любое программное обеспечение, пытающееся использовать несколько библиотек, скомпилированных с конфликтующими библиотеками C, столкнется с вариантами решения именно той проблемы, с которой вы сейчас столкнулись. Как правило, вы должны скомпилировать и установить musl в свой собственный префикс, а затем скомпилировать другие библиотеки (например, среду выполнения Haskell) для musl и установить в тот же префикс. Таким образом, ваши библиотеки musl и glibc останутся разделенными.