next up previous contents
Next: make 命令和 makefile Up: 開發工具 - make 與 Previous: 開發工具 - make 與   Contents

編譯器與可執行檔

  • 為何編譯﹖
    1. Linux 系統上真正認識的可執行檔其實是二進位檔案 (binary file),例如 /usr/bin/passwd, /bin/touch。
    2. 寫一個 C/C++ 程式, 要有 C/C++ 的編譯器(例如:gcc/g++),將原始碼 (source code) 翻譯成機器可以執行的程式碼。
    3. Shell scripts 只是利用 shell (例如 bash) 程式的功能進行一些判斷式,及呼叫一些已經編譯好的 binary 檔案來執行。
    4. 以 file 命令查看檔案型態:
      #binary file 之可執行檔,顯示執行檔類別 ( ELF 32-bit LSB executable ),
      #同時說明是否使用動態函式庫( shared libs )
      ## ELF: Extensible Linking Format
      ## LSB: Linux Standard Base
       
      [root@test root]# file /bin/bash 
      /bin/bash: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
       for GNU/Linux 2.2.5, dynamically linked (uses shared libs), stripped 
      
      #%* shell script test01-hello.sh 檔案 *)
      [root@test root]# file test01-hello.sh 
      test01-hello.sh: Bourne-Again shell script text executable
      
  • 編譯步驟:
    1. 使用任何的文字編輯器產生 C/C++ 原始碼 (source code);
    2. 編譯器 gcc/g++ 將 C/C++ 的原始碼編譯成目的檔 (object file),目的檔為機器可了解的機器語言但還無法執行;
    3. 將目的檔和函式庫中的程式連結成可執行檔,函式庫存放一些 C/C++ 常用的 function,可執行檔為機器可執行的程式;
    4. 執行可執行檔;

      \begin{picture}(150,280)
\setlength{\unitlength}{1mm}
\put(35,40){\vector(-1,0)...
...ox{}(30,10){exection}}
\multiput(15,20)(0,15){5}{\vector(0,-1){5}}
\end{picture}

    5. 程式執行引用函式庫流程

      \begin{picture}(150,150)
\setlength{\unitlength}{1mm}
\put(0,35){\dashbox{}(30,...
...er(15,0)(23,3)(30,0)}
\multiput(15,20)(0,15){2}{\vector(0,-1){5}}
\end{picture}

  • 編譯器 gcc 的用法
    1. 以 vi 編輯程式檔 hello.c
      [dywang@dywOffice test]$ vi hello.c
      #include <stdio.h>
      main()
      {
              printf("Hello!\n");
      }
      
    2. 僅將原始碼編譯成為目標檔,並不製作連結等功能:
      [guest@test guest]# gcc -c hello.c 
      #%* 會自動的產生 hello.o 這個檔案,但是並不會產生 binary 執行檔。 *)
      
    3. 在編譯的時候,依據作業環境給予最佳化執行速度:
      [guest@test guest]# gcc -O hello.c -c 
      #%* 會自動的產生 hello.o 這個檔案,並且進行最佳化。 *)
      
    4. 在進行 binary file 製作時,將連結的函式庫與相關的路徑填入 :
      [guest@test guest]# gcc sin.c -lm -L/usr/lib -I/usr/include 
      #%* 這個指令較常下達在最終連結成 binary file 的時候, *)
      #%* -lm 指的是函式庫檔案 libm.so 或 libm.a; *)
      #%* -L 後面接函式庫的搜尋目錄路徑; *)
      #%* -I 後面接原始碼內的 include 檔案之所在目錄。 *)
      
    5. 將編譯的結果輸出成某個特定檔名 :
      [guest@test guest]# gcc -o hello hello.c 
      #%* -o 後接的是要輸出的 binary file 檔名 *)
      
    6. 在編譯的時候,輸出較多的訊息說明:
      [guest@test guest]# gcc -o hello hello.c -Wall 
      #%* 加入 -Wall ,程式的編譯時會顯示警告訊息。*)
      #%* -Wall 或 -O 等參數為旗標( FLAGS ),簡稱這些旗標為 CCFLAGS。*)
      
練習題
  1. Linux 系統上機器認識的可執行檔,格式為何?
    Sol. 二進位檔案 (binary file)
  2. 程式編譯目的為何?
    Sol. 將原始碼 (source code) 翻譯成機器可以執行的程式碼。
  3. 如何查詢檔案 /bin/touch 之型態?
    Sol. file /bin/touch
  4. 執行 file /bin/bash,出現 ELF 32-bit LSB executable 訊息,則 /bin/bash 檔案型態為何?
    Sol. 二進位可執行檔
  5. 執行 file /etc/init.d/xfs,出現 Bourne shell script text executable 訊息,則 /etc/init.d/xfs 檔案型態為何?
    Sol. Bourne shell script 文字型態的可執行檔
  6. 請簡述程式編譯執行步驟?
    Sol. 1.編輯原始碼;2.將原始碼編譯成目的檔;3.將目的檔和函式庫中的程式連結成可執行檔;4.執行。
  7. 如何僅將原始碼 hello.c 編譯成為目標檔,並不製作連結等功能?
    Sol. gcc -c hello.c
  8. 如何在編譯 hello.c 時,依據作業環境給予最佳化執行速度?
    Sol. gcc -O hello.c -c
  9. 如何在編譯 hello.c 成可執行檔時,連結函式庫檔案 libm.so 或 libm.a ?
    Sol. gcc hello.c -lm
  10. 如何在編譯 hello.c 成可執行檔時,指定函式庫的搜尋目錄為 /usr/lib?
    Sol. gcc hello.c -L/usr/lib
  11. 如何在編譯 hello.c 成可執行檔時,指定原始碼內的 include 檔案所在目錄為 /usr/include?
    Sol. gcc hello.c -I/usr/include
  12. 如何在編譯 hello.c 時,指定可執行檔名稱為 hello?
    Sol. gcc -o hello hello.c
  13. 如何在編譯 hello.c 時,指定可執行檔名稱為 hello,且於程式的編譯時會顯示警告訊息?
    Sol. gcc -o hello hello.c -Wall


next up previous contents
Next: make 命令和 makefile Up: 開發工具 - make 與 Previous: 開發工具 - make 與   Contents
2017-06-14