0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Samtoolsとmrubyでタヌキを表示する

Last updated at Posted at 2022-10-25
    __,-─-、__
   (〆-─-ヽ)
    ( ´・ω・` )  < Samtools ト mruby デ タヌキ ヲ ヒョウジ スル!
   /  ,r‐‐‐、ヽ
    し l  x )J
   _.'、 ヽ  ノ.人
 (_((__,ノU´U. (酒)

はじめに

前回までのあらすじ。Samtoolsにタヌキコマンドを追加して、タヌキを表示した。

今回の記事はこの続きになります。

mrubyとは?

mrubyは組み込み用の小さなRubyです(よくわかっていないので適当な表現)。通常のRubyのように利用することもできますが、C言語等で作られた実行形式のファイルにmrubyを組み込んで使います。組み込まれたツールは、Rubyのコードを評価することができるようになります。組み込みというと、家電の中のマイコン等で動いているようなイメージがありますが、mrubyはマイコンで動かすには大きすぎると思われ、一般的なコンピュータで利用するプログラムに組み込んで使う用途が多いと思われます。

マイコンや小型のデバイスでRubyを実行したい場合は、mruby/cや、picorubyなど、mrubyよりもさらに小さなRuby実装があり、そういったものが好まれるようです。

コマンドラインツールにmrubyを組み込みたい

私は次世代シーケンサーのファイル形式をRubyから操作したいと思い、HTSlibラッパーライブラリを作成しています。これは主にRubyからC言語の関数を呼び出そうという作戦です。しかし、実際にはRubyで記述したい部分はそれほど多くありません。大半がCのコードで、一部分だけRubyを使います。それならば、逆のアプローチがあってもいいと思います。C言語で書かれた既存のコマンドラインツールのうち、本当に必要な部分だけ、mrubyを組み込んでしまうという方法も考えられます。

ここでは、ごく簡単にSamtoolsにmrubyを組み込んで、mrubyのputsメソッドでタヌキを表示してみようと思います。

mrubyを準備する

samtoolsが置いてあるディレクトリと同じ階層に、Gitからmrubyをクローンします。

git clone https://github.com/mruby/mruby
git checkout 3.1.0 # 本文作成時の最新版
git switch -c v3.1.0

mrubyをビルドして、静的ライブラリを作成します。

make

静的ライブラリ build/host/lib/libmruby.a が作成されたことを確認します。

Samtools をビルドするときに、この libmruby.a をリンクすることで、samtoolsからmrubyを使えるようにします。

通常のRuby(つまりCRubyまたはMRI)とは違い、mrubyはあとから動的に外部のライブラリGemを読み込むことができないそうで、あらかじめmrubyをコンパイルするときにmgemを指定しておくそうです。その際には build_config.rb で利用するmgemを指定するそうです。今回はmgemを使わないのでデフォルトのままにします。

SamtoolsのMakefileをいじる

C言語がよくわかっていないのですが、samtoolsがlibmruby.aをリンクするようにMakefileを編集します。
tanuki.o を作る際に、-L ../mruby/build/host/lib/ -I ../mruby/include -lmruby -lm を指定します。
(tanuki.c については以前の記事を参照ください)

--- a/Makefile
+++ b/Makefile
@@ -44,7 +44,7 @@ AOBJS=      bam_aux.o bam_index.o bam_plcmd.o sam_view.o bam_fastq.o \
             bam_tview.o bam_tview_curses.o bam_tview_html.o bam_lpileup.o \
             bam_quickcheck.o bam_addrprg.o bam_markdup.o tmp_file.o \
             bam_ampliconclip.o amplicon_stats.o bam_import.o bam_samples.o \
-            bam_consensus.o consensus_pileup.o reference.o
+            bam_consensus.o consensus_pileup.o reference.o tanuki.o
 LZ4OBJS  =  $(LZ4DIR)/lz4.o
 
 prefix      = /usr/local
@@ -142,7 +142,7 @@ LIBST_OBJS = sam_opts.o sam_utils.o bedidx.o bam.o
 
 
 samtools: $(AOBJS) $(LZ4OBJS) libst.a $(HTSLIB)
-	$(CC) $(ALL_LDFLAGS) -o $@ $(AOBJS) $(LZ4OBJS) libst.a $(HTSLIB_LIB) $(CURSES_LIB) -lm $(ALL_LIBS) -lpthread
+	$(CC) $(ALL_LDFLAGS) -o $@ $(AOBJS) $(LZ4OBJS) ../mruby/build/host/lib/libmruby.a libst.a $(HTSLIB_LIB) $(CURSES_LIB) -lm $(ALL_LIBS) -lpthread
 
 # For building samtools and its test suite only: NOT to be installed.
 libst.a: $(LIBST_OBJS)
@@ -202,6 +202,10 @@ faidx.o: faidx.c config.h $(htslib_faidx_h) $(htslib_hts_h) $(htslib_hfile_h) $(
 padding.o: padding.c config.h $(htslib_kstring_h) $(htslib_sam_h) $(htslib_faidx_h) $(sam_opts_h) $(samtools_h)
 phase.o: phase.c config.h $(htslib_hts_h) $(htslib_sam_h) $(htslib_kstring_h) $(sam_opts_h) $(samtools_h) $(htslib_hts_os_h) $(htslib_kseq_h) $(htslib_khash_h) $(htslib_ksort_h)
 reference.o: reference.c config.h $(htslib_sam_h) $(htslib_cram_h) $(samtools_h) $(sam_opts_h)
+
+tanuki.o:
+	$(CC) tanuki.c -c -o $@ -L ../mruby/build/host/lib/ -I ../mruby/include -lmruby -lm
+
 sam_opts.o: sam_opts.c config.h $(sam_opts_h)
 sam_utils.o: sam_utils.c config.h $(samtools_h)
 sam_view.o: sam_view.c config.h $(htslib_sam_h) $(htslib_faidx_h) $(htslib_khash_h) $(htslib_kstring_h) $(htslib_thread_pool_h) $(htslib_hts_expr_h) $(samtools_h) $(sam_opts_h) $(bam_h) $(bedidx_h)

mrubyでタヌキを表示する部分のコード

初心者なので、難しいことは考えずに、mrb_load_string でタヌキをputsするようにしました。

tanuki.c
#include <mruby.h>
#include <mruby/compile.h>

#include <stdlib.h>
#include <stdio.h>

int main_tanuki(void)
{
    mrb_state *mrb;
    mrb = mrb_open();
    mrb_load_string(mrb, "puts \""
"    __,-─-、__\n"
"   (〆-─-ヽ)\n"
"    ( ´・ω・` )\n"
"   /  ,r‐‐‐、ヽ\n"
"    し l  x )J\n"
"   _.'、 ヽ  ノ.人\n"
" (_((__,ノU´U. (酒)\n\"");
    mrb_load_string(mrb, "puts 'Tanuki in mruby'");
    mrb_close(mrb);

    return 0;
}

ビルド & 実行

autoheader
autoconf -Wno-syntax
./configure
make
samtools tanuki

タヌキが表示されました。

    __,-─-、__
   (〆-─-ヽ)
    ( ´・ω・` )
   /  ,r‐‐‐、ヽ
    し l  x )J
   _.'、 ヽ  ノ.人
 (_((__,ノU´U. (酒)
Tanuki in mruby

mruby が klib/kexpr よりも輝ける場所は存在するか?

BamやBcfファイルに対して、細かい条件を付加してカウントしたりフィルタリングしたりといった用途を実行するためのツールを作成するときに、C言語のライブラリである klib/kexpr が用いられます。これは、C言語のライブラリで、実行時に与えた式を評価してくれます。しかし、mrubyを用いれば、遥かに柔軟な式の評価が可能になるでしょう。高機能なkexprとしてmrubyが活躍できる場所がないか探してみたいと考えています。

この記事は以上です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?