1.目标文件生链接成可执行文件依赖的库和目标文件

使用 ld 链接目标文件生成可执行文件,用于取代命令 g++,仅仅用于学习 ld 命令的使用,不用于实际的项目编译。

首先看一个简单的 C++ 源文件 main.cpp。

//
//@file:main.cpp
//#include <iostream>
using namespace std;int main()
{cout<<"hello world"<<endl;
}

当我使用命令g++ -c将其编译为目标文件main.o时,使用命令ld main.o会报如下错误。

[root@TENCENT64 ~]# ld main.o -o main.out
ld: warning: cannot find entry symbol _start; defaulting to 0000000000400120
main.o: In function `main':
main.i:(.text+0xa): undefined reference to `std::cout'
main.i:(.text+0xf): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
main.i:(.text+0x14): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'
main.i:(.text+0x1c): undefined reference to `std::ostream::operator<<(std::ostream& (*)(std::ostream&))'
main.o: In function `__static_initialization_and_destruction_0(int, int)':
main.i:(.text+0x4a): undefined reference to `std::ios_base::Init::Init()'
main.i:(.text+0x4f): undefined reference to `__dso_handle'
main.i:(.text+0x59): undefined reference to `std::ios_base::Init::~Init()'
main.i:(.text+0x5e): undefined reference to `__cxa_atexit'
ld: main.out: hidden symbol `__dso_handle' isn't defined
ld: final link failed: Bad value

使用ld进行链接,需要注意添加较长的命令选项,不然会报上面的链接错误。Linux系统,链接目标文件生成可执行文件比我们想象的要复杂许多,因为生成一个C++可执行文件,需要依赖很多系统库和相关的目标文件,比如C语言库libc.a。使用g++ -v命令可以查看最后一行collect2使用的命令选项,进而了解生成可执行文所需的相关依赖。

[root@TENCENT64 ~]# g++ -v main.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/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../.. -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o main.o

所以,使用上面的命令选项作用于ld命令,即可完成目标文件的链接。简单地总结,至少有如下的库和目标文件被链接到可执行文件中。

ld-linux-x86-64.so.2
crt1.o
crti.o
crtbegin.o
libstdc++.a
libm.a
libgcc_s.a
libgcc.a
libc.a
crtend.o
crtn.o

2.collect2是什么

从上面的链接过程可以看出,最终编译器 g++ 调用链接器 collect2 来完成链接工作。为什么是 collect2 而不是 ld 呢?实际上 collect2 是对 ld 的封装,最终还是要调用 ld 来完成链接工作。与 ld 不同的是在完成链接工作后,collect2 还会对链接结果做一些处理,主要是收集所有与程序初始化相关的信息并且构造初始化的结构。简单来说,可以把 collect2 看作是链接器 ld。


参考文献

[1] stackoverflow.How to link C++ object files with ld
[2] 余甲子,石凡,潘爱民.程序员的自我修养——链接、装载与库[M].北京:机械工业出版社,2009.C4.5静态库链接.P120-122

使用 ld 命令链接目标文件生成可执行文件相关推荐

  1. linux 反汇编目标文件,用于查看目标文件或可执行文件的组成信息的命令:objdump命令...

    1.功能简介 objdump 命令是 GNU Binutils 二进制工具集的一员,用于查看目标文件或可执行文件的组成信息,以可读的形式打印二进制文件的内容. 2.命令格式 objdump[OPTIO ...

  2. linux下gcc编译c文件生成可执行文件的四个步骤

    Linux下gcc编译c文件为可执行文件分为四个步骤: 分别是 预编译.编译.汇编.链接. 1.预编译( 生成 hello.i 文件) 预编译的处理规则: 1. 将所有的 "#define& ...

  3. C语言 目标文件和可执行文件(ELF文件)

    转自:https://www.jianshu.com/p/7c609b70acbd 1.C语言创建程序 1.1C语言创建(分为4个步骤) 编辑 编译 链接 执行 编辑:就是创建和修改C程序的源代码-我 ...

  4. S32DS中.ld(链接)文件学习

    一..ld文件作用 程序代码(.s 和 .c)源文件会经过预编译.编译.汇编.链接最后生成目标可执行文件,.ld文件是作用在链接过程. 链接的作用是: 合并各个.obj文件的section,合并符号表 ...

  5. 目标文件和可执行文件区别

    解释源代码文件.目标代码文件和可执行文件有什么区别? 源代码文件: 一般指.c文件,例如main.c 目标代码文件:包含机器语言代码,它不是完整的程序代码. 可执行文件: 包含组成可执行程序的完整机器 ...

  6. 怎么在命令行执行.py文件,py文件生成可执行文件

    大家好,小编来为大家解答以下问题,怎么在命令行执行.py文件,怎么运行python的py文件,现在让我们一起来看看吧! 1.后缀PY的文件怎么用? 后缀PY的文件可以用Python软件打开,具体操作步 ...

  7. windows下使用bat命令根据测站文件生成下载链接

    场景描述: 有一个测站list文件,需要根据list里的测站生成不同的wget下载链接 方法: 写bat批处理文件可以很方便的解决这个问题 代码: ::关闭代码输出 @echo off ::设置变量 ...

  8. 使用jdk的xjc命令由schema文件生成相应的实体类

    xjc D:\operate-process.xsd -d D:\workspace\wmsc\src\main\java -p com.yd.wmsc.util operate-process.xs ...

  9. Linux 命令(65)—— ld 命令

    文章目录 1.命令简介 2.命令格式 3.选项说明 4.常用示例 参考文献 1.命令简介 ld(Link eDitor)命令是二进制工具集 GNU Binutils 的一员,是 GNU 链接器,用于将 ...

最新文章

  1. linux 别名管理,Linux 的 15 个命令行别名, 帮系统管理员提升工作效率!
  2. B S架构 服务器虚拟化,B/S 架构及 Tomcat
  3. 符号未定义Java_Java ODBC数据源(未定义符号:SQLAllocEnv)
  4. vue2.0搭建vue手脚架(vue-cli)
  5. C#LeetCode刷题之#645-错误的集合(Set Mismatch)
  6. EventEmitter
  7. cpu out of order, 性能优化
  8. 做公文流转的具体思路
  9. php 打印出心形,利用php输出不同的心形图案_PHP
  10. python 跳过_如果文件已经存在,Python将跳过一个函数
  11. python中有这样一条语句_在Python中一行书写两条语句时,语句之间可以使用__________作为分隔符。_学小易找答案...
  12. python拼音检查
  13. MATLAB与STK互联10:卫星对象操作(2)—卫星轨道参数设置(方法1,通过轨道生成器设置实现)
  14. 如何在博客园中自定义背景
  15. MATLAB中运动造成的图像模糊
  16. CentOS6启动和内核管理
  17. asp.net网站修改aspx.cs文件后如何不替换网站就生效
  18. java错误 找不到或无法加载主类_JAVA报找不到或无法加载主类的错误
  19. Android-Ble蓝牙开发Demo示例–扫描,连接,发送和接收数据
  20. 用Python制作表白神器——爱心墙

热门文章

  1. StringUtils 中 isEmpty 和 isBlank 的区别
  2. 3.3 rsync同步之ssh隧道方式
  3. IOS安全、逆向、反编译
  4. ZH奶酪:PHP遍历目录/文件的3种方法
  5. .NET : 自定义TraceListener
  6. 使用Python批量替换指定目录所有文件中的指定文本
  7. Linux文件及文件内容的查找-转
  8. [Java] 蓝桥杯ADV-193 算法提高 盾神与条状项链
  9. PAT 1090 危险品装箱(25 分)- 乙级
  10. 蓝桥杯 ALGO-20 算法训练 求先序排列 Java版