SOLID が使用しているオプション

SOLID が使用している、あるいは IDE で選択可能なオプションについて解説します。オプションは IDE 上で、プロジェクトまたはファイルのプロパティから確認・設定することができます。

Debug_clangRelease 等、構成ごとにコンパイラ(GCC または Clang)とオプションの組み合わせは異なり、個別に設定することになるので、ゼロからプロジェクトファイルを作成するのは大変です。

しかし基本的には、KMC や半導体ベンダーから既に設定済みのプロジェクトファイルが配布されるか、標準的な設定を SOLID アプリケーションウィザード( ファイル(F) ‣ 新規作成(N) ‣ プロジェクト(P) )が自動生成することになるので、ユーザーが設定項目の詳細を意識する必要はありません。必要に応じてカスタマイズしたい項目のみを設定する形になります。

プロジェクト、あるいはファイルを右クリックして、プロパティ(R) で開くプロパティページから、それぞれの項目ごとにオプションを設定することができます。

../_images/toolchain-compiler-option1.png

注釈

オプションはコンパイルドライバに渡されます。具体的なコマンド名はプロパティの「コマンド名」で確認できます。ライブラリプロジェクトにのみ存在する 構成プロパティ ‣ ライブラリアン プロパティには「コマンド名」がありませんが、これは例外的に ar というアーカイバに渡されるオプションとなります。 ar は、exeGCC は Binutils のオリジナル、exeClang は LLVM Tools の llvm-ar をリネームしたものとなります。( ar のオプションを変更する機会は無いと思われますし、変更しないでください。)

実際に指定される全てのオプションは「コマンドライン」から確認できます。他の項目で設定できないオプションを設定したい場合は、この項目の「追加のオプション」のテキストボックスに、任意のオプションを書くことができます。

../_images/toolchain-compiler-option2.png

ただし、exeGCC には環境変数を読み込んで自動的に必要なオプションを追加する機能があり、暗黙的に追加されたオプションは「コマンドライン」に表示されません。そのようなオプションについては KMC 独自のコンパイラ修正について(exeGCC) を参照してください。(該当するオプションの解説には関連する環境変数が記載されています。)

また、IDE がプロパティの内容に基づいてビルド時に追加する一部のオプションも「コマンドライン」に表示されません。(該当するオプションの解説には関連するプロパティが記載されています。)

注釈

オプションの分類は GCC のマニュアルを参考にしています。

https://gcc.gnu.org/onlinedocs/gcc/Option-Summary.html

昔の C コンパイラは、「プリプロセッサ」「コンパイラ」「アセンブラ」「リンカー」がそれぞれ独立したツールとして存在していたため、ツールごとにオプションを指定して挙動を制御していました。

しかし現代の C/C++ コンパイラのプリプロセッサは言語仕様の一部になっていて、GCC の場合はコンパイラ(cc1/cc1plus)とプリプロセッサが一体化しています。アセンブラ(GNU as)とリンカー(GNU ld)は Binutils という独立したツールを使用しています。そしてコンパイラと一緒に開発されているコンパイラドライバ(gcc/g++)がそれらを統合しています。各ツールをバラバラに制御しなくても、コンパイラドライバが自動的に適切なオプションを各ツールに渡して適切に制御します。

GCC のマニュアルは、このコンパイラドライバに対するオプションを解説しています。コンパイラドライバが対応していないオプションをそれぞれのツールに直接渡すために、 -Wp (プリプロセッサ)、 -Wa (アセンブラ)、 -Wl (リンカー)などのオプションが存在しています。

GCC よりも後進の Clang はさらに統合が進んでいて、プリプロセッサ、コンパイラ、アセンブラ、そしてコンパイラドライバも一体化して単一のツール( clang/clang++ )になっています。もともとコンパイラドライバはコンパイラとセットで開発されるものですし、アセンブラはコンパイラが生成したアセンブラソース内に必要な情報が全て記述されていて、基本的にオプションを設定する必要がないので、この統合は合理的です。

ツールがコンパイラドライバと一体化している場合「未対応のオプション」は存在せず、全機能をコンパイラドライバ経由で制御できるので、オプションを直接渡したい動機は「ツール単体のログを取る( -v など)」ぐらいしか残りません。こうなってくると実質的に「コンパイラドライバオプション」と「リンカーオプション」の 2 種類のみで良いことになります。実際、リンカーオプションを指定する -Wl 以外を使う機会はありません。

このような事情により、SOLID-IDE のプロパティは大きく「C/C++」プロパティと「リンカー」プロパティの 2 つに分かれています。

全体オプション

コンパイラドライバの全工程を制御するオプションです。

-c

