GCCコンパイラC言語コンパイルプロセスの表示


コンパイルプロセス:
  • 前処理:プリプロセッサは、ソースファイル内のマクロを展開します.
  • コンパイル:コンパイラgccはcファイルをアセンブリファイルにコンパイルする.
  • アセンブリ:アセンブリasはアセンブリファイルをマシンコードにコンパイルする.
  • リンク:ターゲットファイルと外部シンボルを接続し、実行可能なバイナリファイルを得る.

  • 簡単な01_でtest.cこの過程を検討する.
    #include 
    #define NUMBER  (1 + 2)
    int main(void)
    {
    	int x = NUMBER;
    	printf("x:%d
    ",x); return 0; }
  • 前処理[csy@local compile_test]$ gcc -E -o 01_test.i 01_test.c

  • catで01_を表示するtest.iの内容は以下の通りである.
    int main(void)
    {
    	 int x = (1 + 2);
    	 printf("x:%d
    ",x); return 0; }

    ファイル内のマクロ定義NUMBERが現れる位置が(1+2)に置き換えられ,他の内容は変わらないことがわかる.2.アセンブリコードにコンパイルgcc-S-o 01_test.s 01_test.i cat testを通過する.sビュー01_test.sの内容はアセンブリコードである.
    [csy@local compile_test]$ cat 01_test.s 
    	.file	"01_test.c"
    	.section	.rodata
    .LC0:
    	.string	"x:%d
    " .text .globl main .type main, @function main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $32, %esp movl $3, 28(%esp) movl $.LC0, %eax movl 28(%esp), %edx movl %edx, 4(%esp) movl %eax, (%esp) call printf movl $0, %eax leave ret .size main, .-main .ident "GCC: (GNU) 4.4.6 20120305 (Red Hat 4.4.6-4)" .section .note.GNU-stack,"",@progbits
  • アセンブリを使用してマシンコード
  • にコンパイルする.
      [csy@local compile_test]$ gcc -c -o 01_test.o 01_test.s 
    

    生成されたマシンコード:
    ELF                      ?      4     (   U   ? $   ?    $ $?$ ?       x:%d
      GCC: (GNU) 4.4.6 20120305 (Red Hat 4.4.6-4)  .symtab .strtab .shstrtab .rel.text .data .bss .rodata .comment .note.GNU-stack                                                      4   -                     	           X     	            %             d                      +             d                      0             d                     8      0       j   -                 A              ?                                   ?  Q                                ?  ?  
                	              @                                                ?                                                                                           -                    01_test.c main printf       "   	  
    
  • リンクを使用するターゲットファイルを実行可能ファイルとしてすべてリンクする.oファイルをリンクして実行可能プログラムを生成する.[root@zhifachen test]# gcc -o 01_test.exe 01_test.o

  • 実行:
    [csy@local compile_test]$ ./01_test.exe 
    x:3
    

    コンパイルプロセスのまとめ
    前処理フェーズ:含むヘッダファイル(#include)とマクロ定義(#define、#ifdefなど)を処理するgcc -E-o 01_test.c 01_test.i//-oは、指定ファイルタイプ-Eに出力してソースファイル(.c)を(.i)コンパイルフェーズに変換することを示す:コード仕様性、構文エラーなどをチェックし、エラーがないことをチェックした後にコードをアセンブリ言語gcc -S -o 01_test.i 01_test.s/-Sに翻訳して前処理されたCイニシャルプログラムを(.i)変換(.s)アセンブリフェーズ:gcc -c -o 01_test.o 01_test.s//アセンブリコードをマシンコードリンクフェーズにコンパイル:ターゲットファイルを統合実行可能プログラムgcc -o 01_test.exe 01_test.o//マシンコード(.o)と一部のライブラリ関数を統合(.exe)
    gcc共通オプション
    クイックコンパイル例:プリコンパイル、プリコンパイルされたCオリジナルプログラム*を生成する.i
      gcc -E gcc_test.c -o gcc_test.i    
    

    コンパイル、アセンブリ言語の元のプログラム*を生成する.s
    gcc -S gcc_test.i -o gcc_test.s
    

    コンパイル、ターゲットファイル*を生成する.o
     gcc -c -o 01_test.o 01_test.s
    

    リンク、実行可能プログラムの生成
      gcc -o 01_test.exe 01_test.o
    

    方法2:コンパイル
     gcc -c gcc_test.c -o gcc_test.o
    

    リンク
    gcc -o gcc_test.exe gcc_test.o
    

    テストプログラムの実行
    ./gcc_test.exe
    

    方法3:コンパイルとリンク
     gcc -o gcc_test.exe gcc_test.c
    

    テストプログラムの実行
    [csy@local compile_gcc]# ./gcc_test.exe
    MAX=100
    max(3,4)=4
    

    コンパイル時にグローバルマクロ定義を渡す例
    コードでは、#defineを直接使用してマクロを定義し、コードで参照することができます.コンパイル時にマクロの内容を決定し、マクロが定義されているかどうかを決定したい場合があります.コンパイル時-Dオプションで指定できます.hello.cソースコード
    #include 
    int main(void)
    {
    #ifdef  CSY//       CSY,        CSY,        
    	printf("CSY is defined!
    "); #else printf("CSY is not defined!
    "); #endif printf("main exit
    "); return 0; }

    条件コンパイル、-Dで転送、CSYが転送されていなければelseを実行
    [csy@local compile_gcc]#  gcc -o hello hello.c -DCSY
    [csy@local compile_gcc]#  ./hello.exe 
    CSY is defined!
    main exit