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


116

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

/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

私はメイクファイルの経験がほとんどないので、これを達成するために何を検索すればよいか本当にわかりません。

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



6
@aaa:OPが各ソースファイルを明示的にリストする必要のないソリューションを必要としていると思います。
カスカベル2010年

7
持っている各ソースファイルを指定したくないので、そのマニュアルを以前に読んだことがありますが、まとまりがなく、理解しにくいと思います。私は、乾いた技術マニュアルよりも、私が期待することを十分に説明する実際の例から、はるかによく学びます。
オースティンハイド

はい。しかし、makeドキュメントは優れた例で優れています(テクニカルマニュアルではありません)。あなたはパターンルールを探しています:gnu.org/software/make/manual/make.html#Pattern-Rules
Anycorn

11
それは私が望むものに少し似ています。IMHOですが、makeのマニュアルは少しドライです。makeの中間レベルにいる開発者を対象としているため、それよりもはるかに大きくて詳細です。多分多すぎる。
オースティンハイド

回答:


180

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

以下のコードのようなものを一般化する必要がない限り、これはかなり簡単です(ただし、スペースのインデントを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) メイクファイル本体の端部に:

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

そして、すでに述べたように、常にGNU Make Manual手元に置いておくと、非常に役立ちます。


11
ああ、あなたは数秒で私を倒しました。しかし、私はお勧めしOBJ_FILES = $(patsubst src/%.cpp,obj/%.o,$(CPP_FILES))ます。
ベータ

1
これを機能させるには、これを変更する$<必要があり$^ました。main.exeのルールを考慮してくださいobj/%.o: src/%cpp

1
@bobah「。」がありません cppのオブジェクトルールで
regomodo

1
特殊変数はmakefile固有であり、検索が難しいため、おそらく説明する価値があります。gnu.org
Blake

2
これは古い質問であることはわかっていますが、プロジェクトに応じて少し変更しましたが、機能しません。ここに私のメイクファイルがあります:pastebin.com/4CksG9Wc コンソールに入る:make: *** No rule to make target '/main.o', needed by 'bin/main'. Pare.
Mateus Felipe

5

ワイルドカードも私にとっては機能しますが、ディレクトリ変数を使用している人のために補足しておきたいと思います。フォルダツリーには常にバックスラッシュではなくスラッシュを使用してください。スラッシュを使用しないと失敗します。

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

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

スラッシュの意味ですか?あなたの例は、伝統的にフォワードスラッシュと考えられているものを示しています。具体的には、「右に傾いている」ものは「前方」と見なされ、左にあるものは「後方」と見なされます
Evan Teran

はい、そうです、私は「スラッシュ」だけを意味します。投稿を更新しました。
xesf 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.