プリプロセス、コンパイル、アセンブルのみを行います。(リンクは行いません。)

-o <FILE>

出力先を <FILE> に設定します。

-x <LANGUAGE>

入力(ファイル)を <LANGUAGE> 言語として解釈します。 SOLID がサポートする <LANGUAGE>c , c++ , c-header , c++-header , assembler , assembler-with-cpp のいずれかとなります。 assembler-with-cpp は、アセンブラソースを C プリプロセッサに通してからアセンブルするという意味になります。(大文字の拡張子 .S に相当。)

@<FILE>

<FILE> からコマンドライン(文字列)を読み込み、本オプションをその内容で置換します。Windows のコマンドラインの長さ制限を回避するために PARTNER-IDE 内部などで使用されています。

GCC 専用オプション

-specs=<FILE>

GCC の設定ファイルである specs ファイル <file> を指定します。exeGCC の Clang はリンカーとして GCC を呼び出すので、間接的に使用しています。(s007 以降の exeGCC で LLVM lld を使用する場合と、exeClang では使用していません。)exeGCC は GCCDIR と `` GCC_DEFAULT`` 環境変数を参照して specs ファイルを検索し、自動的に読み込んでいます。標準システム・スタートアップ・ファイルやコンパイラランタイムライブラリの指定も -B オプションではなく、specs ファイル内で行っています。

Clang 専用オプション

--target=<TRIPLE>

Clang は 1 つのコンパイラ(exe)で複数のアーキテクチャ、複数のターゲットをサポート可能なマルチターゲットコンパイラなので、本オプションでターゲット <TRIPLE> を指定します。(GCC は基本的に 1 つの exe につき 1 つのターゲットのみのサポートなのでオプションが存在しません。)

SOLID ツールチェーンがサポートする <TRIPLE> は以下になります。(SOLID ツールチェーンの Clang は 1 アーキテクチャ 1 ターゲットのみをサポートします。)

  • aarch64-kmc-elf (AArch64 アーキテクチャ)

  • arm-kmc-eabi (ARM アーキテクチャ)

  • riscv32-kmc-elf (RISCV アーキテクチャ)

  • riscv64-kmc-elf (RISCV アーキテクチャ)

Clang のビルド時にデフォルトの <TRIPLE> を設定しているので、本オプションは実際には不要ですが、exeClang ではわかりやすさのため使用しています。(exeGCC では使用していません。)

ディレクトリオプション

コンパイラドライバが必要とする、様々なディレクトリのパスを指定・追加します。オプションの指定順(左から右)にディレクトリを検索します。

-I <DIRECTORY>, --include-directory <DIRECTORY>, --include-directory=<DIRECTORY>

インクルード検索パスの先頭に <DIRECTORY> を追加します。

-idirafter <DIRECTORY>, --include-directory-after <DIRECTORY>, --include-directory-after=<DIRECTORY>

システムインクルード検索パスのリストの最後に <DIRECTORY> を追加します。システムインクルード検索パスの意義については -isystem を参照してください。exeGCC は GCCDIR 環境変数を参照して自動的に本オプションを指定しています。本オプションは exeGCC 付属の libstdc++ が使用している #include_next 指示文を正しく動作させるために使用しています。通常は使用しないでください。

-L <DIRECTORY>

ライブラリ検索パスの先頭に <DIRECTORY> を追加します。exeGCC は GCCDIRGCC_DEFAULT 環境変数を参照して自動的に本オプションを指定しています。

-nostdinc

C の標準インクルードパスを検索しないようにします。exeGCC は GCCDIR 環境変数を参照して自動的に -I-idirafter オプションを指定しているため、本オプションはあまり意味が無くなっています。

-nostdinc++ (C++ のみ)

C++ の標準インクルードパスを検索しないようにします。

--sysroot=<DIRECTORY>

ヘッダファイルやライブラリファイルを検索する際のルートディレクトリに <DIRECTORY> を指定します。exeGCC は GCCDIR 環境変数を参照して、自動的に本オプションを指定しています。

プリプロセッサオプション

ソースコードをコンパイルする前の、文字列の置換やファイルの挿入などの前処理(プリプロセス)を行う、プリプロセッサを制御するオプションです。

-D<MACRO>

#define <MACRO> 1 をソースファイルの先頭に記述した場合と同じ意味になります。

-D<MACRO>=<DEFINITION>, --define-macro <MACRO>=<VALUE>, --define-macro=<MACRO>=<VALUE>

#define <MACRO> <DEFINITION> をソースファイルの先頭に記述した場合と同じ意味になります。

-include <FILE>, --include <FILE>, --include=<FILE>

