Distributing tools created in the Crystal language
People use the Crystal language for different purposes, but looking at the trends on Github, many people are creating web applications, perhaps because the Crsytal language has deep connections with the Ruby language. But I want to make command line tools with Crystal. Rust has a convenient build and package manager like Cargo, but Crystal does not.
So you must built crystal tools from source. This is a major obstacle to distributing the tool to non-Crystal users. Unlike Python or Perl, Crystal is a language that cannot be expected to be pre-installed in your computer at all. So you lose a lot of potential users here.
I want to distribute my tool as Debian package (deb).
So I wrote Github Actions that will create a deb package and add it to the release page when I push the release tag.
- Firing when a release tag is pushed, such as v0.0.0
- deb is created with a classic tool called checkinstall
- Automatically upload the deb file to the release page
https://github.com/bio-crystal/bam-filter/blob/main/.github/workflows/build.yml
name: build
on:
push:
tags:
- "v*.*.*"
jobs:
release:
name: Release
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ 'ubuntu-20.04' ]
steps:
- uses: actions/checkout@v2
- uses: crystal-lang/install-crystal@v1
- run: sudo apt -qy install libhts-dev checkinstall
- run: shards install
- run: make
- run: sudo checkinstall
--pkgname=bam-filter
--pkgversion=$(echo ${{ github.ref }} | sed -e "s#refs/tags/v##g")
--maintainer=2xijok@gmail.com
--requires=libhts3,libc6,libpcre3,libevent-dev,libgc-dev
--nodoc -y
- uses: softprops/action-gh-release@v1
with:
files: "bam-filter*.deb"
--pkgversion=$(echo ${{ github.ref }} | sed -e "s#refs/tags/v##g")
extracts the version number from the tags.--requires=libhts3,libc6,libpcre3,libevent-dev,libgc-dev
For dependencies, I installed the tools on bare Ubuntu using Docker, checked them with ldd, and added any missing dependencies.
I wrote libevent-dev
and libgc-dev
instead of libevent-2.1-7
and libgc1c2
. Why is it necessary to specify the dev package? Of course not. However, since normal packages include version numbers in their names, dependencies can easily be broken by using different environment. For example, libgc-dev
is libgc1c2
in Ubuntu focal, but libgc1
in Ubuntu impish. That is why I specified the -dev package here so that it will work in both environments.
If you build puts 0
, which seems to be one of the minimal Crystal scripts, and ldd
it, you get something like this:
linux-vdso.so.1 (0x00007ffc683a7000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f181a706000)
libevent-2.1.so.7 => /lib/x86_64-linux-gnu/libevent-2.1.so.7 (0x00007f181a6b0000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f181a696000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f181a46e000)
/lib64/ld-linux-x86-64.so.2 (0x00007f181a91f000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f181a469000)
So, I think libevent-dev
, libgc-dev
, libpcre3
and libc6
always need to be added to the dependencies. (On Ubuntu, however, libpcre3
is pre-installed from the start.)
You might think checkinstall is not cool?
Well, maybe not. But this tool works just fine. You know "Done is better than nothing".
But If you know a better way, please let me know in the discussion 👇
Pull requests are also welcome.
Have a nice day!
Top comments (0)