Google Fuchsiaについて調べてみた
本記事は 自作OS Advent Calendar
の14日目の記事となります(狙ったわけではないですが偶然にも昨年と同じ14日目の登場となりました)。
みなさま、ご無沙汰しております。
自作OSに復帰する
みたいなことを去年のAdvent Calendarに書いたものの、今年は昨年と同様かそれ以上に忙しくなかなかOS自作に取り組む時間を捻出できませんでした。。
まずは自作OSもくもく会に復帰したいなと思いつつ、今年のAdvent CalendarもOS自作と関係ないようで関係ありそうなトピックにしました。
今回のテーマは Google Fuchsia
です。今回は、この謎の多いGoogleの新OSについて色々と調べてみました。
余談ですが、GIZMODOの記事によれば、Fuchsia
は フューシャ
と読むみたいですが、Google翻訳でFuchsiaの記事を翻訳すると フクシア
と出ますね。
目次
Google Fuchsiaの概要
Google Fuchsiaとは
Google Fuchsia(以下 Fuchsia
と略して記載します)は2016年8月に何の前触れもなく突然現れました。
※当時の記事
登場から2年以上経過していますが、当時と状況はあまり変わっておらず、2016年から今に至るまで、公式に発表されているプロダクトではありません(私の方でも改めて調べてみましたが、Googleからの公式発表は結局見つからず)。公式の情報源はGoogleのFuchsiaリポジトリにあるドキュメント群と下記Githubリポジトリ(リポジトリ名にmirrorと入っているのでGoogleのFuchsiaリポジトリのミラーと思われます)しかない、未だ謎の多きプロジェクトです。
余談ですが、Fuchsiaのロゴって富士通のロゴの鏡写しみたいなデザインですね。
Google Fuchsiaの特徴
公式発表すらされていないFuchsiaですが、公式リポジトリのドキュメントや各種紹介記事やプレゼン資料を総合すると、下記のような特徴をもったOSです。
- マイクロカーネルである (Linuxはモノリシックカーネル)
- 全くの新規で開発されている (AndroidはLinuxカーネルの上に各種フレームワークを構築しているのに対して、Fuchsiaは新規開発のカーネルを使用している)
- 非POSIX互換のシステムコールインタフェース *1
- C++ベースで実装されている
ところで、Fuchsiaは私自身の感覚としてはOS開発というよりはモバイルアプリケーション開発の文脈で話が出ることが割と多い気がしています。とりわけAndroidからFuchsiaへ置き換えるといった噂は盛んに報じられています。下記の記事もそういった噂を報じた記事の1つです。
それは、ひとえにFuchsiaのGUIアプリケーション開発にFlutterというモバイルアプリ開発で最近話題のフレームワークを使えることが主な理由なのではないかと思います。
Google Fuchsiaのアーキテクチャ
The Fuchsia layer cake
公式ドキュメントによれば、Fuchsiaは下記4つのレイヤ(The Fuchsia layer cake)から構成されています。
- Zircon
- レイヤーの最下層に位置する、Fuchsiaのカーネル
- Garnet
- ネットワーク、メディア、グラフィックスサービスなどのシステムサービスが属するレイヤー
- Peridot
- Topaz
- レイヤーの最上層に位置する
- UIやシェルを提供する
Zirconカーネルについて
Zircon
はFuchsiaのカーネルです。昔は Magenta
と呼ばれていました。
Zirconはマイクロカーネルで、システムコールの他に、スレッド、ソケット、仮想メモリマネージャ、割り込みなどの標準的なカーネルの機能を提供します。 *4 *5 ただし、ファイルシステムはカーネルには含まれず、またユーザ空間で実行されます。ファイルシステムの扱いについてはLinuxなどはカーネル空間でファイルシステムを扱っており、この点はZirconの大きな特徴といえるのではないでしょうか。
Zircon Kernel Concepts によれば、カーネルの各種機能はカーネルオブジェクトとして実装されています(ドキュメントでもZircon is a object-based kernel.
と記載されているほどで、Zirconの大きな特徴です)。ユーザ空間のプログラムは、システムコールを介してこれらのカーネルオブジェクトにアクセスすることができます。
Zirconのシステムコールは libzircon.so
によって提供されます。libzircon.so は vDSO
と呼ばれています。また、Zirconのシステムコールは非POSIX互換です。 *6
ファイルシステム
Filesystem Architectureによれば、Fuchsiaのファイルシステムはユーザ空間内に存在します。これにより、Fuchsiaではカーネルの再コンパイル無しにファイルシステムを柔軟に変更することができます。
Fuchsiaでのファイルシステムにあたるものはファイルシステムサービスとなっており、クライアントアプリはこのファイルシステムサービスに処理の要求を出すことによってファイルの読み書きを実現します。
また、Fuchsiaのファイルシステムでは Namespace
と呼ばれるクライアントごとのファイルシステムを持ちます。クライアントは任意のルート(ディレクトリハンドル)を設定することになります。そのため、Linuxのようなグローバルのルートファイルシステムは持たず、クライアントごとにアクセス範囲を制限することができます。
別なNamespaceへアクセスしたい場合には、別なNamespaceの特定のディレクトリへのマッピングという形でアクセスことになります。 *7
Google Fuchsiaのビルドと実行
※ 本項の内容は公式リポジトリのgetting_started.md、および下記記事とほぼ同じ内容になります(一部元記事にないところで詰まった箇所があったので、そこだけは役に立つかもしれません)。
本当なら、ちょっとしたGUIアプリでも作ってみようかと思ったのですが、残念ながらそこまで到達できませんでした。。ただ、OSの実行まではできたので、macOSでFuchsiaをビルドして動かす方法について紹介します。
なお、ここでの解説内容は公式リポジトリにあるソースのビルド方法となります。公式リポジトリのビルド方法とGithubにあるミラーリポジトリのビルド方法は少し異なるのでご注意ください。
ビルドに必要なツールのインストール
※ Xcodeインストール済みの人は無視してください。
macOSの場合はコマンドラインツールをインストールしてください。下記コマンドでインストールすることができます。
xcode-select --install
プロジェクト一式のダウンロード
それでは、ソースコードとツール一式が含まれたプロジェクトをダウンロードしましょう。ただし、ソースコードのダウンロード方法が少し特殊です。下記コマンドを実行してダウンロードしてください。
curl -s "https://fuchsia.googlesource.com/scripts/+/master/bootstrap?format=TEXT" | base64 --decode | bash
fxのセットアップ
ビルドやFuchsiaの起動には fx
というツールを使います。fxが使えるようシェル周りを設定していきましょう。まず、ダウンロードしてできた fuchsia
というディレクトリのルートに .jiri_root
という名前のディレクトリがあるので、これを ~/
へコピーしましょう。
cd fuchsia cp -r .jiri_root ~/
コピーできたら、 .jiri_root/bin/
の中にfxがあるので、PATHを設定しましょう。
私は今年からfish shellを使っているのですが、fish shellの場合は ~/.config/fish/config.fish
に下記1行を追加してください。
set -x PATH $HOME/.jiri_root/bin $PATH
bashをお使いの方は .bashrcに下記を追加します。
export PATH="$HOME/.jiri_root/bin:$PATH"
zircon/prebuilt/prebuilt/downloadの内容をダウンロードする ※必要に応じて
ひょっとするとこの手順は環境によっては必要ないかもしれませんが、私の環境ではzirconのビルド時に zircon/prebuilt/download
が無いためにビルドエラーが発生しました。
私の環境の場合は zircon/scripts/download-prebuilt
を実行することでビルドに必要なバイナリをダウンロードすることができました。コマンドとしては下記のとおりに実行します。
./zircon/scripts/download-prebuilt
Fuchsiaのビルド
ビルドをはじめる前に、ターゲットのCPUアーキテクチャを設定します。
Fuchsiaが現在サポートしているCPUは x64
arm64
です。ここではターゲットを x64 として解説します。
ターゲットの設定は下記コマンドで行います。
fx set x64
なお、上記コマンドだとデバッグビルドになります。リリースビルドにしたい方は下記コマンドを実行してください。
fx set x64 --release
ここまでできたら、あとは実際にビルドを実行するだけです。下記コマンドでビルドを開始しましょう。
fx full-build
ビルドに使うマシンによりますが、結構な時間がかかりますので気長に待ちましょう。
Fuchsiaの起動
ダウンロードしたプロジェクト一式の中にQEMUが既に含まれており、下記コマンド1つでビルドしたFuchsiaを実行できてしまいます(とてつもなく楽です)。
fx run
なお、GUIを有効にした状態で起動する際には -g
オプションを付加して起動します。
fx run -g
ただし、起動すればわかるとおり、カッコいいUIが出てくるわけではなく、下記のようにコマンドラインしか表示されません。
実は、FuchsiaのGUIは Vulkan というグラフィックスAPIのサポートが必須なのですが、残念ながらQEMUの方がVulkan未サポートなので、カッコいいUIにはお目にかかれなさそうです。。
余談ですが、Pixelbookで起動した猛者がいて、その際の画面の様子を見たい方は下記動画を見てみると、実際のGUIのイメージがつかめると思います。
dmコマンド
Fuchsiaのシェルでは ls
や pwd
などのLinuxなどで使えるコマンドも普通に使えます。
ただ、Fuchsiaのシャットダウンや各種デバッグ、デバイス情報を確認したい場合は dm
コマンドを使います。
$ dm help dump - dump device tree poweroff - power off the system shutdown - power off the system suspend - suspend the system to RAM reboot - reboot the system reboot-bootloader - reboot the system into bootloader reboot-recovery - reboot the system into recovery kerneldebug - send a command to the kernel ktraceoff - stop kernel tracing ktraceon - start kernel tracing devprops - dump published devices and their binding properties drivers - list discovered drivers and their properties
Fuchsiaをシャットダウンしたい場合は shutdown
または poweroff
オプションを使います。
dm shutdown
また、 dump
オプションを使うと、デバイストレースを確認することができます。Fuchsiaの構成が垣間見えるようでおもしろかったので、付録2として実行結果を掲載しておきます。
まとめ
公式発表されていないために情報源が少なく、調査に苦労しましたが、自作OSを嗜む者として、Fuchsiaは面白そうな題材だなという感想を改めて持ちました。
また、LinuxやUNIX系の多くのOSはC言語で実装されたモノリシックカーネルであるのに対し、FuchsiaはC++で実装されたマイクロカーネルであることも、コードが読めるOSの実装例として、とても貴重だと思います。
各種ドキュメントやソースコードの解読が進んで、多くの知見が自作OS界隈にもたらされると良いなと思いつつ、私も時間を見つけて解読を進めたいなと思いました。
付録1:Fuchsiaの情報源
- Googleのリポジトリ
- 公式リポジトリです。
- Githubリポジトリ
- 公式リポジトリのミラーです。コードやドキュメントの検索はこちらの方が良いかもしれません。
- Fuchsia Friday
- 9to5GoogleはFuchsiaの情報が最も多く掲載されている情報源だと思います。特にFuchsia Fridayの各記事はFuchsiaのアーキテクチャ解説記事としては現時点で最も詳しいと思います。
Fuchsia概略その1
プレゼン資料- 日本語で閲覧可能な数少ないFuchsiaに関する資料の1つです。続編を期待しています!
- Fuchsia: a new operating system
- ZirconがMagentaと呼ばれた頃の記事なので少し古いですが、Fuchsiaにおけるカーネルの役割がコンパクトにまとまっていると思います。
付録2:dm dumpの実行結果
※ コマンド実行結果の見方については Zircon Device Modelに記載されています。
$ dm dump [root] <root> pid=2058 [null] pid=2058 /boot/driver/builtin.so [zero] pid=2058 /boot/driver/builtin.so [misc] <misc> pid=2126 [console] pid=2126 /boot/driver/console.so [demo-fifo] pid=2126 /boot/driver/demo-fifo.so [dmctl] pid=2126 /boot/driver/dmctl.so [tapctl] pid=2126 /boot/driver/ethertap.so [hidctl] pid=2126 /boot/driver/hidctl.so [ktrace] pid=2126 /boot/driver/ktrace.so [ptmx] pid=2126 /boot/driver/pty.so [nand-ctl] pid=2126 /boot/driver/ram-nand.so [ramctl] pid=2126 /boot/driver/ramdisk.so [sysinfo] pid=2126 /boot/driver/sysinfo.so [sys] <sys> pid=1990 /boot/driver/bus-acpi.so [cpu-trace] pid=1990 /boot/driver/bus-acpi.so [acpi] pid=1990 /boot/driver/bus-acpi.so [acpi-pwrbtn] pid=1990 /boot/driver/bus-acpi.so [hid-device-000] pid=1990 /boot/driver/hid.so [rtc] pid=1990 /boot/driver/bus-acpi.so [rtc] pid=1990 /boot/driver/intel-rtc.so [i8042] pid=1990 /boot/driver/bus-acpi.so [i8042-keyboard] pid=1990 /boot/driver/pc-ps2.so [hid-device-001] pid=1990 /boot/driver/hid.so [i8042-mouse] pid=1990 /boot/driver/pc-ps2.so [hid-device-002] pid=1990 /boot/driver/hid.so [pci] pid=1990 /boot/driver/bus-acpi.so [00:00.0] pid=1990 /boot/driver/bus-pci.so [00:01.0] pid=1990 /boot/driver/bus-pci.so <00:01.0> pid=2531 /boot/driver/bus-pci.proxy.so [bochs_vbe] pid=2531 /boot/driver/simple.bochs.so [display-controller] pid=2531 /boot/driver/display.so [00:02.0] pid=1990 /boot/driver/bus-pci.so <00:02.0> pid=2581 /boot/driver/bus-pci.proxy.so [ahci] pid=2581 /boot/driver/ahci.so [sata0] pid=2581 /boot/driver/ahci.so [block] pid=2581 /boot/driver/block.so [fvm] pid=2581 /boot/driver/fvm.so [blobfs-p-1] pid=2581 /boot/driver/fvm.so [block] pid=2581 /boot/driver/block.so [minfs-p-2] pid=2581 /boot/driver/fvm.so [block] pid=2581 /boot/driver/block.so [00:1f.0] pid=1990 /boot/driver/bus-pci.so [00:1f.2] pid=1990 /boot/driver/bus-pci.so <00:1f.2> pid=2657 /boot/driver/bus-pci.proxy.so [ahci] pid=2657 /boot/driver/ahci.so [00:1f.3] pid=1990 /boot/driver/bus-pci.so [test] <test> pid=2023 [test] pid=2023 /boot/driver/test.so [wlantapctl] pid=2023 /system/driver/wlantap.so
LLVMについて調べたことまとめ
本記事は 自作OS Advent Calendar
の14日目の記事となります。
みなさま、ご無沙汰しております。
ここ最近、なかなか自作OS活動に時間を割くことができずにいましたが、リハビリを兼ねて、ClangやRustのバックエンドでもあり、自作OS界隈でも徐々に名前を聞くようになってきた(気がする)、 LLVM
について、改めて調べてみました。
目次
- The LLVM compiler Infrastructure project
- バックエンドとフロントエンド
- LLVM IRとbitcode
- 実際に動かしてみる
- まとめ
- 参考文献(と簡単な紹介)
- 余談:お知らせと来年に向けて
The LLVM compiler Infrastructure project
The LLVM compiler Infrastructure project
(以下LLVMプロジェクト) はコンパイラ技術群(toolchain)だと自身を紹介しています。 LLVM
という言葉自体は割と皆さんご存知かと思います。昔は Low Level Virtual Machine
の略語だった気がしますが、現在はそれだけではない広範囲な領域を扱っているといえます(むしろVirtual Machineという単語がもたらすイメージが逆に勘違いを誘いそうです)。
私は普段iOSアプリを書く仕事をしているのでとりわけ目にする機会が多いのかもしれませんが、XcodeでiOSアプリやmac OS用のアプリを作る場合にも、裏側でLLVMが動いていることをよく目にします(Xcode上でアプリのデバッグをする際に立ち上がるデバッガはLLDBです)。
また、私は昨年から今年にかけて、Rustを使って色んなことをやっていましたが、Rustのバックエンドで動いているのもLLVMです。
Primary sub projects
コンパイラと直接関係ないものもありますが、LLVMプロジェクトがプライマリと位置付けるプロジェクトには次のようなものがあります。
- LLVM Core libraries
- Clang
- フロントエンド(後述)を担当するCコンパイラ
- The LLDB project
- デバッガ。
- The libc++ and libc++ ABI projects
- The compiler-rt project
- The OpenMP subproject
- 並列計算用の基盤
- The polly project
- 最適化基盤。
- The libclc project
- OpenCLのライブラリ。
- The klee project
- LLVMのbitcodeをシンボリック実行するための環境。
- シンボリック実行については「シンボリック実行に入門しようとした | 一生あとで読んでろ」が詳しい。
- The SAFECode project
- Valgrindのようなメモリリークをチェックするツール。
- The lld project
- リンカ(gccにおけるldのようなもの)。
OS自作観点で言うと、LLVM Core librariesやClangはもちろんのこと、 compiler-rt
と lld
もおさえておくと良いと思います。個人的には自作OSにJITコンパイラ組み込んでみるのもおもしろうそうかなと考えています。
バックエンドとフロントエンド
LLVMも含めたコンパイラの処理全体のフローで見ると、我々が普段直に接するClangやRustなどのコンパイラは フロントエンド
と呼ばれます。
フロントエンドは主にC言語などの各言語から LLVM IR
という中間言語にコンパイルするところまでを担当しています。
フロントエンドに対して、 バックエンド
は、LLVM IR から各CPU向けのバイナリを生成するところまでを担います。
また、ClangにしてもRustにしても、フロントエンドを実行すると、各CPU向けのバイナリを出力するところまでやってくれます。これは、各フロントエンドが裏側でLLVMを呼び出したりしてくれるためです。コンパイルのプロセスを制御してくれるという意味で、 コンパイラドライバ
と呼ぶこともできます。
LLVM IRとbitcode
LLVMが扱う中間言語は LLVM IR
と呼ばれます。大抵は拡張子 .ll
として扱われます。ファイルの中身は、実はテキストファイルとなっており、これをバイナリに変換したものが bitcode
と呼ばれます。
LLVM IR はアーキテクチャ独立の中間言語で、ターゲットの仮想アーキテクチャは無限個のレジスタを持つ特徴があります。
LLVM IR の言語仕様は LLVM Language Reference Manual — LLVM 6 documentation 、bitcodeのファイルフォーマットは LLVM Bitcode File Format — LLVM 6 documentation で公開されています。
実際に動かしてみる
さて、ここからはClangとLLVMを使ってC言語のソースコードから各CPU向けのバイナリが生成される過程をみていきたいと思います。
※ 以下の実行結果については、全て macOS Sierra
上での実行結果となります。Linux上での実行結果については別途機会があれば紹介できればと思います。
LLVMのインストール
mac OSの場合はHomebrewを使えばすぐにインストールすることができます。
brew install --with-toolchain llvm
インストールができたら、PATHを設定する必要があります。
export PATH="/usr/local/opt/llvm/bin/:$PATH"
x86_64 (Mach-O) 向けバイナリが生成されるまで
以下のような簡単なC言語のコードをx86_64向けバイナリにコンパイルしてみます。
#include <stdio.h> int main() { printf("Hello, world!"); return 0; }
まずはClangを使いLLVM IRを出力してみます。コマンドは次のとおりです。
clang -emit-llvm -S -o hello.ll hello.c
出力されたLLVM IRのコードは次のとおりです。
; ModuleID = 'hello.c' source_filename = "hello.c" target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.12.0" @.str = private unnamed_addr constant [14 x i8] c"Hello, World\0A\00", align 1 ; Function Attrs: noinline nounwind optnone ssp uwtable define i32 @main() #0 { %1 = alloca i32, align 4 store i32 0, i32* %1, align 4 %2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i32 0, i32 0)) ret i32 0 } declare i32 @printf(i8*, ...) #1 attributes #0 = { noinline nounwind optnone ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } !llvm.module.flags = !{!0, !1} !llvm.ident = !{!2} !0 = !{i32 1, !"wchar_size", i32 4} !1 = !{i32 7, !"PIC Level", i32 2} !2 = !{!"clang version 5.0.0 (tags/RELEASE_500/final)"}
今回はLLVM IRの詳細な解説は行いませんが、 @main
と書かれている箇所がmain関数の処理になります。
生成したLLVM IRをさらに各CPU向けのオブジェクトファイルへ変換してみましょう。使用するツールは llc
というツールです。
llc -filetype=obj -o hello.o hello.ll
これでオブジェクトファイルを生成することができました。最後にこのオブジェクトファイルに標準ライブラリ等をリンクして実行形式ファイルを作成します。
使用するのは lld
・・・といきたいところですが、なぜか自分の環境ではlldを用いてリンクすることができませんでした。。
なので、ここではldを使ってリンクを行います。環境にもよりますが、以下のコマンドを実行することで実行形式ファイルを得ることができます。
ld -demangle -lto_library /path/to/llvm/5.0.0/lib/libLTO.dylib -dynamic -arch x86_64 -macosx_version_min 10.12.0 -o hello hello.o -lSystem /path/to/llvm/5.0.0/lib/clang/5.0.0/lib/darwin/libclang_rt.osx.a
※ 上記コマンドは clang -o hello hello.o
で得られる結果と同一の結果です。
もちろん、普通に実行できます。
$ ./hello Hello, World
以上がコンパイルの流れとなります。コンパイル設定によってはこれらのプロセスの間に最適化などの処理をはさむことになると思います。
今回は手作業で各ツールを実行していきましたが、これらのプロセスは通常コンパイラドライバの役割を持つClangがすべてやってくれます。
bitcodeの生成、実行
少し脱線しますが、LLVM IR のソースコードからbitcodeを生成してみましょう。
bitcodeはClangを使って生成することができます。
clang -c -emit-llvm hello.c
bitcodeは lli
というbitcode実行環境を使ってbitcodeのまま実行することができます。実行にはJITコンパイラ、またはインタプリタを選択することができます(lli - directly execute programs from LLVM bitcode — LLVM 6 documentation)。
$ lli hello.bc Hello, World
RustでのLLVM IR・bitcode生成方法 (ただし実行はできず)
Rustのコンパイラ(rustc)についても、LLVM IRやbitcodeを生成することができます。使用したRustのコードは次のとおりです。
fn main() { println!("Hello, World"); }
LLVM IR の生成は次のコマンドでできます。
rustc --emit=llvm-ir hello.rs
bitcodeの生成は次のコマンドです。
rustc --emit=llvm-bc hello.rs
ただし、LLVM IRもbitcodeも、生成自体はできるのですが、どうやらRustの標準ライブラリが別途必要になるらしく、ldでのリンクやlliで実行することはできませんでした。
ld -demangle -lto_library /usr/local/Cellar/llvm/5.0.0/lib/libLTO.dylib -dynamic -arch x86_64 -macosx_version_min 10.12.0 -o hello hello.o -lSystem /usr/local/Cellar/llvm/5.0.0/lib/clang/5.0.0/lib/darwin/libclang_rt.osx.a Undefined symbols for architecture x86_64: "std::io::stdio::_print::hfe7c7aedc93efc1e", referenced from: hello::main::h85c057a2a5f42fc8 in hello.o "std::rt::lang_start::h6e7c6ad302fab11a", referenced from: _main in hello.o ld: symbol(s) not found for architecture x86_64
lli hello.bc LLVM ERROR: Program used external function '__ZN3std2rt10lang_start17h6e7c6ad302fab11aE' which could not be resolved!
さらにマングリングもされちゃってるので、マングリングしないようにオプション指定してあげる必要がありそうですね。
残念ながらここで時間切れとなってしまったので、今度時間ができたらこの続きができればと思います。
まとめ
時間の都合上、概要を説明するだけになってしまいましたが、LLVMはGCCと並ぶ有力な選択肢として、今後OS自作界隈でLLVMの知見が深まっていくことを大いに期待しています。
私もRustやXcodeを使っている以上、LLVMと向き合わざるを得ないですが、今回調べた中で、LLVMは改めておもしろそうだと感じたので、今後もLLVMプロジェクトの動向には注目していきたいと思います。
参考文献(と簡単な紹介)
- The LLVM Compiler Infrastructure Project
- LLVMプロジェクトのオフィシャルサイト。当然のことながら、最も詳しい。
- きつねさんでもわかるLLVM - 達人出版会
- 出版されて日が経ちますが、日本語で読めるLLVMの文献としては未だに最も詳しいのではないかと。
- 大学院生のためのLLVM | インフラ・ミドルウェア | POSTD
- ネット上で読める日本語情報の中でも割と充実していると思います。
余談:お知らせと来年に向けて
本記事とはあまり関連しないですが、この場をお借りしてお知らせを。
昨年末から今年前半にかけ、同人誌の出版やQiitaの記事などのアウトプットを行いました。
おかげさまで記事に対するコメントや同人誌のサンプルコードに対するプルリクなどをいただきました(ありがとうございました)が、技術書典2終了後、色々と忙しい時期が続いた(今も続いている)ことにより、返信や対応が遅くなってしまい、大変申し訳ありません。
いただいたものについては徐々にフォローしていきたいと考えていますので、(既に解決済みかもしれませんが)今しばらくお待ちいただければと思います。
最後に、来年の抱負を少し。
同人誌作りは、今年のハイライトとなる出来事であったとともに、自分にとって忘れられない貴重な経験となりました。絶対にお約束できるわけではありませんが、来年もまた書く機会があれば書きたいと思っています。
そして、自作OSについては、技術書典2以降、すっかり滞ってしまっているので、落ち着いた段階でまた再開したいです。
というわけで、みなさま、良いお年を!
「Rust で GBA のプログラムを作ろう!」サポート情報(随時更新)
サークル「ひみつラボ」技術書典2向け新刊「Rust で GBA のプログラムを作ろう!」関連のサポート情報です。
サンプルコード
各章ごとにブランチを切っています。
第4章
https://github.com/kotetuco/Rust-BareMetal-GBA-Sample/tree/feature/call-rust-entry
第5章
https://github.com/kotetuco/Rust-BareMetal-GBA-Sample/tree/feature/cargo
第6章
https://github.com/kotetuco/Rust-BareMetal-GBA-Sample/tree/feature/fill_graphic
第7章
https://github.com/kotetuco/Rust-BareMetal-GBA-Sample/tree/feature/draw_string
正誤表
v1.0.0(技術書典出展版)
- (随時更新します)