ソースファイルの先頭に #include "file" を追加した場合と基本的には同じ意味となります。ただし #include "file" の場合はソースファイルが存在するディレクトリが最優先となりますが、本オプションの場合はプリプロセッサのカレントワーキングディレクトリが最優先となります。

-U<MACRO>, --undefine-macro <MACRO>, --undefined-macro=<MACRO>

<MACRO>#undef します。

GCC 専用オプション

-finput-charset=<ENC>

ソースコードを <ENC> エンコーディングで読み込みます。デフォルトは utf-8 (UTF-8)です。Clang は本オプションをサポートせず、UTF-8 以外のソースコードは未サポートとなるため、SOLID プロジェクトのソースコードは基本的に UTF-8 になってます。ただし、一部のプロジェクトは exeGCC からソースコードを引きついでいる影響で GCC 専用になっており、cp932 (Shift_JIS)を指定しています。

-fexec-charset=<ENC>

コンパイラが出力する(アセンブリファイル中の)文字列データのエンコーディングを指定します。Clang は本オプションをサポートせず、常に UTF-8 で出力します。どうしても UTF-8 以外で出力する必要がある場合は、メッセージテキストを C ファイルに分割し、そのファイルのみ gcc で、本オプションを付けてコンパイルしてください。また、一部のプロジェクトは exeGCC からソースコードを引きついでいる影響で GCC 専用になっており、cp932 (Shift_JIS)を指定しています。

コンパイラオプション

コンパイラを制御するオプションです。

C 言語オプション

-fsigned-char (exeGCC のみ使用)

char 型を符号あり(signed)として扱います。AArch64/ARM ターゲットの GCC/Clang コンパイラのデフォルトは符号無し(unsigned)ですが、歴史的な理由により exeGCC は全てのアーキテクチャを signed char に統一してきたため、現在でも互換性維持のため本オプションが指定されています。exeGCC のライブラリは本オプションを指定してビルドされていますが、char 型の符号に依存しないように実装されているので、デフォルトが unsigned char でも signed char でも、あるいは指定無しでも正常動作します。

C++ 言語オプション

-fno-use-cxa-atexit (C++ のみ)

C++ プログラム終了時、デストラクタを呼ぶための __cxa_atexit() の呼び出し(とリンク)を禁止します。組み込み環境では Linux や Windows のようなリッチ OS 環境のように明確なプログラムの終了という概念が無いため、そもそもデストラクタの実行に常に頼れるとは限りません。そのような場合に不要なデストラクタコード等のリンクを防ぐために使用します。

注釈

SOLID ツールチェーンに付属の libc の exit() は常に __cxa_atexit() を呼び出すので、 exit() をユーザー定義して上書きする必要があります。

警告オプション

-w (非推奨)

全ての警告を抑制します。特別な理由が無い限り使用しないでください。

-Wall

一般的な警告を全て有効にします。

-Wextra

-Wall で有効にならない警告を追加し、より厳しく警告します。

-Werror

警告をエラーとして扱います。

-Wframe-larger-than=<N>

スタックサイズが <N> バイトを超えた場合に警告します。SOLID-IDE の 構成プロパティ ‣ C/C++ ‣ 全般 ‣ スタックサイズの警告 プロパティで使用しています。

デバッグオプション

-g, -gdwarf

DWARF 形式のデバッグ情報を生成します。Debug ビルド時に指定されます。exeGCC s007(GCC 10、Clang 12 以前)のデフォルトは -gdwarf-4 になります。Clang 18 の本来のデフォルトは -gdwarf-5 ですが、exeClang では独自のパッチを当ててデフォルトを -gdwarf-4 に変更しています。

注釈

基本的に SOLID 環境のデバッガは DWARF 4 をサポートし、最適化により消滅した変数をできる限り再現する等、高度なデバッグ体験を提供します。しかし本質的に、既に無い物をあるかのように見せかける高度な技術なので、コンパイラが(間違っているとまでは言えないものの)紛らわしい情報を出してしまう場合等があり、場合によってはかえってデバッグがしにくくなる場合もあります。また、非常に複雑なデバッグ情報が生成され、デバッガが完全には対応できない(最悪、デバッグ情報を読み込めない)場合もあるかもしれません。その場合は -gstrict-dwarf-gdwarf-3 、あるいは両方を指定してください。

-g0

デバッグ情報を生成しません。-g 系のオプションを上書きして打ち消すために存在します。

-gdwarf-2 (非推奨)(obsolete)

DWARF Version 2 規格のデバッグ情報を生成します。SOLID 環境のデバッガは DWARF 3 以降をサポートしているので指定する意味はありません。現在の GCC や Clang の高度な最適化を表現するには力不足な古い規格で、満足なデバッグができません。

-gdwarf-3

