假设我有一个名为 的 C++ 文件dummy.cpp
,我需要用 g++ 编译它,使其来自标准输入,而 g++ 将编译后的二进制文件输出到标准输出。
如果只需要 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
,它将正常工作。我想问题是标准输出是不可搜索的,当它通过管道传输到文件中时,它会“变成”。但是为什么 ld 文件是可查找的,并且可以以某种方式规避它?
正如评论中提到的,这是因为链接器分阶段写入文件,然后用大小和偏移量填充标题区域中的条目。ELF 格式在文件的前半部分具有这些值,以便轻松高效地找到适当的部分,因此,链接器自然而然地以它的方式工作。为流媒体设计的格式,如 Zip 文件,由于将清单数据放在最后,往往会变得更加复杂。
虽然理论上可以实现流输出支持,但这样做可能需要缓冲大量数据、两次计算数据或各种其他低效做法,并且由于这种情况非常罕见,因此可能认为不值得代码复杂性以及链接器中潜在的低效率。您可能会使用一个小的 shell 脚本,甚至是一个 shell 单行程序,使用带有适当清理的临时文件来实现这一点。