2017-05-23 4 views
-3

私はg++ -std=c++17 -Wall -Og -g -o main *.ccと完全にコンパイルする小さなコードを持っています。それが使用する理由私はCC = g ++を設定しても、私のmakefileはgccを呼び出すのはなぜですか?

CC = g++ 
CFLAGS = -Wall -std=c++17 -Og -g 
DEPS = random_tools.h 
OBJ = main.o random_tools.o 

%.o: %.c $(DEPS) 
    $(CC) $(CFLAGS) -o [email protected] $< 

main: $(OBJ) 
    gcc $(CFLAGS) -o [email protected] $^ 

しかし、私はmakeを実行すると、それがクラッシュし、私は本当に得ることはありません何

g++ -c -o main.o main.cc 
g++ -c -o random_tools.o random_tools.cc 
gcc -Wall -o main main.o random_tools.o 
main.o: In function `main': 
main.cc:(.text+0x1d): undefined reference to `std::cout' 
main.cc:(.text+0x22): undefined reference to `std::ostream::operator<<(int)' 
main.cc:(.text+0x27): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)' 
main.cc:(.text+0x2f): undefined reference to `std::ostream::operator<<(std::ostream& (*)(std::ostream&))' 
main.o: In function `__static_initialization_and_destruction_0(int, int)': 
main.cc:(.text+0x5d): undefined reference to `std::ios_base::Init::Init()' 
main.cc:(.text+0x6c): undefined reference to `std::ios_base::Init::~Init()' 
collect2: error: ld returned 1 exit status 
make: *** [makefile:10: main] Error 1 

を私に告げることです。今、私はTorはメイクファイルを持っているし、これまでのところ、私はこれを得たいですg++の代わりにgcc - g++を使用するように指示しています。誰かがここで何が起きるかについて光を当てることができ、どうすればmake私が言うことをすることができますか?ありがとう。

+8

を使用すると、明示的にリンカコマンドでそれを使用するので:。。 'GCCの$(CFLAGS)-o $ @ $ ^'? –

+1

「CC」は、従来はC++コンパイラではなく、C++コンパイラであることに注意してください。 C++コンパイラの通常の変数は 'CXX'と' CXXFLAGS'です。 – Barmar

+2

一般的にmake変数をCに関連付けてC++に使用するのは悪い考えです。 C++のソースファイルに.cの接尾辞を付けることも悪い考えです。 –

答えて

5

このルール

main: $(OBJ) 
    gcc $(CFLAGS) -o [email protected] $^ 

は "GCC" それにハードワイヤードました。これを$(CC)に変更すると、期待どおりに動作します。それは、このように、このMakefileを書くために、すべての周りの方が良いだろう、と述べた

:後で展開する方がはるかに簡単になりますので

CXX = g++ 
CXXFLAGS = -Wall -std=c++17 -Og -g 
DEPS = random_tools.h 
OBJ = main.o random_tools.o 

# Default goal 
main: $(OBJ) 
    $(LINK.cc) $^ -o [email protected] $(LDLIBS) 

# Header dependencies 
$(OBJ): $(DEPS) 

これはビルトインを使用するには、規則を作成します。

(私はあなたがカバーするGNU Make manualカバーを読むことをお勧めします。ここで規則を作成します。全ての組み込みを説明するためのスペースを持っていない)(これはは、あなたが実際にあなたのソースという名前の場合は何を期待しないことに注意してくださいファイルmain.crandom_tools.cではなくmain.ccrandom_tools.ccしかし、あなたはとにかくC++ソースファイルの.ccを使用する必要があります)

+0

リンカコマンドで 'LDLIBS'と' LDFLAGS'を考慮に入れるべきです。それは '$(LINK.cc)$(OUTPUT_OPTION)$ ^'や '$(LINK.cc)-o $ @ $ ^'で一番簡単にできます。 –

+0

@TobySpeight回答が修正されましたが、OUTPUT_OPTIONについて前に述べたことに加えて、LDLIBSはLINK.ccには含まれていません。なぜなら、-lオプションはコマンドラインで最後に停止する必要があるからです。 – zwol

+0

TBH、私はこのようなルールが必要なときに、 'make --print-data-base'とコピー/ペーストを実行します。これはコメントするときにすべきです! –

3

Makefile(行9)のmain部分にgccコマンドを使用しています。あなたがそれを置き換える必要があります。$(CC) $(CFLAGS) -o [email protected] $^

+0

さらに、 '$(LINK.cc)$(OUTPUT_OPTION)$ ^'に置き換えて、 'LDLIBS'などを余分な労力をかけずにちょうど実行してください。 –

+0

リンクルールでは@TobySpeight $(OUTPUT_OPTION)を使用しないでください。 mv -f $( zwol

+0

本当にどうしたの?常に '-o $ @' AFAICTに展開するべきです。 –