関連記事
GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ
概要
以下、自分用のメモです。興味を惹かれたので忘れないうちにメモメモ。。。
Go 1.26 interactive tour などで有名な antonz さんが新しいリポジトリを公開していました。
上記リポジトリのREADMEに以下のように書かれています。以下引用。
Go in, C out. You write regular Go code and get readable C11 as output.
GoのコードからCのコードを出力してくれるとのこと。GoもCもやっている人には凄く興味が湧きますね。
まだ、公開されたばかりなので、これからのツールだと思いますが、少し触ってみました。
試してみる
インストール
nalgeon/solod は so という実行ファイルを利用して変換やビルド、実行などが行えるみたいです。
なので、まずは so コマンドをインストールします。
go install github.com/nalgeon/solod/cmd/so@latest
Goのコードを用意
helloworld出すだけだと味気ないので、もう少しマシなサンプルを用意。コードに意味は無いです。
package main type ( Language string Languages []Language ) func main() { var ( langs = make(Languages, 0, 4) progs = []string{"Go", "C#", "Java", "Python"} ) for _, p := range progs { langs = append(langs, Language(p)) } for _, l := range langs { println(l) } }
普通にgoでビルドして実行
$ go build -o goapp .
$ ./goapp
Go
C#
Java
Python
そのまんまです。
soコマンドを使ってビルド
インストールした so コマンドを使ってビルドしてみます。
$ so build -o capp .
$ ./capp
Go
C#
Java
Python
おー。ちゃんとビルドして実行出来ました。
C言語でビルドされているのか確認
goのアプリは基本的に静的リンクされた実行ファイルがビルドされます。(一部のパッケージを利用するとその限りではありません)
なので、fileコマンドで確認すると
$ file ./goapp ./goapp: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, Go BuildID=J3WxXoEXsYPZ5WubWfOp/Ka9FGvGNFRzovMkz4GAa/4lqPkXSaf4YdhdwjP1pF/C1S2SXOxHLh14zz05pNH, BuildID[sha1]=a06c2a2599135602e7fc444398a9ebadf98c171b, with debug_info, not stripped
statically linked って出てますね。lddコマンドで確認すると
$ ldd ./goapp
動的実行ファイルではありません
となり、依存している動的リンクは存在しないとなります。
では、soコマンドでビルドされたアプリケーションを見てみると
$ file ./capp ./capp: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=9af6ff5385aee405ad60ee247929c978db327c59, for GNU/Linux 3.7.0, not stripped
dynamically linked と出ていますね。動的リンクが存在するということです。
見てみると
$ ldd ./capp
linux-vdso.so.1 (0x0000007f95367000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000007f95140000)
/lib/ld-linux-aarch64.so.1 (0x0000007f95320000)
ちゃんと、普通のCアプリのように libc に依存しています。
また、ファイルサイズも全然違います。
$ ls -lh *app | awk '{print $5, $9}' 70K capp 1.8M goapp
実際にどのようなCソースになるのか見てみる
so translate で、変換されたCのソースを出力することが出来ます。
$ so translate -o c-src .
main.cとmain.hは以下のようになっていました。
#pragma once #include "so/builtin/builtin.h" // -- Types -- typedef so_String main_Language; typedef so_Slice main_Languages;
#include "main.h" // -- Implementation -- int main(void) { main_Languages langs = so_make_slice(main_Language, 0, 4); so_Slice progs = (so_Slice){(so_String[4]){so_str("Go"), so_str("C#"), so_str("Java"), so_str("Python")}, 4, 4}; for (so_int _ = 0; _ < so_len(progs); _++) { so_String p = so_at(so_String, progs, _); langs = so_append(main_Language, langs, (main_Language)p); } for (so_int _ = 0; _ < so_len(langs); _++) { main_Language l = so_at(main_Language, langs, _); so_println("%s", l.ptr); } }
面白いですね。ちゃんと型定義したものも反映されてて、スライス操作も反映されています。
参考情報
個人的Goのおすすめ書籍
個人的に読んでとても勉強になった書籍さんたちです。
過去の記事については、以下のページからご参照下さい。
サンプルコードは、以下の場所で公開しています。