编译到 stdout 时 g++ 出现链接器错误

编译到 stdout 时 g++ 出现链接器错误

假设我有一个名为 的 C++ 文件dummy.cpp,我需要使用 g++ 对其进行编译,使其来自 stdin,而 g++ 将编译后的二进制文件吐出到 stdout。

如果只需要 stdin 部分,则以下命令可以解决问题:

$ g++ -x c++ -o dummy - < dummy.cpp

现在添加输出部分,据我所知,我们需要使用例如/dev/stdout(或/proc/self/fd/1) 作为输出参数,但是它不会工作,因为它会因链接器错误而退出。

$ g++ -x c++ -o /dev/stdout - < dummy.cpp
/usr/bin/ld: final link failed: Illegal seek
collect2: error: ld returned 1 exit status

如果我通过它将它从终端重定向到文件,g++ -x c++ -o /dev/stdout - < dummy.cpp > dummy它将正常工作。我想问题是 stdout 不可查找,当它通过管道传输到文件中时,它会“变成”。但是为什么 ld 文件是可查找的并且可以以某种方式绕过它吗?

答案1

正如评论中提到的,这是因为链接器分阶段写入文件,然后用大小和偏移量填充标头区域中的条目。 ELF 格式在文件的早期部分包含这些值,以便轻松高效地查找适当的部分,因此链接器很自然地按照其方式工作。专为流式传输而设计的格式(例如 Zip 文件)由于将清单数据放在末尾,因此往往会变得更加复杂。

虽然理论上可以实现流输出支持,但这样做可能需要缓冲大量数据、两次计算数据或各种其他低效实践,并且由于这种情况非常罕见,因此可能不值得考虑代码复杂性以及链接器中潜在的低效率。您可能可以使用一个小的 shell 脚本,甚至一个 shell 单行代码,使用临时文件并进行适当的清理来实现此目的。

相关内容