web-dev-qa-db-ja.com

src /のすべての.cppファイルをobj /の.oにコンパイルしてから、。/のバイナリにリンクできますか?

私のプロジェクトディレクトリは次のようになります。

/project
    Makefile
    main
    /src
        main.cpp
        foo.cpp
        foo.h
        bar.cpp
        bar.h
    /obj
        main.o
        foo.o
        bar.o

メイクファイルにしたいのは、.cppフォルダー内のすべての/srcファイルを.oフォルダー内の/objファイルにコンパイルしてから、すべての.oファイルを/objから最上位フォルダー/projectの出力バイナリーに入れます。

私はMakefileの経験がほとんどないので、これを達成するために何を検索すればよいのかよくわかりません。

また、これはこれを行うための「良い」方法ですか、または私がやろうとしていることにもっと標準的なアプローチがありますか?

110
Austin Hyde

質問のメイクファイル部分

以下のコードのように一般化する必要がない限り、これは非常に簡単です(ただし、スペースのインデントをg ++の近くのタブに置き換えます)

SRC_DIR := .../src
OBJ_DIR := .../obj
SRC_FILES := $(wildcard $(SRC_DIR)/*.cpp)
OBJ_FILES := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES))
LDFLAGS := ...
CPPFLAGS := ...
CXXFLAGS := ...

main.exe: $(OBJ_FILES)
   g++ $(LDFLAGS) -o $@ $^

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
   g++ $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<

依存グラフの自動生成

ほとんどのmakeシステムの「必須」機能。 GCCを使用すると、-MMDフラグをCXXFLAGSおよび-include $(OBJ_FILES:.o=.d)にmakefile本体の最後に追加することにより、コンパイルの副作用として1回のパスで実行できます。

CXXFLAGS += -MMD
-include $(OBJ_FILES:.o=.d)

そして、既に述べたように、常に GNU Make Manual があり、とても役立ちます。

173
bobah

ワイルドカードは私にとっても機能しますが、ディレクトリ変数を使用している人のために、サイドノートを付けたいと思います。フォルダツリーには常にスラッシュを使用します(バックスラッシュではありません)。それ以外の場合は失敗します。

BASEDIR = ../..
SRCDIR = $(BASEDIR)/src
INSTALLDIR = $(BASEDIR)/lib

MODULES = $(wildcard $(SRCDIR)/*.cpp)
OBJS = $(wildcard *.o)
5
xesf