DWARF Version 3 規格のデバッグ情報を生成します。SOLID の開発当初はまだ一部のデバッグ情報にデバッガが未対応だったため本オプションを推奨していましたが、現在は -g-gdwarf-4 に相当)を指定して問題ありません。

-gdwarf-4

DWARF Version 4 規格のデバッグ情報を生成します。SOLID 環境のデフォルトです。SOLID ツールチェーンはどのバージョン、どのコンパイラを使用しても -g が本オプションと同じ意味になるように設定されています。

-gstrict-dwarf

-g オプションまたは -gdwarf-<VERSION><VERSION>34)オプションと必ずセットで指定してください。DWARF <VERSION> 規格に準拠したデバッグ情報を生成します。(GNU 拡張や、後継規格のデバッグ情報の生成を禁止します。)ただし Clang には、本オプションを指定しても DWARF 5 のデバッグ情報が一部出てしまうバグがあるので、SOLID 環境では独自のパッチを当てて修正しています。

注釈

GNU 拡張のデバッグ情報は標準化や(完全な)ドキュメント化がされていないため、GDB 7.0 以降(Clang も GDB を参考に実装していると思われます。)以外での完全なサポートは困難になります。(SOLID 環境のデバッガもできる限り努力はしておりますが、完全ではありません。)

-fdebug-prefix-map=<OLD>=<NEW>

デバッグ情報内のソースパス <OLD><NEW> に変換します。exeClang からツールチェーンのビルド時に本オプションを使用し、付属ライブラリのソースパスはルートディレクトリ( CLANG_ROOT 環境変数)からの相対パスに変換されています。(exeGCC までは、全く不要なビルド時の絶対パスがデバッグ情報に埋め込まれ、そのぶんデバッグ情報が肥大化していました。)

最適化オプション

-fdata-sections

変数ごとに .data.変数名 のような独自の ELF セクションを生成します。GNU ld と LLVM lld は リンク時ガベージコレクション機能 を持ち、セクション単位で使われていないコードやデータを削除できるので、細かくセクションを分けた方がより効果的に不要コードを削除できます。(-ffunction-sections も同様です。)

-ffunction-sections

関数ごとに .text.関数名 のような独自の ELF セクションを生成します。 -fdata-sections と同じ用途に使用します。

-fomit-frame-pointer

フレームポインタの退避/復旧コードの生成を省略し、追加のレジスタとして使用する、 -O2 と並んで昔からよく使われる有名な最適化オプションです。しかし現在の GCC/Clang は最適化オプション -O-O1 )以上で本オプションが有効になるので、本来は指定する必要ありません。付いていた方が安心するユーザーが多く、害も無いため慣例的に指定されています。

-fno-math-errno (exeClang では推奨、exeGCC では非推奨)

プログラムで errno を使用していないことを前提とした最適化を許可します。これにより例えば sqrt() を FPU の sqrt 命令に展開するような最適化が可能になります。デフォルトは -fmath-errno で省略しません。この最適化はいかなる最適化レベルでも有効になりません。プログラムが errno を使用していないことが確実な場合以外は指定しないでください。

注釈

数学関数の最適化や自動ベクトル化がますます重要になってきているため、将来的に C99 math_errhandling をサポートし、この値を常に MATH_ERREXCEPT に規定した上で数学関数が errno を変更しない設定でビルドして、本オプションを常に有効することも検討しています。

注釈

exeClang s008 から上記検討項目が採用されました。exeClang 付属の数学ライブラリ( math.h , complex.h の関数)は errno を使用しないため、常に本オプションを使用可能です。(言い換えると、数学ライブラリのエラーチェックに errno は使用できません。 fenv.h の関数を使用してください。)

-O0

Debug ビルド時に指定されます。一切最適化を行わないので、変数が消滅したりすることが無く、デバッグがやりやすくなります。 -Og という、デバッグを妨げない範囲で最適化を行うというオプションもありますが、必ず思い通りのデバッグができるわけではないので、上級者向けとなります。

-O2

Release ビルド時に指定されます。ほぼ全ての一般的な最適化が有効になります。

-Os

-O2 で有効になる最適化のうち、サイズを増加させない最適化のみを行います。

-O, -O1, -O3, -Og, -Oz

-O0-O2 の他にも段階的に -O1-O3 の最適化オプションが存在します。数字が大きいほど様々な最適化を行い、コンパイル時間が増加します。 -O-O1 は同じ意味です。 -O1 から -O3 は速度の最適化なのでバイナリサイズは増える場合があります。 -Og はデバッグを妨げない程度の最適化を行います。 -Oz-Os に似たサイズ優先の最適化を、より積極的に(速度を犠牲にしてでも)行います。具体的には命令数やサイクル数よりも機械語のバイト数の少なさを優先します。

