仅使用g ++可以工作,但不能使用“g ++ -c”和ld

时间:2011-07-15 09:01:52

标签: c++ linker g++

我在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'

4 个答案:

答案 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++会自动为您执行此操作;这就是我们使用它的原因:它包含对ccplus1ld的调用以及所有额外的处理。

严格来说,BTW相当于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 ++调整的各个编译和链接工具的包装器。因此,它提供cc1plusld的参数,因为它认为合适,包括在C ++标准库中链接的参数:

ld -o main main.o -llibstd++

它还会链接到运行时以及其他一些东西。

一般来说,没有必要尝试自己做这些事情:让g++来处理它。