c! c++!! make!!!
お久しぶりです。 CPPXのXです。
cからc++を呼ぶ処理と、makeの書き方をまとめておきます。
ファイル構成
$ls main.c makefile sub.c sub.h subcpp.cpp subcpp.h
こんな感じでやっていきます。
中身はお好みでどうぞ。 下で書き換えていきます。
make (cの方)
makefileの中身を以下のように書きます。
FILES = main.o sub.o build: $(FILES) cc $(FILES) ./a.out .c.o: cc -c $< sub.o: sub.h
すると、make と打つとコンパイルされて実行ファイルが吐き出されます。
.c.o: cc -c $<
の部分ですが、.cのファイルを探して、.oに変換しますよ という意味らしいです。
ファイル名が $< に格納されます。 なので、echo $< とかやるとファイル名が出てきます。
sub.o: sub.h
ですが、処理を追加すると.c.oの処理よりも優先されてしまうので、依存関係を書くだけに留めておきましょう。
sub.cの変更も検知されなくなります。
c++との連携
cからc++を呼び出していきます。
subcpp.cpp, subcpp.hを以下のようにします。
- subcpp.cpp
#include <iostream> extern "C" void print(int value) { std::cout << value << std::endl; }
- subcpp.h
#define INCLUDE_SUBCPP #ifndef INCLUDE_SUBCPP #ifndef __cplusplus extern "C" #endif int print(int); #endif
extern "C" をつけるとcから見えるようになるみたいです。
戻り値と引数はcにあるものにしないとエラーがでます。
#ifndef __cplusplus
は、cの時は未定義になるので、ただの
int print(int);
として処理されます。
コンパイルしていきましょう。 次に進みます。
make(c++の方)
makefileを以下のように書き換えます。
FILES = main.o sub.o subcpp.o build: $(FILES) cc $(FILES) -lc++ ./a.out .c.o: cc -c $< .cpp.o: cc -c $< sub.o: sub.h subcpp.o: subcpp.h
- FILESにsubcpp.oを追加しました
- ccのコンパイルオプションに-lc++を追加しました
- .cpp.o: を追加しました
- subcpp.o: subcpp.hを追加しました
それぞれ見ていきます。
(1) subcppと連携したいため、リンクするファイルを追加しました。
(2) c++とリンクする際には、-lc++のオプションをつけないと
Undefined symbols for architecture x86_64
のようなエラーが出ます。
オプションをつけずに、clang++でコンパイルしても大丈夫です。
(3) .cppを探して.oに変換してくれます。.c.oの時とだいたい同じです。
(4) こっちも処理は書かずに依存関係を書くだけに留めます。
おわり
ここまで書いて、main.cを以下のように書き換えて make と打つと、10 と表示されると思います。
#include "subcpp.h" int main(){ print(10); }
makeを初めてちゃんと触ったので、もうちょっとまともに扱えるようになりたい・・・。
makeは怖いものだと思ってたので、もう少し深まったらまた記事書きます。