GCC には -wrapper オプションというのがあり、サブプロセスを起動するときのラッパーを指定することができます。

例えば以下のような内容の wrapper.sh を作ります。

#!/bin/sh
echo "$@"
exec "$@"

これをラッパーに指定して実行すると…

[umezawa@devcent7:pts/1 ~]$ gcc -wrapper ./wrapper.sh a.c
/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/cc1 -quiet a.c -quiet -dumpbase a.c -mtune=generic -march=x86-64 -auxbase a -o /tmp/cccfNy2P.s
as --64 -o /tmp/ccl8x25K.o /tmp/cccfNy2P.s
/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/collect2 --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../.. /tmp/ccl8x25K.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o

こんな感じになります。

さらに -no-integrated-cpp オプションと組み合わせると、

/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/cc1 -E -quiet a.c -mtune=generic -march=x86-64 -o /tmp/cc96rUtL.i
/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/cc1 -fpreprocessed /tmp/cc96rUtL.i -quiet -dumpbase a.c -mtune=generic -march=x86-64 -auxbase a -o /tmp/ccGeV7zF.s
as --64 -o /tmp/cc1MBGIz.o /tmp/ccGeV7zF.s
/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/collect2 --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../.. /tmp/cc1MBGIz.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o

となり、プリプロセッサの起動を外部プログラムでフックできます。結果として、容易に他の追加のプリプロセスを挟み込むことができます。(標準プリプロセスの前に追加するのであれば -no-integrated-cpp は不要ですが)。標準プリプロセスの前に追加する場合、ソースコードに前処理をしてから gcc を起動してもいいのですが、こちらは gcc のオプションをいじるだけでいいので、IDE とかを使っている場合はこちらの方が手間が少なそうです。

なお、非常に残念ですが、 Clang にはこのオプションは無いようです。コンパイラの内部構造に依存するオプションなので致し方ありません(Clang はサブプロセスを起動せず自プロセス内で全部処理する)。Xcode で使いたかったんですが。

Trackback

no comment untill now

Add your comment now