Сделать поиски зависимостей не в том месте - PullRequest
0 голосов
/ 21 декабря 2011

Я относительно новичок в (GNU) Make и нахожу это невероятно трудным.Я думаю о переходе на SCons, но все же, я хотел бы понять.

У меня есть make-файл в папке, которая содержит подкаталоги ./src, ./obj/[release|debug] и ./bin[выпуск | отладка].Makefile должен иметь возможность собирать исходные тексты C ++ в ./src, компилировать их в объектные файлы в соответствующем каталоге ./obj, связывать эти объектные файлы и помещать результат в соответствующий каталог ./bin.Вот мой make-файл (отредактированный для простоты):

CONFIG = release
#CONFIG = debug

OBJS = Container.o

OBJDIR = obj/$(CONFIG)
BINDIR = bin/$(CONFIG)

VPATH = src $(BINDIR)
vpath %.o $(OBJDIR)

.PHONY: release

release:  $(OBJS)
    $(CXX) $(LXXFLAGS) -o $(BINDIR)/$@ $^

Container.o: Container.cpp Container.hpp
    $(CXX) -c $(CXXFLAGS) -o $(OBJDIR)/$@ $<

При первом запуске make цель «release» будет искать «Container.o» в текущей папке, а также в $ (OBJDIR).Не найдя его, цель secong будет выполнена правильно, сгенерировав объектный файл в правильной папке.Затем будет выполнена цель «release», но компоновщик пожалуется, что «Container.o» не найден ...

Во второй раз, когда я запускаю make, цель «release» будет искать «Container».o "и найдите его в $ (OBJDIR).После этого компоновщик будет работать правильно (путь к файлу «Container.o» добавляется к имени файла).

Есть ли способ заставить его работать за один проход?Это сводит меня с ума!

1 Ответ

0 голосов
/ 21 декабря 2011

У Make действительно длинная кривая обучения, и вы пытаетесь сделать что-то хитрое (что наталкивается на одну из главных слабостей Make - плохую работу с подстановочными знаками).Я не уверен, что мой ответ поможет более чем запутать, но, по крайней мере, он решит вашу конкретную проблему.

Если вы хотите использовать подход CONFIG, это сделает это:

CONFIG = release
#CONFIG = debug                                                                 

OBJS = Container.o

TRUE_OBJS = $(addprefix obj/$(CONFIG)/, $(OBJS))

vpath %.cpp src

.PHONY: $(CONFIG)

$(CONFIG): bin/$(CONFIG)/$(CONFIG)

bin/$(CONFIG)/$(CONFIG): $(TRUE_OBJS)
    $(CXX) $(LXXFLAGS) -o $@ $^                                               

$(TRUE_OBJS): obj/$(CONFIG)/%.o : %.cpp
    $(CXX) -c $(CXXFLAGS) -o $@ $<

Но вы можете обойтись без него (и без рутинной работы по редактированию make-файла всякий раз, когда вы хотите изменить конфигурации):

OBJS = Container.o

vpath %.cpp src

.PHONY: release debug

release: bin/release/release
debug: bin/debug/debug

bin/release/release: $(addprefix obj/release/, $(OBJS))
bin/debug/debug: $(addprefix obj/debug/, $(OBJS))

bin/release/release bin/debug/debug:
    $(CXX) $(LXXFLAGS) -o $@ $^   

obj/release/%.o obj/debug/%.o: %.cpp
    $(CXX) -c $(CXXFLAGS) -o $@ $<                                            
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...