SanshouSichimiYa

備忘録の為のブログ

Rakeの基本演習

Rakeの基本演習を行いました。 C言語などの要素があり、今まで全然触れてこなかった部分だったので、あまりに基本的なことですが備忘録としてまとめておきます。

開始してから詰まるまで

RubyによるビルドツールRakeの覚え書き

ここで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

GNUコンパイラコレクション

当初はCコンパイラとして開発し、GCCGNU C Compiler を意味していた。しかし、もともと多言語を想定して設計しており、 GNU C Compiler と呼ばれていたときでも多くの言語に対応していた。現在でも GNU C Compiler の意味で「GCC」と呼ぶことも多い。ちなみに GNU C Compiler の実行ファイルの名称もgccである。なお、GNU C++コンパイラをG++、GNU JavaコンパイラGCJGNU 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.cmessage.cを空ファイルじゃなくてちゃんと動くものを入れる。