CentOS 7 (rootなし) でLLVM 15をビルドする方法

入ってるパッケージが諸々古すぎるので、周辺のライブラリのビルドから始める必要がある。 そのへんを自動でやってくれるようにシェルスクリプトにまとめた。 /tmp に tmpfs がいなかったり、ホームディレクトリが NFS だったりする環境のものなので、_build_dir 系の変数は変更して使ったほうがいいと思う。 ビルド手順 まず、標準で入っている GCC は LLVM をビルドするには古すぎるので、GCC のビルドから始める必要がある。 古い LLVM から徐々にバージョンアップしていく方法でもいいが、最新の GCC はビルドできるので。ついでに GCC も最新にしてやる方が首尾が良いと思う。 で、最新の GCC をビルドするには周辺のライブラリが古すぎるので、最初にとりかかるべきは

mallocをフックしてメモリ使用量を測る

いろいろと怪しいけどこれでフックすれば取れるはず。 まあ malloc をフックしている時点で怪しいので細かいことを気にしてはいけない (?) #define _GNU_SOURCE #include <dlfcn.h>#include <string.h>#include <stdio.h> static size_t max_usage; static size_t cur_usage; static void *(*orig_malloc)(size_t); static void (*orig_free)(void *); static void *(*orig_realloc)(void *, size_t); __attribute__((constructor)) void initialize(void) { orig_malloc = dlsym(RTLD_NEXT, "malloc"); orig_free = dlsym(RTLD_NEXT, "free"); orig_realloc = dlsym(RTLD_NEXT, "realloc"); } extern char *__progname; __attribute__((destructor)) void print_stat(void) { size_t result = max_usage; fprintf(stderr, "%s: max memory usage: %zu\n", __progname, result); } void *malloc(size_t size) { void *ptr = orig_malloc(size + sizeof(size_t)); if (ptr == NULL) { return NULL; } memcpy(ptr, &size, sizeof(size_t)); cur_usage += size; if (cur_usage > max_usage) { max_usage = cur_usage; } return (void *)((unsigned char *)ptr + sizeof(size_t)); } void *calloc(size_t nmemb, size_t size) { void *ptr = malloc(nmemb * size); if (ptr != NULL) { memset(ptr, 0, size * nmemb); } return ptr; } void free(void *ptr) { if (ptr == NULL) { return; } void *head = (void *)((unsigned char *)ptr - sizeof(size_t)); size_t size; memcpy(&size, head, sizeof(size_t)); cur_usage -= size; orig_free(head); } void *realloc(void *ptr, size_t size) { size_t old_size = 0; void *result; if (ptr != NULL) { void *head = (void *)((unsigned char *)ptr - sizeof(size_t)); memcpy(&old_size, head, sizeof(size_t)); result = orig_realloc(head, size + sizeof(size_t)); } else { result = orig_realloc(ptr, size + sizeof(size_t)); } if (result != NULL) { cur_usage -= old_size; cur_usage += size; if (cur_usage > max_usage) { max_usage = cur_usage; } memcpy(result, &size, sizeof(size)); return (void *)((unsigned char *)result + sizeof(size_t)); } return NULL; } void

ELF ファイルを適当に編集する方法

patchelf を使うと一発。elfedit というコマンドが binutils にあるっぽかったが、使い方がイマイチ分からなかった。 RPATH の追加 $ORIGIN/../lib を追加する例。ちなみに $ORIGIN はファイルがあるディレクトリを指すので、絶対パスを使うより柔軟にパスの指定ができる。 $ patchelf --add-rpath '$ORIGIN/../lib' NEEDED の追加 $ patchelf --add-needed libhoge.so.0 RPATH と NEEDED を組み合わせると LD_PRELOAD 的なことが環境変数なしでできる 下みたいな内容で適当なライブラリを作る。 int puts(const char *s) { return 0; } で、下みたいな内容の実行ファイルに patchelf する。 #include <stdio.h>int main(void) { puts("hoge"); } $ ./hoge hoge $ patchelf --add-rpath '$ORIGIN/lib' $ patchelf --add-needed 'libhoge.so.0' $ ./hoge (何も出ない) 実用性があるかは謎。

listingsのあれこれ

