簡體   English   中英

GCC鏈接庫用於編譯

[英]GCC linked library for compile

當信息已經以#include的形式存在於源文件中時,為什么我們必須告訴gcc鏈接哪個庫?

例如,如果我有一個使用線程的代碼,並具有:

#include <pthread.h>

我仍然需要在gcc中使用-pthread選項編譯它:

gcc -pthread test.c

如果我不提供-pthread選項,它將在查找線程函數定義時出錯。

我正在使用這個版本:

gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4

這可能是將初學者帶到C的最常見的事情之一。

在C中,有兩個不同的步驟來構建程序,編譯和鏈接。 出於您的問題的目的,這些步驟將您的代碼連接到兩種不同類型的文件,標頭和庫。

C代碼中的#include <pthread.h>指令由編譯器處理。 在將C文件轉換為目標文件之前,編譯器(實際上是預處理器)將pthread.h的內容直接粘貼到代碼中。

pthread.h是頭文件,而不是庫。 它包含了您可以在庫中找到的函數列表,它們采用的參數以及它們返回的內容。 標頭可以在沒有庫的情況下存在,反之亦然。 標題是一個文本文件,通常位於Unix派生系統的/usr/include中。 您可以像任何C文件一樣打開它來讀取內容。

命令行gcc -lpthread test.c同時進行編譯和鏈接。 在過去,你首先會做一些像cc test.c ,然后是ld -lpthread test.o 如您所見, -lpthread實際上是鏈接器的一個選項。

鏈接器對C代碼或頭文本等文本文件一無所知。 它僅適用於編譯的目標文件和現有的庫。 -l標志告訴它查找哪些庫來查找您正在使用的函數。

標題的名稱與庫的名稱無關。 這真的只是出乎意外。 大多數情況下,庫提供了許多標題。

特別是在C ++中,每個類通常有一個標頭,並且該庫通常提供來自同一名稱空間的類實現。 在C中,頭文件被組織起來,它們包含一些常見的函數子集 - math.h包含數學運算, stdio.h提供IO函數等。

它們是兩個不同的東西。 .h文件包含聲明,有時也包含內聯函數。 眾所周知,每個函數都應該有一個實現/定義才能工作。 這些實現是分開保存的。 -lpthread ,例如,它是以二進制形式保存functions declared in headersfunctions declared in headersfunctions declared in headers的實現的庫。

當您不想與他人共享商業代碼時,將實施分離是人們想要的

所以,

gcc -pthread test.c

告訴gcc查找libpthreadpthread.h中聲明的定義。 -pthread由鏈接器自動擴展為libpthread

有一些編譯器,你告訴它lib目錄的位置,它只掃描所有希望找到匹配的文件。 然后有一些編譯器是另一個極端,你必須告訴它要鏈接的所有東西。這里的關鍵是簡單地告訴編譯器尋找一些定義,甚至更簡單地將一些外部文件包含到這個文件中。 這不一定與庫或對象有任何連接,有許多包含與這些東西無關,這是一個不好的假設。 接下來鏈接器是一個不同的步驟,通常是與編譯器不同的程序,因此包含不僅與對象或庫沒有一對一的關系,鏈接器也不是編譯器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM