使用 ld 命令链接目标文件生成可执行文件
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 命令链接目标文件生成可执行文件相关推荐
- linux 反汇编目标文件,用于查看目标文件或可执行文件的组成信息的命令:objdump命令...
1.功能简介 objdump 命令是 GNU Binutils 二进制工具集的一员,用于查看目标文件或可执行文件的组成信息,以可读的形式打印二进制文件的内容. 2.命令格式 objdump[OPTIO ...
- linux下gcc编译c文件生成可执行文件的四个步骤
Linux下gcc编译c文件为可执行文件分为四个步骤: 分别是 预编译.编译.汇编.链接. 1.预编译( 生成 hello.i 文件) 预编译的处理规则: 1. 将所有的 "#define& ...
- C语言 目标文件和可执行文件(ELF文件)
转自:https://www.jianshu.com/p/7c609b70acbd 1.C语言创建程序 1.1C语言创建(分为4个步骤) 编辑 编译 链接 执行 编辑:就是创建和修改C程序的源代码-我 ...
- S32DS中.ld(链接)文件学习
一..ld文件作用 程序代码(.s 和 .c)源文件会经过预编译.编译.汇编.链接最后生成目标可执行文件,.ld文件是作用在链接过程. 链接的作用是: 合并各个.obj文件的section,合并符号表 ...
- 目标文件和可执行文件区别
解释源代码文件.目标代码文件和可执行文件有什么区别? 源代码文件: 一般指.c文件,例如main.c 目标代码文件:包含机器语言代码,它不是完整的程序代码. 可执行文件: 包含组成可执行程序的完整机器 ...
- 怎么在命令行执行.py文件,py文件生成可执行文件
大家好,小编来为大家解答以下问题,怎么在命令行执行.py文件,怎么运行python的py文件,现在让我们一起来看看吧! 1.后缀PY的文件怎么用? 后缀PY的文件可以用Python软件打开,具体操作步 ...
- windows下使用bat命令根据测站文件生成下载链接
场景描述: 有一个测站list文件,需要根据list里的测站生成不同的wget下载链接 方法: 写bat批处理文件可以很方便的解决这个问题 代码: ::关闭代码输出 @echo off ::设置变量 ...
- 使用jdk的xjc命令由schema文件生成相应的实体类
xjc D:\operate-process.xsd -d D:\workspace\wmsc\src\main\java -p com.yd.wmsc.util operate-process.xs ...
- Linux 命令(65)—— ld 命令
文章目录 1.命令简介 2.命令格式 3.选项说明 4.常用示例 参考文献 1.命令简介 ld(Link eDitor)命令是二进制工具集 GNU Binutils 的一员,是 GNU 链接器,用于将 ...
最新文章
- linux 别名管理,Linux 的 15 个命令行别名, 帮系统管理员提升工作效率!
- B S架构 服务器虚拟化,B/S 架构及 Tomcat
- 符号未定义Java_Java ODBC数据源(未定义符号:SQLAllocEnv)
- vue2.0搭建vue手脚架(vue-cli)
- C#LeetCode刷题之#645-错误的集合(Set Mismatch)
- EventEmitter
- cpu out of order, 性能优化
- 做公文流转的具体思路
- php 打印出心形,利用php输出不同的心形图案_PHP
- python 跳过_如果文件已经存在,Python将跳过一个函数
- python中有这样一条语句_在Python中一行书写两条语句时,语句之间可以使用__________作为分隔符。_学小易找答案...
- python拼音检查
- MATLAB与STK互联10:卫星对象操作(2)—卫星轨道参数设置(方法1,通过轨道生成器设置实现)
- 如何在博客园中自定义背景
- MATLAB中运动造成的图像模糊
- CentOS6启动和内核管理
- asp.net网站修改aspx.cs文件后如何不替换网站就生效
- java错误 找不到或无法加载主类_JAVA报找不到或无法加载主类的错误
- Android-Ble蓝牙开发Demo示例–扫描,连接,发送和接收数据
- 用Python制作表白神器——爱心墙