С++ Makefile отсутствует разделитель в .dep

В OS X Mavericks я пытаюсь создать проект, используя следующий Makefile:

CC=g++
EXECUTABLE=minigi
SRC_DIR=src
INTERM_DIR=obj

INCLUDES=-I $(SRC_DIR) -I /usr/local/Cg/examples/OpenGL/glew/include/
LIBS=-L/usr/local/lang/NVIDIA_GPU_Computing_SDK/sdk/C/common/lib/linux/ -lpng -stdc++ -lGL -lGLU -lGLEW -lSDLmain -lSDL -lgomp
CFLAGS_COMMON=$(INCLUDES)
CFLAGS=$(CFLAGS_COMMON) -O3 -DNDEBUG -fopenmp
#CFLAGS=$(CFLAGS_COMMON) -g -O0 -D_DEBUG 

SOURCE_FILES=$(shell find $(SRC_DIR) -iname '*.cpp')
DEP_FILES=$(SOURCE_FILES:$(SRC_DIR)/%.cpp=./$(INTERM_DIR)/%.dep)
OBJ_FILES=$(SOURCE_FILES:$(SRC_DIR)/%.cpp=./$(INTERM_DIR)/%.o)

all: $(EXECUTABLE)

clean:
    rm -rf obj $(EXECUTABLE)

.PHONY: clean all

.SUFFIXES:
.SUFFIXES:.o .dep .cpp .h

$(INTERM_DIR)/%.dep: $(SRC_DIR)/%.cpp
    mkdir -p `dirname $@`
    printf `dirname $@`/ > $@
    $(CC) $(CFLAGS_COMMON) $< -MM | sed -r -e 's,^(.*)\.o\s*\:,\1.o $@ :,g' >> $@

ifneq ($(MAKECMDGOALS),clean)
-include $(DEP_FILES)
endif

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

$(EXECUTABLE): $(OBJ_FILES)
    $(CC) $^ $(LIBS) -o $@

Однако, когда я набираю make, я получаю следующую ошибку:

obj/app/sdl_gl_appliacation.dep:1: *** missing separator.  Stop.

Файл obj/app/sdl_gl_application.dep выглядит следующим образом:

-n  obj/app/

Поскольку я очень мало знаю о make-файлах (и не писал опубликованный), любая помощь будет оценена по достоинству.

P.S. Я изменил строку printf dirname $@/ > $@ . В исходном файле было echo -n, но оно не работает в OS X.


person Heribert    schedule 15.05.2014    source источник
comment
Что ж, файлы, которые included превращаются в makefile, должны иметь синтаксис makefile, а ваш файл .dep, скорее всего, не будет. Хотя мы никак не можем знать, как это должно выглядеть...   -  person twalberg    schedule 15.05.2014
comment
попробуйте запустить make clean, чтобы очистить поврежденные файлы .dep...   -  person Chris Dodd    schedule 16.05.2014


Ответы (1)


Что ж, давайте немного почистим это.

То, как обрабатываются зависимости, действительно уродливо, GCC может сделать это за вас автоматически.

EXECUTABLE  :=  minigi

SRC_DIR     :=  src
OBJ_DIR     :=  obj

SRC_FILES   :=  $(wildcard $(SRC_DIR)/*.cpp)
OBJ_FILES   :=  $(SRC_FILES:$(SRC_DIR)/%.cpp=$(OBJ_DIR)/%.o)
DEP_FILES   :=  $(OBJ_FILES:.o=.d)

LDLIBS      :=  -lpng -lstdc++ -lGL -lGLU -lGLEW -lSDLmain -lSDL -lgomp
LDFLAGS     :=  -L/usr/local/lang/NVIDIA_GPU_Computing_SDK/sdk/C/common/lib/linux/

CPPFLAGS    :=  -MMD -MP -DNDEBUG -fopenmp -I $(SRC_DIR) -I /usr/local/Cg/examples/OpenGL/glew/include/
CXXFLAGS    :=  -O3

.PHONY: all clean

all:    $(EXECUTABLE)

clean:
    $(RM) -r $(OBJ_DIR) $(EXECUTABLE)

$(EXECUTABLE):  $(OBJ_FILES)
    $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | $(OBJ_DIR)
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $<

$(OBJ_DIR):
    mkdir $@

ifeq "$(MAKECMDGOALS)" ""
-include $(DEP_FILES)
endif

Несколько быстрых заметок:

  • Вы используете C++, поэтому вам следует использовать $(CXX) вместо $(CC), который используется для кода C.

  • Наряду с этим вы должны использовать $(CXXFLAGS) вместо $(CFLAGS).

  • $(CPPFLAGS) предназначен для флагов препроцессора (-I, -D или -fopenmp, который является флагом времени компиляции).

  • -MMD -MP флаги препроцессора будут автоматически генерировать файлы зависимостей при компиляции. Подробнее .

  • $(LDFLAGS) предназначен для флагов компоновщика, таких как флаги -L.

  • $(LDLIBS) предназначен для линкерных библиотек, таких как флаги -l

  • Избегайте использования функции $(shell ), так как она будет выполняться каждый раз, когда переменная расширяется при назначении с помощью оператора = вместо оператора :=. $(wildcard ) больше подходит для работы со списком файлов.

person Chnossos    schedule 15.05.2014
comment
Прежде всего большое спасибо за ответ и подробное объяснение. Это очень помогло понять файл. Если я сейчас попытаюсь построить, я получу fatal error: 'omp.h' file not found'. Я нашел эту ссылку что должно быть проблемой. Я установил gcc с помощью brew и добавил CC := gcc-4.8 в make-файл. Однако та же ошибка, что и раньше, возникает при сборке проекта. - person Heribert; 16.05.2014
comment
Как сказано выше в моем ответе, вам нужно использовать переменную CXX, а не CC. Кроме того, поскольку в вашем проекте используется C++, вам нужно использовать g++, а не gcc. Чтобы мне было легче помочь вам, вы должны отредактировать свой вопрос и добавить несколько сведений, таких как ваша ОС/дистрибутив, где вы взяли свой Makefile в первую очередь, и добавить весь вывод при использовании make. - person Chnossos; 16.05.2014
comment
Вы снова были правы :) Замена CC на CXX и gcc-4.8 на g++-4.8 помогла. Тогда у меня была только проблема, что GL/gl.h не был найден. Однако, как объясняется в этой ссылке, необходима простая замена GL на OpenGL на Мак. Теперь, за исключением некоторых ошибок компиляции, проект собирается, и поэтому я считаю эту проблему сборки решенной. Еще раз спасибо за помощь :) - person Heribert; 17.05.2014