Makefile: jak poprawnie dołączyć plik nagłówka i jego katalog?
Mam następujący 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
Ten plik makefile i wszystkie trzy pliki źródłowe Lock.cpp
, DBC.cpp
, Trace.cpp
znajdują się w bieżącym katalogu o nazwie Core
. Jeden z plików źródłowych Trace.cpp
zawiera linię zawierającą plik nagłówkowy poza bieżącym katalogiem:
//in Trace.cpp
#include "StdCUtil/split.h"
Plik nagłówkowy split.h
znajduje się na jednym poziomie nad bieżącym katalogiem, a następnie w podkatalogu o nazwie StdCUtil
. Dlatego dodałem INC_DIR = ../StdCUtil
do makefile. Ogólna struktura katalogów wygląda jak poniżej:
root
|___Core
| |
| |____Makefile
| |____DBC.cpp
| |____Lock.cpp
| |____Trace.cpp
|
|___StdCUtil
|___split.h
Ale kiedy to robię, to daje mi błąd:
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
Dlaczego to nie znajduje pliku nagłówkowego split.h
, nawet jeśli podam INC_DIR
w pliku makefile? Jak to poprawić?
4 answers
Te linie w Twoim makefile,
INC_DIR = ../StdCUtil
CFLAGS=-c -Wall -I$(INC_DIR)
DEPS = split.h
I ta linia w Twoim .plik cpp,
#include "StdCUtil/split.h"
Są w konflikcie.
Z Twoim makefile w katalogu źródłowym i z tą opcją -I
powinieneś używać #include "split.h" in your source file, and your dependency should be
../ StdCUtil / splith`.
Inna opcja:
INC_DIR = ../StdCUtil
CFLAGS=-c -Wall -I$(INC_DIR)/.. # Ugly!
DEPS = $(INC_DIR)/split.h
Z tym #include
dyrektywa pozostanie #include "StdCUtil/split.h"
.
Kolejną opcją jest umieszczenie pliku makefile w katalogu nadrzędnym:
root
|____Makefile
|
|___Core
| |____DBC.cpp
| |____Lock.cpp
| |____Trace.cpp
|
|___StdCUtil
|___split.h
Z tym układem jest wspólne dla umieść pliki obiektowe (i ewentualnie plik wykonywalny) w podkatalogu, który jest równoległy do katalogów Core
i StdCUtil
. Object
, na przykład. Dzięki temu Twój makefile staje się:
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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-20 21:36:04
Preprocesor szuka StdCUtil/split.h
w
-
./
(tj./root/Core/
, katalog zawierający instrukcję # include ). Więc./
+StdCUtil/split.h
=./StdCUtil/split.h
Brak pliku
I w
-
$INC_DIR
(tj.../StdCUtil/
=/root/Core/../StdCUtil/
=/root/StdCUtil/
). Więc../StdCUtil/
+StdCUtil/split.h
=../StdCUtil/StdCUtil/split.h
Brak pliku
Możesz naprawić błąd zmieniając zmienną $INC_DIR
(najlepsze rozwiązanie):
$INC_DIR = ../
Lub dyrektywy include:
#include "split.h"
Ale w w ten sposób straciłeś "składnię ścieżki", która wyjaśnia, do jakiej przestrzeni nazw lub modułu należy plik nagłówkowy.
Odniesienie:
EDYCJA / AKTUALIZACJA
Powinno być też
CXX = g++
CXXFLAGS = -c -Wall -I$(INC_DIR)
...
%.o: %.cpp $(DEPS)
$(CXX) -o $@ $< $(CXXFLAGS)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:00:35
To nie jest pytanie o make, to pytanie o semantykę #include
dyrektywy.
Problem polega na tym, że na ścieżce nie ma pliku"../StdCUtil/stdcutil / split.h". Jest to ścieżka, która powstaje, gdy kompilator połączy ścieżkę include"../StdCUtil "ze ścieżką względną z dyrektywy #include
" stdcutil / split.h".
Aby to naprawić, po prostu użyj -I..
zamiast -I../StdCUtil
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-20 21:17:14
Spróbuj INC_DIR=../ ../StdCUtil
.
Następnie Ustaw CCFLAGS=-c -Wall $(addprefix -I,$(INC_DIR))
EDIT: również zmodyfikuj swoje {[2] } na #include <StdCUtil/split.h>
tak, aby kompilator wiedział, że używa -I zamiast lokalnej ścieżki .cpp za pomocą #include
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-20 21:31:20