はじめに
Crystalを使用してクロスプラットフォームなCバインディングを書く際に、OSごとに適切なリンカーオプションを指定する方法がよくわからなかったので簡単に調べました。
Crsytalにおけるリンカーオプションの書き方
CrystalでCバインディングを書く場合は次のようになります。
@[Link("ui")]
lib LibUI
fun main = uiMain
fun quit = uiQuit
end
ここで、@[Link("ui")] はアノテーション(注釈)です。
codegen/link.cr を見るとリンカーアノテーションの挙動はOSごとに異なります。
- WindowsではMSVCリンカーのオプションを利用します。
- LinuxとMacOSではGNU ldリンカーのフラグをそれぞれ指定します。
このように2種類の異なるリンカーを使うため、最初から macro を利用してOSごとに場合分けをしてLinkアノテーションをつける方法が有効です。
{% if flag?(:windows) %}
@[Link("#{__DIR__}/../../libui")]
{% else %}
@[Link(ldflags: "-L #{__DIR__}/../../ -lui")]
{% end %}
lib LibUI
この方法により、OSに応じて適切なリンカーオプションを動的に設定することが可能です。
共有ライブラリの作成と配布の課題
共有ライブラリの作成や配布は大きな課題で、現状は定まった方法がありません。
Rubyでは、必要なso、dll、dylibファイルをビルドしたり、ベンダーディレクトリにダウンロードするRakeタスクを作成することができました。同様の方向性としては、syard.yml の postinstall を利用できる可能性があります。
scripts:
postinstall: crystal run download.cr
しかし、shards.yml の postinstall はあまり評判がよくありません。
今のところコミュニティで広く受け要られている方法はないと考えられます。