gcc のオプションに"-v" なるものが存在するらしい。このコマンドはgccが実行したすべてのコマンドを見ることができるという。
$ ./gcc -v test.c
/home/denjo/gcc_install/libexec/gcc/x86_64-pc-linux-gnu/6.2.0/collect2 -plugin /home/denjo/gcc_install/libexec/gcc/x86_64-pc-linux-gnu/6.2.0/liblto_plugin.so -plugin-opt=/home/denjo/gcc_install/libexec/gcc/x86_64-pc-linux-gnu/6.2.0/lto-wrapper -plugin-opt=-fresolution=/tmp/ccLtFbvP.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o /home/denjo/gcc_install/lib/gcc/x86_64-pc-linux-gnu/6.2.0/crtbegin.o -L/home/denjo/gcc_install/lib/gcc/x86_64-pc-linux-gnu/6.2.0 -L/home/denjo/gcc_install/lib/gcc/x86_64-pc-linux-gnu/6.2.0/../../../../lib64 -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/home/denjo/gcc_install/lib/gcc/x86_64-pc-linux-gnu/6.2.0/../../.. /tmp/cc2jofoY.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /home/denjo/gcc_install/lib/gcc/x86_64-pc-linux-gnu/6.2.0/crtend.o /usr/lib/x86_64-linux-gnu/crtn.o
COLLECT_GCC_OPTIONS='-v' '-mtune=generic' '-march=x86-64'
このコマンドによってgccが裏で何をやっているのかがわかってきた。赤文字で示しているように、collect2もgccから何かを渡されて動いていることもわかった。
調べてみると、collect2はリンカの役割を担っているが…実際にリンカをしているのは /usr/bin にあるldなる実行ファイルであった…
さて、本当に手探らなくてはいけないのはgccではなく外部のファイルであることがわかってしまった。ここで完全に手詰まりか…と思っていた僕達に一筋の光が!
ここでgccのmain関数を思い出してみる。
main (int argc, char **argv)
{
driver d (false,false);
return d.main (argc, argv);
}
つまり、argvに"-o"オプションがないときにargvに"-o"、"hoge"を加えたnew_argvなるものを定義してやり、それをd.mainに渡せばよいのでは…!
そこでmain関数を以下のように書き換えた。
int main (int argc, char **argv){
driver d (false,false);
追記部分
int i;
bool o_flag = false;
// if there is "-o" in argv, o_flag is true.
for (i = 0; i < argc; i++) {
if (strcmp("-o", argv[i]) == 1) {
o_flag = true;
break;
}
}
if (! o_flag) {
char filename[M];
for (i = 0; i < argc; i++) {
strcpy(filename, argv[i]);
// find the name of source file.
char *p = strstr(filename, ".c");
if (p != NULL) {
// remove substring ".c" from filename.
*p = '\0';
*(p + 1) = '\0';
break;
}
}
int new_argc = argc + 2;
char **new_argv;
new_argv = (char **)xmalloc(sizeof(char*) * new_argc);
for (i = 0; i < new_argc; i++) {
new_argv[i] = (char *)xmalloc(sizeof(char) * M);
}
// copy original arguments to new_argv.
for (i = 0; i < argc; i++) {
strcpy(new_argv[i], argv[i]);
}
// append new arguments "-o filename" to new_argv.
strcpy(new_argv[argc], "-o");
strcpy(new_argv[argc + 1], filename);
return d.main(new_argc, new_argv);
}
return d.main (argc, argv);
}
すると、出力ファイルが標準で"hoge"になっていることを確認できた!
一応の実装完了である。