Clangを使用してみる(hello worldからmicrobitまで)
はじめに
Clang https://clang.llvm.org/ を使っていろいろなものをビルドしてみます。
まだ、不明点は多いですがmicrobitV1.5のLED点滅まで出来たので書いてみました。
どなたかの参考になれば良いかなと思っています。
確認環境
Ubuntu
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.1 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.1 LTS"
VERSION_ID="20.04"
Clang
https://releases.llvm.org/download.html の
Pre-Built Binaries:
https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/clang+llvm-11.0.0-x86_64-linux-gnu-ubuntu-20.04.tar.xz
を使用。
これを展開して、展開されたbin
ディレクトリにパスを通しておきます。設定例は以下。
$ cat .bashrc
<省略>
export PATH="/home/USERNAME/clang/clang+llvm-11.0.0-x86_64-linux-gnu-ubuntu-20.04/bin:$PATH"
$ . .bashrc
$ clang --version
clang version 11.0.0 (https://github.com/llvm/llvm-project.git 0160ad802e899c2922bc9b29564080c22eb0908c)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/USERNAME/clang/clang+llvm-11.0.0-x86_64-linux-gnu-ubuntu-20.04/bin
Hello world
まずは、Hello worldをビルドしてみます。
#include <stdio.h>
int main(void) {
printf("Hello world\n");
return 0;
}
$ clang hello.c
$ ./a.out
Hello world
できました。
Lua
次に, Lua (https://www.lua.org/) をビルドしてみます
使用するバージョンは 5.4にしています。
src/Makefile
を見ると、以下のような記載があります
CC= gcc -std=gnu99
#<省略>
AR= ar rcu
ここを以下のように変更します。
CC= clang -std=gnu99
#<省略>
AR= llvm-ar rcu
makeをします。
lua-5.4.2$ make
<省略>
clang -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_3 -DLUA_USE_LINUX -c -o lapi.o lapi.c
clang -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_3 -DLUA_USE_LINUX -c lcode.c
clang -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_3 -DLUA_USE_LINUX -c -o lctype.o lctype.c
<省略>
clang -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_3 -DLUA_USE_LINUX -c -o linit.o linit.c
llvm-ar rcu liblua.a lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o lundump.o lvm.o lzio.o lauxlib.o lbaselib.o lcorolib.o ldblib.o liolib.o lmathlib.o loadlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o linit.o
ranlib liblua.a
clang -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_3 -DLUA_USE_LINUX -c -o lua.o lua.c
clang -std=gnu99 -o lua lua.o liblua.a -lm -Wl,-E -ldl
clang -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_3 -DLUA_USE_LINUX -c -o luac.o luac.c
clang -std=gnu99 -o luac luac.o liblua.a -lm -Wl,-E -ldl
<省略>
src
ディレクトリにLua
が作成されるので、実行してみます。
$ src/lua
Lua 5.4.2 Copyright (C) 1994-2020 Lua.org, PUC-Rio
> print("hello")
hello
>
動くようです。
microbit
次はクロスコンパイルをしてみます。
以下のコードをClangでビルドしてみます。
修正箇所
変更点すべてを以下におきました。
これで make
で出来る binファイルを microbitにダウンロードすると、LEDが点滅します。
オプション
ターゲットの指定
gccだと、-mcpu
をでターゲットを指定するようですが、
clangの場合は -target
オプションを指定するようです。
ドキュメントは以下。
Target Triple
The basic option is to define the target architecture.
For that, use -target <triple>. If you don’t specify the target,
CPU names won’t match (since Clang assumes the host triple), and
the compilation will go ahead, creating code for the host platform, which
will break later on when assembling or linking.
The triple has the general format <arch><sub>-<vendor>-<sys>-<abi>, where:
* arch = x86_64, i386, arm, thumb, mips, etc.
* sub = for ex. on ARM: v5, v6m, v7a, v7m, etc.
* vendor = pc, apple, nvidia, ibm, etc.
* sys = none, linux, win32, darwin, cuda, etc.
* abi = eabi, gnu, android, macho, elf, etc.
microbitV1.5の場合は以下のようになるのでしょうか。
-target armv6-none-none-eabi
Linker script
Makefileのみの修正だと以下のエラーが出ます。
$ make
clang -nostdlib -target armv6-none-none-eabi -c flash.s
clang -Wall -Werror -O2 -nostdlib -ffreestanding -target armv6-none-none-eabi -mthumb -c notmain.c -o notmain.o
clang -fno-exceptions -fno-unwind-tables -nostdlib -target armv6-none-none-eabi -o notmain.elf -T flash.ld flash.o notmain.o
ld.lld: error: no memory region specified for section '.ARM.exidx'
clang-11: error: ld.lld command failed with exit code 1 (use -v to see invocation)
make: *** [Makefile:26: notmain.bin] エラー 1
今回はただ動けばよかったので(細かいオプションについてはおいおい調べるとして)
.ARM.exidx
セクションは破棄するようにしました。
/DISCARD/ :
{
*(.ARM.exidx)
}
DISCARDについてのドキュメントは以下。
flash.s で出る warning
flash.s をアセンブルすると、以下のワーニングが出ます。
$ make
clang -nostdlib -target armv6-none-none-eabi -c flash.s
flash.s:3:1: warning: new target does not support arm mode, switching to thumb mode
.cpu cortex-m0
^
よくわからないのでコメントアウト (これから調べる)。
まとめ
とりあえず、クロスコンパイルまで出来たが、
まだまだ調べなきゃいけないところはたくさんありそう。
Discussion