使用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进行链接,需要注意添加较长的命令选项。使用g++ -v
命令可以查看最后一行collect2使用的命令选项。collect2是对ld的封装,最终还是要调用ld来完成链接工作。
[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命令,即可完成目标文件的链接。