プログラムインストルメントオプション

-finstrument-functions

関数の入り口と出口にインストルメント(計測)関数呼び出しを生成します。SOLID の様々な機能の実装に使用されています。呼び出されるインストルメント関数(ユーザー定義)のプロトタイプは以下のようになります。第一引数には現在の関数へのポインタ、第二引数には呼び出し元の関数へのポインタが渡されます。

void __cyg_profile_func_enter (void *this_fn, void *call_site);
void __cyg_profile_func_exit  (void *this_fn, void *call_site);

コード生成オプション

-fno-exceptions

C++ 例外処理機能を有効、無効にします。C++ ではデフォルト有効( -fexceptions )です。C でも指定は可能ですが、libgcc 等の特別なランタイムライブラリが使用することを想定している機能なので、サポート外となります。例外を無効にすることにより例外処理テーブルが生成されなくなり、コードサイズが減少するので、組み込みプログラムでは -fno-exceptions を指定することが多いです。(指定した場合、C++ の try , throw , catch キーワードを使用するとコンパイルエラーになります。)異なるオプションでコンパイルされたコードであってもリンク互換性はありますが、 -fno-exceptions でコンパイルされたコードは例外処理テーブルが生成されないため、例外発生時にデストラクタが呼ばれません。

-fno-short-enums (exeGCC のみ必須)

GCC のデフォルトは -fshort-enums で enum サイズは取りうる値の最大値に応じた可変長となります。一方 Clang は -fno-short-enums がデフォルトで enum は 4 バイトまたは 8 バイトの固定長となります。exeGCC は GCC でビルドしたライブラリを Clang も使用するので、GCC に常に -fno-short-enums を付けることで両者の ABI を揃えています。

AArch64、ARM、RISC-V 専用オプション

-mabi=<ABI>

コード生成時の <ABI> を指定します。RISC-V でのみ使用してます。AArch64 や ARM にもオプションは存在しますが、SOLID がサポートする ABI がそれぞれ 1 つだけなので使用していません。(また、ARM は他にも ABI を決定するオプションが複数存在します。)

-march=<ARCH>

コード生成の対象となるアーキテクチャ <ARCH> を指定します。

-mlittle-endian

リトルエンディアンのコードを生成します。SOLID はビッグエンディアンをサポートしないので必須ですが、コンパイラのデフォルトなので、オプションの指定は省略される場合があります。

AArch64、ARM 専用オプション

-mcpu=<CPU>

コード生成の対象となる <CPU> を指定します。 -march が一緒に指定された場合、アーキテクチャは -march の内容に上書きされます。

AArch64、RISC-V 専用オプション

-mcmodel=<CMODEL>

コードモデルを指定します。プログラムがグローバルシンボル(関数や変数)を参照する際、コンパイラはどのようなコードを生成すれば良いのかがコードモデルによって決定します。例えば AArch64 の large モデルの場合は、仮に PC 相対で 1 命令でアクセスできる範囲に配置されるシンボルであっても、常に定数プールから 64-bit フルアドレスをロードしてからアクセスします。若干のオーバーヘッドが発生しますが、どのようなメモリマップであってもリンクエラーは起きなくなります。そのためライブラリは最大の汎用性を持つ large でビルドされていますが、他のコードモデルともリンク互換性があります。コードモデルが許容するメモリアドレスの範囲が狭いほど効率的なコードが生成される可能性が高くなりますが、メモリマップの自由度が下がります。また、プログラムやメモリマップに問題が無くても、コードサイズが大きくなりすぎるとアドレス範囲に収まらず、リンクエラーが発生する可能性があります。

AArch64 では引数 <CMODEL>tiny , small , large のいずれかになります。ライブラリは large でコンパイルされています。

  • tiny

    全てのシンボルは 1MB アドレス範囲内に存在しなければなりません。

  • small

    全てのシンボルは 4GB アドレス範囲内に存在しなければなりません。

  • large

    常に 64-bit フルアドレスを使用するため、アドレス範囲は無制限です。ただし、 -fPIC と同時に指定できないため、DLL は tinysmall (常に PC 相対)モデルである必要があります。

