我的玩具语言自定义编译器使用 Cranelift 生成目标代码,我可以将其写入文件main.o
。为了使这个目标文件成为一个可执行文件,我用gcc -o main main.o
.
但是,我想将代码直接通过管道传输到 GCC,以免将临时目标文件写入磁盘,因此我让编译器将目标代码写入标准输出。用作-
文件名不起作用,因为该-x
选项似乎没有目标文件的任何值。
使用某种 shell 重定向也不起作用:gcc -o main <(compiler)
使用/usr/bin/ld: /proc/self/fd/11: file not recognized: Illegal seek
. (请注意,这在 GCC 本身处理文件时有效,例如使用gcc -xc <(echo "int main(){}") -o main
,但在文件传递给 LD 时无效。该-pipe
选项似乎也没有什么区别。)
有什么方法可以使用 GCC 链接通过管道传输到其中的目标代码吗?
ld
需要一个可搜索的文件,所以你不能使用管道。Korn<(...)
shell 进程替换扩展为管道路径。您需要 zsh 及其
=(...)
一个或 fish 及其(...|psub -f)
获取常规可搜索文件(在后台创建)的$TMPPREFIX
路径$TMPDIR
。如果
ld
需要文件的路径以 结尾.o
,在 中zsh
,设置TMPSUFFIX=.o
。在其他 shell 中,您可以手动创建临时文件,您甚至可以调用
gcc
它,甚至compiler
在它已被删除后将其输出重定向到它。在 Korn/POSIX 类 shell 中:请注意,
gcc
它本身会为自己的处理创建许多临时文件,因此想要尝试避免在此处创建一个额外的临时文件是没有意义的。您不能将目标文件通过管道传递给编译器。如错误所示,那是行不通的,因为 gcc 试图在其中查找,而这不是管道支持的操作。(它适用于源代码只是因为 gcc 是用特定的词法分析/解析编写的,这似乎真的是按顺序消耗输入。)
所以,一个匿名的临时文件必须做!
会解决你的问题:
但是:它只是 zsh 的一个特性,而不是更常见的 bash,所以我不知道你是想使用它还是只是便携式写入目标文件并链接它——就像任何有 makefile 或 ninja 脚本的人一样,或者这些的发电机,会做。
另请注意,如果您的编译器将中间代码作为输入,也许您真的想将其更改为 llvm 后端?这样,您可以将它作为插件加载到 clang 中,然后直接将源代码编译为目标文件,甚至可以同时运行组合链接和编译。