GCC Compiler は、さまざまな Linux ディストリビューション用の非常に強力で人気のある C コンパイラです。この記事では、一般的な GCC コンパイラ オプションのいくつかについて説明します。
C コードの例
この記事では、次の基本的な C コード (main.c) を使用します:
#include<stdio.h> int main(void) { printf("\n The Geek Stuff\n"); return 0; }
GCC コンパイラ オプション
1.出力実行可能ファイル名を指定
最も基本的な形式では、gcc コンパイラは次のように使用できます:
gcc main.c
上記のコマンドは完全なコンパイル プロセスを実行し、a.out という名前の実行可能ファイルを出力します。
以下に示すように、オプション -o を使用して、実行可能ファイルの出力ファイル名を指定します。
gcc main.c -o main
上記のコマンドは、「main」という名前の出力ファイルを生成します。
GCC コンパイラの完全なコンパイル プロセスを理解するには、記事「C プログラムから Linux 実行可能ファイルへの移行 (4 段階)」をお読みください。
2. -Wall オプションで設定されたすべての警告を有効にする
このオプションは、GCC のすべての警告を有効にします。
#include<stdio.h> int main(void) { int i; printf("\n The Geek Stuff [%d]\n", i); return 0; }
上記のコードをコンパイルすると、初期化されていない変数 i に関連する次の警告が生成されます:
$ gcc -Wall main.c -o main main.c: In function ‘main’: main.c:6:10: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
3. -E オプションでプリプロセッサ出力のみを生成
前処理段階の出力は、-E オプションを使用して生成できます。
$ gcc -E main.c > main.i
gcc コマンドは stdout に出力を生成するため、出力を任意のファイルにリダイレクトできます。私たちの場合 (上記)、ファイル main.i には前処理された出力が含まれます。
4. -S オプションを使用してアセンブリ コードのみを生成します
アセンブリ レベルの出力は、-S オプションを使用して生成できます。
gcc -S main.c > main.s
この場合、ファイル main.s にはアセンブリ出力が含まれます。
5. -C オプションを使用してコンパイル済みコードのみを生成
(リンクなしで) コンパイル済みコードのみを生成するには、-C オプションを使用します。
gcc -C main.c
上記のコマンドは、マシン レベルのコードまたはコンパイルされたコードを含むファイル main.o を生成します。
6. -save-temps 関数を使用してすべての中間ファイルを生成します
オプション -save-temps は、上記の例 4、5、および 6 で行われたすべての作業を行うことができます。このオプションを使用すると、コンパイルのすべての段階での出力が現在のディレクトリに格納されます。このオプションは実行可能ファイルも生成することに注意してください。
例:
$ gcc -save-temps main.c $ ls a.out main.c main.i main.o main.s
したがって、すべての中間ファイルと最終的な実行可能ファイルが出力に生成されていることがわかります。
7. -l オプションを使用して共有ライブラリとリンク
オプション -l を使用して、共有ライブラリとリンクできます。例:
gcc -Wall main.c -o main -lCPPfile
上記の gcc コマンドは、コード main.c を共有ライブラリ libCPPfile.so にリンクして、最終的な実行可能ファイル「main」を生成します。
8. -fPIC オプションを使用して位置に依存しないコードを作成
共有ライブラリの作成中に、位置に依存しないコードを生成する必要があります。これにより、共有ライブラリが固定アドレスではなく任意のアドレスとしてロードされるようになります。このために -fPIC オプションが使用されます。
たとえば、次のコマンドは、ソース ファイル Cfile.c から共有ライブラリ libCfile.so を作成します。
$ gcc -c -Wall -Werror -fPIC Cfile.c $ gcc -shared -o libCfile.so Cfile.o
したがって、オプション -fPIC が共有ライブラリの作成に使用されたことがわかります。
9. -V オプションを使用して、実行されたすべてのコマンドを出力します
オプション -v を使用すると、ソース ファイルのコンパイル中に gcc が実行するすべての手順に関する詳細な情報を提供できます。
例:
$ gcc -Wall -v main.c -o main Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/4.6/lto-wrapper Target: i686-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu Thread model: posix gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ... ... ...
したがって、詳細な情報が出力に生成されていることがわかります。
10. -ansi オプションを使用して ISO C89 プログラムのサポートを有効にします
-ansi オプションにより、ISO C89 スタイルのサポートが有効になります。
次のコードを検討してください:
#include<stdio.h> int main(void) { // Print the string printf("\n The Geek Stuff\n"); return 0; }
上記のコードを -ansi オプションでコンパイルすると、ISO C89 スタイルでは C++ コメントが許可されないため、gcc はエラーを生成します。
出力は次のとおりです:
$ gcc -Wall -ansi main.c -o main main.c: In function ‘main’: main.c:5:3: error: expected expression before ‘/’ token
したがって、gcc がコメント スタイルに関連するエラーをスローしたことがわかります。
11. -funsigned-char オプションを使用して、char を unsigned char として解釈します
このオプションにより、char 型は unsigned 型として扱われます。
以下に例を示します:
#include<stdio.h> int main(void) { char c = -10; // Print the string printf("\n The Geek Stuff [%d]\n", c); return 0; }
上記のコードを funsigned-char オプションでコンパイルすると、出力は次のようになります:
$ gcc -Wall -funsigned-char main.c -o main $ ./main The Geek Stuff [246]
したがって、char が実際に unsigned として扱われたことがわかります。
12. -fsigned-char オプションを使用して、char を signed char として解釈します
これは、上記の (12) で説明したことの反対です。このフラグを使用すると、char 変数は符号付きとして扱われます。
以下に例を示します:
$ gcc -Wall -fsigned-char main.c -o main $ ./main The Geek Stuff [-10]
出力は、char が署名済みとして扱われたことを確認します。
13. -D オプションを使用してコンパイル時マクロを使用する
コンパイラ オプション D を使用して、コンパイル時のマクロをコードで定義できます。
以下に例を示します:
#include<stdio.h> int main(void) { #ifdef MY_MACRO printf("\n Macro defined \n"); #endif char c = -10; // Print the string printf("\n The Geek Stuff [%d]\n", c); return 0; }
コンパイラ オプション -D を使用して、コマンド ラインからマクロ MY_MACRO を定義できます。
$ gcc -Wall -DMY_MACRO main.c -o main $ ./main Macro defined The Geek Stuff [-10]
出力内のマクロに関連する出力は、マクロが定義されたことを確認します。
14. -Werror オプションで警告をエラーに変換
このオプションにより、gcc が報告する警告はすべてエラーに変換されます。
以下に例を示します:
#include<stdio.h> int main(void) { char c; // Print the string printf("\n The Geek Stuff [%d]\n", c); return 0; }
上記のコードをコンパイルすると、未定義の変数 c に関連する警告が生成され、これは -Werror オプションを使用してエラーに変換されます。
$ gcc -Wall -Werror main.c -o main main.c: In function ‘main’: main.c:7:10: error: ‘c’ is used uninitialized in this function [-Werror=uninitialized] cc1: all warnings being treated as errors
15. @ オプションを使用してファイルを介して gcc オプションを提供します
gcc へのオプションは、ファイルを介して提供することもできます。これは、@ オプションの後にオプションを含むファイル名を指定することで実行できます。複数のオプションは空白で区切られています。
以下に例を示します:
$ cat opt_file -Wall -omain
opt_file にはオプションが含まれています。
オプション @ とともに opt_file を指定して、コードをコンパイルします。
$ gcc main.c @opt_file main.c: In function ‘main’: main.c:6:11: warning: ‘i’ is used uninitialized in this function [-Wuninitialized] $ ls main main
出力は、オプションを取得するためにファイル opt_file が解析され、それに応じてコンパイルが行われたことを確認します。