указать каталог для объектных файлов C ++ и исполняемого файла в Makefile

Я использую gcc -MM для создания предварительных требований правил зависимостей для компиляции исходных файлов в объектные файлы. Я хочу указать каталог для хранения объектных файлов и исполняемого файла в значении некоторой переменной BIN_DIR = bin / release /. Есть два случая:


ДЕЛО 1

%.d: *.h *.cc Makefile
     @$(CXX) -MM $(CXXFLAGS) *.cc > $@.$$$$; \
     sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; $(RM) -rf $@.$$$$

Хотя я был незнаком с sed, я узнал, что цель утилиты sed - переводить (например):

main.o: main.cc defs.h

в:

main.o main.d: main.cc defs.h

У меня вопрос, как изменить его на: bin / release / main.o bin / release / main.d: main.cc defs.h

Если бы кто-то мог объяснить здесь использование sed, мы были бы очень признательны!


СЛУЧАЙ 2

Makefile.depend: *.h *.cc Makefile
    $(CXX) -MM $(CXXFLAGS) *.cc > Makefile.depend

В файле Makefile.depend вы увидите, что каждое правило похоже на этот пример:

main.o: main.cc defs.h

Как поменять на:

bin / release / main.o: main.cc defs.h

Спасибо и привет!


ЗАМЕТКА:

Не знаю, почему я не могу сейчас комментировать. Итак, я разместил свое обновление здесь:

VPATH - это указать каталог с исходным кодом. Но тогда вам нужно запустить make -f path2Makefile с того места, где вы хотите разместить объектные файлы. Здесь я хотел бы иметь возможность запускать make -f path2 Makefile из любого места. Поэтому предпочтительнее указывать каталог для объектных файлов.


К бета-версии:

Спасибо за вашу помощь! Извините, что не могу прокомментировать ваш ответ. Проблема с вашим методом во втором случае заключается в том, что после команды некоторые правила с несколькими строками будут получать префикс в каждой отдельной строке. например

main.o: main.cc defs.h \

src / misc.h

становится:

$ (BIN_DIR) main.o: main.cc defs.h \

$ (BIN_DIR) src / misc.h


person Tim    schedule 03.09.2009    source источник
comment
Ой, прошу прощения. Прошло довольно много времени с тех пор, как я прикоснулся к своим обработчикам зависимостей, поэтому я забыл. Позвольте мне исправить это ...   -  person Beta    schedule 03.09.2009


Ответы (2)


Для случая 1 вы можете использовать:

sed 's,\($*\)\.o[ :]*,$(BIN_DIR)\1.o $(BIN_DIR)$@ : ,g'

Регулярные выражения, как известно, трудно читать новичкам, но в основном это говорит: «возьмите целевой стержень (помните, что это как элемент 1), за которым следует .o, сожмите все пробелы и двоеточия, которые следуют за ним, и замените все это на BIN_DIR, запомненное вещь, .o, пробел, BIN_DIR, цель правила, пробел и двоеточие ".

Случай 1 доставит вам неприятности. Во-первых, вы всегда будете перестраивать main.o и main.d независимо от того, действительно ли вам это нужно или нет. Есть несколько способов исправить это - самый простой - сделать цели $ (BIN_DIR) main.d и $ (BIN_DIR) main.o, но есть более сложные методы, которые вы можете попробовать позже.

Для случая 2 это должно помочь:

sed 's,^,$(BIN_DIR),'

Здесь регулярное выражение говорит: «Измените начало строки на BIN_DIR».

EDIT: вторая попытка

sed 's,\(.*:\),$(BIN_DIR)\1,'

Это говорит: «Найдите что-нибудь, заканчивающееся двоеточием, и вставьте перед ним BIN_DIR». Следующим шагом в обеспечении пуленепробиваемости будет «втягивать несколько строк и помещать BIN_DIR перед каждым словоподобным элементом, предшествующим двоеточию», но это, вероятно, не обязательно, постучите по дереву.

person Beta    schedule 03.09.2009

Найдите 'vpath' в руководстве по сборке gnu.org. Думаю, это то, что тебе нужно.

person Jay    schedule 03.09.2009