我在main.cpp中有以下源代码:
#include <iostream>
#include <iomanip>
int main() {
std::cout << "Hi" << std::endl;
return 0;
}
使用此命令可以工作,并创建可执行文件:
g++ -o main main.cpp
但是这些命令不起作用:
g++ -c main.cpp
ld -o main main.o
第二个错误:
ld: warning: cannot find entry symbol _start; defaulting to 00000000004000e8
main.o: In function `main':
main.cpp:(.text+0xa): undefined reference to `std::cout'
main.cpp:(.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.cpp:(.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.cpp:(.text+0x1c): undefined reference to `std::ostream::operator<<(std::ostream& (*)(std::ostream&))'
main.o: In function `__static_initialization_and_destruction_0(int, int)':
main.cpp:(.text+0x4a): undefined reference to `std::ios_base::Init::Init()'
main.cpp:(.text+0x4f): undefined reference to `std::ios_base::Init::~Init()'
main.cpp:(.text+0x54): undefined reference to `__dso_handle'
main.cpp:(.text+0x61): undefined reference to `__cxa_atexit'
答案 0 :(得分:14)
我认为如果直接使用ld
,默认情况下它不包含C ++库。您也可以使用g++
进行关联,它会使用正确的设置调用ld
。
g++ -c main.cpp
g++ -o main main.o
答案 1 :(得分:13)
GCC内部链接了一些额外的库和目标文件。要查看它们是什么,请执行-###
,它将打印它将执行的工具命令,包括链接器。我的GCC使用的链接器命令是(我在粗体上创建了我调用的.o
文件g++
,因此您可以轻松地发现它。
/usr/lib/gcc/i686-pc-linux-gnu/4.6.0/collect2 --build-id --eh-frame-hdr -m elf_i386“--hash-style = both”-dynamic-链接器/lib/ld-linux.so.2 /usr/lib/gcc/i686-pc-linux-gnu/4.6.0/../../../crt1.o / usr / lib / gcc / i686 -pc-linux-gnu / 4.6.0 /../../../ crti.o /usr/lib/gcc/i686-pc-linux-gnu/4.6.0/crtbegin.o -L / usr / lib / gcc / i686-pc-linux-gnu / 4.6.0 -L / usr / lib / gcc / i686-pc-linux-gnu / 4.6.0 /../../ .. main1.o “ - lddc ++” - lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/i686-pc-linux-gnu/4.6.0/crtend.o / usr / lib / gcc / i686 -pc-Linux的GNU / 4.6.0 /../../../ crtn.o
您可以在collect2
之前替换ld
路径(如果我没记错的话,{G}后端只需要collect2
作为真实ld
的代理支持现代二进制格式,根据其错位名称收集构造函数和析构函数.ELF格式具有本机部分支持)。
执行该命令,以ld
字面替换,成功链接可执行文件。
答案 2 :(得分:8)
当您使用g++
时,它还会链接链接器用来解析名称的libstd++
库。但是使用g++ -c
然后使用ld
不会自动链接库。您现在要手动链接库。
尝试(未经测试):
ld -o main main.o -llibstd++
或者您可以通过阅读本手册来查看正确的语法:
答案 3 :(得分:1)
好吧,你没有在标准库中链接。 g++
会自动为您执行此操作;这就是我们使用它的原因:它包含对ccplus1
和ld
的调用以及所有额外的处理。
g++ main.cpp -o main
:
cc1plus main.cpp -o main.o
ld -o main main.o
(cc1plus
可能不在您的路上;我在/usr/libexec/gcc/i386-redhat-linux/4.1.1/
找到了我的
g++ -c main.cpp
传统上执行第一步。 g++ main.cpp -o main
包装两者。
g++
是针对C ++调整的各个编译和链接工具的包装器。因此,它提供cc1plus
和ld
的参数,因为它认为合适,包括在C ++标准库中链接的参数:
ld -o main main.o -llibstd++
它还会链接到运行时以及其他一些东西。
一般来说,没有必要尝试自己做这些事情:让g++
来处理它。