次のメイクファイルがあります。
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.cpp
、DBC.cpp
、Trace.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
が見つからないのはなぜですか?これを修正するには?
メイクファイルのこれらの行、
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)
プリプロセッサはStdCUtil/split.h
を探しています
./
(つまり、/root/Core/
、 #includeステートメントを含むディレクトリ )。 ./
+ StdCUtil/split.h
= ./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)
これはmakeに関する質問ではなく、#include
ディレクティブのセマンティックに関する質問です。
問題は、パス "../StdCUtil/StdCUtil/split.h"にファイルがないことです。これは、コンパイラがインクルードパス "../StdCUtil"を#include
ディレクティブ "StdCUtil/split.h"からの相対パスと組み合わせたときに生じるパスです。
これを修正するには、-I..
の代わりに-I../StdCUtil
を使用します。
_INC_DIR=../ ../StdCUtil
_を試してください。
次に、CCFLAGS=-c -Wall $(addprefix -I,$(INC_DIR))
を設定します
編集:また、_#include
_を_#include <StdCUtil/split.h>
_に変更して、コンパイラが_#include
_を使用して.cppのローカルパスではなく-Iを使用することを認識できるようにします。