GCC -c選項:只編譯不連結,僅生成目標檔案

2020-07-16 10:05:30
-c選項表示編譯、組合指定的原始檔(也就是編譯原始檔),但是不進行連結。使用-c選項可以將每一個原始檔編譯成對應的目標檔案。

目標檔案是一種中間檔案或者臨時檔案,如果不設定該選項,gcc 一般不會保留目標檔案,可執行檔案生成完成後就自動刪除了。

下面範例演示了 gcc -c 選項的用法。
$gcc -c test1.c test2.c test3.c
$ls -l *.o
-rwxr--r--  1  root  23  Feb  7  02:57  test1.o
-rwxr--r--  1  root  17  Feb  7  02:57  test2.o
-rwxr--r--  1  root  20  Feb  7  02:57  test3.o

如果不使用-c選項,則僅僅生成一個可執行檔案,沒有目標檔案。

注意,使用-c選項表示只編譯原始檔,而不進行連結,因此,對於連結中的錯誤是無法發現的。

下面例子演示了 gcc 編譯器在使用-c選項的時候不會發現連結錯誤。

1) 編寫如下的兩個原始檔。

在 func.c 中定義了 func_a() 函數:
#include <stdio.h>
void func_a(){
    printf("FUNC_An");
}

在 main.c 中呼叫了 func_a() 和 func_b() 函數:
#include <stdio.h>
int main(void)
{
    func_a();
    func_b();
    return 0;
}

func_b() 函數並沒有定義,所以在連結時會產生錯誤(編譯時不會產生錯誤)。

2) 使用-c選項編譯兩個原始檔,如下所示:

$gcc -c func.c main.c

編譯器沒有輸出任何錯誤資訊。

3) 不使用-c選項編譯兩個原始檔:

$gcc func.c main.c

會看到如下的報錯資訊:

/tmp/ccLlOhvh.o:在函數‘main’中:
main.c:(.text+0x14):對‘func_b’未定義的參照
collect2: 錯誤:ld 返回 1

由於沒有找到 func_b() 函數的定義,所以發生了連結錯誤。