[英]Why does the library linker flag sometimes have to go at the end using GCC?
我正在編寫一個使用librt的小型C程序。 如果將鏈接標志放在開頭而不是結尾,程序將無法編譯,我感到很驚訝:
此刻,我要編譯程序:
gcc -o prog prog.c -lrt -std=gnu99
如果執行以下操作,它將無法在librt中找到函數:
gcc -std=gnu99 -lrt -o prog prog.c
但是,這可以與其他庫一起使用。 我在嘗試使用簡單的Makefile時發現了問題。 進行實際編譯的prog.c而不先喜歡(使用-c標志),然后進行鏈接。
這是Makefile:
CC = gcc
CFLAGS = -std=gnu99
LIBS= -lrt
LDFLAGS := -lrt
prog: prog.o
$(CC) -o prog prog.c -lrt -std=gnu99
鍵入make時,我得到的輸出將是:
gcc -std=gnu99 -c -o prog.o prog.c
gcc -lrt prog.o -o prog
prog.o: In function `main':
prog.c:(.text+0xe6): undefined reference to `clock_gettime'
prog.c:(.text+0x2fc): undefined reference to `clock_gettime'
collect2: ld returned 1 exit status
make: *** [buff] Error 1
我現在已經制作了一個Makefile,它將鏈接放在gcc行的末尾,但是我感到困惑的是,如果鏈接標志位於開始位置,為什么它不起作用。
如果有人可以向我解釋,我將不勝感激。 謝謝。
鏈接器在處理每個模塊(是庫還是目標文件)時,會嘗試解析每個未定義的符號,同時可能將其添加到未定義的符號列表中。 當到達模塊列表的末尾時,它要么解決了所有未定義的符號並成功,要么報告了未定義的符號。
就您而言,當它處理librt時,它沒有未定義的符號。 處理過程導致clock_gettime是未定義的符號。 gcc不會返回並在librt中查找未定義的符號。
因此,您應該始終先獲取代碼,再獲取庫,再獲取平台提供的庫。
希望這可以幫助。
從ld
(GNU鏈接器)文檔( http://sourceware.org/binutils/docs/ld/Options.html#Options ):
鏈接器僅在命令行上指定的位置搜索一次存檔。 如果歸檔文件定義了在命令行上歸檔文件之前出現的某個對象中未定義的符號,則鏈接器將包含歸檔文件中的相應文件。 但是,稍后出現在命令行中的對象中未定義的符號將不會導致鏈接程序再次搜索檔案。
因此,如果您過早指定庫,則鏈接器將對其進行掃描,但找不到任何感興趣的內容。 然后,鏈接器移至由編譯器生成的目標文件,並找到需要解析的引用,但鏈接器已掃描了庫,因此不再費心查找該庫。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.