每天一個 Linux 命令: ld 命令

1. 命令簡介

ld 命令是二進制工具集 GNU Binutils 的一員,是 GNU 鏈接器,用於將目標文件與庫鏈接爲可執行文件或庫文件。

2. 命令格式

ld [OPTIONS] OBJFILES

3. 選項說明

ld 命令支持衆多鏈接選項,但是大部分選項很少被使用,下面是 ld 命令接受的選項。

-b <input-format>
  指定目標代碼輸入文件的格式
-Bstatic
  只使用靜態庫
-Bdynamic
  只使用動態庫
-Bsymbolic
  把引用捆綁到共享庫中的全局符號
-c <MRI-commandfile>, --mri-script=<MRI-commandfile>
  爲與 MRI 鏈接器兼容,ld 接受由 MRI 命令語言編寫的腳本文件
--cref
  創建跨引用表
-d,-dc,-dp
  即使指定了可重定位的輸出文件(使用-r),也會爲公共符號分配空間。腳本命令“FORCE_COMMON_ALLOCATION”具有相同的效果
-defsym
  在輸出文件中創建指定的全局符號
-demangle
  在錯誤消息中還原符號名稱
-e <entry>
  使用指定的符號作爲程序的初始執行點
-E,--export-dynamic
  對於ELF格式文件,創建動態鏈接的可執行文件時,把所有符號添加到動態符號表
-f <name>, --auxiliary=<name>
  對於 ELF 格式共享對象,設置 DT_AUXILIARY 名稱
-F <name>, --filter=<name>
  對於ELF格式共享對象,設置 DT_FILTER 名稱。這告訴動態鏈接器,正在創建的共享對象的符號表應該用作共享對象名稱的符號表的篩選器。
-g
  被忽略。用於提供和其他工具的兼容性
-h
  對於 ELF 格式共享對象,設置 DT_SONAME 名稱
-I<file>, -dynamic-linker <file>, --dynamic-linker=<file>
  指定動態鏈接器。這僅在生成依賴動態鏈接庫的 ELF 可執行文件時纔有意義。默認的動態鏈接器通常是正確的,除非您知道正在做什麼,否則不要使用該選項。
-l <namespec>, --library=<namespec>
  把指定的庫文件添加到要鏈接的文件清單
-L <searchdir>, --library-path=searchdir
  把指定的路徑添加添加到搜索庫的目錄清單
-M, --print-map
  顯示鏈接映射,用於診斷目的
-Map=<mapfile>:
  將鏈接映射輸出到指定的文件
-m <emulation>
  模擬指定的鏈接器
-N,--omagic
  指定讀取/寫入文本和數據段
-n,--nmagic
  關閉節的頁面對齊,並禁用對共享庫的鏈接。如果輸出格式支持Unix樣式的幻數,則將輸出標記爲"NMAGIC"
-noinhibit-exec
  生成輸出文件,即使出現非致命鏈接錯誤。通常,如果鏈接器在鏈接過程中遇到錯誤,它將不會生成輸出文件。
-no-keep-memory
  ld 通常在內存中緩存輸入文件的符號表來優化內存使用速度。此選項告訴 ld 不要緩存符號表。當鏈接大型可執行文件時,如果ld耗盡內存空間,則可能需要使用該選項
-O <level>
  對於非零的優化等級,ld將優化輸出。此操作會比較耗時,應該在生成最終的結果時使用。
-o <output>, --output=<output>
  指定輸出文件的名稱
-oformat=<output-format>
  指定輸出文件的二進制格式
-R <filename>,--just-symbols=<filename>
  從指定的文件讀取符號名稱和地址
-r,--relocatable
  生成可重定位的輸出(稱爲部分連接)
-rpath=<dir>
  把指定的目錄添加到運行時庫搜索路徑
-rpath-link=<dir>
  指定搜索運行時共享庫的目錄
-S,--strip-debug
  忽略來自輸出文件的調試器符號信息
-s,--strip-all
  忽略來自輸出文件的所有符號信息
-shared, -Bshareable
  創建共享庫
-split-by-file[=size]
  爲每個目標文件在輸出文件中創建額外的段大小達到size。size默認爲1
-split-by-reloc[=count]
  按照指定的長度在輸出文件中創建額外的段
--section-start=<sectionname>=<org>
  在輸出文件中指定的地址定位指定的段
-T <scriptfile>, --script=<scriptfile>
  使用 scriptfile 作爲鏈接器腳本。此腳本將替換 ld 的默認鏈接器腳本(而不是添加到其中),因此腳本必須指定輸出文件所需的所有內容。如果當前目錄中不存在腳本文件,ld 會在 -L 選項指定的目錄中查找
-Ttext=<org>
  使用指定的地址作爲文本段的起始點
-Tdata=<org>
  使用指定的地址作爲數據段的起始點
-Tbss=<org>
  使用指定的地址作爲bss段的起始點
-t,--trace
  在處理輸入文件時顯示它們的名稱
-u <symbol>, --undefined=<symbol>
  強制指定符號在輸出文件中作爲未定義符號
-v, -V, --version
  示ld版本號
-warn-common
  當一個通用符號和另一個通用符號結合時發出警告
-warn-constructors
  如果沒有使用任何全局構造器,則發出警告
-warn-once
  對於每個未定義的符號只發出一次警告
-warn-section-align
  如果爲了對齊而改動了輸出段地址,則發出警告
--whole-archive
  對於指定的存檔文件,在存檔中包含所有文件
-X, --discard-locals
  刪除所有本地臨時符號
-x, --discard-al
  刪除所有本地符號

4. 常用示例

鏈接目標文件生成可執行文件。給定 C++ 目標文件 test.o 與 main.o,生成可執行文件 test.out。

ld /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/crtn.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L/usr/lib64 -L/usr/lib -lstdc++ -lm -lgcc_s -lc -lgcc  main.o test.o -o test.out

因爲生成一個 C++ 可執行文件,需要依賴很多系統庫和相關的目標文件,比如 C 語言庫 libc.a,所以使用 ld 進行鏈接時,需要注意添加較長的命令選項,不然會報鏈接錯誤。

使用 g++ -v 命令可以查看最後一行 collect2 使用的命令選項,進而瞭解生成可執行文所需的相關依賴。

g++ -v main.o test.o
...
usr/libexec/gcc/x86_64-redhat-linux/4.8.5/collect2 --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/crtn.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L/usr/lib64 -L/usr/lib -lstdc++ -lm -lgcc_s -lc -lgcc  main.o test.o

轉自:戀貓大鯉魚 blog.csdn.net/k346k346/article/details/89088652

****推薦關注「算法愛好者」,修煉編程內功

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/EXAv0TXJdpuzfKSPDWAxeg