おもちゃ言語用のカスタムコンパイラはCraneliftを使用してファイルに書き込むことができるオブジェクトコードを生成しますmain.o
。このオブジェクトファイルを実行可能にするにはgcc -o main main.o
。
しかし、一時オブジェクトファイルをディスクに書き込むのを避けるために、コードをGCCに直接パイプしたいので、コンパイラにオブジェクトコードを標準出力に書き込むようにしました。オプションにターゲットファイルの値がないように見えるため、ファイル名としての使用は-
機能しません。-x
一種のシェルリダイレクトを使用することも機能しません:error 。gcc -o main <(compiler)
with/usr/bin/ld: /proc/self/fd/11: file not recognized: Illegal seek
gcc -xc <(echo "int main(){}") -o main
-pipe
GCCを使用してパイプで接続されたオブジェクトコードをリンクする方法はありますか?
答え1
ld
検索可能なファイルが必要なため、パイプは使用できません。 Korn<(...)
シェルプロセスは、パイプに拡張されたパスを置き換えます。
通常の検索可能なファイル(背後に作成された)への=(...)
パスを取得するには、zshまたはFishが必要です。(...|psub -f)
$TMPPREFIX
$TMPDIR
gcc -o main =(compiler) # zsh
gcc -o main (compiler|psub -f) # fish
ld
必要なファイルのパス.o
がで終わる場合にzsh
設定しますTMPSUFFIX=.o
。
他のシェルでは一時ファイルを手動で生成することができ、gcc
それを呼び出したりcompiler
削除した後に出力をそのファイルにリダイレクトすることもできます。 Korn/POSIXに似たシェルでは:
file=$(mktemp) && {
rm -f -- "$file" &&
compiler >&3 3>&- 4<&- &&
gcc -o main /dev/fd/4 3>&-
} 3> "$file" 4<> "$file"
自己処理のために独自に多くの一時ファイルを生成するので、gcc
ここで追加の一時ファイルの生成を避けようとすることは意味がありません。
答え2
できない管路コンパイラのオブジェクトファイルです。エラーが示すように、gccがそれを調査しようとしているため機能しません。これはパイプでサポートされている作業ではありません。 (gccは特定の語彙/解析で書かれており、入力を順次消費するように見えるため、ソースコードでのみ機能します。)
だから匿名の一時ファイルが必要です!
gcc -o main =(yourcompiler)
問題を解決します。
<(...)の代わりに=(...)を使用すると、引数として渡されたファイルはリストプロセスの出力を含む一時ファイルの名前になります。これは、入力ファイルに対してlseekを実行したいプログラムの<形式の代わりに使用できます(lseek(2)を参照)。
しかし、これはより一般的なbashではなくzshの機能にすぎないので、それを使用したいのか、それとも移植可能なオブジェクトファイルを作成してリンクするのかわかりません。メイクファイルや忍者スクリプトを使用している人のように、またはジェネレータがします。
また、コンパイラが中間コードを入力として使用している場合は、実際にそれをllvmバックエンドに変更したいかもしれません。これにより、プラグインとしてclangにロードし、ソースコードをオブジェクトファイルに直接コンパイルしたり、結合されたリンクを実行したり、すぐにコンパイルを実行したりできます。