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ć?

 18
Author: tonga, 2014-03-21

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)
 25
Author: David Hammen,
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

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)
 4
Author: manlio,
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.

 0
Author: cmaster,
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.

 0
Author: Bill Perkins,
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