Rakeの基本演習
Rakeの基本演習を行いました。 C言語などの要素があり、今まで全然触れてこなかった部分だったので、あまりに基本的なことですが備忘録としてまとめておきます。
開始してから詰まるまで
ここでRakeの基本を学ぼうと走り出しましたが単純なRakefileのところで転びました。
まずRakefileを作ります。
CC = "gcc" task :default => "hello" file "hello" => ["hello.o", "message.o"] do sh "#{CC} -o hello hello.o message.o" end file "hello.o" => "hello.c" do sh "#{CC} -c hello.c" end file "message.o" => "message.c" do sh "#{CC} -c message.c" end
これをrakeすれば動くよという話ですが。
$ rake rake aborted! Don't know how to build task 'hello.c' Tasks: TOP => default => hello => hello.o (See full trace by running task with --trace)
hello.cがおかしい?
file "hello.o" => "hello.c" do sh "#{CC} -c hello.c" end
hello.c
を生成して再度実行
$ rake gcc -c hello.c rake aborted! Don't know how to build task 'message.c' Tasks: TOP => default => hello => message.o (See full trace by running task with --trace)
message.c
を生成して再度実行
$ rake gcc -c message.c gcc -o hello hello.o message.o Undefined symbols for architecture x86_64: "_main", referenced from: implicit entry/start for main executable ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) rake aborted! Command failed with status (1): [gcc -o hello hello.o message.o...] /Users/hirokiyoshino/Desktop/practice-ruby/Rakefile:6:in `block in <top (required)>' Tasks: TOP => default => hello (See full trace by running task with --trace)
...これは…...gcc
がわかってないので調べます。
GCC
当初はCコンパイラとして開発し、GCCは GNU C Compiler を意味していた。しかし、もともと多言語を想定して設計しており、 GNU C Compiler と呼ばれていたときでも多くの言語に対応していた。現在でも GNU C Compiler の意味で「GCC」と呼ぶことも多い。ちなみに GNU C Compiler の実行ファイルの名称もgccである。なお、GNU C++コンパイラをG++、GNU JavaコンパイラをGCJ、GNU AdaコンパイラをGNATと呼ぶ。
コンパイラ
人間が理解しやすい言語や数式で記述されたプログラムを、機械語に(あるいは、元のプログラムよりも低いレベルのコードに)変換するプログラムのこと。
ファイルやコマンドについて
必要な部分のみ出力の種類を制御するオプションより抜粋引用します。
コンパイル処理には、 4つの段階が含まれます。 それは、 前処理、 狭義のコンパイル処理、 アセンブル処理、 リンク処理であり、 常にこの順序で実行されます。 最初の3つの段階は、 個々のソース・ファイルに対して適用され、 オブジェクト・ファイルを生成することによって終了します。 リンク処理では、 すべてのオブジェクト・ファイル (新たにコンパイルされたオブジェクト・ファイルと入力として指定されたオブジェクト・ファイル) を結合して、 1つの実行可能ファイルを生成します。
hello.c
などのfile.c
前処理が実行されなければならないCのソース・コードとのこと。
-c
ソース・ファイルのコンパイル、 または、 アセンブルを行いますが、 リンクは行いません。 リンク処理段階は実行されません。 最終的な出力形態は、 個々のソース・ファイルに対応するオブジェクト・ファイルとなります。 デフォルトでは、 ソース・ファイルに対応するオブジェクト・ファイルの名前は、 ソース・ファイル名の接尾語
.c'、
.i'、.s'等を
.o'に置き換えることによって作られます。 接尾語が認識されない入力ファイルは、 コンパイルもアセンブルも必要とされないので、 無視されます。
例えばgcc -c hello.c
が処理されるとファイル名がhello.o
に置き換えられたものが作られる。
-o file
fileによって指定されるファイルを出力先とします。 これは、 生成される出力の種類に関係なく適用されます。 出力が、 実行可能ファイル、 オブジェクト・ファイル、 アセンブラ・ファイル、 前処理済みのCコードのいずれであっても、 無関係に適用されます。 出力ファイルは1つしか指定できないので、 複数の入力ファイルをコンパイルする際に
-o'を使うのは、 出力として実行可能ファイルを生成しようとしている場合を除けば、 意味のないことです。
-o'が指定されないと、 デフォルトでは、 実行可能ファイルはa.out'に、
source.suffix'に対応するオブジェクト・ファイルはsource.o'に、
source.suffix'に対応するアセンブラ・ファイルは`source.s'に、 また、 すべての前処理済みのCのソースは標準出力に、 それぞれ出力されます。
例えばgcc -o hello hello.o message.o
が処理されると実行可能ファイルのhello
が作られる。
もう一度やってみる
hello.c
やmessage.c
を空ファイルじゃなくてちゃんと動くものを入れる。