RISC-V では引数 <CMODEL>medlowsmall )か medanymedium )のいずれかになります。ライブラリは medany でコンパイルされています。

  • medlow, small

    全てのシンボルは 0x80000000(2GiB)以下のアドレスに存在しなければなりません。もともと Clang は small 、GCC は medlow をコードモデル名に使っていて、後に Clang にも GCC に名前を合わせたエイリアスとして medlow が追加されました。

  • medany, medium

    全てのシンボルは +-2GiB アドレス範囲内に存在しなければなりません。もともと Clang は medium 、GCC は medany を使っていて、後に Clang にも GCC に名前を合わせたエイリアスとして medany が追加されました。exeClang は GCC から開発が始まり、途中から Clang 一本に変わったという経緯があるため、両対応でもある medany を使い続けています。

  • large

    アドレス範囲は無制限ですが、LLVM 18(exeClang s008)時点では未サポートで、GCC にのみ存在します。(LLVM 20 からサポート。)SOLID の RISC-V ターゲットは exeClang のみを使用し、GCC をサポートしないので、このコードモデルも未サポートとなります。

    注釈

    LLVM 20 以降を採用したツールチェーンでは、 large モデルでライブラリをビルドする予定です。

ARM 専用オプション

-marm

ARM コードを生成します。

-mthumb

Thumb コードを生成します。

-mthumb-interwork

ARM/Thumb 命令間での関数呼び出しをサポートするコードを生成します。本オプションを指定しない場合、ARMv5 以前のアーキテクチャでは ARM/Thumb コードを混在して使用することはできません。SOLID は ARMv5 以前のアーキテクチャはサポートしないので、本オプションはあっても無くても同じですが、exeGCC は設定の統一性のためオプションを使用しています。(Clang は ARMv5 以前をサポートしないので、オプション自体が存在しません。)

-mfpu=<FPU>

コード生成の対象となる浮動小数点数演算ハードウェア <FPU> を指定します。

-mfloat-abi=<ABI>

浮動小数点数演算の <ABI> を指定します。

soft

浮動小数点数演算に FPU を使用しない、ソフトウェアエミュレーション関数を呼び出すコードを生成します。

softfp

FPU を使用しますが、soft と ABI 互換性があり、リンク可能です。

hard

FPU に特化したコードを生成し、効率的ですが、soft/softfp オプションでコンパイルしたコードとリンクすることはできません。

-mno-unaligned-access

アドレス境界が合っていないメモリアクセスを行いません。つまり 16-bit、32-bit のデータは、必ず 16-bit、32-bit アドレス境界でアクセスするようなコード生成を行います。

注釈

AArch64 と RISC-V にも -mstrict-align という似たようなオプションが存在しますが、どちらもオプションを使用していません。AArch64 は memcpy などの文字列関数に ARM 社の Optimized Routines ライブラリを使用していて、そもそもこのライブラリがアンアラインドメモリアクセス前提なので、オプションを使用していません。RISC-V は明示的に Zicclsm 拡張を有効にしない限りアンアラインドメモリアクセスコードは生成されません。

-mfp16-format=<FORMAT>

<FORMAT>ieee , alternative のいずれか。 AArch64 と ARM の半精度(16-bit)浮動小数点数( __fp16 型)のフォーマットを指定します。AArch64 は ieee (IEEE 754-2008)形式のみサポートなのでオプションは存在しません。 alternative は ARM alternative 形式になります。SOLID では ieee を使用しています。

リンカーオプション

../_images/toolchain-compiler-option3.png

リンカーを制御するオプションです。本オプションは「C/C++」プロパティではなく、「リンカー」プロパティの各項目で設定します。設定方法等は「C/C++」プロパティと同様です。

-fuse-ld=<LINKER> (exeGCC Clang のみ指定可能)

リンカー <LINKER> を指定します。exeGCC の Clang で LLVM lld を使用する場合のみ -fuse-ld=lld を指定しています。(SOLID-IDE の 構成プロパティ ‣ リンカー ‣ 詳細設定 ‣ リンカーの指定 ‣ lldリンカーを使用する プロパティ。)exeClang の Clang は lld がデフォルトの設定でビルドされており、lld 以外のリンカは存在しないので指定しないでください。(常に「規定」。)

-l <LIBRARY>

lib<LIBRARY>.a ファイルをリンクします。ファイルは標準のライブラリパスと、-L オプションで追加されたパスの中から検索されます。

-nostartfiles

標準システム・スタートアップ・ファイルを使用しません。exeClang の場合はもともとスタートアップ・ファイルを使用しない設定でコンパイラがビルドされているため、以下のような警告が出て無視されます。

clang: warning: argument unused during compilation: '-nostartfiles' [-Wunused-command-line-argument]

-nodefaultlibs

