0
0

More than 3 years have passed since last update.

Kinx Tips - 実行形式ファイルを作る

Last updated at Posted at 2020-08-09

Kinx Tips - 実行形式ファイルを作る

はじめに

「見た目は JavaScript、頭脳(中身)は Ruby、(安定感は AC/DC)」 でお届けしているスクリプト言語 Kinx。今回は Tips です。

皆さん、実行ファイルを作る時どうしてますか? ...そう、普通は C や C++ で書いてコンパイルしますね。もっと簡単に作れるといいですね。

Kinx は独立した exe を作ることはサポートしていませんが、Kinx のワールドの中であれば exe にして単体実行コマンドのように見せかけて実行できるモジュールを作れるようにしています。

その辺を少々。

コマンド kxrepl.exekxtest.exe

実は v0.13.1 リリースより kxrepl.exekxtest.exe というコマンドが同梱されています。Linux 版では .exe はついて無くて kxreplkxtest です。

kxrepl を実行してみましょう。

$ kxrepl
kinx[  0]> .quit

REPL が動作しましたね。

次は kxtest です。

$ kxtest -v -T declaration.md
Test Cout = 11
Entry: doc/spec/statement/declaration.md
    Suite: Declaration statement
        Case[ 0]: Normal case ................................... successful (  0.10s)
        Case[ 1]: With initializer .............................. successful (  0.09s)
        Case[ 2]: With initializer of expression ................ successful (  0.09s)
        Case[ 3]: Multiple variable declaration ................. successful (  0.10s)
        Case[ 4]: Constant value (1) ............................ successful (  0.07s)
        Case[ 5]: Constant value (2) ............................ successful (  0.10s)
        Case[ 6]: Constant value (3) ............................ successful (  0.07s)
        Case[ 7]: Constant value (4) ............................ successful (  0.07s)
        Case[ 8]: Constant value (5) ............................ successful (  0.09s)
        Case[ 9]: Destructuring assignment (1) .................. successful (  0.09s)
        Case[10]: Destructuring assignment (2) .................. successful (  0.07s)


<Test Result>
    Total Test Cases:       11
        Successful  :       11
        Failed      :        0
        Warning     :        0

SpecTest が動作しましたね。

もう一つ、試しにやってみましょう。

$ diff -s kxrepl kxtest
Files kxrepl and kxtest are identical

「ファイルは同一です」 というメッセージがでました。というか、そうなんです。この 2 つは バイナリとして全く同じ です。

--exec オプションの話

この話の前に、一つ Kinx のオプションに関する情報を書いておきます。--exec というオプションです。README にも書いてある通り、このオプションによって以下の 2 つのオプションがサポートされています。

  • --exec:repl ... REPL を実行する。
  • --exec:specttest ... SpecTest を実行する。

このメカニズムは、以下の通りになっています。

  1. --exec:xxx を認識したら、Kinx の実行ファイルのあるフォルダから見て lib/exec/xxx.kx、または lib/exec/3rdparty/xxx.kx を探す。
  2. そのファイルがあったら、そのファイルがスクリプトファイルとして指定されたとみなして実行する。

なので、REPL と SpecTest はそれぞれ lib/exec/repl.kxlib/exec/spectest.kx ファイルを探してそれを実行する、という動作をしているのです。この仕組みによって、REPL と SpecTest の修正はバイナリを修正せずに実施できるようにもなっています。

kxrepl

さて、kxrepl のバイナリ(= kxtest のバイナリ)ですが、どういう作りになっているのでしょう(概ね見当は付くと思いますが)。答えはこうです。

  1. 自分自身の実行ファイル名(name としましょう)を取得(argv[0] から取得できます)。
  2. コマンドライン引数の先頭に --exec:name を割り込ませて引数リストを更新。
  3. Kinx のメインロジックに制御を渡す。

するとどうでしょう。自動的に lib/exec/name.kx(または lib/exec/3rdparty/name.kx)を参照して実行してくれるのです!

ということで、kxrepllib/exec/kxrepl.kx を、kxtestlib/exec/kxtest.kx を自動的に実行してくれるという寸法です。

ん?、そんなファイルあったっけ?はい、追加したんです(=あります)。中身を見てみましょう。

lib/exec/kxrepl.kx
using exec.repl;
lib/exec/kxtest.kx
using exec.spectest;

これだけです。中で using するだけのファイルを用意して実現しました。using の検索パスに従って repl.kxspectest.kx を見つけてくれるので、これで正しく動作します。というわけで、kxrepl.exerepl.exe に書き換えても同様に動きます。

ということで、もうお分かりですね。

オリジナル exe を作ろう

オリジナル exe ファイルの作り方は以下の通りです。動作には Kinx の dll と各種ライブラリが必要なので、kinx.exe と同じ場所に、作成した exe を置かなくてはなりませんが、やりたいことをコマンド一発でできるようにはなります。

具体的な例で。

kxcat.exe

cat コマンドみたいなものとして、kxcat コマンドを作ってみましょう。指定されたファイルを指定された順に出力します。cat コマンドと名前が重ならないように kxcat にしておきましょう。一先ずオプションは無しで、ファイルだけ複数受け付けるようにします。

lib/exec/3rdparty/kxcat.kx
$$.each {
    // Ignoring the script file name.
    if (_2 > 0) {
        System.print(File.load(_1));
    }
};

さて、そうしたら kxtest.exe をコピーして名前を変えましょう。Windows でも Linux でもコマンドは違いますが、やりたいことは同じです。

Windows
$ copy /y kxtest.exe kxcat.exe
Linux
$ cp -f kxtest kxcat

コピーしたらそのまま kxcat コマンドを実行!

$ ./kxcat README.md ChangeLog.md
<p align="right">
    <img src="https://github.com/Kray-G/kinx/workflows/Unit%20Test/badge.svg?branch=master"/>
    <img src="http://img.shields.io/badge/license-MIT-blue.svg?style=flat"/>
</p>

...(省略)

## V0.1.0 (1st Preview Release)

*   Initial Release.

できましたね。

インストールされたもので実行したい場合、Linux では以下の場所に kinx コマンドのバイナリがあるので、例えば上記の場合、kxcat コマンドは同じ位置に配置してください。kxreplkxtest も同じ場所に配置してあります。

$ which kinx kxrepl kxtest
/usr/bin/kinx
/usr/bin/kxrepl
/usr/bin/kxtest

おわりに

C でがっつり書いてコンパイルして実行ファイルを作る、でもいいんですけど、スクリプトでササっと書いたのを実行形式ファイルにしたいですよね。かといって、必要なライブラリとか dll とかを全部含めると結構なサイズになったりするので、ここは割り切って Kinx 自体が存在する前提でコマンド化できるようにしてみました。

これはこれで便利かなー、と思います。

あと、やればすぐできるんですけど、例えば kinx.dll の位置を環境変数で指定したり、オプションで渡したりできると、.exe ファイル自体はどこにおいても良くなるのでそのくらいの対応は今後するかも入れません(要望があれば)。xxx.exe と同じ場所にある xxx.kx を実行するとかね。そのほうが便利かなー。dll の場所は何かしらの方法で指定しておく必要はありますが。

ではでは、また次回。

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