web-dev-qa-db-ja.com

Makefile:ヘッダーファイルとそのディレクトリを正しく含める方法

次のメイクファイルがあります。

CC=g++
INC_DIR = ../StdCUtil
CFLAGS=-c -Wall -I$(INC_DIR)
DEPS = split.h

all: Lock.o DBC.o Trace.o

%.o: %.cpp $(DEPS)
    $(CC) -o $@ $< $(CFLAGS)

clean:
    rm -rf *o all

このメイクファイルと3つのソースファイルすべてLock.cppDBC.cppTrace.cppは、Coreという現在のディレクトリにあります。ソースファイルの1つTrace.cppには、現在のディレクトリ外のヘッダーファイルを含む行が含まれています。

//in Trace.cpp
#include "StdCUtil/split.h"

ヘッダーファイルsplit.hは、現在のディレクトリの1レベル上にあり、StdCUtilというサブディレクトリにあります。そのため、メイクファイルにINC_DIR = ../StdCUtilを追加しました。全体的なディレクトリ構造は次のようになります。

root
  |___Core
  |     |
  |     |____Makefile
  |     |____DBC.cpp
  |     |____Lock.cpp
  |     |____Trace.cpp
  |
  |___StdCUtil
        |___split.h

しかし、私がそれを作るとき、それは私にエラーを与えます:

Trace.cpp:8:28: fatal error: StdCUtil/split.h: No such file or directory
 #include "StdCUtil/split.h"
                            ^
compilation terminated.
<builtin>: recipe for target 'Trace.o' failed

Makefileでsplit.hを指定しても、ヘッダーファイルINC_DIRが見つからないのはなぜですか?これを修正するには?

19
tonga

メイクファイルのこれらの行、

INC_DIR = ../StdCUtil
CFLAGS=-c -Wall -I$(INC_DIR)
DEPS = split.h

.cppファイルのこの行、

#include "StdCUtil/split.h"

対立しています。

ソースディレクトリのmakefileとその-Iオプションを使用して、#include "split.h" in your source file, and your dependency should be ../StdCUtil/split.h`を使用する必要があります。

別のオプション:

INC_DIR = ../StdCUtil
CFLAGS=-c -Wall -I$(INC_DIR)/..  # Ugly!
DEPS = $(INC_DIR)/split.h

これにより、#includeディレクティブは#include "StdCUtil/split.h"のままになります。

さらに別のオプションは、メイクファイルを親ディレクトリに配置することです。

root
  |____Makefile
  |
  |___Core
  |     |____DBC.cpp
  |     |____Lock.cpp
  |     |____Trace.cpp
  |
  |___StdCUtil
        |___split.h

このレイアウトでは、CoreおよびStdCUtilディレクトリと並行するサブディレクトリにオブジェクトファイル(および場合によっては実行可能ファイル)を配置するのが一般的です。 Objectなど。これにより、メイクファイルは次のようになります。

INC_DIR = StdCUtil
SRC_DIR = Core
OBJ_DIR = Object
CFLAGS  = -c -Wall -I.
SRCS = $(SRC_DIR)/Lock.cpp $(SRC_DIR)/DBC.cpp $(SRC_DIR)/Trace.cpp
OBJS = $(OBJ_DIR)/Lock.o $(OBJ_DIR)/DBC.o $(OBJ_DIR)/Trace.o
# Note: The above will soon get unwieldy.
# The wildcard and patsubt commands will come to your rescue.

DEPS = $(INC_DIR)/split.h
# Note: The above will soon get unwieldy.
# You will soon want to use an automatic dependency generator.


all: $(OBJS)

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
  $(CC) $(CFLAGS) -c $< -o $@

$(OBJ_DIR)/Trace.o: $(DEPS)
26
David Hammen

プリプロセッサはStdCUtil/split.hを探しています

そして

  • $INC_DIR(つまり、../StdCUtil/ = /root/Core/../StdCUtil/ = /root/StdCUtil/)。 ../StdCUtil/ + StdCUtil/split.h = ../StdCUtil/StdCUtil/split.hで、ファイルがありません

$INC_DIR変数の変更エラーを修正できます(最良の解決策):

$INC_DIR = ../

またはincludeディレクティブ:

#include "split.h"

しかし、この方法では、ヘッダーファイルがどのネームスペースまたはモジュールに属するかを非常に明確にする「パス構文」を失いました。

参照:

編集/更新

またする必要があります

CXX = g++
CXXFLAGS = -c -Wall -I$(INC_DIR)

...

%.o: %.cpp $(DEPS)
    $(CXX) -o $@ $< $(CXXFLAGS)
4
manlio

これはmakeに関する質問ではなく、#includeディレクティブのセマンティックに関する質問です。

問題は、パス "../StdCUtil/StdCUtil/split.h"にファイルがないことです。これは、コンパイラがインクルードパス "../StdCUtil"を#includeディレクティブ "StdCUtil/split.h"からの相対パスと組み合わせたときに生じるパスです。

これを修正するには、-I..の代わりに-I../StdCUtilを使用します。

0
cmaster

_INC_DIR=../ ../StdCUtil_を試してください。

次に、CCFLAGS=-c -Wall $(addprefix -I,$(INC_DIR))を設定します

編集:また、_#include_を_#include <StdCUtil/split.h>_に変更して、コンパイラが_#include_を使用して.cppのローカルパスではなく-Iを使用することを認識できるようにします。

0
Bill Perkins