Makefile работает% .c, не работает% .cpp - PullRequest
0 голосов
/ 26 января 2010

У меня есть набор make-файлов, которые я использую для создания «большого» C-проекта. Сейчас я пытаюсь использовать некоторые из них в своем проекте C ++ и столкнулся с этой головной болью, которую я просто не могу понять.

Makefile выглядит так

SOURCES = \
elements/blue.cpp

# Dont edit anything below here

VPATH = $(addprefix $(SOURCE_DIR)/, $(dir $(SOURCES)))

CXXFLAGS = $(OPT_FLAGS) -MMD -MF $(BUILD_DIR)/$*.d -D_LINUX -DNDEBUG -pipe
DCXXFLAGS = $(DEBUG_FLAGS) -MMD -MF $(BUILD_DIR)/$*.d -v -D_LINUX -D_DEBUG -pipe

OBJECTS := $(patsubst %.cpp, $(BUILD_DIR)/Release/%.o, $(notdir $(SOURCES)))
DOBJECTS := $(patsubst %.cpp, $(BUILD_DIR)/Debug/%.o, $(notdir $(SOURCES)))

$(OBJECTS): $(BUILD_DIR)/Release/%.o: %.cpp
    +@[ -d $(dir $@) ] || mkdir -p $(dir $@)
    $(CPP) $(INCLUDE) $(CXXFLAGS) $(DEFINES) -o $@ -c $<

Это немного сложно, но в C он создает все файлы% .c, определенные в SOURCES, и помещает объектные файлы в BUILD_DIR. Это прекрасно работает в c, но это не работает с файлами cpp. Я получаю

make: *** No rule to make target `blue.cpp', needed by `build/Release/blue.o'.  Stop.

Это как VPATH вообще не работает. Я пытался

vpath %.cpp src/elements

но это тоже не работает.

Удивительно, но если переименовать blue.cpp в blue.c и отредактировать make-файл обратно в% .c, он работает, он прекрасно компилируется.

Я схожу с ума здесь?

Ответы [ 3 ]

3 голосов
/ 26 января 2010

Вам действительно нужен VPATH - у меня не было ничего, кроме проблем в прошлом. И на самом деле, я, кажется, помню, что VPATH зависит от расширений, так что это соответствовало бы теории Эйдена. В моих make-файлах я явно указываю исходный каталог SDIR:

SDIR = ./somewhere
... 
$(ODIR)/%.o: $(SDIR)/%.cpp 
    $(CC) -c $(INC) -o $@ $< $(CFLAGS) 

.

Редактировать: Если вы привержены использованию VPATH, вам необходимо изучить использование директивы vpath (обратите внимание на разницу регистра). Например:

vpath %.cpp foo:bar

ищет файлы .cpp в каталогах foo и bar. Но, как я уже сказал, у меня не было ничего, кроме проблем с этим.

3 голосов
/ 26 января 2010

Из вашего примера похоже, что у вас не активировано правило Makefile для компиляции файлов C ++. Может быть, ваши % неправильно расширяются?

Попробуйте

$(OBJECTS): %.o: %.cpp
    ...

И укажите пункт назначения в части правила, используя $(basename ..), где это необходимо.

Это работает для C для blue.c, потому что в Make есть встроенное правило по умолчанию для компиляции C-файлов. Я подозреваю, что запуск Make с параметром --no-builtin-rules приведет к тому, что файл blue.c также перестанет работать.

Из документов

Компиляция программ на C n.o автоматически создается из n.c с помощью команды вида $(CC) -c $(CPPFLAGS) $(CFLAGS)'. Compiling C++ programs n.o is made automatically from n.cc, n.cpp, or n.C with a command of the form $ (CXX) -c $ (CPPFLAGS) $ (CXXFLAGS). Мы рекомендуем вам использовать суффикс .cc' for C++ source files instead of .C '.

Там является правилом C ++ по умолчанию, но оно может не сработать из-за другого правила или плохих переменных. Лучше написать правило явно, чтобы быть уверенным.

Вам нужно правило, такое как:

%.o: %.cpp
    $(CPP) $(CPP_OPTS) -c -o $@ $<

Для компиляции ваших объектных файлов из исходного кода, у вас есть:

executable: $(OBJECTS)
    ... compile objects into final blob ...

Где объекты какого-либо формата %.o вызывают зависимость. Или используйте Autotools / Autoconf , чтобы создать свой Makefile для вас. Вот пример, который я написал, который просто собирает файлы C ++ в каталог объектов:

SOURCES=$(wildcard path/to/src/*.cpp)
OBJECTS=$(SOURCES: .cpp=.o)
CC=g++

final: $(OBJECTS)
    mv $(OBJECTS) /path/to/build_dir

%.o: %.cpp:
    g++ -c -o $@ $<

Ни в коем случае не полный пример, но вы поняли идею. В правиле final вы копируете объектные файлы, но вы можете сделать что угодно здесь или изменить параметр -o, чтобы подключать файлы сборки в определенном месте.

0 голосов
/ 26 января 2010

Хорошо, ребята, я понял это здесь, и это большая ошибка ошибки.

После дополнительных экспериментов я отправил сообщение об ошибке в список make-bugs и включил отладочный вывод, чтобы точно сказать им, что происходит. Оказывается, я должен был сделать это раньше, потому что это привело меня прямо к решению.

Я использую схему автоматической генерации зависимостей, разработанную из http://mad -scientist.net / make / autodep.html и, как ни странно, это нарушило make. Возникла проблема с этой строкой

-include $(patsubst %.c, $(BUILD_DIR)/%.d, $(notdir $(SOURCES)))

Я не изменил это на% .cpp и по какой-то причине попытка включить blue.cpp заставила make не искать его с помощью vpath, когда он пытался разрешить

$(OBJECTS): $(BUILD_DIR)/Release/%.o: %.cpp

Так что решение было просто правильно портировать make-файл, дох!

...