以下の内容はhttps://devlights.hatenablog.com/entry/2026/03/12/073000より取得しました。


Goメモ-665 (nalgeon/solod)(GoのコードをCへ変換)

関連記事

GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ

概要

以下、自分用のメモです。興味を惹かれたので忘れないうちにメモメモ。。。

Go 1.26 interactive tour などで有名な antonz さんが新しいリポジトリを公開していました。

github.com

上記リポジトリのREADMEに以下のように書かれています。以下引用。

Go in, C out. You write regular Go code and get readable C11 as output.

GoのコードからCのコードを出力してくれるとのこと。GoもCもやっている人には凄く興味が湧きますね。

まだ、公開されたばかりなので、これからのツールだと思いますが、少し触ってみました。

試してみる

インストール

nalgeon/solodso という実行ファイルを利用して変換やビルド、実行などが行えるみたいです。

なので、まずは 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);
    }
}

面白いですね。ちゃんと型定義したものも反映されてて、スライス操作も反映されています。

参考情報

github.com

個人的Goのおすすめ書籍

個人的に読んでとても勉強になった書籍さんたちです。


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。




以上の内容はhttps://devlights.hatenablog.com/entry/2026/03/12/073000より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14