📘
C言語のソースコードをZigに変換する機能を試す(その1)
zigのツールにCのソースコードをZigに変換する機能(zig translate-c)があるので、それを試してみました。
予想外に苦労したので、その1の記事はhello.c をhello.zigに変換してビルドして動作確認まで。
まずはHello, world!
hello.c
#include <stdio.h>
int main()
{
printf("Hello, world!\n");
}
$ zig cc hello.c
$ ./a.out
Hello, world!
$ zig translate-c hello.c > hello.zig
hello.c:1:10: 'stdio.h' file not found
いろいろ試行錯誤してたどりついたものはこれ。
zig cc
を実行したときにopenしているファイルをstraceコマンドで調べて、それと同じになるように-I
オプションを明示的に指定した。
$ zig translate-c \
-I /usr/local/zig-linux-aarch64-0.9.1/lib/libc/include/aarch64-linux-gnu \
-I /usr/local/zig-linux-aarch64-0.9.1/lib/libc/include/generic-glibc/ \
hello.c > hello.zig
CからZigに変換できた。
$ wc hello.zig
1057 6531 63259 hello.zig
1000行を超えてる。インクルードヘッダにあるもの全部を変換しているので。
さっそくビルドしてみる。
$ zig build-exe hello.zig
/usr/local/zig-linux-aarch64-0.9.1/lib/std/start.zig:556:17: error: expected return type of main to be 'void', '!void', 'noreturn', 'u8', or '!u8'
@compileError(bad_main_ret);
^
hello.zig を手で修正。
hello.zig
...
pub export fn main() c_int {
_ = printf("Hello, world!\n");
return 0;
}
...
main()の型を以下のように変更。
pub export fn main() u8 {
_ = printf("Hello, world!\n");
return 0;
}
$ zig build-exe hello.zig
ld.lld: error: undefined symbol: printf
>>> referenced by hello.zig:157 (/autofs/usbssd1/koba/work/zig/hello/hello.zig:157)
>>> zig-cache/o/f5b23074efffa90c73ace48f9f903a31/hello.o:(main)
error: LLDReportedFailure
今度はリンクエラー。
$ zig build-exe -lc hello.zig
できた!
$ ls -lt
total 832
-rwxrwxr-x 1 koba koba 561448 7月 18 12:55 hello
-rw-rw-r-- 1 koba koba 29729 7月 18 12:54 hello.zig
-rw-rw-r-- 1 koba koba 29744 7月 18 12:47 hello.zig~
-rw-rw-r-- 1 koba koba 75 7月 18 12:47 hello.c
drwxr-xr-x 5 koba koba 4096 7月 18 12:45 zig-cache
-rw-rw-r-- 1 koba koba 204186 7月 18 12:27 st.log
-rwxrwxr-x 1 koba koba 3784 7月 18 12:18 a.out
$ ./hello
Hello, world!
動いた。
$ file ./hello
./hello: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 2.0.0, with debug_info, not stripped
$ ldd ./hello
linux-vdso.so.1 (0x0000ffff8cb50000)
libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000ffff8cad2000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffff8c95f000)
/lib/ld-linux-aarch64.so.1 (0x0000ffff8cb20000)
まとめ
zig translate-c
には明示的にインクルードファイルのディレクトリを指定する必要がある。
$ zig translate-c -I /usr/local/zig-linux-aarch64-0.9.1/lib/libc/include/aarch64-linux-gnu -I /usr/local/zig-linux-aarch64-0.9.1/lib/libc/include/generic-glibc/ hello.c > hello.zig
main()の戻り値の型はZigの仕様に従うように修正する
c_int -> u8
-lc
をつける
標準Cライブラリのリンクも明示的に $ zig build-exe -lc hello.zig
関連
Discussion