仅使用 g++有效,但不能“g” -c”和ld
我在 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'
I have the following source code in main.cpp:
#include <iostream>
#include <iomanip>
int main() {
std::cout << "Hi" << std::endl;
return 0;
}
Using this command works, and creates the executable file:
g++ -o main main.cpp
But this commands don't work:
g++ -c main.cpp
ld -o main main.o
The second one errors with:
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'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我认为如果你直接使用 ld ,它默认不包含 C++ 库。您也可以使用
g++
进行链接,它将使用正确的设置调用ld
。I think if you use
ld
directly it does not include the C++ libraries by default. You can useg++
to do the linking as well, it will callld
with the correct settings.GCC 内部链接了一些额外的库和目标文件。要查看它们是什么,请执行
-###
,这将打印它将执行的工具命令,包括链接器。我的 GCC 使用的链接器命令是(我制作了在粗体上调用g++
的实际.o
文件,因此您可以轻松发现它) 。您可以将
collect2
路径替换为ld< /code> (如果我没记错的话,
collect2
仅需要作为不支持现代二进制格式的 GCC 后端的真实ld
的代理,收集构造函数和析构函数根据其损坏的名称。ELF 格式具有对此的本机部分支持)。执行该命令并按字面替换 ld 即可成功链接可执行文件。
GCC internally links against a few additional libraries and object files. To see what those are, execute
-###
, which will print the tool commands it would execute, including the linker. The linker command used by my GCC is (I made the actual.o
file I invokedg++
on bold, so you can spot it easily).You can substitute the
collect2
path byld
(if I remember correctly,collect2
is only needed as a proxy for the realld
by GCC backends that don't support modern binary formats, to collect constructor and destructor functions according to their mangled name. The ELF format has native sections support for that).Executing that command, with
ld
substituted literally, successfully links the executable.当您使用 g++ 时,它还会链接链接器用来解析名称的 libstd++ 库。但是使用
g++ -c
然后使用ld
不会自动链接该库。您现在必须手动链接库。尝试(未经测试):
或者您可以通过阅读本手册来查看正确的语法:
When you use
g++
, it also links thelibstd++
library which linker uses to resolve the names. But usingg++ -c
and thenld
do not link the library automatically. You've to link the library manually now.Try (untested):
Or you can look into the correct syntax by reading this manual:
好吧,你没有链接到标准库。
g++
自动为您完成此操作;这就是我们使用它的原因:它包装了对 ccplus1 和 ld 的调用,并处理了所有额外的内容。顺便说一句,严格来说,相当于
g++ main.cpp -o main
的是:(
cc1plus
可能不在您的路径上;我在中找到了我的>/usr/libexec/gcc/i386-redhat-linux/4.1.1/
)g++ -c main.cpp
传统上执行第一步。g++ main.cpp -o main
包装了两者。g++
是单个编译和链接工具的包装器,针对 C++ 进行了调整。因此,它为cc1plus
和ld
提供了它认为合适的参数,包括 C++ 标准库中链接的参数:它还会在运行时中链接,并且可能一些其他的东西。
一般来说,没有必要尝试自己做这些事情:让
g++
来处理它。Well, you didn't link in the standard library.
g++
does this for you automatically; that's why we use it: it wraps calls toccplus1
andld
with all the extras taken care of.BTW, strictly speaking, the equivalent of
g++ main.cpp -o main
is:(
cc1plus
may well not be on your path; I found mine in/usr/libexec/gcc/i386-redhat-linux/4.1.1/
)g++ -c main.cpp
does traditionally perform that first step.g++ main.cpp -o main
wraps both.g++
is a wrapper to the individual compilation and linkage tools, tuned for C++. As such, it provides arguments tocc1plus
andld
as it sees fit, including the argument to link in the C++ Standard Library:It'll also link in the runtime and possibly some other stuff.
In general, there is no need to try to do these things yourself: let
g++
take care of it.