Я создал make-файл, основанный на GNU Make tutorial: https://www.gnu.org/savannah-checkouts/gnu/make/manual/html_node/index.html#SEC_Contents.
Файл make отлично работает при первоначальном make, но если файл был изменен и make запущен, появляется сообщение об удалении циклической зависимости, которое не создает измененный файл. Отброшенная зависимость — bin / main.o <-bin / main.o. Это имеет смысл, так как main.o не должен зависеть от main.o. Я искал несколько сайтов, включая stackoverflow, и нашел несколько полезных ответов, но мне не удалось решить мою проблему. Эти две ссылки были наиболее актуальны для моей проблемы:
Makefile экспортирует .o файл по другому пути, чем .cpp а также
Ошибка циклической зависимости Makefile
Основываясь на вышеупомянутой информации, я отредактировал свой make-файл и, по крайней мере, теперь могу легче отлаживать. Проблема с зависимостями, вероятно, связана с последующей целью и предварительным условием после расширения по шаблону, но я просто не вижу этого.
Вот мой make-файл:
#For compilation
CC=g++
CC_FLAGS= -g -Wall -Werror -ansi -pedantic
#make[1]: main.o all <- all
#Folder structure
BIN_DIR:=bin
SRC_DIR:=src
H_DIR:=src/header
all:rshell
#VPATH = $(SRC_DIR)
H_FILES:=$(wildcard $(H_DIR)/*.h)
DEPS:$(wildcard $(BIN_DIR)/*.d)CPP_FILES:=$(wildcard $(SRC_DIR)/*.cpp)
OBJECTS := $(CPP_FILES:$(SRC_DIR)/%.cpp=$(BIN_DIR)/%.o)
$(BIN_DIR)/%.o: $(SRC_DIR)/%.cpp $(H_DIR)/%.h
mkdir -p $(BIN_DIR)
$(CC) -I$(H_DIR) -o $@ -c $< $(CC_FLAGS)
$(BIN_DIR)/main.o:$(SRC_DIR)/main.cpp $(OBJECTS) $(H_FILES)
$(CC) -I$(H_DIR) -o $@ -c $(SRC_DIR)/main.cpp $(CC_FLAGS)
rshell: $(OBJECTS)
$(CC) -o $(BIN_DIR)/$@ $(OBJECTS) $(CC_FLAGS)
include $(DEPS)
$(MAKEFILE_LIST): ;
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
.PHONY: clean
clean:
rm -rf $(BIN_DIR)
Вопрос 1. Если расширение по шаблону вызывает циклическую зависимость, как я могу это исправить?
Вопрос 2: Как можно отследить расширение по шаблону? Было бы правильно вывести имена файлов и проследить таким образом? Запуск make -d был полезен, но я не вижу, как этого избежать. Я предполагаю, что эти строки вызывают круговые зависимости:
$(BIN_DIR)/main.o:$(SRC_DIR)/main.cpp $(OBJECTS) $(H_FILES)
$(CC) -I$(H_DIR) -o $@ -c $(SRC_DIR)/main.cpp $(CC_FLAGS)
Спасибо за вашу помощь и понимание.
$(BIN_DIR)/main.o:$(SRC_DIR)/main.cpp $(OBJECTS) $(H_FILES)
В этой строке вы говорите, что для сборки main.o мне нужны main.cpp * .h и * .o
Но * .o имеет main.o, поэтому вы пишете main.o в зависимости от main.o. Просто удалите $ (OBJECTS), вам не нужен объект для создания объекта.
$(BIN_DIR)/main.o:$(SRC_DIR)/main.cpp $(H_FILES)
Не используйте подстановочные знаки, лучше указывать исходные файлы. Не используйте CC для компилятора c ++, стандартное использование CXX.
пример Makefile:
NAME = foo
CXX ?= g++
RM = rm
DEBUG ?= no
LEVEL ?= 3
LIB = -l m
INCLUDE = -I include
CXXFLAGS += -Wall -Wextra -O$(LEVEL)
CXXFLAGS += -ansi -pedantic -std=c++11
CXXFLAGS += $(INCLUDE)
ifeq ($(CXX), clang++)
CXXFLAGS += -Weverything
endif
ifneq ($(DEBUG), no)
CXXFLAGS += -g
endif
LDFLAGS = $(LIB)
ifeq ($(DEBUG), no)
LDFLAGS += -s
endif
SRC = main.cpp
SRC += foo.cpp
DPD = $(SRC:.cpp=.dpd)
OBJ = $(SRC:.cpp=.o)
all : $(NAME)
$(NAME) : $(OBJ)
$(CXX) $(OBJ) -o $(NAME) $(LDFLAGS)
clean :
$(RM) -f $(OBJ)
$(RM) -f $(DPD)
fclean : clean
$(RM) -f $(NAME)
re : fclean
$(MAKE) -C .
%.dpd : %.cpp
$(CXX) -MM $(<) -o $(@) $(CXXFLAGS) -MT $(<:.cpp=.o)
%.o : %.cpp
$(CXX) -c $(<) -o $(@) $(CXXFLAGS)
.PHONY : all clean fclean re %.dpd %.o
.SUFFIXES : .o.cpp .dpd.cpp
include $(DPD)
Других решений пока нет …