驚いたこと
Tripletの一覧に efi とかあるのですっかりそちらに気を取られていたのですが、まさか Windows Executable (or DLL) をネイティブビルドするのとほぼ同じ要領で EFI Application もビルドできるとは。
やったこと
といってもコンパイルオプションとリンクオプションだけですが。
コンパイルオプション
-Oz
とか -flto
とかの最適化や、-Wall
-Werror
-Wextra
-pedantic
あたりのオプションは好みに合わせてどうぞ。
必須なのはたぶん --target
に指定するTripletの OS-ABI1 の部分と -ffreestanding
と -nostdlib
あたりかと思います。
$ clang \
--target=<triplet> \
-Oz \
-Wall \
-Werror \
-Wextra \
-c <path-to-source-file> \
-ffreestanding \
-flto \
-fno-builtin \
-fno-stack-check \
-fno-stack-protector \
-fshort-wchar \
-isystem <path-to-efi-headers> \
-mno-red-zone \
-nostdlib \
-o <path-to-object-file> \
-pedantic
リンクオプション
意外だった2のが、-fuse-ld=lld
で lld
ではなく lld-link
を自動的に使ってくれること。
最重要ポイントは -Wl,/subsystem:efi_application
3 ですね。
clang \
--target=<triplet> \
-Wl,/dll \
-Wl,/entry:<name-of-entrypoint-function> \
-Wl,/nodefaultlib \
-Wl,/subsystem:efi_application \
-ffreestanding \
-flto \
-fuse-ld=lld \
-nostdlib
実演
試したTriplet
Architecture | Triplet |
---|---|
x64 | x86_64-pc-windows-msvc |
arm64 | aarch64-pc-windows-msvc |
最後に
今回使用したclangの --version
を載せておきます。
$ clang --version
Ubuntu clang version 14.0.0-++20220209123220+8344ab9c4f191~exp1~20220209123314.30
Target: x86_64-pc-linux-gnu
Thread model: posix