LaTeX でソースコードを貼る listings についてのメモ。 毎回過去に書いた .tex ファイルを掘り返していて効率が悪かったので。 いろいろ設定 \usepackage{listings} \lstset{basicstyle=\ttfamily\footnotesize,frame=single,breaklines=true} 左側に小さく行番号を表示するような設定。 右からあふれた分は改行するようにするくらいしかやってない。 ネットの海を見に行ったらいろいろ細かく設定している人もいるので、やろうと思ったらいろいろできるのだと思う。 キャプション デフォルトだと「Listing 1 ほげほげ」みたいな名前になるので適当に変更。 \renewcommand{\lstlistingname}{リスト} これで「リスト1 ほげほげ」みたいになる。 ソースコードの埋め込み \begin{lstlisting}[caption=ほげ

Emacsのページについて

超久しぶりに投稿。軽いメモ。 form feed (^L) を入れておくと Emacs で適当にスクロールできるところまでは覚えているのだが、 その使い方を毎回忘れる……。 C-x [ (backward-page) で前のページ、 C-x ] (forward-page) で次のページにジャンプする。 page-ext というパッケージを使えばもっといろいろできるらしいけどまあ今のところ必要ないかな。 まあこういう文字が必要になる時点で複数ファイルに分割すべきという話ではあるかもしれないが。

Emacs標準のスプレッドシートses-modeの使い方メモ

ファイル 拡張子を .ses にすると自動で ses-mode になる。 また、そうじゃないファイルでも一回 ses-mode で保存すれば Local Variables が付けられた状態で保存されるので 次からは自動で ses-mode になる。 ファイル自体は先頭に表示内容が入っていて、その後ろに正式なデータといろいろメタデータが S 式で入っているという感じに見える。 ses-mode 自体のコードは読んでないけど。 セルの追加・削除 適当な表 / C- M- o 行を挿入 列を挿入 k 行を削除 列を削除 ただ、一番右に追加していくみたいな場合は C-i で移動していけば追加されていくし、 下に追加していくみたいな場合には C-j でいけるのであんまり表のキーを使うことはなさそう。 コピペ 普通に M-w とか C-y で。 データの入力 ここが Emacs らしくて面白いと思うのだが

QEMUで雑に作るArch Linux ARMビルド環境

QEMU で起動するのが楽な Alpine Linux で aarch64 な Linux 環境を作り、 その中でブートストラップした Arch Linux ARM に chroot して使ってやろうというもの。 Alpine も Arhc も小さいのでビルドしようとするものによるが、tmpfs だけで戦える可能性が十分ある。 bazel と mozc のビルドをやったが、16 GB メモリのマシンで tmpfs しか使わずに作業が終わった (ビルド後にいらなくなった一時ファイルを消したりはしたが)。 準備 aarch64 の仮想マシンの実行には qemu-arch-extra が必要なので事前に入れておく。 Alpine のイメージを公式サイトから落としておく。 多分どれでもいいが、今回は standard を使った。 UEFI を使うため、edk2-armvirt を入れる。 QEMU のイメージの準備 サイズとかは適当に。後で拡張したりできるので大袈裟に気にす

Chromebook を購入し (て Crostini に Arch Linux を入れ) た話

使ってた iPad のボタンの調子が悪かったので移行先を探していたのですが、 「そういや 2-in-1 の Chromebook とかでいいじゃん」てことで Chromebook 1 を購入しました。 CPU が遅かったり aarch64 だったりで、Linux をちゃんと使おうとすると辛さがあるような気がしているので、 開発環境として使いたかったら x86 系のものを買っておいたほうが良いと思います。 操作感 iPad のかわりにしたくて買ったということもあり、タブレットとして使えるかは割と不安だったんですが、 割といい感じです。キーボードを外すとタッチ用の UI になり、少なくとも最近の Android を使ったことがある人は 操作で迷うということはないと思います。UI 自体もけっこう Android に近い。 Arch Linux を入れる 操作感とかはどうでもよくてこ

Dockerメモいろいろ

コンテナからホストと IP 通信する Linux だとホストは 172.17.0.1 に見える。 Mac や Windows だと host.docker.internal に見えるらしい。試してはないけど。 Compose で特定のサービスだけ recreate する イメージが更新されたときとかに。 # docker compose up -d --force-recreate --no-deps hoge

Elasticsearchでサイト内検索できるようにしてみた

このサイトは静的サイトジェネレータの Hugo を使って生成していて、これまで検索欄は Google 検索に site: をつけてクエリを投げるという方法で実現されていました (これは使っているテーマのデフォルトだったため)。 それを今回、Google に飛ばずに自前で検索を行うという感じにしました。 モチベーション Google 検索での一番の問題は、「サイト内のすべてのページにタグ一覧が配置されているために、 キーワードがタグ名と一致する場合すべてのページがヒットしてしまう」という点でした。 Google 検索で検索に使う範囲を指定できればよいのですが、そういったこともできそうになく、 自前で検索する必要性を感じていました。 あと、サイト内の情報が知りたいだけなのに