📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)
| (同じ利用者による、間の8版が非表示) | |||
| 155行目: | 155行目: | ||
*: <br> | *: <br> | ||
*: 大規模なソフトウェアシステムの性能向上を目指す場合は、特に有用なツールである。 | *: 大規模なソフトウェアシステムの性能向上を目指す場合は、特に有用なツールである。 | ||
<br><br> | |||
== LLVMツールチェーン と GNUツールチェーンの比較 == | |||
<center> | |||
{| class="wikitable" | |||
! 項目 !! LLVM !! GNU | |||
|- | |||
! コンパイラ<br>フロントエンド | |||
| Clang (C言語)<br>Clang++ (C++言語) | |||
| gcc (C言語)<br>g++ (C++言語) | |||
|- | |||
! コンパイラ<br>バックエンド | |||
| LLVM<br>(中間表現処理・最適化・コード生成) | |||
| GCCバックエンド<br>(GCC内部に組み込まれている) | |||
|- | |||
! アセンブラ | |||
| llvm-as | |||
| as (GNU Assembler) | |||
|- | |||
! リンカ | |||
| lld (LLVM Linker) | |||
| ld (GNU Linker) | |||
|- | |||
! その他ツール | |||
| llvm-objdump, llvm-ar, llvm-nm など | |||
| objdump, ar, nm など<br>(binutilsに含まれる) | |||
|- | |||
! 設計思想 | |||
| モジュール化・ライブラリ指向<br>再利用可能 | |||
| 統合的・密結合 | |||
|- | |||
! 他言語での利用 | |||
| Rust, Swift, Julia など<br>多数の言語で採用 | |||
| 主にC/C++/Fortran系 | |||
|} | |||
</center> | |||
<br> | |||
<center> | |||
{| class="wikitable" style="width:70%; text-align:center;" | |||
|+ コンパイルからリンクまでの流れ | |||
! style="width:15%; background-color:#e8e8e8;"| ステップ | |||
! style="width:42.5%; background-color:#dae8fc;"| LLVMツールチェーン | |||
! style="width:42.5%; background-color:#f8cecc;"| GNUツールチェーン | |||
|- | |||
! style="background-color:#fff2cc;"| 入力 | |||
| colspan="2" style="background-color:#fff2cc; text-align:center;"| ソースコード (.c, .cpp) | |||
|- | |||
! style="background-color:#e3f2fd;"| ① 解析 | |||
| style="background-color:#e3f2fd;"| Clang / Clang++<br><small>字句・構文・意味解析</small> | |||
| style="background-color:#ffebee;"| gcc / g++<br><small>字句・構文・意味解析</small> | |||
|- | |||
! style="background-color:#f3e5f5;"| ② 中間表現 | |||
| style="background-color:#e3f2fd;"| LLVM IR<br><small>中間表現形式</small> | |||
| style="background-color:#ffebee;"| gcc内部形式<br><small>RTL/GIMPLE</small> | |||
|- | |||
! style="background-color:#fff3e0;"| ③ 最適化 | |||
| style="background-color:#e3f2fd;"| LLVM Optimizer<br><small>各種最適化パス</small> | |||
| style="background-color:#ffebee;"| gcc最適化<br><small>内部で最適化処理</small> | |||
|- | |||
! style="background-color:#e0f2f1;"| ④ コード生成 | |||
| style="background-color:#e3f2fd;"| LLVM Backend<br><small>機械語生成</small> | |||
| style="background-color:#ffebee;"| gcc Backend<br><small>機械語生成</small> | |||
|- | |||
! style="background-color:#fce4ec;"| ⑤ アセンブル | |||
| style="background-color:#e3f2fd;"| llvm-as<br><small>LLVM Assembler</small> | |||
| style="background-color:#ffebee;"| as<br><small>GNU Assembler</small> | |||
|- | |||
! style="background-color:#f0f0f0;"| 中間生成物 | |||
| colspan="2" style="background-color:#f0f0f0; text-align:center;"| オブジェクトファイル (.o) | |||
|- | |||
! style="background-color:#e8f5e9;"| ⑥ リンク | |||
| style="background-color:#e3f2fd;"| lld<br><small>LLVM Linker</small> | |||
| style="background-color:#ffebee;"| ld<br><small>GNU Linker</small> | |||
|- | |||
! style="background-color:#c8e6c9;"| 出力 | |||
| colspan="2" style="background-color:#c8e6c9; text-align:center;"| 実行ファイル (例 : a.out, a.exe) | |||
|} | |||
</center> | |||
<br> | |||
* LLVM | |||
*: 各段階が独立したモジュールとして動作し、LLVM IRという共通の中間表現を使用 | |||
* GNU | |||
*: フロントエンドからバックエンドまでgccの中で統合的に処理される | |||
<br><br> | <br><br> | ||
| 269行目: | 352行目: | ||
<br> | <br> | ||
==== AArch64 ==== | ==== AArch64 ==== | ||
以下の例では、x64のホストPCおよびAArch64のターゲットPCにおけるLLVMツールチェーンをビルドおよびインストールしている。<br> | |||
<br> | |||
<u>※注意</u><br> | |||
<u>LLVM / Clangをビルドする段階では、AArch64のシステムルートをオプションとして追加する必要はない。</u><br> | |||
# ビルドディレクトリの作成 | |||
mkdir build && cd build | mkdir build && cd build | ||
cmake -G Ninja | # CMakeの設定 | ||
-DCMAKE_BUILD_TYPE=Release | cmake -G Ninja \ | ||
-DCMAKE_INSTALL_PREFIX=< | -DCMAKE_BUILD_TYPE=Release \ | ||
- | -DCMAKE_INSTALL_PREFIX=<LLVMツールチェーンのインストールディレクトリ> \ | ||
-DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld" \ | |||
-DLLVM_TARGETS_TO_BUILD="X86;AArch64" \ | |||
-DLLVM_DEFAULT_TARGET_TRIPLE=aarch64-linux-gnu \ | |||
-DLLVM_ENABLE_LLD=ON \ | |||
-DLLVM_ENABLE_LIBCXX=OFF \ | |||
-DLLVM_ENABLE_ASSERTIONS=OFF \ | |||
-DLLVM_TARGETS_TO_BUILD="AArch64" | -DLLVM_OPTIMIZED_TABLEGEN=ON \ | ||
-DLLVM_PARALLEL_LINK_JOBS=2 \ | |||
-DLLVM_DEFAULT_TARGET_TRIPLE=aarch64 | |||
- | |||
- | |||
- | |||
- | |||
- | |||
../llvm | ../llvm | ||
# ビルド | |||
ninja -j$(nproc) | |||
# インストール | |||
ninja install | |||
<br> | <br> | ||
==== | * -DCMAKE_BUILD_TYPE=Release | ||
*: 開発用途であればRelWithDebInfoでもよい。 | |||
*: <br> | |||
* -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld" | |||
*: 必要なプロジェクトを指定する。 | |||
*: lld (LLVMリンカー) はクロスコンパイルで必要となる。 | |||
*: <br> | |||
* -DLLVM_TARGETS_TO_BUILD="X86;AArch64" | |||
*: ホスト (x64) と ターゲット (AArch64) の両方を含める。 | |||
*: これにより、両方のアーキテクチャ用にコンパイルできる。 | |||
*: <br> | |||
* -DLLVM_DEFAULT_TARGET_TRIPLE=aarch64-linux-gnu | |||
*: デフォルトのターゲットをAArch64に設定する。 | |||
*: ただし、Qtのビルドシステムでは明示的に指定することが多いため、このオプションは任意である。 | |||
*: <br> | |||
* -DLLVM_ENABLE_LLD=ON | |||
*: LLDリンカーを有効化する。 | |||
*: これは、クロスリンク時に便利である。 | |||
*: <br> | |||
* -DLLVM_OPTIMIZED_TABLEGEN=ON | |||
*: ビルド時間を短縮するための最適化 | |||
*: <br> | |||
* -DLLVM_PARALLEL_LINK_JOBS=2 | |||
*: リンク処理の並列数を制限する。 | |||
*: メモリ不足を防ぐため、システムRAMが16[GB]未満の場合は1または2に設定することを推奨する。 | |||
<br> | |||
==== ARM EABIHF ==== | |||
===== ABI / HF ===== | |||
ABIとは、コンパイルされたバイナリコード同士がどのように通信し合うかを定めるプロトコルである。<br> | |||
ABIは関数を呼び出す際にどのレジスタを使うか、引数をどの順序でスタックに積むか、戻り値をどこに格納するか、構造体のメモリ配置はどうするか、といった細かい取り決めを規定している。<br> | |||
<br> | |||
異なるABIでコンパイルされたライブラリとプログラムは、例え同じCPUアーキテクチャであっても正しく連携できない。<br> | |||
<br> | |||
Hard Float ABIでは、浮動小数点演算の結果を浮動小数点専用のレジスタ (VFPレジスタ) を使用して関数間で受け渡す。<br> | |||
<br> | |||
EABIHFは32ビットARM用のABIである。<br> | |||
* Raspberry Pi OS 32ビットでは、ARMv8でもEABIHF (hard-float) が使用可能。 | |||
* Raspberry Pi OS 64ビットでは、AAPCS64 (ARM Architecture Procedure Call Standard 64-bit) という別のABIを使用。 | |||
<br> | |||
===== VFPレジスタ ===== | |||
Raspberry Pi 4以降でもVFPレジスタは存在するが、実装が進化している。<br> | |||
* ARMv7以前 (Raspberry Pi 2 / 3等) | |||
** VFP (Vector Floating Point) が独立したコプロセッサ | |||
** VFPv3 / VFPv4として実装 | |||
** NEONと一部統合 | |||
*: <br> | |||
* ARMv8-A (Raspberry Pi 4以降) | |||
** 浮動小数点とSIMDが完全に統合 | |||
** 32個の128ビットレジスタ (V0-V31) として実装 | |||
** これらは以下のようにアクセス可能である。 | |||
*** 64ビット浮動小数点 : D0-D31 | |||
*** 32ビット浮動小数点 : S0-S31 | |||
*** 128ビットSIMD:V0-V31 (NEON) | |||
<br> | |||
32 / 64ビットで、利用できる機能やABIが異なるが、いずれにおいても浮動小数点演算用のレジスタは存在し、ハードウェアアクセラレーションが利用できる。<br> | |||
<br> | |||
===== ビルド / インストール ===== | |||
mkdir build && cd build | mkdir build && cd build | ||
cmake -G Ninja | cmake -G Ninja \ | ||
-DCMAKE_BUILD_TYPE=Release \ | |||
-DCMAKE_INSTALL_PREFIX=<LLVMツールチェーンのインストールディレクトリ> \ | |||
-DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld" \ | |||
-DLLVM_TARGETS_TO_BUILD="X86;ARM;AArch64" \ | |||
-DLLVM_DEFAULT_TARGET_TRIPLE=arm-linux-gnueabihf \ | |||
-DLLVM_ENABLE_LLD=ON \ | |||
-DLLVM_ENABLE_LIBCXX=OFF \ | |||
-DLLVM_ENABLE_ASSERTIONS=OFF \ | |||
-DLLVM_OPTIMIZED_TABLEGEN=ON \ | |||
-DLLVM_PARALLEL_LINK_JOBS=2 \ | |||
../llvm | |||
ninja -j $(nproc) | ninja -j $(nproc) | ||
ninja install | ninja install | ||
<br> | |||
Hard Float ABI用のCMakeツールチェーンファイルの例を以下に示す。<br> | |||
<syntaxhighlight lang="cmake"> | |||
# ターゲットシステムの設定 | |||
set(CMAKE_SYSTEM_NAME Linux) | |||
set(CMAKE_SYSTEM_PROCESSOR arm) | |||
# システムルートのパス (Hard Float ABI用のシステムルート) | |||
set(CMAKE_SYSROOT <Hard Float ABI用のシステムルートのフルパス>) | |||
# LLVMツールチェーンのパス | |||
set(LLVM_PATH <LLVMツールチェーンのインストールディレクトリ>) | |||
# コンパイラの指定 | |||
set(CMAKE_C_COMPILER ${LLVM_PATH}/bin/clang) | |||
set(CMAKE_CXX_COMPILER ${LLVM_PATH}/bin/clang++) | |||
# ターゲットトリプルの設定 | |||
# Hard Float ABIを使用するため、末尾に"hf"を追加 | |||
set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabihf) | |||
set(CMAKE_CXX_COMPILER_TARGET arm-linux-gnueabihf) | |||
# 検索パスの設定 | |||
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) | |||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) | |||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) | |||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) | |||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) | |||
# コンパイラフラグの設定 | |||
# Hard Float ABIを明示的に指定し、適切なFPUも指定する | |||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a -mfpu=neon-vfpv4 -mfloat-abi=hard") | |||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a -mfpu=neon-vfpv4 -mfloat-abi=hard") | |||
# リンカーフラグ | |||
# ライブラリパスをHard Float ABI用のディレクトリに変更 | |||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath-link,${CMAKE_SYSROOT}/lib/arm-linux-gnueabihf") | |||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath-link,${CMAKE_SYSROOT}/usr/lib/arm-linux-gnueabihf") | |||
</syntaxhighlight> | |||
<br> | |||
==== ARM EABI ==== | |||
Soft Float ABIでは、浮動小数点の値も汎用レジスタを使って受け渡す。<br> | |||
<br> | |||
Soft Float ABIが必要になる場面は、古いARMプロセッサやFPU (浮動小数点演算ユニット) を持たない組み込みシステムである。<br> | |||
ARMv5 や ARMv6の一部のバリアント、コスト重視の産業用制御システムなどがこのカテゴリに入る。<br> | |||
これらのシステムでは、浮動小数点演算は全てソフトウェアでエミュレートされるため、VFPレジスタを使った受け渡しができない。<br> | |||
<br> | |||
ただし、FPUを持つプロセッサであっても、Soft Float ABIでコンパイルすることは可能である。<br> | |||
この場合、FPUは利用されず全ての浮動小数点演算がソフトウェアで処理される。<br> | |||
これは、既存のSoft Float ABI用のライブラリとの互換性を保ちたい場合等に用いられる。<br> | |||
<br> | |||
mkdir build && cd build | |||
cmake -G Ninja \ | |||
-DCMAKE_BUILD_TYPE=Release \ | |||
-DCMAKE_INSTALL_PREFIX=<LLVMツールチェーンのインストールディレクトリ> \ | |||
-DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld" \ | |||
-DLLVM_TARGETS_TO_BUILD="X86;ARM;AArch64" \ | |||
-DLLVM_DEFAULT_TARGET_TRIPLE=arm-linux-gnueabi \ | |||
-DLLVM_ENABLE_LLD=ON \ | |||
-DLLVM_ENABLE_LIBCXX=OFF \ | |||
-DLLVM_ENABLE_ASSERTIONS=OFF \ | |||
-DLLVM_OPTIMIZED_TABLEGEN=ON \ | |||
-DLLVM_PARALLEL_LINK_JOBS=2 \ | |||
../llvm | |||
ninja -j $(nproc) | |||
ninja install | |||
<br> | |||
Soft Float ABI用のCMakeツールチェーンファイルの例を以下に示す。<br> | |||
<syntaxhighlight lang="cmake"> | |||
# ターゲットシステムの設定 | |||
set(CMAKE_SYSTEM_NAME Linux) | |||
set(CMAKE_SYSTEM_PROCESSOR arm) | |||
# システムルートのパス (Soft Float ABI用のシステムルート) | |||
set(CMAKE_SYSROOT <Soft Float ABI用のシステムルートのフルパス>) | |||
# LLVMツールチェーンのパス | |||
set(LLVM_PATH <LLVMツールチェーンのインストールディレクトリ>) | |||
# コンパイラの指定 | |||
set(CMAKE_C_COMPILER ${LLVM_PATH}/bin/clang) | |||
set(CMAKE_CXX_COMPILER ${LLVM_PATH}/bin/clang++) | |||
# ターゲットトリプルの設定 | |||
set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabi) | |||
set(CMAKE_CXX_COMPILER_TARGET arm-linux-gnueabi) | |||
# 検索パスの設定 | |||
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) | |||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) | |||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) | |||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) | |||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) | |||
# コンパイラフラグの設定 | |||
# Soft Float ABIを明示的に指定する | |||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7-a -mfloat-abi=softfp") | |||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv7-a -mfloat-abi=softfp") | |||
# リンカーフラグ | |||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath-link,${CMAKE_SYSROOT}/lib/arm-linux-gnueabi") | |||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath-link,${CMAKE_SYSROOT}/usr/lib/arm-linux-gnueabi") | |||
</syntaxhighlight> | |||
<br><br> | <br><br> | ||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:RHEL]][[カテゴリ:SUSE]] | [[カテゴリ:RHEL]][[カテゴリ:SUSE]] | ||