関連記事
GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ
概要
以下、自分用のメモです。忘れないうちにメモメモ。。。
clibs/clibというC言語用のパッケージマネージャを最近知りました。
C言語で実装しているとき、他の言語のようにサクッとライブラリとかをインストールすることが難しい場合が多かったり、そもそも見つけるのが大変だったりします。
なので、大抵は自前で実装したりすることになることが多いです。私の場合。
んで、clibs/clibさんなのですが、npmとかpipとかnugetみたいな感じで利用できます。
$ clib install buffer
みたいな感じです。すごく便利。
ということで、軽く触った軌跡をメモとして残しておきます。
インストール
READMEに環境ごとのインストール方法が記載されています。
私は、git cloneして自分の環境でコンパイルするやり方でやりました。
$ git clone https://github.com/clibs/clib.git $ cd clib # インストール場所はデフォルトで /usr/local/bin ですが、~/.local/bin に変更 $ make PREFIX=~/.local install $ ls -1l ~/.local/bin clib* clib clib-build clib-configure clib-init clib-install clib-search clib-uninstall clib-update clib-upgrade
これでインストール完了。
使ってみる
適当にソース置き場作って、clibを使ってライブラリをインストールしてみます。
今回は以下のライブラリを使います。
$ mkdir a $ cd a # 初期化 # パッケージ名とバージョンを聞かれますが今回はデフォのままで進める $ clib init package name (a): version (default: 0.1.0): $ cat clib.json { "name": "a", "version": "0.1.0" } # ライブラリのインストール # clibs/buffer と tylertreat/chan をインストール # 一部 warning が出るが、clib.json に repo キーが無いよってエラー。問題無いのでそのまま続ける $ clib install clibs/buffer warning : missing repo in clib.json or package.json file for clib1 fetch : clibs/buffer:package.json cache : clibs/buffer $ clib install tylertreat/chan warning : missing repo in clib.json or package.json file for clib1 fetch : tylertreat/chan:package.json cache : tylertreat/chan # 依存関係に追記されてる $ cat clib.json { "name": "a", "version": "0.1.0", "dependencies": { "clibs/buffer": "0.4.0", "tylertreat/chan": "0.0.4" } } # depsディレクトリの下にライブラリはインストールされる $ tree . . ├── clib.json ├── deps │ ├── buffer │ │ ├── buffer.c │ │ ├── buffer.h │ │ └── package.json │ └── chan │ ├── chan.c │ ├── chan.h │ ├── package.json │ ├── queue.c │ └── queue.h
もう普通にパッケージマネージャ使っている感覚で利用できますね。楽すぎる。
てことで、インストールしたライブラリを利用するサンプルプログラムを適当に用意。今回はsrcディレクトリを作成してその下に置きました。
$ mkdir src $ touch src/main.c
main.c
#include <pthread.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include "buffer/buffer.h" #include "chan/chan.h" static chan_t *ch; static void *send(void *arg) { chan_send(ch, "hello"); chan_send(ch, "world"); return (void *)(intptr_t)chan_close(ch); } int main(void) { // // clibs/buffer // buffer_t *buf = buffer_new(); { buffer_append(buf, "Hello World"); buffer_print(buf); } buffer_free(buf); // // tylertreat/chan // ch = chan_init(0); { pthread_t th; pthread_create(&th, NULL, send, NULL); void *msg; while (chan_recv(ch, &msg) == 0) { printf("%s\n", (char *)msg); } void *th_ret; pthread_join(th, &th_ret); } chan_dispose(ch); return EXIT_SUCCESS; }
Taskfile.yml
C言語なのでMakefileでやるべきですが面倒なので Task でちゃちゃっとコンパイルと実行。
# https://taskfile.dev version: '3' tasks: default: cmds: - gcc -Ideps -Wall -o app src/*.c deps/**/*.c - ./app clean: cmds: - rm -f ./app fmt: cmds: - clang-format -i src/*.c
ファイル構成
こんな感じになりました。
$ tree .
.
├── Taskfile.yml
├── clib.json
├── deps
│ ├── buffer
│ │ ├── buffer.c
│ │ ├── buffer.h
│ │ └── package.json
│ └── chan
│ ├── chan.c
│ ├── chan.h
│ ├── package.json
│ ├── queue.c
│ └── queue.h
└── src
└── main.c
実行
$ task task: [default] gcc -Ideps -Wall -o app src/*.c deps/**/*.c task: [default] ./app 48 65 6c 6c 6f 20 57 6f 72 6c 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 hello world
ちゃんとコンパイル出来て動作してますね。楽ですねー。
参考情報
情報さがしてみたら、10年以上前に mattn さんがすでにclibについて記事書かれていました。
過去の記事については、以下のページからご参照下さい。
サンプルコードは、以下の場所で公開しています。