Статическая компоновка
Crystal поддерживает статическую компоновку, то есть может компоновывать исполняемый файл со статическими библиотеками, чтобы эти библиотеки не требовались в качестве зависимостей во время выполнения.
Статическую компоновку можно включить с помощью флага компилятора --static. Инструкции по использованию см. в справочнике по языку.
При указании --static компоновка со статическими библиотеками включается, но не является исключительной. Созданный исполняемый файл не будет полностью статически скомпонован, если динамическая версия библиотеки находится в цепочке поиска библиотек компилятора выше статического варианта (или если статическая библиотека отсутствует). Чтобы создать статический исполняемый файл, необходимо убедиться, что доступны статические версии компонуемых библиотек и что компилятор может их найти.
В качестве первого места поиска статических и динамических библиотек, предназначенных для компоновки, компилятор использует переменную окружения CRYSTAL_LIBRARY_PATH. С её помощью можно указать статические версии библиотек, которые также доступны в виде динамических.
Не все библиотеки хорошо работают при статической компоновке, поэтому могут возникнуть некоторые проблемы. Например, openssl известен своими сложностями, как и glibc (см. раздел Полностью статическая компоновка).
Некоторые менеджеры пакетов предлагают отдельные пакеты со статическими библиотеками: foo, например, содержит динамическую библиотеку, а foo-static — статическую. Иногда статические библиотеки также входят в пакеты для разработки.
Полностью статическая компоновка
Программа, скомпонованная полностью статически, вообще не имеет зависимостей от динамических библиотек. Яркие примеры полностью статически скомпонованных программ на Crystal — двоичные файлы crystal и shards из официальных пакетов дистрибутива.
Чтобы скомпоновать программу полностью статически, все зависимости должны быть доступны во время компиляции в виде статических библиотек. Иногда это может быть непросто, особенно в случае распространённых библиотек libc.
Linux
glibc
glibc — наиболее распространённая реализация libc в системах Linux. К сожалению, она плохо сочетается со статической компоновкой, и её использование крайне не рекомендуется.
Вместо этого в Linux рекомендуется статическая компоновка с musl-libc. Поскольку используется статическая компоновка, исполняемый файл, скомпонованный с musl-libc, также будет работать в системе с glibc. В этом и состоит его основное назначение.
musl-libc
musl-libc — это чистая и эффективная реализация libc с отличной поддержкой статической компоновки.
Рекомендуемый способ создания статически скомпонованной программы на Crystal — использовать Alpine Linux, минималистичный дистрибутив Linux на основе musl-libc.
Официальные образы Docker на основе Alpine Linux доступны на Docker Hub по адресу crystallang/crystal. Последний выпуск помечен тегом crystallang/crystal:latest-alpine. Исходный файл Dockerfile доступен в репозитории crystal-lang/distribution-scripts.
Благодаря предустановленным компилятору crystal, shards и статическим библиотекам всех зависимостей стандартной библиотеки эти образы Docker позволяют легко создавать статические исполняемые файлы Crystal даже в системах на основе glibc. Официальные сборки компилятора Crystal для Linux создаются с использованием этих образов.
Вот пример использования образа Docker для создания статически скомпонованной программы «Привет, мир»:
$ echo 'puts "Hello World!"' > hello-world.cr
$ docker run --rm -it -v $(pwd):/workspace -w /workspace crystallang/crystal:latest-alpine \
crystal build hello-world.cr --static
$ ./hello-world
Hello World!
$ ldd hello-world
statically linked
С менеджером пакетов APK в Alpine также легко устанавливать статические библиотеки. Доступные пакеты можно найти на сайте pkgs.alpinelinux.org.
macOS
macOS официально не поддерживает полностью статическую компоновку, поскольку необходимые системные библиотеки недоступны в виде статических библиотек.
To the extent possible under law, the persons who contributed to this workhave waived
all copyright and related or neighboring rights to this workby associating CC0 with it.
https://crystal-lang.org/reference/1.2/guides/static_linking.html