2016-03-01 150 views
0

我明白如何鏈接和編譯時創建.c和.h文件並將其添加到我的項目。在C程序中包含頭文件時,鏈接器/編譯器如何找到相應的代碼?

但是當我將stdio.h頭文件添加到我的項目時會發生什麼?我知道鏈接器在一些標準目錄中搜索.h文件,然後粘貼它,但是隻包含函數原型和代碼。編譯器或鏈接器在哪裏找到這些函數的代碼,以及它如何被添加到我的源文件中?

我問的原因是因爲我正在爲微控制器編寫bootloader,我想仔細查看實際發送到編譯器的所有C代碼。我爲PIC32使用了非優化的XC32編譯器免費版本,因此我不相信它只包含我實際使用的內容。

+1

它在圖書館裏。標準的或明確鏈接的(看鏈接器設置) –

+0

可能的重複問題? https://stackoverflow.com/questions/3368121/how-does-acc-compiler-find-the-definitions-of-prototypes-in-header-files – user3303504

回答

4

您需要區分標題和庫。

標題聲明程序可用的工具。如果包含一個標頭,如<stdio.h>(注意:這是而不是-重複而不是! - 一個庫),您可以向編譯器提供使用標準I/O庫中設施所需的信息。通常,C頭文件不會定義實現這些設施的實際代碼。 C++具有「僅頭文件」庫(Boost的某些部分是「僅頭文件」庫的主要示例)。

圖書館提供設施的實施。 <stdio.h>標題聲明瞭一個函數fopen();有一個庫定義了該函數。

某些頭文件(實際上通常是很多頭文件)是有特權的,它們聲明的工具包含在C編譯器將程序鏈接到的標準庫中。你不需要做任何特殊的事情來獲得鏈接到你的程序中的功能。其他頭文件來自C編譯器先前不知道的庫,對於這些頭文件,您必須告訴它在哪裏可以找到該庫(例如使用-L /opt/sometool/lib作爲編譯器選項)和庫名(例如使用-lsometool/opt/sometool/lib/libsometool.so/opt/sometool/lib/libsometool.a鏈接)。請注意,SomeTool的標頭可能位於/opt/sometool/include,您需要添加選項-I/opt/sometool/include才能找到sometool.h標頭。

鏈接器不引用標題;編譯器本身不會引用庫。編譯器控制程序處理混合(它通常作爲單獨的程序運行編譯過程的多個階段 - 編譯器與鏈接器分開)。標題不包含有關庫安裝位置的信息。

4

鏈接器不關心頭文件。鏈接器甚至不知道它們存在,因爲它只能看到已編譯的對象文件,這就是爲什麼您明確需要指定與-l...選項鍊接的庫。鏈接器隱式鏈接到標準C庫(-lc)中,這是如何找到標準C函數的。在許多平臺上,這不適用於數學函數,如sinpow,這就是爲什麼當您要使用這些時需要鏈接-lm

要找到庫指定與-l...進行鏈接的問題:編譯器有一組標準目錄,它也可能在工作目錄中查找。您可以使用-L...編譯器選項將更多目錄添加到庫搜索路徑中。這告訴鏈接器也查看庫的指定目錄。

+0

一些編譯器允許在代碼中指定'#pragma'指令,它們指定要鏈接的庫的名稱。 (根據您的看法,這可能是有用的或意大利麪條!) –

+0

@ M.M是的。如果我記得正確,此功能在Plan 9中引入。他們圍繞這個想法構建了他們的整個編譯器工具鏈,你不應該爲編譯器提供'-L'選項,因爲你可以用這樣的指令消除它們。 – fuz

相關問題