標準ライブラリとコンパイラランタイムライブラリを使用しません。-l オプションで指定されたファイルと、exeGCC の場合は標準システム・スタートアップ・ファイルは使用されます。GCC/Clang は本オプションを指定した場合でも、 memcmp(), memset(), memcpy(), memmove() 関数を生成コード内で使用する場合があるので、これらの標準 C 関数の実装は必要です。また、本オプションを使用した場合、コンパイラが生成コード内で使用するランタイム関数もリンクされなくなるため、コンパイラランタイムライブラリの明示的な指定が必要になる場合があります。その場合、exeGCC は -lgcc -lcompiler_rt オプションの指定が必要です。exeClang の場合は -lclang_rt.builtins-<ARCH> 指定が必要です。 <ARCH>aarch64 , arm , riscv32 , riscv64 のいずれかになります。

-nostdlib

-nostartfiles-nodefaultlibs を両方指定した場合と同じ意味になります。

-T <script>

リンカスクリプトファイル <script> を指定します。

-Wl,<OPTION>

リンカーに <OPTION> オプションを渡します。 <OPTION> がカンマ(,)を含む場合、カンマで分割して複数のオプションとして渡します。

-Wl,-MAP=<FILE>

リンカーが ELF ファイルのリンクに成功した時、最終的なメモリマップ情報を <FILE> に出力します。マップファイルは組み込みプログラム開発において非常に重要な情報源となります。組み込みプログラムが期待通り動かない時、コード(関数。実行属性が必要)やデータ(変数。読み書き属性が必要)が不適切な位置に配置されてしまっていて、適切な権限が無いために例外などが発生しているケースが非常に多いのですが、マップファイルを見ることによりコードやデータ(関数や変数のシンボル)が配置されたアドレスを知ることができます。

-Wl,--gc-sections

-Wl オプションを使用し、リンカーに --gc-sections オプションを渡します。どこからも参照されていない関数や変数を削除(ガベージコレクション)してコードサイズを削減します。削除はセクション単位で行われるため、セクションを細かく分ける -ffunction-sections-fdata-sections を使用するとより効果的です。

-Wl,--start-group, -Wl,--end-group

-Wl オプションを使用し、リンカーに --start-group オプションと --end-group オプションを渡しています。この 2 つのオプションの間に -l オプションなどで指定されたライブラリはグループ化されます。リンカーは、通常は左から右に一回だけ未定義シンボルを検索しますが、グループ化されたライブラリ間で未定義シンボルが見つからなかった場合は、もう一度最初のライブラリ(一番左)から検索を開始します。

ELF ローダー

SOLID の ELF ローダー 利用時に使用されるオプションです。

コンパイラオプション

コード生成オプション

-fPIC

位置独立コード(Positiion Independent Code; PIC)を生成します。位置独立コードは、任意のアドレスに配置可能なコードのことで、SOLID では DLL を作成する際に使用します。

-fvisibility=<ARG>

<ARG>default , internal , hidden , protected のいずれか。

ELF のグローバルシンボルのデフォルトの可視属性を設定します。SOLID では DLL を作成する際に選択できます。非公開の関数全てに attribute で hidden を指定するのが煩雑な場合、逆に -fvisibility=hidden でコンパイルしてデフォルトを非公開にして、公開したい関数にのみ attribute で default を指定することができます。デフォルトは default (公開)です。

サニタイザ(Clang のみ)

SOLID-IDE の 構成プロパティ ‣ サニタイザ の利用時に使用されるオプションの解説は割愛します。

サニタイザはコンパイラのオプション指定だけでは実現できず、SOLID-IDE による設定サポート、SOLID-OS によるランタイムサポートが必要なので、基本的には IDE 上での使用を前提としています。

コードカバレッジ(Clang のみ)

SOLID の コードカバレッジ 利用時に使用されるオプションです。

Clang のコードカバレッジ機能とは、実行時にソースコード中の各ベーシックブロック単位ごとに、実行された回数を記録する(コードを生成する)ことです。以後、この記録された生データをコードカバレッジデータと呼びます。

コンパイラオプション

プログラムインストルメントオプション

-fprofile-instr-generate, -fprofile-instr-generate=<FILE>

コードカバレッジデータを取得してファイル <FILE> に出力するコードを生成します。 <FILE> を指定しない場合は default.profraw に出力されます。<FILE>LLVM_PROFILE_FILE 環境変数で指定されたファイル名で上書きされてしまうので、この環境変数は定義しないでください。(SOLID のコードカバレッジ機能が正常に動作しなくなります。)

-fcoverage-mapping

ソース行とコードカバレッジデータの対応関係(マッピング)情報を生成してオブジェクトファイルに埋め込みます。この情報は llvm-cov ツールで解析します。

プロファイルに基づく最適化(Clang のみ)

SOLID の プロファイルに基づく最適化(PGO) 利用時に使用されるオプションです。

コンパイラオプション

警告オプション

-Wno-profile-instr-unprofiled

PGO 有効時の warning: profile data may be out of date: of <N> function(s), <M> has/have mismatched data that will be ignored のような警告を無効化します。

-Wno-profile-instr-out-of-date

PGO 有効時の warning: no profile data available for file "foo.c" のような警告を有効化、無効化します。

プログラムインストルメントオプション

-fprofile-instr-use=<FILE>

<FILE> に取得したコードカバレッジデータに基づき PGO を行います。

リンク時最適化(Clang/lld のみ)

SOLID の リンク時最適化(LTO) 利用時に使用されるオプションです。

GCC と GNU ld の組み合わせでも LTO は可能ですが、SOLID ツールチェーンでは exeGCC/exeClang ともに Clang と lld の組み合わせのみをサポートしています。

注釈

LTO はコンパイラが生成した中間表現をリンカーがリンク時に最適化してコード生成とリンクを行います。GCC の中間表現を lld は読み込めませんし、Clang の中間表現を GNU ld は読み込めないので、これらの組み合わせで LTO を行うことはできません。

コンパイラオプション

最適化オプション

-flto, -flto=<LTO>

生成されたオブジェクトファイルが LTO の対象となります。(LTO の対象となるオブジェクトファイルは、対象外のオブジェクトファイルと互換性があり、リンク可能ですが、対象外のファイルは最適化されず、そのままリンクされるだけとなります。) LTO には fullthin の 2 種類が存在します。デフォルト(引数無しの -flto 指定時)は full です。full は素朴な LTO で、全ての LTO の対象となるオブジェクトファイルを 1 つにまとめて最適化を行うため、非常にリンク時のメモリ消費量とリンク時間が増大します。full は exeGCC でのみ使用可能です。thin は新方式の LTO で、メモリ消費量とリンク時間が大幅に改善されています。原理的には full の方が広範囲の最適化が可能ですが、thin でも十分な最適化が可能であり、full では非現実的な大規模プロジェクトに対しても LTO が可能というメリットがあります。exeClang は thin のみをサポートします。

-fno-lto

LTO を行いません。これが Clang のデフォルトなのでオプションを指定する必要はありませんが、LTO の対象にしたくないソースファイルに大して指定することができます。

-ffat-lto-objects (exeClang のみ)

LTO 時に fat LTO オブジェクト を生成します。GCC は fat LTO オブジェクトがデフォルトなので本オプションは存在しません。Clang は本オプション無しで -flto=thin を指定した場合、生成されるオブジェクトファイル( *.o )は LLVM の LTO 専用のバイナリファイル形式になるため、objdump などの ELF 用ツールは使用できません。本オプションを使用することにより、通常の ELF が生成されるようになり、ELF 用ツールが使用可能になります。LTO 時には ELF の lto.* セクションに格納された中間表現を元に、最適化された機械語を生成します。ELF 内部に機械語と中間表現を両方含むため、ファイルサイズが大きく(fat)なります。

リンカーオプション

--ffat-lto-objects (exeClang のみ)

exeClang で LTO を行う場合は必ずリンカーオプションに本オプションを指定してください。指定しない場合 lld は通常のリンク(最適化無し)を行います。

XRay(Clang/lld のみ)

XRay は LLVM/Clang が提供するインストルメント(計測)機能です。関数呼び出しのトレースなど様々な目的に使用できます。-finstrument-functions に似ていますが、__cyg_profile_func_enter のような関数呼び出しを直接生成するのではなく、代わりに十分な数の NOP 命令を生成(インストルメントポイント)する点が異なります。関数呼び出しを生成しないので、関数を準備しなくてもリンクエラーは発生せず、ランタイムライブラリ側で自由にインストルメントの内容や、機能のオン・オフを切り替えることができます。また、インストルメント機能を無効にした時の速度的オーバーヘッドはほぼゼロ(NOP 数個ぶんのみ)なので、リリースバイナリにも使用できます。

コンパイラはインストルメントポイントのアドレスを xray_instr_map という ELF の特別なセクションに生成し、ランタイムライブラリがこれを元に動的にパッチを当てることになります。

注釈

以下のオプションの他にも、attribute や設定ファイルで関数に対するインストルメントポイントの生成を制御できます。詳細は以下の URL を参照してください。

https://llvm.org/docs/XRay.html

コンパイラオプション

プログラムインストルメントオプション

-fxray-instrument

XRay を有効にします。

-fxray-instruction-threshold=<N>

<N> 命令以上の関数に対してインストルメントポイントを生成します。デフォルトは 200 です。

-fxray-always-instrument=<FILE>

XRay 設定ファイル <FILE> に記述された関数にインストルメントポイントを生成します。

-fxray-never-instrument=<FILE>

XRay 設定ファイル <FILE> に記述された関数にインストルメントポイントを生成しません。